This is Info file parlog.info, produced by Makeinfo-1.55 from the input
file parlog.texi.

This file documents the Parlog system.

Copyright (C) 1989 Imperial College, London.  All rights reserved.


File: parlog.info,  Node: Changes,  Next: BugsFeatures,  Prev: OldChanges,  Up: ReferenceManual

Changes Between V1.4 and V1.5
=============================

`*'
     "channel" abstraction for merging streams (*note ChannelIO::.)

`*'
     recognition of escape characters within atoms (*note
     EscapeSequences::.)

`*'
     primitives to access environment variables (*note Miscellaneous::.)

`*'
     ability to define a search path for files (*note Environment::.)

`*'
     recognition of meta-characters in filenames (*note
     FilenamesAndPaths::.)

`*'
     background processing (*note Running::.)

`*'
     startup file processing (*note StartupFile::.)

`*'
     New primitives `concat_atom/2', `number_chars/2', `atom_chars/2',
     `append/3', `merge/3', `stat/7', `absolute_file_name/2'
     `defined/1', `compare/3', `clock/1', `print/1', `print/2',
     `varoccurs/2', `varsin/2'.

`*'
     Improved compiler messages/warnings

`*'
     Numerous bug fixes


File: parlog.info,  Node: BugsFeatures,  Prev: Changes,  Up: ReferenceManual

Bugs/Features
=============

Suspended guard calls for a candidate clause, which has been rejected in
favour of another clause, are not removed by the system. Such suspended
guard calls are also called "dead" processes.

Deadlock and interrupts do not kill or remove processes; they only
restart the top level command interpreter.

I/O predicates produce a segmentation error when called with an
inappropriate stream argument.

It is possible to overflow a heap by unifying a variable with a very
large term in the source code (e.g. a list of over 128 elements) when
the top heap segment is almost full. This can result in a segmentation
error.  There is no problem with terms constructed dynamically during
execution and a workaround is to break up the source code term into
smaller parts, e.g.
     g(X) <- X = [1,2,....,128|X1], g1(X1).
     g1(X1) <- X1 = [129,130,....,256].

Similarly, it is possible to overflow an argument stack by calling a
large number of goals in a parallel conjunction when the top stack
segment is almost full, if the sum of all the arguments in the parallel
conjunction exceeds 256. The workaround is to replace some of the goals
in the conjunction with a single call to a predicate that invokes the
replaced goals.  In theory, the compiler could be made to detect and fix
both of these cases automatically.

Loading C predicates does not work on the Alliant and Multimax versions.


File: parlog.info,  Node: IC-PrologII,  Next: References,  Prev: ReferenceManual,  Up: Top

Interface with IC-Prolog II
***************************

This chapter describes the extra primitives available when Parlog is
run under the IC-Prolog II system.  These primitives are not available
in the standalone Parlog system.

In IC-Prolog II, a thread is a sequential Prolog process.  IC-Prolog II
is a multi-threaded system so there may be more than one thread running
concurrently.

* Menu:

* CallingProlog::               Parlog calling Prolog
* PipeCommunication::           Inter thread/process communication
* NetworkCommunication::        TCP/IP and Mailboxes
* Other::                       Miscellaneous Additional Primitives


File: parlog.info,  Node: CallingProlog,  Next: PipeCommunication,  Up: IC-PrologII

Calling Prolog
==============

To enable Parlog to call Prolog, there is a suite of Parlog primitives
which execute Prolog goals.  This is achieved by executing the Prolog
goals in separate threads in the multi-threaded IC-Prolog II system.

There is more than one such primitive because the goal may be executed
in a new thread or an existing server thread, the goal may produce one
or more solutions which can be generated eagerly or lazily, and we may
or may not be interested in the answer bindings.

`prolog_cmd(G)'
     "synchronisation:" Suspends until G is instantiated.

     "behaviour:" A new thread is created to execute the Prolog goal G.
     G is a command so no results are expected back to Parlog i.e. any
     variables in G will not be bound.

`prolog(G)'
     "synchronisation:" Suspends until G is instantiated.

     "behaviour:" A new thread is created to execute the Prolog goal G.
     Variables in G will be bound to Prolog's first solution and the
     values communicated back to Parlog.

