3ee81d8c129a511ddb26b34d22ebc4fe257fb124a99e2b2f1afce8a1b3087009.tri (4904B)
1 !export compare 2 !export equal 3 !export lt 4 !export lte 5 !export gt 6 !export gte 7 !export inRange 8 !export minimum 9 !export maximum 10 !export zero 11 !export odd 12 !export even 13 !export successor 14 !export predecessor 15 !export add 16 !export subtract 17 !export multiply 18 !export divMod 19 !export quotient 20 !export remainder 21 !export power 22 !export decimal 23 !export ascii 24 !export digit 25 !export letter 26 !export lowerHex 27 !export printable 28 -- Canonical natural numbers only. No validation or contracts on this path. 29 -- Self-contained binary algorithms. Stable direct recursion is the authoring path. 30 -- Subtraction saturates. divMod a 0 = (0,a); public base division rejects zero. 31 32 triage leaf stem fork = t (t leaf stem) fork 33 choose yes no value = triage no (_ : yes) (_ _ : yes) value 34 lazy yes no value = choose yes no value t 35 not value = choose t (t t) value 36 both a b = choose b t a 37 either a b = choose (t t) b a 38 xor a b = choose (not b) b a 39 -- Ordering: Leaf = equal, Stem Leaf = less, Fork Leaf Leaf = greater. 40 bitOrder a b = choose (choose t (t t t) b) (choose (t t) t b) a 41 compare a b = (triage 42 (triage t (_ : t) (_ _ : t t) b) 43 (_ : t) 44 (abit ar : triage (t t t) (_ : t) 45 (bbit br : triage (bitOrder abit bbit) (_ : t t) (_ _ : t t t) 46 (compare ar br)) b) 47 a) 48 isEqual order = triage (t t) (_ : t) (_ _ : t) order 49 isLess order = triage t (_ : t t) (_ _ : t) order 50 isGreater order = triage t (_ : t) (_ _ : t t) order 51 -- Equality may stop at the first differing low bit; ordering cannot. 52 equal a b = (triage 53 (zero b) 54 (_ : t) 55 (abit ar : triage t (_ : t) 56 (bbit br : lazy (_ : t) (_ : equal ar br) (xor abit bbit)) b) 57 a) 58 lt a b = isLess (compare a b) 59 lte a b = not (isGreater (compare a b)) 60 gt a b = isGreater (compare a b) 61 gte a b = not (isLess (compare a b)) 62 inRange value low high = both (gte value low) (lte value high) 63 minimum a b = choose b a (gt a b) 64 maximum a b = choose a b (gt a b) 65 zero value = triage (t t) (_ : t) (_ _ : t) value 66 odd value = triage t (_ : t) (bit rest : bit) value 67 even value = not (odd value) 68 69 -- Discard a redundant high zero bit when rebuilding after subtraction. 70 node bit rest = choose (t bit rest) (choose t (t bit rest) (zero rest)) bit 71 double value = node t value 72 successor value = (triage (t (t t) t) (_ : t) 73 (bit rest : triage (t (t t) rest) (_ : t t (successor rest)) (_ _ : t) bit) value) 74 predecessor value = (triage t (_ : t) 75 (bit rest : lazy (_ : node t rest) (_ : t (t t) (predecessor rest)) bit) value) 76 77 carry a b c = either (both a b) (both c (xor a b)) 78 addCarry a b c = (triage 79 (lazy (_ : successor b) (_ : b) c) 80 (_ : t) 81 (abit ar : triage 82 (lazy (_ : successor a) (_ : a) c) 83 (_ : t) 84 (bbit br : t (xor (xor abit bbit) c) (addCarry ar br (carry abit bbit c))) b) 85 a) 86 add a b = addCarry a b t 87 88 borrow a b c = either (both (not a) b) (both c (not (xor a b))) 89 subtractBorrow a b c = (triage t (_ : t) 90 (abit ar : triage 91 (lazy (_ : predecessor a) (_ : a) c) 92 (_ : t) 93 (bbit br : node (xor (xor abit bbit) c) (subtractBorrow ar br (borrow abit bbit c))) b) 94 a) 95 subtract a b = lazy (_ : t) (_ : subtractBorrow a b t) (lt a b) 96 97 multiply a b = (let rec 98 walk remaining = (triage t (_ : t) 99 (bit rest : lazy 100 (_ : add a (double (walk rest))) 101 (_ : double (walk rest)) bit) 102 remaining) 103 in walk b) 104 105 -- Binary long division: consume high bits first. If r < divisor, then 106 -- 2*r + bit < 2*divisor, so each step needs at most one subtraction. 107 -- Return a pair, sharing quotient/remainder work rather than dividing twice. 108 divMod dividend divisor = (lazy 109 (_ : t t dividend) 110 (_ : let rec 111 walk remaining = (triage 112 (t t t) 113 (_ : t t t) 114 (bit rest : step bit (walk rest)) 115 remaining) 116 in walk dividend) 117 (zero divisor) 118 where 119 step bit partial = (triage t (_ : t) 120 (quot rem : let shifted = node bit rem in lazy 121 (_ : t (double quot) shifted) 122 (_ : t (t (t t) quot) (subtract shifted divisor)) 123 (lt shifted divisor)) 124 partial)) 125 126 quotient a b = triage t (_ : t) (q r : q) (divMod a b) 127 remainder a b = triage t (_ : t) (q r : r) (divMod a b) 128 129 -- Exponentiation by squaring; 0^0 = 1. Do not square an unused final factor. 130 -- Work is bit-directed, but output size can still be enormous. 131 power base exponent = (let rec 132 walk factor remaining acc = (triage 133 acc 134 (_ : acc) 135 (bit rest : let next = lazy (_ : multiply acc factor) (_ : acc) bit in lazy 136 (_ : next) 137 (_ : walk (multiply factor factor) rest next) 138 (zero rest)) 139 remaining) 140 in walk base exponent 1) 141 142 -- Decimal accumulation: value * 10 + digit (digit must be 0..9). 143 decimal value digit = add (add (double (double (double value))) (double value)) digit 144 145 ascii value = lte value 127 146 digit value = inRange value 48 57 147 letter value = either (inRange value 65 90) (inRange value 97 122) 148 lowerHex value = either (digit value) (inRange value 97 102) 149 printable value = inRange value 32 126