\chapter{Tutorial}

\section{Getting started with Transaction Logic Programming}

Our implementation of Transaction Logic Programming runs under 
Prolog environment. To run the implementation, at query prompt, 
loads ($consult/1$) the main module into Prolog and calls
'$init$'. The predicate init loads all necessary files into
Prolog and initializes the necessary parameters. The following 
shows the output when loading up Prototype 3 of implemenation in 
XSB Prolog. 
\begin{small}
\begin{tabbing}
tabbing \= \kill
\>	XSB Version 1.4.1(94/11/21) \\
\>	[sequential, single word, optimal mode]\\
\>	?- [prot3].\\
\>	[prot3 loaded]\\
\>	\\
\>	yes\\
\> 	?- init.\\
\>	[naming3 loaded]\\
\>	[basic\_funs3 loaded]\\
\>	[tr\_basics3 loaded]\\
\>	[parser3 loaded]\\
\>	[query3 loaded]\\
\>	[upload3 loaded]\\
\>	[keys\_appl3 loaded]\\
\>	[keys\_basics3 loaded]\\
\>	\\
\>	yes\\
\end{tabbing}
\end{small}
The main modules of each module have the name $protN$ when $N$ is the 
prototype number. For example, in the above example, $prot3$ is prototype 
3.

\section{Standard Predicates}

Since this program is under the environment of Prolog interpreter, it is 
free to use those Prolog commands which have no side effect to the 
database.

\subsection{Reading-in Programs}
Transaction Logic is different from normal logic programming because of 
the special rules storing structure. Transaction rules have to be stored 
in transaction base whereas database rules and database tuples have to be 
stored in database. This means there are two types of program files:
transaction program with all transaction rules, and database program 
with all database rules. Each program has to use the corresponding file 
handling predicate to read and compile.

\begin{itemize}
\item loadtrans(F) \\
	Reads transaction base from a file $F$. The file $F$ should 
	contains only transaction rules, and declaration statements 
	of any undeclared database tuples used in the rules. The rules 
	will pass through a parser and be compiled into a set Prolog 
	rules. The compiler stores the rules into a new file with suffix 
	{\em \_tran} and loads them into the Prolog database. For instance, 
	$loadtrans('mytr')$ reads the transaction program file {\em mytr}, 
	stores the compiled rules into {\em mytr\_tran} and loads these rules 
	into the Prolog database.

\item loadbase(F) \\
	Reads database file $F$ from the current directory. Contrary to 
	$loadtrans/1$, the file $F$ should contains only database rules, 
	database tuples, and a set of declaration statements. Note that 
	database rules and transaction rules are treated differently.

\end{itemize}

\subsection{Rules and Queries}

\subsubsection{Transaction Rule:}

Like most logic formula, a transaction rule consists of two parts: 
a rule head and a rule body. 
\begin{eqnarray*}
	Head & \leftarrow & Body. \\
	or  \\
	Head. & & 
\end{eqnarray*}
where {\em Head} is an atomic formula and {\em Body} is a sequence of 
transaction actions (or queries) connected by serial conjunction 
connectives ({\em sc}).

For example, suppose the transaction base consists of the following 
two rules:
\begin{eqnarray*}
	add(0). & & \\
	add(N) & \leftarrow & N>0\; sc\; N1\ is\ N-1\; sc\; create(p(N))\;
			sc\; add(N1). 
\end{eqnarray*}
Then, the transaction query {\em ?- add(N)} would create 10 tuples 
(from {\em p(1)} to {\em p(10)}) in the database.

\subsubsection{Database Rule:}
Database rule has the same format as a Prolog rule.
\begin{eqnarray*}
	Head & :- & Body.\\
	or \\
	Head.
\end{eqnarray*}

\subsubsection{Query:}
To distinguish a transaction from a Prolog query, the user must put 
the transaction query as the argument of the Prolog predicate {\em trans/1}. 
For simplicity, ``{\em ?-}'' is a Prolog query prompt, and ``{\em ?- trans}'' 
is a transaction prompt. For example, suppose the transaction base and 
database contain the following: 
\vspace*{3mm}
\begin{center}
\begin{tabular}{cc}
	transaction base & database \\
		p(1)	 &    p(2) 
\end{tabular}
\end{center}
\vspace*{3mm}
Then, $?- p(X)$ outputs $X=2$ only, but $?- trans p(X)$ outputs $X=1$ 
and $X=2$. So, rules in transaction base are invisible to Prolog queries.
A transaction query is a sequence of goals (or updates), connected by 
serial conjunction, denoted {\em sc}. For example, $?- trans\ p(X)\ sc\ 
create(p(X))$ means if $p(X)$ is in the database (or transaction base), 
create the same tuple $p(X)$ to the database. In the above example, when 
$X$ is bound to 1, since $p(1)$ is in the transaction base but not in the 
database, $create(p(1))$ succeeds.