`prolog(G,P)'
     "synchronisation:" Suspends until G is instantiated.

     "behaviour:" A new thread is created to execute the Prolog goal G.
     All the solutions of G will be available by successively reading
     from the port P using `read_pipe/2'.  When there are no more
     solutions, reading from port P will return `end_of_file'.

`prolog(G,P,Th)'
     "synchronisation:" Suspends until G is instantiated.

     "behaviour:" Same as `prolog/2' with the extra argument returning
     the thread ID of the newly created thread.

`lazy_prolog(G,P,Th)'
     "synchronisation:" Suspends until G is instantiated.

     "behaviour:" Same as `prolog/3' except that the solutions are
     generated lazily and it is the programmer's responsibility to get
     the next solution by explicitly resuming the suspended Prolog
     thread by calling `resume(Th)'.

`qprolog(G)'
     "synchronisation:" Suspends until G is instantiated.

     "behaviour:" Similar to `prolog/1' but quicker to execute since it
     uses the background Prolog server thread instead of creating a new
     thread.  Note that G should be a simple query only since long
     queries will monopolise the Prolog server and cause a bottleneck.

`resume(Th)'
     "synchronisation:" Suspends until Th is instantiated.

     "behaviour:" Resume execution of the specified thread.  This is
     used to wake up explicitly suspended Prolog threads.  If Th is 0,
     the next runnable thread is resumed.  `resume/1' returns an error
     if Th is not a currently valid thread.

`kill_thread(Th)'
     "synchronisation:" Suspends until Th is instantiated.

     "behaviour:" Kills the specified thread and reclaims the memory
     space.


File: parlog.info,  Node: PipeCommunication,  Next: NetworkCommunication,  Prev: CallingProlog,  Up: IC-PrologII

Pipe Communication
==================

In the description below, a pipe is a communication channel between two
threads or processes.  A pipe has two end which are called ports.  An
output port is where terms enter the pipe (i.e. written out by a
thread), and an input port is where the terms leave the pipe (i.e. read
in by a thread).  The same mechanism can be used for Prolog to Prolog,
Parlog to Parlog, Prolog to Parlog or Parlog to Prolog communication.

`pipe(OP,IP)'
     "synchronisation:" No suspension.

     "behaviour:" Creates a new pipe and binds OP to the output end and
     IP to the input end of the pipe.  Terms which are written to OP
     may be read from IP.  The structure of a port term is `port(N)'
     where N is an integer.

`write_pipe(OP,T)'
     "synchronisation:" No suspension.

     "behaviour:" Outputs the term T to the output port OP.  OP must be
     an output port owned by the current thread, otherwise the
     primitive fails.  Ownership of a port is automatically set to the
     current thread if there is no current owner.  Note that creation
     of a pipe does not set ownership for the ports.  Thus a pipe may
     be created by one thread and used by another thread.  If any
     thread is suspended on a read, `write_pipe/2' wakes it after T is
     written out to the pipe.

`look_pipe(IP,T)'
     "synchronisation:" No suspension.

     "behaviour:" Copies a term T from the input port IP.  The term is
     not removed from the pipe.  IP must be an input port owned by the
     current thread, otherwise the primitive fails.  Ownership of a
     port is automatically set to the current thread if there is no
     current owner.  The pipe is `locked' before the term is read.
     This is to prevent multiple readers accessing the pipe
     simultaneously.  The lock is not released by this primitive (see
     `commit_read/1').  `look_pipe/2' suspends if the port is already
     locked or if the pipe is empty.  If the output port of the pipe is
     closed, `look_pipe/2' binds T to the constant `end_of_file'.

`commit_read(IP)'
     "synchronisation:" Suspends until IP is instantiated.

     "behaviour:" Removes the term previously read by `look_pipe/2'
     from the pipe and unlock the pipe.  IP must be an input port owned
     by the current thread, otherwise the primitive fails.
     `commit_read/1' fails if the pipe is not locked (i.e. no previous
     `look_pipe/2').

`read_pipe(IP,T)'
     "synchronisation:" No suspension.

     "behaviour:" Reads a term T from the input port IP.  Semantically,
     this is equivalent to `look_pipe(IP,T)' followed sequentially by
     `commit_read(IP)'.

`empty_pipe(IP)'
     "synchronisation:" Suspends until IP is instantiated.

     "behaviour:" Succeeds if there is no data ready to be read from
     input port IP.

`is_iport(Port)'
     "synchronisation:" Suspends until Port is instantiated.

     "behaviour:" Succeeds if Port is an input port.

`is_oport(Port)'
     "synchronisation:" Suspends until Port is instantiated.

     "behaviour:" Succeeds if Port is an output port.

`unlock(Port)'
     "synchronisation:" Suspends until Port is instantiated.

     "behaviour:" Unlocks a pipe which has been locked by a previous
     `look_pipe/2'.  The port must be owned by the current thread,
     otherwise the primitive fails.  This is used in the case where the
     term read is not the one expected.  The pipe is unlocked so that
     another thread can re-read the same term.

