% Document Type: LaTeX
% Master File: manE-main.tex
\documentstyle[a4]{report}
\title{PIMOS 3.0\\ Introductory Manual}
\author{PIMOS Development Group}
\date{\today}
\begin{document}
\maketitle
\newpage
\newcommand{\outarg}{\^{}}
\baselineskip=0.5cm
\tableofcontents
%\input{manE-intro}		%1. Introduction
%\input{manE-setup}		%2. Setting up PIMOS on PSI-II
%\input{manE-boot}		%3. Boot-Strap, Log in, Shut down
%\input{manE-program}		%4. kl1 Programming
%\input{manE-parallel}		%5. Goal Distribution
%\input{manE-run}		%6. How to Run kl1 Programs
%\input{manE-trouble}		%7. Dealing with Toroubles
%\input{manE-shell}		%8. Facility of Shell
%\input{manE-lis}		%9. Facility of Listener
%\input{manE-CAL}		%10. CAL
%\input{manE-util}		%11. Facility of Other Utilities


\chapter{Preparing To Run PIMOS}
\label{chap:setup}
This chapter explains how to register a PIMOS user and set up their
environment before booting PIMOS.

\section{User Registration to SIMPOS}
Before your personal user name is registered, you can login in to the
PSI using the
following temporary login name.
The password for that account is the same as its login name.
\begin{quote}
pmpsi: A Pseudo Multi-PSI user ~or~ Multi-PSI user using remote function\\
\end{quote}
After you have logged in, you will notice the following 
item in the SYSTEM MENU.
\begin{itemize}
\item Pseudo Multi-PSI\\
Select this to boot PIMOS.
\end{itemize}

The above user name should only be used temporarily.
Before developing KL1-programs on PSI, you should create a new
username in the following way.
\begin{enumerate}
\item Register the new user name.\\

If you have already logged in to SIMPOS, log out.   Login as
``superuser'' with the password ``superuser''.
Select the following sequence of menu items on the console,
starting with ``others'' from the SYSTEM MENU.
\begin{quote}
others  $\rightarrow$ user $\rightarrow$ maintenance
$\rightarrow$ register
\end{quote}
Register the user name in the usual way by filling in the blanks
presented in the window that appears.   Pay careful attention to the
rank and initial mode, being sure to use the following values.
\begin{quote}
For Pseudo Multi-PSI machine users :\\
           rank= general, initial mode = general\\ 
For Multi-PSI machine users :\\
           rank= general, initial mode = general\\
\end{quote}
After completing registration of the new user name, login under that name.
For a more detailed guide to user maintenance, refer to the ``Basic System Administration Manual for PSI/SIMPOS Systems''\cite{SYSTEM}.
\item Set up the new user's environment.

The following example shows how to set up the environment for a new
user name, ``feldmark'', by copying the ``login.com'' file from a standard
user's directory and revising it for the new environment.

\begin{enumerate}
\item Copy the file ``login.com'' from user pmpsi to feldmark's home
directory using the File Manipulator.
\begin{verbatim}

	copy file >sys>user>pmpsi>login.com
	     to   >sys>user>feldmark>*.*

\end{verbatim}
\item Edit this new copy of login.com using the PMACS editor.
\begin{itemize}
\item Confirm the following SYSTEM MENU registration classes 
in the login.com file.

