[comp.lang.lisp] Poplog

alex@umbc3.UMD.EDU (Alex S. Crain) (07/29/88)

	POPLOG came up at a recent systems meeting, and we are interested
in finding out more about the SYSTEM for educational use. Could someone
point me to where we can obtain more information? Comments from 
[dis]satasfied users would also be appreciated.


-- 
					:alex.
					Systems Programmer
nerwin!alex@umbc3.umd.edu		UMBC
alex@umbc3.umd.edu

sfk@otter.hpl.hp.com (Steve Knight) (01/21/91)

> I keep hearing about Poplog from our friends in the UK, but I'm still
> unclear as to what exactly it means "to have CL, ML and Prolog" in this 
> language. Could some poplogger post an example that shows how these 
> three languages might be intertwined in a poplog program? 

The Poplog system includes compilers for four "intrinsic" languages.  Each
language has extensions for accessing the other compilers.  (The compilers
are incremental and interactive and play the role of interpreters.)  
It's normal to organise a multi-language program so that the usages of
the different languages are isolated in different files.  The example I give
below puts the program all in one file, which is less usual.

What makes inter-language working feasible in Poplog is that the four
intrinsic languages share the same underlying datatypes.  For example, Prolog's
numbers, atoms, and lists are identical to those of Common Lisp.  Structures
which are special to Common Lisp (such as vectors) are treated as atoms
by Prolog.  Common Lisp is supplied with a number of functions for manipulating
Prolog terms.

For example, from inside Prolog you can call out to Lisp using
    lisp_apply(Func, Arglist, Result)
or, for multiple values, 
    lisp_mv_apply(Func, Arglist, Resultlist)
There are many other ways to access Lisp entities from Prolog, of course.

The Lisp/Prolog interface utilises the following read macros:
     {functor arg1 arg2 ... argN}    notates a goal in prefix form
     $word                           notates a prolog atom
     ?var                            notates a prolog atom
