\chapter{Benchmark Tests}

This appendix provides a series of complex updates that test the 
correctness of a \TR \hspace{.5in} implementation. For each test, we show the top-level 
\TR command, and the correct answers. In our implementation, the user 
interface to \TR is similar to Prolog's.

\begin{enumerate}

\item	Initially, the database is empty. The following commands declare 
	and insert tuples on $p/2$, $q/2$ and $r/1$. 

\begin{small}
	\lpagebegin
?- declare p/2 key 2. \\
\\
yes \\
	\lpageend
	\ \
	\rpagebegin
@ declare p/2 with the whole tuple as the key. \\
	\rpageend
?- trans create(p(1,a)) sc create(p(2,b)). \\
\\
yes \\
?- p(X,Y). \\
\\
X = 1 \\
Y = a; \\
\\
X = 2 \\
Y = b; \\
\\
no \\
	\lpagebegin
?- declare q/2 key 1. \\
\\
yes \\
	\lpageend
	\ \
	\rpagebegin
@ declare q/2 with the first argument as the key.\\
	\rpageend
?- trans create(q(1,a)) sc create(q(2,b)). \\
\\
yes \\
?- q(X,Y). \\
 \\
X = 1 \\
Y = a; \\
\\
X = 2 \\
Y = b; \\
\\
no \\
	\lpagebegin
?- declare r/1.	\\	
\\		
yes \\	
	\lpageend
	\ \
	\rpagebegin
@ declare r/1. No key field is indicated in the transaction, 
so the whole tuple is used as the key. \\
	\rpageend
?- trans create r(1) sc create r(2). \\
\\
yes \\
| ?- r(X). \\
 \\
X = 1; \\
\\
X = 2; \\
\\
no \\
	\lpagebegin
?- trans create(p(1,c)). \\
\\
yes \\
	\lpageend
\ \
	\rpagebegin
p(1,c) successfully created.\\
	\rpageend
	\lpagebegin
?- trans create(q(1,c)).\\
\\
no		\\
	\lpageend
\ \
	\rpagebegin
@ create q(1,c) failed because the first argument is the key and
q(1,a) is already in the database.\\
	\rpageend
	\lpagebegin
?- q(1,X).	
\\
X = a;
\\
no \\
	\lpageend
\ \
	\rpagebegin
@ q(1,c) is not in the database. \\
	\rpageend
\end{small}

\_\hrulefill \_

\item 	Transaction rules and database rules can be added using
	{\em loadtrans/1} and {\em loadbase/1}, as follows. File 1 is a 
	transaction program file, and File 2 contains database rules only. 
	The following points should be noticed in this example:
	\begin{itemize}
	\item Compare the difference in syntax between database rules and 
		transaction rules.
	\item All database predicates must be declared.
	\item All interactive commands are database queries, unless 
		enclosed inside trans (.), in which case, they are 
		transactions.
	\item These files are not serial Horn, since $p$ occurs in the 
		body of a database rule and the head of a transaction 
		rule.
	\end{itemize}
\begin{small}
	\lpagebegin
File 1:	\\
a(X,Y) <- p(X,Y) sc r(X). \\
\\	 		
q(1,1).	\\		
q(1,2).	\\	
p(2,2).	\\	
r(1).  \\
	\lpageend
\ \
	\rpagebegin
File 2: \\
declare q/2 key 1.\\
declare r/1.\\
b(X,Y) :- p(X,Y), r(X).\\
q(1,1).\\
p(1,a).\\
p(2,a).\\
r(2).\\
	\rpageend
?- loadbase(file2). \\
\\
yes\\
	\lpagebegin
?- loadtrans(file1).\\
\\
yes  \\
	\lpageend
\ \
	\rpagebegin
@ Base predicates in the transaction base do not require declare 
statement because they are derived, not stored, and are not restricted 
by the key of database predicate with same name and number of arguments.\\
	\rpageend
	\lpagebegin
?- r(X).\\
\\
X = 2;\\
\\
no \\
	\lpageend
\ \
	\rpagebegin
@ A database query considers data in database only.\\
	\rpageend
	\lpagebegin
?- trans r(X). \\
\\		
X = 2; \\
\\
X = 1;\\
\\
no\\
	\lpageend
\ \
	\rpagebegin
