diff options
author | Marvin Borner | 2024-05-02 21:57:58 +0200 |
---|---|---|
committer | Marvin Borner | 2024-05-02 21:57:58 +0200 |
commit | a25ed8a75d036de252cfe74b5fa0788215194b41 (patch) | |
tree | 65ab549fe20b719535113a4af40bd4c784765cbb | |
parent | 349e8574c67bf575ed39694c8085eab00473bfaa (diff) |
More math
MAATHTHAHHAHA
-rw-r--r-- | docs/code.js | 2 | ||||
-rw-r--r-- | docs/index.html | 2 | ||||
-rw-r--r-- | editors/vim/syntax/bruijn.vim | 4 | ||||
-rw-r--r-- | samples/euler/007.bruijn | 2 | ||||
-rw-r--r-- | samples/fun/pi-rational.bruijn | 28 | ||||
-rw-r--r-- | samples/rosetta/fibonacci_sequence.bruijn | 2 | ||||
-rw-r--r-- | src/Parser.hs | 6 | ||||
-rw-r--r-- | std/List.bruijn | 11 | ||||
-rw-r--r-- | std/Math.bruijn | 18 | ||||
-rw-r--r-- | std/Math/Complex.bruijn | 35 | ||||
-rw-r--r-- | std/Math/Rational.bruijn | 7 | ||||
-rw-r--r-- | std/Math/Real.bruijn | 68 | ||||
-rw-r--r-- | std/Number/Conversion.bruijn | 2 | ||||
-rw-r--r-- | std/Number/Parigot.bruijn | 24 | ||||
-rw-r--r-- | std/Number/Scott.bruijn | 31 | ||||
-rw-r--r-- | std/Number/Ternary.bruijn | 8 | ||||
-rw-r--r-- | std/Number/Unary.bruijn | 3 | ||||
-rw-r--r-- | std/Number/Wadsworth.bruijn | 23 |
18 files changed, 234 insertions, 42 deletions
diff --git a/docs/code.js b/docs/code.js index 8fd7158..599068e 100644 --- a/docs/code.js +++ b/docs/code.js @@ -11,7 +11,7 @@ const term = (t) => .replaceAll(/'([^\'])'/g, "<span class='string'>'$1'</span>") .replaceAll(/"([^\"]*)"/g, "<span class='string'>\"$1\"</span>") .replaceAll( - /(\([+-][0-9]+\.[0-9]+[frc]?\))/g, + /(\([+-][0-9]+\.[0-9]+[qr]?\))/g, "<span class='number'>$1</span>", ) .replaceAll(/(\([+-][0-9]+[ubtd]?\))/g, "<span class='number'>$1</span>") diff --git a/docs/index.html b/docs/index.html index 837492f..931b706 100644 --- a/docs/index.html +++ b/docs/index.html @@ -153,7 +153,7 @@ in std/Number/Unary.bruijn:35 <li> Compiled binary lambda calculus is incredibly expressive and tiny. Read the articles by - <a href="https://justine.lol/lambda/#why">Justine</a> and + <a href="https://justine.lol/lambda/#why">Jart</a> and <a href="https://tromp.github.io/cl/cl.html">Tromp</a>. </li> <li> diff --git a/editors/vim/syntax/bruijn.vim b/editors/vim/syntax/bruijn.vim index fbe7a47..4f20593 100644 --- a/editors/vim/syntax/bruijn.vim +++ b/editors/vim/syntax/bruijn.vim @@ -10,8 +10,8 @@ syn match bruijnAbstraction /[[\]]/ syn match bruijnIndex /\([^0-9A-Za-z]\)\@<=\d\([^0-9]\)\@=/ syn match bruijnChar /'\@<=.'\@=/ syn match bruijnNumber /([+-]\d\+[dubt]\?)/ -syn match bruijnFloat /([+-]\d\+\.\d\+[fr]\?)/ -syn match bruijnComplex /([+-]\d\+\.\d\+i[+-]\d\+\.\d\+)/ +syn match bruijnFloat /([+-]\d\+\.\d\+[qr]\?)/ +syn match bruijnComplex /([+-]\d\+\.\d\+[+-]\d\+\.\d\+i)/ syn match bruijnDefinition /^\t*\S\+/ syn match bruijnType /\( ⧗ \)\@<=.*$/ syn match bruijnTypeDelim / ⧗ / diff --git a/samples/euler/007.bruijn b/samples/euler/007.bruijn index 6d05451..c14b41f 100644 --- a/samples/euler/007.bruijn +++ b/samples/euler/007.bruijn @@ -4,7 +4,7 @@ :import std/Math . :import std/List . -solve dec → (\index primes) +solve dec → (index primes) :test ((solve (+6)) =? (+13)) ([[1]]) diff --git a/samples/fun/pi-rational.bruijn b/samples/fun/pi-rational.bruijn new file mode 100644 index 0000000..245f45f --- /dev/null +++ b/samples/fun/pi-rational.bruijn @@ -0,0 +1,28 @@ +:import std/Pair . +:import std/Combinator . +:import std/Number/Unary . + +qadd &[[&[[p : q]]]] ⧗ Rational → Rational → Rational + p (3 ⋅ ++0) + (1 ⋅ ++2) + q (2 ⋅ 0) + (2 + 0) + +fac [[1 [[0 (1 [[2 1 (1 0)]])]] [1] i]] ⧗ Unary → Unary + +# challenge: smallest, yet fastest converging, π ratio calculation + +# naive +v1-pi/2 [0 &[[op]] start [[1]]] + start ((+0u) : (+0u)) : (+0u) + op (qadd 1 (enum : --denom)) : ++0 + enum (0 (+2u)) ⋅ ((+2u) (fac 0)) + denom fac ++((+2u) ⋅ 0) + +dfac [[1 [[0 (1 [[2 1 (1 (1 0))]])]] [1] i]] ⧗ Unary → Unary + +# double factorial +# dfac and fac could be shared! +v2-pi/2 [0 &[[op]] start [[1]]] + start ((+0u) : (+0u)) : (+0u) + op (qadd 1 (enum : --denom)) : ++0 + enum fac 0 + denom dfac ++0 diff --git a/samples/rosetta/fibonacci_sequence.bruijn b/samples/rosetta/fibonacci_sequence.bruijn index d2e4752..dc64962 100644 --- a/samples/rosetta/fibonacci_sequence.bruijn +++ b/samples/rosetta/fibonacci_sequence.bruijn @@ -8,7 +8,7 @@ fib-unary [0 [[[2 0 [2 (1 0)]]]] k i] :test (fib-unary (+6u)) ((+8u)) # ternary fibonacci using infinite list iteration (very fast) -fib-list \index fibs +fib-list index fibs fibs head <$> (iterate &[[0 : (1 + 0)]] ((+0) : (+1))) :test (fib-list (+6)) ((+8)) diff --git a/src/Parser.hs b/src/Parser.hs index a24db6f..0274906 100644 --- a/src/Parser.hs +++ b/src/Parser.hs @@ -149,11 +149,11 @@ parseFloat :: Parser Expression parseFloat = do _ <- string "(" <?> "float start" num <- signedFloat <?> "signed float" - base <- try (oneOf "fr") <|> return 'f' + base <- try (oneOf "qr") <|> return 'q' _ <- string ")" <?> "float end" pure $ f base num where - f 'f' = floatToRational + f 'q' = floatToRational f 'r' = floatToReal f _ = invalidProgramState sign :: Parser (Rational -> Rational) @@ -171,8 +171,8 @@ parseComplex :: Parser Expression parseComplex = do _ <- string "(" <?> "complex start" real <- signedFloat <?> "signed complex" - _ <- char 'i' imaginary <- signedFloat <?> "signed complex" + _ <- char 'i' _ <- string ")" <?> "complex end" pure $ floatToComplex real imaginary where diff --git a/std/List.bruijn b/std/List.bruijn index 799e966..d8d7dc9 100644 --- a/std/List.bruijn +++ b/std/List.bruijn @@ -89,11 +89,11 @@ index-unary [[P.fst (0 P.snd 1)]] ⧗ (List a) → Unary → a # returns the element at index in list index z [[[rec]]] ⧗ (List a) → Number → a - rec 0 [[[case-index]]] case-end - case-index =?4 2 (5 --4 1) + rec 1 [[[case-index]]] case-end + case-index =?3 2 (5 1 --3) case-end empty -…!!… \index +…!!… index :test (((+1) : ((+2) : {}(+3))) !! (+0)) ((+1)) :test (((+1) : ((+2) : {}(+3))) !! (+2)) ((+3)) @@ -519,12 +519,15 @@ iterate z [[[rec]]] ⧗ (a → a) → a → (List a) :test (take (+5) (iterate i (+4))) (take (+5) (repeat (+4))) :test (take (+0) (iterate ++‣ (+0))) (empty) +# TODO: performance +nth-iterate index ∘∘ iterate + # enumerate list enumerate zip (iterate ++‣ (+0)) ⧗ (List a) → (List (Pair Number a)) :test (enumerate "abc") (((+0) : 'a') : (((+1) : 'b') : {}((+2) : 'c'))) -# calculates all fixed points of given function as a list +# calculates all fixed points of given functions as a list y* [[[0 1] <$> 0] xs] ⧗ (List a) → (List b) xs [[1 <! ([[1 2 0]] <$> 0)]] <$> 0 diff --git a/std/Math.bruijn b/std/Math.bruijn index 3dcb23b..3e32bef 100644 --- a/std/Math.bruijn +++ b/std/Math.bruijn @@ -162,7 +162,7 @@ arrow z [[[[rec]]]] ⧗ Number → Number → Number → Number # TODO: faster fib? fibs L.map L.head (L.iterate &[[0 : (1 + 0)]] ((+0) : (+1))) ⧗ (List Number) -fib [L.index ++0 fibs] ⧗ Number +fib [L.index fibs ++0] ⧗ Number :test (fib (+5)) ((+8)) @@ -238,12 +238,10 @@ factors \divs primes ⧗ Number → (List Number) # TODO: faster! # → BBP/Bellard's formula with ternary base? # TODO: |log|, better primes/mod/div -π g (+1) (+180) (+60) (+2) ⧗ (List Number) - g z [[[[[calc]]]]] - calc b : (4 q r t i) - a ↑⁰(↑⁺0 ⋅ (↑⁰0 + (+2))) - b (3 ⋅ ↑⁰(↑⁻(↑⁻0)) + ((+5) ⋅ 2)) / ((+5) ⋅ 1) - q (+10) ⋅ 3 ⋅ 0 ⋅ --((+2) ⋅ 0) - r (+10) ⋅ a ⋅ (3 ⋅ ((+5) ⋅ 0 - (+2)) + 2 - (b ⋅ 1)) - t 1 ⋅ a - i ++0 +π y [[[[[calc]]]]] (+1) (+180) (+60) (+2) ⧗ (List Number) + calc [[0 : (6 q r t ++2)]] a b + a ↑⁰(↑⁺0 ⋅ (↑⁰0 + (+2))) + b (3 ⋅ ↑⁰(↑⁻(↑⁻0)) + ((+5) ⋅ 2)) / ((+5) ⋅ 1) + q (+10) ⋅ 5 ⋅ 2 ⋅ --((+2) ⋅ 2) + r (+10) ⋅ 1 ⋅ (5 ⋅ ((+5) ⋅ 2 - (+2)) + 4 - (0 ⋅ 3)) + t 3 ⋅ 1 diff --git a/std/Math/Complex.bruijn b/std/Math/Complex.bruijn index a20717f..d3b5a7d 100644 --- a/std/Math/Complex.bruijn +++ b/std/Math/Complex.bruijn @@ -5,9 +5,29 @@ :import std/Pair . :import std/Math/Real R -ι (+0.0r) : (+1.0r) +ι (+0.0+1.0i) -# returns true of two complex numbers are equal approximately +# converts a balanced ternary number to a complex number +number→complex [[0 (R.number→real 1) (+0.0r)]] ⧗ Number → Complex + +:test (number→complex (+5)) ((+5.0+0.0i)) + +# returns real part of a complex number +real fst ⧗ Complex → Real + +:test (real (+5.0+2.0i)) ((+5.0r)) + +# returns imaginary part of a complex number +imag snd ⧗ Complex → Real + +:test (imag (+5.0+2.0i)) ((+2.0r)) + +# approximates complex number by turning it into a pair of rationals +approx &[[[(2 0) : (1 0)]]] ⧗ Complex → Number → (Pair Rational Rational) + +:test (approx (+5.0+2.0i) (+2)) ((+5.0q) : (+2.0q)) + +# returns true if two complex numbers are equal approximately approx-eq? [[[R.approx-eq? 2 (1 2) (0 2)]]] ⧗ Number → Complex → Complex → Boolean # TODO: bigger value (higher performance first!) @@ -48,3 +68,14 @@ invert &[[p : q]] ⧗ Complex → Complex q R.div 0 (R.add (R.mul 1 1) (R.mul 0 0)) ~‣ invert + +# --- + +:import std/List L + +# power function: complex^number +pow-n [L.nth-iterate (mul 0) (+1.0+0.0i)] ⧗ Complex → Number → Complex + +ln [p : q] ⧗ Complex → Complex + p R.ln (&R.hypot 0) + q &R.atan2 0 diff --git a/std/Math/Rational.bruijn b/std/Math/Rational.bruijn index 54c3a88..f1509b0 100644 --- a/std/Math/Rational.bruijn +++ b/std/Math/Rational.bruijn @@ -3,6 +3,7 @@ # (p : q) ⇔ (1 / (q + 1)) +:import std/Logic . :import std/Combinator . :import std/Logic . :import std/Pair . @@ -91,6 +92,10 @@ div [[1 ⋅ ~0]] ⧗ Rational → Rational → Rational :test ((+8.0) / (+4.0) =? (+2.0)) (true) :test ((+18.0) / (+12.0) =? (+1.5)) (true) +gt? &[[&[[(N.gt? 1 3) ⋀? (N.gt? 0 2)]]]] + +lt? &[[&[[(N.lt? 1 3) ⋀? (N.lt? 0 2)]]]] + # increments a rational number inc add (+1.0) ⧗ Rational → Rational @@ -106,4 +111,4 @@ dec \sub (+1.0) ⧗ Rational → Rational :import std/List L # power function: rational^number -pow-n [L.…!!… (L.iterate (mul 0) (+1.0))] ⧗ Rational → Number → Rational +pow-n [L.nth-iterate (mul 0) (+1.0)] ⧗ Rational → Number → Rational diff --git a/std/Math/Real.bruijn b/std/Math/Real.bruijn index 49f4a92..28bc512 100644 --- a/std/Math/Real.bruijn +++ b/std/Math/Real.bruijn @@ -91,41 +91,79 @@ dec \sub (+1.0r) ⧗ Real → Real :import std/List L -# ∑(1/n^2) -# converges to 1.6449... -unary-1/n² [0 &[[(Q.add 1 op) : N.++0]] start [[0]]] ⧗ Real - op (+1) : N.--(N.mul 0 0) - start (+0.0f) : (+1) - -# e^x using Taylor expansion: ∑(x^n/n!) = e^x +# e^x using Taylor expansion +# tex: \sum_{n=0}^\infty \frac{x^n}{n!} unary-exp [[0 &[[[[[[[2 1 0 (Q.add 4 (1 : N.--0)) N.++3]] pow fac]]]]] start [[[[1]]]]]] ⧗ Number → Real pow N.mul 6 4 fac N.mul 1 3 - start [0 (+1) (+1) (+1.0f) (+1)] + start [0 (+1) (+1) (+1.0q) (+1)] # equivalent to unary-exp but with ternary index using infinite list iteration -exp [[L.index 0 (L.iterate &[[[[op]]]] start) [[[[1]]]] 0]] ⧗ Real → Real +exp [[L.nth-iterate &[[[[op]]]] start 0 [[[[1]]]] 0]] ⧗ Real → Real start [0 (+1.0r) (+1.0r) (+1.0r) (+1)] op [[[2 1 0 (4 + (1 / 0)) N.++3]] pow fac] pow 6 ⋅ 4 fac (number→real 1) ⋅ 3 # power function: real^number -pow-n [L.…!!… (L.iterate (mul 0) (+1.0r))] ⧗ Real → Number → Real +pow-n [L.nth-iterate (mul 0) (+1.0r)] ⧗ Real → Number → Real -# e^x using infinite limit: lim (1+x/n)^n, n to ∞ +# e^x using infinite limit +# tex: \lim_{n\to\infty}(1+x/n)^n lim-exp [[pow-n [(N.add 2 1) : N.--1] 0]] ⧗ Number → Real -# log_e using Taylor expansion -ln [[[L.index 1 (L.iterate &[[[op]]] start)] (--1 / ++1 0) [[[1]]]]] ⧗ Real → Real - start [0 1 (+0.0f) (+0)] +# natural logarithm using Taylor expansion +# tex: \sum_{n=0}^\infty\frac{2}{2n+1}(\frac{x-1}{x+1})^{2n+1} +# error: O((x-1)/2)^{2n+1} +ln [[[L.nth-iterate &[[[op]]] start 1] (--1 / ++1 0) [[[1]]]]] ⧗ Real → Real + start [0 1 (+0.0q) (+0)] op [0 pow (Q.add 2 go) N.++1] - pow Q.mul 3 (Q.pow-n 4 (+2)) + pow Q.mul 3 (Q.mul 4 4) go Q.mul ((+2) : (N.mul (+2) 1)) 3 +:test (Q.eq? (ln (+2.0r) (+2)) ((+168) : (+242))) (true) + derive [[[[((3 (0 + 1)) - (3 0)) / 1]] ((+1.0r) / 0) 0]] ⧗ (Real → Real) → (Real → Real) # power function: real^real pow [[exp (0 ⋅ (ln 1))]] ⧗ Real → Real → Real …**… pow + +# square root by x^{0.5} +sqrt* \pow (+0.5r) ⧗ Real → Real + +# Newton's/Heron's method, quadratic convergence +# tex: x_{n+1}=\frac{x_n+a/x_n}{2} +sqrt [[y [[[N.=?0 guess go]]] (1 0) 0]] ⧗ Real → Real + guess (+1.0q) + go [Q.div (Q.add 0 (Q.div 2 0)) (+2.0q)] (2 1 N.--0) + +# hypotenuse +hypot [[sqrt ((0 ⋅ 0) + (1 ⋅ 1))]] ⧗ Real → Real → Real + +# tex: \sum_{n=0}^\infty\frac{2^n n!^2}{(2n+1)!} +π/2 [L.nth-iterate &[[[[[op]]]]] start 0 [[[[[3]]]]]] ⧗ Real + start [0 (+1) (+0.0q) (+1) (+1) (+1)] + op [0 N.++5 (Q.add 4 ((N.mul 3 2) : N.--1)) enum-pow enum-fac denom] + enum-pow N.mul 3 (+2) + enum-fac N.mul 2 (N.mul 5 5) + denom [N.mul 2 (N.mul 0 N.++0)] (N.mul (+2) 5) + +# ratio of circle's circumference to its diameter +# TODO: Gauss-Legendre +π π/2 ⋅ (+2.0r) ⧗ Real + +# arctan by Taylor expansion, only for |x|<=1 +# tex: \sum_{n=0}^\infty(-1)^n \frac{x^{2n+1}}{2n+1} +arctan* [[[L.nth-iterate &[[[[op]]]] start 1] (1 0) [[[[3]]]]]] ⧗ Real → Real + start [0 1 [[0]] (Q.pow-n 1 (+3)) (+3.0q)] + op [0 ((3 Q.add Q.sub) 4 (Q.div 2 1)) \3 enum denom] + enum Q.mul 2 (Q.mul 5 5) + denom Q.add 1 (+2.0q) + +# actual arctan for arbitrary x +arctan [[Q.sub (π/2 0) (arctan* [Q.div (+1.0q) (2 1)] 0)]] ⧗ Real → Real + +# TODO: atan2 +atan2 [0] ⧗ Real → Real diff --git a/std/Number/Conversion.bruijn b/std/Number/Conversion.bruijn index 52f3c9e..01c7e9f 100644 --- a/std/Number/Conversion.bruijn +++ b/std/Number/Conversion.bruijn @@ -14,6 +14,8 @@ unary→ternary [0 T.inc (+0t)] ⧗ Unary → Ternary :test (¹³(+0u)) ((+0t)) :test (¹³(+2u)) ((+2t)) +binary→unary [[0 (+0u) [U.inc (2 0)] 1]] (U.mul (+2u)) ⧗ Binary → Unary + # converts ternary numbers to unary ternary→unary [T.apply 0 U.inc (+0u)] ⧗ Ternary → Unary diff --git a/std/Number/Parigot.bruijn b/std/Number/Parigot.bruijn new file mode 100644 index 0000000..9a23fd4 --- /dev/null +++ b/std/Number/Parigot.bruijn @@ -0,0 +1,24 @@ +# MIT License, Copyright (c) 2024 Marvin Borner +# see "on the representation of data in lambda-calculus" #5 +# has a "one-step" predecessor *and* addition function +# has 2x space complexity compared to unary/Church + +zero [0] + +inc [[[0 2 1]]] + +++‣ inc + +dec [[1 0 [0]]] + +--‣ dec + +:test (dec (inc zero)) (zero) + +iter [[[0 ι ρ ρ]]] + ρ [[3 (1 0 0)]] + ι [[4]] + +rec [[[0 ι ρ ρ --0]]] + ρ [[[4 0 (2 1 1)]]] + ι [[[5]]] diff --git a/std/Number/Scott.bruijn b/std/Number/Scott.bruijn new file mode 100644 index 0000000..bc776d8 --- /dev/null +++ b/std/Number/Scott.bruijn @@ -0,0 +1,31 @@ +# MIT License, Copyright (c) 2023 Marvin Borner + +:import std/Combinator . +:import std/Logic . + +zero [[1]] ⧗ Scott + +inc [[[0 2]]] ⧗ Scott → Scott + +:test (inc zero) ([[0 zero]]) +:test (inc (inc zero)) ([[0 [[0 zero]]]]) +:test (inc (inc (inc zero))) ([[0 [[0 [[0 zero]]]]]]) + +dec [0 zero [0]] ⧗ Scott → Scott + +:test (dec zero) (zero) +:test (dec (inc zero)) (zero) +:test (dec (inc (inc zero))) (inc zero) + +zero? [0 true [false]] ⧗ Scott → Boolean + +:test (zero? zero) (true) +:test (zero? (inc zero)) (false) +:test (zero? (inc (inc zero))) (false) + +add z [[[1 0 [inc (3 0 1)]]]] ⧗ Scott → Scott → Scott + +:test (add zero zero) (zero) +:test (add zero (inc zero)) (inc zero) +:test (add (inc zero) zero) (inc zero) +:test (add (inc zero) (inc zero)) (inc (inc zero)) diff --git a/std/Number/Ternary.bruijn b/std/Number/Ternary.bruijn index 27da643..2ad5059 100644 --- a/std/Number/Ternary.bruijn +++ b/std/Number/Ternary.bruijn @@ -328,7 +328,7 @@ abs [<?0 -0 0] ⧗ Number → Number :test (|(-1)) ((+1)) :test (|(+42)) ((+42)) -# apply a function n times to a value +# applies a function n times to a value # ~> substitute church numbers apply z [[[rec]]] ⧗ Number → (a → a) → a → a rec =?1 case-end case-apply @@ -382,6 +382,12 @@ log₃ log₃* ∘ strip ⧗ Number → Number :test (log₃ (+5)) ((+3)) :test (log₃ (+42)) ((+5)) +# amount of non-zero trits +hamming-weight [0 (+0) inc inc [0]] ⧗ Number → Number + +:test ((hamming-weight (+5)) =? (+3)) (true) +:test ((hamming-weight (+6)) =? (+2)) (true) + # returns the smallest number in a range such that a predicate is true binary-search z [[[[rec]]]] ⧗ (Number → Boolean) → Number → Number → Number rec (0 =? 1) case-end case-search diff --git a/std/Number/Unary.bruijn b/std/Number/Unary.bruijn index ae54c19..b764e87 100644 --- a/std/Number/Unary.bruijn +++ b/std/Number/Unary.bruijn @@ -143,6 +143,9 @@ pow [[0 [[3 (1 0)]] pow*]] ⧗ Unary → Unary → Unary :test ((+2u) ^ (+3u)) ((+8u)) :test ((+3u) ^ (+2u)) ((+9u)) +# also note that +# [0 ..i.. 0] (+nu) = n^..i..^n + # fibonacci sequence # index +1 vs std/Math fib fib [0 [[[2 0 [2 (1 0)]]]] [[1]] [0]] ⧗ Unary → Unary diff --git a/std/Number/Wadsworth.bruijn b/std/Number/Wadsworth.bruijn new file mode 100644 index 0000000..00bd3c3 --- /dev/null +++ b/std/Number/Wadsworth.bruijn @@ -0,0 +1,23 @@ +# MIT License, Copyright (c) 2023 Marvin Borner +# from Wadsworth's "some unusual numeral systems" (p224, see refs in README) + +:import std/Combinator . + +zero [0 [k]] ⧗ Wadsworth + +# increment Wadsworth number +inc [[[2 [2 (1 0) 1]]]] ⧗ Wadsworth → Wadsworth + +:test (inc (inc zero)) ([[[2 (1 (0 (k [[1]]))) 1 0]]]) + +# decrement Wadsworth number +dec [[1 [k (1 0)] i]] ⧗ Wadsworth → Wadsworth + +:test (dec (dec (inc (inc zero)))) (zero) + +# returns true if Wadsworth number is zero +zero? [0 i (k (k [[0]]))] ⧗ Wadsworth → Bool + +:test (zero? zero) ([[1]]) +:test (zero? (inc zero)) ([[0]]) +:test (zero? (inc (inc zero))) ([[0]]) |