
                 L3P  ESSENTIAL MANUAL  (Last update: Winter '95)
                 -----------------------------------------------

WARNING:

         THESE NOTES ARE NOT A SPECIFICATION LANGUAGE MANUAL !

 A comprehensive manual (let's call it "the full manual") will be provided to
 registered users.
 These pages can be used only as a first and quick reference programmer guide
 in order to have a general idea of what is available and to check syntax.
 The reader should be confident with fundamental programming language
 concepts and with usual syntax conventions.
 This guide can be freely duplicated and distributed provided that this
 warning, as well as any other part of it, is not removed nor modified.


-----------------------------------------------------------------------------
1. LEXICON AND COMMENTS
-----------------------------------------------------------------------------

L3P is not case-sensitive, other than in the logic scopes, if present.
In this brief manual keywords will be uppercase just for reader's convenience.

Comments are enclosed by (* and *) and can be nested.
Only in predicate sections (for PROLOG compatibility) you can use also /* */.

Identifiers can be of any length but only the first 16 are considered.

Many keywords admit abbreviations (e.g. ENDW instead of ENDWHILE).

Semicolons at the end of a line can be omitted.

-----------------------------------------------------------------------------
2. DECLARATIONS AND PROGRAMS
-----------------------------------------------------------------------------

An L3P work can be either a <global-declaration-sequence> or a <program>.

  A <declaration> can be:

   - a variable section;
   - a constant section;
   - a function;
   - a procedure;
   - a predicate section.

Variable and constant sections follow Pascal syntax, but "untyped" (or
"universal") variables are admitted.

Example:

VAR Count: INTEGER
    A,B   (* untyped or UNIV variables *)
    U,K,Z: LIST

A <global-declaration-sequence> stored on a file can be included (in the
usual sense) by specifying the compiler directive:

                            $INCLUDE <filename>

Functions and procedures may have a <local-declarations-sequence> which
differs from a <global-declaration-sequence> because the former cannot
admit predicate sections.

A <program> has the form:

PROGRAM <name>
[ <global-declaration-sequence> ]
BEGIN
  <statement-sequence>
END

Only <program>s can be executed.

Variables and array elements are initialized with a special UNDEFINED VALUE;
accessing them before assigning them a value will cause a run-time error.

L3P is a lexically scoped language in the same sense as Pascal. Moreover,
like Pascal, it follows the convention that any entity (with the exception of
the PROLOG predicates), must be declared before using it. You may overcome
mutual recursion problems with the <Anticipating declaration>:

ANTICIPATING <routine-interface>

e.g. ANTICIPATING PROCEDURE VisitForest(L: LIST)

-----------------------------------------------------------------------------
3. TYPES AND EXPRESSIONS
-----------------------------------------------------------------------------

L3P adopts a flexible approach to the typing problem. It permits a programmer
to "untype" some entities by providing type checks at run-time.

L3P distinguishes between first-class types and second-class types.
The former are predefined (you cannot define new first-class types) and their
values can be read or written.

Second class types are anonymous; i.e., you cannot assign a name to any of
them. Second class values are subject to the following restrictions:

  a) cannot be the result of a function;
  b) cannot be list or array elements;
  c) cannot be read/written on I/O devices.


3.1 FIRST-CLASS TYPES
---------------------

Sometimes, speaking of the type of a variable or an expression, we need to
distinguish between:

a) its STATIC TYPE, i.e. the type deduced from the compiler according to
   the given declarations and to some type-inference rules;

b) its DYNAMIC TYPE, i.e. the type assumed by the entity at a given time
   while running.


3.1.1 BASIC TYPES

Basic types are all the possible dynamic types. Here is a concise
presentation of each of them:


  BOOLEAN: <FALSE,TRUE>
           not, and, or

  INTEGER: <MININT, ...,-1,0,1,..., MAXINT>
          -(unary), +, -, *, //, div, mod, rem

  REAL:   <any IEEE-Short Real>  (on current implementation)

          - (unary),+,-,*,/, power, sin, cos, tan, ...

  CHAR:  <any ASCII-char, e.g. 'A' (or #65) >
         UpCase, Succ, Pred, Ord, Chr

  STRING: <'','A',..., 'ABC', ...>
          FirstChar, StrTail, conc (infix), ...

(Current implementation limits to 255 the maximum string length)

  LIST: < [x1,x2,...,xn] n>=0 >
        Head, Tail, [ h | t ],  & (infix ), ~ (infix)

Notes:
------
Lists are untyped: they can hold values of any first-class type.
& is the list concatenation operator.
~ is the access operator to a list element (see Chapter 8.b ).

  LOGVAR: < any Prolog variable (e.g.  X, Ya, _x, ...) >

  COMPTERM: <any Prolog compound term>
            Functor, ArgList, MkCompTerm

3.1.2 ORDINAL TYPES

The ordinal types are:  BOOLEAN, INTEGER, CHAR.

Ordinal types have these properties:
a) they share SUCC, PRED and ORD operations;
b) they play a role in the FOR and CASE statements;
c) they may be index type in ARRAY declarations.