\subsection{Directives on Database Tuples}

\subsubsection{Declaration:}
Database atoms represent tuples in a relation. Each relation has its 
own key. Each key determines a unique value. A declaration statement 
for a relation should be made before attempting to access it. 
The statement declares the arity of the relation, its key, and 
indexes. The format of a declare statement is:

\begin{center}
	declare $Name/NArgs$ key $Nkey$ size $S$ indexing $IList$.
\end{center}

The statement declares a database relation with Name and number of 
arguments, $NArgs$. The first $Nkey$ arguments of the relation are the 
key, which uniquely identifies the values of the remaining arguments. 
The remaining part of the declaration statement is index specifications. 
With such declaration, the system would create a hash table with $S$ 
entries for the arguments listed in $IList$. Note that in most Prologs 
other than XSB, this part of a declaration is neglected, because most 
Prolog interpreters do not allow user-defined indexing on predicates.

In the declaration, apart from the relation name and arity, if any of 
the remaining declaration is missing, the program uses some default 
settings:
\begin{itemize}
\item If the key field is missing, the program uses the whole tuple as 
	the key.
\item If the size and indexing fields are missing, the program does not 
	define any special indexing.
\item If the indexing field is missing, the program defines a hash table 
	with $S$ entries on the arguments of the key.
\end{itemize}
For example, {\em declare p/1} defines a relation {\em p(X)} with the 
relation itself be the key, and {\em declare q/2 key 1} defines a 
relation {\em q(X,Y)} with the first argument {\em X} be the key.

\subsubsection{Updates:}

After declaration, a relation can be accessed through queries and 
updates. There are three types of simple updates: $create$, $destroy$ and 
$set$; and three types of bulk updates: $bulk\ insert$, $bulk\ delete$ and 
$assignment$. The following examples use declarations of {\em p/1 key 1}, 
and {\em q/2 key 1}.

\begin{itemize} 
\item create($Tuple$) \\
	Inserts the tuple $Tuple$ into database. The tuple specification 
	should have been declared in advance. The predicate also fails if 
	the key of $Tuple$ is already in the database. In other word, the 
	key of tuple has already assigned a value. Note that all variables 
	in $Tuple$ should have been unified before being created. For 
	example, $trans\; create(p(1))\; sc\; create(p(2))$ creates two 
	tuples, $p(1)$ and $p(2)$ to the database, but $trans\; 
	create(q(1,1))\; sc\; create(q(1,2))$ fails.

\item destroy($Tuple$) \\
	Removes the entry $Tuple$ from database. The process fails if
	$Tuple$ was not in the database. Arguments of $Tuple$ can be 
	uninstantiated because the execution would unify the variables by 
	choosing tuples in database. For example, $trans\; destroy(p(1))$ 
	deletes $p(1)$ from database; $trans\; destory(q(X,Y))$ deletes 
	one of the $q(X,Y)$ tuple from database.

\item set($Tuple$) \\
	Change the value of the key identified by $Tuple$. The key of 
	$Tuple$ should not be the tuple itself, otherwise, no value of 
	the key can be set. For instance, if $q(1,1)$ is in the database, 
	$trans\; set(q(1,2))$ succeeds, but if $q(2,2)$ is not in the 
	database, $trans\; set(q(2,3))$ fails.

\item bulk\_ins($Cond$,$ToTuple$) \\
	adds all tuples to $ToTuple$ which satisfy the condition $Cond$. 
	Also, it never fails except $ToTuple$ is not declared.

\item bulk\_del($Dtuple$) \\
	destroys all tuples satisfying $Dtuple$. Again, it never fails 
	unless $Dtuple$ is not declared.

\item $ToTuple$ := $Cond$ \\
	deletes all tuples in the relation of $ToTuple$ and overwrites 
	them with those satisfies the condition $Cond$. For instance, 
	$p(X)\; :=\; q(X,Y)$ selects the first elements of $q(X,Y)$, 
	and then put in the predicate $p(X)$. So, if the database contains 
	$q(1,1)$, $q(2,2)$, then $p(1)$ and $p(2)$ are created. Note 
	that $Cond$ is a database formula and the assignment searches over 
	the database only.

\end{itemize}

\subsection{Loop and Selection}

