aboutsummaryrefslogtreecommitdiffhomepage
path: root/std/Number.bruijn
diff options
context:
space:
mode:
Diffstat (limited to 'std/Number.bruijn')
-rw-r--r--std/Number.bruijn143
1 files changed, 76 insertions, 67 deletions
diff --git a/std/Number.bruijn b/std/Number.bruijn
index ae4a3ac..3a2efe9 100644
--- a/std/Number.bruijn
+++ b/std/Number.bruijn
@@ -8,22 +8,22 @@
:import std/Logic .
# negative trit indicating coeffecient of (-1)
-t⁻ [[[2]]]
+t⁻ [[[2]]] ⧗ Trit
# returns true if a trit is negative
-t⁻? [0 true false false]
+t⁻? [0 true false false] ⧗ Trit → Boolean
# positive trit indicating coeffecient of (+1)
-t⁺ [[[1]]]
+t⁺ [[[1]]] ⧗ Trit
# returns true if a trit is positive
-t⁺? [0 false true false]
+t⁺? [0 false true false] ⧗ Trit → Boolean
# zero trit indicating coeffecient of 0
-t⁰ [[[0]]]
+t⁰ [[[0]]] ⧗ Trit
# returns true if a trit is zero
-t⁰? [0 false false true]
+t⁰? [0 false false true] ⧗ Trit → Boolean
:test (t⁻? t⁻) (true)
:test (t⁻? t⁺) (false)
@@ -36,28 +36,28 @@ t⁰? [0 false false true]
:test (t⁰? t⁰) (true)
# shifts a negative trit into a balanced ternary number
-↑⁻‣ [[[[[2 (4 3 2 1 0)]]]]]
+↑⁻‣ [[[[[2 (4 3 2 1 0)]]]]] ⧗ Number → Number
:test (↑⁻(+0)) ((-1))
:test (↑⁻(-1)) ((-4))
:test (↑⁻(+42)) ((+125))
# shifts a positive trit into a balanced ternary number
-↑⁺‣ [[[[[1 (4 3 2 1 0)]]]]]
+↑⁺‣ [[[[[1 (4 3 2 1 0)]]]]] ⧗ Number → Number
:test (↑⁺(+0)) ((+1))
:test (↑⁺(-1)) ((-2))
:test (↑⁺(+42)) ((+127))
# shifts a zero trit into a balanced ternary number
-↑⁰‣ [[[[[0 (4 3 2 1 0)]]]]]
+↑⁰‣ [[[[[0 (4 3 2 1 0)]]]]] ⧗ Number → Number
:test (↑⁰(+0)) ([[[[0 3]]]])
:test (↑⁰(+1)) ((+3))
:test (↑⁰(+42)) ((+126))
# shifts a specified trit into a balanced ternary number
-up [[[[[[5 2 1 0 (4 3 2 1 0)]]]]]]
+up [[[[[[5 2 1 0 (4 3 2 1 0)]]]]]] ⧗ Trit → Number → Number
:test (up t⁻ (+42)) (↑⁻(+42))
:test (up t⁺ (+42)) (↑⁺(+42))
@@ -65,10 +65,10 @@ up [[[[[[5 2 1 0 (4 3 2 1 0)]]]]]]
# infinity
# WARNING: using this mostly results in undefined behavior! (TODO?)
-infty z [[[[[1 (4 1)]]]]]
+infty z [[[[[1 (4 1)]]]]] ⧗ Number
# negates a balanced ternary number
-negate [[[[[4 3 1 2 0]]]]]
+negate [[[[[4 3 1 2 0]]]]] ⧗ Number → Number
-‣ negate
@@ -77,7 +77,7 @@ negate [[[[[4 3 1 2 0]]]]]
:test (-(+42)) ((-42))
# converts a balanced ternary number to a list of trits
-list! [0 z a⁻ a⁺ a⁰]
+list! [0 z a⁻ a⁺ a⁰] ⧗ Number → List
z [[0]]
a⁻ [t⁻ : 0]
a⁺ [t⁺ : 0]
@@ -86,7 +86,7 @@ list! [0 z a⁻ a⁺ a⁰]
# TODO: Tests!
# strips leading 0s from balanced ternary number
-strip [^(0 z a⁻ a⁺ a⁰)]
+strip [^(0 z a⁻ a⁺ a⁰)] ⧗ Number → Number
z (+0) : true
a⁻ [0 [[↑⁻1 : false]]]
a⁺ [0 [[↑⁺1 : false]]]
@@ -99,15 +99,15 @@ strip [^(0 z a⁻ a⁺ a⁰)]
:test (%(+42)) ((+42))
# extracts least significant trit from balanced ternary numbers
-lst [0 t⁰ [t⁻] [t⁺] [t⁰]]
+lst [0 t⁰ [t⁻] [t⁺] [t⁰]] ⧗ Number → Trit
:test (lst (-1)) (t⁻)
:test (lst (+0)) (t⁰)
:test (lst (+1)) (t⁺)
:test (lst (+42)) (t⁰)
-# checks true if balanced ternary number is zero
-zero? [0 true [false] [false] i]
+# returns true if balanced ternary number is zero
+zero? [0 true [false] [false] i] ⧗ Number → Boolean
=?‣ zero?
@@ -116,11 +116,21 @@ zero? [0 true [false] [false] i]
:test (=?(+1)) (false)
:test (=?(+42)) (false)
+# returns true if balanced ternary number is not
+not-zero? [0 false [true] [true] i] ⧗ Number → Boolean
+
+≠?‣ not-zero?
+
+:test (≠?(+0)) (false)
+:test (≠?(-1)) (true)
+:test (≠?(+1)) (true)
+:test (≠?(+42)) (true)
+
# extracts most significant trit from balanced ternary numbers
# <~>/<>? are hardcoded because list import would be recursive (TODO?)
# while this looks incredibly inefficient it's actually fairly fast because laziness
# TODO: find way of removing requirement of stripping first
-mst [=?0 t⁰ ^(<~>(list! %0))]
+mst [=?0 t⁰ ^(<~>(list! %0))] ⧗ Number → Trit
<~>‣ z [[[[<>?0 1 (3 2 (2 1 ^0) ~0)]]]] f false
<>?‣ [0 [[[false]]] true]
@@ -130,7 +140,7 @@ mst [=?0 t⁰ ^(<~>(list! %0))]
:test (mst (+42)) (t⁺)
# returns true if balanced ternary number is negative
-negative? [t⁻? (mst 0)]
+negative? [t⁻? (mst 0)] ⧗ Number → Boolean
<?‣ negative?
@@ -140,7 +150,7 @@ negative? [t⁻? (mst 0)]
:test (<?(+42)) (false)
# returns true if balanced ternary number is positive
-positive? [t⁺? (mst 0)]
+positive? [t⁺? (mst 0)] ⧗ Number → Boolean
>?‣ positive?
@@ -152,7 +162,7 @@ positive? [t⁺? (mst 0)]
# converts the normal balanced ternary representation into abstract
# infinity can't be abstracted in finite time
# → the abstract representation is used in eq?/add/sub/mul
-abstract! [0 z a⁻ a⁺ a⁰]
+abstract! [0 z a⁻ a⁺ a⁰] ⧗ Number → AbstractNumber
z (+0)
a⁻ [[[[[2 4]]]]]
a⁺ [[[[[1 4]]]]]
@@ -165,7 +175,7 @@ abstract! [0 z a⁻ a⁺ a⁰]
:test (→^(+3)) ([[[[0 [[[[1 [[[[3]]]]]]]]]]]])
# converts the abstracted balanced ternary representation back to normal
-normal! ω [[0 z a⁻ a⁺ a⁰]]
+normal! ω [[0 z a⁻ a⁺ a⁰]] ⧗ AbstractNumber → Number
z (+0)
a⁻ [↑⁻([3 3 0] 0)]
a⁺ [↑⁺([3 3 0] 0)]
@@ -177,10 +187,10 @@ normal! ω [[0 z a⁻ a⁺ a⁰]]
:test (→_(→^(+42))) ((+42))
:test (→_(→^(-42))) ((-42))
-# checks whether two balanced ternary numbers are equal
+# returns true if two balanced ternary numbers are equal
# larger numbers should be second argument (performance)
# → ignores leading 0s!
-eq? [[abs 1 →^0]]
+eq? [[abs 1 →^0]] ⧗ Number → Number → Boolean
abs [0 z a⁻ a⁺ a⁰]
z [=?(→_0)]
a⁻ [[0 false [2 0] [false] [false]]]
@@ -189,9 +199,9 @@ eq? [[abs 1 →^0]]
…=?… eq?
-neq? not! ∘∘ eq?
+not-eq? not! ∘∘ eq? ⧗ Number → Number → Boolean
-…/=?… neq?
+…≠?… not-eq?
:test ((-42) =? (-42)) (true)
:test ((-1) =? (-1)) (true)
@@ -201,8 +211,8 @@ neq? not! ∘∘ eq?
:test ((+1) =? (+1)) (true)
:test ((+42) =? (+42)) (true)
:test ([[[[(1 (0 (0 (0 (0 3)))))]]]] =? (+1)) (true)
-:test ((+1) /=? (+0)) (true)
-:test ((-42) /=? (+42)) (true)
+:test ((+1) ≠? (+0)) (true)
+:test ((-42) ≠? (+42)) (true)
# I believe Mogensen's Paper has an error in its inc/dec/add/mul/eq definitions.
# They use 3 instead of 2 abstractions in the functions, also we use switched
@@ -210,7 +220,7 @@ neq? not! ∘∘ eq?
# the same. Something's weird.
# adds (+1) to a balanced ternary number (can introduce leading 0s)
-inc [~(0 z a⁻ a⁺ a⁰)]
+inc [~(0 z a⁻ a⁺ a⁰)] ⧗ Number → Number
z (+0) : (+1)
a⁻ [0 [[↑⁻1 : ↑⁰1]]]
a⁺ [0 [[↑⁺1 : ↑⁻0]]]
@@ -218,9 +228,6 @@ inc [~(0 z a⁻ a⁺ a⁰)]
++‣ inc
-# adds (+1) to a balanced ternary number and strips leading 0s
-ssinc strip ∘ inc
-
:test ((++(-42)) =? (-41)) (true)
:test ((++(-1)) =? (+0)) (true)
:test ((++(+0)) =? (+1)) (true)
@@ -228,7 +235,7 @@ ssinc strip ∘ inc
:test ((++(+42)) =? (+43)) (true)
# subs (+1) from a balanced ternary number (can introduce leading 0s)
-dec [~(0 z a⁻ a⁺ a⁰)]
+dec [~(0 z a⁻ a⁺ a⁰)] ⧗ Number → Number
z (+0) : (-1)
a⁻ [0 [[↑⁻1 : ↑⁺0]]]
a⁺ [0 [[↑⁺1 : ↑⁰1]]]
@@ -236,9 +243,6 @@ dec [~(0 z a⁻ a⁺ a⁰)]
--‣ dec
-# subs (+1) from a balanced ternary number and strips leading 0s
-sdec strip ∘ dec
-
:test ((--(-42)) =? (-43)) (true)
:test ((--(+0)) =? (-1)) (true)
:test ((--(--(--(--(--(+5)))))) =? (+0)) (true)
@@ -247,7 +251,7 @@ sdec strip ∘ dec
# adds two balanced ternary numbers (can introduce leading 0s)
# second argument gets abstracted (performance)
-add [[abs 1 →^0]]
+add [[abs 1 →^0]] ⧗ Number → Number → Number
abs [c (0 z a⁻ a⁺ a⁰)]
b⁻ [1 ↑⁺(3 0 t⁻) ↑⁰(3 0 t⁰) ↑⁻(3 0 t⁰)]
b⁰ [up 1 (3 0 t⁰)]
@@ -262,9 +266,6 @@ add [[abs 1 →^0]]
…+… add
-# adds two balanced ternary numbers and strips leading 0s
-sadd strip ∘∘ add
-
:test (((-42) + (-1)) =? (-43)) (true)
:test (((-5) + (+6)) =? (+1)) (true)
:test (((-1) + (+0)) =? (-1)) (true)
@@ -274,13 +275,10 @@ sadd strip ∘∘ add
# subs two balanced ternary numbers (can introduce leading 0s)
# second argument gets abstracted (performance)
-sub [[1 + -0]]
+sub [[1 + -0]] ⧗ Number → Number → Number
…-… sub
-# subs two balanced ternary numbers and strips leading 0s
-ssub strip ∘∘ sub
-
:test (((-42) - (-1)) =? (-41)) (true)
:test (((-5) - (+6)) =? (-11)) (true)
:test (((-1) - (+0)) =? (-1)) (true)
@@ -290,7 +288,7 @@ ssub strip ∘∘ sub
# returns true if number is greater than other number
# larger numbers should be second argument (performance)
-gre? [[>?(1 - 0)]]
+gre? [[>?(1 - 0)]] ⧗ Number → Number → Boolean
…>?… gre?
@@ -300,7 +298,7 @@ gre? [[>?(1 - 0)]]
# returns true if number is less than other number
# smaller numbers should be second argument (performance)
-les? \gre?
+les? \gre? ⧗ Number → Number → Boolean
…<?… les?
@@ -310,7 +308,7 @@ les? \gre?
# returns true if number is less than or equal to other number
# smaller numbers should be second argument (performance)
-leq? [[¬(1 >? 0)]]
+leq? [[¬(1 >? 0)]] ⧗ Number → Number → Boolean
…≤?… leq?
@@ -320,7 +318,7 @@ leq? [[¬(1 >? 0)]]
# returns true if number is greater than or equal to other number
# smaller numbers should be second argument (performance)
-geq? \leq?
+geq? \leq? ⧗ Number → Number → Boolean
…≥?… geq?
@@ -329,7 +327,7 @@ geq? \leq?
:test ((+3) ≥? (+2)) (true)
# negates a balanced ternary number if <0
-abs [<?0 -0 0]
+abs [<?0 -0 0] ⧗ Number → Number
|‣ abs
@@ -337,24 +335,31 @@ abs [<?0 -0 0]
:test (|(-1)) ((+1))
:test (|(+42)) ((+42))
+# apply a function n times to a value
+# ~> substitute church numbers
+apply z [[[rec]]] ⧗ Number → (a → a) → a → a
+ rec =?1 case-end case-apply
+ case-apply 0 ∘ (2 --1 0)
+ case-end i
+
+:test (apply (+5) ++‣ (+3)) ((+8))
+
# muls two balanced ternary numbers (can introduce leading 0s)
-mul [[1 z a⁻ a⁺ a⁰]]
+mul [[1 z a⁻ a⁺ a⁰]] ⧗ Number → Number → Number
z (+0)
a⁻ [↑⁰0 - 1]
a⁺ [↑⁰0 + 1]
a⁰ [↑⁰0]
-…*… mul
-
-smul strip ∘∘ mul
+…⋅… mul
-:test (((+42) * (+0)) =? (+0)) (true)
-:test (((-1) * (+42)) =? (-42)) (true)
-:test (((+3) * (+11)) =? (+33)) (true)
-:test (((+42) * (-4)) =? (-168)) (true)
+:test (((+42) ⋅ (+0)) =? (+0)) (true)
+:test (((-1) ⋅ (+42)) =? (-42)) (true)
+:test (((+3) ⋅ (+11)) =? (+33)) (true)
+:test (((+42) ⋅ (-4)) =? (-168)) (true)
# divs a balanced ternary number by three (rshifts least significant trit)
-div³ [~(0 z a⁻ a⁺ a⁰)]
+div³ [~(0 z a⁻ a⁺ a⁰)] ⧗ Number → Number
z (+0) : (+0)
a⁻ [0 [[↑⁻1 : 1]]]
a⁺ [0 [[↑⁺1 : 1]]]
@@ -367,7 +372,7 @@ div³ [~(0 z a⁻ a⁺ a⁰)]
:test (/³(+5)) ((+2))
# divs a balanced ternary number by two (essentially binary >>1)
-div² [z [[[[rec]]]] (+0) 0 0]
+div² [z [[[[rec]]]] (+0) 0 0] ⧗ Number → Number
rec =?1 case-end case-div
case-div 3 /³(2 + 0) /³1 0
case-end 2
@@ -381,7 +386,7 @@ div² [z [[[[rec]]]] (+0) 0 0]
# manually counts how many times a balanced ternary number fits into another one
# TODO: quadratic approximation?
# TODO: fix for negative numbers
-brute-div \[z [[[[[rec]]]]] (+0) 0 0]
+brute-div \[z [[[[[rec]]]]] (+0) 0 0] ⧗ Number → Number → Number
rec (2 >? 0) case-end case-count
case-count 4 ++3 (2 + 1) 1 0
case-end 3
@@ -393,16 +398,20 @@ brute-div \[z [[[[[rec]]]]] (+0) 0 0]
:test ((+4) /! (+5)) ((+0))
# TODO: fix for negative numbers
-brute-mod \[z [[[[[rec]]]]] (+0) 0 0]
+brute-mod \[z [[[[[rec]]]]] (+0) 0 0] ⧗ Number → Number → Number
rec (2 >? 0) case-end case-count
case-count 4 ++3 (2 + 1) 1 0
- case-end 0 - (3 * 1)
+ case-end 0 - (3 ⋅ 1)
…%!… brute-mod
# finds quotient and remainder using long division
# WARNING: don't use; incorrect and slow
-quot-rem [[z [[[[rec]]]] ((+1) : (+0)) 1 0]]
+# TODO: faster algorithm
+# dividend -> divisor -> (quot, rem)
+# 0 divisor, 1 dividend, 2 (quot, rem)
+# align: (quot, divisor)
+quot-rem [[z [[[[rec]]]] ((+1) : (+0)) 1 0]] ⧗ Number → Number → (Pair Number Number)
rec (1 =? 0) case-eq ((1 <? 0) case-les case-div)
case-div calc (z [[[align]]] ^2 0)
align (0 ≤? 4) (1 : 0) (2 ↑⁰1 ↑⁰0)
@@ -413,18 +422,18 @@ quot-rem [[z [[[[rec]]]] ((+1) : (+0)) 1 0]]
# divs two balanced ternary numbers
# WARNING: don't use; incorrect and slow
-div ^‣ ∘∘ quot-rem
+div ^‣ ∘∘ quot-rem ⧗ Number → Number
…/… div
# returns remainder of integer division
# WARNING: don't use; incorrect and slow
-mod ~‣ ∘∘ quot-rem
+mod ~‣ ∘∘ quot-rem ⧗ Number → Number
…%… mod
# returns max number of two
-max [[(1 ≤? 0) 0 1]]
+max [[(1 ≤? 0) 0 1]] ⧗ Number → Number → Number
# returns min number of two
-min [[(1 ≤? 0) 1 0]]
+min [[(1 ≤? 0) 1 0]] ⧗ Number → Number → Number