3.1.3 UNION TYPES

Union types are composed of the disjoint set union of some basic types.
L3P provides two union types:

  NUMERIC = REAL + INTEGER

  UNIV = BOOLEAN + INTEGER + REAL + CHAR + STRING + LIST + LOGVAR + COMPTERM

  "Untyping" an entity means assigning it the type UNIV.

From a logic point of view, universal values will be considered as logical
 terms in which the elements of:

               BOOLEAN + INTEGER + REAL + CHAR + STRING + empty list

 are the constants.

3.2 SECOND CLASS TYPES
-----------------------

3.2.1 ARRAY TYPES

ARRAY types, for the purpose of array passing, are described by :

                  ARRAY [*,*,...] OF <first-class-type>

where the number of '*' stands for the number of array dimensions.
Array declaration and accessing follow Pascal syntax rules:
   e.g.:

    VAR A: ARRAY [1..10,'A'..'Z'] OF LIST
        B: ARRAY[-100..NMAX] OF INTEGER

    A[i+1,'H']:=[1,2,3]
    B[k]:=B[k+1]

Arrays can be dynamically resized with:  <Array-name>.Dim(low1,upp1,...)

  Bounds can be observed with:  <Array-name>.LowBnd(Dimension-index)
                          and:  <Array-name>.UppBnd(Dimension-index)

3.2.2 FUNCTION and PROCEDURE types

Function and procedure types can be used to carry out some higher order
programming.

For example, the classical "MAP" LISP function might be defined as:

FUNCTION Map(L: LIST; F: FUNCTION(X)): LIST
RETURN if L=[] then [] else [F(Head(L)) | Map(Tail(L), F)] endif
END Map

More precisely, input parameters can have types such as:

          FUNCTION(): UNIV
          FUNCTION(X: INTEGER; L: LIST):REAL

          PROCEDURE(INOUT X,Y: INTEGER)
          PROCEDURE(N: INTEGER; OUT A: ARRAY[*] OF REAL)

The corresponding actual parameters must be functions (or procedures) with
EXACTLY the same interface. You can often overcome this restriction by using
anonymous calls ( see 5.3 ).


3.3 EXPRESSIONS
----------------

The formal syntax description of an L3P expression is quite long and will not
be reported here (if interested, the reader should refer to the full manual).
We might instead distinguish among several <expression> categories:

manifest constants       e.g. 100 "home" 'A' 04F10AH  #65  []  _X
symbolic constants       e.g. PI  MAXINT  YELLOW
pseudo-constants         e.g. TurtleX()  Today()
variables or elements    e.g. X  Cost  Sum  A[i+1]  L~i
compound expressions     e.g. X+Y   Head(Tail([A,3*X | L]))
conditions               e.g. X=Y    (X>=3) AND (X<=5)
conditional expressions  e.g. IF N=0 THEN 1 ELSE N*fact(N-1) ENDIF


3.3.1  CONDITIONAL EXPRESSIONS

Conditional expressions take the general form:

IF <cond> THEN <expression>
    { ELSIF <cond> THEN <expression> }
   ELSE <expression>
ENDIF

Each branch of a conditional expression is statically type checked.


3.3.2 PRIORITIES

The programmer should be aware of the following priority hierarchy:

Highest: ~ ?
        NOT
        * // div mod rem AND
        + - conc OR &
Lowest : = < > <> = <= >=

All binary operators are left associative.


3.3.3 ACCESSING THE VALUE BOUND TO A LOGIC VALUE

The ? operator must prefix a logic variable within its scope. It returns the
 value bound to the logic variable.
Scoping rules for logic variables are quite intuitive. However you should
refer to the full manual for a precise definition.

3.4 TYPE COMPATIBILITY
----------------------

Type compatibility rules are quite long to describe and will not be reported
here. Nonetheless, many of them can be summarized by the rule: "What you
expect is what you get".
 For example, given the functions:

     f(X: REAL; I: INTEGER): NUMBER ,
     g(Y: STRING; Z: NUMBER): INTEGER

and the variables:

   VAR U; C: CHAR;

let us look at the following calls:

f(5,3)            OK: INTEGER is converted to REAL when required
f(5,3.1)          ILLEGAL: REAL is not type compatible with INTEGER
f(U,3)            OK, but dynamic type of U will be checked at run time
g(C,5)            OK: CHAR is type-compatible with STRING
g(['a','b'],5)    ILLEGAL: a list of chars is not a STRING
g('abcd',f(0,0))  OK, with no type check at run time

There are two exceptions to the expected rules:

1) actual array parameters with direction other than IN must have
   exactly the same type of the corresponding formal parameter.
   Array length is not considered (i.e., we have "open" arrays);

2) when passing function or procedure as argument their type must be exactly
   the same of the corresponding formal parameter.

