aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEduardo Julian2022-03-16 04:22:45 -0400
committerEduardo Julian2022-03-16 04:22:45 -0400
commitd710d9f4fc098e7c243c8a5f23cd42683f13e07f (patch)
treee48633e5f21df572fbb133855e77f5c1adfd40fb
parentb0093a3849baaeb5e12692b2cf6ac65ba74bbd54 (diff)
Generalized/type-agnostic arithmetic.
-rw-r--r--.github/workflows/test.yml2
-rw-r--r--changelog.md2
-rw-r--r--stdlib/source/library/lux/data/color.lux41
-rw-r--r--stdlib/source/library/lux/extension.lux4
-rw-r--r--stdlib/source/library/lux/math.lux636
-rw-r--r--stdlib/source/library/lux/math/number/complex.lux111
-rw-r--r--stdlib/source/library/lux/math/number/frac.lux442
-rw-r--r--stdlib/source/library/lux/math/number/int.lux31
-rw-r--r--stdlib/source/library/lux/math/number/nat.lux10
-rw-r--r--stdlib/source/library/lux/math/number/rev.lux10
-rw-r--r--stdlib/source/library/lux/static.lux13
-rw-r--r--stdlib/source/program/aedifex/command/build.lux3
-rw-r--r--stdlib/source/program/aedifex/runtime.lux9
-rw-r--r--stdlib/source/test/lux/data/color.lux12
-rw-r--r--stdlib/source/test/lux/math.lux252
-rw-r--r--stdlib/source/test/lux/math/infix.lux33
-rw-r--r--stdlib/source/test/lux/math/number/complex.lux13
-rw-r--r--stdlib/source/test/lux/math/number/frac.lux145
18 files changed, 1051 insertions, 718 deletions
diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml
index 23a031285..11861f6b0 100644
--- a/.github/workflows/test.yml
+++ b/.github/workflows/test.yml
@@ -6,7 +6,7 @@ jobs:
steps:
- uses: actions/checkout@v2
# Setup Aedifex
- - run: wget https://github.com/LuxLang/lux/releases/download/0.6.5/aedifex_do_not_touch_1.jar && mv aedifex_do_not_touch_1.jar aedifex.jar
+ - run: wget https://github.com/LuxLang/lux/releases/download/0.6.5/aedifex_do_not_touch_2.jar && mv aedifex_do_not_touch_2.jar aedifex.jar
- run: mv ./shell/lux.sh ./lux.sh
# Test on the JVM
# https://github.com/actions/setup-java
diff --git a/changelog.md b/changelog.md
index 5772001ac..df0d1be90 100644
--- a/changelog.md
+++ b/changelog.md
@@ -8,8 +8,10 @@
* Code selection based on compiler version.
* Extensible meta-compiler.
* Export machinery to consume Lux code from host-language programs.
+* Generalized/type-agnostic arithmetic.
### Changed
* JVM compilation no longer relies on the ASM library.
+* Friendlier syntax.
### Removed
### Fixed
### Deprecated
diff --git a/stdlib/source/library/lux/data/color.lux b/stdlib/source/library/lux/data/color.lux
index e327ff261..093a2b6ba 100644
--- a/stdlib/source/library/lux/data/color.lux
+++ b/stdlib/source/library/lux/data/color.lux
@@ -1,25 +1,22 @@
(.using
- [library
- [lux "*"
- [abstract
- [equivalence {"+" Equivalence}]
- [monoid {"+" Monoid}]
- ["[0]" hash {"+" Hash}]]
- [control
- [parser
- ["<[0]>" code]]]
- [data
- [collection
- ["[0]" list ("[1]#[0]" functor)]]]
- ["[0]" math
- [number
- ["n" nat]
- ["f" frac]
- ["[0]" int]
- ["[0]" rev ("[1]#[0]" interval)]
- ["[0]" i64]]]
- [type
- abstract]]])
+ [library
+ [lux "*"
+ [abstract
+ [equivalence {"+" Equivalence}]
+ [monoid {"+" Monoid}]
+ ["[0]" hash {"+" Hash}]]
+ [data
+ [collection
+ ["[0]" list ("[1]#[0]" functor)]]]
+ [math
+ [number
+ ["n" nat]
+ ["f" frac]
+ ["[0]" int]
+ ["[0]" rev ("[1]#[0]" interval)]
+ ["[0]" i64]]]
+ [type
+ abstract]]])
(def: rgb_limit 256)
(def: top (-- rgb_limit))
@@ -244,7 +241,7 @@
(def: .public (of_hsb [hue saturation brightness])
(-> HSB Color)
(let [hue (|> hue (f.* +6.0))
- i (math.floor hue)
+ i (f.floor hue)
f (|> hue (f.- i))
p (|> +1.0 (f.- saturation) (f.* brightness))
q (|> +1.0 (f.- (f.* f saturation)) (f.* brightness))
diff --git a/stdlib/source/library/lux/extension.lux b/stdlib/source/library/lux/extension.lux
index cabab0a8f..2e2c74f23 100644
--- a/stdlib/source/library/lux/extension.lux
+++ b/stdlib/source/library/lux/extension.lux
@@ -13,8 +13,8 @@
[collection
["[0]" list ("[1]#[0]" functor)]]]
[macro {"+" with_symbols}
- ["[0]" code]
- [syntax {"+" syntax:}]]
+ [syntax {"+" syntax:}]
+ ["[0]" code]]
[tool
[compiler
["[0]" phase]]]]])
diff --git a/stdlib/source/library/lux/math.lux b/stdlib/source/library/lux/math.lux
index f9df0dd73..7395cb180 100644
--- a/stdlib/source/library/lux/math.lux
+++ b/stdlib/source/library/lux/math.lux
@@ -1,414 +1,228 @@
(.using
[library
[lux "*"
- ["@" target]
- [math
- [number
- ["n" nat]
- ["i" int]]]]])
-
-(template [<name> <value>]
- [(def: .public <name>
- <value>)]
-
- [e +2.7182818284590452354]
- ... ["π is wrong!" by Bob Palais](https://www.math.utah.edu/~palais/pi.html)
- [pi +3.14159265358979323846]
- ... [The Tau Manifesto](https://tauday.com/tau-manifesto)
- [tau +6.28318530717958647692]
- )
-
-(for @.old
- (as_is (template [<name> <method>]
- [(def: .public (<name> it)
- (-> Frac Frac)
- (<method> it))]
-
- [cos "jvm invokestatic:java.lang.Math:cos:double"]
- [sin "jvm invokestatic:java.lang.Math:sin:double"]
- [tan "jvm invokestatic:java.lang.Math:tan:double"]
-
- [acos "jvm invokestatic:java.lang.Math:acos:double"]
- [asin "jvm invokestatic:java.lang.Math:asin:double"]
- [atan "jvm invokestatic:java.lang.Math:atan:double"]
-
- [exp "jvm invokestatic:java.lang.Math:exp:double"]
- [log "jvm invokestatic:java.lang.Math:log:double"]
-
- [ceil "jvm invokestatic:java.lang.Math:ceil:double"]
- [floor "jvm invokestatic:java.lang.Math:floor:double"]
-
- [root/2 "jvm invokestatic:java.lang.Math:sqrt:double"]
- [root/3 "jvm invokestatic:java.lang.Math:cbrt:double"]
- )
- (def: .public (pow param subject)
- (-> Frac Frac Frac)
- ("jvm invokestatic:java.lang.Math:pow:double,double" subject param)))
-
- @.jvm
- (as_is (template: (!double value)
- [(|> value
- (:as (Primitive "java.lang.Double"))
- "jvm object cast")])
-
- (template: (!frac value)
- [(|> value
- "jvm object cast"
- (: (Primitive "java.lang.Double"))
- (:as Frac))])
-
- (template [<name> <method>]
- [(def: .public <name>
- (-> Frac Frac)
- (|>> !double
- ["D"]
- ("jvm member invoke static" [] "java.lang.Math" <method> [])
- !frac))]
-
- [cos "cos"]
- [sin "sin"]
- [tan "tan"]
-
- [acos "acos"]
- [asin "asin"]
- [atan "atan"]
-
- [exp "exp"]
- [log "log"]
-
- [ceil "ceil"]
- [floor "floor"]
-
- [root/2 "sqrt"]
- [root/3 "cbrt"]
- )
-
- (def: .public (pow param subject)
- (-> Frac Frac Frac)
- (|> ("jvm member invoke static" [] "java.lang.Math" "pow" []
- ["D" (!double subject)] ["D" (!double param)])
- !frac)))
-
- @.js
- (as_is (template [<name> <method>]
- [(def: .public <name>
- (-> Frac Frac)
- (|>> []
- ("js apply" ("js constant" <method>))
- (:as Frac)))]
-
- [cos "Math.cos"]
- [sin "Math.sin"]
- [tan "Math.tan"]
-
- [acos "Math.acos"]
- [asin "Math.asin"]
- [atan "Math.atan"]
-
- [exp "Math.exp"]
- [log "Math.log"]
-
- [ceil "Math.ceil"]
- [floor "Math.floor"]
-
- [root/2 "Math.sqrt"]
- [root/3 "Math.cbrt"]
- )
-
- (def: .public (pow param subject)
- (-> Frac Frac Frac)
- (:as Frac ("js apply" ("js constant" "Math.pow") [subject param]))))
-
- @.python
- (as_is (template [<name> <method>]
- [(def: .public <name>
- (-> Frac Frac)
- (|>> []
- ("python object do" <method> ("python import" "math"))
- (:as Frac)))]
-
- [cos "cos"]
- [sin "sin"]
- [tan "tan"]
-
- [acos "acos"]
- [asin "asin"]
- [atan "atan"]
-
- [exp "exp"]
- [log "log"]
-
- [ceil "ceil"]
- [floor "floor"]
-
- [root/2 "sqrt"]
- )
-
- (def: .public (pow param subject)
- (-> Frac Frac Frac)
- (:as Frac ("python object do" "pow" ("python import" "math") [subject param])))
-
- (def: .public (root/3 it)
- (-> Frac Frac)
- (if ("lux f64 <" +0.0 it)
- (|> it
- ("lux f64 *" -1.0)
- (..pow ("lux f64 /" +3.0 +1.0))
- ("lux f64 *" -1.0))
- (|> it
- (..pow ("lux f64 /" +3.0 +1.0))))))
-
- @.lua
- (as_is (template [<name> <method>]
- [(def: .public <name>
- (-> Frac Frac)
- (|>> []
- ("lua apply" ("lua constant" <method>))
- (:as Frac)))]
-
- [cos "math.cos"]
- [sin "math.sin"]
- [tan "math.tan"]
-
- [acos "math.acos"]
- [asin "math.asin"]
- [atan "math.atan"]
-
- [exp "math.exp"]
- [log "math.log"]
-
- [ceil "math.ceil"]
- [floor "math.floor"]
-
- [root/2 "math.sqrt"]
- )
-
- (def: .public (pow param subject)
- (-> Frac Frac Frac)
- ("lua power" param subject))
-
- (def: .public (root/3 it)
- (-> Frac Frac)
- (if ("lux f64 <" +0.0 it)
- (|> it
- ("lux f64 *" -1.0)
- (..pow ("lux f64 /" +3.0 +1.0))
- ("lux f64 *" -1.0))
- (|> it
- (..pow ("lux f64 /" +3.0 +1.0))))))
-
- @.ruby
- (as_is (template [<name> <method>]
- [(def: .public <name>
- (-> Frac Frac)
- (|>> []
- ("ruby apply" ("ruby constant" <method>))
- (:as Frac)))]
-
- [cos "Math.cos"]
- [sin "Math.sin"]
- [tan "Math.tan"]
-
- [acos "Math.acos"]
- [asin "Math.asin"]
- [atan "Math.atan"]
-
- [exp "Math.exp"]
- [log "Math.log"]
-
- [root/2 "Math.sqrt"]
- [root/3 "Math.cbrt"]
- )
-
- (template [<name> <method>]
- [(def: .public (<name> it)
- (-> Frac Frac)
- (|> ("ruby object do" <method> it [])
- (:as Int)
- ("lux i64 f64")))]
-
- [ceil "ceil"]
- [floor "floor"]
- )
-
- (def: .public (pow param subject)
- (-> Frac Frac Frac)
- (:as Frac ("ruby object do" "**" subject [param]))))
-
- @.php
- (as_is (template [<name> <method>]
- [(def: .public <name>
- (-> Frac Frac)
- (|>> ("php apply" ("php constant" <method>))
- (:as Frac)))]
-
- [cos "cos"]
- [sin "sin"]
- [tan "tan"]
-
- [acos "acos"]
- [asin "asin"]
- [atan "atan"]
-
- [exp "exp"]
- [log "log"]
-
- [ceil "ceil"]
- [floor "floor"]
-
- [root/2 "sqrt"]
- )
-
- (def: .public (pow param subject)
- (-> Frac Frac Frac)
- (:as Frac ("php apply" ("php constant" "pow") subject param)))
-
- (def: .public root/3
- (-> Frac Frac)
- (..pow ("lux f64 /" +3.0 +1.0))))
-
- @.scheme
- (as_is (template [<name> <method>]
- [(def: .public <name>
- (-> Frac Frac)
- (|>> ("scheme apply" ("scheme constant" <method>))
- (:as Frac)))]
-
- [cos "cos"]
- [sin "sin"]
- [tan "tan"]
-
- [acos "acos"]
- [asin "asin"]
- [atan "atan"]
-
- [exp "exp"]
- [log "log"]
-
- [ceil "ceiling"]
- [floor "floor"]
-
- [root/2 "sqrt"]
- )
-
- (def: .public (pow param subject)
- (-> Frac Frac Frac)
- (:as Frac ("scheme apply" ("scheme constant" "expt") subject param)))
-
- (def: .public root/3
- (-> Frac Frac)
- (..pow ("lux f64 /" +3.0 +1.0))))
- )
-
-(def: .public (round it)
- (-> Frac Frac)
- (let [floored (floor it)
- diff ("lux f64 -" floored it)]
- (cond ("lux f64 <" diff +0.5)
- ("lux f64 +" +1.0 floored)
-
- ("lux f64 <" -0.5 diff)
- ("lux f64 +" -1.0 floored)
-
- ... else
- floored)))
-
-(def: .public (atan/2 x y)
- (-> Frac Frac Frac)
- (cond ("lux f64 <" x +0.0)
- (..atan ("lux f64 /" x y))
-
- ("lux f64 <" +0.0 x)
- (if (or ("lux f64 <" y +0.0)
- ("lux f64 =" +0.0 y))
- (|> y ("lux f64 /" x) atan ("lux f64 +" pi))
- (|> y ("lux f64 /" x) atan ("lux f64 -" pi)))
-
- ... ("lux f64 =" +0.0 x)
- (cond ("lux f64 <" y +0.0)
- (|> pi ("lux f64 /" +2.0))
-
- ("lux f64 <" +0.0 y)
- (|> pi ("lux f64 /" -2.0))
-
- ... ("lux f64 =" +0.0 y)
- ("lux f64 /" +0.0 +0.0))))
-
-(def: .public (log_by base it)
- (-> Frac Frac Frac)
- ("lux f64 /"
- (..log base)
- (..log it)))
-
-(def: .public (factorial it)
- (-> Nat Nat)
- (loop [acc 1
- it it]
- (if (n.> 1 it)
- (again (n.* it acc) (-- it))
- acc)))
-
-(def: .public (hypotenuse catA catB)
- (-> Frac Frac Frac)
- (..pow +0.5 ("lux f64 +"
- (..pow +2.0 catA)
- (..pow +2.0 catB))))
-
-... Hyperbolic functions
-... https://en.wikipedia.org/wiki/Hyperbolic_function#Definitions
-(template [<name> <comp> <inverse>]
- [(def: .public (<name> it)
- (-> Frac Frac)
- (|> (..exp it) (<comp> (..exp ("lux f64 *" -1.0 it))) ("lux f64 /" +2.0)))
-
- (def: .public (<inverse> it)
- (-> Frac Frac)
- (|> +2.0 ("lux f64 /" (|> (..exp it) (<comp> (..exp ("lux f64 *" -1.0 it)))))))]
-
- [sinh "lux f64 -" csch]
- [cosh "lux f64 +" sech]
- )
-
-(template [<name> <top> <bottom>]
- [(def: .public (<name> it)
- (-> Frac Frac)
- (let [e+ (exp it)
- e- (exp ("lux f64 *" -1.0 it))
- sinh' (|> e+ ("lux f64 -" e-))
- cosh' (|> e+ ("lux f64 +" e-))]
- (|> <top> ("lux f64 /" <bottom>))))]
-
- [tanh sinh' cosh']
- [coth cosh' sinh']
- )
-
-... https://en.wikipedia.org/wiki/Inverse_hyperbolic_functions#Definitions_in_terms_of_logarithms
-(template [<name> <comp>]
- [(def: .public (<name> it)
- (-> Frac Frac)
- (|> it (pow +2.0) (<comp> +1.0) (pow +0.5) ("lux f64 +" it) log))]
-
- [asinh "lux f64 +"]
- [acosh "lux f64 -"]
- )
-
-(template [<name> <base> <diff>]
- [(def: .public (<name> it)
- (-> Frac Frac)
- (let [it+ (|> <base> ("lux f64 +" <diff>))
- it- (|> <base> ("lux f64 -" <diff>))]
- (|> it+ ("lux f64 /" it-) log ("lux f64 /" +2.0))))]
-
- [atanh +1.0 it]
- [acoth it +1.0]
- )
-
-(template [<name> <op>]
- [(def: .public (<name> it)
- (-> Frac Frac)
- (let [it^2 (|> it (pow +2.0))]
- (|> +1.0 (<op> it^2) (pow +0.5) ("lux f64 +" +1.0) ("lux f64 /" it) log)))]
-
- [asech "lux f64 -"]
- [acsch "lux f64 +"]
- )
+ [extension {"+" analysis:}]
+ ["[0]" static]
+ [abstract
+ ["[0]" monad {"+" do}]]
+ [control
+ ["[0]" try {"+" Try}]
+ ["[0]" exception {"+" exception:}]
+ ["<>" parser
+ ["<[0]>" code]]]
+ [data
+ [text
+ ["%" format]]
+ [collection
+ ["[0]" list ("[1]#[0]" mix)]]]
+ [macro
+ [syntax {"+" syntax:}]
+ ["[0]" template]]
+ [tool
+ [compiler
+ ["[0]" phase ("[1]#[0]" monad)]
+ [language
+ [lux
+ ["[0]" analysis {"+" Analysis Operation Phase}
+ ["[0]" type]]]]
+ [meta
+ [archive {"+" Archive}]]]]
+ [type
+ ["[0]" check]]]]
+ [/
+ ["[0]" random]
+ [number
+ ["[0]" nat]
+ ["[0]" int]
+ ["[0]" rev]
+ ["[0]" frac]
+ ["[0]" ratio {"+" Ratio}]
+ ["[0]" complex {"+" Complex}]]])
+
+(exception: (no_arithmetic_for [type Type])
+ (exception.report
+ "Type" (%.type type)))
+
+(def: (composite phase archive <+> last prevs)
+ (-> Phase Archive Code Analysis (List Analysis) (Operation Analysis))
+ (case <+>
+ [_ {.#Text $}]
+ (phase#in (list#mix (function (_ left right)
+ {analysis.#Extension $ (list left right)})
+ last
+ prevs))
+
+ _
+ (do phase.monad
+ [[_ $] (type.inferring
+ (phase archive <+>))]
+ (in (list#mix (function (_ left right)
+ (analysis.reified [$ (list left right)]))
+ last
+ prevs)))))
+
+(with_expansions [<@> (static.text (let [[@ _] (symbol .._)] @))
+ <ratio/0> [ratio.#numerator 0 ratio.#denominator 1]
+ <ratio/1> [ratio.#numerator 1 ratio.#denominator 1]
+ <complex/0> [complex.#real +0.0 complex.#imaginary +0.0]
+ <complex/1> [complex.#real +1.0 complex.#imaginary +0.0]]
+ (as_is (template [<name> <scenarios>']
+ [(with_expansions [<extension> (static.seed)
+ <extension> (template.text [<@> " " <extension>])
+ <scenarios> (template.spliced <scenarios>')]
+ (as_is (analysis: (<extension> self phase archive [operands (<>.some <code>.any)])
+ (<| type.with_var
+ (function (_ [$it :it:]))
+ (do [! phase.monad]
+ [operands (monad.each ! (|>> (phase archive) (type.expecting :it:))
+ operands)
+ _ (type.inference :it:)
+ :it: (type.check (check.identity (list) $it))]
+ (case (list.reversed operands)
+ (pattern (list single))
+ (in single)
+
+ (pattern (list))
+ (`` (cond (check.subsumes? .I64 :it:)
+ (phase.except ..no_arithmetic_for [:it:])
+
+ (~~ (template [<type> <0> <+>]
+ [(check.subsumes? <type> :it:)
+ <0>]
+
+ <scenarios>))
+
+ ... else
+ (phase.except ..no_arithmetic_for [:it:])))
+
+ (pattern (list& last prevs))
+ (`` (cond (check.subsumes? .I64 :it:)
+ (phase.except ..no_arithmetic_for [:it:])
+
+ (~~ (template [<type> <0> <+>]
+ [(check.subsumes? <type> :it:)
+ (..composite phase archive (` <+>) last prevs)]
+
+ <scenarios>))
+
+ ... else
+ (phase.except ..no_arithmetic_for [:it:])))))))
+ (syntax: .public (<name> [operands (<>.some <code>.any)])
+ (in (list (` (<extension> (~+ operands))))))))]
+
+ [+ [[.Nat (in (analysis.nat 0)) "lux i64 +"]
+ [.Int (in (analysis.int +0)) "lux i64 +"]
+ [.Rev (in (analysis.rev .0)) "lux i64 +"]
+ [.Frac (in (analysis.frac +0.0)) "lux f64 +"]
+ [Ratio (type.expecting Ratio (phase archive (` <ratio/0>))) ratio.+]
+ [Complex (type.expecting Complex (phase archive (` <complex/0>))) complex.+]]]
+ [- [[.Nat (in (analysis.nat 0)) "lux i64 -"]
+ [.Int (in (analysis.int -0)) "lux i64 -"]
+ [.Rev (in (analysis.rev .0)) "lux i64 -"]
+ [.Frac (in (analysis.frac -0.0)) "lux f64 -"]
+ [Ratio (type.expecting Ratio (phase archive (` <ratio/0>))) ratio.-]
+ [Complex (type.expecting Complex (phase archive (` <complex/0>))) complex.-]]]
+ [* [[.Nat (in (analysis.nat 1)) nat.*]
+ [.Int (in (analysis.int +1)) "lux i64 *"]
+ [.Rev (in (analysis.rev rev./1)) rev.*]
+ [.Frac (in (analysis.frac +1.0)) "lux f64 *"]
+ [Ratio (type.expecting Ratio (phase archive (` <ratio/1>))) ratio.*]
+ [Complex (type.expecting Complex (phase archive (` <complex/1>))) complex.*]]]
+ [/ [[.Nat (in (analysis.nat 1)) nat./]
+ [.Int (in (analysis.int +1)) "lux i64 /"]
+ [.Rev (in (analysis.rev rev./1)) rev./]
+ [.Frac (in (analysis.frac +1.0)) "lux f64 /"]
+ [Ratio (type.expecting Ratio (phase archive (` <ratio/1>))) ratio./]
+ [Complex (type.expecting Complex (phase archive (` <complex/1>))) complex./]]]
+ )
+ (template [<name> <scenarios>']
+ [(with_expansions [<extension> (static.seed)
+ <extension> (template.text [<@> " " <extension>])
+ <scenarios> (template.spliced <scenarios>')]
+ (as_is (analysis: (<extension> self phase archive [left <code>.any
+ right <code>.any])
+ (<| type.with_var
+ (function (_ [$it :it:]))
+ (do [! phase.monad]
+ [left (type.expecting :it: (phase archive left))
+ right (type.expecting :it: (phase archive right))
+ _ (type.inference .Bit)
+ :it: (type.check (check.identity (list) $it))]
+ (`` (cond (check.subsumes? .I64 :it:)
+ (phase.except ..no_arithmetic_for [:it:])
+
+ (~~ (template [<type> <+>]
+ [(check.subsumes? <type> :it:)
+ (..composite phase archive (` <+>) right (list left))]
+
+ <scenarios>))
+
+ ... else
+ (phase.except ..no_arithmetic_for [:it:]))))))
+ (syntax: .public (<name> [left <code>.any
+ right <code>.any])
+ (in (list (` (<extension> (~ left) (~ right))))))))]
+
+ [= [[.Nat "lux i64 ="]
+ [.Int "lux i64 ="]
+ [.Rev "lux i64 ="]
+ [.Frac "lux f64 ="]
+ [Ratio ratio.=]
+ [Complex complex.=]]]
+ [< [[.Nat nat.<]
+ [.Int "lux i64 <"]
+ [.Rev rev.<]
+ [.Frac "lux f64 <"]
+ [Ratio ratio.<]]]
+ [> [[.Nat nat.>]
+ [.Int int.>]
+ [.Rev rev.>]
+ [.Frac frac.>]
+ [Ratio ratio.>]]]
+ [<= [[.Nat nat.<=]
+ [.Int int.<=]
+ [.Rev rev.<=]
+ [.Frac frac.<=]
+ [Ratio ratio.<=]]]
+ [>= [[.Nat nat.>=]
+ [.Int int.>=]
+ [.Rev rev.>=]
+ [.Frac frac.>=]
+ [Ratio ratio.>=]]]
+ )
+ (template [<name> <scenarios>']
+ [(with_expansions [<extension> (static.seed)
+ <extension> (template.text [<@> " " <extension>])
+ <scenarios> (template.spliced <scenarios>')]
+ (as_is (analysis: (<extension> self phase archive [left <code>.any
+ right <code>.any])
+ (<| type.with_var
+ (function (_ [$it :it:]))
+ (do [! phase.monad]
+ [left (type.expecting :it: (phase archive left))
+ right (type.expecting :it: (phase archive right))
+ _ (type.inference :it:)
+ :it: (type.check (check.identity (list) $it))]
+ (`` (cond (check.subsumes? .I64 :it:)
+ (phase.except ..no_arithmetic_for [:it:])
+
+ (~~ (template [<type> <+>]
+ [(check.subsumes? <type> :it:)
+ (..composite phase archive (` <+>) right (list left))]
+
+ <scenarios>))
+
+ ... else
+ (phase.except ..no_arithmetic_for [:it:]))))))
+ (syntax: .public (<name> [left <code>.any
+ right <code>.any])
+ (in (list (` (<extension> (~ left) (~ right))))))))]
+
+ [% [[.Nat nat.%]
+ [.Int "lux i64 %"]
+ [.Rev rev.%]
+ [.Frac "lux f64 %"]
+ [Ratio ratio.%]
+ [Complex complex.%]]]
+ )
+ ))
diff --git a/stdlib/source/library/lux/math/number/complex.lux b/stdlib/source/library/lux/math/number/complex.lux
index 52947b51b..470a9bfbf 100644
--- a/stdlib/source/library/lux/math/number/complex.lux
+++ b/stdlib/source/library/lux/math/number/complex.lux
@@ -1,24 +1,19 @@
(.using
[library
[lux "*"
- ["[0]" math]
[abstract
- [equivalence {"+" Equivalence}]
- [codec {"+" Codec}]
- ["M" monad {"+" Monad do}]]
+ [equivalence {"+" Equivalence}]]
[control
["[0]" maybe]
["<>" parser
- ["<[0]>" code {"+" Parser}]]]
+ ["<[0]>" code]]]
[data
[collection
["[0]" list ("[1]#[0]" functor)]]]
[macro
- [syntax {"+" syntax:}]
- ["[0]" code]]
+ [syntax {"+" syntax:}]]
[math
[number
- ["n" nat]
["f" frac]
["[0]" int]]]]])
@@ -133,60 +128,60 @@
(-> Complex Complex Complex)
(let [scaled (/ param input)
quotient (|> scaled
- (revised #real math.floor)
- (revised #imaginary math.floor))]
+ (revised #real f.floor)
+ (revised #imaginary f.floor))]
(- (* quotient param)
input)))
(def: .public (cos subject)
(-> Complex Complex)
(let [(open "[0]") subject]
- [..#real (f.* (math.cosh #imaginary)
- (math.cos #real))
- ..#imaginary (f.opposite (f.* (math.sinh #imaginary)
- (math.sin #real)))]))
+ [..#real (f.* (f.cosh #imaginary)
+ (f.cos #real))
+ ..#imaginary (f.opposite (f.* (f.sinh #imaginary)
+ (f.sin #real)))]))
(def: .public (cosh subject)
(-> Complex Complex)
(let [(open "[0]") subject]
- [..#real (f.* (math.cos #imaginary)
- (math.cosh #real))
- ..#imaginary (f.* (math.sin #imaginary)
- (math.sinh #real))]))
+ [..#real (f.* (f.cos #imaginary)
+ (f.cosh #real))
+ ..#imaginary (f.* (f.sin #imaginary)
+ (f.sinh #real))]))
(def: .public (sin subject)
(-> Complex Complex)
(let [(open "[0]") subject]
- [..#real (f.* (math.cosh #imaginary)
- (math.sin #real))
- ..#imaginary (f.* (math.sinh #imaginary)
- (math.cos #real))]))
+ [..#real (f.* (f.cosh #imaginary)
+ (f.sin #real))
+ ..#imaginary (f.* (f.sinh #imaginary)
+ (f.cos #real))]))
(def: .public (sinh subject)
(-> Complex Complex)
(let [(open "[0]") subject]
- [..#real (f.* (math.cos #imaginary)
- (math.sinh #real))
- ..#imaginary (f.* (math.sin #imaginary)
- (math.cosh #real))]))
+ [..#real (f.* (f.cos #imaginary)
+ (f.sinh #real))
+ ..#imaginary (f.* (f.sin #imaginary)
+ (f.cosh #real))]))
(def: .public (tan subject)
(-> Complex Complex)
(let [(open "[0]") subject
r2 (f.* +2.0 #real)
i2 (f.* +2.0 #imaginary)
- d (f.+ (math.cos r2) (math.cosh i2))]
- [..#real (f./ d (math.sin r2))
- ..#imaginary (f./ d (math.sinh i2))]))
+ d (f.+ (f.cos r2) (f.cosh i2))]
+ [..#real (f./ d (f.sin r2))
+ ..#imaginary (f./ d (f.sinh i2))]))
(def: .public (tanh subject)
(-> Complex Complex)
(let [(open "[0]") subject
r2 (f.* +2.0 #real)
i2 (f.* +2.0 #imaginary)
- d (f.+ (math.cosh r2) (math.cos i2))]
- [..#real (f./ d (math.sinh r2))
- ..#imaginary (f./ d (math.sin i2))]))
+ d (f.+ (f.cosh r2) (f.cos i2))]
+ [..#real (f./ d (f.sinh r2))
+ ..#imaginary (f./ d (f.sin i2))]))
(def: .public (abs subject)
(-> Complex Frac)
@@ -196,26 +191,26 @@
(if (f.= +0.0 #imaginary)
(f.abs #real)
(let [q (f./ #imaginary #real)]
- (f.* (math.pow +0.5 (f.+ +1.0 (f.* q q)))
+ (f.* (f.pow +0.5 (f.+ +1.0 (f.* q q)))
(f.abs #imaginary))))
(if (f.= +0.0 #real)
(f.abs #imaginary)
(let [q (f./ #real #imaginary)]
- (f.* (math.pow +0.5 (f.+ +1.0 (f.* q q)))
+ (f.* (f.pow +0.5 (f.+ +1.0 (f.* q q)))
(f.abs #real)))))))
(def: .public (exp subject)
(-> Complex Complex)
(let [(open "[0]") subject
- r_exp (math.exp #real)]
- [..#real (f.* r_exp (math.cos #imaginary))
- ..#imaginary (f.* r_exp (math.sin #imaginary))]))
+ r_exp (f.exp #real)]
+ [..#real (f.* r_exp (f.cos #imaginary))
+ ..#imaginary (f.* r_exp (f.sin #imaginary))]))
(def: .public (log subject)
(-> Complex Complex)
(let [(open "[0]") subject]
- [..#real (|> subject ..abs math.log)
- ..#imaginary (math.atan/2 #real #imaginary)]))
+ [..#real (|> subject ..abs f.log)
+ ..#imaginary (f.atan/2 #real #imaginary)]))
(template [<name> <type> <op>]
[(def: .public (<name> param input)
@@ -233,7 +228,7 @@
(def: .public (root/2 input)
(-> Complex Complex)
(let [(open "[0]") input
- t (|> input ..abs (f.+ (f.abs #real)) (f./ +2.0) (math.pow +0.5))]
+ t (|> input ..abs (f.+ (f.abs #real)) (f./ +2.0) (f.pow +0.5))]
(if (f.< +0.0 #real)
[..#real (f./ (f.* +2.0 t)
(f.abs #imaginary))
@@ -286,27 +281,27 @@
(def: .public (argument (open "[0]"))
(-> Complex Frac)
- (math.atan/2 #real #imaginary))
+ (f.atan/2 #real #imaginary))
(def: .public (roots nth input)
(-> Nat Complex (List Complex))
- (if (n.= 0 nth)
- (list)
- (let [r_nth (|> nth .int int.frac)
- nth_root_of_abs (|> input ..abs (math.pow (f./ r_nth +1.0)))
- nth_phi (|> input ..argument (f./ r_nth))
- slice (|> math.pi (f.* +2.0) (f./ r_nth))]
- (|> (list.indices nth)
- (list#each (function (_ nth')
- (let [inner (|> nth' .int int.frac
- (f.* slice)
- (f.+ nth_phi))
- real (f.* nth_root_of_abs
- (math.cos inner))
- imaginary (f.* nth_root_of_abs
- (math.sin inner))]
- [..#real real
- ..#imaginary imaginary])))))))
+ (case nth
+ 0 (list)
+ _ (let [r_nth (|> nth .int int.frac)
+ nth_root_of_abs (|> input ..abs (f.pow (f./ r_nth +1.0)))
+ nth_phi (|> input ..argument (f./ r_nth))
+ slice (|> f.pi (f.* +2.0) (f./ r_nth))]
+ (|> (list.indices nth)
+ (list#each (function (_ nth')
+ (let [inner (|> nth' .int int.frac
+ (f.* slice)
+ (f.+ nth_phi))
+ real (f.* nth_root_of_abs
+ (f.cos inner))
+ imaginary (f.* nth_root_of_abs
+ (f.sin inner))]
+ [..#real real
+ ..#imaginary imaginary])))))))
(def: .public (approximately? margin_of_error standard value)
(-> Frac Complex Complex Bit)
diff --git a/stdlib/source/library/lux/math/number/frac.lux b/stdlib/source/library/lux/math/number/frac.lux
index d3cd5f138..511b0fef9 100644
--- a/stdlib/source/library/lux/math/number/frac.lux
+++ b/stdlib/source/library/lux/math/number/frac.lux
@@ -21,16 +21,422 @@
["[1][0]" i64]
["[1][0]" nat]
["[1][0]" int]
- ["[1][0]" rev]
- ["/[1]" //]])
+ ["[1][0]" rev]])
-(def: .public (= reference sample)
- (-> Frac Frac Bit)
- ("lux f64 =" reference sample))
+(template [<name> <value>]
+ [(def: .public <name>
+ <value>)]
-(def: .public (< reference sample)
- (-> Frac Frac Bit)
- ("lux f64 <" reference sample))
+ [e +2.7182818284590452354]
+ ... ["π is wrong!" by Bob Palais](https://www.math.utah.edu/~palais/pi.html)
+ [pi +3.14159265358979323846]
+ ... [The Tau Manifesto](https://tauday.com/tau-manifesto)
+ [tau +6.28318530717958647692]
+ )
+
+(for @.old
+ (as_is (template [<name> <method>]
+ [(def: .public (<name> it)
+ (-> Frac Frac)
+ (<method> it))]
+
+ [cos "jvm invokestatic:java.lang.Math:cos:double"]
+ [sin "jvm invokestatic:java.lang.Math:sin:double"]
+ [tan "jvm invokestatic:java.lang.Math:tan:double"]
+
+ [acos "jvm invokestatic:java.lang.Math:acos:double"]
+ [asin "jvm invokestatic:java.lang.Math:asin:double"]
+ [atan "jvm invokestatic:java.lang.Math:atan:double"]
+
+ [exp "jvm invokestatic:java.lang.Math:exp:double"]
+ [log "jvm invokestatic:java.lang.Math:log:double"]
+
+ [ceil "jvm invokestatic:java.lang.Math:ceil:double"]
+ [floor "jvm invokestatic:java.lang.Math:floor:double"]
+
+ [root/2 "jvm invokestatic:java.lang.Math:sqrt:double"]
+ [root/3 "jvm invokestatic:java.lang.Math:cbrt:double"]
+ )
+ (def: .public (pow param subject)
+ (-> Frac Frac Frac)
+ ("jvm invokestatic:java.lang.Math:pow:double,double" subject param)))
+
+ @.jvm
+ (as_is (template: (!double value)
+ [(|> value
+ (:as (Primitive "java.lang.Double"))
+ "jvm object cast")])
+
+ (template: (!frac value)
+ [(|> value
+ "jvm object cast"
+ (: (Primitive "java.lang.Double"))
+ (:as Frac))])
+
+ (template [<name> <method>]
+ [(def: .public <name>
+ (-> Frac Frac)
+ (|>> !double
+ ["D"]
+ ("jvm member invoke static" [] "java.lang.Math" <method> [])
+ !frac))]
+
+ [cos "cos"]
+ [sin "sin"]
+ [tan "tan"]
+
+ [acos "acos"]
+ [asin "asin"]
+ [atan "atan"]
+
+ [exp "exp"]
+ [log "log"]
+
+ [ceil "ceil"]
+ [floor "floor"]
+
+ [root/2 "sqrt"]
+ [root/3 "cbrt"]
+ )
+
+ (def: .public (pow param subject)
+ (-> Frac Frac Frac)
+ (|> ("jvm member invoke static" [] "java.lang.Math" "pow" []
+ ["D" (!double subject)] ["D" (!double param)])
+ !frac)))
+
+ @.js
+ (as_is (template [<name> <method>]
+ [(def: .public <name>
+ (-> Frac Frac)
+ (|>> []
+ ("js apply" ("js constant" <method>))
+ (:as Frac)))]
+
+ [cos "Math.cos"]
+ [sin "Math.sin"]
+ [tan "Math.tan"]
+
+ [acos "Math.acos"]
+ [asin "Math.asin"]
+ [atan "Math.atan"]
+
+ [exp "Math.exp"]
+ [log "Math.log"]
+
+ [ceil "Math.ceil"]
+ [floor "Math.floor"]
+
+ [root/2 "Math.sqrt"]
+ [root/3 "Math.cbrt"]
+ )
+
+ (def: .public (pow param subject)
+ (-> Frac Frac Frac)
+ (:as Frac ("js apply" ("js constant" "Math.pow") [subject param]))))
+
+ @.python
+ (as_is (template [<name> <method>]
+ [(def: .public <name>
+ (-> Frac Frac)
+ (|>> []
+ ("python object do" <method> ("python import" "math"))
+ (:as Frac)))]
+
+ [cos "cos"]
+ [sin "sin"]
+ [tan "tan"]
+
+ [acos "acos"]
+ [asin "asin"]
+ [atan "atan"]
+
+ [exp "exp"]
+ [log "log"]
+
+ [ceil "ceil"]
+ [floor "floor"]
+
+ [root/2 "sqrt"]
+ )
+
+ (def: .public (pow param subject)
+ (-> Frac Frac Frac)
+ (:as Frac ("python object do" "pow" ("python import" "math") [subject param])))
+
+ (def: .public (root/3 it)
+ (-> Frac Frac)
+ (if ("lux f64 <" +0.0 it)
+ (|> it
+ ("lux f64 *" -1.0)
+ (..pow ("lux f64 /" +3.0 +1.0))
+ ("lux f64 *" -1.0))
+ (|> it
+ (..pow ("lux f64 /" +3.0 +1.0))))))
+
+ @.lua
+ (as_is (template [<name> <method>]
+ [(def: .public <name>
+ (-> Frac Frac)
+ (|>> []
+ ("lua apply" ("lua constant" <method>))
+ (:as Frac)))]
+
+ [cos "math.cos"]
+ [sin "math.sin"]
+ [tan "math.tan"]
+
+ [acos "math.acos"]
+ [asin "math.asin"]
+ [atan "math.atan"]
+
+ [exp "math.exp"]
+ [log "math.log"]
+
+ [ceil "math.ceil"]
+ [floor "math.floor"]
+
+ [root/2 "math.sqrt"]
+ )
+
+ (def: .public (pow param subject)
+ (-> Frac Frac Frac)
+ ("lua power" param subject))
+
+ (def: .public (root/3 it)
+ (-> Frac Frac)
+ (if ("lux f64 <" +0.0 it)
+ (|> it
+ ("lux f64 *" -1.0)
+ (..pow ("lux f64 /" +3.0 +1.0))
+ ("lux f64 *" -1.0))
+ (|> it
+ (..pow ("lux f64 /" +3.0 +1.0))))))
+
+ @.ruby
+ (as_is (template [<name> <method>]
+ [(def: .public <name>
+ (-> Frac Frac)
+ (|>> []
+ ("ruby apply" ("ruby constant" <method>))
+ (:as Frac)))]
+
+ [cos "Math.cos"]
+ [sin "Math.sin"]
+ [tan "Math.tan"]
+
+ [acos "Math.acos"]
+ [asin "Math.asin"]
+ [atan "Math.atan"]
+
+ [exp "Math.exp"]
+ [log "Math.log"]
+
+ [root/2 "Math.sqrt"]
+ [root/3 "Math.cbrt"]
+ )
+
+ (template [<name> <method>]
+ [(def: .public (<name> it)
+ (-> Frac Frac)
+ (|> ("ruby object do" <method> it [])
+ (:as Int)
+ ("lux i64 f64")))]
+
+ [ceil "ceil"]
+ [floor "floor"]
+ )
+
+ (def: .public (pow param subject)
+ (-> Frac Frac Frac)
+ (:as Frac ("ruby object do" "**" subject [param]))))
+
+ @.php
+ (as_is (template [<name> <method>]
+ [(def: .public <name>
+ (-> Frac Frac)
+ (|>> ("php apply" ("php constant" <method>))
+ (:as Frac)))]
+
+ [cos "cos"]
+ [sin "sin"]
+ [tan "tan"]
+
+ [acos "acos"]
+ [asin "asin"]
+ [atan "atan"]
+
+ [exp "exp"]
+ [log "log"]
+
+ [ceil "ceil"]
+ [floor "floor"]
+
+ [root/2 "sqrt"]
+ )
+
+ (def: .public (pow param subject)
+ (-> Frac Frac Frac)
+ (:as Frac ("php apply" ("php constant" "pow") subject param)))
+
+ (def: .public root/3
+ (-> Frac Frac)
+ (..pow ("lux f64 /" +3.0 +1.0))))
+
+ @.scheme
+ (as_is (template [<name> <method>]
+ [(def: .public <name>
+ (-> Frac Frac)
+ (|>> ("scheme apply" ("scheme constant" <method>))
+ (:as Frac)))]
+
+ [cos "cos"]
+ [sin "sin"]
+ [tan "tan"]
+
+ [acos "acos"]
+ [asin "asin"]
+ [atan "atan"]
+
+ [exp "exp"]
+ [log "log"]
+
+ [ceil "ceiling"]
+ [floor "floor"]
+
+ [root/2 "sqrt"]
+ )
+
+ (def: .public (pow param subject)
+ (-> Frac Frac Frac)
+ (:as Frac ("scheme apply" ("scheme constant" "expt") subject param)))
+
+ (def: .public root/3
+ (-> Frac Frac)
+ (..pow ("lux f64 /" +3.0 +1.0))))
+ )
+
+(def: .public (round it)
+ (-> Frac Frac)
+ (let [floored (floor it)
+ diff ("lux f64 -" floored it)]
+ (cond ("lux f64 <" diff +0.5)
+ ("lux f64 +" +1.0 floored)
+
+ ("lux f64 <" -0.5 diff)
+ ("lux f64 +" -1.0 floored)
+
+ ... else
+ floored)))
+
+(def: .public (atan/2 x y)
+ (-> Frac Frac Frac)
+ (cond ("lux f64 <" x +0.0)
+ (..atan ("lux f64 /" x y))
+
+ ("lux f64 <" +0.0 x)
+ (if (or ("lux f64 <" y +0.0)
+ ("lux f64 =" +0.0 y))
+ (|> y ("lux f64 /" x) atan ("lux f64 +" pi))
+ (|> y ("lux f64 /" x) atan ("lux f64 -" pi)))
+
+ ... ("lux f64 =" +0.0 x)
+ (cond ("lux f64 <" y +0.0)
+ (|> pi ("lux f64 /" +2.0))
+
+ ("lux f64 <" +0.0 y)
+ (|> pi ("lux f64 /" -2.0))
+
+ ... ("lux f64 =" +0.0 y)
+ ("lux f64 /" +0.0 +0.0))))
+
+(def: .public (log_by base it)
+ (-> Frac Frac Frac)
+ ("lux f64 /"
+ (..log base)
+ (..log it)))
+
+(def: .public (factorial it)
+ (-> Nat Nat)
+ (loop [acc 1
+ it it]
+ (if (//nat.> 1 it)
+ (again (//nat.* it acc) (-- it))
+ acc)))
+
+(def: .public (hypotenuse catA catB)
+ (-> Frac Frac Frac)
+ (..pow +0.5 ("lux f64 +"
+ (..pow +2.0 catA)
+ (..pow +2.0 catB))))
+
+... Hyperbolic functions
+... https://en.wikipedia.org/wiki/Hyperbolic_function#Definitions
+(template [<name> <comp> <inverse>]
+ [(def: .public (<name> it)
+ (-> Frac Frac)
+ (|> (..exp it) (<comp> (..exp ("lux f64 *" -1.0 it))) ("lux f64 /" +2.0)))
+
+ (def: .public (<inverse> it)
+ (-> Frac Frac)
+ (|> +2.0 ("lux f64 /" (|> (..exp it) (<comp> (..exp ("lux f64 *" -1.0 it)))))))]
+
+ [sinh "lux f64 -" csch]
+ [cosh "lux f64 +" sech]
+ )
+
+(template [<name> <top> <bottom>]
+ [(def: .public (<name> it)
+ (-> Frac Frac)
+ (let [e+ (exp it)
+ e- (exp ("lux f64 *" -1.0 it))
+ sinh' (|> e+ ("lux f64 -" e-))
+ cosh' (|> e+ ("lux f64 +" e-))]
+ (|> <top> ("lux f64 /" <bottom>))))]
+
+ [tanh sinh' cosh']
+ [coth cosh' sinh']
+ )
+
+... https://en.wikipedia.org/wiki/Inverse_hyperbolic_functions#Definitions_in_terms_of_logarithms
+(template [<name> <comp>]
+ [(def: .public (<name> it)
+ (-> Frac Frac)
+ (|> it (pow +2.0) (<comp> +1.0) (pow +0.5) ("lux f64 +" it) log))]
+
+ [asinh "lux f64 +"]
+ [acosh "lux f64 -"]
+ )
+
+(template [<name> <base> <diff>]
+ [(def: .public (<name> it)
+ (-> Frac Frac)
+ (let [it+ (|> <base> ("lux f64 +" <diff>))
+ it- (|> <base> ("lux f64 -" <diff>))]
+ (|> it+ ("lux f64 /" it-) log ("lux f64 /" +2.0))))]
+
+ [atanh +1.0 it]
+ [acoth it +1.0]
+ )
+
+(template [<name> <op>]
+ [(def: .public (<name> it)
+ (-> Frac Frac)
+ (let [it^2 (|> it (pow +2.0))]
+ (|> +1.0 (<op> it^2) (pow +0.5) ("lux f64 +" +1.0) ("lux f64 /" it) log)))]
+
+ [asech "lux f64 -"]
+ [acsch "lux f64 +"]
+ )
+
+(template [<name> <op>]
+ [(def: .public (<name> param subject)
+ (-> Frac Frac Bit)
+ (<op> param subject))]
+
+ [= "lux f64 ="]
+ [< "lux f64 <"]
+ )
(def: .public (<= reference sample)
(-> Frac Frac Bit)
@@ -167,13 +573,13 @@
(def: .public smallest
Frac
- (///.pow (//int.frac (//int.- (.int ..mantissa_size) ..min_exponent))
- +2.0))
+ (..pow (//int.frac (//int.- (.int ..mantissa_size) ..min_exponent))
+ +2.0))
(def: .public biggest
Frac
- (let [f2^-52 (///.pow (//nat.frac (//nat.- ..mantissa_size 0)) +2.0)
- f2^+1023 (///.pow ..max_exponent +2.0)]
+ (let [f2^-52 (..pow (//nat.frac (//nat.- ..mantissa_size 0)) +2.0)
+ f2^+1023 (..pow ..max_exponent +2.0)]
(|> +2.0
(..- f2^-52)
(..* f2^+1023))))
@@ -214,8 +620,8 @@
(def: log/2
(-> Frac Frac)
- (|>> ///.log
- (../ (///.log +2.0))))
+ (|>> ..log
+ (../ (..log +2.0))))
(def: double_bias Nat 1023)
@@ -268,7 +674,7 @@
it (..abs it)
exponent (|> it
..log/2
- ///.floor
+ ..floor
(..min ..max_exponent))
min_gap (..- (//int.frac ..min_exponent) exponent)
power (|> (//nat.frac ..mantissa_size)
@@ -276,9 +682,9 @@
(..- exponent))
max_gap (..- ..max_exponent power)
mantissa (|> it
- (..* (///.pow (..min ..max_exponent power) +2.0))
+ (..* (..pow (..min ..max_exponent power) +2.0))
(..* (if (..> +0.0 max_gap)
- (///.pow max_gap +2.0)
+ (..pow max_gap +2.0)
+1.0)))
exponent_bits (|> (if (..< +0.0 min_gap)
(|> (..int exponent)
@@ -339,7 +745,7 @@
(//int.- (.int ..mantissa_size)))]
[(//i64.one ..mantissa_size M)
(|> E (//nat.- ..double_bias) (//nat.- ..mantissa_size) .int)])
- exponent (///.pow (//int.frac power) +2.0)]
+ exponent (..pow (//int.frac power) +2.0)]
(|> (//nat.frac mantissa)
(..* exponent)
(..* sign)))))
diff --git a/stdlib/source/library/lux/math/number/int.lux b/stdlib/source/library/lux/math/number/int.lux
index 8214514a7..7d8d19fe6 100644
--- a/stdlib/source/library/lux/math/number/int.lux
+++ b/stdlib/source/library/lux/math/number/int.lux
@@ -21,13 +21,14 @@
["[1][0]" nat]
["[1][0]" i64]])
-(def: .public (= reference sample)
- (-> Int Int Bit)
- ("lux i64 =" reference sample))
+(template [<name> <op>]
+ [(def: .public (<name> param subject)
+ (-> Int Int Bit)
+ (<op> param subject))]
-(def: .public (< reference sample)
- (-> Int Int Bit)
- ("lux i64 <" reference sample))
+ [= "lux i64 ="]
+ [< "lux i64 <"]
+ )
(def: .public (<= reference sample)
(-> Int Int Bit)
@@ -55,27 +56,27 @@
[..= zero?]
)
-(template [<name> <test> <doc>]
+(template [<name> <test>]
[(def: .public (<name> left right)
(-> Int Int Int)
(if (<test> right left)
left
right))]
- [min ..< "Int(eger) minimum."]
- [max ..> "Int(eger) maximum."]
+ [min ..<]
+ [max ..>]
)
-(template [<name> <op> <doc>]
+(template [<name> <op>]
[(def: .public (<name> param subject)
(-> Int Int Int)
(<op> param subject))]
- [+ "lux i64 +" "Int(eger) addition."]
- [- "lux i64 -" "Int(eger) substraction."]
- [* "lux i64 *" "Int(eger) multiplication."]
- [/ "lux i64 /" "Int(eger) division."]
- [% "lux i64 %" "Int(eger) remainder."]
+ [+ "lux i64 +"]
+ [- "lux i64 -"]
+ [* "lux i64 *"]
+ [/ "lux i64 /"]
+ [% "lux i64 %"]
)
(def: .public (/% param subject)
diff --git a/stdlib/source/library/lux/math/number/nat.lux b/stdlib/source/library/lux/math/number/nat.lux
index c52647e32..9ead2ee82 100644
--- a/stdlib/source/library/lux/math/number/nat.lux
+++ b/stdlib/source/library/lux/math/number/nat.lux
@@ -49,9 +49,8 @@
(def: .public (<= reference sample)
(-> Nat Nat Bit)
- (if (..< reference sample)
- #1
- ("lux i64 =" reference sample)))
+ (or (..< reference sample)
+ ("lux i64 =" reference sample)))
(def: .public (> reference sample)
(-> Nat Nat Bit)
@@ -59,9 +58,8 @@
(def: .public (>= reference sample)
(-> Nat Nat Bit)
- (if (..< sample reference)
- #1
- ("lux i64 =" reference sample)))
+ (or (..< sample reference)
+ ("lux i64 =" reference sample)))
(template [<name> <test>]
[(def: .public (<name> left right)
diff --git a/stdlib/source/library/lux/math/number/rev.lux b/stdlib/source/library/lux/math/number/rev.lux
index 8b5e28996..f00cc8dd7 100644
--- a/stdlib/source/library/lux/math/number/rev.lux
+++ b/stdlib/source/library/lux/math/number/rev.lux
@@ -53,9 +53,8 @@
(def: .public (<= reference sample)
(-> Rev Rev Bit)
- (if (//nat.< (.nat reference) (.nat sample))
- true
- ("lux i64 =" reference sample)))
+ (or (//nat.< (.nat reference) (.nat sample))
+ ("lux i64 =" reference sample)))
(def: .public (> reference sample)
(-> Rev Rev Bit)
@@ -63,9 +62,8 @@
(def: .public (>= reference sample)
(-> Rev Rev Bit)
- (if (..< sample reference)
- true
- ("lux i64 =" reference sample)))
+ (or (..< sample reference)
+ ("lux i64 =" reference sample)))
(template [<name> <test>]
[(def: .public (<name> left right)
diff --git a/stdlib/source/library/lux/static.lux b/stdlib/source/library/lux/static.lux
index e8d213dd8..e4ccd2c3c 100644
--- a/stdlib/source/library/lux/static.lux
+++ b/stdlib/source/library/lux/static.lux
@@ -1,7 +1,7 @@
(.using
[library
[lux {"-" nat int rev if cond}
- ["[0]" meta]
+ ["[0]" meta ("[1]#[0]" functor)]
[abstract
[monad {"+" do}]]
[control
@@ -57,6 +57,9 @@
.let [[format expression] (:as <type> pair)]]
(in (list#each format expression)))))
+(syntax: .public (seed [])
+ (meta#each (|>> code.nat list) meta.seed))
+
(template [<name> <random> <format>]
[(syntax: .public (<name> [])
(do meta.monad
@@ -117,3 +120,11 @@
(~ else))))
else
(list.reversed test,then/*)))))
+
+(syntax: .public (when [test <code>.any
+ then <code>.any])
+ (do meta.monad
+ [test (meta.eval .Bit test)]
+ (in (.if (:as .Bit test)
+ (list then)
+ (list)))))
diff --git a/stdlib/source/program/aedifex/command/build.lux b/stdlib/source/program/aedifex/command/build.lux
index a8a5ffbc1..b9211ceb0 100644
--- a/stdlib/source/program/aedifex/command/build.lux
+++ b/stdlib/source/program/aedifex/command/build.lux
@@ -269,7 +269,8 @@
_
(revised ///runtime.#parameters
- (|>> (list& "-cp" (..jvm_class_path host_dependencies)))
+ (|>> (list& "-cp" (..jvm_class_path host_dependencies)
+ "--add-opens" "java.base/java.lang=ALL-UNNAMED"))
runtime)))
(def: .public (do! console program fs shell resolution)
diff --git a/stdlib/source/program/aedifex/runtime.lux b/stdlib/source/program/aedifex/runtime.lux
index 9179dc2e8..57d18d265 100644
--- a/stdlib/source/program/aedifex/runtime.lux
+++ b/stdlib/source/program/aedifex/runtime.lux
@@ -21,9 +21,10 @@
(def: .public equivalence
(Equivalence Runtime)
- (product.equivalence
- text.equivalence
- (list.equivalence text.equivalence)))
+ ($_ product.equivalence
+ text.equivalence
+ (list.equivalence text.equivalence)
+ ))
(template [<name> <command> <parameters>]
[(def: .public <name>
@@ -31,7 +32,7 @@
[#program <command>
#parameters (`` (list (~~ (template.spliced <parameters>))))])]
- [default_java "java" ["-jar" "--add-opens" "java.base/java.lang=ALL-UNNAMED"]]
+ [default_java "java" ["--add-opens" "java.base/java.lang=ALL-UNNAMED" "-jar"]]
[default_js "node" ["--stack_size=8192"]]
[default_python "python3" []]
[default_lua "lua" []]
diff --git a/stdlib/source/test/lux/data/color.lux b/stdlib/source/test/lux/data/color.lux
index 8df8e5813..a8b175c3a 100644
--- a/stdlib/source/test/lux/data/color.lux
+++ b/stdlib/source/test/lux/data/color.lux
@@ -11,15 +11,13 @@
[data
[collection
["[0]" list]]]
- [macro
- ["[0]" template]]
- ["[0]" math
+ [math
["[0]" random {"+" Random}]
[number
["n" nat]
- ["[0]" int]
["f" frac]
- ["r" rev]]]]]
+ ["r" rev]
+ ["[0]" int]]]]]
[\\library
["[0]" /]])
@@ -34,11 +32,11 @@
(def: square
(-> Frac Frac)
- (math.pow +2.0))
+ (f.pow +2.0))
(def: square_root
(-> Frac Frac)
- (math.pow +0.5))
+ (f.pow +0.5))
(def: (distance/1 from to)
(-> Frac Frac Frac)
diff --git a/stdlib/source/test/lux/math.lux b/stdlib/source/test/lux/math.lux
index aeadbf093..6b5c9749e 100644
--- a/stdlib/source/test/lux/math.lux
+++ b/stdlib/source/test/lux/math.lux
@@ -4,6 +4,8 @@
["_" test {"+" Test}]
[abstract
[monad {"+" do}]]
+ [data
+ ["[0]" bit ("[1]#[0]" equivalence)]]
[macro
["[0]" template]]
[math
@@ -11,7 +13,10 @@
[number
["n" nat]
["i" int]
- ["f" frac]]]]]
+ ["r" rev]
+ ["f" frac]
+ ["[0]" ratio {"+" Ratio}]
+ ["[0]" complex {"+" Complex}]]]]]
[\\library
["[0]" /]]
["[0]" / "_"
@@ -23,152 +28,117 @@
["[1]/[0]" continuous]
["[1]/[0]" fuzzy]]])
-(def: margin_of_error
- +0.0000001)
+(def: ratio/0
+ Ratio
+ [ratio.#numerator 0 ratio.#denominator 1])
-(def: (trigonometric_symmetry forward backward angle)
- (-> (-> Frac Frac) (-> Frac Frac) Frac Bit)
- (let [normal (|> angle forward backward)]
- (|> normal forward backward (f.approximately? ..margin_of_error normal))))
+(def: complex/0
+ Complex
+ [complex.#real +0.0 complex.#imaginary +0.0])
(def: .public test
Test
(<| (_.covering /._)
- ($_ _.and
- (do [! random.monad]
- [.let [~= (f.approximately? ..margin_of_error)]
- angle (|> random.safe_frac (# ! each (f.* /.tau)))]
- ($_ _.and
- (_.cover [/.sin /.asin]
- (trigonometric_symmetry /.sin /.asin angle))
- (_.cover [/.cos /.acos]
- (trigonometric_symmetry /.cos /.acos angle))
- (_.cover [/.tan /.atan]
- (trigonometric_symmetry /.tan /.atan angle))
- (_.cover [/.tau]
- (and (and (~= +0.0 (/.sin /.tau))
- (~= +1.0 (/.cos /.tau)))
- (and (~= +0.0 (/.sin (f./ +2.0 /.tau)))
- (~= -1.0 (/.cos (f./ +2.0 /.tau))))
- (and (~= +1.0 (/.sin (f./ +4.0 /.tau)))
- (~= +0.0 (/.cos (f./ +4.0 /.tau))))
- (and (~= -1.0 (/.sin (f.* +3.0 (f./ +4.0 /.tau))))
- (~= +0.0 (/.cos (f.* +3.0 (f./ +4.0 /.tau)))))
- (let [x2+y2 (f.+ (/.pow +2.0 (/.sin angle))
- (/.pow +2.0 (/.cos angle)))]
- (~= +1.0 x2+y2))))
- (_.cover [/.pi]
- (~= (f./ +2.0 /.tau) /.pi))
- ))
- (do [! random.monad]
- [sample (|> random.safe_frac (# ! each (f.* +1000.0)))]
- ($_ _.and
- (_.cover [/.ceil]
- (let [ceil'd (/.ceil sample)]
- (and (|> ceil'd f.int i.frac (f.= ceil'd))
- (f.>= sample ceil'd)
- (f.<= +1.0 (f.- sample ceil'd)))))
- (_.cover [/.floor]
- (let [floor'd (/.floor sample)]
- (and (|> floor'd f.int i.frac (f.= floor'd))
- (f.<= sample floor'd)
- (f.<= +1.0 (f.- floor'd sample)))))
- (_.cover [/.round]
- (let [round'd (/.round sample)]
- (and (|> round'd f.int i.frac (f.= round'd))
- (f.<= +1.0 (f.abs (f.- sample round'd))))))
- (_.cover [/.root/2]
- (let [sample (f.abs sample)]
- (|> sample
- /.root/2
- (/.pow +2.0)
- (f.approximately? ..margin_of_error sample))))
- (_.cover [/.root/3]
- (|> sample
- /.root/3
- (/.pow +3.0)
- (f.approximately? ..margin_of_error sample)))
- ))
- (do [! random.monad]
- [.let [~= (f.approximately? ..margin_of_error)]
- sample (# ! each (f.* +10.0) random.safe_frac)
- power (# ! each (|>> (n.% 10) ++ n.frac) random.nat)]
- ($_ _.and
- (_.cover [/.exp /.log]
- (|> sample /.exp /.log (f.approximately? +0.000000000000001 sample)))
- (_.cover [/.e]
- (~= +1.0 (/.log /.e)))
- (_.cover [/.pow /.log_by]
- (let [sample (f.abs sample)]
- (|> sample
- (/.pow power)
- (/.log_by sample)
- (~= power))))
- ))
- (do [! random.monad]
- [.let [~= (f.approximately? ..margin_of_error)]
- angle (# ! each (f.* /.tau) random.safe_frac)
- sample (# ! each f.abs random.safe_frac)
- big (# ! each (f.* +1,000,000,000.00) random.safe_frac)]
- (template.let [(odd! <function>)
- [(_.cover [<function>]
- (~= (f.opposite (<function> angle))
- (<function> (f.opposite angle))))]
+ (do random.monad
+ [parameterN (random.only (|>> (n.= 0) not) random.nat)
+ subjectN random.nat
- (even! <function>)
- [(_.cover [<function>]
- (~= (<function> angle)
- (<function> (f.opposite angle))))]
+ parameterI (random.only (|>> (i.= +0) not) random.int)
+ subjectI random.int
- (inverse! <left> <right> <input>)
- [(_.cover [<left> <right>]
- (~= (<right> <input>)
- (<left> (f./ <input> +1.0))))]]
- ($_ _.and
- (odd! /.sinh)
- (even! /.cosh)
- (odd! /.tanh)
- (odd! /.coth)
- (even! /.sech)
- (odd! /.csch)
+ parameterR (random.only (|>> (r.= .0) not) random.rev)
+ subjectR random.rev
- (inverse! /.acosh /.asech sample)
- (inverse! /.asinh /.acsch sample)
- (inverse! /.atanh /.acoth big)
- )))
- (do [! random.monad]
- [x (# ! each (|>> (f.* +10.0) f.abs) random.safe_frac)
- y (# ! each (|>> (f.* +10.0) f.abs) random.safe_frac)]
- (_.cover [/.hypotenuse]
- (let [h (/.hypotenuse x y)]
- (and (f.>= x h)
- (f.>= y h)))))
- (do [! random.monad]
- [.let [~= (f.approximately? ..margin_of_error)
- tau/4 (f./ +4.0 /.tau)]
- x (# ! each (f.* tau/4) random.safe_frac)
- y (# ! each (f.* tau/4) random.safe_frac)]
- (_.cover [/.atan/2]
- (let [expected (/.atan/2 x y)
- actual (if (f.> +0.0 x)
- (/.atan (f./ x y))
- (if (f.< +0.0 y)
- (f.- /.pi (/.atan (f./ x y)))
- (f.+ /.pi (/.atan (f./ x y)))))]
- (and (~= expected actual)
- (~= tau/4 (/.atan/2 +0.0 (f.abs y)))
- (~= (f.opposite tau/4) (/.atan/2 +0.0 (f.opposite (f.abs y))))
- (f.not_a_number? (/.atan/2 +0.0 +0.0))))))
- (do [! random.monad]
- [of (# ! each (|>> (n.% 10) ++) random.nat)]
- (_.cover [/.factorial]
- (and (n.= 1 (/.factorial 0))
- (|> (/.factorial of) (n.% of) (n.= 0)))))
+ parameterF (random.only (|>> (f.= +0.0) not) random.safe_frac)
+ subjectF random.safe_frac
- /infix.test
- /modulus.test
- /modular.test
- /number.test
- /logic/continuous.test
- /logic/fuzzy.test
- )))
+ parameter/ (random.only (|>> (ratio.= ratio/0) not) random.ratio)
+ subject/ random.ratio
+
+ parameterC (random.only (|>> (complex.= complex/0) not) random.complex)
+ subjectC random.complex])
+ (`` ($_ _.and
+ (~~ (template [</> <scenarios>']
+ [(_.cover [</>]
+ (with_expansions [<scenarios> (template.spliced <scenarios>')]
+ (`` (and (~~ (template [<=> <//> <parameter> <subject>]
+ [(<=> (<//> <parameter> <subject>)
+ (</> <parameter> <subject>))]
+
+ <scenarios>))))))]
+
+ [/.+ [[n.= n.+ parameterN subjectN]
+ [i.= i.+ parameterI subjectI]
+ [r.= r.+ parameterR subjectR]
+ [f.= f.+ parameterF subjectF]
+ [ratio.= ratio.+ parameter/ subject/]
+ [complex.= complex.+ parameterC subjectC]]]
+ [/.- [[n.= n.- parameterN subjectN]
+ [i.= i.- parameterI subjectI]
+ [r.= r.- parameterR subjectR]
+ [f.= f.- parameterF subjectF]
+ [ratio.= ratio.- parameter/ subject/]
+ [complex.= complex.- parameterC subjectC]]]
+ [/.* [[n.= n.* parameterN subjectN]
+ [i.= i.* parameterI subjectI]
+ [r.= r.* parameterR subjectR]
+ [f.= f.* parameterF subjectF]
+ [ratio.= ratio.* parameter/ subject/]
+ [complex.= complex.* parameterC subjectC]]]
+ [/./ [[n.= n./ parameterN subjectN]
+ [i.= i./ parameterI subjectI]
+ [r.= r./ parameterR subjectR]
+ [f.= f./ parameterF subjectF]
+ [ratio.= ratio./ parameter/ subject/]
+ [complex.= complex./ parameterC subjectC]]]
+ [/.% [[n.= n.% parameterN subjectN]
+ [i.= i.% parameterI subjectI]
+ [r.= r.% parameterR subjectR]
+ [f.= f.% parameterF subjectF]
+ [ratio.= ratio.% parameter/ subject/]
+ [complex.= complex.% parameterC subjectC]]]
+ ))
+ (~~ (template [</> <scenarios>']
+ [(_.cover [</>]
+ (with_expansions [<scenarios> (template.spliced <scenarios>')]
+ (`` (and (~~ (template [<//> <parameter> <subject>]
+ [(bit#= (<//> <parameter> <subject>)
+ (</> <parameter> <subject>))]
+
+ <scenarios>))))))]
+
+ [/.= [[n.= parameterN subjectN]
+ [i.= parameterI subjectI]
+ [r.= parameterR subjectR]
+ [f.= parameterF subjectF]
+ [ratio.= parameter/ subject/]
+ [complex.= parameterC subjectC]]]
+ [/.< [[n.< parameterN subjectN]
+ [i.< parameterI subjectI]
+ [r.< parameterR subjectR]
+ [f.< parameterF subjectF]
+ [ratio.< parameter/ subject/]]]
+ [/.<= [[n.<= parameterN subjectN]
+ [i.<= parameterI subjectI]
+ [r.<= parameterR subjectR]
+ [f.<= parameterF subjectF]
+ [ratio.<= parameter/ subject/]]]
+ [/.> [[n.> parameterN subjectN]
+ [i.> parameterI subjectI]
+ [r.> parameterR subjectR]
+ [f.> parameterF subjectF]
+ [ratio.> parameter/ subject/]]]
+ [/.>= [[n.>= parameterN subjectN]
+ [i.>= parameterI subjectI]
+ [r.>= parameterR subjectR]
+ [f.>= parameterF subjectF]
+ [ratio.>= parameter/ subject/]]]
+ ))
+
+ /infix.test
+ /modulus.test
+ /modular.test
+ /number.test
+ /logic/continuous.test
+ /logic/fuzzy.test
+ ))))
diff --git a/stdlib/source/test/lux/math/infix.lux b/stdlib/source/test/lux/math/infix.lux
index f52e6dd5f..709a24b0b 100644
--- a/stdlib/source/test/lux/math/infix.lux
+++ b/stdlib/source/test/lux/math/infix.lux
@@ -1,19 +1,18 @@
(.using
- [library
- [lux "*"
- ["_" test {"+" Test}]
- [abstract
- [monad {"+" do}]]
- [data
- ["[0]" bit ("[1]#[0]" equivalence)]]
- [math
- ["[0]" random]
- [number
- ["n" nat]
- ["f" frac]]]]]
- [\\library
- ["[0]" /
- ["[0]" //]]])
+ [library
+ [lux "*"
+ ["_" test {"+" Test}]
+ [abstract
+ [monad {"+" do}]]
+ [data
+ ["[0]" bit ("[1]#[0]" equivalence)]]
+ [math
+ ["[0]" random]
+ [number
+ ["n" nat]
+ ["f" frac]]]]]
+ [\\library
+ ["[0]" /]])
(def: .public test
Test
@@ -30,8 +29,8 @@
(/.infix subject))
unary_functions!
- (f.= (//.sin angle)
- (/.infix [//.sin angle]))
+ (f.= (f.sin angle)
+ (/.infix [f.sin angle]))
binary_functions!
(n.= (n.gcd parameter subject)
diff --git a/stdlib/source/test/lux/math/number/complex.lux b/stdlib/source/test/lux/math/number/complex.lux
index 53b8982a2..bfee3adcc 100644
--- a/stdlib/source/test/lux/math/number/complex.lux
+++ b/stdlib/source/test/lux/math/number/complex.lux
@@ -1,18 +1,15 @@
(.using
[library
[lux "*"
- ["%" data/text/format {"+" format}]
["_" test {"+" Test}]
[abstract
[monad {"+" do}]
[\\specification
- ["$[0]" equivalence]
- ["$[0]" order]
- ["$[0]" codec]]]
+ ["$[0]" equivalence]]]
[data
[collection
["[0]" list ("[1]#[0]" functor)]]]
- ["[0]" math
+ [math
["[0]" random {"+" Random}]]]]
[\\library
["[0]" /
@@ -161,8 +158,8 @@
(let [rem (/.% y x)
quotient (|> x (/.- rem) (/./ y))
floored (|> quotient
- (revised /.#real math.floor)
- (revised /.#imaginary math.floor))]
+ (revised /.#real f.floor)
+ (revised /.#imaginary f.floor))]
(/.approximately? +0.000000000001
x
(|> quotient (/.* y) (/.+ rem)))))
@@ -192,7 +189,7 @@
(let [signum_abs (|> x /.signum /.abs)]
(or (f.= +0.0 signum_abs)
(f.= +1.0 signum_abs)
- (f.= (math.pow +0.5 +2.0) signum_abs))))
+ (f.= (f.pow +0.5 +2.0) signum_abs))))
(_.cover [/.opposite]
(let [own_inverse!
(let [there (/.opposite x)
diff --git a/stdlib/source/test/lux/math/number/frac.lux b/stdlib/source/test/lux/math/number/frac.lux
index f78b23afd..77453c6f2 100644
--- a/stdlib/source/test/lux/math/number/frac.lux
+++ b/stdlib/source/test/lux/math/number/frac.lux
@@ -14,6 +14,8 @@
["$[0]" codec]]]
[data
["[0]" bit ("[1]#[0]" equivalence)]]
+ [macro
+ ["[0]" template]]
[math
["[0]" random {"+" Random}]]]]
[\\library
@@ -126,6 +128,148 @@
@.jvm (as_is <jvm>)
(as_is)))
+(def: margin_of_error
+ +0.0000001)
+
+(def: (trigonometric_symmetry forward backward angle)
+ (-> (-> Frac Frac) (-> Frac Frac) Frac Bit)
+ (let [normal (|> angle forward backward)]
+ (|> normal forward backward (/.approximately? ..margin_of_error normal))))
+
+(def: test|math
+ Test
+ ($_ _.and
+ (do [! random.monad]
+ [.let [~= (/.approximately? ..margin_of_error)]
+ angle (|> random.safe_frac (# ! each (/.* /.tau)))]
+ ($_ _.and
+ (_.cover [/.sin /.asin]
+ (trigonometric_symmetry /.sin /.asin angle))
+ (_.cover [/.cos /.acos]
+ (trigonometric_symmetry /.cos /.acos angle))
+ (_.cover [/.tan /.atan]
+ (trigonometric_symmetry /.tan /.atan angle))
+ (_.cover [/.tau]
+ (and (and (~= +0.0 (/.sin /.tau))
+ (~= +1.0 (/.cos /.tau)))
+ (and (~= +0.0 (/.sin (/./ +2.0 /.tau)))
+ (~= -1.0 (/.cos (/./ +2.0 /.tau))))
+ (and (~= +1.0 (/.sin (/./ +4.0 /.tau)))
+ (~= +0.0 (/.cos (/./ +4.0 /.tau))))
+ (and (~= -1.0 (/.sin (/.* +3.0 (/./ +4.0 /.tau))))
+ (~= +0.0 (/.cos (/.* +3.0 (/./ +4.0 /.tau)))))
+ (let [x2+y2 (/.+ (/.pow +2.0 (/.sin angle))
+ (/.pow +2.0 (/.cos angle)))]
+ (~= +1.0 x2+y2))))
+ (_.cover [/.pi]
+ (~= (/./ +2.0 /.tau) /.pi))
+ ))
+ (do [! random.monad]
+ [sample (|> random.safe_frac (# ! each (/.* +1000.0)))]
+ ($_ _.and
+ (_.cover [/.ceil]
+ (let [ceil'd (/.ceil sample)]
+ (and (|> ceil'd /.int i.frac (/.= ceil'd))
+ (/.>= sample ceil'd)
+ (/.<= +1.0 (/.- sample ceil'd)))))
+ (_.cover [/.floor]
+ (let [floor'd (/.floor sample)]
+ (and (|> floor'd /.int i.frac (/.= floor'd))
+ (/.<= sample floor'd)
+ (/.<= +1.0 (/.- floor'd sample)))))
+ (_.cover [/.round]
+ (let [round'd (/.round sample)]
+ (and (|> round'd /.int i.frac (/.= round'd))
+ (/.<= +1.0 (/.abs (/.- sample round'd))))))
+ (_.cover [/.root/2]
+ (let [sample (/.abs sample)]
+ (|> sample
+ /.root/2
+ (/.pow +2.0)
+ (/.approximately? ..margin_of_error sample))))
+ (_.cover [/.root/3]
+ (|> sample
+ /.root/3
+ (/.pow +3.0)
+ (/.approximately? ..margin_of_error sample)))
+ ))
+ (do [! random.monad]
+ [.let [~= (/.approximately? ..margin_of_error)]
+ sample (# ! each (/.* +10.0) random.safe_frac)
+ power (# ! each (|>> (n.% 10) ++ n.frac) random.nat)]
+ ($_ _.and
+ (_.cover [/.exp /.log]
+ (|> sample /.exp /.log (/.approximately? +0.000000000000001 sample)))
+ (_.cover [/.e]
+ (~= +1.0 (/.log /.e)))
+ (_.cover [/.pow /.log_by]
+ (let [sample (/.abs sample)]
+ (|> sample
+ (/.pow power)
+ (/.log_by sample)
+ (~= power))))
+ ))
+ (do [! random.monad]
+ [.let [~= (/.approximately? ..margin_of_error)]
+ angle (# ! each (/.* /.tau) random.safe_frac)
+ sample (# ! each /.abs random.safe_frac)
+ big (# ! each (/.* +1,000,000,000.00) random.safe_frac)]
+ (template.let [(odd! <function>)
+ [(_.cover [<function>]
+ (~= (/.opposite (<function> angle))
+ (<function> (/.opposite angle))))]
+
+ (even! <function>)
+ [(_.cover [<function>]
+ (~= (<function> angle)
+ (<function> (/.opposite angle))))]
+
+ (inverse! <left> <right> <input>)
+ [(_.cover [<left> <right>]
+ (~= (<right> <input>)
+ (<left> (/./ <input> +1.0))))]]
+ ($_ _.and
+ (odd! /.sinh)
+ (even! /.cosh)
+ (odd! /.tanh)
+ (odd! /.coth)
+ (even! /.sech)
+ (odd! /.csch)
+
+ (inverse! /.acosh /.asech sample)
+ (inverse! /.asinh /.acsch sample)
+ (inverse! /.atanh /.acoth big)
+ )))
+ (do [! random.monad]
+ [x (# ! each (|>> (/.* +10.0) /.abs) random.safe_frac)
+ y (# ! each (|>> (/.* +10.0) /.abs) random.safe_frac)]
+ (_.cover [/.hypotenuse]
+ (let [h (/.hypotenuse x y)]
+ (and (/.>= x h)
+ (/.>= y h)))))
+ (do [! random.monad]
+ [.let [~= (/.approximately? ..margin_of_error)
+ tau/4 (/./ +4.0 /.tau)]
+ x (# ! each (/.* tau/4) random.safe_frac)
+ y (# ! each (/.* tau/4) random.safe_frac)]
+ (_.cover [/.atan/2]
+ (let [expected (/.atan/2 x y)
+ actual (if (/.> +0.0 x)
+ (/.atan (/./ x y))
+ (if (/.< +0.0 y)
+ (/.- /.pi (/.atan (/./ x y)))
+ (/.+ /.pi (/.atan (/./ x y)))))]
+ (and (~= expected actual)
+ (~= tau/4 (/.atan/2 +0.0 (/.abs y)))
+ (~= (/.opposite tau/4) (/.atan/2 +0.0 (/.opposite (/.abs y))))
+ (/.not_a_number? (/.atan/2 +0.0 +0.0))))))
+ (do [! random.monad]
+ [of (# ! each (|>> (n.% 10) ++) random.nat)]
+ (_.cover [/.factorial]
+ (and (n.= 1 (/.factorial 0))
+ (|> (/.factorial of) (n.% of) (n.= 0)))))
+ ))
+
(def: .public test
Test
(<| (_.covering /._)
@@ -242,4 +386,5 @@
..predicate
..conversion
..signature
+ ..test|math
)))