[comp.lang.prolog] PROLOG DIGEST V6 #27

restivo@POLYA.STANFORD.EDU (Chuck Restivo) (07/08/88)

Date: Wed, 4 May 1988 0:4:41 PST
From: Chuck Restivo (The Moderator) <PROLOG-REQUEST@POLYA.STANFORD.EDU>
Reply-to: PROLOG@POLYA.STANFORD.EDU>
US-Mail: P.O. Box 4584, Stanford CA  94305
Subject: PROLOG Digest   V6 #27
To: PROLOG@POLYA.STANFORD.EDU


PROLOG Digest           Friday, 1 Apr 1988      Volume 6 : Issue 27

Today's Topics:
                 Implementation - Trilogy & Destructive Assignments,
                                  & Simple Problem & end_of_file,
                                          & BSI Standard & A Wager
----------------------------------------------------------------------------------------------------------------------------

Date: 23 Mar 88 19:44:15 GMT
From: pacbell!att-ih!alberta!ubc-cs!voda@AMES.ARC.NASA.GOV  (Paul Voda)
Subject:  Compilation in Trilogy

Here is the answer formulated in a slightly more general setting:

The modes and types of Trilogy permit the native code compilation
of programs in such a way that there are no run-time tags on
most of the values, neither there are any reference counters.

The decision when to copy out and when to share the
values of input-output variables is done by a compile
time data-flow analysis. Similarly, the compiler of Trilogy checks whether
the output variables are assigned values in all branches of a predicate
(whether all input-output variables are initialized). There
is also a check to see that if-then-elses do not backtrack
(either before thens or among the branches), e.g.


   if x = 1 | x = 2 then
     x <> 1 & P(x)
   else
     ......
   end

The above is dissalowed by the compiler if x is output or
symbolic (logical), but is OK if x is input or input/output.
Thus we can guarantee that the negation of the formula
before a then is always properly computable.
Consequently if-then-elses and the formulas before thens
are compiled without any settings of choice points. We are
just releasing a version where non-backtracking ors (|)
(implemented by jumps instead of choice points) are permitted
in procedures (this is useful for the writing of the Trilogy
counterparts of Pascal's boolean functions).

There are two situations where the run-time tags on Trilogy values
are present:


1) the tags discriminating the union values, these should
   be also present in Pascal programs.

   For instance, the universal type U of all Trilogy's values has a 
   form of a union:

      U = R(R) | S(S) | P(U,U)
  
   The tags R(eal), S(tring), and P(air) are thus present in the
   values of U variables.

   If a value is not of a union type (tuple, list, array,
   integer, enumerated-type etc.) then it contains no tags,
   except of course the tags of any of its union constituents.

2) When a variable is of symbolic (logical) mode then Trilogy
   uses the type specific tags to identify the constraints
   attached to the variable (=, <, <>, etc.).


Because of the typing, modes, pred/proc modifiers and a quite extensive
data-flow analysis the compiler of Trilogy produces a procedural
code of Pascal-like quality while offering all the high-level
comfort of symbolic values with their associated constructors
and destructors as we know it from Prolog.

------------------------------
   
Date: 16 Mar 88 23:35:51 GMT
From: sanjay@arizona.edu  (Sanjay Manchanda)
Subject: Logic of Database Updates

 I have worked on doing database updates in Prolog in a  "logical"
fashion.   A database update is essentially an assignment  on the
database.   If we are going to update the database, why not first
develop a logic for reasoning about database assignments, and then
mechanize it in the true logic programming tradition?   A dynamic
logic is a reasonable choice for this task, since  dynamic logics
were developed to reason about programs which  explicitly manipulate
their state (i.e.   do assignment).    I have developed a dynamic
logic for reasoning database updates that doesn't look much like  the
dynamic logic's that you may have seen, but it leads to a simple
extension of Prolog.  

