========================================================
(C)1993 Institute for New Generation Computer Technology
(Read COPYRIGHT for detailed information.)
========================================================

KLIC Manual
===========
July 9th, 1993
Takashi Chikayama (ICOT)

Copyright 1993 Institute for New Generation Computer Technology
(Read COPYRIGHT for detailed information)

[CAUTION: PLEASE DO NOT EXPECT THIS VERSION TO BE A COMPLETE SYSTEM]

1. KL1 Language

Here, a very informal and rough description of the KL1 language is
given.  More detailed and accurate specification are planned to be
supplied in future releases.

1.1 Basic Mechanism

Following is a sample KL1 program.

	Example 1: qsort

	:- module(qsort).

	sort(X, Y) :- sort(X, Y, []).

	sort([], Y, Z) :- Y = Z.
	sort([P|X], Y, Z) :-
		partition(P, X, X1, X2),
		sort(X1, Y, [P|Y1]),
		sort(X2, Y1, Z).

	partition(_, [], S, L) :-
		S = [],
		L = [].
	partition(P, [W|X], S, L) :- W =< P |
		S = [W|S1],
		partition(P, X, S1, L).
	partition(P, [W|X], S, L) :- W >= P |
		L = [W|L1],
		partition(P, X, S, L1).

The first line, ":- module(qsort)" declares that this program module
will be called "qsort".  The module mechanism will be discussed more
in detail below.

Execution of a KL1 program is a (possibly parallel) repetitive
reduction of given goals using program clauses.  Each "clause" has the
following form.

	predicate_name(Argument pattern ...) :- Guard | Body.

When a goal is to be reduced, clauses for the predicate of the goal
will be inspected.  For clauses with matching argument pattern, their
guard parts are tested.  All the clauses with matching argument
pattern and satisfied guard conditions are candidates to be used in
the reduction.  Only one of them, arbitrarily chosen, will be used and
the original goal will be replaced by the goals in the body of the
clause chosen.

If no guard condition tests are required, the guard part along with
the vertical bar can be omitted.

1.2 Predicates

Predicates of KL1 corresponds to functions of C or Lisp.  Unlike C or
Lisp, predicates are identified not only by there names but also with
their number of arguments.  In the above example, two predicates with
the name "sort", with 2 and 3 arguments, are defined.  To identify
predicates with the same name but different arity, we use a notation
such as "Predicate/Arity".  In the above example, two predicates
"sort/2" and "sort/3" are defined.

1.3 Module

As mentioned above, the first line of KL1 program, ":- module(qsort)"
in the above example, declares that this program module will be called
"qsort".  Module declarations should be given at the top of programs.
A module consists of the "clauses" following it, up to the next module
declaration or the end of the file.

Goals is associated with a predicate.  A predicate for a goal can be
specified merely by its name if it is defined in the same module.
Otherwise, when a predicate is in a different module, it can be
designated by the syntax "Module:Predicate".  For example, a module
named "top" that uses the module "qsort" might be defined as follows.

	Example 2: top module for qsort

	:- module(top).

	top :-
		X = [9,2,8,3,6,7,4,1,5],
		builtin:print(X),
		qsort:sort(X, Y),
		builtin:print(Y).

Here, the body goal "qsort:sort(X, Y)" is associated with the
predicate "sort/2" of the module "qsort".

2. Built-in Predicates

Some predicates are built in to the system.

There are two kinds of built-in predicates: those which can be used in
the guard part and those which can be used in the body part.

2.1 Guard Built-in Predicates

The comparison predicates, such as "W =< P" in the exmaple 1, are
typical guard built-in predicates.  The following is the list of guard
built-in predicates available with the current system.

 wait(X)
	Waits until instantiation of X
 list(X)
	Tests whether X is a list
 atom(X)
	Tests whether X is an atom
 integer(X)
	Tests whether X is an integer
 X > Y
 X >= Y
 X =:= Y
 X =< Y
 X < Y
	Performs arithemtical comparison of two integer arguments.
	Each sides of the comparison can be an arithmetical expression
	using the following operators.

		+	addition (unary and binary)
		-	subtraction (unary and binary)
		*	multiplication
		/	integer division
		mod	modulo
		\	complement (unary)