@ A transaction query considers data in both database and transaction base.\\
	\rpageend
	\lpagebegin
?- b(X,Y). \\
\\
X = 2 \\
Y = a; \\
\\
no\\
	\lpageend
\ \
	\rpagebegin
@ A database rule accesses predicate in the database only.\\
	\rpageend
	\lpagebegin
?- trans b(X,Y). \\
\\
X = 2\\
Y = a;\\
\\
no\\
	\lpageend
\ \
	\rpagebegin
@ Even in a transaction query, database rule still only consider database items only.
So, r(1) in the transaction base is not considered by in the database rule. \\
	\rpageend
	\lpagebegin
?- a(X,Y).\\
\\
no\\
	\lpageend
\ \
	\rpagebegin
@ transaction rules are invisible to database queries. \\
	\rpageend
	\lpagebegin
?- trans a(X,Y).\\
\\
X = 2 \\
Y = 2;\\
\\
X = 1\\
Y = a;\\
\\
X = 2\\
Y = a;\\
\\
no\\
	\lpageend
\ \
	\rpagebegin
@ A transaction rule considers data in both transaction base and database. \\
	\rpageend

\end{small}

\_\hrulefill \_

\item Test of destroy and set. The database contains $p(1,a)$, $p(2,b)$, 
	$p(1,c)$, $q(1,a)$, $q(2,b)$, $q(3,a)$, $r(1)$, $r(2)$, $r(3)$, 
	where $p/2\; key\; 2$, $q/2\; key\; 1$, and $r/1\; key\; 1$ are declared. 
	The transaction base contains $r(4)$, $s(4)$. \\

\begin{small}
	\lpagebegin
?- trans destroy(r(4)).	\\
\\
no \\
	\lpageend
\ \
	\rpagebegin
@ Destroying q predicate in the transaction base is not allowed.
	\rpageend
	\lpagebegin
?- trans destroy(s(4)).	\\
Undefined predicate/function: destroy\_1\_r/1\\
\\
no\\
	\lpageend
	\ \
	\rpagebegin
@ The destory operation is defined only on tuples declared in the database. Since no
tuple about s is declared in the database, the destroy operation is undefined here. \\
	\rpageend
	\lpagebegin
?- trans destroy(p(1,c)). \\
\\
yes \\
	\lpageend
\ \
	\rpagebegin
@ removes p(1,c) from database
	\rpageend
	\lpagebegin
?- p(X,Y).\\
\\
X = 1\\
Y = a;\\
\\
X = 2\\
Y = b;\\
\\
no\\
	\lpageend
\ \
	\rpagebegin
@ Now, p(1,a) and p(2,b) are left in database. \\
	\rpageend
	\lpagebegin
?- trans destroy(p(X,Y)). \\
\\
X = 1\\
Y = a;	\\
\\
X = 2\\
Y = b\\
\\
yes\\
	\lpageend
\ \
	\rpagebegin
@ We can select an atom to delete. First, p(X,Y) is unified to p(1,a), and 
delete it. Then, the deletion rolled back and delete p(2,b). \\
	\rpageend
	\lpagebegin
?- p(X,Y).\\
\\
X = 1\\
Y = a;\\
\\
no\\
	\lpageend
\ \
	\rpagebegin
@ p(2,b) was deleted, but p(1,a) was not.
	\rpageend
	\lpagebegin
?- trans destroy(q(X,Y)) sc write('aBc ') sc fail. \\
aBc aBc aBc \\
no \\
	\lpageend
\ \
	\rpagebegin
@ The execution deletes an atom from $q(X,Y)$, then printed the word ``aBc'', and 
then forced to fail. So, the number of times ``aBc'' shown indicated the number 
of times destroy(q(X,Y)) succeeded which is the same as number of backtracking, 
or the number of atoms of q(X,Y). Three ``aBc'' were shown, so q(X,Y) has three tuples. \\
	\rpageend
	\lpagebegin
?- q(X,Y). \\
\\
X = 1 \\
Y = a; \\
\\
X = 2 \\
Y = b; \\
\\
X = 3 \\
Y = a; \\
\\
no \\
	\lpageend
\ \
	\rpagebegin
@ The extent and order of q(X,Y) was perserved.
	\rpageend
	\lpagebegin
