# 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/Number N # 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 (higher performance first!) …≈?… approx-eq? (+1000) # TODO: this value could turn the whole equation to garbage (e.g. in div x ε) ε (+0.000000000000000000000001) # extends φ combinator by canceling further reductions when approximator hits 0 φ-lim [[[[[N.=?0 ε (4 (3 0) (2 0))] N.--0]]]] # extends b combinator by canceling further reductions when approximator hits 0 b-lim [[[[N.=?0 ε (3 (2 0))] N.--0]]] # adds two real numbers add φ-lim 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 φ-lim 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 φ-lim 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 φ-lim 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-lim 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-lim 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-lim Q.compress ⧗ Real → Real %‣ compress :test (%[(+4) : (+1)] ≈? (+2.0r)) (true) :test (%[(+4) : (+7)] ≈? (+0.5r)) (true) # --- :import std/List . # for debugging …#… φ-lim cons # real^number pow-n […!!… (iterate (mul 0) (+1.0r))] ⧗ Real → Number → Real exp [y [[[[rec]]]] (+1) (+1.0r) (+1.0r)] rec (1 / 0) + (3 N.++2 (1 ⋅ 4) (0 ⋅ (number→real 2))) ln [y [[[rec]]] (+1) 0] rec (N.=²?1 -‣ [0] (0 / (number→real 1))) + (2 N.++1 (3 ⋅ 0)) # power function pow [[exp (0 ⋅ (ln 1))]] ⧗ Real → Real → Real …**… pow # :test (((+2.0r) ** (+3.0r)) ≈? (+8.0r)) (true)