
OL(P): Object Layer for Prolog -- Reference Manual
Version 1.1 for SICStus Prolog and QUINTUS Prolog

  Copyright (c) 1993 Markus P.J. Fromherz.  All Rights Reserved.
  Copyright (c) 1993 Xerox Corporation.  All Rights Reserved.

  Use, reproduction, preparation of derivative works, and distribution
  of this software is permitted, but only for non-commercial research or
  educational purposes. Any copy of this software or of any derivative
  work must include both the above copyright notices of Markus P.J.
  Fromherz and Xerox Corporation and this paragraph.  Any distribution
  of this software or derivative works must comply with all applicable
  United States export control laws. This software is made available AS
  IS, and XEROX CORPORATION DISCLAIMS ALL WARRANTIES, EXPRESS OR
  IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED WARRANTIES OF
  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, AND
  NOTWITHSTANDING ANY OTHER PROVISION CONTAINED HEREIN, ANY LIABILITY
  FOR DAMAGES RESULTING FROM THE SOFTWARE OR ITS USE IS EXPRESSLY
  DISCLAIMED, WHETHER ARISING IN CONTRACT, TORT (INCLUDING NEGLIGENCE)
  OR STRICT LIABILITY, EVEN IF XEROX CORPORATION IS ADVISED OF THE
  POSSIBILITY OF SUCH DAMAGES.

Author: Markus P.J. Fromherz

Please send comments and bug reports to <fromherz@parc.xerox.com>.


This manual documents syntax and built-in objects. See the User-Manual
for an introductory overview and examples. Note that apart from the
built-in and library objects, all predicate names of the OL(P) system
start with `ol_'.


Table of contents of this file:

   1. Language Syntax and Constructs
   2. Built-in Object `object'
   3. Built-in Object `ol'
   4. Built-in Object `project'


1. Language Syntax and Constructs
---------------------------------

Objects can be mixed with predicates and directives in the base language. In
the following, "predicates" refers to predicates in the base language (e.g.,
Prolog), while "method" refers to predicates defined within objects. Goals
from the shell are equivalent to goals in predicates.
Objects need some special statements:

object Object.
object Object is_a SuperObjects.

   `Object' is an atom (name of the object) or a term `Name(Attributes)',
   where `Attributes' is a list of attributes (any term) and attribute
   assignments `Attribute = Value'. `SuperObjects' is an object name or
   a conjunction of object names.
   
   Begin statement of an object; declares it as inheriting from the
   superobjects, and the attributes as instance variables of its instances.
   Attribute assignments serve as default variables and override assignments
   for inherited attributes.
   All objects are descendant of the built-in object `object'. `object Object.'
   is equivalent to `object Object is_a object.'.

end_object Object.

   `Object' is an atom (name of the object) that matches an earlier begin
   statement.

:- publish Methods.

   `Methods' is a method specification `Name/Arity' or a conjunction of
   method specifications.

   Declares the methods as public, i.e. they can be called from the outside.
   Public methods are also inherited by subobjects. Has to be defined
   between begin and end statement of an object.

:- override Methods.

   `Methods' is a method specification `Name/Arity' or a conjunction of
   method specifications.

   Declares the methods as overriding, i.e. they replace methods inherited
   from superobjects. These methods are automatically public and inherited
   by subobjects. Has to be defined between begin and end statement of an
   object.

:- dynamic.

   Declares the entire object as dynamic, which allows one to use an object
   in meta-programming (e.g., meta-interpretation). (See project program
   `manual_pro', which uses `listener_lib'.)

Object methods, predicates and directives are written in the same syntax as
the base language. Some additional syntactic elements are available for object-
related operations:

Object::Message

   `Object' is an atom (object name), a pseudo-variable, or a term `Name(I)',
   where instance term `I' has been generated with `new/[1,2]' (see below).
   `Object' being an atom is equivalent to being `Object(_)'.
   The available pseudo-variables are: `self' refers to the context object,
   `this' to object the current method is defined in, `super' to the object the
   method for `Message' is inherited from, and `prolog' to the base language.
   `::Message' is equivalent to `self::Message'; `Goal' is equivalent to
   `prolog::Goal'.
   `Message' is a term matching a method (just like a Prolog goal matching
   a predicate), or a goal with subgoals without object qualifiers.

   Goal that sends the message to the object in the following way. `Message'
   is sent to `Object'; if `Object' defines a matching method (same name and
   arity), this method is called. Otherwise, the matching method in the most
   specific, left-most (in the begin statement) superobject of `Object' is
   called. If `Object' is `self', the search for the method start with the
   context object. If `Object' is `super', the context object is skipped. Thus,
   if a method is inherited but overridden in an object, the inherited method
   can be called from within the object using `super', while all other messages
   call the overriding method.
   In all cases, `Object' remains the context object (the object in whose
   context the method is called). Thus, in the method being called, goals
   using `self' send their messages to `Object', not the object the method is
   defined in.
   `prolog' is not really an object, i.e. most other object-related operations
   are not availabe for `prolog'. However, this pseudo-variable allows to write
   general goals; for example, with the goal `call(O::write(X))', `O' can be
   instantiated to an object name or to `prolog', calling either a method or a
   predicate.
   If the message is a goal with subgoals, all the subgoals are sent to the
   object.
   `Object' and `Message' can be variables, which have to be instantiated at
   run-time to an object name or name with instance, and a single message.
   (There will be an overhead if the object is optimized later on, as the goal
   will have to be translated to the internal message representation at run-
   time.)
   Can be used in both methods and predicates, but pseudo-variables are not
   available in predicates.