?- trans destroy(q(X,Y)) sc destroy(r(Z)) sc write('aBc ') sc fail.\\
aBc aBc aBc aBc aBc aBc aBc aBc aBc  \\
no \\ 
	\lpageend
\ \
	\rpagebegin
@ There are 3*3 choices for backtracking p and q, i.e., (X,Y,Z) are 
(1,a,1), (1,a,2), (1,a,3), (2,b,1), (2,b,2), (2,b,3),
(3,a,1), (3,a,3), (3,a,3). So, 9 ``aBc'' are shown. \\
	\rpageend
	\lpagebegin
?- trans set q(1,b). \\
\\
yes \\
	\lpageend
\ \
	\rpagebegin
@ change the value of q(1,a) to q(1,b) \\
	\rpageend
?- q(X,Y). \\
\\
X = 1\\
Y = b;\\
\\
X = 2\\
Y = b;\\
\\
X = 3\\
Y = a;\\
\\
no\\
	\lpagebegin
?- trans set q(4,a).	 \\
\\
no\\
	\lpageend
\ \
	\rpagebegin
@ 'set' is not equivalent to 'create'. If the key is not already in the database, then
'set' fails.
	\rpageend
	\lpagebegin
?- trans set p(1,b). \\
Undefined predicate/function: set\_2\_p/2	\\
\\
no\\
	\lpageend
\ \
	\rpagebegin
@ 'set' is not defined on p/2 because the whole predicate is the key (i.e., there
are no non-key attributes whose values can be set).
	\rpageend
\end{small}

\_\hrulefill \_


\item Test of bulk insertion and deletion. Database contains $p(1,a)$, $p(2,b)$, 
	$p(3,a)$, $r(4)$. Transaction base contains $p(5,5)$. \\

\begin{small}
	\lpagebegin
?- trans bulk\_ins(p(X,Y),r(X)).	\\
\\
X = \_1264924\\
Y = \_1264740\\
\\
yes\\
	\lpageend
\ \
	\rpagebegin
@ bulk insertion of p(X,Y) into r(X), so r(1), r(2) and r(3) are added to the 
database. Also, it copies data from the database only. \\
	\rpageend
?- r(X). \\
\\
X = 4;\\
\\
X = 1;\\
\\
X = 2;\\
\\
X = 3;\\
\\
no\\

	\lpagebegin
?- trans bulk\_ins(p(X,Y),q(X,Y)) sc fail. \\
\\
no\\
	\lpageend
\ \	
	\rpagebegin
@ Bulk insertion into q forced to fail and backtrack, so q(X,Y) should 
still contains no tuples. \\
	\rpageend	
\\ 
\\
\\
\\


?- q(X,Y).\\
\\
no\\
	\lpagebegin
?- trans bulk\_del(p(X,a)).\\
\\
X = \_1264776\\
\\
yes\\
	\lpageend
\ \
	\rpagebegin
@ bulk deletion of p(X,a), so p(1,a) and p(3,a) should be deleted.\\
\\
\\
\\
	\rpageend
\ \
	\lpagebegin
?- p(X,Y).\\
\\
X = 2\\
Y = b; \\
\\
no\\
	\lpageend
\ \	
	\rpagebegin
@ p(2,b) should be the only p-tuple left.
	\rpageend

	\lpagebegin
?- trans bulk\_del(p(X,Y)) sc fail.\\
\\
no\\
	\lpageend
\ \
	\rpagebegin
@ A bulk deletion forced to fail and backtrack, so p(2,b) is still in the 
database after the execution.\\
	\rpageend
?- p(X,Y).\\
\\
X = 2\\
Y = b;\\
\\
no

\end{small}

\_\hrulefill \_

\item Bulk Assignment. Database contains $p(1,a)$, $p(1,b)$, $p(2,b)$, 
	$q(3,c)$ and $r(b)$. Transaction base contains $p(1,1)$.

\begin{small}
	\lpagebegin
?- trans q(X,Y) := p(X,Y). \\
\\
X = \_1267740	\\
Y = \_1267748	\\
\\
yes \\
	\lpageend
\ \
	\rpagebegin
@ Since $q/2$ has the first argument as key, the assignment cannot copy 
both $q(1,a)$ and $q(1,b)$ to the database, so one of them is chosen 
non-deterministically. \\
	\rpageend
	\lpagebegin