Instead of going into the logic, I will briefly explain the extension of 
Prolog. Richard introduced it rather well in a previous
message, so let me borrow some of his words.
>Roughly speaking, there are three classes of predicates:
>
>	pure predicates (don't depend on things that change)
>
>	state predicates (depend on things that change, but change nothing)
>
>	transition (or dynamic) predicates (express a relation between states)
>
>For example, we might say
>
>	p(X) :-
>		<-fred(X)> q(X).
>
>p(X) is true in a world W if there is a world W1 such that
>	-(fred(X), W, W1)			-- roughly, retract
>and	q(X) is true in W1.
>
>Note that this doesn't change W.

There are two sets of predefined dynamic predicates, +p and -p for
every pure predicate p.    Actually, to avoid some thorny
implementation and semantic problems, p is restricted to be a pure
predicate that is defined entirely by ground Prolog facts.    For
obvious reasons, such a predicate is called a database  predicate.
New dynamic (or transition) predicates can be defined by means of
Update Rules.   For example, we might say  

       add_flight(Fno, Src, Dest) <--
                 airport(Src), airport(Dest), 
		 <+flight(Fno, Src, Dest)>.

The use of the `<--' instead `:-' signals that a dynamic predicate is
being defined.    Here the semantics of add_flight(Fno, Src, Dest) is
a transition from a world W to a world W1, such that (airport(Src),
airport(Dest)) is true in W, and   W1 is obtained from W by adding
the fact flight(...)   to W.   Thus, viewed as an operator, + is
roughly equivalent to assert.  

The rule may be used in a top level query like:

   :-     <add_flight(20, 'LA', 'OHARE')>reachable('LA', 'JFK')

which is true in a current world W if there exists W1 accessible
through the meaning of add_flight(..), and reachable('LA','JFK') is
true in W1.  Assume that reachable is the transitive closure of the
flight relation.  The execution of the query is not very different
from Prolog execution.   Thus the call <+flight(..)>  will return a
new (world) database in which reachable(...)   will be evaluated.  If
this evaluation fails, backtracking will cause the inserted fact
flight(...)  to be removed.  Similarly, deletion on the database is
undone on backtracking.  

If the query succeeds, it will return a new updated database and
display to the user, all the changes that have been made to the
current database.  The user can then choose to commit these changes
and make them permanent, or reject them and leave the database
unchanged.    

The language has a well-defined declarative semantics, and a syntax
that reflects this semantics.   This makes it considerably better
than using assert and retract for database updates.   As an example,
note that in my proposed extension, updates are  statically scoped.
If p(X) is pure predicate or a state predicate, the database  is
guaranteed  to remain unchanged after it is executed.  This  can be
quite significant for compiler and database query optimization.

I did not allow updates to rule-defined predicates because  I wanted
to guarantee that (not p(a)) was true after  executing <-p(a)>.
However, I think that can extend the treatment if I use a weaker
semantics.   I will mail copies of [1], [2] and [3] to anyone who
requests them.  My apologies to Richard for forgetting to mail him a
copy of my paper.  

-- sanjay

 References:

[1] Sanjay Manchanda and David Scott Warren.
A Language for Database Updates.
In Jack Minker, editor, Foundations of Deductive Databases and
  Logic Programming, Morgan-Kaufmann, Los Altos, CA, 1987.

[2] Sanjay Manchanda, Soumtira Sengupta, and David S. Warren.
Concurrent Updates in a Prolog Database System
Technical Report 86/28, Department of Computer Science,
SUNY at Stony Brook, Stony Brook, NY 11794,
December 1986, Revised Feb 1987.

[3] Sanjay Manchanda
A Dynamic Logic Programming Language for Relational Updates.
Phd Thesis, SUNY at Stony Brook, Stony Brook, NY 11794, December
1987.

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

Date: 17 Mar 88 03:49:59 GMT
From: munnari!vuwcomp!lindsay@uunet.uu.net  (Lindsay Groves)
Subject:  mine embarrassingly simple problem

I'll save Richard saying it -- this doesn't say much about the program, and 
certainly doesn't explain why ancestral cuts are supposed to be necessary.
Could you describe the problem in a bit more detail and illustrate just 
how the need for ansectral cuts arises?  Perhaps a simplified version of the
problem could be used to illustrate the point.  An example would certainly 
help.

-- Lindsay Groves

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

Date: 23 Mar 88 01:16:54 GMT
From: quintus!ok@unix.sri.com  (Richard A. O'Keefe)
Subject:  mine embarrassingly simple problem

In that case, why not just code it as

	map(Function, Network) :-
		generate(Function, Network),
		test(Network),
		!.

	test(Network) :-
		lemma(Network, StopCondition).

More generally, suppose that you had several cases:

	test(Network) :-
		lemma(Network, ~~~),
		!(map(_,_)),
		p(...).
	...
	test(Network) :-
		lemma(Network, ~~~),
		!(map(_,_)),
		q(...).

Then you could recast this as

	map(Function, Network) :-
		generate(Function, Network),
		test(Network, Continuation),
		!,
		finish(Continuation, ...).

	finish(p, ...) :-
		p(...).
	...
	finish(q, ...) :-
		q(...).

	test(Network, p) :-
		lemma(Network, ~~~).
	...
	test(Network, q) :-
		lemma(Network, ~~~).

The basic idea is to redesign your "test" code so that it breaks into
three pieces: before-the-cut, the ancestral cut, and after-the-cut,
and then unfold the call to it so that the cut is exposed in "map".

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

Date: 20 Mar 88 20:55:02 GMT
From: lagache@violet.Berkeley.EDU  (Edouard Lagache)
Subject: My views on developing a PROLOG standard 

          To help get the creative juices flowing on those position papers,
     I thought I would throw in my two cents worth on this proposed
     standard.

          While I am not really qualified to make much commentary on the
     subject (So what? that has never stopped me before!), there are a
     number of peripheral matters that I would like to see addressed.

          The matter of greatest concern for me is the question of whose
     standard will be the standard?  The BSI group is a British standard;
     Now I hear that the French are working on their own standard (the AFNOR
     group).  All this is fine and good except that in all likelihood the
     resulting standards will have about as much similarity with each other
     as the French and English (natural) languages do (never mind the fact
     that neither standard will have have much to do with existing practice)
     - This is progress!?!

           Perhaps this is a wild fantasy on my part, but I would really
     like to see ONE (1) standard.  That standard should be agreed upon not
     just by the British and the French, but by ALL the major users of
     PROLOG which includes (at the very least) most of Europe, Japan, and
     the U.S.  It seems to me that someone should bug the ANSI standard
     committee, NOT to come up with their own standard (Lord have mercy on
     all those "C" and FORTRAN users once the new standards are in place),
     but to take part in an international effort to come up with the before
     mentioned 1 PROLOG standard.

          Fantasies aside, I do have a few comments on the BSI standard.  On
     the specifics of the "grimoire", I can only steal a quote from the
     venerable Michael Clancy: "Do the right thing".  In this case, "Do the
     right thing" means try to capture existing practice as much as possible
     (see "lots of smoke" on exactly what existing practice means on the
     FORTRAN SIG).  I do believe that asking the question of how existing
     code would run under the new standard is a valuable measure of the
     success at capturing existing practice.  Unless there is a *strong*
     reason to change syntax, the new standard shouldn't depart from
     existing practice.  Thus, I have read Richard O'Keefe's comments on his
     perceptions of the standard syntax with real concern.  Until I see a
     "reasonable" reply from the standards committee, I am inclined support
     Richard O'Keefe's position on this matter.

          At the end of last week there was some discussion of the standard
     library.  Here I have one suggestion, make the library big enough so
     that people don't have to reinvent the wheel all the time.  I took a
     lot of heat for my imfamous PROLOG libraries, while the code quality
     was perhaps inadequate, I believe that the concept was valuable.  Even
     in as rich a language as Franz LISP, I still found the need for 1600
     lines of additional general purpose functions.  So there is a lot of
     room expansion in PROLOG.

          I would like to suggest defining a separate set PROLOG libraries,
     much in the same way the UNIX "C" library is (was?) defined
     independantly of the language.  In this area, I would strongly suggest
     various levels of libraries.  There should be some core set that would
     be required for the standard language, then additional standards would
     be defined for supplemental libraries.  <*Fantasy mode on*>  Ideally
     the standards committee should provide source code for those
     supplemental libraries in the core standard language (when possible),
     so that anyone using any standard PROLOG implementation could use the
     full set of libraries (if more slowly than if all the predicates were
     builtin). <*Fantasy mode off*>  In any case, Everybody knows that the
     first thing PROLOG system implementors do is to embellish on the
     standard core library, so wouldn't it be nice if the standard included
     a few hundred predicates to keep those implementors busy upgrading
     their product in a standard way (maybe I should have kept Fantasy mode
     on?)

          The last thing I would really like to see is some vast
     improvement in the standard user interface tools.  Even if not all
     hardware can support it, I would like to see some standard way to
     access windows, i/o devices (i.e. mice), and or forth.  If one could
     write complete applications in PROLOG that had portable "bells and
     whistles", that would make PROLOG much more attractive for those trying
     to make polished products for end users, since that would greatly reduce
     porting problems (I know, Fantasy mode is still on!)

     Still dreaming in California,

    -- Edouard Lagache

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

Date: 23 Mar 88 01:09:49 GMT
From: quintus!ok@unix.sri.com  (Richard A. O'Keefe)
Subject:  My views on developing a PROLOG standard (long but fun!)

Wrong.  Roger Scowen of NPL get the thing started; since the NPL is in
England he naturally got the thing started as a BSI project.  AFNOR are
not developing a rival standard;  they have been collaborating with the
BSI group for a long time now, and the Formal Specification is French work.
(While many people will find it the most confusING part of the BSI material,
it is arguably the least confusED.)  The whole thing has now become, I hear,
an ISO "work item", and the more recent BSI documents bear ISO reference
numbers.

>      That standard should be agreed upon not
>      just by the British and the French, but by ALL the major users of
>      PROLOG which includes (at the very least) most of Europe, Japan, and
>      the U.S.

Hear hear.  And don't forget the South Pacific (home of NU Prolog and CLP)
or Israel (home of Wisdom Prolog).

>      I took a
>      lot of heat for my imfamous PROLOG libraries, while the code quality
>      was perhaps inadequate, I believe that the concept was valuable.

Too right.

>           The last thing I would really like to see is some vast
>      improvement in the standard user interface tools.  Even if not all
>      hardware can support it, I would like to see some standard way to
>      access windows, i/o devices (i.e. mice), and or forth.

I understand that agreement on the Common Lisp binding for X is at least
a year away.  Plagiarism being the sincerest form of flattery, I suggest
that it might be an idea to wait for the Lisp people to do the work, and
then transliterate as much of it as possible.  Or would a 'curses'
binding be of more immediate use?  Either way, I don't see any need for
a standard way to access Forth; Postscript maybe, but not Forth (:-).

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

Date: 21 Mar 88 09:26:04 GMT
From: nsc!taux01!shahaf@decwrl.dec.com  (Shahaf Moshe)
Subject:  mine embarrassingly simple problem
First I would like to make two comments:
* I am a NOVICE (in Prolog).
* I do not claim that in my application Ansectral Cut are a MUST. I wrote it on
  a system were it was a feature and I used it. Since its not available in
  Quintus Prolog, I asked for help.

About the application,
The program looks for best mapping of a Boolean function onto a set of logic
primitives such as 
	X * Y * Z maps to: 2inputAnd( 2inputAnd( X, Y) , Z)
	               or: 3inputAnd( X, Y, Z)
	       
	       Since the search space is huge I used Ansectral Cut to abort
mapping once I get some "STOP CONDITIONS".

The program looks like:

map(Function,Network) :-
			generate(Function,Network),
			test(Network).
test(Network) :-
		lemma(Network,StopCondition),
		!(map).	    %this cut aborts the process.

I hesitate to post longer description on the net. If anyone would like to
get more elaborated data I will mail upon request.

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

Date: 19 Mar 88 03:04:08 GMT
From: quintus!ok@unix.sri.com  (Richard A. O'Keefe)
Subject:  behavior of read/get0 at end_of_file

I thought you might be interested to know what the BSI committee say.

In document PS/236, "Draft minutes, Prolog Built-In Predicates meeting,
10 December 1987", we find

	4 Design criterion

	<name deleted> suggested: "Whenever possible, a predicate with
	a side effect should always succeed and never instantiate
	variables."

This of course rules get0/1 and read/1 out entirely.  That may not be
what <name deleted> _meant_, but it _is_ what the minutes say he _said_.
As far as I can tell, the real intent is to rule out retract/1, which
is disliked because it unifies its argument with the thing you removed.
The minutes show that Paul Chung proposed naming the standard clause-
removing predicate delete/1 instead of retract/1.  Good on yer, mate!
This should not be construed as endorsement of the name delete/1, but
as praise for Paul Chung's good standardisation manners.

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

Date: 22 Mar 88 15:56:23 GMT
From: mcvax!unido!ecrcvax!micha@uunet.uu.net  (Micha Meier)
Subject:  behavior of read/get0 at end_of_file

	This is true, we have to distinguish various uses
	of get0/1. The above example is indeed easier
	written when get0/1 fails at the eof, because the is_endfile/1
	test is not needed. However, most often one wants to do more
	with the character rather than just test the eof, and only
	then the differences are meaningful.

	By the way, get0/1 does *not* exist in BSI, it uses get_char/1 instead,
	and its argument is a character, i.e. a string of length 1.
	This means that the type 'character' is inferred from
	the type 'string' (and not the other way round like in C).
	Does anybody out there know what advantages this can bring?
	It is independent on the character <-> integer encoding,
	but this only because explicit conversion predicates have
	to be called all the time.

	In his tutorial to the SLP '87 Richard has taken another
	representation of a finite automaton which is more
	appropriate:

	s1 :-
		get0(Char),
		s1(Char).

	s1(0'a) :-
		s2.
	s1(0'b) :-
		s1.
	s1(-1) :-
		accept.

	
	The difference is, that if one wants to perform some action
	in some states, this must be done *before* reading the next character,
	i.e. just at the beginning of s1/0. Such representation can
	be more easily converted to the BSI's variant of get:

	s1 :-
		% do the corresponding action
		( get0(Char) -> s1(Char)
		;
		  accept
		).

	s1(0'a) :-
		s2.
	s1(0'b) :-
		s1.

	Note that the eof arc has to be merged into s1/0 in this way
	since if we'd write it like

	s1 :-
		s1_action,
		get0(Char),
		!,
		s1(Char).
	s1 :-
		accept.

	then after an eof we would backtrack over s1_action and undo
	what we've done.

	I must say, none of the two seems to me satisfactory. Richard's
	version is not portable due to the -1 as eof character. We can
	improve this into

	s1(X) :-
		eof(X),
		accept.
	s1(0'a) :-
		s2.
	s1(0'b) :-
		s1.

	and hope that the compiler will unfold the eof/1 inside the
	indexing mechanism, otherwise we have choice points even
	if the code is deterministic.
	The BSI version is much more arguable, though. Having to
	wrap a disjunction (and a choice point) around the get0/1 call
	suggests that for this application the BSI choice is not
	the appropriate one. It is interesting to note, however, that
	it could work even with nondeterministic automata, where the BSI's
	failure was (I thought) more likely to cause problems.

	For a Prolog system it is better to have get0/1 return
	some *portable* eof (e.g the atom end_of_file, for get0/1
	there can be no confusion with source items) instead of
	some integer.
	
	  This, however, just shifts the problem up to read/1:
	BSI objects that if it returns e.g. the atom end_of_file
	then any occurrence of this atom in the source file
	could not be distinguished from a real end of file.
	In this case, a remedy would be the introduction of
	a term with a local scope (e.g. valid
	only in the module where read/1 and eof/1 are defined) and
	using eof/1 instead of unifying the argument of read/1 with
	the end_of_file term. Hence read/1 would return this term
	on encountering the file end and eof/1 would check whether
	its argument is this term.

--Micha

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

Date: 20 Mar 88 20:51:12 GMT
From: lagache@violet.Berkeley.EDU  (Edouard Lagache)
Subject: Seeking opinions on BSI PROLOG standard proposal.

               I spent a few hours carefully collecting all the
          comments on the proposed BSI PROLOG standard that have been
          posted to the PROLOG SIG.  The result was a 160Kb file!  The
          reason for this exercise in tedium was my desire to write an
          article on the pros and cons on this standard for the next
          issue of the PROLOG Forum newsletter.  However, for obvious
          reasons, I am not particularly anxious to try to comb through
          all them bytes of complex argumentation, and I am not
          optimistic that I could do any of the participants justice.

               Thus, I would like ask those persons who expressed some
          substantial position on the new PROLOG standard, if they
          might be interested in submitting to the PROLOG Forum
          something equivalent to a short (1-3 page) position paper on
          the standard.

               Because we are such a new group, our editorial policies
          are still in the process of coalescing, but at the moment I
          would think that a very informal sort of piece of the sort
          that you might post to the net would be very acceptable.

               Should you have any interest and/or questions please
          direct them to me, and I will do my best to answer them or if
          necessary to rely them to our newsletter editor.

               I am looking forward to a lot of interesting commentary!

-- Edouard Lagache

    P.S. A minor detail, but anyone wishing to submit a text can simply
         e-mail it to this account.  If prefered, one could send an
         PC or Mac compatible disk with the text in "flat ASCII" format to:
              The PROLOG Forum
              P.O. Box 3826
              Redwood City, CA, 94064, USA.

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

Date: 21 Mar 88 16:40:44 GMT
From: eagle!icdoc!doc.ic.ac.uk!cdsm@ucbvax.Berkeley.EDU  (Chris Moss)
Subject:  BSI 

Forwarded for Roger Scowen -- KRG0@gm.rl.ac.uk
 
RESPONSE TO COMMENTS FROM RICHARD O'KEEFE ON PROLOG STANDARDIZATION
 
GENERAL RESPONSE
 
Richard O'Keefe started by saying that he would respond to the
mailing from Chris Moss. In fact many comments refer
to a document (Prolog syntax, Draft 4.1) that
most news readers (and members of the ISO and BSI panels) will
not have seen.
 
This seems somewhat unfair on readers who will be unable to judge 
whether draft, criticism, or rebuttal is justified.
 
First some general comments. The objective is to define an
International Standard for the programming language Prolog.
This means that standard conforming programs will run correctly
on standard conforming processors, neither more nor less.
It will not limit implementers from introducing new features and
facilities into their Prolog compilers. 
 
Neither will it mean programmers cannot use such extensions; only
that if they do, their programs will not conform to the standard.
 
But a standard will permit people and companies to write applications
and libraries that will run on any conforming implementation
and thus give them a framework in which to work. In particular, such users
and their customers will not be restricted to a single implementation.
A standard will also give teachers, authors and students a common core 
of useful Prolog.
 
Once a feature has been included in a standard, it is almost
impossible to remove. The committee remembers that Fortran has been 
burdened with arithmetic if statements and computed goto statements.
In Prolog we hope to avoid such legacies if possible.
So some features of Edinburgh Prolog will not be in the standard 
because although they fulfilled a need at one time, they are
not a sensible longterm solution.
 
Now some replies to specific criticism.
 
DIVERSITY OF EXISTING PROLOG SYSTEMS
 
Chris Moss has produced tests that give
different results on every system tested so far. Perhaps there
is rather more diversity than Richard O'Keefe realizes.
One objective has been to define a syntax where many existing 
systems would not generally disagree on the meaning of 
standard-conforming programs. 
 
PROLOG CONTROL STRUCTURES AS SYNTAX
 
>	(3) The attempt to describe Prolog control structures as *syntax*
>	    is fundamentally misdirected.
 
This is a matter of opinion. One reason for regarding Prolog control
structures as *syntax* is so that a person or program reading
a Prolog program can always recognize its overall structure.
 
NOTICE OF MEETINGS
 
 Meetings are planned and advertised several months in advance,
for example, the following meetings are already planned:
 BSI, London on Thursdays 2nd June, 1st Sept, 1st December 1988.
Any extra meetings to discuss the syntax will be on the previous
day (i.e. 1st June, etc); any meetings to discuss built-in predicates
will be a week later, i.e. 9th June, etc.
Everyone who wishes to attend is welcome. I admit that pressure of
work means that some papers are sent only a week before the meeting.
This is ample for British members of a British panel, but not for 
Californian members. 
But other papers will have been sent four or five weeks earlier.
 
All comments, whether they are received before or after a meeting,
are read and considered.
 
',' and '&' AS OPERATORS
 
 It is not intended that it will be possible to declare ',' and '&'
as operators.
 
A MISTAKE IN COMMENTS
 
	/** By L22, this is not a legal comment **/
 
Thank you. This will be a valid comment in standard Prolog despite
the error in this draft.
 
QUOTE OPERATORS USED AS OPERANDS
 
 Richard O'Keefe realizes that the above example is intended to be
syntactically incorrect in the standard. When operators are
used as operands, there many problems of possible ambiguity.
A cure is still under discussion, but some problems are
avoided by the rule that "An operator used as an operand must be
bracketted".
 
AN INFIX CONS OPERATOR
 
 We are still considering the problems posed by the multiple uses of '.',
i.e. as a decimal point, as an infix cons operator, and as a clause
terminator. At the same time we desire to make layout characters
unimportant in determining the meaning of a program.
Several possibilities have been suggested and are under consideration.
 
NEGATION

It is intended that Standard Prolog will not contain 'not' or '\+'.
Standard Prolog will not require systems to implement true
logical negation and it would be misleading to include an 
operator or predicate that implies that they have done so.
Instead the way is left open for processors to implement a version
of 'not' as an extension and still remain standard conforming.
Standard Prolog will contain a built-in predicate 
that implements 'negation by failure', i.e.
      fail_if(G) :- call(G), !, fail.
      fail_if(_).
 
A PARSER AS STANDARD
 
 A program that resolves ambiguity implicitly is not acceptable as
defining a standard; there must be further definition.
One reason is that a program specifies too much. Some features need to
remain 'implementation dependent' because we must not specify
them, for example: the accuracy and largest values of floating point
numbers, or the integer value corresponding to a character.
 
Another reason is that it is harder to understand and find errors.
 
DISCLAIMER AND CONCLUSION
 
Never rely on working papers and draft standards. They are subject to
changes and review. All documents and working papers, however
confidently expressed, are also subject to review. There will be no
standard until the member bodies of ISO have approved it.
 
The next working drafts will incorporate changes arising from further
consideration and the comments received (including those from
Richard O'Keefe).
 
Many countries, but not at present USA, have national Prolog panels
coordinating their views on the emerging standard. I encourage all 
Prolog implementers and users to participate in this effort in order that
the eventual standard is one that preserves the best of the past
and also provides development paths for the future.
 
-- Roger Scowen

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

Date: 23 Mar 88 05:11:45 GMT
From: quintus!ok@unix.sri.com  (Richard A. O'Keefe)
Subject:  BSI syntax
Message-Id: <797@cresswell.quintus.UUCP>
References: <234@gould.doc.ic.ac.uk>
Sender: prolog-request@score.stanford.edu
To: prolog@score.stanford.edu

My postings were in fact a response to Chris Moss's mailing.  They were
not confined to the content of that mailing, true.  It seemed to me that
Chris Moss's mailing implied that the BSI syntax was in a satisfactory
state, and that it wasn't as difference from the de facto standard as
people feared.  I set out to show that neither of those statements is
true, and I believe that I succeeded.

Many comments did refer to a document that most news readers won't have
seen.  But then, most news readers won't have seen ***ANY*** of the BSI
documents.  Am I then to say nothing?   As for fairness to readers,
(a) I was quoting from the very latest document I had.
    Surely it would be more unfair to quote from something I believed
    to have been superseded?
(b) The "February 88" and "Feb 88" documents arrived in my mailbox here
    in the same week.  I had no way of telling who had or had not
    received the document I was quoting.  All I knew was that this was
    the latest document available, sent to me by the author.
(c) In order to permit readers to judge for themselves whether my
    criticisms were justified, I quoted extensively from the document.
    I did not ask anyone to take it on faith that this or that was the
    case:  where the grimoire appeared to say something particularly
    silly I exhibited the rules responsible.  This is unfair?

> First some general comments. The objective is to define an
> International Standard for the programming language Prolog.
> This means that standard conforming programs will run correctly
> on standard conforming processors, neither more nor less.
> It will not limit implementers from introducing new features and
> facilities into their Prolog compilers. 
>  
> Neither will it mean programmers cannot use such extensions; only
> that if they do, their programs will not conform to the standard.
>  
This is a little misleading.  The general rule in other languages is
that implementors can add extensions, provided that such extensions
are either illegal or undefined in the standard.  Thus a Pascal compiler
can provide alphabetic labels as an extension.  But an implementor
should not provide an extension which alters the meaning of a program
which the standard would have ruled legal.

Let's apply this to the case of :- read(_). directives in a file which
is being consulted or compiled.  Specifically, let's consider a file
which looks like
	:- read(_).
	p(a).
and has nothing else in it.  Does this define p, or does it not?  The
BSI grammar, in all versions, provides the syntax of entire files:
according to the grimoire this MUST mean exactly one directive followed
by exactly one clause.  Since this is a defined and legal file, it would
be most improper for an implementor to give it any other meaning.
Therefore, reading out of a file being compiled or consulted is NOT
a permitted extension.  (This wouldn't bother Quintus, but it is legal
in some other Prologs.)

Let's apply this to another case:  functor/3.  It has always been the
case in DEC-10 Prolog that functor(1, 1, 0).  In at least one draft of
the BSI built-in predicates document, this has been required to raise
an error.  (BSI Prolog includes an error handling facility; needless
to say it doesn't look like IF/Prolog's or M-Prolog's or ...)  So a
BSI conforming program is entitled to rely on this error being raised,
and an implementor may NOT provide DEC-10 compatibility.

The ANSI C committee have found it necessary to explicitly indicate
which identifiers may be used by implementors.  (The list includes
all identifiers starting with "_" or "str" and there are others I
can't remember right at the moment.)  Why is this?  Because the
programmer needs a guarantee that the identifiers he has chosen for
his code won't be in conflict with an implementation.  For example,
(not)/1 is not defined in the BSI stuff, so Scowen says that an
implementation is free to define it.  But if the implementation is
free to do so, then the programmer ISN'T.  Since setof/3 is not in
the BSI Prolog language, a program which defines

	setof(List, Set) :-
		setof(List, [], Set).		

	setof([], Set, Set).
	setof([Head|Tail], Set0, Set) :-
		(   member(Head, Set0) ->
		    setof(Tail, Set0, Set)
		;   /* not member(Head, Set0) */
		    setof(Tail, [Head|Set0], Set)
		).

is a standard-conforming program.  But a Prolog system which is exactly
BSI except for providing setof/3 as an extension is a conforming processor.
Will such a conforming program run correctly on such a conforming
processor?  You must be joking.  So, taken in their ordinary sense,
the claim that "standard conforming programs will run correctly on
standard conforming processors", while true of some standards, is NOT
true of the BSI work, unless "standard conforming processors" is
construed very strictly as meaning "providing NO additional built-in
predicates".

You will recall that Fortran 77 provides the EXTERNAL and INTRINSIC
statements precisely to cope with this problem, and that ANSI C
provides the reserved-to-implementors list and #undef precisely to
cope with this problem.  BSI Prolog does have some reserved words,
but is ludicrously far from providing a solution to this problem.

> So some features of Edinburgh Prolog will not be in the standard 
> because although they fulfilled a need at one time, they are
> not a sensible longterm solution.

Let's be realistic.  There are languages on the horizon which are much
better approximations to logic programming than Prolog.  (NU Prolog has
been around for a while.)  There are lots of software engineering needs
which old Prolog completely failed to address, such as modules.  (Last
I heard, the consensus of the BSI Modules subcommittee was that they
would probably never agree.)  I think we ought to regard Prolog as a
stopgap; and that the goal of the standard should be to protect EXISTING
investments in Prolog.  Frankly, advocates of BSI Prolog, with its
use of user-supplied atoms as stream names, are in no position to talk
about sensible solutions.

************************************************************************
** It would be most interesting to have an explicit list of the features
** of Edinburgh Prolog which fulfilled a need at one time and are now
** disliked by the committee, and a description of their replacements.
************************************************************************

> >	(4) The basic structure of the BSI approach to syntax has been
> >	    to cut the Gordian Goose.  That is, instead of regarding the
> >	    (actually rather low) diversity of Prolog syntax as an
> >	    opportunity to be solved by making the language more powerful
> >	    (e.g. having a table-driven tokeniser), it has been treated as
> >	    a problem to be solved by inventing a new, more restricted,
> >           language.
>  
> Well, yes and no. Chris Moss has produced tests that give
> different results on every system tested so far. Perhaps there
> is rather more diversity than Richard O'Keefe realizes.
> One objective has been to define a syntax where many existing 
> systems would not generally disagree on the meaning of 
> standard-conforming programs. 
  
The amount of diversity one perceives depends on which "Prolog" systems
one decides to include in one's sample.  My sample includes only systems
whose implementors _tried_ to be Edinburgh (or at least Clocksin &
Mellish) compatible.  For example, AAIS Prolog is openly and frankly
not an Edinburgh-compatible system.  We may (and should) look to it for
ideas, but we should not include it in a sample of "Edinburgh compatible"
Prologs.  BIM Prolog has its own unique syntax; while we should perhaps
include the '-c' syntax of BIM Prolog in the sample, we should not
include BIM Prolog's native syntax.  If we go by numbers, then Turbo
Prolog should determine the syntax of standard Prolog.  If not by numbers,
by what?  Simple justice suggests that the Prologs to look at are the
Prologs whose authors TRIED to be compatible with one another.  Prudence
suggests the same sample.

But even if the diversity among the Prologs whose authors didn't suffer
from NIH-itis is much greater than I believe, that doesn't answer my
point.  What I said was that the diversity should be regarded "as an
opportunity to be solved by making the language more powerful (e.g.
having a table-driven tokeniser)".  [As an aside, this is no more than
Lisp and PopLog already have.]  It turns out that it is quite easy to
write a tokeniser which can handle all of
	ALS Prolog
	Arity Prolog
	BIM Prolog native syntax
	C Prolog
	DEC-10 Prolog
	PopLog	(nested comments)
	Quintus Prolog
	Stony Brook Prolog
and can almost handle ADA [ADA is no longer a trademark], simply by fiddling
with a table.  AAIS took exactly this approach (though their tokeniser is
not as flexible as mine).  I found it necessary to support several kinds
of quotes in my tokeniser:
	ATMQT		- the quoted thing is an atom (')
	STRQT		- the quoted thing is a string ($)
	LISQT		- the quoted thing is a list (")
	CHRQT		- the quoted thing is a character (`)
Suppose the standard were to adopt this approach, then they could rule,
if they wished, that the standard assignment was "->STRQT, with nothing
being assigned LISQT.  That needn't prevent me reading my existing code:
I'd be able to change the table while reading my old files.
[The best approach seems to be to associate a read table with a stream;
 naturally this is the approach PopLog takes.]

What I have in mind here is that a file would start with a directive
such as
	:- use_syntax(dec10).
or	:- use_syntax(standard).
or	:- use_syntax(als).

Especially if the tokeniser were made available to user code (as it is
in the DEC-10 Prolog library, or built-in in NU Prolog), the result would
be a much more powerful language at very little cost to the implementor.
And conversion from old dialects to the BSI dialect would be enormously
simplified.

Do we need to come up with a "best possible" tokeniser for the standard?
Of course not.

Again, what are we to do about syntactic variations, such as the
treatment of operators?  My answer, in 1984, was that the standard
should not specify read/1 and write/1, but should specify
	standard_read/1
	standard_write/1
and should allow users to redefine read/1 and write/1, but require
that the initial definitions be the standard one.  consult and compile
should use read/1, not standard_read/1, so that someone who wanted to
read M-Prolog files into standard Prolog could do so by suitably
defining read/1.

Now, if you are a self-appointed standards committee member determined
to impose your vision of what is a "sensible longterm solution" on
every Prolog user whether they like it or not, this sort of approach
won't seem all that attractive.  But if, like me, you think that the
people who matter in all this are the people who have paid money to
USE Prolog, and if, like me, you think that the fact that M-Prolog
is appalling is no reason to make life any harder for people with a
lot of data in M-Prolog format than we have to, you'll think that
letting people do

	read(Term) :- magyar_read(Term).

is obviously the way to go.	(It doesn't much matter how you install
your own code in the hook, the important thing is that there should be
a read-hook where you can install your own reader to be used by compile
and consult.)

> PROLOG CONTROL STRUCTURES AS SYNTAX
> >	(3) The attempt to describe Prolog control structures as *syntax*
> >	    is fundamentally misdirected.
> This is a matter of opinion. One reason for regarding Prolog control
> structures as *syntax* is so that a person or program reading
> a Prolog program can always recognize its overall structure.

It is not a matter of opinion.  Either I am right about this, or I am
wrong.  There is a very important reason for my belief:  Prolog is
simply not the sort of language for which this kind of thing can WORK.
Consider the difference between

	foo(X, P, Q, L) :- bag(X, (P & Q), L).
				  ^^^^^^^
and
	de_morgan((P & Q), (R | S)) :- de_morgan(P, R), de_morgan(Q, S).
		  ^^^^^^^
The first is code, and the treatment of it in the grimoire is appropriate.
(That is, it will be mapped to whatever "(and ?P ?Q)" would have been
mapped to in the BSI Lisp-like syntax.)
But the second is data, and the treatment of it in the grimoire is
NOT appropriate.  It will be mapped to whatever "(and ?P ?Q)" would
have been mapped to in the BSI Lisp-like syntax, but it SHOULD be
mapped to whatever "[& ?P ?Q]" would be mapped to.

If we consider a slightly different example:

	baz(X, P, L) :- bag(X, P, L).
			       ^
and
	de_morgan(not(P), R) :- de_morgan(P, R).
					  ^
we find the opposite problem: the second is data and will be mapped to
whatever "?P" will be mapped to in the BSI Lisp-like syntax, but the
first is code, and should be mapped to whatever "(and ?P)" would be
mapped to, BUT IT WON'T BE.

The trouble is that the grimoire tries to guess whether something is
code or data by looking at its form, but that's the wrong place to
look:  the place to look is the predicate being called.  And the
trouble is that we can't build that information into the grammar,
because the programmer can define new predicates with code-like arguments.

Let me stress this:
	the whole basis of the build-it-all-into-the-syntax approach
	is the assumption that code is code and data are data and
	never the twain shall meet.
This is true of Pascal.  It is true of Fortran.  It is almost true of C.
But it is utterly false of Lisp and Prolog.  A grammar of this type does
not make SENSE for Prolog any more than it makes sense for Lisp.

I hereby wager US$100, payable once to Chris Moss, that if the next draft
of the grimoire attempts to maintain this rigid distinction between code
and data, I will be able to find inconsistencies like the ones above in
it.  I don't think it's Chris Moss's fault:  if anyone can find a way of
working around this basic mistake (not HIS mistake, by the way, this is
the kind of grammar the BSI committee have always wanted), I'm sure that
Chris Moss could.  I make my wager *despite* my belief in Chris Moss's
competence, because I believe that it is _impossible_ for this approach
to work.  (If I do not receive said draft by the end of this year, the
wager will expire.)

> ',' and '&' AS OPERATORS
> > Oddly enough, if one takes the grimoire literally, the user CAN
> > declare ',' and '&' as operators, and can use them in that form.
> > However, ',' and '&' cannot possibly have the same precedence as
> > "," or "&" in BSI Prolog, and it seems clear that (A ',' B) and
> > (A '&' B) must be different terms.  
>  
> It is not intended that it will be possible to declare ',' and '&'
> as operators.
>  
There is nothing in the grimoire to say so, and it is a very odd restriction.
Intentions are beside the point:  all that matters is what the documents
actually say.  It *is* the intention that it should be possible to write
','(A,B) as a term, and it remains the case that ','(A,B) and '&'(A,B)
must be different terms, and if we take the grimoire literally, neither of
them can be the same as (A,B) or (A&B).

[Yes, I know about (P|Q) and (P;Q) in Dec-10 Prolog.  I have always thought
 and said that this was a mistake, and I think it is one of the very few
 areas where a difference between the standard and existing practice might
 be justifiable.
]

> QUOTE OPERATORS USED AS OPERANDS
> >	compare(R, X, Y) :-
> >		( X @> Y -> R = >
> >		; X @< Y -> R = <
> >		;	    R = =
> >		).
>  
> Richard O'Keefe realizes that the above example is intended to be
> syntactically incorrect in the standard. When operators are
> used as operands, there many problems of possible ambiguity.
> A cure is still under discussion, but some problems are
> avoided by the rule that "An operator used as an operand must be
> bracketted".
>  
Well, it would be more accurate to say that I COMPLAIN that it is
intended to be syntactically correct in the standard.
There isn't any problem of possible ambiguity here whatsoever.

	) :- (		:- must be infix
	X @> Y		@> must be infix
	Y -> R		-> must be infix
	R = >		= must be infix or suffix, has no suffix reading
	= > ;		> must be atom or prefix, has no prefix reading
	> ; X		; must be infix
    and so on
Now if = and > _both_ had a suffix reading, (R = >) would be ambiguous.
Since neither of them has, there is no ambiguity here at all.

The elimination of ambiguity is not a very good argument for breaking
existing UNAMBIGUOUS code!

> NEGATION
> >	not Goal :-		% "not" is not a built-in operator
> >	    (	ground(Goal) -> \+ Goal		% neither is "\+".
> >	    ;	signal_error(instantiation_fault(Goal,0))
> >	    ).
> It is intended that Standard Prolog will not contain 'not' or '\+'.
> Standard Prolog will not require systems to implement true
> logical negation and it would be misleading to include an 
> operator or predicate that implies that they have done so.
> Instead the way is left open for processors to implement a version
> of 'not' as an extension and still remain standard conforming.
> Standard Prolog will contain a built-in predicate 
> that implements 'negation by failure', i.e.
>       fail_if(G) :- call(G), !, fail.
>       fail_if(_).

My main point here was a semantic one.  Most other control structures
are defined in the grammar.  It seems odd that
	( G -> fail ; true )	should be in the grammar, but that
	fail_if(G)		which is identical in effect, should not.
Because one of these forms is in the grammar and the other isn't, they
have different properties.  For example,
	( 1 -> fail ; true )	is syntactically illegal, but
	fail_if(1)		is syntactically legal.
There are other differences as well.

If BSI Prolog contains fail_if/1, then it WILL contain '\+', but with
a different name.  Why not use an existing name for an existing
operation?  Looks to me like nonhicinventusitis.  \+ is a crossed-out
|-, meaning, obviously enough, "not provable".

> A program that resolves ambiguity implicitly is not acceptable as
> defining a standard; there must be further definition.
> One reason is that a program specifies too much. Some features need to
> remain 'implementation dependent' because we must not specify
> them, for example: the accuracy and largest values of floating point
> numbers, or the integer value corresponding to a character.
>  
> Another reason is that it is harder to understand and find errors.

It is harder to understand and find errors in a program you can run
than in a never-used-anywhere-else formalism?  Judging by the results,
this is the opposite of the truth.

What is the difference between the public-domain DEC-10 Prolog parser
and the BSI grimoire?  Both are programs, in a formalism based on logic.
Neither is more explicit or less explicit than the other, and both are
of similar size.  So what is the difference?  The difference is that
the public-domain DEC-10 Prolog parser CAN be run, HAS been run, and
has had most of the mistakes knocked out of it by actual experience.
The BSI grimoire is in a new formalism, the definition of which is
provided in ***NO*** BSI document (so that I had to keep guessing what
things meant), and each of the three drafts I have seen was riddled
with errors from end to end.  I haven't told you about all the problems
I found; there are nearly as many problems as rules!

The BSI Prolog group HAVE specified the integer value corresponding to
a character:  they require the ISO 8859 character set.  GREAT!
The DEC-10 public-domain ***parser*** does NOT specify the integer
value corresponding to a character (that's the tokeniser's job).
{The old tokeniser did have ASCII codes built in, but the current
version of the tokeniser uses 0'x syntax for the appropriate
constants to avoid that problem.}
If the BSI committee are so concerned to avoid character code problems,
how come they haven't got anything like 0'x or `x` (in a standard which
doesn't have to cope with existing code that uses ` as an atom, `x` is
a good notation for character code constants)?

The public-domain tokeniser doesn't specify anything more about floating
point numbers than what they look like, it relies on being provided with
a number_chars/2 predicate (which we want ANYWAY) do to the actual
conversion.

Note that the BSI grimoire says NOTHING about what happens if you write
a constant which exceeds the capacity of your implementation.  Is the
program
	p(1.2e3456).
a BSI-conforming program or not?  Well, syntactically it is, but the
lexical rules say nothing about what it MEANS.  For all that the
grimoire or any other BSI document I can recall says to the contrary,
a Prolog implementation which reads this as
	p(0.0).
is conforming.  This kind of thing is a real portability problem; it
exists with respect to integers too.  Is 1000000000000000000 a legal
Prolog term?  According to the grimoire, yes.  What does it mean?
The grimoire doesn't say.

> DISCLAIMER AND CONCLUSION
> Never rely on working papers and draft standards. They are subject to
> changes and review. All documents and working papers, however
> confidently expressed, are also subject to review. There will be no
> standard until the member bodies of ISO have approved it.

But what ELSE is there to comment on?

> Many countries, but not at present USA, have national Prolog panels
> coordinating their views on the emerging standard. I encourage all 
> Prolog implementers and users to participate in this effort in order that
> the eventual standard is one that preserves the best of the past
> and also provides development paths for the future.
>  
> Roger Scowen, 11 March 1988

Sorry, but it's too late.  Prolog implementors and users should have been
invited to contribute before the committee went on a four-year binge of
inventing their own language.  I explicitly suggested some years ago that
the people at WISDOM should be invited to participate, and was told that
that was out of the question.  I have put a lot of effort into writing
responses to the BSI stuff, and for all the feedback I've had I might as
well have been shouting into a vacuum.  The BSI committee having been
resolute in their contempt for existing Prolog users (I have repeatedly
urged that they should explicitly adopt a principle of not breaking
existing code without strong necessity, as the ANSI C committee did, and
the last I heard was that they had explicitly rejected any such idea),
I cannot regard "preserves the best of the past" as anything but a sick
joke.

Look, if you want to preserve the best of the past, why have you
renamed findall/3 to bag/3?  Why have you adopted ESI Prolog-2's
streams rather than Arity/Prolog's streams, despite having been
told about the problems?  Could it be something to do with the
fact that the author of that part of the standard worked for ESI,
not for Arity?  Why have you dropped nl/0 from the standard?  Why
is there no notation for character constants such as PopLog provides?
Why is the error handling facility all new, rather than resembling
either IF/Prolog or M-Prolog?

I have tried, I really have tried, to arouse interest in the BSI work
here in the US.  Do you know what has got in the way?  As soon as I
show people any of the BSI documents (take the 'standardisation issues'
documents as an example) they say "what a pack of turkeys" and assure
me that there is nothing to worry about.  I remain desperately worried
that there will be a BSI/ISO Prolog standard, and that it will be as
bad as the current drafts, and that it will do a great deal of damage.
What *really* worries me is that the people on the BSI committee don't
seem to realise how bad it is.
------------------------------

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