diff --git a/documentation/bookmark/web_browser.md b/documentation/bookmark/web_browser.md index 756ff84ba..63b5f15c7 100644 --- a/documentation/bookmark/web_browser.md +++ b/documentation/bookmark/web_browser.md @@ -21,7 +21,7 @@ 0. https://github.com/wexond/wexond 0. http://next.atlas.engineer 0. https://workona.com/ -0. https://luakit.github.io/ +0. [luakit: A fast, extensible, and customizable web browser](https://luakit.github.io/) 0. https://www.thurrott.com/cloud/web-browsers/204669/opera-web-browser-is-reborn # Security diff --git a/stdlib/source/library/lux/math/number/digit.lux b/stdlib/source/library/lux/math/number/digit.lux new file mode 100644 index 000000000..f2839682c --- /dev/null +++ b/stdlib/source/library/lux/math/number/digit.lux @@ -0,0 +1,110 @@ +... This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. +... If a copy of the MPL was not distributed with this file, You can obtain one at https://mozilla.org/MPL/2.0/. + +(.using + [library + [lux (.except) + [function + [predicate (.only Predicate)]]]]) + +(the with_template (.in_module# .prelude .with_template)) + +... https://en.wikipedia.org/wiki/Numerical_digit +(every .public Digit + (Record + [#character Text + #value Natural])) + +(with_template [,character ,value ,name ,name'] + [(the ,name' + ,character) + + (the .public ,name + Digit + [#character ,character + #value ,value])] + + ["0" 00 the_00 the_00'] + ["1" 01 the_01 the_01'] + + ["2" 02 the_02 the_02'] + ["3" 03 the_03 the_03'] + ["4" 04 the_04 the_04'] + ["5" 05 the_05 the_05'] + ["6" 06 the_06 the_06'] + ["7" 07 the_07 the_07'] + + ["8" 08 the_08 the_08'] + ["9" 09 the_09 the_09'] + + ["A" 10 the_10 the_10'] + ["B" 11 the_11 the_11'] + ["C" 12 the_12 the_12'] + ["D" 13 the_13 the_13'] + ["E" 14 the_14 the_14'] + ["F" 15 the_15 the_15'] + ) + +(the .public (base_02? it) + (Predicate Text) + (`` (when it + (,, (with_template [,digit] + [,digit + true] + + [..the_00'] + [..the_01'] + )) + + else + false))) + +(the .public (base_08? it) + (Predicate Text) + (`` (when it + (,, (with_template [,digit] + [,digit + true] + + [..the_02'] + [..the_03'] + [..the_04'] + [..the_05'] + [..the_06'] + [..the_07'] + )) + + else + (base_02? it)))) + +(the .public (base_10? it) + (Predicate Text) + (`` (when it + (,, (with_template [,digit] + [,digit + true] + + [..the_08'] + [..the_09'] + )) + + else + (base_08? it)))) + +(the .public (base_16? it) + (Predicate Text) + (`` (when it + (,, (with_template [,digit] + [,digit + true] + + [..the_10'] + [..the_11'] + [..the_12'] + [..the_13'] + [..the_14'] + [..the_15'] + )) + + else + (base_10? it)))) diff --git a/stdlib/source/library/lux/math/number/i64.lux b/stdlib/source/library/lux/math/number/i64.lux index 56e1ff2a7..b64b020e0 100644 --- a/stdlib/source/library/lux/math/number/i64.lux +++ b/stdlib/source/library/lux/math/number/i64.lux @@ -31,6 +31,19 @@ (n.* ..bits_per_byte ..bytes_per_i64)) +... TODO: Do some form of type specialization. +(every .public Shift + Natural) + +(the .public shift + (-> Natural + Shift) + (n.% ..width)) + +(the .public (opposite it) + (Change Shift) + (n.- it ..width)) + (with_template [ ] [(the .public ( parameter subject) (for_any (_ it) @@ -42,16 +55,19 @@ [(I64 Any) xor .i64_xor#] [(I64 Any) and .i64_and#] - [Natural left_shifted .i64_left#] - [Natural right_shifted .i64_right#] + [Shift left_shifted .i64_left#] + [Shift right_shifted .i64_right#] ) ... https://en.wikipedia.org/wiki/Mask_(computing) (every .public Mask I64) +(every .public Address + Natural) + (the .public (bit position) - (-> Natural + (-> Address Mask) (|> 1 .i64 (..left_shifted (n.% ..width position)))) @@ -61,8 +77,7 @@ (the .public not (for_any (_ it) - (-> (I64 it) - (I64 it))) + (Change (I64 it))) (..xor (.i64 (-- 0)))) (the .public false @@ -83,8 +98,8 @@ bits (|> 1 .i64 (..left_shifted (n.% ..width bits)) .--)))) (the (with_shift shift value) - (-> Natural Natural - Natural) + (-> Shift + (Change Natural)) (|> value (right_shifted shift) (n.+ value))) @@ -104,15 +119,15 @@ (the .public (zero index input) (for_any (_ it) - (-> Natural (I64 it) - (I64 it))) + (-> Address + (Change (I64 it)))) (|> index ..bit ..not (..and input))) (with_template [ ] [(the .public ( index input) (for_any (_ it) - (-> Natural (I64 it) - (I64 it))) + (-> Address + (Change (I64 it)))) (|> index ..bit ( input)))] [one ..or] @@ -120,31 +135,35 @@ ) (the .public (zero? index input) - (-> Natural + (-> Address (Predicate (I64 Any))) (|> (.i64 input) (..and (..bit index)) (n.= 0))) (the .public (one? index input) - (-> Natural + (-> Address (Predicate (I64 Any))) (.not (..zero? index input))) +(every .public Rotation + Shift) + (with_template [ ] [(the .public ( distance input) (for_any (_ it) - (-> Natural (I64 it) - (I64 it))) - (..or ( distance input) - ( (n.- (n.% ..width distance) ..width) input)))] + (-> Rotation + (Change (I64 it)))) + (let [distance (shift distance)] + (..or ( distance input) + ( (opposite distance) input))))] [left_rotated ..left_shifted ..right_shifted] [right_rotated ..right_shifted ..left_shifted] ) (the .public (region offset size) - (-> Natural Natural + (-> Rotation Natural Mask) (..left_rotated offset (..mask size))) @@ -180,16 +199,14 @@ (the .public reversed (for_any (_ it) - (-> (I64 it) - (I64 it))) + (Change (I64 it))) (let [swapper (is (-> Natural (for_any (_ it) - (-> (I64 it) - (I64 it)))) + (Change (I64 it)))) (function (_ power) (let [size (..left_shifted power 1) - repetitions (is (-> Natural Text - Text) + repetitions (is (-> Natural + (Change Text)) (function (_ times character) (loop (again [iterations 1 output character]) diff --git a/stdlib/source/library/lux/math/number/natural.lux b/stdlib/source/library/lux/math/number/natural.lux index 2fde22f47..a7a7b9dd9 100644 --- a/stdlib/source/library/lux/math/number/natural.lux +++ b/stdlib/source/library/lux/math/number/natural.lux @@ -18,8 +18,10 @@ ["[0]" try (.only Try)]] ["[0]" function (.only) [predicate (.only Predicate)]]]] - [/// - [arithmetic (.only Arithmetic)]]) + [// + ["[0]" digit] + [// + [arithmetic (.only Arithmetic)]]]) (the .public Number .Natural) @@ -169,15 +171,15 @@ (the / ../))) ... https://en.wikipedia.org/wiki/Greatest_common_divisor -(the .public (gcd a b) +(the .public (greatest_common_divisor a b) (-> It It It) (when b 0 a - _ (gcd b (..% b a)))) + _ (greatest_common_divisor b (..% b a)))) -(alias [greatest_common_divisor] - ..gcd) +(alias [gcd] + ..greatest_common_divisor) ... https://en.wikipedia.org/wiki/Coprime_integers (the .public (co_prime? a b) @@ -186,7 +188,7 @@ (..= 1 (..greatest_common_divisor a b))) ... https://en.wikipedia.org/wiki/Least_common_multiple -(the .public (lcm a b) +(the .public (least_common_multiple a b) (-> It It It) (`` (when [a b] @@ -198,20 +200,10 @@ [[0 _]])) _ - (|> a (../ (..gcd a b)) (..* b))))) + (|> a (../ (..greatest_common_divisor a b)) (..* b))))) -(alias [least_common_multiple] - ..lcm) - -(the .public even? - (Predicate It) - (|>> (..% 2) - (.i64_=# 0))) - -(the .public odd? - (Predicate It) - (|>> ..even? - not)) +(alias [lcm] + ..least_common_multiple) (the .public decimal (-> It @@ -251,119 +243,124 @@ (the identity ) (the composite )))] - [addition ..+ 0] - [multiplication ..* 1] + [addition ..+ 0] + [multiplication ..* 1] [minimum ..minor (by ..interval maximum)] [maximum ..major (by ..interval minimum)] ) -(the (binary_character value) +(with_template [,digit ,character ,value ,text] + [(the ,text + (its digit.#character ,digit)) + + (the ,character + (`` (character (,, (static ,text))))) + + (the ,value + (its digit.#value ,digit))] + + [digit.the_00 character_of_00 value_of_00 text_of_00] + [digit.the_01 character_of_01 value_of_01 text_of_01] + + [digit.the_02 character_of_02 value_of_02 text_of_02] + [digit.the_03 character_of_03 value_of_03 text_of_03] + [digit.the_04 character_of_04 value_of_04 text_of_04] + [digit.the_05 character_of_05 value_of_05 text_of_05] + [digit.the_06 character_of_06 value_of_06 text_of_06] + [digit.the_07 character_of_07 value_of_07 text_of_07] + + [digit.the_08 character_of_08 value_of_08 text_of_08] + [digit.the_09 character_of_09 value_of_09 text_of_09] + + [digit.the_10 character_of_10 value_of_10 text_of_10] + [digit.the_11 character_of_11 value_of_11 text_of_11] + [digit.the_12 character_of_12 value_of_12 text_of_12] + [digit.the_13 character_of_13 value_of_13 text_of_13] + [digit.the_14 character_of_14 value_of_14 text_of_14] + [digit.the_15 character_of_15 value_of_15 text_of_15] + ) + +(the (binary_digit it) (-> It Text) - (when value - 0 "0" - 1 "1" + (when it + ..value_of_00 ..text_of_00 + ..value_of_01 ..text_of_01 _ (undefined))) -(the (binary_value digit) +(the (binary_value it) (-> It (Maybe It)) - (when digit - (character "0") {.#Some 0} - (character "1") {.#Some 1} + (when it + ..character_of_00 {.#Some ..value_of_00} + ..character_of_01 {.#Some ..value_of_01} _ {.#None})) -(the (octal_character value) +(the (octal_digit it) (-> It Text) - (when value - 0 "0" - 1 "1" - 2 "2" - 3 "3" - 4 "4" - 5 "5" - 6 "6" - 7 "7" - _ (undefined))) - -(the (octal_value digit) + (when it + ..value_of_02 ..text_of_02 + ..value_of_03 ..text_of_03 + ..value_of_04 ..text_of_04 + ..value_of_05 ..text_of_05 + ..value_of_06 ..text_of_06 + ..value_of_07 ..text_of_07 + _ (binary_digit it))) + +(the (octal_value it) (-> It (Maybe It)) - (when digit - (character "0") {.#Some 0} - (character "1") {.#Some 1} - (character "2") {.#Some 2} - (character "3") {.#Some 3} - (character "4") {.#Some 4} - (character "5") {.#Some 5} - (character "6") {.#Some 6} - (character "7") {.#Some 7} - _ {.#None})) + (when it + ..character_of_02 {.#Some ..value_of_02} + ..character_of_03 {.#Some ..value_of_03} + ..character_of_04 {.#Some ..value_of_04} + ..character_of_05 {.#Some ..value_of_05} + ..character_of_06 {.#Some ..value_of_06} + ..character_of_07 {.#Some ..value_of_07} + _ (binary_value it))) + +(the (decimal_digit it) + (-> It + Text) + (when it + ..value_of_08 ..text_of_08 + ..value_of_09 ..text_of_09 + _ (octal_digit it))) -(the (decimal_value digit) +(the (decimal_value it) (-> It (Maybe It)) - (when digit - (character "0") {.#Some 0} - (character "1") {.#Some 1} - (character "2") {.#Some 2} - (character "3") {.#Some 3} - (character "4") {.#Some 4} - (character "5") {.#Some 5} - (character "6") {.#Some 6} - (character "7") {.#Some 7} - (character "8") {.#Some 8} - (character "9") {.#Some 9} - _ {.#None})) + (when it + ..character_of_08 {.#Some ..value_of_08} + ..character_of_09 {.#Some ..value_of_09} + _ (octal_value it))) -(the (hexadecimal_character value) +(the (hexadecimal_digit it) (-> It Text) - (when value - 0 "0" - 1 "1" - 2 "2" - 3 "3" - 4 "4" - 5 "5" - 6 "6" - 7 "7" - 8 "8" - 9 "9" - 10 "A" - 11 "B" - 12 "C" - 13 "D" - 14 "E" - 15 "F" - _ (undefined))) - -(`` (the (hexadecimal_value digit) - (-> It - (Maybe It)) - (when digit - (,, (with_template [ ] - [(character ) - {.#Some }] - - ["0" 0] ["1" 1] ["2" 2] ["3" 3] ["4" 4] - ["5" 5] ["6" 6] ["7" 7] ["8" 8] ["9" 9])) - - (,, (with_template [ ] - [(character ) - {.#Some } - - (character ) - {.#Some }] - - ["a" "A" 10] ["b" "B" 11] ["c" "C" 12] - ["d" "D" 13] ["e" "E" 14] ["f" "F" 15])) - - _ - {.#None}))) - -(with_template [ ] + (when it + ..value_of_10 ..text_of_10 + ..value_of_11 ..text_of_11 + ..value_of_12 ..text_of_12 + ..value_of_13 ..text_of_13 + ..value_of_14 ..text_of_14 + ..value_of_15 ..text_of_15 + _ (decimal_digit it))) + +(the (hexadecimal_value it) + (-> It + (Maybe It)) + (when it + ..character_of_10 {.#Some ..value_of_10} + ..character_of_11 {.#Some ..value_of_11} + ..character_of_12 {.#Some ..value_of_12} + ..character_of_13 {.#Some ..value_of_13} + ..character_of_14 {.#Some ..value_of_14} + ..character_of_15 {.#Some ..value_of_15} + _ (decimal_value it))) + +(with_template [ ] [(the .public (Format Text It) (implementation @@ -372,7 +369,7 @@ (function (_ value) (loop (again [input value output ""]) - (let [output' (.text_composite# ( (.i64_and# mask input)) + (let [output' (.text_composite# ( (.i64_and# mask input)) output)] (when (is It (.i64_right# input)) 0 @@ -399,9 +396,9 @@ {try.#Success output})) {try.#Failure (.text_composite# repr)})))))] - [1 binary binary_character binary_value "Invalid binary syntax: "] - [3 octal octal_character octal_value "Invalid octal syntax: "] - [4 hex hexadecimal_character hexadecimal_value "Invalid hexadecimal syntax: "] + [1 binary binary_digit binary_value "Invalid binary syntax: "] + [3 octal octal_digit octal_value "Invalid octal syntax: "] + [4 hex hexadecimal_digit hexadecimal_value "Invalid hexadecimal syntax: "] ) (the _expansion#let (.in_module# .prelude .expansion#let)) @@ -529,6 +526,15 @@ (Predicate It)) (multiple? it reference)) +(the .public even? + (Predicate It) + (multiple? 2)) + +(the .public odd? + (Predicate It) + (|>> ..even? + not)) + ... https://en.wikipedia.org/wiki/Primality_test (the .public (prime? it) (Predicate It) diff --git a/stdlib/source/library/lux/math/number/natural/big.lux b/stdlib/source/library/lux/math/number/natural/big.lux index f0f99ae97..4f4c64dfc 100644 --- a/stdlib/source/library/lux/math/number/natural/big.lux +++ b/stdlib/source/library/lux/math/number/natural/big.lux @@ -5,12 +5,21 @@ [library [lux (.except Natural macro) [abstract - [monad (.only do)]] - [error (.only error)] + [monad (.only do)] + [equivalence (.only Equivalence)] + [order (.only Order)] + [hash (.only Hash)] + [monoid (.only Monoid)] + [format (.only Format)]] + [error (.only error) + ["[0]" try (.use "[1]#[0]" functor)]] + [function + [predicate (.only Predicate)]] [data ["[0]" product] + ["[0]" text] [collection - ["[0]" list (.use "[1]#[0]" monoid)]]] + ["[0]" list (.use "[1]#[0]" monoid functor)]]] [math ["[0]" random (.only Random) (.use "[1]#[0]" monad)]]]] ["[0]" // (.only) @@ -62,6 +71,10 @@ Bit) (by (list.equivalence //.equivalence) =)) +(the digits + (macro (_ ,it) + [(.list_size# ,it)])) + (the end //.Number (-- 0)) @@ -69,8 +82,8 @@ (the .public (< reference it) (-> It It Bit) - (let [size_of_reference (list.size reference) - size_of_it (list.size it)] + (let [size_of_reference (..digits reference) + size_of_it (..digits it)] (if (//.= size_of_reference size_of_it) (loop (< [digit (-- size_of_reference)]) (when digit @@ -182,30 +195,30 @@ (the .public (+ origin it) (-> It It It) - (let [size_of_origin (list.size origin) - size_of_it (list.size it) - minimum_size (//.major size_of_origin size_of_it)] - (|> (list.dynamic (function (_ [digit carry]) - (if (//.< minimum_size digit) - (let [digit_of_origin (..digit size_of_origin origin digit) - digit_of_it (..digit size_of_it it digit) - [carry' digit'] (+' digit_of_origin digit_of_it) - [carry'' digit''] (+' carry digit')] - {.#Some [[(++ digit) - (//.+ carry' carry'')] - digit'']}) - - (//.= minimum_size digit) - (when carry - 0 {.#None} - _ {.#Some [[(++ digit) - 0] - carry]}) - - ... else - {.#None})) - [0 0]) - product.right))) + (let [size_of_origin (..digits origin) + size_of_it (..digits it) + minimum_size (//.major size_of_origin size_of_it) + [_ it] (list.dynamic (function (_ [digit carry]) + (if (//.< minimum_size digit) + (let [digit_of_origin (..digit size_of_origin origin digit) + digit_of_it (..digit size_of_it it digit) + [carry' digit'] (+' digit_of_origin digit_of_it) + [carry'' digit''] (+' carry digit')] + {.#Some [[(++ digit) + (//.+ carry' carry'')] + digit'']}) + + (//.= minimum_size digit) + (when carry + 0 {.#None} + _ {.#Some [[(++ digit) + 0] + carry]}) + + ... else + {.#None})) + [0 0])] + it)) (every .public Subtraction (Record @@ -222,8 +235,8 @@ minor (if negative? it origin) - size_of_minor (list.size minor) - size_of_major (list.size major) + size_of_minor (..digits minor) + size_of_major (..digits major) maximum_size (//.major size_of_minor size_of_major) last (-- maximum_size) [[_ _ last_non_zero] it] (list.dynamic (function (it [current carry last_non_zero]) @@ -275,24 +288,24 @@ (the (*'' scale it) (-> Digit (Change It)) - (let [size (list.size it)] - (|> (list.dynamic (function (_ [current carry]) - (if (//.< size current) - (let [[high low] (*''' scale (.list_item# current it)) - [carry low] (+' carry low)] - {.#Some [[(++ current) - (//.+ carry high)] - low]}) - - (//.> 0 carry) - {.#Some [[current - 0] - carry]} - - ... else - {.#None})) - [0 0]) - product.right))) + (let [size (..digits it) + [_ it] (list.dynamic (function (_ [current carry]) + (if (//.< size current) + (let [[high low] (*''' scale (.list_item# current it)) + [carry low] (+' carry low)] + {.#Some [[(++ current) + (//.+ carry high)] + low]}) + + (//.> 0 carry) + {.#Some [[current + 0] + carry]} + + ... else + {.#None})) + [0 0])] + it)) (the (*' level scale it) (-> //.Number Digit @@ -311,21 +324,24 @@ (the .public (* scale it) (-> It It It) - (let [[_ it] (list.mix (function (_ scale [level accumulation]) - [(++ level) - (+ (*' level scale it) - accumulation)]) - [0 ..zero] + (let [[it _] (list.mix (function (_ scale [accumulation level]) + [(+ (*' level scale it) + accumulation) + (++ level)]) + [..zero 0] scale)] it)) (the .public division_by_zero (error "division_by_zero")) +(every .public Exponent + //.Exponent) + (the .public (logarithm_2 it) (-> It - //.Number) - (when (list.size it) + Exponent) + (when (..digits it) 0 0 @@ -346,32 +362,32 @@ (Change It)) (let [block (//.- exponent i64.width) mask (i64.left_shifted block (i64.mask exponent)) - size (list.size it)] - (|> (list.dynamic (function (_ [@ carry]) - (if (//.< size @) - (let [digit (.list_item# @ it) - carry' (|> digit - (i64.and mask) - (i64.right_shifted block)) - digit' (|> digit - (i64.left_shifted exponent) - (i64.or carry))] - {.#Some [[(++ @) - carry'] - digit']}) - - (//.= 0 carry) - {.#None} - - ... else - {.#Some [[(++ @) - 0] - carry]})) - [0 0]) - product.right))) + size (..digits it) + [_ it] (list.dynamic (function (_ [@ carry]) + (if (//.< size @) + (let [digit (.list_item# @ it) + carry' (|> digit + (i64.and mask) + (i64.right_shifted block)) + digit' (|> digit + (i64.left_shifted exponent) + (i64.or carry))] + {.#Some [[(++ @) + carry'] + digit']}) + + (//.= 0 carry) + {.#None} + + ... else + {.#Some [[(++ @) + 0] + carry]})) + [0 0])] + it)) (the (left_shifted exponent it) - (-> //.Number + (-> Exponent (Change It)) (when it (..zero') @@ -394,7 +410,7 @@ (with_padding zeroes))))) (the .public (exponential_2 exponent) - (-> //.Number + (-> Exponent It) (left_shifted exponent ..one)) @@ -454,17 +470,328 @@ (/ scale) (+ (exponential_2 it/scale))))))))))) -(the .public (/% scale it) +(the both + (macro (_ ,left ,right) + [[,left ,right]])) + +(the right + (macro (_ ,left ,right) + [,right])) + +(with_template [,name ,type ,choice] + [(the .public (,name scale it) + (-> It It + ,type) + (let [quotient (/ scale it) + flat (* scale quotient)] + (,choice quotient + (|> it + (- flat) + (its #value)))))] + + [/% [It It] both] + [% It right] + ) + +... https://en.wikipedia.org/wiki/Exponentiation +... https://en.wikipedia.org/wiki/Exponentiation_by_squaring +(the .public (^ power base) + (-> Exponent + (Change It)) + (loop (^ [power power + base base + it ..one]) + (if (.i64_=# 0 power) + it + (^ (.i64_right# 1 power) + (* base base) + (if (.i64_=# 1 (.i64_and# 1 power)) + (* base it) + it))))) + +... https://en.wikipedia.org/wiki/Greatest_common_divisor +(the .public (greatest_common_divisor a b) (-> It It - [It It]) - (let [quotient (/ scale it) - flat (* scale quotient)] - [quotient - (|> it - (- flat) - (its #value))])) - -(the .public (% scale it) + It) + (when b + (..zero') a + _ (greatest_common_divisor b (..% b a)))) + +(alias [gcd] + ..greatest_common_divisor) + +... https://en.wikipedia.org/wiki/Coprime_integers +(the .public (co_prime? a b) + (-> It + (Predicate It)) + (..= ..one (..greatest_common_divisor a b))) + +... https://en.wikipedia.org/wiki/Least_common_multiple +(the .public (least_common_multiple a b) (-> It It It) - (product.right (/% scale it))) + (`` (when [a b] + (,, (with_template [] + [ + ..zero] + + [[_ (..zero')]] + [[(..zero') _]])) + + _ + (|> a + (../ (..greatest_common_divisor a b)) + (..* b))))) + +(alias [lcm] + ..least_common_multiple) + +(the .public equivalence + (Equivalence It) + (implementation + (the = ..=))) + +(the .public order + (Order It) + (implementation + (the equivalence ..equivalence) + (the < ..<))) + +(the .public hash + (Hash It) + (implementation + (the equivalence ..equivalence) + (the (hash it) + (when it + (..zero') + 0 + + _ + (.list_item# 0 it))))) + +(with_template [ ] + [(the .public + (Monoid It) + (implementation + (the identity ) + (the composite )))] + + [addition ..+ ..zero] + [multiplication ..* ..one] + [maximum ..major ..zero] + ) + +(the .public (multiple? reference it) + (-> It + (Predicate It)) + (|> it + (% reference) + (= ..zero))) + +(the .public (divisor? reference it) + (-> It + (Predicate It)) + (multiple? it reference)) + +(the .public even? + (Predicate It) + (multiple? (list 2))) + +(the .public odd? + (Predicate It) + (|>> ..even? + not)) + +(the base_02_digits_per_digit + (//./ 1 i64.width)) + +(the base_16_digits_per_digit + (//./ 4 i64.width)) + +(the (runs_of_digits per_digit it) + (-> //.Number Text + (List Text)) + (let [total (text.size it)] + (if (//.> per_digit total) + (loop (runs_of_digits [end total + suffix (is (List Text) + (list))]) + (if (//.> per_digit end) + (let [start (//.- per_digit end) + run (.text_clip# start per_digit it)] + (runs_of_digits start (list#composite suffix (list run)))) + (list#composite suffix (list (.text_clip# 0 end it))))) + (list it)))) + +(the base_08_digits_per_digit + (//./ 3 i64.width)) + +... 02^64 - 1 = 18,446,744,073,709,551,615 +... 10^19 = 10,000,000,000,000,000,000 + +(the range_of_base_10 + 10,000,000,000,000,000,000) + +(the base_10_digits_per_digit + 19) + +(with_template [,name ,per_digit] + [(the (,name it) + (when (text.size it) + ,per_digit + it + + digits + (let [padding (//.- digits ,per_digit)] + (text (text.interposed "" (list.repeated padding "0")) + it))))] + + [with_padding_for_02 ..base_02_digits_per_digit] + [with_padding_for_16 ..base_16_digits_per_digit] + + [with_padding_for_08 ..base_08_digits_per_digit] + [with_padding_for_10 ..base_10_digits_per_digit] + ) + +(the (with_no_padding it) + (Change Text) + (let [limit (text.size it)] + (loop (with_no_padding [padding 0]) + (if (//.< limit padding) + (when (.text_char# padding it) + (character "0") + (with_no_padding (++ padding)) + + else + (.text_clip# padding (//.- padding limit) it)) + "0")))) + +(with_template [,name ,per_digit ,padding ,//] + [(the .public ,name + (Format Text It) + (implementation + (the (as it) + (when it + (..zero') + "0" + + else + (|> it + (list#each (|>> (by ,// as) ,padding)) + list.reversed + (text.interposed "") + ..with_no_padding))) + + (the of + (|>> ..with_no_padding + (runs_of_digits ,per_digit) + (list.each' try.monad (by ,// of))))))] + + [base_02 ..base_02_digits_per_digit ..with_padding_for_02 //.base_02] + [base_16 ..base_16_digits_per_digit ..with_padding_for_16 //.base_16] + ) + +(the initial_shift_for_head 0) +(the no_head 0) +(the initial_carry 0) + +(the .public base_08 + (Format Text It) + (let [addition_to_shift (//.% 3 i64.width) + initial_shift_for_clean_up addition_to_shift] + (implementation + (the (as it) + (when it + (..zero') + "0" + + else + (let [[it carry _] (list.mix (function (_ digit [it carry shift_for_clean_up]) + (when shift_for_clean_up + i64.width + [(text (by //.base_08 as carry) it) + ..initial_carry + initial_shift_for_clean_up] + + else + (let [proper_digit (|> digit + + (i64.left_shifted shift_for_clean_up) + (i64.right_shifted shift_for_clean_up) + + (i64.left_shifted (-- shift_for_clean_up)) + (i64.or carry))] + [(text (with_padding_for_08 (by //.base_08 as proper_digit)) it) + (i64.right_shifted (i64.opposite shift_for_clean_up) digit) + (//.+ addition_to_shift shift_for_clean_up)]))) + ["" ..initial_carry initial_shift_for_clean_up] + it)] + (..with_no_padding (when carry + ..initial_carry + it + + else + (text (by //.base_08 as carry) it)))))) + + (the (of it) + (do [! try.monad] + [[[head tail] _] (|> it + ..with_no_padding + (runs_of_digits ..base_08_digits_per_digit) + (list.each' try.monad (by //.base_08 of)) + (by ! each (list.mix (function (_ digit [[head tail] shift_for_head]) + [(when (i64.shift shift_for_head) + ..initial_shift_for_head + [digit tail] + + shift_for_head + (let [head' (|> digit + (i64.left_shifted (i64.opposite shift_for_head)) + (i64.or head))] + [(i64.right_shifted shift_for_head digit) + (list#composite tail (list head'))])) + (//.+ addition_to_shift shift_for_head)]) + [[..no_head ..zero] ..initial_shift_for_head])))] + (pure (when head + ..no_head + tail + + else + (list#composite tail (list head))))))))) + +(the factor_for_base_10 + Number + (list ..range_of_base_10)) + +(the .public base_10 + (Format Text It) + (implementation + (the (as it) + (loop (as [input it + output ""]) + (let [[tail head] (/% ..factor_for_base_10 input) + output (text (when head + (list head) + (with_padding_for_10 (by //.base_10 as head)) + + else + "0") + output)] + (when tail + (..zero') + (..with_no_padding output) + + else + (as tail output))))) + + (the of + (|>> ..with_no_padding + (runs_of_digits ..base_10_digits_per_digit) + (list.each' try.monad (by //.base_10 of)) + (try#each (|>> (list.mix (function (_ digit [total factor]) + [(|> (list digit) + (* factor) + (+ total)) + (* factor_for_base_10 factor)]) + [..zero ..one]) + product.left)))))) diff --git a/stdlib/source/library/lux/target/jvm/bytecode/instruction.lux b/stdlib/source/library/lux/target/jvm/bytecode/instruction.lux index 2f12f2251..459314835 100644 --- a/stdlib/source/library/lux/target/jvm/bytecode/instruction.lux +++ b/stdlib/source/library/lux/target/jvm/bytecode/instruction.lux @@ -376,7 +376,7 @@ (template.with [ ] [[ [] []]] - ["4f" iastore] + ["4F" iastore] ["50" lastore] ["51" fastore] ["52" dastore] @@ -390,13 +390,13 @@ ["60" iadd] ["64" isub] ["68" imul] - ["6c" idiv] + ["6C" idiv] ["70" irem] ["74" ineg] ["78" ishl] - ["7a" ishr] - ["7c" iushr] - ["7e" iand] + ["7A" ishr] + ["7C" iushr] + ["7E" iand] ["80" ior] ["82" ixor] diff --git a/stdlib/source/library/lux/test/unit.lux b/stdlib/source/library/lux/test/unit.lux index 8601d2807..dab5ad3d5 100644 --- a/stdlib/source/library/lux/test/unit.lux +++ b/stdlib/source/library/lux/test/unit.lux @@ -70,7 +70,8 @@ (the .public context (-> Text Test Test) - (|>> %.text context')) + (|>> %.text + context')) (template.with [ ] [(the @@ -86,7 +87,8 @@ (the .public (-> Text Test) - (|>> %.text ))] + (|>> %.text + ))] ["Failure" tally.failure failure' failure terminal.red_foreground] ["Success" tally.success success' success terminal.green_foreground] @@ -102,7 +104,7 @@ (the .public (test message condition) (-> Text Bit Test) - (test' (%.text message) condition)) + (test' (terminal.with terminal.yellow_foreground message) condition)) ... https://en.wikipedia.org/wiki/Delimiter (the definition_delimiter " & ") @@ -112,7 +114,8 @@ (the coverage_text (text.Injection Name) (|>> name.as_text - (text ..clean_up_marker))) + (text ..clean_up_marker) + (terminal.with terminal.blue_foreground))) (the (with_coverage coverage condition) (-> (List Name) Bit diff --git a/stdlib/source/test/lux/math/number.lux b/stdlib/source/test/lux/math/number.lux index a5d80050a..3923fb7da 100644 --- a/stdlib/source/test/lux/math/number.lux +++ b/stdlib/source/test/lux/math/number.lux @@ -10,6 +10,7 @@ ["[0]" /]] ["[0]" / ["[1][0]" i64] + ["[1][0]" digit] ["[1][0]" natural] ["[1][0]" integer] ["[1][0]" revolution] @@ -23,6 +24,7 @@ (<| (_.covering /._) (all _.and /i64.test + /digit.test /natural.test /integer.test /revolution.test diff --git a/stdlib/source/test/lux/math/number/digit.lux b/stdlib/source/test/lux/math/number/digit.lux new file mode 100644 index 000000000..33e290608 --- /dev/null +++ b/stdlib/source/test/lux/math/number/digit.lux @@ -0,0 +1,66 @@ +... This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. +... If a copy of the MPL was not distributed with this file, You can obtain one at https://mozilla.org/MPL/2.0/. + +(.using + [library + [lux (.except) + [abstract + [monad (.only do)]] + [data + ["[0]" text] + [collection + ["[0]" list (.use "[1]#[0]" functor)] + ["[0]" set]]] + [macro + ["[0]" expansion]] + [math + ["[0]" random] + [number + ["[0]" natural]]] + [test + ["_" property (.only Test)]]]] + [\\library + ["[0]" /]]) + +(the .public test + Test + (<| (_.covering /._) + (do [! random.monad] + []) + (expansion.let [,every_02 (these /.the_00 /.the_01) + ,every_08 (these /.the_02 /.the_03 /.the_04 /.the_05 /.the_06 /.the_07) + ,every_10 (these /.the_08 /.the_09) + ,every_16 (these /.the_10 /.the_11 /.the_12 /.the_13 /.the_14 /.the_15)]) + (_.for [/.Digit]) + (all _.and + (_.coverage [/.#character] + (let [options (list#each (its /.#character) (list ,every_02 ,every_08 ,every_10 ,every_16))] + (|> options + (set.of_list text.hash) + set.size + (natural.= (list.size options))))) + (_.coverage [/.#value] + (let [options (list#each (its /.#value) (list ,every_02 ,every_08 ,every_10 ,every_16))] + (|> options + (set.of_list natural.hash) + set.size + (natural.= (list.size options))))) + (_.coverage [/.base_02? + ,every_02] + (list.every? (|>> (its /.#character) /.base_02?) (list ,every_02))) + (_.coverage [/.base_08? + ,every_08] + (and (list.every? (|>> (its /.#character) /.base_08?) (list ,every_02)) + (list.every? (|>> (its /.#character) /.base_08?) (list ,every_08)))) + (_.coverage [/.base_10? + ,every_10] + (and (list.every? (|>> (its /.#character) /.base_10?) (list ,every_02)) + (list.every? (|>> (its /.#character) /.base_10?) (list ,every_08)) + (list.every? (|>> (its /.#character) /.base_10?) (list ,every_10)))) + (_.coverage [/.base_16? + ,every_16] + (and (list.every? (|>> (its /.#character) /.base_16?) (list ,every_02)) + (list.every? (|>> (its /.#character) /.base_16?) (list ,every_08)) + (list.every? (|>> (its /.#character) /.base_16?) (list ,every_10)) + (list.every? (|>> (its /.#character) /.base_16?) (list ,every_16)))) + ))) diff --git a/stdlib/source/test/lux/math/number/natural/big.lux b/stdlib/source/test/lux/math/number/natural/big.lux index 64f562feb..6672c7fac 100644 --- a/stdlib/source/test/lux/math/number/natural/big.lux +++ b/stdlib/source/test/lux/math/number/natural/big.lux @@ -5,7 +5,17 @@ [library [lux (.except) [abstract - [monad (.only do)]] + [monad (.only do)] + ["[0]" hash + ["[1]T" \\test]] + ["[0]" format + ["[1]T" \\test]] + ["[0]" equivalence + ["[1]T" \\test]] + ["[0]" order + ["[1]T" \\test]] + ["[0]" monoid + ["[1]T" \\test]]] [data ["[0]" bit] ["[0]" text] @@ -13,6 +23,10 @@ ["[0]" list]]] [function [predicate (.only Predicate)]] + [macro + ["[0]" template]] + [meta + ["[0]" static]] [math ["[0]" random] [number @@ -28,17 +42,76 @@ (|>> list.reversed (list.as_text (by natural.base_10 as)))) -(the (subtraction_as_text it) - (-> /.Subtraction - Text) - (text (number_as_text (its /.#value it)) - "-" - (number_as_text (its /.#offset it)))) +(the test_for_every_interface + Test + (`` (all _.and + (_.for [/.equivalence /.=] + (static.when (same? /.equivalence /.=) + (equivalenceT.spec /.equivalence (/.random 3)))) + (_.for [/.hash] + (hashT.spec /.hash (/.random 1))) + (_.for [/.order /.<] + (orderT.spec /.order (/.random 3))) + (,, (template.with [ ] + [(_.for [ ] + (static.when (same? (by composite)) + (monoidT.spec /.equivalence (/.random 3))))] + + [/.+ /.addition] + [/.* /.multiplication] -(the .public test + [/.major /.maximum] + )) + (,, (template.with [] + [(_.for [] + (formatT.spec /.equivalence (/.random 3)))] + + [/.base_02] + [/.base_08] + [/.base_10] + [/.base_16] + )) + ))) + +(the lattice Test - (<| (_.covering /._) - (do [! random.monad] + (<| (do [! random.monad] + [left (/.random 3) + right (/.random 3) + + digits (by ! each (natural.% 4) + random.natural) + + expected (/.random digits)]) + (all _.and + (_.coverage [/.lcm /.least_common_multiple + /.multiple?] + (and (/.= /.zero + (/.least_common_multiple /.zero expected)) + (/.= (/.least_common_multiple right left) + (/.least_common_multiple left right)) + (and (/.multiple? left (/.least_common_multiple left right)) + (/.multiple? right (/.least_common_multiple left right))) + (alias? /.least_common_multiple /.lcm))) + (_.coverage [/.gcd /.greatest_common_divisor + /.divisor?] + (and (/.= expected + (/.greatest_common_divisor /.zero expected)) + (/.= (/.greatest_common_divisor right left) + (/.greatest_common_divisor left right)) + (and (/.divisor? left (/.greatest_common_divisor left right)) + (/.divisor? right (/.greatest_common_divisor left right))) + (alias? /.greatest_common_divisor /.gcd))) + (_.coverage [/.co_prime?] + (and (bit.= (/.co_prime? expected expected) + (/.= /.one expected)) + (bit.= (/.= /.one (/.greatest_common_divisor left right)) + (/.co_prime? left right)))) + ))) + +(the comparison + Test + (<| (do [! random.monad] [bit_0 random.bit bit_1 random.bit bit_2 random.bit @@ -61,13 +134,9 @@ it_1 (/.random 3) it_2 (/.random 3) - exponent_0 (by ! each (natural.% 200) random.natural) - exponent_1 (by ! each (natural.% 200) random.natural)]) - (_.for [/.Number - /.random]) + left (/.random 3) + right (/.random 3)]) (all _.and - (_.coverage [/.Natural] - (same? /.Number /.Natural)) (_.coverage [/.=] (let [reflection! (/.= it it) @@ -154,6 +223,39 @@ commutativity! relationship!))) + ))) + +(the arithmetic + Test + (<| (do [! random.monad] + [bit_0 random.bit + bit_1 random.bit + bit_2 random.bit + .let [[random_0 random_1 random_2] (if bit_0 + (if bit_1 + (if bit_2 + [(/.random 1) (/.random 2) (/.random 3)] + [(/.random 1) (/.random 3) (/.random 2)]) + (if bit_2 + [(/.random 2) (/.random 1) (/.random 3)] + [(/.random 2) (/.random 3) (/.random 1)])) + (if bit_1 + [(/.random 3) (/.random 1) (/.random 2)] + [(/.random 3) (/.random 2) (/.random 1)]))] + origin random_0 + other random_1 + it random_2 + + exponent_0 (by ! each (natural.% 200) random.natural) + exponent_1 (by ! each (natural.% 200) random.natural) + + left (/.random 3) + right (/.random 3) + + sample (/.random 3) + power (by ! each (natural.% 10) + random.natural)]) + (all _.and (_.coverage [/.+] (and (/.= (/.+ origin it) (/.+ it origin)) @@ -212,41 +314,6 @@ negative!))] (and balance! reconstitution!))) - (_.coverage [/.exponential_2] - (let [double (is (Change /.Number) - (function (_ it) - (/.+ it it)))] - (and (/.= (|> it) - (/.* it (/.exponential_2 0))) - (/.= (|> it double) - (/.* it (/.exponential_2 1))) - (/.= (double (/.* it (/.exponential_2 exponent_0))) - (/.* it (/.exponential_2 (++ exponent_0)))) - (let [e2^x (/.exponential_2 exponent_0)] - (and (|> e2^x - (/.* it) - (/./ it) - (/.= e2^x)) - (|> it - (/.* e2^x) - (/./ e2^x) - (/.= it)))) - (/.= (/.exponential_2 (natural.+ exponent_0 exponent_1)) - (/.* (/.exponential_2 exponent_0) - (/.exponential_2 exponent_1)))))) - (_.coverage [/.logarithm_2] - (and (|> (/.logarithm_2 /.zero) - (natural.= 0)) - (|> (/.logarithm_2 /.one) - (natural.= 0)) - (|> (/.logarithm_2 (/.+ /.one /.one)) - (natural.= 1)) - (natural.= (/.logarithm_2 (/.+ it it)) - (++ (/.logarithm_2 it))) - (|> exponent_0 - /.exponential_2 - /.logarithm_2 - (natural.= exponent_0)))) (_.coverage [/./] (let [itself! (/.= /.one (/./ it it)) @@ -321,4 +388,89 @@ no_room! factor! reconstitution!))) + (_.coverage [/./%] + (let [[div rem] (/./% left right)] + (and (/.= div (/./ left right)) + (/.= rem (/.% left right))))) + (<| (_.for [/.Exponent]) + (all _.and + (_.coverage [/.^] + (and (/.= /.one (/.^ 0 sample)) + (/.= sample (/.^ 1 sample)) + (/.= (list.mix /.* /.one (list.repeated power sample)) + (/.^ power sample)))) + (_.coverage [/.exponential_2] + (let [double (is (Change /.Number) + (function (_ it) + (/.+ it it)))] + (and (/.= (|> it) + (/.* it (/.exponential_2 0))) + (/.= (|> it double) + (/.* it (/.exponential_2 1))) + (/.= (double (/.* it (/.exponential_2 exponent_0))) + (/.* it (/.exponential_2 (++ exponent_0)))) + (let [e2^x (/.exponential_2 exponent_0)] + (and (|> e2^x + (/.* it) + (/./ it) + (/.= e2^x)) + (|> it + (/.* e2^x) + (/./ e2^x) + (/.= it)))) + (/.= (/.exponential_2 (natural.+ exponent_0 exponent_1)) + (/.* (/.exponential_2 exponent_0) + (/.exponential_2 exponent_1)))))) + (_.coverage [/.logarithm_2] + (and (|> (/.logarithm_2 /.zero) + (natural.= 0)) + (|> (/.logarithm_2 /.one) + (natural.= 0)) + (|> (/.logarithm_2 (/.+ /.one /.one)) + (natural.= 1)) + (natural.= (/.logarithm_2 (/.+ it it)) + (++ (/.logarithm_2 it))) + (|> exponent_0 + /.exponential_2 + /.logarithm_2 + (natural.= exponent_0)))) + )) + ))) + +(the .public test + Test + (<| (_.covering /._) + (do [! random.monad] + [bit_0 random.bit + bit_1 random.bit + bit_2 random.bit + .let [[random_0 random_1 random_2] (if bit_0 + (if bit_1 + (if bit_2 + [(/.random 1) (/.random 2) (/.random 3)] + [(/.random 1) (/.random 3) (/.random 2)]) + (if bit_2 + [(/.random 2) (/.random 1) (/.random 3)] + [(/.random 2) (/.random 3) (/.random 1)])) + (if bit_1 + [(/.random 3) (/.random 1) (/.random 2)] + [(/.random 3) (/.random 2) (/.random 1)]))] + origin random_0 + other random_1 + it random_2 + + sample (/.random 3)]) + (_.for [/.Number + /.random]) + (all _.and + ..test_for_every_interface + + (_.coverage [/.Natural] + (same? /.Number /.Natural)) + ..comparison + ..arithmetic + ..lattice + (_.coverage [/.even? /.odd?] + (bit.= (/.even? sample) + (not (/.odd? sample)))) )))