-----------------------------------------------------------------------------
4. STATEMENTS AND CONTROL STRUCTURES
-----------------------------------------------------------------------------

As usual, a <statement> is a command that might produce some change on
variables, screen, I/O devices. Statements can be simple or structured, i.e.
built by means of a control structure.

4.1 SIMPLE STATEMENTS
---------------------

We will not describe in detail the simple statements. We will instead give an
example for each category:


assignment         M[A[i],K]:=[1,2,3]
procedure call     Sort([1,3,2,5,3,0],A)
"read" command     read |'Give me two numbers',X,Y\'and two strings',S,T
"write" command    write \'Here is the sum',X+Y,'and concaten. is',S conc T
abstract command   <<check input data>>
control command    e.g.  RETURN,  or  ERROR('File not found')

Execution of abstract commands will rise a LOGO-like runtime error such as
"I don't know how to ..." but are useful in top-down developments.


4.2 SEQUENCING
--------------

  <statement-sequence>
  or:  BEGIN <statement-sequence> END

A <statement-sequence> has the form:

  <statement>; <statement>; ...

Empty <statement-sequence>s are allowed.

4.3 SELECTING
-------------

  IF <cond> THEN <statement-sequence>
  { ELSIF <cond> THEN <statement-sequence> }
  [ ELSE <statement-sequence> ]
  ENDIF

  CASE <expression> OF
   { <Pascal-ordinal-subset>: <statement-sequence> }
   [ ELSE <statement-sequence> ]
  ENDCASE

  IFEXISTSSOL OF <L3P-Prolog-query> THEN
  <statement-sequence>
  [ELSE <statement-sequence> ]
  ENDIFEXISTS

  The latter deserves some explanation: it might be used for interfacing the
 imperative paradigm with the logic one when we are only interested in the
 first (maybe unique) solution found by the logic engine.
 In the THEN branch you can access the values bound to logic variables
 by prefixing them with '?'.

4.4 LOOPING
-----------

  WHILE <cond> DO <statement-sequence> ENDW

  REPEAT <statement-sequence> UNTIL <cond>

  FOR <expr> TIMES <statement-sequence> ENDFOR

  FOR <index> FROM <expr> (TO | DOWNTO) <expr> DO <statement-sequence> ENDFOR
  (Note: <index> has a local scope and it has not to be declared. )

  LOOP { [EXITIF <cond>] <statement-sequence> }  ENDLOOP
  (Note: at least one EXITIF <cond> must appear.)

  FOREVER  <statement-sequence>  ENDFOREVER

  FOREACHSOL [OF] <L3P-Prolog-query> [WHILE <cond>] [UNTIL <cond>]
    <statement-sequence>
  ENDFOREACH

  The latter deserves some explanation: it is the basic tool
  for interfacing the imperative paradigm with the logic one.
  Each solution found from the logic engine can be processed
  in the loop body.
  The WHILE clause permits exiting before entering the loop.
  The UNTIL clause permits exiting before the next solution is generated.
  In the body and in the exit conditions you can access the values bound to
  logic variables prefixing them with '?'.
  See also SOLCOUNT() and SOLINDEX() in Section 8.b.

-----------------------------------------------------------------------------
5. FUNCTIONS AND PROCEDURES
-----------------------------------------------------------------------------


5.1 FUNCTIONS
-------------

Functions assume the form:

FUNCTION <name> ( <formal-parameter-list>): <first-class-type>
[<local-declaration-sequence> ]
 <function body>
END <name>

Functions can be written according to two different styles:

1) Imperative style.

  The <function body> has the form:
  BEGIN
    <statement-sequence>

  where <statement-sequence> must contain at least a command:

   RETURN <expression>

2) Functional style.

The <function-body> is simply: RETURN <expression>.


5.2 PROCEDURES
--------------

Procedures assume the form:

PROCEDURE <name> [( <formal-parameter-sequence> )]
[<local-declaration-sequence> ]
BEGIN
 <statement-sequence>
END <name>

RETURN statements are permitted (though not recommended).

5.3  PARAMETER PASSING
----------------------

L3P does not adopt the classical call by value/by reference transmission in
favour of a more abstract approach.
Each function or procedure formal parameter has a DIRECTION (mode):

IN (default): parameters can only be read
OUT         : parameters can only be written
OUT VAR     : parameters can be read/written but they are initially undefined
INOUT       : parameters can freely be read or written

Note that only IN actual parameters can be any <expression>. The others must
be variables or array elements.

Array formal parameters must be declared of type:

                     ARRAY [*,*,...] OF <first-class-type>

where the number of '*' stands for the number of array dimensions.
Actual array parameters must have the same number of dimensions.


5.4 ANONYMOUS FUNCTIONS AND PROCEDURES
--------------------------------------

L3P permits to pass anonymous functions and procedures as actual parameters
where functions or procedures are expected.

Examples:

Map([10,20,30],FUNCTION(Y).Y+1)  (* result is [11,21,31] *)

