packages feed

numhask 0.6.0.2 → 0.7.0.0

raw patch · 35 files changed

+2016/−1928 lines, 35 filesdep +QuickCheckdep +doctestdep +numhaskdep ~bifunctorsdep ~mmorphdep ~text

Dependencies added: QuickCheck, doctest, numhask, random

Dependency ranges changed: bifunctors, mmorph, text, transformers

Files

+ ChangeLog.md view
@@ -0,0 +1,23 @@+0.7.0+=====++* GHC 8.10.2 support+* Modules `NumHask.Algebra.Abstract.*` renamed to `NumHask.Algebra.*`+* Renamed `Normed` to `Norm` and added `basis`+* Removed `Metric` and added `distance`+* Added `Direction`, `Polar`, `polar`, `coord`; streamlined `Complex`+* Removed `NumHask.Data.Pair`+* Fixed `FromIntegral` and `FromRational` to work in well with rebindable syntax.+* Added fundeps to `Norm`, `Direction`+* Integrated `NumHask.Algebra.Action` into `NumHask.Algebra.Module`+* Added `atan2`+* Added doctests and laws+* Improved haddocks+* Made (^) a monomorphic `a -> Int -> a` and accept negative Ints++++0.6.0+=====++* GHC 8.10.1 support
numhask.cabal view
@@ -1,10 +1,23 @@ cabal-version: 2.4 name: numhask-version: 0.6.0.2+version: 0.7.0.0 synopsis:-  numeric classes-description:   A numeric class heirarchy.+description:+    This package provides numeric classes alternate to the prelude specified in [haskell98](https://www.haskell.org/onlinereport/standard-prelude.html).+    .+    The numeric class constellation looks somewhat like:+    .+    ![nh](other/nh.svg)+    .+    == Usage+    .+    >>> {-# LANGUAGE NegativeLiterals #-}+    >>> {-# LANGUAGE RebindableSyntax #-}+    >>> import NumHask.Prelude+    .+    See "NumHask" for a detailed overview.+ category:   mathematics homepage:@@ -23,10 +36,16 @@   LICENSE build-type:   Simple+tested-with:+  GHC ==8.8.4+   || ==8.10.2  extra-doc-files:-  other/*.svg,+  other/*.svg++extra-source-files:   readme.md+  ChangeLog.md  source-repository head   type:@@ -38,11 +57,6 @@ library   hs-source-dirs:     src-  default-extensions:-    NoImplicitPrelude-    NegativeLiterals-    OverloadedStrings-    UnicodeSyntax   ghc-options:     -Wall     -Wcompat@@ -52,25 +66,24 @@   build-depends:     base >=4.7 && <5,     protolude >=0.3 && <0.4,-    bifunctors >= 3.2,-    mmorph >= 1.1,-    transformers >= 0.5,-    text >= 1.2+    bifunctors >= 5.5 && < 5.6,+    mmorph >= 1.1 && < 1.2,+    random >= 1.2 && < 1.3,+    transformers >= 0.5 && < 0.6,+    text >= 1.2 && < 1.3,   exposed-modules:-    NumHask.Algebra.Abstract-    NumHask.Algebra.Abstract.Action-    NumHask.Algebra.Abstract.Additive-    NumHask.Algebra.Abstract.Field-    NumHask.Algebra.Abstract.Group-    NumHask.Algebra.Abstract.Lattice-    NumHask.Algebra.Abstract.Module-    NumHask.Algebra.Abstract.Multiplicative-    NumHask.Algebra.Abstract.Ring+    NumHask+    NumHask.Algebra.Additive+    NumHask.Algebra.Field+    NumHask.Algebra.Group+    NumHask.Algebra.Lattice+    NumHask.Algebra.Module+    NumHask.Algebra.Multiplicative+    NumHask.Algebra.Ring     NumHask.Analysis.Metric     NumHask.Data.Complex     NumHask.Data.Integral     NumHask.Data.LogField-    NumHask.Data.Pair     NumHask.Data.Positive     NumHask.Data.Rational     NumHask.Data.Wrapped@@ -78,3 +91,21 @@     NumHask.Prelude   other-modules:   default-language: Haskell2010++test-suite test+  type: exitcode-stdio-1.0+  main-is: test.hs+  hs-source-dirs:+    test+  build-depends:+    QuickCheck >= 2.13 && < 2.15,+    base >=4.7 && <5,+    doctest >= 0.16 && < 0.18,+    numhask,+  default-language: Haskell2010+  ghc-options:+    -Wall+    -Wcompat+    -Wincomplete-record-updates+    -Wincomplete-uni-patterns+    -Wredundant-constraints
− other/field.svg
@@ -1,3 +0,0 @@-<?xml version="1.0" encoding="UTF-8"?>-<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"-    "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg xmlns="http://www.w3.org/2000/svg" height="600.0000" stroke-opacity="1" viewBox="0 0 600 600" font-size="1" width="600.0000" xmlns:xlink="http://www.w3.org/1999/xlink" stroke="rgb(0,0,0)" version="1.1"><defs></defs><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" font-size="7.710100231303007px" stroke="rgb(0,0,0)" stroke-width="1.8087425826099444" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><text dominant-baseline="middle" transform="matrix(1.0000,0.0000,0.0000,1.0000,384.0401,580.7247)" stroke="none" text-anchor="middle">Field</text></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="0.0" opacity="0.3" stroke="rgb(84,84,84)" stroke-width="1.8087425826099444" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 422.5906,600.0000 l -0.0000,-38.5505 h -77.1010 l -0.0000,38.5505 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" font-size="7.710100231303007px" stroke="rgb(0,0,0)" stroke-width="1.8087425826099444" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><text dominant-baseline="middle" transform="matrix(1.0000,0.0000,0.0000,1.0000,348.5736,467.2675)" stroke="none" text-anchor="middle">Ring</text></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="0.0" opacity="0.3" stroke="rgb(84,84,84)" stroke-width="1.8087425826099444" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 387.1241,486.5428 l -0.0000,-38.5505 h -77.1010 l -0.0000,38.5505 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" font-size="7.710100231303007px" stroke="rgb(0,0,0)" stroke-width="1.8087425826099444" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><text dominant-baseline="middle" transform="matrix(1.0000,0.0000,0.0000,1.0000,263.7625,353.8165)" stroke="none" text-anchor="middle">Distributive</text></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="0.0" opacity="0.3" stroke="rgb(84,84,84)" stroke-width="1.8087425826099444" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 302.3130,373.0918 l -0.0000,-38.5505 h -77.1010 l -0.0000,38.5505 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" font-size="7.710100231303007px" stroke="rgb(0,0,0)" stroke-width="1.8087425826099444" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><text dominant-baseline="middle" transform="matrix(1.0000,0.0000,0.0000,1.0000,431.8427,353.8165)" stroke="none" text-anchor="middle">Divisive</text></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="0.0" opacity="0.3" stroke="rgb(84,84,84)" stroke-width="1.8087425826099444" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 470.3932,373.0918 l -0.0000,-38.5505 h -77.1010 l -0.0000,38.5505 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" font-size="7.710100231303007px" stroke="rgb(0,0,0)" stroke-width="1.8087425826099444" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><text dominant-baseline="middle" transform="matrix(1.0000,0.0000,0.0000,1.0000,348.5736,241.3261)" stroke="none" text-anchor="middle">Multiplicative</text></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="0.0" opacity="0.3" stroke="rgb(84,84,84)" stroke-width="1.8087425826099444" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 387.1241,260.6014 l -0.0000,-38.5505 h -77.1010 l -0.0000,38.5505 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" font-size="7.710100231303007px" stroke="rgb(0,0,0)" stroke-width="1.8087425826099444" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><text dominant-baseline="middle" transform="matrix(1.0000,0.0000,0.0000,1.0000,348.5736,353.8165)" stroke="none" text-anchor="middle">Subtractive</text></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="0.0" opacity="0.3" stroke="rgb(84,84,84)" stroke-width="1.8087425826099444" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 387.1241,373.0918 l -0.0000,-38.5505 h -77.1010 l -0.0000,38.5505 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" font-size="7.710100231303007px" stroke="rgb(0,0,0)" stroke-width="1.8087425826099444" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><text dominant-baseline="middle" transform="matrix(1.0000,0.0000,0.0000,1.0000,265.3045,241.3261)" stroke="none" text-anchor="middle">Additive</text></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="0.0" opacity="0.3" stroke="rgb(84,84,84)" stroke-width="1.8087425826099444" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 303.8551,260.6014 l -0.0000,-38.5505 h -77.1010 l -0.0000,38.5505 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" font-size="7.710100231303007px" stroke="rgb(0,0,0)" stroke-width="1.8087425826099444" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><text dominant-baseline="middle" transform="matrix(1.0000,0.0000,0.0000,1.0000,168.1573,241.3261)" stroke="none" text-anchor="middle">Absorbing</text></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="0.0" opacity="0.3" stroke="rgb(84,84,84)" stroke-width="1.8087425826099444" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 206.7078,260.6014 l -0.0000,-38.5505 h -77.1010 l -0.0000,38.5505 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" font-size="7.710100231303007px" stroke="rgb(0,0,0)" stroke-width="1.8087425826099444" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><text dominant-baseline="middle" transform="matrix(1.0000,0.0000,0.0000,1.0000,431.8427,241.3261)" stroke="none" text-anchor="middle">Invertible</text></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="0.0" opacity="0.3" stroke="rgb(84,84,84)" stroke-width="1.8087425826099444" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 470.3932,260.6014 l -0.0000,-38.5505 h -77.1010 l -0.0000,38.5505 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" font-size="7.710100231303007px" stroke="rgb(0,0,0)" stroke-width="1.8087425826099444" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><text dominant-baseline="middle" transform="matrix(1.0000,0.0000,0.0000,1.0000,376.3300,130.3007)" stroke="none" text-anchor="middle">Commutative</text></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="0.0" opacity="0.3" stroke="rgb(84,84,84)" stroke-width="1.8087425826099444" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 414.8805,149.5759 l -0.0000,-38.5505 h -77.1010 l -0.0000,38.5505 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" font-size="7.710100231303007px" stroke="rgb(0,0,0)" stroke-width="1.8087425826099444" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><text dominant-baseline="middle" transform="matrix(1.0000,0.0000,0.0000,1.0000,293.0609,130.3007)" stroke="none" text-anchor="middle">Associative</text></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="0.0" opacity="0.3" stroke="rgb(84,84,84)" stroke-width="1.8087425826099444" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 331.6114,149.5759 l -0.0000,-38.5505 h -77.1010 l -0.0000,38.5505 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" font-size="7.710100231303007px" stroke="rgb(0,0,0)" stroke-width="1.8087425826099444" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><text dominant-baseline="middle" transform="matrix(1.0000,0.0000,0.0000,1.0000,209.7918,130.3007)" stroke="none" text-anchor="middle">Unital</text></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="0.0" opacity="0.3" stroke="rgb(84,84,84)" stroke-width="1.8087425826099444" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 248.3423,149.5759 l -0.0000,-38.5505 h -77.1010 l -0.0000,38.5505 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" font-size="7.710100231303007px" stroke="rgb(0,0,0)" stroke-width="1.8087425826099444" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><text dominant-baseline="middle" transform="matrix(1.0000,0.0000,0.0000,1.0000,293.0609,19.2753)" stroke="none" text-anchor="middle">Magma</text></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="0.0" opacity="0.3" stroke="rgb(84,84,84)" stroke-width="1.8087425826099444" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 331.6114,38.5505 l -0.0000,-38.5505 h -77.1010 l -0.0000,38.5505 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="0.0" opacity="0.3" stroke="rgb(84,84,84)" stroke-width="1.8087425826099444" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 278.6045,38.5505 l -49.5562,66.0749 "/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.3" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(84,84,84)" stroke-linecap="butt" stroke-miterlimit="10.0"></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.3" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(84,84,84)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 224.2483,111.0254 l 7.8036,-5.4906 l -3.2889,-0.5290 l -1.4288,-3.0092 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.3" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(84,84,84)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 228.7630,105.0058 l 0.2853,-0.3804 l 0.7235,0.5426 l -1.0088,-0.1623 l 0.2853,-0.3804 l -0.7235,-0.5426 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="0.0" opacity="0.3" stroke="rgb(84,84,84)" stroke-width="1.8087425826099444" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 293.0609,38.5505 l 0.0000,64.4749 "/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.3" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(84,84,84)" stroke-linecap="butt" stroke-miterlimit="10.0"></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.3" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(84,84,84)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 293.0609,111.0254 l 2.9485,-9.0747 l -2.9485,1.5501 l -2.9485,-1.5501 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.3" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(84,84,84)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 293.0609,103.5009 l -0.0000,-0.4755 l 0.9044,-0.0000 l -0.9044,0.4755 l -0.0000,-0.4755 l -0.9044,0.0000 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="0.0" opacity="0.3" stroke="rgb(84,84,84)" stroke-width="1.8087425826099444" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 307.5173,38.5505 l 49.5562,66.0749 "/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.3" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(84,84,84)" stroke-linecap="butt" stroke-miterlimit="10.0"></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.3" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(84,84,84)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 361.8736,111.0254 l -3.0860,-9.0289 l -1.4288,3.0092 l -3.2889,0.5290 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.3" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(84,84,84)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 357.3588,105.0058 l -0.2853,-0.3804 l 0.7235,-0.5426 l -0.4382,0.9230 l -0.2853,-0.3804 l -0.7235,0.5426 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="0.0" opacity="0.3" stroke="rgb(84,84,84)" stroke-width="1.8087425826099444" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 305.1079,38.5505 l 110.4477,176.7164 "/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.3" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(84,84,84)" stroke-linecap="butt" stroke-miterlimit="10.0"></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.3" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(84,84,84)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 419.7957,222.0509 l -2.3092,-9.2580 l -1.6788,2.8772 l -3.3219,0.2482 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.3" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(84,84,84)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 415.8077,215.6701 l -0.2520,-0.4032 l 0.7669,-0.4793 l -0.5149,0.8825 l -0.2520,-0.4032 l -0.7669,0.4793 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="0.0" opacity="0.3" stroke="rgb(84,84,84)" stroke-width="1.8087425826099444" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 282.2186,38.5505 l -99.2969,176.5278 "/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.3" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(84,84,84)" stroke-linecap="butt" stroke-miterlimit="10.0"></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.3" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(84,84,84)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 178.9996,222.0509 l 7.0188,-6.4637 l -3.3299,-0.0945 l -1.8099,-2.7966 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.3" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(84,84,84)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 182.6886,215.4927 l 0.2331,-0.4144 l 0.7882,0.4434 l -1.0213,-0.0290 l 0.2331,-0.4144 l -0.7882,-0.4434 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="0.0" opacity="0.5" stroke="rgb(255,0,0)" stroke-width="1.8087425826099444" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 357.0547,149.5759 l -66.8181,66.8181 "/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.5" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(255,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.5" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(255,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 284.5798,222.0509 l 8.5017,-4.3318 l -3.1811,-0.9888 l -0.9888,-3.1811 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.5" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(255,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 289.9005,216.7302 l 0.3362,-0.3362 l 0.6395,0.6395 l -0.9757,-0.3033 l 0.3362,-0.3362 l -0.6395,-0.6395 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="0.0" opacity="0.5" stroke="rgb(255,0,0)" stroke-width="1.8087425826099444" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 219.4295,149.5759 l 32.6598,65.3195 "/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.5" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(255,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.5" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(255,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 255.6669,222.0509 l -1.4211,-9.4353 l -1.9440,2.7051 l -3.3305,-0.0679 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.5" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(255,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 252.3018,215.3207 l -0.2126,-0.4253 l 0.8089,-0.4044 l -0.5963,0.8297 l -0.2126,-0.4253 l -0.8089,0.4044 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="0.0" opacity="0.5" stroke="rgb(255,0,0)" stroke-width="1.8087425826099444" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 288.2421,149.5759 l -16.1785,64.7138 "/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.5" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(255,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.5" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(255,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 270.1234,222.0509 l 5.0614,-8.0886 l -3.2365,0.7887 l -2.4845,-2.2190 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.5" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(255,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 271.9483,214.7510 l 0.1153,-0.4613 l 0.8774,0.2193 l -0.9927,0.2419 l 0.1153,-0.4613 l -0.8774,-0.2193 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="0.0" opacity="0.5" stroke="rgb(255,0,0)" stroke-width="1.8087425826099444" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 417.5745,260.6014 l -49.9730,67.5098 "/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.5" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(255,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.5" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(255,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 362.8418,334.5412 l 7.7690,-5.5395 l -3.2922,-0.5083 l -1.4476,-3.0002 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.5" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(255,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 367.3186,328.4934 l 0.2829,-0.3821 l 0.7269,0.5381 l -1.0098,-0.1559 l 0.2829,-0.3821 l -0.7269,-0.5381 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="0.0" opacity="0.5" stroke="rgb(255,0,0)" stroke-width="1.8087425826099444" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 279.5727,260.6014 l 49.9730,67.5098 "/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.5" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(255,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.5" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(255,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 334.3055,334.5412 l -3.0292,-9.0481 l -1.4476,3.0002 l -3.2922,0.5083 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.5" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(255,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 329.8286,328.4934 l -0.2829,-0.3821 l 0.7269,-0.5381 l -0.4440,0.9202 l -0.2829,-0.3821 l -0.7269,0.5381 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="0.0" opacity="0.5" stroke="rgb(0,0,255)" stroke-width="1.8087425826099444" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 233.8859,149.5759 l 84.3467,67.4774 "/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.5" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(0,0,255)" stroke-linecap="butt" stroke-miterlimit="10.0"></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.5" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(0,0,255)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 324.4796,222.0509 l -5.2442,-7.9713 l -0.6315,3.2708 l -3.0524,1.3341 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.5" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(0,0,255)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 318.6039,217.3503 l -0.3713,-0.2970 l 0.5650,-0.7062 l -0.1937,1.0032 l -0.3713,-0.2970 l -0.5650,0.7062 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="0.0" opacity="0.5" stroke="rgb(0,0,255)" stroke-width="1.8087425826099444" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 302.6985,149.5759 l 32.6598,65.3195 "/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.5" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(0,0,255)" stroke-linecap="butt" stroke-miterlimit="10.0"></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.5" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(0,0,255)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 338.9360,222.0509 l -1.4211,-9.4353 l -1.9440,2.7051 l -3.3305,-0.0679 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.5" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(0,0,255)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 335.5709,215.3207 l -0.2126,-0.4253 l 0.8089,-0.4044 l -0.5963,0.8297 l -0.2126,-0.4253 l -0.8089,0.4044 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="0.0" opacity="0.5" stroke="rgb(0,0,255)" stroke-width="1.8087425826099444" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 371.5112,149.5759 l -16.1785,64.7138 "/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.5" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(0,0,255)" stroke-linecap="butt" stroke-miterlimit="10.0"></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.5" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(0,0,255)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 353.3924,222.0509 l 5.0614,-8.0886 l -3.2365,0.7887 l -2.4845,-2.2190 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.5" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(0,0,255)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 355.2174,214.7510 l 0.1153,-0.4613 l 0.8774,0.2193 l -0.9927,0.2419 l 0.1153,-0.4613 l -0.8774,-0.2193 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="0.0" opacity="0.5" stroke="rgb(0,0,255)" stroke-width="1.8087425826099444" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 431.8427,260.6014 l 0.0000,65.9399 "/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.5" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(0,0,255)" stroke-linecap="butt" stroke-miterlimit="10.0"></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.5" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(0,0,255)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 431.8427,334.5412 l 2.9485,-9.0747 l -2.9485,1.5501 l -2.9485,-1.5501 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.5" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(0,0,255)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 431.8427,327.0167 l -0.0000,-0.4755 l 0.9044,-0.0000 l -0.9044,0.4755 l -0.0000,-0.4755 l -0.9044,0.0000 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="0.0" opacity="0.5" stroke="rgb(0,0,255)" stroke-width="1.8087425826099444" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 362.8418,260.6014 l 49.9730,67.5098 "/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.5" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(0,0,255)" stroke-linecap="butt" stroke-miterlimit="10.0"></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.5" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(0,0,255)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 417.5745,334.5412 l -3.0292,-9.0481 l -1.4476,3.0002 l -3.2922,0.5083 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.5" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(0,0,255)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 413.0977,328.4934 l -0.2829,-0.3821 l 0.7269,-0.5381 l -0.4440,0.9202 l -0.2829,-0.3821 l -0.7269,0.5381 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="0.0" opacity="0.5" stroke="rgb(255,0,0)" stroke-width="1.8087425826099444" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 265.0403,260.6014 l -0.9039,65.9406 "/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.5" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(255,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.5" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(255,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 264.0268,334.5412 l 3.0727,-9.0334 l -2.9695,1.5096 l -2.9270,-1.5904 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.5" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(255,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 264.1299,327.0174 l 0.0065,-0.4754 l 0.9043,0.0124 l -0.9108,0.4630 l 0.0065,-0.4754 l -0.9043,-0.0124 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="0.0" opacity="0.5" stroke="rgb(0,0,255)" stroke-width="1.8087425826099444" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 334.0412,260.6014 l -50.9302,67.5520 "/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.5" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(0,0,255)" stroke-linecap="butt" stroke-miterlimit="10.0"></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.5" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(0,0,255)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 278.2949,334.5412 l 7.8174,-5.4710 l -3.2876,-0.5373 l -1.4212,-3.0128 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.5" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(0,0,255)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 282.8248,328.5330 l 0.2862,-0.3796 l 0.7221,0.5444 l -1.0084,-0.1648 l 0.2862,-0.3796 l -0.7221,-0.5444 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="0.0" opacity="0.3" stroke="rgb(84,84,84)" stroke-width="1.8087425826099444" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 184.5393,260.6014 l 57.6605,67.8440 "/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.3" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(84,84,84)" stroke-linecap="butt" stroke-miterlimit="10.0"></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.3" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(84,84,84)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 247.3805,334.5412 l -3.6301,-8.8242 l -1.2428,3.0907 l -3.2506,0.7283 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.3" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(84,84,84)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 242.5076,328.8077 l -0.3079,-0.3623 l 0.6891,-0.5857 l -0.3812,0.9480 l -0.3079,-0.3623 l -0.6891,0.5857 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="0.0" opacity="0.3" stroke="rgb(84,84,84)" stroke-width="1.8087425826099444" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 278.1719,373.0918 l 51.2024,68.4930 "/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.3" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(84,84,84)" stroke-linecap="butt" stroke-miterlimit="10.0"></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.3" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(84,84,84)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 334.1643,447.9923 l -3.0718,-9.0337 l -1.4335,3.0070 l -3.2897,0.5239 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.3" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(84,84,84)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 329.6590,441.9656 l -0.2847,-0.3808 l 0.7243,-0.5415 l -0.4397,0.9223 l -0.2847,-0.3808 l -0.7243,0.5415 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="0.0" opacity="0.5" stroke="rgb(255,0,0)" stroke-width="1.8087425826099444" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 348.5736,373.0918 l 0.0000,66.9005 "/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.5" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(255,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.5" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(255,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 348.5736,447.9923 l 2.9485,-9.0747 l -2.9485,1.5501 l -2.9485,-1.5501 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.5" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(255,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 348.5736,440.4677 l -0.0000,-0.4755 l 0.9044,-0.0000 l -0.9044,0.4755 l -0.0000,-0.4755 l -0.9044,0.0000 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="0.0" opacity="0.3" stroke="rgb(84,84,84)" stroke-width="1.8087425826099444" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 354.5990,486.5428 l 21.0288,67.2711 "/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.3" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(84,84,84)" stroke-linecap="butt" stroke-miterlimit="10.0"></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.3" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(84,84,84)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 378.0147,561.4495 l 0.1067,-9.5411 l -2.3517,2.3593 l -3.2767,-0.5998 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.3" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(84,84,84)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 375.7697,554.2677 l -0.1419,-0.4538 l 0.8632,-0.2698 l -0.7213,0.7236 l -0.1419,-0.4538 l -0.8632,0.2698 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="0.0" opacity="0.5" stroke="rgb(0,0,255)" stroke-width="1.8087425826099444" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 427.7820,373.0918 l -38.0321,180.5296 "/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.5" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(0,0,255)" stroke-linecap="butt" stroke-miterlimit="10.0"></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.5" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(0,0,255)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 388.1008,561.4495 l 4.7559,-8.2719 l -3.2048,0.9090 l -2.5657,-2.1247 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.5" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(0,0,255)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 389.6519,554.0866 l 0.0980,-0.4652 l 0.8849,0.1864 l -0.9830,0.2788 l 0.0980,-0.4652 l -0.8849,-0.1864 Z"/></g></svg>
+ other/nh.svg view
@@ -0,0 +1,1 @@+<svg xmlns="http://www.w3.org/2000/svg" height="300.0" viewBox="-1.1992055357331681 -0.5225 2.3984110714663363 1.045" width="688.5390635788526" xmlns:xlink="http://www.w3.org/1999/xlink"><g stroke-opacity="1.0" fill-opacity="0.0" stroke="#1f78b4" stroke-width="5.0e-3" fill="#000000"><path d="M -0.2848,-0.413 C -0.2536,-0.373 -0.2075,-0.313 -0.1763,-0.273"/></g><g stroke-opacity="1.0" fill-opacity="0.0" stroke="#1f78b4" stroke-width="5.0e-3" fill="#000000"><path d="M -0.3520,-0.413 C -0.3826,-0.373 -0.4276,-0.313 -0.4581,-0.273"/></g><g stroke-opacity="1.0" fill-opacity="0.0" stroke="#1f78b4" stroke-width="5.0e-3" fill="#000000"><path d="M -0.1311,-0.185 C -0.1207,-0.144 -0.1053,-0.084 -0.0949,-0.044"/></g><g stroke-opacity="1.0" fill-opacity="0.0" stroke="#1f78b4" stroke-width="5.0e-3" fill="#000000"><path d="M -1.0140,-0.414 C -1.0692,-0.383 -1.1338,-0.336 -1.1655,-0.272"/></g><g stroke-opacity="1.0" fill-opacity="0.0" stroke="#1f78b4" stroke-width="5.0e-3" fill="#000000"><path d="M -1.1655,-0.272 C -1.2066,-0.190 -1.1257,-0.097 -1.0667,-0.044"/></g><g stroke-opacity="1.0" fill-opacity="0.0" stroke="#1f78b4" stroke-width="5.0e-3" fill="#000000"><path d="M -0.8372,-0.414 C -0.7612,-0.373 -0.6483,-0.313 -0.5723,-0.272"/></g><g stroke-opacity="1.0" fill-opacity="0.0" stroke="#1f78b4" stroke-width="5.0e-3" fill="#000000"><path d="M -0.9185,-0.413 C -0.9185,-0.373 -0.9185,-0.313 -0.9185,-0.273"/></g><g stroke-opacity="1.0" fill-opacity="0.0" stroke="#1f78b4" stroke-width="5.0e-3" fill="#000000"><path d="M -0.9015,0.028 C -0.7154,0.074 -0.3445,0.166 -0.1770,0.207"/></g><g stroke-opacity="1.0" fill-opacity="0.0" stroke="#1f78b4" stroke-width="5.0e-3" fill="#000000"><path d="M -0.4127,-0.185 C -0.3400,-0.144 -0.2327,-0.084 -0.1606,-0.043"/></g><g stroke-opacity="1.0" fill-opacity="0.0" stroke="#1f78b4" stroke-width="5.0e-3" fill="#000000"><path d="M -0.5072,-0.185 C -0.5217,-0.144 -0.5432,-0.084 -0.5578,-0.044"/></g><g stroke-opacity="1.0" fill-opacity="0.0" stroke="#1f78b4" stroke-width="5.0e-3" fill="#000000"><path d="M -0.0851,0.044 C -0.0865,0.085 -0.0886,0.144 -0.0900,0.185"/></g><g stroke-opacity="1.0" fill-opacity="0.0" stroke="#1f78b4" stroke-width="5.0e-3" fill="#000000"><path d="M -0.0067,0.004 C 0.2507,0.017 1.0704,0.066 1.1472,0.154"/></g><g stroke-opacity="1.0" fill-opacity="0.0" stroke="#1f78b4" stroke-width="5.0e-3" fill="#000000"><path d="M 1.1472,0.154 C 1.1911,0.204 1.1817,0.247 1.1472,0.304"/></g><g stroke-opacity="1.0" fill-opacity="0.0" stroke="#1f78b4" stroke-width="5.0e-3" fill="#000000"><path d="M 1.1472,0.304 C 1.1151,0.356 1.0585,0.392 1.0032,0.415"/></g><g stroke-opacity="1.0" fill-opacity="0.0" stroke="#1f78b4" stroke-width="5.0e-3" fill="#000000"><path d="M -0.0071,0.005 C 0.1543,0.016 0.5396,0.052 0.8454,0.154"/></g><g stroke-opacity="1.0" fill-opacity="0.0" stroke="#1f78b4" stroke-width="5.0e-3" fill="#000000"><path d="M 0.8454,0.154 C 0.8696,0.162 0.8947,0.173 0.9171,0.185"/></g><g stroke-opacity="1.0" fill-opacity="0.0" stroke="#1f78b4" stroke-width="5.0e-3" fill="#000000"><path d="M -0.0066,0.010 C 0.1197,0.029 0.3773,0.074 0.5828,0.154"/></g><g stroke-opacity="1.0" fill-opacity="0.0" stroke="#1f78b4" stroke-width="5.0e-3" fill="#000000"><path d="M 0.5828,0.154 C 0.6045,0.162 0.6271,0.174 0.6473,0.185"/></g><g stroke-opacity="1.0" fill-opacity="0.0" stroke="#1f78b4" stroke-width="5.0e-3" fill="#000000"><path d="M -0.0061,0.021 C 0.0842,0.046 0.2366,0.093 0.3593,0.154"/></g><g stroke-opacity="1.0" fill-opacity="0.0" stroke="#1f78b4" stroke-width="5.0e-3" fill="#000000"><path d="M 0.3593,0.154 C 0.3771,0.163 0.3955,0.174 0.4121,0.185"/></g><g stroke-opacity="1.0" fill-opacity="0.0" stroke="#1f78b4" stroke-width="5.0e-3" fill="#000000"><path d="M -0.0277,0.044 C 0.0237,0.085 0.0994,0.144 0.1507,0.185"/></g><g stroke-opacity="1.0" fill-opacity="0.0" stroke="#1f78b4" stroke-width="5.0e-3" fill="#000000"><path d="M -0.0227,0.272 C -0.0024,0.283 0.0201,0.295 0.0418,0.304"/></g><g stroke-opacity="1.0" fill-opacity="0.0" stroke="#1f78b4" stroke-width="5.0e-3" fill="#000000"><path d="M 0.0418,0.304 C 0.1804,0.358 0.2275,0.331 0.3672,0.382"/></g><g stroke-opacity="1.0" fill-opacity="0.0" stroke="#1f78b4" stroke-width="5.0e-3" fill="#000000"><path d="M 0.3672,0.382 C 0.3905,0.391 0.4150,0.402 0.4372,0.413"/></g><g stroke-opacity="1.0" fill-opacity="0.0" stroke="#1f78b4" stroke-width="5.0e-3" fill="#000000"><path d="M -0.0259,0.272 C -0.0051,0.284 0.0187,0.296 0.0418,0.304"/></g><g stroke-opacity="1.0" fill-opacity="0.0" stroke="#1f78b4" stroke-width="5.0e-3" fill="#000000"><path d="M 0.0418,0.304 C 0.3054,0.391 0.3924,0.313 0.6612,0.382"/></g><g stroke-opacity="1.0" fill-opacity="0.0" stroke="#1f78b4" stroke-width="5.0e-3" fill="#000000"><path d="M 0.6612,0.382 C 0.6918,0.390 0.7241,0.402 0.7532,0.414"/></g><g stroke-opacity="1.0" fill-opacity="0.0" stroke="#1f78b4" stroke-width="5.0e-3" fill="#000000"><path d="M -0.0915,0.273 C -0.0915,0.313 -0.0915,0.373 -0.0915,0.413"/></g><g stroke-opacity="1.0" fill-opacity="0.0" stroke="#1f78b4" stroke-width="5.0e-3" fill="#000000"><path d="M -0.1758,0.272 C -0.2546,0.313 -0.3716,0.373 -0.4504,0.414"/></g><g stroke-opacity="1.0" fill-opacity="0.0" stroke="#1f78b4" stroke-width="5.0e-3" fill="#000000"><path d="M -0.1763,0.242 C -0.3047,0.263 -0.5547,0.310 -0.7578,0.382"/></g><g stroke-opacity="1.0" fill-opacity="0.0" stroke="#1f78b4" stroke-width="5.0e-3" fill="#000000"><path d="M -0.7578,0.382 C -0.7818,0.391 -0.8069,0.402 -0.8297,0.413"/></g><g stroke-opacity="1.0" fill-opacity="0.0" stroke="#1f78b4" stroke-width="5.0e-3" fill="#000000"><path d="M -0.0257,0.273 C 0.0347,0.313 0.1237,0.373 0.1840,0.413"/></g><g stroke-opacity="1.0" fill-opacity="0.0" stroke="#1f78b4" stroke-width="5.0e-3" fill="#000000"><path d="M -0.8520,-0.185 C -0.7910,-0.144 -0.7009,-0.084 -0.6399,-0.044"/></g><g stroke-opacity="0.8" fill-opacity="0.1" stroke="#1f78b4" stroke-width="5.0e-3" fill="#a6cee3"><rect height="8.534662209045607e-2" width="0.22000193566955695" x="-0.428805203927738" y="-0.5"/></g><g stroke-opacity="0.8" fill-opacity="0.1" stroke="#1f78b4" stroke-width="5.0e-3" fill="#a6cee3"><rect height="8.534662209045618e-2" width="0.27107209623570483" x="-0.27794550797302786" y="-0.2713366555226141"/></g><g stroke-opacity="0.8" fill-opacity="0.1" stroke="#1f78b4" stroke-width="5.0e-3" fill="#a6cee3"><rect height="8.534662209045607e-2" width="0.322147913978321" x="-1.0796204322905858" y="-0.5"/></g><g stroke-opacity="0.8" fill-opacity="0.1" stroke="#1f78b4" stroke-width="5.0e-3" fill="#a6cee3"><rect height="8.534662209045629e-2" width="0.22000193566955706" x="-1.1226246571296887" y="-4.26733110452282e-2"/></g><g stroke-opacity="0.8" fill-opacity="0.1" stroke="#1f78b4" stroke-width="5.0e-3" fill="#a6cee3"><rect height="8.534662209045618e-2" width="0.28679056105243594" x="-0.6346744089405665" y="-0.2713366555226141"/></g><g stroke-opacity="0.8" fill-opacity="0.1" stroke="#1f78b4" stroke-width="5.0e-3" fill="#a6cee3"><rect height="8.534662209045629e-2" width="0.15321613887491203" x="-0.16021927054670337" y="-4.26733110452282e-2"/></g><g stroke-opacity="0.8" fill-opacity="0.1" stroke="#1f78b4" stroke-width="5.0e-3" fill="#a6cee3"><rect height="8.534662209045607e-2" width="0.16892894651517532" x="-0.17591544219962563" y="0.18599003343215792"/></g><g stroke-opacity="0.8" fill-opacity="0.1" stroke="#1f78b4" stroke-width="5.0e-3" fill="#a6cee3"><rect height="8.534662209045607e-2" width="0.22000193566955728" x="0.4061300702644397" y="0.41465337790954393"/></g><g stroke-opacity="0.8" fill-opacity="0.1" stroke="#1f78b4" stroke-width="5.0e-3" fill="#a6cee3"><rect height="8.534662209045607e-2" width="0.3064209633968875" x="0.6961106892943665" y="0.41465337790954393"/></g><g stroke-opacity="0.8" fill-opacity="0.1" stroke="#1f78b4" stroke-width="5.0e-3" fill="#a6cee3"><rect height="8.534662209045607e-2" width="0.3732039316032981" x="-0.278052934743687" y="0.41465337790954393"/></g><g stroke-opacity="0.8" fill-opacity="0.1" stroke="#1f78b4" stroke-width="5.0e-3" fill="#a6cee3"><rect height="8.534662209045607e-2" width="0.37320393160329823" x="-0.7209998172963448" y="0.41465337790954393"/></g><g stroke-opacity="0.8" fill-opacity="0.1" stroke="#1f78b4" stroke-width="5.0e-3" fill="#a6cee3"><rect height="8.534662209045607e-2" width="0.2357147433098199" x="-1.0285640791235449" y="0.41465337790954393"/></g><g stroke-opacity="0.8" fill-opacity="0.1" stroke="#1f78b4" stroke-width="5.0e-3" fill="#a6cee3"><rect height="8.534662209045618e-2" width="0.42428823511061653" x="-1.1306905928567335" y="-0.2713366555226141"/></g><g stroke-opacity="0.8" fill-opacity="0.1" stroke="#1f78b4" stroke-width="5.0e-3" fill="#a6cee3"><rect height="8.534662209045629e-2" width="0.18857349180079652" x="-0.6678834365590459" y="-4.26733110452282e-2"/></g><g stroke-opacity="0.8" fill-opacity="0.1" stroke="#1f78b4" stroke-width="5.0e-3" fill="#a6cee3"><rect height="8.534662209045607e-2" width="0.22000193566955728" x="0.8804360241482592" y="0.18599003343215792"/></g><g stroke-opacity="0.8" fill-opacity="0.1" stroke="#1f78b4" stroke-width="5.0e-3" fill="#a6cee3"><rect height="8.534662209045607e-2" width="0.16892894651517443" x="0.16511445852675743" y="0.41465337790954393"/></g><g stroke-opacity="0.8" fill-opacity="0.1" stroke="#1f78b4" stroke-width="5.0e-3" fill="#a6cee3"><rect height="8.534662209045607e-2" width="0.18857349180079686" x="0.6217583719349751" y="0.18599003343215792"/></g><g stroke-opacity="0.8" fill-opacity="0.1" stroke="#1f78b4" stroke-width="5.0e-3" fill="#a6cee3"><rect height="8.534662209045607e-2" width="0.1532161388749118" x="0.39640424558141496" y="0.18599003343215792"/></g><g stroke-opacity="0.8" fill-opacity="0.1" stroke="#1f78b4" stroke-width="5.0e-3" fill="#a6cee3"><rect height="8.534662209045607e-2" width="0.23571474330982012" x="8.860283704908722e-2" y="0.18599003343215792"/></g><g fill-opacity="1.0" font-size="4.0e-2" stroke="none" stroke-width="0.0" fill="#333333" text-anchor="middle"><text x="-0.3188042360929595" y="-0.4494417460417588">Additive</text><text x="-0.1424094598551755" y="-0.22077840156437267">Subtractive</text><text x="-0.9185464753014252" y="-0.4494417460417588">Multiplicative</text><text x="-1.0126236892949103" y="7.884942913013337e-3">Divisive</text><text x="-0.4912791284143482" y="-0.22077840156437267">Distributive</text><text x="-8.361120110924736e-2" y="7.884942913013337e-3">Ring</text><text x="-9.145096894203797e-2" y="0.2365482873903993">Field</text><text x="0.5161310380992183" y="0.4652116318677853">ExpField</text><text x="0.8493211709928097" y="0.4652116318677853">QuotientField</text><text x="-9.145096894203797e-2" y="0.4652116318677853">UpperBoundedField</text><text x="-0.5343978514946957" y="0.4652116318677853">LowerBoundedField</text><text x="-0.9107067074686348" y="0.4652116318677853">TrigField</text><text x="-0.9185464753014252" y="-0.22077840156437267">MultiplicativeAction</text><text x="-0.5735966906586477" y="7.884942913013337e-3">Module</text><text x="0.9904369919830376" y="0.2365482873903993">Integral</text><text x="0.24957893178434443" y="0.4652116318677853">Ratio</text><text x="0.7160451178353733" y="0.2365482873903993">Signed</text><text x="0.4730123150188712" y="0.2365482873903993">Norm</text><text x="0.2064602087039975" y="0.2365482873903993">Direction</text></g></svg>
+ other/nhmagma.svg view
@@ -0,0 +1,2 @@+<svg xmlns="http://www.w3.org/2000/svg" height="300.0" viewBox="-0.6392534367128863 -0.5225 1.2785068734257725 1.045" width="367.03546605524576" xmlns:xlink="http://www.w3.org/1999/xlink"><g stroke-opacity="1.0" fill-opacity="0.0" stroke="#1f78b4" stroke-width="5.0e-3" fill="#000000"><path d="M -0.0604,-0.429 C -0.1040,-0.396 -0.1684,-0.348 -0.2120,-0.315"/></g><g stroke-opacity="1.0" fill-opacity="0.0" stroke="#1f78b4" stroke-width="5.0e-3" fill="#000000"><path d="M -0.0128,-0.429 C -0.0128,-0.396 -0.0128,-0.348 -0.0128,-0.315"/></g><g stroke-opacity="1.0" fill-opacity="0.0" stroke="#1f78b4" stroke-width="5.0e-3" fill="#000000"><path d="M -0.0824,-0.439 C -0.1687,-0.406 -0.3161,-0.351 -0.4123,-0.315"/></g><g stroke-opacity="1.0" fill-opacity="0.0" stroke="#1f78b4" stroke-width="5.0e-3" fill="#000000"><path d="M 0.0570,-0.441 C 0.1482,-0.408 0.3087,-0.351 0.4127,-0.314"/></g><g stroke-opacity="1.0" fill-opacity="0.0" stroke="#1f78b4" stroke-width="5.0e-3" fill="#000000"><path d="M 0.0384,-0.429 C 0.0855,-0.396 0.1549,-0.348 0.2019,-0.315"/></g><g stroke-opacity="1.0" fill-opacity="0.0" stroke="#1f78b4" stroke-width="5.0e-3" fill="#000000"><path d="M -0.2057,-0.243 C -0.1563,-0.210 -0.0836,-0.162 -0.0343,-0.129"/></g><g stroke-opacity="1.0" fill-opacity="0.0" stroke="#1f78b4" stroke-width="5.0e-3" fill="#000000"><path d="M -0.2594,-0.243 C -0.2594,-0.210 -0.2594,-0.162 -0.2594,-0.129"/></g><g stroke-opacity="1.0" fill-opacity="0.0" stroke="#1f78b4" stroke-width="5.0e-3" fill="#000000"><path d="M -0.0066,-0.243 C -0.0010,-0.210 0.0074,-0.162 0.0131,-0.129"/></g><g stroke-opacity="1.0" fill-opacity="0.0" stroke="#1f78b4" stroke-width="5.0e-3" fill="#000000"><path d="M -0.0604,-0.243 C -0.1040,-0.210 -0.1684,-0.162 -0.2120,-0.129"/></g><g stroke-opacity="1.0" fill-opacity="0.0" stroke="#1f78b4" stroke-width="5.0e-3" fill="#000000"><path d="M -0.4309,-0.244 C -0.4099,-0.235 -0.3868,-0.225 -0.3651,-0.218"/></g><g stroke-opacity="1.0" fill-opacity="0.0" stroke="#1f78b4" stroke-width="5.0e-3" fill="#000000"><path d="M -0.3651,-0.218 C -0.2498,-0.180 -0.2132,-0.196 -0.0993,-0.154"/></g><g stroke-opacity="1.0" fill-opacity="0.0" stroke="#1f78b4" stroke-width="5.0e-3" fill="#000000"><path d="M -0.0993,-0.154 C -0.0806,-0.147 -0.0611,-0.138 -0.0435,-0.129"/></g><g stroke-opacity="1.0" fill-opacity="0.0" stroke="#1f78b4" stroke-width="5.0e-3" fill="#000000"><path d="M -0.4585,-0.243 C -0.4148,-0.210 -0.3504,-0.162 -0.3068,-0.129"/></g><g stroke-opacity="1.0" fill-opacity="0.0" stroke="#1f78b4" stroke-width="5.0e-3" fill="#000000"><path d="M 0.4753,-0.244 C 0.4281,-0.199 0.3441,-0.121 0.2690,-0.058"/></g><g stroke-opacity="1.0" fill-opacity="0.0" stroke="#1f78b4" stroke-width="5.0e-3" fill="#000000"><path d="M 0.2690,-0.058 C 0.2211,-0.017 0.1644,0.027 0.1250,0.057"/></g><g stroke-opacity="1.0" fill-opacity="0.0" stroke="#1f78b4" stroke-width="5.0e-3" fill="#000000"><path d="M 0.4907,-0.243 C 0.4453,-0.169 0.3347,0.003 0.2178,0.128"/></g><g stroke-opacity="1.0" fill-opacity="0.0" stroke="#1f78b4" stroke-width="5.0e-3" fill="#000000"><path d="M 0.2178,0.128 C 0.1783,0.171 0.1289,0.214 0.0941,0.244"/></g><g stroke-opacity="1.0" fill-opacity="0.0" stroke="#1f78b4" stroke-width="5.0e-3" fill="#000000"><path d="M 0.2426,-0.243 C 0.2270,-0.195 0.1934,-0.110 0.1377,-0.058"/></g><g stroke-opacity="1.0" fill-opacity="0.0" stroke="#1f78b4" stroke-width="5.0e-3" fill="#000000"><path d="M 0.1377,-0.058 C 0.0735,0.002 -0.0182,0.041 -0.0911,0.064"/></g><g stroke-opacity="1.0" fill-opacity="0.0" stroke="#1f78b4" stroke-width="5.0e-3" fill="#000000"><path d="M 0.0303,-0.057 C 0.0406,-0.024 0.0556,0.024 0.0658,0.057"/></g><g stroke-opacity="1.0" fill-opacity="0.0" stroke="#1f78b4" stroke-width="5.0e-3" fill="#000000"><path d="M -0.0246,-0.057 C -0.0649,-0.024 -0.1242,0.024 -0.1645,0.057"/></g><g stroke-opacity="1.0" fill-opacity="0.0" stroke="#1f78b4" stroke-width="5.0e-3" fill="#000000"><path d="M 0.0312,0.129 C -0.0108,0.162 -0.0727,0.210 -0.1146,0.243"/></g><g stroke-opacity="1.0" fill-opacity="0.0" stroke="#1f78b4" stroke-width="5.0e-3" fill="#000000"><path d="M -0.2960,-0.056 C -0.3371,-0.010 -0.3931,0.069 -0.3523,0.128"/></g><g stroke-opacity="1.0" fill-opacity="0.0" stroke="#1f78b4" stroke-width="5.0e-3" fill="#000000"><path d="M -0.3523,0.128 C -0.3336,0.155 -0.1519,0.216 -0.0388,0.252"/></g><g stroke-opacity="1.0" fill-opacity="0.0" stroke="#1f78b4" stroke-width="5.0e-3" fill="#000000"><path d="M -0.2495,-0.057 C -0.2405,-0.024 -0.2271,0.024 -0.2180,0.057"/></g><g stroke-opacity="1.0" fill-opacity="0.0" stroke="#1f78b4" stroke-width="5.0e-3" fill="#000000"><path d="M 0.0309,0.315 C 0.0121,0.348 -0.0154,0.397 -0.0341,0.429"/></g><g stroke-opacity="1.0" fill-opacity="0.0" stroke="#1f78b4" stroke-width="5.0e-3" fill="#000000"><path d="M -0.1989,0.129 C -0.1904,0.162 -0.1779,0.210 -0.1694,0.243"/></g><g stroke-opacity="1.0" fill-opacity="0.0" stroke="#1f78b4" stroke-width="5.0e-3" fill="#000000"><path d="M -0.1398,0.315 C -0.1210,0.348 -0.0934,0.397 -0.0747,0.429"/></g><g stroke-opacity="0.8" fill-opacity="0.1" stroke="#1f78b4" stroke-width="5.0e-3" fill="#a6cee3"><rect height="6.946298387924843e-2" width="0.13802057661037992" x="-8.181419517777266e-2" y="-0.5"/></g><g stroke-opacity="0.8" fill-opacity="0.1" stroke="#1f78b4" stroke-width="5.0e-3" fill="#a6cee3"><rect height="6.946298387924854e-2" width="0.15407082450159398" x="-0.33644535092046735" y="-0.3138925967758498"/></g><g stroke-opacity="0.8" fill-opacity="0.1" stroke="#1f78b4" stroke-width="5.0e-3" fill="#a6cee3"><rect height="6.946298387924854e-2" width="0.22147493249225647" x="-0.12354137311871094" y="-0.3138925967758498"/></g><g stroke-opacity="0.8" fill-opacity="0.1" stroke="#1f78b4" stroke-width="5.0e-3" fill="#a6cee3"><rect height="6.946298387924854e-2" width="0.22147493249225653" x="-0.6167534367128863" y="-0.3138925967758498"/></g><g stroke-opacity="0.8" fill-opacity="0.1" stroke="#1f78b4" stroke-width="5.0e-3" fill="#a6cee3"><rect height="6.946298387924854e-2" width="0.20863704523009718" x="0.4081163914827891" y="-0.3138925967758498"/></g><g stroke-opacity="0.8" fill-opacity="0.1" stroke="#1f78b4" stroke-width="5.0e-3" fill="#a6cee3"><rect height="6.946298387924854e-2" width="0.1925867973388833" x="0.1567247806808103" y="-0.3138925967758498"/></g><g stroke-opacity="0.8" fill-opacity="0.1" stroke="#1f78b4" stroke-width="5.0e-3" fill="#a6cee3"><rect height="6.946298387924843e-2" width="0.17974891007672433" x="-7.065160453469976e-2" y="-0.12778519355169937"/></g><g stroke-opacity="0.8" fill-opacity="0.1" stroke="#1f78b4" stroke-width="5.0e-3" fill="#a6cee3"><rect height="6.94629838792486e-2" width="0.22147493249225658" x="-3.386645246522468e-2" y="5.832220967245083e-2"/></g><g stroke-opacity="0.8" fill-opacity="0.1" stroke="#1f78b4" stroke-width="5.0e-3" fill="#a6cee3"><rect height="6.946298387924843e-2" width="0.26320557700941327" x="-0.39101272717437696" y="-0.12778519355169937"/></g><g stroke-opacity="0.8" fill-opacity="0.1" stroke="#1f78b4" stroke-width="5.0e-3" fill="#a6cee3"><rect height="6.946298387924843e-2" width="0.17974891007672422" x="-3.862484715845449e-2" y="0.24442961289660126"/></g><g stroke-opacity="0.8" fill-opacity="0.1" stroke="#1f78b4" stroke-width="5.0e-3" fill="#a6cee3"><rect height="6.94629838792486e-2" width="0.23431744185604025" x="-0.32532584779569823" y="5.832220967245083e-2"/></g><g stroke-opacity="0.8" fill-opacity="0.1" stroke="#1f78b4" stroke-width="5.0e-3" fill="#a6cee3"><rect height="6.946298387924843e-2" width="0.1251826893482209" x="-0.22271833547742087" y="0.24442961289660126"/></g><g stroke-opacity="0.8" fill-opacity="0.1" stroke="#1f78b4" stroke-width="5.0e-3" fill="#a6cee3"><rect height="6.946298387924843e-2" width="0.13802057661037997" x="-0.12344897976689145" y="0.43053701612075157"/></g><g fill-opacity="1.0" font-size="4.0e-2" stroke="none" stroke-width="0.0" fill="#333333" text-anchor="middle"><text x="-1.2803906872582704e-2" y="-0.4588510113974741">Magma</text><text x="-0.2594099386696704" y="-0.27274360817332377">Unital</text><text x="-1.2803906872582704e-2" y="-0.27274360817332377">Associative</text><text x="-0.5060159704667582" y="-0.27274360817332377">Commutative</text><text x="0.5124349140978378" y="-0.27274360817332377">Invertible</text><text x="0.25301817935025206" y="-0.27274360817332377">Absorbing</text><text x="1.9222850503662348e-2" y="-8.663620494917346e-2">Additive</text><text x="7.687101378090355e-2" y="9.947119827497686e-2">Subtractive</text><text x="-0.2594099386696704" y="-8.663620494917346e-2">Multiplicative</text><text x="5.124960787990751e-2" y="0.2855786014991273">Divisive</text><text x="-0.2081671268676782" y="9.947119827497686e-2">Distributive</text><text x="-0.16012699080331044" y="0.2855786014991273">Ring</text><text x="-5.443869146170133e-2" y="0.47168600472327754">Field</text></g><g stroke-opacity="1.0" stroke="#e63305" stroke-width="5.0e-3" fill="none" stroke-linecap="round" stroke-dasharray="3.0e-2 1.0e-2"><polyline points="-0.5092186462043825,-0.18610740322415043+0.515637589835462,-0.18610740322415043"/></g></svg>
− other/numhask.svg
@@ -1,3 +0,0 @@-<?xml version="1.0" encoding="UTF-8"?>-<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"-    "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg xmlns="http://www.w3.org/2000/svg" height="600.0000" stroke-opacity="1" viewBox="0 0 600 600" font-size="1" width="600.0000" xmlns:xlink="http://www.w3.org/1999/xlink" stroke="rgb(0,0,0)" version="1.1"><defs></defs><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" font-size="4.777070063694268px" stroke="rgb(0,0,0)" stroke-width="2.06640091435653" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><text dominant-baseline="middle" transform="matrix(1.0000,0.0000,0.0000,1.0000,387.8981,369.2436)" stroke="none" text-anchor="middle">Epsilon</text></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="0.0" opacity="0.3" stroke="rgb(84,84,84)" stroke-width="2.06640091435653" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 411.7834,381.1863 l -0.0000,-23.8854 h -47.7707 l -0.0000,23.8854 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" font-size="4.777070063694268px" stroke="rgb(0,0,0)" stroke-width="2.06640091435653" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><text dominant-baseline="middle" transform="matrix(1.0000,0.0000,0.0000,1.0000,184.3949,298.6385)" stroke="none" text-anchor="middle">Signed</text></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="0.0" opacity="0.3" stroke="rgb(84,84,84)" stroke-width="2.06640091435653" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 208.2803,310.5812 l -0.0000,-23.8854 h -47.7707 l -0.0000,23.8854 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" font-size="4.777070063694268px" stroke="rgb(0,0,0)" stroke-width="2.06640091435653" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><text dominant-baseline="middle" transform="matrix(1.0000,0.0000,0.0000,1.0000,342.9936,298.6385)" stroke="none" text-anchor="middle">Normed</text></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="0.0" opacity="0.3" stroke="rgb(84,84,84)" stroke-width="2.06640091435653" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 366.8790,310.5812 l -0.0000,-23.8854 h -47.7707 l -0.0000,23.8854 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" font-size="4.777070063694268px" stroke="rgb(0,0,0)" stroke-width="2.06640091435653" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><text dominant-baseline="middle" transform="matrix(1.0000,0.0000,0.0000,1.0000,495.8599,369.2436)" stroke="none" text-anchor="middle">BoundedLattice</text></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="0.0" opacity="0.3" stroke="rgb(84,84,84)" stroke-width="2.06640091435653" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 519.7452,381.1863 l -0.0000,-23.8854 h -47.7707 l -0.0000,23.8854 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" font-size="4.777070063694268px" stroke="rgb(0,0,0)" stroke-width="2.06640091435653" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><text dominant-baseline="middle" transform="matrix(1.0000,0.0000,0.0000,1.0000,469.1083,298.6385)" stroke="none" text-anchor="middle">BoundedMeetSemiLattice</text></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="0.0" opacity="0.3" stroke="rgb(84,84,84)" stroke-width="2.06640091435653" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 492.9936,310.5812 l -0.0000,-23.8854 h -47.7707 l -0.0000,23.8854 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" font-size="4.777070063694268px" stroke="rgb(0,0,0)" stroke-width="2.06640091435653" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><text dominant-baseline="middle" transform="matrix(1.0000,0.0000,0.0000,1.0000,522.6115,298.6385)" stroke="none" text-anchor="middle">BoundedJoinSemiLattice</text></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="0.0" opacity="0.3" stroke="rgb(84,84,84)" stroke-width="2.06640091435653" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 546.4968,310.5812 l -0.0000,-23.8854 h -47.7707 l -0.0000,23.8854 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" font-size="4.777070063694268px" stroke="rgb(0,0,0)" stroke-width="2.06640091435653" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><text dominant-baseline="middle" transform="matrix(1.0000,0.0000,0.0000,1.0000,576.1146,298.6385)" stroke="none" text-anchor="middle">Lattice</text></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="0.0" opacity="0.3" stroke="rgb(84,84,84)" stroke-width="2.06640091435653" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 600.0000,310.5812 l -0.0000,-23.8854 h -47.7707 l -0.0000,23.8854 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" font-size="4.777070063694268px" stroke="rgb(0,0,0)" stroke-width="2.06640091435653" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><text dominant-baseline="middle" transform="matrix(1.0000,0.0000,0.0000,1.0000,469.1083,228.0334)" stroke="none" text-anchor="middle">MeetSemiLattice</text></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="0.0" opacity="0.3" stroke="rgb(84,84,84)" stroke-width="2.06640091435653" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 492.9936,239.9761 l -0.0000,-23.8854 h -47.7707 l -0.0000,23.8854 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" font-size="4.777070063694268px" stroke="rgb(0,0,0)" stroke-width="2.06640091435653" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><text dominant-baseline="middle" transform="matrix(1.0000,0.0000,0.0000,1.0000,522.6115,228.0334)" stroke="none" text-anchor="middle">JoinSemiLattice</text></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="0.0" opacity="0.3" stroke="rgb(84,84,84)" stroke-width="2.06640091435653" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 546.4968,239.9761 l -0.0000,-23.8854 h -47.7707 l -0.0000,23.8854 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" font-size="4.777070063694268px" stroke="rgb(0,0,0)" stroke-width="2.06640091435653" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><text dominant-baseline="middle" transform="matrix(1.0000,0.0000,0.0000,1.0000,167.1975,369.2436)" stroke="none" text-anchor="middle">Module</text></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="0.0" opacity="0.3" stroke="rgb(84,84,84)" stroke-width="2.06640091435653" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 191.0828,381.1863 l -0.0000,-23.8854 h -47.7707 l -0.0000,23.8854 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" font-size="4.777070063694268px" stroke="rgb(0,0,0)" stroke-width="2.06640091435653" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><text dominant-baseline="middle" transform="matrix(1.0000,0.0000,0.0000,1.0000,130.8917,298.6385)" stroke="none" text-anchor="middle">MultiplicativeAction</text></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="0.0" opacity="0.3" stroke="rgb(84,84,84)" stroke-width="2.06640091435653" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 154.7771,310.5812 l -0.0000,-23.8854 h -47.7707 l -0.0000,23.8854 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" font-size="4.777070063694268px" stroke="rgb(0,0,0)" stroke-width="2.06640091435653" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><text dominant-baseline="middle" transform="matrix(1.0000,0.0000,0.0000,1.0000,184.3949,510.4538)" stroke="none" text-anchor="middle">TrigField</text></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="0.0" opacity="0.3" stroke="rgb(84,84,84)" stroke-width="2.06640091435653" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 208.2803,522.3965 l -0.0000,-23.8854 h -47.7707 l -0.0000,23.8854 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" font-size="4.777070063694268px" stroke="rgb(0,0,0)" stroke-width="2.06640091435653" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><text dominant-baseline="middle" transform="matrix(1.0000,0.0000,0.0000,1.0000,130.8917,510.4538)" stroke="none" text-anchor="middle">LowerBoundedField</text></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="0.0" opacity="0.3" stroke="rgb(84,84,84)" stroke-width="2.06640091435653" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 154.7771,522.3965 l -0.0000,-23.8854 h -47.7707 l -0.0000,23.8854 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" font-size="4.777070063694268px" stroke="rgb(0,0,0)" stroke-width="2.06640091435653" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><text dominant-baseline="middle" transform="matrix(1.0000,0.0000,0.0000,1.0000,77.3885,510.4538)" stroke="none" text-anchor="middle">UpperBoundedField</text></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="0.0" opacity="0.3" stroke="rgb(84,84,84)" stroke-width="2.06640091435653" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 101.2739,522.3965 l -0.0000,-23.8854 h -47.7707 l -0.0000,23.8854 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" font-size="4.777070063694268px" stroke="rgb(0,0,0)" stroke-width="2.06640091435653" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><text dominant-baseline="middle" transform="matrix(1.0000,0.0000,0.0000,1.0000,237.8981,510.4538)" stroke="none" text-anchor="middle">QuotientField</text></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="0.0" opacity="0.3" stroke="rgb(84,84,84)" stroke-width="2.06640091435653" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 261.7834,522.3965 l -0.0000,-23.8854 h -47.7707 l -0.0000,23.8854 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" font-size="4.777070063694268px" stroke="rgb(0,0,0)" stroke-width="2.06640091435653" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><text dominant-baseline="middle" transform="matrix(1.0000,0.0000,0.0000,1.0000,23.8854,510.4538)" stroke="none" text-anchor="middle">ExpField</text></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="0.0" opacity="0.3" stroke="rgb(84,84,84)" stroke-width="2.06640091435653" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 47.7707,522.3965 l -0.0000,-23.8854 h -47.7707 l -0.0000,23.8854 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" font-size="4.777070063694268px" stroke="rgb(0,0,0)" stroke-width="2.06640091435653" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><text dominant-baseline="middle" transform="matrix(1.0000,0.0000,0.0000,1.0000,130.8917,439.8478)" stroke="none" text-anchor="middle">Field</text></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="0.0" opacity="0.3" stroke="rgb(84,84,84)" stroke-width="2.06640091435653" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 154.7771,451.7904 l -0.0000,-23.8854 h -47.7707 l -0.0000,23.8854 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" font-size="4.777070063694268px" stroke="rgb(0,0,0)" stroke-width="2.06640091435653" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><text dominant-baseline="middle" transform="matrix(1.0000,0.0000,0.0000,1.0000,237.8981,369.2436)" stroke="none" text-anchor="middle">Ring</text></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="0.0" opacity="0.3" stroke="rgb(84,84,84)" stroke-width="2.06640091435653" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 261.7834,381.1863 l -0.0000,-23.8854 h -47.7707 l -0.0000,23.8854 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" font-size="4.777070063694268px" stroke="rgb(0,0,0)" stroke-width="2.06640091435653" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><text dominant-baseline="middle" transform="matrix(1.0000,0.0000,0.0000,1.0000,237.8981,298.6385)" stroke="none" text-anchor="middle">Distributive</text></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="0.0" opacity="0.3" stroke="rgb(84,84,84)" stroke-width="2.06640091435653" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 261.7834,310.5812 l -0.0000,-23.8854 h -47.7707 l -0.0000,23.8854 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" font-size="4.777070063694268px" stroke="rgb(0,0,0)" stroke-width="2.06640091435653" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><text dominant-baseline="middle" transform="matrix(1.0000,0.0000,0.0000,1.0000,77.3885,298.6385)" stroke="none" text-anchor="middle">Divisive</text></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="0.0" opacity="0.3" stroke="rgb(84,84,84)" stroke-width="2.06640091435653" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 101.2739,310.5812 l -0.0000,-23.8854 h -47.7707 l -0.0000,23.8854 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" font-size="4.777070063694268px" stroke="rgb(0,0,0)" stroke-width="2.06640091435653" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><text dominant-baseline="middle" transform="matrix(1.0000,0.0000,0.0000,1.0000,291.4013,228.0334)" stroke="none" text-anchor="middle">Multiplicative</text></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="0.0" opacity="0.3" stroke="rgb(84,84,84)" stroke-width="2.06640091435653" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 315.2866,239.9761 l -0.0000,-23.8854 h -47.7707 l -0.0000,23.8854 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" font-size="4.777070063694268px" stroke="rgb(0,0,0)" stroke-width="2.06640091435653" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><text dominant-baseline="middle" transform="matrix(1.0000,0.0000,0.0000,1.0000,290.4459,298.6385)" stroke="none" text-anchor="middle">Subtractive</text></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="0.0" opacity="0.3" stroke="rgb(84,84,84)" stroke-width="2.06640091435653" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 314.3312,310.5812 l -0.0000,-23.8854 h -47.7707 l -0.0000,23.8854 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" font-size="4.777070063694268px" stroke="rgb(0,0,0)" stroke-width="2.06640091435653" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><text dominant-baseline="middle" transform="matrix(1.0000,0.0000,0.0000,1.0000,343.9490,228.0334)" stroke="none" text-anchor="middle">Additive</text></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="0.0" opacity="0.3" stroke="rgb(84,84,84)" stroke-width="2.06640091435653" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 367.8344,239.9761 l -0.0000,-23.8854 h -47.7707 l -0.0000,23.8854 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" font-size="4.777070063694268px" stroke="rgb(0,0,0)" stroke-width="2.06640091435653" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><text dominant-baseline="middle" transform="matrix(1.0000,0.0000,0.0000,1.0000,238.8535,228.0334)" stroke="none" text-anchor="middle">AbelianGroup</text></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="0.0" opacity="0.3" stroke="rgb(84,84,84)" stroke-width="2.06640091435653" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 262.7389,239.9761 l -0.0000,-23.8854 h -47.7707 l -0.0000,23.8854 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" font-size="4.777070063694268px" stroke="rgb(0,0,0)" stroke-width="2.06640091435653" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><text dominant-baseline="middle" transform="matrix(1.0000,0.0000,0.0000,1.0000,187.2611,228.0334)" stroke="none" text-anchor="middle">Group</text></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="0.0" opacity="0.3" stroke="rgb(84,84,84)" stroke-width="2.06640091435653" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 211.1465,239.9761 l -0.0000,-23.8854 h -47.7707 l -0.0000,23.8854 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" font-size="4.777070063694268px" stroke="rgb(0,0,0)" stroke-width="2.06640091435653" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><text dominant-baseline="middle" transform="matrix(1.0000,0.0000,0.0000,1.0000,121.3376,158.3360)" stroke="none" text-anchor="middle">Absorbing</text></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="0.0" opacity="0.3" stroke="rgb(84,84,84)" stroke-width="2.06640091435653" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 145.2229,170.2787 l -0.0000,-23.8854 h -47.7707 l -0.0000,23.8854 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" font-size="4.777070063694268px" stroke="rgb(0,0,0)" stroke-width="2.06640091435653" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><text dominant-baseline="middle" transform="matrix(1.0000,0.0000,0.0000,1.0000,187.2611,158.3360)" stroke="none" text-anchor="middle">Invertible</text></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="0.0" opacity="0.3" stroke="rgb(84,84,84)" stroke-width="2.06640091435653" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 211.1465,170.2787 l -0.0000,-23.8854 h -47.7707 l -0.0000,23.8854 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" font-size="4.777070063694268px" stroke="rgb(0,0,0)" stroke-width="2.06640091435653" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><text dominant-baseline="middle" transform="matrix(1.0000,0.0000,0.0000,1.0000,343.9490,158.3360)" stroke="none" text-anchor="middle">Commutative</text></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="0.0" opacity="0.3" stroke="rgb(84,84,84)" stroke-width="2.06640091435653" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 367.8344,170.2787 l -0.0000,-23.8854 h -47.7707 l -0.0000,23.8854 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" font-size="4.777070063694268px" stroke="rgb(0,0,0)" stroke-width="2.06640091435653" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><text dominant-baseline="middle" transform="matrix(1.0000,0.0000,0.0000,1.0000,292.3567,158.3360)" stroke="none" text-anchor="middle">Associative</text></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="0.0" opacity="0.3" stroke="rgb(84,84,84)" stroke-width="2.06640091435653" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 316.2420,170.2787 l -0.0000,-23.8854 h -47.7707 l -0.0000,23.8854 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" font-size="4.777070063694268px" stroke="rgb(0,0,0)" stroke-width="2.06640091435653" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><text dominant-baseline="middle" transform="matrix(1.0000,0.0000,0.0000,1.0000,240.7643,158.3360)" stroke="none" text-anchor="middle">Unital</text></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="0.0" opacity="0.3" stroke="rgb(84,84,84)" stroke-width="2.06640091435653" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 264.6497,170.2787 l -0.0000,-23.8854 h -47.7707 l -0.0000,23.8854 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" font-size="4.777070063694268px" stroke="rgb(0,0,0)" stroke-width="2.06640091435653" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><text dominant-baseline="middle" transform="matrix(1.0000,0.0000,0.0000,1.0000,240.7643,89.5462)" stroke="none" text-anchor="middle">Magma</text></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="0.0" opacity="0.3" stroke="rgb(84,84,84)" stroke-width="2.06640091435653" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 264.6497,101.4889 l -0.0000,-23.8854 h -47.7707 l -0.0000,23.8854 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="0.0" opacity="0.3" stroke="rgb(84,84,84)" stroke-width="2.06640091435653" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 240.7643,101.4889 l 0.0000,36.9045 "/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.3" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(84,84,84)" stroke-linecap="butt" stroke-miterlimit="10.0"></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.3" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(84,84,84)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 240.7643,146.3933 l 2.9220,-8.9930 l -2.9220,1.5362 l -2.9220,-1.5362 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.3" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(84,84,84)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 240.7643,138.9365 l -0.0000,-0.5432 l 1.0332,-0.0000 l -1.0332,0.5432 l -0.0000,-0.5432 l -1.0332,0.0000 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="0.0" opacity="0.3" stroke="rgb(84,84,84)" stroke-width="2.06640091435653" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 249.7213,101.4889 l 28.8783,38.5045 "/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.3" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(84,84,84)" stroke-linecap="butt" stroke-miterlimit="10.0"></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.3" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(84,84,84)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 283.3997,146.3933 l -3.0582,-8.9476 l -1.4159,2.9822 l -3.2593,0.5243 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.3" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(84,84,84)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 278.9256,140.4279 l -0.3259,-0.4345 l 0.8266,-0.6199 l -0.5006,1.0545 l -0.3259,-0.4345 l -0.8266,0.6199 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="0.0" opacity="0.3" stroke="rgb(84,84,84)" stroke-width="2.06640091435653" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 258.6783,101.4889 l 60.7003,40.4669 "/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.3" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(84,84,84)" stroke-linecap="butt" stroke-miterlimit="10.0"></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.3" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(84,84,84)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 326.0350,146.3933 l -5.8618,-7.4197 l -0.3427,3.2834 l -2.8990,1.5791 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.3" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(84,84,84)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 319.8306,142.2570 l -0.4520,-0.3013 l 0.5731,-0.8597 l -0.1212,1.1610 l -0.4520,-0.3013 l -0.5731,0.8597 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="0.0" opacity="0.3" stroke="rgb(84,84,84)" stroke-width="2.06640091435653" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 231.4756,101.4889 l -30.0142,38.5896 "/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.3" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(84,84,84)" stroke-linecap="butt" stroke-miterlimit="10.0"></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.3" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(84,84,84)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 196.5499,146.3933 l 7.8277,-5.3047 l -3.2496,-0.5813 l -1.3634,-3.0065 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.3" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(84,84,84)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 201.1279,140.5073 l 0.3335,-0.4288 l 0.8156,0.6343 l -1.1490,-0.2056 l 0.3335,-0.4288 l -0.8156,-0.6343 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="0.0" opacity="0.3" stroke="rgb(84,84,84)" stroke-width="2.06640091435653" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 220.0305,101.4889 l -71.0269,40.9115 "/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.3" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(84,84,84)" stroke-linecap="butt" stroke-miterlimit="10.0"></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.3" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(84,84,84)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 142.0714,146.3933 l 9.2512,-1.9566 l -2.7896,-1.7653 l -0.1273,-3.2988 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.3" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(84,84,84)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 148.5330,142.6715 l 0.4707,-0.2711 l 0.5157,0.8953 l -0.9864,-0.6242 l 0.4707,-0.2711 l -0.5157,-0.8953 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="0.0" opacity="0.3" stroke="rgb(84,84,84)" stroke-width="2.06640091435653" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 231.5965,170.2787 l -30.2962,39.4663 "/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.3" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(84,84,84)" stroke-linecap="butt" stroke-miterlimit="10.0"></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.3" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(84,84,84)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 196.4289,216.0908 l 7.7939,-5.3542 l -3.2532,-0.5607 l -1.3824,-2.9978 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.3" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(84,84,84)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 200.9696,210.1758 l 0.3308,-0.4309 l 0.8196,0.6291 l -1.1503,-0.1983 l 0.3308,-0.4309 l -0.8196,-0.6291 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="0.0" opacity="0.3" stroke="rgb(84,84,84)" stroke-width="2.06640091435653" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 187.2611,170.2787 l 0.0000,37.8121 "/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.3" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(84,84,84)" stroke-linecap="butt" stroke-miterlimit="10.0"></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.3" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(84,84,84)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 187.2611,216.0908 l 2.9220,-8.9930 l -2.9220,1.5362 l -2.9220,-1.5362 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.3" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(84,84,84)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 187.2611,208.6339 l -0.0000,-0.5432 l 1.0332,-0.0000 l -1.0332,0.5432 l -0.0000,-0.5432 l -1.0332,0.0000 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="0.0" opacity="0.3" stroke="rgb(84,84,84)" stroke-width="2.06640091435653" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 274.3485,170.2787 l -62.4121,41.3906 "/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.3" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(84,84,84)" stroke-linecap="butt" stroke-miterlimit="10.0"></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.3" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(84,84,84)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 205.2693,216.0908 l 9.1096,-2.5352 l -2.8952,-1.5861 l -0.3347,-3.2842 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.3" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(84,84,84)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 211.4837,211.9695 l 0.4527,-0.3002 l 0.5710,0.8611 l -1.0237,-0.5608 l 0.4527,-0.3002 l -0.5710,-0.8611 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="0.0" opacity="0.3" stroke="rgb(84,84,84)" stroke-width="2.06640091435653" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 240.4369,170.2787 l -1.0367,37.8151 "/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.3" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(84,84,84)" stroke-linecap="butt" stroke-miterlimit="10.0"></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.3" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(84,84,84)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 239.1809,216.0908 l 3.1674,-8.9095 l -2.9630,1.4555 l -2.8788,-1.6157 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.3" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(84,84,84)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 239.3853,208.6368 l 0.0149,-0.5430 l 1.0328,0.0283 l -1.0477,0.5147 l 0.0149,-0.5430 l -1.0328,-0.0283 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="0.0" opacity="0.3" stroke="rgb(84,84,84)" stroke-width="2.06640091435653" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 196.1015,170.2787 l 29.1519,39.3821 "/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.3" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(84,84,84)" stroke-linecap="butt" stroke-miterlimit="10.0"></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.3" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(84,84,84)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 230.0131,216.0908 l -3.0019,-8.9666 l -1.4346,2.9732 l -3.2625,0.5038 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.3" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(84,84,84)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 225.5766,210.0973 l -0.3232,-0.4366 l 0.8304,-0.6147 l -0.5073,1.0513 l -0.3232,-0.4366 l -0.8304,0.6147 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="0.0" opacity="0.3" stroke="rgb(84,84,84)" stroke-width="2.06640091435653" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 283.1889,170.2787 l -30.2962,39.4663 "/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.3" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(84,84,84)" stroke-linecap="butt" stroke-miterlimit="10.0"></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.3" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(84,84,84)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 248.0213,216.0908 l 7.7939,-5.3542 l -3.2532,-0.5607 l -1.3824,-2.9978 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.3" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(84,84,84)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 252.5619,210.1758 l 0.3308,-0.4309 l 0.8196,0.6291 l -1.1503,-0.1983 l 0.3308,-0.4309 l -0.8196,-0.6291 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="0.0" opacity="0.3" stroke="rgb(84,84,84)" stroke-width="2.06640091435653" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 325.9409,170.2787 l -62.4121,41.3906 "/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.3" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(84,84,84)" stroke-linecap="butt" stroke-miterlimit="10.0"></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.3" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(84,84,84)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 256.8616,216.0908 l 9.1096,-2.5352 l -2.8952,-1.5861 l -0.3347,-3.2842 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.3" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(84,84,84)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 263.0761,211.9695 l 0.4527,-0.3002 l 0.5710,0.8611 l -1.0237,-0.5608 l 0.4527,-0.3002 l -0.5710,-0.8611 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="0.0" opacity="0.5" stroke="rgb(255,0,0)" stroke-width="2.06640091435653" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 343.9490,170.2787 l 0.0000,37.8121 "/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.5" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(255,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.5" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(255,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 343.9490,216.0908 l 2.9220,-8.9930 l -2.9220,1.5362 l -2.9220,-1.5362 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.5" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(255,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 343.9490,208.6339 l -0.0000,-0.5432 l 1.0332,-0.0000 l -1.0332,0.5432 l -0.0000,-0.5432 l -1.0332,0.0000 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="0.0" opacity="0.5" stroke="rgb(255,0,0)" stroke-width="2.06640091435653" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 258.4451,170.2787 l 61.1939,41.3342 "/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.5" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(255,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.5" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(255,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 326.2683,216.0908 l -5.8167,-7.4551 l -0.3626,3.2812 l -2.9085,1.5615 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.5" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(255,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 320.0891,211.9169 l -0.4501,-0.3040 l 0.5783,-0.8562 l -0.1282,1.1602 l -0.4501,-0.3040 l -0.5783,0.8562 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="0.0" opacity="0.5" stroke="rgb(255,0,0)" stroke-width="2.06640091435653" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 301.1971,170.2787 l 29.1519,39.3821 "/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.5" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(255,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.5" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(255,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 335.1087,216.0908 l -3.0019,-8.9666 l -1.4346,2.9732 l -3.2625,0.5038 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.5" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(255,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 330.6721,210.0973 l -0.3232,-0.4366 l 0.8304,-0.6147 l -0.5073,1.0513 l -0.3232,-0.4366 l -0.8304,0.6147 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="0.0" opacity="0.5" stroke="rgb(255,0,0)" stroke-width="2.06640091435653" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 196.0443,170.2787 l 80.8786,109.9725 "/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.5" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(255,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.5" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(255,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 281.6627,286.6959 l -2.9741,-8.9759 l -1.4438,2.9687 l -3.2641,0.4937 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.5" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(255,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 277.2448,280.6887 l -0.3218,-0.4376 l 0.8323,-0.6121 l -0.5105,1.0497 l -0.3218,-0.4376 l -0.8323,0.6121 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="0.0" opacity="0.5" stroke="rgb(255,0,0)" stroke-width="2.06640091435653" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 334.8991,239.9761 l -30.5716,40.3436 "/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.5" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(255,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.5" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(255,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 299.4958,286.6959 l 7.7603,-5.4028 l -3.2567,-0.5404 l -1.4011,-2.9891 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.5" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(255,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 303.9994,280.7527 l 0.3281,-0.4329 l 0.8235,0.6240 l -1.1515,-0.1911 l 0.3281,-0.4329 l -0.8235,-0.6240 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="0.0" opacity="0.5" stroke="rgb(0,0,255)" stroke-width="2.06640091435653" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 249.4410,170.2787 l 28.5814,39.3399 "/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.5" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(0,0,255)" stroke-linecap="butt" stroke-miterlimit="10.0"></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.5" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(0,0,255)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 282.7246,216.0908 l -2.9219,-8.9930 l -1.4610,2.9603 l -3.2669,0.4747 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.5" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(0,0,255)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 278.3417,210.0580 l -0.3193,-0.4395 l 0.8359,-0.6073 l -0.5166,1.0467 l -0.3193,-0.4395 l -0.8359,0.6073 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="0.0" opacity="0.5" stroke="rgb(0,0,255)" stroke-width="2.06640091435653" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 292.1930,170.2787 l -0.5183,37.8129 "/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.5" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(0,0,255)" stroke-linecap="butt" stroke-miterlimit="10.0"></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.5" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(0,0,255)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 291.5650,216.0908 l 3.0450,-8.9521 l -2.9428,1.4960 l -2.9007,-1.5761 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.5" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(0,0,255)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 291.6672,208.6347 l 0.0074,-0.5431 l 1.0331,0.0142 l -1.0405,0.5290 l 0.0074,-0.5431 l -1.0331,-0.0142 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="0.0" opacity="0.5" stroke="rgb(0,0,255)" stroke-width="2.06640091435653" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 334.9450,170.2787 l -29.7235,39.4242 "/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.5" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(0,0,255)" stroke-linecap="butt" stroke-miterlimit="10.0"></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.5" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(0,0,255)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 300.4053,216.0908 l 7.7471,-5.4217 l -3.2580,-0.5325 l -1.4084,-2.9857 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.5" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(0,0,255)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 304.8944,210.1366 l 0.3270,-0.4337 l 0.8250,0.6220 l -1.1520,-0.1883 l 0.3270,-0.4337 l -0.8250,-0.6220 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="0.0" opacity="0.5" stroke="rgb(0,0,255)" stroke-width="2.06640091435653" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 177.9087,170.2787 l -86.2353,110.1187 "/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.5" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(0,0,255)" stroke-linecap="butt" stroke-miterlimit="10.0"></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.5" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(0,0,255)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 86.7410,286.6959 l 7.8452,-5.2787 l -3.2477,-0.5921 l -1.3534,-3.0110 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.5" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(0,0,255)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 91.3385,280.8250 l 0.3349,-0.4277 l 0.8135,0.6370 l -1.1484,-0.2094 l 0.3349,-0.4277 l -0.8135,-0.6370 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="0.0" opacity="0.5" stroke="rgb(0,0,255)" stroke-width="2.06640091435653" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 267.5159,235.9135 l -158.6448,52.3386 "/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.5" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(0,0,255)" stroke-linecap="butt" stroke-miterlimit="10.0"></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.5" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(0,0,255)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 101.2739,290.7585 l 9.4557,-0.0426 l -2.3743,-2.2936 l 0.5434,-3.2562 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.5" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(0,0,255)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 108.3553,288.4223 l 0.5158,-0.1702 l 0.3237,0.9812 l -0.8395,-0.8110 l 0.5158,-0.1702 l -0.3237,-0.9812 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="0.0" opacity="0.5" stroke="rgb(255,0,0)" stroke-width="2.06640091435653" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 326.0108,239.9761 l -63.5153,42.2863 "/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.5" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(255,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.5" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(255,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 255.8363,286.6959 l 9.1051,-2.5515 l -2.8980,-1.5809 l -0.3406,-3.2836 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.5" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(255,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 262.0434,282.5634 l 0.4521,-0.3010 l 0.5726,0.8600 l -1.0247,-0.5590 l 0.4521,-0.3010 l -0.5726,-0.8600 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="0.0" opacity="0.5" stroke="rgb(0,0,255)" stroke-width="2.06640091435653" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 282.3513,239.9761 l -30.5716,40.3436 "/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.5" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(0,0,255)" stroke-linecap="butt" stroke-miterlimit="10.0"></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.5" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(0,0,255)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 246.9480,286.6959 l 7.7603,-5.4028 l -3.2567,-0.5404 l -1.4011,-2.9891 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.5" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(0,0,255)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 251.4516,280.7527 l 0.3281,-0.4329 l 0.8235,0.6240 l -1.1515,-0.1911 l 0.3281,-0.4329 l -0.8235,-0.6240 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="0.0" opacity="0.3" stroke="rgb(84,84,84)" stroke-width="2.06640091435653" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 131.2593,170.2787 l 91.6048,110.2637 "/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.3" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(84,84,84)" stroke-linecap="butt" stroke-miterlimit="10.0"></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.3" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(84,84,84)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 227.9764,286.6959 l -3.4992,-8.7845 l -1.2659,3.0488 l -3.2292,0.6856 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.3" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(84,84,84)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 223.2113,280.9602 l -0.3471,-0.4178 l 0.7947,-0.6602 l -0.4476,1.0781 l -0.3471,-0.4178 l -0.7947,0.6602 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="0.0" opacity="0.3" stroke="rgb(84,84,84)" stroke-width="2.06640091435653" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 237.8981,310.5812 l 0.0000,38.7197 "/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.3" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(84,84,84)" stroke-linecap="butt" stroke-miterlimit="10.0"></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.3" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(84,84,84)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 237.8981,357.3010 l 2.9220,-8.9930 l -2.9220,1.5362 l -2.9220,-1.5362 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.3" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(84,84,84)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 237.8981,349.8441 l -0.0000,-0.5432 l 1.0332,-0.0000 l -1.0332,0.5432 l -0.0000,-0.5432 l -1.0332,0.0000 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="0.0" opacity="0.5" stroke="rgb(255,0,0)" stroke-width="2.06640091435653" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 281.5575,310.5812 l -29.9948,40.3021 "/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.5" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(255,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.5" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(255,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 246.7864,357.3010 l 7.7133,-5.4697 l -3.2612,-0.5122 l -1.4269,-2.9769 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.5" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(255,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 251.2385,351.3190 l 0.3243,-0.4357 l 0.8288,0.6169 l -1.1531,-0.1811 l 0.3243,-0.4357 l -0.8288,-0.6169 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="0.0" opacity="0.3" stroke="rgb(84,84,84)" stroke-width="2.06640091435653" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 219.7980,381.1863 l -64.1287,42.3129 "/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.3" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(84,84,84)" stroke-linecap="butt" stroke-miterlimit="10.0"></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.3" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(84,84,84)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 148.9918,427.9051 l 9.1155,-2.5138 l -2.8915,-1.5929 l -0.3270,-3.2850 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.3" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(84,84,84)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 155.2159,423.7984 l 0.4534,-0.2992 l 0.5690,0.8624 l -1.0224,-0.5632 l 0.4534,-0.2992 l -0.5690,-0.8624 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="0.0" opacity="0.5" stroke="rgb(0,0,255)" stroke-width="2.06640091435653" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 81.9135,310.5812 l 41.6187,109.8429 "/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.5" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(0,0,255)" stroke-linecap="butt" stroke-miterlimit="10.0"></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.5" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(0,0,255)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 126.3667,427.9051 l -0.4539,-9.4449 l -2.1882,2.4718 l -3.2767,-0.4012 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.5" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(0,0,255)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 123.7247,420.9320 l -0.1925,-0.5079 l 0.9662,-0.3661 l -0.7737,0.8740 l -0.1925,-0.5079 l -0.9662,0.3661 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="0.0" opacity="0.3" stroke="rgb(84,84,84)" stroke-width="2.06640091435653" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 112.7921,451.7904 l -64.1297,42.3148 "/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.3" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(84,84,84)" stroke-linecap="butt" stroke-miterlimit="10.0"></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.3" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(84,84,84)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 41.9850,498.5111 l 9.1155,-2.5139 l -2.8915,-1.5929 l -0.3271,-3.2850 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.3" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(84,84,84)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 48.2090,494.4044 l 0.4534,-0.2992 l 0.5690,0.8624 l -1.0224,-0.5632 l 0.4534,-0.2992 l -0.5690,-0.8624 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="0.0" opacity="0.3" stroke="rgb(84,84,84)" stroke-width="2.06640091435653" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 148.9913,451.7904 l 64.1297,42.3148 "/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.3" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(84,84,84)" stroke-linecap="butt" stroke-miterlimit="10.0"></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.3" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(84,84,84)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 219.7985,498.5111 l -5.8970,-7.3918 l -0.3271,3.2850 l -2.8915,1.5929 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.3" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(84,84,84)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 213.5745,494.4044 l -0.4534,-0.2992 l 0.5690,-0.8624 l -0.1156,1.1615 l -0.4534,-0.2992 l -0.5690,0.8624 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="0.0" opacity="0.3" stroke="rgb(84,84,84)" stroke-width="2.06640091435653" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 237.8981,381.1863 l 0.0000,109.3248 "/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.3" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(84,84,84)" stroke-linecap="butt" stroke-miterlimit="10.0"></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.3" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(84,84,84)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 237.8981,498.5111 l 2.9220,-8.9930 l -2.9220,1.5362 l -2.9220,-1.5362 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.3" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(84,84,84)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 237.8981,491.0543 l -0.0000,-0.5432 l 1.0332,-0.0000 l -1.0332,0.5432 l -0.0000,-0.5432 l -1.0332,0.0000 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="0.0" opacity="0.3" stroke="rgb(84,84,84)" stroke-width="2.06640091435653" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 139.9415,451.7904 l 30.5719,40.3446 "/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.3" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(84,84,84)" stroke-linecap="butt" stroke-miterlimit="10.0"></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.3" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(84,84,84)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 175.3451,498.5111 l -3.1025,-8.9323 l -1.4011,2.9891 l -3.2567,0.5404 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.3" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(84,84,84)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 170.8415,492.5679 l -0.3281,-0.4329 l 0.8235,-0.6240 l -0.4954,1.0569 l -0.3281,-0.4329 l -0.8235,0.6240 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="0.0" opacity="0.3" stroke="rgb(84,84,84)" stroke-width="2.06640091435653" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 121.8419,451.7904 l -30.5719,40.3446 "/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.3" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(84,84,84)" stroke-linecap="butt" stroke-miterlimit="10.0"></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.3" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(84,84,84)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 86.4383,498.5111 l 7.7603,-5.4028 l -3.2567,-0.5404 l -1.4011,-2.9891 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.3" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(84,84,84)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 90.9419,492.5679 l 0.3281,-0.4329 l 0.8235,0.6240 l -1.1515,-0.1911 l 0.3281,-0.4329 l -0.8235,-0.6240 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="0.0" opacity="0.3" stroke="rgb(84,84,84)" stroke-width="2.06640091435653" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 130.8917,451.7904 l 0.0000,38.7207 "/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.3" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(84,84,84)" stroke-linecap="butt" stroke-miterlimit="10.0"></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.3" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(84,84,84)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 130.8917,498.5111 l 2.9220,-8.9930 l -2.9220,1.5362 l -2.9220,-1.5362 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.3" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(84,84,84)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 130.8917,491.0543 l -0.0000,-0.5432 l 1.0332,-0.0000 l -1.0332,0.5432 l -0.0000,-0.5432 l -1.0332,0.0000 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="0.0" opacity="0.5" stroke="rgb(0,128,0)" stroke-width="2.06640091435653" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 267.5159,238.5402 l -105.4160,46.3705 "/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.5" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(0,128,0)" stroke-linecap="butt" stroke-miterlimit="10.0"></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.5" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(0,128,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 154.7771,288.1318 l 9.4083,-0.9463 l -2.5827,-2.0561 l 0.2296,-3.2932 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.5" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(0,128,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 161.6027,285.1294 l 0.4972,-0.2187 l 0.4160,0.9457 l -0.9132,-0.7270 l 0.4972,-0.2187 l -0.4160,-0.9457 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="0.0" opacity="0.5" stroke="rgb(0,128,0)" stroke-width="2.06640091435653" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 225.9393,310.5812 l -41.1223,41.0667 "/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.5" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(0,128,0)" stroke-linecap="butt" stroke-miterlimit="10.0"></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.5" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(0,128,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 179.1563,357.3010 l 8.4281,-4.2871 l -3.1518,-0.9821 l -0.9778,-3.1531 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.5" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(0,128,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 184.4326,352.0318 l 0.3843,-0.3838 l 0.7301,0.7311 l -1.1144,-0.3472 l 0.3843,-0.3838 l -0.7301,-0.7311 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="0.0" opacity="0.3" stroke="rgb(84,84,84)" stroke-width="2.06640091435653" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 137.0327,310.5812 l 20.3653,39.6052 "/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.3" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(84,84,84)" stroke-linecap="butt" stroke-miterlimit="10.0"></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.3" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(84,84,84)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 161.0564,357.3010 l -1.5139,-9.3338 l -1.8961,2.7024 l -3.3011,-0.0299 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.3" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(84,84,84)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 157.6465,350.6695 l -0.2484,-0.4831 l 0.9188,-0.4725 l -0.6704,0.9555 l -0.2484,-0.4831 l -0.9188,0.4725 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="0.0" opacity="0.3" stroke="rgb(84,84,84)" stroke-width="2.06640091435653" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 316.2420,165.5660 l 174.8272,52.9197 "/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.3" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(84,84,84)" stroke-linecap="butt" stroke-miterlimit="10.0"></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.3" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(84,84,84)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 498.7261,220.8034 l -7.7608,-5.4021 l 0.6238,3.2417 l -2.3169,2.3516 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.3" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(84,84,84)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 491.5891,218.6431 l -0.5199,-0.1574 l 0.2993,-0.9889 l 0.2206,1.1463 l -0.5199,-0.1574 l -0.2993,0.9889 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="0.0" opacity="0.3" stroke="rgb(84,84,84)" stroke-width="2.06640091435653" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 367.8344,167.6538 l 123.4388,48.1543 "/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.3" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(84,84,84)" stroke-linecap="butt" stroke-miterlimit="10.0"></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.3" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(84,84,84)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 498.7261,218.7156 l -7.3161,-5.9905 l 0.3692,3.2805 l -2.4931,2.1639 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.3" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(84,84,84)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 491.7792,216.0056 l -0.5060,-0.1974 l 0.3755,-0.9626 l 0.1305,1.1600 l -0.5060,-0.1974 l -0.3755,0.9626 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="0.0" opacity="0.3" stroke="rgb(84,84,84)" stroke-width="2.06640091435653" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 316.2420,167.7546 l 121.5386,47.9256 "/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.3" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(84,84,84)" stroke-linecap="butt" stroke-miterlimit="10.0"></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.3" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(84,84,84)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 445.2229,218.6149 l -7.2942,-6.0172 l 0.3572,3.2818 l -2.5010,2.1548 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.3" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(84,84,84)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 438.2860,215.8794 l -0.5053,-0.1993 l 0.3790,-0.9612 l 0.1263,1.1604 l -0.5053,-0.1993 l -0.3790,0.9612 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="0.0" opacity="0.3" stroke="rgb(84,84,84)" stroke-width="2.06640091435653" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 365.3951,170.2787 l 75.2778,41.9199 "/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.3" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(84,84,84)" stroke-linecap="butt" stroke-miterlimit="10.0"></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.3" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(84,84,84)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 447.6622,216.0908 l -6.4353,-6.9281 l -0.0795,3.3003 l -2.7637,1.8055 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.3" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(84,84,84)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 441.1474,212.4629 l -0.4746,-0.2643 l 0.5027,-0.9027 l -0.0281,1.1669 l -0.4746,-0.2643 l -0.5027,0.9027 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="0.0" opacity="0.3" stroke="rgb(84,84,84)" stroke-width="2.06640091435653" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 531.6614,239.9761 l 30.5716,40.3436 "/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.3" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(84,84,84)" stroke-linecap="butt" stroke-miterlimit="10.0"></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.3" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(84,84,84)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 567.0647,286.6959 l -3.1026,-8.9323 l -1.4011,2.9891 l -3.2567,0.5404 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.3" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(84,84,84)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 562.5611,280.7527 l -0.3281,-0.4329 l 0.8235,-0.6240 l -0.4954,1.0569 l -0.3281,-0.4329 l -0.8235,0.6240 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="0.0" opacity="0.3" stroke="rgb(84,84,84)" stroke-width="2.06640091435653" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 487.2081,239.9761 l 64.1292,42.3138 "/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.3" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(84,84,84)" stroke-linecap="butt" stroke-miterlimit="10.0"></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.3" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(84,84,84)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 558.0148,286.6959 l -5.8970,-7.3917 l -0.3270,3.2850 l -2.8915,1.5929 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.3" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(84,84,84)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 551.7908,282.5891 l -0.4534,-0.2992 l 0.5690,-0.8624 l -0.1156,1.1615 l -0.4534,-0.2992 l -0.5690,0.8624 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="0.0" opacity="0.3" stroke="rgb(84,84,84)" stroke-width="2.06640091435653" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 522.6115,239.9761 l 0.0000,38.7197 "/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.3" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(84,84,84)" stroke-linecap="butt" stroke-miterlimit="10.0"></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.3" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(84,84,84)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 522.6115,286.6959 l 2.9220,-8.9930 l -2.9220,1.5362 l -2.9220,-1.5362 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.3" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(84,84,84)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 522.6115,279.2390 l -0.0000,-0.5432 l 1.0332,-0.0000 l -1.0332,0.5432 l -0.0000,-0.5432 l -1.0332,0.0000 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="0.0" opacity="0.3" stroke="rgb(84,84,84)" stroke-width="2.06640091435653" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 264.6497,170.2260 l 226.9147,112.9574 "/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.3" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(84,84,84)" stroke-linecap="butt" stroke-miterlimit="10.0"></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.3" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(84,84,84)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 498.7261,286.7485 l -6.7485,-6.6234 l 0.0731,3.3004 l -2.6774,1.9312 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.3" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(84,84,84)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 492.0507,283.4255 l -0.4863,-0.2421 l 0.4604,-0.9249 l 0.0258,1.1670 l -0.4863,-0.2421 l -0.4604,0.9249 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="0.0" opacity="0.3" stroke="rgb(84,84,84)" stroke-width="2.06640091435653" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 469.1083,239.9761 l 0.0000,38.7197 "/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.3" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(84,84,84)" stroke-linecap="butt" stroke-miterlimit="10.0"></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.3" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(84,84,84)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 469.1083,286.6959 l 2.9220,-8.9930 l -2.9220,1.5362 l -2.9220,-1.5362 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.3" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(84,84,84)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 469.1083,279.2390 l -0.0000,-0.5432 l 1.0332,-0.0000 l -1.0332,0.5432 l -0.0000,-0.5432 l -1.0332,0.0000 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="0.0" opacity="0.3" stroke="rgb(84,84,84)" stroke-width="2.06640091435653" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 260.2012,170.2787 l 182.6541,112.2291 "/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.3" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(84,84,84)" stroke-linecap="butt" stroke-miterlimit="10.0"></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.3" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(84,84,84)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 449.6714,286.6959 l -6.1325,-7.1975 l -0.2208,3.2938 l -2.8386,1.6854 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.3" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(84,84,84)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 443.3181,282.7921 l -0.4628,-0.2844 l 0.5409,-0.8803 l -0.0781,1.1647 l -0.4628,-0.2844 l -0.5409,0.8803 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="0.0" opacity="0.3" stroke="rgb(84,84,84)" stroke-width="2.06640091435653" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 518.0865,310.5812 l -14.8672,39.2387 "/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.3" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(84,84,84)" stroke-linecap="butt" stroke-miterlimit="10.0"></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.3" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(84,84,84)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 500.3848,357.3010 l 5.9188,-7.3743 l -3.2767,0.4012 l -2.1882,-2.4718 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.3" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(84,84,84)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 503.0269,350.3279 l 0.1925,-0.5079 l 0.9662,0.3661 l -1.1586,0.1419 l 0.1925,-0.5079 l -0.9662,-0.3661 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="0.0" opacity="0.3" stroke="rgb(84,84,84)" stroke-width="2.06640091435653" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 473.6332,310.5812 l 14.8672,39.2387 "/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.3" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(84,84,84)" stroke-linecap="butt" stroke-miterlimit="10.0"></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.3" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(84,84,84)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 491.3349,357.3010 l -0.4539,-9.4449 l -2.1882,2.4718 l -3.2767,-0.4012 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.3" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(84,84,84)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 488.6929,350.3279 l -0.1925,-0.5079 l 0.9662,-0.3661 l -0.7737,0.8740 l -0.1925,-0.5079 l -0.9662,0.3661 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="0.0" opacity="0.3" stroke="rgb(84,84,84)" stroke-width="2.06640091435653" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 273.3014,239.9761 l -64.1292,42.3138 "/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.3" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(84,84,84)" stroke-linecap="butt" stroke-miterlimit="10.0"></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.3" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(84,84,84)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 202.4948,286.6959 l 9.1155,-2.5139 l -2.8915,-1.5929 l -0.3270,-3.2850 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.3" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(84,84,84)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 208.7188,282.5891 l 0.4534,-0.2992 l 0.5690,0.8624 l -1.0224,-0.5632 l 0.4534,-0.2992 l -0.5690,-0.8624 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="0.0" opacity="0.3" stroke="rgb(84,84,84)" stroke-width="2.06640091435653" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 343.7874,239.9761 l -0.5240,38.7205 "/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.3" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(84,84,84)" stroke-linecap="butt" stroke-miterlimit="10.0"></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.3" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(84,84,84)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 343.1552,286.6959 l 3.0434,-8.9526 l -2.9425,1.4965 l -2.9010,-1.5756 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.3" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(84,84,84)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 343.2561,279.2397 l 0.0073,-0.5431 l 1.0331,0.0140 l -1.0405,0.5292 l 0.0073,-0.5431 l -1.0331,-0.0140 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="0.0" opacity="0.3" stroke="rgb(84,84,84)" stroke-width="2.06640091435653" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 347.6660,239.9761 l 34.1378,109.6862 "/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.3" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(84,84,84)" stroke-linecap="butt" stroke-miterlimit="10.0"></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.3" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(84,84,84)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 384.1812,357.3010 l 0.1175,-9.4551 l -2.3335,2.3351 l -3.2465,-0.5985 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.3" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(84,84,84)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 381.9652,350.1810 l -0.1614,-0.5186 l 0.9865,-0.3070 l -0.8251,0.8257 l -0.1614,-0.5186 l -0.9865,0.3070 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="0.0" opacity="0.3" stroke="rgb(84,84,84)" stroke-width="2.06640091435653" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 306.9297,310.5812 l 58.0062,42.0261 "/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.3" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(84,84,84)" stroke-linecap="butt" stroke-miterlimit="10.0"></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.3" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(84,84,84)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 371.4143,357.3010 l -5.5682,-7.6425 l -0.4704,3.2675 l -2.9584,1.4649 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.3" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(84,84,84)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 365.3758,352.9260 l -0.4399,-0.3187 l 0.6062,-0.8367 l -0.1663,1.1554 l -0.4399,-0.3187 l -0.6062,0.8367 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="0.0" opacity="0.3" stroke="rgb(84,84,84)" stroke-width="2.06640091435653" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 462.2400,239.9761 l -63.4854,110.3899 "/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.3" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(84,84,84)" stroke-linecap="butt" stroke-miterlimit="10.0"></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.3" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(84,84,84)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 394.7663,357.3010 l 7.0163,-6.3390 l -3.2988,-0.1251 l -1.7671,-2.7884 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.3" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(84,84,84)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 398.4838,350.8369 l 0.2708,-0.4709 l 0.8956,0.5151 l -1.1664,-0.0442 l 0.2708,-0.4709 l -0.8956,-0.5151 Z"/></g></svg>
readme.md view
@@ -1,41 +1,27 @@ numhask === -[![Build Status](https://travis-ci.org/tonyday567/numhask.svg)](https://travis-ci.org/tonyday567/numhask) [![Gitter chat](https://badges.gitter.im/numhask/Lobby.png)](https://gitter.im/numhask/Lobby)--A numeric class hierarchy, providing a structure for numbers and functions that combine them.--Field hierarchy------[![Field Hierarchy](other/field.svg)](numhask/other/field.svg)---NumHask class structure------[![NumHask Hierarchy](other/numhask.svg)](numhask/other/numhask.svg)---`numhask` begins with separately named magma-derived classes for addition and multiplication, and then being symetrical in the treatment of the two heirarchies.  A short magma structure is provided with the intention of supplying appropriate classes for operators that are neither addition nor multiplication, but this structure is not hooked up to the main classes.--To be as compatible as practical with the existing haskell ecosystem.  Ints, Integers, Floats, Doubles and Complex are taken from base and given numhask class instances, so they are also Num instances.  Monoid and Semigroup are not used in numhask to maintain compatability.--`numhask` replaces all the relevant numeric operators in Prelude, so you're going to get clashes.+[![Build Status](https://travis-ci.org/tonyday567/numhask.svg)](https://travis-ci.org/tonyday567/numhask) [![Hackage](https://img.shields.io/hackage/v/numhask.svg)](https://hackage.haskell.org/package/numhask) -QuickCheck tests of numeric laws are included.  This also includes tracking where laws are approximate or fail for non-exact numbers.+This package provides numeric classes alternate to the prelude specified in haskell98. -The usual operators (+) and (*) operators are reserved for commutative relationships, with plus and times being used for non-commutative ones.+The numeric class constellation looks somewhat like: -In summary, the library doesn't do anything fancy. But if having to define `(*)` when you just want a `(+)` offends your sensibilities, it may bring some sanity.+![nh](other/nh.svg) -NumHask.Prelude----+Usage+=== -``` {.sourceCode .literate .haskell}-{-# LANGUAGE NoImplicitPrelude #-}+``` haskell+{-# LANGUAGE NegativeLiterals #-}+{-# LANGUAGE RebindableSyntax #-} import NumHask.Prelude ```+See the documentation in the Numhask module for a detailed overview. -'Numhask.Prelude' is designed as a drop-in replacement for Prelude and 'NoImplicitPrelude' is obligatory. Behind the scenes, the module wraps [protolude](https://www.stackage.org/package/protolude).+Develop+=== +```+stack build --test --haddock --file-watch+```
+ src/NumHask.hs view
@@ -0,0 +1,204 @@+{-# LANGUAGE NegativeLiterals #-}+{-# LANGUAGE RebindableSyntax #-}+{-# OPTIONS_GHC -Wall #-}+{-# OPTIONS_HADDOCK prune #-}++-- | Numeric classes.+module NumHask+  ( -- * Usage+    -- $setup++    -- * Overview+    -- $overview+    -- $pictures++    -- * Prelude Mappings+    -- $mapping+    -- $backend++    -- * Extensions+    -- $extensions++    -- * Exports+    module NumHask.Algebra.Additive,+    module NumHask.Algebra.Field,+    module NumHask.Algebra.Group,+    module NumHask.Algebra.Lattice,+    module NumHask.Algebra.Module,+    module NumHask.Algebra.Multiplicative,+    module NumHask.Algebra.Ring,+    module NumHask.Analysis.Metric,+    module NumHask.Data.Complex,+    module NumHask.Data.Integral,+    module NumHask.Data.LogField,+    module NumHask.Data.Rational,+    module NumHask.Data.Positive,+    module NumHask.Exception,+  )+where++import NumHask.Algebra.Additive+import NumHask.Algebra.Field+import NumHask.Algebra.Group+import NumHask.Algebra.Lattice+import NumHask.Algebra.Module+import NumHask.Algebra.Multiplicative+import NumHask.Algebra.Ring+import NumHask.Analysis.Metric+import NumHask.Data.Complex+import NumHask.Data.Integral+import NumHask.Data.LogField+import NumHask.Data.Positive+import NumHask.Data.Rational+import NumHask.Exception++-- $setup+--+-- >>> :set -XRebindableSyntax+-- >>> :set -XNegativeLiterals+-- >>> import NumHask.Prelude+-- >>> 1+1+-- 2++-- $extensions+--+-- [RebindableSyntax](https://ghc.gitlab.haskell.org/ghc/doc/users_guide/exts/rebindable_syntax.html) and [NegativeLiterals](https://ghc.gitlab.haskell.org/ghc/doc/users_guide/exts/negative_literals.html) are both recommended for use with numhask. [LexicalNegation](https://ghc.gitlab.haskell.org/ghc/doc/users_guide/exts/lexical_negation.html) also looks sweet when it arrives.+--+-- As a replacement for the numerical classes, numhask clashes significantly with an unqualified import of the @Prelude@. Either numhask modules should be qualified, or prelude turned off with the NoImplicitPrelude extension, or with RebindableSyntax, which implies NoImplicitPrelude.+--+-- == defaulting+--+-- Without RebindableSyntax, numeric literals default as follows:+--+-- >>> :set -XNoRebindableSyntax+-- >>> :t 1+-- 1 :: Num p => p+--+-- >>> :t 1.0+-- 1.0 :: Fractional p => p+--+-- With RebindableSyntax (which also switches NoImplicitPrelude on) literal numbers change to the numhask types, 'FromInteger' and 'FromRational':+--+-- >>> :set -XRebindableSyntax+-- >>> :t 1+-- 1 :: FromInteger a => a+--+-- >>> :t 1.0+-- 1.0 :: FromRational a => a+--+-- >>> 1+-- 1+--+-- >>> 1.0+-- 1.0+--+-- It is recommended to switch on RebindableSyntax to avoid Num constraints being introduced due to literal defaulting. The extension is a tradeoff, however, and usage comes attached with other non-numeric changes that "NumHask.Prelude" attempts to counteract.+--+-- See See [haskell2010 Section 4.3.4](https://www.haskell.org/onlinereport/haskell2010/haskellch4.html#x10-750004.3) for the nuts and bolts to defaulting.+--+-- The effect of [ExtendedDefaultRules](https://ghc.gitlab.haskell.org/ghc/doc/users_guide/ghci.html#extension-ExtendedDefaultRules) in ghci or switched on as an extension also need to be understood. It can lead to unusual interactions with numerics and strange error messages at times because it adds @()@ and @[]@ to the start of the type defaulting list.+--+-- == Negatives+--+-- Without [NegativeLiterals](https://ghc.gitlab.haskell.org/ghc/doc/users_guide/exts/negative_literals.html), GHC and Haskell often reads a negative as subtraction rather than a minus.+--+-- > :set -XNoNegativeLiterals+-- > :t Point 1 -2+-- Point 1 -2+--   :: (Subtractive (Point a), FromInteger a,+--       FromInteger (a -> Point a)) =>+--      a -> Pair a+-- ...+--+-- > :set -XNegativeLiterals+-- > :t Point 1 -2+-- Point 1 -2 :: FromInteger a => Point a+--+-- > Point 1 -2+-- Point 1 -2+--+-- [LexicalNegation](https://ghc.gitlab.haskell.org/ghc/doc/users_guide/exts/lexical_negation.html) is coming soon as a valid replacement for NegativeLiterals and will tighten things up further.++-- $overview+-- numhask is largely a set of classes that can replace the 'GHC.Num.Num' class and it's descendents. Principles that have guided design include:+--+-- - __/balanced class density/__. The numeric heirarchy begins with addition and multiplication, choosing not to build from a 'Magma' base. Whilst not being as principled as other approaches, this circumvents the instance explosion problems of Haskell whilst maintaining clarity of class purpose.+--+-- - __/operator-first/__. In most cases, a class exists to define useful operators. The exceptions are 'Distributive', 'Ring' and 'Field', which are collections of operators representing major teleological fault lines.+--+-- - __/lawful/__. Most classes have laws associated with them that serve to relate class operators together in a meaningful way.+--+-- - __/low-impact/__. The library attempts to fit in with the rest of the Haskell ecosystem. It provides instances for common numbers: 'GHC.Num.Int', 'GHC.Num.Integer', 'GHC.Float.Double', 'GHC.Float.Float' and the Word classes. It avoids name (or idea) clashes with other popular libraries and adopts conventions in the <https://hackage.haskell.org/package/base/docs/Prelude.html current prelude> where they make sense.+--+-- - __/proof-of-concept/__. The library may be below industrial-strength depending on a definition of this term. At the same time, correspondence around improving the library is most welcome.++-- $pictures+--+-- The class heirarchy looks somewhat like this:+-- ![classes](other/nh.svg)+--+-- If the base started with magma, and the library tolerated clashing with 'Data.Semigroup' and 'Data.Monoid' in base, it would look like:+--+-- ![magma classes](other/nhmagma.svg)+--+-- These first two levels, contained in 'NumHask.Algebra.Group' can be considered "morally" super-classes.++-- $mapping+--+-- 'GHC.Num' is a very old part of haskell, and is virtually unchanged since it's specification in [haskell98](https://www.haskell.org/onlinereport/standard-prelude.html).+--+-- A deconstruction of 'GHC.Num.Num' and mapping to numhask.+--+-- > -- | Basic numeric class.+-- > class  Num a  where+-- >    {-# MINIMAL (+), (*), abs, signum, fromInteger, (negate | (-)) #-}+-- >+-- >    (+), (-), (*)       :: a -> a -> a+-- >    -- | Unary negation.+-- >    negate              :: a -> a+--+-- '(+)' is an operator of the 'Additive' class+--+-- '(-)' & 'negate' are functions in the 'Subtractive' class, and+--+-- '(*)' is an operator of the 'Multiplicative' class.+--+-- 'zero' and 'one' are also introduced to the numeric heirarchy.+--+-- >    -- | Absolute value.+-- >    abs                 :: a -> a+-- >    -- | Sign of a number.+-- >    -- The functions 'abs' and 'signum' should satisfy the law:+-- >    --+-- >    -- > abs x * signum x == x+-- >    --+-- >    -- For real numbers, the 'signum' is either @-1@ (negative), @0@ (zero)+-- >    -- or @1@ (positive).+-- >    signum              :: a -> a+--+-- 'abs' is a function in the 'NumHask.Analysis.Metric.Signed' class. The concept of an absolute value can also include situations where the domain and codomain are different, and 'norm' as a function in the 'NumHask.Analysis.Metric.Norm' class is supplied for these cases.+--+--  'NumHask.Analysis.Metric.sign' replaces 'GHC.Num.signum', because signum is simply a naming crime. 'NumHask.Analysis.Metric.basis' can also be seen as a generalisation of sign.+--+-- >    -- | Conversion from an 'Integer'.+-- >    -- An integer literal represents the application of the function+-- >    -- 'fromInteger' to the appropriate value of type 'Integer',+-- >    -- so such literals have type @('Num' a) => a@.+-- >    fromInteger         :: Integer -> a+--+-- 'FromInteger' becomes its own class and 'FromIntegral' is introduced to polymorphise the covariant.+--+-- Mappings from other areas of prelude include:\+--+-- 'GHC.Real.Integral' becomes 'Integral' and a polymorphic 'ToIntegral' is introduced.+--+-- 'GHC.Real.Fractional' is roughly synonymous to 'Field' together with a polymorphic 'FromRatio'.+--+-- 'GHC.Real.RealFrac' becomes the polymorphic 'QuotientField'+--+-- 'GHC.Float.Floating' is split into 'ExpField' and 'TrigField'+--+-- 'GHC.Float.RealFloat' is not attempted. Life is too short.++-- $backend+-- NumHask imports [protolude](https://hackage.haskell.org/package/protolude) as a base prelude with some minor tweaks.
− src/NumHask/Algebra/Abstract.hs
@@ -1,70 +0,0 @@-{-# OPTIONS_GHC -Wall #-}---- | The abstract algebraic class structure of a number.-module NumHask.Algebra.Abstract-  ( -- * Mapping from Num-    ---    -- $numMap-    module NumHask.Algebra.Abstract.Group,-    module NumHask.Algebra.Abstract.Additive,-    module NumHask.Algebra.Abstract.Multiplicative,-    module NumHask.Algebra.Abstract.Ring,-    module NumHask.Algebra.Abstract.Field,-    module NumHask.Algebra.Abstract.Module,-    module NumHask.Algebra.Abstract.Action,-    module NumHask.Algebra.Abstract.Lattice,-  )-where--import NumHask.Algebra.Abstract.Action-import NumHask.Algebra.Abstract.Additive-import NumHask.Algebra.Abstract.Field-import NumHask.Algebra.Abstract.Group-import NumHask.Algebra.Abstract.Lattice-import NumHask.Algebra.Abstract.Module-import NumHask.Algebra.Abstract.Multiplicative-import NumHask.Algebra.Abstract.Ring---- $numMap------ `Num` is a very old part of haskell, and a lot of different numeric concepts are tossed in there. The closest analogue in numhask is the `Ring` class, which magmaines the classical `+`, `-` and `*`, together with the Distributive  laws.------ ![ring example](other/ring.svg)------ No attempt is made, however, to reconstruct the particular magmaination of laws and classes that represent the old `Num`.  A rough mapping of `Num` to numhask classes follows:------ > -- | Basic numeric class.--- > class  Num a  where--- >    {-# MINIMAL (+), (*), abs, signum, fromInteger, (negate | (-)) #-}--- >--- >    (+), (-), (*)       :: a -> a -> a--- >    -- | Unary negation.--- >    negate              :: a -> a------ `+` is a function of the `Additive` class,--- `-` is a function of the `Subtractive` class, and--- `*` is a function of the `Multiplicative` class.--- `negate` is specifically in the `Subtractive` class.  There are many useful constructions between negate and (-), involving cancellative properties.------ >    -- | Absolute value.--- >    abs                 :: a -> a--- >    -- | Sign of a number.--- >    -- The functions 'abs' and 'signum' should satisfy the law:--- >    ----- >    -- > abs x * signum x == x--- >    ----- >    -- For real numbers, the 'signum' is either @-1@ (negative), @0@ (zero)--- >    -- or @1@ (positive).--- >    signum              :: a -> a------ `abs` is a function in the `Signed` class.  The concept of an absolute value of a number can include situations where the domain and codomain are different, and `size` as a function in the `Normed` class is supplied for these cases.------  `sign` replaces `signum`, because signum is a heinous name.------ >    -- | Conversion from an 'Integer'.--- >    -- An integer literal represents the application of the function--- >    -- 'fromInteger' to the appropriate value of type 'Integer',--- >    -- so such literals have type @('Num' a) => a@.--- >    fromInteger         :: Integer -> a------ `fromInteger` is given its own class `FromInteger`
− src/NumHask/Algebra/Abstract/Action.hs
@@ -1,54 +0,0 @@-{-# LANGUAGE FlexibleContexts #-}-{-# LANGUAGE MultiParamTypeClasses #-}-{-# LANGUAGE TypeFamilies #-}-{-# OPTIONS_GHC -Wall #-}---- | Action-module NumHask.Algebra.Abstract.Action-  ( Actor,-    AdditiveAction (..),-    SubtractiveAction (..),-    MultiplicativeAction (..),-    DivisiveAction (..),-  )-where--import NumHask.Algebra.Abstract.Additive-import NumHask.Algebra.Abstract.Multiplicative---- | a type class to represent an action on elements of a higher-kinded number-type family Actor h--class-  (Additive (Actor h)) =>-  AdditiveAction h where-  infixl 6 .+-  (.+) :: h -> Actor h -> h--  infixl 6 +.-  (+.) :: Actor h -> h -> h--class-  (Subtractive (Actor h)) =>-  SubtractiveAction h where-  infixl 6 .--  (.-) :: h -> Actor h -> h--  infixl 6 -.-  (-.) :: Actor h -> h -> h--class-  (Multiplicative (Actor h)) =>-  MultiplicativeAction h where-  infixl 7 .*-  (.*) :: h -> Actor h -> h-  infixl 7 *.-  (*.) :: Actor h -> h -> h--class-  (Divisive (Actor h)) =>-  DivisiveAction h where-  infixl 7 ./-  (./) :: h -> Actor h -> h-  infixl 7 /.-  (/.) :: Actor h -> h -> h
− src/NumHask/Algebra/Abstract/Additive.hs
@@ -1,157 +0,0 @@-{-# OPTIONS_GHC -Wall #-}---- | Additive-module NumHask.Algebra.Abstract.Additive-  ( Additive (..),-    sum,-    Subtractive (..),-  )-where--import Data.Int (Int16, Int32, Int64, Int8)-import Data.Word (Word, Word16, Word32, Word64, Word8)-import GHC.Natural (Natural (..))-import Prelude (Bool, Double, Float, Int, Integer)-import qualified Prelude as P---- | For practical reasons, 'Additive' has no super classes. Using `Associative` and 'Unital' from this library, or using 'Semigroup' and 'Monoid' from base tends to complexify the interface once you start having to disinguish between (say) monoidal addition and monoidal multiplication.------ > zero + a == a--- > a + zero == a--- > (a + b) + c == a + (b + c)--- > a + b == b + a------ By convention, (+) is regarded as commutative, but this is not universal, and the introduction of another symbol which means non-commutative multiplication seems a bit dogmatic.-class Additive a where-  infixl 6 +-  (+) :: a -> a -> a--  zero :: a---- | Compute the sum of a 'Foldable'.-sum :: (Additive a, P.Foldable f) => f a -> a-sum = P.foldr (+) zero---- |--- > a - a = zero--- > negate a = zero - a--- > negate a + a = zero--- > a + negate a = zero-class (Additive a) => Subtractive a where-  negate :: a -> a--  infixl 6 --  (-) :: a -> a -> a-  (-) a b = a + negate b--instance Additive Double where-  (+) = (P.+)-  zero = 0--instance Subtractive Double where-  negate = P.negate--instance Additive Float where-  (+) = (P.+)-  zero = 0--instance Subtractive Float where-  negate = P.negate--instance Additive Int where-  (+) = (P.+)-  zero = 0--instance Subtractive Int where-  negate = P.negate--instance Additive Integer where-  (+) = (P.+)-  zero = 0--instance Subtractive Integer where-  negate = P.negate--instance Additive Bool where-  (+) = (P.||)-  zero = P.False--instance Subtractive Bool where-  negate = P.not--instance Additive Natural where-  (+) = (P.+)-  zero = 0--instance Subtractive Natural where-  negate = P.negate--instance Additive Int8 where-  (+) = (P.+)-  zero = 0--instance Subtractive Int8 where-  negate = P.negate--instance Additive Int16 where-  (+) = (P.+)-  zero = 0--instance Subtractive Int16 where-  negate = P.negate--instance Additive Int32 where-  (+) = (P.+)-  zero = 0--instance Subtractive Int32 where-  negate = P.negate--instance Additive Int64 where-  (+) = (P.+)-  zero = 0--instance Subtractive Int64 where-  negate = P.negate--instance Additive Word where-  (+) = (P.+)-  zero = 0--instance Subtractive Word where-  negate = P.negate--instance Additive Word8 where-  (+) = (P.+)-  zero = 0--instance Subtractive Word8 where-  negate = P.negate--instance Additive Word16 where-  (+) = (P.+)-  zero = 0--instance Subtractive Word16 where-  negate = P.negate--instance Additive Word32 where-  (+) = (P.+)-  zero = 0--instance Subtractive Word32 where-  negate = P.negate--instance Additive Word64 where-  (+) = (P.+)-  zero = 0--instance Subtractive Word64 where-  negate = P.negate--instance Additive b => Additive (a -> b) where-  f + f' = \a -> f a + f' a-  zero _ = zero--instance Subtractive b => Subtractive (a -> b) where-  negate f = negate P.. f
− src/NumHask/Algebra/Abstract/Field.hs
@@ -1,257 +0,0 @@-{-# LANGUAGE DefaultSignatures #-}-{-# LANGUAGE FlexibleContexts #-}-{-# LANGUAGE FlexibleInstances #-}-{-# LANGUAGE MultiParamTypeClasses #-}-{-# LANGUAGE ScopedTypeVariables #-}-{-# LANGUAGE TypeApplications #-}-{-# OPTIONS_GHC -Wall #-}---- | Field classes-module NumHask.Algebra.Abstract.Field-  ( Field,-    ExpField (..),-    QuotientField (..),-    UpperBoundedField (..),-    LowerBoundedField (..),-    TrigField (..),-    half,-  )-where--import Data.Bool (bool)-import NumHask.Algebra.Abstract.Additive-import NumHask.Algebra.Abstract.Multiplicative-import NumHask.Algebra.Abstract.Ring-import NumHask.Data.Integral-import Prelude ((.))-import qualified Prelude as P---- | A <https://en.wikipedia.org/wiki/Field_(mathematics) Field> is a set---   on which addition, subtraction, multiplication, and division are defined. It is also assumed that multiplication is distributive over addition.------ A summary of the rules thus inherited from super-classes of Field------ > zero + a == a--- > a + zero == a--- > (a + b) + c == a + (b + c)--- > a + b == b + a--- > a - a = zero--- > negate a = zero - a--- > negate a + a = zero--- > a + negate a = zero--- > one * a == a--- > a * one == a--- > (a * b) * c == a * (b * c)--- > a * (b + c) == a * b + a * c--- > (a + b) * c == a * c + b * c--- > a * zero == zero--- > zero * a == zero--- > a * b == b * a--- > a / a = one--- > recip a = one / a--- > recip a * a = one--- > a * recip a = one-class-  (Distributive a, Subtractive a, Divisive a) =>-  Field a--instance Field P.Double--instance Field P.Float--instance Field b => Field (a -> b)---- | A hyperbolic field class------ > sqrt . (**2) == identity--- > log . exp == identity--- > for +ive b, a != 0,1: a ** logBase a b ≈ b-class-  (Field a) =>-  ExpField a where-  exp :: a -> a-  log :: a -> a-  logBase :: a -> a -> a-  logBase a b = log b / log a-  (**) :: a -> a -> a-  (**) a b = exp (log a * b)-  sqrt :: a -> a-  sqrt a = a ** (one / (one + one))--instance ExpField P.Double where-  exp = P.exp-  log = P.log-  (**) = (P.**)--instance ExpField P.Float where-  exp = P.exp-  log = P.log-  (**) = (P.**)--instance ExpField b => ExpField (a -> b) where-  exp f = exp . f-  log f = log . f-  logBase f f' a = logBase (f a) (f' a)-  f ** f' = \a -> f a ** f' a-  sqrt f = sqrt . f---- > a - one < floor a <= a <= ceiling a < a + one--- > round a == floor (a + one/(one+one))----class (Field a, Subtractive a, Multiplicative b, Additive b) => QuotientField a b where-  properFraction :: a -> (b, a)--  round :: a -> b-  default round :: (P.Ord a, P.Ord b, Subtractive b, Integral b) => a -> b-  round x = case properFraction x of-    (n, r) ->-      let m = bool (n + one) (n - one) (r P.< zero)-          half_down = abs' r - (one / (one + one))-          abs' a-            | a P.< zero = negate a-            | P.otherwise = a-       in case P.compare half_down zero of-            P.LT -> n-            P.EQ -> bool m n (even n)-            P.GT -> m--  ceiling :: a -> b-  default ceiling :: (P.Ord a) => a -> b-  ceiling x = bool n (n + one) (r P.>= zero)-    where-      (n, r) = properFraction x--  floor :: a -> b-  default floor :: (P.Ord a, Subtractive b) => a -> b-  floor x = bool n (n - one) (r P.< zero)-    where-      (n, r) = properFraction x--  truncate :: a -> b-  default truncate :: (P.Ord a) => a -> b-  truncate x = bool (ceiling x) (floor x) (x P.> zero)--instance QuotientField P.Float P.Integer where-  properFraction = P.properFraction--instance QuotientField P.Double P.Integer where-  properFraction = P.properFraction--instance QuotientField P.Float P.Int where-  properFraction = P.properFraction--instance QuotientField P.Double P.Int where-  properFraction = P.properFraction--instance QuotientField b c => QuotientField (a -> b) (a -> c) where-  properFraction f = (P.fst . frac, P.snd . frac)-    where-      frac a = properFraction @b @c (f a)--  round f = round . f--  ceiling f = ceiling . f--  floor f = floor . f--  truncate f = truncate . f---- | A bounded field includes the concepts of infinity and NaN, thus moving away from error throwing.------ > one / zero + infinity == infinity--- > infinity + a == infinity--- > zero / zero != nan------ Note the tricky law that, although nan is assigned to zero/zero, they are never-the-less not equal. A committee decided this.-class-  (Field a) =>-  UpperBoundedField a where-  infinity :: a-  infinity = one / zero--  nan :: a-  nan = zero / zero--instance UpperBoundedField P.Float--instance UpperBoundedField P.Double--instance UpperBoundedField b => UpperBoundedField (a -> b) where-  infinity _ = infinity-  nan _ = nan--class-  (Subtractive a, Field a) =>-  LowerBoundedField a where-  negInfinity :: a-  negInfinity = negate (one / zero)--instance LowerBoundedField P.Float--instance LowerBoundedField P.Double--instance LowerBoundedField b => LowerBoundedField (a -> b) where-  negInfinity _ = negInfinity---- | Trigonometric Field-class-  (Field a) =>-  TrigField a where-  pi :: a-  sin :: a -> a-  cos :: a -> a-  tan :: a -> a-  tan x = sin x / cos x-  asin :: a -> a-  acos :: a -> a-  atan :: a -> a-  sinh :: a -> a-  cosh :: a -> a-  tanh :: a -> a-  tanh x = sinh x / cosh x-  asinh :: a -> a-  acosh :: a -> a-  atanh :: a -> a--instance TrigField P.Double where-  pi = P.pi-  sin = P.sin-  cos = P.cos-  asin = P.asin-  acos = P.acos-  atan = P.atan-  sinh = P.sinh-  cosh = P.cosh-  asinh = P.sinh-  acosh = P.acosh-  atanh = P.atanh--instance TrigField P.Float where-  pi = P.pi-  sin = P.sin-  cos = P.cos-  asin = P.asin-  acos = P.acos-  atan = P.atan-  sinh = P.sinh-  cosh = P.cosh-  asinh = P.sinh-  acosh = P.acosh-  atanh = P.atanh--instance TrigField b => TrigField (a -> b) where-  pi _ = pi-  sin f = sin . f-  cos f = cos . f-  asin f = asin . f-  acos f = acos . f-  atan f = atan . f-  sinh f = sinh . f-  cosh f = cosh . f-  asinh f = asinh . f-  acosh f = acosh . f-  atanh f = atanh . f---- | A 'half' is a 'Field' because it requires addition, multiplication and division to be computed.-half :: (Field a) => a-half = one / two
− src/NumHask/Algebra/Abstract/Group.hs
@@ -1,127 +0,0 @@-{-# LANGUAGE FlexibleInstances #-}-{-# LANGUAGE UndecidableInstances #-}-{-# OPTIONS_GHC -Wall #-}---- | The Group hierarchy-module NumHask.Algebra.Abstract.Group-  ( Magma (..),-    Unital (..),-    Associative,-    Commutative,-    Absorbing (..),-    Invertible (..),-    Idempotent,-    Group,-    AbelianGroup,-  )-where--import Prelude---- * Magma structure---- | A <https://en.wikipedia.org/wiki/Magma_(algebra) Magma> is a tuple (T,magma) consisting of------ - a type a, and------ - a function (magma) :: T -> T -> T------ The mathematical laws for a magma are:------ - magma is defined for all possible pairs of type T, and------ - magma is closed in the set of all possible values of type T------ or, more tersly,------ > ∀ a, b ∈ T: a magma b ∈ T------ These laws are true by construction in haskell: the type signature of 'magma' and the above mathematical laws are synonyms.-class Magma a where-  magma :: a -> a -> a--instance Magma b => Magma (a -> b) where-  {-# INLINE magma #-}-  f `magma` g = \a -> f a `magma` g a---- | A Unital Magma is a magma with an---   <https://en.wikipedia.org/wiki/Identity_element identity element> (the---   unit).------ > unit magma a = a--- > a magma unit = a-class-  Magma a =>-  Unital a where-  unit :: a--instance Unital b => Unital (a -> b) where-  {-# INLINE unit #-}-  unit _ = unit---- | An Associative Magma------ > (a magma b) magma c = a magma (b magma c)-class-  Magma a =>-  Associative a--instance Associative b => Associative (a -> b)---- | A Commutative Magma is a Magma where the binary operation is--- <https://en.wikipedia.org/wiki/Commutative_property commutative>.------ > a magma b = b magma a-class-  Magma a =>-  Commutative a--instance Commutative b => Commutative (a -> b)---- | An Invertible Magma------ > ∀ a,b ∈ T: inv a `magma` (a `magma` b) = b = (b `magma` a) `magma` inv a-class-  Magma a =>-  Invertible a where-  inv :: a -> a--instance Invertible b => Invertible (a -> b) where-  {-# INLINE inv #-}-  inv f = inv . f---- | A <https://en.wikipedia.org/wiki/Group_(mathematics) Group> is a---   Associative, Unital and Invertible Magma.-class (Associative a, Unital a, Invertible a) => Group a--instance (Associative a, Unital a, Invertible a) => Group a---- | An Absorbing is a Magma with an---   <https://en.wikipedia.org/wiki/Absorbing_element Absorbing Element>------ > a `times` absorb = absorb-class-  Magma a =>-  Absorbing a where-  absorb :: a--instance Absorbing b => Absorbing (a -> b) where-  {-# INLINE absorb #-}-  absorb _ = absorb---- | An Idempotent Magma is a magma where every element is---   <https://en.wikipedia.org/wiki/Idempotence Idempotent>.------ > a magma a = a-class-  Magma a =>-  Idempotent a--instance Idempotent b => Idempotent (a -> b)---- | An <https://en.wikipedia.org/wiki/Abelian_group Abelian Group> is an---   Associative, Unital, Invertible and Commutative Magma . In other words, it---   is a Commutative Group-class (Associative a, Unital a, Invertible a, Commutative a) => AbelianGroup a--instance (Associative a, Unital a, Invertible a, Commutative a) => AbelianGroup a
− src/NumHask/Algebra/Abstract/Lattice.hs
@@ -1,255 +0,0 @@-{-# LANGUAGE FlexibleInstances #-}-{-# LANGUAGE UndecidableInstances #-}-{-# OPTIONS_GHC -Wall #-}--module NumHask.Algebra.Abstract.Lattice where--import Data.Int (Int16, Int32, Int64, Int8)-import Data.Word (Word16, Word32, Word64, Word8)-import GHC.Natural (Natural (..))-import NumHask.Algebra.Abstract.Field-import Data.Bool-import Data.Eq-import GHC.Float (Float, Double)-import GHC.Int (Int)-import GHC.Num (Integer)-import GHC.Word (Word)-import Data.Ord (Ord(..))-import GHC.Enum (Bounded(..))-import Data.Function (const)---- | A algebraic structure with element joins: <http://en.wikipedia.org/wiki/Semilattice>------ > Associativity: x \/ (y \/ z) == (x \/ y) \/ z--- > Commutativity: x \/ y == y \/ x--- > Idempotency:   x \/ x == x-class (Eq a) => JoinSemiLattice a where-  infixr 5 \/-  (\/) :: a -> a -> a---- | The partial ordering induced by the join-semilattice structure-joinLeq :: (JoinSemiLattice a) => a -> a -> Bool-joinLeq x y = (x \/ y) == y---- | A algebraic structure with element meets: <http://en.wikipedia.org/wiki/Semilattice>------ > Associativity: x /\ (y /\ z) == (x /\ y) /\ z--- > Commutativity: x /\ y == y /\ x--- > Idempotency:   x /\ x == x-class (Eq a) => MeetSemiLattice a where-  infixr 6 /\-  (/\) :: a -> a -> a---- | The partial ordering induced by the meet-semilattice structure-meetLeq :: (MeetSemiLattice a) => a -> a -> Bool-meetLeq x y = (x /\ y) == x---- | The combination of two semi lattices makes a lattice if the absorption law holds:--- see <http://en.wikipedia.org/wiki/Absorption_law> and <http://en.wikipedia.org/wiki/Lattice_(order)>------ > Absorption: a \/ (a /\ b) == a /\ (a \/ b) == a-class (JoinSemiLattice a, MeetSemiLattice a) => Lattice a--instance (JoinSemiLattice a, MeetSemiLattice a) => Lattice a---- | A join-semilattice with an identity element 'bottom' for '\/'.------ > Identity: x \/ bottom == x-class JoinSemiLattice a => BoundedJoinSemiLattice a where-  bottom :: a---- | A meet-semilattice with an identity element 'top' for '/\'.------ > Identity: x /\ top == x-class MeetSemiLattice a => BoundedMeetSemiLattice a where-  top :: a---- | Lattices with both bounds-class (JoinSemiLattice a, MeetSemiLattice a, BoundedJoinSemiLattice a, BoundedMeetSemiLattice a) => BoundedLattice a--instance (JoinSemiLattice a, MeetSemiLattice a, BoundedJoinSemiLattice a, BoundedMeetSemiLattice a) => BoundedLattice a--instance JoinSemiLattice Float where-  (\/) = min--instance MeetSemiLattice Float where-  (/\) = max--instance JoinSemiLattice Double where-  (\/) = min--instance MeetSemiLattice Double where-  (/\) = max--instance JoinSemiLattice Int where-  (\/) = min--instance MeetSemiLattice Int where-  (/\) = max--instance JoinSemiLattice Integer where-  (\/) = min--instance MeetSemiLattice Integer where-  (/\) = max--instance JoinSemiLattice Bool where-  (\/) = (||)--instance MeetSemiLattice Bool where-  (/\) = (&&)--instance JoinSemiLattice Natural where-  (\/) = min--instance MeetSemiLattice Natural where-  (/\) = max--instance JoinSemiLattice Int8 where-  (\/) = min--instance MeetSemiLattice Int8 where-  (/\) = max--instance JoinSemiLattice Int16 where-  (\/) = min--instance MeetSemiLattice Int16 where-  (/\) = max--instance JoinSemiLattice Int32 where-  (\/) = min--instance MeetSemiLattice Int32 where-  (/\) = max--instance JoinSemiLattice Int64 where-  (\/) = min--instance MeetSemiLattice Int64 where-  (/\) = max--instance JoinSemiLattice Word where-  (\/) = min--instance MeetSemiLattice Word where-  (/\) = max--instance JoinSemiLattice Word8 where-  (\/) = min--instance MeetSemiLattice Word8 where-  (/\) = max--instance JoinSemiLattice Word16 where-  (\/) = min--instance MeetSemiLattice Word16 where-  (/\) = max--instance JoinSemiLattice Word32 where-  (\/) = min--instance MeetSemiLattice Word32 where-  (/\) = max--instance JoinSemiLattice Word64 where-  (\/) = min--instance MeetSemiLattice Word64 where-  (/\) = max--instance (Eq (a -> b), JoinSemiLattice b) => JoinSemiLattice (a -> b) where-  f \/ f' = \a -> f a \/ f' a--instance (Eq (a -> b), MeetSemiLattice b) => MeetSemiLattice (a -> b) where-  f /\ f' = \a -> f a /\ f' a---- from here--instance BoundedJoinSemiLattice Float where-  bottom = negInfinity--instance BoundedMeetSemiLattice Float where-  top = infinity--instance BoundedJoinSemiLattice Double where-  bottom = negInfinity--instance BoundedMeetSemiLattice Double where-  top = infinity--instance BoundedJoinSemiLattice Int where-  bottom = minBound--instance BoundedMeetSemiLattice Int where-  top = maxBound--instance BoundedJoinSemiLattice Bool where-  bottom = False--instance BoundedMeetSemiLattice Bool where-  top = True--instance BoundedJoinSemiLattice Natural where-  bottom = 0--instance BoundedJoinSemiLattice Int8 where-  bottom = minBound--instance BoundedMeetSemiLattice Int8 where-  top = maxBound--instance BoundedJoinSemiLattice Int16 where-  bottom = minBound--instance BoundedMeetSemiLattice Int16 where-  top = maxBound--instance BoundedJoinSemiLattice Int32 where-  bottom = minBound--instance BoundedMeetSemiLattice Int32 where-  top = maxBound--instance BoundedJoinSemiLattice Int64 where-  bottom = minBound--instance BoundedMeetSemiLattice Int64 where-  top = maxBound--instance BoundedJoinSemiLattice Word where-  bottom = minBound--instance BoundedMeetSemiLattice Word where-  top = maxBound--instance BoundedJoinSemiLattice Word8 where-  bottom = minBound--instance BoundedMeetSemiLattice Word8 where-  top = maxBound--instance BoundedJoinSemiLattice Word16 where-  bottom = minBound--instance BoundedMeetSemiLattice Word16 where-  top = maxBound--instance BoundedJoinSemiLattice Word32 where-  bottom = minBound--instance BoundedMeetSemiLattice Word32 where-  top = maxBound--instance BoundedJoinSemiLattice Word64 where-  bottom = minBound--instance BoundedMeetSemiLattice Word64 where-  top = maxBound--instance (Eq (a -> b), BoundedJoinSemiLattice b) => BoundedJoinSemiLattice (a -> b) where-  bottom = const bottom--instance (Eq (a -> b), BoundedMeetSemiLattice b) => BoundedMeetSemiLattice (a -> b) where-  top = const top
− src/NumHask/Algebra/Abstract/Module.hs
@@ -1,23 +0,0 @@-{-# LANGUAGE FlexibleContexts #-}-{-# LANGUAGE MultiParamTypeClasses #-}-{-# OPTIONS_GHC -Wall #-}---- | Algebra for Modules-module NumHask.Algebra.Abstract.Module-  ( Module,-  )-where--import NumHask.Algebra.Abstract.Action-import NumHask.Algebra.Abstract.Ring---- | A <https://en.wikipedia.org/wiki/Module_(mathematics) Module> over r a is---   a (Ring a), an abelian (Group r a) and a scalar multiplier (.*, *.) with the---   laws:------ > a .* one == a--- > (a + b) .* c == (a .* c) + (b .* c)--- > c *. (a + b) == (c *. a) + (c *. b)--- > a .* zero == zero--- > a .* b == b *. a-class (Distributive (Actor h), MultiplicativeAction h) => Module h
− src/NumHask/Algebra/Abstract/Multiplicative.hs
@@ -1,119 +0,0 @@-{-# OPTIONS_GHC -Wall #-}---- | Multiplicative-module NumHask.Algebra.Abstract.Multiplicative-  ( Multiplicative (..),-    product,-    Divisive (..),-  )-where--import Data.Int (Int16, Int32, Int64, Int8)-import Data.Word (Word, Word16, Word32, Word64, Word8)-import GHC.Natural (Natural (..))-import Prelude (Double, Float, Int, Integer)-import qualified Prelude as P---- | For practical reasons, 'Multiplicative' has no super classes. Using 'Associative' and 'Unital' from this library, or using 'Semigroup' and 'Monoid' from base tends to complexify the interface once you start having to disinguish between (say) monoidal addition and monoidal multiplication.------ > one * a == a--- > a * one == a--- > (a * b) * c == a * (b * c)--- > a * b == b * a------ By convention, (*) is regarded as commutative, but this is not universal, and the introduction of another symbol which means non-commutative multiplication seems a bit dogmatic.-class Multiplicative a where-  infixl 7 *-  (*) :: a -> a -> a--  one :: a---- | Compute the product of a 'Foldable'.-product :: (Multiplicative a, P.Foldable f) => f a -> a-product = P.foldr (*) one---- |------ > a / a = one--- > recip a = one / a--- > recip a * a = one--- > a * recip a = one-class (Multiplicative a) => Divisive a where-  recip :: a -> a--  infixl 7 /-  (/) :: a -> a -> a-  (/) a b = a * recip b--instance Multiplicative Double where-  (*) = (P.*)-  one = 1.0--instance Divisive Double where-  recip = P.recip--instance Multiplicative Float where-  (*) = (P.*)-  one = 1.0--instance Divisive Float where-  recip = P.recip--instance Multiplicative Int where-  (*) = (P.*)-  one = 1--instance Multiplicative Integer where-  (*) = (P.*)-  one = 1--instance Multiplicative P.Bool where-  (*) = (P.&&)-  one = P.True--instance Multiplicative Natural where-  (*) = (P.*)-  one = 1--instance Multiplicative Int8 where-  (*) = (P.*)-  one = 1--instance Multiplicative Int16 where-  (*) = (P.*)-  one = 1--instance Multiplicative Int32 where-  (*) = (P.*)-  one = 1--instance Multiplicative Int64 where-  (*) = (P.*)-  one = 1--instance Multiplicative Word where-  (*) = (P.*)-  one = 1--instance Multiplicative Word8 where-  (*) = (P.*)-  one = 1--instance Multiplicative Word16 where-  (*) = (P.*)-  one = 1--instance Multiplicative Word32 where-  (*) = (P.*)-  one = 1--instance Multiplicative Word64 where-  (*) = (P.*)-  one = 1--instance Multiplicative b => Multiplicative (a -> b) where-  f * f' = \a -> f a * f' a-  one _ = one--instance Divisive b => Divisive (a -> b) where-  recip f = recip P.. f
− src/NumHask/Algebra/Abstract/Ring.hs
@@ -1,170 +0,0 @@-{-# LANGUAGE FlexibleInstances #-}-{-# LANGUAGE UndecidableInstances #-}-{-# OPTIONS_GHC -Wall #-}---- | Ring-module NumHask.Algebra.Abstract.Ring-  ( Distributive,-    Semiring,-    Ring,-    IntegralDomain,-    StarSemiring (..),-    KleeneAlgebra,-    InvolutiveRing (..),-    two,-  )-where--import Data.Int (Int16, Int32, Int64, Int8)-import Data.Word (Word, Word16, Word32, Word64, Word8)-import GHC.Natural (Natural (..))-import NumHask.Algebra.Abstract.Additive-import NumHask.Algebra.Abstract.Group-import NumHask.Algebra.Abstract.Multiplicative-import qualified Prelude as P---- | <https://en.wikipedia.org/wiki/Distributive_property Distributive> laws------ > a * (b + c) == a * b + a * c--- > (a * b) * c == a * c + b * c--- > zero * a == zero--- > a * zero == zero------ The sneaking in of the <https://en.wikipedia.org/wiki/Absorbing_element annihilation> laws here glosses over the possibility that the multiplicative zero element does not have to correspond with the additive unital zero.-class-  (Additive a, Multiplicative a) =>-  Distributive a--instance Distributive P.Double--instance Distributive P.Float--instance Distributive P.Int--instance Distributive P.Integer--instance Distributive Natural--instance Distributive Int8--instance Distributive Int16--instance Distributive Int32--instance Distributive Int64--instance Distributive Word--instance Distributive Word8--instance Distributive Word16--instance Distributive Word32--instance Distributive Word64--instance Distributive P.Bool--instance Distributive b => Distributive (a -> b)---- | A <https://en.wikipedia.org/wiki/Semiring Semiring> is commutative monoidal under addition, has a monoidal multiplication operator (not necessarily commutative), and where multiplication distributes over addition.-class-  (Distributive a) =>-  Semiring a--instance-  (Distributive a) =>-  Semiring a---- | A <https://en.wikipedia.org/wiki/Ring_(mathematics) Ring> is an abelian---   group under addition and monoidal under multiplication, and where multiplication---   distributes over addition.-class-  (Distributive a, Subtractive a) =>-  Ring a--instance-  (Distributive a, Subtractive a) =>-  Ring a---- | An <https://en.wikipedia.org/wiki/Integral_domain Integral Domain>---   generalizes a ring of integers by requiring the product of any two nonzero---   elements to be nonzero. This means that if a ≠ 0, an equality ab = ac---   implies b = c.-class-  (Distributive a) =>-  IntegralDomain a--instance IntegralDomain P.Double--instance IntegralDomain P.Float--instance IntegralDomain b => IntegralDomain (a -> b)---- | A <https://en.wikipedia.org/wiki/Semiring#Star_semirings StarSemiring>---   is a semiring with an additional unary operator star satisfying:------ > star a = one + a `times` star a-class (Distributive a) => StarSemiring a where-  star :: a -> a-  star a = one + plus a--  plus :: a -> a-  plus a = a * star a--instance StarSemiring b => StarSemiring (a -> b)---- | A <https://en.wikipedia.org/wiki/Kleene_algebra Kleene Algebra> is---   a Star Semiring with idempotent addition------ > a `times` x + x = a ==> star a `times` x + x = x--- > x `times` a + x = a ==> x `times` star a + x = x-class (StarSemiring a, Idempotent a) => KleeneAlgebra a--instance KleeneAlgebra b => KleeneAlgebra (a -> b)---- | Involutive Ring------ > adj (a + b) ==> adj a + adj b--- > adj (a * b) ==> adj a * adj b--- > adj one ==> one--- > adj (adj a) ==> a------ Note: elements for which @adj a == a@ are called "self-adjoint".-class (Distributive a) => InvolutiveRing a where-  adj :: a -> a-  adj x = x--instance InvolutiveRing P.Double--instance InvolutiveRing P.Float--instance InvolutiveRing P.Integer--instance InvolutiveRing P.Int--instance InvolutiveRing Natural--instance InvolutiveRing Int8--instance InvolutiveRing Int16--instance InvolutiveRing Int32--instance InvolutiveRing Int64--instance InvolutiveRing Word--instance InvolutiveRing Word8--instance InvolutiveRing Word16--instance InvolutiveRing Word32--instance InvolutiveRing Word64--instance InvolutiveRing b => InvolutiveRing (a -> b)---- | Defining 'two' requires adding the multiplicative unital to itself.-two :: (Multiplicative a, Additive a) => a-two = one + one
+ src/NumHask/Algebra/Additive.hs view
@@ -0,0 +1,181 @@+{-# OPTIONS_GHC -Wall #-}++-- | Additive classes+module NumHask.Algebra.Additive+  ( Additive (..),+    sum,+    Subtractive (..),+  )+where++import Data.Int (Int16, Int32, Int64, Int8)+import Data.Word (Word, Word16, Word32, Word64, Word8)+import GHC.Natural (Natural (..))+import Prelude (Bool, Double, Float, Int, Integer)+import qualified Prelude as P++-- $setup+--+-- >>> :set -XRebindableSyntax+-- >>> :set -XNegativeLiterals+-- >>> :set -XFlexibleContexts+-- >>> import NumHask.Prelude+-- >>> import Test.QuickCheck++-- | or [Addition](https://en.wikipedia.org/wiki/Addition)+--+-- For practical reasons, we begin the class tree with 'NumHask.Algebra.Additive.Additive'.  Starting with  'NumHask.Algebra.Group.Associative' and 'NumHask.Algebra.Group.Unital', or using 'Data.Semigroup.Semigroup' and 'Data.Monoid.Monoid' from base tends to confuse the interface once you start having to disinguish between (say) monoidal addition and monoidal multiplication.+--+-- prop> \a -> zero + a == a+-- prop> \a -> a + zero == a+-- prop> \a b c -> (a + b) + c == a + (b + c)+-- prop> \a b -> a + b == b + a+--+-- By convention, (+) is regarded as commutative, but this is not universal, and the introduction of another symbol which means non-commutative addition seems a bit dogmatic.+--+-- >>> zero + 1+-- 1+--+-- >>> 1 + 1+-- 2+class Additive a where+  infixl 6 ++  (+) :: a -> a -> a++  zero :: a++-- | Compute the sum of a 'Data.Foldable.Foldable'.+sum :: (Additive a, P.Foldable f) => f a -> a+sum = P.foldr (+) zero++-- | or [Subtraction](https://en.wikipedia.org/wiki/Subtraction)+--+-- prop> \a -> a - a == zero+-- prop> \a -> negate a == zero - a+-- prop> \a -> negate a + a == zero+-- prop> \a -> a + negate a == zero+--+--+-- >>> negate 1+-- -1+--+-- >>> 1 - 2+-- -1+class (Additive a) => Subtractive a where+  negate :: a -> a++  infixl 6 -+  (-) :: a -> a -> a+  (-) a b = a + negate b++instance Additive Double where+  (+) = (P.+)+  zero = 0++instance Subtractive Double where+  negate = P.negate++instance Additive Float where+  (+) = (P.+)+  zero = 0++instance Subtractive Float where+  negate = P.negate++instance Additive Int where+  (+) = (P.+)+  zero = 0++instance Subtractive Int where+  negate = P.negate++instance Additive Integer where+  (+) = (P.+)+  zero = 0++instance Subtractive Integer where+  negate = P.negate++instance Additive Bool where+  (+) = (P.||)+  zero = P.False++instance Subtractive Bool where+  negate = P.not++instance Additive Natural where+  (+) = (P.+)+  zero = 0++instance Subtractive Natural where+  negate = P.negate++instance Additive Int8 where+  (+) = (P.+)+  zero = 0++instance Subtractive Int8 where+  negate = P.negate++instance Additive Int16 where+  (+) = (P.+)+  zero = 0++instance Subtractive Int16 where+  negate = P.negate++instance Additive Int32 where+  (+) = (P.+)+  zero = 0++instance Subtractive Int32 where+  negate = P.negate++instance Additive Int64 where+  (+) = (P.+)+  zero = 0++instance Subtractive Int64 where+  negate = P.negate++instance Additive Word where+  (+) = (P.+)+  zero = 0++instance Subtractive Word where+  negate = P.negate++instance Additive Word8 where+  (+) = (P.+)+  zero = 0++instance Subtractive Word8 where+  negate = P.negate++instance Additive Word16 where+  (+) = (P.+)+  zero = 0++instance Subtractive Word16 where+  negate = P.negate++instance Additive Word32 where+  (+) = (P.+)+  zero = 0++instance Subtractive Word32 where+  negate = P.negate++instance Additive Word64 where+  (+) = (P.+)+  zero = 0++instance Subtractive Word64 where+  negate = P.negate++instance Additive b => Additive (a -> b) where+  f + f' = \a -> f a + f' a+  zero _ = zero++instance Subtractive b => Subtractive (a -> b) where+  negate f = negate P.. f
+ src/NumHask/Algebra/Field.hs view
@@ -0,0 +1,273 @@+{-# LANGUAGE DefaultSignatures #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE TypeApplications #-}+{-# OPTIONS_GHC -Wall #-}++-- | Field classes+module NumHask.Algebra.Field+  ( Field,+    ExpField (..),+    QuotientField (..),+    UpperBoundedField (..),+    LowerBoundedField (..),+    TrigField (..),+    half,+  )+where++import Data.Bool (bool)+import NumHask.Algebra.Additive+import NumHask.Algebra.Multiplicative+import NumHask.Algebra.Ring+import NumHask.Data.Integral+import Prelude ((.))+import qualified Prelude as P++-- $setup+--+-- >>> :set -XRebindableSyntax+-- >>> :set -XNegativeLiterals+-- >>> :set -XFlexibleContexts+-- >>> :set -XScopedTypeVariables+-- >>> import NumHask.Prelude+-- >>> import Test.QuickCheck++-- | A <https://en.wikipedia.org/wiki/Field_(mathematics) Field> is a set+--   on which addition, subtraction, multiplication, and division are defined. It is also assumed that multiplication is distributive over addition.+--+-- A summary of the rules inherited from super-classes of Field. Floating point computation is a terrible, messy business and, in practice, only rough approximation can be achieve for association and distribution.+--+-- > zero + a == a+-- > a + zero == a+-- > ((a + b) + c) (a + (b + c))+-- > a + b == b + a+-- > a - a == zero+-- > negate a == zero - a+-- > negate a + a == zero+-- > a + negate a == zero+-- > one * a == a+-- > a * one == a+-- > ((a * b) * c) == (a * (b * c))+-- > (a * (b + c)) == (a * b + a * c)+-- > ((a + b) * c) == (a * c + b * c)+-- > a * zero == zero+-- > zero * a == zero+-- > a / a == one || a == zero+-- > recip a == one / a || a == zero+-- > recip a * a == one || a == zero+-- > a * recip a == one || a == zero+class+  (Distributive a, Subtractive a, Divisive a) =>+  Field a++instance Field P.Double++instance Field P.Float++instance Field b => Field (a -> b)++-- | A hyperbolic field class+--+-- > sqrt . (**2) == id+-- > log . exp == id+-- > for +ive b, a != 0,1: a ** logBase a b ≈ b+class+  (Field a) =>+  ExpField a where+  exp :: a -> a+  log :: a -> a+  logBase :: a -> a -> a+  logBase a b = log b / log a+  (**) :: a -> a -> a+  (**) a b = exp (log a * b)+  sqrt :: a -> a+  sqrt a = a ** (one / (one + one))++instance ExpField P.Double where+  exp = P.exp+  log = P.log+  (**) = (P.**)++instance ExpField P.Float where+  exp = P.exp+  log = P.log+  (**) = (P.**)++instance ExpField b => ExpField (a -> b) where+  exp f = exp . f+  log f = log . f+  logBase f f' a = logBase (f a) (f' a)+  f ** f' = \a -> f a ** f' a+  sqrt f = sqrt . f++-- | Conversion from a 'Field' to a 'Ring'+--+-- See [Field of fractions](https://en.wikipedia.org/wiki/Field_of_fractions)+--+-- > a - one < floor a <= a <= ceiling a < a + one+-- > round a == floor (a + half)+class (Field a, Multiplicative b, Additive b) => QuotientField a b where+  properFraction :: a -> (b, a)++  round :: a -> b+  default round :: (P.Ord a, P.Ord b, Subtractive b, Integral b) => a -> b+  round x = case properFraction x of+    (n, r) ->+      let m = bool (n + one) (n - one) (r P.< zero)+          half_down = abs' r - (one / (one + one))+          abs' a+            | a P.< zero = negate a+            | P.otherwise = a+       in case P.compare half_down zero of+            P.LT -> n+            P.EQ -> bool m n (even n)+            P.GT -> m++  ceiling :: a -> b+  default ceiling :: (P.Ord a) => a -> b+  ceiling x = bool n (n + one) (r P.>= zero)+    where+      (n, r) = properFraction x++  floor :: a -> b+  default floor :: (P.Ord a, Subtractive b) => a -> b+  floor x = bool n (n - one) (r P.< zero)+    where+      (n, r) = properFraction x++  truncate :: a -> b+  default truncate :: (P.Ord a) => a -> b+  truncate x = bool (ceiling x) (floor x) (x P.> zero)++instance QuotientField P.Float P.Integer where+  properFraction = P.properFraction++instance QuotientField P.Double P.Integer where+  properFraction = P.properFraction++instance QuotientField P.Float P.Int where+  properFraction = P.properFraction++instance QuotientField P.Double P.Int where+  properFraction = P.properFraction++instance QuotientField b c => QuotientField (a -> b) (a -> c) where+  properFraction f = (P.fst . frac, P.snd . frac)+    where+      frac a = properFraction @b @c (f a)++  round f = round . f++  ceiling f = ceiling . f++  floor f = floor . f++  truncate f = truncate . f++-- | A bounded field introduces the concepts of infinity and NaN.+--+-- > one / zero + infinity == infinity+-- > infinity + a == infinity+-- > zero / zero != nan+--+-- Note the tricky law that, although nan is assigned to zero/zero, they are never-the-less not equal. A committee decided this.+class+  (Field a) =>+  UpperBoundedField a where+  infinity :: a+  infinity = one / zero++  nan :: a+  nan = zero / zero++instance UpperBoundedField P.Float++instance UpperBoundedField P.Double++instance UpperBoundedField b => UpperBoundedField (a -> b) where+  infinity _ = infinity+  nan _ = nan++-- | Negative infinity.+class+  (Subtractive a, Field a) =>+  LowerBoundedField a where+  negInfinity :: a+  negInfinity = negate (one / zero)++instance LowerBoundedField P.Float++instance LowerBoundedField P.Double++instance LowerBoundedField b => LowerBoundedField (a -> b) where+  negInfinity _ = negInfinity++-- | Trigonometric Field+class+  (Field a) =>+  TrigField a where+  pi :: a+  sin :: a -> a+  cos :: a -> a+  tan :: a -> a+  tan x = sin x / cos x+  asin :: a -> a+  acos :: a -> a+  atan :: a -> a+  atan2 :: a -> a -> a+  sinh :: a -> a+  cosh :: a -> a+  tanh :: a -> a+  tanh x = sinh x / cosh x+  asinh :: a -> a+  acosh :: a -> a+  atanh :: a -> a++instance TrigField P.Double where+  pi = P.pi+  sin = P.sin+  cos = P.cos+  asin = P.asin+  acos = P.acos+  atan = P.atan+  atan2 = P.atan2+  sinh = P.sinh+  cosh = P.cosh+  asinh = P.sinh+  acosh = P.acosh+  atanh = P.atanh++instance TrigField P.Float where+  pi = P.pi+  sin = P.sin+  cos = P.cos+  asin = P.asin+  acos = P.acos+  atan = P.atan+  atan2 = P.atan2+  sinh = P.sinh+  cosh = P.cosh+  asinh = P.sinh+  acosh = P.acosh+  atanh = P.atanh++instance TrigField b => TrigField (a -> b) where+  pi _ = pi+  sin f = sin . f+  cos f = cos . f+  asin f = asin . f+  acos f = acos . f+  atan f = atan . f+  atan2 f g x = atan2 (f x) (g x)+  sinh f = sinh . f+  cosh f = cosh . f+  asinh f = asinh . f+  acosh f = acosh . f+  atanh f = atanh . f++-- | A 'half' is a 'Field' because it requires addition, multiplication and division.+half :: (Field a) => a+half = one / two
+ src/NumHask/Algebra/Group.hs view
@@ -0,0 +1,127 @@+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE UndecidableInstances #-}+{-# OPTIONS_GHC -Wall #-}++-- | The Group hierarchy+module NumHask.Algebra.Group+  ( Magma (..),+    Unital (..),+    Associative,+    Commutative,+    Absorbing (..),+    Invertible (..),+    Idempotent,+    Group,+    AbelianGroup,+  )+where++import Prelude++-- * Magma structure++-- | A <https://en.wikipedia.org/wiki/Magma_(algebra) Magma> is a tuple (T,magma) consisting of+--+-- - a type a, and+--+-- - a function (magma) :: T -> T -> T+--+-- The mathematical laws for a magma are:+--+-- - magma is defined for all possible pairs of type T, and+--+-- - magma is closed in the set of all possible values of type T+--+-- or, more tersly,+--+-- > ∀ a, b ∈ T: a ⊕ b ∈ T+--+-- These laws are true by construction in haskell: the type signature of '⊕' and the above mathematical laws are synonyms.+class Magma a where+  infix 3 ⊕+  (⊕) :: a -> a -> a++instance Magma b => Magma (a -> b) where+  f ⊕ g = \a -> f a ⊕ g a++-- | A Unital Magma is a magma with an+--   <https://en.wikipedia.org/wiki/Identity_element identity element> (the+--   unit).+--+-- > unit ⊕ a = a+-- > a ⊕ unit = a+class+  Magma a =>+  Unital a where+  unit :: a++instance Unital b => Unital (a -> b) where+  {-# INLINE unit #-}+  unit _ = unit++-- | An Associative Magma+--+-- > (a ⊕ b) ⊕ c = a ⊕ (b ⊕ c)+class+  Magma a =>+  Associative a++instance Associative b => Associative (a -> b)++-- | A Commutative Magma is a Magma where the binary operation is+-- <https://en.wikipedia.org/wiki/Commutative_property commutative>.+--+-- > a ⊕ b = b ⊕ a+class+  Magma a =>+  Commutative a++instance Commutative b => Commutative (a -> b)++-- | An Invertible Magma+--+-- > ∀ a,b ∈ T: inv a ⊕ (a ⊕ b) = b = (b ⊕ a) ⊕ inv a+class+  Magma a =>+  Invertible a where+  inv :: a -> a++instance Invertible b => Invertible (a -> b) where+  {-# INLINE inv #-}+  inv f = inv . f++-- | A <https://en.wikipedia.org/wiki/Group_(mathematics) Group> is a+--   Associative, Unital and Invertible Magma.+class (Associative a, Unital a, Invertible a) => Group a++instance (Associative a, Unital a, Invertible a) => Group a++-- | An Absorbing is a Magma with an+--   <https://en.wikipedia.org/wiki/Absorbing_element Absorbing Element>+--+-- > a ⊕ absorb = absorb+class+  Magma a =>+  Absorbing a where+  absorb :: a++instance Absorbing b => Absorbing (a -> b) where+  {-# INLINE absorb #-}+  absorb _ = absorb++-- | An Idempotent Magma is a magma where every element is+--   <https://en.wikipedia.org/wiki/Idempotence Idempotent>.+--+-- > a ⊕ a = a+class+  Magma a =>+  Idempotent a++instance Idempotent b => Idempotent (a -> b)++-- | An <https://en.wikipedia.org/wiki/Abelian_group Abelian Group> is an+--   Associative, Unital, Invertible and Commutative Magma . In other words, it+--   is a Commutative Group+class (Associative a, Unital a, Invertible a, Commutative a) => AbelianGroup a++instance (Associative a, Unital a, Invertible a, Commutative a) => AbelianGroup a
+ src/NumHask/Algebra/Lattice.hs view
@@ -0,0 +1,266 @@+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE RebindableSyntax #-}+{-# LANGUAGE UndecidableInstances #-}+{-# OPTIONS_GHC -Wall #-}++-- | [Lattices](https://en.wikipedia.org/wiki/Lattice_(order\))+module NumHask.Algebra.Lattice+  ( JoinSemiLattice (..),+    joinLeq,+    MeetSemiLattice (..),+    meetLeq,+    BoundedJoinSemiLattice (..),+    BoundedMeetSemiLattice (..),+  )+where++import Data.Bool+import Data.Eq+import Data.Function (const)+import Data.Int (Int16, Int32, Int64, Int8)+import Data.Ord (Ord (..))+import Data.Word (Word16, Word32, Word64, Word8)+import GHC.Enum (Bounded (..))+import GHC.Float (Double, Float)+import GHC.Int (Int)+import GHC.Natural (Natural (..))+import GHC.Num (Integer)+import GHC.Word (Word)+import NumHask.Algebra.Additive (zero)+import NumHask.Algebra.Field++-- | A algebraic structure with element joins: See [Semilattice](http://en.wikipedia.org/wiki/Semilattice)+--+-- > Associativity: x \/ (y \/ z) == (x \/ y) \/ z+-- > Commutativity: x \/ y == y \/ x+-- > Idempotency:   x \/ x == x+class (Eq a) => JoinSemiLattice a where+  infixr 5 \/+  (\/) :: a -> a -> a++-- | The partial ordering induced by the join-semilattice structure+joinLeq :: (JoinSemiLattice a) => a -> a -> Bool+joinLeq x y = (x \/ y) == y++-- | A algebraic structure with element meets: See [Semilattice](http://en.wikipedia.org/wiki/Semilattice)+--+-- > Associativity: x /\ (y /\ z) == (x /\ y) /\ z+-- > Commutativity: x /\ y == y /\ x+-- > Idempotency:   x /\ x == x+class (Eq a) => MeetSemiLattice a where+  infixr 6 /\+  (/\) :: a -> a -> a++-- | The partial ordering induced by the meet-semilattice structure+meetLeq :: (MeetSemiLattice a) => a -> a -> Bool+meetLeq x y = (x /\ y) == x++-- | The combination of two semi lattices makes a lattice if the absorption law holds:+-- see [Absorption Law](http://en.wikipedia.org/wiki/Absorption_law) and [Lattice](http://en.wikipedia.org/wiki/Lattice_(order\))+--+-- > Absorption: a \/ (a /\ b) == a /\ (a \/ b) == a+class (JoinSemiLattice a, MeetSemiLattice a) => Lattice a++instance (JoinSemiLattice a, MeetSemiLattice a) => Lattice a++-- | A join-semilattice with an identity element 'bottom' for '\/'.+--+-- > Identity: x \/ bottom == x+class JoinSemiLattice a => BoundedJoinSemiLattice a where+  bottom :: a++-- | A meet-semilattice with an identity element 'top' for '/\'.+--+-- > Identity: x /\ top == x+class MeetSemiLattice a => BoundedMeetSemiLattice a where+  top :: a++-- | Lattices with both bounds+class (JoinSemiLattice a, MeetSemiLattice a, BoundedJoinSemiLattice a, BoundedMeetSemiLattice a) => BoundedLattice a++instance (JoinSemiLattice a, MeetSemiLattice a, BoundedJoinSemiLattice a, BoundedMeetSemiLattice a) => BoundedLattice a++instance JoinSemiLattice Float where+  (\/) = min++instance MeetSemiLattice Float where+  (/\) = max++instance JoinSemiLattice Double where+  (\/) = min++instance MeetSemiLattice Double where+  (/\) = max++instance JoinSemiLattice Int where+  (\/) = min++instance MeetSemiLattice Int where+  (/\) = max++instance JoinSemiLattice Integer where+  (\/) = min++instance MeetSemiLattice Integer where+  (/\) = max++instance JoinSemiLattice Bool where+  (\/) = (||)++instance MeetSemiLattice Bool where+  (/\) = (&&)++instance JoinSemiLattice Natural where+  (\/) = min++instance MeetSemiLattice Natural where+  (/\) = max++instance JoinSemiLattice Int8 where+  (\/) = min++instance MeetSemiLattice Int8 where+  (/\) = max++instance JoinSemiLattice Int16 where+  (\/) = min++instance MeetSemiLattice Int16 where+  (/\) = max++instance JoinSemiLattice Int32 where+  (\/) = min++instance MeetSemiLattice Int32 where+  (/\) = max++instance JoinSemiLattice Int64 where+  (\/) = min++instance MeetSemiLattice Int64 where+  (/\) = max++instance JoinSemiLattice Word where+  (\/) = min++instance MeetSemiLattice Word where+  (/\) = max++instance JoinSemiLattice Word8 where+  (\/) = min++instance MeetSemiLattice Word8 where+  (/\) = max++instance JoinSemiLattice Word16 where+  (\/) = min++instance MeetSemiLattice Word16 where+  (/\) = max++instance JoinSemiLattice Word32 where+  (\/) = min++instance MeetSemiLattice Word32 where+  (/\) = max++instance JoinSemiLattice Word64 where+  (\/) = min++instance MeetSemiLattice Word64 where+  (/\) = max++instance (Eq (a -> b), JoinSemiLattice b) => JoinSemiLattice (a -> b) where+  f \/ f' = \a -> f a \/ f' a++instance (Eq (a -> b), MeetSemiLattice b) => MeetSemiLattice (a -> b) where+  f /\ f' = \a -> f a /\ f' a++-- from here++instance BoundedJoinSemiLattice Float where+  bottom = negInfinity++instance BoundedMeetSemiLattice Float where+  top = infinity++instance BoundedJoinSemiLattice Double where+  bottom = negInfinity++instance BoundedMeetSemiLattice Double where+  top = infinity++instance BoundedJoinSemiLattice Int where+  bottom = minBound++instance BoundedMeetSemiLattice Int where+  top = maxBound++instance BoundedJoinSemiLattice Bool where+  bottom = False++instance BoundedMeetSemiLattice Bool where+  top = True++instance BoundedJoinSemiLattice Natural where+  bottom = zero++instance BoundedJoinSemiLattice Int8 where+  bottom = minBound++instance BoundedMeetSemiLattice Int8 where+  top = maxBound++instance BoundedJoinSemiLattice Int16 where+  bottom = minBound++instance BoundedMeetSemiLattice Int16 where+  top = maxBound++instance BoundedJoinSemiLattice Int32 where+  bottom = minBound++instance BoundedMeetSemiLattice Int32 where+  top = maxBound++instance BoundedJoinSemiLattice Int64 where+  bottom = minBound++instance BoundedMeetSemiLattice Int64 where+  top = maxBound++instance BoundedJoinSemiLattice Word where+  bottom = minBound++instance BoundedMeetSemiLattice Word where+  top = maxBound++instance BoundedJoinSemiLattice Word8 where+  bottom = minBound++instance BoundedMeetSemiLattice Word8 where+  top = maxBound++instance BoundedJoinSemiLattice Word16 where+  bottom = minBound++instance BoundedMeetSemiLattice Word16 where+  top = maxBound++instance BoundedJoinSemiLattice Word32 where+  bottom = minBound++instance BoundedMeetSemiLattice Word32 where+  top = maxBound++instance BoundedJoinSemiLattice Word64 where+  bottom = minBound++instance BoundedMeetSemiLattice Word64 where+  top = maxBound++instance (Eq (a -> b), BoundedJoinSemiLattice b) => BoundedJoinSemiLattice (a -> b) where+  bottom = const bottom++instance (Eq (a -> b), BoundedMeetSemiLattice b) => BoundedMeetSemiLattice (a -> b) where+  top = const top
+ src/NumHask/Algebra/Module.hs view
@@ -0,0 +1,80 @@+{-# LANGUAGE FunctionalDependencies #-}+{-# LANGUAGE RebindableSyntax #-}+{-# OPTIONS_GHC -Wall #-}++-- | Algebra for Modules+module NumHask.Algebra.Module+  ( AdditiveAction (..),+    SubtractiveAction (..),+    MultiplicativeAction (..),+    DivisiveAction (..),+    Module,+  )+where++import NumHask.Algebra.Additive+import NumHask.Algebra.Multiplicative+import NumHask.Algebra.Ring++-- $setup+--+-- >>> :set -XRebindableSyntax+-- >>> :set -XNegativeLiterals+-- >>> :set -XFlexibleContexts+-- >>> :set -XFlexibleInstances+-- >>> :set -XScopedTypeVariables+-- >>> :set -XMultiParamTypeClasses+-- >>> import NumHask.Prelude+-- >>> import Test.QuickCheck+-- >>> import Prelude (Int, fmap)++-- | Additive Action+class+  (Additive a) =>+  AdditiveAction m a+    | m -> a where+  infixl 6 .++  (.+) :: a -> m -> m++  infixl 6 +.+  (+.) :: m -> a -> m++-- | Subtractive Action+class+  (Subtractive a) =>+  SubtractiveAction m a+    | m -> a where+  infixl 6 .-+  (.-) :: a -> m -> m++  infixl 6 -.+  (-.) :: m -> a -> m++-- | Multiplicative Action+class+  (Multiplicative a) =>+  MultiplicativeAction m a+    | m -> a where+  infixl 7 .*+  (.*) :: a -> m -> m+  infixl 7 *.+  (*.) :: m -> a -> m++-- | Divisive Action+class+  (Divisive a) =>+  DivisiveAction m a+    | m -> a where+  infixl 7 ./+  (./) :: a -> m -> m+  infixl 7 /.+  (/.) :: m -> a -> m++-- | A <https://en.wikipedia.org/wiki/Module_(mathematics) Module>+--+-- > a .* one == a+-- > (a + b) .* c == (a .* c) + (b .* c)+-- > c *. (a + b) == (c *. a) + (c *. b)+-- > a .* zero == zero+-- > a .* b == b *. a+class (Distributive a, MultiplicativeAction m a) => Module m a
+ src/NumHask/Algebra/Multiplicative.hs view
@@ -0,0 +1,144 @@+{-# OPTIONS_GHC -Wall #-}++-- | Multiplicative classes+module NumHask.Algebra.Multiplicative+  ( Multiplicative (..),+    product,+    Divisive (..),+  )+where++import Data.Int (Int16, Int32, Int64, Int8)+import Data.Word (Word, Word16, Word32, Word64, Word8)+import GHC.Natural (Natural (..))+import Prelude (Double, Float, Int, Integer)+import qualified Prelude as P++-- $setup+--+-- >>> :set -XRebindableSyntax+-- >>> :set -XNegativeLiterals+-- >>> :set -XFlexibleContexts+-- >>> :set -XScopedTypeVariables+-- >>> import NumHask.Prelude+-- >>> import Test.QuickCheck++-- | or [Multiplication](https://en.wikipedia.org/wiki/Multiplication)+--+-- For practical reasons, we begin the class tree with 'NumHask.Algebra.Additive.Additive' and 'Multiplicative'.  Starting with  'NumHask.Algebra.Group.Associative' and 'NumHask.Algebra.Group.Unital', or using 'Data.Semigroup.Semigroup' and 'Data.Monoid.Monoid' from base tends to confuse the interface once you start having to disinguish between (say) monoidal addition and monoidal multiplication.+--+--+-- prop> \a -> one * a == a+-- prop> \a -> a * one == a+-- prop> \a b c -> (a * b) * c == a * (b * c)+--+-- By convention, (*) is regarded as not necessarily commutative, but this is not universal, and the introduction of another symbol which means commutative multiplication seems a bit dogmatic.+--+-- >>> one * 2+-- 2+--+-- >>> 2 * 3+-- 6+class Multiplicative a where+  infixl 7 *+  (*) :: a -> a -> a++  one :: a++-- | Compute the product of a 'Data.Foldable.Foldable'.+product :: (Multiplicative a, P.Foldable f) => f a -> a+product = P.foldr (*) one++-- | or [Division](https://en.wikipedia.org/wiki/Division_(mathematics\))+--+-- Though unusual, the term Divisive usefully fits in with the grammer of other classes and avoids name clashes that occur with some popular libraries.+--+-- prop> \(a :: Double) -> a / a ~= one || a == zero+-- prop> \(a :: Double) -> recip a ~= one / a || a == zero+-- prop> \(a :: Double) -> recip a * a ~= one || a == zero+-- prop> \(a :: Double) -> a * recip a ~= one || a == zero+--+-- >>> recip 2.0+-- 0.5+--+-- >>> 1 / 2+-- 0.5+class (Multiplicative a) => Divisive a where+  recip :: a -> a++  infixl 7 /+  (/) :: a -> a -> a+  (/) a b = a * recip b++instance Multiplicative Double where+  (*) = (P.*)+  one = 1.0++instance Divisive Double where+  recip = P.recip++instance Multiplicative Float where+  (*) = (P.*)+  one = 1.0++instance Divisive Float where+  recip = P.recip++instance Multiplicative Int where+  (*) = (P.*)+  one = 1++instance Multiplicative Integer where+  (*) = (P.*)+  one = 1++instance Multiplicative P.Bool where+  (*) = (P.&&)+  one = P.True++instance Multiplicative Natural where+  (*) = (P.*)+  one = 1++instance Multiplicative Int8 where+  (*) = (P.*)+  one = 1++instance Multiplicative Int16 where+  (*) = (P.*)+  one = 1++instance Multiplicative Int32 where+  (*) = (P.*)+  one = 1++instance Multiplicative Int64 where+  (*) = (P.*)+  one = 1++instance Multiplicative Word where+  (*) = (P.*)+  one = 1++instance Multiplicative Word8 where+  (*) = (P.*)+  one = 1++instance Multiplicative Word16 where+  (*) = (P.*)+  one = 1++instance Multiplicative Word32 where+  (*) = (P.*)+  one = 1++instance Multiplicative Word64 where+  (*) = (P.*)+  one = 1++instance Multiplicative b => Multiplicative (a -> b) where+  f * f' = \a -> f a * f' a+  one _ = one++instance Divisive b => Divisive (a -> b) where+  recip f = recip P.. f
+ src/NumHask/Algebra/Ring.hs view
@@ -0,0 +1,169 @@+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE UndecidableInstances #-}+{-# OPTIONS_GHC -Wall #-}++-- | Ring classes+module NumHask.Algebra.Ring+  ( Distributive,+    Ring,+    StarSemiring (..),+    KleeneAlgebra,+    InvolutiveRing (..),+    two,+  )+where++import Data.Int (Int16, Int32, Int64, Int8)+import Data.Word (Word, Word16, Word32, Word64, Word8)+import GHC.Natural (Natural (..))+import NumHask.Algebra.Additive+import NumHask.Algebra.Group+import NumHask.Algebra.Multiplicative+import qualified Prelude as P++-- $setup+--+-- >>> :set -XRebindableSyntax+-- >>> :set -XNegativeLiterals+-- >>> :set -XFlexibleContexts+-- >>> :set -XScopedTypeVariables+-- >>> import NumHask.Prelude+-- >>> import Test.QuickCheck++-- | <https://en.wikipedia.org/wiki/Distributive_property Distributive>+--+-- prop> \a b c -> a * (b + c) == a * b + a * c+-- prop> \a b c -> (a + b) * c == a * c + b * c+-- prop> \a -> zero * a == zero+-- prop> \a -> a * zero == zero+--+-- The sneaking in of the <https://en.wikipedia.org/wiki/Absorbing_element Absorption> laws here glosses over the possibility that the multiplicative zero element does not have to correspond with the additive unital zero.+class+  (Additive a, Multiplicative a) =>+  Distributive a++instance Distributive P.Double++instance Distributive P.Float++instance Distributive P.Int++instance Distributive P.Integer++instance Distributive Natural++instance Distributive Int8++instance Distributive Int16++instance Distributive Int32++instance Distributive Int64++instance Distributive Word++instance Distributive Word8++instance Distributive Word16++instance Distributive Word32++instance Distributive Word64++instance Distributive P.Bool++instance Distributive b => Distributive (a -> b)++-- | A <https://en.wikipedia.org/wiki/Ring_(mathematics) Ring> is an abelian group under addition ('Unital', 'Associative', 'Commutative', 'Invertible') and monoidal under multiplication ('Unital', 'Associative'), and where multiplication distributes over addition.+--+-- prop> \a -> zero + a == a+-- prop> \a -> a + zero == a+-- prop> \a b c -> (a + b) + c == a + (b + c)+-- prop> \a b -> a + b == b + a+-- prop> \a -> a - a == zero+-- prop> \a -> negate a == zero - a+-- prop> \a -> negate a + a == zero+-- prop> \a -> a + negate a == zero+-- prop> \a -> one * a == a+-- prop> \a -> a * one == a+-- prop> \a b c -> (a * b) * c == a * (b * c)+-- prop> \a b c -> a * (b + c) == a * b + a * c+-- prop> \a b c -> (a + b) * c == a * c + b * c+-- prop> \a -> zero * a == zero+-- prop> \a -> a * zero == zero+class+  (Distributive a, Subtractive a) =>+  Ring a++instance+  (Distributive a, Subtractive a) =>+  Ring a++-- | A <https://en.wikipedia.org/wiki/Semiring#Star_semirings StarSemiring> is a semiring with an additional unary operator (star) satisfying:+--+-- > \a -> star a = one + a * star a+class (Distributive a) => StarSemiring a where+  star :: a -> a+  star a = one + plus a++  plus :: a -> a+  plus a = a * star a++instance StarSemiring b => StarSemiring (a -> b)++-- | A <https://en.wikipedia.org/wiki/Kleene_algebra Kleene Algebra> is a Star Semiring with idempotent addition.+--+-- > a * x + x = a ==> star a * x + x = x+-- > x * a + x = a ==> x * star a + x = x+class (StarSemiring a, Idempotent a) => KleeneAlgebra a++instance KleeneAlgebra b => KleeneAlgebra (a -> b)++-- | Involutive Ring+--+-- > adj (a + b) ==> adj a + adj b+-- > adj (a * b) ==> adj a * adj b+-- > adj one ==> one+-- > adj (adj a) ==> a+--+-- Note: elements for which @adj a == a@ are called "self-adjoint".+class (Distributive a) => InvolutiveRing a where+  adj :: a -> a+  adj x = x++instance InvolutiveRing P.Double++instance InvolutiveRing P.Float++instance InvolutiveRing P.Integer++instance InvolutiveRing P.Int++instance InvolutiveRing Natural++instance InvolutiveRing Int8++instance InvolutiveRing Int16++instance InvolutiveRing Int32++instance InvolutiveRing Int64++instance InvolutiveRing Word++instance InvolutiveRing Word8++instance InvolutiveRing Word16++instance InvolutiveRing Word32++instance InvolutiveRing Word64++instance InvolutiveRing b => InvolutiveRing (a -> b)++-- | Defining 'two' requires adding the multiplicative unital to itself. In other words, the concept of 'two' is a Ring one.+--+-- >>> two+-- 2+two :: (Multiplicative a, Additive a) => a+two = one + one
src/NumHask/Analysis/Metric.hs view
@@ -1,12 +1,18 @@+{-# LANGUAGE AllowAmbiguousTypes #-}+{-# LANGUAGE DeriveGeneric #-} {-# LANGUAGE FlexibleInstances #-}-{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE FunctionalDependencies #-} {-# OPTIONS_GHC -Wall #-}  -- | Metric classes module NumHask.Analysis.Metric   ( Signed (..),-    Normed (..),-    Metric (..),+    Norm (..),+    distance,+    Direction (..),+    Polar (..),+    polar,+    coord,     Epsilon (..),     (~=),   )@@ -14,25 +20,26 @@  import Data.Int (Int16, Int32, Int64, Int8) import Data.Word (Word16, Word32, Word64, Word8)+import GHC.Generics (Generic) import GHC.Natural (Natural (..))-import NumHask.Algebra.Abstract.Additive-import NumHask.Algebra.Abstract.Lattice-import NumHask.Algebra.Abstract.Multiplicative+import NumHask.Algebra.Additive+import NumHask.Algebra.Lattice+import NumHask.Algebra.Module+import NumHask.Algebra.Multiplicative import Prelude hiding-  ( (-),+  ( (*),+    (-),     Bounded (..),     Integral (..),     negate,   ) import qualified Prelude as P --- | 'signum' from base is not an operator replicated in numhask, being such a very silly name, and preferred is the much more obvious 'sign'.  Compare with 'Norm' where there is a change in codomain+-- | 'signum' from base is not an operator name in numhask and is replaced by 'sign'.  Compare with 'Norm' where there is a change in codomain -- -- > abs a * sign a == a------ Generalising this class tends towards size and direction (abs is the size on the one-dim number line of a vector with its tail at zero, and sign is the direction, right?). class-  (Multiplicative a) =>+  (Additive a, Multiplicative a) =>   Signed a where   sign :: a -> a   abs :: a -> a@@ -129,109 +136,104 @@     | otherwise = one   abs = P.abs --- | Cab be Normed+-- | Norm is a slight generalisation of Signed. The class has the same shape but allows the codomain to be different to the domain. -- -- > norm a >= zero -- > norm zero == zero------ Note that the Normed codomain can be different to the domain.-class (Additive a, Additive b) => Normed a b where+-- > a == norm a .* basis a+-- > norm (basis a) == one+class (Additive a, Multiplicative b, Additive b) => Norm a b | a -> b where   norm :: a -> b+  basis :: a -> a -instance Normed Double Double where+instance Norm Double Double where   norm = P.abs+  basis = P.signum -instance Normed Float Float where+instance Norm Float Float where   norm = P.abs+  basis = P.signum -instance Normed Int Int where+instance Norm Int Int where   norm = P.abs+  basis = P.signum -instance Normed Integer Integer where+instance Norm Integer Integer where   norm = P.abs+  basis = P.signum -instance Normed Natural Natural where+instance Norm Natural Natural where   norm = P.abs+  basis = P.signum -instance Normed Int8 Int8 where+instance Norm Int8 Int8 where   norm = P.abs+  basis = P.signum -instance Normed Int16 Int16 where+instance Norm Int16 Int16 where   norm = P.abs+  basis = P.signum -instance Normed Int32 Int32 where+instance Norm Int32 Int32 where   norm = P.abs+  basis = P.signum -instance Normed Int64 Int64 where+instance Norm Int64 Int64 where   norm = P.abs+  basis = P.signum -instance Normed Word Word where+instance Norm Word Word where   norm = P.abs+  basis = P.signum -instance Normed Word8 Word8 where+instance Norm Word8 Word8 where   norm = P.abs+  basis = P.signum -instance Normed Word16 Word16 where+instance Norm Word16 Word16 where   norm = P.abs+  basis = P.signum -instance Normed Word32 Word32 where+instance Norm Word32 Word32 where   norm = P.abs+  basis = P.signum -instance Normed Word64 Word64 where+instance Norm Word64 Word64 where   norm = P.abs+  basis = P.signum --- | distance between numbers using L1 norm+-- | Distance, which combines the Subtractive notion of difference, with Norm. -- -- > distance a b >= zero -- > distance a a == zero----class Metric a b where-  distance :: a -> a -> b--instance Metric Double Double where-  distance a b = norm (a - b)--instance Metric Float Float where-  distance a b = norm (a - b)--instance Metric Int Int where-  distance a b = norm (a - b)--instance Metric Integer Integer where-  distance a b = norm (a - b)--instance Metric Natural Natural where-  distance a b = P.fromInteger $ norm (P.toInteger a - P.toInteger b)--instance Metric Int8 Int8 where-  distance a b = norm (a - b)--instance Metric Int16 Int16 where-  distance a b = norm (a - b)--instance Metric Int32 Int32 where-  distance a b = norm (a - b)--instance Metric Int64 Int64 where-  distance a b = norm (a - b)----- fixme: circular distance may be more appropriate-instance Metric Word Word where-  distance a b = P.fromInteger $ norm (P.toInteger a - P.toInteger b)+-- > distance a b .* basis (a - b) == a - b+distance :: (Norm a b, Subtractive a) => a -> a -> b+distance a b = norm (a - b) -instance Metric Word8 Word8 where-  distance a b = P.fromInteger $ norm (P.toInteger a - P.toInteger b)+-- | Convert between a "co-ordinated" or "higher-kinded" number and representations of an angle. Typically thought of as polar co-ordinate conversion.+--+-- See [Polar coordinate system](https://en.wikipedia.org/wiki/Polar_coordinate_system)+--+-- > ray . angle == basis+-- > norm (ray x) == 1+class (Additive coord, Multiplicative coord, Additive dir, Multiplicative dir) => Direction coord dir | coord -> dir where+  angle :: coord -> dir+  ray :: dir -> coord -instance Metric Word16 Word16 where-  distance a b = P.fromInteger $ norm (P.toInteger a - P.toInteger b)+-- | Something that has a magnitude and a direction.+data Polar mag dir+  = Polar {magnitude :: mag, direction :: dir}+  deriving (Eq, Show, Generic) -instance Metric Word32 Word32 where-  distance a b = P.fromInteger $ norm (P.toInteger a - P.toInteger b)+-- | Convert from a number to a Polar.+polar :: (Norm coord mag, Direction coord dir) => coord -> Polar mag dir+polar z = Polar (norm z) (angle z) -instance Metric Word64 Word64 where-  distance a b = P.fromInteger $ norm (P.toInteger a - P.toInteger b)+-- | Convert from a Polar to a (coordinated aka higher-kinded) number.+coord :: (MultiplicativeAction coord mag, Direction coord dir) => Polar mag dir -> coord+coord (Polar m d) = m .* ray d +-- | A small number, especially useful for approximate equality. class   (Eq a, Additive a, Subtractive a, MeetSemiLattice a) =>   Epsilon a where@@ -246,15 +248,19 @@  infixl 4 ~= +-- | About equal. (~=) :: (Epsilon a) => a -> a -> Bool (~=) = aboutEqual +-- | 1e-14 instance Epsilon Double where   epsilon = 1e-14 +-- | 1e-6 instance Epsilon Float where   epsilon = 1e-6 +-- | 0 instance Epsilon Int  instance Epsilon Integer
src/NumHask/Data/Complex.hs view
@@ -5,36 +5,34 @@ {-# LANGUAGE DeriveTraversable #-} {-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE MultiParamTypeClasses #-}-{-# LANGUAGE NoImplicitPrelude #-}+{-# LANGUAGE RebindableSyntax #-} {-# OPTIONS_GHC -Wall #-} +-- | Complex numbers. module NumHask.Data.Complex   ( Complex (..),     realPart,     imagPart,-    mkPolar,-    cis,-    polar,-    magnitude,-    phase,   ) where  import Data.Data (Data) import GHC.Generics (Generic, Generic1)-import NumHask.Algebra.Abstract.Additive-import NumHask.Algebra.Abstract.Field-import NumHask.Algebra.Abstract.Lattice-import NumHask.Algebra.Abstract.Multiplicative-import NumHask.Algebra.Abstract.Ring+import NumHask.Algebra.Additive+import NumHask.Algebra.Field+import NumHask.Algebra.Lattice+import NumHask.Algebra.Multiplicative+import NumHask.Algebra.Ring import NumHask.Analysis.Metric import NumHask.Data.Integral import Prelude hiding   ( (/),     Num (..),     atan,+    atan2,     cos,     exp,+    fromIntegral,     log,     negate,     pi,@@ -48,13 +46,9 @@ -- The Complex type infix 6 :+ --- | Complex numbers are an algebraic type.------ For a complex number @z@, @'abs' z@ is a number with the magnitude of @z@,--- but oriented in the positive real direction, whereas @'sign' z@--- has the phase of @z@, but unit magnitude.+-- | Complex numbers have real and imaginary parts. ----- The 'Foldable' and 'Traversable' instances traverse the real part first.+-- The 'Data.Foldable.Foldable' and 'Data.Traversable.Traversable' instances traverse the real part first. data Complex a   = -- | forms a complex number from its real and imaginary     -- rectangular components.@@ -110,19 +104,19 @@   (Additive a, FromIntegral a b) =>   FromIntegral (Complex a) b   where-  fromIntegral_ x = fromIntegral_ x :+ zero+  fromIntegral x = fromIntegral x :+ zero +-- | A euclidean-style norm is strong convention for Complex. instance-  (ExpField a, Normed a a) =>-  Normed (Complex a) a+  (ExpField a) =>+  Norm (Complex a) a   where-  norm (rx :+ ix) = norm rx + norm ix+  norm (rx :+ ix) = sqrt (rx * rx + ix * ix)+  basis x@(rx :+ ix) = rx / norm x :+ ix / norm x -instance-  (Subtractive a, ExpField a, Normed a a) =>-  Metric (Complex a) a-  where-  distance a b = norm (a - b)+instance (TrigField a) => Direction (Complex a) a where+  angle (x :+ y) = atan2 y x+  ray x = cos x :+ sin x  instance   (Ord a, Signed a, Subtractive a, Epsilon a) =>@@ -131,11 +125,9 @@   epsilon = epsilon :+ epsilon   nearZero (a :+ b) = nearZero a && nearZero b -instance (IntegralDomain a, Subtractive a) => IntegralDomain (Complex a)--instance (Field a, Subtractive a) => Field (Complex a)+instance (Field a) => Field (Complex a) -instance (Ord a, TrigField a, ExpField a, Subtractive a) => ExpField (Complex a) where+instance (Ord a, TrigField a, ExpField a) => ExpField (Complex a) where   exp (rx :+ ix) = (exp rx * cos ix) :+ (exp rx * sin ix)   log (rx :+ ix) = log (sqrt (rx * rx + ix * ix)) :+ atan2' ix rx     where@@ -152,7 +144,7 @@ instance (Distributive a, Subtractive a) => InvolutiveRing (Complex a) where   adj (a :+ b) = a :+ negate b -instance (UpperBoundedField a, IntegralDomain a, Subtractive a) => UpperBoundedField (Complex a)+instance (UpperBoundedField a, Subtractive a) => UpperBoundedField (Complex a)  instance (LowerBoundedField a) => LowerBoundedField (Complex a) @@ -167,41 +159,3 @@  instance (BoundedMeetSemiLattice a) => BoundedMeetSemiLattice (Complex a) where   top = top :+ top---- * Helpers from Data.Complex--mkPolar :: TrigField a => a -> a -> Complex a-mkPolar r theta = (r * cos theta) :+ (r * sin theta)---- | @'cis' t@ is a complex value with magnitude @1@--- and phase @t@ (modulo @2*'pi'@).-{-# SPECIALIZE cis :: Double -> Complex Double #-}-cis :: TrigField a => a -> Complex a-cis theta = cos theta :+ sin theta---- | The function 'polar' takes a complex number and--- returns a (magnitude, phase) pair in canonical form:--- the magnitude is nonnegative, and the phase in the range @(-'pi', 'pi']@;--- if the magnitude is zero, then so is the phase.-{-# SPECIALIZE polar :: Complex Double -> (Double, Double) #-}-polar :: (RealFloat a, ExpField a) => Complex a -> (a, a)-polar z = (magnitude z, phase z)---- | The nonnegative magnitude of a complex number.-{-# SPECIALIZE magnitude :: Complex Double -> Double #-}-magnitude :: (ExpField a, RealFloat a) => Complex a -> a-magnitude (x :+ y) =-  scaleFloat-    k-    (sqrt (sqr (scaleFloat mk x) + sqr (scaleFloat mk y)))-  where-    k = max (exponent x) (exponent y)-    mk = - k-    sqr z = z * z---- | The phase of a complex number, in the range @(-'pi', 'pi']@.--- If the magnitude is zero, then so is the phase.-{-# SPECIALIZE phase :: Complex Double -> Double #-}-phase :: (RealFloat a) => Complex a -> a-phase (0 :+ 0) = 0 -- SLPJ July 97 from John Peterson-phase (x :+ y) = atan2 y x
src/NumHask/Data/Integral.hs view
@@ -3,36 +3,33 @@ {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE RebindableSyntax #-} {-# LANGUAGE TypeFamilies #-}-{-# LANGUAGE NoImplicitPrelude #-} {-# OPTIONS_GHC -Wall #-}  -- | Integral classes module NumHask.Data.Integral   ( Integral (..),     ToIntegral (..),-    ToInteger,-    toInteger,     FromIntegral (..),     FromInteger (..),-    fromIntegral,     even,     odd,-    (^),     (^^),+    (^),   ) where  import Data.Int (Int16, Int32, Int64, Int8) import Data.Word (Word, Word16, Word32, Word64, Word8) import GHC.Natural (Natural (..))-import NumHask.Algebra.Abstract.Additive-import NumHask.Algebra.Abstract.Multiplicative-import NumHask.Algebra.Abstract.Ring+import NumHask.Algebra.Additive+import NumHask.Algebra.Multiplicative+import NumHask.Algebra.Ring import Prelude ((.), Double, Float, Int, Integer, fst, snd) import qualified Prelude as P --- | Integral laws+-- | An Integral is anything that satisfies the law: -- -- > b == zero || b * (a `div` b) + (a `mod` b) == a class@@ -110,18 +107,15 @@   quotRem f f' = (\a -> fst (f a `quotRem` f' a), \a -> snd (f a `quotRem` f' a))  -- | toIntegral is kept separate from Integral to help with compatability issues.+-- -- > toIntegral a == a class ToIntegral a b where+  {-# MINIMAL toIntegral #-}+   toIntegral :: a -> b   default toIntegral :: (a ~ b) => a -> b   toIntegral = P.id -type ToInteger a = ToIntegral a Integer---- fitting in with legacy naming conventions.-toInteger :: (ToInteger a) => a -> Integer-toInteger = toIntegral- instance ToIntegral Integer Integer where   toIntegral = P.id @@ -161,6 +155,39 @@ instance ToIntegral Int Int where   toIntegral = P.id +instance ToIntegral Integer Int where+  toIntegral = P.fromIntegral++instance ToIntegral Natural Int where+  toIntegral = P.fromIntegral++instance ToIntegral Int8 Int where+  toIntegral = P.fromIntegral++instance ToIntegral Int16 Int where+  toIntegral = P.fromIntegral++instance ToIntegral Int32 Int where+  toIntegral = P.fromIntegral++instance ToIntegral Int64 Int where+  toIntegral = P.fromIntegral++instance ToIntegral Word Int where+  toIntegral = P.fromIntegral++instance ToIntegral Word8 Int where+  toIntegral = P.fromIntegral++instance ToIntegral Word16 Int where+  toIntegral = P.fromIntegral++instance ToIntegral Word32 Int where+  toIntegral = P.fromIntegral++instance ToIntegral Word64 Int where+  toIntegral = P.fromIntegral+ instance ToIntegral Natural Natural where   toIntegral = P.id @@ -191,168 +218,220 @@ instance ToIntegral Word64 Word64 where   toIntegral = P.id --- | fromIntegral abstracts the codomain type, compared with the preludes Integral type.--- > fromIntegral_ a == a+-- | Polymorphic version of fromInteger ----- fromIntegral is widely used as general coercion, hence the underscore for the operator.+-- > fromIntegral a == a class FromIntegral a b where-  fromIntegral_ :: b -> a-  default fromIntegral_ :: (a ~ b) => b -> a-  fromIntegral_ = P.id+  {-# MINIMAL fromIntegral #-} --- | general coercion via Integer-fromIntegral :: (FromInteger b, ToInteger a) => a -> b-fromIntegral = fromInteger . toInteger+  fromIntegral :: b -> a+  default fromIntegral :: (a ~ b) => b -> a+  fromIntegral = P.id  instance (FromIntegral a b) => FromIntegral (c -> a) b where-  fromIntegral_ i _ = fromIntegral_ i+  fromIntegral i _ = fromIntegral i  instance FromIntegral Double Integer where-  fromIntegral_ = P.fromInteger+  fromIntegral = P.fromInteger  instance FromIntegral Float Integer where-  fromIntegral_ = P.fromInteger+  fromIntegral = P.fromInteger  instance FromIntegral Int Integer where-  fromIntegral_ = P.fromInteger+  fromIntegral = P.fromInteger  instance FromIntegral Integer Integer where-  fromIntegral_ = P.id+  fromIntegral = P.id  instance FromIntegral Natural Integer where-  fromIntegral_ = P.fromInteger+  fromIntegral = P.fromInteger  instance FromIntegral Int8 Integer where-  fromIntegral_ = P.fromInteger+  fromIntegral = P.fromInteger  instance FromIntegral Int16 Integer where-  fromIntegral_ = P.fromInteger+  fromIntegral = P.fromInteger  instance FromIntegral Int32 Integer where-  fromIntegral_ = P.fromInteger+  fromIntegral = P.fromInteger  instance FromIntegral Int64 Integer where-  fromIntegral_ = P.fromInteger+  fromIntegral = P.fromInteger  instance FromIntegral Word Integer where-  fromIntegral_ = P.fromInteger+  fromIntegral = P.fromInteger  instance FromIntegral Word8 Integer where-  fromIntegral_ = P.fromInteger+  fromIntegral = P.fromInteger  instance FromIntegral Word16 Integer where-  fromIntegral_ = P.fromInteger+  fromIntegral = P.fromInteger  instance FromIntegral Word32 Integer where-  fromIntegral_ = P.fromInteger+  fromIntegral = P.fromInteger  instance FromIntegral Word64 Integer where-  fromIntegral_ = P.fromInteger+  fromIntegral = P.fromInteger +instance FromIntegral Double Int where+  fromIntegral = P.fromIntegral++instance FromIntegral Float Int where+  fromIntegral = P.fromIntegral+ instance FromIntegral Int Int where-  fromIntegral_ = P.id+  fromIntegral = P.id +instance FromIntegral Integer Int where+  fromIntegral = P.fromIntegral++instance FromIntegral Natural Int where+  fromIntegral = P.fromIntegral++instance FromIntegral Int8 Int where+  fromIntegral = P.fromIntegral++instance FromIntegral Int16 Int where+  fromIntegral = P.fromIntegral++instance FromIntegral Int32 Int where+  fromIntegral = P.fromIntegral++instance FromIntegral Int64 Int where+  fromIntegral = P.fromIntegral++instance FromIntegral Word Int where+  fromIntegral = P.fromIntegral++instance FromIntegral Word8 Int where+  fromIntegral = P.fromIntegral++instance FromIntegral Word16 Int where+  fromIntegral = P.fromIntegral++instance FromIntegral Word32 Int where+  fromIntegral = P.fromIntegral++instance FromIntegral Word64 Int where+  fromIntegral = P.fromIntegral+ instance FromIntegral Natural Natural where-  fromIntegral_ = P.id+  fromIntegral = P.id  instance FromIntegral Int8 Int8 where-  fromIntegral_ = P.id+  fromIntegral = P.id  instance FromIntegral Int16 Int16 where-  fromIntegral_ = P.id+  fromIntegral = P.id  instance FromIntegral Int32 Int32 where-  fromIntegral_ = P.id+  fromIntegral = P.id  instance FromIntegral Int64 Int64 where-  fromIntegral_ = P.id+  fromIntegral = P.id  instance FromIntegral Word Word where-  fromIntegral_ = P.id+  fromIntegral = P.id  instance FromIntegral Word8 Word8 where-  fromIntegral_ = P.id+  fromIntegral = P.id  instance FromIntegral Word16 Word16 where-  fromIntegral_ = P.id+  fromIntegral = P.id  instance FromIntegral Word32 Word32 where-  fromIntegral_ = P.id+  fromIntegral = P.id  instance FromIntegral Word64 Word64 where-  fromIntegral_ = P.id+  fromIntegral = P.id --- | ghc defaulting rules and, it seems, -XExtendedDefaultRules do not permit multiple parameter typeclasses to be in the mix when types are resolved, hence the simpler `type FromInteger a = FromIntegral a Integer` does not suffice.+-- | 'fromInteger' is special in two ways:+--+-- - numeric integral literals (like "42") are interpreted specifically as "fromInteger (42 :: GHC.Num.Integer)". The prelude version is used as default (or whatever fromInteger is in scope if RebindableSyntax is set).+--+-- - The default rules in < https://www.haskell.org/onlinereport/haskell2010/haskellch4.html#x10-750004.3 haskell2010> specify that constraints on 'fromInteger' need to be in a form @C v@, where v is a Num or a subclass of Num.+--+-- So a type synonym of `type FromInteger a = FromIntegral a Integer` doesn't work well with type defaulting; hence the need for a separate class. class FromInteger a where   fromInteger :: Integer -> a-  default fromInteger :: (FromIntegral a Integer) => Integer -> a-  fromInteger = fromIntegral_ -instance FromInteger Integer--instance FromInteger Int+instance FromInteger Double where+  fromInteger = P.fromInteger -instance FromInteger Double+instance FromInteger Float where+  fromInteger = P.fromInteger -instance FromInteger Float+instance FromInteger Int where+  fromInteger = P.fromInteger -instance FromInteger Natural+instance FromInteger Integer where+  fromInteger = P.id -instance FromInteger Int8+instance FromInteger Natural where+  fromInteger = P.fromInteger -instance FromInteger Int16+instance FromInteger Int8 where+  fromInteger = P.fromInteger -instance FromInteger Int32+instance FromInteger Int16 where+  fromInteger = P.fromInteger -instance FromInteger Int64+instance FromInteger Int32 where+  fromInteger = P.fromInteger -instance FromInteger Word+instance FromInteger Int64 where+  fromInteger = P.fromInteger -instance FromInteger Word8+instance FromInteger Word where+  fromInteger = P.fromInteger -instance FromInteger Word16+instance FromInteger Word8 where+  fromInteger = P.fromInteger -instance FromInteger Word32+instance FromInteger Word16 where+  fromInteger = P.fromInteger -instance FromInteger Word64+instance FromInteger Word32 where+  fromInteger = P.fromInteger --- $operators+instance FromInteger Word64 where+  fromInteger = P.fromInteger +-- |+-- >>> even 2+-- True even :: (P.Eq a, Integral a) => a -> P.Bool even n = n `rem` (one + one) P.== zero +-- |+-- >>> odd 3+-- True odd :: (P.Eq a, Integral a) => a -> P.Bool odd = P.not . even ------------------------------------------------------------ | raise a number to a non-negative integral power-(^) ::-  (P.Ord b, Multiplicative a, Integral b) =>+-- | raise a number to an 'Integral' power+(^^) ::+  (P.Ord b, Divisive a, Subtractive b, Integral b) =>   a ->   b ->   a-x0 ^ y0-  | y0 P.< zero = P.undefined-  | -- P.errorWithoutStackTrace "Negative exponent"-    y0 P.== zero =-    one+x0 ^^ y0+  | y0 P.< zero = recip (x0 ^^ negate y0)+  | y0 P.== zero = one   | P.otherwise = f x0 y0   where-    -- f : x0 ^ y0 = x ^ y     f x y       | even y = f (x * x) (y `quot` two)       | y P.== one = x       | P.otherwise = g (x * x) (y `quot` two) x-    -- See Note [Half of y - 1]-    -- g : x0 ^ y0 = (x ^ y) * z     g x y z       | even y = g (x * x) (y `quot` two) z       | y P.== one = x * z       | P.otherwise = g (x * x) (y `quot` two) (x * z) --- See Note [Half of y - 1]--(^^) ::-  (Divisive a, Subtractive b, Integral b, P.Ord b) => a -> b -> a-(^^) x n = if n P.>= zero then x ^ n else recip (x ^ negate n)+-- | raise a number to an 'Int' power+--+-- Note: This differs from (^) found in prelude which is a partial function (it errors on negative integrals). This monomorphic version is provided to help reduce ambiguous type noise in common usages of this sign.+(^) ::+  (Divisive a) => a -> Int -> a+(^) x n = x ^^ n
src/NumHask/Data/LogField.hs view
@@ -8,6 +8,17 @@ {-# LANGUAGE UndecidableInstances #-} {-# OPTIONS_GHC -Wall #-} +-- Module      :  Data.Number.LogFloat+-- Copyright   :  Copyright (c) 2007--2015 wren gayle romano+-- License     :  BSD3+-- Maintainer  :  wren@community.haskell.org+-- Stability   :  stable+-- Portability :  portable (with CPP, FFI)+-- Link        :  https://hackage.haskell.org/package/logfloat++-- | A 'Field' in the log domain.+--+-- LogField is adapted from [logfloat](https://hackage.haskell.org/package/logfloat) module NumHask.Data.LogField   ( -- * @LogField@     LogField (),@@ -28,31 +39,15 @@ import Data.Data (Data) import qualified Data.Foldable as F import GHC.Generics (Generic, Generic1)-import NumHask.Algebra.Abstract.Additive-import NumHask.Algebra.Abstract.Field-import NumHask.Algebra.Abstract.Lattice-import NumHask.Algebra.Abstract.Multiplicative-import NumHask.Algebra.Abstract.Ring+import NumHask.Algebra.Additive+import NumHask.Algebra.Field+import NumHask.Algebra.Lattice+import NumHask.Algebra.Multiplicative+import NumHask.Algebra.Ring import NumHask.Analysis.Metric import NumHask.Data.Integral import NumHask.Data.Rational-import Prelude hiding (Num (..), exp, log, negate)---- LogField is adapted from LogFloat--------------------------------------------------------------------                                                  ~ 2015.08.06---- |--- Module      :  Data.Number.LogFloat--- Copyright   :  Copyright (c) 2007--2015 wren gayle romano--- License     :  BSD3--- Maintainer  :  wren@community.haskell.org--- Stability   :  stable--- Portability :  portable (with CPP, FFI)--- Link        :  https://hackage.haskell.org/package/logfloat-------------------------------------------------------------------------------------------------------------------------------------+import Prelude hiding (Num (..), exp, fromIntegral, log, negate)  -- | A @LogField@ is just a 'Field' with a special interpretation. -- The 'LogField' function is presented instead of the constructor,@@ -69,7 +64,6 @@ -- > logField (p + q) == logField p + logField q -- > logField (p * q) == logField p * logField q ----- -- Performing operations in the log-domain is cheap, prevents -- underflow, and is otherwise very nice for dealing with miniscule -- probabilities. However, crossing into and out of the log-domain@@ -80,7 +74,7 @@ -- won't underflow; because that way you enter the log-domain only -- once, instead of twice. Also note that, for precision, if you're -- doing more than a few multiplications in the log-domain, you--- should use 'product' rather than using '(*)' repeatedly.+-- should use 'NumHask.Algebra.Multiplication.product' rather than using '(*)' repeatedly. -- -- Even more particularly, you should /avoid addition/ whenever -- possible. Addition is provided because sometimes we need it, and@@ -222,7 +216,7 @@   (**) x (LogField y) = pow x $ exp y  instance (FromIntegral a b, ExpField a) => FromIntegral (LogField a) b where-  fromIntegral_ = logField . fromIntegral_+  fromIntegral = logField . fromIntegral  instance (ToIntegral a b, ExpField a) => ToIntegral (LogField a) b where   toIntegral = toIntegral . fromLogField@@ -254,10 +248,6 @@   LowerBoundedField (LogField a)  instance-  (Ord a, ExpField a, LowerBoundedField a) =>-  IntegralDomain (LogField a)--instance   (Ord a, ExpField a, LowerBoundedField a, UpperBoundedField a) =>   UpperBoundedField (LogField a) @@ -276,8 +266,6 @@ -- equivalence holds (modulo underflow and all that): -- -- > LogField (p ** m) == LogField p `pow` m------ /Since: 0.13/ pow :: (ExpField a, LowerBoundedField a, Ord a) => LogField a -> a -> LogField a {-# INLINE pow #-} 
− src/NumHask/Data/Pair.hs
@@ -1,220 +0,0 @@-{-# LANGUAGE DeriveGeneric #-}-{-# LANGUAGE FlexibleContexts #-}-{-# LANGUAGE FlexibleInstances #-}-{-# LANGUAGE MultiParamTypeClasses #-}-{-# LANGUAGE PatternSynonyms #-}-{-# LANGUAGE TypeFamilies #-}-{-# LANGUAGE UndecidableInstances #-}-{-# OPTIONS_GHC -Wall #-}---- | A Pair is *the* classical higher-kinded number but there is no canon.-module NumHask.Data.Pair-  ( Pair (..),-    pattern Pair,-  )-where--import Data.Functor.Classes-import GHC.Generics (Generic)-import NumHask.Algebra.Abstract-import NumHask.Analysis.Metric-import NumHask.Data.Integral-import NumHask.Data.Rational-import Text.Show-import Prelude ((&&), (<$>), (<*>), Applicative, Bounded (..), Eq (..), Foldable, Functor (..), Monad, Monoid (..), Semigroup (..), Traversable)-import qualified Prelude as P---- $setup--- >>> :set -XNoImplicitPrelude--- >>> :set -XFlexibleContexts---- | A pair of a's, implemented as a tuple, but api represented as a Pair of a's.------ >>> fmap (+1) (Pair 1 2)--- Pair 2 3--- >>> pure one :: Pair Int--- Pair 1 1--- >>> (*) <$> Pair 1 2 <*> pure 2--- Pair 2 4--- >>> foldr (++) [] (Pair [1,2] [3])--- [1,2,3]--- >>> Pair "a" "pair" `mappend` pure " " `mappend` Pair "string" "mappended"--- Pair "a string" "pair mappended"------ As a Ring and Field class------ >>> Pair 0 1 + zero--- Pair 0 1--- >>> Pair 0 1 + Pair 2 3--- Pair 2 4--- >>> Pair 1 1 - one--- Pair 0 0--- >>> Pair 0 1 * one--- Pair 0 1--- >>> Pair 0.0 1.0 / one--- Pair 0.0 1.0--- >>> Pair 11 12 `mod` (pure 6)--- Pair 5 0------ As an action------ >>> Pair 1 2 .+ 3--- Pair 4 5-newtype Pair a-  = Pair' (a, a)-  deriving (Eq, Generic)---- | the preferred pattern-pattern Pair :: a -> a -> Pair a-pattern Pair a b = Pair' (a, b)--{-# COMPLETE Pair #-}--instance (Show a) => Show (Pair a) where-  show (Pair a b) = "Pair " <> Text.Show.show a <> " " <> Text.Show.show b--instance Functor Pair where-  fmap f (Pair a b) = Pair (f a) (f b)--instance Eq1 Pair where-  liftEq f (Pair a b) (Pair c d) = f a c && f b d--instance Show1 Pair where-  liftShowsPrec sp _ d (Pair' (a, b)) = showsBinaryWith sp sp "Pair" d a b--instance Applicative Pair where-  pure a = Pair a a-  (Pair fa fb) <*> Pair a b = Pair (fa a) (fb b)--instance Monad Pair where-  Pair a b >>= f = Pair a' b'-    where-      Pair a' _ = f a-      Pair _ b' = f b--instance Foldable Pair where-  foldMap f (Pair a b) = f a `mappend` f b--instance Traversable Pair where-  traverse f (Pair a b) = Pair <$> f a <*> f b--instance (Semigroup a) => Semigroup (Pair a) where-  (Pair a0 b0) <> (Pair a1 b1) = Pair (a0 <> a1) (b0 <> b1)--instance (Semigroup a, Monoid a) => Monoid (Pair a) where-  mempty = Pair mempty mempty-  mappend = (<>)--instance (Bounded a) => Bounded (Pair a) where-  minBound = Pair minBound minBound-  maxBound = Pair maxBound maxBound--unaryOp :: (a -> a) -> (Pair a -> Pair a)-unaryOp f (Pair a b) = Pair (f a) (f b)--binOp :: (a -> a -> a) -> (Pair a -> Pair a -> Pair a)-binOp (#) (Pair a0 b0) (Pair a1 b1) = Pair (a0 # a1) (b0 # b1)---- numeric heirarchy-instance (Additive a) => Additive (Pair a) where-  (Pair a0 b0) + (Pair a1 b1) = Pair (a0 + a1) (b0 + b1)-  zero = Pair zero zero--instance (Subtractive a) => Subtractive (Pair a) where-  negate = unaryOp negate--instance (Multiplicative a) => Multiplicative (Pair a) where-  (Pair a0 b0) * (Pair a1 b1) = Pair (a0 * a1) (b0 * b1)-  one = Pair one one--instance (Divisive a) => Divisive (Pair a) where-  recip = unaryOp recip--instance (Integral a) => Integral (Pair a) where-  (Pair a0 b0) `divMod` (Pair a1 b1) = (Pair da db, Pair ma mb)-    where-      (da, ma) = a0 `divMod` a1-      (db, mb) = b0 `divMod` b1-  (Pair a0 b0) `quotRem` (Pair a1 b1) = (Pair da db, Pair ma mb)-    where-      (da, ma) = a0 `quotRem` a1-      (db, mb) = b0 `quotRem` b1--instance (Signed a) => Signed (Pair a) where-  sign = unaryOp sign-  abs = unaryOp abs--instance-  (ExpField a, Normed a a) =>-  Normed (Pair a) a-  where-  norm (Pair a b) = norm a + norm b--instance (Subtractive a, Epsilon a) => Epsilon (Pair a) where-  epsilon = Pair epsilon epsilon-  nearZero (Pair a b) = nearZero a && nearZero b--instance (ExpField a, Subtractive a, Normed a a) => Metric (Pair a) a where-  distance a b = norm (a - b)--instance (Distributive a) => Distributive (Pair a)--instance (Field a) => Field (Pair a)--instance (IntegralDomain a) => IntegralDomain (Pair a)--instance (ExpField a) => ExpField (Pair a) where-  exp = unaryOp exp-  log = unaryOp log--instance (UpperBoundedField a) => UpperBoundedField (Pair a)--instance (LowerBoundedField a) => LowerBoundedField (Pair a)--type instance Actor (Pair a) = a--instance (Additive a) => AdditiveAction (Pair a) where-  (.+) r s = fmap (s +) r-  (+.) s r = fmap (s +) r--instance (Subtractive a) => SubtractiveAction (Pair a) where-  (.-) r s = fmap (\x -> x - s) r-  (-.) s r = fmap (\x -> x - s) r--instance (Multiplicative a) => MultiplicativeAction (Pair a) where-  (.*) r s = fmap (s *) r-  (*.) s r = fmap (s *) r--instance (Divisive a) => DivisiveAction (Pair a) where-  (./) r s = fmap (/ s) r-  (/.) s r = fmap (/ s) r--instance (JoinSemiLattice a) => JoinSemiLattice (Pair a) where-  (\/) = binOp (\/)--instance (MeetSemiLattice a) => MeetSemiLattice (Pair a) where-  (/\) = binOp (/\)--instance (BoundedJoinSemiLattice a) => BoundedJoinSemiLattice (Pair a) where-  bottom = Pair bottom bottom--instance (BoundedMeetSemiLattice a) => BoundedMeetSemiLattice (Pair a) where-  top = Pair top top--instance (FromIntegral a b) => FromIntegral (Pair a) b where-  fromIntegral_ x = P.pure (fromIntegral_ x)--instance (FromRatio a b) => FromRatio (Pair a) b where-  fromRatio x = P.pure (fromRatio x)--instance-  (Normed a a) =>-  Normed (Pair a) (Pair a)-  where-  norm = fmap norm--instance-  (Subtractive a, Normed a a) =>-  Metric (Pair a) (Pair a)-  where-  distance a b = norm (a - b)
src/NumHask/Data/Positive.hs view
@@ -2,21 +2,29 @@ {-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE GeneralizedNewtypeDeriving #-} {-# LANGUAGE MultiParamTypeClasses #-}-{-# LANGUAGE RoleAnnotations #-} {-# OPTIONS_GHC -Wall #-} -module NumHask.Data.Positive where+-- | Positive numbers.+--+-- Positivity is enforced via the positive constructor+module NumHask.Data.Positive+  ( Positive,+    positive,+    positive_,+  )+where -import NumHask.Algebra.Abstract.Additive-import NumHask.Algebra.Abstract.Field-import NumHask.Algebra.Abstract.Lattice-import NumHask.Algebra.Abstract.Multiplicative-import NumHask.Algebra.Abstract.Ring+import NumHask.Algebra.Additive+import NumHask.Algebra.Field+import NumHask.Algebra.Lattice+import NumHask.Algebra.Multiplicative+import NumHask.Algebra.Ring import NumHask.Analysis.Metric import NumHask.Data.Integral import NumHask.Exception import qualified Prelude as P +-- | Wrapper for positive numbers.  Note that the constructor is not exported. newtype Positive a = Positive {unPositive :: a}   deriving     ( P.Show,@@ -26,7 +34,6 @@       Multiplicative,       Divisive,       Distributive,-      IntegralDomain,       Field,       ExpField,       TrigField,@@ -37,16 +44,15 @@       Epsilon     ) --- not sure if this is correct or needed-type role Positive representational--positive :: (P.Ord a, Additive a) => a -> P.Maybe (Positive a)-positive a+-- | maybe construct a 'Positive'+positive_ :: (P.Ord a, Additive a) => a -> P.Maybe (Positive a)+positive_ a   | a P.< zero = P.Nothing   | P.otherwise = P.Just (Positive a) -positive_ :: (P.Ord a, Additive a) => a -> Positive a-positive_ a+-- | Construct a Positive, throwing an error if the input is negative.+positive :: (P.Ord a, Additive a) => a -> Positive a+positive a   | a P.< zero = throw (NumHaskException "positive number less than zero")   | P.otherwise = Positive a @@ -74,13 +80,3 @@ instance (P.Ord a, UpperBoundedField a) => P.Bounded (Positive a) where   minBound = zero   maxBound = infinity---- Metric-instance-  (Normed a a) =>-  Normed a (Positive a)-  where-  norm a = Positive (norm a)--instance (Subtractive a, Normed a a) => Metric a (Positive a) where-  distance a b = Positive P.$ norm (a - b)
src/NumHask/Data/Rational.hs view
@@ -3,24 +3,18 @@ {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE RebindableSyntax #-} {-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE TypeFamilies #-} {-# OPTIONS_GHC -Wall #-} --- | Integral classes+-- | Rational classes module NumHask.Data.Rational   ( Ratio (..),     Rational,     ToRatio (..),-    ToRational,-    toRational,     FromRatio (..),-    FromRational,-    fromRational,-    fromRational',-    fromBaseRational,--    -- * \$integral_functionality+    FromRational (..),     reduce,     gcd,   )@@ -32,16 +26,23 @@ import GHC.Float import GHC.Natural (Natural (..)) import qualified GHC.Real-import NumHask.Algebra.Abstract.Additive-import NumHask.Algebra.Abstract.Field-import NumHask.Algebra.Abstract.Lattice-import NumHask.Algebra.Abstract.Multiplicative-import NumHask.Algebra.Abstract.Ring+import NumHask.Algebra.Additive+import NumHask.Algebra.Field+import NumHask.Algebra.Lattice+import NumHask.Algebra.Multiplicative+import NumHask.Algebra.Ring import NumHask.Analysis.Metric import NumHask.Data.Integral import Prelude ((.), Int, Integer, Rational) import qualified Prelude as P +-- $setup+--+-- >>> :set -XRebindableSyntax+-- >>> :set -XNegativeLiterals+-- >>> import NumHask.Prelude++-- | A rational number data Ratio a = !a :% !a deriving (P.Show)  instance (P.Eq a, Additive a) => P.Eq (Ratio a) where@@ -52,6 +53,7 @@       (x :% y) = a       (x' :% y') = b +-- | Has a zero denominator isRNaN :: (P.Eq a, Additive a) => Ratio a -> P.Bool isRNaN (x :% y)   | x P.== zero P.&& y P.== zero = P.True@@ -61,10 +63,7 @@   (x :% y) <= (x' :% y') = x * y' P.<= x' * y   (x :% y) < (x' :% y') = x * y' P.< x' * y --- | These common constraints over the Ratio instances are due to the gcd algorithm. Subtractive is somewhat problematic with obtaining a `Ratio (Positive Integer)` which should be made possible.-type GCDConstraints a = (P.Ord a, Signed a, Integral a, Subtractive a)--instance (GCDConstraints a) => Additive (Ratio a) where+instance (P.Ord a, Signed a, Integral a, Ring a) => Additive (Ratio a) where   (x :% y) + (x' :% y')     | y P.== zero P.&& y' P.== zero = bool one (negate one) (x + x' P.< zero) :% zero     | y P.== zero = x :% y@@ -73,66 +72,66 @@    zero = zero :% one -instance (GCDConstraints a) => Subtractive (Ratio a) where+instance (P.Ord a, Signed a, Integral a, Ring a) => Subtractive (Ratio a) where   negate (x :% y) = negate x :% y -instance (GCDConstraints a) => Multiplicative (Ratio a) where+instance (P.Ord a, Signed a, Integral a, Ring a, Multiplicative a) => Multiplicative (Ratio a) where   (x :% y) * (x' :% y') = reduce (x * x') (y * y')    one = one :% one  instance-  (GCDConstraints a) =>+  (P.Ord a, Signed a, Integral a, Ring a) =>   Divisive (Ratio a)   where   recip (x :% y)     | sign x P.== negate one = negate y :% negate x     | P.otherwise = y :% x -instance (GCDConstraints a) => Distributive (Ratio a)--instance (GCDConstraints a) => IntegralDomain (Ratio a)+instance (P.Ord a, Signed a, Integral a, Ring a) => Distributive (Ratio a) -instance (GCDConstraints a) => Field (Ratio a)+instance (P.Ord a, Signed a, Integral a, Ring a) => Field (Ratio a) -instance (GCDConstraints a, GCDConstraints b, ToInteger a, Field a, FromIntegral b a) => QuotientField (Ratio a) b where-  properFraction (n :% d) = let (w, r) = quotRem n d in (fromIntegral_ w, r :% d)+instance (P.Ord a, Signed a, Integral a, Ring a, P.Ord b, Signed b, Integral b, Ring b, Field a, FromIntegral b a) => QuotientField (Ratio a) b where+  properFraction (n :% d) = let (w, r) = quotRem n d in (fromIntegral w, r :% d)  instance-  (GCDConstraints a, Distributive a, IntegralDomain a) =>+  (P.Ord a, Signed a, Integral a, Ring a, Distributive a) =>   UpperBoundedField (Ratio a) -instance (GCDConstraints a, Field a) => LowerBoundedField (Ratio a)+instance (P.Ord a, Signed a, Integral a, Field a) => LowerBoundedField (Ratio a) -instance (GCDConstraints a) => Signed (Ratio a) where+instance (P.Ord a, Signed a, Integral a, Ring a) => Signed (Ratio a) where   sign (n :% _)     | n P.== zero = zero     | n P.> zero = one     | P.otherwise = negate one   abs (n :% d) = abs n :% abs d -instance (GCDConstraints a) => Normed (Ratio a) (Ratio a) where+instance (P.Ord a, Signed a, Integral a, Ring a) => Norm (Ratio a) (Ratio a) where   norm = abs+  basis = sign -instance (GCDConstraints a) => Metric (Ratio a) (Ratio a) where-  distance a b = norm (a - b)+instance (P.Ord a, Signed a) => JoinSemiLattice (Ratio a) where+  (\/) = P.min -instance (GCDConstraints a, MeetSemiLattice a) => Epsilon (Ratio a)+instance (P.Ord a, Signed a) => MeetSemiLattice (Ratio a) where+  (/\) = P.max +instance (P.Ord a, Signed a, Integral a, Ring a, MeetSemiLattice a) => Epsilon (Ratio a)+ instance (FromIntegral a b, Multiplicative a) => FromIntegral (Ratio a) b where-  fromIntegral_ x = fromIntegral_ x :% one+  fromIntegral x = fromIntegral x :% one --- | toRatio is equivalent to `Real` in base, but is polymorphic in the Integral type.+-- | toRatio is equivalent to `GHC.Real.Real` in base, but is polymorphic in the Integral type.+--+-- > toRatio (3.1415927 :: Float) :: Ratio Integer+-- 13176795 :% 4194304 class ToRatio a b where   toRatio :: a -> Ratio b-  default toRatio :: (Ratio c ~ a, ToIntegral c Integer, ToRatio (Ratio b) b, FromInteger b) => a -> Ratio b+  default toRatio :: (Ratio c ~ a, FromIntegral b c, ToRatio (Ratio b) b) => a -> Ratio b   toRatio (n :% d) = toRatio ((fromIntegral n :: b) :% fromIntegral d) -type ToRational a = ToRatio a Integer--toRational :: (ToRatio a Integer) => a -> Ratio Integer-toRational = toRatio- instance ToRatio Double Integer where   toRatio = fromBaseRational . P.toRational @@ -181,13 +180,12 @@ instance ToRatio Word64 Integer where   toRatio = fromBaseRational . P.toRational --- | `Fractional` in base splits into fromRatio and Field--- FIXME: work out why the default type isn't firing so that an explicit instance is needed--- for `FromRatio (Ratio Integer) Integer`+-- | `GHC.Real.Fractional` in base splits into fromRatio and Field+--+-- >>> fromRatio (5 :% 2 :: Ratio Integer) :: Double+-- 2.5 class FromRatio a b where   fromRatio :: Ratio b -> a-  -- default fromRatio :: (a ~ Ratio c, ToIntegral b c) => Ratio b -> a-  -- fromRatio (n :% d) = toIntegral n :% toIntegral d   default fromRatio :: (Ratio b ~ a) => Ratio b -> a   fromRatio = P.id @@ -203,37 +201,26 @@ instance FromRatio Rational Integer where   fromRatio (n :% d) = n GHC.Real.% d -instance FromRatio (Ratio Integer) Integer where-  fromRatio = P.id---- | with RebindableSyntax the literal '1.0' mean exactly `fromRational (1.0::GHC.Real.Rational)`.+-- | fromRational is special in two ways:+--+-- - numeric decimal literals (like "53.66") are interpreted as exactly "fromRational (53.66 :: GHC.Real.Ratio Integer)". The prelude version, GHC.Real.fromRational is used as default (or whatever is in scope if RebindableSyntax is set).+--+-- - The default rules in < https://www.haskell.org/onlinereport/haskell2010/haskellch4.html#x10-750004.3 haskell2010> specify that contraints on 'fromRational' need to be in a form @C v@, where v is a Num or a subclass of Num.+--+-- So a type synonym of `type FromRational a = FromRatio a Integer` doesn't work well with type defaulting; hence the need for a separate class. class FromRational a where   fromRational :: P.Rational -> a-  default fromRational :: (FromRatio a Integer) => P.Rational -> a-  fromRational = fromRatio . fromBaseRational -instance FromRational Double--instance FromRational Float--instance FromRational Rational---- | Given that fromRational is reserved, fromRational' provides general conversion between numhask rationals.-fromRational' :: (FromRatio b Integer, ToRatio a Integer) => a -> b-fromRational' a = fromRatio (toRatio a :: Ratio Integer)--instance (GCDConstraints a) => JoinSemiLattice (Ratio a) where-  (\/) = P.min+instance FromRational Double where+  fromRational (n GHC.Real.:% d) = rationalToDouble n d -instance (GCDConstraints a) => MeetSemiLattice (Ratio a) where-  (/\) = P.max+instance FromRational Float where+  fromRational (n GHC.Real.:% d) = rationalToFloat n d --- * \$integral_functions--- integral functionality is largely based on GHC.Real---+instance FromRational (Ratio Integer) where+  fromRational (n GHC.Real.:% d) = n :% d --- | 'reduce' is a subsidiary function used only in this module.--- It normalises a ratio by dividing both numerator and denominator by+-- | 'reduce' normalises a ratio by dividing both numerator and denominator by -- their greatest common divisor. reduce ::   (P.Eq a, Subtractive a, Signed a, Integral a) => a -> a -> Ratio a@@ -253,9 +240,9 @@ -- (That is, the common divisor that is \"greatest\" in the divisibility -- preordering.) ----- Note: Since for signed fixed-width integer types, @'abs' 'minBound' < 0@,--- the result may be negative if one of the arguments is @'minBound'@ (and--- necessarily is if the other is @0@ or @'minBound'@) for such types.+-- Note: Since for signed fixed-width integer types, @'abs' 'GHC.Enum.minBound' < 0@,+-- the result may be negative if one of the arguments is @'GHC.Enum.minBound'@ (and+-- necessarily is if the other is @0@ or @'GHC.Enum.minBound'@) for such types. gcd :: (P.Eq a, Signed a, Integral a) => a -> a -> a gcd x y = gcd' (abs x) (abs y)   where
src/NumHask/Data/Wrapped.hs view
@@ -3,21 +3,27 @@ {-# LANGUAGE GeneralizedNewtypeDeriving #-} {-# LANGUAGE MultiParamTypeClasses #-} {-# LANGUAGE RoleAnnotations #-}+{-# LANGUAGE UndecidableInstances #-} {-# OPTIONS_GHC -Wall #-} -module NumHask.Data.Wrapped where+-- | Wrapped numhask instances, useful for derivingvia situations to quickly specifiy a numhask friendly numerical type.+module NumHask.Data.Wrapped+  ( Wrapped (..),+  )+where -import NumHask.Algebra.Abstract.Additive-import NumHask.Algebra.Abstract.Field-import NumHask.Algebra.Abstract.Group-import NumHask.Algebra.Abstract.Lattice-import NumHask.Algebra.Abstract.Multiplicative-import NumHask.Algebra.Abstract.Ring+import NumHask.Algebra.Additive+import NumHask.Algebra.Field+import NumHask.Algebra.Group+import NumHask.Algebra.Lattice+import NumHask.Algebra.Multiplicative+import NumHask.Algebra.Ring import NumHask.Analysis.Metric import NumHask.Data.Integral import NumHask.Data.Rational import qualified Prelude as P +-- | Wrapped numeric instances newtype Wrapped a = Wrapped {unWrapped :: a}   deriving     ( P.Show,@@ -30,7 +36,7 @@       Multiplicative,       Divisive,       Distributive,-      IntegralDomain,+      Ring,       InvolutiveRing,       StarSemiring,       KleeneAlgebra,@@ -41,14 +47,13 @@       Signed,       MeetSemiLattice,       JoinSemiLattice,+      BoundedJoinSemiLattice,+      BoundedMeetSemiLattice,       Epsilon,       UpperBoundedField,       LowerBoundedField     ) --- not sure if this is correct or needed-type role Wrapped representational- instance   (P.Ord a, QuotientField a P.Integer) =>   QuotientField (Wrapped a) (Wrapped P.Integer)@@ -56,7 +61,7 @@   properFraction (Wrapped a) = let (i, r) = properFraction a in (Wrapped i, Wrapped r)  instance (FromIntegral a b) => FromIntegral (Wrapped a) b where-  fromIntegral_ a = Wrapped (fromIntegral_ a)+  fromIntegral a = Wrapped (fromIntegral a)  instance (ToIntegral a b) => ToIntegral (Wrapped a) b where   toIntegral (Wrapped a) = toIntegral a@@ -66,9 +71,3 @@  instance (ToRatio a b) => ToRatio (Wrapped a) b where   toRatio (Wrapped a) = toRatio a--instance (Normed a b) => Normed (Wrapped a) (Wrapped b) where-  norm (Wrapped a) = Wrapped (norm a)--instance (Metric a b) => Metric (Wrapped a) (Wrapped b) where-  distance (Wrapped a) (Wrapped b) = Wrapped (distance a b)
src/NumHask/Exception.hs view
@@ -1,5 +1,6 @@ {-# OPTIONS_GHC -Wall #-} +-- | Exceptions arising within numhask. module NumHask.Exception   ( NumHaskException (..),     throw,@@ -10,6 +11,7 @@ import Data.Typeable (Typeable) import qualified Prelude as P +-- | A numhask exception. newtype NumHaskException = NumHaskException {errorMessage :: P.String}   deriving (P.Show, Typeable) 
src/NumHask/Prelude.hs view
@@ -1,43 +1,50 @@+{-# LANGUAGE NegativeLiterals #-}+{-# LANGUAGE RebindableSyntax #-} {-# OPTIONS_GHC -Wall #-} {-# OPTIONS_HADDOCK prune #-} --- | Combines 'Protolude' and 'numhask'.+-- | A numeric prelude, composed by splicing numhask modules with [protolude](https://hackage.haskell.org/package/protolude), together with a few minor tweaks and additions. module NumHask.Prelude-  ( -- * NumHask-    -- $instances-    module NumHask.Algebra.Abstract.Action,-    module NumHask.Algebra.Abstract.Additive,-    module NumHask.Algebra.Abstract.Field,-    module NumHask.Algebra.Abstract.Group,-    module NumHask.Algebra.Abstract.Lattice,-    module NumHask.Algebra.Abstract.Module,-    module NumHask.Algebra.Abstract.Multiplicative,-    module NumHask.Algebra.Abstract.Ring,+  ( -- * numhask exports+    module NumHask.Algebra.Additive,+    module NumHask.Algebra.Field,+    module NumHask.Algebra.Group,+    module NumHask.Algebra.Lattice,+    module NumHask.Algebra.Module,+    module NumHask.Algebra.Multiplicative,+    module NumHask.Algebra.Ring,     module NumHask.Analysis.Metric,     module NumHask.Data.Complex,     module NumHask.Data.Integral,     module NumHask.Data.LogField,     module NumHask.Data.Rational,-    module NumHask.Data.Pair,     module NumHask.Data.Positive,-    Natural (..),     module NumHask.Exception, -    -- * Backend-    -- $backend-    Category (..),-    module Protolude,-    module Data.Biapplicative,-    module Control.Monad.Morph,-    module Data.Functor.Constant,-    pack,-    unpack,-    -- | Using different types for numbers requires RebindableSyntax.  This then removes all sorts of base-level stuff that has to be put back in.+    -- * rebindables+    -- $rebindables     fromString,     fail,     ifThenElse,     fromList,     fromListN,++    -- * extras+    -- $extras+    Category (..),+    pack,+    unpack,+    module Data.Bifunctor,+    module Data.Biapplicative,+    module Control.Monad.Morph,+    module Data.Functor.Constant,+    module System.Random,+    module System.Random.Stateful,+    Natural (..),++    -- * protolude+    -- $protolude+    module Protolude,   ) where @@ -45,40 +52,60 @@ import Control.Monad (fail) import Control.Monad.Morph import Data.Biapplicative+import Data.Bifunctor import Data.Functor.Constant import Data.String import Data.Text (pack, unpack) import GHC.Exts import GHC.Natural (Natural (..))-import NumHask.Algebra.Abstract.Action-import NumHask.Algebra.Abstract.Additive-import NumHask.Algebra.Abstract.Field-import NumHask.Algebra.Abstract.Group-import NumHask.Algebra.Abstract.Lattice-import NumHask.Algebra.Abstract.Module-import NumHask.Algebra.Abstract.Multiplicative-import NumHask.Algebra.Abstract.Ring+import NumHask.Algebra.Additive+import NumHask.Algebra.Field+import NumHask.Algebra.Group+import NumHask.Algebra.Lattice+import NumHask.Algebra.Module+import NumHask.Algebra.Multiplicative+import NumHask.Algebra.Ring import NumHask.Analysis.Metric import NumHask.Data.Complex import NumHask.Data.Integral import NumHask.Data.LogField-import NumHask.Data.Pair import NumHask.Data.Positive import NumHask.Data.Rational import NumHask.Exception-import Protolude hiding ((*), (**), (+), (-), (.), (/), (<<$>>), (<<*>>), Complex (..), Integral (..), Product (..), Ratio, Rep, Semiring (..), Sum (..), (^), (^^), abs, acos, acosh, asin, asinh, atan, atan2, atanh, ceiling, cis, cos, cosh, even, exp, floor, fromInteger, fromIntegral, fromRational, gcd, imagPart, infinity, log, logBase, magnitude, mkPolar, negate, odd, phase, pi, polar, product, properFraction, realPart, recip, reduce, round, sin, sinh, sqrt, subtract, sum, tan, tanh, toInteger, toRational, trans, truncate, zero)+import Protolude hiding ((*), (**), (+), (-), (.), (/), (<<$>>), (<<*>>), Complex (..), Integral (..), Ratio, Product (..), Rep, Semiring (..), Sum (..), (^), (^^), abs, acos, acosh, asin, asinh, atan, atan2, atanh, ceiling, cis, cos, cosh, even, exp, floor, fromInteger, fromIntegral, fromRational, gcd, imagPart, infinity, log, logBase, magnitude, mkPolar, negate, odd, phase, pi, polar, product, properFraction, realPart, recip, reduce, round, sin, sinh, sqrt, subtract, sum, tan, tanh, toInteger, toRational, trans, truncate, zero)+import System.Random+import System.Random.Stateful --- $backend--- NumHask imports Protolude as a starting prelude.+-- $usage ----- In addition, 'id' is imported (protolude uses 'identity')+-- >>> :set -XRebindableSyntax+-- >>> :set -XNegativeLiterals+-- >>> import NumHask.Prelude+-- >>> 1+1+-- 2 --- $instances--- NumHask replaces much of the 'Num' and 'Real' heirarchies in protolude & base.+-- $rebindables ----- Instances for 'Int', 'Integer', 'Float', 'Double', 'Bool', 'Complex' and 'Natural'are supplied.+-- Using different types for numbers requires RebindableSyntax.  This then removes base-level stuff that has to be put back in. --- | rebindable syntax splats this, and I'm not sure where it exists in GHC land+-- | RebindableSyntax splats this, and I'm not sure where it exists in GHC land ifThenElse :: Bool -> a -> a -> a ifThenElse True x _ = x ifThenElse False _ y = y++-- $extras+--+-- Bits and pieces different to protolude, including:+--+-- - re-inserting 'id' which should never be overwritten in haskell code.+--+-- - 'Data.Bifunctors' & 'Data.Biapplicative' which are favorites of the OA.+--+-- - 'Control.Monad.Morph'; another essential, ubiquitous library.+--+-- - 'Data.Functor.Constant'+--+-- - 'pack' and 'unpack', which may encourage usage of 'String' but can also quickly escape from the same.++-- $protolude+-- It would be nice to just link straight through to the [protolude documentation](https://hackage.haskell.org/package/protolude), but, alas, at time of production, haddock insists on dumping everything here.
+ test/test.hs view
@@ -0,0 +1,21 @@+{-# LANGUAGE RebindableSyntax #-}+{-# OPTIONS_GHC -Wall #-}++module Main where++import NumHask.Prelude+import Test.DocTest++main :: IO ()+main =+  doctest+  [ "src/NumHask.hs",+    "src/NumHask/Prelude.hs",+    "src/NumHask/Algebra/Additive.hs",+    "src/NumHask/Algebra/Multiplicative.hs",+    "src/NumHask/Algebra/Ring.hs",+    "src/NumHask/Algebra/Field.hs",+    "src/NumHask/Algebra/Module.hs"+    -- FIXME: When doctest hits this module, it can't resolve even the simplest instances ...+    -- "src/NumHask/Data/Rational.hs"+  ]