|
|
1.1 ! root 1: .ds l] /usr/lib/bmac ! 2: 'so \*(l]/bmac.std ! 3: .de s[ \" start reference ! 4: .nh ! 5: .IP \\*([F. 5n ! 6: .. ! 7: .\" RT - reset everything to normal state ! 8: .de RT ! 9: .if !\\n(1T .BG ! 10: .if !\\n(IK .if !\\n(IF .if !\\n(IX .di ! 11: .ce 0 ! 12: .ul 0 ! 13: .if \\n(NX=0 .if \\n(AJ=0 .ll \\n(LLu ! 14: .ps \\n(PS ! 15: .if \\n(VS>=40 .vs \\n(VSu ! 16: .if \\n(VS<=39 .vs \\n(VSp ! 17: .if \\n(IP .in -\\n(IQu ! 18: .if !\\n(IP .nr IQ \\n(PIu ! 19: .if \\n(IP .nr IP -1 ! 20: .ft 1 ! 21: .bd 1 ! 22: .ta 5n 10n 15n 20n 25n 30n 35n 40n 45n 50n 55n 60n 65n 70n 75n 80n ! 23: .fi ! 24: .. ! 25: . \"IZ - initialization ! 26: .de IZ ! 27: .if \\n(FM=0 .nr FM 1i ! 28: .nr YY -\\n(FMu ! 29: .nr XX 0 1 ! 30: .nr IP 0 ! 31: .nr PI 3n ! 32: .nr IQ \\n(PIu ! 33: .nr PS 10 ! 34: .nr VS 12 ! 35: .if !\\n(PD .if n .nr PD 1v ! 36: .if !\\n(PD .if t .nr PD 0.3v ! 37: .nr ML 3v ! 38: .ps \\n(PS ! 39: .if \\n(VS>40 .vs \\n(VSu ! 40: .if \\n(VS<=39 .vs \\n(VSp ! 41: .if \\n(IR=0 .nr IR 5n ! 42: .nr TB 0 ! 43: .nr SJ \\n(.j ! 44: .nr LL 6.5i ! 45: .ll \\n(LLu ! 46: .nr LT \\n(.l ! 47: .lt \\n(LTu ! 48: .ev 1 ! 49: .nr FL \\n(LLu*11u/12u ! 50: .ll \\n(FLu ! 51: .ps 8 ! 52: .vs 10p ! 53: .ev ! 54: .if \\*(CF .ds CF "\(hy \\\\n(PN \(hy ! 55: .wh 0 NP ! 56: .wh -\\n(FMu FO ! 57: .ch FO 16i ! 58: .wh -\\n(FMu FX ! 59: .ch FO -\\n(FMu ! 60: .wh -\\n(FMu/2u BT ! 61: .. ! 62: .de TR \" Tech Report ! 63: .nr ST 2 ! 64: .pn 0 ! 65: .ds MN \\$1 ! 66: .rm SG ! 67: .br ! 68: .. ! 69: .de GR \" Grant - full ! 70: .ds GS * ! 71: .de GX ! 72: *This work was supported by the National Science Foundation under ! 73: .if \\n(.$=1 Grant \\$1. ! 74: .if \\n(.$=2 Grants \\$1 and \\$2. ! 75: .if \\n(.$=3 Grants \\$1, \\$2, and \\$3. ! 76: .if \\n(.$=4 Grants \\$1, \\$2, \\$3, and \\$4. ! 77: \\.. ! 78: .. ! 79: .de GP \" Grant - part ! 80: .ds GS * ! 81: .de GX ! 82: *This work was supported in part by the National Science Foundation under ! 83: .if \\n(.$=1 Grant \\$1. ! 84: .if \\n(.$=2 Grants \\$1 and \\$2. ! 85: .if \\n(.$=3 Grants \\$1, \\$2, and \\$3. ! 86: .if \\n(.$=4 Grants \\$1, \\$2, \\$3, and \\$4. ! 87: \\.. ! 88: .. ! 89: . \"TL - title and initialization ! 90: .de TL ! 91: .br ! 92: .nr TV 1 ! 93: .ME ! 94: .rm ME ! 95: .di WT ! 96: .nr SJ \\n(.j ! 97: .na ! 98: .fi ! 99: .ll 3.75i ! 100: .ft 3 ! 101: .ps 10 ! 102: .hy 0 ! 103: .. ! 104: .de TX ! 105: .rs ! 106: .sp .5i ! 107: .ce 1000 ! 108: .ps 12 ! 109: .ft 3 ! 110: .vs 15p ! 111: .if n .vs 1P ! 112: .ne 4 ! 113: .hy 0 ! 114: .WT ! 115: .hy 14 ! 116: .ce 0 ! 117: .. ! 118: .de TY ! 119: .di XT ! 120: .ll 3.75i ! 121: .fi ! 122: .hy 0 ! 123: .WT ! 124: \h'-\w' 'u'\\*(GS ! 125: .hy 14 ! 126: .nf ! 127: .di ! 128: .ll \\n(LLu ! 129: .ce 1000 ! 130: .ps 12 ! 131: .ft 3 ! 132: .if t .vs 15p ! 133: .if n .vs 1P ! 134: .ne 4 ! 135: .XT ! 136: .ce 0 ! 137: .. ! 138: . \" AU - author(s) ! 139: .de AU ! 140: .nr AV 1 ! 141: .ad \\n(SJ ! 142: .br ! 143: .di ! 144: .br ! 145: .nf ! 146: .nr NA +1 ! 147: .ds R\\n(NA \\$1 ! 148: .ds E\\n(NA \\$2 ! 149: .di A\\n(NA ! 150: .ll \\n(LLu ! 151: .if t .ft 2 ! 152: .if n .ft 1 ! 153: .ps 10 ! 154: .. ! 155: .de AX ! 156: .ft 1 ! 157: .rs ! 158: .ce 1000 ! 159: .ps 10 ! 160: .vs 12p ! 161: .if n .sp 2 ! 162: .if t .sp ! 163: .A1 ! 164: .if n .sp ! 165: .if t .sp 0.5 ! 166: .ns ! 167: .I1 ! 168: .if \\n(NA-1 .if n .sp 2 ! 169: .if \\n(NA-1 .if t .sp ! 170: .A2 ! 171: .if \\n(NA-1 .if n .sp ! 172: .if \\n(NA-1 .if t .sp 0.5 ! 173: .ns ! 174: .I2 ! 175: .if \\n(NA-2 .if t .sp ! 176: .if \\n(NA-2 .if n .sp 2 ! 177: .A3 ! 178: .if \\n(NA-2 .if t .sp 0.5 ! 179: .if \\n(NA-2 .if n .sp ! 180: .ns ! 181: .I3 ! 182: .if \\n(NA-3 .if t .sp ! 183: .if \\n(NA-3 .if n .sp 2 ! 184: .A4 ! 185: .if \\n(NA-3 .if t .sp 0.5 ! 186: .if \\n(NA-3 .if n .sp ! 187: .ns ! 188: .I4 ! 189: .if \\n(NA-4 .if t .sp ! 190: .if \\n(NA-4 .if n .sp 2 ! 191: .A5 ! 192: .if \\n(NA-4 .if n .sp ! 193: .if \\n(NA-4 .if t .sp 0.5 ! 194: .ns ! 195: .I5 ! 196: .if \\n(NA-5 .if t .sp ! 197: .if \\n(NA-5 .if n .sp 2 ! 198: .A6 ! 199: .if \\n(NA-5 .if n .sp ! 200: .if \\n(NA-5 .if t .sp 0.5 ! 201: .ns ! 202: .I6 ! 203: .if \\n(NA-6 .if t .sp ! 204: .if \\n(NA-6 .if n .sp 2 ! 205: .A7 ! 206: .if \\n(NA-6 .if n .sp ! 207: .if \\n(NA-6 .if t .sp 0.5 ! 208: .ns ! 209: .I7 ! 210: .if \\n(NA-7 .if t .sp ! 211: .if \\n(NA-7 .if n .sp 2 ! 212: .A8 ! 213: .if \\n(NA-7 .if n .sp ! 214: .if \\n(NA-7 .if t .sp 0.5 ! 215: .ns ! 216: .I8 ! 217: .if \\n(NA-8 .if t .sp ! 218: .if \\n(NA-8 .if n .sp 2 ! 219: .A9 ! 220: .if \\n(NA-8 .if n .sp ! 221: .if \\n(NA-8 .if t .sp 0.5 ! 222: .ns ! 223: .I9 ! 224: .. ! 225: . \"AI - authors institution ! 226: .de AI ! 227: .br ! 228: .ft 1 ! 229: .di ! 230: .di I\\n(NA ! 231: .nf ! 232: .. ! 233: . \"AB - begin an abstract ! 234: .de AB ! 235: .br ! 236: .di ! 237: .ul 0 ! 238: .ce 0 ! 239: .nr 1T 1 ! 240: .nr IK 1 ! 241: .nr KI 1 ! 242: .di WB ! 243: .rs ! 244: .nr AJ 1 ! 245: .ce 1 ! 246: .ft 2 ! 247: .if n .ul ! 248: .ll \\n(LLu ! 249: .if \\n(.$=0 ABSTRACT ! 250: .if \\n(.$>0 .if !"\\$1"-" .if !"\\$1"no" \\$1 ! 251: .if \\n(.$=0 .sp ! 252: .if \\n(.$>0 .if !"\\$1"-" .if !"\\$1"no" .sp ! 253: .hy 14 ! 254: .ul 0 ! 255: .ce 0 ! 256: .fi ! 257: .ft 1 ! 258: .nr OJ \\n(.i ! 259: .in +\\n(.lu/12u ! 260: .ll -\\n(.lu/12u ! 261: .br ! 262: .ps \\n(PS ! 263: .if \\n(VS>40 .vs \\n(VSu ! 264: .if \\n(VS<=39 .vs \\n(VSp ! 265: .ti +\\n(PIu ! 266: .. ! 267: . \"AE - end of an abstract ! 268: .de AE ! 269: .br ! 270: .di ! 271: .ll \\n(LLu ! 272: .ps \\n(PS ! 273: .if \\n(VS>40 .vs \\n(VSu ! 274: .if \\n(VS<=39 .vs \\n(VSp ! 275: .nr 1T 0 ! 276: .nr IK 0 ! 277: .in \\n(OJu ! 278: .nr AJ 0 ! 279: .di ! 280: .ce 0 ! 281: .if \\n(ST=2 .SY ! 282: .if \\n(ST<3 .rm SY ! 283: .. ! 284: . \"S2 - tech report style ! 285: . \"SY - cover sheet of released paper ! 286: .de SY ! 287: .ch FO 16i ! 288: .ch FX 16i ! 289: .ll \\n(LLu ! 290: .rs ! 291: .sp |13P ! 292: .ns ! 293: .if \\n(TV .TY ! 294: .if \\n(AV .AX ! 295: .rs ! 296: .sp |22P ! 297: .if !'\\*(MN'' TR \\*(MN ! 298: .ce 0 ! 299: .nf ! 300: .sp |28P ! 301: .ls 1 ! 302: .ll -\\n(.lu/12u ! 303: .WB ! 304: .ll \\n(LLu ! 305: .ls ! 306: .ce 1000 ! 307: .sp |8i ! 308: \\*(DY ! 309: .sp 2 ! 310: Department of Computer Science ! 311: .sp 1 ! 312: The University of Arizona ! 313: .sp 1 ! 314: Tucson, Arizona 85721 ! 315: .ce 0 ! 316: .sp |10i ! 317: .na ! 318: .fi ! 319: .GX ! 320: .br ! 321: .. ! 322: . \"S2 - first text page, released paper format ! 323: .de S2 ! 324: .ce 0 ! 325: .br ! 326: .SY ! 327: .rm SY ! 328: .bp 1 ! 329: .if \\n(TV .TX ! 330: .rs ! 331: .ce 0 ! 332: .ft 1 ! 333: .ad \\n(SJ ! 334: .. ! 335: . \"S0- mike lesk conserve paper style ! 336: .de S0 ! 337: .ce 0 ! 338: .br ! 339: .ll \\n(LLu ! 340: .if \\n(TV+\\n(AV>0 .ns ! 341: .if \\n(TV .TX ! 342: .if \\n(AV .AX ! 343: .if \\n(TV+\\n(AV>0 .rs ! 344: .ce 0 ! 345: .nf ! 346: .if \\n(TV>0 .sp 2 ! 347: .ls 1 ! 348: .WB ! 349: .ls ! 350: .fi ! 351: .ad \\n(SJ ! 352: .. ! 353: . \"SG - signature ! 354: .de SG ! 355: .br ! 356: .KS ! 357: .in +2u*\\n(.lu/3u ! 358: .sp 2 ! 359: .A1 ! 360: .if \\n(NA-1 .sp 2 ! 361: .A2 ! 362: .if \\n(NA-2 .sp 2 ! 363: .A3 ! 364: .if \\n(NA-3 .sp 2 ! 365: .A4 ! 366: .if \\n(NA-4 .sp 2 ! 367: .A5 ! 368: .if \\n(NA>5 .sp 2 ! 369: .A6 ! 370: .if \\n(NA>6 .sp 2 ! 371: .A7 ! 372: .if \\n(NA>7 .sp 2 ! 373: .A8 ! 374: .if \\n(NA>8 .sp 2 ! 375: .A9 ! 376: .in ! 377: .nf ! 378: .sp -1 ! 379: .if \\n(.$>=1 \\$1 ! 380: .if \\n(.$>=2 \\$2 ! 381: .if \\n(.$>=3 \\$3 ! 382: .if \\n(.$>=4 \\$4 ! 383: .if \\n(.$>=5 \\$5 ! 384: .if \\n(.$>=6 \\$6 ! 385: .if \\n(.$>=7 \\$7 ! 386: .if \\n(.$>=8 \\$8 ! 387: .if \\n(.$>=9 \\$9 ! 388: .fi ! 389: .br ! 390: .KE ! 391: .. ! 392: . \"Tables. TS - table start, TE - table end ! 393: .de TS ! 394: .br ! 395: .if !\\n(1T .RT ! 396: .ul 0 ! 397: .ti \\n(.iu ! 398: .if t .sp 0.5 ! 399: .if n .sp ! 400: .if \\$1H .TQ ! 401: .nr IX 1 ! 402: .. ! 403: .de TQ ! 404: .di TT ! 405: .nr IT 1 ! 406: .. ! 407: .de TH ! 408: .if \\n(.d>0.5v .nr T. 0 ! 409: .if \\n(.d>0.5v .T# 0 ! 410: .di ! 411: .nr TQ \\n(.i ! 412: .nr HT 1 ! 413: .in 0 ! 414: .TT ! 415: .in \\n(TQu ! 416: .mk #T ! 417: .. ! 418: .de TE ! 419: .nr IX 0 ! 420: .if \\n(IT>0 .if \\n(HT=0 .di ! 421: .if \\n(IT>0 .if \\n(HT=0 .nr EF \\n(.u ! 422: .if \\n(IT>0 .if \\n(HT=0 .nf ! 423: .if \\n(IT>0 .if \\n(HT=0 .TT ! 424: .if \\n(IT>0 .if \\n(HT=0 .if \\n(EF>0 .fi ! 425: .nr IT 0 ! 426: .nr HT 0 ! 427: .if n .sp 1 ! 428: .if t .sp 0.5 ! 429: .. ! 430: . \"DS - display. If .DS C, center; L, left-adjust; I, indent. ! 431: .de DS ! 432: .KS ! 433: .\\$1D \\$2 \\$1 ! 434: .. ! 435: .de D ! 436: .ID \\$1 ! 437: .. ! 438: .de CD ! 439: .ce 1000 ! 440: .XD ! 441: .. ! 442: .de ID ! 443: .XD ! 444: .if t .in +0.5i ! 445: .if n .in +8 ! 446: .if \\n(.$ .if !"\\$1"I" .in \\n(OIu ! 447: .if \\n(.$ .if !"\\$1"I" .in +\\$1n ! 448: .. ! 449: .de LD ! 450: .XD ! 451: .. ! 452: .de XD ! 453: .nf ! 454: .nr OI \\n(.i ! 455: .if t .sp 0.5 ! 456: .if n .sp 1 ! 457: .. ! 458: .de BD \" block display: save everything, then center it. ! 459: .XD ! 460: .nr BD 1 ! 461: .nr RD 2 ! 462: .di DD ! 463: .. ! 464: .de RD \" right block display: save everything, then right adjust it. ! 465: .XD ! 466: .nr BD 1 ! 467: .nr RD 1 ! 468: .di DD ! 469: .. ! 470: . \"DE - display end ! 471: .de DE ! 472: .ce 0 ! 473: .in \\n(OIu ! 474: .if t .sp 0.5 ! 475: .if n .sp 1 ! 476: .if \\n(BD>0 .DF ! 477: .nr BD 0 ! 478: .KE ! 479: .fi ! 480: .. ! 481: .de DF \" finish a block display to be recentered. ! 482: .di ! 483: .if \\n(dl>\\n(BD .nr BD \\n(dl ! 484: .if \\n(BD<\\n(.l .in (\\n(.lu-\\n(BDu)/\\n(RDu ! 485: .ta \\n(.luR ! 486: .DD ! 487: .in \\n(OIu ! 488: .. ! 489: . \"KS keep - for keep release features. As in IFM ! 490: .de KS ! 491: .if \\n(IK=0 .if \\n(IF=0 .KQ ! 492: .nr IK +1 ! 493: .. ! 494: . \"KQ - real keep processor ! 495: .de KQ ! 496: .br ! 497: .nr KI \\n(.i ! 498: .ev 2 ! 499: .br ! 500: .in \\n(KIu ! 501: .ps \\n(PS ! 502: .if \\n(VS>40 .vs \\n(VSu ! 503: .if \\n(VS<=39 .vs \\n(VSp ! 504: .ll \\n(LLu ! 505: .lt \\n(LTu ! 506: .if \\n(NX>0 .ll \\n(CWu ! 507: .if \\n(NX>0 .lt \\n(CWu ! 508: .di KK ! 509: .nr TB 0 ! 510: .. ! 511: . \"KF - floating keep ! 512: .de KF ! 513: .if !\\n(IK .FQ ! 514: .nr IK +1 ! 515: .. ! 516: . \"FQ real floating keep processor ! 517: .de FQ ! 518: .nr KI \\n(.i ! 519: .ev 2 ! 520: .br ! 521: .in \\n(KIu ! 522: .ps \\n(PS ! 523: .if \\n(VS>40 .vs \\n(VSu ! 524: .if \\n(VS<=39 .vs \\n(VSp ! 525: .ll \\n(LLu ! 526: .lt \\n(LTu ! 527: .if \\n(NX>0 .ll \\n(CWu ! 528: .if \\n(NX>0 .lt \\n(CWu ! 529: .di KK ! 530: .nr TB 1 ! 531: .. ! 532: . \"KE release - everything between keep and release is together ! 533: .de KE ! 534: .if \\n(IK .if !\\n(IK-1 .if \\n(IF=0 .RQ ! 535: .if \\n(IK .nr IK -1 ! 536: .. ! 537: . \"RQ real release ! 538: .de RQ ! 539: .br ! 540: .di ! 541: .nr NF 0 ! 542: .if \\n(dn-\\n(.t .nr NF 1 ! 543: .if \\n(TC .nr NF 1 ! 544: .if \\n(NF .if !\\n(TB .sp 200 ! 545: .if !\\n(NF .if \\n(TB .nr TB 0 ! 546: .nf ! 547: .\".rs ! 548: .nr TC 5 ! 549: .in 0 ! 550: .ls 1 ! 551: .if \\n(TB=0 .ev ! 552: .if \\n(TB=0 .br ! 553: .if \\n(TB=0 .ev 2 ! 554: .if \\n(TB=0 .KK ! 555: .ls ! 556: .ce 0 ! 557: .if \\n(TB=0 .rm KK ! 558: .if \\n(TB .da KJ ! 559: .if \\n(TB \!.KD \\n(dn ! 560: .if \\n(TB .KK ! 561: .if \\n(TB .di ! 562: .nr TC \\n(TB ! 563: .fi ! 564: .in ! 565: .ev ! 566: .. ! 567: .de EQ \"equation, breakout and display ! 568: .nr EF \\n(.u ! 569: .rm EE ! 570: .nr LE 1 \" 1 is center ! 571: .ds EL \\$1 ! 572: .if "\\$1"L" .ds EL \\$2 ! 573: .if "\\$1"L" .nr LE 0 ! 574: .if "\\$1"C" .ds EL \\$2 ! 575: .if "\\$1"I" .nr LE 0 ! 576: .if "\\$1"I" .ds EE \\h'|10n' ! 577: .if "\\$1"I" .if !"\\$3"" .ds EE \\h'\\$3' ! 578: .if "\\$1"I" .ds EL \\$2 ! 579: .if \\n(YE>0 .nf ! 580: .di EZ ! 581: .. ! 582: .de EN \" end of a displayed equation ! 583: .br ! 584: .di ! 585: .rm EZ ! 586: .nr ZN \\n(dn ! 587: .if \\n(ZN>0 .if \\n(YE=0 .LP ! 588: .if \\n(ZN=0 .if !"\\*(EL"" .nr ZN 1 ! 589: .if "\\n(.z"" .if \\n(ZN>0 .if !\\n(nl=\\n(PE .if t .sp .5 ! 590: .if "\\n(.z"" .if \\n(ZN>0 .if !\\n(nl=\\n(PE .if n .sp 1 ! 591: .if !"\\n(.z"" .if \\n(ZN>0 .if !\\n(.d=\\n(PE .if t .sp .5 ! 592: .if !"\\n(.z"" .if \\n(ZN>0 .if !\\n(.d=\\n(PE .if n .sp 1 ! 593: .pc ! 594: .if \\n(BD>0 .nr LE 0 \" can't mean centering in this case. ! 595: .lt \\n(.lu ! 596: .if \\n(EP=0 .if \\n(ZN>0 .if \\n(LE>0 .tl \(ts\(ts\\*(10\(ts\\*(EL\(ts ! 597: .if \\n(EP=0 .if \\n(ZN>0 .if \\n(LE=0 .if \\n(BD=0 .tl \(ts\\*(EE\\*(10\(ts\(ts\\*(EL\(ts ! 598: .if \\n(EP=0 .if \\n(ZN>0 .if \\n(LE=0 .if \\n(BD>0 .if \\n(BD<\\w\(ts\\*(10\(ts .nr BD \\w\(ts\\*(10\(ts ! 599: .if \\n(EP=0 .if \\n(ZN>0 .if \\n(LE=0 .if \\n(BD>0 \!\\*(10\\\\t\\*(EL ! 600: .if \\n(EP>0 .if \\n(ZN>0 .if \\n(LE>0 .tl \(ts\\*(EL\(ts\\*(10\(ts\(ts ! 601: .if \\n(EP>0 .if \\n(ZN>0 .if \\n(LE=0 .if \\n(BD=0 .tl \(ts\\*(EL\\*(EE\\*(10\(ts\(ts\(ts ! 602: .if \\n(EP>0 .if \\n(ZN>0 .if \\n(LE=0 .if \\n(BD>0 .if \\n(BD<\\w\(ts\\*(10\(ts .nr BD \\w\(ts\\*(10\(ts ! 603: .if \\n(EP>0 .if \\n(ZN>0 .if \\n(LE=0 .if \\n(BD>0 \!\\h'-\\\\n(.iu'\\*(EL\\h'|0'\\*(10 ! 604: .\".di EZ \" GCOS patch ! 605: .\"\\*(10 \" GCOS patch ! 606: .\".br \" GCOS patch ! 607: .\".di \" GCOS patch ! 608: .\".rm EZ \" GCOS patch ! 609: .lt \\n(LLu ! 610: .pc % ! 611: .if \\n(YE>0 .if \\n(EF>0 .fi ! 612: .rm EL ! 613: .rm 10 ! 614: .rm 11 ! 615: .rm 12 ! 616: .rm 13 ! 617: .rm 14 ! 618: .rm 15 ! 619: .rm 16 ! 620: .rm 17 ! 621: .rm 18 ! 622: .rm 19 ! 623: .rm 20 ! 624: .rm 21 ! 625: .rm 22 ! 626: .rm 23 ! 627: .if \\n(ZN>0 .if t .sp .5 ! 628: .if \\n(ZN>0 .if n .sp ! 629: .if "\\n(.z"" .nr PE \\n(nl ! 630: .if !"\\n(.z"" .nr PE \\n(.d ! 631: .. ! 632: .de ME ! 633: .nr SJ \\n(.j ! 634: .if \\n(LL>0 .nr LT \\n(LL ! 635: .nr YE 1 ! 636: .if \\n(PO=0 .nr PO \\n(.o ! 637: .. ! 638: . \"EM end up macro - process left over keep-release ! 639: .de EM ! 640: .br ! 641: .if \\n(TB=0 .if t .if \\nd=0 .wh -1p CM ! 642: .if \\n(TB \&\c ! 643: .if \\n(TB 'bp ! 644: .if \\n(TB .NP ! 645: .if \\n(TB .ch CM 160 ! 646: .. ! 647: . \"NP new page ! 648: .de NP ! 649: .if \\n(FM+\\n(HM>=\\n(.p .tm Margins bigger than page length. ! 650: .if \\n(FM+\\n(HM>=\\n(.p .ab ! 651: .if \\n(FM+\\n(HM>=\\n(.p .ex ! 652: .nr PX \\n(.s ! 653: .nr PF \\n(.f ! 654: .if t .if \\nd=0 .CM ! 655: .if \\n(HM=0 .nr HM 1i ! 656: 'sp \\n(HMu/2u ! 657: .lt \\n(LTu ! 658: .ps \\n(PS ! 659: .ft 1 ! 660: .PT ! 661: .ps \\n(PX ! 662: .ft \\n(PF ! 663: 'sp |\\n(HMu ! 664: .nr XX 0 1 ! 665: .nr YY 0-\\n(FMu ! 666: .ch FO 16i ! 667: .ch FX 17i ! 668: .ch FO -\\n(FMu ! 669: .ch FX -\\n(FMu ! 670: .if \\n(MF .FV ! 671: .nr MF 0 ! 672: .mk ! 673: .os ! 674: .ev 1 ! 675: .if \\n(TD=0 .if \\n(TC<5 .XK ! 676: .nr TC 0 ! 677: .ns ! 678: .ev ! 679: .nr TQ \\n(.i ! 680: .if \\n(IT>0 .in 0 ! 681: .if \\n(IT>0 .TT ! 682: .if \\n(IT>0 .in \\n(TQu ! 683: .mk #T ! 684: .if \\n(PO>0 .po \\n(POu ! 685: .if t .if \\n(.o+\\n(LL>7.75i .tm Offset + line length exceeds 7.75 inches, too wide ! 686: .. ! 687: .de XK ! 688: .nr TD 1 ! 689: .nf ! 690: .ls 1 ! 691: .in 0 ! 692: .rn KJ KL ! 693: .KL ! 694: .rm KL ! 695: .if "\\n(.z"KJ" .di ! 696: .nr TB 0 ! 697: .if "\\n(.z"KJ" .nr TB 1 ! 698: .br ! 699: .in ! 700: .ls ! 701: .fi ! 702: .nr TD 0 ! 703: .. ! 704: .de KD ! 705: .nr KM 0 ! 706: .if "\\n(.z"KJ" .nr KM 1 \" KM is 1 if in a rediversion of keeps ! 707: .if \\n(KM>0 \!.KD \\$1 ! 708: .if \\n(KM=0 .if \\n(.t<\\$1 .di KJ ! 709: .. ! 710: .de PT ! 711: .lt \\n(LLu ! 712: .pc % ! 713: .nr PN \\n% ! 714: .if \\n%-1 .tl '\\*(LH'\\*(CH'\\*(RH' ! 715: .lt \\n(.lu ! 716: .. ! 717: . \"FO - footer of page ! 718: .de FO ! 719: .rn FO FZ ! 720: .if \\n(K1>0 .tm This memo has a multi-page cover sheet. You are ! 721: .if \\n(K1>0 .tm rebuked in the name of the Committee on Technical Memoranda. ! 722: .if \\n(IT>0 .nr T. 1 ! 723: .if \\n(IT>0 .if \\n(FC=0 .T# 1 ! 724: .if \\n(IT>0 .br ! 725: .nr FC +1 ! 726: .if !\\n(NX .nr WF 0 ! 727: .nr dn 0 ! 728: .if \\n(FC<=1 .if \\n(XX .XF ! 729: .rn FZ FO ! 730: .nr MF 0 ! 731: .if \\n(dn .nr MF 1 ! 732: .if !\\n(WF .nr YY 0-\\n(FMu ! 733: .if !\\n(WF .ch FO \\n(YYu ! 734: .if !\\n(dn .nr WF 0 ! 735: .if \\n(FC<=1 .if \\n(XX=0 .if \\n(NX>0 .RC ! 736: .if \\n(FC<=1 .if \\n(XX=0 .if \\n(NX<=0 'bp ! 737: .nr FC -1 ! 738: .if \\n(ML>0 .ne \\n(MLu ! 739: .. ! 740: . \"2C - begin double column ! 741: .de 2C ! 742: .if !\\n(1T .if n .sp 4 ! 743: .if !\\n(1T .if t .sp 2 ! 744: .RT ! 745: .if \\n(NX=0 .mk ! 746: .if \\n(NX=0 .nr NC 1 ! 747: .hy 12 ! 748: .if \\n(L1=0 .nr L1 \\n(.l ! 749: .nr NX 1 ! 750: .if \\n(CW=0 .nr CW \\n(.l*7/15 ! 751: .ll \\n(CWu ! 752: .nr FL \\n(CWu*11u/12u ! 753: .if \\n(GW=0 .nr GW \\n(L1-(2*\\n(CW) ! 754: .nr RO \\n(CW+\\n(GW ! 755: .ns ! 756: .. ! 757: .de RC ! 758: .if \\n(NC>1 .C2 ! 759: .if \\n(NC<=1 .C1 ! 760: .nr NC \\n(ND ! 761: .. ! 762: .de C1 ! 763: .rt ! 764: .po +\\n(ROu ! 765: .nr ND 2 ! 766: .nr XX 0 1 ! 767: .if \\n(MF .FV ! 768: .ev 1 ! 769: .if \\n(TB .XK ! 770: .nr TC 0 ! 771: .ev ! 772: .ns ! 773: .. ! 774: .ch FO \\n(YYu ! 775: .de C2 ! 776: .po \\n(POu ! 777: 'bp ! 778: .nr ND 1 ! 779: .. ! 780: . \"1C - return to single column format ! 781: .de 1C ! 782: .br ! 783: .RT ! 784: .po \\n(POu ! 785: .nr ND 1 ! 786: .if \\n(NX>0 .ll \\n(L1u ! 787: .if \\n(NX>0 .bp ! 788: .nr NX 0 ! 789: .hy 14 ! 790: .. ! 791: . \".de R3 ! 792: . \".pl 102 ! 793: . \".nr LT \\n(.l ! 794: . \".. ! 795: .de BT ! 796: .nr PX \\n(.s ! 797: .nr PF \\n(.f ! 798: .ft 1 ! 799: .ps \\n(PS ! 800: 'lt \\n(LTu ! 801: .if \\n%>0 .tl '\\*(LF'\\*(CF'\\*(RF' ! 802: .ft \\n(PF ! 803: .ps \\n(PX ! 804: .. ! 805: . \"PP - paragraph ! 806: .de PP ! 807: .RT ! 808: .ne 1.1 ! 809: .if \\n(1T .sp \\n(PDu ! 810: .ti +\\n(PIu ! 811: .. ! 812: . \"SH - (unnumbered) section heading ! 813: .de SH ! 814: .RT ! 815: .if \\n(1T .sp 1 ! 816: .if !\\n(1T .BG ! 817: .RT ! 818: .ne 4 ! 819: .ft 3 ! 820: .if n .cu 1000 ! 821: .. ! 822: . \"NH - numbered heading ! 823: .de NH ! 824: .RT ! 825: .if \\n(1T .sp 1 ! 826: .if \\n(1T .if !\\n(.$ .sp 1 ! 827: .if !\\n(1T .BG ! 828: .RT ! 829: .ne 4 ! 830: .ft 3 ! 831: .if n .cu 1000 ! 832: .nr NS \\$1 ! 833: .if !\\n(.$ .nr NS 1 ! 834: .if !\\n(NS .nr NS 1 ! 835: .nr H\\n(NS +1 ! 836: .if !\\n(NS-4 .nr H5 0 ! 837: .if !\\n(NS-3 .nr H4 0 ! 838: .if !\\n(NS-2 .nr H3 0 ! 839: .if !\\n(NS-1 .nr H2 0 ! 840: .if !\\$1 .if \\n(.$ .nr H1 1 ! 841: .ds SN \\n(H1. ! 842: .if \\n(NS-1 .as SN \\n(H2 ! 843: .if \\n(NS-2 .as SN .\\n(H3 ! 844: .if \\n(NS-3 .as SN .\\n(H4 ! 845: .if \\n(NS-4 .as SN .\\n(H5 ! 846: .nr IQ \w'\\*(SN\ \ ' ! 847: .nr IP +1 ! 848: .in +\\n(IQu ! 849: .ti -\\n(IQu ! 850: .nf ! 851: \\*(SN\ \ \\c ! 852: .. ! 853: . \"BG - begin, execute at first PP ! 854: .de BG ! 855: .br ! 856: .ME ! 857: .rm ME ! 858: .di ! 859: .ce 0 ! 860: .nr KI 0 ! 861: .hy 14 ! 862: .nr 1T 1 ! 863: .S\\n(ST ! 864: .rm S0 ! 865: .rm S2 ! 866: .rm TX ! 867: .rm AX ! 868: .rm WT ! 869: .rm XT ! 870: .rm GR ! 871: .rm GP ! 872: .rm GS ! 873: .rm GX ! 874: .rm I1 ! 875: .rm I2 ! 876: .rm I3 ! 877: .rm I4 ! 878: .rm I5 ! 879: .rm CB ! 880: .rm E1 ! 881: .rm E2 ! 882: .de TL ! 883: .ft 3 ! 884: .sp ! 885: .ce 100 ! 886: .LG ! 887: \\.. ! 888: .de AU ! 889: .ft 2 ! 890: .ce 100 ! 891: .sp ! 892: .NL ! 893: \\.. ! 894: .de AI ! 895: .ft 1 ! 896: .ce 100 ! 897: .if n .sp ! 898: .if t .sp .5 ! 899: .NL ! 900: \\.. ! 901: .RA ! 902: .rm RA ! 903: .rn FJ FS ! 904: .rn FK FE ! 905: .nf ! 906: .if \\n(KG=0 .nr FP 0 \"KI should be new ! 907: .nr KG 0 \"KI should be new ! 908: .if \\n(FP>0 .FS ! 909: .if \\n(FP>0 .FG ! 910: .if \\n(FP>0 .FE ! 911: .br ! 912: .if \\n(TV>0 .if n .sp 2 ! 913: .if \\n(TV>0 .if t .sp 1 ! 914: .fi ! 915: .ll \\n(LLu ! 916: .. ! 917: .de RA \"redefine abstract macros ! 918: .de AB ! 919: .br ! 920: .if !\\n(1T .BG ! 921: .ce 1 ! 922: .sp 1 ! 923: ABSTRACT ! 924: .sp 1 ! 925: .nr AJ 1 ! 926: .in +\\n(.lu/12u ! 927: .ll -\\n(.lu/12u ! 928: .RT ! 929: \\.. ! 930: .de AE ! 931: .nr AJ 0 ! 932: .br ! 933: .in 0 ! 934: .ll \\n(LLu ! 935: .if \\n(VS>40 .vs \\n(VSu ! 936: .if \\n(VS<=39 .vs \\n(VSp ! 937: \\.. ! 938: .. ! 939: . \"IP - indented paragraph ! 940: .de IP ! 941: .RT ! 942: .if !\\n(IP .nr IP +1 ! 943: .sp \\n(PDu ! 944: .ne 3v ! 945: .if \\n(.$-1 .nr IQ \\$2n ! 946: .if \\n(.$ .LB "\\$1" ! 947: .if !\\n(.$ .LB ! 948: .. ! 949: . \"LP - left aligned (block) paragraph ! 950: .de LP ! 951: .ti \\n(.iu ! 952: .RT ! 953: .if \\n(1T .sp \\n(PDu ! 954: .ne 1.1 ! 955: .if \\n(.$ .LB \\$1 ! 956: .. ! 957: . \"IE - synonym for .LP ! 958: .de IE ! 959: .LP ! 960: .. ! 961: . \"LB - label paragraph ! 962: .de LB ! 963: .in +\\n(IQu ! 964: .ta \\n(IQu ! 965: .if \\n(.$ .ti -\\n(IQu ! 966: .if \\n(.$ \\$1\t\c ! 967: .. ! 968: . \"RS - prepare for double indenting ! 969: .de RS ! 970: .in +\\n(IRu ! 971: .. ! 972: . \"RE - retreat to the left ! 973: .de RE ! 974: .br ! 975: .in -\\n(IRu ! 976: .. ! 977: . \"CM - cut mark ! 978: .de CM ! 979: .po 0 ! 980: .\"lt 7i ! 981: .ft 1 ! 982: .ps 10 ! 983: .vs 4p ! 984: .\"tl '--''--' ! 985: .tl '---''' ! 986: .po ! 987: .vs ! 988: .\"lt ! 989: .ps ! 990: .ft ! 991: .. ! 992: . \"B - bold font ! 993: .de B ! 994: .nr PQ \\n(.f ! 995: .if n .if \\n(.$>2 \\&\\$3\\c ! 996: .if "\\$1"" .if n .ul 1000 ! 997: .if !"\\$1"" .if n .ul 1 ! 998: .if t .if !"\\$1"" \\$3\\fB\\$1\\f\\n(PQ\\$2 ! 999: .if n .if \\n(.$=1 \\$1 ! 1000: .if n .if \\n(.$>1 \\$1\\c ! 1001: .if n .if \\n(.$>1 \\&\\$2 ! 1002: .. ! 1003: . \"R - Roman font ! 1004: .de R ! 1005: .if n .ul 0 ! 1006: .ft 1 ! 1007: .. ! 1008: . \"I - italic font ! 1009: .de I ! 1010: .nr PQ \\n(.f ! 1011: .if n .if \\n(.$>2 \\&\\$3\\c ! 1012: .if "\\$1"" .if n .ul 1000 ! 1013: .if !"\\$1"" .if n .ul 1 ! 1014: .if t .if !"\\$1"" \\$3\\fI\\$1\\f\\n(PQ\\$2 ! 1015: .if n .if \\n(.$=1 \\$1 ! 1016: .if n .if \\n(.$>1 \\$1\\c ! 1017: .if n .if \\n(.$>1 \\&\\$2 ! 1018: .. ! 1019: . \"TA - tabs set in ens or chars ! 1020: .de TA ! 1021: .ta \\$1n \\$2n \\$3n \\$4n \\$5n \\$6n \\$7n \\$8n \\$9n ! 1022: .. ! 1023: . \"SM - make smaller size ! 1024: .de SM ! 1025: .ps -2 ! 1026: .. ! 1027: . \"LG - make larger size ! 1028: .de LG ! 1029: .ps +2 ! 1030: .. ! 1031: . \"NL - return to normal size ! 1032: .de NL ! 1033: .ps \\n(PS ! 1034: .. ! 1035: . \"DA - force date; ND - no date or new date. ! 1036: .de DA ! 1037: .ds DY \\$1 ! 1038: .. ! 1039: .if \n(mo-0 .ds MO January ! 1040: .if \n(mo-1 .ds MO February ! 1041: .if \n(mo-2 .ds MO March ! 1042: .if \n(mo-3 .ds MO April ! 1043: .if \n(mo-4 .ds MO May ! 1044: .if \n(mo-5 .ds MO June ! 1045: .if \n(mo-6 .ds MO July ! 1046: .if \n(mo-7 .ds MO August ! 1047: .if \n(mo-8 .ds MO September ! 1048: .if \n(mo-9 .ds MO October ! 1049: .if \n(mo-10 .ds MO November ! 1050: .if \n(mo-11 .ds MO December ! 1051: .if \n(dw-0 .ds DW Sunday ! 1052: .if \n(dw-1 .ds DW Monday ! 1053: .if \n(dw-2 .ds DW Tuesday ! 1054: .if \n(dw-3 .ds DW Wednesday ! 1055: .if \n(dw-4 .ds DW Thursday ! 1056: .if \n(dw-5 .ds DW Friday ! 1057: .if \n(dw-6 .ds DW Saturday ! 1058: .ds DY \*(MO \n(dy, 19\n(yr ! 1059: .IZ ! 1060: .rm IZ ! 1061: .rm MO ! 1062: .de FN ! 1063: .FS ! 1064: .. ! 1065: . \"FS - begin footnote ! 1066: .de FJ ! 1067: 'ce 0 ! 1068: .di ! 1069: .ev1 ! 1070: .ll \\n(FLu ! 1071: .da FF ! 1072: .br ! 1073: .if \\n(IF>0 .tm Footnote within footnote-illegal. ! 1074: .nr IF 1 ! 1075: .if !\\n+(XX-1 .FA ! 1076: .. ! 1077: . \"FE - footnote end ! 1078: .de FK ! 1079: .br ! 1080: .in 0 ! 1081: .nr IF 0 ! 1082: .di ! 1083: .ev ! 1084: .if !\\n(XX-1 .nr dn +\\n(.v ! 1085: .nr YY -\\n(dn ! 1086: .if \\n(NX=0 .nr WF 1 ! 1087: .if \\n(dl>\\n(CW .nr WF 1 ! 1088: .if (\\n(nl+\\n(.v)<=(\\n(.p+\\n(YY) .ch FO \\n(YYu ! 1089: .if (\\n(nl+\\n(.v)>(\\n(.p+\\n(YY) .if \\n(nl>(\\n(HM+1.5v) .ch FO \\n(nlu+\\n(.vu ! 1090: .if (\\n(nl+\\n(.v)>(\\n(.p+\\n(YY) .if \\n(nl>(\\n(HM+1.5v) .ch FX 16i ! 1091: .if (\\n(nl+\\n(.v)>(\\n(.p+\\n(YY) .if \\n(nl<=(\\n(HM+1.5v) .ch FO \\n(HMu+(4u*\\n(.vu) ! 1092: .. ! 1093: .\" First page footer. ! 1094: .de FS ! 1095: .ev1 ! 1096: .br ! 1097: .ll \\n(FLu ! 1098: .da FG ! 1099: .. ! 1100: .de FE ! 1101: .br ! 1102: .di ! 1103: .nr FP \\n(dn ! 1104: .if \\n(1T=0 .nr KG 1 \";not in abstract repeat next page. KI should be new ! 1105: .ev ! 1106: .. ! 1107: .de FA ! 1108: .if n __________________________ ! 1109: .if t \l'1i' ! 1110: .br ! 1111: .. ! 1112: .de FV ! 1113: .FS ! 1114: .nf ! 1115: .ls 1 ! 1116: .FY ! 1117: .ls ! 1118: .fi ! 1119: .FE ! 1120: .. ! 1121: .de FX ! 1122: .if \\n(XX>0 .di FY ! 1123: .if \\n(XX>0 .ns ! 1124: .. ! 1125: .de XF ! 1126: .if \\n(nlu+1v>(\\n(.pu-\\n(FMu) .ch FX \\n(nlu+1.9v ! 1127: .ev1 ! 1128: .nf ! 1129: .ls 1 ! 1130: .FF ! 1131: .rm FF ! 1132: .nr XX 0 1 ! 1133: .br ! 1134: .ls ! 1135: .di ! 1136: .fi ! 1137: .ev ! 1138: .. ! 1139: .de FL ! 1140: .ev1 ! 1141: .nr FL \\$1n ! 1142: .ll \\$1 ! 1143: .ev ! 1144: .. ! 1145: .de UL \" underline argument, don't italicize ! 1146: .if t \\$1\l'|0\(ul'\\$2 ! 1147: .if n .I \\$1 \\$2 ! 1148: .. ! 1149: .em EM ! 1150: . \" ACCENTS say \*'e or \*`e to get e acute or e grave ! 1151: .ds ' \h'\w'e'u*4/10'\z\(aa\h'-\w'e'u*4/10' ! 1152: .ds ` \h'\w'e'u*4/10'\z\(ga\h'-\w'e'u*4/10' ! 1153: . \" UMLAUT \*:u, etc. ! 1154: .ds : \v'-0.6m'\h'(1u-(\\n(.fu%2u))*0.13m+0.06m'\z.\h'0.2m'\z.\h'-((1u-(\\n(.fu%2u))*0.13m+0.26m)'\v'0.6m' ! 1155: . \" TILDE and CIRCUMFLEX ! 1156: .ds ^ \\k:\h'-\\n(.fu+1u/2u*2u+\\n(.fu-1u*0.13m+0.06m'\z^\h'|\\n:u' ! 1157: .ds ~ \\k:\h'-\\n(.fu+1u/2u*2u+\\n(.fu-1u*0.13m+0.06m'\z~\h'|\\n:u' ! 1158: . \" czech v symbol ! 1159: .ds C \\k:\\h'+\\w'e'u/4u'\\v'-0.6m'\\s6v\\s0\\v'0.6m'\\h'|\\n:u' ! 1160: . \" cedilla ! 1161: .ds , \\k:\\h'\\w'c'u*0.4u'\\z,\\h'|\\n:u' ! 1162: .if n .ds oq "" ! 1163: .if n .ds cq "" ! 1164: .if n .ds OQ ' ! 1165: .if n .ds CQ ' ! 1166: .if n .ds em -- ! 1167: .if t .ds oq `` ! 1168: .if t .ds cq '' ! 1169: .if t .ds OQ ` ! 1170: .if t .ds CQ ' ! 1171: .if t .ds em \(em ! 1172: .if n .na ! 1173: .if t .if \nd=0 .ss 4 ! 1174: .if t .if \nd=1 .ss 10 ! 1175: .if t .if \nd=2 .ss 12 ! 1176: .if n .po 1i ! 1177: .if t .if \\nd=3 .po 1.0625i ! 1178: .if t .if \\nd=3 .nr PO 1.0625i ! 1179: .ds Ag a\(ga ! 1180: .ds At a\(um ! 1181: .ds Cd \o'c,' ! 1182: .ds Ea e\(aa ! 1183: .ds Eg e\(ga ! 1184: .ds Ic i\(cf\h'-\w'.'u'\^\^\^ ! 1185: .ds Na n\(aa ! 1186: .ds Ol o\(um ! 1187: .ds Oo \s-2\v'-8u'o\v'8u'\s+2 ! 1188: .ds eA E\(aa ! 1189: .ds mi - ! 1190: .if t .if !\nd .nr T. 1 ! 1191: .ie \n(T. .ds M \fM ! 1192: .el .ds M \fB ! 1193: .if \nd .ds v+ \v'.25m' ! 1194: .if \nd .ds v- \v'-.25m' ! 1195: .ds ra >\^ ! 1196: .ds lS \\*(v-+\(mi\(mi\(mi\\*(v+ ! 1197: .ds rS \\*(v-\(mi\(mi\(mi\\*(ra ! 1198: .ds rE \\*(v+ ! 1199: .ds CF \s10\fR\- \\n(PN \-\s0\fP ! 1200: .de dU ! 1201: .sp -.65 ! 1202: .. ! 1203: .de dD ! 1204: .sp -.2 ! 1205: .. ! 1206: .de Nt ! 1207: .Ds ! 1208: .ta 2.7i ! 1209: icon-project.arizona@csnet-relay \fR(CSNET or ARPANET)\fP ! 1210: arizona!icon-project \fR(Usenet and uucpnet) ! 1211: .De ! 1212: There are currently uucp connections to Arizona through ! 1213: \*Mnoao\fR, \*Mmcnc\fR, \*Mihnp4\fR, and \*Mutah-cs\fR. ! 1214: .. ! 1215: .ds U UNIX\u\s-2*\s0\d ! 1216: .de Un ! 1217: .FS ! 1218: \u\s-2*\s0\dUNIX is a trademark of AT&T Bell Laboratories. ! 1219: .FE ! 1220: .. ! 1221: .if \nv .ss 10 ! 1222: .hy 14 ! 1223: .de Gr ! 1224: .GR DCR-8401831 ! 1225: .. ! 1226: .de Gi ! 1227: .GR DCR-8502015 ! 1228: .. ! 1229: .de Gs ! 1230: .GR DCR-8401831 DCR-8502015 ! 1231: .. ! 1232: .de Nh ! 1233: .sp -.8 ! 1234: .NH ! 1235: .. ! 1236: .de Wd ! 1237: .ll 7.8i ! 1238: .lt 7.8i ! 1239: .nr LL 7.8i ! 1240: .nr LT 7.8i ! 1241: .. ! 1242: .de Pf ! 1243: .nr VS 20 ! 1244: .vs 20 ! 1245: .. ! 1246: .de do ! 1247: .if '\\$1'' .in +.5i ! 1248: .if !'\\$1'' .in +\\$1 ! 1249: .vs 6p ! 1250: \&. ! 1251: \&.\\$2 ! 1252: \&. ! 1253: .vs ! 1254: .in ! 1255: .. ! 1256: .de Ve ! 1257: .nf ! 1258: .sp -.5 ! 1259: .do .74i ! 1260: .. ! 1261: .de tR ! 1262: .de SY ! 1263: .ch FO 16i ! 1264: .ch FX 16i ! 1265: .ll \\n(LLu ! 1266: .rs ! 1267: .sp |13P ! 1268: .ns ! 1269: .if \\n(TV .TY ! 1270: .if \\n(AV .AX ! 1271: .rs ! 1272: .sp |22P ! 1273: .if !'\\*(MN'' \\*(MN ! 1274: .ce 0 ! 1275: .nf ! 1276: .sp |28P ! 1277: .ls 1 ! 1278: .ll -\\n(.lu/12u ! 1279: .WB ! 1280: .ll \\n(LLu ! 1281: .ls ! 1282: .ce 1000 ! 1283: .sp |8i ! 1284: \\*(DY ! 1285: .sp 2 ! 1286: Department of Computer Science ! 1287: .sp 1 ! 1288: The University of Arizona ! 1289: .sp 1 ! 1290: Tucson, Arizona 85721 ! 1291: .ce 0 ! 1292: .sp |10i ! 1293: .na ! 1294: .fi ! 1295: .GX ! 1296: .br ! 1297: .. ! 1298: .. ! 1299: .ds d \s+5\fR\&.\h'-1.5p'\fP\s-5 ! 1300: .ds t ! 1301: .ds >= >= ! 1302: .ds >: >: ! 1303: .ds >> >> ! 1304: .ds <= <= ! 1305: .ds <: <: ! 1306: .ds << << ! 1307: .ds <- <- ! 1308: .ds -> -> ! 1309: .ds <> <-> ! 1310: .if n .fp 4 M c1 ! 1311: .ds cf ^ ! 1312: .ds fm ' ! 1313: .ds sl / ! 1314: .ds v \fR|\fP ! 1315: .ds b \| ! 1316: .ds El \fR.\^.\^.\fP ! 1317: .ds sd \s8\v'.2m'\h'-0.4n' ! 1318: .ds su \v'-.2m'\s0 ! 1319: .ds 0 \fIexpr\fP ! 1320: .ds 1 \fIexpr\*(sd1\*(su\fP ! 1321: .ds 2 \fIexpr\*(sd2\*(su\fP ! 1322: .ds 3 \fIexpr\*(sd3\*(su\fP ! 1323: .ds 4 \fIexpr\*(sd4\*(su\fP ! 1324: .ds 5 \fIexpr\*(sd5\*(su\fP ! 1325: .ds i \fIexpr\*(sdi\*(su\fP ! 1326: .ds n \fIexpr\*(sdn\*(su\fP ! 1327: .ds z \fIexpr\*(sd0\*(su\fP ! 1328: .de Ds ! 1329: .DS ! 1330: .tr -\\-'\\(fm/\\(sl ! 1331: .ie \n(T. .ss9 ! 1332: .el .ss 20 ! 1333: .Ta ! 1334: .In ! 1335: .if t \\*M\c ! 1336: .. ! 1337: .de De ! 1338: .ie \n(T. .ss4 ! 1339: .el .ss 10 ! 1340: .DE ! 1341: .ft R ! 1342: .tr -\\*(mi'\\*(fm/\\*(sl ! 1343: .. ! 1344: .de Dd ! 1345: .De ! 1346: .sp -.4 ! 1347: .Ds ! 1348: .. ! 1349: .de Ua ! 1350: Technical Report \\$1, Department of Computer Science, The University of Arizona. ! 1351: .. ! 1352: .de ! 1353: .if \nv .ss 10 ! 1354: .if \nv .rm CM ! 1355: .de Li ! 1356: .Sd ! 1357: .de Ta ! 1358: .ta 3i ! 1359: \\.. ! 1360: .de Ti ! 1361: .ce 10 ! 1362: \f3\\\\$1\f1 ! 1363: .ce 0 ! 1364: .sp 2 ! 1365: .ds RF \s10\*(DY\s0 ! 1366: .ds LF \s10\\\\$3\s0 ! 1367: 'so \\\\$2 ! 1368: .bp ! 1369: \\.. ! 1370: .. ! 1371: .de Sd ! 1372: .am Ds ! 1373: .ps 8 ! 1374: .vs 10 ! 1375: .nr PS 8 ! 1376: .nr VS 10 ! 1377: \\.. ! 1378: .am De ! 1379: .nr VS 12 ! 1380: .nr PS 10 ! 1381: .vs 12 ! 1382: .ps 10 ! 1383: \\.. ! 1384: .. ! 1385: .de Qs ! 1386: .br ! 1387: .ps -1p ! 1388: .vs -1p ! 1389: .in +5n ! 1390: .ll -5n ! 1391: .sp ! 1392: .. ! 1393: .de Qe ! 1394: .br ! 1395: .ps +1p ! 1396: .vs +1p ! 1397: .in -5n ! 1398: .ll +5n ! 1399: .sp ! 1400: .. ! 1401: .de Qd ! 1402: .Qe ! 1403: .sp -.7 ! 1404: .Qs ! 1405: .. ! 1406: .de Ap ! 1407: .bp ! 1408: .ce 10 ! 1409: \f3\\$1\f1 ! 1410: .ce 0 ! 1411: .sp 2 ! 1412: .if !''\\$2' .so \\$2 ! 1413: .. ! 1414: .if \nd=3 .po 1.0625i ! 1415: .if \nd=3 .nr PO 1.0625i ! 1416: .if \nd=3 .ds M \fH ! 1417: .de CS ! 1418: .cs H 22 ! 1419: .ft H ! 1420: .. ! 1421: .de CE ! 1422: .cs H ! 1423: .ft R ! 1424: .. ! 1425: .DA "June 4, 1986" ! 1426: .TR 86-13a ! 1427: .Gr ! 1428: .TL ! 1429: The Icon Program Library; Version 6.0 ! 1430: .AU ! 1431: Ralph E. Griswold ! 1432: .AE ! 1433: .tr *\(** ! 1434: .SH ! 1435: Introduction ! 1436: .PP ! 1437: This version of the Icon program library is intended for use with ! 1438: Version 6.0 of Icon. ! 1439: Basic documentation for Version 6 of Icon is contained in the Icon book\*([<\*([[1\*(]]\*(>] ! 1440: and a supplementary report\*([<\*([[2\*(]]\*(>]. ! 1441: .PP ! 1442: The library contains both complete programs and collections ! 1443: of procedures. The programs range from demonstrations and games to ! 1444: text-processing utilities. The procedures range from straightforward ! 1445: extensions to Icon's function repertoire to such ! 1446: relatively esoteric subjects as programmer-defined control operations. ! 1447: This manual is divided into two main parts according to the ! 1448: composition of the library: ! 1449: complete programs and collections of procedures. ! 1450: .PP ! 1451: While the library provides some useful application programs and ! 1452: components that may be helpful in building other programs, it also ! 1453: provides examples of Icon programming techniques. In particular, persons ! 1454: who are new to Icon may find it helpful to read the source code for ! 1455: the library to see how experienced persons program in Icon. While ! 1456: not all of the code is the best possible \(em far from it \(em ! 1457: it illustrates useful idioms and a variety programming techniques. ! 1458: .PP ! 1459: In the descriptions that follow, there are pointers to interesting ! 1460: programming techniques as well as several suggestions for ! 1461: extensions and improvements to programs. ! 1462: Such extensions are good exercises ! 1463: persons who are just starting in Icon. Some of these extensions, however, will ! 1464: challenge the most experienced Icon programmer. ! 1465: .SH ! 1466: Library Format ! 1467: .PP ! 1468: The root directory of the library is \*Mipl\fR (``Icon program library''). ! 1469: There are four subdirectories: \*Msource\fR, \*Mprogs\fR, \*Mprocs\fR, ! 1470: and \*Mdata\fR. ! 1471: The subdirectory \*Msource\fR contains Icon source code for both ! 1472: programs and procedure libraries. Compiled programs are in \*Mprogs\fR ! 1473: and translated procedures are in \*Mprocs\fR. ! 1474: The subdirectory \*Mdata\fR contains sample input for programs in ! 1475: \*Mprogs\fR. The names of programs and data files generally ! 1476: coincide, with the extensions of data files providing some ! 1477: differentiating identification. For example, the data file ! 1478: \*Mcsgen.abc\fR is input to the program \*Mcsgen\fR. There are ! 1479: also several files with the extension \*M.txt\fR ! 1480: that contain English-language text ! 1481: that is suitable as input to any of the programs ! 1482: that process text files. ! 1483: .SH ! 1484: Disclaimer ! 1485: .PP ! 1486: The material contained in the Icon program library is provided on ! 1487: an as-is basis. No claim is made that the programs are free of error ! 1488: or that they will function properly. ! 1489: The responsibility for the use of library material resides entirely ! 1490: with the user. ! 1491: .PP ! 1492: Notes of errors will be appreciated and corrections will be incorporated ! 1493: in future releases of the library. ! 1494: .SH ! 1495: New Material ! 1496: .PP ! 1497: Additions are made to the Icon program library from time to time. ! 1498: New material ! 1499: is welcome. Such material should be sent to: ! 1500: .DS ! 1501: .ft R ! 1502: Icon Project ! 1503: Department of Computer Science ! 1504: The University of Arizona ! 1505: Tucson, AZ 87521 ! 1506: .DE ! 1507: Documentation similar in form to that provided in this manual \fImust\fR ! 1508: be included and test data should be provided where appropriate. ! 1509: The final decision on inclusion of material in the library resides ! 1510: with the Icon Project. ! 1511: .SH ! 1512: Acknowledgements ! 1513: .PP ! 1514: Several persons have contributed programs and procedures to the ! 1515: Icon program library. ! 1516: In addition to the author of this manual, these persons include ! 1517: Allan Anderson, Ward Cunningham, Tom Hicks, William ! 1518: Malloy, Bill Mitchell, Mike Novak, Randal Schwartz, ! 1519: Steve Wampler, and George Yee. See the source files for specific attributions. ! 1520: .ds CH \s10Programs\s0 ! 1521: .bp ! 1522: .SH ! 1523: Introduction ! 1524: .PP ! 1525: Most programs take input from standard input and write ! 1526: output to standard output. ! 1527: Input and output can be redirected and piped in the usual fashion. ! 1528: For example, ! 1529: .Ds ! 1530: csgen <..\edata\ecsgen.abc | more ! 1531: .De ! 1532: runs the program \*Mcsgen\fR\s-2\u1\d\s0 on the data file \*Mcsgen.abc\fR in the parallel ! 1533: .FS ! 1534: \s-2\u1\d\s0\^On some systems, including DOS\*([<\*([[3\*(]]\*(>] and VMS\*([<\*([[4\*(]]\*(>], ! 1535: compiled programs cannot be run directly, but must be executed using ! 1536: \*Miconx\fR. For DOS, the example above is done as follows: ! 1537: .Ds ! 1538: iconx csgen <..\edata\ecsgen.abc | more ! 1539: .De ! 1540: .FE ! 1541: subdirectory and pipes the output through \*Mmore\fR. ! 1542: .PP ! 1543: Many programs take ! 1544: command line arguments, which may be the names of files to ! 1545: process or options that select specific processing functions. ! 1546: An option is prefixed by a dash, sometimes followed by an ! 1547: argument. For example, ! 1548: .Ds ! 1549: deal -h 5 ! 1550: .De ! 1551: runs the program \*Mdeal\fR with the option \*M\-h\fR and the ! 1552: argument \*M5\fR. ! 1553: .PP ! 1554: If a program is not called with the proper options or arguments, ! 1555: it generally terminates with an error message such as ! 1556: .Ds ! 1557: usage: [ -h n ] [ -s n ] ! 1558: .De ! 1559: which indicates the proper usage. Some programs provide ! 1560: more specific errors messages. Error messages are written ! 1561: to standard error output. Standard error output ! 1562: is always written to the console and cannot be ! 1563: redirected. Consult the descriptions of the ! 1564: programs that follow for details. ! 1565: .PP ! 1566: The programs that follow are divided into categories by their function. ! 1567: .NH ! 1568: Demonstrations and Games ! 1569: .PP ! 1570: .NH 2 ! 1571: Non-Attacking Queens: \*Mqueens\fR ! 1572: .PP ! 1573: This program displays the solutions to the non-attacking ! 1574: \fIn\fR-queens problem: the ways in which \fIn\fR queens can be ! 1575: placed on an \fIn\fR-by-\fIn\fR chessboard so that no queen can ! 1576: attack another. A positive integer can be given as a command line ! 1577: argument to specify the number of queens. For example, ! 1578: .Ds ! 1579: iconx queens 8 ! 1580: .De ! 1581: displays the solutions for 8 queens on an 8-by-8 chessboard. ! 1582: The default value in the absence of an argument is 6. ! 1583: One solution for six queens is: ! 1584: .br ! 1585: .ne 1.8i ! 1586: .in .5i ! 1587: .CS ! 1588: \-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\- ! 1589: | | Q | | | | | ! 1590: \-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\- ! 1591: | | | | Q | | | ! 1592: \-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\- ! 1593: | | | | | | Q | ! 1594: \-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\- ! 1595: | Q | | | | | | ! 1596: \-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\- ! 1597: | | | Q | | | | ! 1598: \-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\- ! 1599: | | | | | Q | | ! 1600: \-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\- ! 1601: .sp .1 ! 1602: .CE ! 1603: .in 0 ! 1604: .LP ! 1605: \fBComments:\fR ! 1606: There are many approaches to programming solutions to the \fIn\fR-queens problem. ! 1607: This library program is worth reading for its ! 1608: programming techniques. Other solutions may be found in ! 1609: \*([[1\*(]] and\*([<\*([[5\*(]]\*(>]. ! 1610: .NH 2 ! 1611: Word Intersections: \*Mcross\fR ! 1612: .PP ! 1613: This program takes a list of words and tries to arrange them ! 1614: in cross-word format so that they intersect. Uppercase letters ! 1615: are mapped into lowercase letters on input. ! 1616: For example, the input ! 1617: .Ds ! 1618: and ! 1619: eggplants ! 1620: elephants ! 1621: purple ! 1622: .De ! 1623: produces the output ! 1624: .ne 2i ! 1625: .CS ! 1626: .nf ! 1627: .in .5i ! 1628: +\-\-\-\-\-\-\-\-\-+ ! 1629: | p | ! 1630: | u e | ! 1631: | r g | ! 1632: | p g | ! 1633: |elephants| ! 1634: | e l | ! 1635: | and | ! 1636: | n | ! 1637: | t | ! 1638: | s | ! 1639: +\-\-\-\-\-\-\-\-\-+ ! 1640: .in 0 ! 1641: .CE ! 1642: .LP ! 1643: \fBDiagnostics:\fR ! 1644: The program objects if the input contains a nonalphabetic ! 1645: character. ! 1646: .LP ! 1647: \fBComments:\fR ! 1648: This program produces only one possible intersection and ! 1649: it does not attempt to produce the most compact result. ! 1650: The program is not very fast, either. ! 1651: There is a lot of room for improvement here. In particular, ! 1652: it is natural for Icon to generate a sequence of solutions. ! 1653: .NH 2 ! 1654: Bridge Hands: \*Mdeal ! 1655: .PP ! 1656: This program shuffles, deals, and displays hands in the game of bridge. ! 1657: An example of the output of \*Mdeal\fR is ! 1658: .br ! 1659: .ne 2.2i ! 1660: .CS ! 1661: .in .5i ! 1662: .nf ! 1663: \-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\- ! 1664: ! 1665: S: KQ987 ! 1666: H: 52 ! 1667: D: T94 ! 1668: C: T82 ! 1669: ! 1670: S: 3 S: JT4 ! 1671: H: T7 H: J9863 ! 1672: D: AKQ762 D: J85 ! 1673: C: QJ94 C: K7 ! 1674: ! 1675: S: A652 ! 1676: H: AKQ4 ! 1677: D: 3 ! 1678: C: A653 ! 1679: ! 1680: \-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\- ! 1681: .in 0 ! 1682: .CE ! 1683: .LP ! 1684: \fBOptions:\fR ! 1685: The following options are available: ! 1686: .RS ! 1687: .IP "\*M\-h\fI n\fR" .5i ! 1688: Produce \fIn\fR hands. The default is 1. ! 1689: .IP "\*M\-s\fI n\fR" ! 1690: Set the seed for random generation to \fIn\fR. ! 1691: Different seeds give different hands. ! 1692: The default seed is 0. ! 1693: .RE ! 1694: .NH 2 ! 1695: Farberisms: \*Mfarb ! 1696: .PP ! 1697: Dave Farber, co-author of the original SNOBOL programming language, ! 1698: is noted for his creative use of the English language. Hence the ! 1699: terms ``farberisms'' and ``to farberate''. ! 1700: This program produces a randomly selected farberism. ! 1701: .LP ! 1702: \fBNotes:\fR Not all of the farberisms contained in this program were ! 1703: uttered by the master himself; others have learned to emulate him. ! 1704: A few of the farberisms may be objectionable to some persons. ! 1705: ``I wouldn't marry her with a twenty-foot pole.'' ! 1706: .NH ! 1707: Random Strings ! 1708: .PP ! 1709: The programs in this section involve the random generation of ! 1710: strings according to various criteria. ! 1711: These programs are only loosely related to each other. ! 1712: .NH 2 ! 1713: Random Sentence Generation: \*Mrsg ! 1714: .PP ! 1715: This program generates randomly selected strings (``sentences'') ! 1716: from a grammar specified by ! 1717: the user. ! 1718: Grammars are basically context-free and resemble BNF in form, although ! 1719: there are a number of extensions. ! 1720: .PP ! 1721: The program works interactively, allowing the user to build, test, modify, ! 1722: and save grammars. Input to \*Mrsg\fR consists of various kinds of ! 1723: specifications, which can be intermixed: ! 1724: .PP ! 1725: \fIProductions\fR define nonterminal symbols in a syntax similar to ! 1726: the rewriting rules of BNF with various alternatives consisting ! 1727: of the concatenation of nonterminal and terminal symbols. ! 1728: \fIGeneration specifications\fR cause the generation of a specified ! 1729: number of sentences from the language defined by a given nonterminal ! 1730: symbol. ! 1731: \fIGrammar output specifications\fR cause the definition of a ! 1732: specified nonterminal or the entire current grammar to be written ! 1733: to a given file. ! 1734: \fISource specifications\fR cause subsequent input to be read from ! 1735: a specified file. ! 1736: .PP ! 1737: In addition, any line beginning with \*M#\fR is considered to be ! 1738: a comment, while any line beginning with \*M=\fR causes the rest ! 1739: of that line to be used subsequently as a prompt to the user whenever \*Mrsg\fR ! 1740: is ready for input (there normally is no prompt). A line consisting ! 1741: of a single \*M=\fR stops prompting. ! 1742: .LP ! 1743: \fBProductions:\fR ! 1744: Examples of productions are: ! 1745: .Ds ! 1746: <expr>::=<term>|<term>+<expr> ! 1747: <term>::=<elem>|<elem>*<term> ! 1748: <elem>::=x|y|z|(<expr>) ! 1749: .De ! 1750: Productions may occur in any order. The definition for a nonterminal ! 1751: symbol can be changed by specifying a new production for it. ! 1752: .PP ! 1753: There are a number of special devices to facilitate the definition of ! 1754: grammars, including eight predefined, built-in nonterminal symbols: ! 1755: .nf ! 1756: .sp .5 ! 1757: .ta .3i 1.2i ! 1758: symbol definition ! 1759: .sp .5 ! 1760: \*M<lb> < ! 1761: <rb> > ! 1762: <vb> | ! 1763: <nl>\fR newline ! 1764: \*M<>\fR empty string ! 1765: \*M<&lcase>\fR any single lowercase letter ! 1766: \*M<&ucase>\fR any single uppercase letter ! 1767: \*M<&digit>\fR any single digit ! 1768: .sp 1 ! 1769: .fi ! 1770: In addition, if the string between a \*M<\fR and a \*M>\fR ! 1771: begins and ! 1772: ends with a single quotation mark, it stands for ! 1773: any single character between the quotation marks. For example, ! 1774: .Ds ! 1775: <'xyz'> ! 1776: .De ! 1777: is equivalent to ! 1778: .Ds ! 1779: x|y|z ! 1780: .De ! 1781: Finally, if the name of a nonterminal symbol between the \*M<\fR and ! 1782: \*M>\fR begins with \*M?\fR, the user is queried during generation ! 1783: to supply a string for that nonterminal symbol. For example, in ! 1784: .Ds ! 1785: <expr>::=<?term>|<term>+<expr> ! 1786: .De ! 1787: if the first alternative is encountered during generation, the user is ! 1788: asked to provide a string for \*M<term>\fR. ! 1789: Note that this is a \fIstrongly\fR context-sensitive feature. ! 1790: .LP ! 1791: \fBGeneration Specifications:\fR ! 1792: A generation specification consists of a nonterminal symbol ! 1793: followed by a nonnegative integer. An example is ! 1794: .Ds ! 1795: <expr>10 ! 1796: .De ! 1797: which specifies the generation of 10 \*M<expr>\fRs. If the ! 1798: integer is omitted, it is assumed to be 1. Generated sentences ! 1799: are written to standard output. ! 1800: .LP ! 1801: \fBGrammar Output Specifications:\fR ! 1802: A grammar output specification consists of a nonterminal symbol, ! 1803: followed by \*M\->\fR, followed by a file name. Such a specification ! 1804: causes the current definition of the nonterminal symbol to be ! 1805: written to the given file. If the file is omitted, standard output ! 1806: is assumed. If the nonterminal symbol is omitted, the entire grammar ! 1807: is written out. Thus, ! 1808: .Ds ! 1809: \-> ! 1810: .De ! 1811: causes the entire grammar to be written to standard output. ! 1812: .LP ! 1813: \fBSource Specifications:\fR ! 1814: A source specification consists of \*M@\fR followed by a file name. ! 1815: Subsequent input is read from that file. When an end of file is encountered, ! 1816: input reverts to the previous file. Input files can be nested. ! 1817: .LP ! 1818: \fBOptions:\fR ! 1819: The following options are available: ! 1820: .RS ! 1821: .IP "\*M\-s\fI n\fR" .5i ! 1822: Set the seed for random generation to \fIn\fR. ! 1823: The default seed is 0. ! 1824: .IP "\*M\-l\fI n\fR" ! 1825: Terminate generation if the number of symbols remaining to be processed ! 1826: exceeds \fIn\fR. There is no default limit. ! 1827: .IP \*M\-t\fR ! 1828: Trace the generation of sentences. Trace output goes to standard error ! 1829: output. ! 1830: .RE ! 1831: .LP ! 1832: \fBDiagnostics:\fR ! 1833: Syntactically erroneous input lines are noted but are otherwise ignored. ! 1834: Specifications for a file that cannot be opened are noted and treated as ! 1835: erroneous. ! 1836: .PP ! 1837: If an undefined nonterminal symbol is encountered during generation, ! 1838: an error message that identifies the undefined symbol is produced, ! 1839: followed by the partial sentence generated to that point. Exceeding ! 1840: the limit of symbols remaining to be generated as specified by ! 1841: the \*M\-l\fR option is handled similarly. ! 1842: .LP ! 1843: \fBCaveats:\fR ! 1844: Generation may fail to terminate because of a loop in the rewriting ! 1845: rules or, more seriously, because of the progressive accumulation ! 1846: of nonterminal symbols. The latter problem can be identified ! 1847: by using the \*M\-t\fR option and controlled by using the \*M\-l\fR ! 1848: option. The problem often can be circumvented by duplicating alternatives ! 1849: that lead to fewer rather than more nonterminal symbols. For ! 1850: example, changing ! 1851: .Ds ! 1852: <term>::=<elem>|<elem>*<term> ! 1853: .De ! 1854: to ! 1855: .Ds ! 1856: <term>::=<elem>|<elem>|<elem>*<term> ! 1857: .De ! 1858: increases the probability of selecting \*M<elem>\fR from 1/2 to 2/3. ! 1859: See\*([<\*([[6\*(]]\*(>] for a discussion of the general ! 1860: problem. ! 1861: .LP ! 1862: \fBComments:\fR This program is an extension and elaboration of ! 1863: a program described in some detail in\*([<\*([[1\*(]]\*(>]. It illustrates ! 1864: many features of Icon, including a combination of string and ! 1865: list processing as well as extensive use of generators. The source ! 1866: code is worth studying. ! 1867: .PP ! 1868: There are many possible extensions to the program. One of the most ! 1869: useful would be a way to specify the probability of selecting ! 1870: an alternative. ! 1871: .NH 2 ! 1872: Context-Sensitive Generation: \*Mcsgen ! 1873: .PP ! 1874: This program accepts a context-sensitive production grammar ! 1875: and generates randomly selected sentences from the corresponding ! 1876: language. ! 1877: See\*([<\*([[7\*(]]\*(>] for a discussion of such grammars. ! 1878: .PP ! 1879: Uppercase letters stand for nonterminal symbols and \*M\->\fR indicates the ! 1880: lefthand side can be rewritten by the righthand side. Other characters ! 1881: are considered to be terminal symbols. Lines beginning with \*M#\fR ! 1882: are considered to be comments and are ignored. ! 1883: A line consisting of a nonterminal symbol followed by a colon and ! 1884: a nonnegative integer \*Mi\fR is a generation specification for \fIi\fR ! 1885: instances of sentences for the language defined by the nonterminal ! 1886: (goal) symbol. ! 1887: An example of input to \*Mcsgen\fR is: ! 1888: .Ds ! 1889: # a(n)b(n)c(n) ! 1890: # Salomaa, p. 11. ! 1891: # Attributed to M. Soittola. ! 1892: # ! 1893: X\->abc ! 1894: X\->aYbc ! 1895: Yb\->bY ! 1896: Yc\->Zbcc ! 1897: bZ\->Zb ! 1898: aZ\->aaY ! 1899: aZ\->aa ! 1900: X:10 ! 1901: .De ! 1902: The output of \*Mcsgen\fR for this example is ! 1903: .Ds ! 1904: aaabbbccc ! 1905: aaaaaaaaabbbbbbbbbccccccccc ! 1906: abc ! 1907: aabbcc ! 1908: aabbcc ! 1909: aaabbbccc ! 1910: aabbcc ! 1911: abc ! 1912: aaaabbbbcccc ! 1913: aaabbbccc ! 1914: .De ! 1915: .PP ! 1916: A positive integer followed by a colon can be prefixed to a production ! 1917: to replicate that production, making its selection more likely. For ! 1918: example, ! 1919: .Ds ! 1920: 3:X\->abc ! 1921: .De ! 1922: is equivalent to ! 1923: .Ds ! 1924: X\->abc ! 1925: X\->abc ! 1926: X\->abc ! 1927: .De ! 1928: .LP ! 1929: \fBOption:\fR ! 1930: The \*M\-t\fR option writes a trace of the derivations to standard ! 1931: error output. ! 1932: .LP ! 1933: \fBLimitations\fR: ! 1934: Nonterminal symbols can only be represented by single uppercase letters, ! 1935: and there is no way to represent uppercase letters as terminal symbols. ! 1936: .PP ! 1937: There can be only one generation specification and it must appear as ! 1938: the last line of input. ! 1939: .LP ! 1940: \fBComments:\fR ! 1941: Generation of context-sensitive strings is a slow process. It may not ! 1942: terminate, either because of a loop in the rewriting rules ! 1943: or because of the progressive accumulation of nonterminal symbols. ! 1944: The program avoids deadlock, in which there are no possible rewrites for ! 1945: a string in the derivation. ! 1946: .PP ! 1947: This program would be improved if the specification of nonterminal ! 1948: symbols were more general, as in \*Mrsg\fR. ! 1949: .NH 2 ! 1950: Parenthesis-Balanced Strings: \*Mparens ! 1951: .PP ! 1952: This program produces parenthesis-balanced strings in which the ! 1953: parentheses are randomly distributed. ! 1954: .LP ! 1955: \fBOptions:\fR ! 1956: The following options are available: ! 1957: .RS ! 1958: .IP \*M\-b\0\fIn\fR .5i ! 1959: Bound the length of the strings to \fIn\fR left and right parentheses each. The default is 10. ! 1960: .IP \*M\-n\0\fIn\fR ! 1961: Produce \fIn\fR strings. The default is 10. ! 1962: .IP \*M\-l\0\fIs\fR ! 1963: Use the string \fIs\fR for the left parenthesis. The default is \*M(\fR . ! 1964: .IP \*M\-r\0\fIs\fR ! 1965: Use the string \fIs\fR for the right parenthesis. The default is \*M)\fR . ! 1966: .IP \*M\-v\fR ! 1967: Randomly vary the length of the strings between 0 and the bound. ! 1968: In the absence of this option, all strings are the exactly as long ! 1969: as the specified bound. ! 1970: .RE ! 1971: .PP ! 1972: For example, the output for ! 1973: .Ds ! 1974: parens -v -b 4 -l "begin " -r "end " ! 1975: .De ! 1976: is ! 1977: .Ds ! 1978: begin end ! 1979: begin end begin end ! 1980: begin begin end end begin end ! 1981: begin end begin begin end end ! 1982: begin end ! 1983: begin begin end end ! 1984: begin begin begin end end end ! 1985: begin end begin begin end end ! 1986: begin end begin end ! 1987: begin begin end begin end begin end end ! 1988: .De ! 1989: .LP ! 1990: \fBComments:\fR This program was motivated by the need for test ! 1991: data for error repair schemes for block-structured programming ! 1992: langauges. ! 1993: See\*([<\*([[8\*(]]\*(>]. A useful ! 1994: extension to this program would be some way of generating other ! 1995: text among the parentheses. ! 1996: In addition to the intended use of the program, it can produce ! 1997: a variety of interesting patterns, depending on the strings ! 1998: specified by \*M\-l\fR and \*M\-r\fR. ! 1999: .NH 2 ! 2000: Shuffled Files: \*Mshuffile ! 2001: .PP ! 2002: This program writes a version of the input file with ! 2003: the lines shuffled. ! 2004: For example, the result of shuffling ! 2005: .Ds ! 2006: On the Future!-how it tells ! 2007: Of the rapture that impells ! 2008: To the swinging and the ringing ! 2009: Of the bells, bells, bells- ! 2010: Of the bells, bells, bells, bells, ! 2011: Bells, bells, bells- ! 2012: To the rhyming and the chiming of the bells! ! 2013: .De ! 2014: is ! 2015: .Ds ! 2016: To the rhyming and the chiming of the bells! ! 2017: To the swinging and the ringing ! 2018: Bells, bells, bells- ! 2019: Of the bells, bells, bells- ! 2020: On the Future!-how it tells ! 2021: Of the bells, bells, bells, bells, ! 2022: Of the rapture that impells ! 2023: .De ! 2024: .LP ! 2025: \fBOption:\fR ! 2026: The option \*M\-s\fI n\fR sets the seed for random generation to \fIn\fR. ! 2027: The default seed is 0. ! 2028: .LP ! 2029: \fBLimitation:\fR ! 2030: This program stores the input file in memory and shuffles pointers to ! 2031: the lines; there must be enough memory available to store the entire ! 2032: file. ! 2033: .ig ! 2034: .NH ! 2035: Turing Machines ! 2036: .NH ! 2037: Indexes ! 2038: .. ! 2039: .NH ! 2040: Text Tabulation ! 2041: .NH 2 ! 2042: Character Tabulation:\*M tablc ! 2043: .PP ! 2044: This program tabulates characters and lists ! 2045: each character and the number of times it ! 2046: occurs. Characters are written using Icon's escape conventions. ! 2047: Line termination characters and other control characters are included in the tabulation. ! 2048: .LP ! 2049: \fBOptions:\fR ! 2050: The following options are available: ! 2051: .RS ! 2052: .IP \*M\-a\fP .5i ! 2053: Write the summary in alphabetical order of the characters. This is the ! 2054: default. ! 2055: .IP \*M\-n\fP ! 2056: Write the summary in numerical order of the counts. ! 2057: .IP \*M\-u\fP ! 2058: Write only the characters that occur just once. ! 2059: .RE ! 2060: .NH 2 ! 2061: Word Tabulation: \*Mtablw ! 2062: .PP ! 2063: This program tabulates words and lists ! 2064: number of times each word ! 2065: occurs. A word is defined to be a string of consecutive ! 2066: upper- and lowercase letters with at most one interior occurrence ! 2067: of a dash or apostrophe. ! 2068: .LP ! 2069: \fBOptions:\fR ! 2070: The following options are available: ! 2071: .RS ! 2072: .IP \*M\-a\fP .5i ! 2073: Write the summary in alphabetical order of the words. This is the ! 2074: default. ! 2075: .IP \*M\-i\fR ! 2076: Ignore case distinctions among letters; uppercase letters are mapped into ! 2077: to corresponding lowercase letters on input. The default is to ! 2078: maintain case distinctions. ! 2079: .IP \*M\-n\fP ! 2080: Write the summary in numerical order of the counts. ! 2081: .IP "\*M\-l \fIn\fR" ! 2082: Tabulate only words longer than \fIn\fR characters. The default ! 2083: is to tabulate all words. ! 2084: .IP \*M\-u\fP ! 2085: Write only the words that occur just once. ! 2086: .RE ! 2087: .NH ! 2088: Mailing Labels ! 2089: .NH 2 ! 2090: Produce Mailing Labels: \*Mlabels ! 2091: .PP ! 2092: This program produces labels using ! 2093: coded information taken from the input file. In the input file, a line ! 2094: beginning with \*M#\fR is a label header. Subsequent lines up to the ! 2095: next header or end-of-file are accumulated and output so as to be ! 2096: centered horizontally and vertically on ! 2097: label forms. Lines beginning with \*M*\fR are treated as comments ! 2098: and are ignored. ! 2099: .LP ! 2100: \fBOptions:\fR ! 2101: The following options are available: ! 2102: .RS ! 2103: .IP \*M\-c\ \fIn\fR .5i ! 2104: Print \fIn\fR copies of each label. ! 2105: .IP "\*M\-s\fP\0\fIs\fP" ! 2106: Select only those labels whose headers contain a character ! 2107: in \fIs\fP. ! 2108: .IP \*M\-t\fP ! 2109: Format for curved tape labels (the default is to format ! 2110: for rectangular mailing labels). ! 2111: .IP "\*M\-w\ \fIn\fR" ! 2112: Limit line width to \fIn\fR characters. The default width is 40. ! 2113: .IP "\*M\-l\ \fIn\fR" ! 2114: Limit the number of printed lines per label to \fIn\fR. The default ! 2115: is 8. ! 2116: .IP "\*M\-d\ \fIn\fR" ! 2117: Limit the depth of the label to \fIn\fR. The default is 9 for ! 2118: rectangular labels and 12 for tape labels (\*M\-t\fR). ! 2119: .IP \*M\-f\fR ! 2120: Print the first line of each selected entry instead of labels. ! 2121: .RE ! 2122: .PP ! 2123: Options are processed from left to right. ! 2124: If the number of printed lines is set to a value that exceeds the depth of the label, the ! 2125: depth is set to the number of lines. ! 2126: If the depth is set to a value that is less than the number of printed ! 2127: lines, the number of printed lines is set to the depth. Note that ! 2128: the order in which these options are specified may affect the ! 2129: results. ! 2130: .LP ! 2131: \fBPrinting Labels:\fR ! 2132: Label forms should be used with a pin-feed platen. For mailing labels, ! 2133: the carriage ! 2134: should be adjusted so that the first character is printed at the ! 2135: leftmost position on the label and so that the first line of the ! 2136: output is printed on the topmost line of the label. ! 2137: For curved tape labels, some experimentation may be required ! 2138: to get the text positioned properly. ! 2139: .LP ! 2140: \fBDiagnostics:\fR ! 2141: If the limits on line width or the number of lines per label are exceeded, ! 2142: a label ! 2143: with an error message is written to standard error output. ! 2144: .NH 2 ! 2145: Zip Code Sorting: \*Mzipsort ! 2146: .PP ! 2147: This program sorts labels produced by \*Mlabels\fR in ascending order of ! 2148: their postal zip codes. ! 2149: .LP ! 2150: \fBOption:\fR ! 2151: The option \*M\-d\ \fIn\fR sets the number of lines per label to \fIn\fR. ! 2152: The default is 9. This value must agree with the value used to format ! 2153: the labels. ! 2154: .LP ! 2155: \fBZip Codes:\fR ! 2156: The zip code must be the last nonblank string at the end of the label. ! 2157: It must consist of digits but may have an embedded dash for extended zip codes. ! 2158: If a label does not end with a legal zip code, ! 2159: it is placed after ! 2160: all labels with legal zip codes. ! 2161: In such a case, an error messages also is written to standard error ! 2162: output. ! 2163: .NH ! 2164: Laminated Files ! 2165: .NH 2 ! 2166: Laminating Files: \*Mlam ! 2167: .PP ! 2168: This program laminates files named on the command line onto the standard output, ! 2169: producing a concatenation ! 2170: of corresponding lines from each file named. ! 2171: If the files are different lengths, ! 2172: empty lines are substituted for missing lines in the shorter files. ! 2173: A command line argument of the form ! 2174: \*M\- \fIs ! 2175: \fRcauses the string \fIs\fR to be inserted between the concatenated ! 2176: file lines. ! 2177: .PP ! 2178: Each command line ! 2179: argument is placed in the output line ! 2180: at the point that it appears in the argument list. ! 2181: For example, lines from \*Mfile1\fR and \*Mfile2\fR can be laminated ! 2182: with a colon between each line from \*Mfile1\fR and the corresponding ! 2183: line from \*Mfile2\fR by the command ! 2184: .Ds ! 2185: lam file1 \-: file2 ! 2186: .De ! 2187: .PP ! 2188: File names and strings may appear in any order in the argument list. ! 2189: If ! 2190: \*M\-\fR ! 2191: is given for a file name, ! 2192: standard input is read at that point. ! 2193: If a file is named more than once, ! 2194: each of its lines will be duplicated on the output line, ! 2195: except that if standard input is named more than once, ! 2196: its lines will be read alternately. ! 2197: For example, each pair of lines from standard input can be ! 2198: joined onto one line with a space between them by the command ! 2199: .Ds ! 2200: lam \- "\-\0" \- ! 2201: .De ! 2202: .LP ! 2203: while the command ! 2204: .Ds ! 2205: lam file1 "\-\0" file1 ! 2206: .De ! 2207: .LP ! 2208: replicates each line from \*Mfile1\fR. ! 2209: .NH 2 ! 2210: Delaminating Files: \*Mdelam ! 2211: .PP ! 2212: This program delaminates standard input into several output files ! 2213: according to the specified fields. ! 2214: It writes the fields in each line to the ! 2215: corresponding output files as individual lines. If no data occurs in ! 2216: the specified position for a given input line an empty output line is ! 2217: written. This insures that all output files contain the same number of ! 2218: lines as the input file. ! 2219: .PP ! 2220: If \*M\-\fR is used for the input file, the standard input is read. ! 2221: If \*M\-\fR is used as an output file name, the corresponding field ! 2222: is written to the standard output. ! 2223: .PP ! 2224: The fields are defined by a list of field ! 2225: specifications, separated by commas, colons, or semicolons, of the ! 2226: following form: ! 2227: .Ds ! 2228: .ft I ! 2229: .ta .5i ! 2230: n \fRthe character in column \fIn ! 2231: n\*M\-\fIm \fRthe characters in columns \fIn\fR through \fIm ! 2232: n+m m \fRcharacters beginning at column \fIn ! 2233: .ft R ! 2234: .De ! 2235: where the columns in a line are numbered from 1 to the length of the ! 2236: line. ! 2237: .PP ! 2238: The use of \*Mdelam\fR is illustrated by the following examples. ! 2239: The command ! 2240: .Ds ! 2241: delam 1\-10,5 x.txt y.txt ! 2242: .De ! 2243: reads standard input and writes characters 1 through 10 to file \*Mx.txt\fR and ! 2244: character 5 to file \*My.txt\fR. ! 2245: The command ! 2246: .Ds ! 2247: delam 10+5:1\-10:1\-10:80 mid x1 x2 end ! 2248: .De ! 2249: writes characters 10 through 14 to ! 2250: \*Mmid\fR, 1 through 10 to \*Mx1\fR and \*Mx2\fR, and character 80 to ! 2251: \*Mend\fR. ! 2252: The command ! 2253: .Ds ! 2254: delam 1\-80;1\-80 \- \- ! 2255: .De ! 2256: copies standard input to standard output, replicating the ! 2257: first eighty columns of each line twice. ! 2258: .NH 2 ! 2259: Delaminating Files by Separators: \*Mdelamc ! 2260: .PP ! 2261: This program delaminates standard input into several output files ! 2262: according to the separator characters specified by the string ! 2263: following the \*M\-t\fR option. ! 2264: It writes the fields in each line to the ! 2265: corresponding output files as individual lines. If no data occurs in ! 2266: the specified position for a given input line an empty output line is ! 2267: written. This insures that all output files contain the same number of ! 2268: lines as the input file. ! 2269: .PP ! 2270: If \*M\-\fR is used as an output file name, the corresponding field ! 2271: is written to the standard output. If the \*M\-t\fR option is not used, ! 2272: an ascii horizontal tab character is assumed as the default ! 2273: field separator. ! 2274: .PP ! 2275: The use of \*Mdelamc\fR is illustrated by the following examples. ! 2276: The command ! 2277: .Ds ! 2278: delamc labels opcodes operands ! 2279: .De ! 2280: writes the fields of standard input, each of which ! 2281: is separated by a tab character, to the output files \*Mlabels\fR, ! 2282: \*Mopcodes\fR, ! 2283: and \*Moperands\fR. ! 2284: The command ! 2285: .Ds ! 2286: delamc \-t: scores names matric ps1 ps2 ps3 ! 2287: .De ! 2288: writes the fields of standard input, each of which are separated ! 2289: by a colon, to the indicated output files. ! 2290: The command ! 2291: .Ds ! 2292: delamc \-t,: oldata f1 f2 ! 2293: .De ! 2294: separates the fields using either a comma or a colon. ! 2295: .NH ! 2296: Icon Program Utilities ! 2297: .NH 2 ! 2298: Icon Program Cross Reference: \*Mipxref ! 2299: .PP ! 2300: This program cross-references Icon programs. It lists ! 2301: the occurrences of each variable by line number. Variables are listed ! 2302: by procedure or separately as globals. ! 2303: The options specify the formatting of the ! 2304: output and whether or not to cross-reference quoted strings and ! 2305: non-alphanumerics. Variables that are followed by a left parenthesis ! 2306: are listed with an asterisk following the name. ! 2307: If a file is not specified, then standard input is cross-referenced. ! 2308: .LP ! 2309: \fBOptions:\fR ! 2310: The following options change the format defaults: ! 2311: .RS ! 2312: .IP "\*M\-c\fR \fIn\fR" 0.5i ! 2313: The column width per line number. The default is 4 columns wide. ! 2314: .IP "\*M\-l\fR \fIn\fR" ! 2315: The starting column (i.e. left margin) of the line numbers. ! 2316: The default is column 40. ! 2317: .IP "\*M\-w\fR \fIn\fR" ! 2318: The column width of the whole output line. The default is 80 columns wide. ! 2319: .RE ! 2320: .PP ! 2321: Normally only alphanumerics are cross-referenced. These options expand ! 2322: what is considered: ! 2323: .RS ! 2324: .IP \*M\-q\fR 0.5i ! 2325: Include quoted strings. ! 2326: .IP \*M\-x\fR ! 2327: Include all non-alphanumerics. ! 2328: .RE ! 2329: .LP ! 2330: \fBNote:\fR ! 2331: This program assumes the subject file is a valid Icon program. For example, ! 2332: quotes are expected to be matched. ! 2333: .NH 2 ! 2334: Sort Icon Declarations: \*Mipsort ! 2335: .PP ! 2336: This program reads an Icon program and writes ! 2337: an equivalent program with the procedures ! 2338: sorted alphabetically. Global, link, and record declarations ! 2339: come first in the order they appear in the original program. ! 2340: The main procedure comes next followed by the remaining procedures ! 2341: in alphabetical order. ! 2342: .PP ! 2343: Comments and white space between declarations are attached to the next ! 2344: following declaration. ! 2345: .LP ! 2346: \fBLimitations:\fR ! 2347: This program only recognizes declarations that start at the beginning ! 2348: of a line. ! 2349: .PP ! 2350: Comments and interline white space between declarations may not come ! 2351: out as intended. ! 2352: .NH 2 ! 2353: Icon Program Splitting: \*Mipsplit ! 2354: .PP ! 2355: This progam reads an Icon program and writes ! 2356: each procedure to a separate file. The output file names consist of ! 2357: the procedure name with \*M.icn\fR appended. ! 2358: If the \*M\-g\fR option is specified, any ! 2359: global, link, and record declarations ! 2360: are written to that file. Otherwise they are written in the file for ! 2361: the procedure that immediately follows them. ! 2362: .PP ! 2363: Comments and white space between declarations are attached to the next ! 2364: following declaration. ! 2365: .LP ! 2366: \fBNotes:\fR ! 2367: The program only recognizes declarations that start at the beginning ! 2368: of lines. ! 2369: Comments and interline white space between declarations may not come ! 2370: out as intended. ! 2371: .PP ! 2372: If the \*M\-g\fR option is not specified, any global, link, or ! 2373: record declarations that follow the last procedure are discarded. ! 2374: .NH ! 2375: Miscellaneous Utilities ! 2376: .NH 2 ! 2377: Line Lengths: \*Mll ! 2378: .PP ! 2379: This program prints the lengths of the shortest and longest lines ! 2380: in files named on the command line. ! 2381: If there is no command line argument, the standard input is used. ! 2382: The argument \*M\-\fR may be used to explicitly specify the standard input. ! 2383: .NH 2 ! 2384: Trimming Lines: \*Mtrim ! 2385: .PP ! 2386: This program copies lines from standard input to standard output, truncating ! 2387: the lines at \fIn\fR characters and removing any trailing blanks. The ! 2388: default value for \fIn\fR is 80. ! 2389: For example, ! 2390: .Ds ! 2391: trim 70 <grade.txt >grade.fix ! 2392: .De ! 2393: copies \*Mgrade.txt\fR to \*Mgrade.fix\fR, with lines longer than ! 2394: 70 characters truncated to 70 characters and the trailing blanks removed from ! 2395: all lines. ! 2396: .PP ! 2397: The \*M\-f\fR option causes all lines to be \fIn\fR characters long ! 2398: by adding blanks to short lines; ! 2399: otherwise, short lines are left as is. ! 2400: .NH 2 ! 2401: Sorting Groups of Lines: \*Mgrpsort ! 2402: .PP ! 2403: This program sorts input containing ``records'' defined to be ! 2404: groups of consecutive lines. Output is written to standard output. ! 2405: Each input record is separated by one or more repetitions of a ! 2406: demarcation line (a line beginning with the separator string). ! 2407: The first line of each record is used as the key. ! 2408: .PP ! 2409: If no separator string is specified on the command line, ! 2410: the default is the empty string. Because all input lines ! 2411: are trimmed of whitespace (blanks and tabs), empty lines are default ! 2412: demarcation lines. The separator string specified can be an initial ! 2413: substring of the string used to demarcate lines, in which case the ! 2414: resulting partition of the input file may be different ! 2415: from a partition created using the entire demarcation string. ! 2416: .PP ! 2417: The \*M\-o\fP option sorts the input file but does not produce the sorted records. ! 2418: Instead it lists the keys (in sorted order) and line numbers defining the ! 2419: extent of the record associated with each key. ! 2420: .PP ! 2421: The use of \*Mgrpsort\fR is illustrated by the following examples. ! 2422: The command ! 2423: .Ds ! 2424: grpsort "catscats" <x >y ! 2425: .De ! 2426: sorts the file \*Mx\fR, whose records are separated by ! 2427: lines containing the ! 2428: string \*M"catscats"\fR, into the file \*My\fR placing a single line ! 2429: of \*M"catscats"\fR between each output record. Similarly, the ! 2430: command ! 2431: .Ds ! 2432: grpsort "cats" <x >y ! 2433: .De ! 2434: sorts the file \*Mx\fR as before but assumes that any line beginning with the ! 2435: string \*M"cats"\fR delimits a new record. This may or may not divide the ! 2436: lines of the input file into a number of records different from the previous ! 2437: example. ! 2438: In any case, the output records will be separated by a single line of \*M"cats"\fR. ! 2439: Another example is ! 2440: .Ds ! 2441: grpsort \-o <bibliography >bibkeys ! 2442: .De ! 2443: which sorts the file \*Mbibliography\fR and produces a sorted list of ! 2444: the keys and the extents of the associated records in \*Mbibkeys\fR. ! 2445: Each output key line is of the form: ! 2446: .ne 10 ! 2447: .Ds ! 2448: [s\-e] key ! 2449: .De ! 2450: where ! 2451: .Ds ! 2452: .ta .6i ! 2453: .ss 4 ! 2454: \*Ms\fR is the line number of the key line ! 2455: \*Me\fR is the line number of the last line ! 2456: \*Mkey\fR is the actual key of the record ! 2457: .De ! 2458: .ds CH \s10Procedures\s0 ! 2459: .bp ! 2460: .SH ! 2461: Introduction ! 2462: .PP ! 2463: Collections of translated procedures are in the distribution directory \*Mprocs\fR. ! 2464: These files can be linked into other programs. ! 2465: .PP ! 2466: For example, to include the procedures in \*Mgener.icn\fR in ! 2467: an Icon program, the following link declaration can be used\s-2\u2\d\s0: ! 2468: .Ds ! 2469: link "/ipl/procs/gener" ! 2470: .De ! 2471: .FS ! 2472: \s-2\u2\d\s0\^In DOS, backslashes can be used in place of slashes in such link ! 2473: declarations, but they must be escaped, as in ! 2474: .Ds ! 2475: link "\e\eipl\e\eprocs\e\egener" ! 2476: .De ! 2477: .FE ! 2478: .NH 0 ! 2479: Math Procedures: \*Mmath ! 2480: .LP ! 2481: The following procedures compute standard trigonometric functions. ! 2482: The arguments are in radians. ! 2483: .RS ! 2484: .IP \*Msin(x)\fR 1i ! 2485: sine of \*Mx\fR ! 2486: .IP \*Mcos(x)\fR ! 2487: cosine of \*Mx\fR ! 2488: .IP \*Mtan(x)\fR ! 2489: tangent of \*Mx\fR ! 2490: .IP \*Masin(x)\fR ! 2491: arc sine of \*Mx\fR in the range \-\(*p/2 to \(*p/2 ! 2492: .IP \*Macos(x)\fR ! 2493: arc cosine of \*Mx\fR in the range 0 to \(*p ! 2494: .IP \*Matan(x)\fR ! 2495: arc tangent of \*Mx\fR in the range \-\(*p/2 to \(*p/2 ! 2496: .IP \*Matan2(y,x)\fR ! 2497: arc tangent of \*Mx/y\fR in the range \-\(*p to \(*p ! 2498: .RE ! 2499: .LP ! 2500: The following procedures convert from degrees to radians and conversely: ! 2501: .RS ! 2502: .IP \*Mdtor(d)\fR 1i ! 2503: radian equivalent of \*Md\fR ! 2504: .IP \*Mrtod(r)\fR ! 2505: degree equivalent of \*Mr\fR ! 2506: .RE ! 2507: .LP ! 2508: The following ! 2509: additional procedures are available: ! 2510: .RS ! 2511: .IP \*Msqrt(x)\fR 1i ! 2512: square root of \*Mx\fR ! 2513: .IP \*Mexp(x)\fR ! 2514: exponential function of \*Mx\fR ! 2515: .IP \*Mlog(x)\fR ! 2516: natural logarithm of \*Mx\fR ! 2517: .IP \*Mlog10(x)\fR ! 2518: base-10 logarithm of \*Mx\fR ! 2519: .IP \*Mfloor(x)\fR ! 2520: largest integer not greater than \*Mx\fR ! 2521: .IP \*Mceil(x)\fR ! 2522: smallest integer nor less than \*Mx\fR ! 2523: .RE ! 2524: .LP ! 2525: \fBFailure Conditions:\fR ! 2526: \*Masin(x)\fR and \*Macos(x)\fR fail if the absolute value of \*Mx\fR is ! 2527: greater than one. \*Msqrt(x)\fR, \*Mlog(x)\fR, and \*Mlog10(x)\fR ! 2528: fail if \*Mx\fR is less than zero. ! 2529: .NH ! 2530: Bit Operations: \*Mbitops ! 2531: .LP ! 2532: The following procedures perform operations on characters strings of zeros and ! 2533: ones (``bit strings''). ! 2534: .RS ! 2535: .IP \*Mand(b1,\*bb2)\fR 1i ! 2536: logical ``and'' of \*Mb1\fR and \*Mb2\fR ! 2537: .IP \*Mbitstring(i)\fR ! 2538: convert integer \*Mi\fR to bit string ! 2539: .IP \*Mbsum(b1,\*bb2)\fR ! 2540: arithmetic sum of \*Mb1\fR and \*Mb2\fR ! 2541: (used by other procedures) ! 2542: .IP \*Mdecimal(b)\fR ! 2543: convert \*Mb\fR to integer ! 2544: .IP \*Mexor(b1,\*bb2)\fR ! 2545: ``exclusive-or'' of \*Mb1\fR and \*Mb2\fR ! 2546: .IP \*Mneg(b)\fR ! 2547: negation of \*Mb\fR ! 2548: .IP \*Mor(b1,\*bb2)\fR ! 2549: logical ``or'' of \*Mb1\fR and \*Mb2\fR ! 2550: .RE ! 2551: .LP ! 2552: \fBNote:\fR ! 2553: If \*Mi\fR in \*Mbitstring(i)\fR is negative, the value produced is ! 2554: the corresponding unsigned 32-bit bit string. ! 2555: .LP ! 2556: \fBBugs:\fR ! 2557: Integer values that exceed those allowable in Icon may produce bogus ! 2558: results or spurious diagnostics. ! 2559: .NH ! 2560: Radix Conversions: \*Mradcon ! 2561: .LP ! 2562: The following procedures convert numbers from one radix to another. The letters ! 2563: from \*Ma\fR to \*Mz\fR are used for ``digits'' greater than 9. All the ! 2564: conversion procedures fail if the conversion cannot be made. ! 2565: .RS ! 2566: .IP \*Mexbase10(i,\*bj)\fR 1i ! 2567: convert base-10 integer \*Mi\fR to base \*Mj\fR ! 2568: .IP \*Minbase10(s,\*bi)\fR ! 2569: convert base-\*Mi\fR integer \*Ms\fR to base 10 ! 2570: .IP \*Mradcon(s,\*bi,\*bj)\fR ! 2571: convert base-\*Mi\fR integer \*Ms\fR to base \*Mj\fR ! 2572: .RE ! 2573: .LP ! 2574: \fBLimitation:\fR ! 2575: The maximum base allowed is 36. ! 2576: .ig ! 2577: .NH ! 2578: Formatting Numbers: \*Mnumbers ! 2579: .. ! 2580: .NH ! 2581: Complex Arithmetic: \*Mcomplex ! 2582: .LP ! 2583: The following procedures perform operations on complex numbers. ! 2584: .RS ! 2585: .IP \*Mcomplex(r,\*bi)\fR 1i ! 2586: create complex number with real part \*Mr\fR ! 2587: and imaginary part \*Mi\fR ! 2588: .IP \*Mcpxadd(x1,\*bx2)\fR ! 2589: add complex numbers \*Mx1\fR and \*Mx2\fR ! 2590: .IP \*Mcpxdiv(x1,\*bx2)\fR ! 2591: divide complex number \*Mx1\fR by complex number \*Mx2\fR ! 2592: .IP \*Mcpxmul(x1,\*bx2)\fR ! 2593: multiply complex number \*Mx1\fR by complex number \*Mx2\fR ! 2594: .IP \*Mcpxsub(x1,\*bx2)\fR ! 2595: subtract complex number \*Mx2\fR from complex number \*Mx1\fR ! 2596: .IP \*Mcpxstr(x)\fR ! 2597: convert complex number \*Mx\fR to string representation ! 2598: .IP\*Mstrcpx(s)\fR ! 2599: convert string representation \*Ms\fR of complex number ! 2600: to complex number ! 2601: .RE ! 2602: .NH ! 2603: Collated Strings: \*Mcollate ! 2604: .LP ! 2605: These procedures collate (interleave) respective characters of two ! 2606: strings and decollate such strings by selecting every other character of a string. ! 2607: produce a string consisting of ! 2608: interleaved characters of \*Ms1\fR and \*Ms2\fR. ! 2609: .RS ! 2610: .IP \*Mcollate(s1,\*bs2)\fR 1i ! 2611: collate the characters of \*Ms1\fR and \*Ms2\fR. ! 2612: For example, ! 2613: .sp .5 ! 2614: \*Mcollate("abc",\*b"def")\fR ! 2615: .sp .5 ! 2616: produces \*M"adbecf"\fR. ! 2617: .IP \*Mdecollate(s,\*bi)\fR ! 2618: produce a string consisting of ! 2619: every other character of \*Ms\fR. If \*Mi\fR ! 2620: is odd, the odd-numbered characters are selected, while if \*Mi\fR ! 2621: is even, the even-numbered characters are selected. ! 2622: .RE ! 2623: .LP ! 2624: \fBDiagnostics:\fR ! 2625: Run-time error 208 occurs if the arguments to \*Mcollate\fR are not ! 2626: of the same size. ! 2627: .NH ! 2628: Emphasized Text: \*Mbold ! 2629: .LP ! 2630: These procedures produce text with interspersed characters suitable for ! 2631: printing to produce the effect of boldface (by overstriking) and ! 2632: underscoring (using backspaces). ! 2633: .RS ! 2634: .IP \*Mbold(s)\fR 1i ! 2635: bold version of \*Ms ! 2636: .IP \*Muscore(s)\fR ! 2637: underscored version of \*Ms ! 2638: .RE ! 2639: .NH ! 2640: Shuffling: \*Mshuffle ! 2641: .LP ! 2642: The procedure \*Mshuffle(x)\fR shuffles a string or list. In the case ! 2643: that \*Mx\fR is a string, a corresponding string with the characters ! 2644: randomly rearranged is produced. In the case that \*Mx\fR is a list, ! 2645: the values in the list are randomly rearranged. ! 2646: .NH ! 2647: Segmented Strings: \*Msegment ! 2648: .LP ! 2649: The procedure \*Msegment(s,\*bc)\fR generates ! 2650: consecutive substrings of \*Ms\fR consisting of characters that ! 2651: respectively do/do not occur in \*Mc\fR. ! 2652: For example, ! 2653: .Ds ! 2654: segment("Not a sentence.",\*b&lcase ++ &ucase) ! 2655: .De ! 2656: generates ! 2657: .Ds ! 2658: "Not" ! 2659: " " ! 2660: "a" ! 2661: " " ! 2662: "sentence" ! 2663: "." ! 2664: .De ! 2665: .NH ! 2666: String Utilities: \*Mstrutil ! 2667: .LP ! 2668: These procedures perform simple operations on strings. ! 2669: .RS ! 2670: .IP \*Mcompress(s,\*bc)\fR 1i ! 2671: compress consecutive occurrences of characters in \*Mc\fR that occur in \*Ms\fR ! 2672: .IP \*Mdelete(s,\*bc)\fR ! 2673: delete all occurrences of characters in \*Mc\fR that occur in \*Ms\fR ! 2674: .IP \*Mrotate(s,\*bi)\fR ! 2675: rotate \*Ms\fR \*Mi\fR characters to the left (negative \*Mi\fR produces ! 2676: rotation to the right); the default value of \*Mi\fR is 1 ! 2677: .RE ! 2678: .NH ! 2679: Structure Utilities: \*Mstructs ! 2680: .LP ! 2681: These procedures manipulate trees and acyclic graphs (dags). ! 2682: The structures are represented with lists. ! 2683: See\*([<\*([[1\*(]]\*(>]. ! 2684: .RS ! 2685: .IP \*Mdepth(t)\fR 1i ! 2686: compute maximum depth of tree \*Mt\fR ! 2687: .IP \*Meq(x,\*by)\fR ! 2688: compare list structures \*Mx\fR and \*My\fR ! 2689: .IP \*Mldag(s)\fR ! 2690: construct a dag from the string \*Ms\fR ! 2691: .IP \*Mltree(s)\fR ! 2692: construct a tree from the string \*Ms\fR ! 2693: .IP \*Mstree(t)\fR ! 2694: construct a string from the tree \*Mt\fR ! 2695: .IP \*Mtcopy(t)\fR ! 2696: copy tree \*Mt\fR ! 2697: .IP \*Mteq(t1,\*bt2)\fR ! 2698: compare trees \*Mt1\fR and \*Mt2\fR ! 2699: .IP \*Mvisit(t)\fR ! 2700: visit, in preorder, the nodes of the tree \*Mt\fR ! 2701: .RE ! 2702: .LP ! 2703: \fBNote:\fR ! 2704: The procedure \*Mldag\fR has a second argument that is used on internal ! 2705: recursive calls; a second argument must not be supplied by the user. ! 2706: .NH ! 2707: Icon Literal Escapes: \*Mescape ! 2708: .LP ! 2709: The procedure \*Mescape(s)\fR produces a string in which Icon ! 2710: quoted literal escape conventions in \*Ms\fR are replaced by the corresponding ! 2711: characters. ! 2712: For example, \*Mescape("\e\e143\e\e141\e\e164")\fR produces the string \*M"cat"\fR. ! 2713: .NH ! 2714: Images of Icon Values: \*Mimage ! 2715: .LP ! 2716: The procedure \*MImage(x)\fR produces a string ! 2717: image of the value \*Mx\fR. The value produced is a generalization of ! 2718: the value produced by the Icon function \*Mimage(x)\fR, providing detailed ! 2719: information about structures. ! 2720: .PP ! 2721: Tags are used to uniquely identify ! 2722: structures. A tag consists of a letter identifying the type followed ! 2723: by an integer. The tag letters are \*ML\fR for lists, \*MR\fR for ! 2724: records, \*MS\fR for sets, and \*MT\fR for tables. The first time a structure is encountered, ! 2725: it is imaged as the tag followed by a colon, followed by a representation ! 2726: of the structure. If the same structure is encountered again, only the ! 2727: tag is given. ! 2728: .PP ! 2729: An example is ! 2730: .de In ! 2731: .in 3n ! 2732: .. ! 2733: .Ds ! 2734: a := \^["x"] ! 2735: push(a,\*ba) ! 2736: t := table() ! 2737: push(a,\*bt) ! 2738: t\^[a] := t ! 2739: t\^["x"] := \^[\^] ! 2740: t\^[t] := a ! 2741: write(Image(t)) ! 2742: .De ! 2743: which produces ! 2744: .Ds ! 2745: T1:\^["x"\->L1:\^[\^],\*bL2:\^[T1,\*bL2,\*b"x"]\^\->T1,\*bT1\->L2] ! 2746: .De ! 2747: Note that a table is represented as a list of entry and assigned ! 2748: values separated by \*M\->\fR. ! 2749: .NH ! 2750: List Mapping: \*Mlmap ! 2751: .LP ! 2752: The procedure ! 2753: \*Mlmap(a1,\*ba2,\*ba3)\fR maps elements of \*Ma1\fR according to \*Ma2\fR and \*Ma3\fR. ! 2754: This procedure is the analog for lists of the built-in string-mapping ! 2755: function \*Mmap(s1,\*bs2,\*bs3)\fR. Elements in \*Ma1\fR that are the ! 2756: same as elements in \*Ma2\fR are mapped into the corresponding ! 2757: elements of \*Ma3\fR. For example, given the lists ! 2758: .Ds ! 2759: a1 := [1,\*b2,\*b3,\*b4] ! 2760: a2 := [4,\*b3,\*b2,\*b1] ! 2761: a3 := ["a",\*b"b",\*b"c",\*b"d"] ! 2762: .De ! 2763: then ! 2764: .Ds ! 2765: lmap(a1,\*ba2,\*ba3) ! 2766: .De ! 2767: changes \*Ma1\fR to ! 2768: .Ds ! 2769: ["d",\*b"c",\*b"b",\*b"a"] ! 2770: .De ! 2771: Note that the value of \*Ma1\fR is modified. ! 2772: .PP ! 2773: Lists that are mapped can have any kinds of elements. The operation ! 2774: .Ds ! 2775: x =\^=\^= y ! 2776: .De ! 2777: is used to determine if elements \*Mx\fR and \*My\fR are equivalent. ! 2778: .PP ! 2779: All cases in \*Mlmap\fR are handled as they are in \*Mmap\fR, ! 2780: except that no defaults are provided for omitted arguments. As with ! 2781: \*Mmap\fR, \*Mlmap\fR can be used for transposition as well as ! 2782: substitution. ! 2783: .LP ! 2784: \fBWarning:\fR ! 2785: If \*Mlmap\fR is called with the same lists \*Ma2\fR and \*Ma3\fR ! 2786: as in the immediately preceding call, the same mapping is performed, ! 2787: even if the values in \*Ma2\fR and \*Ma3\fR have been changed. This ! 2788: improves performance, but it may cause unexpected effects. ! 2789: .LP ! 2790: \fBComments:\fR ! 2791: It is easy to change \*Mlmap\fR to produce a new list instead of ! 2792: modifying \*Ma1\fR; this is a good exercise for beginning Icon ! 2793: programmers. The ``caching'' of the mapping table based on ! 2794: \*Ma2\fR and \*Ma3\fR also can be removed easily to avoid ! 2795: the potential problem mentioned in the warning above. ! 2796: .NH ! 2797: Snapshots of Scanning: \*Msnapshot ! 2798: .LP ! 2799: The procedure \*Msnapshot()\fR writes a snapshot of the state of string ! 2800: scanning, showing the value of \*M&subject\fR and \*M&pos\fR. For ! 2801: example, ! 2802: .Ds ! 2803: "((a+b)\-delta)/(c*d))" ? { ! 2804: tab(bal('+\-/*')) ! 2805: snapshot() ! 2806: } ! 2807: .De ! 2808: produces ! 2809: .nf ! 2810: .CS ! 2811: .in .5i ! 2812: \-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\- ! 2813: | | ! 2814: | &subject = "((a+b)\-delta)/(c*d))" | ! 2815: | | | ! 2816: \-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\- ! 2817: .in 0 ! 2818: .CE ! 2819: .LP ! 2820: Note that the bar showing the \*M&pos\fR is positioned under the ! 2821: \*M&pos\fRth character (actual positions are between characters). ! 2822: If \*M&pos\fR is at the end of \*M&subject\fR, the bar is positioned ! 2823: under the quotation mark delimiting the subject. For example, ! 2824: .Ds ! 2825: "abcdefgh" ? (tab(0) & snapshot()) ! 2826: .De ! 2827: produces ! 2828: .nf ! 2829: .CS ! 2830: .in .5i ! 2831: \-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\- ! 2832: | | ! 2833: | &subject = "abcdefgh" | ! 2834: | | | ! 2835: \-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\- ! 2836: .in 0 ! 2837: .CE ! 2838: .LP ! 2839: Escape sequences are handled properly. For example, ! 2840: .Ds ! 2841: "abc\etdef\enghi" ? (tab(upto('\en')) & snapshot()) ! 2842: .De ! 2843: produces ! 2844: .nf ! 2845: .CS ! 2846: .in .5i ! 2847: \-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\- ! 2848: | | ! 2849: | &subject = "abc\etdef\enghi" | ! 2850: | | | ! 2851: \-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\- ! 2852: .in 0 ! 2853: .CE ! 2854: .LP ! 2855: .NH ! 2856: Miscellaneous Generators: \*Mgener ! 2857: .LP ! 2858: These procedures generate sequences of results. ! 2859: .RS ! 2860: .IP \*Mhex()\fR 1i ! 2861: sequence of hexadecimal codes for numbers from 0 to 255 ! 2862: .IP \*Mlabel(s,\*bi)\fR ! 2863: sequence of labels with prefix \*Ms\fR starting at \*Mi\fR ! 2864: .IP \*Moctal()\fR ! 2865: sequence of octal codes for numbers from 0 to 255 ! 2866: .IP \*Mstar(s)\fR ! 2867: sequence consisting of the closure of \*Ms\fR starting with the ! 2868: empty string and continuing in lexical order as given in \*Ms\fR ! 2869: .RE ! 2870: .NH ! 2871: Result Sequences: \*Mseqimage ! 2872: .LP ! 2873: The procedure \*MSeqimage\^{e,\*bi,\*bj}\fR produces a string image ! 2874: of the result sequence for the expression \*Me\fR. The first \*Mi\fR ! 2875: results are printed. If \*Mi\fR is omitted, ! 2876: there is no limit. If there are more than \*Mi\fR results for ! 2877: \*Me\fR, ellipses are provided in the image after the first \*Mi\fR. ! 2878: If \*Mj\fR is specified, at most \*Mj\fR results from the end ! 2879: of the sequence are printed after ! 2880: the ellipses. ! 2881: If \*Mj\fR is omitted, only the first \*Mi\fR results are produced. ! 2882: .LP ! 2883: For example, the expressions ! 2884: .Ds ! 2885: Seqimage\^{1 to 12} ! 2886: Seqimage\^{1 to 12\*b,10} ! 2887: Seqimage\^{1 to 12\*b,6\*b,3} ! 2888: .De ! 2889: produce, respectively, ! 2890: .Ds ! 2891: {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12} ! 2892: {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, ...} ! 2893: {1, 2, 3, 4, 5, 6, ..., 10, 11, 12} ! 2894: .De ! 2895: .LP ! 2896: \fBWarning:\fR ! 2897: If \*Mj\fR is not omitted and \*Me\fR has a infinite result ! 2898: sequence, \*MSeqimage\fR does not terminate. ! 2899: .NH ! 2900: SNOBOL4 Pattern Matching: \*Mpatterns ! 2901: .LP ! 2902: These procedures ! 2903: provide procedural equivalents for most SNOBOL4 patterns and ! 2904: some extensions. See\*([<\*([[9\*(]-11\*(]]\*(>]. ! 2905: Procedures and their pattern equivalents are: ! 2906: .RS ! 2907: .IP \*MAny(s)\fR 1i ! 2908: \*MANY(S)\fR ! 2909: .IP \*MArb()\fR ! 2910: \*MARB\fR ! 2911: .IP \*MArbno(p)\fR ! 2912: \*MARBNO(P)\fR ! 2913: .IP \*MArbx(i)\fR ! 2914: \*MARB(I)\fR ! 2915: .IP \*MBal()\fR ! 2916: \*MBAL\*M ! 2917: .IP \*MBreak(s)\*M ! 2918: \*MBREAK(S)\fR ! 2919: .IP \*MBreakx(s)\fR ! 2920: \*MBREAKX(S)\fR ! 2921: .IP \*MCat(p1,\*bp2)\fR ! 2922: \*MP1 P2\fR ! 2923: .IP \*MDiscard(p)\fR ! 2924: \*M/P\fR ! 2925: .IP \*MExog(s)\fR ! 2926: \*M\eS\fR ! 2927: .IP \*MFind(s)\*M ! 2928: \*MFIND(S)\fR ! 2929: .IP \*MLen(i)\fR ! 2930: \*MLEN(I)\fR ! 2931: .IP \*MLimit(p,\*bi)\fR ! 2932: \*MP \e i\fR ! 2933: .IP \*MLocate(p)\fR ! 2934: \*MLOCATE(P)\fR ! 2935: .IP \*MMarb()\fR ! 2936: \*M\fRlongest-first\*M ARB\fR ! 2937: .IP \*MNotany(s)\fR ! 2938: \*MNOTANY(S)\fR ! 2939: .IP \*MPos(i)\fR ! 2940: \*MPOS(I)\fR ! 2941: .IP \*MReplace(p,\*bs)\fR ! 2942: \*MP \(== S\fR ! 2943: .IP \*MRpos(i)\fR ! 2944: \*MRPOS(I)\fR ! 2945: .IP \*MRtab(i)\fR ! 2946: \*MRTAB(I)\fR ! 2947: .IP \*MSpan(s)\*M ! 2948: \*MSPAN(S)\fR ! 2949: .IP \*MString(s)\fR ! 2950: \*MS\fR ! 2951: .IP \*MSucceed()\*M ! 2952: \*MSUCCEED\fR ! 2953: .IP \*MTab(i)\fR ! 2954: \*MTAB(I)\fR ! 2955: .IP \*MXform(f,\*bp)\*M ! 2956: \*MF(P)\fR ! 2957: .RE ! 2958: .PP ! 2959: The following procedures relate to the application and control of ! 2960: pattern matching: ! 2961: .RS ! 2962: .IP \*MApply(s,\*bp)\fR 1i ! 2963: \*MS ? P\fR ! 2964: .IP \*MMode()\fR ! 2965: \fRanchored or unanchored matching (see \*MAnchor\fR and \*MFloat\fR) ! 2966: .IP \*MAnchor()\fR ! 2967: \*M&ANCHOR = 1 \fR if \*MMode := Anchor ! 2968: .IP \*MFloat()\*M ! 2969: \*M&ANCHOR = 0 \fR if \*MMode := Float\fR ! 2970: .RE ! 2971: .LP ! 2972: In addition to the procedures above, the following expressions can be ! 2973: used: ! 2974: .RS ! 2975: .IP \*Mp1()\ |\ p2()\fR 1i ! 2976: \*MP1 | P2\fR ! 2977: .IP \*Mv\ <\-\ p()\fR ! 2978: \*MP . V \fR (approximate) ! 2979: .IP \*Mv\ :=\ p()\fR ! 2980: \*MP $ V \fR (approximate) ! 2981: .IP \*Mfail\fR ! 2982: \*MFAIL\fR ! 2983: .IP \*M=s\fR ! 2984: \*MS\fR (in place of \*MString(s)\fR) ! 2985: .IP \*Mp1()\ ||\ p2()\fR ! 2986: \*MP1 P2 \fR (in place of \*MCat(p1,\*bp2)\fR) ! 2987: .RE ! 2988: .LP ! 2989: Using this system, most SNOBOL4 patterns can be satisfactorily transliterated ! 2990: into Icon procedures and expressions. For example, the pattern ! 2991: .Ds ! 2992: SPAN("0123456789") $ N "H" LEN(*N) $ LIT ! 2993: .De ! 2994: can be transliterated into ! 2995: .Ds ! 2996: (n <\- Span('0123456789')) || ="H" || ! 2997: (lit <\- Len(n)) ! 2998: .De ! 2999: Concatenation of components is necessary to preserve the pattern-matching properties ! 3000: of SNOBOL4. ! 3001: See the documents referenced above for details and limitations. ! 3002: .LP ! 3003: \fBCaveats\fR: ! 3004: Simulating SNOBOL4 pattern matching using the procedures above ! 3005: is inefficient. ! 3006: .NH ! 3007: Defined Control Operations: \*Mpdco ! 3008: LPP ! 3009: These procedures ! 3010: use co-expressions to used to model the built-in control ! 3011: structures of Icon and also provide new ones. See\*([<\*([[12\*(]]\*(>]. ! 3012: .RS ! 3013: .IP \*MAlt\^{e1,\*be2}\fR 1.5i ! 3014: models \*Me1 | e2\fR ! 3015: .IP \*MColseq\^{e1,\\*be2,\ \*(El}\fR ! 3016: produces results of \*Me1\fR, \*Me2\fR, \*(El alternately ! 3017: .IP \*MComseq\^{e1,\*be2}\fR ! 3018: compares result sequences of \*Me1\fR and \*Me2\fR ! 3019: .IP \*MCond\^{e1,\*be2,\ \*(El}\fR ! 3020: models the generalized Lisp conditional ! 3021: .IP \*MEvery\^{e1,\*be2}\fR ! 3022: models \*Mevery e1 do e2\fR ! 3023: .IP \*MGalt\^{e1,\*be2,\ \*(El}\fR ! 3024: models generalized alternation: \*Me1 | e2 | \*(El\fR ! 3025: .IP \*MLcond\^{e1,\*be2,\ \*(El}\fR ! 3026: models the Lisp conditional ! 3027: .IP \*MLimit\^{e1,\*be2}\fR ! 3028: models \*Me1 \e e2\fR ! 3029: .IP \*MRanseq\^{e1,\*be2,\ \*(El}\fR ! 3030: produces results of \*Me1\fR, \*Me2\fR, \*(El at random ! 3031: .IP \*MRepalt\^{e}\fR ! 3032: models \*M|e\fR ! 3033: .IP \*MResume\^{e1,\*be2,\*be3}\fR ! 3034: models \*Mevery e1 \e e2 do e3\fR ! 3035: .IP \*MSelect\^{e1,\*be2}\fR ! 3036: produces results from \*Me1\fR by position according to \*Me2\fR ! 3037: .RE ! 3038: .LP ! 3039: \fBComments\fR: ! 3040: Because of the handling of the scope of local identifiers in co-expressions, ! 3041: expressions in programmer-defined control operations cannot communicate ! 3042: through local identifiers. ! 3043: Some constructions, such ! 3044: as \*Mbreak\fR and \*Mreturn\fR, cannot be used in arguments to programmer-defined ! 3045: control operations. ! 3046: .NH ! 3047: Defined Control Regimes: \*Mpdae ! 3048: .LP ! 3049: These procedures ! 3050: use co-expressions to model the built-in argument ! 3051: evaluation regime of Icon and also provide new ones. ! 3052: See\*([<\*([[13\*(]]\*(>]. ! 3053: .RS ! 3054: .IP \*MAllpar\^{e1,\*be2,\ \*(El}\fR 1.5i ! 3055: parallel evaluation with last result used for short sequences ! 3056: .IP \*MExtract\^{e1,\*be2,\ \*(El}\fR ! 3057: extract results of even-numbered arguments according to ! 3058: odd-numbered values ! 3059: .IP \*MLifo\^{e1,\*be2,\ \*(El}\fR ! 3060: models standard Icon ``lifo'' evaluation ! 3061: .IP \*MParallel\^{e1,\*be2,\ \*(El}\fR ! 3062: parallel evaluation terminating on shortest sequence ! 3063: .IP \*MReverse\^{e1,\*be2,\ \*(El}\fR ! 3064: left-to-right reversal of lifo evaluation ! 3065: .IP \*MRotate\^{e1,\*be2,\ \*(El}\fR ! 3066: parallel evaluation with shorter sequences re-evaluated ! 3067: .IP \*MSimple\^{e1,\*be2,\ \*(El}\fR ! 3068: simple evaluation with only success or failure ! 3069: .RE ! 3070: .LP ! 3071: \fBComments:\fR ! 3072: Because of the handling of the scope of local identifiers in co-expressions, ! 3073: expressions in programmer-defined argument evaluation regimes cannot communicate ! 3074: through local identifiers. ! 3075: Some constructions, such ! 3076: as \*Mbreak\fR and \*Mreturn\fR, cannot be used in arguments to programmer-defined ! 3077: argument evaluation regimes. ! 3078: .LP ! 3079: At most 10 arguments can be used in the invocation of a programmer-defined ! 3080: argument evaluation regime. This limit can be increased by ! 3081: modifying \*MCall\fR, a utility procedure that is included. ! 3082: .rm CH ! 3083: .bp ! 3084: .[] ! 3085: .[- ! 3086: .ds [F 1 ! 3087: .ds [A R\*(p]\*(a]E\*(p] Griswold ! 3088: .as [A \*(n]M\*(p]\*(a]T\*(p] Griswold ! 3089: .ds [T The Icon Programming Language ! 3090: .ds [I Prentice-Hall, Inc. ! 3091: .ds [C Englewood Cliffs, NJ ! 3092: .ds [D 1983 ! 3093: .][ ! 3094: .[- ! 3095: .ds [F 2 ! 3096: .ds [A R\*(p]\*(a]E\*(p] Griswold ! 3097: .as [A \*(c]W\*(p]\*(a]H\*(p] Mitchell ! 3098: .as [A \*(m]J\*(p] O'Bagy ! 3099: .ds [T \fIVersion 6.0 of Icon\fR ! 3100: .ds [R The Univ. of Arizona Tech. Rep. 86-10 ! 3101: .ds [D May 1986 ! 3102: .][ ! 3103: .[- ! 3104: .ds [F 3 ! 3105: .ds [A R\*(p]\*(a]E\*(p] Griswold ! 3106: .ds [T \fIThe Translation and Execution of Icon Programs under MS-DOS\fR ! 3107: .ds [R The Univ. of Arizona Tech. Rep. ! 3108: .ds [D Dec. 1985 ! 3109: .][ ! 3110: .[- ! 3111: .ds [F 4 ! 3112: .ds [A G\*(p]\*(a]M\*(p] Townsend ! 3113: .ds [T \fIUsing Version 6.0 of Icon Under VMS\fR ! 3114: .ds [R The Univ. of Arizona Tech. Rep. ! 3115: .ds [D May 1986 ! 3116: .][ ! 3117: .[- ! 3118: .ds [F 5 ! 3119: .ds [A R\*(p]\*(a]E\*(p] Griswold ! 3120: .ds [T \fIProgramming in Icon; Problems and Solutions from the Icon Newsletter\fR ! 3121: .ds [R The Univ. of Arizona Tech. Rep. 86-2 ! 3122: .ds [D Jan. 1986 ! 3123: .][ ! 3124: .[- ! 3125: .ds [F 6 ! 3126: .ds [A C\*(p]\*(a]S\*(p] Wetherwell ! 3127: .ds [T ``Probablistic Languages: A Review and Some Open Questions'' ! 3128: .ds [J Computing Surveys ! 3129: .ds [V 12 ! 3130: .ds [N 4 ! 3131: .nr [P 1 ! 3132: .ds [P 362-379 ! 3133: .ds [D 1980 ! 3134: .][ ! 3135: .[- ! 3136: .ds [F 7 ! 3137: .ds [A A\*(p] Salomaa ! 3138: .ds [T Formal Languages ! 3139: .ds [I Academic Press ! 3140: .ds [D 1973 ! 3141: .][ ! 3142: .[- ! 3143: .ds [F 8 ! 3144: .ds [A D\*(p]\*(a]B\*(p] Anderson ! 3145: .as [A \*(n]M\*(p]\*(a]R\*(p] Sleep ! 3146: .ds [T ``Uniform Random Generation of Balanced Parenthesis Strings'' ! 3147: .ds [J ACM Trans. Prog. Lang. and Systems ! 3148: .ds [V 2 ! 3149: .ds [N 1 ! 3150: .nr [P 1 ! 3151: .ds [P 122-128 ! 3152: .ds [D 1980 ! 3153: .][ ! 3154: .[- ! 3155: .ds [F 9 ! 3156: .ds [A R\*(p]\*(a]E\*(p] Griswold ! 3157: .ds [T \fIPattern Matching in Icon\fR ! 3158: .ds [R The Univ. of Arizona Tech. Rep. 80-25 ! 3159: .ds [d Oct. 1980 ! 3160: .][ ! 3161: .[- ! 3162: .ds [F 10 ! 3163: .ds [A R\*(p]\*(a]E\*(p] Griswold ! 3164: .ds [T \fIModels of String Pattern Matching\fR ! 3165: .ds [R The Univ. of Arizona Tech. Rep. 81-6 ! 3166: .ds [D May 1981 ! 3167: .][ ! 3168: .[- ! 3169: .ds [F 11 ! 3170: .ds [A A\*(p]\*(a]C\*(p] Fleck ! 3171: .ds [T ``Formal Models for String Patterns'' ! 3172: .ds [B Current Trends in Programming Methodology; Data Structuring ! 3173: .ds [I Prentice-Hall, Inc. ! 3174: .ds [C Englewood Cliffs, NJ ! 3175: .ds [V IV ! 3176: .ds [D 1978 ! 3177: .nr [P 1 ! 3178: .ds [P 216-240 ! 3179: .][ ! 3180: .[- ! 3181: .ds [F 12 ! 3182: .ds [A R\*(p]\*(a]E\*(p] Griswold ! 3183: .as [A \*(n]M\*(p] Novak ! 3184: .ds [T ``Programmer-Defined Control Operations'' ! 3185: .ds [J Computer J. ! 3186: .ds [V 26 ! 3187: .ds [N 2 ! 3188: .ds [D May 1983 ! 3189: .nr [P 1 ! 3190: .ds [P 175-183 ! 3191: .][ ! 3192: .[- ! 3193: .ds [F 13 ! 3194: .ds [A M\*(p] Novak ! 3195: .as [A \*(n]R\*(p]\*(a]E\*(p] Griswold ! 3196: .ds [T \fIProgrammer-Defined Argument Evaluation Regimes\fR ! 3197: .ds [R The Univ. of Arizona Tech. Rep. 82-16 ! 3198: .ds [D Dec. 1982 ! 3199: .][
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.