Rotate(45, PROCEDURE(N: INTEGER; K: REAL).BEGIN
                                           SetColor(RED)
                                           FOR N TIMES
                                             Left(360/N); Forwd(K)
                                           ENDFOR
                                         END)

A suitable use of them can overcome some type incompatibility problems.

---------------------------------------------------------------------------
6. PREDICATE SECTIONS AND L3P-PROLOG
---------------------------------------------------------------------------

A predicate section assumes the form:

PREDIC
  { <L3P-PROLOG-clause>. }
ENDPREDIC

where <L3P-PROLOG-clause> can be either a "standard" pure Prolog clause with
lists (Edinburgh syntax has been adopted)or a <special-clause>.
Here we will briefly describe only the <special-clause>s devoted to the
interfacing of PROLOG with the other two paradigms.
Communication with the functional paradigm can be accomplished with the "val"
special clause:

                            <term> val <expression>

where we mean that the proposition is true if, and only if, the value of
<expression> can be unified with <term>.

Conceptually the "val" predicate is very similar to the well known "is"
predicate, but there are some significant differences:

a) <expression> can belong to any L3P basic type (not only numeric ones);

b) in <expression>  global constants, variables, or user functions may be
used.

Access to the value bound to a logic variable which appears in the logic
clause
containing the val proposition is distinguished by the '?' prefix.
Special cases of the form TRUE val <expression> can be written more clearly
as:

                             est <expression>

They permit the direct use of proposition defined as boolean expressions.
The logic paradigm can also communicate with the imperative paradigm by means
of a

                           do(<statement-sequence>)

predicate which has the effect of executing the specified statements.
 Although not recommendable because of the side effects it might produce,
this  possibility is very useful for implementing special tracing or
monitoring techniques of the logic computations. (see, for instance, the
ANQUEENS.L3P demo).
 In the <statement-sequence> it is possible to access the values bound to the
logic variables with the '?' prefix.

---------------------------------------------------------------------------
7 TEXT, GRAPHICS, FILES AND LOW LEVEL FACILITIES
---------------------------------------------------------------------------

7.1. TEXT AND GRAPHICS
----------------------

Default screen mode is text (80x25). You can switch to graphics with one of
these commands:

GRMODE : enter one of the default graphics mode (CGA, EGA, or VGA depending
on your hardware and settings) with screen integer coordinates ranging from
0,0 (left upper corner) to MAXX(),MAXY() (right lower corner).
You can use absolute commands (such as LINE, POINT, etc. ) as well as
relative commands (i.e. commands relative to a graphic cursor (GCurs)).

TURTLEMODE: enter "turtle graphics" mode with a Cartesian system having
origin (0,0) in the screen center, real coordinates, and screen bounds
observable with:

             TURTLEMINX(), TURTLEMINY(),TURTLEMAXX(),TURTLEMAXY()

Their values depends on the graphic card and can be modified with commands:

                    SETZOOM, SETQUADRANT, SETASPECT

The two Graphics modes are mostly incompatible. They share only a few
commands and functions. For example you cannot invoke a LINE command while
being in Turtle mode.
However they share many text primitives. For example the "read" and "write"
commands as well as text coloring work also while being in a graphic mode
(but scrolling is not active).

For switching to text mode use the TEXTMODE command.

7.2 FILE HANDLING
-----------------

File handling was not a main objective in the language design process.
Nonetheless you have three ways of saving and restoring data:

1) Single item data saving/restoring (typically lists).

2) Traditional byte-block (by means of the STRING data type) oriented file
 handling. Channel numbers are used to identify open files.

3) Logic Data Base (LDB) file handling. You can save groups of dynamically
added pure Prolog clauses ("marked" clauses) on a file by means of the command
SAVELDB. You can then "consult" this file, (i.e. add them to the present
clauses) by invoking the LOADLDB command.

More details on Chapter 8 and on the full manual.

7.3 LOW-LEVEL FACILITIES
-----------------------

Low level access was not a language design objective. In fact it is a source
of subtle errors, it can damage system integrity and it conjures against
portability.
Nonetheless the SYSTEMCALL procedure and the REG function can satisfy many
pragmatic requirements (such as mouse handling). Details on the full manual.


----------------------------------------------------------------------------
8.a PREDEFINED PROCEDURES
----------------------------------------------------------------------------

In case of doubt you might find it useful to test the command in the
imperative environment.

 ADDRULE(H: UNIV;T: list)
-- Add the rule H:-P1,P2,...,Pn to the LDB (T is the list [P1,P2,...,Pn])
 ARCH(X0,Y0,Alfa0,Alfa1,Radius,AColor: INTEGER)
-- Draw the arch of circle of radius R from Alfa0 (degrees) to Alfa1
 BACK(X: REAL)
-- Turtle command
 BAR(X0,Y0,X1,Y1,AColor: INTEGER)
-- Draw a box with color AColor
 CIRCLE(X0,Y0,Radius,AColor: INTEGER)