\begin{verbatim}
  menu :-
      items_list(
          .......................................
%%%  On a Pseudo Multi-PSI Machine use this:
     {"Pseudo Multi-PSI",  mpsicsp##pseudo_csp_main_program},

%%%  On a Multi-PSI Machine use this:
     {"REMOTE CSP",         mpsicsp##remote_csp},
               .......................................
%%%  To login PIMOS:
     {"PIMOS LOGIN",       mpsicsp##pimos_remote_login},
\end{verbatim}
\item Change the definition of the logical name ``me'' to your own user name.
\begin{verbatim}
  define :- 
 %%%%         "me" := ["user:pmpsi"], 
              "me" := ["user:feldmark"],
         .......................
\end{verbatim}
\item Confirm the following logical name definitions :
\begin{verbatim}

On a Pseudo Multi-PSI machine :
---
        "root"  := ["user:pmpsi"],
        "psys"  := [">sys>csp>SYSTEM.DIR"],
        "pmpsi" := [">sys>csp>PMPSI.DIR"],
        "pimos" := [">sys>csp>PIMOS.DIR"],
---
On a Multi-PSI machine :
---

        "root"  := [">sys>csp"],
        "mpsi"  := ["root:MPSI.DIR"],
        "msys"  := ["root:SYSTEM.DIR"],
        "pimos" := [">sys>csp>PIMOS.DIR"],
---

\end{verbatim}
\end{itemize}
\item When you have finished confirming the above information and
making the necessary changes, log out and log back in order to
reset the parts of your environment that you have changed.
\item Check that the item ``Pseudo Multi-PSI'' or ``REMOTE CSP'' and the
item ``PIMOS LOGIN'' appear in your SYSTEM MENU.
\end{enumerate}
\end{enumerate}

\subsection{How to set up the configurataion of PIMOS}
When PIMOS starts up, PIMOS is initiated according to the contents
of the file with the following pathname on FEP with FEP number 0.

\[\hbox {\tt pimos:pimos.conf}\]\\

If you use Multi-Psi by using remote function, you don't have to
set up the configuration of PIMOS

\section{User Environment Set-up Program}
\subsection{Initial user parameter file for login}

The initial registration of users and user groups for PIMOS is done
according to the contents of files \hbox{\tt pimos:pimos.logins} and
\hbox{\tt pimos:pimos.groups} respectively. If you use Muliti-PSI by 
remote function, you have to do following sequence on actual Multi-PSI's
FEP by using remote function of SIMPOS.

\subsubsection{Initial user file}

Contents of Initial user file is a sequence of the following term.


\[\hbox{\bf \{User, Pass, UID, MaxPrio, Dir, Node, Prog, Com\}}\]
\begin{description}
\item[User: ] String of user name.
Each user name needs to be unique.

\item[Pass: ] String of password.
Initial state of the password is null string.  You should
change your password by using shell utility command
``change\_password''.  Password is encrypted by login handling procedure.

\item[UID: ] user ID, which is not negative number.
Each user ID needs to be unique. ID 0 is reserved for a super
user.

\item[MaxPrio: ] Max Priority of a task which is Prog described below.
It must be integer number from 0 up to 4096.

\item[Dir: ] String of initial current directory. It also stands for home
directory.
Usually, It is \verb|*|, which means directory of remote site.

\item[Node: ] Node number where \verb|Prog| runs initially.
Usually, It is \verb|*|, which stands for the same node
of login handling procedure running.

\item[Prog: ] Initial program for \verb|User|. The \verb|Prog| is
described as following format:
\begin{verbatim}
    package:: module: predicate
\end{verbatim}
\begin{description}
\item[package: ] Package name atom.  Usually, this will be ``pimos''.
\item[module: ] Module name atom.
\item[predicate: ] Term of predicate.  
Variables should not appear as arguments of the predicate. 
\item[Com: ] List of strings, which is used for comments.
\end{description}

This file can be updated using the shell utility command
``change\_password''.  Such a change will be effected after you exit
from your login shell.
\end{description}

\subsection{Initial group parameter file for login}

\[\hbox{\bf\{Group, GID, UserList, Com\}}\]

\begin{description}
\item[Group: ] String of group name
Each group name needs to be unique.

\item[GID: ] Group ID, which is not negative number.
Each group ID needs to be unique. Group ID 0 is reserved for
super group.

\item[UserList: ] List of group member name string.
\item[Com: ] List of string, which is used for comments.

\end{description}

\subsection{Contents of Initial parameter files}
\subsubsection{Initial user parameter file}
\bgroup\small
\begin{verbatim}
    {"me",         "",103,2000,*,0,pimos:: shell: login,[" "]}.
    {"pmpsi",      "",102,3000,*,0,pimos:: shell: login,[" "]}.
    {"pimos",      "",101,4095,*,0,pimos:: shell: login,[" "]}.
    {"shutdown",   "", 10,4095,*,0,pimos:: shutdown: go,[" "]}.
    {"super_pimos","",  0,4095,*,0,pimos:: shell: login,[" "]}.
\end{verbatim}
\egroup

\subsubsection{Initial group parameter file}
\bgroup\small
\begin{verbatim}
    {"super_pimos",0,["super_pimos","shutdown"],[" "]}.
    {"user",       1,["pimos","pmpsi","me"],[""]}.
\end{verbatim}
\egroup

\vspace{1 cm}
\chapter{Booting Up, Logging Into, and Shutting Down PIMOS}
\label{chap:boot}

This chapter explains how to boot up, login to, and shut down your (Pseudo)
Multi-PSI machine, along with what to do if booting fails.

\section{Booting CSP on (Pseudo) Multi-PSI}
\subsection{Pseudo Multi-PSI}

On a Pseudo Multi-PSI machine, select the item ``Pseudo Multi-PSI'' in
the system menu that appears after logging in and clicking the mouse's
left-button.

\setlength{\unitlength}{1.1mm}
\begin{picture}(120,65)(-60,-30)
\small
\put(-60,22){\framebox(120,7)[l]{~~SYSTEM MENU}}
\put(-60,-22){\framebox(120,44){}}
\put(-17.5,14){\framebox(35,6){Pseudo Multi-PSI}}
\put(0,7.5){\makebox(0,0){Login PIMOS}}
\put(0,.5){\makebox(0,0){(Pseudo)Multi-PSI Installer}}
\end{picture}

After the ``Multi-PSI CSP'' program starts up, you will see the ``Monitor
Panel'' in the upper-left corner of your console and the ``CSP Command
Window'' on the right-hand side of the panel.

The first time this sequence is performed each time after booting
SIMPOS, it may take a long time since many CSP programs must be
loaded.

The following messages appear in the ``CSP Command Window''.
\begin{verbatim}
  Initiating all PEs from configuration file MPSI.CONFIG
  Current PEs are
      0, 1, 2, 3, 4, 5, 6, 7
  Current Default PEs are
      0, 1, 2, 3, 4, 5, 6, 7
  PE auto power on... All PEs power ready.
  PEs initiation completed

  $
\end{verbatim}
The \$ that appears is the CSP prompt symbol.


\subsection{Multi-PSI by using remote function}
This sections explains how to boot a Multi-PSI machine in ICOT using 
remote function.
Details on how to boot with other configurations 
can be found in Chapters 4 and 6 of the
``Multi-PSI/V2 Console System (CSP) Operating Manual''\cite{CSP}.

\begin{enumerate}
\item Select the item ``REMOTE CSP'' from the SYSTEM MENU. 

\setlength{\unitlength}{1.1mm}
\begin{picture}(120,65)(-60,-30)
\small
\put(-60,22){\framebox(120,7)[l]{~~SYSTEM MENU}}
\put(-60,-22){\framebox(120,44){}}
\put(-17.5,14){\framebox(35,6){REMOTE-CSP}}
\put(0,7.5){\makebox(0,0){PIMOS LOGIN}}
\put(0,.5){\makebox(0,0){(Pseudo)Multi-PSI Installer}}
\end{picture}
\item The following window appearing on the PSI machine that
you can select which Multi-PSI you want to start up. And you
input the password which protect the right of control.

\begin{picture}(100,55)(-50,-25)
\small
\put(-50,20){\framebox(100,7)[l]{~~Remote CSP}}
\put(-50,-22){\framebox(100,42){}}
\put(-20,10){\makebox(0,0){Multi-PSI or Pseudo Multi-PSI?}}
\put(40,10){\makebox(0,0){Multi-PSI}}
\put(60,10){\makebox(0,0){Pseudo}}
\put(-20,0){\makebox(0,0){Multi-PSI's FEP Node =}}
\put(20,0){\makebox(0,0){icpsi383}}
\put(-20,-8){\makebox(0,0){Password (Max 30char)=}}
\put(-20,-16){\makebox(0,0){do\_it}}
\put(10,-16){\makebox(0,0){abort}}
\end{picture}

\item Confirm that CSP has started up on Multi-PSI.

\item If you have the right of control, two windows appear.
Upperside one is black, which is minitor window of actual Multi-PSI,
and lowerside one is white, which is command window.
If you cannot get the right of control, only black window appears.

\item The following messages will appear in the ``CSP black Window''.
\begin{verbatim}			
Initiating all PEs from configuration file MPSI.CONFIG
Current PEs are
    0, 1, 2, 3, 4, 5, 6, 7....
Current Default PEs are
    0, 1, 2, 3, 4, 5, 6, 7....
PE auto power on... All pes power ready.  Memory Configuration...
PEs initiation completed
...
\end{verbatim}

\end{enumerate}

All CSP commands can be displayed by typing ``?'' to this promptin
the white window,  and
each command is also described in detail in the
``Multi-PSI/V2 Console System (CSP) Operating Manual''\cite{CSP}.


\section{Setting the Auto-Boot Switch}
If you use Multi-PSI by remote function, you don't have to read
this and next section.
Booting PIMOS can be done automatically by setting the auto-boot
switch in the CSP Command Window.
From the CSP Command Window, type the following command.
\begin{quote}
       \$ ~~\underline{\tt panel}
\end{quote}
When you do this, the ``CSP Console Panel'' should appear.
The CSP Control Panel is made up of several sub-menus, which you
should set as shown below.
\begin{enumerate}
\item Auto-Boot switch definitions:
\begin{tabbing}
        CLEAR \=********** \=ON***  \=OFF \kill
        CLEAR \> \> \fbox{ON}  \> OFF \\
        INIT  \> \> \fbox{ON}  \> OFF \\
        IMPL  \> \> \fbox{ON}  \> OFF \\
        Patch \> \> \fbox{ON}  \> OFF \\
        - - - - - - - - - - - - - - - - - -\\
        IPL \>   \>  \fbox{ON} \> OFF \\
        START \\
        \> \fbox{PIMOS} \> ON \> OFF
\end{tabbing}

\item Boot file name definitions:
\begin{itemize}
\item Pseudo Multi-PSI:
\begin{tabbing}
        SYMBOL \= FILE (.sym)   \= kl1:mypimos \kill
        CLEAR \> FILE (.mbn)   \> \fbox{(Don't care on Pseudo)} \\
        INIT  \> FILE (.mbn)   \> \fbox{(Don't care on Pseudo)} \\
        INIT  \> FILE (.mbn)   \> \fbox{(Don't care on Pseudo)} \\
        IMPL  \> FILE (.mbn)   \> \fbox{(Don't care on Pseudo)} \\
        IMPL  \> FILE (.kbn)   \> \fbox{pmpsi:kl1kp.kbn} \\ 
        PATCH \> FILE (.com)   \> \fbox{pmpsi:kl1pat.com} \\
        IPL   \> FILE (.kbn)     \> \fbox{pimos:pimos.kbn} \\
        SYMBOL \> FILE (.sym)  \>  \fbox{pimos:pimos.sym} \\
        START \> ADDRESS  \>  \fbox{202}
\end{tabbing}
\end{itemize}

\item Select the ``AUTO'' setting by clicking on it once with the left mouse
button.
\begin{quote}
        Power On Auto Boot  ~~~~ \fbox{AUTO}   CONSOLE
\end{quote}      
\item Next, select ``SAVE'' to save the settings you have choosen.
\begin{quote}
       \fbox{SAVE}    EXIT
\end{quote}
\item Finally, exit by selecting the ``EXIT'' box.
\begin{quote}
       SAVE   \fbox{EXIT}
\end{quote}
\end{enumerate}

\section{Booting PIMOS from CSP}
To bootstrap PIMOS from CSP, type the ``boot'' command into the ``CSP
Command Window''.   If you are using a real Multi-PSI machine, 
all nodes will automatically turn on.
\begin{quote}
     \$~~\underline{\tt boot}
\end{quote}

\section{Logging In}
\begin{enumerate}
\item
After booting of PIMOS is completed, messages as follows will appear
on the CSP black window.
\begin{verbatim}
    DC> TCPIP LOGIN STARTED **********
    DC> (INTo) 00 00000000
\end{verbatim}
\item
By clicking the menu item ``PIMOS LOGIN'' in the system menu, a window
labeled ``Pimos remote login'' will appear.
\item
That window prompts you to type in your user identification
information.  Type as follows, for example, if you are registered as
``ICOT'' with password ``FGCS'', you want to use Multi-PSI which is
connected with icpsi383 (which is also PSI-II machine) as FEP. 

\begin{verbatim}
    Enter FEP node name---------> icpsi383(Multi-PSI)  local(pseudo Multi-PSI)
    Enter your PIMOS user name--> ICOT
    Enter your PIMOS password---> FGCS
\end{verbatim}
Each input line should be followed by a carriage return.

The password actually is not echoed.  If you have not registered your
password yet, you can just hit carriage return. 
\item
When you successfully logged in, the initial program for you.
Usually this is the PIMOS shell.
\end{enumerate}

\section{Shutting Down}
To shutdown PIMOS, execute ``shutdown'' command in the shell.
\begin{quote}
{\tt Shell>>} \underline{\tt shutdown}
\end{quote}
Answer ``yes'' when asked if you really want to shut down.  (Or no if
you have made a mistake and didn't really intend to shut down PIMOS.)
\begin{quote}
Really(yes/no)? \underline{\tt yes}
\end{quote}
You have now shut down (Pseudo) Multi-PSI.   On Multi-PSI, the power
to all nodes will automatically be turned off.

For more details about the shutdown process,
refer to the ``PIMOS 2.5 Manual''\cite{PIMOS}.
For more information about CSP and Multi-PSI's power supply,
refer to the ``Multi-PSI/V2 Console System (CSP) Operating Manual''\cite{CSP}.

\section{Returning to CSP from PIMOS}
If for some reason you want to interrupt PIMOS and return to CSP,
you can do so in either of the following ways:

\begin{enumerate}
\item Select the CSP white Window (by clicking the left mouse button)
and type a control-C to the CSP prompt.

\end{enumerate}
To return to PIMOS, use the ``go'' command in response to the CSP white
window prompt.
\begin{quote}
{\tt \$}\underline{\tt go}
\end{quote}

\section{If Booting Fails}
In Pseudo Multi-PSI, PIMOS may fail to boot displaying a message of
the form ``Copying GC Memory Shortage'' in the CSP Command Window.
You should change the configuration of your pseudo machine to have
fewer pseudo nodes and more memory for exch nodes.  Refer to the last
section of Chapter \ref{chap:setup} for how to do this.  Then enter
the command ``exit'' in the CSP Command Window and reboot.

\chapter{Programming in KL1}
\label{chap:program}
The parallel logic programming language KL1
has many features that can be used to efficiently describe 
parallel algorithms and systems.
It is based on the parallel logic programming language, GHC, developed
at the Institute for New Generation Computer Technology (ICOT) as part of the
Japanese Fifth Generation Computer Project.

This chapter explains how to develop KL1 programs on a
(Pseudo) Multi-PSI machine, assuming that you know how to write simple
programs in Prolog.

\section{Features of KL1}
The following section outlines the main features of KL1.

\subsection{Selection and Execution of Clauses}
Each KL1 clause is divided into two parts by
an operator, $\mid$, called the ``commit operator''. 
The goals on the left-hand side
of this commit operator form the ``guard'' part, while
those on the right of the commit operator form the ``body'' of the
clause.
Any type of goal may be used in the body part of a clause,
but only built-in predicates, described later in this section,
may be used in the guard part.
The first goal of a clause is called the ``head''
predicate, in the example below, ``a''.
\begin{verbatim}
        a(X) :- integer(X) | b1(X,Y), b2(Y).       %(0-1)
        a(X) :- X=3     | c1(X,Y), c2(Y,Z), c3(Z). %(0-2)
        a(X) :- list(X) | d1(X,Y), d2(Y), d3(Y).   %(0-3)
\end{verbatim}

All clauses with the same head are in an OR-relationship.
That is, the predicate succeeds if the first clause is true, OR the
second clause is true, OR etc.
The guard part plays an important role in selecting one clause to be
executed from all those in this OR-relationship.
Suppose the goal ``?- a(3)'' is called from another clause.
Each of the above definitions, (0-1), (0-2), and (0-3) can be
tested in parallel, but only the two guards in
(0-1) and (0-2) (integer(3), 3=3) will succeed.
The KL1 system selects and executes one clause at random
from those whose guard part succeeds, and discards the rest.
All goals from the body of this clause are then activated in a random
order.   In this case, either the body part from clause (0-1)
or from clause (0-2) will be activated.

Suppose that the clause (0-2) was selected.
The goals c1, c2, and c3 will be called in an order irrelevant to their
order in clause (0-2).  In fact, they may all be executed in
parallel on different nodes.
How to force goals to be executed parallel is
explained in the next chapter.

\subsection{Failure of Goals}
The commit operator, $\mid$, in KL1 programs works like the cut operator,
{\tt !}, in Prolog.   The failure of a goal in a guard part on
the left-hand side of the commit operator can be thought of as causing
the guard part of another (randomly selected) clause to be tried.
But if a body goal on the right hand side of a commit operator fails,
it means that the parent goal also fails.
The failure of the parent goal causes a failure of the grand-parent
goal.
This continues until all the goals in the KL1 program have failed.

\subsection{Kl1 Data Types}
The following data types are available in KL1.
\begin{itemize}
\item Variable ( {\tt Var,\_,} etc. )
\item Integer ( {\tt 138, 16'8A,} etc. ) 
\item Floating point  ( {\tt 1.23, 1.0E10,} etc. )
\item Atom  ( {\tt a, 'ABC',} etc. )
\item List ({\tt [1,2,3], [a,[A,b],c|Y]}, etc. )
\item Vector ( {\tt \{a,b,c\}, \{\}, a(b),} etc. )
\item String ( {\tt "abc", "",} etc. )
\item Module ( {\tt module\#foo,} etc. )
\end{itemize}

Refer to Section 2.1.3 of the ``PIMOS 2.5 Manual'' \cite{PIMOS} for
more details on these data types.

\subsection{Built-in Predicates}
There are three types of built-in predicates in KL1.
The first type can only be used in the guard part,
the second can only be used in the body, and the third can be
used in both the guard part and the body.
All PIMOS built-in predicates are listed in Section 2.2 of
the ``PIMOS 2.5  Manual''\cite{PIMOS}.

\section{A Sample KL1 Program}
Next is an actual KL1 program, which
should be entered into a file named ``sample1.kl1''.
Note that any file containing a KL1 program must
have the ``.kl1'' extension at the end of its name.

\begin{verbatim}

        :- module sample1.                       %(1-1)
        :- public sieve/3.                       %(1-2)

        sieve([],Even,Odd):- true |              %(1-3)
                Even=[],
                Odd=[].
        sieve([N|List],Even,Odd):-               %(1-4)
                N mod 2 =:= 0 |
                Even=[N|Tail],
                sieve(List,Tail,Odd).
        sieve([N|List],Even,Odd):-               %(1-5)
                N mod 2 =\= 0 |
                Odd=[N|Tail],
                sieve(List,Even,Tail).           %(1-6)

\end{verbatim}
Here you can see the use of the 
``=:='' operator, which performs a comparison of the two values on
either side of it.
For an explanation of these kinds of operators in KL1, refer to
Section  2.1.6 of the ``PIMOS 2.5 Manual''\cite{PIMOS}. 

Line (1-1) declares the module name of this program to be ``sample1''.
Line (1-2) declares that the predicate named ``sieve'' may be called
from external modules and that it has 3 arguments.
Both of these two declarations must be placed at the top of any file
that contains a KL1 program.

We can call any goal in a module from any other module or from
the Listener prompt (see Chapter \ref{chap:Listener}) by using
the following format.
\begin{verbatim}
                module_name:goal_name
\end{verbatim}

To call the goal ``sieve'' from the Listener type :
\begin{verbatim}
        ?- sample1:sieve([2,5,6,8,0,9],Even,Odd).
\end{verbatim}
This goal will be matched with the clauses (1-4) and (1-5), but only
the guard part of (1-4) will succeed.
The body part of (1-4) will then be
activated, resulting in the unification :
\begin{quote}
 {\tt Even = [2|Tail]}
\end{quote}
and the recursive call of the goal :
\begin{quote}
 {\tt sieve([5,6,8,0,9],Tail,Odd)}.
\end{quote}
As in the above example, all instantiation of output
variables (such as {\tt Even=[N|Tail]}) must be done in the body part
of each clause. This restriction comes from the synchronization
mechanism of KL1 processes, and will be explained in the next section.

The goal {\tt sieve([5,6,8,0,9],Tail,Odd)} called recursively will be
successfully matched with clause (1-5), and the goals of its body
part :
\begin{quote}
{\tt Odd=[5|Tail], and
sieve([6,8,0,9],Odd,Tail)}
\end{quote}
will be executed.
Finally, the result of this program will be the instantiations
{\tt Odd=[5,9], Even=[2,6,8,0]}.
\vspace{3mm}

Clause (1-5) in the above program could be replaced with the following one:
\begin{verbatim}
        otherwise.
        sieve([N|List],Odd,Even):-              %(1-5')
                true |
                Odd=[N|Tail],
                sieve(List,Tail,Even).
\end{verbatim}
The {\tt otherwise} statement is a simple expression indicating
negation. If inserted among clauses that are placed in
OR-relationships, the KL1 system selects the clauses under the
{\tt otherwise} statement only when all clauses above it fail.
So, by using the {\tt otherwise} statement, it is not necessary
to describe the negative conditions of the guard parts of
all the other clauses.
\vspace{3mm}

Here is another example of how to use the {\tt otherwise.} statement.

\begin{verbatim}
        :- module sample2.
        :- public check/2.

        check([], Out):- true | Out = []
        check([M|In], Out):- atom(M) |
                Out = [atom|Out1], check(In, Out1).
        check([M|In], Out):- integer(M) |
                Out = [integer|Out1], check(In, Out1).
        check([M|In], Out):- string(M,_,_) |
                Out = [string|Out1], check(In, Out1).
        check([M|In], Out):- list(M) |
                Out = [list|Out1], check(In, Out1).
        check([M|In], Out):- vector(M,_) |
                Out = [vector|Out1], check(In, Out1).
        otherwise.
        check([_|In], Out):- true |                     %(2-1)
                check(In, Out).

\end{verbatim}
Clause (2-1) is a definition for ignoring exceptional input data.
The program executes as follows.
\begin{verbatim}
        ?- sample2:check([1,a,"ds",23.5,{a,b}],X).
        X = [integer, atom, string, vector]
        yes.
        ?-
\end{verbatim}
The goals defined under the {\tt otherwise}
statement were responsible for ignoring the data 23.5 in the input list.

\section{Stream Communication and Process Synchronization}

Consider the following example :
\begin{verbatim}

        :- module sample3.
        :- public go/3, generate/2.

        go(Max,Even,Odd):- true |
                generate(Max,Numbers),                  %(3-1)
                sample1:sieve(Numbers,Even,Odd).        %(3-2)

        generate(0,Numbers):- true |
                Numbers=[].
        otherwise.
        generate(N,Numbers):- true |
                Numbers=[N|NewNumbers],
                N1 := N-1,
                generate(N1,NewNumbers).

\end{verbatim}
When we call the goal ``go'' with an appropriate number as the first
argument, it activates the two subgoals ``generate'' and
``sample1:sieve.''
The goal ``generate'' generates a list of integers in the variable
``Numbers.'' The goal ``sieve'' defined in the module ``sample1'' divides the
list ``Numbers'' into two lists ``Even'' and ``Odd.''
Both predicates ``generate'' and ``sieve'' continue to run by calling
themselves recursively. We call predicates that do this ``processes''.

Now assume that the two process are running in parallel on different
nodes.   These processes share the
variable ``Numbers'' which is instantiated by the process ``generate'' and
is read by the process ``sieve''.
We call this kind of communication between processes by shared
variables ``stream communication.''

When the process ``sieve'' runs faster than the process ``generate,''
``sieve'' waits for data in the shared variable ``Numbers'' to be
instantiated by ``generate.''
This synchronization is performed automatically by the KL1 system.

In the above program, consider the process ``sieve'' called
with no data in the first argument :
\begin{verbatim}
        sieve(List,Even,Tail)                          %(1-6)
\end{verbatim}
This goal could be matched with clauses (1-3), (1-4), or (1-5) by one
of the following unifications :
\begin{verbatim}
        List = [] or List = [N|List']
\end{verbatim}
Unifications that try to instantiate a variable in the calling goal
are suspended until the variable becomes instantiated by another
process (in this case ``generate''.)
This mechanism controls the process ``sieve'' and prevents it from
running faster than the process ``generate.''
It provides us with a natural facility for describing process synchronization.

\section{Merging Streams}
To merge the output from the streams of two or more subprocesses
into one stream, we can use a ``merge'' process that is
easily defined by a KL1 program, but available as a built-in
predicate in KL1 since it is used so frequently.

The ``merge'' predicate takes an arbitrary number of streams as input and
merges them into one output stream. If data is sent on any input
stream, the process will immediately forward the data on the output stream.
Unlike the ``append'' program in Prolog, the sequence of
data on output stream of a ``merge'' process is unrelated to the order
of data on the input streams.   The builtin predicate, ``merge,'' is called in
the following way.
\begin{verbatim}
        merge(In,Out)
\end{verbatim}
The first argument must be instantiated to a vector of
input streams such as:
\begin{verbatim}
        In = { In1,In2, ... }
\end{verbatim}
The second argument is a single output stream.

The following example shows how to use the merge predicate.
\begin{verbatim}
        :- module sample4.
        :- public flatten/2.
        flatten([],Out):- true |                %(4-1)
                Out=[].
        flatten([Top|Tail],Out):- true |        %(4-2)
                flatten(Top,X1),
                flatten(Tail,X2),
                merge({X1,X2},Out).
        flatten(A,Out):- atom(A),A\=[] |        %(4-3)
                Out=[A].
\end{verbatim}
This program receives a list, possibly containing other lists,
as the first argument.
In the second argument, it returns a list of all atoms that
were anywhere in the input list.
This invocation,
\begin{verbatim}
        ?- sample3:flatten([a,[b,c],[d,[e,f]]],X).
\end{verbatim}
returns the following list :
\begin{verbatim}
        X = [ c,a,f,e,d,b ]
\end{verbatim}
Note that the order of the atoms {\tt a,b,c,\ldots} cannot be determined by
looking at the program because the order of execution of the
two goals ``flatten'' in clause (4-2) cannot be determined. 

The goal {\tt merge(\{X1,X2\},Out)} will immediately send
data received from
the input streams ``X1'' and ``X2'' into the output stream ``Out''.
When the goal ``flatten'' has consumed all data in
the first argument, the clause (4-1) will put {\tt []} in the
stream ``Out.''   This instantiation unifies the ``Cdr'' part of the
list  with {\tt []}, and the stream is ``closed.''
Thus, merge will close its output stream
when all of its input streams are closed.

Execution of the goal ``flatten'' in the program ``sample3'' will
generate many instances of merge.
But generating too many instances of merge will degrade
the efficiency of your KL1 programs.
We can modify the original ``flatten'' example and come up with
the following program that avoids this problem.
\begin{verbatim}
        :- module sample5.
        :- public flatten/2.
        flatten(In,Out):- true |
                flatten1(In,X),
                merge(X,Out).
        flatten1([],Out):- true |
                Out=[].
        flatten1([Top|Tail],Out):- true |
                flatten1(Top,X1),
                flatten1(Tail,X2),
                Out = {X1,X2}.
        flatten1(A,Out):- atom(A),A\=[] |
                Out=[A].
\end{verbatim}

\section{I/O Interface}
This section shows how to use the window interface utilities
and how to do file I/O within KL1 programs.
Details can be found in Chapters 4, 5, 6 and section 10.3 of the
``PIMOS 2.5 Manual''\cite{PIMOS}.

\subsection{Standard I/O Devices}
Any KL1 program can access a window of the Shell or the Listener by using
the Standard I/O device represented by the streams Standard-Input,
Standard-Output,
Standard-Input/Output(Listener dose not support this function),
Message-Output, and Standard-Interaction.

In order to perform I/O, messages are sent to these streams
requesting operations such as ``getc(C)'' to read a character,
``putc(C)'' to output a character, etc.
A complete list of these messages can be found in Section
4.1 of the ``PIMOS 2.5 Manual''\cite{PIMOS}.

The following module shows how to access the streams Standard-Input,
Standard-Output, and Message-Output.

\begin{verbatim}

        :- module std_io.
        :- public create/3.

        create(Input,Output,Message):- true|
            shoen:raise(pimos_tag#shell,get_std_in,Input),
            shoen:raise(pimos_tag#shell,get_std_out,Output),
            shoen:raise(pimos_tag#shell,get_std_mes,Message).

\end{verbatim}
This module can be called as :
\begin{verbatim}
        ?- std_io:create(Input,Output,Message),
           Input=[ ... ], Output=[ ... ], Message=[ ... ].
\end{verbatim}
Which results in the following streams :
\begin{itemize}

\item Input : A Standard-Input device stream\\
Accepts any message provided by a {\tt buffer:input\_filter}.
\item Output : A Standard-Output device stream\\
Accepts any messages provided by a {\tt buffer:output\_filter}.
\item Message : A Message-Output device stream\\
Accepts any messages provided by a {\tt buffer:output\_filter}. 
\end{itemize}

An explanation of the buffer and the filter utilities can also be found in
Chapter 4 of the ``PIMOS 2.5 Manual''\cite{PIMOS}.

\subsection{Window I/O}
The following module creates a window for input and output.
\begin{verbatim}

        :- module window.
        :- public create/1.

        create(Window):- true|
            shoen:raise(pimos_tag#task,
                general_request,General_Request_Device),
            General_Request_Device=
                [window(normal(Window_Request_Device,_,_))],
            Window_Request_Device=
                [create(normal(Window_Device,_,_))],
            Window_Device=[
        %        set_size(mouse,_),
                set_size(char(50,25),_),
                set_position(mouse,_),
        %        set_position(at(0,0),_),
                set_title("Interactive Window",_),
                activate(_)| Stream ],
            buffer:interaction_filter(Window,Stream).      %(5-1)

\end{verbatim}
This module can be called as :
\begin{verbatim}
        ?- window:create(Window),
           Window=[ putl("Hit return to exit."), getl(_) ].
\end{verbatim}
You will now see the frame of a window on your display. 
Click the mouse-button to confirm its position.
If you hit the return key, the window will disappear immediately.

The variable ``Window'' becomes a stream to which we can send messages
prepared by an I/O-filter to manipulate the window that just appeared.
See Section 4.1.4 in the ``PIMOS 2.5 Manual''\cite{PIMOS} for further
details.

\subsection{Files I/O}
%%% added by feldman
File I/O is performed in a similar manner to window I/O.
A stream representing the file is created, and messages requesting
file operations like ``putc(C)'' and ``getc(C)'' are sent to initiate I/O.
The following module allows input and output to be done on a file.

\begin{verbatim}

        :- module file.
        :- public open/4.

        open(FileName,Mode,File,Status):- true|
            shoen:raise(pimos_tag#task,
                general_request,General_Request_Device),
            General_Request_Device=
                [file(normal(File_Request_Device,_,_))],
            File_Request_Device=
                [open(FileName,Access)],
            ( Mode=r ->                                   %(6-1)
                Access=read(Result),
                ( Result=normal(Stream,_,_) ->
                    buffer:input_filter(File,Stream),     %(6-2)
                    Status=success
                ; otherwise
                ; true -> Status=Result )
            ; Mode=w ->
                Access=write(Result),
                ( Result=normal(Stream,_,_) ->
                    buffer:output_filter(File,Stream),     %(6-3)
                    Status=success
                ; otherwise
                ; true -> Status=Result )
            ; Mode=a ->
                Access=append(Result),
                ( Result=normal(Stream,_,_) ->
                    buffer:output_filter(File,Stream),     %(6-4)
                    Status=success
                ; otherwise
                ; true -> Status=Result ) ).

\end{verbatim}
Here, the expression in (6-1) is a ``Macro symbol'' for conditional
selection of execution. 
``Macro symbols'' are explained in Section 2.1.6 of
the ``PIMOS 2.5 Manual''\cite{PIMOS}.

The arguments in the above goal, {\tt open(FileName, Mode, File, Status)}
 have the following meanings.
\begin{itemize}
\item FileName : The name of the file to open, specified as string data.\\
{\tt "sample.kl1", ">sys>user>feldmark>sample.kl1", etc.}
\item Mode : The mode for opening the file. (r, w, a)\\
r $\rightarrow$ read, w $\rightarrow$ write, a $\rightarrow$ append
\item File : A stream to the file opened.
\item Status : Other information concerning the opening of this file.
(success, failure, etc.)
\end{itemize}

This predicate returns a stream to the file which accpets
any message provided by the following filter utilities :

\begin{itemize}
\item Mode = r\\
Messages from {\tt buffer:input\_filter }
\item Mode = w,a \\
Messages from {\tt buffer:output\_filter }
\end{itemize}

\subsection{A Sample Program Using the I/O Interface}
Below is a sample program that uses the PIMOS I/O interface.
Before compiling this program, compile the three modules above,
``std\_io'', ``window'', and ``file''.
This program prints out the contents of the
named files in a new window, and
is  executed as follows.
\begin{quote}
 {\tt ?- sample6:demo. }
\end{quote}
Input the name of any file when the program asks you to.
Next, confirm the position of the window by
clicking the mouse button when the window frame appears.
The contents of the file are then displayed in the window.

\begin{verbatim}

        :- module sample6.
        :- public demo/0.

        demo:- true|
            std_io:create(In,Out,Mes),
            In=[prompt("File name ? "),getl(FName)],
            Out=[putt('Opening file : '),putl(FName)],
            Mes=[putt(Status),nl],
            type_file(FName,Status).

        type_file(FName,St):- string(FName,_,_)|
            file:open(FName,r,File,St),
            ( St=success ->
                window:create(Win),
                File=[getl(Line)|RF],
                type(Line,RF,Win)
            ; otherwise
            ; true -> true ).

        type(-1,File,Win):- true|
            File=[],
            Win=[prompt("*** Hit Return key to exit.***"),
                    getl(_)].
        otherwise.
        type(L,File,Win):- true|
            Win=[putl(L),flush(_)|W],
            File=[getl(N)|F],
            type(N,F,W).

\end{verbatim}

\section{Deadlock}
As mentioned in the section ``Stream Communications and Process
Synchronizations'', instantiation of undefined variables in
a guard part will be suspended by the KL1 system.
If the variable is not
instantiated by any other processes, the suspended execution will
never resume.
We call this situation ``Deadlock''.

There are many situations where deadlock can occur.
For example, if we modify clause (4-1) in the module sample4 like this:

\begin{verbatim}
                flatten([],[]):- true|true.               %(4-1')
\end{verbatim}
The goal {\tt ?- flatten([],X1) } which activates this clause will
be suspended because of an attempt to instantiate the variable X1 with {\tt
[]}.
This will cause a deadlock to occur because X1 is never
instantiated by another process.

Or when we rewrite the same clause as :
\begin{verbatim}
                flatten([],Out):- true|true.              %(4-1")
\end{verbatim}
a deadlock will occur because the variable ``Out'' that is read from a
merge will never be instantiated to anything.

Chapter \ref{chap:run} shows how to detect deadlock
in a KL1 program.



\chapter{Load Distribution}
\label{chap:parallel}
This chapter shows briefly how to do load
distribution in KL1. 
In the current version of PIMOS,
a node number must be explicity assigned to a goal
in order to make it execute on a different node.

\section{Implementing Load Distribution}

Any KL1 body goal may be assigned to a specific node
by attaching an experssion containing the Node number in the
following manner, where Node is an integer greater than or equal to zero.
\begin{verbatim}
                goal@node(Node)
\end{verbatim}
The following sample program illustrates this concept.
\begin{verbatim}

        :- module sample7.
        :- public foo/0.

        foo:- true |
                a@node(0),
                a@node(1),
                a@node(2).
        a :- true | true.
\end{verbatim}
Node numbers may also be variables.
Execution of the corresponding goal is suspended until the variable is
instantiated to a number.
\begin{verbatim}
        :- module sample8.
        :- public foo/3.

        foo(P1,P2, P3):- true |
                a@node(P1),
                a@node(P2),
                a@node(P3).
        a :- true | true.
\end{verbatim}

\section{An Example of Load Distribution}
The following is a more complex example of load distribution.
\begin{verbatim}

        :- module sample9.
        :- public distribute/1.

        distribute(N):- true |
                current_node(_,Nodes),                      %(1)
                fork(N, Nodes, 0)@priority(*,4096).         %(2)

        fork(0,Nodes, Node):- true | true.
        otherwise.
        fork(N, Nodes, Node):- true |
                NodeNo := Node mod Nodes,
                job_ext@node(NodeNo),                       %(3)
                NextNode := Node+1,
                N1 := N-1,
                fork(N1, Nodes, NextNode).

        job_ext :- true | job@priority(*,2000).             %(4)
        job :- true | true.

\end{verbatim}
In line (1), ``current\_node'' is a built-in predicate that
returns the total number of nodes of the machine.
In line (2), the goal {\tt fork} that distributes the goal {\tt
job\_ext} to other nodes is called with the highest priority.
(An explaination of priority can be found in Section 2.1.4 of the 
``PIMOS 2.5 Manual''\cite{PIMOS}.)
In line (3), the goal {\tt job\_ext} represents an actual job that
is distributed to the node numbered {\tt NodeNo}.
Finally, in line (4), the goal {\tt job} is called with lower priority
than that of the goal {\tt fork}.
\vspace{3mm}

If this program is executed in the following way,
\begin{verbatim}
        ?- sample9:distribute(8).
\end{verbatim}
the {\tt job} will be executed 8 times. If only 4 nodes are
available, the goals will be distributed to nodes
number 0 through 3, in the order {\tt 0,1,2,3,0,1,2,3 }.

\section{Efficient Load Distribution}
In order to do load distribution in your programs efficiently, you
should keep in mind the following fact.
Since each node in the Multi-PSI machine has its own private memory,
communication between two nodes is necessary
whenever a goal on one node reads data from
a goal on another node.
If you distribute goals that need to
communicate large amounts of data,
the resulting communications overhead may degrade the
parallel performance of your program. 

The following suggestions may help.
\begin{itemize}
\item Never distribute goals that only have a small amount of work to do.
\item If one goal must read data from another goal, it is desireable
for them to be on the same node.
%\item It is desirable that many goals runs on the node that has
%the data to be read by the goals.
\item Databases that must be accessed by many goals should probably be
distributed to each node.
\item Make any data that will be read by goals on other nodes
as compact as possible.\\
%(The same applies to data that is returned by goals.)
\item Give high priority to any goal that will distribute other goals.
Give low priority to goals that will themselves be distributed.
\end{itemize}

For more details about load distribution,
see Section 11.5 of ``KL1 Programming''\cite{KL1}.


\chapter{Running KL1 Programs}
\label{chap:run}
This chapter explains the operations necessary to compile, execute,
and debug KL1 programs along with how to evaluate their performance.

\section{Compiling KL1 Programs}
You can compile KL1 programs contained in files with a
``{\tt .kl1}'' suffix using the PIMOS Native-Compiler.

\section{How to Use the PIMOS Native-Compiler}
\subsection{Starting It Up}
You can find out what the current directory is by typing the {\tt pwd}
command in the Shell Window.
\begin{verbatim}

        Shell> pwd
         The value of the task:directory is "sys>user>feldmark".
        Shell>

\end{verbatim}
To change current directory type :
\begin{quote}
 {\tt Shell>} \underline{\tt  cd "Directory Name"}
\end{quote}
Next, start up the Native-Compiler with the {\tt compile} command.
\begin{quote}
 {\tt Shell> } \underline{\tt  compile}
\end{quote}
The following prompt appears in the window.
\begin{verbatim}

        ** KL1 Compiler **
        COMPILE>

\end{verbatim}

Type the name(s) of your KL1 program(s), omitting the {\tt .kl1}
extension.
Two or more names can be input on the same line separated by comma or
space(s).
For example, you can compile the programs in the files
``sample1.kl1'',``sample2.kl1'', and ``sample3.kl1'' with the
following command.
\begin{quote}
 {\tt COMPILE>} \underline{\tt sample1, sample2, sample3}    
\end{quote}
To compile files in the other directories, type their
names along with their path-names, in string data form, like :
\begin {quote}
{\tt ">sys>user>your-name>directory-name>file-name"}
\end{quote}
If you need to change
the current directory, you can also use {\tt !pwd} and {\tt !cd}
commands in the compiler.

On a Pseudo Multi-PSI machine, compiling too many files at the same
time may cause a memory shortage error.
If this happens, divide the files into two or more groups
that can be compiled at the same time, observing the following rules.

\begin{itemize}
\item Group together files (modules) that call each other.  
\item Compile lower groups before compiling upper groups. In other
words, first compile groups that do not call other groups.
Next, compile groups that call other groups that have already been compiled.
\end{itemize}

For example :
\begin{verbatim}

        Compile File : **psi***::>sys>**>sample1.kl1.1

        Compile Module : sample1
        sieve/3
        Compile Succeeded : sample1

        Compile File : **psi***::>sys>***>sample2.kl1.1

        Compile Module : sample2
        check/2
        Compile Succeeded : sample2

        Compile File : **psi***::>sys>***>sample3.kl1.1

        Compile Module : sample3
        go/3
        generate/2
        Compile Succeeded : sample3

        "nak::sample1" Loaded
        "nak::sample2" Loaded
        "nak::sample3" Loaded

        Compilation(s) Succeeded
        COMPILE> 

\end{verbatim}

To exit from the compiler and return to the shell prompt, type :
\begin{quote}
{\tt COMPILE>}\underline{\tt  !exit}
\end{quote}

\subsection{Batch Compilation}
You can also compile your programs directly from the Shell Prompt.
\begin{quote}
{\tt Shell>} \underline{\tt compile(["sample1","sample2","sample3"])}
\end{quote}
This command is useful in a ``Command File''. (See Chapter \ref{chap:Shell})

\section{Executing Programs}
KL1 programs can be executed with either of the following two utilities.
\begin{itemize}
\item The Listener (see Chapter \ref{chap:Listener})
\item Shell (see Chapter \ref{chap:Shell})
\end{itemize}
Listener utilities are very useful for debugging your programs.
\subsection{Starting up the Listener}
Type the {\tt listener} command at the Shell Prompt,
and set the position and size of the window that appears
after clicking the mouse button.

\subsection{Executing a Goal}
A Listener plays a role similar to that of a Prolog interpreter.
We can call any goal in any KL1 program by typing its name in the
following form to a Listener prompt.  Note that it must be followed by
a period.
\begin{quote}
{\tt [event-number] module-name:goal. }
\end{quote}
For example:
\begin{verbatim}

        [1] sample1:sieve([1,2,3],E,O).
         E = [2]
         O = [1,3]

\end{verbatim}
Values instantiated to any variables can be stored in something called
a ``Variable Pool'' (see Chapter \ref{chap:Listener}) that corresponds
to and is created at the same time as each individual Listener.

This mode can be selected by the {\tt remember} command as follows.
\begin{verbatim}

        [2] remember.

\end{verbatim}
To get out of this mode, use {\tt forget} command as follows.
\begin{verbatim}

        [6] forget.

\end{verbatim}

If the above example is executed in the ``remembering'' mode, the
variables {\tt E} and {\tt O} retain the values that were set above.
To show this fact, try the following unification.
\begin{verbatim}

        [4] X = [E,O].
        ^E = [2]
        ^O = [1,3]
        ^X = [[2],[1,3]]

\end{verbatim}
The character ``\outarg'' placed in front of the variable name shows
it is stored in the Variable Pool.

If you call another goal with a variable currently in the Variable
Pool by mistake, the goal may fail.
This is an easy mistake to make.
For example, the following goal called with the variables {\tt E} and
{\tt O} from the Variable Pool will certainly fail.
\begin{verbatim}
        [5] sample1:sieve([5,2,3],E,O).
         Unification failure>> 5
                        With > 1
                        Node > 0
\end{verbatim}
It fails because the program tried to unify the variable {\tt O} that
had already been bound to {\tt [1,3]} with {\tt [5|Tail]}.
You can free all bindings kept in the Variable Pool by typing a period
at the Listener prompt.
\begin{quote}
{\tt [6] .}
\end{quote}

\section{Debugging Your Programs}
Two tools, the Tracer and the Inspector are available to help debug
your KL1 programs.

\subsection{The Tracer}
Unlike Prolog, KL1 goals are not executed in a sequential order.
At any particular moment, it is not possible to determine which goal
will be executed next.
But by using the Listener's  Tracer tool,
it is possible to select specific goals to be traced,
even while many goals are executing in parallel,
thus allowing you to debug without worrying about the order of execution.

\vspace{3mm}

To use the Tracer, enter the following command.
\begin{verbatim}
      [7] trace.

      {Trace}
      [8]
\end{verbatim}
This puts you into trace mode where a variety of information regarding
the execution of a goal can be displayed.
For example, execution of the predicate ``{\tt go}'' in the module
``{\tt sample3}'' can be traced like this:
\begin{verbatim}

      {Trace}
      [8] sample3:go(3,E,O).
      @0@4096   1   sample3:go(3,E,O)                 (a)
         2     * (1)  generate(3,C)                   (b)
         3     * (2)  sample1: sieve(C,E,O)?          (c)

\end{verbatim}
In line (a), there are three numbers: {\tt @0@4096 1}. The first
number ``{\tt 0}'' is the number of the node on which the goal is
executed. 
The second number ``{\tt 4096}'' is the priority given to the goal. 
The last number ``{\tt 1}'' is a goal number to identify the goal in
this trace.

On lines (b) and (c), we see subgoals that are called from
the goal ``{\tt go}''.
The numbers, ``{\tt 2}'' and ``{\tt 3}'', at the front are goal
numbers.
The mark, ``{\tt *}'',
indicates that trace-mode is active for the goal.
The parenthesized numbers, ``{\tt (1)}'' and ``{\tt (2)}'', are used
in some trace commands to indicate the subgoal to which the trace
command is applied. (A detailed explanation of all the information 
displayed by the Tracer may be found in Section 13.7 of
the ``PIMOS 2.5 Manual''\cite{PIMOS}.)

In the above example, both subgoals {\tt (1)} and {\tt (2)} are now in
trace-mode.
We can reverse the mode of any subgoals that do not need to be traced
by typing the {\tt t} command followed by their number, as in:
\begin{quote}
{\tt t N1,N2,...}
\end{quote}
For example, typing the following command at the prompt in the line (c),
\begin{verbatim}

         3     * (2)  sample1: sieve(C,E,O)? t 1      (c)
      @0@4096   1   sample3:go(3,E,O)
         2       (1)  generate(3,C)                   (d)
         3     * (2)  sample1: sieve(C,E,O)?          (e)

\end{verbatim}
removes the ``{\tt *}'' from subgoal {\tt (1)} in line (d).
This means that subgoal {\tt (1)} is now in notrace-mode.
Typing the same command again will return the goal to trace-mode.
To continue to trace, hit the  ``return'' key at the prompt in
line (e).
\begin{verbatim}

      @0@4096   3   sample1: sieve([3,2,1],E,O)
                        O=[3|D]
         4     * (1)  sieve([2,1],E,D)?

\end{verbatim}
We can finish tracing a sequence of goals by typing the {\tt n}
command.  This command ignores the mark ``{\tt *}'', and all subgoals
are executed in notrace-mode. 
\begin{verbatim}

         4     * (1)  sieve([2,1],E,D)? n
       E = [2]
       O = [1,3]

      {Trace}
      [9]

\end{verbatim}
In this case, all execution has finished, but in other
cases, some goals in trace-mode may remain to be executed,
and the tracer will show what goal is to be executed next.

Display of trace information can be stopped with the {\tt ntr}
command, and a help menu can be displayed with the {\tt h} command.
For more information on the trace commands, see Section 13.7.4 of the
``PIMOS 2.5 Manual''\cite{PIMOS}.

The Tracer has two facilities for spying on goals and tracing specific
types of goals selected by the user.
\begin{itemize}
\item Reduction Spy\\
Report the reduction of selected goals.
\item Fork Spy\\
Report the reduction of a parent goal with a selected goal as a
child.
\end{itemize}
To select spy mode for a goal, type :
\begin{quote}
{\tt [10]}~ 
\underline{\tt spy(module-name,predicate-name,number-of-arguments).}
\end{quote}
Next, to select which spy mode to use, type one of the following :
\begin{quote}
{\tt [11]}~ \underline{\tt  spy\_reduction.} ( or just {\tt sr.})\\
{\tt [11]}~ \underline{\tt  spy\_fork.} ( or just {\tt sf.})
\end{quote}
The next example illustrates tracing using the spy facilities.
\begin{verbatim}

       [10] spy(sample1,sieve,3).
        Spypoint set on sample1:sieve/3
 
       [11] sr.

       {SpyReduction} 
       [12] sample3:go(3,E,O).
       <1> sample3: go/3 -->
       @0@4096     + sample1:sieve([3,2,1],E,O)
                         O=[3|C]
          2   + * (1)  sieve([2,1],E,C)?

\end{verbatim}
Trace commands are also available in spy mode.

We can continue until the execution of the next spied goal with the
following command.
\begin{itemize}
\item {\tt sr} command : Trace until the next goal with Reduction Spy mode.
\item {\tt sf} command : Trace until the next goal with Fork Spy mode.
\end{itemize}
To reset a goal's spy mode, type :
\begin{quote}
{\tt [13]}~ 
\underline{\tt nospy(module-name,predicate-name,number-of-arguments).}
\end{quote}
To reset the spy mode of all goals, type :
\begin{quote}
{\tt [13]}~ \underline{\tt  nospy.}
\end{quote}

The {\tt nospy} command resets the spy mode of a goal(s), but does
not actually take you out of spy mode.
To exit trace and spy mode completely, i.e. to return to the Listener
top level, use the {\tt notrace} command.
\begin{quote}
{\tt [14]}~ \underline{\tt  notrace.} (or just {\tt ntr.})
\end{quote}

\subsection{The Inspector}
The Inspector is a tool for displaying any piece of KL1 data
or registering it in the Variable Pool.
The Inspector can be called from the top level of the Listener
or from the prompt of the Tracer.
A more detailed explanation of
the Inspector appears in Chapter 14 of the
``PIMOS 2.5 Manual''\cite{PIMOS}.

\begin{itemize}
\item Invoking the Inspector from the Listener.\\
You can see the data bound to any variable in the Variable Pool. 
To display variables kept in the pool, simply type :
\begin{quote}
{\tt [15]}~~\underline{\tt value.}
\end{quote}
Next, if you want to see the data bound to the variable ``{\tt X}'' in
detail, invoke the Inspector by typing :
\begin{quote}
{\tt [16]}~~\underline{\tt  inspect(X).}
\end{quote}
If ``{\tt X}'' is bound to {\tt \{1,2,3,a(b)\}}, then the following
will appear.
\begin{quote}
{\tt \{1,2,3,a(b)\}>}
\end{quote}
The Inspector can be applied to any command.
For example, in order to show the fourth element of this data item,
we can use the {\tt me} command.  (Note that data elements are
numbered starting at zero.)
\begin{quote}
{\tt \{1,2,3,a(b)\}> me 3}\\
{\tt 3 : a(b) }
\end{quote}

\item Invoking the Inspector from the Tracer.\\
To invoke the Inspector from the Tracer, type:
\begin{quote}
  {\tt ins} goal\_number
\end{quote}
although the goal number may be omitted.
For example:
\begin{verbatim}

      {Trace}
      [17] sample3:go(3,E,O).
      @0@4096   1   sample3:go(3,E,O)
         2     * (1)  generate(3,C)
         3     * (2)  sample1: sieve(C,E,O)? ins 1
      generate(3,C)>

\end{verbatim}
\end{itemize}
The commands that can be used from the Inspector are
displayed by typing the {\tt help}
command on the Inspector prompt.
To exit the Inspector, type the {\tt exit} command.

\section{Dealing with Program Informations}
After debugging a program, you must re-compile any modules you
modified.
Unmodified modules do not need to be recompiled.
If modules that have not been recompiled call modules that have been
recompiled, you must call the Re-Linker to link these
modules again.
The Re-Linker can be executed in the Shell as shown here.
\begin{quote}
{\tt Shell>}\underline{\tt  relinker([sample1, sample2,...])}\\
\end{quote}
The elements of the argument list are names (as atoms)
of modules.

The information for executing a KL1 program generated by
compiling it is normally lost when you shutdown PIMOS.
In order to not have to recompile every program you use
every time you reboot PIMOS, you can save this information into a file
using the Unloader utility.
The Unloader can also be executed in a Shell as follows.
\begin{quote}
{\tt Shell>}\underline
{\tt unload([sample1,sample2,\ldots],"sample.sav.")}
\end{quote}
This will save the information needed to execute the modules
sample1, sample2, \ldots \ in the file ``sample.sav''.
The name of the file must be string type data.
The next time you boot PIMOS, you can load the information
into PIMOS using the Loader, which can also be executed in the Shell.
For example :
\begin{quote}
{\tt Shell>}\underline{\tt  load("sample.sav")}
\end{quote}
Now you can call any of the modules sample1, sample2, \ldots \ from
the Shell or from the Listener. 

\section{Dealing with Deadlock}
When a running program does not show any response,
deadlock may have occurred between goals.
You can check for deadlock in your program by trying either of
the following.

\begin{itemize}
\item In case of the Pseudo-Multi-PSI system,
check if the color of the Monitor Panel is black when 
``Silent Mode'' in the CSP Console Panel is OFF.
(See Section 7.2 of the
``Multi-PSI/V2 Console System (CSP) Operating Manual''\cite{CSP}.)
\item Suspend the execution of your program several times by typing
{\tt Control-C}. Use the {\tt r} command to check whether or not the
number of reductions are increasing. 
(See Chapter \ref{chap:Listener}.)
\end{itemize}

\subsection{Invoking the Garbage Collector}
Deadlock can be detected by the Garbage Collector.
The Garbage Collector is automatically invoked when
available memory space becomes short, but
if you suspect that your program is deadlocked, you can invoke it
yourself by either of the the following two methods.
\begin{itemize}
\item Type {\tt Control-C} in the Listener, and use the {\tt g}
command. 
\begin{verbatim}

      [18] sample3:go(_,E,O).
       ?? Interruption (2422 msec): g
        *** Deadlock is detected during GC.
        Goal> sample3: generate(C,D)
        Node> 0

\end{verbatim}
\item Use the {\tt gc} command in Shell.
\end{itemize}

You can call the Garbage Collector from anywhere.
If deadlock is detected, it will be reported in the window which the
program was started from.

\subsection{The Variable Checker}
To prevent deadlock, you had better use ``The Variable Checker''.
The variable checker is a static analyzer, which examines the number
of apperances of each variable in one clause.  

For example, in the following case user mistook the spell of
variables ``{\tt Numbers}'' and ``{\tt Number}''.
If the goal ``{\tt sample3:go(3,Even,Odd)}'' is executed, the goal
``{\tt sample1:sieve(Number,Even,Odd)}'' will be fallen into deadlock.
Because the variable ``{\tt Number}'' is never instatiated.
This is a easy mistake to make. 
If you use the variable checker, you can find out the singleton
variables in a clause easily. 
To invoke the variable checker, type {\tt varchk} command at the Shell
or at the Listener.
\begin{verbatim}

      [19] varchk.
      *** KL1 Variable Checker ***
      VARCHK[o,l] sample3

      *********************************************
      go(Max,Even,Odd) :- 
          true |
              generate(Max,Numbers),
              sample1: sieve(Number,Even,Odd).

      ONE::: Numbers Number
      DONE.

      VARCHK[o,l] !exit

\end{verbatim}
The variable checker reports the singleton variables ``{\tt Numbers}''
and ``{\tt Number}''. 
You will be able to avoid the deadlock caused by a careless mistake.
To exit the variable checker, type {\tt !exit} command.

%\section{Dealing with Running away}

\section{Evaluating Program Performance}
The following facilities can be used to evaluate the performance of
your programs.
\begin{itemize}
\item Reporting resource consumption (the number
of reductions) and total execution time of a goal called from
the Listener.\\

To get this information, give the following command
to the Listener before executing a goal.
\begin{quote}
{\tt [20]} \underline{\tt statistics.} (or just {\tt st.})
\end{quote}
For example:
\begin{verbatim}

      [21] sample3:go(3,E,O).
       E = [2]
       O = [1,3]
       12 reductions
       61 msec

\end{verbatim}
To reset this display mode, type {\tt nostatistics} or just {\tt nst.}
\item Performance-Meter (Only on Multi-PSI. )\\
The Performance-Meter is a tool for showing the average work load of
each node on a Multi PSI machine.
To invoke it, type the following command in the Shell window.
\begin{quote}
 {\tt Shell>} \underline{\tt pmeter \&}
\end{quote}
An explanation of the Performance-Meter
can be seen in Appendix B of the ``PIMOS 2.5 Manual''\cite{PIMOS}.
\end{itemize}


\chapter{The Shell}
\label{chap:Shell}
This chapter illustrates the essential functions of the Shell.

\section{Setting Up an Initialization File}
As explained in Chapter \ref{chap:setup}, the Shell wakes up with its
default directory set to the user's home directory specified in the
``User Environment File.''
In this directory, you can create a file ``{\tt shell.com}''
with commands to do things like set environment variables or executes programs.
The commands in this file are executed automatically when the shell
starts up.

Following is a small sample ``{\tt shell.com}'' file.
\begin{verbatim}
        set hl = 20
        set rscinc = infinite
        set prompt = "% "
        listener(mouse,char(50,20),"font:test_11") &
\end{verbatim}

\section{Basic Shell Commands}
The following examples show how to use some of the most common shell
commands.
\begin{itemize}
\item Terminate the Shell\\
{\tt Shell> exit}
\item Change the current directory\\
{\tt Shell> cd ">sys>csp>SYSTEM.DIR"}
\item Execute a command file (which may contain any Shell command(s))\\
{\tt Shell> take  "test.com"}
\item Display a list of Shell commands\\
{\tt Shell> help}
\end{itemize}

\section{The History Function}
The history function is available after
setting the length of the history stack.
\begin{quote}
{\tt Shell> set hl=20}
\end{quote}
You should put this command in your ``{\tt shell.com}'' file.\\
You can see contents of the history stack by typing:
\begin{quote}
{\tt Shell> history}
\end{quote}
If you want to use one of the commands that is displayed in
the history stack, type its number at the prompt.
Typing ``{\tt 0}'' executes the last command you entered.
The following executes the third command on the history stack.
\begin{quote}
{\tt Shell> 3}
\end{quote}

\section{Executing Tasks}
You can enter any Shell command or call any goal of a KL1 program from the
Shell prompt.   But you cannot use any variables when you call
a KL1 goal from Shell, so you cannot call goals
that return values through variables.

\subsection{Task Job Control and I/O}
\begin{itemize}
\item A task can be executed either in the foreground or in the background of
the Shell.
\item Every task has a ``Standard Input,'' ``Standard Output,'' and
``Standard Message Output,'' all of which are set by default
to the Shell's window.
You can redirect any of them to or from another file if necessary.
\item You can combine two or more tasks by means of pipes $\mid$.
Tasks connected by pipes are called a ``job.''
\end{itemize}

\subsection{Examples of Tasks}
\begin{itemize}
\item Executing a Listener in the foreground\\
{\tt Shell> listener}
\item Executing a Listener in the  background\\
{\tt Shell> listener \&}
\item Executing multiple tasks\\
{\tt Shell> listener \& listener \& compiler}
\item Executing a user's KL1 program\\
{\tt Shell> sample6:demo}
\item Executing a task with Standard Input redirected from a file\\
{\tt Shell> cat <= file("me:sample1.kl1")}\\
This task displays the contents of a file. (The {\tt cat} command
recognizes a blank line as end of input.)
\item Executing a task with Standard Output redirected to a file\\
{\tt Shell> cat => file(\outarg "file.new")}\\
Keyboard input is written to the file. (Hitting the
{\tt return} key will terminate this command.)\\
The character {\tt \outarg } placed in front of the file name is a
command to set the output mode to ``write mode''. If you omit the
character, the default mode is ``append mode.''
\item Executing a task with Standard Input redirected from a window
and Standard Output redirected to a file\\
{\tt Shell> cat <= window("window name") => file(\outarg "file.new")}
\item Executing a task with Standard Message Output redirected to
file\\ 
{\tt Shell> compile(["sample1","sample2","sample3"]) ->
file(\outarg "compile.log")}\\
This task does a batch compile. (See Section 9.1.4 of the
``PIMOS 2.5 Manual''\cite{PIMOS}.)
\item Combining two tasks with a pipe\\
{\tt Shell> grep(":-") <= file("sample1.kl1") | lc}\\
This job will count the number of lines in the file that contains the
string ":-".
\end{itemize}

\section{Job Control}
The following commands are available for controlling jobs in the Shell.
\begin{itemize}
\item The {\tt Control-C} command moves a job running in
foreground to the background.
\begin{verbatim}
        Shell> compile
        COMPILE> ^C
        Shell>
\end{verbatim}
\item The {\tt status} command displays information on all jobs.
\begin{verbatim}
        Shell> status
               1 --> running compile
\end{verbatim}
\item The {\tt stop JobNo} command stops the job numbered {\tt
JobNo}.\\ 
{\tt Shell> stop 1}
\item The {\tt fore JobNo} command brings the job numbered {\tt JobNo}
into the foreground and resumes it if it was stopped.\\
{\tt Shell> fore 1}
\item The {\tt back JobNo} command puts the job numbered {\tt JobNo}
into background and resumes it if it was stopped.\\
{\tt Shell> back 1}
\item The {\tt kill JobNo} command terminates the job numbered {\tt
JobNo}.\\ 
{\tt Shell> kill 1}
\item The {\tt kill all} command terminates all jobs.\\
\end{itemize}

\section{Programs as Shell Utilities}
You can turn any KL1 program into a Shell utility
by giving it a module name to be used as a Shell command name,
and giving it a single public predicate named ``{\tt go}''.
(See Section 11.3 in the  ``PIMOS 2.5 Manual''\cite{PIMOS}. )
The ``{\tt echo}'' utility can be implemented by the following KL1
program.
\begin{verbatim}
        :- with_macro pimos.
        :- module echo.
        :- public go/1.

        go(Arg):- true|
                shoen:raise(pimos_tag#shell,get_std_out,Out),
        Out = [putt(Arg),nl,flush(_)].
\end{verbatim}
This program can be used just like any other Shell utility,
in the following manner.
\begin{verbatim}
        Shell> echo([a,b,c])
        [a,b,c]
        Shell> echo("a b c")
        "a b c"
\end{verbatim}





\chapter{The Listener}
\label{chap:Listener}
Chapter \ref{chap:run} introduced Listener functions
to aid debugging, for detecting deadlocks, and to manipulate the
Variable Pool.
This chapter describes several more
functions of the Listener.

\section{Basic Listener Commands}
The following are examples of how to use some of the most common
Listener commands.
\begin{itemize}
\item Terminating the Listener
\begin{quote}
{\tt [73] exit.}
\end{quote}
\item Change the current directory\\
{\tt [10] cd ">sys>csp>SYSTEM.DIR".}
\item Execute a command file (which may contain any Listener
command(s))\\ 
{\tt [7] take "test.com"}
\item Calling a Public Predicate
\begin{quote}
{\tt [1] module-name : goal.}
\end{quote}
\item Calling a Local Predicate\\
We can call local predicates that are not declared as public
predicates in the following way :
\begin{quote}
{\tt [2] module-name ! goal.}
\end{quote}
For example :
\begin{quote}
{\tt [2] sample9!fork(100,32,0).}
\end{quote}
\item Calling Built-in Predicates\\
We can also call built-in predicates which are available in the
body part of clauses.
For example :
\begin{quote}
{\tt [3] current\_node(Node,Total), new\_vector(Vector,Total).}
\end{quote}
\item Re-executing last event\\
Type ``{\tt !!.}'', the last event is printed.
Then you modify it and hit the ``{\tt return}'' key, the Listener
execute it. 
The following example, the Listener executes the third event you
entered. 
\begin{quote}
{\tt [4] !!.}\\
{\tt [4] current\_node(Node,Total), new\_vector(Vector,Total).}
\end{quote}
\item Re-executing designated event\\
Type ``{\tt !}'' and ``{\tt event-number}'', the designated event is
printed.
Then you modify it and hit the ``{\tt return}'' key, the Listener
execute it.
The event-number is displayed in the Listener prompt
The following example, the Listener executes the third event you
entered.
\begin{quote}
{\tt [5] !3.}\\
{\tt [5] current\_node(Node,Total), new\_vector(Vector,Total).}
\end{quote}
\item Using the Help Menu
\begin{quote}
{\tt [6] help.}\\
{\tt [6] help all.}\\
{\tt [6] help basic.}\\
etc.
\end{quote}
\item Viewing statistics\\
The {\tt statistics} command (or just {\tt st}) turns ON the mode
that displays the amount of resources consumed (number of reductions)
and the elapsed execution time of a goal called from the Listener.
(The inverse command is {\tt nostatistics} or just {\tt nst})
\item Setting the Default Module Name
\begin{quote}
{\tt [7] default\_module module-name.}
\end{quote}
This allows you to omit the module name when calling predicates from
this module.

For example :
\begin{quote}
{\tt [7] default\_module sample9.}
\end{quote}
Calling a public predicate :
\begin{quote}
{\tt [8] distribute(10).}
\end{quote}
This format is equivalent to executing the goal ``{\tt
sample9:distribute(10)}''.
Calling a local predicate :
\begin{quote}
{\tt [9] !fork(10,8,0).}
\end{quote}
\item Other Commands\\
Explanations of other commands are given in Section 13.6 of the 
``PIMOS 2.5 Manual''\cite{PIMOS}.
\end{itemize}

\section{Suspending Execution}
All programs called from the Listener can be suspended by hitting the
attention key, {\tt Control-C}.
While the execution of a program is suspended,
the following commands are available
for displaying information about that program.
\begin{itemize}
\item {\tt $<cr>$ } : Resume execution
\item {\tt g } : Call the Garbage Collector and resume execution.
\item {\tt r } : Display the amount of resources consumed (number of reductions.)
\item {\tt s } : Display the the execution state of the program (task.)
\item {\tt @ } : Display the state of the program (task) resources.
\item {\tt t } : Display the names of goals for which execution is being traced.
\item {\tt k } : Display the names of goals whose execution is suspended.
\item {\tt a } : Abort execution.
\item {\tt b } : Break (interrupt) execution. (To return the break
level, type {\tt exit})
\item {\tt h } : Display the help menu.
\end{itemize}

\section{Changing Standard I/O Devices}
The default device for Standard I/O is the Listener window.
You can change it to a file or new window in the following manner.\\
\ \\
Set Standard Output to the file {\tt demo.out}
\begin{quote}
{\tt [10] sample7:demo => file(\outarg "demo.out").}
\end{quote}
Set Standard Input to a new window
\begin{quote}
{\tt [11] sample7:demo <= window("any name").}
\end{quote}
Set Standard Message Output to the file {\tt demo.mes}
\begin{quote}
{\tt [12] sample7:demo -> file(\outarg "demo.mes").}
\end{quote}


\chapter{Other Utilities}
\label{chap:util}
This chapter explains how to use two other PIMOS utilities,
Pools and the Timer device.
%There are some other utilities on PIMOS that have not been explained. In
%this chapter, we will explain how to use the functions of Pool utility
%and Timer devices.
\section{Pools}
A Pool is a database for storing and retrieving KL1 data.
It is controlled just like an I/O device, by first
creating a stream representing the Pool, and then
sending messages to that stream.

There are two types of Pools, those that use keys to index data, and
those that do not.   The following types of Pools are available in PIMOS.
\begin{itemize}
\item Pools without a key : {\tt bag, stack, queue, sorted\_bag}
\item Pools with a key : {\tt keyed\_bag, keyed\_set, keyed\_sorted\_bag,
keyed\_sorted\_set}
\end{itemize}
The control messages available to each type are
described in Section 3.3 of
the ``PIMOS 2.5 Manual''\cite{PIMOS}.

The following example illustrates the basic functions of the frequently used 
bag, keyd\_bag, and keyed\_set types of Pools.
More details may be found in
Section 3.3 of the ``PIMOS 2.5 Manual''\cite{PIMOS}.
\begin{itemize}
\item Bag : This is the most basic kind of pool, and can only
store and retrieve data.  A bag is created by :
\begin{quote}
{\tt pool:bag(S)}
\end{quote}
Data is stored and retrieved from this bag by sending messages to the
stream variable {\tt S} as in : 
\begin{verbatim}
        [1] pool:bag(S),
            S=[empty(A), put("str"), put(atom), put({vect}),
               get(B), get_all(C), get_if_any(D)].
         A = yes
         B = {vect}
         C = [atom,"str"]
         D = {}
         S = [empty(yes),put("str"), ... ]
\end{verbatim}
This examples first asks whether the Pool is empty or not and gets the answer
{\tt yes} in the variable {\tt A}.
Next, it stores three data pieces of data {\tt "str"} (a string), {\tt atom}
(an atom), and {\tt \{vect\}} (a vector) into the Pool.
Next, the message {\tt get(B)} is sent in order to extract one piece of data.
The item {\tt \{vect\}} is returned in the variable {\tt B}.
The next message {\tt get\_all(C)} retrieves all data still in the Pool.
The last message {\tt get\_if\_any(D)} can be sent at any time,
even if the Pool is empty.
This message retrieves data in the same way as messages like 
{\tt get},
but if the pool is empty, it returns \verb|{}| whereas
{\tt get} and other goals will simply fail.

\item Keyed Bag : This is a pool that indexes data via a key, using a hash
table to store the datas.
\begin{quote}
{\tt pool:keyed\_bag(S)}
\end{quote}
For example :
\begin{verbatim}
       [2] pool:keyed_bag(S),
          S=[empty(A), put("atom",atom), put(str,"str1"),
             put(str,"str2"), put({vect},v(1)),
             empty(str,B), get(str,C), get_if_any("atom",D),
             get_and_put({vect},E,v(100)), get_all(F) ]
        A = yes
        B = no
        C = "str2"
        D = {atom}
        E = v(1)
        F = [{{vect},v(100)},str("str1")]
        S = [empty(yes),put("atom",atom), ... ]
\end{verbatim}
Again the first message asks whether the Pool is empty or not and gets
the answer {\tt yes}.
But this time, the first three pieces of data are each associated and
stored with a key.
The string {\tt "atom"} is the key for {\tt atom}, {\tt str} is the key for
both {\tt "str1"} and {\tt "str2"}, and \verb|{vect}| is the key for
{\tt v(1)}.
Next the Pool is queried again as to whether or not it is empty, with
respect to items with the key {\tt str}, to
which the answer is {\tt no}.
Next, data with the key {\tt "atom"} is retrieved via the {\tt get\_if\_any}
message without asking whether or not the Pool is empty.
The {\tt get\_and\_put} message
retrieves a piece of data with the key \verb|{vect}|
replacing it with {\tt v(100)} and returning it and the key to the Pool.
The last message {\tt get\_all } retrieves all data remaining in the
Pool.
\item Keyed Set : A Pool that can store only one piece of data with each key.
\begin{quote}
{\tt pool:keyed\_set(S)}
\end{quote}
For example :
\begin{verbatim}
       [3] pool:keyed_set(S),
          S=[put(key,"str",A), put(key,atom,B), get(key,C)].
        A = {}
        B = {"str"}
        C = atom
        S = [put(key,"str", ...),put(key,atom, ...), ... ]
\end{verbatim}
In a {\tt keyed\_set}, the message {\tt put} stores an item
with a key and returns the old data that used to be associated with
the key onto the optional third argument.
In this case, the first message {\tt put}
returns {\tt \{\}} to the variable {\tt A} because there was no data
with the key {\tt key}. The second message returns the old data
{\tt "str"} in the variable {\tt  B}.
\end{itemize}

\subsection{Using Pools}
The following program puts each line of a text file into a ``Keyed
Bag'' and allows the user to retrieve any line accoring to its line number.
Before compiling this program, you must have finished compiling
the module {\tt file} from Chapter \ref{chap:program}.
\begin{verbatim}
        :- module sample10.
        :- public go/1.
        :- with_macro pimos.

        go(Name):- true|
                file:open(Name,r,[getl(L)|F],success),
                std_inter(IO)@priority($,-100),
                IO=[putt('Number of Lines = '),putt(NL),nl,
                    prompt("> "),gett(T)|IO1],
                pool:keyed_bag(Pool),
                read_file(L,F,P1,1,NL),
                display(T,IO1,P2),
                merge({P1,P2},Pool).

        std_inter(IO):- true|
                shoen:raise(pimos_tag#shell,get_std_inter,IO).

        read_file(-1,F,P,N,NL):- true|
                F=[],P=[],NL:=N-1.
        otherwise.
        read_file(L,F,P,N,NL):- true|
                P=[put(N,L)|P1],
                F=[getl(L1)|F1],
                N1 := N+1,
                read_file(L1,F1,P1,N1,NL).

        display(exit,IO,P):- true|
                IO=[],P=[].
        display(N,IO,P):- integer(N)|
                P=[get_if_any(N,L)|P0],
                ( L={St} -> 
                  P0=[put(N,St)|P1],
                  IO=[putt(N),putt(' : '),putl(St),
                      prompt("> "),gett(T)|IO1]
                ; otherwise
                ; true -> IO=[prompt("> "),gett(T)|IO1],
                              P1=P0 ),
                display(T,IO1,P1).
        otherwise.
        display(_,IO,P):- true|
                IO=[prompt("> "),gett(T)|IO1],
                display(T,IO1,P).

\end{verbatim}
The program can be used like this.
\begin{verbatim}

        [7] sample10:go("sample10.kl1").
        Number of Lines = 42
        > 5.
        5 : go(Name):- true|
        > 7.
        7 : std_inter(IO)@priority($,-100),
        > 1.
        1 : :- module sample10.
        > exit.
         yes.

\end{verbatim}

\section{The Timer}
The Timer is one of PIMOS resources just like files, windows, etc.
Creating the following module will illustrate how it can be used.
\begin{verbatim}

        :- module timer.
        :- public create/1.

        create(Timer):- true|
                shoen:raise(pimos_tag#task,
                        general_request,General_Request_Device),
                General_Request_Device=
                        [timer(normal(Timer_Request_Device,_,_))],
                Timer_Request_Device=
                        [create(normal(Timer,_,_))].

\end{verbatim}

Calling this module as,
\begin{quote}
 {\tt [9] timer:create(Timer), Timer = [\ldots]. }
\end{quote}
will return a stream to the Timer in the variable {\tt Timer}.
You can then use Timer functions by sending the following
messages to this stream.
\begin{itemize}
\item {\tt get\_count(\outarg  Result)}\\
This returns the elapsed time since 0:00 AM (midnight) in milliseconds.
The variable {\tt Result} is instantiated to {\tt normal(Count)}
where the variable {\tt Count} is the actual time.
\item {\tt on\_at(Count,\outarg  Result)}\\
When given a time in milliseconds since 0:00 AM (midnight)
in the variable {\tt Count},
the variable {\tt Result} will be instantiated to the value
{\tt normal(Now)}, and the variable {\tt Now}
will be instantiated to the atom {\tt wake\_up}
at the actual time specified by {\tt Count}.
\item {\tt on\_after(Count,\outarg Result)}\\
When given an amount of time in milliseconds
in the variable {\tt Count},
the variable {\tt Result} will be instantiated to the value
{\tt normal(Now)}, and the variable {\tt Now}
will be instantiated to the atom {\tt wake\_up}
after the amount of time specified by {\tt Count} elapses.
\end{itemize}

\subsection{Using the Timer}
The following alarm program shows how to use the Timer.
In this program, sending the message {\tt on\_at(Count,\outarg Result)},
returns the value {\tt normal(Now)} to the variable {\tt Result}.
The variable {\tt Now} will be instantiated to {\tt wake\_up} when the
specified time arrives.
The alarm process detects the instantiation and sends
a message to Message-Output.
\begin{verbatim}

        :- module alarm.
        :- public go/3.

        go(H,M,Mes):- 
                integer(H),integer(M), string(Mes,_,_)|
                Time := ( H*3600 + M*60 )*1000,
                timer:create( [on_at(Time,St)] ),
                alarm( St, Mes ).
        alarm( normal(wake_up), Mes ):- true|
                shoen:raise( pimos_tag#shell, get_std_mes, Stream),
                Stream=[ putl(Mes) ].

\end{verbatim}
Before compiling this program, you must compile the
module {\tt timer} above.
This program can be used as a Shell utility,
(see Chapter \ref{chap:Shell}) and is executed as follows.
\begin{verbatim}

        Shell> alarm(17,30,"### Time is up. ###")&
        Shell> ......

        Shell> (Shell Command or <cr> )
        ### Time is up. ###

\end{verbatim}
In this example, the message {\tt \#\#\# Time is up. \#\#\#} will be
appear following the first carriage return pressed
after 17:30.


\chapter{Dealing with Problems}
\label{chap:trouble}
This chapter explains briefly how to deal with PIMOS or
SIMPOS problems that could be caused by KL1 programs.
Greater detail on this subject
can be seen in Chapter 12 of the
``Multi-PSI/V2 Console System (CSP) Operating Manual''\cite{CSP}.

\section{Problems with PIMOS}
\begin{itemize}
\item If PIMOS doesn't appear to be running correctly
(because of bugs in your program or for other reasons)
you can stop PIMOS execution by typing {\tt Control-C}
in the ``CSP Command Window''.
You will then see a CSP prompt, {\tt \$}, in the window.
If typing {\tt Control-C} has no effect,
click a mouse button on the ``Monitor Panel'' in
the upper-left corner of your display and push the {\tt ABORT} key.
Next, select the menu item ``Return to CSP Toplevel''
in the window that pops up.
You will then get a prompt in the ``CSP Command Window.''
Input the {\tt exit} command at this prompt,
\begin{quote}
 {\tt \$ exit}
\end{quote}
to terminate CSP.
You can reboot PIMOS by selecting ``(Pseudo) Multi-PSI''  from the SYSTEM MENU.
\item If a KL1 program consumes all the PIMOS memory or causes a PIMOS error,
PIMOS will abort execution and a {\tt \$} prompt
will appear in the ``CSP Command Window''.
You should then shutdown PIMOS with  the
{\tt exit} command  and reboot from the SYSTEM MENU.
\item When the cause of a problem is a shortage of memory, the
following error message will be displayed in the ``CSP Command Window'':
\begin{verbatim}
        Copying GC Memory Shortage : xxx words
\end{verbatim}

Sometimes this type of error can be avoided in Pseudo Multi-PSI by
changing the information that specifies the
number of processors in your configuration file.
See Chapters 4 and 6 in the
``Multi-PSI/V2 Console System (CSP) Operating Manual''\cite{CSP} for
directions on how to do this.
\end{itemize}

\section{Problems with SIMPOS}
SIMPOS execution may halt because of problems with one of your
programs. 
In this case, the CONSOLE Window
(which first appears on the display when SIMPOS is booted) will appear
with messages and a prompt something like the following :
\begin{verbatim}
        %F-SRGHLT, CPU HALT BY STOP REGISTER

        MPC = ....              PMPC = ....
        CIR0 = ....
        CIR1 = ....

          ....................

        $
\end{verbatim}
You can recover from this situation with the following operations.
\begin{enumerate}
\item Type the {\tt deb} command to the prompt to enter the 
PSI-CSP debugging mode.
\begin{quote}
{\tt \$deb}
\end{quote}
\item Input {\tt go} to the {\tt >} prompt that appears on the CONSOLE.
\begin{quote}
{\tt >go}
\end{quote}
\item Next, push the {\tt CTRL} key and the {\tt BREAK} key at the same time.
The CONSOLE Window will disappear. Return to the CSP Command Window by
clicking the mouse button on it if necessary.
\item If there is not a {\tt \$} prompt in the CSP Command Window, type
{\tt Control-C} to make the prompt appear.
\item Input the {\tt exit} command at the {\tt \$} prompt to terminate CSP.
\item Reboot PIMOS by selecting ``(Pseudo) Multi-PSI''from the SYSTEM MENU.
\end{enumerate}

\begin{itemize}
\item If SIMPOS does not respond correctly after operation 3 above,
push the {\tt BREAK} key to return to the {\tt >} prompt.
Next, perform the following operations to shutdown SIMPOS and
reboot it.
\begin{quote}
{\tt >go/tr}\\
{\tt @q simpos}\\
{\tt @}$<cr>$\\
{\tt DC> OK to SHUT DOWN ?? [Y/N] -> [1/0]}\\
{\tt RC> 1}\\
.........\\
{\tt >q}\\
{\tt \$bo}
\end{quote}
\item If operations 4 or 5 above fail and you cannot terminate
CSP, select the item {\tt process} from the
SYSTEM MENU to start up the ``Process Manipulator.''
(See the ``Basic PSI/SIMPOS Operating Manual (1),(2)''\cite{SIMPOS}. ) 
In the ``Process Manipulator'' window,
select {\tt (Pseudo\_) multi\_psi\_main\_program} and
execute the {\tt exterminate} command.
You may then shut down SIMPOS.
\item If all the above operations fail, push the RESET button on the
PSI-II and cross your fingers.
\end{itemize}


\begin{thebibliography}{99}
\bibitem{INSTALL}
(Pseudo) Multi-PSI System Administration Manual
\bibitem{CSP}
Multi-PSI/V2 Console System (CSP) Operating Manual
\bibitem{PIMOS}
PIMOS 2.5 Manual
\bibitem{KL1}
KL1 Programming: Introduction, Beginning Level, and Intermediate Level
\bibitem{SYSTEM}
Basic System Administration Manual for PSI/SIMPOS Systems
\bibitem{SIMPOS}
Basic PSI/SIMPOS Operating Manual (1),(2)
\end{thebibliography}
\end{document}