2.2 Body Built-in Predicates

The body built-in predicates are considered to be defined in the
module "builtin".  In the above example 2, "builtin:print(X)" is an
instance of a goal that is associated with such a built-in predicate
(the notation with the module name "builtin" will be changed in future
releases and the module name "builtin" will become optional).  The
following is the list of body built-in predicates available with the
current system.

 builtin:add(X, Y, Z)
 builtin:sub(X, Y, Z)
 builtin:mul(X, Y, Z)
 builtin:div(X, Y, Z)
	Unifies Z with the sum, difference, product or integer
	quotient of X and Y.
 builtin:print(X)
	Prints the value of X to stdout stream.

The following body built-in predicates are for preliminary system
testing and measurement.  They are currently available but they might
be omitted in future releases.

 builtin:readint(X)
	Reads an integer value X from stdin stream.
 builtin:start_measure.
	Starts measurement of resource usage, such as CPU time,
	number of GC, etc.  What can be measured depends on the
	operating system used.
 builtin:report_measure(X)
	Prints the result of resource usage measurement to stdout
	stream.  It also unifies X with the CPU time used since the
	start_message predicate is called.

3. Running KLIC

Read INSTALL for information on installation of the KLIC system.

3.1 Compilation

After proper installation, compilation of the KL1 programs into C and
then to executable can be effected by simply running "klic" with
an argument which is the name of the KL1 program source file without
the trailing ".kl1".  For example, to compile "XXX.kl1", type in:

	% klic XXX

The compilation result will be found in "XXX".

If you want to see the C code generated by the KLIC compiler, do:

	% klic XXX.c

This will compile "XXX.kl1" into "XXX.c".

It is also possible to separately compile several KL1 source files and
link them afterwards.  No appropriate shell commands are provided.
Please read the makefile (KLICmakefile) in the distribution to for
further details.

3.2 Running Compiled Code

You can simply run the compiled excutable.  The predicate "top" with
no arguments in the module "top" will be the initial goal to be
executed.

Following options are available on running the system.

    h = SIZE
	Specifies heap size in words.  As copying garbage collection
	is used, actually used memory size for heap will be twice this
	size.


4. Diagnostics

Currently minimal diagnostics are provided.

Undefined predicates are reported by C compiler and linker.
For example, assume that you compile the following program.

	:- module(top).
	top :- foo.

The C compiler will report errors such in a way as follows.

  test.c: In function `top_module':
  test.c:33: label `foo_0_ext_interrupt' used but not defined
  test.c:32: label `foo_0_loop' used but not defined

The undefined labels `foo_0_...' correspond to the fact that predicate
foo/0, meant to be defined in the same module, was not defined.

The message will be different when a predicate of an external module
is left undefined.  For the program:

	:- module(top).
	top :- foo:bar.

	:- module(foo).
	baz.

the linker will report that predicate bar/0 is not defined in the
module foo by reporting the following.

 ld: Undefined symbol 
    _predicate_foo__bar__0 

The same error will be reported when the module foo was not defined at
all.

5. Bugs

- Requires a Prolog system to compile KL1 programs.
  The compiler will be written in KL1 itself and its translation in C
  will become available with future releases.

- Compilation-time error report is quite poor.

- The provided set of built-in predicates is incomplete.

- Only a simple tracer is provided for debugging.

- Performance analysis tools are not provided.

- When execution completes with suspended goals, only the number of
  such goals is reported.

- Failures are reported but normal executables would not report which
  goal failed.  Use traced executables for knowing failed goals.

There sure are many more.

Please report bugs and comments to the following address:

	klic-bugs@icot.or.jp