-- Draw a circle
 CLREOLN
-- clear from Text Cursor to the end of line
 CLRSCR
-- clear screen
 DELAY(N: INTEGER)
-- delay the execution of N milliseconds
 FILECLOSE(Ch: INTEGER)
-- Close the file whose channel number is Ch
 FILESEEK(Ch,BytePos: INTEGER)
--Move the File pointer to the byte BytePos (start=0)
 FILEWRITE(Ch: INTEGER; S: STRING)
-- Write the string S from file pointer
 FILEWRITELN(Ch: INTEGER; S: STRING)
-- Write (from file pointer) the string S and then an <end-of-line>
 FILL(X,Y,FillColor,BorderColor: INTEGER)
-- Fill from point (X,Y) with FillColor until find BorderColor-ed pixels
 FORWD(X: REAL)
-- Turtle command
 GRMODE
-- Enter Graphic Mode, clear screen, set GCurs to (0,0), Color=MaxColor()
 GRMOVETO(X,Y: INTEGER)
-- Moves GCurs to pixel (X,Y)
 GRMOVETOREL(DeltaX,DeltaY: INTEGER)
-- Move GCurs to (GCusr.X+DeltaX,GCurs.Y+DeltaY)
 GRWINDOW(X0,Y0,X1,Y1: INTEGER; ClipOn: BOOLEAN)
-- Set a Graphic window  from (X0,Y0) to (X1,Y1) "clipping" if Clipon=TRUE
 HIDETURTLE
-- Turtle command
 HOME
-- Turtle command (differently from many LOGOs, North is 90 degrees)
 LEFT(X: REAL)
-- Turtle command
 LINE(X0,Y0,X1,Y1,AColor: INTEGER)
-- Draw a line  with AColor
 LINEREL(DetaX,DeltaY: INTEGER)
-- Draw a line from GCurs to (GCurs.X+DeltaX,GCurs.Y+DeltaY)
 LINETO(X,Y: INTEGER)
-- Draw a line from GCurs to (X,Y) with current Color
 LOADLDB(FileName: STRING)
-- Add the clauses contained in FileName to current PROLOG clauses.
 MOVETURTLE(X,Y: REAL)
-- Turtle Command
 MOVETURTLEREL(DeltaX,DeltaY: REAL)
