1\chapter{The unwind Library}
2
3This document describes the facilities provided by the \ml{unwind} library
4for the HOL system~\cite{description}. The library provides conversions and
5rules for unfolding, unwinding and pruning device implementations (logical
6representations of hardware). For a detailed description of these techniques,
7see~\cite{HVusingHOL}.
8
9Most of the functions fall into one of five groups. The first group consists
10of conversions and inference rules for moving universal quantifiers up and
11down through conjunctions; they have names beginning with either
12\ml{CONJ\_FORALL} or \ml{FORALL\_CONJ}. The second group of functions are for
13unfolding, that is expanding sub-components using their definitions. The names
14of these begin with \ml{UNFOLD}. The functions in the third group perform
15unwinding and have names beginning with \ml{UNWIND}. The fourth group of
16functions prune internal lines that have been unwound. Their names begin with
17\ml{PRUNE}. The final group of functions combine unfolding, unwinding and
18pruning. They have names beginning with \ml{EXPAND}.
19
20I have tried to make the behaviour of the functions uniform. The conversions
21apply to the smallest term possible, to provide maximum flexibility. The
22inference rules, on the other hand, are designed to apply to the definition
23of a hardware component. They expect to be given a theorem of the form:
24
25\begin{small}\begin{verbatim}
26   |- !x1 ... xn. DEVICE (x1,...,xn) = ?l1 ... lm. t1 /\ ... /\ tp
27\end{verbatim}\end{small}
28
29
30\section{Using the library}
31
32The \ml{unwind} library can be loaded into a \HOL\ session using the function
33\ml{load\_library}\index{load\_library@{\ptt load\_library}} (see the \HOL\
34manual for a general description of library loading). The first action in the
35load sequence initiated by \ml{load\_library} is to update the \HOL\
36help\index{help!updating search path} search path. The help search path is
37updated with a pathname to online help files for the \ML\ functions in the
38library. After updating the help search path, the \ML\ functions in the
39library are loaded into \HOL.
40
41The following session shows how the \ml{unwind} library may be loaded using
42\ml{load\_library}:
43
44\setcounter{sessioncount}{1}
45\begin{session}\begin{verbatim}
46#load_library `unwind`;;
47Loading library `unwind` ...
48Updating help search path
49..................................
50Library `unwind` loaded.
51() : void
52\end{verbatim}\end{session}
53
54We now illustrate the use of the library on the parity-checker example.
55Firstly, we begin a new theory:
56
57\begin{session}\begin{verbatim}
58#new_theory `PARITY`;;
59() : void
60\end{verbatim}\end{session}
61
62\vfill
63
64\noindent
65We define the sub-components used:
66
67\vfill
68
69\begin{session}\begin{verbatim}
70#let ONE_DEF =
71# new_definition
72#  (`ONE_DEF`, "ONE(out:num->bool) = !t. out t = T");;
73ONE_DEF = |- !out. ONE out = (!t. out t = T)
74\end{verbatim}\end{session}
75
76\vfill
77
78\begin{session}\begin{verbatim}
79#let NOT_DEF =
80# new_definition
81#  (`NOT_DEF`, "NOT(in,out:num->bool) = !t. out t = ~(in t)");;
82NOT_DEF = |- !in out. NOT(in,out) = (!t. out t = ~in t)
83\end{verbatim}\end{session}
84
85\vfill
86
87\begin{session}\begin{verbatim}
88#let MUX_DEF =
89# new_definition
90#  (`MUX_DEF`,
91#   "MUX(sw,in1,in2,out:num->bool) =
92#     !t. out t = (sw t => in1 t | in2 t)");;
93MUX_DEF =
94|- !sw in1 in2 out.
95    MUX(sw,in1,in2,out) = (!t. out t = (sw t => in1 t | in2 t))
96\end{verbatim}\end{session}
97
98\vfill
99
100\begin{session}\begin{verbatim}
101#let REG_DEF =
102# new_definition
103# (`REG_DEF`, "REG(in,out:num->bool) =
104#              !t. out t = ((t=0) => F | in(t-1))");;
105REG_DEF =
106|- !in out. REG(in,out) = (!t. out t = ((t = 0) => F | in(t - 1)))
107\end{verbatim}\end{session}
108
109\vfill
110
111\noindent
112Now we define the parity-checker implementation:
113
114\begin{session}\begin{verbatim}
115#let PARITY_IMP_DEF =
116# new_definition
117#  (`PARITY_IMP_DEF`,
118#   "PARITY_IMP(in,out) =
119#    ?l1 l2 l3 l4 l5.
120#     NOT(l2,l1) /\ MUX(in,l1,l2,l3) /\ REG(out,l2) /\
121#     ONE l4     /\ REG(l4,l5)       /\ MUX(l5,l3,l4,out)");;
122PARITY_IMP_DEF =
123|- !in out.
124    PARITY_IMP(in,out) =
125    (?l1 l2 l3 l4 l5.
126      NOT(l2,l1) /\
127      MUX(in,l1,l2,l3) /\
128      REG(out,l2) /\
129      ONE l4 /\
130      REG(l4,l5) /\
131      MUX(l5,l3,l4,out))
132\end{verbatim}\end{session}
133
134\noindent
135The function \ml{EXPAND\_AUTO\_RIGHT\_RULE} can be used to unfold, unwind and
136prune the body of this definition:
137
138\begin{session}\begin{verbatim}
139#EXPAND_AUTO_RIGHT_RULE [ONE_DEF;NOT_DEF;MUX_DEF;REG_DEF] PARITY_IMP_DEF;;
140|- !in out.
141    PARITY_IMP(in,out) =
142    (!t.
143      out t =
144      (((t = 0) => F | T) =>
145       (in t =>
146        ~((t = 0) => F | out(t - 1)) |
147        ((t = 0) => F | out(t - 1))) |
148       T))
149\end{verbatim}\end{session}
150
151
152\section{Automatic unwinding}
153
154\def\putbox(#1,#2){\put(#1,#2){\framebox(2,2){}}}
155
156Hardware implementations often contain feedbacks. This presents a problem
157when trying to unwind and prune the internal lines in the logical
158representation. The mutual dependencies between lines can cause a brute-force
159unwind to loop indefinitely. To avoid this one has to be selective about
160which lines to unwind. The tools in the \ml{unwind} library allow the user
161to be selective in this way. However, it is possible for the machine itself to
162be selective. The function \ml{UNWIND\_AUTO\_CONV} attempts to analyze the
163dependencies between lines and unwind as far as possible without looping.
164
165Consider the following term which arises in the parity-checker example:
166
167\begin{small}\begin{verbatim}
168   "?l1 l2 l3 l4 l5.
169     (!t. l1 (t:num) = ~l2 t) /\
170     (!t. l3 t = (in t => l1 t | l2 t)) /\
171     (!t. l2 t = ((t = 0) => F | out (t - 1))) /\
172     (!t. l4 t = T) /\
173     (!t. l5 t = ((t = 0) => F | l4 (t - 1))) /\
174     (!t. out t = (l5 t => l3 t | l4 t))"
175\end{verbatim}\end{small}
176
177\noindent
178We can represent the dependencies of the lines using a directed graph:
179
180{\setlength{\unitlength}{4mm}
181\begin{center}
182\begin{picture}(14,10)(0,0)
183\put(0,2){\makebox(2,2){\small{\tt l2}}}
184\put(4,2){\makebox(2,2){\small{\tt l1}}}
185\put(8,4){\makebox(2,2){\small{\tt l3}}}
186\put(12,6){\makebox(2,2){\small{\tt out}}}
187\put(2,8){\makebox(2,2){\small{\tt l4}}}
188\put(6,8){\makebox(2,2){\small{\tt l5}}}
189
190\put(2,3){\vector(1,0){2}}
191\put(2,3){\vector(3,1){6}}
192\put(6,3){\vector(1,1){2}}
193\put(10,5){\vector(1,1){2}}
194\put(4,9){\vector(1,0){2}}
195\put(4,9){\vector(4,-1){8}}
196\put(8,9){\vector(2,-1){4}}
197
198\put(13,6){\line(0,-1){6}}
199\put(13,0){\line(-1,0){12}}
200\put(1,0){\vector(0,1){2}}
201\end{picture}
202\end{center}}
203
204\noindent
205which can in turn be represented by the following list:
206
207\begin{small}\begin{verbatim}
208   l1, [l2]
209   l3, [l1;l2]
210   l2, [out]
211   l4, []
212   l5, [l4]
213   out,[l5;l3;l4]
214\end{verbatim}\end{small}
215
216Since we wish to eliminate the internal lines, we want to be left with a
217recursive equation for {\small\verb%out%} in terms of itself. We can do this
218be `breaking the loop' at {\small\verb%out%}, giving the following structure:
219
220\begin{small}\begin{verbatim}
221   l1, [l2]
222   l3, [l1;l2]
223   l2, []
224   l4, []
225   l5, [l4]
226\end{verbatim}\end{small}
227
228\noindent
229Note that {\small\verb%out%} has been removed from the structure. From the
230graph we can see that {\small\verb%l2%} and {\small\verb%l4%} do not depend
231on any internal lines. They can therefore be used to unwind without any risk
232of looping. They can be recognized in the datastructure by the fact that their
233corresponding dependency lists are empty.
234
235Once we have unwound with {\small\verb%l2%} and {\small\verb%l4%} they can be
236removed from the datastructure:
237
238\begin{small}\begin{verbatim}
239   l1, []
240   l3, [l1]
241   l5, []
242\end{verbatim}\end{small}
243
244\noindent
245We now see that {\small\verb%l1%} and {\small\verb%l5%} can be unwound to give:
246
247\begin{small}\begin{verbatim}
248   l3, []
249\end{verbatim}\end{small}
250
251\noindent
252Unwinding {\small\verb%l3%} then leaves us with the required recursive
253equation for {\small\verb%out%}.
254
255The problem with the approach just described is that it only unwinds fully if
256there is at most one loop in the circuit, and the output is in that loop. We
257can be a bit more general. Consider the circuit:
258
259\vfill
260
261{\setlength{\unitlength}{4mm}
262\begin{center}
263\begin{picture}(4,18)(0,0)
264\put(1,0){\makebox(2,2){\small{\tt out}}}
265\putbox(1,4)
266\put(0,6){\makebox(2,2){\small{\tt l2}}}
267\putbox(1,8)
268\put(0,10){\makebox(2,2){\small{\tt l1}}}
269\putbox(1,12)
270\put(1,16){\makebox(2,2){\small{\tt in}}}
271
272\put(2,16){\vector(0,-1){2}}
273\put(2,12){\vector(0,-1){2}}
274\put(2,8){\vector(0,-1){2}}
275\put(2,4){\vector(0,-1){2}}
276
277\put(2,7){\circle*{0.2}}
278\put(2,7){\line(1,0){2}}
279\put(4,7){\line(0,1){8}}
280\put(4,15){\line(-1,0){1}}
281\put(3,15){\vector(0,-1){1}}
282\end{picture}
283\end{center}}
284
285\vfill
286
287\noindent
288represented by the graph:
289
290\vfill
291
292\begin{small}\begin{verbatim}
293   l1, [l2]
294   l2, [l1]
295   out,[l2]
296\end{verbatim}\end{small}
297
298\vfill
299
300\noindent
301There are no lines with an empty dependency list, and eliminating
302{\small\verb%out%} will not help because it is not in the loop. However, if we
303break the loop at {\small\verb%l2%} we can unwind {\small\verb%l1%}. This will
304leave us with a recursive equation for {\small\verb%l2%} and an equation for
305{\small\verb%out%} in terms of {\small\verb%l2%}. This is the best that we can
306do, and it is now up to the user to deal with the recursive equation.
307
308Now let's consider an example with more than one loop:
309
310{\setlength{\unitlength}{4mm}
311\begin{center}
312\begin{picture}(12,30)(0,0)
313\put(1,0){\makebox(2,2){\small{\tt out}}}
314\putbox(1,4)
315\put(0,6){\makebox(2,2){\small{\tt l5}}}
316\putbox(1,8)
317\put(0,10){\makebox(2,2){\small{\tt l4}}}
318\putbox(1,12)
319\put(0,14){\makebox(2,2){\small{\tt l3}}}
320\putbox(1,16)
321\putbox(5,16)
322\put(0,18){\makebox(2,2){\small{\tt l2}}}
323\put(6,18){\makebox(2,2){\small{\tt l6}}}
324\putbox(1,20)
325\putbox(9,20)
326\put(0,22){\makebox(2,2){\small{\tt l1}}}
327\put(10,22){\makebox(2,2){\small{\tt l7}}}
328\putbox(1,24)
329\put(1,28){\makebox(2,2){\small{\tt in}}}
330
331\put(2,28){\vector(0,-1){2}}
332\put(2,24){\vector(0,-1){2}}
333\put(2,20){\vector(0,-1){2}}
334\put(2,16){\vector(0,-1){2}}
335\put(2,12){\vector(0,-1){2}}
336\put(2,8){\vector(0,-1){2}}
337\put(2,4){\vector(0,-1){2}}
338
339\put(2,11){\circle*{0.2}}
340\put(2,11){\line(1,0){4}}
341\put(6,11){\vector(0,1){5}}
342\put(6,18){\line(0,1){1}}
343\put(6,19){\line(-1,0){3}}
344\put(3,19){\vector(0,-1){1}}
345\put(2,7){\circle*{0.2}}
346\put(2,7){\line(1,0){8}}
347\put(10,7){\vector(0,1){13}}
348\put(10,22){\line(0,1){1}}
349\put(10,23){\line(-1,0){7}}
350\put(3,23){\vector(0,-1){1}}
351\end{picture}
352\end{center}}
353
354\noindent
355We could unwind {\small\verb%l1%} but then we would get stuck. If we break at
356{\small\verb%l2%} or {\small\verb%l7%} we will still get stuck because of the
357inner loop. If we break at {\small\verb%l5%} we can unwind {\small\verb%l7%},
358but then get stuck. If we break at {\small\verb%l6%} we get stuck because of
359the outer loop. However, if we break at {\small\verb%l3%} or {\small\verb%l4%}
360both loops are broken and we can unwind fully to leave a recursive equation
361for either {\small\verb%l3%} or {\small\verb%l4%} and an equation for
362{\small\verb%out%} in terms of that line. So, the choice of where to break a
363loop may determine how far the unwinding can go.
364
365\ml{UNWIND\_AUTO\_CONV} attempts to break every loop in the circuit using the
366minimum number of breaks, so that there are as few equations left as possible.
367The function also gives priority to non-internal lines when determining where
368to break, so that if possible the recursive equations are in terms of these
369lines.
370
371The algorithm used determines from the term a list of line variables. Each
372line variable has a right-hand side of an equation associated with it. The
373free variables in each right-hand side are computed and those that are also
374line variables are placed in the dependency list for the corresponding line.
375From the dependency structure, the loops are determined. Lines are then
376eliminated so that all loops are broken.
377
378A study of the following circuit reveals why {\em all\/} loops have to be
379broken. If not all loops are broken, then a remaining loop can make the
380breaking of other loops fruitless.
381
382{\setlength{\unitlength}{4mm}
383\begin{center}
384\begin{picture}(12,30)(0,0)
385\put(1,0){\makebox(2,2){\small{\tt out}}}
386\putbox(1,4)
387\put(0,6){\makebox(2,2){\small{\tt l5}}}
388\putbox(1,8)
389\put(0,10){\makebox(2,2){\small{\tt l4}}}
390\putbox(1,12)
391\putbox(9,12)
392\put(0,14){\makebox(2,2){\small{\tt l3}}}
393\put(10,14){\makebox(2,2){\small{\tt l7}}}
394\putbox(1,16)
395\putbox(5,16)
396\put(0,18){\makebox(2,2){\small{\tt l2}}}
397\put(6,18){\makebox(2,2){\small{\tt l6}}}
398\putbox(1,20)
399\put(0,22){\makebox(2,2){\small{\tt l1}}}
400\putbox(1,24)
401\put(1,28){\makebox(2,2){\small{\tt in}}}
402
403\put(2,28){\vector(0,-1){2}}
404\put(2,24){\vector(0,-1){2}}
405\put(2,20){\vector(0,-1){2}}
406\put(2,16){\vector(0,-1){2}}
407\put(2,12){\vector(0,-1){2}}
408\put(2,8){\vector(0,-1){2}}
409\put(2,4){\vector(0,-1){2}}
410
411\put(2,11){\circle*{0.2}}
412\put(2,11){\line(1,0){4}}
413\put(6,11){\vector(0,1){5}}
414\put(6,18){\line(0,1){1}}
415\put(6,19){\line(-1,0){3}}
416\put(3,19){\vector(0,-1){1}}
417\put(2,7){\circle*{0.2}}
418\put(2,7){\line(1,0){8}}
419\put(10,7){\vector(0,1){5}}
420\put(10,14){\line(0,1){1}}
421\put(10,15){\line(-1,0){7}}
422\put(3,15){\vector(0,-1){1}}
423\end{picture}
424\end{center}}
425
426\noindent
427The dependency structure for the circuit is:
428
429\begin{small}\begin{verbatim}
430   l1, []
431   l2, [l1]
432   l3, [l2;l6]
433   l4, [l3;l7]
434   l5, [l4]
435   l6, [l4]
436   l7, [l5]
437   out,[l5]
438\end{verbatim}\end{small}
439
440\noindent
441The loops for the circuit are:
442
443\begin{small}\begin{verbatim}
444   [l3;l4;l6]
445   [l4;l5;l7]
446\end{verbatim}\end{small}
447
448\noindent
449Both loops can be broken by eliminating {\small\verb%l4%}:
450
451\begin{small}\begin{verbatim}
452   l1, []
453   l2, [l1]
454   l3, [l2;l6]
455   l5, []
456   l6, []
457   l7, [l5]
458   out,[l5]
459\end{verbatim}\end{small}
460
461\noindent
462We can now unwind {\small\verb%l1%}, {\small\verb%l5%} and {\small\verb%l6%}:
463
464\begin{small}\begin{verbatim}
465   l2, []
466   l3, [l2]
467   l7, []
468   out,[]
469\end{verbatim}\end{small}
470
471\noindent
472and then unwind {\small\verb%l2%}, {\small\verb%l7%} and {\small\verb%out%},
473followed by unwinding with {\small\verb%l3%} to yield a recursive equation for
474{\small\verb%l4%} and all other equations in terms of {\small\verb%l4%}. All
475the internal lines except for {\small\verb%l4%} can be pruned. This leaves
476equations for {\small\verb%l4%} and {\small\verb%out%} only.
477
478The technique does not always yield a single recursive equation. Mutual
479recursion is also possible. This is illustrated by the following example:
480
481{\setlength{\unitlength}{4mm}
482\begin{center}
483\begin{picture}(10,30)(0,0)
484\put(1,0){\makebox(2,2){\small{\tt out}}}
485\putbox(1,4)
486\put(0,6){\makebox(2,2){\small{\tt l5}}}
487\putbox(1,8)
488\put(0,10){\makebox(2,2){\small{\tt l4}}}
489\putbox(1,12)
490\putbox(5,10)
491\put(0,14){\makebox(2,2){\small{\tt l3}}}
492\put(6,12){\makebox(2,2){\small{\tt l7}}}
493\putbox(1,16)
494\put(0,18){\makebox(2,2){\small{\tt l2}}}
495\putbox(1,20)
496\putbox(5,18)
497\put(0,22){\makebox(2,2){\small{\tt l1}}}
498\put(6,20){\makebox(2,2){\small{\tt l6}}}
499\putbox(1,24)
500\put(1,28){\makebox(2,2){\small{\tt in}}}
501
502\put(2,28){\vector(0,-1){2}}
503\put(2,24){\vector(0,-1){2}}
504\put(2,20){\vector(0,-1){2}}
505\put(2,16){\vector(0,-1){2}}
506\put(2,12){\vector(0,-1){2}}
507\put(2,8){\vector(0,-1){2}}
508\put(2,4){\vector(0,-1){2}}
509
510\put(2,15){\circle*{0.2}}
511\put(2,15){\line(1,0){4}}
512\put(6,15){\vector(0,1){3}}
513\put(6,20){\line(0,1){2}}
514\put(6,22){\vector(-1,0){3}}
515\put(2,7){\circle*{0.2}}
516\put(2,7){\line(1,0){4}}
517\put(6,7){\vector(0,1){3}}
518\put(6,12){\line(0,1){2}}
519\put(6,14){\vector(-1,0){3}}
520\put(6,7){\circle*{0.2}}
521\put(6,7){\line(1,0){4}}
522\put(10,7){\line(0,1){16}}
523\put(10,23){\line(-1,0){7}}
524\put(3,23){\vector(0,-1){1}}
525\end{picture}
526\end{center}}
527
528There are three loops, but breaking at {\small\verb%l2%} and {\small\verb%l4%}
529is sufficient to break all the loops. The result is three equations: an
530equation for {\small\verb%l2%} in terms of itself and {\small\verb%l4%}, an
531equation for {\small\verb%l4%} in terms of itself and {\small\verb%l2%}, and
532an equation for {\small\verb%out%} in terms of {\small\verb%l4%}. So, it can
533be seen that the loop analysis technique used by \ml{UNWIND\_AUTO\_CONV} does
534not eliminate loops; it simply `shrinks' them.
535