::Message

   Equivalent to `self::Message' (see above).

Object::new(AttributeAssignments, Instance)

   `Object' is an atom (object name), `this', or `self'. `Instance' is a
   variable, `AttributeAssignments' a list of assignments `Attribute = Value'.

   Creates instance `Instance' of `Object'.Instance`I' will be an attribute-
   value list with elements `Attribute = Value' and an open (variable) tail.
   `Instance' will be initialized to the default attribute assignment given in
   the object's begin statement (and inherited from superobjects), but the
   `AttributeAssignments' override those values.
   This method is built into the compiler, not inherited from `object'.

Object::new(Instance)

   Equivalent to `Object::new([], Instance)' (see above).

call(Object::Message)

   Same as `Object::Message', except that the goal will be fully compiled at
   run-time, i.e. `Object' and `Message' can use pseudo-variables etc.

Instance.Attribute = Value
Instance.Attribute == Value
Instance.Attribute \== Value

   `Instance' is an instance term generated with `new/[1,2]' (see above).
   `Attribute' is the term for an attribute, `Value' any term.

   Accesses an instance attribute.
   For `=': if the attribute is set in `Instance', its value is unified with
   `Value'; otherwise, it is added to the instance. Changes are undone on
   backtracking.
   For `==': succeeds only if the attribute is defined in `Instance' and its
   value is identical to `Value'.
   For `\==': succeeds if the attribute is not set or has a different value.
   Available in methods only; use `val/3' of object `ol' in predicates.

.Attribute = Value
.Attribute == Value
.Attribute \== Value

   Equivalent to `Instance.Attribute = Value' (or related), where `Instance'
   is the instance of the context object.

UpdatedInstance := Instance.AttributeAssignments

   `UpdatedInstance' is a variable, `Instance' an term generated with
   `new/[1,2]' (see above), `AttributeAssignments' a list of assignments
   `Attribute = Value'.

   Copies `Instance' to `UpdatedInstance', replacing the values for the
   attributes defined in the assignments in the process.
   Available in methods only.

UpdatedInstance := .AttributeAssignments

   Equivalent to `UpdatedInstance := Instance.AttributeAssignments', where
   `Instance' is the instance of the context object.

`Term

   `Term' can be any term in methods (goals, arguments etc.).

   A quoted term, which is replaced by `Term' without further compilation of
   `Term.


2. Built-in Object `object'
---------------------------

This object is the root object for all objects. The following methods are
available and inherited by all objects.

super(?Object)
   is true if Object is a superobject of self.

val(+Attribute, ?Value)
   is true if Value is the value of Attribute of self.


3. Built-in Object `ol'
-----------------------

This object gives access to meta-information about objects and provides some
useful message-related mechanisms. The following methods are available.

object(?Object)
   is true if `Object' is an object name.

super(?Object, ?Super)
   is true if `Super' is the name of a superobject of `Object'.

sub(?Object, ?Sub)
   is true if `Sub' is the name of a subobject of `Object'.

ancestor(?Object, ?Ancestor)
   true if `Ancestor' is an ancestor object of `Object'.

descendant(?Object, ?Descendant)
   true if `Descendant' is an descendant object of `Object'.

defined(?Object, ?Name/Arity)
   is true if `Name/Arity' specifies a method defined in `Object'.

method(?Object, ?Name/Arity)
   is true if `Name/Arity' specifies a public method of `Object'.