?- q(X,Y). \\
\\
X = 1\\
Y = a;\\
\\
X = 2\\
Y = b;\\
\\
no\\
	\lpageend
\ \
	\rpagebegin
@ Also, $p(1,1)$ in the transaction base has no effect on the assignment.
	\rpageend
	\lpagebegin
?- trans q(X,Y) := (p(X,Y), r(Y)).\\
\\
X = \_1268180\\
Y = \_1268188\\
\\
yes \\
	\lpageend
\ \
	\rpagebegin
@ This test shows the use of a database formula $(q(X,Y),r(Y))$ rather than 
a single query in assignment. Since r has only one tuple in the database, 
i.e., $r(b)$, Y is bound to b, and so $p(1,b)$ and $p(2,b)$ are satisfied.
	\rpageend
	\lpagebegin
?- q(X,Y). \\
\\
X = 1\\
Y = b;\\
\\
X = 2\\
Y = b;\\
\\
no\\
	\lpageend
\ \
	\rpagebegin
@ q(1,b) and q(2,b) were inserted. \\
	\rpageend
\\
\\
\\

\end{small}

\_\hrulefill \_


\item Test of while loop and for loop. Transaction base contains $p(4,4)$ 
	and database contains $p(1,a)$, $p(2,b)$, $p(3,a)$, and $s/2$ is 
	declared with whole tuple as the key. The following cases are 
	tested separately. Note that the transaction base predicate, $p(4,4)$ 
	has no effect in loop conditions. \\
\begin{small}

{\bf Case 1:} \\
	\lpagebegin
?- trans Y = a sc while p(X,Y) do destroy(p(X,Y)). \\
\\
Y = a	\\
X = \_1265180\\
\\
yes\\
	\lpageend
\ \
	\rpagebegin
@ Although Y is bound to a, inside the while loop, it is still 
considered to be a free variable. So, p is empty after the execution. \\
	\rpageend
?- p(X,Y). \\
\\
no\\
	\lpagebegin
?- trans p(X,Y).\\
\\
X = 4 \\
Y = 4; \\
\\
yes \\
	\lpageend
\ \
	\rpagebegin
@ p(4,4) is still in transaction base. \\
	\rpageend

{\bf Case 2:} \\
	\lpagebegin
?- trans Y = a sc with [Y] while p(X,Y) do destroy(p(X,Y)).\\
\\
Y = a	\\
X = \_1265312 \\ 
\\
yes\\
	\lpageend
\ \
	\rpagebegin
@ The term ``with [Y]'' in the loop causes Y to be imported into the loop. 
Since Y is bound to 1, database atoms of the form $p(X,1)$ are
destroyed during the execution of the loop.
	\rpageend
\\

?- p(X,Y). \\
\\
X = 2\\
Y = b;\\
\\
no\\
\\
{\bf Case 3:} \\
	\lpagebegin
?- trans Y = a sc forall [X,Y] in p(X,Y) do create(s(X,Y)). \\
\\
Y = a	\\
X = \_1265380\\
\\
yes\\
	\lpageend
\ \
	\rpagebegin
@ As in case 1 above, Y is unified to a, but it is still a free 
variable inside the for-loop. So, the loop iterates on all pairs X,Y.
So, when the loop terminates, s will contain the same information as p.
	\rpageend
	\lpagebegin
?- s(X,Y).\\
\\
X = 2\\
Y = b;\\
\\
X = 1\\
Y = a;\\
\\
X = 3\\
Y = a;\\
\\
no\\
	\lpageend
\ \
	\rpagebegin
@ X,Y unified with data in database only, so $s(4,4)$ was not created. \\
	\rpageend
\\
{\bf Case 4:} \\
	\lpagebegin
?- trans Y = a sc with [Y] forall [X,Y] in p(X,Y) do create(s(X,Y)). \\
\\
Y = a\\
X = \_1265512	\\
\\
yes \\
	\lpageend
\ \
	\rpagebegin
@ As in case 2 above, $Y = a$ is imported into the for loop, so $X$ 
binds to 1 and 3 during loop iteration, and $s(1,a)$, $s(3,a)$ are created.
	\rpageend
\\
?- s(X,Y).\\
\\
X = 1\\
Y = a;\\
\\
X = 3\\
Y = a;\\
\\
no\\

\end{small}


\_\hrulefill \_

