# some ideas by u/DaVinci103 # MIT License, Copyright (c) 2024 Marvin Borner :import std/Logic . :import std/Combinator . :import std/Pair . :import std/Math/Rational Q :import std/Math N # a Real is just a Unary → Rational! # converts a balanced ternary number to a real number number→real [[Q.number→rational 1]] ⧗ Number → Real :test (number→real (+5)) ((+5.0r)) # returns true if two real numbers are equal approximately approx-eq? [[[Q.eq? (1 2) (0 2)]]] ⧗ Number → Real → Real → Boolean # TODO: bigger value?? …≈?… approx-eq? (+100u) # adds two real numbers add φ Q.add ⧗ Real → Real → Real …+… add :test ((+1.0r) + (+0.0r) ≈? (+1.0r)) (true) :test ((+0.0r) + (-1.0r) ≈? (-1.0r)) (true) # subtracts two real numbers sub φ Q.sub ⧗ Real → Real → Real …-… sub :test ((+1.0r) - (+0.5r) ≈? (+0.5r)) (true) :test ((+0.0r) - (-1.0r) ≈? (+1.0r)) (true) # multiplies two real numbers mul φ Q.mul ⧗ Real → Real → Real …⋅… mul :test ((+5.0r) ⋅ (+5.0r) ≈? (+25.0r)) (true) :test ((+1.8r) ⋅ (+1.2r) ≈? (+2.16r)) (true) # divides two real numbers div φ Q.div ⧗ Real → Real → Real …/… div :test ((+8.0r) / (+4.0r) ≈? (+2.0r)) (true) :test ((+18.0r) / (+12.0r) ≈? (+1.5r)) (true) # negates a real number negate b Q.negate ⧗ Real → Real -‣ negate :test (-(+0.0r) ≈? (+0.0r)) (true) :test (-(+4.2r) ≈? (-4.2r)) (true) :test (-(-4.2r) ≈? (+4.2r)) (true) # inverts a real number invert b Q.invert ⧗ Real → Real ~‣ invert :test (~(+0.5r) ≈? (+2.0r)) (true) :test (~(-0.5r) ≈? (-2.0r)) (true) # finds smallest equivalent representation of a real number compress b Q.compress ⧗ Real → Real %‣ compress :test (%[(+4) : (+1)] ≈? (+2.0r)) (true) :test (%[(+4) : (+7)] ≈? (+0.5r)) (true) # increments a real number inc add (+1.0r) ⧗ Real → Real ++‣ inc # decrements a real number dec \sub (+1.0r) ⧗ Real → Real --‣ dec # --- :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 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)] # equivalent to unary-exp but with ternary index using infinite list iteration exp [[L.index 0 (L.iterate &[[[[op]]]] start) [[[[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 # e^x using infinite limit: lim (1+x/n)^n, n to ∞ 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)] op [0 pow (Q.add 2 go) N.++1] pow Q.mul 3 (Q.pow-n 4 (+2)) go Q.mul ((+2) : (N.mul (+2) 1)) 3 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