`close_port(Port)'
     "synchronisation:" Suspends until Port is instantiated.

     "behaviour:" Closes the specified port.  The port must be owned by
     the current thread, otherwise the primitive fails.  `close_port/1'
     suspends if the pipe is locked and fails if the port has a
     suspended operation pending.  If an output port is closed,
     subsequent (and suspended) reads from the input port will return
     `end_of_file'.  Closing an input port does not affect the output
     port.  If both ports are closed, space used for the pipe is
     reclaimed.

`release_port(Port)'
     "synchronisation:" Suspends until Port is instantiated.

     "behaviour:" Releases ownership of the port to allow other threads
     to use it.  The port must be owned by the current thread,
     otherwise the primitive fails.  `release_port/1' suspends if the
     pipe is locked.


File: parlog.info,  Node: NetworkCommunication,  Next: Other,  Prev: PipeCommunication,  Up: IC-PrologII

Network Communication Primitives
================================

Parlog under IC-Prolog II has a large set of primitives for
communication over a network.  The set consists of an interface to
TCP/IP library calls and an alternative communication model based on
the notion of mailboxes.

The Parlog primitives are identical to those available under the Prolog
component of IC-Prolog II. Please refer to the Prolog manual for
further details.


File: parlog.info,  Node: Other,  Prev: NetworkCommunication,  Up: IC-PrologII

Miscellaneous
=============

`prolog'
     "synchronisation:" No suspension.

     "behaviour:" Switches the query evaluator from Parlog to Prolog in
     the case where Prolog and Parlog share the same window.  Normally,
     Parlog and Prolog will each have their own windows.  This is only
     used interactively as a top level goal.

`parlog(G)'
     "synchronisation:" Suspends until G is instantiated.

     "behaviour:" Start executing the goal G as a separate Parlog
     process.  This is similar to meta-call `call/1' except that
     variables are not instantiated and `parlog/1' returns immediately
     regardless of the how long it takes to execute G or indeed whether
     it succeeds or fails.  This primitive is most useful for setting
     up `background' goals.