\item Tests on different types of for-loop. The database contains 
	$p(1,a)$, $p(2,b)$, $p(3,a)$. \\

\begin{small}
	\lpagebegin
?- trans forall [Y] in p(X,Y) do write('aBc ').\\
aBc aBc aBc \\
Y = \_1264920 \\
X = \_1264964 \\
\\
yes\\
	\lpageend
\ \
	\rpagebegin
@ Y = a,b,a are chosen
	\rpageend
	\lpagebegin
?- trans forall unique [Y] in p(X,Y) do write('aBc '). \\
aBc aBc\\
Y = \_1264936\\
X = \_1264980\\
\\
yes\\
	\lpageend
\ \
	\rpagebegin
@ Y = a,b are chosen
	\rpageend
	\lpagebegin
?- trans forall possible [Y] in p(X,Y) do write('aBc '). \\
aBc aBc \\
Y = \_1264936\\
X = \_1264980\\
\\
yes\\
	\lpageend
\ \
	\rpagebegin
@ Y = a,b are chosen
	\rpageend
	\lpagebegin
?- trans forall [X,Y] in p(X,Y) do write('ac ') sc write('l ') sc fail.	\\
ac ac ac l\\
no\\
	\lpageend
\ \
	\rpagebegin
@ Forced failure of for loop but no attemp to re-execute it in a different 
way. \\
	\rpageend
	\lpagebegin
?- trans forall unique [X,Y] in p(X,Y) do write('ac ') sc write('l ') sc fail.\\
ac ac ac l\\
no\\
	\lpageend
\ \
	\rpagebegin
@ Forced failure of for loop but no attemp to re-execute it in a 
different way \\
	\rpageend
	\lpagebegin
?- trans forall possible [X,Y] in p(X,Y) do write('ac ') sc write('l ') sc fail.\\
ac ac ac l ac ac l ac ac ac l ac ac l ac ac ac l ac ac l\\
no\\
	\lpageend
\ \
	\rpagebegin
@ Loop passed sixth times (six '1' printed). Note that sometimes there are
3 iterations to execute a loop, but sometimes there are only two, because
the transaction does not backtrack to the first iteration. For example, 
the order p(X,Y) in the first succeeded loop is p(1,a), p(2,b), p(3,a).
When it was forced to fail, it backtracks and the second and the third 
iteration only, i.e., exchange the order to p(1,a), p(3,a), p(2,b). So, 
only 2 'ac' printed in the second loop. In the next backtracking, the 
iteration backtracks to the first iteration, and the order is p(2,b), p(1,a),
p(3,a). Eventually, all possible combinations are chosen. \\
	\rpageend

\end{small}

\_\hrulefill \_

\item Test on backtracking of for-loop and while-loop, database contains 
	$p(1,a)$, $p(2,b)$, $p(3,a)$. \\

\begin{small}
	\lpagebegin
?- trans while p(X,Y) do destroy(p(X,Y)) sc write('aBc ') sc fail.\\
aBc aBc aBc aBc aBc aBc\\
no\\
	\lpageend
\ \
	\rpagebegin
@ Loop passed six times because there are 6 different orders to destroy
$p(X,Y)$. \\
	\rpageend
	\lpagebegin
?- p(X,Y).\\
\\
X = 1 \\
Y = a; \\
\\
X = 2\\
Y = b;\\
\\
X = 3\\
Y = a;\\
\\
no\\
	\lpageend
\ \
	\rpagebegin
@ p(X,Y) unchanged. \\
	\rpageend
	\lpagebegin
?- trans forall [X,Y] in p(X,Y) do destroy(p(X,Y)) sc fail. \\
\\
no \\
	\lpageend
\ \
	\rpagebegin
@ The for loop forced to fail. So, the destroy operations should be 
undone. \\
	\rpageend
	\lpagebegin
?- p(X,Y). \\
\\
X = 1\\
Y = a;\\
\\
X = 2\\
Y = b;\\
\\
X = 3\\
Y = a;\\
\\
no\\
	\lpageend
\ \
	\rpagebegin
@ p(X,Y) unchanged
	\rpageend

\end{small}

\_\hrulefill \_

\item Test on if-then-else. Database contains: $p(1,a)$, $p(2,b)$, $q(1)$, 
	$q(2)$. \\

\begin{small}
	\lpagebegin