There are two types of loop iterations: while-loop and for-loop. 
It should be noticed that the conditions of loops are represented 
by database formulas, i.e., ``$pred_1, pred_2, \ldots , pred_N$''.

\begin{itemize}
\item {[with $VList$]} while $Cond$ do $Action$. \\
	repeatedly executes $Actions$ until $Cond$ fails. The list 
	$VList$ contains variables that are exported into the loop 
	and whose values cannot change from one iteration to the next. 
	Comparing the following formulas:
	\begin{enumerate}
	\item  p(X) sc with [X] while q(Y) do r(X,Y).
	\item  p(X) sc while q(Y) do r(X,Y).
	\end{enumerate}
	Suppose $p(1)$ is in the database. In the first formula, 
	since $X$ is defined to be a constant in the loop, it is bounded 
	to 1 at every iterations. However, in the second formula, $X$ is 
	a free variable in the loop. It remains unbound at every call 
	to $r(X,Y)$ in each iterations and can have different values in 
	each iterations, e.g., $while\; q(Y)\; do\; (X=Y\; sc\; r(X,Y))$, 
	where value of $X$ in each iteration is unified to the value of 
	$Y$ at that occasions. 

\item {[with $VList$]} forall $Vars$ in $Cond$ do $Actions$. \\
	executes $Actions$ for all sets of distinct variables denoted by 
	$Vars$ chosen from $Cond$. Similar to while-loop, $VList$ contains 
	the variable list that are exported into the loop but the values 
	cannot change from one iteration to another. On the other hand, 
	$Vars$ contains the list of variables which are selected to test 
	against the loop condition. For example, with $p(1)$ in the 
	database, $p(X)\; sc\; with\; [X]\; forall\; [Y]\; in\; q(X,Y)\; 
	do\; r(Y)$ executes $r(Y)$ for every Y in $q(1,Y)$. More details 
	of for-loop can be found in Section 4.3.8.

\end{itemize}

The simplest selection statement is an if-then-ese statement. It has the 
following format:

\begin{center}
		if $Cond$ then $Action1$ else $Action2$
\end{center}

This exeuctes $Action1$ if $Cond$ is true, and executes Action2 otherwise.

\section{Programming Examples}

The following shows some simple transaction queries (or updates) and 
declaration. More examples can be found in benchmark tests.

\begin{enumerate}

\item Initially, the \TR database is empty. A predicate $q$ is defined 
	with 1 arguments and the whole predicate is the key. 
	\begin{quote}
	?- declare q/1. 
	\end{quote}
\item The following steps create three tuples $p(1,1)$, $p(2,1)$ and $p(3,3)$. 
	The first argument of $p(X,Y)$ is chosen as the key.
	\begin{quote}
	?- declare p/2 key 1. \\
	?- trans create(p(1,1)) sc create(p(2,1)) sc create(p(3,3)). 
	\end{quote}
\item With the above database, the following steps create a copy of tuples 
	$q(X)$ from the first argument of $p(X,Y)$: 
	\begin{quote}	
	?- trans bulk\_ins(p(X,Y),q(X)). 
	\end{quote}
	Now, the database contains $p(1,1)$, $p(2,1)$, $p(3,3)$, $q(1)$, $q(2)$ 
	and $q(3)$.

\item The tuples $p(1,1)$ and $p(2,1)$ can be removed by either of the 
	following commands: 
	\begin{quote}
	?- trans destroy(p(1,1)) sc destroy(p(2,1)). \\
	{\bf or} \\
	?- trans bulk\_del(p(X,1)). 
	\end{quote}
	Now, the database contains $p(3,3)$, $q(1)$, $q(2)$, $q(3)$.

\item The following assignment changes the extent of predicate $p$ to 
	$p(1,1)$, $p(2,1)$ and $p(3,1)$: 
	\begin{quote}
	?- trans p(X,1) := q(X). 
	\end{quote}
	In this operation, contents of $p(X,Y)$ are removed first. 
	Then, since X has 3 choices: 1,2 and 3, $p(1,1)$, $p(2,1)$ 
	and $p(3,1)$ are created into database.  

\item Note: We can simulate the effect of $bulk\_del/1$ by using 
	a while-loop. For example, 
	\begin{quote}
	?- trans while p(X,1) do destroy(p(X,1)). 
	\end{quote}
	has the same effect on the database as the updates in {\bf 4}, 
	i.e., $p(X,1)$ is destroyed at each iteration until there is no 
	possible choice left.

\item We can also use a for-loop to simulate the bulk insert in {\bf 3}: 
	\begin{quote}
	?- trans for [X] in q(X) do create(p(X,1)).
	\end{quote}
	
\end{enumerate}