handler(+Object, +Name/Arity, ?Handler)
   is true if `Handler' specifies the object that handles method
   `Name/Arity' for `Object' (i.e. `Object::M' will call the method in
   `Handler', where `M' is the message for `Name/Arity').

attribute(+Instance, ?Name)
   true if `Name' is an attribute name in `Instance'.

val(+Instance, +Attribute, ?Value)
   is true if `Value' is the value of `Attribute' of `Instance', or if the
   value has not been set yet. Cf. `Instance.Attribute = Value' above.

o_attribute(+Object(Instance), ?Name)
   true if `Name' is an attribute name in `Instance'.

o_val(+Object(Instance), +Attribute, ?Value)
   is true if `Value' is the value of `Attribute' of `Instance', or if the
   value has not been set yet. Cf. `Instance.Attribute = Value' above.

goal(+Object::+Message, -Goal)
   Goal is the Prolog goal for Object::Message.

all(+Objects, +Message)
   is true if `O::Message' true for all `O' in `Objects' (independently).
   `Objects' has to be a list of object names or names with instance terms.
   `Message' has to be a single message.
   This is a broadcasting method without argument sharing: argument
   instantiations are not carried over to other objects or reported back.
   Useful for independent messages such as initializations, output etc.

and(+Objects, +Message)
   is true if `O::Message' true for all `O' in `Objects' (successively).
   `Objects' has to be a list of object names or names with instance terms.
   `Message' has to be a single message.
   This is a broadcasting method with argument sharing: argument
   instantiations are carried over to other objects and reported back.
   Useful to verify terms across objects such as whether all attributes have
   the same value.

or(+Objects, +Message)
   is true if `O::Message' true for one `O' in `Objects' (backtrackable).
   `Objects' has to be a list of object names or names with instance terms.
   `Message' has to be a single message.
   This is a broadcasting method on backtracking without argument sharing:
   the message is sent to one object after the other in `Objects' until it
   succeeds or no more objects are available; continues on backtracking;
   argument instantiations are not carried over to other objects.
   Useful to find an object or a number of objects that satisfies certain
   conditions.

map(+MapSpec, +List, ?MappedList)
   is true if the `MappedList' with elements Yi is generated from `List'
   with elements Xi, such that for all i:
      self::N(Xi,Yi,...)
   where `MapSpec' is N(...).


4. Built-in Object `project'
----------------------------

This object provides operations for project/file management. It is intended
for online use and will not be part of the run-time system. The following
methods are available. (Use `project::help' and `project::help(Name)' for
online help.)

create(+Project, +Files)

   `Project' is an atom (project name, possibly with path); `Files' is a list
   of atoms (OL(P) file names without extension `.ol').

   Creates a new project that consists of these files. All the files must be
   in the directory indicated by the path of `Project' (the current directory
   if no path is given). File names are expected to have one extension indica-
   ting the base language; `.ol' is automatically appended.
   A file `Project.pl' is generated, holding the project's information. The
   idea is that one program consists of a set of files, and that certain
   operations can or have to be performed on all files (and their objects).

rename(+Project)

   `Project' is an atom (new project name).

   Renames the current project to `Project'. The old project file is deleted.

switch(+Project)

   `Project' is an atom (project name, possibly with path).

   Switches to another project by removing the current project's information
   and loading the information of that project.
   This can also be used to clean up the internal object store, e.g., in
   case old files were removed from the project but are still loaded.

add_files+(Files)

   `Files' is a list of atoms (OL(P) file names without extension `.ol').

   Extends the current project to include these files. The files must be in
   the same directory as the project's other files.

remove_files(+Files)

   `Files' is a list of atoms (OL(P) file names without extension `.ol').

   Removes these files from the list of files that make up the current
   project. The files' object information is also removed.

add_library(+Project)

   `Project' is an atom (project name, possibly with path).

   Adds the project as library to the current project. The project's files
   are added to the current program, but most files operations such as
   compilation are not performed on these files. The idea is that this
   project has been set up and tested as a library of objects, and is not
   changed within the current project.
   The added project itself can include libraries (i.e. other projects).
   Note that it makes a difference whether you add a library with absolute
   or relative path. Using a path relative to the project's directory makes
   the project portable. However, if you set up a library which includes
   other libraries, the paths to those libraries should be absolute, or
   they won't be found if you add the library to another project.

remove_library(+Project)

   `Project' is an atom (project name).

   Removes this library from the current project. The library's object
   information is also removed. (Note that libraries loaded together with
   this library are not removed.)

compile
compile(Files)
compile(Files, Options)

   `Files' is a list of atoms (file names), `Options' a list of atoms.

   Compiles all files of the current project, or the ones given in `Files',
   with options if given. For each file `File', a file `File.ol' must exist,
   which will be compiled to `File. Currently, the only available option is
   `verbose', which lists some information during compilation.
   `compile(Files)' is equivalent to `compile(Files,[verbose])'.