?- trans q(X) sc if p(X,Y) then write(Y) else write(X).	\\
a\\
X = 1\\	
Y = a;	\\
b\\
X = 2\\
Y = b;\\
\\
no\\
	\lpageend
\ \
	\rpagebegin
@ X unifies to 1 first, then the condition $p(1,Y)$ succeeds, unifying 
	Y to a in the then-part, which writes a. The transaction backtracks 
	to unify X to 2 and Y to b. \\
	\rpageend
	\lpagebegin
?- trans q(X) sc if p(X,Y) then write(Y).\\
a\\
X = 1\\
Y = a;	\\
b\\
X = 2\\
Y = b;\\
\\
no\\
	\lpageend
\ \
	\rpagebegin
@ Since in the above test, the else-part was not used, we can drop the 
	else-part and obtain same result. \\
	\rpageend
	\lpagebegin
?- trans if p(1,1) then write(then) else write(else). \\
else \\
yes \\
	\lpageend
\ \
	\rpagebegin
@ Since p(1,1) is not in the database, else-part is executed. \\
	\rpageend
	\lpagebegin
?- trans if p(1,1) then write(then).\\
\\
yes\\
	\lpageend
\ \
	\rpagebegin
@ If the condition fails, an if-then formula is still true. \\
	\rpageend

\end{small}

\_\hrulefill \_

\item Test of Nested Loops. Database contains: $p(1,1)$, $p(2,1)$, 
	$p(2,2)$, $p(3,3)$, $q(1)$, $q(2)$.\\

\begin{small}

{\bf Case 1:} \\
?- trans forall [X] in q(X) do (with [X] while p(X,Y) do destroy(p(X,Y))).\\
\\
X = \_1265480\\
Y = \_1265012\\
\\
yes\\
	\lpagebegin
?- p(X,Y).\\
\\
X = 3 \\
Y = 3;\\
\\
no\\
	\lpageend
\ \
	\rpagebegin
@ In the forall loop, X is successfully unified to 1 and 2. So, all 
	tuples of the form p(1,Y) and p(2,Y) are eventually deleted, 
	leaving p(3,3) in database. \\
	\rpageend
{\bf Case 2:} \\
?- trans while q(X) do (write(X) sc with [X] forall [Y] in p(X,Y) do destroy(q(Y))).\\
122		\\
X = \_1265488\\
Y = \_1265564\\
\\
yes\\
?- q(X). \\
\\
no\\
{\bf Explanation} : 
Normally, this execution should fail because in the first iteration of 
the outer loop, X is bound to 1, and q(1) is destroyed in the forall loop. 
In the next iteration of the outer loop, X is bound to 2. The inner
loop becomes forall [Y] in p(2,Y) do destroy(q(Y)), and Y is unified to
1 and 2 in the iterations. The iteration fails because destroy(q(1)) fails
in the execution of this inner loop. Therefore, the program backtracks and
chooses other order to executing the outer while loop.
During backtracking of the outer loop, the program chooses to bind
X to 2 first. Then, both q(1) and q(2) are destroyed in the forall
loop. Since there is no q(X) left in the database, the while loop succeeds.


\end{small}

\_\hrulefill \_

\item Test of Recursion Through Iteration. \\
	Database contains: $p(1,a)$, $p(1,b)$, $p(1,2)$, $p(2,a)$. \\
	Transaction base contains the rule: \\
	\hspace{2.5in} $a(X)\; \leftarrow \; with\; 
	[X]\; forall\; [Y]\; in\; p(X,Y)\; do\; (write(Y)\; sc\; a(Y)).$ \\

\begin{small}

?- trans a(1). \\
ab2a\\
yes\\

{\bf Explanation} : 
During execution of the loop, Y is unified successively to 
a, b, and 2. In the first iteration, a is printed and a(a) is called, 
i.e., forall [Y] in p(a,Y) do destroy(q(Y)). Since there is no 
p(a,Y) in database, the loop succeeds without any iteration.
In the second iteration, b is printed and a(b) is called. Similar,
there is no p(b,Y) in the database, and so a(b) succeeds without 
any updates to database. In the third iteration, 2 is printed 
and a(2) is called. Since p(2,a) is in database, the loop iterates, 
binding Y to a, so a is printed. \\

\end{small}

 \_\hrulefill \_

\end{enumerate}

