Integrating Prolog Into the Poplog Environment
Total Page:16
File Type:pdf, Size:1020Kb
INTEGRATING PROLOG INTO THE POPLOG ENVIRONMENT Chris Mellish and Steve Hardy* Cognitive Studies Programme, University of Sussex, Falmer, BRIGHTON, UK. ABSTRACT Although Prolog undoubtedly has its good "syntactic sugar" has been provided in POP-11 to points, there are some tasks (such as writing a make it easy to create closures; an expression screen editor or network interface controller) for such as: which it is not the language of choice. The most natural computational concepts [2] for these tasks are hard to reconcile with Prolog's declarative doubled 3 %) nature. Just as there is a need for even the most committed Prolog programmer to use "conventional" evaluates to a closure which when later invoked languages for some tasks, so too is there a need calls the procedure DOUBLE with argument 3. for "logic" oriented components in conventional applications programs, such as CAD systems [73 and relational databases [5]. At Sussex, the problems II BACKTRACKING AND CONTINUATION PASSING of integrating logic with procedural programming are being addressed by two projects. One of these In this section, we illustrate, using [43 involves a distributed ring of processors examples written in POP-11, how backtracking communicating by message passing. The other programs are implemented in POPLOG using a project is the POPLOG system, a mixed language AI technique called continuation passing. Although programming environment which runs on conventional examples are shown in POP-11 for clarity, in hardware. This paper describes the way in which we practice Prolog programs are compiled directly to have integrated Prolog into POPLOG. POPLOG virtual machine code. Continuation passing is a technique in which I THE POPLOG ENVIRONMENT procedures are given an additional argument, called a continuation. This continuation (which is a procedure closure) describes whatever The POPLOG system is an AI programming environment developed at Sussex University [3D. It computation remains to be performed once the supports Prolog, POP-11, a dialect of POP-2 [13, called procedure has finished its computation. In and a basic LISP. POPLOG currently runs on the conventional programming, the continuation is DEC VAX series of computers under the VMS represented implicitly by the "return address" and operating system, but other implementations are in code in the calling procedure. Suppose, for progress. example that we have a procedure, called PROG, that has just two steps: calling the subprocedure F00 and then the subprocedure BAZ, thus: In POPLOG, the link between the programming languages and the underlying machine is the POPLOG virtual machine. The compilers produce POPLOG virtual machine instructions, which are then further translated into the machine code for the host machine. At the level of host machine code, it is possible to link in programs written in languages such as FORTRAN. Procedures for "planting" instructions for the virtual machine are fully accessible to the user. Thus the Prolog compiler is just one of the many possible POPLOG programs that create new pieces of machine code. In particular, it is easy to create procedure closures. For the purposes of this paper, a closure is a structure which contains a pointer to a procedure plus a set of arguments for that procedure. The closure can then be applied as if This definition presupposes that F00 and BAZ it were a normal procedure with no arguments. Some do not themselves take continuations. If they do, then we must arrange for BAZ to be passed *Steve Hardy is now at Teknowledge Inc, 525 CONTINUATION and for F00 to be passed an University Ave, Palo Alto, CA 94301, USA. appropriate closure of BAZ, thus: 534 C. Mellish and S. Hardy define prog(continuation); define jogs(x, continuation); foo(baz(%continuationX)> unify(x,"chris",continuation); enddefine; unify(x,"jon",continuation) enddefine; Thus F00 gets as argument a closure. This closure, when applied, will cause BAZ to be UNIFY is a procedure that takes two data invoked with CONTINUATION as its argument. structures and a continuation. It attempts to unify (that is, "make equal") the two structures. Continuations have proved of great If it is unsuccessful, UNIFY immediately returns significance in studies on the semantics of to its invoker. If, however, it is successful, programming languages C63. This apparently round then it applies the continuation and when that about way of programming also has an enormous returns, UNIFY undoes any changes it made to the practical advantage - since procedures have two structures and then itself returns to its explicit continuations there is no need for them invoker. to "return" to their invoker. Conventionally, sub-procedures returning to their invokers means Before we can present a definition of UNIFY, "I have finished - continue with the computation", we must consider the representation of Prolog with explicit continuations we can assign a variables. In Prolog, variables start off different meaning to a sub-procedure returning to "uninstantiated" and can be given a value only its invoker, "Sorry - I wasn't able to do what you once (without backtracking); moreover two wanted me to do". "uninstantiated" variables when unified are said to "share", so that as soon as one of them obtains This can be illustrated if we define a new a value, the other one automatically obtains the procedure NEWPROG, whose definition is try doing same value. F00 and if that doesn't work then try doing BAZ, thus: In POPLOG, a Prolog variable is represented by a single element data structures called a REF. define newprog(continuation); REFs are created by the procedure CONSREF and foo(cont i nua t i on); their components are accessed by the procedure baz(continuation); CONT. An uninstantiated Prolog variable is enddefine; represented by a REF containing the unique word "undef". If a variable is assigned some value, If we now invoke NEWPROG (with a this value is placed into the CONT. If two continuation) then it first calls F00 (giving it variables come to "share", we make one point to the same continuation as itself). If F00 is the other. To find the "real" value of a succesful then it will invoke the continuation. If variable, especially one that is sharing, it is not then the call of F00 will return to NEWPROG necessary to "dereference" it (look for the which then tries BAZ. If BAZ too fails (by contents of the "innermost" REF). returning) then NEWPROG itself fails by returning to its invoker. Here now is a simple definition of UNIFY written in POP-11: define unify(x,y,continuation); if x == y then continuationO elseif isref(x) and cont(x) = "undef" then y -> cont(x); continuationO; "undef" -> cont(x) elseif isref(x) and cont(x) /= "undef" then uni f y (cont (x) ,y, cont i nuat i on) elseif isref(y) then unify(y,x,continuation) elseif ispair(x) and ispair(y) then unify(front(x),front(y), unify(Xback(x),back(y),continuation%)) end if enddefine; The procedure first sees if the two given data structures, X and Y, are identical. If so, it immediately applies the CONTINUATION. If the structures aren't identical then UNIFY looks to see whether X is a REF and if so whether it is uninstantiated (ie. whether its CONT is the word "undef"). If so, UNIFY sets its value to Y (by assigning to the CONT; assignment works from left to right in POP-11), does the CONTINUATION and if this returns (ie fails) unbinds the REF by setting C. Mellish and S. Hardy 535 the CONT back to "undef". The final case of UNIFY (2) The continuation passing model provides a deals with the possibility that X and Y may be semantics for communication between these two list pairs. A complete definition of UNIFY must Languages which allows for far more than have a case here for each type of datastructure simple "subroutine calling". recognised as a Prolog complex term. Note that (3) The control facilities available within POPLOG there is no ELSE part to the IF statement. The (not shown here) make it possible to implement default action is simply to return (ie indicate a system which is faithful to the theoretical failure). modeL, but which is nevertheless efficient. As a more complex example, here is a translation of the Prolog MEMBER predicate into ACKNOWLEDGEMENTS POP-11. The Prolog definition is: We would like to thank John Gibson, the main member(X,[X|Y3). implementer of the POPLOG virtual machine and the member(X,[Y|Z3) :- member(X,Z). POP-11 compiler, for providing us with a powerful programming environment, without which this work When translated into POP-11, it will be would not have been possible. We would also like necessary to make explicit the unifications which to thank Aaron Sloman and Jon Cunningham for many are implicitly done when a Prolog predicate is useful discussions. invoked. It may therefore be easier to understand the POP-11 translation if we rewrite the Prolog REFERENCES definition to make the various unifications explicit: [13 Burstall, R.M., Collins, J.S. and Popplestone, R.J., Programming in POP-2, member(X,Y) :- Y = [X|M3. Department of Artificial Intelligence, member(X,Y) :- Y = [L|M3, member(X,M). University of Edinburgh, 1977. [23 Hardy, S., "Towards More Natural Programming This translates into the following POP-11 Languages" Cognitive Studies Memo 82-06, procedure: University of Sussex, 1982. define member(x, y, continuation); [3] Hardy, S., "The POPLOG Programming vars I; consref("undef") -> I; Environment", Cognitive Studies Memo 82-05, vars m; consref("undef") -> m; University of Sussex, 1982. unify(y, conspair(x,m), continuation); [43 Hunter J.R.W., Mellish, C.S. and Owen, D., "A unify(y, conspair(l,m), Heterogeneous Interactive Distributed Computing Environment for the Implementation member(%x/m,cont i nuat i on%)) enddefine; of AI Programs", SERC grant application, School of Engineering and Applied Sciences, The first two lines of this definition create University of Sussex, 1982.