-- Turtle Command (move the Turtle to (Turtle.X + DeltaX,Turtle.Y + DeltaY)
 NL
-- Move the text cursor to the beginning of the next line
 NOESC
-- Do not ask to type ESC at the end of execution
 PENDOWN
-- Turtle Command
 PENUP
-- Turtle Command
 POINT(X,Y,AColor: INTEGER)
-- Draw a point
 POINTREL(DeltaX,DeltaY: INTEGER)
-- Draw the point (GCurs.X+DeltaX, GCurs.Y+DeltaY) with current Color
 PRINTNL
-- Move the printer cursor to the beginning of the next line
 RECTANGLE(X0,Y0,X1,Y1,AColor: INTEGER)
-- Draw a rectangle
 RELEASELDB
-- Remove all the "marked" clauses from current LDB
 RIGHT(X: REAL)
-- Turtle command
 RMLDBMARKS
-- Remove the marks from all the "marked" clauses
 SAVEDATA(FileName: STRING; Datum: UNIV)
-- Save Datum on the file FileName
 SAVELDB(FileName: STRING)
-- Save the "marked" clauses on the specified file
 SETASPECT(Asp: REAL)
-- Set the aspect ratio to Asp
 SETCOLOR(AColor: INTEGER)
-- Set the Graphic (or Turtle) Color to Acolor
 SETCOPYWRMODE
-- Set the "copy" Write mode for Graphics/Turtle
 SETGRBKGR(AColor: INTEGER)
-- Set the graphic Background color
 SETHEADING(Angle: REAL)
-- Turtle Command
 SETHEADINGTOW(X,Y: REAL)
-- Turtle command: set the turtle heading towards (X,Y)
 SETQUADRANT(Q: INTEGER)
-- Turtle command: Q=0 means 4 quadrants, 1 means Positive quadrant, etc.
 SETRANDOMSEED
-- Initialize random generator with a random seed
 SETSEED(N: INTEGER)
-- Initialize random generator with seed N
 SETTEXTBKGR(AColor: INTEGER)
-- Set text background color to AColor
 SETTEXTCOLOR(AColor: INTEGER)
-- Set text color to Acolor
 SETXORWRMODE
-- Set "xor" write mode for graphics
 SETZOOM(Z: REAL)
-- Turtle Command . Set the Zoom factor to Z
 SHOWTURTLE
-- Turtle Command
 SOUND(Freq: REAL)
-- Produce a sound of frequency Freq on the PC speaker
 STOPSOUND
-- Stop the sound generation
 SYSTEMCALL(InterrNum,AH,AL,BH,BL,CH,CL,DH,DL: INTEGER)
-- Generate the software interrupt InterrNum after loading A,B,C,D registers
 TEXTGOTO(X,Y: INTEGER)
-- Move text cursor to column X, row Y
 TEXTGOTOPIXEL(X,Y: INTEGER)
-- Move text cursor to pixel (X,Y)
 TEXTMODE
-- Restore TextMode with the last mode set
 TEXTMODE(M: INTEGER)
-- Set TextMode with mode M (choose M=1 for entering 40x25  mode)
 TEXTWINDOW(X0,Y0,X1,Y: INTEGER)
-- Set a text window
 TURTLEDELAY(N: INTEGER)
-- Turtle command.  Delay turtle actions of N milliseconds
 TURTLEFILL(FillColor,BorderColor: INTEGER)
-- Fill from Turtle position with FillColor until find BorderColor-ed pixels
 TURTLEMODE
-- Set Turtle mode, clear screen and execute Home, Color=MaxColor(), etc.
 TURTLETRACETOXY(X,Y: REAL)
-- Turtle command.
 WAITKEY(Message:  STRING)
-- Display Message on the right bottom corner and wait the typing of any key.

-----------------------------------------------------------------------------
8.b  NON STANDARD OPERATORS AND PREDEFINED FUNCTIONS
-----------------------------------------------------------------------------

In case of doubt you might find it useful to test the function in the
evaluation environment.

 S{I}
-- The I-th char of S

 S{I,N}
-- The substring of S starting at I-th char of maximum length N

 L ~ I
-- The I-th element of list L

 L1 & L2
-- The list obtained appending list L1 with list L2

 [x1,x2,...,xn | L]
-- The list with first N elements  x1,x2,...,xn and with tail L

 ABS(X: NUMERIC/INTEGER/REAL) : same type of X
-- Absolute value of X
 ACTIVESCRNENV() : INTEGER
-- Return 0 if in TextMode, 1 if in GrMode and 2 if in TurtleMode
 ARCTAN(X: REAL) : REAL
-- Solution of tan(Alfa)=X, with Alfa in the range -PI/2 ... PI/2
 ARGLIST(T: COMPTERM) : LIST
-- The argument list of the compound term T
 ASPECT() : REAL
-- The current aspect ratio
 ATOM(X: UNIV) : BOOLEAN
-- TRUE if X is of type INTEGER,REAL,CHAR,BOOLEAN STRING, LOGVAR
 CHR(X: INTEGER) : CHAR
-- Conversion from ASCII-code to character
 CLIPPING() : BOOLEAN
-- True if Clipping is set
 COLOR(): INTEGER
-- Current Graphics or Turtle color
 CONVERR(): INTEGER
-- It yelds 0 if the last Conv-xxxx operation was ok.
 COS(X: REAL): REAL
-- cosine of X radiants
 DIRECTORY(Mask: STRING) : LIST
--The list of the file names which match Mask
 ENDOFINPUT(): BOOLEAN
--True if you typed <Ctrl-Z> in the last read
 EOF(Ch: INTEGER): BOOLEAN
-- True if the file pointer associated to channel Ch is beyond last byte
 EXP(X: REAL): REAL
-- 2.7182... raised to X
 FILELENGTH(Ch: INTEGER) : INTEGER
--The lenght of the file bound to channel Ch
 FILEOPEN(Filename: STRING; Mode: CHAR) : INTEGER
--Depending on Mode value different actions are taken:
  'R'(read)   If FileName exists then return its channel number else 0
  'W'(write)  Create FileName (if not yet existing) else empty it.
  'A'(append) If FileName exists then move file pointer at EOF else create it
 FILEPOS(Ch: INTEGER) : INTEGER
-- The value of File Pointer of the file bound to Ch (0=first)
 FILEREAD(Ch,N: INTEGER) : STRING
--The string composed by the first N chars of the file bound to Ch. Advance.
 FILEREADLN(Ch: INTEGER) : STRING
-- The string composed by the chars from File Pointer to end of current line
 FILEREADSTRING(Ch: INTEGER; Separators: STRING) : STRING
-- The string from File Pointer to a char belonging to Separators
 FIRSTCHAR(S: STRING) : CHAR
--The first char of string S
 FLOAT(X: INTEGER) : REAL
--Real conversion of INTEGER
 FLOOR(X: REAL) : INTEGER
 FRAC(X: REAL) : REAL
--fractional part of a REAL number
 FUNCTOR(T: COMPTERM) : STRING
--the functor name of a compound term
 GCMEM(N: INTEGER) : INTEGER
-- if N<0 then give the size of the heap free memomry.
    If N<= 0 Garbage Collect first. If N=0 then do not show 'G.C.'
 GETITEM() : UNIV
-- Read an item from keybord and return its value
 GETITEMFROM(FileName: STRING) : UNIV
-- Read the item conteined in FileName and return its value
 GETKEY() : CHAR
-- Read a key from keybord queue without echoing
 GRBKGR() : INTEGER
-- Background Color under Grmode/TurtleMode
 GRMAXX() : INTEGER
-- Maximum X pixel coordinate  under GrMode/TurtleMode
 GRMAXY() : INTEGER
-- Maximum Y pixel coordinate  under GrMode/TurtleMode
 GRMINX() : INTEGER
-- Minimum X pixel coordinate  under GrMode/TurtleMode
 GRMINY() : INTEGER
-- Minimum Y pixel coordinate  under GrMode/TurtleMode
 GRWRMODE() : INTEGER
-- Graphic write mode
 GRX() : INTEGER
-- X-coordinate of the Graphic Cursor (GCurs)
 GRY() : INTEGER
-- Y-coordinate of the Graphic Cursor (GCurs)
 HEAD(L: LIST) : UNIV
-- First element of a list
 HEADING() : REAL
-- Current Turtle orientation (in degrees)
 IOERR() : INTEGER
-- Code error of the last IO operation
 ISBOOLEAN(X: UNIV) : BOOLEAN
-- Is the dynamic type of X BOOLEAN?
 ISCHAR(X: UNIV) : BOOLEAN
-- Is the dynamic type of X CHAR?
 ISCOMPTERM(X: UNIV) : BOOLEAN
-- is the dynamic type of X COMPTERM?
 ISDIGIT(C: CHAR) : BOOLEAN
-- Is C a decimal digit ?
 ISEMPTYLIST(L: LIST) : BOOLEAN
-- Is L=[] ?
 ISINTEGER(X: UNIV) : BOOLEAN
-- Is the dynamic type of X INTEGER?
 ISLETTER(C: CHAR) : BOOLEAN
-- Is C a letter?
 ISLIST(X: UNIV) : BOOLEAN
-- Is the dynamic type of X LIST?
 ISNUMBER(X: UNIV) : BOOLEAN
-- Is the dynamic type of X INTEGER or REAL?
 ISREAL(UNIV) : BOOLEAN
-- Is the dynamic type of X REAL?
 ISSTRING(X: UNIV) : BOOLEAN
-- Is the dynamic type of X STRING?
 ISVAR(UNIV) : BOOLEAN
-- Is the dynamic type of X LOGVAR?
 KEYPRESSED() : BOOLEAN
-- Is there any character in the keyboard buffer?
 LISTLENGTH(L: LIST) : INTEGER
-- Number of elements of L
 LN(X: REAL) : REAL
-- Natural logarithm
 LOG10(X: REAL) : REAL
-- Base 10 logarithm
 LOOKUP(T: UNIV; L: LIST) : UNIV
-- Replace logic variables of T with the values contained in assoc. list L
 MAXCOLOR() : INTEGER
-- Maximum color code(correspondig to white color)
 MAXX() : INTEGER
-- Maximum X pixel coordinate
 MAXY() : INTEGER
-- Maximum Y pixel coordinate
 MKCOMPTERM(F: STRING; A: LIST) : COMPTERM
-- Build the term whose functor is F and whose arglist is A
 ORD(X: ordinal) : INTEGER
-- INTEGER code of X
 PIXELCOLOR(X,Y: INTEGER) : INTEGER
-- Color code of pixel (X,Y)
 POWER(X,Y: REAL) : REAL
-- X raised to Y
 PRED(X: ordinal) : same type of X
-- Previous value of X according to its type order
 QUADRANT() : INTEGER
-- Integer code of the selected quadrant
 RANDOM() : REAL
-- Generate a real random numbers in the range 0..1
 RANDOM(N: INTEGER) : INTEGER
-- Generate a random INTEGER number in the range 0..N-1
 REALTOSTR(X: REAL) : STRING
-- REAL to STRING conversion
 REGS(I: INTEGER) : INTEGER
-- Integer content of I-th CPU register (see full manual)
 ROUND(X: REAL) : INTEGER
-- X rounded to an INTEGER
 SEED() : INTEGER
-- Seed of the random generator
 SELCHAR(S: STRING; I: INTEGER) : CHAR
-- I-th char of S. Same as S{I}
SGN(N: NUMERIC/INTEGER/REAL) : INTEGER
--  -1,0,1 according to the sign of N.
 SIN(X: REAL) : REAL
-- Sine of X radiants.
 SOLCOUNT() : INTEGER
-- Number of solutions found in the last FOREACHSOL statement
 SOLINDEX() : INTEGER
-- Index (starting by 1) of the logic solution just found
 SOUNDFREQ() : REAL
-- Sound frequency given at the last SOUND command
 SQR(X: NUMERIC/INTEGER/REAL) : same type of X
-- Square of X
 SQRT(X: REAL): REAL
-- Square root of X.
 STRDEL(S: STRING; I,N: INTEGER) : STRING
-- The string obtained by S deleting N chars starting at I
 STRINSERT(S1,S2: STRING; I: INTEGER) : STRING
-- The string obtained by inserting S1 in S2 starting at I
 STRLENGTH(S: STRING) : INTEGER
-- Number of chars of S
 STRSEARCH(S1,S2: STRING) : INTEGER
-- Index of the first occorrence of S1 inside S2. Return 0 if none.
 STRTAIL(S: STRING) : STRING
-- S without the first CHAR
 STRTOINT(S: STRING) : INTEGER
-- STRING to INTEGER conversion
 STRTOLIST(S: STRING) : LIST
-- STRING to LIST conversion
 STRTOREAL(S: STRING) : REAL
-- STRING to REAL conversion
 STRTOUNIV(S: STRING) : UNIV
-- STRING to UNIV conversion
 STRUPCASE(S: STRING) : STRING
-- Upcase conversion of S
 SUBLIST(L:LIST; I,N:INTEGER,INTEGER) : LIST
-- The list L restricted to max N elements starting at I
 SUBSTR(S:STRING; I,N: INTEGER) : STRING
-- The substring of S starting at I of maximum length N. Same as S{I,N}
 SUCC(X: ordinal) : same type of X
-- The next value of X according to its type order
 TAIL(L: list) : list
-- L without the first element
 TAN(X: REAL) : REAL
-- Tangent of X radiants
 TEXTBKGR() : INTEGER
-- Current color code of the text background
 TEXTCOLOR() : INTEGER
-- Current color code of the text
 TEXTMAXX( ) : INTEGER
 TEXTMAXY() : INTEGER
 TEXTMINX() : INTEGER
 TEXTMINY() : INTEGER
-- Bounds of the current text window
 TEXTX() : INTEGER
-- X coordinate (column) of text cursor
 TEXTY() : INTEGER
-- Y coordinate (row) of text cursor
 TIME() : INTEGER
-- 1/100-seconds elapsed since Midnight
 TODAY() : INTEGER
-- Integer code of today's date in the form: yyyymmdd
 TRUNC(X: REAL) : INTEGER
-- Truncation of X
 TURTLEMAXX() : REAL
 TURTLEMAXY() : REAL
 TURTLEMINX() : REAL
 TURTLEMINY() : REAL
-- Current screen bounds for the Turtle
 TURTLEX() : REAL
 TURTLEY() : REAL
-- Current Turtle's position
 TYPEOF(X: UNIV) : INTEGER
-- Integer code of the dynamic type of X
 UNIFIABLE(T1,T2: UNIV; Env: LIST) : BOOLEAN
-- Try to unify T1 with T2 in the environment Env
 UNIFIER() : LIST
-- Result of the last call to UNIFIABLE
 UNIVTOSTR(X: UNIV; N: INTEGER) : STRING
-- UNIV to STRING conversion
 UPCASE(C: CHAR) : CHAR
-- Upcase conversion of C
 VARLIST(U: UNIV) : LIST
-- The list of variables contained in U
 ZOOM() : REAL
-- Current Zoom factor (must be in Turtle mode)

-----------------------------------------------------------------------------
8.c PREDEFINED PREDICATES
-----------------------------------------------------------------------------

In case of doubt you might find it useful to test the predicate in the logic
interactive environment.
The reader should be confident with PROLOG.

 <termX> = <termY>
--"unifiable" predicate

 <termX> <> <termY>
--"not unifiable" predicate

 assert(<pure-PROLOG-clause>)
 --command: append a new clause

 asserta(<pure-PROLOG-clause>)
-- command: insert a new clause on the top

 call(<term>)
-- same as usual "call" predicate

 clause(<Term>,<Lterm>)
-- similar to the usual clause/2 predicate. <Lterm> should unify with a list.

 do(<statement-sequence>)
-- (see Chapter 6)

 est (<condition>)
-- (see Chapter 6)

 fail
-- never satisfied

 listing
--command: list all clauses in alphabetical order

 listing(<name>[/<arity>])
-- command: like listing restricted to the specified predicate <name>

 mclause(<Term>,<Lterm>)
-- like clause, restricted to the marked clauses

 nl
-- "writes" a nl on the screen

 not <goal>
-- satisfied iff <goal> is not satisfied

 notrace
-- command: stop tracing

 retractall(<term>)
-- command: remove all clauses whose head matches <term>

 trace
-- command: enable logic tracing

 true
-- always satisfied

<term> val <expression>
--  (see Chapter 6)

 var(<term>)
-- satisfied iff <term> is an unbounded variable

 write(<term>)
-- command: print a string representation of <term> replacing bounded
-- variables with their values

"Missing" predicates can often be built by using the "est" and "val"
paradigm-interfacing predicates.

-----------------------------------------------------------------------------
8.d PREDEFINED  CONSTANTS
-----------------------------------------------------------------------------
Values in the current MSDOS implementation.

     MININT = -2147483648
     MAXINT =  2147483647
 MINPOSREAL =  1.175494E-38
    MINREAL = -3.402823E+38
    MAXREAL =  3.402823E+38
         PI =  3.141593

------------------END OF L3P ESSENTIAL MANUAL -------------------------------
