diff options
author | Marvin Borner | 2022-08-16 23:18:14 +0200 |
---|---|---|
committer | Marvin Borner | 2022-08-16 23:18:14 +0200 |
commit | c5f1bbbf5aa9544465fc14f19c5009181ef9fc1c (patch) | |
tree | 65badb97d72cb897a6b9fc3bc5dc9ba23c39fa6c | |
parent | e06bf5c88f10c14286ea9fd91f4bdba00cda6da9 (diff) |
Std improvements
very descriptive as always :D
I honestly don't know though
-rw-r--r-- | std/Combinator.bruijn | 10 | ||||
-rw-r--r-- | std/List.bruijn | 116 | ||||
-rw-r--r-- | std/Logic.bruijn | 16 | ||||
-rw-r--r-- | std/Number.bruijn | 220 |
4 files changed, 213 insertions, 149 deletions
diff --git a/std/Combinator.bruijn b/std/Combinator.bruijn index 6144519..a1ffd1a 100644 --- a/std/Combinator.bruijn +++ b/std/Combinator.bruijn @@ -15,11 +15,13 @@ B [[[2 (1 0)]]] # Blackbird combinator B' [[[[3 (2 1 0)]]]] -(...) B' +(..) B' # Bunting combinator B'' [[[[[4 (3 2 1 0)]]]]] +(...) B'' + # Becard combinator B''' [[[[3 (2 (1 0))]]]] @@ -179,12 +181,6 @@ Z [[1 [1 1 0]] [1 [1 1 0]]] # iota combinator i [0 S K] -# True -true K - -# False -false KI - # -- combinator equivalency tests -- :test (A) (S (S K)) diff --git a/std/List.bruijn b/std/List.bruijn index 1ccae40..44d833f 100644 --- a/std/List.bruijn +++ b/std/List.bruijn @@ -1,4 +1,5 @@ # MIT License, Copyright (c) 2022 Marvin Borner +# Lists in Church/Boehm-Berarducci encoding using pairs :import std/Combinator . @@ -14,10 +15,12 @@ empty false # returns whether a list is empty empty? [0 [[[false]]] true] -:test (empty? empty) (true) -:test (empty? (cons (+2) empty)) (false) +<>?( empty? -# appends an element to a list +:test (<>?empty) (true) +:test (<>?(cons (+2) empty)) (false) + +# prepends an element to a list cons P.pair (:) cons @@ -28,17 +31,21 @@ cons P.pair # returns the head of a list or empty head P.fst -:test (head ((+1) : ((+2) : empty))) ((+1)) +^( head + +:test (^((+1) : ((+2) : empty))) ((+1)) # returns the tail of a list or empty tail P.snd -:test (tail ((+1) : ((+2) : empty))) ((+2) : empty) +~( tail + +:test (~((+1) : ((+2) : empty))) ((+2) : empty) # returns the length of a list in balanced ternary length Z [[[case-some]]] case-empty - case-some empty? 0 case-end case-inc - case-inc 2 (++1) (tail 0) + case-some <>?0 case-end case-inc + case-inc 2 ++1 ~0 case-end 1 case-empty (+0) @@ -49,8 +56,8 @@ length Z [[[case-some]]] case-empty # returns the element at index in list index Z [[[case-some]]] - case-some empty? 0 case-end case-index - case-index =?1 (head 0) (2 (--1) (tail 0)) + case-some <>?0 case-end case-index + case-index =?1 ^0 (2 --1 ~0) case-end empty (!!) C index @@ -62,8 +69,8 @@ index Z [[[case-some]]] # reverses a list reverse Z [[[case-some]]] case-empty - case-some empty? 0 case-end case-rev - case-rev 2 ((head 0) : 1) (tail 0) + case-some <>?0 case-end case-rev + case-rev 2 (^0 : 1) ~0 case-end 1 case-empty empty @@ -77,18 +84,26 @@ list [0 [[[2 (0 : 1)]]] reverse empty] # appends two lists append Z [[[case-some]]] - case-some empty? 1 case-end case-merge - case-merge (head 1) : (2 (tail 1) 0) + case-some <>?1 case-end case-merge + case-merge ^1 : (2 ~1 0) case-end 0 (++) append :test (((+1) : ((+2) : ((+3) : empty))) ++ ((+4) : empty)) ((+1) : ((+2) : ((+3) : ((+4) : empty)))) +# appends an element to a list +snoc [[1 ++ (0 : empty)]] + +(;) snoc + +:test (empty ; (+1)) ((+1) : empty) +:test (((+1) : empty) ; (+2)) ((+1) : ((+2) : empty)) + # maps each element to a function map Z [[[case-some]]] - case-some empty? 0 case-end case-map - case-map (1 (head 0)) : (2 1 (tail 0)) + case-some <>?0 case-end case-map + case-map (1 ^0) : (2 1 ~0) case-end empty (<$>) map @@ -97,8 +112,8 @@ map Z [[[case-some]]] # applies a left fold on a list foldl Z [[[[case-some]]]] - case-some empty? 0 case-end case-fold - case-fold 3 2 (2 1 (head 0)) (tail 0) + case-some <>?0 case-end case-fold + case-fold 3 2 (2 1 ^0) ~0 case-end 1 :test ((foldl add (+0) ((+1) : ((+2) : ((+3) : empty)))) =? (+6)) (true) @@ -106,8 +121,8 @@ foldl Z [[[[case-some]]]] # applies a right fold on a list foldr [[[Z [[case-some]] case-empty]]] - case-some empty? 0 case-end case-fold - case-fold 4 (head 0) (1 (tail 0)) + case-some <>?0 case-end case-fold + case-fold 4 ^0 (1 ~0) case-end 3 case-empty 0 @@ -116,82 +131,105 @@ foldr [[[Z [[case-some]] case-empty]]] # filters a list based on a predicate filter Z [[[case-some]]] - case-some empty? 0 case-end case-filter - case-filter 1 (head 0) (cons (head 0)) I (2 1 (tail 0)) + case-some <>?0 case-end case-filter + case-filter 1 ^0 (cons ^0) I (2 1 ~0) case-end empty -:test (filter zero? ((+1) : ((+0) : ((+3) : empty)))) ((+0) : empty) +(<#>) C filter + +:test (((+1) : ((+0) : ((+3) : empty))) <#> zero?) ((+0) : empty) # returns the last element of a list last Z [[case-some]] - case-some empty? 0 case-end case-last - case-last empty? (tail 0) (head 0) (1 (tail 0)) + case-some <>?0 case-end case-last + case-last <>?(~0) ^0 (1 ~0) case-end empty +_( last + :test (last ((+1) : ((+2) : ((+3) : empty)))) ((+3)) # returns everything but the last element of a list init Z [[case-some]] - case-some empty? 0 case-end case-init - case-init empty? (tail 0) empty ((head 0) : (1 (tail 0))) + case-some <>?0 case-end case-init + case-init <>?(~0) empty (^0 : (1 ~0)) case-end empty :test (init ((+1) : ((+2) : ((+3) : empty)))) ((+1) : ((+2) : empty)) # zips two lists discarding excess elements zip Z [[[case-some]]] - case-some empty? 1 case-end case-zip - case-zip empty? 0 empty (((head 1) : (head 0)) : (2 (tail 1) (tail 0))) + case-some <>?1 case-end case-zip + case-zip <>?0 empty ((^1 : ^0) : (2 ~1 ~0)) case-end empty :test (zip ((+1) : ((+2) : empty)) ((+2) : ((+1) : empty))) (((+1) : (+2)) : (((+2) : (+1)) : empty)) # applies pairs of the zipped list as arguments to a function zip-with Z [[[[case-some]]]] - case-some empty? 1 case-end case-zip - case-zip empty? 0 empty ((2 (head 1) (head 0)) : (3 2 (tail 1) (tail 0))) + case-some <>?1 case-end case-zip + case-zip <>?0 empty ((2 ^1 ^0) : (3 2 ~1 ~0)) case-end empty :test (zip-with add ((+1) : ((+2) : empty)) ((+2) : ((+1) : empty))) ((+3) : ((+3) : empty)) # returns first n elements of a list take Z [[[case-some]]] - case-some empty? 0 case-end case-take - case-take =?1 empty ((head 0) : (2 (--1) (tail 0))) + case-some <>?0 case-end case-take + case-take =?1 empty (^0 : (2 --1 ~0)) case-end empty :test (take (+2) ((+1) : ((+2) : ((+3) : empty)))) ((+1) : ((+2) : empty)) # takes elements while a predicate is satisfied take-while Z [[[case-some]]] - case-some empty? 0 case-end case-take - case-take 1 (head 0) ((head 0) : (2 1 (tail 0))) empty + case-some <>?0 case-end case-take + case-take 1 ^0 (^0 : (2 1 ~0)) empty case-end empty :test (take-while zero? ((+0) : ((+0) : ((+1) : empty)))) ((+0) : ((+0) : empty)) # removes first n elements of a list drop Z [[[case-some]]] - case-some empty? 0 case-end case-drop - case-drop =?1 0 (2 (--1) (tail 0)) + case-some <>?0 case-end case-drop + case-drop =?1 0 (2 --1 ~0) case-end empty :test (drop (+2) ((+1) : ((+2) : ((+3) : empty)))) ((+3) : empty) # removes elements while a predicate is satisfied drop-while Z [[[case-some]]] - case-some empty? 0 case-end case-drop - case-drop 1 (head 0) (2 1 (tail 0)) 0 + case-some <>?0 case-end case-drop + case-drop 1 ^0 (2 1 ~0) 0 case-end empty :test (drop-while zero? ((+0) : ((+0) : ((+1) : empty)))) ((+1) : empty) +# removes duplicates from list based on eq predicate (keeps only first occurrence) +nub Z [[[case-some]]] + case-some <>?0 case-end case-nub + case-nub ^0 : (2 1 (~0 <#> [!(2 0 ^1)])) + case-end empty + +:test (nub eq? ((+1) : ((+2) : ((+3) : empty)))) (((+1) : ((+2) : ((+3) : empty)))) +:test (nub eq? ((+1) : ((+2) : ((+1) : empty)))) (((+1) : ((+2) : empty))) + # returns a list with n-times a element repeat Z [[[case-some]]] case-some =?1 case-end case-repeat - case-repeat 0 : (2 (--1) 0) + case-repeat 0 : (2 --1 0) case-end empty :test (repeat (+5) (+4)) (((+4) : ((+4) : ((+4) : ((+4) : ((+4) : empty)))))) :test (repeat (+1) (+4)) (((+4) : empty)) :test (repeat (+0) (+4)) (empty) + +# returns a list with infinite-times previous (or start) value applied to a function +iterate Z [[[case-some]]] + case-some case-iterate + case-iterate 0 : (2 1 (1 0)) + +:test (take (+5) (iterate inc (+0))) (((+0) : ((+1) : ((+2) : ((+3) : ((+4) : empty)))))) +:test (take (+2) (iterate dec (+5))) (((+5) : ((+4) : empty))) +:test (take (+5) (iterate I (+4))) (repeat (+5) (+4)) +:test (take (+0) (iterate inc (+0))) (empty) diff --git a/std/Logic.bruijn b/std/Logic.bruijn index f4b7470..4174712 100644 --- a/std/Logic.bruijn +++ b/std/Logic.bruijn @@ -2,6 +2,13 @@ :import std/Combinator . +# true +true K + +# false +false KI + +# inverts boolean value not [0 false true] !( not @@ -9,6 +16,7 @@ not [0 false true] :test (!true) (false) :test (!false) (true) +# true if both args are true and [[1 0 false]] (&&) and @@ -18,6 +26,7 @@ and [[1 0 false]] :test (false && true) (false) :test (false && false) (false) +# true if not both args are true nand [[1 0 1 false true]] :test (nand true true) (false) @@ -25,6 +34,7 @@ nand [[1 0 1 false true]] :test (nand false true) (true) :test (nand false false) (true) +# true if one of the args is true or [[1 true 0]] (||) or @@ -34,6 +44,7 @@ or [[1 true 0]] :test (false || true) (true) :test (false || false) (false) +# true if both args are false nor [[1 1 0 false true]] :test (nor true true) (false) @@ -41,6 +52,7 @@ nor [[1 1 0 false true]] :test (nor false true) (false) :test (nor false false) (true) +# true if args are not same bools xor [[1 (not 0) 0]] :test (xor true true) (false) @@ -48,6 +60,7 @@ xor [[1 (not 0) 0]] :test (xor false true) (true) :test (xor false false) (false) +# true if both args are same bools xnor [[1 0 (not 0)]] :test (xnor true true) (true) @@ -55,6 +68,7 @@ xnor [[1 0 (not 0)]] :test (xnor false true) (false) :test (xnor false false) (true) +# if first arg is true, exec first exp; else second exp # this function is generally redundant # I personally just write (exp? case-T case-F) directly if [[[2 1 0]]] @@ -66,6 +80,7 @@ if [[[2 1 0]]] :test (if false true false) (false) :test ((false ?! true) false) (false) +# mathematical implies definition implies [[or (not 1) 0]] (=>?) implies @@ -75,6 +90,7 @@ implies [[or (not 1) 0]] :test (false =>? true) (true) :test (false =>? false) (true) +# mathematical iff (if and only if) definition iff [[and (implies 1 0) (implies 0 1)]] (<=>?) iff diff --git a/std/Number.bruijn b/std/Number.bruijn index 89d04d3..81e6636 100644 --- a/std/Number.bruijn +++ b/std/Number.bruijn @@ -8,32 +8,32 @@ :import std/Logic . # negative trit indicating coeffecient of (-1) -trit-neg [[[2]]] +t< [[[2]]] # returns whether a trit is negative -trit-neg? [0 true false false] +t<? [0 true false false] # positive trit indicating coeffecient of (+1) -trit-pos [[[1]]] +t> [[[1]]] # returns whether a trit is positive -trit-pos? [0 false true false] +t>? [0 false true false] # zero trit indicating coeffecient of 0 -trit-zero [[[0]]] +t= [[[0]]] # returns whether a trit is zero -trit-zero? [0 false false true] - -:test (trit-neg? trit-neg) (true) -:test (trit-neg? trit-pos) (false) -:test (trit-neg? trit-zero) (false) -:test (trit-pos? trit-neg) (false) -:test (trit-pos? trit-pos) (true) -:test (trit-pos? trit-zero) (false) -:test (trit-zero? trit-neg) (false) -:test (trit-zero? trit-pos) (false) -:test (trit-zero? trit-zero) (true) +t=? [0 false false true] + +:test (t<? t<) (true) +:test (t<? t>) (false) +:test (t<? t=) (false) +:test (t>? t<) (false) +:test (t>? t>) (true) +:test (t>? t=) (false) +:test (t=? t<) (false) +:test (t=? t>) (false) +:test (t=? t=) (true) # shifts a negative trit into a balanced ternary number up-neg [[[[[2 (4 3 2 1 0)]]]]] @@ -65,16 +65,16 @@ up-zero [[[[[0 (4 3 2 1 0)]]]]] # shifts a specified trit into a balanced ternary number up [[[[[[5 2 1 0 (4 3 2 1 0)]]]]]] -:test (up trit-neg (+42)) (^<(+42)) -:test (up trit-pos (+42)) (^>(+42)) -:test (up trit-zero (+42)) (^=(+42)) +:test (up t< (+42)) (^<(+42)) +:test (up t> (+42)) (^>(+42)) +:test (up t= (+42)) (^=(+42)) # shifts the least significant trit out - basically div by 3 -down [snd (0 z neg pos zero)] +down [snd (0 z a< a> a=)] z (+0) : (+0) - neg [0 [[(^<1) : 1]]] - pos [0 [[(^>1) : 1]]] - zero [0 [[(^=1) : 1]]] + a< [0 [[^<1 : 1]]] + a> [0 [[^>1 : 1]]] + a= [0 [[^=1 : 1]]] # negates a balanced ternary number negate [[[[[4 3 1 2 0]]]]] @@ -86,49 +86,49 @@ negate [[[[[4 3 1 2 0]]]]] :test (-(+42)) ((-42)) # converts a balanced ternary number to a list of trits -list! [0 z neg pos zero] +list! [0 z a< a> a=] z [[0]] - neg [trit-neg : 0] - pos [trit-pos : 0] - zero [trit-zero : 0] + a< [t< : 0] + a> [t> : 0] + a= [t= : 0] # TODO: Tests! # strips leading 0s from balanced ternary number -strip [fst (0 z neg pos zero)] +strip [fst (0 z a< a> a=)] z (+0) : true - neg [0 [[(^<1) : false]]] - pos [0 [[(^>1) : false]]] - zero [0 [[(0 (+0) (^=1)) : 0]]] + a< [0 [[^<1 : false]]] + a> [0 [[^>1 : false]]] + a= [0 [[(0 (+0) ^=1) : 0]]] -~( strip +%( strip -:test (~[[[[0 3]]]]) ((+0)) -:test (~[[[[2 (0 (0 (0 (0 3))))]]]]) ((-1)) -:test (~(+42)) ((+42)) +:test (%[[[[0 3]]]]) ((+0)) +:test (%[[[[2 (0 (0 (0 (0 3))))]]]]) ((-1)) +:test (%(+42)) ((+42)) # extracts least significant trit from balanced ternary numbers -lst [0 trit-zero [trit-neg] [trit-pos] [trit-zero]] +lst [0 t= [t<] [t>] [t=]] -:test (lst (+0)) (trit-zero) -:test (lst (-1)) (trit-neg) -:test (lst (+1)) (trit-pos) -:test (lst (+42)) (trit-zero) +:test (lst (-1)) (t<) +:test (lst (+0)) (t=) +:test (lst (+1)) (t>) +:test (lst (+42)) (t=) # extracts most significant trit from balanced ternary numbers # TODO: Find a more elegant way to do this (and resolve list import loop?) -mst [fix (last (list! (~0)))] - last Z [[empty? 0 [false] [empty? (snd 1) (fst 1) (2 (snd 1))] I]] - empty? [0 [[[false]]] true] - fix [((trit-neg? 0) || ((trit-pos? 0) || (trit-zero? 0))) 0 trit-zero] +mst [fix (last (list! %0))] + last Z [[<>?0 [false] [<>?(snd 1) (fst 1) (2 (snd 1))] I]] + <>?( [0 [[[false]]] true] + fix [((t<? 0) || ((t>? 0) || (t=? 0))) 0 t=] -:test (mst (+0)) (trit-zero) -:test (mst (-1)) (trit-neg) -:test (mst (+1)) (trit-pos) -:test (mst (+42)) (trit-pos) +:test (mst (-1)) (t<) +:test (mst (+0)) (t=) +:test (mst (+1)) (t>) +:test (mst (+42)) (t>) # returns whether balanced ternary number is negative -negative? [trit-neg? (mst 0)] +negative? [t<? (mst 0)] <?( negative? @@ -138,7 +138,7 @@ negative? [trit-neg? (mst 0)] :test (<?(+42)) (false) # returns whether balanced ternary number is positive -positive? [trit-pos? (mst 0)] +positive? [t>? (mst 0)] >?( positive? @@ -158,35 +158,39 @@ zero? [0 true [false] [false] I] :test (=?(+42)) (false) # converts the normal balanced ternary representation into abstract -# -> the abstract representation is used in add/sub/mul -abstract! [0 z neg pos zero] +# -> the abstract representation is used in eq?/add/sub/mul +abstract! [0 z a< a> a=] z (+0) - neg [[[[[2 4]]]]] - pos [[[[[1 4]]]]] - zero [[[[[0 4]]]]] + a< [[[[[2 4]]]]] + a> [[[[[1 4]]]]] + a= [[[[[0 4]]]]] -:test (abstract! (-3)) ([[[[0 [[[[2 [[[[3]]]]]]]]]]]]) -:test (abstract! (+0)) ([[[[3]]]]) -:test (abstract! (+3)) ([[[[0 [[[[1 [[[[3]]]]]]]]]]]]) +->^( abstract! + +:test (->^(-3)) ([[[[0 [[[[2 [[[[3]]]]]]]]]]]]) +:test (->^(+0)) ([[[[3]]]]) +:test (->^(+3)) ([[[[0 [[[[1 [[[[3]]]]]]]]]]]]) # converts the abstracted balanced ternary representation back to normal # using ω to solve recursion normal! ω rec rec [[0 (+0) [^<([3 3 0] 0)] [^>([3 3 0] 0)] [^=([3 3 0] 0)]]] -:test (normal! [[[[3]]]]) ((+0)) -:test (normal! (abstract! (+42))) ((+42)) -:test (normal! (abstract! (-42))) ((-42)) +->_( normal! + +:test (->_[[[[3]]]]) ((+0)) +:test (->_(->^(+42))) ((+42)) +:test (->_(->^(-42))) ((-42)) # checks whether two balanced ternary numbers are equal -# smaller numbers should be second argument (performance) +# larger numbers should be second argument (performance) # -> ignores leading 0s! -eq? [[abs 1 (abstract! 0)]] - abs [0 z neg pos zero] - z [zero? (normal! 0)] - neg [[0 false [2 0] [false] [false]]] - pos [[0 false [false] [2 0] [false]]] - zero [[0 (1 0) [false] [false] [2 0]]] +eq? [[abs 1 ->^0]] + abs [0 z a< a> a=] + z [=?(->_0)] + a< [[0 false [2 0] [false] [false]]] + a> [[0 false [false] [2 0] [false]]] + a= [[0 (1 0) [false] [false] [2 0]]] (=?) eq? @@ -205,11 +209,11 @@ eq? [[abs 1 (abstract! 0)]] # the same. Something's weird. # adds (+1) to a balanced ternary number (can introduce leading 0s) -inc [snd (0 z neg pos zero)] +inc [snd (0 z a< a> a=)] z (+0) : (+1) - neg [0 [[(^<1) : (^=1)]]] - zero [0 [[(^=1) : (^>1)]]] - pos [0 [[(^>1) : (^<0)]]] + a< [0 [[^<1 : ^=1]]] + a> [0 [[^>1 : ^<0]]] + a= [0 [[^=1 : ^>1]]] ++( inc @@ -223,11 +227,11 @@ ssinc strip . inc :test ((++(+42)) =? (+43)) (true) # subs (+1) from a balanced ternary number (can introduce leading 0s) -dec [snd (0 dec-z dec-neg dec-pos dec-zero)] - dec-z (+0) : (-1) - dec-neg [0 [[(^<1) : (^>0)]]] - dec-zero [0 [[(^=1) : (^<1)]]] - dec-pos [0 [[(^>1) : (^=1)]]] +dec [snd (0 z a< a> a=)] + z (+0) : (-1) + a< [0 [[^<1 : ^>0]]] + a> [0 [[^>1 : ^=1]]] + a= [0 [[^=1 : ^<1]]] --( dec @@ -241,24 +245,24 @@ sdec strip . dec :test ((--(+42)) =? (+41)) (true) # adds two balanced ternary numbers (can introduce leading 0s) -# smaller numbers should be second argument (performance) -add [[abs 1 (abstract! 0)]] - abs [c (0 z a-neg a-pos a-zero)] - b-neg [1 (^>(3 0 trit-neg)) (^=(3 0 trit-zero)) (^<(3 0 trit-zero))] - b-zero [up 1 (3 0 trit-zero)] - b-pos [1 (^=(3 0 trit-zero)) (^<(3 0 trit-pos)) (^>(3 0 trit-zero))] - a-neg [[[1 (b-neg 1) b-neg' b-zero b-neg]]] - b-neg' [1 (^=(3 0 trit-neg)) (^<(3 0 trit-zero)) (^>(3 0 trit-neg))] - a-pos [[[1 (b-pos 1) b-zero b-pos' b-pos]]] - b-pos' [1 (^>(3 0 trit-zero)) (^=(3 0 trit-pos)) (^<(3 0 trit-pos))] - a-zero [[[1 (b-zero 1) b-neg b-pos b-zero]]] - z [[0 (--(normal! 1)) (++(normal! 1)) (normal! 1)]] - c [[1 0 trit-zero]] +# larger numbers should be second argument (performance) +add [[abs 1 ->^0]] + abs [c (0 z a< a> a=)] + b< [1 ^>(3 0 t<) ^=(3 0 t=) ^<(3 0 t=)] + b= [up 1 (3 0 t=)] + b> [1 ^=(3 0 t=) ^<(3 0 t>) ^>(3 0 t=)] + a< [[[1 (b< 1) b<' b= b<]]] + b<' [1 ^=(3 0 t<) ^<(3 0 t=) ^>(3 0 t<)] + a> [[[1 (b> 1) b= b>' b>]]] + b>' [1 ^>(3 0 t=) ^=(3 0 t>) ^<(3 0 t>)] + a= [[[1 (b= 1) b< b> b=]]] + z [[0 --(->_1) ++(->_1) ->_1]] + c [[1 0 t=]] (+) add # adds two balanced ternary numbers and strips leading 0s -sadd strip ... add +sadd strip .. add :test (((-42) + (-1)) =? (-43)) (true) :test (((-5) + (+6)) =? (+1)) (true) @@ -268,13 +272,13 @@ sadd strip ... add :test (((+42) + (+1)) =? (+43)) (true) # subs two balanced ternary numbers (can introduce leading 0s) -# smaller numbers should be second argument (performance) +# larger numbers should be second argument (performance) sub [[1 + -0]] (-) sub # subs two balanced ternary numbers and strips leading 0s -ssub strip ... sub +ssub strip .. sub :test (((-42) - (-1)) =? (-41)) (true) :test (((-5) - (+6)) =? (-11)) (true) @@ -284,8 +288,8 @@ ssub strip ... sub :test (((+42) - (+1)) =? (+41)) (true) # returns whether number is greater than other number -# smaller numbers should be second argument (performance) -gre? [[positive? (sub 1 0)]] +# larger numbers should be second argument (performance) +gre? [[>?(1 - 0)]] (>?) gre? @@ -295,7 +299,7 @@ gre? [[positive? (sub 1 0)]] # returns whether number is less than other number # smaller numbers should be second argument (performance) -les? [[negative? (sub 1 0)]] +les? [[<?(1 - 0)]] (<?) les? @@ -305,7 +309,7 @@ les? [[negative? (sub 1 0)]] # returns whether number is less than or equal to other number # smaller numbers should be second argument (performance) -leq? [[not (gre? 1 0)]] +leq? [[!(1 >? 0)]] (<=?) leq? @@ -315,7 +319,7 @@ leq? [[not (gre? 1 0)]] # returns whether number is greater than or equal to other number # smaller numbers should be second argument (performance) -geq? [[not (les? 1 0)]] +geq? [[!(1 <? 0)]] (>=?) geq? @@ -324,20 +328,30 @@ geq? [[not (les? 1 0)]] :test ((+3) >=? (+2)) (true) # muls two balanced ternary numbers (can introduce leading 0s) -mul [[1 (+0) neg pos zero]] - neg [(^=0) - 1] - pos [(^=0) + 1] - zero [^=0] +mul [[1 (+0) a< a> a=]] + a< [^=0 - 1] + a> [^=0 + 1] + a= [^=0] (*) mul -smul strip ... mul +smul strip .. mul :test (((+42) * (+0)) =? (+0)) (true) :test (((-1) * (+42)) =? (-42)) (true) :test (((+3) * (+11)) =? (+33)) (true) :test (((+42) * (-4)) =? (-168)) (true) +# greatest common divisor +gcd Z [[[(1 =? 0) case-eq ((1 >? 0) case-gre case-les)]]] + case-eq 1 + case-gre 2 (1 - 0) 0 + case-les 2 1 (0 - 1) + +:test ((gcd (+2) (+4)) =? ((+2))) (true) +:test ((gcd (+10) (+5)) =? ((+5))) (true) +:test ((gcd (+3) (+8)) =? ((+1))) (true) + # factorial function fac Z [[(0 <? (+2)) (+1) (0 * (1 --0))]] |