`timeslice(N)'
     "synchronisation:" Suspends until N is instantiated.

     "behaviour:" If N is the integer 0, time-slicing is switched off.
     This has the effect of preventing runnable Prolog threads from
     executing, thus allowing Parlog exclusive use of the processor.
     If N is the integer 1, time-slicing is resumed.  This primitive is
     used when atomicity is required or when critical code regions are
     entered.

`ensure_loaded(F)'
     "synchronisation:" Suspends until F is instantiated.

     "behaviour:" Loads the file F if not already loaded.  This
     primitive can be safely used instead of `load/1' to ensure that
     the file is loaded once and once only.


File: parlog.info,  Node: References,  Next: PredicateIndex,  Prev: IC-PrologII,  Up: Top

References
**********

Clark, K., McCabe, F.G., Johns, N., and Spenser, C. 1987., "LPA
MacPROLOG Reference Manual", Logic Programming Associates Ltd, London.

Conlon, T., and Gregory, S. 1989., "Hands on  MacParlog  1.0", Parallel
Logic Programming Limited, London, January.

Crammond, J.A. 1990., "The Abstract Machine and Implementation of
Parallel Parlog", Research Report, Dept. of Computing, Imperial
College, London.

Foster, I., Gregory, S., Ringwood, G., and Satoh, K. 1986., "A
Sequential  Implementation  of PARLOG", 3rd International Conference on
Logic Programming, London, July.

Gregory, S. 1987., "Parallel Logic Programming in  PARLOG : The
Language  and  its Implementation", Addison-Wesley.


File: parlog.info,  Node: PredicateIndex,  Prev: References,  Up: Top

Predicate Index
***************

* Menu:

* #/2:                                  Metalevel.
* </2:                                  TermComparison.
* <=/2:                                 UnificationRelated.
* =../2:                                TermManipulation.
* =/2:                                  UnificationRelated.
* =:=/2:                                TermComparison.
* =</2:                                 TermComparison.
* ==/2:                                 UnificationRelated.
* =@=/2:                                TermComparison.
* =\=/2:                                TermComparison.
* >/2:                                  TermComparison.
* >=/2:                                 TermComparison.
* @</2:                                 TermComparison.
* @=</2:                                TermComparison.
* @>=/2:                                TermComparison.
* @>Y/2:                                TermComparison.
* absolute_file_name/2:                 Miscellaneous.
* append/3:                             Miscellaneous.
* arg/3:                                TermManipulation.
* atom/1:                               TypeTests.
* atomic/1:                             TypeTests.
* atom_chars/2:                         TermManipulation.
* call/1:                               Metalevel.
* call/3:                               Metalevel.
* clear_input/1:                        Streams.
* clock/1:                              Miscellaneous.
* close/1:                              Streams.
* close_channel/1:                      ChannelIO.
* close_port/1:                         PipeCommunication.
* commit_read/1:                        PipeCommunication.
* compare/3:                            TermComparison.
* compile/1:                            CompilationAndLoading.
* concat_atom/2:                        TermManipulation.
* copy_term/2:                          TermManipulation.
* create_channel/2:                     ChannelIO.
* current_input/1:                      Streams.
* current_module/1:                     CompilationAndLoading.
* current_op/3:                         Operators.
* current_op/4:                         Operators.
* current_output/1:                     Streams.
* data/1:                               UnificationRelated.
* defined/1:                            CompilationAndLoading.
* display/1:                            TermIO.
* display/2:                            TermIO.
* empty_pipe/1:                         PipeCommunication.
* ensure_loaded/1:                      Other.
* export/1:                             CompilationAndLoading.
* fail/0:                               Metalevel.
* float/1:                              TypeTests.
* flush_output/1:                       Streams.
* functor/3:                            TermManipulation.
* get/1:                                CharacterIO.
* get/2:                                CharacterIO.
* get0/1:                               CharacterIO.
* get0/2:                               CharacterIO.
* getenv/2:                             Miscellaneous.
* get_channel/2:                        ChannelIO.
* ground/1:                             UnificationRelated.
* halt/0:                               Metalevel.
* import/2:                             CompilationAndLoading.
* integer/1:                            TypeTests.
* is/2:                                 ArithmeticExpressions.
* is_iport/1:                           PipeCommunication.
* is_oport/1:                           PipeCommunication.
* kill_thread/1:                        CallingProlog.
* lazy_prolog/3:                        CallingProlog.
* load/1:                               CompilationAndLoading.
* load_foreign/2:                       CompilationAndLoading.
* load_foreign/3:                       CompilationAndLoading.
* load_foreign_io/2:                    CompilationAndLoading.
* load_foreign_io/3:                    CompilationAndLoading.
* look_pipe/2:                          PipeCommunication.
* merge/3:                              Miscellaneous.
* module/1:                             CompilationAndLoading.
* name/2:                               TermManipulation.
* nl/0:                                 CharacterIO.
* nl/1:                                 CharacterIO.
* nonvar/1:                             UnificationRelated.
* nospy/1:                              Spypoints.
* not/1:                                Metalevel.
* number/1:                             TypeTests.
* number_chars/2:                       TermManipulation.
* op/3:                                 Operators.
* op/4:                                 Operators.
* open/3:                               Streams.
* parlog/1:                             Other.
* pipe/2:                               PipeCommunication.
* print/2:                              TermIO.
* prolog/0:                             Other.
* prolog/1:                             CallingProlog.
* prolog/2:                             CallingProlog.
* prolog/3:                             CallingProlog.
* prolog_cmd/1:                         CallingProlog.
* public/1:                             CompilationAndLoading.
* put/1:                                CharacterIO.
* put/2:                                CharacterIO.
* qprolog/1:                            CallingProlog.
* read/1:                               TermIO.
* read/2:                               TermIO.
* read/4:                               TermIO.
* read_pipe/2:                          PipeCommunication.
* release_port/1:                       PipeCommunication.
* resume/1:                             CallingProlog.
* setenv/2:                             Miscellaneous.
* set_input/1:                          Streams.
* set_output/1:                         Streams.
* skip/1:                               CharacterIO.
* skip/2:                               CharacterIO.
* spy/1:                                Spypoints.
* stat/7:                               Miscellaneous.
* statistics/0:                         Miscellaneous.
* statistics/2:                         Miscellaneous.
* tab/1:                                CharacterIO.
* tab/2:                                CharacterIO.
* timeslice/1:                          Other.
* true/0:                               Metalevel.
* unix/1:                               Miscellaneous.
* unlock/1:                             PipeCommunication.
* util/1:                               Miscellaneous.
* var/1:                                UnificationRelated.
* varoccurs/2:                          TermManipulation.
* varsin/2:                             TermManipulation.
* write/1:                              TermIO.
* write/2:                              TermIO.
* writeq/1:                             TermIO.
* writeq/2:                             TermIO.
* write_canonical/1:                    TermIO.
* write_canonical/2:                    TermIO.
* write_channel/2:                      ChannelIO.
* write_pipe/2:                         PipeCommunication.
* \==/2:                                UnificationRelated.
* \=@=/2:                               TermComparison.