To illustrate:
     {$append ?x ?y '(a b c d e)}
This creates a Prolog 'goal', a data structure comprising a Prolog term
and an association list mapping Lisp symbols to Prolog variables. Note
that the forms inside the {} brackets are evaluated as normal Lisp forms
(hence the use of $ to notate the functor).

Prolog goals can be invoked as boolean functions, by using:
     (PLOG-GOAL-CALL goal)
There's a special-form DO-PLOG that can be used to iterate over all the 
solutions to a Prolog goal.  e.g.

     (do-plog {$append ?x ?y '(a b c)} (x y)
         (pprint x)
         (pprint y)
         (terpri))

     NIL
     (A B C)

     (A)
     (B C)

     (A B)
     (C)

Finally, here's a tiny example showing Prolog interworking with Pop11 to write
a predicate 'shuffles' that creates random permutations of a list.  I'd do it 
in Commn Lisp, but I write Common Lisp so rarely I'd be bound to make a 
mistake!

    /* Note that the RHS of an 'is' call call Pop11 functions -- exploiting
       the syntactic similarity of Pop11 expressions and Prolog terms in order
       to look natural.
    */
    shuffles( L, S ) :- repeat, S is shuffle( L ).

    /* Drop into Pop11 to define the shuffle function.  It's easier to write
       shuffle in Pop11.
    */
    :- prolog_language( 'pop11' ).

    define shuffle( L ); lvars L;
        ;;; copies the list L to a simple vector v
        lvars v = L.destlist.consvector;
        ;;; iterate over decreasing segments of v, swapping the ith element
        ;;; for any item in the segment.
        lvars i;
        for i from v.datalength by -1 to 2 do
            lvars r = random( i );
            ;;; this expression exploits the open stack
            ( v( r ), v( i ) ) -> ( v( i ), v( r ) );
        endfor;
        ;;; returns v copied back to a list
        v.destvector.conslist;
    enddefine;
    
    /* Switch back to prolog */
    :- prolog_language( 'prolog' ).
    
I hope these small examples give you a feel for what Poplog folks are talking
about.  It's only a tiny glimpse, of course, but it may enable you to relate
it to previous work.  

You should also bear in mind that the implementations of
Common Lisp, Prolog, and ML in Poplog do not currently perform as well as
standalone implementations of the same languages -- perhaps half the 
performance, sometimes much worse, sometimes much better.  This is a 
consequence of the underlying compiler backend, which is optimised for
speed of compilation rather than speed of execution of final code.  
(Compilation speed is excellent, though.  There's no need for an interpreter.)

Steve 

aarons@syma.sussex.ac.uk (Aaron Sloman) (01/27/91)

eliot@phoenix.Princeton.EDU (Eliot Handelman) writes:

> Date: 21 Jan 91 04:25:21 GMT
> In article <4255@syma.sussex.ac.uk> aarons@syma.sussex.ac.uk (Aaron Sloman)
    writes:
>
> ;The largest implementation of Pop-11 is in Poplog (which also has
> ;Common Lisp, ML and Prolog), and the latest version includes
> ;mechanisms for interfacing to X windows by linking in widget sets.
>
>
> I keep hearing about Poplog from our friends in the UK, but I'm still
> unclear as to what exactly it means "to have CL, ML and Prolog" in this
> language. Could some poplogger post an example that shows how these
> three languages might be intertwined in a poplog program?
>
Actually, Poplog is not a language: it is a development environment,
which includes several languages.

As for what it means, I'll try to answer in enough detail for you
to imagine how you could implement it and use it.

When the core Poplog starts up it includes a working version of
Pop-11, including store manager, garbage collector, facilities for
interfacing to the operating system, arithmetic, data-structuring
facilities, and external language interface. It also includes the
Poplog editor VED and the incremental compiler for Pop-11.

This compiler reads Pop-11 code from the terminal or form files or
from the editor buffer, and compiles it to machine code procedures,
as you might expect an incremental compiler for Lisp to do. This
works by reading in a character stream, breaking it into tokens,
analysing them, and then planting instructions for the "Poplog
virtual machine". These Poplog VM instructions are then translated
to a low level virtual machine, and from there a host-specific
translater generates executable machine code (in procedure records).

The core Poplog also includes many built in procedures, including
the procedures that are used to define the Pop-11 compiler. These
procedures are also available to define other compilers.

So among the Poplog libraries are (in source code) compilers for
other languages. These usually include a portion written in Pop-11
to get the language going, and the rest written in the new language.

For example, one of the prolog predicates could be defined in Pop-11
thus:

define:predicate retract/1(Clause);
	lvars Clause;

    prolog_deref(Clause) -> Clause;

	if isprologvar(Clause) then
        bad_goal(Clause, "retract", 1)
    endif;

	prolog_retract(Clause);
enddefine;


And later in the same file you could find a call of a Pop-11 macro
to switch to the Prolog compiler, followed by a prolog definition
using the above Pop-11 procedure:

retractall(Clause) :-
	retract(Clause),
	fail.
retractall(Head) :-
	retract(Head :- Body),
	fail.
retractall(_).


All the Poplog compilers essentially use the same mechanisms as
Pop-11 to read in a text stream, but do different analyses, and then
call the built-in Pop-11 procedures for planting Poplog VM
instructions, which then get compiled in a language independent
manner.

In this way the core Poplog can be extended with compilers for
Common Lisp, Prolog or ML. To avoid having to compile the ocmpilers
every time you use them, they can be pre-compiled and stored in a
saved image, which can then be started up as if it were a standalone
Common Lisp, or Prolog, or ML, etc. If desired a saved image can
include more than one of the extra languages, though Pop-11 is
always there even for people who don't use it explicitly (except
perhaps to extend the editor). Similarly, users can define other
languages using the same mechanism. One user claimed that in a
few weeks of his spare time he implemented Scheme in Poplog. It
then ran fully compiled on all the machines that Poplog runs on.

For all this to be possible, the Poplog VM, and its compiler, had to
include facilities that are not necessarily required for Pop-11. For
example, there is a mechanism for handling a stack of continuations,
used by the Prolog compiler. Also, because Pop-11 has a distinct
boolean data-type, unlike Lisp (which uses NIL for False) there are
special facilities for optimising Lisp conditionals. There are also
some built in sub-routines (defined in the system in Pop-11) that
are required only for particular languages and could not be defined
efficiently in libraries. E.g. procedures for creating and
manipulating Prolog terms and prolog variables, are built in, and
the Prolog unifier is built in as a Pop-11 procedure, as are some
list-processing facilities needed for Lisp. (So the Poplog Pop-11
users has a small overhead of unused facilities, though Poplog
could be linked without them if required.)

Although not strictly necessary, it was decided to use exactly the
same internal data-structures for the different languages wherever
possible. So for example, the integers, bigintegers, floats, double
floats, complex numbers, and rationals, are the same entities for
all the languages (for which they are defined). Hence the same
system routines are used to operate on them. Similarly, Lisp, Pop-11
and Prolog by default use the same data-structures for lists (hence
the problem that arises because Lisp uses NIL instead of a boolean
data type).

Prolog atoms are Pop-11 words, and this makesit possile for Prolog
and Pop-11 to use the same symbol table. Also the Pop-11 "section"
mechanism can then be used to implement Prolog modules.

Pop-11 and ML use the same data-types for strings. Lisp and Pop-11
use the same structures for arrays. And so on.

However some things have to be done differently. E.g. the
requirements for symbol tables in Pop-11 and Lisp are different.
(Pop-11's sections are very different from Lisp's packages). So all
Pop-11 identifiers are accessed via a special Lisp package. Lisp
identifiers are accessed from Pop-11 by prefixing them with a
special prefix (which acts as a Pop-11 macro).

The sharing of data-structures between the languages, means that a
list, or array, or string, etc constructed in one language can be
given as argument to a procedure written in another language. (In
the case of Prolog you have to be careful about lists containing
variables.)

Moreover, Pop-11 procedures, Lisp procedures, ML PRocedures and
compiled Prolog predicates are all the same kinds of Poplog
datastructures, and they all use the same procedure call stack when
invoked. Hence they can all be called in the same way, and any one
of them can call one of the others, provided that the language is
extended with syntax that can be compiled into such a call. This
sort of unofficial extension is provided in all the Poplog versions
of these languages. So for example, to call the Pop-11 function
"last" from Lisp, with the list '(a b c)

    (pop11::last '(a b c))

This will return the lisp atom 'c

Mechanisms are also provided for switching compilers in the same
file, so that, for example, a prolog program can define some prolog
code, then switch to pop-11 to define some procedures, then switch
back to prolog to define some predicates that make use of those
procedures. E.g. Some Prolog programmers struggling with assert and
retract for storing global information have found that they can
speed up their programs by a few orders of magnitude by using Pop-11
properties (hash tables) instead.

Poplog also provides an external language interface, implemented
in Pop-11. So a Prolog user wanting to invoke C programs can use
this via Pop-11. Libraries that call the relevant Pop-11 utilities
would normally hide the interface from the user who does not want
to learn a new syntax.

I doubt that any user has seriously employed more than two of the
Poplog languages in one application, though people combining Lisp
and Prolog will be implicitly using Pop-11, and since the Poplog
editor VED is implementedin Pop-11 it is generally most convenient
to use Pop-11 to extend and tailor it.

Examples of applications mixing the languages have been described at
Poplog user group conferences (so far, there are no printed
proceedings). One of the earliest was a medical image processing
system that used Pascal for the lowest level image processing,
Pop-11 for intermediate level processing and Prolog for an expert
system advisor.

A big project at Sussex combines Prolog and Pop-11 in a system that
takes in shorthand typed English reports of traffic incidents as
recorded at police stations, interprets them, makes plans for
distributing the information, and provides a variety of interactive
graphical displays showing what's going on. I don't happen to know
which bits are in Prolog and which in Pop-11, but I expect Prolog is
used for parsing and planning and Pop-11 for managing the graphical
display, inter-process communication, etc.

Sometimes special purpose langauges are added. For example, RESCU
the "Real Time Expert System Club" project in the UK Alvey programme
developed a plant control system based on a mixture of Pop-11 and
a special purpose language implemented for expressing rules for
the plant control system. That prototype has been extended in a
system called COGSYS and a company called COGSYS Ltd has been set up
to market it.


You can find out more in
James A.D.W. Anderson (ed)
    Pop-11 comes of age: the advancement of an AI programming language
    Ellis Horwood, Chichester, 1989

though I fear the price of the book is horrendous.

I hope this helps to answer the question. Apologies for the length.

Aaron Sloman,
School of Cognitive and Computing Sciences,
Univ of Sussex, Brighton, BN1 9QH, England
    EMAIL   aarons@cogs.sussex.ac.uk