do(+Operation)
do(+Operation(Project))

   `Operation' is an atom (name of a unary predicate); `Project' is an atom
   (project name, possibly with path) or a variable.

   Switches to `Project' first if not current project or added library; then
   calls `Operation(File)' for all files of the project (project and all
   added libraries if `Project' is a variable, libraries first).
   `Operation' might be `consult', `fcompile', `load', `translate' etc.

do(+Operation, +WhichFiles)

   `Operation' is an atom (name of a unary predicate); `WhichFiles' is either
   `all' or `new'.

   Calls `Operation(File)' for all files of the current project, if
   `WhichFiles' is `all', or for the changed files only, if `WhichFiles' is
   `new'. A file is marked as changed if it is compiled by OL(P); this mark
   is removed if the file is `consult'ed or `load'ed.

do(+Operation, ?Extension)
do(+Operation(Project), ?Extension)

   `Operation' is an atom (name of a unary predicate); `Project' is an atom
   (project name, possibly with path) or a variable; `Extensions' is a
   variable or a list of atoms (extensions to be concatenated).

   Switches to `Project' first if not current project or added library; then
   calls `Operation(File)' for all files of the project (all projects if
   `Project' is a variable). If `Extension' is a list, the elements of the
   list will be concatenated and replace the files' extensions.
   (E.g., with files ['a.pl','b.cc'], `project::do(load,[ql])' will call
   "load('a.ql')" and "load('b.ql')".)

do(+Operation, +WhichFiles, ?BaseLanguage)
do(+Operation, +WhichFiles, ?BaseLanguage, +Extension)
do(+Operation(Project), +WhichFiles, ?BaseLanguage)
do(+Operation(Project), +WhichFiles, ?BaseLanguage, +Extension)

   `Operation' is an atom (name of a unary predicate); `Project' is an atom
   (project name, possibly with path) or a variable; `WhichFiles' is either
   `all' or `new'; `BaseLanguage' is a variable or an atom; `Extensions' is
   a variable or a list of atoms (extensions to be concatenated).

   Switches to `Project' first if not current project or added library; then
   calls `Operation(File)' for all files of the current project that are
   defined in the base language, if `WhichFiles' is `all', or for the changed
   files only, if `WhichFiles' is `new' (cf. above; all projects if `Project'
   is a variable).
   (E.g., with files ['a.pl','b.cc'], `project::do(translate,all,cc)' will
   call "translate('b.cc')".)
   If `Extension' is given and a list, the elements of the list will be
   concatenated and replace the files' extensions (see above). `BaseLanguage'
   can also be a variable, and this variable can be used in `Extension'.
   (E.g., with files ['a.pl','b.cc'], `project::do(list,all,BL,[BL,'.ol])' will
   call "list('a.pl.ol')" and "list('b.cc.ol')".)

info

   Equivalent to `info(project), info(library)'.

info(+ProjectType)

   `ProjectType' is either `project' or `library'.

   Lists information about files and objects of the current project if
   `ProjectType' is `project', or of its libraries if `ProjectType' is
   `library'.

info(+Type, ?Information)

   `Type' is either `project', `library', `files', `files(Project)', `object',
   `object(Project)', `method', or `method(Project)' (`Project' an atom, name
   of a library, or a variable). `Information' will be instantiated to a list.

   Returns information depending on the requested type as follows:
     `project'  : `[Project,Path]' (of current project)
     `library'  : `[Project,Path]' (of added library; all on backtracking)
     `files'    : list of files of the current project
     `files(P)' : list of files of added library `P' (all projects if variable)
     `object'   : `[Object,File]' (of current project; all on backtracking)
     `object(P)': `[Object,File]' (of library `P' (all projects if variable);
                  all on backtracking)
     `method'   : `[Method,Object,File]' (of current project; all on backtr.)
     `method(P)': `[Method,Object,File]' (of `P' (all projects if variable);
                  all on backtracking)

info(+Type, +Argument, +Options)

   `Type' is `text', `Argument' a string, `Options' depends.

   Lists information depending on the requested type and argument as follows:
     `text', Text: lists files and lines of current project where Text occurs
                   (uses grep with Options (characters); useful Options are
                   c - number of lines only, h - no file names, i - ignore
                   case, l - file names only, n - with line number;
                   `Argument' can actually be any expression for grep)

external_info(+Project)

   `Project' is an atom (project name, possibly with path).

   Lists information about files and objects of this external project without
   switching to it.

portray
noportray

   Switches pretty-printing of OL(P) terms (e.g., messages) on and off.

help
help(+Name)

   Lists an overview of the above commands, respectively a detailed
   explanation for the named command.