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