|
|
1.1 ! root 1: .\" Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1984. ! 2: .St 6 "EXPRESSIONS, TARGETS AND TESTS" ! 3: .Se 3 6.1 EXPRESSIONS ! 4: .Xx scratch-pad copy ! 5: .Xx compound ! 6: .Tx ! 7: In \*B, the evaluation of an expression cannot alter the values of targets ! 8: that currently exist, nor can it create new targets that survive the expression. ! 9: If an expression appears to alter a target, it effectively modifies ! 10: a local ``scratch-pad'' ! 11: \fIcopy\fP of that target, and the change is invisible outside the expression. ! 12: .Sy 3 ! 13: .Pr expression 4 ! 14: .Al ! 15: single-expression ! 16: .Al ! 17: multiple-expression ! 18: .Pr single-expression 3 ! 19: .Al ! 20: basic-expression ! 21: .Al ! 22: \*(<:(\*(:> expression \*(<:)\*(:> ! 23: .Pr basic-expression 3 ! 24: .Al ! 25: simple-expression ! 26: .Al ! 27: formula ! 28: .Pr simple-expression 7 ! 29: .Al ! 30: constant ! 31: .Al ! 32: target-content ! 33: .Al ! 34: trimmed-text ! 35: .Al ! 36: table-selection ! 37: .Al ! 38: display ! 39: .Al ! 40: refined-expression ! 41: .Pr tight-expression 3 ! 42: .Al ! 43: simple-expression ! 44: .Al ! 45: zeroadic-formula ! 46: .Al ! 47: \*(<:(\*(:> expression \*(<:)\*(:> ! 48: .Pr right-expression 3 ! 49: .Al ! 50: tight-expression ! 51: .Al ! 52: monadic-formula ! 53: .Eo 6 basic-:\0\0\k2simple-:\0\k3tight-:\0\0\0\0\k4right-expressions: ! 54: \h'|\n1u'\*(<:a\*(:> \h'|\n2u'\*(<:a\*(:> \h'|\n3u'\*(<:a\*(:> \h'|\n4u'\*(<:a\*(:> ! 55: \h'|\n1u'\*(<:-a\*(:> \h'|\n4u'\*(<:-a\*(:> ! 56: \h'|\n1u'\*(<:a+b\*(:> ! 57: \h'|\n3u'\*(<:(a+b)\*(:> \h'|\n4u'\*(<:(a+b)\*(:> ! 58: .Xe ! 59: .Tx ! 60: The various kinds of expressions that are distinguished here ! 61: serve to define the syntax ! 62: in such a way that no parentheses are needed where the meaning is ! 63: sufficiently clear. ! 64: .Pr multiple-expression 1 ! 65: .Al ! 66: single-expression\*(<:,\*(:> single-expression ! 67: .Al ! 68: single-expression\*(<:,\*(:> multiple-expression ! 69: .Ex 3 ! 70: \k1multiple-expressions: ! 71: \h'|\n1u'\*(<:1, 'abc'\*(:> ! 72: \h'|\n1u'\*(<:(1, 0), (0, 1), (-1, 0), (0, -1)\*(:> ! 73: .Xe ! 74: .Tx ! 75: The value of a multiple-expression composed of single-expressions ! 76: separated by commas ! 77: is the compound whose fields are the values of the ! 78: successive single-expressions. ! 79: .Se 3 6.1.1 NUMERIC-CONSTANTS ! 80: .Sy 3 ! 81: .Pr numeric-constant 3 ! 82: .Al ! 83: exact-constant ! 84: .Al ! 85: approximate-constant ! 86: .Pr exact-constant 3 ! 87: .Al ! 88: integral-part\0optional-fractional-part ! 89: .Al ! 90: integral-part \*(<:.\*(:> ! 91: .Al ! 92: fractional-part ! 93: .Pr integral-part 3 ! 94: .Al ! 95: digit ! 96: .Al ! 97: integral-part\0digit ! 98: .Pr digit 2 ! 99: .Al ! 100: \*(<:0\*(:> ! 101: .Al ! 102: \*(<:1\*(:> ! 103: .Al ! 104: \*(<:2\*(:> ! 105: .Al ! 106: \*(<:3\*(:> ! 107: .Al ! 108: \*(<:4\*(:> ! 109: .Al ! 110: \*(<:5\*(:> ! 111: .Al ! 112: \*(<:6\*(:> ! 113: .Al ! 114: \*(<:7\*(:> ! 115: .Al ! 116: \*(<:8\*(:> ! 117: .Al ! 118: \*(<:9\*(:> ! 119: .Pr fractional-part 3 ! 120: .Al ! 121: \&\*(<:.\*(:> digit ! 122: .Al ! 123: fractional-part\0digit ! 124: .Pr approximate-constant 2 ! 125: .Sl ! 126: exact-constant\0exponent-part ! 127: .Pr exponent-part 2 ! 128: .Sl ! 129: \*(<:E\*(:> optional-plusminus\0integral-part ! 130: .Pr plusminus 2 ! 131: .Al ! 132: \*(<:+\*(:> ! 133: .Al ! 134: \*(<:-\*(:> ! 135: .Eo 5 exact-constants:\0\0\0\0\0\0\k2approximate-constants: ! 136: \h'|\n1u'\*(<:666\*(:> \h'|\n2u'\*(<:2.99793E8\*(:> ! 137: \h'|\n1u'\*(<:666.\*(:> \h'|\n2u'\*(<:2.99793E+8\*(:> ! 138: \h'|\n1u'\*(<:3.14\*(:> \h'|\n2u'\*(<:1E-9\*(:> ! 139: .Xe ! 140: .Tx ! 141: The value of an exact-constant is an exact number. ! 142: For example, \*(<:1.25\*(:> stands for the exact number \*(<:5/4\*(:>. ! 143: The value of an approximate-constant is an approximate number. ! 144: The exponent-part gives the power of ten in floating-point notation. ! 145: For example, \*(<:1.2345E2\*(:> and \*(<:~123.45\*(:> are (approximately) the same, ! 146: because \*(<:123.45 = 1.2345*10**2\*(:>. ! 147: .Se 2 6.1.2 TARGET-CONTENTS ! 148: .Sy 2 ! 149: .Pr target-content 2 ! 150: .Sl ! 151: tag ! 152: .Tx ! 153: The value of a target-content is the value last put in the target whose ! 154: name is the given tag. ! 155: .Se 2 6.1.3 TRIMMED-TEXTS ! 156: .Xx integer ! 157: .Sy 2 ! 158: .Pr trimmed-text 2 ! 159: .Al ! 160: tight-expression \*(<:@\*(:> right-expression ! 161: .Al ! 162: tight-expression \*(<:|\*(:> right-expression ! 163: .Ps ! 164: .Ex 6 ! 165: \k1trimmed-texts: ! 166: \h'|\n1u'\*(<:t@p\*(:> ! 167: \h'|\n1u'\*(<:t|1\*(:> ! 168: \h'|\n1u'\*(<:t|q@p\*(:> ! 169: \h'|\n1u'\*(<:t@p|(q-p+1)\*(:> ! 170: .Xe ! 171: .Tx ! 172: The value of the tight-expression must be a text T, and that ! 173: of the right-expression must be an integer N. ! 174: .br ! 175: If the sign between the expressions is \*(<:@\*(:>, then the value of ! 176: the trimmed-text is that of T after removing the first N\(mi1 characters. ! 177: For example, \*(<:'lamplight'@4 = 'plight'\*(:>. ! 178: N must be at least 1 and at most one more than the length of T. ! 179: .br ! 180: If the sign between the expressions is \*(<:|\*(:>, then the value of ! 181: the trimmed-text is the text consisting of the first N characters of T. ! 182: For example, \*(<:'scarface'|5 = 'scarf'\*(:>. ! 183: N must be at least 0 and at most equal to the length of T. ! 184: .br ! 185: Note that the tight-expression itself may be a trimmed-text ! 186: again. ! 187: For example, \*(<:'department'|6@3 = 'depart'@3 = 'part'\*(:>. ! 188: .Se 3 6.1.4 TABLE-SELECTIONS ! 189: .Xx key ! 190: .Xx associate ! 191: .Xx table entry ! 192: .Sy 3 ! 193: .Pr table-selection 3 ! 194: .Sl ! 195: tight-expression \*(<:[\*(:> expression \*(<:]\*(:> ! 196: .Sx 2 table-selection: ! 197: \*(<:t[i, j]\*(:> ! 198: .Xe ! 199: .Tx ! 200: The value of the tight-expression must be a table T, and ! 201: the value of the expression between the square brackets must ! 202: be a key K of T. ! 203: The value of the table-selection is then the associate of ! 204: the table entry in T whose key is K. ! 205: .Se 3 6.1.5 DISPLAYS ! 206: .Xx integer ! 207: .Xx character ! 208: .Xx quote ! 209: .Xx convert to a text ! 210: .Xx ambiguity ! 211: .Xx empty list ! 212: .Xx empty table ! 213: .Xx key ! 214: .Xx associate ! 215: .Sy 3 ! 216: .Pr display 4 ! 217: .Al ! 218: text-display ! 219: .Al ! 220: list-display ! 221: .Al ! 222: table-display ! 223: .Pr text-display 3 ! 224: .Al ! 225: \&\*(<:'\*(:> optional-text-body \*(<:'\*(:> ! 226: .Al ! 227: \*(<:"\*(:> optional-text-body \*(<:"\*(:> ! 228: .Ps ! 229: The text-displays \*(<:''\*(:> and \*(<:""\*(:> stand for the empty text. ! 230: A text-body may be any sequence of printable characters ! 231: (see section 1 under `Texts') ! 232: and conversions ! 233: (see below). ! 234: However, in a text-display in the \*(<:'\*(:>\^...\^\*(<:'\*(:> style, ! 235: any single quote \*(<:'\*(:> in the text must be written twice to give \*(<:''\*(:>. ! 236: Otherwise, it will signal the end of the text-display. ! 237: Similarly, in a text-display in the \*(<:"\*(:>\^...\^\*(<:"\*(:> style, ! 238: any double quote \*(<:"\*(:> in the text must be written twice to give \*(<:""\*(:>. ! 239: Finally, the back-quote \*(<:`\*(:> must be written twice too, giving \*(<:``\*(:>. ! 240: Otherwise, it signals a conversion. ! 241: .Pr conversion 2 ! 242: .Sl ! 243: \*(<:`\*(:> expression \*(<:`\*(:> ! 244: .Ps ! 245: The requirement that some signs be written twice does not hold ! 246: \fIinside\fP a conversion. ! 247: For example, \*(<:'`t['a']`'\*(:> is proper, whereas \*(<:'`t[''a'']`'\*(:> is not. ! 248: .Eo 6 text-displays: ! 249: \h'|\n1u'\*(<:''\*(:> ! 250: \h'|\n1u'\*(<:'He said: "Don''t!"'\*(:> ! 251: \h'|\n1u'\*(<:"He said: ""Don't!"""\*(:> ! 252: \h'|\n1u'\*(<:'altitude is `a/1E3` km'\*(:> ! 253: .Xe ! 254: .Tx ! 255: The value of a text-display is the text composed of the ! 256: characters given between the enclosing text quotes. ! 257: If the text-display contains conversions, the expressions of ! 258: these conversions are evaluated first and converted to a ! 259: text in the same way as for a write-command. ! 260: For example, ! 261: since ! 262: .Di 1 ! 263: \*(<:WRITE 239*4649\*(:> ! 264: .Ed ! 265: causes the text \*(<:1111111\*(:> to be written, ! 266: the text-display ! 267: .Di 1 ! 268: \&\*(<:'239 times 4649 gives `239*4649`'\*(:> ! 269: .Ed ! 270: is equivalent to ! 271: .Di 1 ! 272: \&\*(<:'239 times 4649 gives 1111111'\*(:>. ! 273: .Ed ! 274: The quotes and conversion-signs that had to be written twice ! 275: according to the above rules correspond to one character of ! 276: the resulting text. ! 277: For example, the number of characters in \*(<:'x''y""z'\*(:> is 6, ! 278: because it consists of one \*(<:x\*(:>, \fIone\fP \*(<:'\*(:> character, ! 279: one \*(<:y\*(:>, \fItwo\fP \*(<:"\*(:> characters, and finally one \*(<:z\*(:>. ! 280: Another way to specify the same text is \*(<:"x'y""""z"\*(:>. ! 281: .Pr list-display 2 ! 282: .Sl ! 283: \*(<:{\*(:> optional-list-body \*(<:}\*(:> ! 284: .Pr list-body 5 ! 285: .Al ! 286: list-filler-series ! 287: .Al ! 288: single-expression \*(<:..\*(:> single-expression ! 289: .Ps ! 290: The ambiguity in, e.g., \*(<:{1...9}\*(:>, is resolved by parsing it ! 291: as \*(<:{1. .. 9}\*(:>. ! 292: .Pr list-filler-series 2 ! 293: .Al ! 294: list-filler ! 295: .Al ! 296: list-filler\*(<:;\*(:> list-filler-series ! 297: .Pr list-filler 2 ! 298: .Sl ! 299: single-expression ! 300: .Eo 6 list-displays: ! 301: \h'|\n1u'\*(<:{}\*(:> ! 302: \h'|\n1u'\*(<:{x1; x2; x3}\*(:> ! 303: \h'|\n1u'\*(<:{1..n-1}\*(:> ! 304: \h'|\n1u'\*(<:{'a'..'z'}\*(:> ! 305: .Xe ! 306: .Tx ! 307: The value of \*(<:{}\*(:> is an empty list. ! 308: (It may also be an empty table; see below.) ! 309: .br ! 310: The value of a list-display containing list-fillers is the ! 311: list whose entries are the values of those list-fillers. ! 312: If values occur multiply, they give rise to multiple entries ! 313: in the list. ! 314: .br ! 315: For a list-display of the form \*(<:{\*(:>p\*(<:..\*(:>q\*(<:}\*(:>, p and q must both be ! 316: integers, or both be characters (texts of length one). ! 317: The resulting value is then the list of all integers ! 318: or characters x such that p\ \(<= x\ \(<=\ q. ! 319: For example, \*(<:{1..4} = {1; 2; 3; 4}\*(:> and \*(<:{'a'..'c'} = {'a'; 'b'; 'c'}\*(:>. ! 320: .br ! 321: If p\ >\ q, the list is empty, but this is only allowed if p ! 322: and q are adjacent. ! 323: If there is an intervening integer or character x (such that ! 324: p\ >\ x\ >\ q), an error is reported. ! 325: .Pr table-display 2 ! 326: .Sl ! 327: \*(<:{\*(:> optional-table-filler-series \*(<:}\*(:> ! 328: .Pr table-filler-series 2 ! 329: .Al ! 330: table-filler ! 331: .Al ! 332: table-filler\*(<:;\*(:> table-filler-series ! 333: .Pr table-filler 2 ! 334: .Sl ! 335: \*(<:[\*(:> expression \*(<:] :\*(:> single-expression ! 336: .Eo 6 table-displays: ! 337: \h'|\n1u'\*(<:{}\*(:> ! 338: \h'|\n1u'\*(<:{[i, j]: 0}\*(:> ! 339: \h'|\n1u'\*(<:{[0]: {}; [1]: {0}}\*(:> ! 340: \h'|\n1u'\*(<:{[name]: (month, day, year)}\*(:> ! 341: .Xe ! 342: .Tx ! 343: The table-display \*(<:{}\*(:> stands for an empty table. ! 344: Otherwise, each table-filler gives a table entry with key K ! 345: and associate A, where K is the value of the expression ! 346: between square brackets, and A is the value of the ! 347: single-expression following the colon. ! 348: The result is then the table containing these table ! 349: entries. ! 350: .br ! 351: If there are \fIdifferent\fP table entries with the same ! 352: key, an error is reported. ! 353: Multiple occurrences of the \fIsame\fP table entry, however, ! 354: are allowed. ! 355: The extra occurrences are then simply discarded. ! 356: .Se 2 6.1.6 FORMULAS ! 357: .Xx formula ! 358: .Xx function ! 359: .Xx ambiguity ! 360: .Xx parentheses ! 361: .Xx brackets ! 362: .Xx priority ! 363: .Xx user-defined-function ! 364: .Xx yield-unit ! 365: .Xx target ! 366: .Xx scratch-pad copy ! 367: .Xx local ! 368: .Xx return-command ! 369: .Xx predefined functions ! 370: .Xx number ! 371: .Xx denominator ! 372: .Xx numerator ! 373: .Xx text ! 374: .Xx convert to a text ! 375: .Xx text, list and table ! 376: .Xx key ! 377: .Xx character ! 378: .Xx associate ! 379: .Xx list entry ! 380: .Xx integer ! 381: .Sy 2 ! 382: .Pr zeroadic-formula 2 ! 383: .Sl ! 384: zeroadic-function ! 385: .Pr monadic-formula 2 ! 386: .Sl ! 387: monadic-function\0actual-operand ! 388: .Pr dyadic-formula 2 ! 389: .Al ! 390: actual-operand\0dyadic-function\0actual-operand ! 391: .Ps ! 392: The parsing ambiguities introduced by these rules ! 393: are resolved by priority rules, as follows: ! 394: .in +\w'2.\ 'u ! 395: .ti -\w'2.\ 'u ! 396: 1.\ If there is no parsing ambiguity (as in \*(<:1 + sin x\*(:>), ! 397: no parentheses are needed. ! 398: .ti -\w'2.\ 'u ! 399: 2.\ If the order makes no difference (as in \*(<:a*b*c\*(:>, \*(<:a*b/c\*(:> or ! 400: \*(<:a^b^c\*(:>), no parentheses are needed. ! 401: .ti -\w'2.\ 'u ! 402: 3.\ The five arithmetic functions ! 403: \*(<:**\*(:>, \*(<:*\*(:>, \*(<:/\*(:>, \*(<:+\*(:> and \*(<:-\*(:> ! 404: have their traditional priority rules: ! 405: .in +4 ! 406: \*(<:**\*(:> comes before \*(<:*\*(:>, \*(<:/\*(:>, \*(<:+\*(:> and \*(<:-\*(:>; ! 407: .br ! 408: \*(<:*\*(:> and \*(<:/\*(:> come before \*(<:+\*(:> and \*(<:-\*(:>; ! 409: .br ! 410: combinations of \*(<:+\*(:> and \*(<:-\*(:> are computed from left to right. ! 411: .in -4 ! 412: Note, however, that \*(<:a**b**c\*(:>, \*(<:a/b*c\*(:> and \*(<:a/b/c\*(:> are wrong. ! 413: .ti -\w'2.\ 'u ! 414: 4.\ The function \*(<:#\*(:> has a high priority, higher than the ! 415: five arithmetic functions, and the function \*(<:~\*(:> has a ! 416: higher priority than all other functions. ! 417: .ti -\w'2.\ 'u ! 418: 5.\ All other functions, ! 419: in particular \*(<:^\*(:>, \*(<:^^\*(:>, \*(<:<<\*(:>, \*(<:><\*(:>, \*(<:>>\*(:> ! 420: and all tags (like \*(<:sin\*(:> or \*(<:floor\*(:>) have no established priority and ! 421: may be used ! 422: .in +4 ! 423: .ti -\w'\(em\ 'u ! 424: \(em\ having formulas as operands only if these operands ! 425: are parenthesized (except as in, e.g., \*(<:exp -x\*(:>, because of ! 426: point 1 above, or as in \*(<:~1>>20\*(:> because of point 4); ! 427: .ti -\w'\(em\ 'u ! 428: \(em\ in operands of other formulas only if these operands are ! 429: parenthesized (except as above). ! 430: .in -4 ! 431: .in -\w'2.\ 'u ! 432: .Bl 3 ! 433: None of ! 434: \*(<:a/b/c\*(:>, \*(<:a/b*c\*(:> and \*(<:sin x+y\*(:> ! 435: is a correct formula. ! 436: Each of these can be made correct by inserting parentheses, ! 437: depending on the intention: ! 438: either \*(<:(a/b)/c\*(:> or \*(<:a/(b/c)\*(:>, ! 439: either \*(<:(a/b)*c\*(:> or \*(<:a/(b*c)\*(:>, ! 440: and either \*(<:(sin x) + y\*(:> or \*(<:sin(x+y)\*(:>. ! 441: Note that because of point 5 above ! 442: \*(<:sin(x)+1\*(:> is just as wrong as \*(<:sin x + 1\*(:>, ! 443: in spite of what other programming languages might lead you to expect. ! 444: .br ! 445: The function \*(<:#\*(:> has been given ! 446: a high priority since expressions like \*(<:#t+1\*(:> are so common, ! 447: that it would be a nuisance to have to parenthesize these, ! 448: and more so since \*(<:#(t+1)\*(:> is meaningless anyway. ! 449: The reason for the high priority of the function \*(<:~\*(:> is ! 450: to make ! 451: \*(<:~0\*(:>, for example, for all practical purposes behave as a constant. ! 452: .Pr zeroadic-function 2 ! 453: .Sl ! 454: tag ! 455: .Pr monadic-function 6 ! 456: .Al ! 457: \*(<:~\*(:> ! 458: .Al ! 459: \*(<:+\*(:> ! 460: .Al ! 461: \*(<:-\*(:> ! 462: .Al ! 463: \*(<:*/\*(:> ! 464: .Al ! 465: \*(<:/*\*(:> ! 466: .Al ! 467: \*(<:#\*(:> ! 468: .Al ! 469: tag ! 470: .Pr dyadic-function 3 ! 471: .Al ! 472: \*(<:+\*(:> ! 473: .Al ! 474: \*(<:-\*(:> ! 475: .Al ! 476: \*(<:*\*(:> ! 477: .Al ! 478: \*(<:/\*(:> ! 479: .Al ! 480: \*(<:**\*(:> ! 481: .Al ! 482: \*(<:^\*(:> ! 483: .Al ! 484: \*(<:^^\*(:> ! 485: .Al ! 486: \*(<:<<\*(:> ! 487: .Al ! 488: \*(<:><\*(:> ! 489: .Al ! 490: \*(<:>>\*(:> ! 491: .Al ! 492: \*(<:#\*(:> ! 493: .Al ! 494: tag ! 495: .Pr actual-operand 3 ! 496: .Sl ! 497: single-expression ! 498: .Eo 3 zeroadic-formula:\0\0\0\k2monadic-formula:\0\0\0\k3dyadic-formula: ! 499: \h'|\n1u'\*(<:pi\*(:> \h'|\n2u'\*(<:atan(y/x)\*(:> \h'|\n3u'\*(<:x atan y\*(:> ! 500: .Xe ! 501: .Us 7 Formulas with user-defined functions ! 502: A formula whose function is defined by a yield-unit, is ! 503: evaluated in the following steps: ! 504: .in \w'2.\ 'u ! 505: .ti 0 ! 506: 1.\ A copy is made of the current environment (the value of ! 507: all targets), and all computations during the evaluation of ! 508: the formula will take place in this ``scratch-pad copy''. ! 509: .ti 0 ! 510: 2.\ Any local tags in the yield-unit that might clash with tags currently ! 511: in use are systematically replaced by other tags that do not cause conflict. ! 512: .ti 0 ! 513: 3.\ Each actual-operand is evaluated and put in the ! 514: corresponding formal-operand, used as a (new) ! 515: target. ! 516: .ti 0 ! 517: 4.\ The command-suite of the unit, thus modified, is executed. ! 518: .in 0 ! 519: The evaluation of the formula is complete when the execution ! 520: of this command-suite terminates because of the execution of a return-command; ! 521: the value of the formula is the value returned. ! 522: .Us 7 Formulas with predefined functions ! 523: .de Qr ! 524: .sp 1 ! 525: .in 0 ! 526: .ne 3 ! 527: .. ! 528: .de Qe ! 529: .br ! 530: .sp -1 ! 531: .in 7m ! 532: .. ! 533: .Us 0 A. Functions on numbers ! 534: .Qr ! 535: \*(<:~x\*(:> ! 536: .Qe ! 537: returns an approximate number, as close as possible ! 538: in arithmetic magnitude to \*(<:x\*(:>. ! 539: .Qr ! 540: \*(<:x+y\*(:> ! 541: .Qe ! 542: returns the sum of \*(<:x\*(:> and \*(<:y\*(:>. ! 543: The result is exact if both operands are exact. ! 544: .Qr ! 545: \*(<:+x\*(:> ! 546: .Qe ! 547: returns the value of \*(<:x\*(:>. ! 548: .Qr ! 549: \*(<:x-y\*(:> ! 550: .Qe ! 551: returns the difference of \*(<:x\*(:> and \*(<:y\*(:>. ! 552: The result is exact if both operands are exact. ! 553: .Qr ! 554: \*(<:-x\*(:> ! 555: .Qe ! 556: returns minus the value of \*(<:x\*(:>. ! 557: The result is exact if the operand is exact. ! 558: .Qr ! 559: \*(<:x*y\*(:> ! 560: .Qe ! 561: returns the product of \*(<:x\*(:> and \*(<:y\*(:>. ! 562: The result is exact if both operands are exact. ! 563: .Qr ! 564: \*(<:x/y\*(:> ! 565: .Qe ! 566: returns the quotient of \*(<:x\*(:> and \*(<:y\*(:>. ! 567: The value of \*(<:y\*(:> must not be zero. ! 568: The result is exact if both operands are exact. ! 569: .Qr ! 570: \*(<:x**y\*(:> ! 571: .Qe ! 572: returns \*(<:x\*(:> to the power \*(<:y\*(:>. ! 573: The result is exact if \*(<:x\*(:> is exact and \*(<:y\*(:> is an integer. ! 574: If \*(<:x\*(:> is negative, ! 575: \*(<:y\*(:> must be an integer or an exact number with an odd denominator. ! 576: If \*(<:x\*(:> is zero, ! 577: \*(<:y\*(:> must not be negative. ! 578: If \*(<:y\*(:> is zero, the result is one (exact or approximate). ! 579: .Qr ! 580: \*(<:n root x\*(:> ! 581: .Qe ! 582: returns the same as \*(<:x**(1/n)\*(:>. ! 583: .Qr ! 584: \*(<:root x\*(:> ! 585: .Qe ! 586: returns the same as \*(<:2 root x\*(:>, the square root of \*(<:x\*(:>. ! 587: .Qr ! 588: \*(<:abs x\*(:> ! 589: .Qe ! 590: returns the absolute value of \*(<:x\*(:>. ! 591: The result is exact if the operand is exact. ! 592: .Qr ! 593: \*(<:sign x\*(:> ! 594: .Qe ! 595: returns \(mi1 if \*(<:x\*(:> is negative, 0 if \*(<:x\*(:> is zero, and 1 otherwise. ! 596: .Qr ! 597: \*(<:floor x\*(:> ! 598: .Qe ! 599: returns the largest integer not exceeding \*(<:x\*(:> in arithmetic ! 600: magnitude. ! 601: .Qr ! 602: \*(<:ceiling x\*(:> ! 603: .Qe ! 604: returns the same as \*(<:- floor -x\*(:>. ! 605: .Qr ! 606: \*(<:n round x\*(:> ! 607: .Qe ! 608: returns the same as \*(<:(10**-n)*floor(x*10**n+.5)\*(:>. ! 609: For example, \*(<:4 round pi = 3.1416\*(:>. ! 610: The value of \*(<:n\*(:> must be an integer. ! 611: It may be negative: \*(<:(-2) round 666 = 700\*(:>. ! 612: .Qr ! 613: \*(<:round x\*(:> ! 614: .Qe ! 615: returns the same as \*(<:0 round x\*(:>. ! 616: .Qr ! 617: \*(<:a mod n\*(:> ! 618: .Qe ! 619: returns the same as \*(<:a-n*floor(a/n)\*(:>, ! 620: that is, the remainder after dividing \*(<:a\*(:> by \*(<:n\*(:>. ! 621: (Both operands may be approximate, and \*(<:n\*(:> may be negative, but not zero.) ! 622: .Qr ! 623: \*(<:/*x\*(:> ! 624: .Qe ! 625: returns the ``denominator'' of \*(<:x\*(:>, ! 626: that is, regarding \*(<:x\*(:> as the fraction \*(<:p/q\*(:>, ! 627: the smallest positive integer \*(<:q\*(:> such that \*(<:q*x\*(:> is an integer. ! 628: The value of \*(<:x\*(:> must be an exact number. ! 629: .Qr ! 630: \*(<:*/x\*(:> ! 631: .Qe ! 632: returns the corresponding ``numerator'' with the same sign as \*(<:x\*(:>, ! 633: the same integer as \*(<:(/*x)*x\*(:>. ! 634: So, if \*(<:x\*(:> is exact, \*(<:x = (*/x)/(/*x)\*(:>. ! 635: .Qr ! 636: \*(<:pi\*(:> ! 637: .Qe ! 638: returns approximately \*(<:3.1415926535\*(:>... ! 639: .Qr ! 640: \*(<:sin x\*(:> ! 641: .Qe ! 642: returns an approximate number by applying the sine function to \*(<:x\*(:>, ! 643: with \*(<:x\*(:> in radians. ! 644: .Qr ! 645: \*(<:cos x\*(:> ! 646: .Qe ! 647: returns an approximate number by applying the cosine function to \*(<:x\*(:>, ! 648: with \*(<:x\*(:> in radians. ! 649: .Qr ! 650: \*(<:tan x\*(:> ! 651: .Qe ! 652: returns the same as \*(<:(sin x) / (cos x)\*(:>. ! 653: .Qr ! 654: \*(<:x atan y\*(:> ! 655: .Qe ! 656: returns an approximate number \*(<:phi\*(:>, in the range from (about) ! 657: \*(<:-pi\*(:> to \*(<:+pi\*(:>, such that ! 658: \*(<:x\*(:> is approximated by \*(<:r * cos phi\*(:> ! 659: and \*(<:y\*(:> by \*(<:r * sin phi\*(:>, where \*(<:r = root(x*x+y*y)\*(:>. ! 660: The operands must not both be zero. ! 661: .Qr ! 662: \*(<:atan x\*(:> ! 663: .Qe ! 664: returns the same as \*(<:1 atan x\*(:>. ! 665: .Qr ! 666: \*(<:e\*(:> ! 667: .Qe ! 668: returns approximately \*(<:2.7182818284\*(:>... ! 669: .Qr ! 670: \*(<:exp x\*(:> ! 671: .Qe ! 672: returns approximately the same as \*(<:e**x\*(:>. ! 673: .Qr ! 674: \*(<:log x\*(:> ! 675: .Qe ! 676: returns an approximate number by applying the natural logarithm function ! 677: (with base \*(<:e\*(:>) ! 678: to \*(<:x\*(:>. ! 679: The value of \*(<:x\*(:> must be positive. ! 680: .Qr ! 681: \*(<:b log x\*(:> ! 682: .Qe ! 683: returns the same as \*(<:(log x) / (log b)\*(:>, ! 684: that is, the logarithm with base \*(<:b\*(:> of \*(<:x\*(:>. ! 685: .Us 7 B. Functions on texts ! 686: .Qr ! 687: \*(<:t^u\*(:> ! 688: .Qe ! 689: returns the text consisting of \*(<:t\*(:> and \*(<:u\*(:> joined. ! 690: For example, \*(<:'now'^'here' = 'nowhere'\*(:>. ! 691: .Qr ! 692: \*(<:t^^n\*(:> ! 693: .Qe ! 694: returns the text consisting of \*(<:n\*(:> copies of \*(<:t\*(:> joined together. ! 695: For \pexample, \*(<:'Fi! '^^3 = 'Fi! Fi! Fi! '\*(:>. ! 696: The value of \*(<:n\*(:> must be an integer and not negative. ! 697: .Qr ! 698: \*(<:x<<n\*(:> ! 699: .Qe ! 700: converts \*(<:x\*(:> to a text and adds space characters to ! 701: the right until the length is \*(<:n\*(:>. ! 702: For example, \*(<:123<<6 = '123 '\*(:>. ! 703: In no case is the text truncated; if \*(<:n\*(:> is too small, ! 704: the resulting text is as long as necessary. ! 705: The value of \*(<:n\*(:> must be an integer, but \*(<:x\*(:> may be of any type. ! 706: See write-commands, section 5.1.2, for details about converting values to ! 707: texts. ! 708: .Qr ! 709: \*(<:x><n\*(:> ! 710: .Qe ! 711: converts \*(<:x\*(:> to a text and adds space characters to ! 712: the right and to the left, in turn, until the length is \*(<:n\*(:>. ! 713: For example, \*(<:123><6 = ' 123 '\*(:>. ! 714: In no case is the text truncated. ! 715: The value of \*(<:n\*(:> must be an integer, but \*(<:x\*(:> may be of any type. ! 716: .Qr ! 717: \*(<:x>>n\*(:> ! 718: .Qe ! 719: converts \*(<:x\*(:> to a text and adds space characters to ! 720: the left until the length is \*(<:n\*(:>. ! 721: For example, \*(<:123>>6 = ' 123'\*(:>. ! 722: In no case is the text truncated. ! 723: The value of \*(<:n\*(:> must be an integer, but \*(<:x\*(:> may be of any type. ! 724: .Bl 7 ! 725: .Us 7 C. Functions on texts, lists and tables ! 726: .Qr ! 727: \*(<:keys t\*(:> ! 728: .Qe ! 729: requires a table as operand, and returns a list of all keys ! 730: in the table. ! 731: For example, \*(<:keys {[1]: 1; [4]: 2; [9]: 3} = {1; 4; 9}\*(:>. ! 732: .Qr ! 733: \*(<:#t\*(:> ! 734: .Qe ! 735: accepts texts, lists and tables. ! 736: For a text operand, its length is returned, and ! 737: for a list or table operand, the number of ! 738: entries is returned (where duplicates in lists are counted). ! 739: .Qr ! 740: \*(<:e#t\*(:> ! 741: .Qe ! 742: accepts texts, lists and tables for the right operand. ! 743: .br ! 744: For a text operand, the first operand must ! 745: be a character, and the number of times the character ! 746: occurs in the text is returned. ! 747: For example, \*(<:'i'#'mississippi' = 4\*(:>. ! 748: .br ! 749: For a list operand, the number of entries is returned ! 750: that are equal to the first operand ! 751: (which must be of the same type as the list entries.) ! 752: .br ! 753: For example, \*(<:3#{1; 3; 3; 4} = 2\*(:>. ! 754: .br ! 755: .?? ! 756: For a table operand, the number of \fIassociates\fP is returned ! 757: that are equal to the first operand ! 758: (which must be of the same type as the associates in the table.) ! 759: For example, \*(<:3#{[1]: 3; [2]: 4; [3]: 3} = 2\*(:>. ! 760: .Qr ! 761: \*(<:min t\*(:> ! 762: .Qe ! 763: accepts texts, lists and tables. ! 764: For a text operand, its smallest (in the ASCII order) character is returned, ! 765: for a list operand, its smallest ! 766: entry is returned, and ! 767: for a table operand, its smallest ! 768: \fIassociate\fP ! 769: .?? ! 770: is returned. ! 771: For example, \*(<:min 'uscule' = 'c'\*(:>, ! 772: \*(<:min{1; 3; 3; 4} = 1\*(:>, and ! 773: \*(<:min{[1]: 3; [2]: 4; [3]: 3} = 3\*(:>. ! 774: The text, list or table must not be empty. ! 775: .br ! 776: To get the smallest \fIkey\fP of a table \*(<:t\*(:>, ! 777: use \*(<:min keys t\*(:>. ! 778: .Qr ! 779: \*(<:e min t\*(:> ! 780: .Qe ! 781: accepts texts, lists and tables for the right operand. ! 782: .br ! 783: For a text operand, ! 784: the first operand ! 785: must ! 786: be a character, and the smallest character in the text ! 787: \fIexceeding\fP ! 788: that character is returned. ! 789: For example, \*(<:'i' min 'mississippi' = 'm'\*(:>. ! 790: .br ! 791: For a list operand, the smallest ! 792: entry is returned exceeding the first operand ! 793: (which must be of the same type as the list entries.) ! 794: For example, \*(<:3 min {1; 3; 3; 4} = 4\*(:>. ! 795: .br ! 796: For a table operand, the smallest associate ! 797: is returned exceeding the first operand ! 798: (which must be of the same type as the associates in the table.) ! 799: For example, \*(<:3 min {[1]: 3; [2]: 4; [3]: 3} = 4\*(:>. ! 800: .br ! 801: There must be a character, list entry or table associate exceeding ! 802: the first operand. ! 803: .Qr ! 804: \*(<:max t\*(:> and ! 805: .br ! 806: \*(<:e max t\*(:> ! 807: .Qe ! 808: .Qe ! 809: are like \*(<:min\*(:>, except that they return the largest ! 810: element, and in the dyadic case the largest element ! 811: that is less than the first operand. ! 812: For example, \*(<:'m' max 'mississippi' = 'i'\*(:>. ! 813: .Qr ! 814: \*(<:n th'of t\*(:> ! 815: .Qe ! 816: requires an integer in \*(<:{1..#t}\*(:> for the left operand, and ! 817: accepts texts, lists and tables for the right operand. ! 818: It returns the \*(<:n\*(:>'th character, list entry or associate. ! 819: .br ! 820: In fact, \*(<:n th'of t\*(:>, for a text \*(<:t\*(:>, is written as easily ! 821: \*(<:t@n|1\*(:>. ! 822: For a table, it is the same as \*(<:t[n th'of (keys t)]\*(:>, ! 823: which is something different from \*(<:t[n]\*(:>, unless, ! 824: of course, \*(<:keys t = {1..#t}\*(:>. ! 825: For a list, ! 826: \*(<:1 th'of t\*(:> is \*(<:min t\*(:>. ! 827: .Se 2 6.1.7 REFINED-EXPRESSIONS ! 828: .Xx expression-refinement ! 829: .Xx scratch-pad copy ! 830: .Xx return-command ! 831: .Sy 2 ! 832: .Pr refined-expression 2 ! 833: .Sl ! 834: tag ! 835: .Ps ! 836: The tag of a refined-expression must occur as ! 837: the tag of one ! 838: expression-refinement in the unit ! 839: in which it occurs. ! 840: .Sx 3 \k1refined-expression: ! 841: \*(<:stack'pointer\*(:> ! 842: .Xe ! 843: .Tx ! 844: A refined-expression is ! 845: evaluated in the following steps: ! 846: .in \w'2.\ 'u ! 847: .ti 0 ! 848: 1.\ A copy is made of the current environment (the value of ! 849: all targets), and all computations during the evaluation of ! 850: the expression will take place in this ``scratch-pad copy''. ! 851: .ti 0 ! 852: 2.\ The command-suite of the corresponding ! 853: expression-refinement is executed. ! 854: .in 0 ! 855: The evaluation of the refined-expression is complete when the execution ! 856: of this command-suite terminates because of the execution of a return-command; ! 857: the value of the refined-expression is the value returned. ! 858: .Sa ! 859: expression-refinements (4.4). ! 860: .Se 4 6.2 TARGETS ! 861: .Xx compound ! 862: .Sy 4 ! 863: .Pr target 4 ! 864: .Al ! 865: single-target ! 866: .Al ! 867: multiple-target ! 868: .Pr single-target 3 ! 869: .Al ! 870: basic-target ! 871: .Al ! 872: \*(<:(\*(:> target \*(<:)\*(:> ! 873: .Pr basic-target 4 ! 874: .Al ! 875: tag ! 876: .Al ! 877: trimmed-text-target ! 878: .Al ! 879: table-selection-target ! 880: .Tx ! 881: For the use of a tag as target, see below under IDENTIFIERS. ! 882: For other kinds of targets, see below under the appropriate heading. ! 883: .Pr multiple-target 1 ! 884: .Al ! 885: single-target\*(<:,\*(:> single-target ! 886: .Al ! 887: single-target\*(<:,\*(:> multiple-target ! 888: .Ex 3 ! 889: \k1multiple-targets: ! 890: \h'|\n1u'\*(<:nn, t2\*(:> ! 891: \h'|\n1u'\*(<:(x0, y0), (x1, y1), (x2, y2), (x3, y3)\*(:> ! 892: .Xe ! 893: .Tx ! 894: If a value is put in a multiple-target, the value must be ! 895: a compound with as many fields as there are single-targets ! 896: separated by commas in the multiple-target. ! 897: The successive fields are then put in the ! 898: successive single-targets. ! 899: If it makes a difference in what order the fields are put in ! 900: the single-targets (as in \*(<:PUT 1, 2 IN x, x\*(:> ! 901: where the final value of \*(<:x\*(:> might be either \*(<:1\*(:> or \*(<:2\*(:>), ! 902: an error is reported {{but this is currently not checked}}. ! 903: .br ! 904: Note that the meaning of \*(<:PUT a, b IN b, a\*(:> ! 905: is well defined (provided that \*(<:a\*(:> and \*(<:b\*(:> are defined and have ! 906: values of the same type): ! 907: first the value of the expression \*(<:a, b\*(:> is determined, ! 908: and that value is next put in \*(<:b, a\*(:>. ! 909: Note also that the meaning of \*(<:PUT t[i], t[j] IN t[j], t[i]\*(:> ! 910: is well defined, even if \*(<:i\*(:> and \*(<:j\*(:> have the same value. ! 911: For although in this case a value is put twice in the same ! 912: target, that value is the same each time, so the order does not matter. ! 913: .Se 2 6.2.1 IDENTIFIERS ! 914: .Xx tag ! 915: .Xx target ! 916: .Xx location ! 917: .Xx local ! 918: .Sy 2 ! 919: .Pr identifier 4 ! 920: .Al ! 921: single-identifier ! 922: .Al ! 923: multiple-identifier ! 924: .Pr single-identifier 3 ! 925: .Al ! 926: tag ! 927: .Al ! 928: \*(<:(\*(:> identifier \*(<:)\*(:> ! 929: .Pr multiple-identifier 1 ! 930: .Al ! 931: single-identifier\*(<:,\*(:> single-identifier ! 932: .Al ! 933: single-identifier\*(<:,\*(:> multiple-identifier ! 934: .Eo 6 identifiers:\0\0\0\0\0\0\0\0\0\0\0\k2single-identifiers: ! 935: \h'|\n1u'\*(<:a\*(:>\h'|\n2u'\*(<:a\*(:> ! 936: \h'|\n1u'\*(<:(a)\*(:>\h'|\n2u'\*(<:(a)\*(:> ! 937: \h'|\n1u'\*(<:(a, b, (c, d))\*(:>\h'|\n2u'\*(<:(a, b, (c, d))\*(:> ! 938: \h'|\n1u'\*(<:a, b, (c, d)\*(:> ! 939: .Xe ! 940: .Tx ! 941: All identifiers can be used as targets, but the converse is ! 942: not true. ! 943: For example, ! 944: .Di 1 ! 945: \*(<:FOR a[1] IN {1..3}: WRITE a\*(:> ! 946: .Ed ! 947: is wrong, because \*(<:a[1]\*(:>, although a target, is not an identifier. ! 948: If something is put in a target that is a tag, and no ! 949: location for that tag exists already, it is created first. ! 950: If the location is created locally (the tag did not occur in ! 951: an immediate command and was not listed in a share-heading), ! 952: the location will cease to exist when the current unit is exited. ! 953: For putting in multiple-identifiers, see multiple-targets in section 6.2. ! 954: .Se 2 6.2.2 TRIMMED-TEXT-TARGETS ! 955: .Sy 2 ! 956: .Pr trimmed-text-target 3 ! 957: .Al ! 958: target \*(<:@\*(:> right-expression ! 959: .Al ! 960: target \*(<:|\*(:> right-expression ! 961: .Ps\"(The \*(<:|\*(:> in the last line is not the BNF choice indicator, but should be takenliterally.) ! 962: .Ex 6 ! 963: \k1trimmed-text-targets: ! 964: \h'|\n1u'\*(<:t@p\*(:> ! 965: \h'|\n1u'\*(<:t|1\*(:> ! 966: \h'|\n1u'\*(<:t|q@p\*(:> ! 967: \h'|\n1u'\*(<:t@p|(q-p+1)\*(:> ! 968: .Xe ! 969: .Tx ! 970: The target must hold a text T, and the value ! 971: of the right-expression must be an integer N. ! 972: .br ! 973: If the sign used is \*(<:@\*(:>, then the ! 974: trimmed-text-target indicates a location consisting of the ! 975: positions of T starting with the N'th position. ! 976: N must be at least 1 and at most one more than the length of T. ! 977: For example, after ! 978: .Di 2 ! 979: \*(<:PUT 'computer' IN tt ! 980: PUT 'ass' IN tt@5\*(:> ! 981: .Ed ! 982: \*(<:tt\*(:> will contain the text \*(<:'compass'\*(:>. ! 983: .br ! 984: If the sign used is \*(<:|\*(:>, then the ! 985: trimmed-text-target indicates a location ! 986: consisting of the first N characters of T. ! 987: N must be at least 0 and at most equal to the length of T. ! 988: For example, after ! 989: .Di 2 ! 990: \*(<:PUT 'computer' IN tt ! 991: PUT 'ne' IN tt|4\*(:> ! 992: .Ed ! 993: \*(<:tt\*(:> will contain the text \*(<:'neuter'\*(:>. ! 994: .Bl 1 ! 995: Note that the target itself may be a trimmed-text-target ! 996: again. ! 997: For example, after ! 998: .Di 2 ! 999: \*(<:PUT 'computer' IN tt ! 1000: PUT 'm' IN tt@4|1\*(:> ! 1001: .Ed ! 1002: \*(<:tt\*(:> will contain the text \*(<:'commuter'\*(:>. ! 1003: .br ! 1004: Some useful special cases: \*(<:PUT '' IN t|1\*(:> ! 1005: removes the first character of the text in \*(<:t\*(:>; ! 1006: .br ! 1007: \*(<:PUT '.' IN t@(#t+1)\*(:> ! 1008: appends a period to the text in \*(<:t\*(:>. ! 1009: .Se 2 6.2.3 TABLE-SELECTION-TARGETS ! 1010: .Xx key ! 1011: .Xx associate ! 1012: .Xx table entry ! 1013: .Xx location ! 1014: .Xx type ! 1015: .Sy 2 ! 1016: .Pr table-selection-target 2 ! 1017: .Sl ! 1018: target \*(<:[\*(:> expression \*(<:]\*(:> ! 1019: .Sx 3 \k1table-selection-target: ! 1020: \*(<:t[i, j]\*(:> ! 1021: .Xe ! 1022: .Tx ! 1023: The target must contain a table. ! 1024: The value of the expression is a key K, to be used as selector. ! 1025: For each key in the table, there is a location for the ! 1026: corresponding associate. ! 1027: If K is an existing key of the table, the location for the ! 1028: table-selection-target is that of the associate corresponding to K. ! 1029: If a value A is then put in the table-selection-target, ! 1030: the original associate held in that location is superseded by A. ! 1031: If K is not an existing key and a value A is to be put in the ! 1032: table-selection-target, a new location is created, and the ! 1033: (original) table is made to contain a new table entry ! 1034: consisting of K and A. ! 1035: K must be of the same type as the other keys of the ! 1036: table, and A of the same type as the other associates. ! 1037: .Se 5 6.3 TESTS ! 1038: .Xx bound tags ! 1039: .Xx scratch-pad copy ! 1040: .Tx ! 1041: Tests do not return a value, but succeed or fail when ! 1042: tested. ! 1043: In \*B, the testing of a test cannot alter the values of targets ! 1044: that currently exist, nor can it create new targets that survive the test, ! 1045: with the exception of the temporary survival of bound tags ! 1046: as described under QUANTIFICATIONS (section 6.3.7) and ! 1047: REFINED-TESTS (section 6.3.3). ! 1048: .br ! 1049: If a test appears to alter an existing target, it effectively modifies ! 1050: a local, ``scratch-pad'' ! 1051: \fIcopy\fP of that target, and the change is invisible outside the test. ! 1052: .Sy 6 ! 1053: .Pr test 6 ! 1054: .Al ! 1055: tight-test ! 1056: .Al ! 1057: conjunction ! 1058: .Al ! 1059: disjunction ! 1060: .Al ! 1061: negation ! 1062: .Al ! 1063: quantification ! 1064: .Pr tight-test 6 ! 1065: .Al ! 1066: \*(<:(\*(:> test \*(<:)\*(:> ! 1067: .Al ! 1068: order-test ! 1069: .Al ! 1070: proposition ! 1071: .Al ! 1072: refined-test ! 1073: .Pr right-test 4 ! 1074: .Al ! 1075: tight-test ! 1076: .Al ! 1077: negation ! 1078: .Al ! 1079: quantification ! 1080: .Tx ! 1081: The various kinds of tests that are distinguished here ! 1082: serve to define the syntax ! 1083: in such a way that no parentheses are needed where the meaning is ! 1084: sufficiently clear. ! 1085: .Se 7 6.3.1 ORDER-TESTS ! 1086: .Xx order ! 1087: .Xx approximate ! 1088: .Xx exact ! 1089: .Xx equal ! 1090: .Xx number ! 1091: .Sy 7 ! 1092: .Pr order-test 3 ! 1093: .Al ! 1094: single-expression\0order-sign\0single-expression ! 1095: .Al ! 1096: order-test\0order-sign\0single-expression ! 1097: .Pr order-sign 7 ! 1098: .Al ! 1099: \*(<:<\*(:> ! 1100: .Al ! 1101: \*(<:<=\*(:> ! 1102: .Al ! 1103: \*(<:=\*(:> ! 1104: .Al ! 1105: \*(<:<>\*(:> ! 1106: .Al ! 1107: \*(<:>=\*(:> ! 1108: .Al ! 1109: \*(<:>\*(:> ! 1110: .Ps ! 1111: (The order-sign \*(<:<>\*(:> stands for ``not equals''.) ! 1112: .Ex 5 ! 1113: \k1order-tests: ! 1114: \h'|\n1u'\*(<:(i', j') > (i, j)\*(:> ! 1115: \&\h'|\n1u'\*(<:'0' <= d <= '9'\*(:> ! 1116: \h'|\n1u'\*(<:fa <= f(x) >= fb\*(:> ! 1117: .Xe ! 1118: The single-expressions are evaluated one by one, from left to right, ! 1119: and each adjacent pair is compared. ! 1120: As soon as a comparison does not comply with the given order-sign, ! 1121: the whole order-test fails and no further single-expressions are evaluated. ! 1122: The order-test succeeds if all comparisons comply with the ! 1123: specified order-signs. ! 1124: .br ! 1125: Note carefully that an approximate number is \fInever\fP equal to an exact ! 1126: number, so, for instance, if you want to compare an approximate number \*(<:a\*(:> ! 1127: for equality with an exact number \*(<:e\*(:>, you should write ! 1128: .Di 1 ! 1129: \*(<:IF a = ~e:\*(:>\ ... ! 1130: .Ed ! 1131: .br ! 1132: This also allows you to test if a number is exact or not: ! 1133: .Di 3 ! 1134: \*(<:SELECT: ! 1135: x = ~x: WRITE 'Approximate' ! 1136: ELSE: WRITE 'Exact'\*(:> ! 1137: .Ed ! 1138: .Se 2 6.3.2 PROPOSITIONS ! 1139: .Xx proposition ! 1140: .Xx user-defined predicate ! 1141: .Xx scratch-pad copy ! 1142: .Xx test-unit ! 1143: .Xx report-command ! 1144: .Xx succeed-command ! 1145: .Xx fail-command ! 1146: .Xx text, list or table ! 1147: .Sy 2 ! 1148: .Pr zeroadic-proposition 2 ! 1149: .Sl ! 1150: zeroadic-predicate ! 1151: .Pr monadic-proposition 2 ! 1152: .Sl ! 1153: monadic-predicate\0actual-operand ! 1154: .Pr dyadic-proposition 2 ! 1155: .Al ! 1156: actual-operand\0dyadic-predicate\0actual-operand ! 1157: .Pr zeroadic-predicate 2 ! 1158: .Sl ! 1159: tag ! 1160: .Pr monadic-predicate 2 ! 1161: .Sl ! 1162: tag ! 1163: .Pr dyadic-predicate 2 ! 1164: .Sl ! 1165: tag ! 1166: .Us 7 Propositions with user-defined predicates ! 1167: A proposition whose predicate is defined by a test-unit, is ! 1168: tested in the following steps: ! 1169: .in \w'2.\ 'u ! 1170: .ti 0 ! 1171: 1.\ A copy is made of the current environment (the value of ! 1172: all targets), and all computations during the testing of ! 1173: the proposition will take place in this ``scratch-pad copy''. ! 1174: .ti 0 ! 1175: 2.\ Any local tags in the test-unit that might clash with tags currently ! 1176: in use are systematically replaced by other tags that do not cause conflict. ! 1177: .ti 0 ! 1178: 3.\ Each actual-operand is evaluated and put in the ! 1179: corresponding formal-operand, used as a (new) ! 1180: target. ! 1181: .ti 0 ! 1182: 4.\ The command-suite of the unit, thus modified, is executed. ! 1183: .in 0 ! 1184: The testing of the proposition is complete when the execution ! 1185: of this command-suite terminates because of the execution ! 1186: of a report-, succeed- or fail-command; ! 1187: the proposition succeeds or fails accordingly. ! 1188: .Us 7 Propositions with predefined predicates ! 1189: .Qr ! 1190: \*(<:e in t\*(:> ! 1191: .Qe ! 1192: accepts texts, lists and tables for the right operand. ! 1193: It succeeds if \*(<:e#t > 0\*(:> succeeds, ! 1194: in other words, if the value \*(<:e\*(:> occurs in \*(<:t\*(:>. ! 1195: .Qr ! 1196: \*(<:e not'in t\*(:> ! 1197: .Qe ! 1198: is the same as \*(<:(NOT e in t)\*(:>. ! 1199: .Se 2 6.3.3 REFINED-TESTS ! 1200: .Xx scratch-pad copy ! 1201: .Xx report-command ! 1202: .Xx succeed-command ! 1203: .Xx fail-command ! 1204: .Xx bound tags ! 1205: .Sy 2 ! 1206: .Pr refined-test 2 ! 1207: .Sl ! 1208: tag ! 1209: .Sx 3 \k1refined-test: ! 1210: \*(<:special'case\*(:> ! 1211: .Xe ! 1212: .Tx ! 1213: A refined-test is ! 1214: tested in the following steps: ! 1215: .in \w'2.\ 'u ! 1216: .ti 0 ! 1217: 1.\ A copy is made of the current environment (the value of all targets), ! 1218: and all computations during the testing of ! 1219: the test will take place in this ``scratch-pad copy''. ! 1220: .ti 0 ! 1221: 2.\ The command-suite of the corresponding ! 1222: test-refinement is executed. ! 1223: .in 0 ! 1224: The testing of the refined-test is complete when the execution ! 1225: of this command-suite terminates because of the execution ! 1226: of a report-, succeed- or fail-command, and the refined-test ! 1227: succeeds or fails accordingly. ! 1228: .ne 3 ! 1229: .br ! 1230: Any bound tags set by a for-command or ! 1231: a quantification (see 6.3.7) at that time will temporarily survive ! 1232: for those parts that are reachable only by virtue of the outcome of the test. ! 1233: This is so that you can turn any test into a refined-test with the same effect. ! 1234: .br ! 1235: For example, in ! 1236: .Di 3 ! 1237: \*(<: IF divisible AND n > d**2: WRITE d ! 1238: \*(:>...\*(<: ! 1239: divisible: REPORT SOME d IN {2..n-1} HAS n mod d = 0\*(:>, ! 1240: .Ed ! 1241: the bound tag \*(<:d\*(:> is set to a divisor of \*(<:n\*(:> if the ! 1242: refined-test succeeds, and since the part \*(<:n > d**2\*(:> ! 1243: is only reached after success, \*(<:d\*(:> may be used there. ! 1244: The same is true for the write-command using \*(<:d\*(:>. ! 1245: The line after (indicated with three dots), however, can be ! 1246: reached if the divisibility test fails. ! 1247: So there \*(<:d\*(:> has ceased to exist. ! 1248: .Sa ! 1249: test-refinements (4.4). ! 1250: .Se 2 6.3.4 CONJUNCTIONS ! 1251: .Sy 2 ! 1252: .Pr conjunction 3 ! 1253: .Al ! 1254: tight-test \*(<:AND\*(:> right-test ! 1255: .Al ! 1256: tight-test \*(<:AND\*(:> conjunction ! 1257: .Ex 4 ! 1258: \k1conjunctions: ! 1259: \h'|\n1u'\*(<:a > 0 AND b > 0\*(:> ! 1260: \h'|\n1u'\*(<:i in keys t AND t[i] in keys u AND u[t[i]] <> 'dummy'\*(:> ! 1261: .Xe ! 1262: .Tx ! 1263: The tests of the conjunction, separated by \*(<:AND\*(:>, are tested ! 1264: one by one, from left to right. ! 1265: As soon as one of these tests fails, ! 1266: the whole conjunction fails and no further parts ! 1267: are tested. ! 1268: The conjunction succeeds if all its tests succeed. ! 1269: .Se 2 6.3.5 DISJUNCTIONS ! 1270: .Sy 2 ! 1271: .Pr disjunction 3 ! 1272: .Al ! 1273: tight-test \*(<:OR\*(:> right-test ! 1274: .Al ! 1275: tight-test \*(<:OR\*(:> disjunction ! 1276: .Ex 4 ! 1277: \k1disjunctions: ! 1278: \h'|\n1u'\*(<:a <= 0 OR b <= 0\*(:> ! 1279: \h'|\n1u'\*(<:n = 0 OR s[1] = s[n] OR t[1] = t[n]\*(:> ! 1280: .Xe ! 1281: .Tx ! 1282: The tests of the disjunction, separated by \*(<:OR\*(:>, are tested ! 1283: one by one, from left to right. ! 1284: As soon as one of these tests succeeds, ! 1285: the whole disjunction succeeds and no further parts ! 1286: are tested. ! 1287: The disjunction fails if all its tests fail. ! 1288: .Se 2 6.3.6 NEGATIONS ! 1289: .Sy 2 ! 1290: .Pr negation 2 ! 1291: .Sl ! 1292: \*(<:NOT\*(:> right-test ! 1293: .Sx 3 \k1negation: ! 1294: \*(<:NOT a subset b\*(:> ! 1295: .Xe ! 1296: .Tx ! 1297: A negation succeeds if its right-test fails, and fails if ! 1298: that test succeeds. ! 1299: .Se 3 6.3.7 QUANTIFICATIONS ! 1300: .Xx bound tags ! 1301: .Xx text, list or table ! 1302: .Xx character ! 1303: .Xx list entry ! 1304: .Xx associate ! 1305: .Sy 3 ! 1306: .Pr quantification 2 ! 1307: .Sl ! 1308: quantifier\0ranger \*(<:HAS\*(:> right-test ! 1309: .Pr quantifier 4 ! 1310: .Al ! 1311: \*(<:SOME\*(:> ! 1312: .Al ! 1313: \*(<:EACH\*(:> ! 1314: .Al ! 1315: \*(<:NO\*(:> ! 1316: .Pr ranger 3 ! 1317: .Al ! 1318: in-ranger ! 1319: .Al ! 1320: parsing-ranger ! 1321: .Pr parsing-ranger 3 ! 1322: .Sl ! 1323: multiple-identifier \*(<:PARSING\*(:> expression ! 1324: .Ps ! 1325: Note that the identifier of a parsing-ranger must be a multiple-identifier ! 1326: (like \*(<:p, q, r\*(:>): ! 1327: it may not be a single-identifier (like \*(<:pqr\*(:>). ! 1328: Moreover, each of the single-identifiers (like \*(<:p\*(:>) must be ! 1329: plain tags. ! 1330: The reason is that this determines the number of parts ! 1331: which the value of the expression must be split into (see below). ! 1332: .Bl 1 ! 1333: (For in-rangers, see for-commands, section 5.2.4.) ! 1334: .Ex 5 ! 1335: \k1quantifications: ! 1336: \h'|\n1u'\*(<:SOME p, q, r PARSING line HAS q in {'. '; '? '; '! '}\*(:> ! 1337: \h'|\n1u'\*(<:EACH i, j IN keys t HAS t[i, j] = t[j, i]\*(:> ! 1338: \h'|\n1u'\*(<:NO d IN {2..n-1} HAS n mod d = 0\*(:> ! 1339: .Xe ! 1340: .Tx ! 1341: The tags of the identifier of a quantifier may not be used as targets ! 1342: or target-contents ! 1343: outside such a quantifier. ! 1344: They are ``bound tags'', and lose their meaning outside the ! 1345: quantifier, except as described below. ! 1346: .Bl 2 ! 1347: The meaning of quantifications will first be described for ! 1348: the case of \*(<:SOME\*(:>\ ...\ \*(<:IN\*(:>\ ... ! 1349: .br ! 1350: The value of the expression must be a text, list or table. ! 1351: The items (characters, list entries or associates) of that value are ! 1352: assigned one by one to the identifier, and the right-test is ! 1353: tested each time. ! 1354: The quantification succeeds as soon as ! 1355: the right-test succeeds once. ! 1356: It fails only if the text, list or table is exhausted and the ! 1357: right-test has failed each time. ! 1358: .br ! 1359: If the quantification succeeds, ! 1360: the bound tags set at that moment ! 1361: will temporarily survive and may be used ! 1362: in those parts that are reachable only by virtue of the ! 1363: outcome of the test. ! 1364: .br ! 1365: For example, in ! 1366: .Di 3 ! 1367: \*(<: IF (SOME d IN {2..n-1} HAS n mod d = 0) AND n > d**2: WRITE d ! 1368: \*(:>\ ... ! 1369: .Ed ! 1370: the bound tag \*(<:d\*(:> is set to a divisor of \*(<:n\*(:> if the ! 1371: quantification succeeds, and since the part \*(<:n > d**2\*(:> ! 1372: is only reached after success, \*(<:d\*(:> may be used there. ! 1373: The same is true for the write-command using \*(<:d\*(:>. ! 1374: So, if \*(<:n\*(:> has the value \*(<:77\*(:>, \*(<:7\*(:> will be written, since ! 1375: the test \*(<:n mod d = 0\*(:> succeeds the first time when ! 1376: \*(<:d\*(:> is set to \*(<:7\*(:> (and \*(<:77 > 7**2\*(:>). ! 1377: The line after (indicated with three dots), however, can be ! 1378: reached if the divisibility test fails. ! 1379: So there \*(<:d\*(:> has ceased to exist and may not be used. ! 1380: .sp ! 1381: The meaning of a quantification \*(<:SOME id IN tlt HAS prop\*(:> ! 1382: can also be described as the meaning of the refined-test ! 1383: \*(<:test'if'some\*(:>, given ! 1384: a test-refinement ! 1385: .Di 4 ! 1386: \*(<:test'if'some: ! 1387: FOR id IN tlt: ! 1388: IF prop: SUCCEED ! 1389: FAIL\*(:> ! 1390: .Ed ! 1391: .Bl 3 ! 1392: The meaning of \*(<:EACH id IN tlt HAS prop\*(:> ! 1393: is the same as that of \*(<:NOT SOME id IN tlt HAS NOT prop\*(:>. ! 1394: In other words, an \*(<:EACH\*(:> quantification succeeds only if its ! 1395: right-test succeeds each time. ! 1396: .br ! 1397: The meaning of \*(<:NO id IN tlt HAS prop\*(:> ! 1398: is the same as that of \*(<:NOT SOME id IN tlt HAS prop\*(:>. ! 1399: In other words, a \*(<:NO\*(:> quantification succeeds only if its ! 1400: right-test fails each time. ! 1401: .br ! 1402: The rules for temporary survival are the same as for \*(<:SOME\*(:>. ! 1403: So an \*(<:EACH\*(:> or \*(<:NO\*(:> quantification will only have set its ! 1404: bound tags on failure. ! 1405: Thus, in the following, the bound tag \*(<:d\*(:> survives into the \*(<:ELSE\*(:>: ! 1406: .Di 4 ! 1407: \*(<:SELECT: ! 1408: NO d IN {2..n-1} HAS n mod d = 0: ! 1409: WRITE 'prime' ! 1410: ELSE: WRITE 'divisible by `d`'\*(:> ! 1411: .Ed ! 1412: .Bl 3 ! 1413: If \*(<:PARSING\*(:> is specified, ! 1414: all \fIparsings\fP of the value of the given expression are ! 1415: tried, instead of its items. ! 1416: The value of the expression must be a text. ! 1417: A ``parsing'' of a text is a way of splitting it in parts. ! 1418: The text is split in all possible ways in as many parts as ! 1419: there are tags in the multiple-identifier, and each split ! 1420: is put in that identifier, whereupon the right-test is tested. ! 1421: For example, ! 1422: .Di 1 ! 1423: \*(<:SOME p, q, r PARSING 'abracadabra' HAS (p = r AND #p > 3)\*(:> ! 1424: .Ed ! 1425: will succeed with \*(<:p\*(:> and \*(<:r\*(:> set to \*(<:'abra'\*(:> and \*(<:q\*(:> set to \*(<:'cad'\*(:>. ! 1426: If the test \*(<:#p > 3\*(:> is omitted, the quantification will ! 1427: succeed with the uninteresting result that \*(<:p\*(:> and \*(<:r\*(:> are set ! 1428: to \*(<:''\*(:> and \*(<:q\*(:> to \*(<:'abracadabra'\*(:>. ! 1429: .br ! 1430: To give another example, ! 1431: .Di 3 ! 1432: \*(<: PUT 'a man, a plan, a canal: panama!' IN palindrome ! 1433: WHILE SOME hd, x, tl PARSING palindrome HAS x'non'letter: ! 1434: PUT hd^tl IN palindrome ! 1435: WRITE palindrome / ! 1436: x'non'letter: REPORT #x = 1 AND x not'in {'a'..'z'}\*(:> ! 1437: .Ed ! 1438: will successively find and remove all non-letters from the ! 1439: text in \*(<:palindrome\*(:> finally leaving the text \*(<:'amanaplanacanalpanama'\*(:>. ! 1440: (This is not a recommended way, because it will be very slow. ! 1441: There are equally simple and much faster ways to achieve the same effect. ! 1442: The example is only chosen to illustrate the possibilities of \*(<:PARSING\*(:>.) ! 1443: Note that the test \*(<:#x = 1\*(:> here is essential. ! 1444: If it is omitted, the program will go ! 1445: into an endless loop ``removing'' empty texts \*(<:x\*(:> from \*(<:palindrome\*(:>. ! 1446: .br ! 1447: The meaning of \*(<:SOME p, q,\*(:>\ ...\ \*(<:PARSING whole HAS prop\*(:> ! 1448: may more precisely be described as follows. ! 1449: Let \*(<:parsings\*(:> stand for a list, containing ! 1450: \fIall\fP compounds with the same number of fields as the ! 1451: multiple-identifier \*(<:p, q,\*(:>\ ..., such that those fields ! 1452: (which are texts) joined together give the text \*(<:whole\*(:>. ! 1453: For example, in ! 1454: .Di 1 ! 1455: \*(<:SOME p, q, r PARSING 'abracadabra' HAS (p = r AND #p > 3)\*(:> ! 1456: .Ed ! 1457: the list \*(<:parsings\*(:> will begin with ! 1458: .Di 1 ! 1459: \*(<:{('', '', 'abracadabra'); ('', 'a', 'bracadabra');\*(:>\ ...\ , ! 1460: .Ed ! 1461: contain somewhere in the middle ! 1462: .Di 1 ! 1463: \&...\ \*(<:; ('abra', 'cad', 'abra');\*(:>\ ...\ , ! 1464: .Ed ! 1465: and end with ! 1466: .Di 1 ! 1467: \&...\ \*(<:; ('abracadabr', 'a', ''); ('abracadabra', '', '')}\*(:>. ! 1468: .Ed ! 1469: The effect of the quantification is then the same as that ! 1470: of ! 1471: .Di 1 ! 1472: \*(<:SOME p, q,\*(:>\ ...\ \*(<:IN parsings HAS prop\*(:>. ! 1473: .Ed ! 1474: The meaning of \*(<:EACH\*(:> or \*(<:NO\*(:> is accordingly defined. ! 1475: .Sa ! 1476: for-commands (5.2.4). ! 1477: .ps 10 ! 1478: .vs 12 ! 1479: .de PH\"Page Header ! 1480: .ie \\n+(cl<3 \{\ ! 1481: .po +\\n(TWu/3u ! 1482: .rt ! 1483: .ns \} ! 1484: .el \{\ ! 1485: .po \\n(POu ! 1486: .nr f1 \\n(.f\" current font ! 1487: .ft ! 1488: .nr f2 \\n(.f\" previous font ! 1489: .ft R ! 1490: .nr sp \\n(.s\"current point size ! 1491: .ps \\n(ms-1 ! 1492: 'bp ! 1493: .CM \" Cut Mark ! 1494: 'ie o 'tl ''\\*(TL'\\*(Sn' ! 1495: 'el 'tl '\\*(Sn'\\*(TL'' ! 1496: .ft \\n(f2\" restore previous font ! 1497: .ft \\n(f1\" restore current font ! 1498: .ps \\n(sp\"restore point size ! 1499: 'sp 2 ! 1500: .mk ! 1501: 'ns ! 1502: 'EH\"Extra Header ! 1503: 'nr cl 0 1 \} ! 1504: 'na ! 1505: .. ! 1506: .ch PH ! 1507: .wh -(\n(HFu-1v) PH ! 1508: .de Fo\" Page footer ! 1509: .nr f1 \\n(.f\" current font ! 1510: .ft ! 1511: .nr f2 \\n(.f\" previous font ! 1512: .ft R ! 1513: .nr sp \\n(.s\"current point size ! 1514: .ps \\n(ms-1 ! 1515: .po \\n(POu ! 1516: .if \\n%>2 .tl ''%'' ! 1517: .po ! 1518: .ft \\n(f2\" restore previous font ! 1519: .ft \\n(f1\" restore current font ! 1520: .ps \\n(sp\"restore point size ! 1521: .. ! 1522: .de XX ! 1523: .br ! 1524: .ti 0 ! 1525: .. ! 1526: .ds Sn Index ! 1527: .nr cl 4 1 ! 1528: .ll \n(TWu/3u-2n ! 1529: .na ! 1530: .bp ! 1531: .Us 3 INDEX ! 1532: .mk ! 1533: .in 2n ! 1534: .XX ! 1535: actual-operand 6.1.6 ! 1536: .XX ! 1537: actual-parameter 5.1.16 ! 1538: .XX ! 1539: alternative-sequence 5.2.2 ! 1540: .XX ! 1541: alternative-suite 5.2.2 ! 1542: .XX ! 1543: ambiguity 6.1.5, 6.1.6 ! 1544: .XX ! 1545: approximate 6.3.1 ! 1546: .XX ! 1547: approximate-constant 6.1.1 ! 1548: .XX ! 1549: approximate number 1 ! 1550: .XX ! 1551: associate 1, 5.1.6, 5.2.4, 6.1.4, 6.1.5, 6.1.6, 6.2.3, 6.3.7 ! 1552: .XX ! 1553: basic-expression 6.1 ! 1554: .XX ! 1555: basic-target 6.2 ! 1556: .XX ! 1557: bound tags 5.1.13, 5.1.14, 5.1.15, 5.2.4, 6.3, 6.3.3, 6.3.7 ! 1558: .XX ! 1559: brackets 6.1.6 ! 1560: .XX ! 1561: character 1, 5.1.6, 5.2.4, 6.1.5, 6.1.6, 6.3.7 ! 1562: .XX ! 1563: check-command 5.1.1 ! 1564: .XX ! 1565: choose-command 5.1.6 ! 1566: .XX ! 1567: command 5 ! 1568: .XX ! 1569: command-refinement 4.4, 5.1.11, 5.1.17 ! 1570: .XX ! 1571: command-sequence 4.5 ! 1572: .XX ! 1573: command-suite 4.5 ! 1574: .XX ! 1575: comment 3 ! 1576: .XX ! 1577: compound 1, 6.1, 6.2 ! 1578: .XX ! 1579: conjunction 6.3.4 ! 1580: .XX ! 1581: control-command 5.2 ! 1582: .XX ! 1583: conversion 6.1.5 ! 1584: .XX ! 1585: convert to a text 5.1.2, 6.1.5, 6.1.6 ! 1586: .XX ! 1587: decrease-indentation 3 ! 1588: .XX ! 1589: delete-command 5.1.10 ! 1590: .XX ! 1591: denominator 6.1.6 ! 1592: .XX ! 1593: digit 6.1.1 ! 1594: .XX ! 1595: disjunction 6.3.5 ! 1596: .XX ! 1597: display 6.1.5 ! 1598: .XX ! 1599: draw-command 5.1.5 ! 1600: .XX ! 1601: dyadic 4.2, 4.3 ! 1602: .XX ! 1603: dyadic-formula 6.1.6 ! 1604: .XX ! 1605: dyadic-function 6.1.6 ! 1606: .XX ! 1607: dyadic-predicate 6.3.2 ! 1608: .XX ! 1609: dyadic-proposition 6.3.2 ! 1610: .XX ! 1611: else-alternative 5.2.2 ! 1612: .XX ! 1613: empty 2 ! 1614: .XX ! 1615: empty list 6.1.5 ! 1616: .XX ! 1617: empty table 6.1.5 ! 1618: .XX ! 1619: entry 1 ! 1620: .XX ! 1621: equal 6.3.1 ! 1622: .XX ! 1623: exact 6.3.1 ! 1624: .XX ! 1625: exact-constant 6.1.1 ! 1626: .XX ! 1627: exact number 1 ! 1628: .XX ! 1629: exponent-part 6.1.1 ! 1630: .XX ! 1631: expression 6.1 ! 1632: .XX ! 1633: expression-refinement 4.4, 4.5, 5.1.12, 6.1.7 ! 1634: .XX ! 1635: fail-command 4.5, 5.1.15, 6.3.2, 6.3.3 ! 1636: .XX ! 1637: field 1 ! 1638: .XX ! 1639: for-command 5.2.4 ! 1640: .XX ! 1641: formal-dyadic-formula 4.2 ! 1642: .XX ! 1643: formal-dyadic-proposition 4.3 ! 1644: .XX ! 1645: formal-formula 4.2 ! 1646: .XX ! 1647: formal-monadic-formula 4.2 ! 1648: .XX ! 1649: formal-monadic-proposition 4.3 ! 1650: .XX ! 1651: formal-operand 4.2 ! 1652: .XX ! 1653: formal-parameter 4.1 ! 1654: .XX ! 1655: formal-proposition 4.3 ! 1656: .XX ! 1657: formal-tail 4.1 ! 1658: .XX ! 1659: formal-trailer 4.1 ! 1660: .XX ! 1661: formal-user-defined-command 4.1 ! 1662: .XX ! 1663: formal-zeroadic-formula 4.2 ! 1664: .XX ! 1665: formal-zeroadic-proposition 4.3 ! 1666: .XX ! 1667: formula 4.2, 4.3, 6.1.6 ! 1668: .XX ! 1669: fractional-part 6.1.1 ! 1670: .XX ! 1671: function 4.2, 4.3, 6.1.6 ! 1672: .XX ! 1673: further-comment 3 ! 1674: .XX ! 1675: global 4.5, 5 ! 1676: .XX ! 1677: how-to-unit 4.1, 5.1.11, 5.1.16 ! 1678: .XX ! 1679: identifier 6.2.1 ! 1680: .XX ! 1681: if-command 5.2.1 ! 1682: .XX ! 1683: immediate command 5, 5.1.11 ! 1684: .XX ! 1685: in-ranger 5.2.4 ! 1686: .XX ! 1687: increase-indentation 3 ! 1688: .XX ! 1689: indentation 3 ! 1690: .XX ! 1691: insert-command 5.1.9 ! 1692: .XX ! 1693: integer 6.1.3, 6.1.5, 6.1.6 ! 1694: .XX ! 1695: integral-part 6.1.1 ! 1696: .XX ! 1697: interrupt key 5, 5.1.2 ! 1698: .XX ! 1699: key 1, 6.1.4, 6.1.5, 6.1.6, 6.2.3 ! 1700: .XX ! 1701: keyword 3, 4.1, 4.4, 5.1.16, 5.1.17 ! 1702: .XX ! 1703: list 1 ! 1704: .XX ! 1705: list-body 6.1.5 ! 1706: .XX ! 1707: list-display 6.1.5 ! 1708: .XX ! 1709: list entry 1, 5.1.6, 5.1.8, 5.1.9, 5.2.4, 6.1.6, 6.3.7 ! 1710: .XX ! 1711: list-filler 6.1.5 ! 1712: .XX ! 1713: list-filler-series 6.1.5 ! 1714: .XX ! 1715: local 4.5, 6.1.6, 6.2.1 ! 1716: .XX ! 1717: location 5.1.4, 5.1.10, 6.2.1, 6.2.3 ! 1718: .XX ! 1719: monadic 4.2, 4.3 ! 1720: .XX ! 1721: monadic-formula 6.1.6 ! 1722: .XX ! 1723: monadic-function 6.1.6 ! 1724: .XX ! 1725: monadic-predicate 6.3.2 ! 1726: .XX ! 1727: monadic-proposition 6.3.2 ! 1728: .XX ! 1729: multiple-expression 6.1 ! 1730: .XX ! 1731: multiple-identifier 6.2.1 ! 1732: .XX ! 1733: multiple-target 6.2 ! 1734: .XX ! 1735: negation 6.3.6 ! 1736: .XX ! 1737: new-line 3 ! 1738: .XX ! 1739: new-line-proper 3 ! 1740: .XX ! 1741: new-liners 5.1.2 ! 1742: .XX ! 1743: number 1, 5.1.5, 6.1.6, 6.3.1 ! 1744: .XX ! 1745: numerator 6.1.6 ! 1746: .XX ! 1747: numeric-constant 6.1.1 ! 1748: .XX ! 1749: optional-ANYTHING 2 ! 1750: .XX ! 1751: order 1, 6.3.1 ! 1752: .XX ! 1753: order-sign 6.3.1 ! 1754: .XX ! 1755: order-test 6.3.1 ! 1756: .XX ! 1757: overloading of functions and predicates 4.2, 4.3 ! 1758: .XX ! 1759: parentheses 6.1.6 ! 1760: .XX ! 1761: parsing-ranger 6.3.7 ! 1762: .XX ! 1763: permanent environment 4.5, 5.1.2, 5.1.11 ! 1764: .XX ! 1765: plusminus 6.1.1 ! 1766: .XX ! 1767: predefined functions 6.1.6 ! 1768: .XX ! 1769: predefined predicates 6.3.2 ! 1770: .XX ! 1771: predicate 4.2, 4.3 ! 1772: .XX ! 1773: priority 6.1.6 ! 1774: .XX ! 1775: proposition 4.3, 6.3.2 ! 1776: .XX ! 1777: put-command 5.1.4 ! 1778: .XX ! 1779: quantification 6.3.7 ! 1780: .XX ! 1781: quantifier 6.3.7 ! 1782: .XX ! 1783: quit-command 5.1.11, 5.1.16, 5.1.17 ! 1784: .XX ! 1785: quote 6.1.5 ! 1786: .XX ! 1787: random 5.1.5, 5.1.6, 5.1.7 ! 1788: .XX ! 1789: ranger 6.3.7 ! 1790: .XX ! 1791: read-command 5.1.3 ! 1792: .XX ! 1793: refined-command 5.1.17 ! 1794: .XX ! 1795: refined-expression 5.1.12, 6.1.7 ! 1796: .XX ! 1797: refined-test 5.1.13, 5.1.14, 5.1.15, 6.3.3 ! 1798: .XX ! 1799: refinement 4.4 ! 1800: .XX ! 1801: refinement-suite 4 ! 1802: .XX ! 1803: remove-command 5.1.8 ! 1804: .XX ! 1805: report-command 4.5, 5.1.13, 6.3.2, 6.3.3 ! 1806: .XX ! 1807: return-command 4.5, 5.1.12, 6.1.6, 6.1.7 ! 1808: .XX ! 1809: right-expression 6.1 ! 1810: .XX ! 1811: right-test 6.3 ! 1812: .XX ! 1813: scratch-pad copy 6.1, 6.1.6, 6.1.7, 6.3, 6.3.2, 6.3.3 ! 1814: .XX ! 1815: select-command 5.2.2 ! 1816: .XX ! 1817: set-random-command 5.1.7 ! 1818: .XX ! 1819: share-heading 4.5 ! 1820: .XX ! 1821: simple-command 5.1 ! 1822: .XX ! 1823: simple-expression 6.1 ! 1824: .XX ! 1825: single-alternative 5.2.2 ! 1826: .XX ! 1827: single-expression 6.1 ! 1828: .XX ! 1829: single-identifier 6.2.1 ! 1830: .XX ! 1831: single-target 6.2 ! 1832: .XX ! 1833: spaces 3 ! 1834: .XX ! 1835: succeed-command 4.5, 5.1.14, 6.3.2, 6.3.3 ! 1836: .XX ! 1837: table 1 ! 1838: .XX ! 1839: table-display 6.1.5 ! 1840: .XX ! 1841: table entry 1, 5.1.10, 6.1.4, 6.2.3 ! 1842: .XX ! 1843: table-filler 6.1.5 ! 1844: .XX ! 1845: table-filler-series 6.1.5 ! 1846: .XX ! 1847: table-selection 6.1.4 ! 1848: .XX ! 1849: table-selection-target 5.1.10, 6.2.3 ! 1850: .XX ! 1851: tag 3, 6.2.1 ! 1852: .XX ! 1853: target 4.5, 5.1.4, 5.2.4, 6.1.6, 6.2, 6.2.1 ! 1854: .XX ! 1855: target-content 6.1.2 ! 1856: .XX ! 1857: terminating-command 5.1, 5.2.3 ! 1858: .XX ! 1859: test 4.3, 6.3 ! 1860: .XX ! 1861: test-refinement 4.4, 4.5, 5.1.13, 5.1.14, 5.1.15 ! 1862: .XX ! 1863: test-unit 4.3, 4.5, 5.1.13, 5.1.14, 5.1.15, 6.3.2 ! 1864: .XX ! 1865: text 1, 6.1.6 ! 1866: .XX ! 1867: text, list and table 5.1.6, 5.2.4, 6.1.6, 6.3.2, 6.3.7 ! 1868: .XX ! 1869: text-display 6.1.5 ! 1870: .XX ! 1871: tight-expression 6.1 ! 1872: .XX ! 1873: tight-test 6.3 ! 1874: .XX ! 1875: trailer 5.1.16 ! 1876: .XX ! 1877: trimmed-text 6.1.3 ! 1878: .XX ! 1879: trimmed-text-target 6.2.2 ! 1880: .XX ! 1881: type 5.1.4, 6.2.3 ! 1882: .XX ! 1883: unit 4 ! 1884: .XX ! 1885: user-defined-command 4.1, 5.1.16 ! 1886: .XX ! 1887: user-defined-function 4.2, 5.1.12, 6.1.6 ! 1888: .XX ! 1889: user-defined-predicate 4.3, 5.1.13, 5.1.14, 5.1.15, 6.3.2 ! 1890: .XX ! 1891: while-command 5.2.3 ! 1892: .XX ! 1893: work-space 4, 4.5 ! 1894: .XX ! 1895: write-command 5.1.2 ! 1896: .XX ! 1897: yield-unit 4.2, 4.5, 5.1.12, 6.1.6 ! 1898: .XX ! 1899: zeroadic 4.2, 4.3 ! 1900: .XX ! 1901: zeroadic-formula 6.1.6 ! 1902: .XX ! 1903: zeroadic-function 6.1.6 ! 1904: .XX ! 1905: zeroadic-predicate 6.3.2 ! 1906: .XX ! 1907: zeroadic-proposition 6.3.2 ! 1908: .rm PH ! 1909: .wh -0 CM ! 1910: .bp
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.