kind-rational 0.4 → 0.5.0
raw patch · 4 files changed
+3233/−2529 lines, 4 filesdep +singletons-basedep ~kind-integer
Dependencies added: singletons-base
Dependency ranges changed: kind-integer
Files
- CHANGELOG.md +36/−1
- kind-rational.cabal +4/−3
- lib/KindRational.hs +1119/−673
- test/Main.hs +2074/−1852
CHANGELOG.md view
@@ -1,4 +1,39 @@-# Version 0.3.1+# Version 0.5.0++* COMPILER ASSISTED BREAKING CHANGE: `KindRational.Rational` is now+ is now only ever used as a kind. So, all term-level functions in+ the `KindRational` consume and produce `Prelude.Rational`s. Term-level+ functions crash will `error` if they are supplied `Rational`s that+ are not `Reduced` as input.++* COMPILER ASSISTED BREAKING CHANGE: Removed `Eq`, `Ord`, `Show` and+ `Read` instances for `KindRational.Rational`.++* COMPILER ASSISTED BREAKING CHANGE: Removed `withTerminating` in favor of+ `termination`.++* COMPILER ASSISTED BREAKING CHANGE: `Rational`s that are not `Reduced`+ are not `KnownRational`s anymore.++* COMPILER ASSISTED BREAKING CHANGE: `KnownRational` is now a type-synonym+ that implies `Normalize r ~ r`, `KnownInteger (Num r)` and+ `KnownNat (Den r)` as well.++* Added `singletons-base` support for `Rational`, including `PNum`, `SNum`,+ `PEq`, `SEq`, `POrd`, `SOrd`, `PShow` and `SShow`. Most arithmetic+ functions are now exported through `PNum` and `SNum`, rather than standalone.++* Added `readPrecTypeLit`, `SRationalTerminates`, `SRationalTerminatesNot`,+ `normalize`, `rationalLit`, `NonTerminating`, `%`, `%%`, `ToRational`,+ `mkRational`, `sMkRational`, `sRecip'`.++* Added `ShowLit`, `ShowsLit`, `ShowsPrecLit` and its singletons and+ promoted versions.++* Added defunctionalization symbols.+++# Version 0.4 * COMPILER ASSISTED BREAKING CHANGE: `rationalVal`, `someRationalVal`, `fromSRational`, `terminates`, `divRem`, `div` and `rem` now deal
kind-rational.cabal view
@@ -1,6 +1,6 @@ cabal-version: 2.4 name: kind-rational-version: 0.4+version: 0.5.0 license: BSD-3-Clause license-file: LICENSE extra-source-files: README.md CHANGELOG.md@@ -13,7 +13,7 @@ description: Type-level rationals. Like KnownNat, but for rationals. homepage: https://github.com/k0001/hs-kind bug-reports: https://github.com/k0001/hs-kind/issues-tested-with: GHC ==9.4.3+tested-with: GHC ==9.4.5, GHC ==9.6.1 source-repository head type: git@@ -25,8 +25,9 @@ ghc-options: -O2 -Wall -Werror=incomplete-patterns build-depends: base ==4.*,- kind-integer >=0.5,+ kind-integer >=0.6, singletons,+ singletons-base, default-extensions: DataKinds NoStarIsType
lib/KindRational.hs view
@@ -10,677 +10,1123 @@ -- import "KindRational" qualified as KR -- @ ----- The implementation details are the same as the ones for type-level 'Natural's--- in "GHC.TypeNats" as of @base-4.18@, and it will continue to evolve together--- with @base@, trying to follow its core API as much as possible until the day--- @base@ provides its own type-level rationals, making this module redundant.-module KindRational {--}- ( -- * Rational kind- Rational- , type (%)- , type (/)- , Normalize- , Num- , Den-- -- Prelude support- , rational- , fromPrelude- , toPrelude- , showsPrecTypeLit-- -- * Types ⇔ Terms- , KnownRational(rationalSing)- , rationalVal- , SomeRational(..)- , someRationalVal- , sameRational-- -- * Singletons- , SRational- , pattern SRational- , fromSRational- , withSomeSRational- , withKnownRational-- -- * Arithmethic- , type (+)- , type (*)- , type (-)- , Negate- , Sign- , Abs- , Recip- , Div- , div- , Rem- , rem- , DivRem- , divRem- , I.Round(..)-- -- * Decimals- , Terminating- , withTerminating- , Terminates- , terminates-- -- * Comparisons- , CmpRational- , cmpRational- , eqRationalRep-- -- * Extra- --- -- | This stuff should be exported by the "Data.Type.Ord" module.- , type (==?), type (==), type (/=?), type (/=)- ) --}- where--import Control.Monad-import Data.Proxy-import Data.Singletons-import Data.Singletons.Decide-import Data.Type.Bool (If)-import Data.Type.Coercion-import Data.Type.Equality (TestEquality(..))-import Data.Type.Ord-import GHC.Base (WithDict(..))-import GHC.Exts (TYPE, Constraint)-import GHC.Read qualified as Read-import GHC.Real qualified as P (Ratio(..), (%))-import GHC.Show (appPrec, appPrec1)-import GHC.TypeLits qualified as L-import GHC.TypeNats qualified as N-import KindInteger (Integer, N, P)-import KindInteger (type (==?), type (==), type (/=?), type (/=))-import KindInteger qualified as I-import Numeric.Natural (Natural)-import Prelude hiding (Rational, Integer, Num, div, rem)-import Prelude qualified as P-import Text.ParserCombinators.ReadPrec as Read-import Text.Read.Lex qualified as Read-import Unsafe.Coerce(unsafeCoerce)-------------------------------------------------------------------------------------- | Type-level version of 'P.Rational'. Use '/' to construct one, use '%' to--- pattern-match on it.------ 'Rational' is mostly used as a kind, with its types constructed--- using '/'. However, it is also used as type, with its terms--- constructed using 'rational' or 'fromPrelude'. One reason why you may want a--- 'Rational' at the term-level is so that you embed it in larger data-types--- (for example, this 'Rational' embeds the 'I.Integer' similarly offered by--- the "KindInteger" module). But perhaps more importantly, this 'Rational'--- offers better safety than the 'P.Rational' from "Prelude", since it's not--- possible to construct one with a zero denominator, or so large that--- operating with it would exhaust system resources. Additionally,--- a "KindRational"'s 'Rational' can fully represent the internal structure--- of a type-level 'Rational'. For these reasons, functions like--- 'fromSRational' and 'withSomeSRational' deal with it, rather than with--- "Prelude"'s 'P.Rational'.-data Rational- = -- | This constructor is /unsafe/ because it doesn't check for the things- -- that 'rational' checks for.- --- -- * At the term-level, safely construct a 'Rational' using 'rational'- -- or 'fromPrelude' instead.- --- -- * At the type-level, safely construct a 'Rational' using '/'.- --- -- * We keep the numerator and denominator unnormalized because we use them- -- to implement 'SDecide', 'TestEquality' and 'TestCoercion'. Even if “1/2”- -- and “2/4” mean the same, in 'SDecide' and friends we treat them as the- -- different types that they are.- I.Integer :% Natural---- | Arithmethic equality. That is, \(\frac{1}{2} == \frac{2}{4}\).-instance Eq Rational where- a == b = toPrelude a == toPrelude b--instance Ord Rational where- compare a b = compare (toPrelude a) (toPrelude b)- a <= b = toPrelude a <= toPrelude b---- | Same as "Prelude" 'P.Rational'.-instance Show Rational where- showsPrec p = showsPrec p . toPrelude---- | Same as "Prelude" 'P.Rational'.-instance Read Rational where- readPrec = Read.parens $ Read.prec 7 $ do -- 7 is GHC.Real.ratioPrec- n :: P.Integer <- Read.step Read.readPrec- Read.expectP (Read.Symbol "%")- d :: P.Integer <- Read.step Read.readPrec- Just r <- pure (rational n d)- pure r---- | Shows the 'Rational' as it appears literally at the type-level.------ This is remerent from normal 'show' for 'Rational', which shows--- the term-level value.------ @--- 'shows' 0 ('rationalVal' ('Proxy' \@(1'/'2))) \"z\" == \"1 % 2z\"--- 'showsPrecTypeLit' 0 ('rationalVal' ('Proxy' \@(1'/'2))) \"z\" == \"P 1 % 2z\"--- @-showsPrecTypeLit :: Int -> Rational -> ShowS-showsPrecTypeLit p (n :% d) = showParen (p > appPrec) $- I.showsPrecTypeLit appPrec n . showString " % " . shows d---- | Make a term-level "KindRational" 'Rational' number, provided that--- the numerator is not @0@, and that its numerator and denominator are--- not so large that they would exhaust system resources. The 'Rational'--- is 'Normalize'd.-rational :: (Integral num, Integral den) => num -> den -> Maybe Rational-rational = \(toInteger -> n) (toInteger -> d) -> do- guard (d /= 0 && abs n <= max_ && abs d <= max_)- pure $ let n1 P.:% d1 = n P.% d -- 'P.%' normalizes- in I.fromPrelude n1 :% fromInteger d1- where- max_ :: P.Integer -- Some big enough number. TODO: Pick good number.- max_ = 10 ^ (1000 :: Int)---- | Try to obtain a term-level "KindRational" 'Rational' from a term-level--- "Prelude" 'P.Rational'. This can fail if the "Prelude" 'P.Rational' is--- infinite, or if it is so big that it would exhaust system resources.------ @--- 'fromPrelude' . 'toPrelude' == 'Just'--- @-fromPrelude :: P.Rational -> Maybe Rational-fromPrelude (n P.:% d) = rational n d---- | Convert a term-level "KindRational" 'Rational' into a 'Normalized'--- term-level "Prelude" 'P.Rational'.------ @'fromPrelude' . 'toPrelude' == 'Just'@-toPrelude :: Rational -> P.Rational-toPrelude (n :% d) = I.toPrelude n P.% toInteger d -- 'P.%' normalizes.-------------------------------------------------------------------------------------- | 'Normalize'd /'Num'erator/ of the type-level 'Rational'.-type Num (r :: Rational) = Num_ (Normalize r) :: Integer-type family Num_ (r :: Rational) :: Integer where- Num_ (n :% _) = n---- | 'Normalize'd /'Den'ominator/ of the type-level 'Rational'.-type Den (r :: Rational) = Den_ (Normalize r) :: Natural-type family Den_ (r :: Rational) :: Natural where- Den_ (_ :% d) = d---- | Pattern-match on a type-level 'Rational'.------ __NB:__ When /constructing/ a 'Rational' number, prefer to use '/',--- which not only accepts more polymorphic inputs, but also 'Normalize's--- the type-level 'Rational'. Also note that while @n '%' 0@ is a valid--- type, all tools in the "KindRational" will reject such input.-type (n :: I.Integer) % (d :: Natural) = n :% d :: Rational---- | Normalize a type-level 'Rational' so that a /0/ denominator fails to--- type-check, and that the 'Num'erator and denominator have no common factors.------ Only 'Normalize'd 'Rational's can be reliably constrained for equality--- using '~'.------ All of the functions in the "KindRational" module accept both--- 'Normalize'd and non-'Normalize'd inputs, but they always produce--- 'Normalize'd output.-type family Normalize (r :: Rational) :: Rational where- Normalize (_ % 0) = L.TypeError ('L.Text "KindRational: Denominator is zero")- Normalize (P 0 % _) = P 0 % 1- Normalize (N 0 % _) = P 0 % 1- Normalize (P n % d) = P (L.Div n (GCD n d)) % L.Div d (GCD n d)- Normalize (N n % d) = N (L.Div n (GCD n d)) % L.Div d (GCD n d)------------------------------------------------------------------------------------infixl 6 +, --infixl 7 *, /---type (/) :: kn -> kd -> Rational--- | @n'/'d@ constructs and 'Normalize's a type-level 'Rational'--- with numerator @n@ and denominator @d@.------ This type-family accepts any combination of 'Natural', 'Integer' and--- 'Rational' as input.------ @--- ('/') :: 'Natural' -> 'Natural' -> 'Rational'--- ('/') :: 'Natural' -> 'Integer' -> 'Rational'--- ('/') :: 'Natural' -> 'Rational' -> 'Rational'------ ('/') :: 'Integer' -> 'Natural' -> 'Rational'--- ('/') :: 'Integer' -> 'Integer' -> 'Rational'--- ('/') :: 'Integer' -> 'Rational' -> 'Rational'------ ('/') :: 'Rational' -> 'Natural' -> 'Rational'--- ('/') :: 'Rational' -> 'Integer' -> 'Rational'--- ('/') :: 'Rational' -> 'Rational' -> 'Rational'--- @------ It's not possible to pattern-match on @n'/'d@. Instead, you must--- pattern match on @x'%'y@, where @x'%'y ~ n'/'d@.-type family n / d :: Rational where- -- Natural/Natural- (n :: Natural) / (d :: Natural) = Normalize (P n % d)- -- Natural/Integer- (n :: Natural) / (P d :: Integer) = Normalize (P n % d)- (n :: Natural) / (N d :: Integer) = Normalize (N n % d)- -- Natural/Rational- (n :: Natural) / (d :: Rational) = (P n % 1) * Recip d- -- Integer/Natural- (i :: Integer) / (d :: Natural) = Normalize (i % d)- -- Integer/Integer- (P n :: Integer) / (P d :: Integer) = Normalize (P n % d)- (N n :: Integer) / (N d :: Integer) = Normalize (P n % d)- (P n :: Integer) / (N d :: Integer) = Normalize (N n % d)- (N n :: Integer) / (P d :: Integer) = Normalize (N n % d)- -- Integer/Rational- (n :: Integer) / (d :: Rational) = (n % 1) * Recip d- -- Rational/Natural- (n :: Rational) / (d :: Natural) = n * Recip (P d % 1)- -- Rational/Integer- (n :: Rational) / (d :: Integer) = n * Recip (d % 1)- -- Rational/Rational- (n :: Rational) / (d :: Rational) = n * Recip d-------------------------------------------------------------------------------------- | /'Negate'/ a type-level 'Rational'. Also known as /additive inverse/.-type family Negate (r :: Rational) :: Rational where- Negate (P n % d) = Normalize (N n % d)- Negate (N n % d) = Normalize (P n % d)---- | Sign of type-level 'Rational's, as a type-level 'Integer'.------ * @'P' 0@ if zero.------ * @'P' 1@ if positive.------ * @'N' 1@ if negative.-type Sign (r :: Rational) = I.Sign (Num r) :: Integer---- | /'Abs'olute/ value of a type-level 'Rational'.-type Abs (r :: Rational) = Normalize (P (I.Abs (Num_ r)) % Den_ r) :: Rational-------------------------------------------------------------------------------------- | @a t'*' b@ multiplies type-level 'Rational's @a@ and @b@.-type (a :: Rational) * (b :: Rational) =- Mul_ (Normalize a) (Normalize b) :: Rational-type family Mul_ (a :: Rational) (b :: Rational) where- Mul_ (n1 % d1) (n2 % d2) = Normalize ((n1 I.* n2) % (d1 L.* d2))---- | /'Recip'rocal/ of the type-level 'Rational'.--- Also known as /multiplicative inverse/.-type Recip (a :: Rational) = Recip_ (Normalize a) :: Rational-type family Recip_ (a :: Rational) :: Rational where- Recip_ (P n % d) = Normalize (P d % n)- Recip_ (N n % d) = Normalize (N d % n)---- | @a t'+' b@ adds type-level 'Rational's @a@ and @b@.-type (a :: Rational) + (b :: Rational) =- Add_ (Normalize a) (Normalize b) :: Rational-type family Add_ (a :: Rational) (r :: Rational) :: Rational where- Add_ (an % ad) (bn % bd) =- Normalize ((an I.* P bd I.+ bn I.* P ad) % (ad L.* bd))---- | @a t'-' b@ subtracts the type-level 'Rational' @b@ from--- the type-level 'Rational' @a@.-type (a :: Rational) - (b :: Rational) = a + Negate b :: Rational--------------------------------------------------------------------------------------- | Quotient of the 'Div'ision of the 'Num'erator of type-level 'Rational' @a@--- by its 'Den'ominator, using the specified 'I.Round'ing @r@.------ @--- forall (r :: 'I.Round') (a :: 'Rational').--- ('Den' a '/=' 0) =>--- 'Rem' r a '==' a '-' 'Div' r a '%' 1--- @------ Use this to approximate a type-level 'Rational' to an 'Integer'.-type Div (r :: I.Round) (a :: Rational) =- Div_ r (Normalize a) :: Integer-type Div_ (r :: I.Round) (a :: Rational) =- I.Div r (Num_ a) (P (Den_ a)) :: Integer---- | 'Rem'ainder from 'Div'iding the 'Num'erator of the type-level 'Rational'--- @a@ by its 'Den'ominator, using the specified 'I.Round'ing @r@.------ @--- forall (r :: 'I.Round') (a :: 'Rational').--- ('Den' a '/=' 0) =>--- 'Rem' r a '==' a '-' 'Div' r a '%' 1--- @-type Rem (r :: I.Round) (a :: Rational) = Snd (DivRem r a) :: Rational---- | Get both the quotient and the 'Rem'ainder of the 'Div'ision of the--- 'Num'erator of type-level 'Rational' @a@ by its 'Den'ominator,--- using the specified 'I.Round'ing @r@.------ @--- forall (r :: 'I.Round') (a :: 'Rational').--- ('Den' a '/=' 0) =>--- 'DivRem' r a '==' '('Div' r a, 'Rem' r a)--- @-type DivRem (r :: I.Round) (a :: Rational) =- DivRem_ r (Normalize a) :: (Integer, Rational)-type DivRem_ (r :: I.Round) (a :: Rational) =- DivRem__ (Den_ a) (I.DivRem r (Num_ a) (P (Den_ a))) :: (Integer, Rational)-type DivRem__ (d :: Natural) (qm :: (Integer, Integer)) =- '(Fst qm, Normalize (Snd qm % d)) :: (Integer, Rational)---- | Term-level version of 'Div'.------ Takes a "KindInteger" 'Rational' as input, returns a "Prelude"--- 'P.Integer'.-div :: I.Round -> Rational -> P.Integer-div r = let f = I.div r- in \(n :% d) -> f (I.toPrelude n) (toInteger d)---- | Term-level version of 'Rem'.------ Takes a "KindInteger" 'Rational' as input, returns a "KindInteger" 'Rational'.-rem :: I.Round -> Rational -> Rational-rem r = snd . divRem r---- | Term-level version of 'DivRem'.------ Takes a "KindInteger" 'Rational' as input, returns a pair of--- /(quotient, reminder)/.------ @--- forall ('r' :: 'I.Round') (a :: 'Rational').--- ('P.denominator' a 'P./=' 0) =>--- 'divRem' r a 'P.==' ('div' r a, 'rem' r a)--- @-divRem :: I.Round -> Rational -> (P.Integer, Rational)-divRem r = let f = I.divRem r- in \(n :% d) -> let (q, m) = f (I.toPrelude n) (toInteger d)- in (q, I.fromPrelude m :% d) -- (m % d) == (a - q)-------------------------------------------------------------------------------------- | 'Constraint' version of @'Terminates' r@. Satisfied by all type-level--- 'Rational's that can be represented as a finite decimal number.---- Written as a class rather than as a type-synonym so that downstream doesn't--- need to use UndecidableSuperClasses.-class (KnownRational r, Terminates r ~ True)- => Terminating (r :: Rational)---- Note: Even if @Terminates r ~ 'False@, GHC shows our @TypeError@ first.-instance- ( KnownRational r- , Terminates r ~ 'True- , If (Terminates r)- (() :: Constraint)- (L.TypeError ('L.Text "‘" 'L.:<>: 'L.ShowType r 'L.:<>:- 'L.Text "’ is not a terminating "- 'L.:<>: 'L.ShowType Rational))- ) => Terminating r--withTerminating- :: forall r a- . KnownRational r- => (Terminating r => a)- -> Maybe a-withTerminating g = do- guard (terminates (rationalVal (Proxy @r)))- case unsafeCoerce (Dict @(Terminating (P 1 % 1))) of- (Dict :: Dict (Terminating r)) -> pure g---- | Whether the type-level 'Rational' terminates. That is, whether--- it can be fully represented as a finite decimal number.-type Terminates (r :: Rational) = Terminates_ (Den r) :: Bool-type family Terminates_ (n :: Natural) :: Bool where- Terminates_ 5 = 'True- Terminates_ 2 = 'True- Terminates_ 1 = 'True- Terminates_ d = Terminates_5 d (L.Mod d 5)---- @Terminates_5@ is here to prevent @Terminates_@ from recursing into--- @Terminates_ (Div d 5)@ if it would diverge.-type family Terminates_5 (d :: Natural) (md5 :: Natural) :: Bool where- Terminates_5 d 0 = Terminates_ (L.Div d 5)- Terminates_5 d _ = Terminates_2 d (L.Mod d 2)---- @Terminates_2@ is here to prevent @Terminates_5@ from recursing into--- @Terminates_ (Div d 2)@ if it would diverge, and also to prevent calculating--- @Mod d 2@ unless necessary.-type family Terminates_2 (d :: Natural) (md2 :: Natural) :: Bool where- Terminates_2 d 0 = Terminates_ (L.Div d 2)- Terminates_2 _ _ = 'False---- | Term-level version of the "Terminates" function.--- Takes a "KindRational" 'Rational' as input.-terminates :: Rational -> Bool-terminates = \(_ :% d) -> go (toInteger d)- where- go = \case- 5 -> True- 2 -> True- 1 -> True- n | (q, 0) <- P.divMod n 5 -> go q- | (q, 0) <- P.divMod n 2 -> go q- _ -> False-------------------------------------------------------------------------------------- | Comparison of type-level 'Rational's, as a function.-type CmpRational (a :: Rational) (b :: Rational) =- CmpRational_ (Normalize a) (Normalize b) :: Ordering-type family CmpRational_ (a :: Rational) (b :: Rational) :: Ordering where- CmpRational_ a a = 'EQ- CmpRational_ (an % ad) (bn % bd) = I.CmpInteger (an I.* P bd) (bn I.* P ad)---- | "Data.Type.Ord" support for type-level 'Rational's.-type instance Compare (a :: Rational) (b :: Rational) = CmpRational a b-------------------------------------------------------------------------------------- | This class gives the rational associated with a type-level rational.--- There are instances of the class for every rational.-class KnownRational (r :: Rational) where- rationalSing :: SRational r---- | This instance checks that @r@ 'Normalize's, but the obtained 'SRational' is--- not normalized. This is so that 'SDecide', 'TestEquality' and 'TestCoercion'--- behave as expected. If you want a 'Normalize'd 'SRational', then use--- @'rationalSing' \@('Normalize' r)@.-instance forall r n d.- ( Normalize r ~ n % d- , I.KnownInteger (Num_ r)- , L.KnownNat (Den_ r)- ) => KnownRational r where- rationalSing =- let n = I.fromSInteger (I.SInteger @(Num_ r))- d = N.natVal (Proxy @(Den_ r))- in UnsafeSRational (n :% d)---- | Term-level "KindRational" 'Rational' representation of the type-level--- 'Rational' @r@.-rationalVal :: forall r proxy. KnownRational r => proxy r -> Rational-rationalVal _ = case rationalSing :: SRational r of UnsafeSRational x -> x---- | This type represents unknown type-level 'Rational'.-data SomeRational = forall n. KnownRational n => SomeRational (Proxy n)---- | Convert a term-level "KindRational" 'Rational' into an unknown--- type-level 'Rational'.-someRationalVal :: Rational -> SomeRational-someRationalVal r = withSomeSRational r $ \(sr :: SRational r) ->- withKnownRational sr (SomeRational @r Proxy)---- | Arithmethic equality. That is, \(\frac{1}{2} == \frac{2}{4}\).-instance Eq SomeRational where- SomeRational x == SomeRational y = rationalVal x P.== rationalVal y--instance Ord SomeRational where- SomeRational x <= SomeRational y =- rationalVal x <= rationalVal y- compare (SomeRational x) (SomeRational y) =- compare (rationalVal x) (rationalVal y)--instance Show SomeRational where- showsPrec p (SomeRational x) = showsPrec p (rationalVal x)--instance Read SomeRational where- readsPrec p xs = do (a, ys) <- readsPrec p xs- [(someRationalVal a, ys)]----- | We either get evidence that this function was instantiated with the--- same type-level 'Rational's, or 'Nothing'.-sameRational- :: forall a b proxy1 proxy2- . (KnownRational a, KnownRational b)- => proxy1 a- -> proxy2 b- -> Maybe (a :~: b)-sameRational _ _ = testEquality (rationalSing @a) (rationalSing @b)---- | Like 'sameRational', but if the type-level 'Rational's aren't equal, this--- additionally provides proof of 'LT' or 'GT'.-cmpRational- :: forall a b proxy1 proxy2- . (KnownRational a, KnownRational b)- => proxy1 a- -> proxy2 b- -> OrderingI a b-cmpRational x y = case compare (rationalVal x) (rationalVal y) of- EQ -> case unsafeCoerce Refl :: CmpRational a b :~: 'EQ of- Refl -> case unsafeCoerce Refl :: a :~: b of- Refl -> EQI- LT -> case unsafeCoerce Refl :: (CmpRational a b :~: 'LT) of- Refl -> LTI- GT -> case unsafeCoerce Refl :: (CmpRational a b :~: 'GT) of- Refl -> GTI-------------------------------------------------------------------------------------- | Singleton type for a type-level 'Rational' @r@.-newtype SRational (r :: Rational) = UnsafeSRational Rational-type role SRational nominal---- | A explicitly bidirectional pattern synonym relating an 'SRational' to a--- 'KnownRational' constraint.------ As an __expression__: Constructs an explicit @'SRational' r@ value from an--- implicit @'KnownRational' r@ constraint:------ @--- 'SRational' @r :: 'KnownRational' r => 'SRational' r--- @------ As a __pattern__: Matches on an explicit @'SRational' r@ value bringing--- an implicit @'KnownRational' r@ constraint into scope:------ @--- f :: 'SRational' r -> ..--- f SRational = {- SRational r in scope -}--- @-pattern SRational :: forall r. () => KnownRational r => SRational r-pattern SRational <- (knownRationalInstance -> KnownRationalegerInstance)- where SRational = rationalSing---- | An internal data type that is only used for defining the 'SRational' pattern--- synonym.-data KnownRationalegerInstance (r :: Rational) where- KnownRationalegerInstance :: KnownRational r => KnownRationalegerInstance r---- | An internal function that is only used for defining the 'SRational' pattern--- synonym.-knownRationalInstance :: SRational r -> KnownRationalegerInstance r-knownRationalInstance si = withKnownRational si KnownRationalegerInstance--instance Show (SRational r) where- showsPrec p (UnsafeSRational r) = showParen (p > appPrec) $- showString "SRational @" . showsPrecTypeLit appPrec1 r---- | Note that this checks for type equality, not arithmetic equality.--- That is, @'P' 1 '%' 2@ and @'P' 2 '%' 4@ are not equal types,--- even if they are arithmetically equal.-instance TestEquality SRational where- testEquality = decideEquality- {-# INLINE testEquality #-}---- | Note that this checks for type equality, not arithmetic equality.--- That is, @'P' 1 '%' 2@ and @'P' 2 '%' 4@ are not equal types,--- even if they are arithmetically equal.-instance TestCoercion SRational where- testCoercion = decideCoercion- {-# INLINE testCoercion #-}---- | Return the term-level "KindRational" 'Rational' number corresponding--- to @r@ in a @'SRational' r@ value. This 'Rational' is not 'Normalize'd.-fromSRational :: SRational r -> Rational-fromSRational (UnsafeSRational r) = r---- | Whether the internal representation of the 'Rational's are equal.------ Note that this is not the same as '(P.==)'. Use '(P.==)' unless you--- know what you are doing.-eqRationalRep :: Rational -> Rational -> Bool-eqRationalRep (ln :% ld) (rn :% rd) = I.eqIntegerRep ln rn && ld P.== rd-{-# INLINE eqRationalRep #-}---- | Convert an explicit @'SRational' r@ value into an implicit--- @'KnownRational' r@ constraint.-withKnownRational- :: forall r rep (a :: TYPE rep). SRational r -> (KnownRational r => a) -> a-withKnownRational = withDict @(KnownRational r)---- | Convert a "KindRational" 'Rational' number into an @'SRational' n@ value,--- where @n@ is a fresh type-level 'Rational'.-withSomeSRational- :: forall rep (a :: TYPE rep). Rational -> (forall r. SRational r -> a) -> a-withSomeSRational r k = k (UnsafeSRational r)--- It's very important to keep this NOINLINE! See the docs at "GHC.TypeNats"-{-# NOINLINE withSomeSRational #-}------------------------------------------------------------------------------------type instance Sing = SRational--instance KnownRational r => SingI (r :: Rational) where- sing = rationalSing- {-# INLINE sing #-}---- | 'Demote' refers to "KindRational"'s 'Rational' rather than "Prelude"'s--- 'Rational' so that the 'SRational''s internal representation is preserved.--- Use 'toPrelude' and 'fromPrelude' as necessary.-instance SingKind Rational where- type Demote Rational = Rational- fromSing = fromSRational- {-# INLINE fromSing #-}- toSing r = withSomeSRational r SomeSing- {-# INLINE toSing #-}---- | Note that this checks for type equality, not arithmetic equality.--- That is, @'P' 1 '%' 2@ and @'P' 2 '%' 4@ are not equal types,--- even if they are arithmetically equal.-instance SDecide Rational where- UnsafeSRational l %~ UnsafeSRational r =- case eqRationalRep l r of- True -> Proved (unsafeCoerce Refl)- False -> Disproved (\Refl -> error "SDecide.Rational")------------------------------------------------------------------------------------- Extra stuff that doesn't belong here.---- | /Greatest Common Divisor/ of 'Natural' numbers @a@ and @b@.-type GCD (a :: Natural) (b :: Natural) = I.GCD (P a) (P b) :: Natural--data Dict c where Dict :: c => Dict c--type family Fst (ab :: (a, b)) :: a where Fst '(a, b) = a-type family Snd (ab :: (a, b)) :: b where Snd '(a, b) = b+-- The implementation details are similar to the ones for type-level 'Natural's+-- as of @base-4.18@ and @singletons-base-3.1.1@, and they will continue to+-- evolve together with @base@ and @singletons-base@, trying to more or less+-- follow their API.+module KindRational {--}+ ( -- * Rational+ Rational+ , type (:%)+ , FromNatural, fromNatural, sFromNatural+ , FromInteger, fromInteger, sFromInteger+ , Num, sNum+ , Den, sDen+ , ToRational(..)+ , sMkRational+ , (%%)+ , (%)++ -- * SRational+ , KnownRational+ , Reduced+ , rationalSing+ , rationalVal+ , withKnownRational+ , SomeRational(..)+ , someRationalVal+ , SRational+ , pattern SRational+ , fromSRational+ , withSomeSRational++ -- * Proofs+ , sNegateRefl++ -- * Show+ --+ -- | Besides the following /\*Lit/ tools, 'P.PShow' and 'P.SShow' can+ -- be used to display as "Prelude".'P.Rational' does.+ , ShowLit, showLit, sShowLit+ , ShowsLit, showsLit, sShowsLit+ , ShowsPrecLit, showsPrecLit, sShowsPrecLit+ , readPrecLit++ -- * Arithmethic+ , Signum, sSignum, sSignumRefl+ , Recip, sRecip, sRecip'+ , Div, sDiv, div+ , Rem, rem, sRem+ , DivRem, divRem, sDivRem+ , I.Round(..), I.SRound(..)++ -- * Decimals+ , IsTerminating+ , isTerminating+ , termination+ , Terminating+ , NonTerminating+ , pattern SRationalTerminating+ , pattern SRationalNonTerminating++ -- * Comparisons+ --+ -- | Additional comparison tools are available at 'SDdecide',+ -- 'TestEquality', 'TestCoercion', 'P.PEq', 'P.SEq', 'P.POrd', 'P.SOrd'+ -- and 'Compare'.+ , cmpRational+ , sameRational+++ -- * Defunctionalization+ , type (%@#@$), type (%@#@$$), type (%@#@$$$)+ , type (:%@#@$), type (:%@#@$$), type (:%@#@$$$)+ , FromNaturalSym0, FromNaturalSym1+ , FromIntegerSym0, FromIntegerSym1+ , NumSym0, NumSym1+ , DenSym0, DenSym1+ , ToRationalSym0, ToRationalSym1, ToRationalSym2+ , ReducedSym0, ReducedSym1+ , ShowLitSym0, ShowLitSym1+ , ShowsLitSym0, ShowsLitSym1, ShowsLitSym2+ , ShowsPrecLitSym0, ShowsPrecLitSym1, ShowsPrecLitSym2, ShowsPrecLitSym3+ , IsTerminatingSym0, IsTerminatingSym1+ , TerminatingSym0, TerminatingSym1+ , NonTerminatingSym0, NonTerminatingSym1+ , SignumSym0, SignumSym1+ , RecipSym0, RecipSym1+ , DivSym0, DivSym1, DivSym2+ , RemSym0, RemSym1, RemSym2+ , DivRemSym0, DivRemSym1, DivRemSym2+ , I.RoundUpSym0+ , I.RoundDownSym0+ , I.RoundZeroSym0+ , I.RoundAwaySym0+ , I.RoundHalfUpSym0+ , I.RoundHalfDownSym0+ , I.RoundHalfZeroSym0+ , I.RoundHalfAwaySym0+ , I.RoundHalfEvenSym0+ , I.RoundHalfOddSym0+ ) --}+ where++import Control.Monad+import Data.Bits+import Data.Bool.Singletons (SBool(..))+import Data.Eq.Singletons qualified as EqS+import Data.Maybe+import Data.Ord.Singletons qualified as OrdS+import Data.Proxy+import Data.Singletons+import Data.Singletons.Decide+import Data.String+import Data.Type.Coercion+import Data.Type.Equality (TestEquality(..))+import Data.Type.Ord+import GHC.Base (WithDict(..))+import GHC.Exts (TYPE, Constraint)+import GHC.Read qualified as Read+import GHC.Real qualified as P (Ratio(..), (%))+import GHC.Show (appPrec, appPrec1)+import GHC.Stack (HasCallStack)+import GHC.TypeLits qualified as L hiding (someNatVal)+import GHC.TypeNats qualified as L (someNatVal)+import KindInteger (SInteger, Integer)+import KindInteger qualified as I+import Numeric.Natural (Natural)+import Prelude hiding (Rational, Integer, Num, div, rem, fromInteger)+import Prelude qualified as P+import Prelude.Singletons qualified as P+import Text.ParserCombinators.ReadP as ReadP+import Text.ParserCombinators.ReadPrec as ReadPrec+import Text.Read.Lex qualified as Read+import Text.Show.Singletons (AppPrec1)+import Unsafe.Coerce(unsafeCoerce)++--------------------------------------------------------------------------------++-- | Type-level version of "Prelude".'P.Rational', used only as a kind.+--+-- Use t'%' to construct one, use t':%' to pattern-match on it.+data Rational = Integer :% Natural+ -- ^ Note that @n ':%' d@ doesn't guarantee that @n@ be 'I.Normalized', nor+ -- that @d@ be non-zero, nor that the rational number is in 'Reduced' form.+ -- To make sure that's the case, use t'%' to construct type-level rationals,+ -- and use t':%' only for pattern-matching purposes. Alternatively, consider+ -- using the 'KnownRational' constraint or the 'Reduced' type-family. Both+ -- of them will reject any 'Rational' that fails to satisfy any of these+ -- constraints.++ -- Note: We export type-synonym ':%' rather than type-constructor ':%' so+ -- as to avoid having to use the leading tick, and to prevent term-level+ -- uses of the constructor.+++-- | Shows just as a term-level "Prelude".'P.Rational'.+instance P.SShow Rational where+ sShowsPrec _ si ss = withSomeSing+ (fromString (show (fromSing si)) <> fromSing ss)+ unsafeCoerce++-- | Shows just as a term-level "Prelude".'P.Rational'.+--+-- 'ShowsPrec' type-checks only if the type-level 'Rational' is 'Reduced'.+instance P.PShow Rational where+ type ShowsPrec p r s = P.ShowParen (p P.>= AppPrec1)+ (P.ShowsPrecSym2 AppPrec1 (Num r) P..@#@$$$+ P.ShowStringSym1 " % " P..@#@$$$+ P.ShowsSym1 (Den r)) s++-- | Shows as a type-level "KindRational".'Rational' apears literally at the+-- type-level. Type-checks only if the type-level 'Rational' is 'Reduced'.+type ShowLit (r :: Rational) = ShowsLit r "" :: L.Symbol++data ShowLitSym0 :: Rational ~> L.Symbol+type ShowLitSym1 :: Rational -> L.Symbol++type instance Apply ShowLitSym0 i = ShowLitSym1 i+type ShowLitSym1 i = ShowLit i++-- | Shows as a type-level "KindRational".'Rational' apears literally at the+-- type-level. Type-checks only if the type-level 'Rational' is 'Reduced'.+type ShowsLit (r :: Rational) (s :: L.Symbol) = ShowsPrecLit 0 r s :: L.Symbol++data ShowsLitSym0 :: Rational ~> L.Symbol ~> L.Symbol+data ShowsLitSym1 :: Rational -> L.Symbol ~> L.Symbol+type ShowsLitSym2 :: Rational -> L.Symbol -> L.Symbol++type instance Apply ShowsLitSym0 i = ShowsLitSym1 i+type instance Apply (ShowsLitSym1 i) s = ShowsLitSym2 i s+type ShowsLitSym2 i s = ShowsLit i s++-- | Shows as a type-level "KindRational".'Rational' apears literally at the+-- type-level. Type-checks only if the type-level 'Rational' is 'Reduced'.+type ShowsPrecLit (p :: Natural) (r :: Rational) (s :: L.Symbol) =+ P.ShowParen (p P.>= AppPrec1)+ (I.ShowsLitSym1 (Num r) P..@#@$$$+ P.ShowStringSym1 " :% " P..@#@$$$+ P.ShowsSym1 (Den r)) s :: L.Symbol++data ShowsPrecLitSym0 :: Natural ~> Rational ~> L.Symbol ~> L.Symbol+data ShowsPrecLitSym1 :: Natural -> Rational ~> L.Symbol ~> L.Symbol+data ShowsPrecLitSym2 :: Natural -> Rational -> L.Symbol ~> L.Symbol+type ShowsPrecLitSym3 :: Natural -> Rational -> L.Symbol -> L.Symbol++type instance Apply ShowsPrecLitSym0 p = ShowsPrecLitSym1 p+type instance Apply (ShowsPrecLitSym1 p) i = ShowsPrecLitSym2 p i+type instance Apply (ShowsPrecLitSym2 p i) s = ShowsPrecLitSym3 p i s+type ShowsPrecLitSym3 p i s = ShowsPrecLit p i s++-- | Singleton version of 'ShowLit'.+sShowLit :: SRational r -> Sing (ShowLit r)+sShowLit sr = sShowsLit sr (sing @"")++-- | Demoted version of 'ShowLit'.+showLit :: P.Rational -> String+showLit r = showsLit r ""++-- | Singleton version of 'ShowsLit'.+sShowsLit :: SRational r -> Sing (s :: P.Symbol) -> Sing (ShowsLit r s)+sShowsLit = sShowsPrecLit (sing @0)++-- | Demoted version of 'ShowsLit'.+showsLit :: P.Rational -> ShowS+showsLit = showsPrecLit 0++-- | Singleton version of 'ShowsPrecLit'.+sShowsPrecLit+ :: Sing (p :: Natural)+ -> SRational r+ -> Sing (s :: P.Symbol)+ -> Sing (ShowsPrecLit p r s)+sShowsPrecLit sp si ss =+ let p = fromMaybe (error "sShowsPrecLit: invalid precedence")+ (toIntegralSized (fromSing sp))+ t = fromString (showsPrecLit p (fromSing si) "")+ in withSomeSing (t <> fromSing ss) unsafeCoerce++-- | Demoted version of 'ShowsPrecLit'.+showsPrecLit :: Int -> P.Rational -> ShowS+showsPrecLit p _ | p < 0 = error "showsPrecLit: negative precedence"+showsPrecLit p (unsafeReduced -> n P.:% d) =+ showParen (p >= appPrec1) $+ I.showsPrecLit appPrec n .+ showString " :% " .+ shows d++-- | Inverse of 'showsPrecLit'.+readPrecLit :: ReadPrec.ReadPrec P.Rational+readPrecLit = Read.parens $ do+ n :: P.Integer <- Read.parens $ ReadPrec.step I.readPrecLit+ Read.expectP (Read.Symbol ":%")+ d :: Natural <- Read.parens $ ReadPrec.step $ ReadPrec.lift pNatural+ either fail pure $ rationalLit n (toInteger d)+ where+ pNatural :: ReadP.ReadP Natural+ pNatural = read <$> ReadP.munch1 (\c -> c >= '0' && c <= '9')++-- | Creates a "Prelude".'P.Rational' using the given literal numerator+-- and denominator, if in reduced form with a non-zero denominator.+rationalLit :: P.Integer -> P.Integer -> Either String P.Rational+rationalLit = \n d -> do+ when (d == 0) $ Left "Denominator is zero."+ when (d < 0) $ Left "Rational is not reduced."+ let r@(n' P.:% d') = n P.% d+ when (n /= n' || d /= d') $ Left "Rational is not reduced."+ Right r++-- | Reduces the given rational. 'error's if it can't be reduced.+unsafeReduce :: HasCallStack => P.Rational -> P.Rational+unsafeReduce = \case+ n P.:% d | d /= 0 -> n P.% d+ | otherwise -> error "Denominator is zero."++-- | 'error's if the given rational is not reduced. Otherwise, returns it.+unsafeReduced :: HasCallStack => P.Rational -> P.Rational+unsafeReduced = \r0 -> case unsafeReduce r0 of+ r1 | r0 == r1 -> r0+ | otherwise -> error $ concat+ [ "Expected reduced rational ", showsPrec appPrec1 r1 ""+ , ", got " , showsPrec appPrec1 r0 "." ]++--------------------------------------------------------------------------------++-- | Singleton version of 'Num'.+sNum :: SRational r -> SInteger (Num r)+sNum sr | n P.:% _ <- fromSing sr =+ withSomeSing n unsafeCoerce++-- | Literal /'Num'erator/ of a type-level 'Rational'.+-- It fails to type-check if the 'Rational' is not 'Reduced'.+type Num (r :: Rational) = Num_ (Reduced r) :: Integer+type family Num_ (r :: Rational) :: Integer where Num_ (n :% _) = n++data NumSym0 :: Rational ~> Integer+type NumSym1 :: Rational -> Integer++type instance Apply NumSym0 i = Num i+type NumSym1 i = Num i++-- | Singleton version of 'Den'.+sDen :: SRational r -> Sing (Den r :: Natural)+sDen sr | _ P.:% d <- fromSing sr =+ withSomeSing @Natural (P.fromInteger d) unsafeCoerce++-- | Literal /'Den'ominator/ of a type-level 'Rational'.+-- It fails to type-check if the 'Rational' is not 'Reduced'.+type Den (r :: Rational) = Den_ (Reduced r) :: Natural+type family Den_ (r :: Rational) :: Natural where Den_ (_ :% d) = d++data DenSym0 :: Rational ~> Natural+type DenSym1 :: Rational -> Natural++type instance Apply DenSym0 i = Den i+type DenSym1 i = Den i++-- | Pattern-match on a type-level 'Rational'.+--+-- Note that t':%' doesn't check that the 'Rational' be 'Reduced' nor+-- have a non-zero denominator.+--+-- When constructing 'Rational's, use t'%' instead, which not only accepts+-- more polymorphic inputs, but also returns a 'Reduced' result with+-- denominator known to be non-zero.+type (n :: I.Integer) :% (d :: Natural) = n ':% d :: Rational++data (:%@#@$) :: Integer ~> Natural ~> Rational+data (:%@#@$$) :: Integer -> Natural ~> Rational+type (:%@#@$$$) :: Integer -> Natural -> Rational++type instance Apply ((:%@#@$$) b) p = (:%@#@$$$) b p+type instance Apply (:%@#@$) b = (:%@#@$$) b+type (:%@#@$$$) b p = b :% p++--------------------------------------------------------------------------------++-- | A 'Reduce'd rational number is one in which the numerator and denominator+-- have no common denominators. 'Reduced' fails to type-check if the given+-- type-level 'Rational' is not reduced, otherwise it returns the given+-- 'Rational', unmodified. It also fails to type-check if the 'I.Integer'+-- numerator isn't 'I.Normalized', or if the denominator is zero.+--+-- Only reduced 'Rational's can be reliably constrained for equality+-- using '~'. Only reduced 'Rational's are 'KnownRational's.+--+-- The type-level functions in the "KindRational" module+-- always produce reduced 'Rational's.+type Reduced (r :: Rational) = Reduced_ r (Reduce r) :: Rational+type family Reduced_ (r :: Rational) (x :: Rational) :: Rational where+ Reduced_ r r = r+ Reduced_ (na :% da) (nb :% db) = L.TypeError+ ('L.Text "Expected reduced rational (" 'L.:<>:+ 'L.Text (I.ShowsLit nb " :% ") 'L.:<>:+ 'L.Text (P.Shows db "), got (") 'L.:<>:+ 'L.Text (I.ShowsLit na " :% ") 'L.:<>:+ 'L.Text (P.Shows da ")."))++data ReducedSym0 :: Rational ~> Rational+type ReducedSym1 :: Rational -> Rational++type instance Apply ReducedSym0 i = Reduced i+type ReducedSym1 i = Reduced i++-- | 'SRational's always contain a 'Reduced' 'Rational'.+sReducedRefl :: SRational r -> (r :~: Reduced r)+sReducedRefl !_ = unsafeCoerce Refl++-- | Reduce a type-level 'Rational' so that the numerator and denominator+-- have no common factors. It fails to type-check if the 'I.Integer'+-- numerator isn't 'I.Normalized'.+--+-- Only reduced 'Rational's can be reliably constrained for equality+-- using '~'. Only reduced 'Rational's are 'KnownRational's.+type family Reduce (r :: Rational) :: Rational where+ Reduce (n :% 0) = L.TypeError+ ('L.Text "Denominator is zero in (" 'L.:<>: 'L.Text (I.ShowsLit n " :% 0)"))+ Reduce (n :% d) =+ I.Fold (FromNatural 0) (ReduceNegSym1 d) (ReducePosSym1 d) n++data ReduceNegSym1 :: Natural -> Natural ~> Rational+type instance Apply (ReduceNegSym1 d) n = ReduceNeg d n+type ReduceNeg (d :: Natural) (n :: Natural)+ = ReduceNeg_ (ReducePos d n) :: Rational+type ReduceNeg_ (rpos :: Rational) = P.Negate (Num_ rpos) :% Den_ rpos++data ReducePosSym1 :: Natural -> Natural ~> Rational+type instance Apply (ReducePosSym1 d) n = ReducePos d n+type family ReducePos (d :: Natural) (n :: Natural) :: Rational where+ ReducePos d n =+ I.FromNatural (L.Div n (I.GCD (I.FromNatural n) (I.FromNatural d)))+ :% (L.Div d (I.GCD (I.FromNatural n) (I.FromNatural d)))++--------------------------------------------------------------------------------++-- | Construct a type-level 'Rational' from a type-level 'Natural'.+type FromNatural (n :: Natural) = I.FromNatural n :% 1 :: Rational++data FromNaturalSym0 :: Natural ~> Rational+type FromNaturalSym1 :: Natural -> Rational++type instance Apply FromNaturalSym0 i = FromNatural i+type FromNaturalSym1 i = FromNatural i++-- | Singleton version of 'FromNatural'.+sFromNatural :: Sing (n :: Natural) -> SRational (FromNatural n)+sFromNatural = UnsafeSRational . fromIntegral . fromSing+{-# INLINE sFromNatural #-}++-- | Demoted version of 'FromNatural'.+fromNatural :: Natural -> P.Rational+fromNatural = P.fromIntegral+{-# INLINE fromNatural #-}++--------------------------------------------------------------------------------++-- | Construct a type-level 'Rational' from a type-level 'Integer'.+-- It fails to type-check if the 'I.Integer' isn't 'I.Normalized'.+type FromInteger (i :: Integer) = I.Normalized i :% 1 :: Rational++data FromIntegerSym0 :: Integer ~> Rational+type FromIntegerSym1 :: Integer -> Rational++type instance Apply FromIntegerSym0 i = FromInteger i+type FromIntegerSym1 i = FromInteger i++-- | Singleton version of 'FromInteger'.+sFromInteger :: SInteger n -> SRational (FromInteger n)+sFromInteger = UnsafeSRational . fromInteger . fromSing+{-# INLINE sFromInteger #-}++-- | Demoted version of 'FromInteger'.+fromInteger :: P.Integer -> P.Rational+fromInteger = P.fromInteger+{-# INLINE fromInteger #-}++--------------------------------------------------------------------------------++infixl 7 %, %%, :%, :%@#@$$$, %@#@$$$++-- | @'ToRational' kn kd@ enables constructing type-level 'Rational's+-- from a numerator of kind @kn@ and a denominator of kind @kd@.+class (SingKind kn, SingKind kd) => ToRational kn kd where+ -- | @n t'%' d@ constructs and reduces a type-level 'Rational'+ -- with numerator @n@ and denominator @d@.+ --+ -- This type-family accepts any combination of 'Natural', 'Integer' and+ -- 'Rational' as input.+ --+ -- @+ -- ( t'%') :: 'Natural' -> 'Natural' -> 'Rational'+ -- ( t'%') :: 'Natural' -> 'Integer' -> 'Rational'+ -- ( t'%') :: 'Natural' -> 'Rational' -> 'Rational'+ --+ -- ( t'%') :: 'Integer' -> 'Natural' -> 'Rational'+ -- ( t'%') :: 'Integer' -> 'Integer' -> 'Rational'+ -- ( t'%') :: 'Integer' -> 'Rational' -> 'Rational'+ --+ -- ( t'%') :: 'Rational' -> 'Natural' -> 'Rational'+ -- ( t'%') :: 'Rational' -> 'Integer' -> 'Rational'+ -- ( t'%') :: 'Rational' -> 'Rational' -> 'Rational'+ -- @+ --+ -- It's not possible to pattern-match on @n t'%' d@. Instead, you must+ -- pattern match on @x t':%' y@, where @x t':%' y ~ n t'%' d@.+ type (n :: kn) % (d :: kd) :: Rational+ -- | Demoted version of t'%'. Returns 'Nothing' where t'%' would fail+ -- to type-check (that is, denominator is 0).+ -- See '%' for an unsafe version of this.+ mkRational :: Demote kn -> Demote kd -> Maybe P.Rational++-- | Like 'mkRational', but fails with 'error' where 'mkRational' would+-- fail with 'Nothing'.+(%) :: forall kn kd+ . (ToRational kn kd, HasCallStack)+ => Demote kn+ -> Demote kd+ -> P.Rational+n % d = fromMaybe (error "Denominator is zero.") (mkRational n d)+{-# INLINE (%) #-}++-- | Like 'sMkRational', but never fails, thanks to a+-- 'KnownRational' constraint.+(%%) :: forall kn kd n d+ . (ToRational kn kd, KnownRational (n % d))+ => Sing (n :: kn)+ -> Sing (d :: kd)+ -> SRational (n % d)+(%%) sn sd = fromJust (sMkRational sn sd)+{-# INLINE (%%) #-}++-- | Singleton version of 'mkRational'.+sMkRational+ :: forall kn kd n d+ . (ToRational kn kd)+ => Sing (n :: kn)+ -> Sing (d :: kd)+ -> Maybe (SRational (n % d))+sMkRational sn sd =+ UnsafeSRational <$> mkRational (fromSing sn) (fromSing sd)+{-# INLINE sMkRational #-}++data ToRationalSym0 :: kkn ~> kkd ~> Constraint+data ToRationalSym1 :: kkn -> kkd ~> Constraint+-- type ToRationalSym2 :: kkn -> kkd -> Constraint -- (inferred)++type instance Apply ToRationalSym0 kn = ToRationalSym1 kn+type instance Apply (ToRationalSym1 kn) kd = ToRationalSym2 kn kd+type ToRationalSym2 kn kd = ToRational kn kd++data (%@#@$) :: kn ~> kd ~> Rational+data (%@#@$$) :: kn -> kd ~> Rational+type (%@#@$$$) :: kn -> kd -> Rational++type instance Apply ((%@#@$$) b) p = (%@#@$$$) b p+type instance Apply (%@#@$) b = (%@#@$$) b+type (%@#@$$$) b p = b % p++instance ToRational Natural Natural where+ type n % d = I.FromNatural n % d+ mkRational _ 0 = Nothing+ mkRational n d = Just $! toInteger n P.% toInteger d++instance ToRational Natural Integer where+ type n % d = (I.FromNatural n P.* P.Signum d) % I.Abs d+ mkRational _ 0 = Nothing+ mkRational n d = Just $! toInteger n P.% d++instance ToRational Natural Rational where+ type n % d = FromNatural n P.* Recip d+ mkRational _ 0 = Nothing+ mkRational n d = Just $! fromIntegral n P./ d++instance ToRational Integer Natural where+ type n % d = Reduce (n :% d)+ mkRational _ 0 = Nothing+ mkRational n d = Just $! n P.% toInteger d++instance ToRational Integer Integer where+ type n % d = (n P.* P.Signum d) % I.Abs d+ mkRational _ 0 = Nothing+ mkRational n d = Just $! (n P.* P.signum d) P.% P.abs d++instance ToRational Integer Rational where+ type n % d = FromInteger n P.* Recip d+ mkRational _ 0 = Nothing+ mkRational n d = Just $! fromInteger n P.* recip d++instance ToRational Rational Natural where+ type n % d = n P.* Recip (FromNatural d)+ mkRational _ 0 = Nothing+ mkRational n d = Just $! n P.* P.recip (fromNatural d)++instance ToRational Rational Integer where+ type n % d = n P.* Recip (FromInteger d)+ mkRational _ 0 = Nothing+ mkRational n d = Just $! n P.* P.recip (fromInteger d)++instance ToRational Rational Rational where+ type n % d = n P.* Recip d+ mkRational _ 0 = Nothing+ mkRational n d = Just $! n P.* P.recip d++--------------------------------------------------------------------------------++instance P.PNum Rational where+ type l + r = Add l r+ type l - r = Add l (P.Negate r)+ type l * r = Mul l r+ type Negate r = Reduce (P.Negate (Num r) :% Den r)+ type Abs r = Reduce (P.Abs (Num r) :% Den r)+ type Signum r = P.Signum (Num r) :% 1+ type FromInteger n = FromNatural n++instance P.SNum Rational where+ l %+ r = UnsafeSRational (fromSing l + fromSing r)+ l %- r = UnsafeSRational (fromSing l - fromSing r)+ l %* r = UnsafeSRational (fromSing l * fromSing r)+ sNegate = UnsafeSRational . negate . fromSing+ sAbs = UnsafeSRational . abs . fromSing+ sSignum = UnsafeSRational . signum . fromSing+ sFromInteger = sFromNatural++sNegateRefl :: Sing (r :: Rational) -> (r :~: P.Negate (P.Negate r))+sNegateRefl !_ = unsafeCoerce Refl++-- | Sign of type-level 'Rational's, as a type-level 'Integer'.+--+-- * 'I.Z' if zero.+--+-- * @'I.P' 1@ if positive.+--+-- * @'I.N' 1@ if negative.+type Signum (r :: Rational) = P.Signum (Num r) :: Integer++data SignumSym0 :: Rational ~> Integer+type SignumSym1 :: Rational -> Integer++type instance Apply SignumSym0 i = Signum i+type SignumSym1 i = Signum i++-- | Singleton version of 'Signum'.+sSignum :: Sing (r :: Rational) -> SInteger (Signum r)+sSignum sr = P.sSignum (sNum sr)++-- | The 'Signum' of a 'Rational' equals the 'PNum' 'P.Signum' of its+-- 'Num'erator, as well as the 'Num'erator of its 'PNum' 'P.Signum'.+sSignumRefl+ :: SRational r+ -> (Signum r :~: P.Signum (Num r),+ Signum r :~: Num (P.Signum r))+sSignumRefl !_ = unsafeCoerce (Refl, Refl)++type Mul (a :: Rational) (b :: Rational) =+ Mul_ (Reduce a) (Reduce b) :: Rational+type family Mul_ (a :: Rational) (b :: Rational) where+ Mul_ (n1 :% d1) (n2 :% d2) = Reduce ((n1 P.* n2) :% (d1 L.* d2))++type Add (a :: Rational) (b :: Rational) =+ Add_ (Reduce a) (Reduce b) :: Rational+type family Add_ (a :: Rational) (r :: Rational) :: Rational where+ Add_ (an :% ad) (bn :% bd) =+ (an P.* I.FromNatural bd P.+ bn P.* I.FromNatural ad) % (ad L.* bd)++--------------------------------------------------------------------------------++-- | Singleton version of 'Recip'. Type-checks only with a non-zero @r@.+sRecip :: I.Z :% 1 < P.Abs r => SRational r -> SRational (Recip r)+sRecip = UnsafeSRational . recip . fromSing++-- | Like 'sRecip', except it fails with 'Nothing' when @r@ is zero, rather+-- than requiring to satisfy this as a type-level constraint.+sRecip' :: forall r. SRational r -> Maybe (SRational (Recip r))+sRecip' sa = case fromSing sa of+ 0 -> Nothing+ a -> Just (UnsafeSRational (recip a))++-- | /'Recip'rocal/ of the type-level 'Rational'.+-- Also known as /multiplicative inverse/.+type Recip (a :: Rational) = Den a % Num a :: Rational++data RecipSym0 :: Rational ~> Rational+type RecipSym1 :: Rational -> Rational++type instance Apply RecipSym0 i = Recip i+type RecipSym1 i = Recip i++--------------------------------------------------------------------------------++-- | Singleton version of 'Div'.+sDiv :: I.SRound r -> SRational a -> SInteger (Div r a)+sDiv sr sa = withSomeSing (div (fromSing sr) (fromSing sa)) unsafeCoerce++-- | Quotient of the 'Div'ision of the 'Num'erator of type-level 'Rational' @a@+-- by its 'Den'ominator, using the specified 'I.Round'ing @r@.+--+-- @+-- forall (r :: 'I.Round') (a :: 'Rational').+-- ('KnownRational' a) =>+-- 'Rem' r a '==' a '-' 'Div' r a t'%' 1+-- @+--+-- Use this to approximate a type-level 'Rational' to an 'Integer'.+type Div (r :: I.Round) (a :: Rational) = Div_ r (Reduce a) :: Integer+type Div_ (r :: I.Round) (a :: Rational) =+ I.Div r (Num a) (I.FromNatural (Den a)) :: Integer++data DivSym0 :: I.Round ~> Rational ~> Integer+data DivSym1 :: I.Round -> Rational ~> Integer+type DivSym2 :: I.Round -> Rational -> Integer++type instance Apply DivSym0 a = DivSym1 a+type instance Apply (DivSym1 a) b = DivSym2 a b+type DivSym2 a b = Div a b++-- | Singleton version of 'Rem'.+sRem :: I.SRound r -> SRational a -> SRational (Rem r a)+sRem sr sa = snd (sDivRem sr sa)++-- | 'Rem'ainder from 'Div'iding the 'Num'erator of the type-level 'Rational'+-- @a@ by its 'Den'ominator, using the specified 'I.Round'ing @r@.+--+-- @+-- forall (r :: 'I.Round') (a :: 'Rational').+-- ('KnownRational' a) =>+-- 'Rem' r a '==' a '-' 'Div' r a t'%' 1+-- @+type Rem (r :: I.Round) (a :: Rational) = P.Snd (DivRem r a) :: Rational++data RemSym0 :: I.Round ~> Rational ~> Rational+data RemSym1 :: I.Round -> Rational ~> Rational+type RemSym2 :: I.Round -> Rational -> Rational++type instance Apply RemSym0 a = RemSym1 a+type instance Apply (RemSym1 a) b = RemSym2 a b+type RemSym2 a b = Rem a b++-- | Singleton version of 'DivRem'.+sDivRem :: I.SRound r -> SRational a+ -> (SInteger (Div r a), SRational (Rem r a))+sDivRem sr sa =+ let (d1, r1) = divRem (fromSing sr) (fromSing sa)+ in (withSomeSing d1 unsafeCoerce, UnsafeSRational r1)++-- | Get both the quotient and the 'Rem'ainder of the 'Div'ision of the+-- 'Num'erator of type-level 'Rational' @a@ by its 'Den'ominator,+-- using the specified 'I.Round'ing @r@.+--+-- @+-- forall (r :: 'I.Round') (a :: 'Rational').+-- ('KnownRational' a) =>+-- 'DivRem' r a '==' '('Div' r a, 'Rem' r a)+-- @+type DivRem (r :: I.Round) (a :: Rational) =+ DivRem_ r (Reduce a) :: (Integer, Rational)+type DivRem_ (r :: I.Round) (a :: Rational) =+ DivRem__ (Den a) (I.DivRem r (Num a) (I.FromNatural (Den a)))+ :: (Integer, Rational)+type DivRem__ (d :: Natural) (qm :: (Integer, Integer)) =+ '(P.Fst qm, Reduce (P.Snd qm :% d)) :: (Integer, Rational)++data DivRemSym0 :: I.Round ~> Rational ~> (Integer, Rational)+data DivRemSym1 :: I.Round -> Rational ~> (Integer, Rational)+type DivRemSym2 :: I.Round -> Rational -> (Integer, Rational)++type instance Apply DivRemSym0 a = DivRemSym1 a+type instance Apply (DivRemSym1 a) b = DivRemSym2 a b+type DivRemSym2 a b = DivRem a b++-- | Term-level version of 'Div'.+--+-- Takes a "KindRational".'Rational' as input, returns a "Prelude"+-- 'P.Integer'.+--+-- NB: 'error's if the 'P.Rational' denominator is 0.+div :: I.Round -> P.Rational -> P.Integer+div rnd = \(unsafeReduce -> n P.:% d) -> f n d+ where f = I.div rnd++-- | Term-level version of 'Rem'.+--+-- Takes a "Prelude".'P.Rational' as input, returns a "Prelude".'P.Rational'.+--+-- NB: 'error's if the 'P.Rational' denominator is 0.+rem :: I.Round -> P.Rational -> P.Rational+rem rnd = snd . divRem rnd++-- | Term-level version of 'DivRem'.+--+-- Takes a "Prelude".'P.Rational' as input, returns a pair of+-- /(quotient, reminder)/.+--+-- @+-- forall ('r' :: 'I.Round') (a :: 'P.Rational').+-- ('P.denominator' a 'P./=' 0) =>+-- 'divRem' r a 'P.==' ('div' r a, 'rem' r a)+-- @+--+-- NB: 'error's if the 'P.Rational' denominator is 0.+divRem :: I.Round -> P.Rational -> (P.Integer, P.Rational)+divRem rnd = \(unsafeReduce -> n P.:% d) ->+ let (q, m) = f n d+ in (q, m P.:% d) -- (m :% d) == ((n :% d) - q)+ where f = I.divRem rnd++--------------------------------------------------------------------------------++-- | Determine whether @r@ is 'Terminating' or 'NonTerminating' at the+-- term-level, and create the corresponding type-level proof.+termination+ :: forall r a+ . (NonTerminating r => a)+ -> (Terminating r => a)+ -> SRational r+ -> a+termination f t sr =+ withKnownRational sr $ case isTerminating (fromSRational sr) of+ False | Refl <- (unsafeCoerce Refl :: IsTerminating r :~: 'False) -> f+ True | Refl <- (unsafeCoerce Refl :: IsTerminating r :~: 'True) -> t++-- | This is essentially the same as @('KnownRational' r, 'IsTerminating' r ~ 'True')@,+-- except with a nicer error message when @'IsTerminating' r ~ 'False'@.+type Terminating (r :: Rational) = Terminating_ r (IsTerminating r) :: Constraint+type family Terminating_ r (b :: Bool):: Constraint where+ Terminating_ r 'True = (IsTerminating r ~ 'True, KnownRational r)+ Terminating_ r 'False = L.TypeError+ ('L.Text "Unexpected: IsTerminating ("+ 'L.:<>: 'L.ShowType r 'L.:<>: 'L.Text ") ~ 'False")++data TerminatingSym0 :: Rational ~> Constraint+type TerminatingSym1 :: Rational -> Constraint++type instance Apply TerminatingSym0 i = Terminating i+type TerminatingSym1 i = Terminating i++-- | This is essentially the same as @('KnownRational' r, 'IsTerminating' r ~ 'False')@,+-- except with a nicer error message when @'IsTerminating' r ~ 'False'@.+type NonTerminating (r :: Rational) = NonTerminating_ r (IsTerminating r) :: Constraint+type family NonTerminating_ r (b :: Bool):: Constraint where+ NonTerminating_ r 'False = (IsTerminating r ~ 'False, KnownRational r)+ NonTerminating_ r 'True = L.TypeError+ ('L.Text "Unexpected: IsTerminating ("+ 'L.:<>: 'L.ShowType r 'L.:<>: 'L.Text ") ~ 'True")++data NonTerminatingSym0 :: Rational ~> Constraint+type NonTerminatingSym1 :: Rational -> Constraint++type instance Apply NonTerminatingSym0 i = NonTerminating i+type NonTerminatingSym1 i = NonTerminating i+++-- | Whether the type-level 'Rational' is terminating. That is, whether+-- it can be fully represented as a finite decimal number.+type IsTerminating (r :: Rational) = IsTerminating_ (Den r) :: Bool+type family IsTerminating_ (n :: Natural) :: Bool where+ IsTerminating_ 5 = 'True+ IsTerminating_ 2 = 'True+ IsTerminating_ 1 = 'True+ IsTerminating_ d = IsTerminating_5 d (L.Mod d 5)++-- @IsTerminating_5@ is here to prevent @IsTerminating_@ from recursing into+-- @IsTerminating_ (Div d 5)@ if it would diverge.+type family IsTerminating_5 (d :: Natural) (md5 :: Natural) :: Bool where+ IsTerminating_5 d 0 = IsTerminating_ (L.Div d 5)+ IsTerminating_5 d _ = IsTerminating_2 d (L.Mod d 2)++-- @IsTerminating_2@ is here to prevent @IsTerminating_5@ from recursing into+-- @IsTerminating_ (Div d 2)@ if it would diverge, and also to prevent calculating+-- @Mod d 2@ unless necessary.+type family IsTerminating_2 (d :: Natural) (md2 :: Natural) :: Bool where+ IsTerminating_2 d 0 = IsTerminating_ (L.Div d 2)+ IsTerminating_2 _ _ = 'False++data IsTerminatingSym0 :: Rational ~> Bool+type IsTerminatingSym1 :: Rational -> Bool++type instance Apply IsTerminatingSym0 i = IsTerminating i+type IsTerminatingSym1 i = IsTerminating i++-- | Term-level version of the "IsTerminating" function.+--+-- NB: 'error's if the 'P.Rational' denominator is 0.+isTerminating :: P.Rational -> Bool+isTerminating = \(unsafeReduce -> _ P.:% d) -> go d+ where+ go = \case+ 5 -> True+ 2 -> True+ 1 -> True+ n | (q, 0) <- P.divMod n 5 -> go q+ | (q, 0) <- P.divMod n 2 -> go q+ _ -> False++{-# COMPLETE SRationalTerminating, SRationalNonTerminating #-}++-- | Matches a 'SRational' that is 'Terminating'.+pattern SRationalTerminating+ :: forall r. () => (Terminating r) => SRational r+pattern SRationalTerminating <-+ (termination Nothing (Just Dict) -> Just (Dict :: Dict (Terminating r)))++-- | Matches a 'SRational' that is 'NonTerminating'.+pattern SRationalNonTerminating+ :: forall r. () => (NonTerminating r) => SRational r+pattern SRationalNonTerminating <-+ (termination (Just Dict) Nothing -> Just (Dict :: Dict (NonTerminating r)))++--------------------------------------------------------------------------------++-- | Comparison of type-level 'Rational's, as a function.+type CmpRational (a :: Rational) (b :: Rational) =+ CmpRational_ (Reduce a) (Reduce b) :: Ordering+type family CmpRational_ (a :: Rational) (b :: Rational) :: Ordering where+ CmpRational_ a a = 'EQ+ CmpRational_ (an :% ad) (bn :% bd) =+ P.Compare (an P.* I.FromNatural bd) (bn P.* I.FromNatural ad)++-- | "Data.Type.Ord" support for type-level 'Rational's.+type instance Compare (a :: Rational) (b :: Rational) = CmpRational a b++instance OrdS.POrd Rational where+ type Compare a b = CmpRational a b++instance OrdS.SOrd Rational where+ sCompare sa sb = case compare (fromSing sa) (fromSing sb) of+ LT -> unsafeCoerce OrdS.SLT+ EQ -> unsafeCoerce OrdS.SEQ+ GT -> unsafeCoerce OrdS.SGT++instance EqS.PEq Rational where+ type a == b = CmpRational a b P.== 'EQ++instance EqS.SEq Rational where+ sa %== sb+ | fromSing sa P.== fromSing sb = unsafeCoerce STrue+ | otherwise = unsafeCoerce SFalse++--------------------------------------------------------------------------------++-- | This class gives the 'SRational' associated with a type-level 'Rational'.+--+-- There are instances for every 'Reduced' 'Rational'.++-- Note: Ideally, 'KnownRational' wouldn' exist and the 'Constraint's metioned+-- there would be superclasses to 'KnownRational_'. However, 'withDict' doesn't+-- allow superclasses, so we treat 'KnownRational_' as internal an export+-- 'KnownRational' only.+class KnownRational_ (r :: Rational) where+ rationalSing_ :: SRational r++-- | Type-level 'Rational's satisfying 'KnownRational' can be converted to+-- 'SRational's using 'rationalSing'. Moreover, 'KnownRational' implies that+-- the numerator is a 'I.KnownInteger', and that the denominator is a+-- 'L.KnownNat'.+type KnownRational (r :: Rational) =+ ( KnownRational_ r+ , Reduced r ~ r+ , I.KnownInteger (Num r)+ , L.KnownNat (Den r)+ )++-- | Convert an implicit 'KnownRational' to an explicit 'SRational'.+rationalSing :: KnownRational r => SRational r+rationalSing = rationalSing_ -- The difference is in the constraint.+{-# INLINE rationalSing #-}++instance (KnownRational r) => KnownRational_ r where+ rationalSing_ =+ UnsafeSRational (demote @(Num r) P.:% L.natVal (Proxy @(Den r)))++-- | Normalized term-level "Prelude" 'P.Rational' representation of the+-- type-level 'Rational' @r@.+rationalVal :: forall r proxy. KnownRational r => proxy r -> P.Rational+rationalVal _ = case rationalSing :: SRational r of UnsafeSRational x -> x+{-# INLINE rationalVal #-}++-- | This type represents unknown type-level 'Rational'.+data SomeRational = forall n. KnownRational n => SomeRational (Proxy n)+++-- | Convert a term-level "Prelude".'P.Rational' into an+-- extistentialized 'KnownRational' wrapped in 'SomeRational'.+--+-- NB: 'error's if a non-'Reduced' 'P.Rational' is given.+someRationalVal :: P.Rational -> SomeRational+someRationalVal = \r ->+ withSomeSRational r $ \(sr :: SRational r) ->+ withKnownRational sr $ SomeRational (Proxy @r)++instance Eq SomeRational where+ SomeRational x == SomeRational y =+ rationalVal x P.== rationalVal y+ {-# INLINE (==) #-}++instance Ord SomeRational where+ compare (SomeRational x) (SomeRational y) =+ compare (rationalVal x) (rationalVal y)+ {-# INLINE compare #-}++-- | As for "Prelude".'P.Rational'.+instance Show SomeRational where+ showsPrec p (SomeRational i) = showsPrec p (rationalVal i)++-- | As for "Prelude".'P.Rational'.+instance Read SomeRational where+ readPrec = fmap someRationalVal Read.readPrec++--------------------------------------------------------------------------------++-- | We either get evidence that this function was instantiated with the+-- same type-level 'Rational's, or 'Nothing'.+sameRational+ :: forall a b proxy1 proxy2+ . (KnownRational a, KnownRational b)+ => proxy1 a+ -> proxy2 b+ -> Maybe (a :~: b)+sameRational _ _ = testEquality (rationalSing @a) (rationalSing @b)++-- | Like 'sameRational', but if the type-level 'Rational's aren't equal, this+-- additionally provides proof of 'LT' or 'GT'.+cmpRational+ :: forall a b proxy1 proxy2+ . (KnownRational a, KnownRational b)+ => proxy1 a+ -> proxy2 b+ -> OrderingI a b+cmpRational x y = case compare (rationalVal x) (rationalVal y) of+ EQ -> case unsafeCoerce Refl :: CmpRational a b :~: 'EQ of+ Refl -> case unsafeCoerce Refl :: a :~: b of+ Refl -> EQI+ LT -> case unsafeCoerce Refl :: (CmpRational a b :~: 'LT) of+ Refl -> LTI+ GT -> case unsafeCoerce Refl :: (CmpRational a b :~: 'GT) of+ Refl -> GTI++--------------------------------------------------------------------------------++-- | Singleton type for a type-level 'Rational' @r@.+newtype SRational (r :: Rational) = UnsafeSRational P.Rational+type role SRational nominal++-- | A explicitly bidirectional pattern synonym relating an 'SRational' to a+-- 'KnownRational' constraint.+--+-- As an __expression__: Constructs an explicit @'SRational' r@ value from an+-- implicit @'KnownRational' r@ constraint:+--+-- @+-- 'SRational' @r :: 'KnownRational' r => 'SRational' r+-- @+--+-- As a __pattern__: Matches on an explicit @'SRational' r@ value bringing+-- an implicit @'KnownRational' r@ constraint into scope:+--+-- @+-- f :: 'SRational' r -> ..+-- f SRational = {- SRational r in scope -}+-- @+pattern SRational :: forall r. () => KnownRational r => SRational r+pattern SRational <- (knownRationalInstance -> KnownRationalInstance)+ where SRational = rationalSing_++-- | An internal data type that is only used for defining the 'SRational' pattern+-- synonym.+data KnownRationalInstance (r :: Rational) where+ KnownRationalInstance :: KnownRational r => KnownRationalInstance r++-- | An internal function that is only used for defining the 'SRational' pattern+-- synonym.+knownRationalInstance :: SRational r -> KnownRationalInstance r+knownRationalInstance si = withKnownRational si KnownRationalInstance++instance Show (SRational r) where+ showsPrec p (UnsafeSRational r) =+ showParen (p >= appPrec1) $+ showString "SRational @" .+ showsPrecLit appPrec1 r++instance Eq (SRational r) where+ _ == _ = True+ {-# INLINE (==) #-}++instance Ord (SRational r) where+ compare _ _ = EQ+ {-# INLINE compare #-}++instance TestEquality SRational where+ testEquality = decideEquality+ {-# INLINE testEquality #-}++instance TestCoercion SRational where+ testCoercion = decideCoercion+ {-# INLINE testCoercion #-}++-- | Return the term-level "Prelude".'P.Rational' number corresponding to @r@.+fromSRational :: SRational r -> P.Rational+fromSRational (UnsafeSRational r) = r++-- | Convert an explicit @'SRational' r@ value into an implicit+-- @'KnownRational_' r@ constraint.+withKnownRational_+ :: forall r rep (x :: TYPE rep)+ . SRational r+ -> (KnownRational_ r => x)+ -> x+withKnownRational_ = withDict @(KnownRational_ r)++-- | Convert an explicit @'SRational' r@ value into an implicit+-- @'KnownRational' r@ constraint.+withKnownRational+ :: forall r rep (x :: TYPE rep)+ . SRational r+ -> (KnownRational r => x)+ -> x+withKnownRational sr x+ | n P.:% d <- fromSRational sr+ , I.SomeInteger @n _ <- I.someIntegerVal n+ , L.SomeNat @d _ <- L.someNatVal (P.fromInteger d)+ , Refl <- sReducedRefl sr+ , -- These unsafeCoreces are safe because this module doesn't offer any tool+ -- for constructing non-reduced SRationals. Very unsafe otherwise.+ Refl <- unsafeCoerce Refl :: d :~: Den r+ , Refl <- unsafeCoerce Refl :: n :~: Num r+ = withKnownRational_ sr x++-- | Convert a "Prelude".'P.Rational' number into an @'SRational' n@ value,+-- where @n@ is a fresh type-level 'Rational'.+withSomeSRational+ :: forall rep (x :: TYPE rep). P.Rational -> (forall r. SRational r -> x) -> x+withSomeSRational (unsafeReduced -> !r) k = k (UnsafeSRational r)+-- It's very important to keep this NOINLINE! See the docs at "GHC.TypeNats"+{-# NOINLINE withSomeSRational #-}++--------------------------------------------------------------------------------++type instance Sing = SRational++instance (KnownRational r) => SingI (r :: Rational) where+ sing = rationalSing+ {-# INLINE sing #-}++instance SingKind Rational where+ type Demote Rational = P.Rational+ fromSing = fromSRational+ {-# INLINE fromSing #-}+ toSing r = withSomeSRational r SomeSing+ {-# INLINE toSing #-}++instance SDecide Rational where+ UnsafeSRational l %~ UnsafeSRational r =+ -- This is safe because this library doesn't expose any tool to construct+ -- non-normalized SRationals. Otherwise, very unsafe.+ case l P.== r of+ True -> Proved (unsafeCoerce Refl)+ False -> Disproved (\Refl -> error "Rational: SDecide")++--------------------------------------------------------------------------------+-- Extra stuff that doesn't belong here.++data Dict (c :: Constraint) where+ Dict :: c => Dict c
test/Main.hs view
@@ -8,1855 +8,2077 @@ import Control.Monad import Data.List qualified as List import Data.Maybe-import Data.Proxy-import Data.Type.Equality (TestEquality(..))-import Data.Type.Ord (type (<=), type (<))-import GHC.Exts (Constraint)-import System.Exit-import Text.Read-import GHC.Real qualified as P-import Prelude hiding (Rational, Integer)-import Prelude qualified as P--import KindInteger (P, N)-import KindRational (type (%), type (/))-import KindRational qualified as K------------------------------------------------------------------------------------data Dict (c :: Constraint) where- Dict :: c => Dict c------------------------------------------------------------------------------------_testNormalize = Dict-_testNormalize :: Dict- ( P 0 % 1 ~ K.Normalize (P 0 % 1)- , P 1 % 1 ~ K.Normalize (P 1 % 1)- , P 2 % 1 ~ K.Normalize (P 2 % 1)- , P 3 % 1 ~ K.Normalize (P 3 % 1)- , P 4 % 1 ~ K.Normalize (P 4 % 1)- , P 0 % 1 ~ K.Normalize (P 0 % 2)- , P 1 % 1 ~ K.Normalize (P 2 % 2)- , P 3 % 2 ~ K.Normalize (P 3 % 2)- , P 2 % 1 ~ K.Normalize (P 4 % 2)- , P 0 % 1 ~ K.Normalize (P 0 % 3)- , P 1 % 3 ~ K.Normalize (P 1 % 3)- , P 2 % 3 ~ K.Normalize (P 2 % 3)- , P 1 % 1 ~ K.Normalize (P 3 % 3)- , P 4 % 3 ~ K.Normalize (P 4 % 3)- , P 0 % 1 ~ K.Normalize (P 0 % 4)- , P 1 % 4 ~ K.Normalize (P 1 % 4)- , P 1 % 2 ~ K.Normalize (P 2 % 4)- , P 3 % 4 ~ K.Normalize (P 3 % 4)- , P 1 % 1 ~ K.Normalize (P 4 % 4)- , P 0 % 1 ~ K.Normalize (N 0 % 1)- , N 1 % 1 ~ K.Normalize (N 1 % 1)- , N 2 % 1 ~ K.Normalize (N 2 % 1)- , N 3 % 1 ~ K.Normalize (N 3 % 1)- , N 4 % 1 ~ K.Normalize (N 4 % 1)- , P 0 % 1 ~ K.Normalize (N 0 % 2)- , N 1 % 2 ~ K.Normalize (N 1 % 2)- , N 1 % 1 ~ K.Normalize (N 2 % 2)- , N 3 % 2 ~ K.Normalize (N 3 % 2)- , N 2 % 1 ~ K.Normalize (N 4 % 2)- , P 0 % 1 ~ K.Normalize (N 0 % 3)- , N 1 % 3 ~ K.Normalize (N 1 % 3)- , N 2 % 3 ~ K.Normalize (N 2 % 3)- , N 1 % 1 ~ K.Normalize (N 3 % 3)- , N 4 % 3 ~ K.Normalize (N 4 % 3)- , P 0 % 1 ~ K.Normalize (N 0 % 4)- , N 1 % 4 ~ K.Normalize (N 1 % 4)- , N 1 % 2 ~ K.Normalize (N 2 % 4)- , N 3 % 4 ~ K.Normalize (N 3 % 4)- , N 1 % 1 ~ K.Normalize (N 4 % 4)- )--_testNegate = Dict-_testNegate :: Dict- ( P 0 % 1 ~ K.Negate (P 0 % 1)- , P 0 % 1 ~ K.Negate (P 0 % 2)- , P 0 % 1 ~ K.Negate (N 0 % 1)- , P 0 % 1 ~ K.Negate (N 0 % 2)-- , P 1 % 1 ~ K.Negate (N 1 % 1)- , P 1 % 2 ~ K.Negate (N 1 % 2)- , P 1 % 1 ~ K.Negate (N 1 % 1)- , P 1 % 2 ~ K.Negate (N 1 % 2)-- , N 1 % 1 ~ K.Negate (P 1 % 1)- , N 1 % 2 ~ K.Negate (P 1 % 2)- , N 1 % 1 ~ K.Negate (P 1 % 1)- , N 1 % 2 ~ K.Negate (P 1 % 2)-- , P 1 % 1 ~ K.Negate (N 1 % 1)- , P 2 % 1 ~ K.Negate (N 2 % 1)- , P 1 % 1 ~ K.Negate (N 1 % 1)- , P 2 % 1 ~ K.Negate (N 2 % 1)-- , N 1 % 1 ~ K.Negate (P 1 % 1)- , N 2 % 1 ~ K.Negate (P 2 % 1)- , N 1 % 1 ~ K.Negate (P 1 % 1)- , N 2 % 1 ~ K.Negate (P 2 % 1)- )--_testSign = Dict-_testSign :: Dict- ( P 0 ~ K.Sign (P 0 % 1)- , P 0 ~ K.Sign (P 0 % 2)- , P 0 ~ K.Sign (N 0 % 1)- , P 0 ~ K.Sign (N 0 % 2)-- , N 1 ~ K.Sign (N 1 % 1)- , N 1 ~ K.Sign (N 1 % 2)- , N 1 ~ K.Sign (N 1 % 1)- , N 1 ~ K.Sign (N 1 % 2)-- , P 1 ~ K.Sign (P 1 % 1)- , P 1 ~ K.Sign (P 1 % 2)- , P 1 ~ K.Sign (P 1 % 1)- , P 1 ~ K.Sign (P 1 % 2)-- , N 1 ~ K.Sign (N 1 % 1)- , N 1 ~ K.Sign (N 2 % 1)- , N 1 ~ K.Sign (N 1 % 1)- , N 1 ~ K.Sign (N 2 % 1)-- , P 1 ~ K.Sign (P 1 % 1)- , P 1 ~ K.Sign (P 2 % 1)- , P 1 ~ K.Sign (P 1 % 1)- , P 1 ~ K.Sign (P 2 % 1)- )--_testAbs = Dict-_testAbs :: Dict- ( P 0 % 1 ~ K.Abs (P 0 % 1)- , P 0 % 1 ~ K.Abs (P 0 % 2)- , P 0 % 1 ~ K.Abs (N 0 % 1)- , P 0 % 1 ~ K.Abs (N 0 % 2)-- , P 1 % 1 ~ K.Abs (N 1 % 1)- , P 1 % 2 ~ K.Abs (N 1 % 2)- , P 1 % 1 ~ K.Abs (N 1 % 1)- , P 1 % 2 ~ K.Abs (N 1 % 2)-- , P 1 % 1 ~ K.Abs (P 1 % 1)- , P 1 % 2 ~ K.Abs (P 1 % 2)- , P 1 % 1 ~ K.Abs (P 1 % 1)- , P 1 % 2 ~ K.Abs (P 1 % 2)-- , P 1 % 1 ~ K.Abs (N 1 % 1)- , P 2 % 1 ~ K.Abs (N 2 % 1)- , P 1 % 1 ~ K.Abs (N 1 % 1)- , P 2 % 1 ~ K.Abs (N 2 % 1)-- , P 1 % 1 ~ K.Abs (P 1 % 1)- , P 2 % 1 ~ K.Abs (P 2 % 1)- , P 1 % 1 ~ K.Abs (P 1 % 1)- , P 2 % 1 ~ K.Abs (P 2 % 1)- )---_testEq = Dict-_testEq :: Dict- ( 1/2 K.== 1/2- , (1/2 K.==? 1/2) ~ 'True-- , 1/2 K.== 2/4- , (1/2 K.==? 2/4) ~ 'True-- , 1/2 K./= 3/4- , (1/2 K.==? 3/4) ~ 'False- , (1/2 K./=? 3/4) ~ 'True- )--_testCmp = Dict-_testCmp :: Dict- ( 1/4 <= 1/4- , 2/8 <= 1/4- , 1/4 <= 1/2- , 1/4 <= 2/4- , 2/8 <= 1/2- , 1/4 < 1/2- , 1/4 < 2/4- , 2/8 < 1/2- , 2/8 < 2/4- )--_testAdd = Dict-_testAdd :: Dict- ( (P 0 / 1) ~ (N 0 / 1) K.+ (N 0 / 1)- , (N 0 / 1) ~ (N 5 / 1) K.+ (P 5 / 1)- , (N 5 / 9) ~ (N 0 / 1) K.+ (N 5 / 9)- , (N 9 / 2) ~ (N 3 / 2) K.+ (N 3 / 1)- , (9 / 2) ~ (3 / 2) K.+ (3 / 1)- , (N 11 / 3)~ (N 3 / 1) K.+ (N 2 / 3)- )--_testMul = Dict-_testMul :: Dict- ( (0 / 1) ~ (N 0 / 1) K.* (N 0 / 1)- , (N 25 / 1) ~ (N 5 / 1) K.* (5 / 1)- , (N 1 / 1) ~ (N 5 / 1) K.* (1 / 5)- , (5 / 9) ~ (N 1 / 1) K.* (N 5 / 9)- , (9 / 1) ~ (N 3 / 1) K.* (N 3 / 1)- , (2 / 1) ~ (N 3 / 1) K.* (N 2 / 3)- , (1 / 1) ~ (P 3 / 2) K.* (P 2 / 3)- )--_testRecip = Dict-_testRecip :: Dict- ( (1 / 1) ~ K.Recip (1 / 1)- , (1 / 2) ~ K.Recip (2 / 1)- , (4 / 3) ~ K.Recip (3 / 4)- , (N 1 / 1) ~ K.Recip (N 1 / 1)- , (N 1 / 2) ~ K.Recip (N 2 / 1)- , (N 4 / 3) ~ K.Recip (N 3 / 4)- )--_testDiv = Dict-_testDiv :: Dict- ( P 1 ~ K.Div 'K.RoundDown (3 / 2)- , P 2 ~ K.Div 'K.RoundUp (3 / 2)- , P 1 ~ K.Div 'K.RoundZero (3 / 2)- , P 2 ~ K.Div 'K.RoundAway (3 / 2)- , P 1 ~ K.Div 'K.RoundHalfDown (3 / 2)- , P 2 ~ K.Div 'K.RoundHalfUp (3 / 2)- , P 1 ~ K.Div 'K.RoundHalfZero (3 / 2)- , P 2 ~ K.Div 'K.RoundHalfAway (3 / 2)- , P 2 ~ K.Div 'K.RoundHalfEven (3 / 2)- , P 1 ~ K.Div 'K.RoundHalfOdd (3 / 2)-- , N 2 ~ K.Div 'K.RoundDown (N 3 / 2)- , N 1 ~ K.Div 'K.RoundUp (N 3 / 2)- , N 1 ~ K.Div 'K.RoundZero (N 3 / 2)- , N 2 ~ K.Div 'K.RoundAway (N 3 / 2)- , N 2 ~ K.Div 'K.RoundHalfDown (N 3 / 2)- , N 1 ~ K.Div 'K.RoundHalfUp (N 3 / 2)- , N 1 ~ K.Div 'K.RoundHalfZero (N 3 / 2)- , N 2 ~ K.Div 'K.RoundHalfAway (N 3 / 2)- , N 2 ~ K.Div 'K.RoundHalfEven (N 3 / 2)- , N 1 ~ K.Div 'K.RoundHalfOdd (N 3 / 2)-- , P 0 ~ K.Div 'K.RoundDown (3 / 4)- , P 1 ~ K.Div 'K.RoundUp (3 / 4)- , P 0 ~ K.Div 'K.RoundZero (3 / 4)- , P 1 ~ K.Div 'K.RoundAway (3 / 4)- , P 1 ~ K.Div 'K.RoundHalfDown (3 / 4)- , P 1 ~ K.Div 'K.RoundHalfUp (3 / 4)- , P 1 ~ K.Div 'K.RoundHalfZero (3 / 4)- , P 1 ~ K.Div 'K.RoundHalfAway (3 / 4)- , P 1 ~ K.Div 'K.RoundHalfEven (3 / 4)- , P 1 ~ K.Div 'K.RoundHalfOdd (3 / 4)-- , N 1 ~ K.Div 'K.RoundDown (N 3 / 4)- , P 0 ~ K.Div 'K.RoundUp (N 3 / 4)- , P 0 ~ K.Div 'K.RoundZero (N 3 / 4)- , N 1 ~ K.Div 'K.RoundAway (N 3 / 4)- , N 1 ~ K.Div 'K.RoundHalfDown (N 3 / 4)- , N 1 ~ K.Div 'K.RoundHalfUp (N 3 / 4)- , N 1 ~ K.Div 'K.RoundHalfZero (N 3 / 4)- , N 1 ~ K.Div 'K.RoundHalfAway (N 3 / 4)- , N 1 ~ K.Div 'K.RoundHalfEven (N 3 / 4)- , N 1 ~ K.Div 'K.RoundHalfOdd (N 3 / 4)- )--_testRem = Dict-_testRem :: Dict- ( P 1 / 2 ~ K.Rem 'K.RoundDown (3 / 2)- , N 1 / 2 ~ K.Rem 'K.RoundUp (3 / 2)- , P 1 / 2 ~ K.Rem 'K.RoundZero (3 / 2)- , N 1 / 2 ~ K.Rem 'K.RoundAway (3 / 2)- , P 1 / 2 ~ K.Rem 'K.RoundHalfDown (3 / 2)- , N 1 / 2 ~ K.Rem 'K.RoundHalfUp (3 / 2)- , P 1 / 2 ~ K.Rem 'K.RoundHalfZero (3 / 2)- , N 1 / 2 ~ K.Rem 'K.RoundHalfAway (3 / 2)- , N 1 / 2 ~ K.Rem 'K.RoundHalfEven (3 / 2)- , P 1 / 2 ~ K.Rem 'K.RoundHalfOdd (3 / 2)-- , P 1 / 2 ~ K.Rem 'K.RoundDown (N 3 / 2)- , N 1 / 2 ~ K.Rem 'K.RoundUp (N 3 / 2)- , N 1 / 2 ~ K.Rem 'K.RoundZero (N 3 / 2)- , P 1 / 2 ~ K.Rem 'K.RoundAway (N 3 / 2)- , P 1 / 2 ~ K.Rem 'K.RoundHalfDown (N 3 / 2)- , N 1 / 2 ~ K.Rem 'K.RoundHalfUp (N 3 / 2)- , N 1 / 2 ~ K.Rem 'K.RoundHalfZero (N 3 / 2)- , P 1 / 2 ~ K.Rem 'K.RoundHalfAway (N 3 / 2)- , P 1 / 2 ~ K.Rem 'K.RoundHalfEven (N 3 / 2)- , N 1 / 2 ~ K.Rem 'K.RoundHalfOdd (N 3 / 2)-- , P 3 / 4 ~ K.Rem 'K.RoundDown (3 / 4)- , N 1 / 4 ~ K.Rem 'K.RoundUp (3 / 4)- , P 3 / 4 ~ K.Rem 'K.RoundZero (3 / 4)- , N 1 / 4 ~ K.Rem 'K.RoundAway (3 / 4)- , N 1 / 4 ~ K.Rem 'K.RoundHalfDown (3 / 4)- , N 1 / 4 ~ K.Rem 'K.RoundHalfUp (3 / 4)- , N 1 / 4 ~ K.Rem 'K.RoundHalfZero (3 / 4)- , N 1 / 4 ~ K.Rem 'K.RoundHalfAway (3 / 4)- , N 1 / 4 ~ K.Rem 'K.RoundHalfEven (3 / 4)- , N 1 / 4 ~ K.Rem 'K.RoundHalfOdd (3 / 4)-- , P 1 / 4 ~ K.Rem 'K.RoundDown (N 3 / 4)- , N 3 / 4 ~ K.Rem 'K.RoundUp (N 3 / 4)- , N 3 / 4 ~ K.Rem 'K.RoundZero (N 3 / 4)- , P 1 / 4 ~ K.Rem 'K.RoundAway (N 3 / 4)- , P 1 / 4 ~ K.Rem 'K.RoundHalfDown (N 3 / 4)- , P 1 / 4 ~ K.Rem 'K.RoundHalfUp (N 3 / 4)- , P 1 / 4 ~ K.Rem 'K.RoundHalfZero (N 3 / 4)- , P 1 / 4 ~ K.Rem 'K.RoundHalfAway (N 3 / 4)- , P 1 / 4 ~ K.Rem 'K.RoundHalfEven (N 3 / 4)- , P 1 / 4 ~ K.Rem 'K.RoundHalfOdd (N 3 / 4)- )--_testDivRem = Dict-_testDivRem :: Dict- ( '(P 1, P 1 / 2) ~ K.DivRem 'K.RoundDown (3 / 2)- , '(P 2, N 1 / 2) ~ K.DivRem 'K.RoundUp (3 / 2)- , '(P 1, P 1 / 2) ~ K.DivRem 'K.RoundZero (3 / 2)- , '(P 2, N 1 / 2) ~ K.DivRem 'K.RoundAway (3 / 2)- , '(P 1, P 1 / 2) ~ K.DivRem 'K.RoundHalfDown (3 / 2)- , '(P 2, N 1 / 2) ~ K.DivRem 'K.RoundHalfUp (3 / 2)- , '(P 1, P 1 / 2) ~ K.DivRem 'K.RoundHalfZero (3 / 2)- , '(P 2, N 1 / 2) ~ K.DivRem 'K.RoundHalfAway (3 / 2)- , '(P 2, N 1 / 2) ~ K.DivRem 'K.RoundHalfEven (3 / 2)- , '(P 1, P 1 / 2) ~ K.DivRem 'K.RoundHalfOdd (3 / 2)-- , '(N 2, P 1 / 2) ~ K.DivRem 'K.RoundDown (N 3 / 2)- , '(N 1, N 1 / 2) ~ K.DivRem 'K.RoundUp (N 3 / 2)- , '(N 1, N 1 / 2) ~ K.DivRem 'K.RoundZero (N 3 / 2)- , '(N 2, P 1 / 2) ~ K.DivRem 'K.RoundAway (N 3 / 2)- , '(N 2, P 1 / 2) ~ K.DivRem 'K.RoundHalfDown (N 3 / 2)- , '(N 1, N 1 / 2) ~ K.DivRem 'K.RoundHalfUp (N 3 / 2)- , '(N 1, N 1 / 2) ~ K.DivRem 'K.RoundHalfZero (N 3 / 2)- , '(N 2, P 1 / 2) ~ K.DivRem 'K.RoundHalfAway (N 3 / 2)- , '(N 2, P 1 / 2) ~ K.DivRem 'K.RoundHalfEven (N 3 / 2)- , '(N 1, N 1 / 2) ~ K.DivRem 'K.RoundHalfOdd (N 3 / 2)-- , '(P 0, P 3 / 4) ~ K.DivRem 'K.RoundDown (3 / 4)- , '(P 1, N 1 / 4) ~ K.DivRem 'K.RoundUp (3 / 4)- , '(P 0, P 3 / 4) ~ K.DivRem 'K.RoundZero (3 / 4)- , '(P 1, N 1 / 4) ~ K.DivRem 'K.RoundAway (3 / 4)- , '(P 1, N 1 / 4) ~ K.DivRem 'K.RoundHalfDown (3 / 4)- , '(P 1, N 1 / 4) ~ K.DivRem 'K.RoundHalfUp (3 / 4)- , '(P 1, N 1 / 4) ~ K.DivRem 'K.RoundHalfZero (3 / 4)- , '(P 1, N 1 / 4) ~ K.DivRem 'K.RoundHalfAway (3 / 4)- , '(P 1, N 1 / 4) ~ K.DivRem 'K.RoundHalfEven (3 / 4)- , '(P 1, N 1 / 4) ~ K.DivRem 'K.RoundHalfOdd (3 / 4)-- , '(N 1, P 1 / 4) ~ K.DivRem 'K.RoundDown (N 3 / 4)- , '(P 0, N 3 / 4) ~ K.DivRem 'K.RoundUp (N 3 / 4)- , '(P 0, N 3 / 4) ~ K.DivRem 'K.RoundZero (N 3 / 4)- , '(N 1, P 1 / 4) ~ K.DivRem 'K.RoundAway (N 3 / 4)- , '(N 1, P 1 / 4) ~ K.DivRem 'K.RoundHalfDown (N 3 / 4)- , '(N 1, P 1 / 4) ~ K.DivRem 'K.RoundHalfUp (N 3 / 4)- , '(N 1, P 1 / 4) ~ K.DivRem 'K.RoundHalfZero (N 3 / 4)- , '(N 1, P 1 / 4) ~ K.DivRem 'K.RoundHalfAway (N 3 / 4)- , '(N 1, P 1 / 4) ~ K.DivRem 'K.RoundHalfEven (N 3 / 4)- , '(N 1, P 1 / 4) ~ K.DivRem 'K.RoundHalfOdd (N 3 / 4)- )--_testTerminates = Dict-_testTerminates :: Dict- ( K.Terminating (0/1)- , K.Terminating (N 1/1)- , K.Terminating (2/1)- , K.Terminating (N 1/2)- , K.Terminating (1/4)- , K.Terminating (N 1/5)- , K.Terminating (1/10)- , K.Terminating (N 1/20)- , K.Terminating (1/50)- , K.Terminating (N 1/10000000)-- , K.Terminating (3/1)- , K.Terminating (N 3/1)- , K.Terminating (3/2)- , K.Terminating (N 3/3)- , K.Terminating (3/4)- , K.Terminating (N 3/5)- , K.Terminating (3/6)- , K.Terminating (N 3/10)- , K.Terminating (3/20)- , K.Terminating (N 3/50)- , K.Terminating (3/10000000)-- , 'True ~ K.Terminates (N 0/1)- , 'True ~ K.Terminates (1/1)- , 'True ~ K.Terminates (N 2/1)- , 'True ~ K.Terminates (1/2)- , 'True ~ K.Terminates (N 1/4)- , 'True ~ K.Terminates (1/5)- , 'True ~ K.Terminates (N 1/10)- , 'True ~ K.Terminates (1/20)- , 'True ~ K.Terminates (N 1/50)- , 'True ~ K.Terminates (1/10000000)-- , 'True ~ K.Terminates (N 3/1)- , 'True ~ K.Terminates (3/1)- , 'True ~ K.Terminates (N 3/2)- , 'True ~ K.Terminates (3/3)- , 'True ~ K.Terminates (N 3/4)- , 'True ~ K.Terminates (3/5)- , 'True ~ K.Terminates (N 3/6)- , 'True ~ K.Terminates (3/10)- , 'True ~ K.Terminates (N 3/20)- , 'True ~ K.Terminates (3/50)- , 'True ~ K.Terminates (N 3/10000000)-- , 'False ~ K.Terminates (1/3)- , 'False ~ K.Terminates (N 1/12)- , 'False ~ K.Terminates (1/15)- , 'False ~ K.Terminates (N 2/3)- , 'False ~ K.Terminates (75/7)- , 'False ~ K.Terminates (N 8/3)- )------------------------------------------------------------------------------------assert- :: String -- ^ Test name- -> Bool -- ^ Successful is true- -> IO Bool -- ^ Return the same 'Bool' given as input.-assert n x = do- putStrLn ((if x then "[OK] " else "[FAIL] ") <> n)- pure x--testsMain :: [IO Bool] -> IO a-testsMain xs = do- res <- sequence xs- let (oks, bads) = List.partition id res- putStrLn ("[TOTAL] OK: " <> show (length oks) <>- ". FAIL: " <> show (length bads) <> ".")- case bads of- [] -> exitSuccess- _ -> exitFailure--rats :: P.Integer -> [K.Rational]-rats i = do n <- [negate i .. i]- d <- [negate i .. i]- maybeToList $ K.rational n d--main :: IO ()-main = testsMain $- [ assert "rationalVal . someRationalVal == id" $- flip all (rats 4) $ \a ->- case K.someRationalVal a of- K.SomeRational pa ->- a == K.rationalVal pa-- , assert "sameRationalVal a a" $- flip all (rats 4) $ \a ->- case K.someRationalVal a of- K.SomeRational pa ->- isJust (K.sameRational pa pa)-- , assert "sameRationalVal a a'" $- flip all (rats 4) $ \a ->- case (K.someRationalVal a, K.someRationalVal a) of- (K.SomeRational pa1, K.SomeRational pa2) ->- isJust (K.sameRational pa1 pa2)-- , assert "sameRationalVal a b" $- flip all (liftA2 (,) (rats 4) (rats 4)) $ \(a, b) ->- case (K.someRationalVal a, K.someRationalVal b) of- (K.SomeRational pa, K.SomeRational pb)- | a == b -> isJust (K.sameRational pa pb)- | otherwise -> isNothing (K.sameRational pa pb)-- , assert "Eq SomeRational" $- flip all (liftA2 (,) (rats 4) (rats 4))$ \(a, b) ->- (a == b) == (K.someRationalVal a == K.someRationalVal b)-- , assert "Ord SomeRational" $- flip all (liftA2 (,) (rats 4) (rats 4))$ \(a, b) ->- compare a b == compare (K.someRationalVal a) (K.someRationalVal b)-- , assert "Show SomeRational" $- flip all (rats 4) $ \a ->- show a == show (K.someRationalVal a)-- , assert "Read SomeRational" $- flip all (rats 4) $ \a ->- let str = show a- in readMaybe @P.Rational str- == fmap (\(K.SomeRational p) -> K.toPrelude (K.rationalVal p))- (readMaybe @K.SomeRational str)-- -- TODO test TestEquality-- , assert "TestEquality +0/1 +0/1" $- isJust (testEquality (K.SRational @(P 0 % 1)) (K.SRational @(P 0 % 1)))- , assert "TestEquality -0/1 -0/1" $- isJust (testEquality (K.SRational @(N 0 % 1)) (K.SRational @(N 0 % 1)))- , assert "TestEquality +1/2 +1/2" $- isJust (testEquality (K.SRational @(P 1 % 2)) (K.SRational @(P 1 % 2)))- , assert "TestEquality -1/2 -1/2" $- isJust (testEquality (K.SRational @(N 1 % 2)) (K.SRational @(N 1 % 2)))- , assert "TestEquality +0/1 -0/1" $- isNothing (testEquality (K.SRational @(P 0 % 1)) (K.SRational @(N 0 % 1)))- , assert "TestEquality -0/1 +0/1" $- isNothing (testEquality (K.SRational @(N 0 % 1)) (K.SRational @(P 0 % 1)))- , assert "TestEquality +0/1 +1/1" $- isNothing (testEquality (K.SRational @(P 0 % 1)) (K.SRational @(P 1 % 1)))- , assert "TestEquality +0/1 -1/1" $- isNothing (testEquality (K.SRational @(P 0 % 1)) (K.SRational @(N 1 % 1)))- , assert "TestEquality -0/1 +1/1" $- isNothing (testEquality (K.SRational @(N 0 % 1)) (K.SRational @(P 1 % 1)))- , assert "TestEquality -0/1 -1/1" $- isNothing (testEquality (K.SRational @(N 0 % 1)) (K.SRational @(N 1 % 1)))- , assert "TestEquality +1/1 +0/1" $- isNothing (testEquality (K.SRational @(P 1 % 1)) (K.SRational @(P 0 % 1)))- , assert "TestEquality +1/1 -0/1" $- isNothing (testEquality (K.SRational @(P 1 % 1)) (K.SRational @(N 0 % 1)))- , assert "TestEquality -1/1 +0/1" $- isNothing (testEquality (K.SRational @(N 1 % 1)) (K.SRational @(P 0 % 1)))- , assert "TestEquality -1/1 -0/1" $- isNothing (testEquality (K.SRational @(N 1 % 1)) (K.SRational @(N 0 % 1)))- , assert "TestEquality +1/2 +2/4" $- isNothing (testEquality (K.SRational @(P 1 % 2)) (K.SRational @(P 2 % 4)))- , assert "TestEquality -1/2 -2/4" $- isNothing (testEquality (K.SRational @(N 1 % 2)) (K.SRational @(N 2 % 4)))-- , assert "Show Rational +0" $- "0 % 1" == show (K.fromSRational (K.SRational @(P 0 % 1)))- , assert "Show Rational -0" $- "0 % 1" == show (K.fromSRational (K.SRational @(N 0 % 1)))- , assert "Show Rational +1" $- "1 % 1" == show (K.fromSRational (K.SRational @(P 1 % 1)))- , assert "Show Rational -1" $- "(-1) % 1" == show (K.fromSRational (K.SRational @(N 1 % 1)))-- , assert "Show SRational +0" $- "SRational @(P 0 % 1)" == show (K.SRational @(P 0 % 1))- , assert "Show SRational -0" $- "SRational @(N 0 % 1)" == show (K.SRational @(N 0 % 1))- , assert "Show SRational +1" $- "SRational @(P 1 % 1)" == show (K.SRational @(P 1 % 1))- , assert "Show SRational -1" $- "SRational @(N 1 % 1)" == show (K.SRational @(N 1 % 1))-- ] <> testsDivRem <> testsTerminating--testsDivRem :: [IO Bool]-testsDivRem = do- a <- rats 4- let n P.:% d = K.toPrelude a- r :: K.Round <- [minBound .. maxBound]- let tname :: String -> ShowS- tname t = showString t . showChar ' ' . shows r . showChar ' '- . shows n . showChar ' ' . shows d- [ assert (tname "divRem" "") $- case K.divRem r a of- (q, x) -> Just a == K.fromPrelude (toRational q + K.toPrelude x)- , assert (tname "divRem/div" "") $ fst (K.divRem r a) == K.div r a- , assert (tname "divRem/rem" "") $ snd (K.divRem r a) == K.rem r a- ]--testsTerminating :: [IO Bool]-testsTerminating = concat- [ do a <- ok- pure $ assert ("withTerminating(ok) (" <> show a <> ")") $- case K.someRationalVal a of- K.SomeRational (_ :: Proxy a) ->- isJust (K.withTerminating @a () :: Maybe ())-- , do a <- no- pure $ assert ("withTerminating(no) (" <> show a <> ")") $- case K.someRationalVal a of- K.SomeRational (_ :: Proxy a) ->- isNothing (K.withTerminating @a () :: Maybe ())- ]- where- ok :: [K.Rational]- Just ok = traverse K.fromPrelude- [ 0 P.% 1- , -1 P.% 1- , 2 P.% 1- , -1 P.% 2- , 1 P.% 4- , -1 P.% 5- , 1 P.% 10- , -1 P.% 20- , 1 P.% 50- , -1 P.% 10000000- , 3 P.% 1- , -3 P.% 1- , 3 P.% 2- , -3 P.% 3- , 3 P.% 4- , -3 P.% 5- , 3 P.% 6- , -3 P.% 10- , 3 P.% 20- , -3 P.% 50- , 3 P.% 10000000- ]- no :: [K.Rational]- Just no = traverse K.fromPrelude- [ 1 P.% 3- , -1 P.% 12- , 1 P.% 15- , -2 P.% 3- , 75 P.% 7- , -8 P.% 3- ]---_testSlash_Nat0_Nat1 = Dict @((P 0 % 1) ~ (0 / 1))-_testSlash_Nat0_Nat2 = Dict @((P 0 % 1) ~ (0 / 2))-_testSlash_Nat0_Nat3 = Dict @((P 0 % 1) ~ (0 / 3))-_testSlash_Nat0_Nat4 = Dict @((P 0 % 1) ~ (0 / 4))-_testSlash_Nat0_IntN4 = Dict @((P 0 % 1) ~ (0 / (N 4)))-_testSlash_Nat0_IntN3 = Dict @((P 0 % 1) ~ (0 / (N 3)))-_testSlash_Nat0_IntN2 = Dict @((P 0 % 1) ~ (0 / (N 2)))-_testSlash_Nat0_IntN1 = Dict @((P 0 % 1) ~ (0 / (N 1)))-_testSlash_Nat0_IntP1 = Dict @((P 0 % 1) ~ (0 / (P 1)))-_testSlash_Nat0_IntP2 = Dict @((P 0 % 1) ~ (0 / (P 2)))-_testSlash_Nat0_IntP3 = Dict @((P 0 % 1) ~ (0 / (P 3)))-_testSlash_Nat0_IntP4 = Dict @((P 0 % 1) ~ (0 / (P 4)))-_testSlash_Nat0_Rat4N1 = Dict @((P 0 % 1) ~ (0 / (N 4 % 1)))-_testSlash_Nat0_Rat3N1 = Dict @((P 0 % 1) ~ (0 / (N 3 % 1)))-_testSlash_Nat0_Rat2N1 = Dict @((P 0 % 1) ~ (0 / (N 2 % 1)))-_testSlash_Nat0_Rat3N2 = Dict @((P 0 % 1) ~ (0 / (N 3 % 2)))-_testSlash_Nat0_Rat4N3 = Dict @((P 0 % 1) ~ (0 / (N 4 % 3)))-_testSlash_Nat0_Rat1N1 = Dict @((P 0 % 1) ~ (0 / (N 1 % 1)))-_testSlash_Nat0_Rat3N4 = Dict @((P 0 % 1) ~ (0 / (N 3 % 4)))-_testSlash_Nat0_Rat2N3 = Dict @((P 0 % 1) ~ (0 / (N 2 % 3)))-_testSlash_Nat0_Rat1N2 = Dict @((P 0 % 1) ~ (0 / (N 1 % 2)))-_testSlash_Nat0_Rat1N3 = Dict @((P 0 % 1) ~ (0 / (N 1 % 3)))-_testSlash_Nat0_Rat1N4 = Dict @((P 0 % 1) ~ (0 / (N 1 % 4)))-_testSlash_Nat0_Rat1P4 = Dict @((P 0 % 1) ~ (0 / (P 1 % 4)))-_testSlash_Nat0_Rat1P3 = Dict @((P 0 % 1) ~ (0 / (P 1 % 3)))-_testSlash_Nat0_Rat1P2 = Dict @((P 0 % 1) ~ (0 / (P 1 % 2)))-_testSlash_Nat0_Rat2P3 = Dict @((P 0 % 1) ~ (0 / (P 2 % 3)))-_testSlash_Nat0_Rat3P4 = Dict @((P 0 % 1) ~ (0 / (P 3 % 4)))-_testSlash_Nat0_Rat1P1 = Dict @((P 0 % 1) ~ (0 / (P 1 % 1)))-_testSlash_Nat0_Rat4P3 = Dict @((P 0 % 1) ~ (0 / (P 4 % 3)))-_testSlash_Nat0_Rat3P2 = Dict @((P 0 % 1) ~ (0 / (P 3 % 2)))-_testSlash_Nat0_Rat2P1 = Dict @((P 0 % 1) ~ (0 / (P 2 % 1)))-_testSlash_Nat0_Rat3P1 = Dict @((P 0 % 1) ~ (0 / (P 3 % 1)))-_testSlash_Nat0_Rat4P1 = Dict @((P 0 % 1) ~ (0 / (P 4 % 1)))-_testSlash_Nat1_Nat1 = Dict @((P 1 % 1) ~ (1 / 1))-_testSlash_Nat1_Nat2 = Dict @((P 1 % 2) ~ (1 / 2))-_testSlash_Nat1_Nat3 = Dict @((P 1 % 3) ~ (1 / 3))-_testSlash_Nat1_Nat4 = Dict @((P 1 % 4) ~ (1 / 4))-_testSlash_Nat1_IntN4 = Dict @((N 1 % 4) ~ (1 / (N 4)))-_testSlash_Nat1_IntN3 = Dict @((N 1 % 3) ~ (1 / (N 3)))-_testSlash_Nat1_IntN2 = Dict @((N 1 % 2) ~ (1 / (N 2)))-_testSlash_Nat1_IntN1 = Dict @((N 1 % 1) ~ (1 / (N 1)))-_testSlash_Nat1_IntP1 = Dict @((P 1 % 1) ~ (1 / (P 1)))-_testSlash_Nat1_IntP2 = Dict @((P 1 % 2) ~ (1 / (P 2)))-_testSlash_Nat1_IntP3 = Dict @((P 1 % 3) ~ (1 / (P 3)))-_testSlash_Nat1_IntP4 = Dict @((P 1 % 4) ~ (1 / (P 4)))-_testSlash_Nat1_Rat4N1 = Dict @((N 1 % 4) ~ (1 / (N 4 % 1)))-_testSlash_Nat1_Rat3N1 = Dict @((N 1 % 3) ~ (1 / (N 3 % 1)))-_testSlash_Nat1_Rat2N1 = Dict @((N 1 % 2) ~ (1 / (N 2 % 1)))-_testSlash_Nat1_Rat3N2 = Dict @((N 2 % 3) ~ (1 / (N 3 % 2)))-_testSlash_Nat1_Rat4N3 = Dict @((N 3 % 4) ~ (1 / (N 4 % 3)))-_testSlash_Nat1_Rat1N1 = Dict @((N 1 % 1) ~ (1 / (N 1 % 1)))-_testSlash_Nat1_Rat3N4 = Dict @((N 4 % 3) ~ (1 / (N 3 % 4)))-_testSlash_Nat1_Rat2N3 = Dict @((N 3 % 2) ~ (1 / (N 2 % 3)))-_testSlash_Nat1_Rat1N2 = Dict @((N 2 % 1) ~ (1 / (N 1 % 2)))-_testSlash_Nat1_Rat1N3 = Dict @((N 3 % 1) ~ (1 / (N 1 % 3)))-_testSlash_Nat1_Rat1N4 = Dict @((N 4 % 1) ~ (1 / (N 1 % 4)))-_testSlash_Nat1_Rat1P4 = Dict @((P 4 % 1) ~ (1 / (P 1 % 4)))-_testSlash_Nat1_Rat1P3 = Dict @((P 3 % 1) ~ (1 / (P 1 % 3)))-_testSlash_Nat1_Rat1P2 = Dict @((P 2 % 1) ~ (1 / (P 1 % 2)))-_testSlash_Nat1_Rat2P3 = Dict @((P 3 % 2) ~ (1 / (P 2 % 3)))-_testSlash_Nat1_Rat3P4 = Dict @((P 4 % 3) ~ (1 / (P 3 % 4)))-_testSlash_Nat1_Rat1P1 = Dict @((P 1 % 1) ~ (1 / (P 1 % 1)))-_testSlash_Nat1_Rat4P3 = Dict @((P 3 % 4) ~ (1 / (P 4 % 3)))-_testSlash_Nat1_Rat3P2 = Dict @((P 2 % 3) ~ (1 / (P 3 % 2)))-_testSlash_Nat1_Rat2P1 = Dict @((P 1 % 2) ~ (1 / (P 2 % 1)))-_testSlash_Nat1_Rat3P1 = Dict @((P 1 % 3) ~ (1 / (P 3 % 1)))-_testSlash_Nat1_Rat4P1 = Dict @((P 1 % 4) ~ (1 / (P 4 % 1)))-_testSlash_Nat2_Nat1 = Dict @((P 2 % 1) ~ (2 / 1))-_testSlash_Nat2_Nat2 = Dict @((P 1 % 1) ~ (2 / 2))-_testSlash_Nat2_Nat3 = Dict @((P 2 % 3) ~ (2 / 3))-_testSlash_Nat2_Nat4 = Dict @((P 1 % 2) ~ (2 / 4))-_testSlash_Nat2_IntN4 = Dict @((N 1 % 2) ~ (2 / (N 4)))-_testSlash_Nat2_IntN3 = Dict @((N 2 % 3) ~ (2 / (N 3)))-_testSlash_Nat2_IntN2 = Dict @((N 1 % 1) ~ (2 / (N 2)))-_testSlash_Nat2_IntN1 = Dict @((N 2 % 1) ~ (2 / (N 1)))-_testSlash_Nat2_IntP1 = Dict @((P 2 % 1) ~ (2 / (P 1)))-_testSlash_Nat2_IntP2 = Dict @((P 1 % 1) ~ (2 / (P 2)))-_testSlash_Nat2_IntP3 = Dict @((P 2 % 3) ~ (2 / (P 3)))-_testSlash_Nat2_IntP4 = Dict @((P 1 % 2) ~ (2 / (P 4)))-_testSlash_Nat2_Rat4N1 = Dict @((N 1 % 2) ~ (2 / (N 4 % 1)))-_testSlash_Nat2_Rat3N1 = Dict @((N 2 % 3) ~ (2 / (N 3 % 1)))-_testSlash_Nat2_Rat2N1 = Dict @((N 1 % 1) ~ (2 / (N 2 % 1)))-_testSlash_Nat2_Rat3N2 = Dict @((N 4 % 3) ~ (2 / (N 3 % 2)))-_testSlash_Nat2_Rat4N3 = Dict @((N 3 % 2) ~ (2 / (N 4 % 3)))-_testSlash_Nat2_Rat1N1 = Dict @((N 2 % 1) ~ (2 / (N 1 % 1)))-_testSlash_Nat2_Rat3N4 = Dict @((N 8 % 3) ~ (2 / (N 3 % 4)))-_testSlash_Nat2_Rat2N3 = Dict @((N 3 % 1) ~ (2 / (N 2 % 3)))-_testSlash_Nat2_Rat1N2 = Dict @((N 4 % 1) ~ (2 / (N 1 % 2)))-_testSlash_Nat2_Rat1N3 = Dict @((N 6 % 1) ~ (2 / (N 1 % 3)))-_testSlash_Nat2_Rat1N4 = Dict @((N 8 % 1) ~ (2 / (N 1 % 4)))-_testSlash_Nat2_Rat1P4 = Dict @((P 8 % 1) ~ (2 / (P 1 % 4)))-_testSlash_Nat2_Rat1P3 = Dict @((P 6 % 1) ~ (2 / (P 1 % 3)))-_testSlash_Nat2_Rat1P2 = Dict @((P 4 % 1) ~ (2 / (P 1 % 2)))-_testSlash_Nat2_Rat2P3 = Dict @((P 3 % 1) ~ (2 / (P 2 % 3)))-_testSlash_Nat2_Rat3P4 = Dict @((P 8 % 3) ~ (2 / (P 3 % 4)))-_testSlash_Nat2_Rat1P1 = Dict @((P 2 % 1) ~ (2 / (P 1 % 1)))-_testSlash_Nat2_Rat4P3 = Dict @((P 3 % 2) ~ (2 / (P 4 % 3)))-_testSlash_Nat2_Rat3P2 = Dict @((P 4 % 3) ~ (2 / (P 3 % 2)))-_testSlash_Nat2_Rat2P1 = Dict @((P 1 % 1) ~ (2 / (P 2 % 1)))-_testSlash_Nat2_Rat3P1 = Dict @((P 2 % 3) ~ (2 / (P 3 % 1)))-_testSlash_Nat2_Rat4P1 = Dict @((P 1 % 2) ~ (2 / (P 4 % 1)))-_testSlash_Nat3_Nat1 = Dict @((P 3 % 1) ~ (3 / 1))-_testSlash_Nat3_Nat2 = Dict @((P 3 % 2) ~ (3 / 2))-_testSlash_Nat3_Nat3 = Dict @((P 1 % 1) ~ (3 / 3))-_testSlash_Nat3_Nat4 = Dict @((P 3 % 4) ~ (3 / 4))-_testSlash_Nat3_IntN4 = Dict @((N 3 % 4) ~ (3 / (N 4)))-_testSlash_Nat3_IntN3 = Dict @((N 1 % 1) ~ (3 / (N 3)))-_testSlash_Nat3_IntN2 = Dict @((N 3 % 2) ~ (3 / (N 2)))-_testSlash_Nat3_IntN1 = Dict @((N 3 % 1) ~ (3 / (N 1)))-_testSlash_Nat3_IntP1 = Dict @((P 3 % 1) ~ (3 / (P 1)))-_testSlash_Nat3_IntP2 = Dict @((P 3 % 2) ~ (3 / (P 2)))-_testSlash_Nat3_IntP3 = Dict @((P 1 % 1) ~ (3 / (P 3)))-_testSlash_Nat3_IntP4 = Dict @((P 3 % 4) ~ (3 / (P 4)))-_testSlash_Nat3_Rat4N1 = Dict @((N 3 % 4) ~ (3 / (N 4 % 1)))-_testSlash_Nat3_Rat3N1 = Dict @((N 1 % 1) ~ (3 / (N 3 % 1)))-_testSlash_Nat3_Rat2N1 = Dict @((N 3 % 2) ~ (3 / (N 2 % 1)))-_testSlash_Nat3_Rat3N2 = Dict @((N 2 % 1) ~ (3 / (N 3 % 2)))-_testSlash_Nat3_Rat4N3 = Dict @((N 9 % 4) ~ (3 / (N 4 % 3)))-_testSlash_Nat3_Rat1N1 = Dict @((N 3 % 1) ~ (3 / (N 1 % 1)))-_testSlash_Nat3_Rat3N4 = Dict @((N 4 % 1) ~ (3 / (N 3 % 4)))-_testSlash_Nat3_Rat2N3 = Dict @((N 9 % 2) ~ (3 / (N 2 % 3)))-_testSlash_Nat3_Rat1N2 = Dict @((N 6 % 1) ~ (3 / (N 1 % 2)))-_testSlash_Nat3_Rat1N3 = Dict @((N 9 % 1) ~ (3 / (N 1 % 3)))-_testSlash_Nat3_Rat1N4 = Dict @((N 12 % 1) ~ (3 / (N 1 % 4)))-_testSlash_Nat3_Rat1P4 = Dict @((P 12 % 1) ~ (3 / (P 1 % 4)))-_testSlash_Nat3_Rat1P3 = Dict @((P 9 % 1) ~ (3 / (P 1 % 3)))-_testSlash_Nat3_Rat1P2 = Dict @((P 6 % 1) ~ (3 / (P 1 % 2)))-_testSlash_Nat3_Rat2P3 = Dict @((P 9 % 2) ~ (3 / (P 2 % 3)))-_testSlash_Nat3_Rat3P4 = Dict @((P 4 % 1) ~ (3 / (P 3 % 4)))-_testSlash_Nat3_Rat1P1 = Dict @((P 3 % 1) ~ (3 / (P 1 % 1)))-_testSlash_Nat3_Rat4P3 = Dict @((P 9 % 4) ~ (3 / (P 4 % 3)))-_testSlash_Nat3_Rat3P2 = Dict @((P 2 % 1) ~ (3 / (P 3 % 2)))-_testSlash_Nat3_Rat2P1 = Dict @((P 3 % 2) ~ (3 / (P 2 % 1)))-_testSlash_Nat3_Rat3P1 = Dict @((P 1 % 1) ~ (3 / (P 3 % 1)))-_testSlash_Nat3_Rat4P1 = Dict @((P 3 % 4) ~ (3 / (P 4 % 1)))-_testSlash_Nat4_Nat1 = Dict @((P 4 % 1) ~ (4 / 1))-_testSlash_Nat4_Nat2 = Dict @((P 2 % 1) ~ (4 / 2))-_testSlash_Nat4_Nat3 = Dict @((P 4 % 3) ~ (4 / 3))-_testSlash_Nat4_Nat4 = Dict @((P 1 % 1) ~ (4 / 4))-_testSlash_Nat4_IntN4 = Dict @((N 1 % 1) ~ (4 / (N 4)))-_testSlash_Nat4_IntN3 = Dict @((N 4 % 3) ~ (4 / (N 3)))-_testSlash_Nat4_IntN2 = Dict @((N 2 % 1) ~ (4 / (N 2)))-_testSlash_Nat4_IntN1 = Dict @((N 4 % 1) ~ (4 / (N 1)))-_testSlash_Nat4_IntP1 = Dict @((P 4 % 1) ~ (4 / (P 1)))-_testSlash_Nat4_IntP2 = Dict @((P 2 % 1) ~ (4 / (P 2)))-_testSlash_Nat4_IntP3 = Dict @((P 4 % 3) ~ (4 / (P 3)))-_testSlash_Nat4_IntP4 = Dict @((P 1 % 1) ~ (4 / (P 4)))-_testSlash_Nat4_Rat4N1 = Dict @((N 1 % 1) ~ (4 / (N 4 % 1)))-_testSlash_Nat4_Rat3N1 = Dict @((N 4 % 3) ~ (4 / (N 3 % 1)))-_testSlash_Nat4_Rat2N1 = Dict @((N 2 % 1) ~ (4 / (N 2 % 1)))-_testSlash_Nat4_Rat3N2 = Dict @((N 8 % 3) ~ (4 / (N 3 % 2)))-_testSlash_Nat4_Rat4N3 = Dict @((N 3 % 1) ~ (4 / (N 4 % 3)))-_testSlash_Nat4_Rat1N1 = Dict @((N 4 % 1) ~ (4 / (N 1 % 1)))-_testSlash_Nat4_Rat3N4 = Dict @((N 16 % 3) ~ (4 / (N 3 % 4)))-_testSlash_Nat4_Rat2N3 = Dict @((N 6 % 1) ~ (4 / (N 2 % 3)))-_testSlash_Nat4_Rat1N2 = Dict @((N 8 % 1) ~ (4 / (N 1 % 2)))-_testSlash_Nat4_Rat1N3 = Dict @((N 12 % 1) ~ (4 / (N 1 % 3)))-_testSlash_Nat4_Rat1N4 = Dict @((N 16 % 1) ~ (4 / (N 1 % 4)))-_testSlash_Nat4_Rat1P4 = Dict @((P 16 % 1) ~ (4 / (P 1 % 4)))-_testSlash_Nat4_Rat1P3 = Dict @((P 12 % 1) ~ (4 / (P 1 % 3)))-_testSlash_Nat4_Rat1P2 = Dict @((P 8 % 1) ~ (4 / (P 1 % 2)))-_testSlash_Nat4_Rat2P3 = Dict @((P 6 % 1) ~ (4 / (P 2 % 3)))-_testSlash_Nat4_Rat3P4 = Dict @((P 16 % 3) ~ (4 / (P 3 % 4)))-_testSlash_Nat4_Rat1P1 = Dict @((P 4 % 1) ~ (4 / (P 1 % 1)))-_testSlash_Nat4_Rat4P3 = Dict @((P 3 % 1) ~ (4 / (P 4 % 3)))-_testSlash_Nat4_Rat3P2 = Dict @((P 8 % 3) ~ (4 / (P 3 % 2)))-_testSlash_Nat4_Rat2P1 = Dict @((P 2 % 1) ~ (4 / (P 2 % 1)))-_testSlash_Nat4_Rat3P1 = Dict @((P 4 % 3) ~ (4 / (P 3 % 1)))-_testSlash_Nat4_Rat4P1 = Dict @((P 1 % 1) ~ (4 / (P 4 % 1)))-_testSlash_IntN4_Nat1 = Dict @((N 4 % 1) ~ ((N 4) / 1))-_testSlash_IntN4_Nat2 = Dict @((N 2 % 1) ~ ((N 4) / 2))-_testSlash_IntN4_Nat3 = Dict @((N 4 % 3) ~ ((N 4) / 3))-_testSlash_IntN4_Nat4 = Dict @((N 1 % 1) ~ ((N 4) / 4))-_testSlash_IntN4_IntN4 = Dict @((P 1 % 1) ~ ((N 4) / (N 4)))-_testSlash_IntN4_IntN3 = Dict @((P 4 % 3) ~ ((N 4) / (N 3)))-_testSlash_IntN4_IntN2 = Dict @((P 2 % 1) ~ ((N 4) / (N 2)))-_testSlash_IntN4_IntN1 = Dict @((P 4 % 1) ~ ((N 4) / (N 1)))-_testSlash_IntN4_IntP1 = Dict @((N 4 % 1) ~ ((N 4) / (P 1)))-_testSlash_IntN4_IntP2 = Dict @((N 2 % 1) ~ ((N 4) / (P 2)))-_testSlash_IntN4_IntP3 = Dict @((N 4 % 3) ~ ((N 4) / (P 3)))-_testSlash_IntN4_IntP4 = Dict @((N 1 % 1) ~ ((N 4) / (P 4)))-_testSlash_IntN4_Rat4N1 = Dict @((P 1 % 1) ~ ((N 4) / (N 4 % 1)))-_testSlash_IntN4_Rat3N1 = Dict @((P 4 % 3) ~ ((N 4) / (N 3 % 1)))-_testSlash_IntN4_Rat2N1 = Dict @((P 2 % 1) ~ ((N 4) / (N 2 % 1)))-_testSlash_IntN4_Rat3N2 = Dict @((P 8 % 3) ~ ((N 4) / (N 3 % 2)))-_testSlash_IntN4_Rat4N3 = Dict @((P 3 % 1) ~ ((N 4) / (N 4 % 3)))-_testSlash_IntN4_Rat1N1 = Dict @((P 4 % 1) ~ ((N 4) / (N 1 % 1)))-_testSlash_IntN4_Rat3N4 = Dict @((P 16 % 3) ~ ((N 4) / (N 3 % 4)))-_testSlash_IntN4_Rat2N3 = Dict @((P 6 % 1) ~ ((N 4) / (N 2 % 3)))-_testSlash_IntN4_Rat1N2 = Dict @((P 8 % 1) ~ ((N 4) / (N 1 % 2)))-_testSlash_IntN4_Rat1N3 = Dict @((P 12 % 1) ~ ((N 4) / (N 1 % 3)))-_testSlash_IntN4_Rat1N4 = Dict @((P 16 % 1) ~ ((N 4) / (N 1 % 4)))-_testSlash_IntN4_Rat1P4 = Dict @((N 16 % 1) ~ ((N 4) / (P 1 % 4)))-_testSlash_IntN4_Rat1P3 = Dict @((N 12 % 1) ~ ((N 4) / (P 1 % 3)))-_testSlash_IntN4_Rat1P2 = Dict @((N 8 % 1) ~ ((N 4) / (P 1 % 2)))-_testSlash_IntN4_Rat2P3 = Dict @((N 6 % 1) ~ ((N 4) / (P 2 % 3)))-_testSlash_IntN4_Rat3P4 = Dict @((N 16 % 3) ~ ((N 4) / (P 3 % 4)))-_testSlash_IntN4_Rat1P1 = Dict @((N 4 % 1) ~ ((N 4) / (P 1 % 1)))-_testSlash_IntN4_Rat4P3 = Dict @((N 3 % 1) ~ ((N 4) / (P 4 % 3)))-_testSlash_IntN4_Rat3P2 = Dict @((N 8 % 3) ~ ((N 4) / (P 3 % 2)))-_testSlash_IntN4_Rat2P1 = Dict @((N 2 % 1) ~ ((N 4) / (P 2 % 1)))-_testSlash_IntN4_Rat3P1 = Dict @((N 4 % 3) ~ ((N 4) / (P 3 % 1)))-_testSlash_IntN4_Rat4P1 = Dict @((N 1 % 1) ~ ((N 4) / (P 4 % 1)))-_testSlash_IntN3_Nat1 = Dict @((N 3 % 1) ~ ((N 3) / 1))-_testSlash_IntN3_Nat2 = Dict @((N 3 % 2) ~ ((N 3) / 2))-_testSlash_IntN3_Nat3 = Dict @((N 1 % 1) ~ ((N 3) / 3))-_testSlash_IntN3_Nat4 = Dict @((N 3 % 4) ~ ((N 3) / 4))-_testSlash_IntN3_IntN4 = Dict @((P 3 % 4) ~ ((N 3) / (N 4)))-_testSlash_IntN3_IntN3 = Dict @((P 1 % 1) ~ ((N 3) / (N 3)))-_testSlash_IntN3_IntN2 = Dict @((P 3 % 2) ~ ((N 3) / (N 2)))-_testSlash_IntN3_IntN1 = Dict @((P 3 % 1) ~ ((N 3) / (N 1)))-_testSlash_IntN3_IntP1 = Dict @((N 3 % 1) ~ ((N 3) / (P 1)))-_testSlash_IntN3_IntP2 = Dict @((N 3 % 2) ~ ((N 3) / (P 2)))-_testSlash_IntN3_IntP3 = Dict @((N 1 % 1) ~ ((N 3) / (P 3)))-_testSlash_IntN3_IntP4 = Dict @((N 3 % 4) ~ ((N 3) / (P 4)))-_testSlash_IntN3_Rat4N1 = Dict @((P 3 % 4) ~ ((N 3) / (N 4 % 1)))-_testSlash_IntN3_Rat3N1 = Dict @((P 1 % 1) ~ ((N 3) / (N 3 % 1)))-_testSlash_IntN3_Rat2N1 = Dict @((P 3 % 2) ~ ((N 3) / (N 2 % 1)))-_testSlash_IntN3_Rat3N2 = Dict @((P 2 % 1) ~ ((N 3) / (N 3 % 2)))-_testSlash_IntN3_Rat4N3 = Dict @((P 9 % 4) ~ ((N 3) / (N 4 % 3)))-_testSlash_IntN3_Rat1N1 = Dict @((P 3 % 1) ~ ((N 3) / (N 1 % 1)))-_testSlash_IntN3_Rat3N4 = Dict @((P 4 % 1) ~ ((N 3) / (N 3 % 4)))-_testSlash_IntN3_Rat2N3 = Dict @((P 9 % 2) ~ ((N 3) / (N 2 % 3)))-_testSlash_IntN3_Rat1N2 = Dict @((P 6 % 1) ~ ((N 3) / (N 1 % 2)))-_testSlash_IntN3_Rat1N3 = Dict @((P 9 % 1) ~ ((N 3) / (N 1 % 3)))-_testSlash_IntN3_Rat1N4 = Dict @((P 12 % 1) ~ ((N 3) / (N 1 % 4)))-_testSlash_IntN3_Rat1P4 = Dict @((N 12 % 1) ~ ((N 3) / (P 1 % 4)))-_testSlash_IntN3_Rat1P3 = Dict @((N 9 % 1) ~ ((N 3) / (P 1 % 3)))-_testSlash_IntN3_Rat1P2 = Dict @((N 6 % 1) ~ ((N 3) / (P 1 % 2)))-_testSlash_IntN3_Rat2P3 = Dict @((N 9 % 2) ~ ((N 3) / (P 2 % 3)))-_testSlash_IntN3_Rat3P4 = Dict @((N 4 % 1) ~ ((N 3) / (P 3 % 4)))-_testSlash_IntN3_Rat1P1 = Dict @((N 3 % 1) ~ ((N 3) / (P 1 % 1)))-_testSlash_IntN3_Rat4P3 = Dict @((N 9 % 4) ~ ((N 3) / (P 4 % 3)))-_testSlash_IntN3_Rat3P2 = Dict @((N 2 % 1) ~ ((N 3) / (P 3 % 2)))-_testSlash_IntN3_Rat2P1 = Dict @((N 3 % 2) ~ ((N 3) / (P 2 % 1)))-_testSlash_IntN3_Rat3P1 = Dict @((N 1 % 1) ~ ((N 3) / (P 3 % 1)))-_testSlash_IntN3_Rat4P1 = Dict @((N 3 % 4) ~ ((N 3) / (P 4 % 1)))-_testSlash_IntN2_Nat1 = Dict @((N 2 % 1) ~ ((N 2) / 1))-_testSlash_IntN2_Nat2 = Dict @((N 1 % 1) ~ ((N 2) / 2))-_testSlash_IntN2_Nat3 = Dict @((N 2 % 3) ~ ((N 2) / 3))-_testSlash_IntN2_Nat4 = Dict @((N 1 % 2) ~ ((N 2) / 4))-_testSlash_IntN2_IntN4 = Dict @((P 1 % 2) ~ ((N 2) / (N 4)))-_testSlash_IntN2_IntN3 = Dict @((P 2 % 3) ~ ((N 2) / (N 3)))-_testSlash_IntN2_IntN2 = Dict @((P 1 % 1) ~ ((N 2) / (N 2)))-_testSlash_IntN2_IntN1 = Dict @((P 2 % 1) ~ ((N 2) / (N 1)))-_testSlash_IntN2_IntP1 = Dict @((N 2 % 1) ~ ((N 2) / (P 1)))-_testSlash_IntN2_IntP2 = Dict @((N 1 % 1) ~ ((N 2) / (P 2)))-_testSlash_IntN2_IntP3 = Dict @((N 2 % 3) ~ ((N 2) / (P 3)))-_testSlash_IntN2_IntP4 = Dict @((N 1 % 2) ~ ((N 2) / (P 4)))-_testSlash_IntN2_Rat4N1 = Dict @((P 1 % 2) ~ ((N 2) / (N 4 % 1)))-_testSlash_IntN2_Rat3N1 = Dict @((P 2 % 3) ~ ((N 2) / (N 3 % 1)))-_testSlash_IntN2_Rat2N1 = Dict @((P 1 % 1) ~ ((N 2) / (N 2 % 1)))-_testSlash_IntN2_Rat3N2 = Dict @((P 4 % 3) ~ ((N 2) / (N 3 % 2)))-_testSlash_IntN2_Rat4N3 = Dict @((P 3 % 2) ~ ((N 2) / (N 4 % 3)))-_testSlash_IntN2_Rat1N1 = Dict @((P 2 % 1) ~ ((N 2) / (N 1 % 1)))-_testSlash_IntN2_Rat3N4 = Dict @((P 8 % 3) ~ ((N 2) / (N 3 % 4)))-_testSlash_IntN2_Rat2N3 = Dict @((P 3 % 1) ~ ((N 2) / (N 2 % 3)))-_testSlash_IntN2_Rat1N2 = Dict @((P 4 % 1) ~ ((N 2) / (N 1 % 2)))-_testSlash_IntN2_Rat1N3 = Dict @((P 6 % 1) ~ ((N 2) / (N 1 % 3)))-_testSlash_IntN2_Rat1N4 = Dict @((P 8 % 1) ~ ((N 2) / (N 1 % 4)))-_testSlash_IntN2_Rat1P4 = Dict @((N 8 % 1) ~ ((N 2) / (P 1 % 4)))-_testSlash_IntN2_Rat1P3 = Dict @((N 6 % 1) ~ ((N 2) / (P 1 % 3)))-_testSlash_IntN2_Rat1P2 = Dict @((N 4 % 1) ~ ((N 2) / (P 1 % 2)))-_testSlash_IntN2_Rat2P3 = Dict @((N 3 % 1) ~ ((N 2) / (P 2 % 3)))-_testSlash_IntN2_Rat3P4 = Dict @((N 8 % 3) ~ ((N 2) / (P 3 % 4)))-_testSlash_IntN2_Rat1P1 = Dict @((N 2 % 1) ~ ((N 2) / (P 1 % 1)))-_testSlash_IntN2_Rat4P3 = Dict @((N 3 % 2) ~ ((N 2) / (P 4 % 3)))-_testSlash_IntN2_Rat3P2 = Dict @((N 4 % 3) ~ ((N 2) / (P 3 % 2)))-_testSlash_IntN2_Rat2P1 = Dict @((N 1 % 1) ~ ((N 2) / (P 2 % 1)))-_testSlash_IntN2_Rat3P1 = Dict @((N 2 % 3) ~ ((N 2) / (P 3 % 1)))-_testSlash_IntN2_Rat4P1 = Dict @((N 1 % 2) ~ ((N 2) / (P 4 % 1)))-_testSlash_IntN1_Nat1 = Dict @((N 1 % 1) ~ ((N 1) / 1))-_testSlash_IntN1_Nat2 = Dict @((N 1 % 2) ~ ((N 1) / 2))-_testSlash_IntN1_Nat3 = Dict @((N 1 % 3) ~ ((N 1) / 3))-_testSlash_IntN1_Nat4 = Dict @((N 1 % 4) ~ ((N 1) / 4))-_testSlash_IntN1_IntN4 = Dict @((P 1 % 4) ~ ((N 1) / (N 4)))-_testSlash_IntN1_IntN3 = Dict @((P 1 % 3) ~ ((N 1) / (N 3)))-_testSlash_IntN1_IntN2 = Dict @((P 1 % 2) ~ ((N 1) / (N 2)))-_testSlash_IntN1_IntN1 = Dict @((P 1 % 1) ~ ((N 1) / (N 1)))-_testSlash_IntN1_IntP1 = Dict @((N 1 % 1) ~ ((N 1) / (P 1)))-_testSlash_IntN1_IntP2 = Dict @((N 1 % 2) ~ ((N 1) / (P 2)))-_testSlash_IntN1_IntP3 = Dict @((N 1 % 3) ~ ((N 1) / (P 3)))-_testSlash_IntN1_IntP4 = Dict @((N 1 % 4) ~ ((N 1) / (P 4)))-_testSlash_IntN1_Rat4N1 = Dict @((P 1 % 4) ~ ((N 1) / (N 4 % 1)))-_testSlash_IntN1_Rat3N1 = Dict @((P 1 % 3) ~ ((N 1) / (N 3 % 1)))-_testSlash_IntN1_Rat2N1 = Dict @((P 1 % 2) ~ ((N 1) / (N 2 % 1)))-_testSlash_IntN1_Rat3N2 = Dict @((P 2 % 3) ~ ((N 1) / (N 3 % 2)))-_testSlash_IntN1_Rat4N3 = Dict @((P 3 % 4) ~ ((N 1) / (N 4 % 3)))-_testSlash_IntN1_Rat1N1 = Dict @((P 1 % 1) ~ ((N 1) / (N 1 % 1)))-_testSlash_IntN1_Rat3N4 = Dict @((P 4 % 3) ~ ((N 1) / (N 3 % 4)))-_testSlash_IntN1_Rat2N3 = Dict @((P 3 % 2) ~ ((N 1) / (N 2 % 3)))-_testSlash_IntN1_Rat1N2 = Dict @((P 2 % 1) ~ ((N 1) / (N 1 % 2)))-_testSlash_IntN1_Rat1N3 = Dict @((P 3 % 1) ~ ((N 1) / (N 1 % 3)))-_testSlash_IntN1_Rat1N4 = Dict @((P 4 % 1) ~ ((N 1) / (N 1 % 4)))-_testSlash_IntN1_Rat1P4 = Dict @((N 4 % 1) ~ ((N 1) / (P 1 % 4)))-_testSlash_IntN1_Rat1P3 = Dict @((N 3 % 1) ~ ((N 1) / (P 1 % 3)))-_testSlash_IntN1_Rat1P2 = Dict @((N 2 % 1) ~ ((N 1) / (P 1 % 2)))-_testSlash_IntN1_Rat2P3 = Dict @((N 3 % 2) ~ ((N 1) / (P 2 % 3)))-_testSlash_IntN1_Rat3P4 = Dict @((N 4 % 3) ~ ((N 1) / (P 3 % 4)))-_testSlash_IntN1_Rat1P1 = Dict @((N 1 % 1) ~ ((N 1) / (P 1 % 1)))-_testSlash_IntN1_Rat4P3 = Dict @((N 3 % 4) ~ ((N 1) / (P 4 % 3)))-_testSlash_IntN1_Rat3P2 = Dict @((N 2 % 3) ~ ((N 1) / (P 3 % 2)))-_testSlash_IntN1_Rat2P1 = Dict @((N 1 % 2) ~ ((N 1) / (P 2 % 1)))-_testSlash_IntN1_Rat3P1 = Dict @((N 1 % 3) ~ ((N 1) / (P 3 % 1)))-_testSlash_IntN1_Rat4P1 = Dict @((N 1 % 4) ~ ((N 1) / (P 4 % 1)))-_testSlash_IntP0_Nat1 = Dict @((P 0 % 1) ~ ((P 0) / 1))-_testSlash_IntP0_Nat2 = Dict @((P 0 % 1) ~ ((P 0) / 2))-_testSlash_IntP0_Nat3 = Dict @((P 0 % 1) ~ ((P 0) / 3))-_testSlash_IntP0_Nat4 = Dict @((P 0 % 1) ~ ((P 0) / 4))-_testSlash_IntP0_IntN4 = Dict @((P 0 % 1) ~ ((P 0) / (N 4)))-_testSlash_IntP0_IntN3 = Dict @((P 0 % 1) ~ ((P 0) / (N 3)))-_testSlash_IntP0_IntN2 = Dict @((P 0 % 1) ~ ((P 0) / (N 2)))-_testSlash_IntP0_IntN1 = Dict @((P 0 % 1) ~ ((P 0) / (N 1)))-_testSlash_IntP0_IntP1 = Dict @((P 0 % 1) ~ ((P 0) / (P 1)))-_testSlash_IntP0_IntP2 = Dict @((P 0 % 1) ~ ((P 0) / (P 2)))-_testSlash_IntP0_IntP3 = Dict @((P 0 % 1) ~ ((P 0) / (P 3)))-_testSlash_IntP0_IntP4 = Dict @((P 0 % 1) ~ ((P 0) / (P 4)))-_testSlash_IntP0_Rat4N1 = Dict @((P 0 % 1) ~ ((P 0) / (N 4 % 1)))-_testSlash_IntP0_Rat3N1 = Dict @((P 0 % 1) ~ ((P 0) / (N 3 % 1)))-_testSlash_IntP0_Rat2N1 = Dict @((P 0 % 1) ~ ((P 0) / (N 2 % 1)))-_testSlash_IntP0_Rat3N2 = Dict @((P 0 % 1) ~ ((P 0) / (N 3 % 2)))-_testSlash_IntP0_Rat4N3 = Dict @((P 0 % 1) ~ ((P 0) / (N 4 % 3)))-_testSlash_IntP0_Rat1N1 = Dict @((P 0 % 1) ~ ((P 0) / (N 1 % 1)))-_testSlash_IntP0_Rat3N4 = Dict @((P 0 % 1) ~ ((P 0) / (N 3 % 4)))-_testSlash_IntP0_Rat2N3 = Dict @((P 0 % 1) ~ ((P 0) / (N 2 % 3)))-_testSlash_IntP0_Rat1N2 = Dict @((P 0 % 1) ~ ((P 0) / (N 1 % 2)))-_testSlash_IntP0_Rat1N3 = Dict @((P 0 % 1) ~ ((P 0) / (N 1 % 3)))-_testSlash_IntP0_Rat1N4 = Dict @((P 0 % 1) ~ ((P 0) / (N 1 % 4)))-_testSlash_IntP0_Rat1P4 = Dict @((P 0 % 1) ~ ((P 0) / (P 1 % 4)))-_testSlash_IntP0_Rat1P3 = Dict @((P 0 % 1) ~ ((P 0) / (P 1 % 3)))-_testSlash_IntP0_Rat1P2 = Dict @((P 0 % 1) ~ ((P 0) / (P 1 % 2)))-_testSlash_IntP0_Rat2P3 = Dict @((P 0 % 1) ~ ((P 0) / (P 2 % 3)))-_testSlash_IntP0_Rat3P4 = Dict @((P 0 % 1) ~ ((P 0) / (P 3 % 4)))-_testSlash_IntP0_Rat1P1 = Dict @((P 0 % 1) ~ ((P 0) / (P 1 % 1)))-_testSlash_IntP0_Rat4P3 = Dict @((P 0 % 1) ~ ((P 0) / (P 4 % 3)))-_testSlash_IntP0_Rat3P2 = Dict @((P 0 % 1) ~ ((P 0) / (P 3 % 2)))-_testSlash_IntP0_Rat2P1 = Dict @((P 0 % 1) ~ ((P 0) / (P 2 % 1)))-_testSlash_IntP0_Rat3P1 = Dict @((P 0 % 1) ~ ((P 0) / (P 3 % 1)))-_testSlash_IntP0_Rat4P1 = Dict @((P 0 % 1) ~ ((P 0) / (P 4 % 1)))-_testSlash_IntP1_Nat1 = Dict @((P 1 % 1) ~ ((P 1) / 1))-_testSlash_IntP1_Nat2 = Dict @((P 1 % 2) ~ ((P 1) / 2))-_testSlash_IntP1_Nat3 = Dict @((P 1 % 3) ~ ((P 1) / 3))-_testSlash_IntP1_Nat4 = Dict @((P 1 % 4) ~ ((P 1) / 4))-_testSlash_IntP1_IntN4 = Dict @((N 1 % 4) ~ ((P 1) / (N 4)))-_testSlash_IntP1_IntN3 = Dict @((N 1 % 3) ~ ((P 1) / (N 3)))-_testSlash_IntP1_IntN2 = Dict @((N 1 % 2) ~ ((P 1) / (N 2)))-_testSlash_IntP1_IntN1 = Dict @((N 1 % 1) ~ ((P 1) / (N 1)))-_testSlash_IntP1_IntP1 = Dict @((P 1 % 1) ~ ((P 1) / (P 1)))-_testSlash_IntP1_IntP2 = Dict @((P 1 % 2) ~ ((P 1) / (P 2)))-_testSlash_IntP1_IntP3 = Dict @((P 1 % 3) ~ ((P 1) / (P 3)))-_testSlash_IntP1_IntP4 = Dict @((P 1 % 4) ~ ((P 1) / (P 4)))-_testSlash_IntP1_Rat4N1 = Dict @((N 1 % 4) ~ ((P 1) / (N 4 % 1)))-_testSlash_IntP1_Rat3N1 = Dict @((N 1 % 3) ~ ((P 1) / (N 3 % 1)))-_testSlash_IntP1_Rat2N1 = Dict @((N 1 % 2) ~ ((P 1) / (N 2 % 1)))-_testSlash_IntP1_Rat3N2 = Dict @((N 2 % 3) ~ ((P 1) / (N 3 % 2)))-_testSlash_IntP1_Rat4N3 = Dict @((N 3 % 4) ~ ((P 1) / (N 4 % 3)))-_testSlash_IntP1_Rat1N1 = Dict @((N 1 % 1) ~ ((P 1) / (N 1 % 1)))-_testSlash_IntP1_Rat3N4 = Dict @((N 4 % 3) ~ ((P 1) / (N 3 % 4)))-_testSlash_IntP1_Rat2N3 = Dict @((N 3 % 2) ~ ((P 1) / (N 2 % 3)))-_testSlash_IntP1_Rat1N2 = Dict @((N 2 % 1) ~ ((P 1) / (N 1 % 2)))-_testSlash_IntP1_Rat1N3 = Dict @((N 3 % 1) ~ ((P 1) / (N 1 % 3)))-_testSlash_IntP1_Rat1N4 = Dict @((N 4 % 1) ~ ((P 1) / (N 1 % 4)))-_testSlash_IntP1_Rat1P4 = Dict @((P 4 % 1) ~ ((P 1) / (P 1 % 4)))-_testSlash_IntP1_Rat1P3 = Dict @((P 3 % 1) ~ ((P 1) / (P 1 % 3)))-_testSlash_IntP1_Rat1P2 = Dict @((P 2 % 1) ~ ((P 1) / (P 1 % 2)))-_testSlash_IntP1_Rat2P3 = Dict @((P 3 % 2) ~ ((P 1) / (P 2 % 3)))-_testSlash_IntP1_Rat3P4 = Dict @((P 4 % 3) ~ ((P 1) / (P 3 % 4)))-_testSlash_IntP1_Rat1P1 = Dict @((P 1 % 1) ~ ((P 1) / (P 1 % 1)))-_testSlash_IntP1_Rat4P3 = Dict @((P 3 % 4) ~ ((P 1) / (P 4 % 3)))-_testSlash_IntP1_Rat3P2 = Dict @((P 2 % 3) ~ ((P 1) / (P 3 % 2)))-_testSlash_IntP1_Rat2P1 = Dict @((P 1 % 2) ~ ((P 1) / (P 2 % 1)))-_testSlash_IntP1_Rat3P1 = Dict @((P 1 % 3) ~ ((P 1) / (P 3 % 1)))-_testSlash_IntP1_Rat4P1 = Dict @((P 1 % 4) ~ ((P 1) / (P 4 % 1)))-_testSlash_IntP2_Nat1 = Dict @((P 2 % 1) ~ ((P 2) / 1))-_testSlash_IntP2_Nat2 = Dict @((P 1 % 1) ~ ((P 2) / 2))-_testSlash_IntP2_Nat3 = Dict @((P 2 % 3) ~ ((P 2) / 3))-_testSlash_IntP2_Nat4 = Dict @((P 1 % 2) ~ ((P 2) / 4))-_testSlash_IntP2_IntN4 = Dict @((N 1 % 2) ~ ((P 2) / (N 4)))-_testSlash_IntP2_IntN3 = Dict @((N 2 % 3) ~ ((P 2) / (N 3)))-_testSlash_IntP2_IntN2 = Dict @((N 1 % 1) ~ ((P 2) / (N 2)))-_testSlash_IntP2_IntN1 = Dict @((N 2 % 1) ~ ((P 2) / (N 1)))-_testSlash_IntP2_IntP1 = Dict @((P 2 % 1) ~ ((P 2) / (P 1)))-_testSlash_IntP2_IntP2 = Dict @((P 1 % 1) ~ ((P 2) / (P 2)))-_testSlash_IntP2_IntP3 = Dict @((P 2 % 3) ~ ((P 2) / (P 3)))-_testSlash_IntP2_IntP4 = Dict @((P 1 % 2) ~ ((P 2) / (P 4)))-_testSlash_IntP2_Rat4N1 = Dict @((N 1 % 2) ~ ((P 2) / (N 4 % 1)))-_testSlash_IntP2_Rat3N1 = Dict @((N 2 % 3) ~ ((P 2) / (N 3 % 1)))-_testSlash_IntP2_Rat2N1 = Dict @((N 1 % 1) ~ ((P 2) / (N 2 % 1)))-_testSlash_IntP2_Rat3N2 = Dict @((N 4 % 3) ~ ((P 2) / (N 3 % 2)))-_testSlash_IntP2_Rat4N3 = Dict @((N 3 % 2) ~ ((P 2) / (N 4 % 3)))-_testSlash_IntP2_Rat1N1 = Dict @((N 2 % 1) ~ ((P 2) / (N 1 % 1)))-_testSlash_IntP2_Rat3N4 = Dict @((N 8 % 3) ~ ((P 2) / (N 3 % 4)))-_testSlash_IntP2_Rat2N3 = Dict @((N 3 % 1) ~ ((P 2) / (N 2 % 3)))-_testSlash_IntP2_Rat1N2 = Dict @((N 4 % 1) ~ ((P 2) / (N 1 % 2)))-_testSlash_IntP2_Rat1N3 = Dict @((N 6 % 1) ~ ((P 2) / (N 1 % 3)))-_testSlash_IntP2_Rat1N4 = Dict @((N 8 % 1) ~ ((P 2) / (N 1 % 4)))-_testSlash_IntP2_Rat1P4 = Dict @((P 8 % 1) ~ ((P 2) / (P 1 % 4)))-_testSlash_IntP2_Rat1P3 = Dict @((P 6 % 1) ~ ((P 2) / (P 1 % 3)))-_testSlash_IntP2_Rat1P2 = Dict @((P 4 % 1) ~ ((P 2) / (P 1 % 2)))-_testSlash_IntP2_Rat2P3 = Dict @((P 3 % 1) ~ ((P 2) / (P 2 % 3)))-_testSlash_IntP2_Rat3P4 = Dict @((P 8 % 3) ~ ((P 2) / (P 3 % 4)))-_testSlash_IntP2_Rat1P1 = Dict @((P 2 % 1) ~ ((P 2) / (P 1 % 1)))-_testSlash_IntP2_Rat4P3 = Dict @((P 3 % 2) ~ ((P 2) / (P 4 % 3)))-_testSlash_IntP2_Rat3P2 = Dict @((P 4 % 3) ~ ((P 2) / (P 3 % 2)))-_testSlash_IntP2_Rat2P1 = Dict @((P 1 % 1) ~ ((P 2) / (P 2 % 1)))-_testSlash_IntP2_Rat3P1 = Dict @((P 2 % 3) ~ ((P 2) / (P 3 % 1)))-_testSlash_IntP2_Rat4P1 = Dict @((P 1 % 2) ~ ((P 2) / (P 4 % 1)))-_testSlash_IntP3_Nat1 = Dict @((P 3 % 1) ~ ((P 3) / 1))-_testSlash_IntP3_Nat2 = Dict @((P 3 % 2) ~ ((P 3) / 2))-_testSlash_IntP3_Nat3 = Dict @((P 1 % 1) ~ ((P 3) / 3))-_testSlash_IntP3_Nat4 = Dict @((P 3 % 4) ~ ((P 3) / 4))-_testSlash_IntP3_IntN4 = Dict @((N 3 % 4) ~ ((P 3) / (N 4)))-_testSlash_IntP3_IntN3 = Dict @((N 1 % 1) ~ ((P 3) / (N 3)))-_testSlash_IntP3_IntN2 = Dict @((N 3 % 2) ~ ((P 3) / (N 2)))-_testSlash_IntP3_IntN1 = Dict @((N 3 % 1) ~ ((P 3) / (N 1)))-_testSlash_IntP3_IntP1 = Dict @((P 3 % 1) ~ ((P 3) / (P 1)))-_testSlash_IntP3_IntP2 = Dict @((P 3 % 2) ~ ((P 3) / (P 2)))-_testSlash_IntP3_IntP3 = Dict @((P 1 % 1) ~ ((P 3) / (P 3)))-_testSlash_IntP3_IntP4 = Dict @((P 3 % 4) ~ ((P 3) / (P 4)))-_testSlash_IntP3_Rat4N1 = Dict @((N 3 % 4) ~ ((P 3) / (N 4 % 1)))-_testSlash_IntP3_Rat3N1 = Dict @((N 1 % 1) ~ ((P 3) / (N 3 % 1)))-_testSlash_IntP3_Rat2N1 = Dict @((N 3 % 2) ~ ((P 3) / (N 2 % 1)))-_testSlash_IntP3_Rat3N2 = Dict @((N 2 % 1) ~ ((P 3) / (N 3 % 2)))-_testSlash_IntP3_Rat4N3 = Dict @((N 9 % 4) ~ ((P 3) / (N 4 % 3)))-_testSlash_IntP3_Rat1N1 = Dict @((N 3 % 1) ~ ((P 3) / (N 1 % 1)))-_testSlash_IntP3_Rat3N4 = Dict @((N 4 % 1) ~ ((P 3) / (N 3 % 4)))-_testSlash_IntP3_Rat2N3 = Dict @((N 9 % 2) ~ ((P 3) / (N 2 % 3)))-_testSlash_IntP3_Rat1N2 = Dict @((N 6 % 1) ~ ((P 3) / (N 1 % 2)))-_testSlash_IntP3_Rat1N3 = Dict @((N 9 % 1) ~ ((P 3) / (N 1 % 3)))-_testSlash_IntP3_Rat1N4 = Dict @((N 12 % 1) ~ ((P 3) / (N 1 % 4)))-_testSlash_IntP3_Rat1P4 = Dict @((P 12 % 1) ~ ((P 3) / (P 1 % 4)))-_testSlash_IntP3_Rat1P3 = Dict @((P 9 % 1) ~ ((P 3) / (P 1 % 3)))-_testSlash_IntP3_Rat1P2 = Dict @((P 6 % 1) ~ ((P 3) / (P 1 % 2)))-_testSlash_IntP3_Rat2P3 = Dict @((P 9 % 2) ~ ((P 3) / (P 2 % 3)))-_testSlash_IntP3_Rat3P4 = Dict @((P 4 % 1) ~ ((P 3) / (P 3 % 4)))-_testSlash_IntP3_Rat1P1 = Dict @((P 3 % 1) ~ ((P 3) / (P 1 % 1)))-_testSlash_IntP3_Rat4P3 = Dict @((P 9 % 4) ~ ((P 3) / (P 4 % 3)))-_testSlash_IntP3_Rat3P2 = Dict @((P 2 % 1) ~ ((P 3) / (P 3 % 2)))-_testSlash_IntP3_Rat2P1 = Dict @((P 3 % 2) ~ ((P 3) / (P 2 % 1)))-_testSlash_IntP3_Rat3P1 = Dict @((P 1 % 1) ~ ((P 3) / (P 3 % 1)))-_testSlash_IntP3_Rat4P1 = Dict @((P 3 % 4) ~ ((P 3) / (P 4 % 1)))-_testSlash_IntP4_Nat1 = Dict @((P 4 % 1) ~ ((P 4) / 1))-_testSlash_IntP4_Nat2 = Dict @((P 2 % 1) ~ ((P 4) / 2))-_testSlash_IntP4_Nat3 = Dict @((P 4 % 3) ~ ((P 4) / 3))-_testSlash_IntP4_Nat4 = Dict @((P 1 % 1) ~ ((P 4) / 4))-_testSlash_IntP4_IntN4 = Dict @((N 1 % 1) ~ ((P 4) / (N 4)))-_testSlash_IntP4_IntN3 = Dict @((N 4 % 3) ~ ((P 4) / (N 3)))-_testSlash_IntP4_IntN2 = Dict @((N 2 % 1) ~ ((P 4) / (N 2)))-_testSlash_IntP4_IntN1 = Dict @((N 4 % 1) ~ ((P 4) / (N 1)))-_testSlash_IntP4_IntP1 = Dict @((P 4 % 1) ~ ((P 4) / (P 1)))-_testSlash_IntP4_IntP2 = Dict @((P 2 % 1) ~ ((P 4) / (P 2)))-_testSlash_IntP4_IntP3 = Dict @((P 4 % 3) ~ ((P 4) / (P 3)))-_testSlash_IntP4_IntP4 = Dict @((P 1 % 1) ~ ((P 4) / (P 4)))-_testSlash_IntP4_Rat4N1 = Dict @((N 1 % 1) ~ ((P 4) / (N 4 % 1)))-_testSlash_IntP4_Rat3N1 = Dict @((N 4 % 3) ~ ((P 4) / (N 3 % 1)))-_testSlash_IntP4_Rat2N1 = Dict @((N 2 % 1) ~ ((P 4) / (N 2 % 1)))-_testSlash_IntP4_Rat3N2 = Dict @((N 8 % 3) ~ ((P 4) / (N 3 % 2)))-_testSlash_IntP4_Rat4N3 = Dict @((N 3 % 1) ~ ((P 4) / (N 4 % 3)))-_testSlash_IntP4_Rat1N1 = Dict @((N 4 % 1) ~ ((P 4) / (N 1 % 1)))-_testSlash_IntP4_Rat3N4 = Dict @((N 16 % 3) ~ ((P 4) / (N 3 % 4)))-_testSlash_IntP4_Rat2N3 = Dict @((N 6 % 1) ~ ((P 4) / (N 2 % 3)))-_testSlash_IntP4_Rat1N2 = Dict @((N 8 % 1) ~ ((P 4) / (N 1 % 2)))-_testSlash_IntP4_Rat1N3 = Dict @((N 12 % 1) ~ ((P 4) / (N 1 % 3)))-_testSlash_IntP4_Rat1N4 = Dict @((N 16 % 1) ~ ((P 4) / (N 1 % 4)))-_testSlash_IntP4_Rat1P4 = Dict @((P 16 % 1) ~ ((P 4) / (P 1 % 4)))-_testSlash_IntP4_Rat1P3 = Dict @((P 12 % 1) ~ ((P 4) / (P 1 % 3)))-_testSlash_IntP4_Rat1P2 = Dict @((P 8 % 1) ~ ((P 4) / (P 1 % 2)))-_testSlash_IntP4_Rat2P3 = Dict @((P 6 % 1) ~ ((P 4) / (P 2 % 3)))-_testSlash_IntP4_Rat3P4 = Dict @((P 16 % 3) ~ ((P 4) / (P 3 % 4)))-_testSlash_IntP4_Rat1P1 = Dict @((P 4 % 1) ~ ((P 4) / (P 1 % 1)))-_testSlash_IntP4_Rat4P3 = Dict @((P 3 % 1) ~ ((P 4) / (P 4 % 3)))-_testSlash_IntP4_Rat3P2 = Dict @((P 8 % 3) ~ ((P 4) / (P 3 % 2)))-_testSlash_IntP4_Rat2P1 = Dict @((P 2 % 1) ~ ((P 4) / (P 2 % 1)))-_testSlash_IntP4_Rat3P1 = Dict @((P 4 % 3) ~ ((P 4) / (P 3 % 1)))-_testSlash_IntP4_Rat4P1 = Dict @((P 1 % 1) ~ ((P 4) / (P 4 % 1)))-_testSlash_Rat4N1_Nat1 = Dict @((N 4 % 1) ~ ((N 4 % 1) / 1))-_testSlash_Rat4N1_Nat2 = Dict @((N 2 % 1) ~ ((N 4 % 1) / 2))-_testSlash_Rat4N1_Nat3 = Dict @((N 4 % 3) ~ ((N 4 % 1) / 3))-_testSlash_Rat4N1_Nat4 = Dict @((N 1 % 1) ~ ((N 4 % 1) / 4))-_testSlash_Rat4N1_IntN4 = Dict @((P 1 % 1) ~ ((N 4 % 1) / (N 4)))-_testSlash_Rat4N1_IntN3 = Dict @((P 4 % 3) ~ ((N 4 % 1) / (N 3)))-_testSlash_Rat4N1_IntN2 = Dict @((P 2 % 1) ~ ((N 4 % 1) / (N 2)))-_testSlash_Rat4N1_IntN1 = Dict @((P 4 % 1) ~ ((N 4 % 1) / (N 1)))-_testSlash_Rat4N1_IntP1 = Dict @((N 4 % 1) ~ ((N 4 % 1) / (P 1)))-_testSlash_Rat4N1_IntP2 = Dict @((N 2 % 1) ~ ((N 4 % 1) / (P 2)))-_testSlash_Rat4N1_IntP3 = Dict @((N 4 % 3) ~ ((N 4 % 1) / (P 3)))-_testSlash_Rat4N1_IntP4 = Dict @((N 1 % 1) ~ ((N 4 % 1) / (P 4)))-_testSlash_Rat4N1_Rat4N1 = Dict @((P 1 % 1) ~ ((N 4 % 1) / (N 4 % 1)))-_testSlash_Rat4N1_Rat3N1 = Dict @((P 4 % 3) ~ ((N 4 % 1) / (N 3 % 1)))-_testSlash_Rat4N1_Rat2N1 = Dict @((P 2 % 1) ~ ((N 4 % 1) / (N 2 % 1)))-_testSlash_Rat4N1_Rat3N2 = Dict @((P 8 % 3) ~ ((N 4 % 1) / (N 3 % 2)))-_testSlash_Rat4N1_Rat4N3 = Dict @((P 3 % 1) ~ ((N 4 % 1) / (N 4 % 3)))-_testSlash_Rat4N1_Rat1N1 = Dict @((P 4 % 1) ~ ((N 4 % 1) / (N 1 % 1)))-_testSlash_Rat4N1_Rat3N4 = Dict @((P 16 % 3) ~ ((N 4 % 1) / (N 3 % 4)))-_testSlash_Rat4N1_Rat2N3 = Dict @((P 6 % 1) ~ ((N 4 % 1) / (N 2 % 3)))-_testSlash_Rat4N1_Rat1N2 = Dict @((P 8 % 1) ~ ((N 4 % 1) / (N 1 % 2)))-_testSlash_Rat4N1_Rat1N3 = Dict @((P 12 % 1) ~ ((N 4 % 1) / (N 1 % 3)))-_testSlash_Rat4N1_Rat1N4 = Dict @((P 16 % 1) ~ ((N 4 % 1) / (N 1 % 4)))-_testSlash_Rat4N1_Rat1P4 = Dict @((N 16 % 1) ~ ((N 4 % 1) / (P 1 % 4)))-_testSlash_Rat4N1_Rat1P3 = Dict @((N 12 % 1) ~ ((N 4 % 1) / (P 1 % 3)))-_testSlash_Rat4N1_Rat1P2 = Dict @((N 8 % 1) ~ ((N 4 % 1) / (P 1 % 2)))-_testSlash_Rat4N1_Rat2P3 = Dict @((N 6 % 1) ~ ((N 4 % 1) / (P 2 % 3)))-_testSlash_Rat4N1_Rat3P4 = Dict @((N 16 % 3) ~ ((N 4 % 1) / (P 3 % 4)))-_testSlash_Rat4N1_Rat1P1 = Dict @((N 4 % 1) ~ ((N 4 % 1) / (P 1 % 1)))-_testSlash_Rat4N1_Rat4P3 = Dict @((N 3 % 1) ~ ((N 4 % 1) / (P 4 % 3)))-_testSlash_Rat4N1_Rat3P2 = Dict @((N 8 % 3) ~ ((N 4 % 1) / (P 3 % 2)))-_testSlash_Rat4N1_Rat2P1 = Dict @((N 2 % 1) ~ ((N 4 % 1) / (P 2 % 1)))-_testSlash_Rat4N1_Rat3P1 = Dict @((N 4 % 3) ~ ((N 4 % 1) / (P 3 % 1)))-_testSlash_Rat4N1_Rat4P1 = Dict @((N 1 % 1) ~ ((N 4 % 1) / (P 4 % 1)))-_testSlash_Rat3N1_Nat1 = Dict @((N 3 % 1) ~ ((N 3 % 1) / 1))-_testSlash_Rat3N1_Nat2 = Dict @((N 3 % 2) ~ ((N 3 % 1) / 2))-_testSlash_Rat3N1_Nat3 = Dict @((N 1 % 1) ~ ((N 3 % 1) / 3))-_testSlash_Rat3N1_Nat4 = Dict @((N 3 % 4) ~ ((N 3 % 1) / 4))-_testSlash_Rat3N1_IntN4 = Dict @((P 3 % 4) ~ ((N 3 % 1) / (N 4)))-_testSlash_Rat3N1_IntN3 = Dict @((P 1 % 1) ~ ((N 3 % 1) / (N 3)))-_testSlash_Rat3N1_IntN2 = Dict @((P 3 % 2) ~ ((N 3 % 1) / (N 2)))-_testSlash_Rat3N1_IntN1 = Dict @((P 3 % 1) ~ ((N 3 % 1) / (N 1)))-_testSlash_Rat3N1_IntP1 = Dict @((N 3 % 1) ~ ((N 3 % 1) / (P 1)))-_testSlash_Rat3N1_IntP2 = Dict @((N 3 % 2) ~ ((N 3 % 1) / (P 2)))-_testSlash_Rat3N1_IntP3 = Dict @((N 1 % 1) ~ ((N 3 % 1) / (P 3)))-_testSlash_Rat3N1_IntP4 = Dict @((N 3 % 4) ~ ((N 3 % 1) / (P 4)))-_testSlash_Rat3N1_Rat4N1 = Dict @((P 3 % 4) ~ ((N 3 % 1) / (N 4 % 1)))-_testSlash_Rat3N1_Rat3N1 = Dict @((P 1 % 1) ~ ((N 3 % 1) / (N 3 % 1)))-_testSlash_Rat3N1_Rat2N1 = Dict @((P 3 % 2) ~ ((N 3 % 1) / (N 2 % 1)))-_testSlash_Rat3N1_Rat3N2 = Dict @((P 2 % 1) ~ ((N 3 % 1) / (N 3 % 2)))-_testSlash_Rat3N1_Rat4N3 = Dict @((P 9 % 4) ~ ((N 3 % 1) / (N 4 % 3)))-_testSlash_Rat3N1_Rat1N1 = Dict @((P 3 % 1) ~ ((N 3 % 1) / (N 1 % 1)))-_testSlash_Rat3N1_Rat3N4 = Dict @((P 4 % 1) ~ ((N 3 % 1) / (N 3 % 4)))-_testSlash_Rat3N1_Rat2N3 = Dict @((P 9 % 2) ~ ((N 3 % 1) / (N 2 % 3)))-_testSlash_Rat3N1_Rat1N2 = Dict @((P 6 % 1) ~ ((N 3 % 1) / (N 1 % 2)))-_testSlash_Rat3N1_Rat1N3 = Dict @((P 9 % 1) ~ ((N 3 % 1) / (N 1 % 3)))-_testSlash_Rat3N1_Rat1N4 = Dict @((P 12 % 1) ~ ((N 3 % 1) / (N 1 % 4)))-_testSlash_Rat3N1_Rat1P4 = Dict @((N 12 % 1) ~ ((N 3 % 1) / (P 1 % 4)))-_testSlash_Rat3N1_Rat1P3 = Dict @((N 9 % 1) ~ ((N 3 % 1) / (P 1 % 3)))-_testSlash_Rat3N1_Rat1P2 = Dict @((N 6 % 1) ~ ((N 3 % 1) / (P 1 % 2)))-_testSlash_Rat3N1_Rat2P3 = Dict @((N 9 % 2) ~ ((N 3 % 1) / (P 2 % 3)))-_testSlash_Rat3N1_Rat3P4 = Dict @((N 4 % 1) ~ ((N 3 % 1) / (P 3 % 4)))-_testSlash_Rat3N1_Rat1P1 = Dict @((N 3 % 1) ~ ((N 3 % 1) / (P 1 % 1)))-_testSlash_Rat3N1_Rat4P3 = Dict @((N 9 % 4) ~ ((N 3 % 1) / (P 4 % 3)))-_testSlash_Rat3N1_Rat3P2 = Dict @((N 2 % 1) ~ ((N 3 % 1) / (P 3 % 2)))-_testSlash_Rat3N1_Rat2P1 = Dict @((N 3 % 2) ~ ((N 3 % 1) / (P 2 % 1)))-_testSlash_Rat3N1_Rat3P1 = Dict @((N 1 % 1) ~ ((N 3 % 1) / (P 3 % 1)))-_testSlash_Rat3N1_Rat4P1 = Dict @((N 3 % 4) ~ ((N 3 % 1) / (P 4 % 1)))-_testSlash_Rat2N1_Nat1 = Dict @((N 2 % 1) ~ ((N 2 % 1) / 1))-_testSlash_Rat2N1_Nat2 = Dict @((N 1 % 1) ~ ((N 2 % 1) / 2))-_testSlash_Rat2N1_Nat3 = Dict @((N 2 % 3) ~ ((N 2 % 1) / 3))-_testSlash_Rat2N1_Nat4 = Dict @((N 1 % 2) ~ ((N 2 % 1) / 4))-_testSlash_Rat2N1_IntN4 = Dict @((P 1 % 2) ~ ((N 2 % 1) / (N 4)))-_testSlash_Rat2N1_IntN3 = Dict @((P 2 % 3) ~ ((N 2 % 1) / (N 3)))-_testSlash_Rat2N1_IntN2 = Dict @((P 1 % 1) ~ ((N 2 % 1) / (N 2)))-_testSlash_Rat2N1_IntN1 = Dict @((P 2 % 1) ~ ((N 2 % 1) / (N 1)))-_testSlash_Rat2N1_IntP1 = Dict @((N 2 % 1) ~ ((N 2 % 1) / (P 1)))-_testSlash_Rat2N1_IntP2 = Dict @((N 1 % 1) ~ ((N 2 % 1) / (P 2)))-_testSlash_Rat2N1_IntP3 = Dict @((N 2 % 3) ~ ((N 2 % 1) / (P 3)))-_testSlash_Rat2N1_IntP4 = Dict @((N 1 % 2) ~ ((N 2 % 1) / (P 4)))-_testSlash_Rat2N1_Rat4N1 = Dict @((P 1 % 2) ~ ((N 2 % 1) / (N 4 % 1)))-_testSlash_Rat2N1_Rat3N1 = Dict @((P 2 % 3) ~ ((N 2 % 1) / (N 3 % 1)))-_testSlash_Rat2N1_Rat2N1 = Dict @((P 1 % 1) ~ ((N 2 % 1) / (N 2 % 1)))-_testSlash_Rat2N1_Rat3N2 = Dict @((P 4 % 3) ~ ((N 2 % 1) / (N 3 % 2)))-_testSlash_Rat2N1_Rat4N3 = Dict @((P 3 % 2) ~ ((N 2 % 1) / (N 4 % 3)))-_testSlash_Rat2N1_Rat1N1 = Dict @((P 2 % 1) ~ ((N 2 % 1) / (N 1 % 1)))-_testSlash_Rat2N1_Rat3N4 = Dict @((P 8 % 3) ~ ((N 2 % 1) / (N 3 % 4)))-_testSlash_Rat2N1_Rat2N3 = Dict @((P 3 % 1) ~ ((N 2 % 1) / (N 2 % 3)))-_testSlash_Rat2N1_Rat1N2 = Dict @((P 4 % 1) ~ ((N 2 % 1) / (N 1 % 2)))-_testSlash_Rat2N1_Rat1N3 = Dict @((P 6 % 1) ~ ((N 2 % 1) / (N 1 % 3)))-_testSlash_Rat2N1_Rat1N4 = Dict @((P 8 % 1) ~ ((N 2 % 1) / (N 1 % 4)))-_testSlash_Rat2N1_Rat1P4 = Dict @((N 8 % 1) ~ ((N 2 % 1) / (P 1 % 4)))-_testSlash_Rat2N1_Rat1P3 = Dict @((N 6 % 1) ~ ((N 2 % 1) / (P 1 % 3)))-_testSlash_Rat2N1_Rat1P2 = Dict @((N 4 % 1) ~ ((N 2 % 1) / (P 1 % 2)))-_testSlash_Rat2N1_Rat2P3 = Dict @((N 3 % 1) ~ ((N 2 % 1) / (P 2 % 3)))-_testSlash_Rat2N1_Rat3P4 = Dict @((N 8 % 3) ~ ((N 2 % 1) / (P 3 % 4)))-_testSlash_Rat2N1_Rat1P1 = Dict @((N 2 % 1) ~ ((N 2 % 1) / (P 1 % 1)))-_testSlash_Rat2N1_Rat4P3 = Dict @((N 3 % 2) ~ ((N 2 % 1) / (P 4 % 3)))-_testSlash_Rat2N1_Rat3P2 = Dict @((N 4 % 3) ~ ((N 2 % 1) / (P 3 % 2)))-_testSlash_Rat2N1_Rat2P1 = Dict @((N 1 % 1) ~ ((N 2 % 1) / (P 2 % 1)))-_testSlash_Rat2N1_Rat3P1 = Dict @((N 2 % 3) ~ ((N 2 % 1) / (P 3 % 1)))-_testSlash_Rat2N1_Rat4P1 = Dict @((N 1 % 2) ~ ((N 2 % 1) / (P 4 % 1)))-_testSlash_Rat3N2_Nat1 = Dict @((N 3 % 2) ~ ((N 3 % 2) / 1))-_testSlash_Rat3N2_Nat2 = Dict @((N 3 % 4) ~ ((N 3 % 2) / 2))-_testSlash_Rat3N2_Nat3 = Dict @((N 1 % 2) ~ ((N 3 % 2) / 3))-_testSlash_Rat3N2_Nat4 = Dict @((N 3 % 8) ~ ((N 3 % 2) / 4))-_testSlash_Rat3N2_IntN4 = Dict @((P 3 % 8) ~ ((N 3 % 2) / (N 4)))-_testSlash_Rat3N2_IntN3 = Dict @((P 1 % 2) ~ ((N 3 % 2) / (N 3)))-_testSlash_Rat3N2_IntN2 = Dict @((P 3 % 4) ~ ((N 3 % 2) / (N 2)))-_testSlash_Rat3N2_IntN1 = Dict @((P 3 % 2) ~ ((N 3 % 2) / (N 1)))-_testSlash_Rat3N2_IntP1 = Dict @((N 3 % 2) ~ ((N 3 % 2) / (P 1)))-_testSlash_Rat3N2_IntP2 = Dict @((N 3 % 4) ~ ((N 3 % 2) / (P 2)))-_testSlash_Rat3N2_IntP3 = Dict @((N 1 % 2) ~ ((N 3 % 2) / (P 3)))-_testSlash_Rat3N2_IntP4 = Dict @((N 3 % 8) ~ ((N 3 % 2) / (P 4)))-_testSlash_Rat3N2_Rat4N1 = Dict @((P 3 % 8) ~ ((N 3 % 2) / (N 4 % 1)))-_testSlash_Rat3N2_Rat3N1 = Dict @((P 1 % 2) ~ ((N 3 % 2) / (N 3 % 1)))-_testSlash_Rat3N2_Rat2N1 = Dict @((P 3 % 4) ~ ((N 3 % 2) / (N 2 % 1)))-_testSlash_Rat3N2_Rat3N2 = Dict @((P 1 % 1) ~ ((N 3 % 2) / (N 3 % 2)))-_testSlash_Rat3N2_Rat4N3 = Dict @((P 9 % 8) ~ ((N 3 % 2) / (N 4 % 3)))-_testSlash_Rat3N2_Rat1N1 = Dict @((P 3 % 2) ~ ((N 3 % 2) / (N 1 % 1)))-_testSlash_Rat3N2_Rat3N4 = Dict @((P 2 % 1) ~ ((N 3 % 2) / (N 3 % 4)))-_testSlash_Rat3N2_Rat2N3 = Dict @((P 9 % 4) ~ ((N 3 % 2) / (N 2 % 3)))-_testSlash_Rat3N2_Rat1N2 = Dict @((P 3 % 1) ~ ((N 3 % 2) / (N 1 % 2)))-_testSlash_Rat3N2_Rat1N3 = Dict @((P 9 % 2) ~ ((N 3 % 2) / (N 1 % 3)))-_testSlash_Rat3N2_Rat1N4 = Dict @((P 6 % 1) ~ ((N 3 % 2) / (N 1 % 4)))-_testSlash_Rat3N2_Rat1P4 = Dict @((N 6 % 1) ~ ((N 3 % 2) / (P 1 % 4)))-_testSlash_Rat3N2_Rat1P3 = Dict @((N 9 % 2) ~ ((N 3 % 2) / (P 1 % 3)))-_testSlash_Rat3N2_Rat1P2 = Dict @((N 3 % 1) ~ ((N 3 % 2) / (P 1 % 2)))-_testSlash_Rat3N2_Rat2P3 = Dict @((N 9 % 4) ~ ((N 3 % 2) / (P 2 % 3)))-_testSlash_Rat3N2_Rat3P4 = Dict @((N 2 % 1) ~ ((N 3 % 2) / (P 3 % 4)))-_testSlash_Rat3N2_Rat1P1 = Dict @((N 3 % 2) ~ ((N 3 % 2) / (P 1 % 1)))-_testSlash_Rat3N2_Rat4P3 = Dict @((N 9 % 8) ~ ((N 3 % 2) / (P 4 % 3)))-_testSlash_Rat3N2_Rat3P2 = Dict @((N 1 % 1) ~ ((N 3 % 2) / (P 3 % 2)))-_testSlash_Rat3N2_Rat2P1 = Dict @((N 3 % 4) ~ ((N 3 % 2) / (P 2 % 1)))-_testSlash_Rat3N2_Rat3P1 = Dict @((N 1 % 2) ~ ((N 3 % 2) / (P 3 % 1)))-_testSlash_Rat3N2_Rat4P1 = Dict @((N 3 % 8) ~ ((N 3 % 2) / (P 4 % 1)))-_testSlash_Rat4N3_Nat1 = Dict @((N 4 % 3) ~ ((N 4 % 3) / 1))-_testSlash_Rat4N3_Nat2 = Dict @((N 2 % 3) ~ ((N 4 % 3) / 2))-_testSlash_Rat4N3_Nat3 = Dict @((N 4 % 9) ~ ((N 4 % 3) / 3))-_testSlash_Rat4N3_Nat4 = Dict @((N 1 % 3) ~ ((N 4 % 3) / 4))-_testSlash_Rat4N3_IntN4 = Dict @((P 1 % 3) ~ ((N 4 % 3) / (N 4)))-_testSlash_Rat4N3_IntN3 = Dict @((P 4 % 9) ~ ((N 4 % 3) / (N 3)))-_testSlash_Rat4N3_IntN2 = Dict @((P 2 % 3) ~ ((N 4 % 3) / (N 2)))-_testSlash_Rat4N3_IntN1 = Dict @((P 4 % 3) ~ ((N 4 % 3) / (N 1)))-_testSlash_Rat4N3_IntP1 = Dict @((N 4 % 3) ~ ((N 4 % 3) / (P 1)))-_testSlash_Rat4N3_IntP2 = Dict @((N 2 % 3) ~ ((N 4 % 3) / (P 2)))-_testSlash_Rat4N3_IntP3 = Dict @((N 4 % 9) ~ ((N 4 % 3) / (P 3)))-_testSlash_Rat4N3_IntP4 = Dict @((N 1 % 3) ~ ((N 4 % 3) / (P 4)))-_testSlash_Rat4N3_Rat4N1 = Dict @((P 1 % 3) ~ ((N 4 % 3) / (N 4 % 1)))-_testSlash_Rat4N3_Rat3N1 = Dict @((P 4 % 9) ~ ((N 4 % 3) / (N 3 % 1)))-_testSlash_Rat4N3_Rat2N1 = Dict @((P 2 % 3) ~ ((N 4 % 3) / (N 2 % 1)))-_testSlash_Rat4N3_Rat3N2 = Dict @((P 8 % 9) ~ ((N 4 % 3) / (N 3 % 2)))-_testSlash_Rat4N3_Rat4N3 = Dict @((P 1 % 1) ~ ((N 4 % 3) / (N 4 % 3)))-_testSlash_Rat4N3_Rat1N1 = Dict @((P 4 % 3) ~ ((N 4 % 3) / (N 1 % 1)))-_testSlash_Rat4N3_Rat3N4 = Dict @((P 16 % 9) ~ ((N 4 % 3) / (N 3 % 4)))-_testSlash_Rat4N3_Rat2N3 = Dict @((P 2 % 1) ~ ((N 4 % 3) / (N 2 % 3)))-_testSlash_Rat4N3_Rat1N2 = Dict @((P 8 % 3) ~ ((N 4 % 3) / (N 1 % 2)))-_testSlash_Rat4N3_Rat1N3 = Dict @((P 4 % 1) ~ ((N 4 % 3) / (N 1 % 3)))-_testSlash_Rat4N3_Rat1N4 = Dict @((P 16 % 3) ~ ((N 4 % 3) / (N 1 % 4)))-_testSlash_Rat4N3_Rat1P4 = Dict @((N 16 % 3) ~ ((N 4 % 3) / (P 1 % 4)))-_testSlash_Rat4N3_Rat1P3 = Dict @((N 4 % 1) ~ ((N 4 % 3) / (P 1 % 3)))-_testSlash_Rat4N3_Rat1P2 = Dict @((N 8 % 3) ~ ((N 4 % 3) / (P 1 % 2)))-_testSlash_Rat4N3_Rat2P3 = Dict @((N 2 % 1) ~ ((N 4 % 3) / (P 2 % 3)))-_testSlash_Rat4N3_Rat3P4 = Dict @((N 16 % 9) ~ ((N 4 % 3) / (P 3 % 4)))-_testSlash_Rat4N3_Rat1P1 = Dict @((N 4 % 3) ~ ((N 4 % 3) / (P 1 % 1)))-_testSlash_Rat4N3_Rat4P3 = Dict @((N 1 % 1) ~ ((N 4 % 3) / (P 4 % 3)))-_testSlash_Rat4N3_Rat3P2 = Dict @((N 8 % 9) ~ ((N 4 % 3) / (P 3 % 2)))-_testSlash_Rat4N3_Rat2P1 = Dict @((N 2 % 3) ~ ((N 4 % 3) / (P 2 % 1)))-_testSlash_Rat4N3_Rat3P1 = Dict @((N 4 % 9) ~ ((N 4 % 3) / (P 3 % 1)))-_testSlash_Rat4N3_Rat4P1 = Dict @((N 1 % 3) ~ ((N 4 % 3) / (P 4 % 1)))-_testSlash_Rat1N1_Nat1 = Dict @((N 1 % 1) ~ ((N 1 % 1) / 1))-_testSlash_Rat1N1_Nat2 = Dict @((N 1 % 2) ~ ((N 1 % 1) / 2))-_testSlash_Rat1N1_Nat3 = Dict @((N 1 % 3) ~ ((N 1 % 1) / 3))-_testSlash_Rat1N1_Nat4 = Dict @((N 1 % 4) ~ ((N 1 % 1) / 4))-_testSlash_Rat1N1_IntN4 = Dict @((P 1 % 4) ~ ((N 1 % 1) / (N 4)))-_testSlash_Rat1N1_IntN3 = Dict @((P 1 % 3) ~ ((N 1 % 1) / (N 3)))-_testSlash_Rat1N1_IntN2 = Dict @((P 1 % 2) ~ ((N 1 % 1) / (N 2)))-_testSlash_Rat1N1_IntN1 = Dict @((P 1 % 1) ~ ((N 1 % 1) / (N 1)))-_testSlash_Rat1N1_IntP1 = Dict @((N 1 % 1) ~ ((N 1 % 1) / (P 1)))-_testSlash_Rat1N1_IntP2 = Dict @((N 1 % 2) ~ ((N 1 % 1) / (P 2)))-_testSlash_Rat1N1_IntP3 = Dict @((N 1 % 3) ~ ((N 1 % 1) / (P 3)))-_testSlash_Rat1N1_IntP4 = Dict @((N 1 % 4) ~ ((N 1 % 1) / (P 4)))-_testSlash_Rat1N1_Rat4N1 = Dict @((P 1 % 4) ~ ((N 1 % 1) / (N 4 % 1)))-_testSlash_Rat1N1_Rat3N1 = Dict @((P 1 % 3) ~ ((N 1 % 1) / (N 3 % 1)))-_testSlash_Rat1N1_Rat2N1 = Dict @((P 1 % 2) ~ ((N 1 % 1) / (N 2 % 1)))-_testSlash_Rat1N1_Rat3N2 = Dict @((P 2 % 3) ~ ((N 1 % 1) / (N 3 % 2)))-_testSlash_Rat1N1_Rat4N3 = Dict @((P 3 % 4) ~ ((N 1 % 1) / (N 4 % 3)))-_testSlash_Rat1N1_Rat1N1 = Dict @((P 1 % 1) ~ ((N 1 % 1) / (N 1 % 1)))-_testSlash_Rat1N1_Rat3N4 = Dict @((P 4 % 3) ~ ((N 1 % 1) / (N 3 % 4)))-_testSlash_Rat1N1_Rat2N3 = Dict @((P 3 % 2) ~ ((N 1 % 1) / (N 2 % 3)))-_testSlash_Rat1N1_Rat1N2 = Dict @((P 2 % 1) ~ ((N 1 % 1) / (N 1 % 2)))-_testSlash_Rat1N1_Rat1N3 = Dict @((P 3 % 1) ~ ((N 1 % 1) / (N 1 % 3)))-_testSlash_Rat1N1_Rat1N4 = Dict @((P 4 % 1) ~ ((N 1 % 1) / (N 1 % 4)))-_testSlash_Rat1N1_Rat1P4 = Dict @((N 4 % 1) ~ ((N 1 % 1) / (P 1 % 4)))-_testSlash_Rat1N1_Rat1P3 = Dict @((N 3 % 1) ~ ((N 1 % 1) / (P 1 % 3)))-_testSlash_Rat1N1_Rat1P2 = Dict @((N 2 % 1) ~ ((N 1 % 1) / (P 1 % 2)))-_testSlash_Rat1N1_Rat2P3 = Dict @((N 3 % 2) ~ ((N 1 % 1) / (P 2 % 3)))-_testSlash_Rat1N1_Rat3P4 = Dict @((N 4 % 3) ~ ((N 1 % 1) / (P 3 % 4)))-_testSlash_Rat1N1_Rat1P1 = Dict @((N 1 % 1) ~ ((N 1 % 1) / (P 1 % 1)))-_testSlash_Rat1N1_Rat4P3 = Dict @((N 3 % 4) ~ ((N 1 % 1) / (P 4 % 3)))-_testSlash_Rat1N1_Rat3P2 = Dict @((N 2 % 3) ~ ((N 1 % 1) / (P 3 % 2)))-_testSlash_Rat1N1_Rat2P1 = Dict @((N 1 % 2) ~ ((N 1 % 1) / (P 2 % 1)))-_testSlash_Rat1N1_Rat3P1 = Dict @((N 1 % 3) ~ ((N 1 % 1) / (P 3 % 1)))-_testSlash_Rat1N1_Rat4P1 = Dict @((N 1 % 4) ~ ((N 1 % 1) / (P 4 % 1)))-_testSlash_Rat3N4_Nat1 = Dict @((N 3 % 4) ~ ((N 3 % 4) / 1))-_testSlash_Rat3N4_Nat2 = Dict @((N 3 % 8) ~ ((N 3 % 4) / 2))-_testSlash_Rat3N4_Nat3 = Dict @((N 1 % 4) ~ ((N 3 % 4) / 3))-_testSlash_Rat3N4_Nat4 = Dict @((N 3 % 16) ~ ((N 3 % 4) / 4))-_testSlash_Rat3N4_IntN4 = Dict @((P 3 % 16) ~ ((N 3 % 4) / (N 4)))-_testSlash_Rat3N4_IntN3 = Dict @((P 1 % 4) ~ ((N 3 % 4) / (N 3)))-_testSlash_Rat3N4_IntN2 = Dict @((P 3 % 8) ~ ((N 3 % 4) / (N 2)))-_testSlash_Rat3N4_IntN1 = Dict @((P 3 % 4) ~ ((N 3 % 4) / (N 1)))-_testSlash_Rat3N4_IntP1 = Dict @((N 3 % 4) ~ ((N 3 % 4) / (P 1)))-_testSlash_Rat3N4_IntP2 = Dict @((N 3 % 8) ~ ((N 3 % 4) / (P 2)))-_testSlash_Rat3N4_IntP3 = Dict @((N 1 % 4) ~ ((N 3 % 4) / (P 3)))-_testSlash_Rat3N4_IntP4 = Dict @((N 3 % 16) ~ ((N 3 % 4) / (P 4)))-_testSlash_Rat3N4_Rat4N1 = Dict @((P 3 % 16) ~ ((N 3 % 4) / (N 4 % 1)))-_testSlash_Rat3N4_Rat3N1 = Dict @((P 1 % 4) ~ ((N 3 % 4) / (N 3 % 1)))-_testSlash_Rat3N4_Rat2N1 = Dict @((P 3 % 8) ~ ((N 3 % 4) / (N 2 % 1)))-_testSlash_Rat3N4_Rat3N2 = Dict @((P 1 % 2) ~ ((N 3 % 4) / (N 3 % 2)))-_testSlash_Rat3N4_Rat4N3 = Dict @((P 9 % 16) ~ ((N 3 % 4) / (N 4 % 3)))-_testSlash_Rat3N4_Rat1N1 = Dict @((P 3 % 4) ~ ((N 3 % 4) / (N 1 % 1)))-_testSlash_Rat3N4_Rat3N4 = Dict @((P 1 % 1) ~ ((N 3 % 4) / (N 3 % 4)))-_testSlash_Rat3N4_Rat2N3 = Dict @((P 9 % 8) ~ ((N 3 % 4) / (N 2 % 3)))-_testSlash_Rat3N4_Rat1N2 = Dict @((P 3 % 2) ~ ((N 3 % 4) / (N 1 % 2)))-_testSlash_Rat3N4_Rat1N3 = Dict @((P 9 % 4) ~ ((N 3 % 4) / (N 1 % 3)))-_testSlash_Rat3N4_Rat1N4 = Dict @((P 3 % 1) ~ ((N 3 % 4) / (N 1 % 4)))-_testSlash_Rat3N4_Rat1P4 = Dict @((N 3 % 1) ~ ((N 3 % 4) / (P 1 % 4)))-_testSlash_Rat3N4_Rat1P3 = Dict @((N 9 % 4) ~ ((N 3 % 4) / (P 1 % 3)))-_testSlash_Rat3N4_Rat1P2 = Dict @((N 3 % 2) ~ ((N 3 % 4) / (P 1 % 2)))-_testSlash_Rat3N4_Rat2P3 = Dict @((N 9 % 8) ~ ((N 3 % 4) / (P 2 % 3)))-_testSlash_Rat3N4_Rat3P4 = Dict @((N 1 % 1) ~ ((N 3 % 4) / (P 3 % 4)))-_testSlash_Rat3N4_Rat1P1 = Dict @((N 3 % 4) ~ ((N 3 % 4) / (P 1 % 1)))-_testSlash_Rat3N4_Rat4P3 = Dict @((N 9 % 16) ~ ((N 3 % 4) / (P 4 % 3)))-_testSlash_Rat3N4_Rat3P2 = Dict @((N 1 % 2) ~ ((N 3 % 4) / (P 3 % 2)))-_testSlash_Rat3N4_Rat2P1 = Dict @((N 3 % 8) ~ ((N 3 % 4) / (P 2 % 1)))-_testSlash_Rat3N4_Rat3P1 = Dict @((N 1 % 4) ~ ((N 3 % 4) / (P 3 % 1)))-_testSlash_Rat3N4_Rat4P1 = Dict @((N 3 % 16) ~ ((N 3 % 4) / (P 4 % 1)))-_testSlash_Rat2N3_Nat1 = Dict @((N 2 % 3) ~ ((N 2 % 3) / 1))-_testSlash_Rat2N3_Nat2 = Dict @((N 1 % 3) ~ ((N 2 % 3) / 2))-_testSlash_Rat2N3_Nat3 = Dict @((N 2 % 9) ~ ((N 2 % 3) / 3))-_testSlash_Rat2N3_Nat4 = Dict @((N 1 % 6) ~ ((N 2 % 3) / 4))-_testSlash_Rat2N3_IntN4 = Dict @((P 1 % 6) ~ ((N 2 % 3) / (N 4)))-_testSlash_Rat2N3_IntN3 = Dict @((P 2 % 9) ~ ((N 2 % 3) / (N 3)))-_testSlash_Rat2N3_IntN2 = Dict @((P 1 % 3) ~ ((N 2 % 3) / (N 2)))-_testSlash_Rat2N3_IntN1 = Dict @((P 2 % 3) ~ ((N 2 % 3) / (N 1)))-_testSlash_Rat2N3_IntP1 = Dict @((N 2 % 3) ~ ((N 2 % 3) / (P 1)))-_testSlash_Rat2N3_IntP2 = Dict @((N 1 % 3) ~ ((N 2 % 3) / (P 2)))-_testSlash_Rat2N3_IntP3 = Dict @((N 2 % 9) ~ ((N 2 % 3) / (P 3)))-_testSlash_Rat2N3_IntP4 = Dict @((N 1 % 6) ~ ((N 2 % 3) / (P 4)))-_testSlash_Rat2N3_Rat4N1 = Dict @((P 1 % 6) ~ ((N 2 % 3) / (N 4 % 1)))-_testSlash_Rat2N3_Rat3N1 = Dict @((P 2 % 9) ~ ((N 2 % 3) / (N 3 % 1)))-_testSlash_Rat2N3_Rat2N1 = Dict @((P 1 % 3) ~ ((N 2 % 3) / (N 2 % 1)))-_testSlash_Rat2N3_Rat3N2 = Dict @((P 4 % 9) ~ ((N 2 % 3) / (N 3 % 2)))-_testSlash_Rat2N3_Rat4N3 = Dict @((P 1 % 2) ~ ((N 2 % 3) / (N 4 % 3)))-_testSlash_Rat2N3_Rat1N1 = Dict @((P 2 % 3) ~ ((N 2 % 3) / (N 1 % 1)))-_testSlash_Rat2N3_Rat3N4 = Dict @((P 8 % 9) ~ ((N 2 % 3) / (N 3 % 4)))-_testSlash_Rat2N3_Rat2N3 = Dict @((P 1 % 1) ~ ((N 2 % 3) / (N 2 % 3)))-_testSlash_Rat2N3_Rat1N2 = Dict @((P 4 % 3) ~ ((N 2 % 3) / (N 1 % 2)))-_testSlash_Rat2N3_Rat1N3 = Dict @((P 2 % 1) ~ ((N 2 % 3) / (N 1 % 3)))-_testSlash_Rat2N3_Rat1N4 = Dict @((P 8 % 3) ~ ((N 2 % 3) / (N 1 % 4)))-_testSlash_Rat2N3_Rat1P4 = Dict @((N 8 % 3) ~ ((N 2 % 3) / (P 1 % 4)))-_testSlash_Rat2N3_Rat1P3 = Dict @((N 2 % 1) ~ ((N 2 % 3) / (P 1 % 3)))-_testSlash_Rat2N3_Rat1P2 = Dict @((N 4 % 3) ~ ((N 2 % 3) / (P 1 % 2)))-_testSlash_Rat2N3_Rat2P3 = Dict @((N 1 % 1) ~ ((N 2 % 3) / (P 2 % 3)))-_testSlash_Rat2N3_Rat3P4 = Dict @((N 8 % 9) ~ ((N 2 % 3) / (P 3 % 4)))-_testSlash_Rat2N3_Rat1P1 = Dict @((N 2 % 3) ~ ((N 2 % 3) / (P 1 % 1)))-_testSlash_Rat2N3_Rat4P3 = Dict @((N 1 % 2) ~ ((N 2 % 3) / (P 4 % 3)))-_testSlash_Rat2N3_Rat3P2 = Dict @((N 4 % 9) ~ ((N 2 % 3) / (P 3 % 2)))-_testSlash_Rat2N3_Rat2P1 = Dict @((N 1 % 3) ~ ((N 2 % 3) / (P 2 % 1)))-_testSlash_Rat2N3_Rat3P1 = Dict @((N 2 % 9) ~ ((N 2 % 3) / (P 3 % 1)))-_testSlash_Rat2N3_Rat4P1 = Dict @((N 1 % 6) ~ ((N 2 % 3) / (P 4 % 1)))-_testSlash_Rat1N2_Nat1 = Dict @((N 1 % 2) ~ ((N 1 % 2) / 1))-_testSlash_Rat1N2_Nat2 = Dict @((N 1 % 4) ~ ((N 1 % 2) / 2))-_testSlash_Rat1N2_Nat3 = Dict @((N 1 % 6) ~ ((N 1 % 2) / 3))-_testSlash_Rat1N2_Nat4 = Dict @((N 1 % 8) ~ ((N 1 % 2) / 4))-_testSlash_Rat1N2_IntN4 = Dict @((P 1 % 8) ~ ((N 1 % 2) / (N 4)))-_testSlash_Rat1N2_IntN3 = Dict @((P 1 % 6) ~ ((N 1 % 2) / (N 3)))-_testSlash_Rat1N2_IntN2 = Dict @((P 1 % 4) ~ ((N 1 % 2) / (N 2)))-_testSlash_Rat1N2_IntN1 = Dict @((P 1 % 2) ~ ((N 1 % 2) / (N 1)))-_testSlash_Rat1N2_IntP1 = Dict @((N 1 % 2) ~ ((N 1 % 2) / (P 1)))-_testSlash_Rat1N2_IntP2 = Dict @((N 1 % 4) ~ ((N 1 % 2) / (P 2)))-_testSlash_Rat1N2_IntP3 = Dict @((N 1 % 6) ~ ((N 1 % 2) / (P 3)))-_testSlash_Rat1N2_IntP4 = Dict @((N 1 % 8) ~ ((N 1 % 2) / (P 4)))-_testSlash_Rat1N2_Rat4N1 = Dict @((P 1 % 8) ~ ((N 1 % 2) / (N 4 % 1)))-_testSlash_Rat1N2_Rat3N1 = Dict @((P 1 % 6) ~ ((N 1 % 2) / (N 3 % 1)))-_testSlash_Rat1N2_Rat2N1 = Dict @((P 1 % 4) ~ ((N 1 % 2) / (N 2 % 1)))-_testSlash_Rat1N2_Rat3N2 = Dict @((P 1 % 3) ~ ((N 1 % 2) / (N 3 % 2)))-_testSlash_Rat1N2_Rat4N3 = Dict @((P 3 % 8) ~ ((N 1 % 2) / (N 4 % 3)))-_testSlash_Rat1N2_Rat1N1 = Dict @((P 1 % 2) ~ ((N 1 % 2) / (N 1 % 1)))-_testSlash_Rat1N2_Rat3N4 = Dict @((P 2 % 3) ~ ((N 1 % 2) / (N 3 % 4)))-_testSlash_Rat1N2_Rat2N3 = Dict @((P 3 % 4) ~ ((N 1 % 2) / (N 2 % 3)))-_testSlash_Rat1N2_Rat1N2 = Dict @((P 1 % 1) ~ ((N 1 % 2) / (N 1 % 2)))-_testSlash_Rat1N2_Rat1N3 = Dict @((P 3 % 2) ~ ((N 1 % 2) / (N 1 % 3)))-_testSlash_Rat1N2_Rat1N4 = Dict @((P 2 % 1) ~ ((N 1 % 2) / (N 1 % 4)))-_testSlash_Rat1N2_Rat1P4 = Dict @((N 2 % 1) ~ ((N 1 % 2) / (P 1 % 4)))-_testSlash_Rat1N2_Rat1P3 = Dict @((N 3 % 2) ~ ((N 1 % 2) / (P 1 % 3)))-_testSlash_Rat1N2_Rat1P2 = Dict @((N 1 % 1) ~ ((N 1 % 2) / (P 1 % 2)))-_testSlash_Rat1N2_Rat2P3 = Dict @((N 3 % 4) ~ ((N 1 % 2) / (P 2 % 3)))-_testSlash_Rat1N2_Rat3P4 = Dict @((N 2 % 3) ~ ((N 1 % 2) / (P 3 % 4)))-_testSlash_Rat1N2_Rat1P1 = Dict @((N 1 % 2) ~ ((N 1 % 2) / (P 1 % 1)))-_testSlash_Rat1N2_Rat4P3 = Dict @((N 3 % 8) ~ ((N 1 % 2) / (P 4 % 3)))-_testSlash_Rat1N2_Rat3P2 = Dict @((N 1 % 3) ~ ((N 1 % 2) / (P 3 % 2)))-_testSlash_Rat1N2_Rat2P1 = Dict @((N 1 % 4) ~ ((N 1 % 2) / (P 2 % 1)))-_testSlash_Rat1N2_Rat3P1 = Dict @((N 1 % 6) ~ ((N 1 % 2) / (P 3 % 1)))-_testSlash_Rat1N2_Rat4P1 = Dict @((N 1 % 8) ~ ((N 1 % 2) / (P 4 % 1)))-_testSlash_Rat1N3_Nat1 = Dict @((N 1 % 3) ~ ((N 1 % 3) / 1))-_testSlash_Rat1N3_Nat2 = Dict @((N 1 % 6) ~ ((N 1 % 3) / 2))-_testSlash_Rat1N3_Nat3 = Dict @((N 1 % 9) ~ ((N 1 % 3) / 3))-_testSlash_Rat1N3_Nat4 = Dict @((N 1 % 12) ~ ((N 1 % 3) / 4))-_testSlash_Rat1N3_IntN4 = Dict @((P 1 % 12) ~ ((N 1 % 3) / (N 4)))-_testSlash_Rat1N3_IntN3 = Dict @((P 1 % 9) ~ ((N 1 % 3) / (N 3)))-_testSlash_Rat1N3_IntN2 = Dict @((P 1 % 6) ~ ((N 1 % 3) / (N 2)))-_testSlash_Rat1N3_IntN1 = Dict @((P 1 % 3) ~ ((N 1 % 3) / (N 1)))-_testSlash_Rat1N3_IntP1 = Dict @((N 1 % 3) ~ ((N 1 % 3) / (P 1)))-_testSlash_Rat1N3_IntP2 = Dict @((N 1 % 6) ~ ((N 1 % 3) / (P 2)))-_testSlash_Rat1N3_IntP3 = Dict @((N 1 % 9) ~ ((N 1 % 3) / (P 3)))-_testSlash_Rat1N3_IntP4 = Dict @((N 1 % 12) ~ ((N 1 % 3) / (P 4)))-_testSlash_Rat1N3_Rat4N1 = Dict @((P 1 % 12) ~ ((N 1 % 3) / (N 4 % 1)))-_testSlash_Rat1N3_Rat3N1 = Dict @((P 1 % 9) ~ ((N 1 % 3) / (N 3 % 1)))-_testSlash_Rat1N3_Rat2N1 = Dict @((P 1 % 6) ~ ((N 1 % 3) / (N 2 % 1)))-_testSlash_Rat1N3_Rat3N2 = Dict @((P 2 % 9) ~ ((N 1 % 3) / (N 3 % 2)))-_testSlash_Rat1N3_Rat4N3 = Dict @((P 1 % 4) ~ ((N 1 % 3) / (N 4 % 3)))-_testSlash_Rat1N3_Rat1N1 = Dict @((P 1 % 3) ~ ((N 1 % 3) / (N 1 % 1)))-_testSlash_Rat1N3_Rat3N4 = Dict @((P 4 % 9) ~ ((N 1 % 3) / (N 3 % 4)))-_testSlash_Rat1N3_Rat2N3 = Dict @((P 1 % 2) ~ ((N 1 % 3) / (N 2 % 3)))-_testSlash_Rat1N3_Rat1N2 = Dict @((P 2 % 3) ~ ((N 1 % 3) / (N 1 % 2)))-_testSlash_Rat1N3_Rat1N3 = Dict @((P 1 % 1) ~ ((N 1 % 3) / (N 1 % 3)))-_testSlash_Rat1N3_Rat1N4 = Dict @((P 4 % 3) ~ ((N 1 % 3) / (N 1 % 4)))-_testSlash_Rat1N3_Rat1P4 = Dict @((N 4 % 3) ~ ((N 1 % 3) / (P 1 % 4)))-_testSlash_Rat1N3_Rat1P3 = Dict @((N 1 % 1) ~ ((N 1 % 3) / (P 1 % 3)))-_testSlash_Rat1N3_Rat1P2 = Dict @((N 2 % 3) ~ ((N 1 % 3) / (P 1 % 2)))-_testSlash_Rat1N3_Rat2P3 = Dict @((N 1 % 2) ~ ((N 1 % 3) / (P 2 % 3)))-_testSlash_Rat1N3_Rat3P4 = Dict @((N 4 % 9) ~ ((N 1 % 3) / (P 3 % 4)))-_testSlash_Rat1N3_Rat1P1 = Dict @((N 1 % 3) ~ ((N 1 % 3) / (P 1 % 1)))-_testSlash_Rat1N3_Rat4P3 = Dict @((N 1 % 4) ~ ((N 1 % 3) / (P 4 % 3)))-_testSlash_Rat1N3_Rat3P2 = Dict @((N 2 % 9) ~ ((N 1 % 3) / (P 3 % 2)))-_testSlash_Rat1N3_Rat2P1 = Dict @((N 1 % 6) ~ ((N 1 % 3) / (P 2 % 1)))-_testSlash_Rat1N3_Rat3P1 = Dict @((N 1 % 9) ~ ((N 1 % 3) / (P 3 % 1)))-_testSlash_Rat1N3_Rat4P1 = Dict @((N 1 % 12) ~ ((N 1 % 3) / (P 4 % 1)))-_testSlash_Rat1N4_Nat1 = Dict @((N 1 % 4) ~ ((N 1 % 4) / 1))-_testSlash_Rat1N4_Nat2 = Dict @((N 1 % 8) ~ ((N 1 % 4) / 2))-_testSlash_Rat1N4_Nat3 = Dict @((N 1 % 12) ~ ((N 1 % 4) / 3))-_testSlash_Rat1N4_Nat4 = Dict @((N 1 % 16) ~ ((N 1 % 4) / 4))-_testSlash_Rat1N4_IntN4 = Dict @((P 1 % 16) ~ ((N 1 % 4) / (N 4)))-_testSlash_Rat1N4_IntN3 = Dict @((P 1 % 12) ~ ((N 1 % 4) / (N 3)))-_testSlash_Rat1N4_IntN2 = Dict @((P 1 % 8) ~ ((N 1 % 4) / (N 2)))-_testSlash_Rat1N4_IntN1 = Dict @((P 1 % 4) ~ ((N 1 % 4) / (N 1)))-_testSlash_Rat1N4_IntP1 = Dict @((N 1 % 4) ~ ((N 1 % 4) / (P 1)))-_testSlash_Rat1N4_IntP2 = Dict @((N 1 % 8) ~ ((N 1 % 4) / (P 2)))-_testSlash_Rat1N4_IntP3 = Dict @((N 1 % 12) ~ ((N 1 % 4) / (P 3)))-_testSlash_Rat1N4_IntP4 = Dict @((N 1 % 16) ~ ((N 1 % 4) / (P 4)))-_testSlash_Rat1N4_Rat4N1 = Dict @((P 1 % 16) ~ ((N 1 % 4) / (N 4 % 1)))-_testSlash_Rat1N4_Rat3N1 = Dict @((P 1 % 12) ~ ((N 1 % 4) / (N 3 % 1)))-_testSlash_Rat1N4_Rat2N1 = Dict @((P 1 % 8) ~ ((N 1 % 4) / (N 2 % 1)))-_testSlash_Rat1N4_Rat3N2 = Dict @((P 1 % 6) ~ ((N 1 % 4) / (N 3 % 2)))-_testSlash_Rat1N4_Rat4N3 = Dict @((P 3 % 16) ~ ((N 1 % 4) / (N 4 % 3)))-_testSlash_Rat1N4_Rat1N1 = Dict @((P 1 % 4) ~ ((N 1 % 4) / (N 1 % 1)))-_testSlash_Rat1N4_Rat3N4 = Dict @((P 1 % 3) ~ ((N 1 % 4) / (N 3 % 4)))-_testSlash_Rat1N4_Rat2N3 = Dict @((P 3 % 8) ~ ((N 1 % 4) / (N 2 % 3)))-_testSlash_Rat1N4_Rat1N2 = Dict @((P 1 % 2) ~ ((N 1 % 4) / (N 1 % 2)))-_testSlash_Rat1N4_Rat1N3 = Dict @((P 3 % 4) ~ ((N 1 % 4) / (N 1 % 3)))-_testSlash_Rat1N4_Rat1N4 = Dict @((P 1 % 1) ~ ((N 1 % 4) / (N 1 % 4)))-_testSlash_Rat1N4_Rat1P4 = Dict @((N 1 % 1) ~ ((N 1 % 4) / (P 1 % 4)))-_testSlash_Rat1N4_Rat1P3 = Dict @((N 3 % 4) ~ ((N 1 % 4) / (P 1 % 3)))-_testSlash_Rat1N4_Rat1P2 = Dict @((N 1 % 2) ~ ((N 1 % 4) / (P 1 % 2)))-_testSlash_Rat1N4_Rat2P3 = Dict @((N 3 % 8) ~ ((N 1 % 4) / (P 2 % 3)))-_testSlash_Rat1N4_Rat3P4 = Dict @((N 1 % 3) ~ ((N 1 % 4) / (P 3 % 4)))-_testSlash_Rat1N4_Rat1P1 = Dict @((N 1 % 4) ~ ((N 1 % 4) / (P 1 % 1)))-_testSlash_Rat1N4_Rat4P3 = Dict @((N 3 % 16) ~ ((N 1 % 4) / (P 4 % 3)))-_testSlash_Rat1N4_Rat3P2 = Dict @((N 1 % 6) ~ ((N 1 % 4) / (P 3 % 2)))-_testSlash_Rat1N4_Rat2P1 = Dict @((N 1 % 8) ~ ((N 1 % 4) / (P 2 % 1)))-_testSlash_Rat1N4_Rat3P1 = Dict @((N 1 % 12) ~ ((N 1 % 4) / (P 3 % 1)))-_testSlash_Rat1N4_Rat4P1 = Dict @((N 1 % 16) ~ ((N 1 % 4) / (P 4 % 1)))-_testSlash_Rat0P1_Nat1 = Dict @((P 0 % 1) ~ ((P 0 % 1) / 1))-_testSlash_Rat0P1_Nat2 = Dict @((P 0 % 1) ~ ((P 0 % 1) / 2))-_testSlash_Rat0P1_Nat3 = Dict @((P 0 % 1) ~ ((P 0 % 1) / 3))-_testSlash_Rat0P1_Nat4 = Dict @((P 0 % 1) ~ ((P 0 % 1) / 4))-_testSlash_Rat0P1_IntN4 = Dict @((P 0 % 1) ~ ((P 0 % 1) / (N 4)))-_testSlash_Rat0P1_IntN3 = Dict @((P 0 % 1) ~ ((P 0 % 1) / (N 3)))-_testSlash_Rat0P1_IntN2 = Dict @((P 0 % 1) ~ ((P 0 % 1) / (N 2)))-_testSlash_Rat0P1_IntN1 = Dict @((P 0 % 1) ~ ((P 0 % 1) / (N 1)))-_testSlash_Rat0P1_IntP1 = Dict @((P 0 % 1) ~ ((P 0 % 1) / (P 1)))-_testSlash_Rat0P1_IntP2 = Dict @((P 0 % 1) ~ ((P 0 % 1) / (P 2)))-_testSlash_Rat0P1_IntP3 = Dict @((P 0 % 1) ~ ((P 0 % 1) / (P 3)))-_testSlash_Rat0P1_IntP4 = Dict @((P 0 % 1) ~ ((P 0 % 1) / (P 4)))-_testSlash_Rat0P1_Rat4N1 = Dict @((P 0 % 1) ~ ((P 0 % 1) / (N 4 % 1)))-_testSlash_Rat0P1_Rat3N1 = Dict @((P 0 % 1) ~ ((P 0 % 1) / (N 3 % 1)))-_testSlash_Rat0P1_Rat2N1 = Dict @((P 0 % 1) ~ ((P 0 % 1) / (N 2 % 1)))-_testSlash_Rat0P1_Rat3N2 = Dict @((P 0 % 1) ~ ((P 0 % 1) / (N 3 % 2)))-_testSlash_Rat0P1_Rat4N3 = Dict @((P 0 % 1) ~ ((P 0 % 1) / (N 4 % 3)))-_testSlash_Rat0P1_Rat1N1 = Dict @((P 0 % 1) ~ ((P 0 % 1) / (N 1 % 1)))-_testSlash_Rat0P1_Rat3N4 = Dict @((P 0 % 1) ~ ((P 0 % 1) / (N 3 % 4)))-_testSlash_Rat0P1_Rat2N3 = Dict @((P 0 % 1) ~ ((P 0 % 1) / (N 2 % 3)))-_testSlash_Rat0P1_Rat1N2 = Dict @((P 0 % 1) ~ ((P 0 % 1) / (N 1 % 2)))-_testSlash_Rat0P1_Rat1N3 = Dict @((P 0 % 1) ~ ((P 0 % 1) / (N 1 % 3)))-_testSlash_Rat0P1_Rat1N4 = Dict @((P 0 % 1) ~ ((P 0 % 1) / (N 1 % 4)))-_testSlash_Rat0P1_Rat1P4 = Dict @((P 0 % 1) ~ ((P 0 % 1) / (P 1 % 4)))-_testSlash_Rat0P1_Rat1P3 = Dict @((P 0 % 1) ~ ((P 0 % 1) / (P 1 % 3)))-_testSlash_Rat0P1_Rat1P2 = Dict @((P 0 % 1) ~ ((P 0 % 1) / (P 1 % 2)))-_testSlash_Rat0P1_Rat2P3 = Dict @((P 0 % 1) ~ ((P 0 % 1) / (P 2 % 3)))-_testSlash_Rat0P1_Rat3P4 = Dict @((P 0 % 1) ~ ((P 0 % 1) / (P 3 % 4)))-_testSlash_Rat0P1_Rat1P1 = Dict @((P 0 % 1) ~ ((P 0 % 1) / (P 1 % 1)))-_testSlash_Rat0P1_Rat4P3 = Dict @((P 0 % 1) ~ ((P 0 % 1) / (P 4 % 3)))-_testSlash_Rat0P1_Rat3P2 = Dict @((P 0 % 1) ~ ((P 0 % 1) / (P 3 % 2)))-_testSlash_Rat0P1_Rat2P1 = Dict @((P 0 % 1) ~ ((P 0 % 1) / (P 2 % 1)))-_testSlash_Rat0P1_Rat3P1 = Dict @((P 0 % 1) ~ ((P 0 % 1) / (P 3 % 1)))-_testSlash_Rat0P1_Rat4P1 = Dict @((P 0 % 1) ~ ((P 0 % 1) / (P 4 % 1)))-_testSlash_Rat1P4_Nat1 = Dict @((P 1 % 4) ~ ((P 1 % 4) / 1))-_testSlash_Rat1P4_Nat2 = Dict @((P 1 % 8) ~ ((P 1 % 4) / 2))-_testSlash_Rat1P4_Nat3 = Dict @((P 1 % 12) ~ ((P 1 % 4) / 3))-_testSlash_Rat1P4_Nat4 = Dict @((P 1 % 16) ~ ((P 1 % 4) / 4))-_testSlash_Rat1P4_IntN4 = Dict @((N 1 % 16) ~ ((P 1 % 4) / (N 4)))-_testSlash_Rat1P4_IntN3 = Dict @((N 1 % 12) ~ ((P 1 % 4) / (N 3)))-_testSlash_Rat1P4_IntN2 = Dict @((N 1 % 8) ~ ((P 1 % 4) / (N 2)))-_testSlash_Rat1P4_IntN1 = Dict @((N 1 % 4) ~ ((P 1 % 4) / (N 1)))-_testSlash_Rat1P4_IntP1 = Dict @((P 1 % 4) ~ ((P 1 % 4) / (P 1)))-_testSlash_Rat1P4_IntP2 = Dict @((P 1 % 8) ~ ((P 1 % 4) / (P 2)))-_testSlash_Rat1P4_IntP3 = Dict @((P 1 % 12) ~ ((P 1 % 4) / (P 3)))-_testSlash_Rat1P4_IntP4 = Dict @((P 1 % 16) ~ ((P 1 % 4) / (P 4)))-_testSlash_Rat1P4_Rat4N1 = Dict @((N 1 % 16) ~ ((P 1 % 4) / (N 4 % 1)))-_testSlash_Rat1P4_Rat3N1 = Dict @((N 1 % 12) ~ ((P 1 % 4) / (N 3 % 1)))-_testSlash_Rat1P4_Rat2N1 = Dict @((N 1 % 8) ~ ((P 1 % 4) / (N 2 % 1)))-_testSlash_Rat1P4_Rat3N2 = Dict @((N 1 % 6) ~ ((P 1 % 4) / (N 3 % 2)))-_testSlash_Rat1P4_Rat4N3 = Dict @((N 3 % 16) ~ ((P 1 % 4) / (N 4 % 3)))-_testSlash_Rat1P4_Rat1N1 = Dict @((N 1 % 4) ~ ((P 1 % 4) / (N 1 % 1)))-_testSlash_Rat1P4_Rat3N4 = Dict @((N 1 % 3) ~ ((P 1 % 4) / (N 3 % 4)))-_testSlash_Rat1P4_Rat2N3 = Dict @((N 3 % 8) ~ ((P 1 % 4) / (N 2 % 3)))-_testSlash_Rat1P4_Rat1N2 = Dict @((N 1 % 2) ~ ((P 1 % 4) / (N 1 % 2)))-_testSlash_Rat1P4_Rat1N3 = Dict @((N 3 % 4) ~ ((P 1 % 4) / (N 1 % 3)))-_testSlash_Rat1P4_Rat1N4 = Dict @((N 1 % 1) ~ ((P 1 % 4) / (N 1 % 4)))-_testSlash_Rat1P4_Rat1P4 = Dict @((P 1 % 1) ~ ((P 1 % 4) / (P 1 % 4)))-_testSlash_Rat1P4_Rat1P3 = Dict @((P 3 % 4) ~ ((P 1 % 4) / (P 1 % 3)))-_testSlash_Rat1P4_Rat1P2 = Dict @((P 1 % 2) ~ ((P 1 % 4) / (P 1 % 2)))-_testSlash_Rat1P4_Rat2P3 = Dict @((P 3 % 8) ~ ((P 1 % 4) / (P 2 % 3)))-_testSlash_Rat1P4_Rat3P4 = Dict @((P 1 % 3) ~ ((P 1 % 4) / (P 3 % 4)))-_testSlash_Rat1P4_Rat1P1 = Dict @((P 1 % 4) ~ ((P 1 % 4) / (P 1 % 1)))-_testSlash_Rat1P4_Rat4P3 = Dict @((P 3 % 16) ~ ((P 1 % 4) / (P 4 % 3)))-_testSlash_Rat1P4_Rat3P2 = Dict @((P 1 % 6) ~ ((P 1 % 4) / (P 3 % 2)))-_testSlash_Rat1P4_Rat2P1 = Dict @((P 1 % 8) ~ ((P 1 % 4) / (P 2 % 1)))-_testSlash_Rat1P4_Rat3P1 = Dict @((P 1 % 12) ~ ((P 1 % 4) / (P 3 % 1)))-_testSlash_Rat1P4_Rat4P1 = Dict @((P 1 % 16) ~ ((P 1 % 4) / (P 4 % 1)))-_testSlash_Rat1P3_Nat1 = Dict @((P 1 % 3) ~ ((P 1 % 3) / 1))-_testSlash_Rat1P3_Nat2 = Dict @((P 1 % 6) ~ ((P 1 % 3) / 2))-_testSlash_Rat1P3_Nat3 = Dict @((P 1 % 9) ~ ((P 1 % 3) / 3))-_testSlash_Rat1P3_Nat4 = Dict @((P 1 % 12) ~ ((P 1 % 3) / 4))-_testSlash_Rat1P3_IntN4 = Dict @((N 1 % 12) ~ ((P 1 % 3) / (N 4)))-_testSlash_Rat1P3_IntN3 = Dict @((N 1 % 9) ~ ((P 1 % 3) / (N 3)))-_testSlash_Rat1P3_IntN2 = Dict @((N 1 % 6) ~ ((P 1 % 3) / (N 2)))-_testSlash_Rat1P3_IntN1 = Dict @((N 1 % 3) ~ ((P 1 % 3) / (N 1)))-_testSlash_Rat1P3_IntP1 = Dict @((P 1 % 3) ~ ((P 1 % 3) / (P 1)))-_testSlash_Rat1P3_IntP2 = Dict @((P 1 % 6) ~ ((P 1 % 3) / (P 2)))-_testSlash_Rat1P3_IntP3 = Dict @((P 1 % 9) ~ ((P 1 % 3) / (P 3)))-_testSlash_Rat1P3_IntP4 = Dict @((P 1 % 12) ~ ((P 1 % 3) / (P 4)))-_testSlash_Rat1P3_Rat4N1 = Dict @((N 1 % 12) ~ ((P 1 % 3) / (N 4 % 1)))-_testSlash_Rat1P3_Rat3N1 = Dict @((N 1 % 9) ~ ((P 1 % 3) / (N 3 % 1)))-_testSlash_Rat1P3_Rat2N1 = Dict @((N 1 % 6) ~ ((P 1 % 3) / (N 2 % 1)))-_testSlash_Rat1P3_Rat3N2 = Dict @((N 2 % 9) ~ ((P 1 % 3) / (N 3 % 2)))-_testSlash_Rat1P3_Rat4N3 = Dict @((N 1 % 4) ~ ((P 1 % 3) / (N 4 % 3)))-_testSlash_Rat1P3_Rat1N1 = Dict @((N 1 % 3) ~ ((P 1 % 3) / (N 1 % 1)))-_testSlash_Rat1P3_Rat3N4 = Dict @((N 4 % 9) ~ ((P 1 % 3) / (N 3 % 4)))-_testSlash_Rat1P3_Rat2N3 = Dict @((N 1 % 2) ~ ((P 1 % 3) / (N 2 % 3)))-_testSlash_Rat1P3_Rat1N2 = Dict @((N 2 % 3) ~ ((P 1 % 3) / (N 1 % 2)))-_testSlash_Rat1P3_Rat1N3 = Dict @((N 1 % 1) ~ ((P 1 % 3) / (N 1 % 3)))-_testSlash_Rat1P3_Rat1N4 = Dict @((N 4 % 3) ~ ((P 1 % 3) / (N 1 % 4)))-_testSlash_Rat1P3_Rat1P4 = Dict @((P 4 % 3) ~ ((P 1 % 3) / (P 1 % 4)))-_testSlash_Rat1P3_Rat1P3 = Dict @((P 1 % 1) ~ ((P 1 % 3) / (P 1 % 3)))-_testSlash_Rat1P3_Rat1P2 = Dict @((P 2 % 3) ~ ((P 1 % 3) / (P 1 % 2)))-_testSlash_Rat1P3_Rat2P3 = Dict @((P 1 % 2) ~ ((P 1 % 3) / (P 2 % 3)))-_testSlash_Rat1P3_Rat3P4 = Dict @((P 4 % 9) ~ ((P 1 % 3) / (P 3 % 4)))-_testSlash_Rat1P3_Rat1P1 = Dict @((P 1 % 3) ~ ((P 1 % 3) / (P 1 % 1)))-_testSlash_Rat1P3_Rat4P3 = Dict @((P 1 % 4) ~ ((P 1 % 3) / (P 4 % 3)))-_testSlash_Rat1P3_Rat3P2 = Dict @((P 2 % 9) ~ ((P 1 % 3) / (P 3 % 2)))-_testSlash_Rat1P3_Rat2P1 = Dict @((P 1 % 6) ~ ((P 1 % 3) / (P 2 % 1)))-_testSlash_Rat1P3_Rat3P1 = Dict @((P 1 % 9) ~ ((P 1 % 3) / (P 3 % 1)))-_testSlash_Rat1P3_Rat4P1 = Dict @((P 1 % 12) ~ ((P 1 % 3) / (P 4 % 1)))-_testSlash_Rat1P2_Nat1 = Dict @((P 1 % 2) ~ ((P 1 % 2) / 1))-_testSlash_Rat1P2_Nat2 = Dict @((P 1 % 4) ~ ((P 1 % 2) / 2))-_testSlash_Rat1P2_Nat3 = Dict @((P 1 % 6) ~ ((P 1 % 2) / 3))-_testSlash_Rat1P2_Nat4 = Dict @((P 1 % 8) ~ ((P 1 % 2) / 4))-_testSlash_Rat1P2_IntN4 = Dict @((N 1 % 8) ~ ((P 1 % 2) / (N 4)))-_testSlash_Rat1P2_IntN3 = Dict @((N 1 % 6) ~ ((P 1 % 2) / (N 3)))-_testSlash_Rat1P2_IntN2 = Dict @((N 1 % 4) ~ ((P 1 % 2) / (N 2)))-_testSlash_Rat1P2_IntN1 = Dict @((N 1 % 2) ~ ((P 1 % 2) / (N 1)))-_testSlash_Rat1P2_IntP1 = Dict @((P 1 % 2) ~ ((P 1 % 2) / (P 1)))-_testSlash_Rat1P2_IntP2 = Dict @((P 1 % 4) ~ ((P 1 % 2) / (P 2)))-_testSlash_Rat1P2_IntP3 = Dict @((P 1 % 6) ~ ((P 1 % 2) / (P 3)))-_testSlash_Rat1P2_IntP4 = Dict @((P 1 % 8) ~ ((P 1 % 2) / (P 4)))-_testSlash_Rat1P2_Rat4N1 = Dict @((N 1 % 8) ~ ((P 1 % 2) / (N 4 % 1)))-_testSlash_Rat1P2_Rat3N1 = Dict @((N 1 % 6) ~ ((P 1 % 2) / (N 3 % 1)))-_testSlash_Rat1P2_Rat2N1 = Dict @((N 1 % 4) ~ ((P 1 % 2) / (N 2 % 1)))-_testSlash_Rat1P2_Rat3N2 = Dict @((N 1 % 3) ~ ((P 1 % 2) / (N 3 % 2)))-_testSlash_Rat1P2_Rat4N3 = Dict @((N 3 % 8) ~ ((P 1 % 2) / (N 4 % 3)))-_testSlash_Rat1P2_Rat1N1 = Dict @((N 1 % 2) ~ ((P 1 % 2) / (N 1 % 1)))-_testSlash_Rat1P2_Rat3N4 = Dict @((N 2 % 3) ~ ((P 1 % 2) / (N 3 % 4)))-_testSlash_Rat1P2_Rat2N3 = Dict @((N 3 % 4) ~ ((P 1 % 2) / (N 2 % 3)))-_testSlash_Rat1P2_Rat1N2 = Dict @((N 1 % 1) ~ ((P 1 % 2) / (N 1 % 2)))-_testSlash_Rat1P2_Rat1N3 = Dict @((N 3 % 2) ~ ((P 1 % 2) / (N 1 % 3)))-_testSlash_Rat1P2_Rat1N4 = Dict @((N 2 % 1) ~ ((P 1 % 2) / (N 1 % 4)))-_testSlash_Rat1P2_Rat1P4 = Dict @((P 2 % 1) ~ ((P 1 % 2) / (P 1 % 4)))-_testSlash_Rat1P2_Rat1P3 = Dict @((P 3 % 2) ~ ((P 1 % 2) / (P 1 % 3)))-_testSlash_Rat1P2_Rat1P2 = Dict @((P 1 % 1) ~ ((P 1 % 2) / (P 1 % 2)))-_testSlash_Rat1P2_Rat2P3 = Dict @((P 3 % 4) ~ ((P 1 % 2) / (P 2 % 3)))-_testSlash_Rat1P2_Rat3P4 = Dict @((P 2 % 3) ~ ((P 1 % 2) / (P 3 % 4)))-_testSlash_Rat1P2_Rat1P1 = Dict @((P 1 % 2) ~ ((P 1 % 2) / (P 1 % 1)))-_testSlash_Rat1P2_Rat4P3 = Dict @((P 3 % 8) ~ ((P 1 % 2) / (P 4 % 3)))-_testSlash_Rat1P2_Rat3P2 = Dict @((P 1 % 3) ~ ((P 1 % 2) / (P 3 % 2)))-_testSlash_Rat1P2_Rat2P1 = Dict @((P 1 % 4) ~ ((P 1 % 2) / (P 2 % 1)))-_testSlash_Rat1P2_Rat3P1 = Dict @((P 1 % 6) ~ ((P 1 % 2) / (P 3 % 1)))-_testSlash_Rat1P2_Rat4P1 = Dict @((P 1 % 8) ~ ((P 1 % 2) / (P 4 % 1)))-_testSlash_Rat2P3_Nat1 = Dict @((P 2 % 3) ~ ((P 2 % 3) / 1))-_testSlash_Rat2P3_Nat2 = Dict @((P 1 % 3) ~ ((P 2 % 3) / 2))-_testSlash_Rat2P3_Nat3 = Dict @((P 2 % 9) ~ ((P 2 % 3) / 3))-_testSlash_Rat2P3_Nat4 = Dict @((P 1 % 6) ~ ((P 2 % 3) / 4))-_testSlash_Rat2P3_IntN4 = Dict @((N 1 % 6) ~ ((P 2 % 3) / (N 4)))-_testSlash_Rat2P3_IntN3 = Dict @((N 2 % 9) ~ ((P 2 % 3) / (N 3)))-_testSlash_Rat2P3_IntN2 = Dict @((N 1 % 3) ~ ((P 2 % 3) / (N 2)))-_testSlash_Rat2P3_IntN1 = Dict @((N 2 % 3) ~ ((P 2 % 3) / (N 1)))-_testSlash_Rat2P3_IntP1 = Dict @((P 2 % 3) ~ ((P 2 % 3) / (P 1)))-_testSlash_Rat2P3_IntP2 = Dict @((P 1 % 3) ~ ((P 2 % 3) / (P 2)))-_testSlash_Rat2P3_IntP3 = Dict @((P 2 % 9) ~ ((P 2 % 3) / (P 3)))-_testSlash_Rat2P3_IntP4 = Dict @((P 1 % 6) ~ ((P 2 % 3) / (P 4)))-_testSlash_Rat2P3_Rat4N1 = Dict @((N 1 % 6) ~ ((P 2 % 3) / (N 4 % 1)))-_testSlash_Rat2P3_Rat3N1 = Dict @((N 2 % 9) ~ ((P 2 % 3) / (N 3 % 1)))-_testSlash_Rat2P3_Rat2N1 = Dict @((N 1 % 3) ~ ((P 2 % 3) / (N 2 % 1)))-_testSlash_Rat2P3_Rat3N2 = Dict @((N 4 % 9) ~ ((P 2 % 3) / (N 3 % 2)))-_testSlash_Rat2P3_Rat4N3 = Dict @((N 1 % 2) ~ ((P 2 % 3) / (N 4 % 3)))-_testSlash_Rat2P3_Rat1N1 = Dict @((N 2 % 3) ~ ((P 2 % 3) / (N 1 % 1)))-_testSlash_Rat2P3_Rat3N4 = Dict @((N 8 % 9) ~ ((P 2 % 3) / (N 3 % 4)))-_testSlash_Rat2P3_Rat2N3 = Dict @((N 1 % 1) ~ ((P 2 % 3) / (N 2 % 3)))-_testSlash_Rat2P3_Rat1N2 = Dict @((N 4 % 3) ~ ((P 2 % 3) / (N 1 % 2)))-_testSlash_Rat2P3_Rat1N3 = Dict @((N 2 % 1) ~ ((P 2 % 3) / (N 1 % 3)))-_testSlash_Rat2P3_Rat1N4 = Dict @((N 8 % 3) ~ ((P 2 % 3) / (N 1 % 4)))-_testSlash_Rat2P3_Rat1P4 = Dict @((P 8 % 3) ~ ((P 2 % 3) / (P 1 % 4)))-_testSlash_Rat2P3_Rat1P3 = Dict @((P 2 % 1) ~ ((P 2 % 3) / (P 1 % 3)))-_testSlash_Rat2P3_Rat1P2 = Dict @((P 4 % 3) ~ ((P 2 % 3) / (P 1 % 2)))-_testSlash_Rat2P3_Rat2P3 = Dict @((P 1 % 1) ~ ((P 2 % 3) / (P 2 % 3)))-_testSlash_Rat2P3_Rat3P4 = Dict @((P 8 % 9) ~ ((P 2 % 3) / (P 3 % 4)))-_testSlash_Rat2P3_Rat1P1 = Dict @((P 2 % 3) ~ ((P 2 % 3) / (P 1 % 1)))-_testSlash_Rat2P3_Rat4P3 = Dict @((P 1 % 2) ~ ((P 2 % 3) / (P 4 % 3)))-_testSlash_Rat2P3_Rat3P2 = Dict @((P 4 % 9) ~ ((P 2 % 3) / (P 3 % 2)))-_testSlash_Rat2P3_Rat2P1 = Dict @((P 1 % 3) ~ ((P 2 % 3) / (P 2 % 1)))-_testSlash_Rat2P3_Rat3P1 = Dict @((P 2 % 9) ~ ((P 2 % 3) / (P 3 % 1)))-_testSlash_Rat2P3_Rat4P1 = Dict @((P 1 % 6) ~ ((P 2 % 3) / (P 4 % 1)))-_testSlash_Rat3P4_Nat1 = Dict @((P 3 % 4) ~ ((P 3 % 4) / 1))-_testSlash_Rat3P4_Nat2 = Dict @((P 3 % 8) ~ ((P 3 % 4) / 2))-_testSlash_Rat3P4_Nat3 = Dict @((P 1 % 4) ~ ((P 3 % 4) / 3))-_testSlash_Rat3P4_Nat4 = Dict @((P 3 % 16) ~ ((P 3 % 4) / 4))-_testSlash_Rat3P4_IntN4 = Dict @((N 3 % 16) ~ ((P 3 % 4) / (N 4)))-_testSlash_Rat3P4_IntN3 = Dict @((N 1 % 4) ~ ((P 3 % 4) / (N 3)))-_testSlash_Rat3P4_IntN2 = Dict @((N 3 % 8) ~ ((P 3 % 4) / (N 2)))-_testSlash_Rat3P4_IntN1 = Dict @((N 3 % 4) ~ ((P 3 % 4) / (N 1)))-_testSlash_Rat3P4_IntP1 = Dict @((P 3 % 4) ~ ((P 3 % 4) / (P 1)))-_testSlash_Rat3P4_IntP2 = Dict @((P 3 % 8) ~ ((P 3 % 4) / (P 2)))-_testSlash_Rat3P4_IntP3 = Dict @((P 1 % 4) ~ ((P 3 % 4) / (P 3)))-_testSlash_Rat3P4_IntP4 = Dict @((P 3 % 16) ~ ((P 3 % 4) / (P 4)))-_testSlash_Rat3P4_Rat4N1 = Dict @((N 3 % 16) ~ ((P 3 % 4) / (N 4 % 1)))-_testSlash_Rat3P4_Rat3N1 = Dict @((N 1 % 4) ~ ((P 3 % 4) / (N 3 % 1)))-_testSlash_Rat3P4_Rat2N1 = Dict @((N 3 % 8) ~ ((P 3 % 4) / (N 2 % 1)))-_testSlash_Rat3P4_Rat3N2 = Dict @((N 1 % 2) ~ ((P 3 % 4) / (N 3 % 2)))-_testSlash_Rat3P4_Rat4N3 = Dict @((N 9 % 16) ~ ((P 3 % 4) / (N 4 % 3)))-_testSlash_Rat3P4_Rat1N1 = Dict @((N 3 % 4) ~ ((P 3 % 4) / (N 1 % 1)))-_testSlash_Rat3P4_Rat3N4 = Dict @((N 1 % 1) ~ ((P 3 % 4) / (N 3 % 4)))-_testSlash_Rat3P4_Rat2N3 = Dict @((N 9 % 8) ~ ((P 3 % 4) / (N 2 % 3)))-_testSlash_Rat3P4_Rat1N2 = Dict @((N 3 % 2) ~ ((P 3 % 4) / (N 1 % 2)))-_testSlash_Rat3P4_Rat1N3 = Dict @((N 9 % 4) ~ ((P 3 % 4) / (N 1 % 3)))-_testSlash_Rat3P4_Rat1N4 = Dict @((N 3 % 1) ~ ((P 3 % 4) / (N 1 % 4)))-_testSlash_Rat3P4_Rat1P4 = Dict @((P 3 % 1) ~ ((P 3 % 4) / (P 1 % 4)))-_testSlash_Rat3P4_Rat1P3 = Dict @((P 9 % 4) ~ ((P 3 % 4) / (P 1 % 3)))-_testSlash_Rat3P4_Rat1P2 = Dict @((P 3 % 2) ~ ((P 3 % 4) / (P 1 % 2)))-_testSlash_Rat3P4_Rat2P3 = Dict @((P 9 % 8) ~ ((P 3 % 4) / (P 2 % 3)))-_testSlash_Rat3P4_Rat3P4 = Dict @((P 1 % 1) ~ ((P 3 % 4) / (P 3 % 4)))-_testSlash_Rat3P4_Rat1P1 = Dict @((P 3 % 4) ~ ((P 3 % 4) / (P 1 % 1)))-_testSlash_Rat3P4_Rat4P3 = Dict @((P 9 % 16) ~ ((P 3 % 4) / (P 4 % 3)))-_testSlash_Rat3P4_Rat3P2 = Dict @((P 1 % 2) ~ ((P 3 % 4) / (P 3 % 2)))-_testSlash_Rat3P4_Rat2P1 = Dict @((P 3 % 8) ~ ((P 3 % 4) / (P 2 % 1)))-_testSlash_Rat3P4_Rat3P1 = Dict @((P 1 % 4) ~ ((P 3 % 4) / (P 3 % 1)))-_testSlash_Rat3P4_Rat4P1 = Dict @((P 3 % 16) ~ ((P 3 % 4) / (P 4 % 1)))-_testSlash_Rat1P1_Nat1 = Dict @((P 1 % 1) ~ ((P 1 % 1) / 1))-_testSlash_Rat1P1_Nat2 = Dict @((P 1 % 2) ~ ((P 1 % 1) / 2))-_testSlash_Rat1P1_Nat3 = Dict @((P 1 % 3) ~ ((P 1 % 1) / 3))-_testSlash_Rat1P1_Nat4 = Dict @((P 1 % 4) ~ ((P 1 % 1) / 4))-_testSlash_Rat1P1_IntN4 = Dict @((N 1 % 4) ~ ((P 1 % 1) / (N 4)))-_testSlash_Rat1P1_IntN3 = Dict @((N 1 % 3) ~ ((P 1 % 1) / (N 3)))-_testSlash_Rat1P1_IntN2 = Dict @((N 1 % 2) ~ ((P 1 % 1) / (N 2)))-_testSlash_Rat1P1_IntN1 = Dict @((N 1 % 1) ~ ((P 1 % 1) / (N 1)))-_testSlash_Rat1P1_IntP1 = Dict @((P 1 % 1) ~ ((P 1 % 1) / (P 1)))-_testSlash_Rat1P1_IntP2 = Dict @((P 1 % 2) ~ ((P 1 % 1) / (P 2)))-_testSlash_Rat1P1_IntP3 = Dict @((P 1 % 3) ~ ((P 1 % 1) / (P 3)))-_testSlash_Rat1P1_IntP4 = Dict @((P 1 % 4) ~ ((P 1 % 1) / (P 4)))-_testSlash_Rat1P1_Rat4N1 = Dict @((N 1 % 4) ~ ((P 1 % 1) / (N 4 % 1)))-_testSlash_Rat1P1_Rat3N1 = Dict @((N 1 % 3) ~ ((P 1 % 1) / (N 3 % 1)))-_testSlash_Rat1P1_Rat2N1 = Dict @((N 1 % 2) ~ ((P 1 % 1) / (N 2 % 1)))-_testSlash_Rat1P1_Rat3N2 = Dict @((N 2 % 3) ~ ((P 1 % 1) / (N 3 % 2)))-_testSlash_Rat1P1_Rat4N3 = Dict @((N 3 % 4) ~ ((P 1 % 1) / (N 4 % 3)))-_testSlash_Rat1P1_Rat1N1 = Dict @((N 1 % 1) ~ ((P 1 % 1) / (N 1 % 1)))-_testSlash_Rat1P1_Rat3N4 = Dict @((N 4 % 3) ~ ((P 1 % 1) / (N 3 % 4)))-_testSlash_Rat1P1_Rat2N3 = Dict @((N 3 % 2) ~ ((P 1 % 1) / (N 2 % 3)))-_testSlash_Rat1P1_Rat1N2 = Dict @((N 2 % 1) ~ ((P 1 % 1) / (N 1 % 2)))-_testSlash_Rat1P1_Rat1N3 = Dict @((N 3 % 1) ~ ((P 1 % 1) / (N 1 % 3)))-_testSlash_Rat1P1_Rat1N4 = Dict @((N 4 % 1) ~ ((P 1 % 1) / (N 1 % 4)))-_testSlash_Rat1P1_Rat1P4 = Dict @((P 4 % 1) ~ ((P 1 % 1) / (P 1 % 4)))-_testSlash_Rat1P1_Rat1P3 = Dict @((P 3 % 1) ~ ((P 1 % 1) / (P 1 % 3)))-_testSlash_Rat1P1_Rat1P2 = Dict @((P 2 % 1) ~ ((P 1 % 1) / (P 1 % 2)))-_testSlash_Rat1P1_Rat2P3 = Dict @((P 3 % 2) ~ ((P 1 % 1) / (P 2 % 3)))-_testSlash_Rat1P1_Rat3P4 = Dict @((P 4 % 3) ~ ((P 1 % 1) / (P 3 % 4)))-_testSlash_Rat1P1_Rat1P1 = Dict @((P 1 % 1) ~ ((P 1 % 1) / (P 1 % 1)))-_testSlash_Rat1P1_Rat4P3 = Dict @((P 3 % 4) ~ ((P 1 % 1) / (P 4 % 3)))-_testSlash_Rat1P1_Rat3P2 = Dict @((P 2 % 3) ~ ((P 1 % 1) / (P 3 % 2)))-_testSlash_Rat1P1_Rat2P1 = Dict @((P 1 % 2) ~ ((P 1 % 1) / (P 2 % 1)))-_testSlash_Rat1P1_Rat3P1 = Dict @((P 1 % 3) ~ ((P 1 % 1) / (P 3 % 1)))-_testSlash_Rat1P1_Rat4P1 = Dict @((P 1 % 4) ~ ((P 1 % 1) / (P 4 % 1)))-_testSlash_Rat4P3_Nat1 = Dict @((P 4 % 3) ~ ((P 4 % 3) / 1))-_testSlash_Rat4P3_Nat2 = Dict @((P 2 % 3) ~ ((P 4 % 3) / 2))-_testSlash_Rat4P3_Nat3 = Dict @((P 4 % 9) ~ ((P 4 % 3) / 3))-_testSlash_Rat4P3_Nat4 = Dict @((P 1 % 3) ~ ((P 4 % 3) / 4))-_testSlash_Rat4P3_IntN4 = Dict @((N 1 % 3) ~ ((P 4 % 3) / (N 4)))-_testSlash_Rat4P3_IntN3 = Dict @((N 4 % 9) ~ ((P 4 % 3) / (N 3)))-_testSlash_Rat4P3_IntN2 = Dict @((N 2 % 3) ~ ((P 4 % 3) / (N 2)))-_testSlash_Rat4P3_IntN1 = Dict @((N 4 % 3) ~ ((P 4 % 3) / (N 1)))-_testSlash_Rat4P3_IntP1 = Dict @((P 4 % 3) ~ ((P 4 % 3) / (P 1)))-_testSlash_Rat4P3_IntP2 = Dict @((P 2 % 3) ~ ((P 4 % 3) / (P 2)))-_testSlash_Rat4P3_IntP3 = Dict @((P 4 % 9) ~ ((P 4 % 3) / (P 3)))-_testSlash_Rat4P3_IntP4 = Dict @((P 1 % 3) ~ ((P 4 % 3) / (P 4)))-_testSlash_Rat4P3_Rat4N1 = Dict @((N 1 % 3) ~ ((P 4 % 3) / (N 4 % 1)))-_testSlash_Rat4P3_Rat3N1 = Dict @((N 4 % 9) ~ ((P 4 % 3) / (N 3 % 1)))-_testSlash_Rat4P3_Rat2N1 = Dict @((N 2 % 3) ~ ((P 4 % 3) / (N 2 % 1)))-_testSlash_Rat4P3_Rat3N2 = Dict @((N 8 % 9) ~ ((P 4 % 3) / (N 3 % 2)))-_testSlash_Rat4P3_Rat4N3 = Dict @((N 1 % 1) ~ ((P 4 % 3) / (N 4 % 3)))-_testSlash_Rat4P3_Rat1N1 = Dict @((N 4 % 3) ~ ((P 4 % 3) / (N 1 % 1)))-_testSlash_Rat4P3_Rat3N4 = Dict @((N 16 % 9) ~ ((P 4 % 3) / (N 3 % 4)))-_testSlash_Rat4P3_Rat2N3 = Dict @((N 2 % 1) ~ ((P 4 % 3) / (N 2 % 3)))-_testSlash_Rat4P3_Rat1N2 = Dict @((N 8 % 3) ~ ((P 4 % 3) / (N 1 % 2)))-_testSlash_Rat4P3_Rat1N3 = Dict @((N 4 % 1) ~ ((P 4 % 3) / (N 1 % 3)))-_testSlash_Rat4P3_Rat1N4 = Dict @((N 16 % 3) ~ ((P 4 % 3) / (N 1 % 4)))-_testSlash_Rat4P3_Rat1P4 = Dict @((P 16 % 3) ~ ((P 4 % 3) / (P 1 % 4)))-_testSlash_Rat4P3_Rat1P3 = Dict @((P 4 % 1) ~ ((P 4 % 3) / (P 1 % 3)))-_testSlash_Rat4P3_Rat1P2 = Dict @((P 8 % 3) ~ ((P 4 % 3) / (P 1 % 2)))-_testSlash_Rat4P3_Rat2P3 = Dict @((P 2 % 1) ~ ((P 4 % 3) / (P 2 % 3)))-_testSlash_Rat4P3_Rat3P4 = Dict @((P 16 % 9) ~ ((P 4 % 3) / (P 3 % 4)))-_testSlash_Rat4P3_Rat1P1 = Dict @((P 4 % 3) ~ ((P 4 % 3) / (P 1 % 1)))-_testSlash_Rat4P3_Rat4P3 = Dict @((P 1 % 1) ~ ((P 4 % 3) / (P 4 % 3)))-_testSlash_Rat4P3_Rat3P2 = Dict @((P 8 % 9) ~ ((P 4 % 3) / (P 3 % 2)))-_testSlash_Rat4P3_Rat2P1 = Dict @((P 2 % 3) ~ ((P 4 % 3) / (P 2 % 1)))-_testSlash_Rat4P3_Rat3P1 = Dict @((P 4 % 9) ~ ((P 4 % 3) / (P 3 % 1)))-_testSlash_Rat4P3_Rat4P1 = Dict @((P 1 % 3) ~ ((P 4 % 3) / (P 4 % 1)))-_testSlash_Rat3P2_Nat1 = Dict @((P 3 % 2) ~ ((P 3 % 2) / 1))-_testSlash_Rat3P2_Nat2 = Dict @((P 3 % 4) ~ ((P 3 % 2) / 2))-_testSlash_Rat3P2_Nat3 = Dict @((P 1 % 2) ~ ((P 3 % 2) / 3))-_testSlash_Rat3P2_Nat4 = Dict @((P 3 % 8) ~ ((P 3 % 2) / 4))-_testSlash_Rat3P2_IntN4 = Dict @((N 3 % 8) ~ ((P 3 % 2) / (N 4)))-_testSlash_Rat3P2_IntN3 = Dict @((N 1 % 2) ~ ((P 3 % 2) / (N 3)))-_testSlash_Rat3P2_IntN2 = Dict @((N 3 % 4) ~ ((P 3 % 2) / (N 2)))-_testSlash_Rat3P2_IntN1 = Dict @((N 3 % 2) ~ ((P 3 % 2) / (N 1)))-_testSlash_Rat3P2_IntP1 = Dict @((P 3 % 2) ~ ((P 3 % 2) / (P 1)))-_testSlash_Rat3P2_IntP2 = Dict @((P 3 % 4) ~ ((P 3 % 2) / (P 2)))-_testSlash_Rat3P2_IntP3 = Dict @((P 1 % 2) ~ ((P 3 % 2) / (P 3)))-_testSlash_Rat3P2_IntP4 = Dict @((P 3 % 8) ~ ((P 3 % 2) / (P 4)))-_testSlash_Rat3P2_Rat4N1 = Dict @((N 3 % 8) ~ ((P 3 % 2) / (N 4 % 1)))-_testSlash_Rat3P2_Rat3N1 = Dict @((N 1 % 2) ~ ((P 3 % 2) / (N 3 % 1)))-_testSlash_Rat3P2_Rat2N1 = Dict @((N 3 % 4) ~ ((P 3 % 2) / (N 2 % 1)))-_testSlash_Rat3P2_Rat3N2 = Dict @((N 1 % 1) ~ ((P 3 % 2) / (N 3 % 2)))-_testSlash_Rat3P2_Rat4N3 = Dict @((N 9 % 8) ~ ((P 3 % 2) / (N 4 % 3)))-_testSlash_Rat3P2_Rat1N1 = Dict @((N 3 % 2) ~ ((P 3 % 2) / (N 1 % 1)))-_testSlash_Rat3P2_Rat3N4 = Dict @((N 2 % 1) ~ ((P 3 % 2) / (N 3 % 4)))-_testSlash_Rat3P2_Rat2N3 = Dict @((N 9 % 4) ~ ((P 3 % 2) / (N 2 % 3)))-_testSlash_Rat3P2_Rat1N2 = Dict @((N 3 % 1) ~ ((P 3 % 2) / (N 1 % 2)))-_testSlash_Rat3P2_Rat1N3 = Dict @((N 9 % 2) ~ ((P 3 % 2) / (N 1 % 3)))-_testSlash_Rat3P2_Rat1N4 = Dict @((N 6 % 1) ~ ((P 3 % 2) / (N 1 % 4)))-_testSlash_Rat3P2_Rat1P4 = Dict @((P 6 % 1) ~ ((P 3 % 2) / (P 1 % 4)))-_testSlash_Rat3P2_Rat1P3 = Dict @((P 9 % 2) ~ ((P 3 % 2) / (P 1 % 3)))-_testSlash_Rat3P2_Rat1P2 = Dict @((P 3 % 1) ~ ((P 3 % 2) / (P 1 % 2)))-_testSlash_Rat3P2_Rat2P3 = Dict @((P 9 % 4) ~ ((P 3 % 2) / (P 2 % 3)))-_testSlash_Rat3P2_Rat3P4 = Dict @((P 2 % 1) ~ ((P 3 % 2) / (P 3 % 4)))-_testSlash_Rat3P2_Rat1P1 = Dict @((P 3 % 2) ~ ((P 3 % 2) / (P 1 % 1)))-_testSlash_Rat3P2_Rat4P3 = Dict @((P 9 % 8) ~ ((P 3 % 2) / (P 4 % 3)))-_testSlash_Rat3P2_Rat3P2 = Dict @((P 1 % 1) ~ ((P 3 % 2) / (P 3 % 2)))-_testSlash_Rat3P2_Rat2P1 = Dict @((P 3 % 4) ~ ((P 3 % 2) / (P 2 % 1)))-_testSlash_Rat3P2_Rat3P1 = Dict @((P 1 % 2) ~ ((P 3 % 2) / (P 3 % 1)))-_testSlash_Rat3P2_Rat4P1 = Dict @((P 3 % 8) ~ ((P 3 % 2) / (P 4 % 1)))-_testSlash_Rat2P1_Nat1 = Dict @((P 2 % 1) ~ ((P 2 % 1) / 1))-_testSlash_Rat2P1_Nat2 = Dict @((P 1 % 1) ~ ((P 2 % 1) / 2))-_testSlash_Rat2P1_Nat3 = Dict @((P 2 % 3) ~ ((P 2 % 1) / 3))-_testSlash_Rat2P1_Nat4 = Dict @((P 1 % 2) ~ ((P 2 % 1) / 4))-_testSlash_Rat2P1_IntN4 = Dict @((N 1 % 2) ~ ((P 2 % 1) / (N 4)))-_testSlash_Rat2P1_IntN3 = Dict @((N 2 % 3) ~ ((P 2 % 1) / (N 3)))-_testSlash_Rat2P1_IntN2 = Dict @((N 1 % 1) ~ ((P 2 % 1) / (N 2)))-_testSlash_Rat2P1_IntN1 = Dict @((N 2 % 1) ~ ((P 2 % 1) / (N 1)))-_testSlash_Rat2P1_IntP1 = Dict @((P 2 % 1) ~ ((P 2 % 1) / (P 1)))-_testSlash_Rat2P1_IntP2 = Dict @((P 1 % 1) ~ ((P 2 % 1) / (P 2)))-_testSlash_Rat2P1_IntP3 = Dict @((P 2 % 3) ~ ((P 2 % 1) / (P 3)))-_testSlash_Rat2P1_IntP4 = Dict @((P 1 % 2) ~ ((P 2 % 1) / (P 4)))-_testSlash_Rat2P1_Rat4N1 = Dict @((N 1 % 2) ~ ((P 2 % 1) / (N 4 % 1)))-_testSlash_Rat2P1_Rat3N1 = Dict @((N 2 % 3) ~ ((P 2 % 1) / (N 3 % 1)))-_testSlash_Rat2P1_Rat2N1 = Dict @((N 1 % 1) ~ ((P 2 % 1) / (N 2 % 1)))-_testSlash_Rat2P1_Rat3N2 = Dict @((N 4 % 3) ~ ((P 2 % 1) / (N 3 % 2)))-_testSlash_Rat2P1_Rat4N3 = Dict @((N 3 % 2) ~ ((P 2 % 1) / (N 4 % 3)))-_testSlash_Rat2P1_Rat1N1 = Dict @((N 2 % 1) ~ ((P 2 % 1) / (N 1 % 1)))-_testSlash_Rat2P1_Rat3N4 = Dict @((N 8 % 3) ~ ((P 2 % 1) / (N 3 % 4)))-_testSlash_Rat2P1_Rat2N3 = Dict @((N 3 % 1) ~ ((P 2 % 1) / (N 2 % 3)))-_testSlash_Rat2P1_Rat1N2 = Dict @((N 4 % 1) ~ ((P 2 % 1) / (N 1 % 2)))-_testSlash_Rat2P1_Rat1N3 = Dict @((N 6 % 1) ~ ((P 2 % 1) / (N 1 % 3)))-_testSlash_Rat2P1_Rat1N4 = Dict @((N 8 % 1) ~ ((P 2 % 1) / (N 1 % 4)))-_testSlash_Rat2P1_Rat1P4 = Dict @((P 8 % 1) ~ ((P 2 % 1) / (P 1 % 4)))-_testSlash_Rat2P1_Rat1P3 = Dict @((P 6 % 1) ~ ((P 2 % 1) / (P 1 % 3)))-_testSlash_Rat2P1_Rat1P2 = Dict @((P 4 % 1) ~ ((P 2 % 1) / (P 1 % 2)))-_testSlash_Rat2P1_Rat2P3 = Dict @((P 3 % 1) ~ ((P 2 % 1) / (P 2 % 3)))-_testSlash_Rat2P1_Rat3P4 = Dict @((P 8 % 3) ~ ((P 2 % 1) / (P 3 % 4)))-_testSlash_Rat2P1_Rat1P1 = Dict @((P 2 % 1) ~ ((P 2 % 1) / (P 1 % 1)))-_testSlash_Rat2P1_Rat4P3 = Dict @((P 3 % 2) ~ ((P 2 % 1) / (P 4 % 3)))-_testSlash_Rat2P1_Rat3P2 = Dict @((P 4 % 3) ~ ((P 2 % 1) / (P 3 % 2)))-_testSlash_Rat2P1_Rat2P1 = Dict @((P 1 % 1) ~ ((P 2 % 1) / (P 2 % 1)))-_testSlash_Rat2P1_Rat3P1 = Dict @((P 2 % 3) ~ ((P 2 % 1) / (P 3 % 1)))-_testSlash_Rat2P1_Rat4P1 = Dict @((P 1 % 2) ~ ((P 2 % 1) / (P 4 % 1)))-_testSlash_Rat3P1_Nat1 = Dict @((P 3 % 1) ~ ((P 3 % 1) / 1))-_testSlash_Rat3P1_Nat2 = Dict @((P 3 % 2) ~ ((P 3 % 1) / 2))-_testSlash_Rat3P1_Nat3 = Dict @((P 1 % 1) ~ ((P 3 % 1) / 3))-_testSlash_Rat3P1_Nat4 = Dict @((P 3 % 4) ~ ((P 3 % 1) / 4))-_testSlash_Rat3P1_IntN4 = Dict @((N 3 % 4) ~ ((P 3 % 1) / (N 4)))-_testSlash_Rat3P1_IntN3 = Dict @((N 1 % 1) ~ ((P 3 % 1) / (N 3)))-_testSlash_Rat3P1_IntN2 = Dict @((N 3 % 2) ~ ((P 3 % 1) / (N 2)))-_testSlash_Rat3P1_IntN1 = Dict @((N 3 % 1) ~ ((P 3 % 1) / (N 1)))-_testSlash_Rat3P1_IntP1 = Dict @((P 3 % 1) ~ ((P 3 % 1) / (P 1)))-_testSlash_Rat3P1_IntP2 = Dict @((P 3 % 2) ~ ((P 3 % 1) / (P 2)))-_testSlash_Rat3P1_IntP3 = Dict @((P 1 % 1) ~ ((P 3 % 1) / (P 3)))-_testSlash_Rat3P1_IntP4 = Dict @((P 3 % 4) ~ ((P 3 % 1) / (P 4)))-_testSlash_Rat3P1_Rat4N1 = Dict @((N 3 % 4) ~ ((P 3 % 1) / (N 4 % 1)))-_testSlash_Rat3P1_Rat3N1 = Dict @((N 1 % 1) ~ ((P 3 % 1) / (N 3 % 1)))-_testSlash_Rat3P1_Rat2N1 = Dict @((N 3 % 2) ~ ((P 3 % 1) / (N 2 % 1)))-_testSlash_Rat3P1_Rat3N2 = Dict @((N 2 % 1) ~ ((P 3 % 1) / (N 3 % 2)))-_testSlash_Rat3P1_Rat4N3 = Dict @((N 9 % 4) ~ ((P 3 % 1) / (N 4 % 3)))-_testSlash_Rat3P1_Rat1N1 = Dict @((N 3 % 1) ~ ((P 3 % 1) / (N 1 % 1)))-_testSlash_Rat3P1_Rat3N4 = Dict @((N 4 % 1) ~ ((P 3 % 1) / (N 3 % 4)))-_testSlash_Rat3P1_Rat2N3 = Dict @((N 9 % 2) ~ ((P 3 % 1) / (N 2 % 3)))-_testSlash_Rat3P1_Rat1N2 = Dict @((N 6 % 1) ~ ((P 3 % 1) / (N 1 % 2)))-_testSlash_Rat3P1_Rat1N3 = Dict @((N 9 % 1) ~ ((P 3 % 1) / (N 1 % 3)))-_testSlash_Rat3P1_Rat1N4 = Dict @((N 12 % 1) ~ ((P 3 % 1) / (N 1 % 4)))-_testSlash_Rat3P1_Rat1P4 = Dict @((P 12 % 1) ~ ((P 3 % 1) / (P 1 % 4)))-_testSlash_Rat3P1_Rat1P3 = Dict @((P 9 % 1) ~ ((P 3 % 1) / (P 1 % 3)))-_testSlash_Rat3P1_Rat1P2 = Dict @((P 6 % 1) ~ ((P 3 % 1) / (P 1 % 2)))-_testSlash_Rat3P1_Rat2P3 = Dict @((P 9 % 2) ~ ((P 3 % 1) / (P 2 % 3)))-_testSlash_Rat3P1_Rat3P4 = Dict @((P 4 % 1) ~ ((P 3 % 1) / (P 3 % 4)))-_testSlash_Rat3P1_Rat1P1 = Dict @((P 3 % 1) ~ ((P 3 % 1) / (P 1 % 1)))-_testSlash_Rat3P1_Rat4P3 = Dict @((P 9 % 4) ~ ((P 3 % 1) / (P 4 % 3)))-_testSlash_Rat3P1_Rat3P2 = Dict @((P 2 % 1) ~ ((P 3 % 1) / (P 3 % 2)))-_testSlash_Rat3P1_Rat2P1 = Dict @((P 3 % 2) ~ ((P 3 % 1) / (P 2 % 1)))-_testSlash_Rat3P1_Rat3P1 = Dict @((P 1 % 1) ~ ((P 3 % 1) / (P 3 % 1)))-_testSlash_Rat3P1_Rat4P1 = Dict @((P 3 % 4) ~ ((P 3 % 1) / (P 4 % 1)))-_testSlash_Rat4P1_Nat1 = Dict @((P 4 % 1) ~ ((P 4 % 1) / 1))-_testSlash_Rat4P1_Nat2 = Dict @((P 2 % 1) ~ ((P 4 % 1) / 2))-_testSlash_Rat4P1_Nat3 = Dict @((P 4 % 3) ~ ((P 4 % 1) / 3))-_testSlash_Rat4P1_Nat4 = Dict @((P 1 % 1) ~ ((P 4 % 1) / 4))-_testSlash_Rat4P1_IntN4 = Dict @((N 1 % 1) ~ ((P 4 % 1) / (N 4)))-_testSlash_Rat4P1_IntN3 = Dict @((N 4 % 3) ~ ((P 4 % 1) / (N 3)))-_testSlash_Rat4P1_IntN2 = Dict @((N 2 % 1) ~ ((P 4 % 1) / (N 2)))-_testSlash_Rat4P1_IntN1 = Dict @((N 4 % 1) ~ ((P 4 % 1) / (N 1)))-_testSlash_Rat4P1_IntP1 = Dict @((P 4 % 1) ~ ((P 4 % 1) / (P 1)))-_testSlash_Rat4P1_IntP2 = Dict @((P 2 % 1) ~ ((P 4 % 1) / (P 2)))-_testSlash_Rat4P1_IntP3 = Dict @((P 4 % 3) ~ ((P 4 % 1) / (P 3)))-_testSlash_Rat4P1_IntP4 = Dict @((P 1 % 1) ~ ((P 4 % 1) / (P 4)))-_testSlash_Rat4P1_Rat4N1 = Dict @((N 1 % 1) ~ ((P 4 % 1) / (N 4 % 1)))-_testSlash_Rat4P1_Rat3N1 = Dict @((N 4 % 3) ~ ((P 4 % 1) / (N 3 % 1)))-_testSlash_Rat4P1_Rat2N1 = Dict @((N 2 % 1) ~ ((P 4 % 1) / (N 2 % 1)))-_testSlash_Rat4P1_Rat3N2 = Dict @((N 8 % 3) ~ ((P 4 % 1) / (N 3 % 2)))-_testSlash_Rat4P1_Rat4N3 = Dict @((N 3 % 1) ~ ((P 4 % 1) / (N 4 % 3)))-_testSlash_Rat4P1_Rat1N1 = Dict @((N 4 % 1) ~ ((P 4 % 1) / (N 1 % 1)))-_testSlash_Rat4P1_Rat3N4 = Dict @((N 16 % 3) ~ ((P 4 % 1) / (N 3 % 4)))-_testSlash_Rat4P1_Rat2N3 = Dict @((N 6 % 1) ~ ((P 4 % 1) / (N 2 % 3)))-_testSlash_Rat4P1_Rat1N2 = Dict @((N 8 % 1) ~ ((P 4 % 1) / (N 1 % 2)))-_testSlash_Rat4P1_Rat1N3 = Dict @((N 12 % 1) ~ ((P 4 % 1) / (N 1 % 3)))-_testSlash_Rat4P1_Rat1N4 = Dict @((N 16 % 1) ~ ((P 4 % 1) / (N 1 % 4)))-_testSlash_Rat4P1_Rat1P4 = Dict @((P 16 % 1) ~ ((P 4 % 1) / (P 1 % 4)))-_testSlash_Rat4P1_Rat1P3 = Dict @((P 12 % 1) ~ ((P 4 % 1) / (P 1 % 3)))-_testSlash_Rat4P1_Rat1P2 = Dict @((P 8 % 1) ~ ((P 4 % 1) / (P 1 % 2)))-_testSlash_Rat4P1_Rat2P3 = Dict @((P 6 % 1) ~ ((P 4 % 1) / (P 2 % 3)))-_testSlash_Rat4P1_Rat3P4 = Dict @((P 16 % 3) ~ ((P 4 % 1) / (P 3 % 4)))-_testSlash_Rat4P1_Rat1P1 = Dict @((P 4 % 1) ~ ((P 4 % 1) / (P 1 % 1)))-_testSlash_Rat4P1_Rat4P3 = Dict @((P 3 % 1) ~ ((P 4 % 1) / (P 4 % 3)))-_testSlash_Rat4P1_Rat3P2 = Dict @((P 8 % 3) ~ ((P 4 % 1) / (P 3 % 2)))-_testSlash_Rat4P1_Rat2P1 = Dict @((P 2 % 1) ~ ((P 4 % 1) / (P 2 % 1)))-_testSlash_Rat4P1_Rat3P1 = Dict @((P 4 % 3) ~ ((P 4 % 1) / (P 3 % 1)))-_testSlash_Rat4P1_Rat4P1 = Dict @((P 1 % 1) ~ ((P 4 % 1) / (P 4 % 1)))+import Data.Singletons+import Data.Type.Equality (TestEquality(..))+import Data.Type.Ord (type (<=), type (<))+import GHC.Exts (Constraint)+import GHC.Show (appPrec, appPrec1)+import Numeric.Natural (Natural)+import System.Exit+import Text.Read (readMaybe, readPrec_to_S)+import GHC.Real qualified as P+import Prelude hiding (Rational, Integer)+import Prelude qualified as P+import Prelude.Singletons qualified as P++import KindInteger (P, N, Z)+import KindInteger qualified as KI+import KindRational (type (%), type (:%))+import KindRational qualified as K++--------------------------------------------------------------------------------++data Dict (c :: Constraint) where+ Dict :: c => Dict c++--------------------------------------------------------------------------------+_testNum = Dict+_testNum :: Dict+ ( K.Num (Z :% 1) ~ Z+ , K.Num (P 1 :% 1) ~ P 1+ , K.Num (P 2 :% 1) ~ P 2+ , K.Num (N 1 :% 1) ~ N 1+ , K.Num (N 2 :% 1) ~ N 2+ )++_testDen = Dict+_testDen :: Dict+ ( K.Den (Z :% 1) ~ 1+ , K.Den (P 1 :% 1) ~ 1+ , K.Den (P 2 :% 1) ~ 1+ , K.Den (N 1 :% 1) ~ 1+ , K.Den (N 2 :% 1) ~ 1+ , K.Den (P 1 :% 2) ~ 2+ , K.Den (N 1 :% 2) ~ 2+ )++_testShow = Dict+_testShow :: Dict+ ( P.Show_ (Z :% 1) ~ "0 % 1"+ , P.Show_ (P 1 :% 1) ~ "1 % 1"+ , P.Show_ (N 2 :% 1) ~ "(-2) % 1"+ )++_testShowLit = Dict+_testShowLit :: Dict+ ( K.ShowLit (Z :% 1) ~ "Z :% 1"+ , K.ShowLit (P 1 :% 1) ~ "P 1 :% 1"+ , K.ShowLit (N 2 :% 1) ~ "N 2 :% 1"+ )++_testFromNatural = Dict+_testFromNatural :: Dict+ ( Z :% 1 ~ K.FromNatural 0+ , P 1 :% 1 ~ K.FromNatural 1+ , P 2 :% 1 ~ K.FromNatural 2+ )++_testFromInteger = Dict+_testFromInteger :: Dict+ ( Z :% 1 ~ K.FromInteger Z+ , P 1 :% 1 ~ K.FromInteger (P 1)+ , P 2 :% 1 ~ K.FromInteger (P 2)+ , N 1 :% 1 ~ K.FromInteger (N 1)+ , N 2 :% 1 ~ K.FromInteger (N 2)+ )++_testReduced = Dict+_testReduced :: Dict+ ( Z :% 1 ~ K.Reduced (Z :% 1)+ , P 1 :% 1 ~ K.Reduced (P 1 :% 1)+ , P 2 :% 1 ~ K.Reduced (P 2 :% 1)+ , P 3 :% 1 ~ K.Reduced (P 3 :% 1)+ , P 4 :% 1 ~ K.Reduced (P 4 :% 1)+ , P 3 :% 2 ~ K.Reduced (P 3 :% 2)+ , P 1 :% 3 ~ K.Reduced (P 1 :% 3)+ , P 2 :% 3 ~ K.Reduced (P 2 :% 3)+ , P 4 :% 3 ~ K.Reduced (P 4 :% 3)+ , P 1 :% 4 ~ K.Reduced (P 1 :% 4)+ , P 3 :% 4 ~ K.Reduced (P 3 :% 4)+ , N 1 :% 1 ~ K.Reduced (N 1 :% 1)+ , N 2 :% 1 ~ K.Reduced (N 2 :% 1)+ , N 3 :% 1 ~ K.Reduced (N 3 :% 1)+ , N 4 :% 1 ~ K.Reduced (N 4 :% 1)+ , N 3 :% 2 ~ K.Reduced (N 3 :% 2)+ , N 1 :% 3 ~ K.Reduced (N 1 :% 3)+ , N 2 :% 3 ~ K.Reduced (N 2 :% 3)+ , N 4 :% 3 ~ K.Reduced (N 4 :% 3)+ , N 1 :% 4 ~ K.Reduced (N 1 :% 4)+ , N 3 :% 4 ~ K.Reduced (N 3 :% 4)+ )++_testReduce = Dict+_testReduce :: Dict+ ( Z :% 1 ~ Z % 1+ , P 1 :% 1 ~ P 1 % 1+ , P 2 :% 1 ~ P 2 % 1+ , P 3 :% 1 ~ P 3 % 1+ , P 4 :% 1 ~ P 4 % 1+ , Z :% 1 ~ Z % 2+ , P 1 :% 1 ~ P 2 % 2+ , P 3 :% 2 ~ P 3 % 2+ , P 2 :% 1 ~ P 4 % 2+ , Z :% 1 ~ Z % 3+ , P 1 :% 3 ~ P 1 % 3+ , P 2 :% 3 ~ P 2 % 3+ , P 1 :% 1 ~ P 3 % 3+ , P 4 :% 3 ~ P 4 % 3+ , Z :% 1 ~ Z % 4+ , P 1 :% 4 ~ P 1 % 4+ , P 1 :% 2 ~ P 2 % 4+ , P 3 :% 4 ~ P 3 % 4+ , P 1 :% 1 ~ P 4 % 4+ , Z :% 1 ~ Z % 1+ , N 1 :% 1 ~ N 1 % 1+ , N 2 :% 1 ~ N 2 % 1+ , N 3 :% 1 ~ N 3 % 1+ , N 4 :% 1 ~ N 4 % 1+ , Z :% 1 ~ Z % 2+ , N 1 :% 2 ~ N 1 % 2+ , N 1 :% 1 ~ N 2 % 2+ , N 3 :% 2 ~ N 3 % 2+ , N 2 :% 1 ~ N 4 % 2+ , Z :% 1 ~ Z % 3+ , N 1 :% 3 ~ N 1 % 3+ , N 2 :% 3 ~ N 2 % 3+ , N 1 :% 1 ~ N 3 % 3+ , N 4 :% 3 ~ N 4 % 3+ , Z :% 1 ~ Z % 4+ , N 1 :% 4 ~ N 1 % 4+ , N 1 :% 2 ~ N 2 % 4+ , N 3 :% 4 ~ N 3 % 4+ , N 1 :% 1 ~ N 4 % 4+ )++_testNegate = Dict+_testNegate :: Dict+ ( Z :% 1 ~ P.Negate (Z % 1)+ , Z :% 1 ~ P.Negate (Z % 2)++ , P 1 :% 1 ~ P.Negate (N 1 % 1)+ , P 1 :% 2 ~ P.Negate (N 1 % 2)++ , N 1 :% 1 ~ P.Negate (P 1 % 1)+ , N 1 :% 2 ~ P.Negate (P 1 % 2)++ , P 1 :% 1 ~ P.Negate (N 1 % 1)+ , P 2 :% 1 ~ P.Negate (N 2 % 1)++ , N 1 :% 1 ~ P.Negate (P 1 % 1)+ , N 2 :% 1 ~ P.Negate (P 2 % 1)+ )++_testSignum = Dict+_testSignum :: Dict+ ( Z ~ K.Signum (Z % 1)+ , Z ~ K.Signum (Z % 2)++ , N 1 ~ K.Signum (N 1 % 1)+ , N 1 ~ K.Signum (N 1 % 2)++ , P 1 ~ K.Signum (P 1 % 1)+ , P 1 ~ K.Signum (P 1 % 2)++ , N 1 ~ K.Signum (N 1 % 1)+ , N 1 ~ K.Signum (N 2 % 1)++ , P 1 ~ K.Signum (P 1 % 1)+ , P 1 ~ K.Signum (P 2 % 1)+ )++_testAbs = Dict+_testAbs :: Dict+ ( Z :% 1 ~ P.Abs (Z % 1)+ , Z :% 1 ~ P.Abs (Z % 2)+ , Z :% 1 ~ P.Abs (Z % 1)+ , Z :% 1 ~ P.Abs (Z % 2)++ , P 1 :% 1 ~ P.Abs (N 1 % 1)+ , P 1 :% 2 ~ P.Abs (N 1 % 2)+ , P 1 :% 1 ~ P.Abs (N 1 % 1)+ , P 1 :% 2 ~ P.Abs (N 1 % 2)++ , P 1 :% 1 ~ P.Abs (P 1 % 1)+ , P 1 :% 2 ~ P.Abs (P 1 % 2)+ , P 1 :% 1 ~ P.Abs (P 1 % 1)+ , P 1 :% 2 ~ P.Abs (P 1 % 2)++ , P 1 :% 1 ~ P.Abs (N 1 % 1)+ , P 2 :% 1 ~ P.Abs (N 2 % 1)+ , P 1 :% 1 ~ P.Abs (N 1 % 1)+ , P 2 :% 1 ~ P.Abs (N 2 % 1)++ , P 1 :% 1 ~ P.Abs (P 1 % 1)+ , P 2 :% 1 ~ P.Abs (P 2 % 1)+ , P 1 :% 1 ~ P.Abs (P 1 % 1)+ , P 2 :% 1 ~ P.Abs (P 2 % 1)+ )+++_testEq = Dict+_testEq :: Dict+ ( (1%2 P.== 1%2) ~ 'True+ , (1%2 P.== 2%4) ~ 'True+ , (1%2 P.== 3%4) ~ 'False+ , (1%2 P./= 3%4) ~ 'True+ )++_testCmp = Dict+_testCmp :: Dict+ ( 1%4 <= 1%4+ , 2%8 <= 1%4+ , 1%4 <= 1%2+ , 1%4 <= 2%4+ , 2%8 <= 1%2+ , 1%4 < 1%2+ , 1%4 < 2%4+ , 2%8 < 1%2+ , 2%8 < 2%4+ )++_testAdd = Dict+_testAdd :: Dict+ ( (Z % 1) ~ (Z % 1) P.+ (Z % 1)+ , (Z % 1) ~ (N 5 % 1) P.+ (P 5 % 1)+ , (N 5 % 9) ~ (Z % 1) P.+ (N 5 % 9)+ , (N 9 % 2) ~ (N 3 % 2) P.+ (N 3 % 1)+ , (9 % 2) ~ (3 % 2) P.+ (3 % 1)+ , (N 11 % 3)~ (N 3 % 1) P.+ (N 2 % 3)+ )++_testMul = Dict+_testMul :: Dict+ ( (0 % 1) ~ (Z % 1) P.* (Z % 1)+ , (N 25 % 1) ~ (N 5 % 1) P.* (5 % 1)+ , (N 1 % 1) ~ (N 5 % 1) P.* (1 % 5)+ , (5 % 9) ~ (N 1 % 1) P.* (N 5 % 9)+ , (9 % 1) ~ (N 3 % 1) P.* (N 3 % 1)+ , (2 % 1) ~ (N 3 % 1) P.* (N 2 % 3)+ , (1 % 1) ~ (P 3 % 2) P.* (P 2 % 3)+ )++_testRecip = Dict+_testRecip :: Dict+ ( (1 % 1) ~ K.Recip (1 % 1)+ , (1 % 2) ~ K.Recip (2 % 1)+ , (4 % 3) ~ K.Recip (3 % 4)+ , (N 1 % 1) ~ K.Recip (N 1 % 1)+ , (N 1 % 2) ~ K.Recip (N 2 % 1)+ , (N 4 % 3) ~ K.Recip (N 3 % 4)+ )++_testDiv = Dict+_testDiv :: Dict+ ( P 1 ~ K.Div 'K.RoundDown (3 % 2)+ , P 2 ~ K.Div 'K.RoundUp (3 % 2)+ , P 1 ~ K.Div 'K.RoundZero (3 % 2)+ , P 2 ~ K.Div 'K.RoundAway (3 % 2)+ , P 1 ~ K.Div 'K.RoundHalfDown (3 % 2)+ , P 2 ~ K.Div 'K.RoundHalfUp (3 % 2)+ , P 1 ~ K.Div 'K.RoundHalfZero (3 % 2)+ , P 2 ~ K.Div 'K.RoundHalfAway (3 % 2)+ , P 2 ~ K.Div 'K.RoundHalfEven (3 % 2)+ , P 1 ~ K.Div 'K.RoundHalfOdd (3 % 2)++ , N 2 ~ K.Div 'K.RoundDown (N 3 % 2)+ , N 1 ~ K.Div 'K.RoundUp (N 3 % 2)+ , N 1 ~ K.Div 'K.RoundZero (N 3 % 2)+ , N 2 ~ K.Div 'K.RoundAway (N 3 % 2)+ , N 2 ~ K.Div 'K.RoundHalfDown (N 3 % 2)+ , N 1 ~ K.Div 'K.RoundHalfUp (N 3 % 2)+ , N 1 ~ K.Div 'K.RoundHalfZero (N 3 % 2)+ , N 2 ~ K.Div 'K.RoundHalfAway (N 3 % 2)+ , N 2 ~ K.Div 'K.RoundHalfEven (N 3 % 2)+ , N 1 ~ K.Div 'K.RoundHalfOdd (N 3 % 2)++ , Z ~ K.Div 'K.RoundDown (3 % 4)+ , P 1 ~ K.Div 'K.RoundUp (3 % 4)+ , Z ~ K.Div 'K.RoundZero (3 % 4)+ , P 1 ~ K.Div 'K.RoundAway (3 % 4)+ , P 1 ~ K.Div 'K.RoundHalfDown (3 % 4)+ , P 1 ~ K.Div 'K.RoundHalfUp (3 % 4)+ , P 1 ~ K.Div 'K.RoundHalfZero (3 % 4)+ , P 1 ~ K.Div 'K.RoundHalfAway (3 % 4)+ , P 1 ~ K.Div 'K.RoundHalfEven (3 % 4)+ , P 1 ~ K.Div 'K.RoundHalfOdd (3 % 4)++ , N 1 ~ K.Div 'K.RoundDown (N 3 % 4)+ , Z ~ K.Div 'K.RoundUp (N 3 % 4)+ , Z ~ K.Div 'K.RoundZero (N 3 % 4)+ , N 1 ~ K.Div 'K.RoundAway (N 3 % 4)+ , N 1 ~ K.Div 'K.RoundHalfDown (N 3 % 4)+ , N 1 ~ K.Div 'K.RoundHalfUp (N 3 % 4)+ , N 1 ~ K.Div 'K.RoundHalfZero (N 3 % 4)+ , N 1 ~ K.Div 'K.RoundHalfAway (N 3 % 4)+ , N 1 ~ K.Div 'K.RoundHalfEven (N 3 % 4)+ , N 1 ~ K.Div 'K.RoundHalfOdd (N 3 % 4)+ )++_testRem = Dict+_testRem :: Dict+ ( P 1 % 2 ~ K.Rem 'K.RoundDown (3 % 2)+ , N 1 % 2 ~ K.Rem 'K.RoundUp (3 % 2)+ , P 1 % 2 ~ K.Rem 'K.RoundZero (3 % 2)+ , N 1 % 2 ~ K.Rem 'K.RoundAway (3 % 2)+ , P 1 % 2 ~ K.Rem 'K.RoundHalfDown (3 % 2)+ , N 1 % 2 ~ K.Rem 'K.RoundHalfUp (3 % 2)+ , P 1 % 2 ~ K.Rem 'K.RoundHalfZero (3 % 2)+ , N 1 % 2 ~ K.Rem 'K.RoundHalfAway (3 % 2)+ , N 1 % 2 ~ K.Rem 'K.RoundHalfEven (3 % 2)+ , P 1 % 2 ~ K.Rem 'K.RoundHalfOdd (3 % 2)++ , P 1 % 2 ~ K.Rem 'K.RoundDown (N 3 % 2)+ , N 1 % 2 ~ K.Rem 'K.RoundUp (N 3 % 2)+ , N 1 % 2 ~ K.Rem 'K.RoundZero (N 3 % 2)+ , P 1 % 2 ~ K.Rem 'K.RoundAway (N 3 % 2)+ , P 1 % 2 ~ K.Rem 'K.RoundHalfDown (N 3 % 2)+ , N 1 % 2 ~ K.Rem 'K.RoundHalfUp (N 3 % 2)+ , N 1 % 2 ~ K.Rem 'K.RoundHalfZero (N 3 % 2)+ , P 1 % 2 ~ K.Rem 'K.RoundHalfAway (N 3 % 2)+ , P 1 % 2 ~ K.Rem 'K.RoundHalfEven (N 3 % 2)+ , N 1 % 2 ~ K.Rem 'K.RoundHalfOdd (N 3 % 2)++ , P 3 % 4 ~ K.Rem 'K.RoundDown (3 % 4)+ , N 1 % 4 ~ K.Rem 'K.RoundUp (3 % 4)+ , P 3 % 4 ~ K.Rem 'K.RoundZero (3 % 4)+ , N 1 % 4 ~ K.Rem 'K.RoundAway (3 % 4)+ , N 1 % 4 ~ K.Rem 'K.RoundHalfDown (3 % 4)+ , N 1 % 4 ~ K.Rem 'K.RoundHalfUp (3 % 4)+ , N 1 % 4 ~ K.Rem 'K.RoundHalfZero (3 % 4)+ , N 1 % 4 ~ K.Rem 'K.RoundHalfAway (3 % 4)+ , N 1 % 4 ~ K.Rem 'K.RoundHalfEven (3 % 4)+ , N 1 % 4 ~ K.Rem 'K.RoundHalfOdd (3 % 4)++ , P 1 % 4 ~ K.Rem 'K.RoundDown (N 3 % 4)+ , N 3 % 4 ~ K.Rem 'K.RoundUp (N 3 % 4)+ , N 3 % 4 ~ K.Rem 'K.RoundZero (N 3 % 4)+ , P 1 % 4 ~ K.Rem 'K.RoundAway (N 3 % 4)+ , P 1 % 4 ~ K.Rem 'K.RoundHalfDown (N 3 % 4)+ , P 1 % 4 ~ K.Rem 'K.RoundHalfUp (N 3 % 4)+ , P 1 % 4 ~ K.Rem 'K.RoundHalfZero (N 3 % 4)+ , P 1 % 4 ~ K.Rem 'K.RoundHalfAway (N 3 % 4)+ , P 1 % 4 ~ K.Rem 'K.RoundHalfEven (N 3 % 4)+ , P 1 % 4 ~ K.Rem 'K.RoundHalfOdd (N 3 % 4)+ )++_testDivRem = Dict+_testDivRem :: Dict+ ( '(P 1, P 1 % 2) ~ K.DivRem 'K.RoundDown (3 % 2)+ , '(P 2, N 1 % 2) ~ K.DivRem 'K.RoundUp (3 % 2)+ , '(P 1, P 1 % 2) ~ K.DivRem 'K.RoundZero (3 % 2)+ , '(P 2, N 1 % 2) ~ K.DivRem 'K.RoundAway (3 % 2)+ , '(P 1, P 1 % 2) ~ K.DivRem 'K.RoundHalfDown (3 % 2)+ , '(P 2, N 1 % 2) ~ K.DivRem 'K.RoundHalfUp (3 % 2)+ , '(P 1, P 1 % 2) ~ K.DivRem 'K.RoundHalfZero (3 % 2)+ , '(P 2, N 1 % 2) ~ K.DivRem 'K.RoundHalfAway (3 % 2)+ , '(P 2, N 1 % 2) ~ K.DivRem 'K.RoundHalfEven (3 % 2)+ , '(P 1, P 1 % 2) ~ K.DivRem 'K.RoundHalfOdd (3 % 2)++ , '(N 2, P 1 % 2) ~ K.DivRem 'K.RoundDown (N 3 % 2)+ , '(N 1, N 1 % 2) ~ K.DivRem 'K.RoundUp (N 3 % 2)+ , '(N 1, N 1 % 2) ~ K.DivRem 'K.RoundZero (N 3 % 2)+ , '(N 2, P 1 % 2) ~ K.DivRem 'K.RoundAway (N 3 % 2)+ , '(N 2, P 1 % 2) ~ K.DivRem 'K.RoundHalfDown (N 3 % 2)+ , '(N 1, N 1 % 2) ~ K.DivRem 'K.RoundHalfUp (N 3 % 2)+ , '(N 1, N 1 % 2) ~ K.DivRem 'K.RoundHalfZero (N 3 % 2)+ , '(N 2, P 1 % 2) ~ K.DivRem 'K.RoundHalfAway (N 3 % 2)+ , '(N 2, P 1 % 2) ~ K.DivRem 'K.RoundHalfEven (N 3 % 2)+ , '(N 1, N 1 % 2) ~ K.DivRem 'K.RoundHalfOdd (N 3 % 2)++ , '(Z, P 3 % 4) ~ K.DivRem 'K.RoundDown (3 % 4)+ , '(P 1, N 1 % 4) ~ K.DivRem 'K.RoundUp (3 % 4)+ , '(Z, P 3 % 4) ~ K.DivRem 'K.RoundZero (3 % 4)+ , '(P 1, N 1 % 4) ~ K.DivRem 'K.RoundAway (3 % 4)+ , '(P 1, N 1 % 4) ~ K.DivRem 'K.RoundHalfDown (3 % 4)+ , '(P 1, N 1 % 4) ~ K.DivRem 'K.RoundHalfUp (3 % 4)+ , '(P 1, N 1 % 4) ~ K.DivRem 'K.RoundHalfZero (3 % 4)+ , '(P 1, N 1 % 4) ~ K.DivRem 'K.RoundHalfAway (3 % 4)+ , '(P 1, N 1 % 4) ~ K.DivRem 'K.RoundHalfEven (3 % 4)+ , '(P 1, N 1 % 4) ~ K.DivRem 'K.RoundHalfOdd (3 % 4)++ , '(N 1, P 1 % 4) ~ K.DivRem 'K.RoundDown (N 3 % 4)+ , '(Z, N 3 % 4) ~ K.DivRem 'K.RoundUp (N 3 % 4)+ , '(Z, N 3 % 4) ~ K.DivRem 'K.RoundZero (N 3 % 4)+ , '(N 1, P 1 % 4) ~ K.DivRem 'K.RoundAway (N 3 % 4)+ , '(N 1, P 1 % 4) ~ K.DivRem 'K.RoundHalfDown (N 3 % 4)+ , '(N 1, P 1 % 4) ~ K.DivRem 'K.RoundHalfUp (N 3 % 4)+ , '(N 1, P 1 % 4) ~ K.DivRem 'K.RoundHalfZero (N 3 % 4)+ , '(N 1, P 1 % 4) ~ K.DivRem 'K.RoundHalfAway (N 3 % 4)+ , '(N 1, P 1 % 4) ~ K.DivRem 'K.RoundHalfEven (N 3 % 4)+ , '(N 1, P 1 % 4) ~ K.DivRem 'K.RoundHalfOdd (N 3 % 4)+ )++_testTerminating = Dict+_testTerminating :: Dict+ ( K.Terminating (Z%1)+ , K.Terminating (1%1)+ , K.Terminating (N 2%1)+ , K.Terminating (1%2)+ , K.Terminating (N 1%4)+ , K.Terminating (1%5)+ , K.Terminating (N 1%10)+ , K.Terminating (1%20)+ , K.Terminating (N 1%50)+ , K.Terminating (1%10000000)++ , K.Terminating (N 3%1)+ , K.Terminating (3%1)+ , K.Terminating (N 3%2)+ , K.Terminating (3%3)+ , K.Terminating (N 3%4)+ , K.Terminating (3%5)+ , K.Terminating (N 3%6)+ , K.Terminating (3%10)+ , K.Terminating (N 3%20)+ , K.Terminating (3%50)+ , K.Terminating (N 3%10000000)++ , K.NonTerminating (1%3)+ , K.NonTerminating (N 1%12)+ , K.NonTerminating (1%15)+ , K.NonTerminating (N 2%3)+ , K.NonTerminating (75%7)+ , K.NonTerminating (N 8%3)+ )++_testIsTerminating = Dict+_testIsTerminating :: Dict+ ( 'True ~ K.IsTerminating (Z%1)+ , 'True ~ K.IsTerminating (1%1)+ , 'True ~ K.IsTerminating (N 2%1)+ , 'True ~ K.IsTerminating (1%2)+ , 'True ~ K.IsTerminating (N 1%4)+ , 'True ~ K.IsTerminating (1%5)+ , 'True ~ K.IsTerminating (N 1%10)+ , 'True ~ K.IsTerminating (1%20)+ , 'True ~ K.IsTerminating (N 1%50)+ , 'True ~ K.IsTerminating (1%10000000)++ , 'True ~ K.IsTerminating (N 3%1)+ , 'True ~ K.IsTerminating (3%1)+ , 'True ~ K.IsTerminating (N 3%2)+ , 'True ~ K.IsTerminating (3%3)+ , 'True ~ K.IsTerminating (N 3%4)+ , 'True ~ K.IsTerminating (3%5)+ , 'True ~ K.IsTerminating (N 3%6)+ , 'True ~ K.IsTerminating (3%10)+ , 'True ~ K.IsTerminating (N 3%20)+ , 'True ~ K.IsTerminating (3%50)+ , 'True ~ K.IsTerminating (N 3%10000000)++ , 'False ~ K.IsTerminating (1%3)+ , 'False ~ K.IsTerminating (N 1%12)+ , 'False ~ K.IsTerminating (1%15)+ , 'False ~ K.IsTerminating (N 2%3)+ , 'False ~ K.IsTerminating (75%7)+ , 'False ~ K.IsTerminating (N 8%3)+ )++--------------------------------------------------------------------------------++assert+ :: String -- ^ Test name+ -> Bool -- ^ Successful is true+ -> IO Bool -- ^ Return the same 'Bool' given as input.+assert n x = do+ putStrLn ((if x then "[OK] " else "[FAIL] ") <> n)+ pure x++testsMain :: [IO Bool] -> IO a+testsMain xs = do+ res <- sequence xs+ let (oks, bads) = List.partition id res+ putStrLn ("[TOTAL] OK: " <> show (length oks) <>+ ". FAIL: " <> show (length bads) <> ".")+ case bads of+ [] -> exitSuccess+ _ -> exitFailure++rats :: P.Integer -> [P.Rational]+rats i = do n <- [negate i .. i]+ d <- [negate i .. i]+ guard (d /= 0)+ pure (n P.% d)++main :: IO ()+main = testsMain $+ [ assert "sNum" $ do+ flip all (rats 4) $ \a@(n P.:% _) ->+ case K.someRationalVal a of+ K.SomeRational (_ :: Proxy a) ->+ n == fromSing (K.sNum (sing @a))++ , assert "sDen" $ do+ flip all (rats 4) $ \a@(_ P.:% d) ->+ case K.someRationalVal a of+ K.SomeRational (_ :: Proxy a) ->+ d == toInteger (fromSing (K.sDen (sing @a)))++ , assert "rationalVal . someRationalVal == id" $+ flip all (rats 4) $ \a ->+ case K.someRationalVal a of+ K.SomeRational pa ->+ a == K.rationalVal pa++ , assert "sameRationalVal a a" $+ flip all (rats 4) $ \a ->+ case K.someRationalVal a of+ K.SomeRational pa ->+ isJust (K.sameRational pa pa)++ , assert "sameRationalVal a a'" $+ flip all (rats 4) $ \a ->+ case (K.someRationalVal a, K.someRationalVal a) of+ (K.SomeRational pa1, K.SomeRational pa2) ->+ isJust (K.sameRational pa1 pa2)++ , assert "sameRationalVal a b" $+ flip all (liftA2 (,) (rats 4) (rats 4)) $ \(a, b) ->+ case (K.someRationalVal a, K.someRationalVal b) of+ (K.SomeRational pa, K.SomeRational pb)+ | a == b -> isJust (K.sameRational pa pb)+ | otherwise -> isNothing (K.sameRational pa pb)++ , assert "demote @(Z :% 1)" $ demote @(Z :% 1) == (0 :: P.Rational)+ , assert "demote @(P 1 :% 1)" $ demote @(P 1 :% 1) == (1 :: P.Rational)+ , assert "demote @(N 1 :% 1)" $ demote @(N 1 :% 1) == ((-1) :: P.Rational)++ , assert "show (SRational @(Z :% 1))" $+ show (K.SRational @(Z :% 1)) == "SRational @(Z :% 1)"+ , assert "show (SRational @(P 1 :% 1))" $+ show (K.SRational @(P 1 :% 1)) == "SRational @(P 1 :% 1)"+ , assert "show (SRational @(N 1 :% 1))" $+ show (K.SRational @(N 1 :% 1)) == "SRational @(N 1 :% 1)"++ , assert "Eq SomeRational" $+ and [ K.someRationalVal 0 == K.someRationalVal 0+ , K.someRationalVal 1 == K.someRationalVal 1+ , K.someRationalVal 2 == K.someRationalVal 2+ , K.someRationalVal (1 P.% 2) == K.someRationalVal (1 P.% 2)+ ]++ , assert "Ord SomeRational" $+ flip all (liftA2 (,) (rats 4) (rats 4)) $ \(a, b) ->+ compare (K.someRationalVal a) (K.someRationalVal b)+ == compare a b++ , assert "Show SomeRational" $+ flip all (rats 4) $ \a ->+ show (K.someRationalVal a) == show a++ , assert "Read SomeRational" $+ flip all (rats 4) $ \a ->+ fmap K.someRationalVal (readMaybe (show a))+ == Just (K.someRationalVal a)++ , assert "TestEquality 0%1 0%1" $+ isJust (testEquality (K.SRational @(Z :% 1)) (K.SRational @(Z :% 1)))+ , assert "TestEquality +1%2 +1%2" $+ isJust (testEquality (K.SRational @(P 1 :% 2)) (K.SRational @(P 1 :% 2)))+ , assert "TestEquality -1%2 -1%2" $+ isJust (testEquality (K.SRational @(N 1 :% 2)) (K.SRational @(N 1 :% 2)))+ , assert "TestEquality 0%1 +1%1" $+ isNothing (testEquality (K.SRational @(Z :% 1)) (K.SRational @(P 1 :% 1)))+ , assert "TestEquality 0%1 -1%1" $+ isNothing (testEquality (K.SRational @(Z :% 1)) (K.SRational @(N 1 :% 1)))+ , assert "TestEquality 0%1 +1%1" $+ isNothing (testEquality (K.SRational @(Z :% 1)) (K.SRational @(P 1 :% 1)))+ , assert "TestEquality +1%1 0%1" $+ isNothing (testEquality (K.SRational @(P 1 :% 1)) (K.SRational @(Z :% 1)))+ , assert "TestEquality -1%1 0%1" $+ isNothing (testEquality (K.SRational @(N 1 :% 1)) (K.SRational @(Z :% 1)))++ , assert "Show Rational 0" $+ "0 % 1" == show (K.fromSRational (K.SRational @(Z :% 1)))+ , assert "Show Rational +1" $+ "1 % 1" == show (K.fromSRational (K.SRational @(P 1 :% 1)))+ , assert "Show Rational -1" $+ "(-1) % 1" == show (K.fromSRational (K.SRational @(N 1 :% 1)))++ , assert "Show Rational 0" $+ isJust (testEquality (sing @"0 % 1") (P.sShow_ (K.SRational @(Z :% 1))))+ , assert "Show Rational 1" $+ isJust (testEquality (sing @"1 % 1") (P.sShow_ (K.SRational @(P 1 :% 1))))+ , assert "Show Rational -2" $+ isJust (testEquality (sing @"(-2) % 1") (P.sShow_ (K.SRational @(N 2 :% 1))))++ , assert "Show SRational 0" $+ "SRational @(Z :% 1)" == show (K.SRational @(Z :% 1))+ , assert "Show SRational +1" $+ "SRational @(P 1 :% 1)" == show (K.SRational @(P 1 :% 1))+ , assert "Show SRational -1" $+ "SRational @(N 1 :% 1)" == show (K.SRational @(N 1 :% 1))++ , assert "showLit Rational 0" $+ "Z :% 1" == K.showLit (K.fromSRational (K.SRational @(Z :% 1)))+ , assert "showLit Rational +1" $+ "P 1 :% 1" == K.showLit (K.fromSRational (K.SRational @(P 1 :% 1)))+ , assert "showLit Rational -1" $+ "N 1 :% 1" == K.showLit (K.fromSRational (K.SRational @(N 1 :% 1)))++ , assert "readPrecLit appPrec" $+ flip all (rats 4) $ \a ->+ [(a, "")] == readPrec_to_S K.readPrecLit appPrec (K.showsPrecLit appPrec a "")++ , assert "readPrecLit appPrec1" $+ flip all (rats 4) $ \a ->+ [(a, "")] == readPrec_to_S K.readPrecLit appPrec1 (K.showsPrecLit appPrec1 a "")++ , assert "sShowLit Rational 0" $+ isJust (testEquality (sing @"Z :% 1") (K.sShowLit (K.SRational @(Z :% 1))))+ , assert "sShowLit Rational 1" $+ isJust (testEquality (sing @"P 1 :% 1") (K.sShowLit (K.SRational @(P 1 :% 1))))+ , assert "sShowLit Rational -2" $+ isJust (testEquality (sing @"N 2 :% 1") (K.sShowLit (K.SRational @(N 2 :% 1))))++ , assert "sFromNatural 0" $+ isJust (testEquality (K.SRational @(Z :% 1)) (K.sFromNatural (sing @0)))+ , assert "sFromNatural 1" $+ isJust (testEquality (K.SRational @(P 1 :% 1)) (K.sFromNatural (sing @1)))+ , assert "sFromNatural 2" $+ isJust (testEquality (K.SRational @(P 2 :% 1)) (K.sFromNatural (sing @2)))++ , assert "fromNatural 0" $+ K.mkRational (0 :: P.Integer) (1 :: P.Integer) == Just (K.fromNatural 0)+ , assert "fromNatural 1" $+ K.mkRational (1 :: P.Integer) (1 :: P.Integer) == Just (K.fromNatural 1)+ , assert "fromNatural 2" $+ K.mkRational (2 :: P.Integer) (1 :: P.Integer) == Just (K.fromNatural 2)++ , assert "sFromInteger 0" $+ isJust (testEquality (K.SRational @(Z :% 1)) (K.sFromInteger (sing @Z)))+ , assert "sFromInteger 1" $+ isJust (testEquality (K.SRational @(P 1 :% 1)) (K.sFromInteger (sing @(P 1))))+ , assert "sFromInteger 2" $+ isJust (testEquality (K.SRational @(P 2 :% 1)) (K.sFromInteger (sing @(P 2))))+ , assert "sFromInteger -1" $+ isJust (testEquality (K.SRational @(N 1 :% 1)) (K.sFromInteger (sing @(N 1))))+ , assert "sFromInteger -2" $+ isJust (testEquality (K.SRational @(N 2 :% 1)) (K.sFromInteger (sing @(N 2))))++ , assert "fromInteger 0" $+ K.mkRational (0 :: P.Integer) (1 :: P.Integer) == Just (K.fromInteger 0)+ , assert "fromInteger 1" $+ K.mkRational (1 :: P.Integer) (1 :: P.Integer) == Just (K.fromInteger 1)+ , assert "fromInteger 2" $+ K.mkRational (2 :: P.Integer) (1 :: P.Integer) == Just (K.fromInteger 2)+ , assert "fromInteger -1" $+ K.mkRational ((-1) :: P.Integer) (1 :: P.Integer) == Just (K.fromInteger (-1))+ , assert "fromInteger -2" $+ K.mkRational ((-2) :: P.Integer) (1 :: P.Integer) == Just (K.fromInteger (-2))++ , assert "mkRational Natural Natural" $+ flip all ((,) <$> [0..2] <*> [1, 2]) $ \(n, d) ->+ K.mkRational @Natural @Natural n d == Just (toInteger n P.% toInteger d)++ , assert "mkRational Natural Integer" $+ flip all ((,) <$> [0..2] <*> [(-2), (-1), 1, 2]) $ \(n, d) ->+ K.mkRational @Natural @KI.Integer n d == Just (toInteger n P.% d)++ , assert "mkRational Natural Rational" $+ flip all ((,) <$> [0..2] <*> filter (/= 0) (rats 4)) $ \(n, d) ->+ K.mkRational @Natural @K.Rational n d == Just (P.fromIntegral n P./ d)++ , assert "mkRational Integer Natural" $+ flip all ((,) <$> [(-2)..2] <*> [1, 2]) $ \(n, d) ->+ K.mkRational @KI.Integer @Natural n d == Just (n P.% toInteger d)++ , assert "mkRational Integer Integer" $+ flip all ((,) <$> [(-2)..2] <*> [(-2), (-1), 1, 2]) $ \(n, d) ->+ K.mkRational @KI.Integer @KI.Integer n d == Just (n P.% d)++ , assert "mkRational Integer Rational" $+ flip all ((,) <$> [(-2)..2] <*> filter (/= 0) (rats 4)) $ \(n, d) ->+ K.mkRational @KI.Integer @K.Rational n d == Just (P.fromInteger n P./ d)++ , assert "mkRational Rational Natural" $+ flip all ((,) <$> rats 4 <*> [1, 2]) $ \(n, d) ->+ K.mkRational @K.Rational @Natural n d == Just (n P./ K.fromNatural d)++ , assert "mkRational Rational Integer" $+ flip all ((,) <$> rats 4 <*> [(-2), (-1), 1, 2]) $ \(n, d) ->+ K.mkRational @K.Rational @KI.Integer n d == Just (n P./ K.fromInteger d)++ , assert "mkRational Rational Rational" $+ flip all ((,) <$> rats 4 <*> filter (/= 0) (rats 4)) $ \(n, d) ->+ K.mkRational @K.Rational @K.Rational n d == Just (n P./ d)++ , assert "sMkRational Natural Natural" $+ flip all ((,) <$> [0..2] <*> [1, 2]) $ \(n, d) ->+ K.mkRational @Natural @Natural n d == Just (toInteger n P.% toInteger d)++ , assert "mkRational Natural Natural 0" $+ flip all [0..2] $ \n ->+ isNothing $ K.mkRational @Natural @Natural n 0++ , assert "mkRational Natural Integer 0" $+ flip all [0..2] $ \n ->+ isNothing $ K.mkRational @Natural @KI.Integer n 0++ , assert "mkRational Natural Rational 0" $+ flip all [0..2]$ \n ->+ isNothing $ K.mkRational @Natural @K.Rational n 0++ , assert "mkRational Integer Natural 0" $+ flip all [(-2)..2] $ \n ->+ isNothing $ K.mkRational @KI.Integer @Natural n 0++ , assert "mkRational Integer Integer 0" $+ flip all [(-2)..2] $ \n ->+ isNothing $ K.mkRational @KI.Integer @KI.Integer n 0++ , assert "mkRational Integer Rational 0" $+ flip all [(-2)..2] $ \n ->+ isNothing $ K.mkRational @KI.Integer @K.Rational n 0++ , assert "mkRational Rational Natural 0" $+ flip all (rats 4) $ \n ->+ isNothing $ K.mkRational @K.Rational @Natural n 0++ , assert "mkRational Rational Integer 0" $+ flip all (rats 4) $ \n ->+ isNothing $ K.mkRational @K.Rational @KI.Integer n 0++ , assert "mkRational Rational Rational 0" $+ flip all (rats 4) $ \n ->+ isNothing $ K.mkRational @K.Rational @K.Rational n 0++ , assert "sRecip (Z :% 1)" $+ isNothing $ K.sRecip' (K.SRational @(Z :% 1))++ , assert "sRecip (P 2 :% 1)" $+ isJust $ K.sRecip' (K.SRational @(P 2 :% 1))++ ] <> testsDivRem <> testsTermination++testsDivRem :: [IO Bool]+testsDivRem = do+ a@(n P.:% d) <- rats 4+ r :: K.Round <- [minBound .. maxBound]+ let tname :: String -> ShowS+ tname t = showString t . showChar ' ' . shows r . showChar ' '+ . shows n . showChar ' ' . shows d+ [ assert (tname "divRem" "") $+ case K.divRem r a of+ (q, x) -> a == toRational q + x+ , assert (tname "divRem/div" "") $ fst (K.divRem r a) == K.div r a+ , assert (tname "divRem/rem" "") $ snd (K.divRem r a) == K.rem r a+ ]++testsTermination :: [IO Bool]+testsTermination = concat+ [ do a <- ok+ pure $ assert ("termination(ok) (" <> show a <> ")") $+ K.withSomeSRational a $ \(sa :: K.SRational a) ->+ K.termination False True sa++ , do a <- no+ pure $ assert ("termination(no) (" <> show a <> ")") $+ K.withSomeSRational a $ \(sa :: K.SRational a) ->+ K.termination True False sa++ , do a <- ok+ pure $ assert ("SRationalTerminating (" <> show a <> ")") $+ K.withSomeSRational a $ \case+ K.SRationalTerminating -> True+ K.SRationalNonTerminating -> False++ , do a <- no+ pure $ assert ("SRationalNonTerminating (" <> show a <> ")") $+ K.withSomeSRational a $ \case+ K.SRationalTerminating -> False+ K.SRationalNonTerminating -> True++ ]+ where+ ok :: [P.Rational]+ ok = [ 0 P.% 1+ , -1 P.% 1+ , 2 P.% 1+ , -1 P.% 2+ , 1 P.% 4+ , -1 P.% 5+ , 1 P.% 10+ , -1 P.% 20+ , 1 P.% 50+ , -1 P.% 10000000+ , 3 P.% 1+ , -3 P.% 1+ , 3 P.% 2+ , -3 P.% 3+ , 3 P.% 4+ , -3 P.% 5+ , 3 P.% 6+ , -3 P.% 10+ , 3 P.% 20+ , -3 P.% 50+ , 3 P.% 10000000+ ]+ no :: [P.Rational]+ no = [ 1 P.% 3+ , -1 P.% 12+ , 1 P.% 15+ , -2 P.% 3+ , 75 P.% 7+ , -8 P.% 3+ ]+++_testSlash_Nat0_Nat1 = Dict @((Z :% 1) ~ (0 % 1))+_testSlash_Nat0_Nat2 = Dict @((Z :% 1) ~ (0 % 2))+_testSlash_Nat0_Nat3 = Dict @((Z :% 1) ~ (0 % 3))+_testSlash_Nat0_Nat4 = Dict @((Z :% 1) ~ (0 % 4))+_testSlash_Nat0_IntN4 = Dict @((Z :% 1) ~ (0 % (N 4)))+_testSlash_Nat0_IntN3 = Dict @((Z :% 1) ~ (0 % (N 3)))+_testSlash_Nat0_IntN2 = Dict @((Z :% 1) ~ (0 % (N 2)))+_testSlash_Nat0_IntN1 = Dict @((Z :% 1) ~ (0 % (N 1)))+_testSlash_Nat0_IntP1 = Dict @((Z :% 1) ~ (0 % (P 1)))+_testSlash_Nat0_IntP2 = Dict @((Z :% 1) ~ (0 % (P 2)))+_testSlash_Nat0_IntP3 = Dict @((Z :% 1) ~ (0 % (P 3)))+_testSlash_Nat0_IntP4 = Dict @((Z :% 1) ~ (0 % (P 4)))+_testSlash_Nat0_Rat4N1 = Dict @((Z :% 1) ~ (0 % (N 4 :% 1)))+_testSlash_Nat0_Rat3N1 = Dict @((Z :% 1) ~ (0 % (N 3 :% 1)))+_testSlash_Nat0_Rat2N1 = Dict @((Z :% 1) ~ (0 % (N 2 :% 1)))+_testSlash_Nat0_Rat3N2 = Dict @((Z :% 1) ~ (0 % (N 3 :% 2)))+_testSlash_Nat0_Rat4N3 = Dict @((Z :% 1) ~ (0 % (N 4 :% 3)))+_testSlash_Nat0_Rat1N1 = Dict @((Z :% 1) ~ (0 % (N 1 :% 1)))+_testSlash_Nat0_Rat3N4 = Dict @((Z :% 1) ~ (0 % (N 3 :% 4)))+_testSlash_Nat0_Rat2N3 = Dict @((Z :% 1) ~ (0 % (N 2 :% 3)))+_testSlash_Nat0_Rat1N2 = Dict @((Z :% 1) ~ (0 % (N 1 :% 2)))+_testSlash_Nat0_Rat1N3 = Dict @((Z :% 1) ~ (0 % (N 1 :% 3)))+_testSlash_Nat0_Rat1N4 = Dict @((Z :% 1) ~ (0 % (N 1 :% 4)))+_testSlash_Nat0_Rat1P4 = Dict @((Z :% 1) ~ (0 % (P 1 :% 4)))+_testSlash_Nat0_Rat1P3 = Dict @((Z :% 1) ~ (0 % (P 1 :% 3)))+_testSlash_Nat0_Rat1P2 = Dict @((Z :% 1) ~ (0 % (P 1 :% 2)))+_testSlash_Nat0_Rat2P3 = Dict @((Z :% 1) ~ (0 % (P 2 :% 3)))+_testSlash_Nat0_Rat3P4 = Dict @((Z :% 1) ~ (0 % (P 3 :% 4)))+_testSlash_Nat0_Rat1P1 = Dict @((Z :% 1) ~ (0 % (P 1 :% 1)))+_testSlash_Nat0_Rat4P3 = Dict @((Z :% 1) ~ (0 % (P 4 :% 3)))+_testSlash_Nat0_Rat3P2 = Dict @((Z :% 1) ~ (0 % (P 3 :% 2)))+_testSlash_Nat0_Rat2P1 = Dict @((Z :% 1) ~ (0 % (P 2 :% 1)))+_testSlash_Nat0_Rat3P1 = Dict @((Z :% 1) ~ (0 % (P 3 :% 1)))+_testSlash_Nat0_Rat4P1 = Dict @((Z :% 1) ~ (0 % (P 4 :% 1)))+_testSlash_Nat1_Nat1 = Dict @((P 1 :% 1) ~ (1 % 1))+_testSlash_Nat1_Nat2 = Dict @((P 1 :% 2) ~ (1 % 2))+_testSlash_Nat1_Nat3 = Dict @((P 1 :% 3) ~ (1 % 3))+_testSlash_Nat1_Nat4 = Dict @((P 1 :% 4) ~ (1 % 4))+_testSlash_Nat1_IntN4 = Dict @((N 1 :% 4) ~ (1 % (N 4)))+_testSlash_Nat1_IntN3 = Dict @((N 1 :% 3) ~ (1 % (N 3)))+_testSlash_Nat1_IntN2 = Dict @((N 1 :% 2) ~ (1 % (N 2)))+_testSlash_Nat1_IntN1 = Dict @((N 1 :% 1) ~ (1 % (N 1)))+_testSlash_Nat1_IntP1 = Dict @((P 1 :% 1) ~ (1 % (P 1)))+_testSlash_Nat1_IntP2 = Dict @((P 1 :% 2) ~ (1 % (P 2)))+_testSlash_Nat1_IntP3 = Dict @((P 1 :% 3) ~ (1 % (P 3)))+_testSlash_Nat1_IntP4 = Dict @((P 1 :% 4) ~ (1 % (P 4)))+_testSlash_Nat1_Rat4N1 = Dict @((N 1 :% 4) ~ (1 % (N 4 :% 1)))+_testSlash_Nat1_Rat3N1 = Dict @((N 1 :% 3) ~ (1 % (N 3 :% 1)))+_testSlash_Nat1_Rat2N1 = Dict @((N 1 :% 2) ~ (1 % (N 2 :% 1)))+_testSlash_Nat1_Rat3N2 = Dict @((N 2 :% 3) ~ (1 % (N 3 :% 2)))+_testSlash_Nat1_Rat4N3 = Dict @((N 3 :% 4) ~ (1 % (N 4 :% 3)))+_testSlash_Nat1_Rat1N1 = Dict @((N 1 :% 1) ~ (1 % (N 1 :% 1)))+_testSlash_Nat1_Rat3N4 = Dict @((N 4 :% 3) ~ (1 % (N 3 :% 4)))+_testSlash_Nat1_Rat2N3 = Dict @((N 3 :% 2) ~ (1 % (N 2 :% 3)))+_testSlash_Nat1_Rat1N2 = Dict @((N 2 :% 1) ~ (1 % (N 1 :% 2)))+_testSlash_Nat1_Rat1N3 = Dict @((N 3 :% 1) ~ (1 % (N 1 :% 3)))+_testSlash_Nat1_Rat1N4 = Dict @((N 4 :% 1) ~ (1 % (N 1 :% 4)))+_testSlash_Nat1_Rat1P4 = Dict @((P 4 :% 1) ~ (1 % (P 1 :% 4)))+_testSlash_Nat1_Rat1P3 = Dict @((P 3 :% 1) ~ (1 % (P 1 :% 3)))+_testSlash_Nat1_Rat1P2 = Dict @((P 2 :% 1) ~ (1 % (P 1 :% 2)))+_testSlash_Nat1_Rat2P3 = Dict @((P 3 :% 2) ~ (1 % (P 2 :% 3)))+_testSlash_Nat1_Rat3P4 = Dict @((P 4 :% 3) ~ (1 % (P 3 :% 4)))+_testSlash_Nat1_Rat1P1 = Dict @((P 1 :% 1) ~ (1 % (P 1 :% 1)))+_testSlash_Nat1_Rat4P3 = Dict @((P 3 :% 4) ~ (1 % (P 4 :% 3)))+_testSlash_Nat1_Rat3P2 = Dict @((P 2 :% 3) ~ (1 % (P 3 :% 2)))+_testSlash_Nat1_Rat2P1 = Dict @((P 1 :% 2) ~ (1 % (P 2 :% 1)))+_testSlash_Nat1_Rat3P1 = Dict @((P 1 :% 3) ~ (1 % (P 3 :% 1)))+_testSlash_Nat1_Rat4P1 = Dict @((P 1 :% 4) ~ (1 % (P 4 :% 1)))+_testSlash_Nat2_Nat1 = Dict @((P 2 :% 1) ~ (2 % 1))+_testSlash_Nat2_Nat2 = Dict @((P 1 :% 1) ~ (2 % 2))+_testSlash_Nat2_Nat3 = Dict @((P 2 :% 3) ~ (2 % 3))+_testSlash_Nat2_Nat4 = Dict @((P 1 :% 2) ~ (2 % 4))+_testSlash_Nat2_IntN4 = Dict @((N 1 :% 2) ~ (2 % (N 4)))+_testSlash_Nat2_IntN3 = Dict @((N 2 :% 3) ~ (2 % (N 3)))+_testSlash_Nat2_IntN2 = Dict @((N 1 :% 1) ~ (2 % (N 2)))+_testSlash_Nat2_IntN1 = Dict @((N 2 :% 1) ~ (2 % (N 1)))+_testSlash_Nat2_IntP1 = Dict @((P 2 :% 1) ~ (2 % (P 1)))+_testSlash_Nat2_IntP2 = Dict @((P 1 :% 1) ~ (2 % (P 2)))+_testSlash_Nat2_IntP3 = Dict @((P 2 :% 3) ~ (2 % (P 3)))+_testSlash_Nat2_IntP4 = Dict @((P 1 :% 2) ~ (2 % (P 4)))+_testSlash_Nat2_Rat4N1 = Dict @((N 1 :% 2) ~ (2 % (N 4 :% 1)))+_testSlash_Nat2_Rat3N1 = Dict @((N 2 :% 3) ~ (2 % (N 3 :% 1)))+_testSlash_Nat2_Rat2N1 = Dict @((N 1 :% 1) ~ (2 % (N 2 :% 1)))+_testSlash_Nat2_Rat3N2 = Dict @((N 4 :% 3) ~ (2 % (N 3 :% 2)))+_testSlash_Nat2_Rat4N3 = Dict @((N 3 :% 2) ~ (2 % (N 4 :% 3)))+_testSlash_Nat2_Rat1N1 = Dict @((N 2 :% 1) ~ (2 % (N 1 :% 1)))+_testSlash_Nat2_Rat3N4 = Dict @((N 8 :% 3) ~ (2 % (N 3 :% 4)))+_testSlash_Nat2_Rat2N3 = Dict @((N 3 :% 1) ~ (2 % (N 2 :% 3)))+_testSlash_Nat2_Rat1N2 = Dict @((N 4 :% 1) ~ (2 % (N 1 :% 2)))+_testSlash_Nat2_Rat1N3 = Dict @((N 6 :% 1) ~ (2 % (N 1 :% 3)))+_testSlash_Nat2_Rat1N4 = Dict @((N 8 :% 1) ~ (2 % (N 1 :% 4)))+_testSlash_Nat2_Rat1P4 = Dict @((P 8 :% 1) ~ (2 % (P 1 :% 4)))+_testSlash_Nat2_Rat1P3 = Dict @((P 6 :% 1) ~ (2 % (P 1 :% 3)))+_testSlash_Nat2_Rat1P2 = Dict @((P 4 :% 1) ~ (2 % (P 1 :% 2)))+_testSlash_Nat2_Rat2P3 = Dict @((P 3 :% 1) ~ (2 % (P 2 :% 3)))+_testSlash_Nat2_Rat3P4 = Dict @((P 8 :% 3) ~ (2 % (P 3 :% 4)))+_testSlash_Nat2_Rat1P1 = Dict @((P 2 :% 1) ~ (2 % (P 1 :% 1)))+_testSlash_Nat2_Rat4P3 = Dict @((P 3 :% 2) ~ (2 % (P 4 :% 3)))+_testSlash_Nat2_Rat3P2 = Dict @((P 4 :% 3) ~ (2 % (P 3 :% 2)))+_testSlash_Nat2_Rat2P1 = Dict @((P 1 :% 1) ~ (2 % (P 2 :% 1)))+_testSlash_Nat2_Rat3P1 = Dict @((P 2 :% 3) ~ (2 % (P 3 :% 1)))+_testSlash_Nat2_Rat4P1 = Dict @((P 1 :% 2) ~ (2 % (P 4 :% 1)))+_testSlash_Nat3_Nat1 = Dict @((P 3 :% 1) ~ (3 % 1))+_testSlash_Nat3_Nat2 = Dict @((P 3 :% 2) ~ (3 % 2))+_testSlash_Nat3_Nat3 = Dict @((P 1 :% 1) ~ (3 % 3))+_testSlash_Nat3_Nat4 = Dict @((P 3 :% 4) ~ (3 % 4))+_testSlash_Nat3_IntN4 = Dict @((N 3 :% 4) ~ (3 % (N 4)))+_testSlash_Nat3_IntN3 = Dict @((N 1 :% 1) ~ (3 % (N 3)))+_testSlash_Nat3_IntN2 = Dict @((N 3 :% 2) ~ (3 % (N 2)))+_testSlash_Nat3_IntN1 = Dict @((N 3 :% 1) ~ (3 % (N 1)))+_testSlash_Nat3_IntP1 = Dict @((P 3 :% 1) ~ (3 % (P 1)))+_testSlash_Nat3_IntP2 = Dict @((P 3 :% 2) ~ (3 % (P 2)))+_testSlash_Nat3_IntP3 = Dict @((P 1 :% 1) ~ (3 % (P 3)))+_testSlash_Nat3_IntP4 = Dict @((P 3 :% 4) ~ (3 % (P 4)))+_testSlash_Nat3_Rat4N1 = Dict @((N 3 :% 4) ~ (3 % (N 4 :% 1)))+_testSlash_Nat3_Rat3N1 = Dict @((N 1 :% 1) ~ (3 % (N 3 :% 1)))+_testSlash_Nat3_Rat2N1 = Dict @((N 3 :% 2) ~ (3 % (N 2 :% 1)))+_testSlash_Nat3_Rat3N2 = Dict @((N 2 :% 1) ~ (3 % (N 3 :% 2)))+_testSlash_Nat3_Rat4N3 = Dict @((N 9 :% 4) ~ (3 % (N 4 :% 3)))+_testSlash_Nat3_Rat1N1 = Dict @((N 3 :% 1) ~ (3 % (N 1 :% 1)))+_testSlash_Nat3_Rat3N4 = Dict @((N 4 :% 1) ~ (3 % (N 3 :% 4)))+_testSlash_Nat3_Rat2N3 = Dict @((N 9 :% 2) ~ (3 % (N 2 :% 3)))+_testSlash_Nat3_Rat1N2 = Dict @((N 6 :% 1) ~ (3 % (N 1 :% 2)))+_testSlash_Nat3_Rat1N3 = Dict @((N 9 :% 1) ~ (3 % (N 1 :% 3)))+_testSlash_Nat3_Rat1N4 = Dict @((N 12 :% 1) ~ (3 % (N 1 :% 4)))+_testSlash_Nat3_Rat1P4 = Dict @((P 12 :% 1) ~ (3 % (P 1 :% 4)))+_testSlash_Nat3_Rat1P3 = Dict @((P 9 :% 1) ~ (3 % (P 1 :% 3)))+_testSlash_Nat3_Rat1P2 = Dict @((P 6 :% 1) ~ (3 % (P 1 :% 2)))+_testSlash_Nat3_Rat2P3 = Dict @((P 9 :% 2) ~ (3 % (P 2 :% 3)))+_testSlash_Nat3_Rat3P4 = Dict @((P 4 :% 1) ~ (3 % (P 3 :% 4)))+_testSlash_Nat3_Rat1P1 = Dict @((P 3 :% 1) ~ (3 % (P 1 :% 1)))+_testSlash_Nat3_Rat4P3 = Dict @((P 9 :% 4) ~ (3 % (P 4 :% 3)))+_testSlash_Nat3_Rat3P2 = Dict @((P 2 :% 1) ~ (3 % (P 3 :% 2)))+_testSlash_Nat3_Rat2P1 = Dict @((P 3 :% 2) ~ (3 % (P 2 :% 1)))+_testSlash_Nat3_Rat3P1 = Dict @((P 1 :% 1) ~ (3 % (P 3 :% 1)))+_testSlash_Nat3_Rat4P1 = Dict @((P 3 :% 4) ~ (3 % (P 4 :% 1)))+_testSlash_Nat4_Nat1 = Dict @((P 4 :% 1) ~ (4 % 1))+_testSlash_Nat4_Nat2 = Dict @((P 2 :% 1) ~ (4 % 2))+_testSlash_Nat4_Nat3 = Dict @((P 4 :% 3) ~ (4 % 3))+_testSlash_Nat4_Nat4 = Dict @((P 1 :% 1) ~ (4 % 4))+_testSlash_Nat4_IntN4 = Dict @((N 1 :% 1) ~ (4 % (N 4)))+_testSlash_Nat4_IntN3 = Dict @((N 4 :% 3) ~ (4 % (N 3)))+_testSlash_Nat4_IntN2 = Dict @((N 2 :% 1) ~ (4 % (N 2)))+_testSlash_Nat4_IntN1 = Dict @((N 4 :% 1) ~ (4 % (N 1)))+_testSlash_Nat4_IntP1 = Dict @((P 4 :% 1) ~ (4 % (P 1)))+_testSlash_Nat4_IntP2 = Dict @((P 2 :% 1) ~ (4 % (P 2)))+_testSlash_Nat4_IntP3 = Dict @((P 4 :% 3) ~ (4 % (P 3)))+_testSlash_Nat4_IntP4 = Dict @((P 1 :% 1) ~ (4 % (P 4)))+_testSlash_Nat4_Rat4N1 = Dict @((N 1 :% 1) ~ (4 % (N 4 :% 1)))+_testSlash_Nat4_Rat3N1 = Dict @((N 4 :% 3) ~ (4 % (N 3 :% 1)))+_testSlash_Nat4_Rat2N1 = Dict @((N 2 :% 1) ~ (4 % (N 2 :% 1)))+_testSlash_Nat4_Rat3N2 = Dict @((N 8 :% 3) ~ (4 % (N 3 :% 2)))+_testSlash_Nat4_Rat4N3 = Dict @((N 3 :% 1) ~ (4 % (N 4 :% 3)))+_testSlash_Nat4_Rat1N1 = Dict @((N 4 :% 1) ~ (4 % (N 1 :% 1)))+_testSlash_Nat4_Rat3N4 = Dict @((N 16 :% 3) ~ (4 % (N 3 :% 4)))+_testSlash_Nat4_Rat2N3 = Dict @((N 6 :% 1) ~ (4 % (N 2 :% 3)))+_testSlash_Nat4_Rat1N2 = Dict @((N 8 :% 1) ~ (4 % (N 1 :% 2)))+_testSlash_Nat4_Rat1N3 = Dict @((N 12 :% 1) ~ (4 % (N 1 :% 3)))+_testSlash_Nat4_Rat1N4 = Dict @((N 16 :% 1) ~ (4 % (N 1 :% 4)))+_testSlash_Nat4_Rat1P4 = Dict @((P 16 :% 1) ~ (4 % (P 1 :% 4)))+_testSlash_Nat4_Rat1P3 = Dict @((P 12 :% 1) ~ (4 % (P 1 :% 3)))+_testSlash_Nat4_Rat1P2 = Dict @((P 8 :% 1) ~ (4 % (P 1 :% 2)))+_testSlash_Nat4_Rat2P3 = Dict @((P 6 :% 1) ~ (4 % (P 2 :% 3)))+_testSlash_Nat4_Rat3P4 = Dict @((P 16 :% 3) ~ (4 % (P 3 :% 4)))+_testSlash_Nat4_Rat1P1 = Dict @((P 4 :% 1) ~ (4 % (P 1 :% 1)))+_testSlash_Nat4_Rat4P3 = Dict @((P 3 :% 1) ~ (4 % (P 4 :% 3)))+_testSlash_Nat4_Rat3P2 = Dict @((P 8 :% 3) ~ (4 % (P 3 :% 2)))+_testSlash_Nat4_Rat2P1 = Dict @((P 2 :% 1) ~ (4 % (P 2 :% 1)))+_testSlash_Nat4_Rat3P1 = Dict @((P 4 :% 3) ~ (4 % (P 3 :% 1)))+_testSlash_Nat4_Rat4P1 = Dict @((P 1 :% 1) ~ (4 % (P 4 :% 1)))+_testSlash_IntN4_Nat1 = Dict @((N 4 :% 1) ~ ((N 4) % 1))+_testSlash_IntN4_Nat2 = Dict @((N 2 :% 1) ~ ((N 4) % 2))+_testSlash_IntN4_Nat3 = Dict @((N 4 :% 3) ~ ((N 4) % 3))+_testSlash_IntN4_Nat4 = Dict @((N 1 :% 1) ~ ((N 4) % 4))+_testSlash_IntN4_IntN4 = Dict @((P 1 :% 1) ~ ((N 4) % (N 4)))+_testSlash_IntN4_IntN3 = Dict @((P 4 :% 3) ~ ((N 4) % (N 3)))+_testSlash_IntN4_IntN2 = Dict @((P 2 :% 1) ~ ((N 4) % (N 2)))+_testSlash_IntN4_IntN1 = Dict @((P 4 :% 1) ~ ((N 4) % (N 1)))+_testSlash_IntN4_IntP1 = Dict @((N 4 :% 1) ~ ((N 4) % (P 1)))+_testSlash_IntN4_IntP2 = Dict @((N 2 :% 1) ~ ((N 4) % (P 2)))+_testSlash_IntN4_IntP3 = Dict @((N 4 :% 3) ~ ((N 4) % (P 3)))+_testSlash_IntN4_IntP4 = Dict @((N 1 :% 1) ~ ((N 4) % (P 4)))+_testSlash_IntN4_Rat4N1 = Dict @((P 1 :% 1) ~ ((N 4) % (N 4 :% 1)))+_testSlash_IntN4_Rat3N1 = Dict @((P 4 :% 3) ~ ((N 4) % (N 3 :% 1)))+_testSlash_IntN4_Rat2N1 = Dict @((P 2 :% 1) ~ ((N 4) % (N 2 :% 1)))+_testSlash_IntN4_Rat3N2 = Dict @((P 8 :% 3) ~ ((N 4) % (N 3 :% 2)))+_testSlash_IntN4_Rat4N3 = Dict @((P 3 :% 1) ~ ((N 4) % (N 4 :% 3)))+_testSlash_IntN4_Rat1N1 = Dict @((P 4 :% 1) ~ ((N 4) % (N 1 :% 1)))+_testSlash_IntN4_Rat3N4 = Dict @((P 16 :% 3) ~ ((N 4) % (N 3 :% 4)))+_testSlash_IntN4_Rat2N3 = Dict @((P 6 :% 1) ~ ((N 4) % (N 2 :% 3)))+_testSlash_IntN4_Rat1N2 = Dict @((P 8 :% 1) ~ ((N 4) % (N 1 :% 2)))+_testSlash_IntN4_Rat1N3 = Dict @((P 12 :% 1) ~ ((N 4) % (N 1 :% 3)))+_testSlash_IntN4_Rat1N4 = Dict @((P 16 :% 1) ~ ((N 4) % (N 1 :% 4)))+_testSlash_IntN4_Rat1P4 = Dict @((N 16 :% 1) ~ ((N 4) % (P 1 :% 4)))+_testSlash_IntN4_Rat1P3 = Dict @((N 12 :% 1) ~ ((N 4) % (P 1 :% 3)))+_testSlash_IntN4_Rat1P2 = Dict @((N 8 :% 1) ~ ((N 4) % (P 1 :% 2)))+_testSlash_IntN4_Rat2P3 = Dict @((N 6 :% 1) ~ ((N 4) % (P 2 :% 3)))+_testSlash_IntN4_Rat3P4 = Dict @((N 16 :% 3) ~ ((N 4) % (P 3 :% 4)))+_testSlash_IntN4_Rat1P1 = Dict @((N 4 :% 1) ~ ((N 4) % (P 1 :% 1)))+_testSlash_IntN4_Rat4P3 = Dict @((N 3 :% 1) ~ ((N 4) % (P 4 :% 3)))+_testSlash_IntN4_Rat3P2 = Dict @((N 8 :% 3) ~ ((N 4) % (P 3 :% 2)))+_testSlash_IntN4_Rat2P1 = Dict @((N 2 :% 1) ~ ((N 4) % (P 2 :% 1)))+_testSlash_IntN4_Rat3P1 = Dict @((N 4 :% 3) ~ ((N 4) % (P 3 :% 1)))+_testSlash_IntN4_Rat4P1 = Dict @((N 1 :% 1) ~ ((N 4) % (P 4 :% 1)))+_testSlash_IntN3_Nat1 = Dict @((N 3 :% 1) ~ ((N 3) % 1))+_testSlash_IntN3_Nat2 = Dict @((N 3 :% 2) ~ ((N 3) % 2))+_testSlash_IntN3_Nat3 = Dict @((N 1 :% 1) ~ ((N 3) % 3))+_testSlash_IntN3_Nat4 = Dict @((N 3 :% 4) ~ ((N 3) % 4))+_testSlash_IntN3_IntN4 = Dict @((P 3 :% 4) ~ ((N 3) % (N 4)))+_testSlash_IntN3_IntN3 = Dict @((P 1 :% 1) ~ ((N 3) % (N 3)))+_testSlash_IntN3_IntN2 = Dict @((P 3 :% 2) ~ ((N 3) % (N 2)))+_testSlash_IntN3_IntN1 = Dict @((P 3 :% 1) ~ ((N 3) % (N 1)))+_testSlash_IntN3_IntP1 = Dict @((N 3 :% 1) ~ ((N 3) % (P 1)))+_testSlash_IntN3_IntP2 = Dict @((N 3 :% 2) ~ ((N 3) % (P 2)))+_testSlash_IntN3_IntP3 = Dict @((N 1 :% 1) ~ ((N 3) % (P 3)))+_testSlash_IntN3_IntP4 = Dict @((N 3 :% 4) ~ ((N 3) % (P 4)))+_testSlash_IntN3_Rat4N1 = Dict @((P 3 :% 4) ~ ((N 3) % (N 4 :% 1)))+_testSlash_IntN3_Rat3N1 = Dict @((P 1 :% 1) ~ ((N 3) % (N 3 :% 1)))+_testSlash_IntN3_Rat2N1 = Dict @((P 3 :% 2) ~ ((N 3) % (N 2 :% 1)))+_testSlash_IntN3_Rat3N2 = Dict @((P 2 :% 1) ~ ((N 3) % (N 3 :% 2)))+_testSlash_IntN3_Rat4N3 = Dict @((P 9 :% 4) ~ ((N 3) % (N 4 :% 3)))+_testSlash_IntN3_Rat1N1 = Dict @((P 3 :% 1) ~ ((N 3) % (N 1 :% 1)))+_testSlash_IntN3_Rat3N4 = Dict @((P 4 :% 1) ~ ((N 3) % (N 3 :% 4)))+_testSlash_IntN3_Rat2N3 = Dict @((P 9 :% 2) ~ ((N 3) % (N 2 :% 3)))+_testSlash_IntN3_Rat1N2 = Dict @((P 6 :% 1) ~ ((N 3) % (N 1 :% 2)))+_testSlash_IntN3_Rat1N3 = Dict @((P 9 :% 1) ~ ((N 3) % (N 1 :% 3)))+_testSlash_IntN3_Rat1N4 = Dict @((P 12 :% 1) ~ ((N 3) % (N 1 :% 4)))+_testSlash_IntN3_Rat1P4 = Dict @((N 12 :% 1) ~ ((N 3) % (P 1 :% 4)))+_testSlash_IntN3_Rat1P3 = Dict @((N 9 :% 1) ~ ((N 3) % (P 1 :% 3)))+_testSlash_IntN3_Rat1P2 = Dict @((N 6 :% 1) ~ ((N 3) % (P 1 :% 2)))+_testSlash_IntN3_Rat2P3 = Dict @((N 9 :% 2) ~ ((N 3) % (P 2 :% 3)))+_testSlash_IntN3_Rat3P4 = Dict @((N 4 :% 1) ~ ((N 3) % (P 3 :% 4)))+_testSlash_IntN3_Rat1P1 = Dict @((N 3 :% 1) ~ ((N 3) % (P 1 :% 1)))+_testSlash_IntN3_Rat4P3 = Dict @((N 9 :% 4) ~ ((N 3) % (P 4 :% 3)))+_testSlash_IntN3_Rat3P2 = Dict @((N 2 :% 1) ~ ((N 3) % (P 3 :% 2)))+_testSlash_IntN3_Rat2P1 = Dict @((N 3 :% 2) ~ ((N 3) % (P 2 :% 1)))+_testSlash_IntN3_Rat3P1 = Dict @((N 1 :% 1) ~ ((N 3) % (P 3 :% 1)))+_testSlash_IntN3_Rat4P1 = Dict @((N 3 :% 4) ~ ((N 3) % (P 4 :% 1)))+_testSlash_IntN2_Nat1 = Dict @((N 2 :% 1) ~ ((N 2) % 1))+_testSlash_IntN2_Nat2 = Dict @((N 1 :% 1) ~ ((N 2) % 2))+_testSlash_IntN2_Nat3 = Dict @((N 2 :% 3) ~ ((N 2) % 3))+_testSlash_IntN2_Nat4 = Dict @((N 1 :% 2) ~ ((N 2) % 4))+_testSlash_IntN2_IntN4 = Dict @((P 1 :% 2) ~ ((N 2) % (N 4)))+_testSlash_IntN2_IntN3 = Dict @((P 2 :% 3) ~ ((N 2) % (N 3)))+_testSlash_IntN2_IntN2 = Dict @((P 1 :% 1) ~ ((N 2) % (N 2)))+_testSlash_IntN2_IntN1 = Dict @((P 2 :% 1) ~ ((N 2) % (N 1)))+_testSlash_IntN2_IntP1 = Dict @((N 2 :% 1) ~ ((N 2) % (P 1)))+_testSlash_IntN2_IntP2 = Dict @((N 1 :% 1) ~ ((N 2) % (P 2)))+_testSlash_IntN2_IntP3 = Dict @((N 2 :% 3) ~ ((N 2) % (P 3)))+_testSlash_IntN2_IntP4 = Dict @((N 1 :% 2) ~ ((N 2) % (P 4)))+_testSlash_IntN2_Rat4N1 = Dict @((P 1 :% 2) ~ ((N 2) % (N 4 :% 1)))+_testSlash_IntN2_Rat3N1 = Dict @((P 2 :% 3) ~ ((N 2) % (N 3 :% 1)))+_testSlash_IntN2_Rat2N1 = Dict @((P 1 :% 1) ~ ((N 2) % (N 2 :% 1)))+_testSlash_IntN2_Rat3N2 = Dict @((P 4 :% 3) ~ ((N 2) % (N 3 :% 2)))+_testSlash_IntN2_Rat4N3 = Dict @((P 3 :% 2) ~ ((N 2) % (N 4 :% 3)))+_testSlash_IntN2_Rat1N1 = Dict @((P 2 :% 1) ~ ((N 2) % (N 1 :% 1)))+_testSlash_IntN2_Rat3N4 = Dict @((P 8 :% 3) ~ ((N 2) % (N 3 :% 4)))+_testSlash_IntN2_Rat2N3 = Dict @((P 3 :% 1) ~ ((N 2) % (N 2 :% 3)))+_testSlash_IntN2_Rat1N2 = Dict @((P 4 :% 1) ~ ((N 2) % (N 1 :% 2)))+_testSlash_IntN2_Rat1N3 = Dict @((P 6 :% 1) ~ ((N 2) % (N 1 :% 3)))+_testSlash_IntN2_Rat1N4 = Dict @((P 8 :% 1) ~ ((N 2) % (N 1 :% 4)))+_testSlash_IntN2_Rat1P4 = Dict @((N 8 :% 1) ~ ((N 2) % (P 1 :% 4)))+_testSlash_IntN2_Rat1P3 = Dict @((N 6 :% 1) ~ ((N 2) % (P 1 :% 3)))+_testSlash_IntN2_Rat1P2 = Dict @((N 4 :% 1) ~ ((N 2) % (P 1 :% 2)))+_testSlash_IntN2_Rat2P3 = Dict @((N 3 :% 1) ~ ((N 2) % (P 2 :% 3)))+_testSlash_IntN2_Rat3P4 = Dict @((N 8 :% 3) ~ ((N 2) % (P 3 :% 4)))+_testSlash_IntN2_Rat1P1 = Dict @((N 2 :% 1) ~ ((N 2) % (P 1 :% 1)))+_testSlash_IntN2_Rat4P3 = Dict @((N 3 :% 2) ~ ((N 2) % (P 4 :% 3)))+_testSlash_IntN2_Rat3P2 = Dict @((N 4 :% 3) ~ ((N 2) % (P 3 :% 2)))+_testSlash_IntN2_Rat2P1 = Dict @((N 1 :% 1) ~ ((N 2) % (P 2 :% 1)))+_testSlash_IntN2_Rat3P1 = Dict @((N 2 :% 3) ~ ((N 2) % (P 3 :% 1)))+_testSlash_IntN2_Rat4P1 = Dict @((N 1 :% 2) ~ ((N 2) % (P 4 :% 1)))+_testSlash_IntN1_Nat1 = Dict @((N 1 :% 1) ~ ((N 1) % 1))+_testSlash_IntN1_Nat2 = Dict @((N 1 :% 2) ~ ((N 1) % 2))+_testSlash_IntN1_Nat3 = Dict @((N 1 :% 3) ~ ((N 1) % 3))+_testSlash_IntN1_Nat4 = Dict @((N 1 :% 4) ~ ((N 1) % 4))+_testSlash_IntN1_IntN4 = Dict @((P 1 :% 4) ~ ((N 1) % (N 4)))+_testSlash_IntN1_IntN3 = Dict @((P 1 :% 3) ~ ((N 1) % (N 3)))+_testSlash_IntN1_IntN2 = Dict @((P 1 :% 2) ~ ((N 1) % (N 2)))+_testSlash_IntN1_IntN1 = Dict @((P 1 :% 1) ~ ((N 1) % (N 1)))+_testSlash_IntN1_IntP1 = Dict @((N 1 :% 1) ~ ((N 1) % (P 1)))+_testSlash_IntN1_IntP2 = Dict @((N 1 :% 2) ~ ((N 1) % (P 2)))+_testSlash_IntN1_IntP3 = Dict @((N 1 :% 3) ~ ((N 1) % (P 3)))+_testSlash_IntN1_IntP4 = Dict @((N 1 :% 4) ~ ((N 1) % (P 4)))+_testSlash_IntN1_Rat4N1 = Dict @((P 1 :% 4) ~ ((N 1) % (N 4 :% 1)))+_testSlash_IntN1_Rat3N1 = Dict @((P 1 :% 3) ~ ((N 1) % (N 3 :% 1)))+_testSlash_IntN1_Rat2N1 = Dict @((P 1 :% 2) ~ ((N 1) % (N 2 :% 1)))+_testSlash_IntN1_Rat3N2 = Dict @((P 2 :% 3) ~ ((N 1) % (N 3 :% 2)))+_testSlash_IntN1_Rat4N3 = Dict @((P 3 :% 4) ~ ((N 1) % (N 4 :% 3)))+_testSlash_IntN1_Rat1N1 = Dict @((P 1 :% 1) ~ ((N 1) % (N 1 :% 1)))+_testSlash_IntN1_Rat3N4 = Dict @((P 4 :% 3) ~ ((N 1) % (N 3 :% 4)))+_testSlash_IntN1_Rat2N3 = Dict @((P 3 :% 2) ~ ((N 1) % (N 2 :% 3)))+_testSlash_IntN1_Rat1N2 = Dict @((P 2 :% 1) ~ ((N 1) % (N 1 :% 2)))+_testSlash_IntN1_Rat1N3 = Dict @((P 3 :% 1) ~ ((N 1) % (N 1 :% 3)))+_testSlash_IntN1_Rat1N4 = Dict @((P 4 :% 1) ~ ((N 1) % (N 1 :% 4)))+_testSlash_IntN1_Rat1P4 = Dict @((N 4 :% 1) ~ ((N 1) % (P 1 :% 4)))+_testSlash_IntN1_Rat1P3 = Dict @((N 3 :% 1) ~ ((N 1) % (P 1 :% 3)))+_testSlash_IntN1_Rat1P2 = Dict @((N 2 :% 1) ~ ((N 1) % (P 1 :% 2)))+_testSlash_IntN1_Rat2P3 = Dict @((N 3 :% 2) ~ ((N 1) % (P 2 :% 3)))+_testSlash_IntN1_Rat3P4 = Dict @((N 4 :% 3) ~ ((N 1) % (P 3 :% 4)))+_testSlash_IntN1_Rat1P1 = Dict @((N 1 :% 1) ~ ((N 1) % (P 1 :% 1)))+_testSlash_IntN1_Rat4P3 = Dict @((N 3 :% 4) ~ ((N 1) % (P 4 :% 3)))+_testSlash_IntN1_Rat3P2 = Dict @((N 2 :% 3) ~ ((N 1) % (P 3 :% 2)))+_testSlash_IntN1_Rat2P1 = Dict @((N 1 :% 2) ~ ((N 1) % (P 2 :% 1)))+_testSlash_IntN1_Rat3P1 = Dict @((N 1 :% 3) ~ ((N 1) % (P 3 :% 1)))+_testSlash_IntN1_Rat4P1 = Dict @((N 1 :% 4) ~ ((N 1) % (P 4 :% 1)))+_testSlash_IntP0_Nat1 = Dict @((Z :% 1) ~ (Z % 1))+_testSlash_IntP0_Nat2 = Dict @((Z :% 1) ~ (Z % 2))+_testSlash_IntP0_Nat3 = Dict @((Z :% 1) ~ (Z % 3))+_testSlash_IntP0_Nat4 = Dict @((Z :% 1) ~ (Z % 4))+_testSlash_IntP0_IntN4 = Dict @((Z :% 1) ~ (Z % (N 4)))+_testSlash_IntP0_IntN3 = Dict @((Z :% 1) ~ (Z % (N 3)))+_testSlash_IntP0_IntN2 = Dict @((Z :% 1) ~ (Z % (N 2)))+_testSlash_IntP0_IntN1 = Dict @((Z :% 1) ~ (Z % (N 1)))+_testSlash_IntP0_IntP1 = Dict @((Z :% 1) ~ (Z % (P 1)))+_testSlash_IntP0_IntP2 = Dict @((Z :% 1) ~ (Z % (P 2)))+_testSlash_IntP0_IntP3 = Dict @((Z :% 1) ~ (Z % (P 3)))+_testSlash_IntP0_IntP4 = Dict @((Z :% 1) ~ (Z % (P 4)))+_testSlash_IntP0_Rat4N1 = Dict @((Z :% 1) ~ (Z % (N 4 :% 1)))+_testSlash_IntP0_Rat3N1 = Dict @((Z :% 1) ~ (Z % (N 3 :% 1)))+_testSlash_IntP0_Rat2N1 = Dict @((Z :% 1) ~ (Z % (N 2 :% 1)))+_testSlash_IntP0_Rat3N2 = Dict @((Z :% 1) ~ (Z % (N 3 :% 2)))+_testSlash_IntP0_Rat4N3 = Dict @((Z :% 1) ~ (Z % (N 4 :% 3)))+_testSlash_IntP0_Rat1N1 = Dict @((Z :% 1) ~ (Z % (N 1 :% 1)))+_testSlash_IntP0_Rat3N4 = Dict @((Z :% 1) ~ (Z % (N 3 :% 4)))+_testSlash_IntP0_Rat2N3 = Dict @((Z :% 1) ~ (Z % (N 2 :% 3)))+_testSlash_IntP0_Rat1N2 = Dict @((Z :% 1) ~ (Z % (N 1 :% 2)))+_testSlash_IntP0_Rat1N3 = Dict @((Z :% 1) ~ (Z % (N 1 :% 3)))+_testSlash_IntP0_Rat1N4 = Dict @((Z :% 1) ~ (Z % (N 1 :% 4)))+_testSlash_IntP0_Rat1P4 = Dict @((Z :% 1) ~ (Z % (P 1 :% 4)))+_testSlash_IntP0_Rat1P3 = Dict @((Z :% 1) ~ (Z % (P 1 :% 3)))+_testSlash_IntP0_Rat1P2 = Dict @((Z :% 1) ~ (Z % (P 1 :% 2)))+_testSlash_IntP0_Rat2P3 = Dict @((Z :% 1) ~ (Z % (P 2 :% 3)))+_testSlash_IntP0_Rat3P4 = Dict @((Z :% 1) ~ (Z % (P 3 :% 4)))+_testSlash_IntP0_Rat1P1 = Dict @((Z :% 1) ~ (Z % (P 1 :% 1)))+_testSlash_IntP0_Rat4P3 = Dict @((Z :% 1) ~ (Z % (P 4 :% 3)))+_testSlash_IntP0_Rat3P2 = Dict @((Z :% 1) ~ (Z % (P 3 :% 2)))+_testSlash_IntP0_Rat2P1 = Dict @((Z :% 1) ~ (Z % (P 2 :% 1)))+_testSlash_IntP0_Rat3P1 = Dict @((Z :% 1) ~ (Z % (P 3 :% 1)))+_testSlash_IntP0_Rat4P1 = Dict @((Z :% 1) ~ (Z % (P 4 :% 1)))+_testSlash_IntP1_Nat1 = Dict @((P 1 :% 1) ~ ((P 1) % 1))+_testSlash_IntP1_Nat2 = Dict @((P 1 :% 2) ~ ((P 1) % 2))+_testSlash_IntP1_Nat3 = Dict @((P 1 :% 3) ~ ((P 1) % 3))+_testSlash_IntP1_Nat4 = Dict @((P 1 :% 4) ~ ((P 1) % 4))+_testSlash_IntP1_IntN4 = Dict @((N 1 :% 4) ~ ((P 1) % (N 4)))+_testSlash_IntP1_IntN3 = Dict @((N 1 :% 3) ~ ((P 1) % (N 3)))+_testSlash_IntP1_IntN2 = Dict @((N 1 :% 2) ~ ((P 1) % (N 2)))+_testSlash_IntP1_IntN1 = Dict @((N 1 :% 1) ~ ((P 1) % (N 1)))+_testSlash_IntP1_IntP1 = Dict @((P 1 :% 1) ~ ((P 1) % (P 1)))+_testSlash_IntP1_IntP2 = Dict @((P 1 :% 2) ~ ((P 1) % (P 2)))+_testSlash_IntP1_IntP3 = Dict @((P 1 :% 3) ~ ((P 1) % (P 3)))+_testSlash_IntP1_IntP4 = Dict @((P 1 :% 4) ~ ((P 1) % (P 4)))+_testSlash_IntP1_Rat4N1 = Dict @((N 1 :% 4) ~ ((P 1) % (N 4 :% 1)))+_testSlash_IntP1_Rat3N1 = Dict @((N 1 :% 3) ~ ((P 1) % (N 3 :% 1)))+_testSlash_IntP1_Rat2N1 = Dict @((N 1 :% 2) ~ ((P 1) % (N 2 :% 1)))+_testSlash_IntP1_Rat3N2 = Dict @((N 2 :% 3) ~ ((P 1) % (N 3 :% 2)))+_testSlash_IntP1_Rat4N3 = Dict @((N 3 :% 4) ~ ((P 1) % (N 4 :% 3)))+_testSlash_IntP1_Rat1N1 = Dict @((N 1 :% 1) ~ ((P 1) % (N 1 :% 1)))+_testSlash_IntP1_Rat3N4 = Dict @((N 4 :% 3) ~ ((P 1) % (N 3 :% 4)))+_testSlash_IntP1_Rat2N3 = Dict @((N 3 :% 2) ~ ((P 1) % (N 2 :% 3)))+_testSlash_IntP1_Rat1N2 = Dict @((N 2 :% 1) ~ ((P 1) % (N 1 :% 2)))+_testSlash_IntP1_Rat1N3 = Dict @((N 3 :% 1) ~ ((P 1) % (N 1 :% 3)))+_testSlash_IntP1_Rat1N4 = Dict @((N 4 :% 1) ~ ((P 1) % (N 1 :% 4)))+_testSlash_IntP1_Rat1P4 = Dict @((P 4 :% 1) ~ ((P 1) % (P 1 :% 4)))+_testSlash_IntP1_Rat1P3 = Dict @((P 3 :% 1) ~ ((P 1) % (P 1 :% 3)))+_testSlash_IntP1_Rat1P2 = Dict @((P 2 :% 1) ~ ((P 1) % (P 1 :% 2)))+_testSlash_IntP1_Rat2P3 = Dict @((P 3 :% 2) ~ ((P 1) % (P 2 :% 3)))+_testSlash_IntP1_Rat3P4 = Dict @((P 4 :% 3) ~ ((P 1) % (P 3 :% 4)))+_testSlash_IntP1_Rat1P1 = Dict @((P 1 :% 1) ~ ((P 1) % (P 1 :% 1)))+_testSlash_IntP1_Rat4P3 = Dict @((P 3 :% 4) ~ ((P 1) % (P 4 :% 3)))+_testSlash_IntP1_Rat3P2 = Dict @((P 2 :% 3) ~ ((P 1) % (P 3 :% 2)))+_testSlash_IntP1_Rat2P1 = Dict @((P 1 :% 2) ~ ((P 1) % (P 2 :% 1)))+_testSlash_IntP1_Rat3P1 = Dict @((P 1 :% 3) ~ ((P 1) % (P 3 :% 1)))+_testSlash_IntP1_Rat4P1 = Dict @((P 1 :% 4) ~ ((P 1) % (P 4 :% 1)))+_testSlash_IntP2_Nat1 = Dict @((P 2 :% 1) ~ ((P 2) % 1))+_testSlash_IntP2_Nat2 = Dict @((P 1 :% 1) ~ ((P 2) % 2))+_testSlash_IntP2_Nat3 = Dict @((P 2 :% 3) ~ ((P 2) % 3))+_testSlash_IntP2_Nat4 = Dict @((P 1 :% 2) ~ ((P 2) % 4))+_testSlash_IntP2_IntN4 = Dict @((N 1 :% 2) ~ ((P 2) % (N 4)))+_testSlash_IntP2_IntN3 = Dict @((N 2 :% 3) ~ ((P 2) % (N 3)))+_testSlash_IntP2_IntN2 = Dict @((N 1 :% 1) ~ ((P 2) % (N 2)))+_testSlash_IntP2_IntN1 = Dict @((N 2 :% 1) ~ ((P 2) % (N 1)))+_testSlash_IntP2_IntP1 = Dict @((P 2 :% 1) ~ ((P 2) % (P 1)))+_testSlash_IntP2_IntP2 = Dict @((P 1 :% 1) ~ ((P 2) % (P 2)))+_testSlash_IntP2_IntP3 = Dict @((P 2 :% 3) ~ ((P 2) % (P 3)))+_testSlash_IntP2_IntP4 = Dict @((P 1 :% 2) ~ ((P 2) % (P 4)))+_testSlash_IntP2_Rat4N1 = Dict @((N 1 :% 2) ~ ((P 2) % (N 4 :% 1)))+_testSlash_IntP2_Rat3N1 = Dict @((N 2 :% 3) ~ ((P 2) % (N 3 :% 1)))+_testSlash_IntP2_Rat2N1 = Dict @((N 1 :% 1) ~ ((P 2) % (N 2 :% 1)))+_testSlash_IntP2_Rat3N2 = Dict @((N 4 :% 3) ~ ((P 2) % (N 3 :% 2)))+_testSlash_IntP2_Rat4N3 = Dict @((N 3 :% 2) ~ ((P 2) % (N 4 :% 3)))+_testSlash_IntP2_Rat1N1 = Dict @((N 2 :% 1) ~ ((P 2) % (N 1 :% 1)))+_testSlash_IntP2_Rat3N4 = Dict @((N 8 :% 3) ~ ((P 2) % (N 3 :% 4)))+_testSlash_IntP2_Rat2N3 = Dict @((N 3 :% 1) ~ ((P 2) % (N 2 :% 3)))+_testSlash_IntP2_Rat1N2 = Dict @((N 4 :% 1) ~ ((P 2) % (N 1 :% 2)))+_testSlash_IntP2_Rat1N3 = Dict @((N 6 :% 1) ~ ((P 2) % (N 1 :% 3)))+_testSlash_IntP2_Rat1N4 = Dict @((N 8 :% 1) ~ ((P 2) % (N 1 :% 4)))+_testSlash_IntP2_Rat1P4 = Dict @((P 8 :% 1) ~ ((P 2) % (P 1 :% 4)))+_testSlash_IntP2_Rat1P3 = Dict @((P 6 :% 1) ~ ((P 2) % (P 1 :% 3)))+_testSlash_IntP2_Rat1P2 = Dict @((P 4 :% 1) ~ ((P 2) % (P 1 :% 2)))+_testSlash_IntP2_Rat2P3 = Dict @((P 3 :% 1) ~ ((P 2) % (P 2 :% 3)))+_testSlash_IntP2_Rat3P4 = Dict @((P 8 :% 3) ~ ((P 2) % (P 3 :% 4)))+_testSlash_IntP2_Rat1P1 = Dict @((P 2 :% 1) ~ ((P 2) % (P 1 :% 1)))+_testSlash_IntP2_Rat4P3 = Dict @((P 3 :% 2) ~ ((P 2) % (P 4 :% 3)))+_testSlash_IntP2_Rat3P2 = Dict @((P 4 :% 3) ~ ((P 2) % (P 3 :% 2)))+_testSlash_IntP2_Rat2P1 = Dict @((P 1 :% 1) ~ ((P 2) % (P 2 :% 1)))+_testSlash_IntP2_Rat3P1 = Dict @((P 2 :% 3) ~ ((P 2) % (P 3 :% 1)))+_testSlash_IntP2_Rat4P1 = Dict @((P 1 :% 2) ~ ((P 2) % (P 4 :% 1)))+_testSlash_IntP3_Nat1 = Dict @((P 3 :% 1) ~ ((P 3) % 1))+_testSlash_IntP3_Nat2 = Dict @((P 3 :% 2) ~ ((P 3) % 2))+_testSlash_IntP3_Nat3 = Dict @((P 1 :% 1) ~ ((P 3) % 3))+_testSlash_IntP3_Nat4 = Dict @((P 3 :% 4) ~ ((P 3) % 4))+_testSlash_IntP3_IntN4 = Dict @((N 3 :% 4) ~ ((P 3) % (N 4)))+_testSlash_IntP3_IntN3 = Dict @((N 1 :% 1) ~ ((P 3) % (N 3)))+_testSlash_IntP3_IntN2 = Dict @((N 3 :% 2) ~ ((P 3) % (N 2)))+_testSlash_IntP3_IntN1 = Dict @((N 3 :% 1) ~ ((P 3) % (N 1)))+_testSlash_IntP3_IntP1 = Dict @((P 3 :% 1) ~ ((P 3) % (P 1)))+_testSlash_IntP3_IntP2 = Dict @((P 3 :% 2) ~ ((P 3) % (P 2)))+_testSlash_IntP3_IntP3 = Dict @((P 1 :% 1) ~ ((P 3) % (P 3)))+_testSlash_IntP3_IntP4 = Dict @((P 3 :% 4) ~ ((P 3) % (P 4)))+_testSlash_IntP3_Rat4N1 = Dict @((N 3 :% 4) ~ ((P 3) % (N 4 :% 1)))+_testSlash_IntP3_Rat3N1 = Dict @((N 1 :% 1) ~ ((P 3) % (N 3 :% 1)))+_testSlash_IntP3_Rat2N1 = Dict @((N 3 :% 2) ~ ((P 3) % (N 2 :% 1)))+_testSlash_IntP3_Rat3N2 = Dict @((N 2 :% 1) ~ ((P 3) % (N 3 :% 2)))+_testSlash_IntP3_Rat4N3 = Dict @((N 9 :% 4) ~ ((P 3) % (N 4 :% 3)))+_testSlash_IntP3_Rat1N1 = Dict @((N 3 :% 1) ~ ((P 3) % (N 1 :% 1)))+_testSlash_IntP3_Rat3N4 = Dict @((N 4 :% 1) ~ ((P 3) % (N 3 :% 4)))+_testSlash_IntP3_Rat2N3 = Dict @((N 9 :% 2) ~ ((P 3) % (N 2 :% 3)))+_testSlash_IntP3_Rat1N2 = Dict @((N 6 :% 1) ~ ((P 3) % (N 1 :% 2)))+_testSlash_IntP3_Rat1N3 = Dict @((N 9 :% 1) ~ ((P 3) % (N 1 :% 3)))+_testSlash_IntP3_Rat1N4 = Dict @((N 12 :% 1) ~ ((P 3) % (N 1 :% 4)))+_testSlash_IntP3_Rat1P4 = Dict @((P 12 :% 1) ~ ((P 3) % (P 1 :% 4)))+_testSlash_IntP3_Rat1P3 = Dict @((P 9 :% 1) ~ ((P 3) % (P 1 :% 3)))+_testSlash_IntP3_Rat1P2 = Dict @((P 6 :% 1) ~ ((P 3) % (P 1 :% 2)))+_testSlash_IntP3_Rat2P3 = Dict @((P 9 :% 2) ~ ((P 3) % (P 2 :% 3)))+_testSlash_IntP3_Rat3P4 = Dict @((P 4 :% 1) ~ ((P 3) % (P 3 :% 4)))+_testSlash_IntP3_Rat1P1 = Dict @((P 3 :% 1) ~ ((P 3) % (P 1 :% 1)))+_testSlash_IntP3_Rat4P3 = Dict @((P 9 :% 4) ~ ((P 3) % (P 4 :% 3)))+_testSlash_IntP3_Rat3P2 = Dict @((P 2 :% 1) ~ ((P 3) % (P 3 :% 2)))+_testSlash_IntP3_Rat2P1 = Dict @((P 3 :% 2) ~ ((P 3) % (P 2 :% 1)))+_testSlash_IntP3_Rat3P1 = Dict @((P 1 :% 1) ~ ((P 3) % (P 3 :% 1)))+_testSlash_IntP3_Rat4P1 = Dict @((P 3 :% 4) ~ ((P 3) % (P 4 :% 1)))+_testSlash_IntP4_Nat1 = Dict @((P 4 :% 1) ~ ((P 4) % 1))+_testSlash_IntP4_Nat2 = Dict @((P 2 :% 1) ~ ((P 4) % 2))+_testSlash_IntP4_Nat3 = Dict @((P 4 :% 3) ~ ((P 4) % 3))+_testSlash_IntP4_Nat4 = Dict @((P 1 :% 1) ~ ((P 4) % 4))+_testSlash_IntP4_IntN4 = Dict @((N 1 :% 1) ~ ((P 4) % (N 4)))+_testSlash_IntP4_IntN3 = Dict @((N 4 :% 3) ~ ((P 4) % (N 3)))+_testSlash_IntP4_IntN2 = Dict @((N 2 :% 1) ~ ((P 4) % (N 2)))+_testSlash_IntP4_IntN1 = Dict @((N 4 :% 1) ~ ((P 4) % (N 1)))+_testSlash_IntP4_IntP1 = Dict @((P 4 :% 1) ~ ((P 4) % (P 1)))+_testSlash_IntP4_IntP2 = Dict @((P 2 :% 1) ~ ((P 4) % (P 2)))+_testSlash_IntP4_IntP3 = Dict @((P 4 :% 3) ~ ((P 4) % (P 3)))+_testSlash_IntP4_IntP4 = Dict @((P 1 :% 1) ~ ((P 4) % (P 4)))+_testSlash_IntP4_Rat4N1 = Dict @((N 1 :% 1) ~ ((P 4) % (N 4 :% 1)))+_testSlash_IntP4_Rat3N1 = Dict @((N 4 :% 3) ~ ((P 4) % (N 3 :% 1)))+_testSlash_IntP4_Rat2N1 = Dict @((N 2 :% 1) ~ ((P 4) % (N 2 :% 1)))+_testSlash_IntP4_Rat3N2 = Dict @((N 8 :% 3) ~ ((P 4) % (N 3 :% 2)))+_testSlash_IntP4_Rat4N3 = Dict @((N 3 :% 1) ~ ((P 4) % (N 4 :% 3)))+_testSlash_IntP4_Rat1N1 = Dict @((N 4 :% 1) ~ ((P 4) % (N 1 :% 1)))+_testSlash_IntP4_Rat3N4 = Dict @((N 16 :% 3) ~ ((P 4) % (N 3 :% 4)))+_testSlash_IntP4_Rat2N3 = Dict @((N 6 :% 1) ~ ((P 4) % (N 2 :% 3)))+_testSlash_IntP4_Rat1N2 = Dict @((N 8 :% 1) ~ ((P 4) % (N 1 :% 2)))+_testSlash_IntP4_Rat1N3 = Dict @((N 12 :% 1) ~ ((P 4) % (N 1 :% 3)))+_testSlash_IntP4_Rat1N4 = Dict @((N 16 :% 1) ~ ((P 4) % (N 1 :% 4)))+_testSlash_IntP4_Rat1P4 = Dict @((P 16 :% 1) ~ ((P 4) % (P 1 :% 4)))+_testSlash_IntP4_Rat1P3 = Dict @((P 12 :% 1) ~ ((P 4) % (P 1 :% 3)))+_testSlash_IntP4_Rat1P2 = Dict @((P 8 :% 1) ~ ((P 4) % (P 1 :% 2)))+_testSlash_IntP4_Rat2P3 = Dict @((P 6 :% 1) ~ ((P 4) % (P 2 :% 3)))+_testSlash_IntP4_Rat3P4 = Dict @((P 16 :% 3) ~ ((P 4) % (P 3 :% 4)))+_testSlash_IntP4_Rat1P1 = Dict @((P 4 :% 1) ~ ((P 4) % (P 1 :% 1)))+_testSlash_IntP4_Rat4P3 = Dict @((P 3 :% 1) ~ ((P 4) % (P 4 :% 3)))+_testSlash_IntP4_Rat3P2 = Dict @((P 8 :% 3) ~ ((P 4) % (P 3 :% 2)))+_testSlash_IntP4_Rat2P1 = Dict @((P 2 :% 1) ~ ((P 4) % (P 2 :% 1)))+_testSlash_IntP4_Rat3P1 = Dict @((P 4 :% 3) ~ ((P 4) % (P 3 :% 1)))+_testSlash_IntP4_Rat4P1 = Dict @((P 1 :% 1) ~ ((P 4) % (P 4 :% 1)))+_testSlash_Rat4N1_Nat1 = Dict @((N 4 :% 1) ~ ((N 4 :% 1) % 1))+_testSlash_Rat4N1_Nat2 = Dict @((N 2 :% 1) ~ ((N 4 :% 1) % 2))+_testSlash_Rat4N1_Nat3 = Dict @((N 4 :% 3) ~ ((N 4 :% 1) % 3))+_testSlash_Rat4N1_Nat4 = Dict @((N 1 :% 1) ~ ((N 4 :% 1) % 4))+_testSlash_Rat4N1_IntN4 = Dict @((P 1 :% 1) ~ ((N 4 :% 1) % (N 4)))+_testSlash_Rat4N1_IntN3 = Dict @((P 4 :% 3) ~ ((N 4 :% 1) % (N 3)))+_testSlash_Rat4N1_IntN2 = Dict @((P 2 :% 1) ~ ((N 4 :% 1) % (N 2)))+_testSlash_Rat4N1_IntN1 = Dict @((P 4 :% 1) ~ ((N 4 :% 1) % (N 1)))+_testSlash_Rat4N1_IntP1 = Dict @((N 4 :% 1) ~ ((N 4 :% 1) % (P 1)))+_testSlash_Rat4N1_IntP2 = Dict @((N 2 :% 1) ~ ((N 4 :% 1) % (P 2)))+_testSlash_Rat4N1_IntP3 = Dict @((N 4 :% 3) ~ ((N 4 :% 1) % (P 3)))+_testSlash_Rat4N1_IntP4 = Dict @((N 1 :% 1) ~ ((N 4 :% 1) % (P 4)))+_testSlash_Rat4N1_Rat4N1 = Dict @((P 1 :% 1) ~ ((N 4 :% 1) % (N 4 :% 1)))+_testSlash_Rat4N1_Rat3N1 = Dict @((P 4 :% 3) ~ ((N 4 :% 1) % (N 3 :% 1)))+_testSlash_Rat4N1_Rat2N1 = Dict @((P 2 :% 1) ~ ((N 4 :% 1) % (N 2 :% 1)))+_testSlash_Rat4N1_Rat3N2 = Dict @((P 8 :% 3) ~ ((N 4 :% 1) % (N 3 :% 2)))+_testSlash_Rat4N1_Rat4N3 = Dict @((P 3 :% 1) ~ ((N 4 :% 1) % (N 4 :% 3)))+_testSlash_Rat4N1_Rat1N1 = Dict @((P 4 :% 1) ~ ((N 4 :% 1) % (N 1 :% 1)))+_testSlash_Rat4N1_Rat3N4 = Dict @((P 16 :% 3) ~ ((N 4 :% 1) % (N 3 :% 4)))+_testSlash_Rat4N1_Rat2N3 = Dict @((P 6 :% 1) ~ ((N 4 :% 1) % (N 2 :% 3)))+_testSlash_Rat4N1_Rat1N2 = Dict @((P 8 :% 1) ~ ((N 4 :% 1) % (N 1 :% 2)))+_testSlash_Rat4N1_Rat1N3 = Dict @((P 12 :% 1) ~ ((N 4 :% 1) % (N 1 :% 3)))+_testSlash_Rat4N1_Rat1N4 = Dict @((P 16 :% 1) ~ ((N 4 :% 1) % (N 1 :% 4)))+_testSlash_Rat4N1_Rat1P4 = Dict @((N 16 :% 1) ~ ((N 4 :% 1) % (P 1 :% 4)))+_testSlash_Rat4N1_Rat1P3 = Dict @((N 12 :% 1) ~ ((N 4 :% 1) % (P 1 :% 3)))+_testSlash_Rat4N1_Rat1P2 = Dict @((N 8 :% 1) ~ ((N 4 :% 1) % (P 1 :% 2)))+_testSlash_Rat4N1_Rat2P3 = Dict @((N 6 :% 1) ~ ((N 4 :% 1) % (P 2 :% 3)))+_testSlash_Rat4N1_Rat3P4 = Dict @((N 16 :% 3) ~ ((N 4 :% 1) % (P 3 :% 4)))+_testSlash_Rat4N1_Rat1P1 = Dict @((N 4 :% 1) ~ ((N 4 :% 1) % (P 1 :% 1)))+_testSlash_Rat4N1_Rat4P3 = Dict @((N 3 :% 1) ~ ((N 4 :% 1) % (P 4 :% 3)))+_testSlash_Rat4N1_Rat3P2 = Dict @((N 8 :% 3) ~ ((N 4 :% 1) % (P 3 :% 2)))+_testSlash_Rat4N1_Rat2P1 = Dict @((N 2 :% 1) ~ ((N 4 :% 1) % (P 2 :% 1)))+_testSlash_Rat4N1_Rat3P1 = Dict @((N 4 :% 3) ~ ((N 4 :% 1) % (P 3 :% 1)))+_testSlash_Rat4N1_Rat4P1 = Dict @((N 1 :% 1) ~ ((N 4 :% 1) % (P 4 :% 1)))+_testSlash_Rat3N1_Nat1 = Dict @((N 3 :% 1) ~ ((N 3 :% 1) % 1))+_testSlash_Rat3N1_Nat2 = Dict @((N 3 :% 2) ~ ((N 3 :% 1) % 2))+_testSlash_Rat3N1_Nat3 = Dict @((N 1 :% 1) ~ ((N 3 :% 1) % 3))+_testSlash_Rat3N1_Nat4 = Dict @((N 3 :% 4) ~ ((N 3 :% 1) % 4))+_testSlash_Rat3N1_IntN4 = Dict @((P 3 :% 4) ~ ((N 3 :% 1) % (N 4)))+_testSlash_Rat3N1_IntN3 = Dict @((P 1 :% 1) ~ ((N 3 :% 1) % (N 3)))+_testSlash_Rat3N1_IntN2 = Dict @((P 3 :% 2) ~ ((N 3 :% 1) % (N 2)))+_testSlash_Rat3N1_IntN1 = Dict @((P 3 :% 1) ~ ((N 3 :% 1) % (N 1)))+_testSlash_Rat3N1_IntP1 = Dict @((N 3 :% 1) ~ ((N 3 :% 1) % (P 1)))+_testSlash_Rat3N1_IntP2 = Dict @((N 3 :% 2) ~ ((N 3 :% 1) % (P 2)))+_testSlash_Rat3N1_IntP3 = Dict @((N 1 :% 1) ~ ((N 3 :% 1) % (P 3)))+_testSlash_Rat3N1_IntP4 = Dict @((N 3 :% 4) ~ ((N 3 :% 1) % (P 4)))+_testSlash_Rat3N1_Rat4N1 = Dict @((P 3 :% 4) ~ ((N 3 :% 1) % (N 4 :% 1)))+_testSlash_Rat3N1_Rat3N1 = Dict @((P 1 :% 1) ~ ((N 3 :% 1) % (N 3 :% 1)))+_testSlash_Rat3N1_Rat2N1 = Dict @((P 3 :% 2) ~ ((N 3 :% 1) % (N 2 :% 1)))+_testSlash_Rat3N1_Rat3N2 = Dict @((P 2 :% 1) ~ ((N 3 :% 1) % (N 3 :% 2)))+_testSlash_Rat3N1_Rat4N3 = Dict @((P 9 :% 4) ~ ((N 3 :% 1) % (N 4 :% 3)))+_testSlash_Rat3N1_Rat1N1 = Dict @((P 3 :% 1) ~ ((N 3 :% 1) % (N 1 :% 1)))+_testSlash_Rat3N1_Rat3N4 = Dict @((P 4 :% 1) ~ ((N 3 :% 1) % (N 3 :% 4)))+_testSlash_Rat3N1_Rat2N3 = Dict @((P 9 :% 2) ~ ((N 3 :% 1) % (N 2 :% 3)))+_testSlash_Rat3N1_Rat1N2 = Dict @((P 6 :% 1) ~ ((N 3 :% 1) % (N 1 :% 2)))+_testSlash_Rat3N1_Rat1N3 = Dict @((P 9 :% 1) ~ ((N 3 :% 1) % (N 1 :% 3)))+_testSlash_Rat3N1_Rat1N4 = Dict @((P 12 :% 1) ~ ((N 3 :% 1) % (N 1 :% 4)))+_testSlash_Rat3N1_Rat1P4 = Dict @((N 12 :% 1) ~ ((N 3 :% 1) % (P 1 :% 4)))+_testSlash_Rat3N1_Rat1P3 = Dict @((N 9 :% 1) ~ ((N 3 :% 1) % (P 1 :% 3)))+_testSlash_Rat3N1_Rat1P2 = Dict @((N 6 :% 1) ~ ((N 3 :% 1) % (P 1 :% 2)))+_testSlash_Rat3N1_Rat2P3 = Dict @((N 9 :% 2) ~ ((N 3 :% 1) % (P 2 :% 3)))+_testSlash_Rat3N1_Rat3P4 = Dict @((N 4 :% 1) ~ ((N 3 :% 1) % (P 3 :% 4)))+_testSlash_Rat3N1_Rat1P1 = Dict @((N 3 :% 1) ~ ((N 3 :% 1) % (P 1 :% 1)))+_testSlash_Rat3N1_Rat4P3 = Dict @((N 9 :% 4) ~ ((N 3 :% 1) % (P 4 :% 3)))+_testSlash_Rat3N1_Rat3P2 = Dict @((N 2 :% 1) ~ ((N 3 :% 1) % (P 3 :% 2)))+_testSlash_Rat3N1_Rat2P1 = Dict @((N 3 :% 2) ~ ((N 3 :% 1) % (P 2 :% 1)))+_testSlash_Rat3N1_Rat3P1 = Dict @((N 1 :% 1) ~ ((N 3 :% 1) % (P 3 :% 1)))+_testSlash_Rat3N1_Rat4P1 = Dict @((N 3 :% 4) ~ ((N 3 :% 1) % (P 4 :% 1)))+_testSlash_Rat2N1_Nat1 = Dict @((N 2 :% 1) ~ ((N 2 :% 1) % 1))+_testSlash_Rat2N1_Nat2 = Dict @((N 1 :% 1) ~ ((N 2 :% 1) % 2))+_testSlash_Rat2N1_Nat3 = Dict @((N 2 :% 3) ~ ((N 2 :% 1) % 3))+_testSlash_Rat2N1_Nat4 = Dict @((N 1 :% 2) ~ ((N 2 :% 1) % 4))+_testSlash_Rat2N1_IntN4 = Dict @((P 1 :% 2) ~ ((N 2 :% 1) % (N 4)))+_testSlash_Rat2N1_IntN3 = Dict @((P 2 :% 3) ~ ((N 2 :% 1) % (N 3)))+_testSlash_Rat2N1_IntN2 = Dict @((P 1 :% 1) ~ ((N 2 :% 1) % (N 2)))+_testSlash_Rat2N1_IntN1 = Dict @((P 2 :% 1) ~ ((N 2 :% 1) % (N 1)))+_testSlash_Rat2N1_IntP1 = Dict @((N 2 :% 1) ~ ((N 2 :% 1) % (P 1)))+_testSlash_Rat2N1_IntP2 = Dict @((N 1 :% 1) ~ ((N 2 :% 1) % (P 2)))+_testSlash_Rat2N1_IntP3 = Dict @((N 2 :% 3) ~ ((N 2 :% 1) % (P 3)))+_testSlash_Rat2N1_IntP4 = Dict @((N 1 :% 2) ~ ((N 2 :% 1) % (P 4)))+_testSlash_Rat2N1_Rat4N1 = Dict @((P 1 :% 2) ~ ((N 2 :% 1) % (N 4 :% 1)))+_testSlash_Rat2N1_Rat3N1 = Dict @((P 2 :% 3) ~ ((N 2 :% 1) % (N 3 :% 1)))+_testSlash_Rat2N1_Rat2N1 = Dict @((P 1 :% 1) ~ ((N 2 :% 1) % (N 2 :% 1)))+_testSlash_Rat2N1_Rat3N2 = Dict @((P 4 :% 3) ~ ((N 2 :% 1) % (N 3 :% 2)))+_testSlash_Rat2N1_Rat4N3 = Dict @((P 3 :% 2) ~ ((N 2 :% 1) % (N 4 :% 3)))+_testSlash_Rat2N1_Rat1N1 = Dict @((P 2 :% 1) ~ ((N 2 :% 1) % (N 1 :% 1)))+_testSlash_Rat2N1_Rat3N4 = Dict @((P 8 :% 3) ~ ((N 2 :% 1) % (N 3 :% 4)))+_testSlash_Rat2N1_Rat2N3 = Dict @((P 3 :% 1) ~ ((N 2 :% 1) % (N 2 :% 3)))+_testSlash_Rat2N1_Rat1N2 = Dict @((P 4 :% 1) ~ ((N 2 :% 1) % (N 1 :% 2)))+_testSlash_Rat2N1_Rat1N3 = Dict @((P 6 :% 1) ~ ((N 2 :% 1) % (N 1 :% 3)))+_testSlash_Rat2N1_Rat1N4 = Dict @((P 8 :% 1) ~ ((N 2 :% 1) % (N 1 :% 4)))+_testSlash_Rat2N1_Rat1P4 = Dict @((N 8 :% 1) ~ ((N 2 :% 1) % (P 1 :% 4)))+_testSlash_Rat2N1_Rat1P3 = Dict @((N 6 :% 1) ~ ((N 2 :% 1) % (P 1 :% 3)))+_testSlash_Rat2N1_Rat1P2 = Dict @((N 4 :% 1) ~ ((N 2 :% 1) % (P 1 :% 2)))+_testSlash_Rat2N1_Rat2P3 = Dict @((N 3 :% 1) ~ ((N 2 :% 1) % (P 2 :% 3)))+_testSlash_Rat2N1_Rat3P4 = Dict @((N 8 :% 3) ~ ((N 2 :% 1) % (P 3 :% 4)))+_testSlash_Rat2N1_Rat1P1 = Dict @((N 2 :% 1) ~ ((N 2 :% 1) % (P 1 :% 1)))+_testSlash_Rat2N1_Rat4P3 = Dict @((N 3 :% 2) ~ ((N 2 :% 1) % (P 4 :% 3)))+_testSlash_Rat2N1_Rat3P2 = Dict @((N 4 :% 3) ~ ((N 2 :% 1) % (P 3 :% 2)))+_testSlash_Rat2N1_Rat2P1 = Dict @((N 1 :% 1) ~ ((N 2 :% 1) % (P 2 :% 1)))+_testSlash_Rat2N1_Rat3P1 = Dict @((N 2 :% 3) ~ ((N 2 :% 1) % (P 3 :% 1)))+_testSlash_Rat2N1_Rat4P1 = Dict @((N 1 :% 2) ~ ((N 2 :% 1) % (P 4 :% 1)))+_testSlash_Rat3N2_Nat1 = Dict @((N 3 :% 2) ~ ((N 3 :% 2) % 1))+_testSlash_Rat3N2_Nat2 = Dict @((N 3 :% 4) ~ ((N 3 :% 2) % 2))+_testSlash_Rat3N2_Nat3 = Dict @((N 1 :% 2) ~ ((N 3 :% 2) % 3))+_testSlash_Rat3N2_Nat4 = Dict @((N 3 :% 8) ~ ((N 3 :% 2) % 4))+_testSlash_Rat3N2_IntN4 = Dict @((P 3 :% 8) ~ ((N 3 :% 2) % (N 4)))+_testSlash_Rat3N2_IntN3 = Dict @((P 1 :% 2) ~ ((N 3 :% 2) % (N 3)))+_testSlash_Rat3N2_IntN2 = Dict @((P 3 :% 4) ~ ((N 3 :% 2) % (N 2)))+_testSlash_Rat3N2_IntN1 = Dict @((P 3 :% 2) ~ ((N 3 :% 2) % (N 1)))+_testSlash_Rat3N2_IntP1 = Dict @((N 3 :% 2) ~ ((N 3 :% 2) % (P 1)))+_testSlash_Rat3N2_IntP2 = Dict @((N 3 :% 4) ~ ((N 3 :% 2) % (P 2)))+_testSlash_Rat3N2_IntP3 = Dict @((N 1 :% 2) ~ ((N 3 :% 2) % (P 3)))+_testSlash_Rat3N2_IntP4 = Dict @((N 3 :% 8) ~ ((N 3 :% 2) % (P 4)))+_testSlash_Rat3N2_Rat4N1 = Dict @((P 3 :% 8) ~ ((N 3 :% 2) % (N 4 :% 1)))+_testSlash_Rat3N2_Rat3N1 = Dict @((P 1 :% 2) ~ ((N 3 :% 2) % (N 3 :% 1)))+_testSlash_Rat3N2_Rat2N1 = Dict @((P 3 :% 4) ~ ((N 3 :% 2) % (N 2 :% 1)))+_testSlash_Rat3N2_Rat3N2 = Dict @((P 1 :% 1) ~ ((N 3 :% 2) % (N 3 :% 2)))+_testSlash_Rat3N2_Rat4N3 = Dict @((P 9 :% 8) ~ ((N 3 :% 2) % (N 4 :% 3)))+_testSlash_Rat3N2_Rat1N1 = Dict @((P 3 :% 2) ~ ((N 3 :% 2) % (N 1 :% 1)))+_testSlash_Rat3N2_Rat3N4 = Dict @((P 2 :% 1) ~ ((N 3 :% 2) % (N 3 :% 4)))+_testSlash_Rat3N2_Rat2N3 = Dict @((P 9 :% 4) ~ ((N 3 :% 2) % (N 2 :% 3)))+_testSlash_Rat3N2_Rat1N2 = Dict @((P 3 :% 1) ~ ((N 3 :% 2) % (N 1 :% 2)))+_testSlash_Rat3N2_Rat1N3 = Dict @((P 9 :% 2) ~ ((N 3 :% 2) % (N 1 :% 3)))+_testSlash_Rat3N2_Rat1N4 = Dict @((P 6 :% 1) ~ ((N 3 :% 2) % (N 1 :% 4)))+_testSlash_Rat3N2_Rat1P4 = Dict @((N 6 :% 1) ~ ((N 3 :% 2) % (P 1 :% 4)))+_testSlash_Rat3N2_Rat1P3 = Dict @((N 9 :% 2) ~ ((N 3 :% 2) % (P 1 :% 3)))+_testSlash_Rat3N2_Rat1P2 = Dict @((N 3 :% 1) ~ ((N 3 :% 2) % (P 1 :% 2)))+_testSlash_Rat3N2_Rat2P3 = Dict @((N 9 :% 4) ~ ((N 3 :% 2) % (P 2 :% 3)))+_testSlash_Rat3N2_Rat3P4 = Dict @((N 2 :% 1) ~ ((N 3 :% 2) % (P 3 :% 4)))+_testSlash_Rat3N2_Rat1P1 = Dict @((N 3 :% 2) ~ ((N 3 :% 2) % (P 1 :% 1)))+_testSlash_Rat3N2_Rat4P3 = Dict @((N 9 :% 8) ~ ((N 3 :% 2) % (P 4 :% 3)))+_testSlash_Rat3N2_Rat3P2 = Dict @((N 1 :% 1) ~ ((N 3 :% 2) % (P 3 :% 2)))+_testSlash_Rat3N2_Rat2P1 = Dict @((N 3 :% 4) ~ ((N 3 :% 2) % (P 2 :% 1)))+_testSlash_Rat3N2_Rat3P1 = Dict @((N 1 :% 2) ~ ((N 3 :% 2) % (P 3 :% 1)))+_testSlash_Rat3N2_Rat4P1 = Dict @((N 3 :% 8) ~ ((N 3 :% 2) % (P 4 :% 1)))+_testSlash_Rat4N3_Nat1 = Dict @((N 4 :% 3) ~ ((N 4 :% 3) % 1))+_testSlash_Rat4N3_Nat2 = Dict @((N 2 :% 3) ~ ((N 4 :% 3) % 2))+_testSlash_Rat4N3_Nat3 = Dict @((N 4 :% 9) ~ ((N 4 :% 3) % 3))+_testSlash_Rat4N3_Nat4 = Dict @((N 1 :% 3) ~ ((N 4 :% 3) % 4))+_testSlash_Rat4N3_IntN4 = Dict @((P 1 :% 3) ~ ((N 4 :% 3) % (N 4)))+_testSlash_Rat4N3_IntN3 = Dict @((P 4 :% 9) ~ ((N 4 :% 3) % (N 3)))+_testSlash_Rat4N3_IntN2 = Dict @((P 2 :% 3) ~ ((N 4 :% 3) % (N 2)))+_testSlash_Rat4N3_IntN1 = Dict @((P 4 :% 3) ~ ((N 4 :% 3) % (N 1)))+_testSlash_Rat4N3_IntP1 = Dict @((N 4 :% 3) ~ ((N 4 :% 3) % (P 1)))+_testSlash_Rat4N3_IntP2 = Dict @((N 2 :% 3) ~ ((N 4 :% 3) % (P 2)))+_testSlash_Rat4N3_IntP3 = Dict @((N 4 :% 9) ~ ((N 4 :% 3) % (P 3)))+_testSlash_Rat4N3_IntP4 = Dict @((N 1 :% 3) ~ ((N 4 :% 3) % (P 4)))+_testSlash_Rat4N3_Rat4N1 = Dict @((P 1 :% 3) ~ ((N 4 :% 3) % (N 4 :% 1)))+_testSlash_Rat4N3_Rat3N1 = Dict @((P 4 :% 9) ~ ((N 4 :% 3) % (N 3 :% 1)))+_testSlash_Rat4N3_Rat2N1 = Dict @((P 2 :% 3) ~ ((N 4 :% 3) % (N 2 :% 1)))+_testSlash_Rat4N3_Rat3N2 = Dict @((P 8 :% 9) ~ ((N 4 :% 3) % (N 3 :% 2)))+_testSlash_Rat4N3_Rat4N3 = Dict @((P 1 :% 1) ~ ((N 4 :% 3) % (N 4 :% 3)))+_testSlash_Rat4N3_Rat1N1 = Dict @((P 4 :% 3) ~ ((N 4 :% 3) % (N 1 :% 1)))+_testSlash_Rat4N3_Rat3N4 = Dict @((P 16 :% 9) ~ ((N 4 :% 3) % (N 3 :% 4)))+_testSlash_Rat4N3_Rat2N3 = Dict @((P 2 :% 1) ~ ((N 4 :% 3) % (N 2 :% 3)))+_testSlash_Rat4N3_Rat1N2 = Dict @((P 8 :% 3) ~ ((N 4 :% 3) % (N 1 :% 2)))+_testSlash_Rat4N3_Rat1N3 = Dict @((P 4 :% 1) ~ ((N 4 :% 3) % (N 1 :% 3)))+_testSlash_Rat4N3_Rat1N4 = Dict @((P 16 :% 3) ~ ((N 4 :% 3) % (N 1 :% 4)))+_testSlash_Rat4N3_Rat1P4 = Dict @((N 16 :% 3) ~ ((N 4 :% 3) % (P 1 :% 4)))+_testSlash_Rat4N3_Rat1P3 = Dict @((N 4 :% 1) ~ ((N 4 :% 3) % (P 1 :% 3)))+_testSlash_Rat4N3_Rat1P2 = Dict @((N 8 :% 3) ~ ((N 4 :% 3) % (P 1 :% 2)))+_testSlash_Rat4N3_Rat2P3 = Dict @((N 2 :% 1) ~ ((N 4 :% 3) % (P 2 :% 3)))+_testSlash_Rat4N3_Rat3P4 = Dict @((N 16 :% 9) ~ ((N 4 :% 3) % (P 3 :% 4)))+_testSlash_Rat4N3_Rat1P1 = Dict @((N 4 :% 3) ~ ((N 4 :% 3) % (P 1 :% 1)))+_testSlash_Rat4N3_Rat4P3 = Dict @((N 1 :% 1) ~ ((N 4 :% 3) % (P 4 :% 3)))+_testSlash_Rat4N3_Rat3P2 = Dict @((N 8 :% 9) ~ ((N 4 :% 3) % (P 3 :% 2)))+_testSlash_Rat4N3_Rat2P1 = Dict @((N 2 :% 3) ~ ((N 4 :% 3) % (P 2 :% 1)))+_testSlash_Rat4N3_Rat3P1 = Dict @((N 4 :% 9) ~ ((N 4 :% 3) % (P 3 :% 1)))+_testSlash_Rat4N3_Rat4P1 = Dict @((N 1 :% 3) ~ ((N 4 :% 3) % (P 4 :% 1)))+_testSlash_Rat1N1_Nat1 = Dict @((N 1 :% 1) ~ ((N 1 :% 1) % 1))+_testSlash_Rat1N1_Nat2 = Dict @((N 1 :% 2) ~ ((N 1 :% 1) % 2))+_testSlash_Rat1N1_Nat3 = Dict @((N 1 :% 3) ~ ((N 1 :% 1) % 3))+_testSlash_Rat1N1_Nat4 = Dict @((N 1 :% 4) ~ ((N 1 :% 1) % 4))+_testSlash_Rat1N1_IntN4 = Dict @((P 1 :% 4) ~ ((N 1 :% 1) % (N 4)))+_testSlash_Rat1N1_IntN3 = Dict @((P 1 :% 3) ~ ((N 1 :% 1) % (N 3)))+_testSlash_Rat1N1_IntN2 = Dict @((P 1 :% 2) ~ ((N 1 :% 1) % (N 2)))+_testSlash_Rat1N1_IntN1 = Dict @((P 1 :% 1) ~ ((N 1 :% 1) % (N 1)))+_testSlash_Rat1N1_IntP1 = Dict @((N 1 :% 1) ~ ((N 1 :% 1) % (P 1)))+_testSlash_Rat1N1_IntP2 = Dict @((N 1 :% 2) ~ ((N 1 :% 1) % (P 2)))+_testSlash_Rat1N1_IntP3 = Dict @((N 1 :% 3) ~ ((N 1 :% 1) % (P 3)))+_testSlash_Rat1N1_IntP4 = Dict @((N 1 :% 4) ~ ((N 1 :% 1) % (P 4)))+_testSlash_Rat1N1_Rat4N1 = Dict @((P 1 :% 4) ~ ((N 1 :% 1) % (N 4 :% 1)))+_testSlash_Rat1N1_Rat3N1 = Dict @((P 1 :% 3) ~ ((N 1 :% 1) % (N 3 :% 1)))+_testSlash_Rat1N1_Rat2N1 = Dict @((P 1 :% 2) ~ ((N 1 :% 1) % (N 2 :% 1)))+_testSlash_Rat1N1_Rat3N2 = Dict @((P 2 :% 3) ~ ((N 1 :% 1) % (N 3 :% 2)))+_testSlash_Rat1N1_Rat4N3 = Dict @((P 3 :% 4) ~ ((N 1 :% 1) % (N 4 :% 3)))+_testSlash_Rat1N1_Rat1N1 = Dict @((P 1 :% 1) ~ ((N 1 :% 1) % (N 1 :% 1)))+_testSlash_Rat1N1_Rat3N4 = Dict @((P 4 :% 3) ~ ((N 1 :% 1) % (N 3 :% 4)))+_testSlash_Rat1N1_Rat2N3 = Dict @((P 3 :% 2) ~ ((N 1 :% 1) % (N 2 :% 3)))+_testSlash_Rat1N1_Rat1N2 = Dict @((P 2 :% 1) ~ ((N 1 :% 1) % (N 1 :% 2)))+_testSlash_Rat1N1_Rat1N3 = Dict @((P 3 :% 1) ~ ((N 1 :% 1) % (N 1 :% 3)))+_testSlash_Rat1N1_Rat1N4 = Dict @((P 4 :% 1) ~ ((N 1 :% 1) % (N 1 :% 4)))+_testSlash_Rat1N1_Rat1P4 = Dict @((N 4 :% 1) ~ ((N 1 :% 1) % (P 1 :% 4)))+_testSlash_Rat1N1_Rat1P3 = Dict @((N 3 :% 1) ~ ((N 1 :% 1) % (P 1 :% 3)))+_testSlash_Rat1N1_Rat1P2 = Dict @((N 2 :% 1) ~ ((N 1 :% 1) % (P 1 :% 2)))+_testSlash_Rat1N1_Rat2P3 = Dict @((N 3 :% 2) ~ ((N 1 :% 1) % (P 2 :% 3)))+_testSlash_Rat1N1_Rat3P4 = Dict @((N 4 :% 3) ~ ((N 1 :% 1) % (P 3 :% 4)))+_testSlash_Rat1N1_Rat1P1 = Dict @((N 1 :% 1) ~ ((N 1 :% 1) % (P 1 :% 1)))+_testSlash_Rat1N1_Rat4P3 = Dict @((N 3 :% 4) ~ ((N 1 :% 1) % (P 4 :% 3)))+_testSlash_Rat1N1_Rat3P2 = Dict @((N 2 :% 3) ~ ((N 1 :% 1) % (P 3 :% 2)))+_testSlash_Rat1N1_Rat2P1 = Dict @((N 1 :% 2) ~ ((N 1 :% 1) % (P 2 :% 1)))+_testSlash_Rat1N1_Rat3P1 = Dict @((N 1 :% 3) ~ ((N 1 :% 1) % (P 3 :% 1)))+_testSlash_Rat1N1_Rat4P1 = Dict @((N 1 :% 4) ~ ((N 1 :% 1) % (P 4 :% 1)))+_testSlash_Rat3N4_Nat1 = Dict @((N 3 :% 4) ~ ((N 3 :% 4) % 1))+_testSlash_Rat3N4_Nat2 = Dict @((N 3 :% 8) ~ ((N 3 :% 4) % 2))+_testSlash_Rat3N4_Nat3 = Dict @((N 1 :% 4) ~ ((N 3 :% 4) % 3))+_testSlash_Rat3N4_Nat4 = Dict @((N 3 :% 16) ~ ((N 3 :% 4) % 4))+_testSlash_Rat3N4_IntN4 = Dict @((P 3 :% 16) ~ ((N 3 :% 4) % (N 4)))+_testSlash_Rat3N4_IntN3 = Dict @((P 1 :% 4) ~ ((N 3 :% 4) % (N 3)))+_testSlash_Rat3N4_IntN2 = Dict @((P 3 :% 8) ~ ((N 3 :% 4) % (N 2)))+_testSlash_Rat3N4_IntN1 = Dict @((P 3 :% 4) ~ ((N 3 :% 4) % (N 1)))+_testSlash_Rat3N4_IntP1 = Dict @((N 3 :% 4) ~ ((N 3 :% 4) % (P 1)))+_testSlash_Rat3N4_IntP2 = Dict @((N 3 :% 8) ~ ((N 3 :% 4) % (P 2)))+_testSlash_Rat3N4_IntP3 = Dict @((N 1 :% 4) ~ ((N 3 :% 4) % (P 3)))+_testSlash_Rat3N4_IntP4 = Dict @((N 3 :% 16) ~ ((N 3 :% 4) % (P 4)))+_testSlash_Rat3N4_Rat4N1 = Dict @((P 3 :% 16) ~ ((N 3 :% 4) % (N 4 :% 1)))+_testSlash_Rat3N4_Rat3N1 = Dict @((P 1 :% 4) ~ ((N 3 :% 4) % (N 3 :% 1)))+_testSlash_Rat3N4_Rat2N1 = Dict @((P 3 :% 8) ~ ((N 3 :% 4) % (N 2 :% 1)))+_testSlash_Rat3N4_Rat3N2 = Dict @((P 1 :% 2) ~ ((N 3 :% 4) % (N 3 :% 2)))+_testSlash_Rat3N4_Rat4N3 = Dict @((P 9 :% 16) ~ ((N 3 :% 4) % (N 4 :% 3)))+_testSlash_Rat3N4_Rat1N1 = Dict @((P 3 :% 4) ~ ((N 3 :% 4) % (N 1 :% 1)))+_testSlash_Rat3N4_Rat3N4 = Dict @((P 1 :% 1) ~ ((N 3 :% 4) % (N 3 :% 4)))+_testSlash_Rat3N4_Rat2N3 = Dict @((P 9 :% 8) ~ ((N 3 :% 4) % (N 2 :% 3)))+_testSlash_Rat3N4_Rat1N2 = Dict @((P 3 :% 2) ~ ((N 3 :% 4) % (N 1 :% 2)))+_testSlash_Rat3N4_Rat1N3 = Dict @((P 9 :% 4) ~ ((N 3 :% 4) % (N 1 :% 3)))+_testSlash_Rat3N4_Rat1N4 = Dict @((P 3 :% 1) ~ ((N 3 :% 4) % (N 1 :% 4)))+_testSlash_Rat3N4_Rat1P4 = Dict @((N 3 :% 1) ~ ((N 3 :% 4) % (P 1 :% 4)))+_testSlash_Rat3N4_Rat1P3 = Dict @((N 9 :% 4) ~ ((N 3 :% 4) % (P 1 :% 3)))+_testSlash_Rat3N4_Rat1P2 = Dict @((N 3 :% 2) ~ ((N 3 :% 4) % (P 1 :% 2)))+_testSlash_Rat3N4_Rat2P3 = Dict @((N 9 :% 8) ~ ((N 3 :% 4) % (P 2 :% 3)))+_testSlash_Rat3N4_Rat3P4 = Dict @((N 1 :% 1) ~ ((N 3 :% 4) % (P 3 :% 4)))+_testSlash_Rat3N4_Rat1P1 = Dict @((N 3 :% 4) ~ ((N 3 :% 4) % (P 1 :% 1)))+_testSlash_Rat3N4_Rat4P3 = Dict @((N 9 :% 16) ~ ((N 3 :% 4) % (P 4 :% 3)))+_testSlash_Rat3N4_Rat3P2 = Dict @((N 1 :% 2) ~ ((N 3 :% 4) % (P 3 :% 2)))+_testSlash_Rat3N4_Rat2P1 = Dict @((N 3 :% 8) ~ ((N 3 :% 4) % (P 2 :% 1)))+_testSlash_Rat3N4_Rat3P1 = Dict @((N 1 :% 4) ~ ((N 3 :% 4) % (P 3 :% 1)))+_testSlash_Rat3N4_Rat4P1 = Dict @((N 3 :% 16) ~ ((N 3 :% 4) % (P 4 :% 1)))+_testSlash_Rat2N3_Nat1 = Dict @((N 2 :% 3) ~ ((N 2 :% 3) % 1))+_testSlash_Rat2N3_Nat2 = Dict @((N 1 :% 3) ~ ((N 2 :% 3) % 2))+_testSlash_Rat2N3_Nat3 = Dict @((N 2 :% 9) ~ ((N 2 :% 3) % 3))+_testSlash_Rat2N3_Nat4 = Dict @((N 1 :% 6) ~ ((N 2 :% 3) % 4))+_testSlash_Rat2N3_IntN4 = Dict @((P 1 :% 6) ~ ((N 2 :% 3) % (N 4)))+_testSlash_Rat2N3_IntN3 = Dict @((P 2 :% 9) ~ ((N 2 :% 3) % (N 3)))+_testSlash_Rat2N3_IntN2 = Dict @((P 1 :% 3) ~ ((N 2 :% 3) % (N 2)))+_testSlash_Rat2N3_IntN1 = Dict @((P 2 :% 3) ~ ((N 2 :% 3) % (N 1)))+_testSlash_Rat2N3_IntP1 = Dict @((N 2 :% 3) ~ ((N 2 :% 3) % (P 1)))+_testSlash_Rat2N3_IntP2 = Dict @((N 1 :% 3) ~ ((N 2 :% 3) % (P 2)))+_testSlash_Rat2N3_IntP3 = Dict @((N 2 :% 9) ~ ((N 2 :% 3) % (P 3)))+_testSlash_Rat2N3_IntP4 = Dict @((N 1 :% 6) ~ ((N 2 :% 3) % (P 4)))+_testSlash_Rat2N3_Rat4N1 = Dict @((P 1 :% 6) ~ ((N 2 :% 3) % (N 4 :% 1)))+_testSlash_Rat2N3_Rat3N1 = Dict @((P 2 :% 9) ~ ((N 2 :% 3) % (N 3 :% 1)))+_testSlash_Rat2N3_Rat2N1 = Dict @((P 1 :% 3) ~ ((N 2 :% 3) % (N 2 :% 1)))+_testSlash_Rat2N3_Rat3N2 = Dict @((P 4 :% 9) ~ ((N 2 :% 3) % (N 3 :% 2)))+_testSlash_Rat2N3_Rat4N3 = Dict @((P 1 :% 2) ~ ((N 2 :% 3) % (N 4 :% 3)))+_testSlash_Rat2N3_Rat1N1 = Dict @((P 2 :% 3) ~ ((N 2 :% 3) % (N 1 :% 1)))+_testSlash_Rat2N3_Rat3N4 = Dict @((P 8 :% 9) ~ ((N 2 :% 3) % (N 3 :% 4)))+_testSlash_Rat2N3_Rat2N3 = Dict @((P 1 :% 1) ~ ((N 2 :% 3) % (N 2 :% 3)))+_testSlash_Rat2N3_Rat1N2 = Dict @((P 4 :% 3) ~ ((N 2 :% 3) % (N 1 :% 2)))+_testSlash_Rat2N3_Rat1N3 = Dict @((P 2 :% 1) ~ ((N 2 :% 3) % (N 1 :% 3)))+_testSlash_Rat2N3_Rat1N4 = Dict @((P 8 :% 3) ~ ((N 2 :% 3) % (N 1 :% 4)))+_testSlash_Rat2N3_Rat1P4 = Dict @((N 8 :% 3) ~ ((N 2 :% 3) % (P 1 :% 4)))+_testSlash_Rat2N3_Rat1P3 = Dict @((N 2 :% 1) ~ ((N 2 :% 3) % (P 1 :% 3)))+_testSlash_Rat2N3_Rat1P2 = Dict @((N 4 :% 3) ~ ((N 2 :% 3) % (P 1 :% 2)))+_testSlash_Rat2N3_Rat2P3 = Dict @((N 1 :% 1) ~ ((N 2 :% 3) % (P 2 :% 3)))+_testSlash_Rat2N3_Rat3P4 = Dict @((N 8 :% 9) ~ ((N 2 :% 3) % (P 3 :% 4)))+_testSlash_Rat2N3_Rat1P1 = Dict @((N 2 :% 3) ~ ((N 2 :% 3) % (P 1 :% 1)))+_testSlash_Rat2N3_Rat4P3 = Dict @((N 1 :% 2) ~ ((N 2 :% 3) % (P 4 :% 3)))+_testSlash_Rat2N3_Rat3P2 = Dict @((N 4 :% 9) ~ ((N 2 :% 3) % (P 3 :% 2)))+_testSlash_Rat2N3_Rat2P1 = Dict @((N 1 :% 3) ~ ((N 2 :% 3) % (P 2 :% 1)))+_testSlash_Rat2N3_Rat3P1 = Dict @((N 2 :% 9) ~ ((N 2 :% 3) % (P 3 :% 1)))+_testSlash_Rat2N3_Rat4P1 = Dict @((N 1 :% 6) ~ ((N 2 :% 3) % (P 4 :% 1)))+_testSlash_Rat1N2_Nat1 = Dict @((N 1 :% 2) ~ ((N 1 :% 2) % 1))+_testSlash_Rat1N2_Nat2 = Dict @((N 1 :% 4) ~ ((N 1 :% 2) % 2))+_testSlash_Rat1N2_Nat3 = Dict @((N 1 :% 6) ~ ((N 1 :% 2) % 3))+_testSlash_Rat1N2_Nat4 = Dict @((N 1 :% 8) ~ ((N 1 :% 2) % 4))+_testSlash_Rat1N2_IntN4 = Dict @((P 1 :% 8) ~ ((N 1 :% 2) % (N 4)))+_testSlash_Rat1N2_IntN3 = Dict @((P 1 :% 6) ~ ((N 1 :% 2) % (N 3)))+_testSlash_Rat1N2_IntN2 = Dict @((P 1 :% 4) ~ ((N 1 :% 2) % (N 2)))+_testSlash_Rat1N2_IntN1 = Dict @((P 1 :% 2) ~ ((N 1 :% 2) % (N 1)))+_testSlash_Rat1N2_IntP1 = Dict @((N 1 :% 2) ~ ((N 1 :% 2) % (P 1)))+_testSlash_Rat1N2_IntP2 = Dict @((N 1 :% 4) ~ ((N 1 :% 2) % (P 2)))+_testSlash_Rat1N2_IntP3 = Dict @((N 1 :% 6) ~ ((N 1 :% 2) % (P 3)))+_testSlash_Rat1N2_IntP4 = Dict @((N 1 :% 8) ~ ((N 1 :% 2) % (P 4)))+_testSlash_Rat1N2_Rat4N1 = Dict @((P 1 :% 8) ~ ((N 1 :% 2) % (N 4 :% 1)))+_testSlash_Rat1N2_Rat3N1 = Dict @((P 1 :% 6) ~ ((N 1 :% 2) % (N 3 :% 1)))+_testSlash_Rat1N2_Rat2N1 = Dict @((P 1 :% 4) ~ ((N 1 :% 2) % (N 2 :% 1)))+_testSlash_Rat1N2_Rat3N2 = Dict @((P 1 :% 3) ~ ((N 1 :% 2) % (N 3 :% 2)))+_testSlash_Rat1N2_Rat4N3 = Dict @((P 3 :% 8) ~ ((N 1 :% 2) % (N 4 :% 3)))+_testSlash_Rat1N2_Rat1N1 = Dict @((P 1 :% 2) ~ ((N 1 :% 2) % (N 1 :% 1)))+_testSlash_Rat1N2_Rat3N4 = Dict @((P 2 :% 3) ~ ((N 1 :% 2) % (N 3 :% 4)))+_testSlash_Rat1N2_Rat2N3 = Dict @((P 3 :% 4) ~ ((N 1 :% 2) % (N 2 :% 3)))+_testSlash_Rat1N2_Rat1N2 = Dict @((P 1 :% 1) ~ ((N 1 :% 2) % (N 1 :% 2)))+_testSlash_Rat1N2_Rat1N3 = Dict @((P 3 :% 2) ~ ((N 1 :% 2) % (N 1 :% 3)))+_testSlash_Rat1N2_Rat1N4 = Dict @((P 2 :% 1) ~ ((N 1 :% 2) % (N 1 :% 4)))+_testSlash_Rat1N2_Rat1P4 = Dict @((N 2 :% 1) ~ ((N 1 :% 2) % (P 1 :% 4)))+_testSlash_Rat1N2_Rat1P3 = Dict @((N 3 :% 2) ~ ((N 1 :% 2) % (P 1 :% 3)))+_testSlash_Rat1N2_Rat1P2 = Dict @((N 1 :% 1) ~ ((N 1 :% 2) % (P 1 :% 2)))+_testSlash_Rat1N2_Rat2P3 = Dict @((N 3 :% 4) ~ ((N 1 :% 2) % (P 2 :% 3)))+_testSlash_Rat1N2_Rat3P4 = Dict @((N 2 :% 3) ~ ((N 1 :% 2) % (P 3 :% 4)))+_testSlash_Rat1N2_Rat1P1 = Dict @((N 1 :% 2) ~ ((N 1 :% 2) % (P 1 :% 1)))+_testSlash_Rat1N2_Rat4P3 = Dict @((N 3 :% 8) ~ ((N 1 :% 2) % (P 4 :% 3)))+_testSlash_Rat1N2_Rat3P2 = Dict @((N 1 :% 3) ~ ((N 1 :% 2) % (P 3 :% 2)))+_testSlash_Rat1N2_Rat2P1 = Dict @((N 1 :% 4) ~ ((N 1 :% 2) % (P 2 :% 1)))+_testSlash_Rat1N2_Rat3P1 = Dict @((N 1 :% 6) ~ ((N 1 :% 2) % (P 3 :% 1)))+_testSlash_Rat1N2_Rat4P1 = Dict @((N 1 :% 8) ~ ((N 1 :% 2) % (P 4 :% 1)))+_testSlash_Rat1N3_Nat1 = Dict @((N 1 :% 3) ~ ((N 1 :% 3) % 1))+_testSlash_Rat1N3_Nat2 = Dict @((N 1 :% 6) ~ ((N 1 :% 3) % 2))+_testSlash_Rat1N3_Nat3 = Dict @((N 1 :% 9) ~ ((N 1 :% 3) % 3))+_testSlash_Rat1N3_Nat4 = Dict @((N 1 :% 12) ~ ((N 1 :% 3) % 4))+_testSlash_Rat1N3_IntN4 = Dict @((P 1 :% 12) ~ ((N 1 :% 3) % (N 4)))+_testSlash_Rat1N3_IntN3 = Dict @((P 1 :% 9) ~ ((N 1 :% 3) % (N 3)))+_testSlash_Rat1N3_IntN2 = Dict @((P 1 :% 6) ~ ((N 1 :% 3) % (N 2)))+_testSlash_Rat1N3_IntN1 = Dict @((P 1 :% 3) ~ ((N 1 :% 3) % (N 1)))+_testSlash_Rat1N3_IntP1 = Dict @((N 1 :% 3) ~ ((N 1 :% 3) % (P 1)))+_testSlash_Rat1N3_IntP2 = Dict @((N 1 :% 6) ~ ((N 1 :% 3) % (P 2)))+_testSlash_Rat1N3_IntP3 = Dict @((N 1 :% 9) ~ ((N 1 :% 3) % (P 3)))+_testSlash_Rat1N3_IntP4 = Dict @((N 1 :% 12) ~ ((N 1 :% 3) % (P 4)))+_testSlash_Rat1N3_Rat4N1 = Dict @((P 1 :% 12) ~ ((N 1 :% 3) % (N 4 :% 1)))+_testSlash_Rat1N3_Rat3N1 = Dict @((P 1 :% 9) ~ ((N 1 :% 3) % (N 3 :% 1)))+_testSlash_Rat1N3_Rat2N1 = Dict @((P 1 :% 6) ~ ((N 1 :% 3) % (N 2 :% 1)))+_testSlash_Rat1N3_Rat3N2 = Dict @((P 2 :% 9) ~ ((N 1 :% 3) % (N 3 :% 2)))+_testSlash_Rat1N3_Rat4N3 = Dict @((P 1 :% 4) ~ ((N 1 :% 3) % (N 4 :% 3)))+_testSlash_Rat1N3_Rat1N1 = Dict @((P 1 :% 3) ~ ((N 1 :% 3) % (N 1 :% 1)))+_testSlash_Rat1N3_Rat3N4 = Dict @((P 4 :% 9) ~ ((N 1 :% 3) % (N 3 :% 4)))+_testSlash_Rat1N3_Rat2N3 = Dict @((P 1 :% 2) ~ ((N 1 :% 3) % (N 2 :% 3)))+_testSlash_Rat1N3_Rat1N2 = Dict @((P 2 :% 3) ~ ((N 1 :% 3) % (N 1 :% 2)))+_testSlash_Rat1N3_Rat1N3 = Dict @((P 1 :% 1) ~ ((N 1 :% 3) % (N 1 :% 3)))+_testSlash_Rat1N3_Rat1N4 = Dict @((P 4 :% 3) ~ ((N 1 :% 3) % (N 1 :% 4)))+_testSlash_Rat1N3_Rat1P4 = Dict @((N 4 :% 3) ~ ((N 1 :% 3) % (P 1 :% 4)))+_testSlash_Rat1N3_Rat1P3 = Dict @((N 1 :% 1) ~ ((N 1 :% 3) % (P 1 :% 3)))+_testSlash_Rat1N3_Rat1P2 = Dict @((N 2 :% 3) ~ ((N 1 :% 3) % (P 1 :% 2)))+_testSlash_Rat1N3_Rat2P3 = Dict @((N 1 :% 2) ~ ((N 1 :% 3) % (P 2 :% 3)))+_testSlash_Rat1N3_Rat3P4 = Dict @((N 4 :% 9) ~ ((N 1 :% 3) % (P 3 :% 4)))+_testSlash_Rat1N3_Rat1P1 = Dict @((N 1 :% 3) ~ ((N 1 :% 3) % (P 1 :% 1)))+_testSlash_Rat1N3_Rat4P3 = Dict @((N 1 :% 4) ~ ((N 1 :% 3) % (P 4 :% 3)))+_testSlash_Rat1N3_Rat3P2 = Dict @((N 2 :% 9) ~ ((N 1 :% 3) % (P 3 :% 2)))+_testSlash_Rat1N3_Rat2P1 = Dict @((N 1 :% 6) ~ ((N 1 :% 3) % (P 2 :% 1)))+_testSlash_Rat1N3_Rat3P1 = Dict @((N 1 :% 9) ~ ((N 1 :% 3) % (P 3 :% 1)))+_testSlash_Rat1N3_Rat4P1 = Dict @((N 1 :% 12) ~ ((N 1 :% 3) % (P 4 :% 1)))+_testSlash_Rat1N4_Nat1 = Dict @((N 1 :% 4) ~ ((N 1 :% 4) % 1))+_testSlash_Rat1N4_Nat2 = Dict @((N 1 :% 8) ~ ((N 1 :% 4) % 2))+_testSlash_Rat1N4_Nat3 = Dict @((N 1 :% 12) ~ ((N 1 :% 4) % 3))+_testSlash_Rat1N4_Nat4 = Dict @((N 1 :% 16) ~ ((N 1 :% 4) % 4))+_testSlash_Rat1N4_IntN4 = Dict @((P 1 :% 16) ~ ((N 1 :% 4) % (N 4)))+_testSlash_Rat1N4_IntN3 = Dict @((P 1 :% 12) ~ ((N 1 :% 4) % (N 3)))+_testSlash_Rat1N4_IntN2 = Dict @((P 1 :% 8) ~ ((N 1 :% 4) % (N 2)))+_testSlash_Rat1N4_IntN1 = Dict @((P 1 :% 4) ~ ((N 1 :% 4) % (N 1)))+_testSlash_Rat1N4_IntP1 = Dict @((N 1 :% 4) ~ ((N 1 :% 4) % (P 1)))+_testSlash_Rat1N4_IntP2 = Dict @((N 1 :% 8) ~ ((N 1 :% 4) % (P 2)))+_testSlash_Rat1N4_IntP3 = Dict @((N 1 :% 12) ~ ((N 1 :% 4) % (P 3)))+_testSlash_Rat1N4_IntP4 = Dict @((N 1 :% 16) ~ ((N 1 :% 4) % (P 4)))+_testSlash_Rat1N4_Rat4N1 = Dict @((P 1 :% 16) ~ ((N 1 :% 4) % (N 4 :% 1)))+_testSlash_Rat1N4_Rat3N1 = Dict @((P 1 :% 12) ~ ((N 1 :% 4) % (N 3 :% 1)))+_testSlash_Rat1N4_Rat2N1 = Dict @((P 1 :% 8) ~ ((N 1 :% 4) % (N 2 :% 1)))+_testSlash_Rat1N4_Rat3N2 = Dict @((P 1 :% 6) ~ ((N 1 :% 4) % (N 3 :% 2)))+_testSlash_Rat1N4_Rat4N3 = Dict @((P 3 :% 16) ~ ((N 1 :% 4) % (N 4 :% 3)))+_testSlash_Rat1N4_Rat1N1 = Dict @((P 1 :% 4) ~ ((N 1 :% 4) % (N 1 :% 1)))+_testSlash_Rat1N4_Rat3N4 = Dict @((P 1 :% 3) ~ ((N 1 :% 4) % (N 3 :% 4)))+_testSlash_Rat1N4_Rat2N3 = Dict @((P 3 :% 8) ~ ((N 1 :% 4) % (N 2 :% 3)))+_testSlash_Rat1N4_Rat1N2 = Dict @((P 1 :% 2) ~ ((N 1 :% 4) % (N 1 :% 2)))+_testSlash_Rat1N4_Rat1N3 = Dict @((P 3 :% 4) ~ ((N 1 :% 4) % (N 1 :% 3)))+_testSlash_Rat1N4_Rat1N4 = Dict @((P 1 :% 1) ~ ((N 1 :% 4) % (N 1 :% 4)))+_testSlash_Rat1N4_Rat1P4 = Dict @((N 1 :% 1) ~ ((N 1 :% 4) % (P 1 :% 4)))+_testSlash_Rat1N4_Rat1P3 = Dict @((N 3 :% 4) ~ ((N 1 :% 4) % (P 1 :% 3)))+_testSlash_Rat1N4_Rat1P2 = Dict @((N 1 :% 2) ~ ((N 1 :% 4) % (P 1 :% 2)))+_testSlash_Rat1N4_Rat2P3 = Dict @((N 3 :% 8) ~ ((N 1 :% 4) % (P 2 :% 3)))+_testSlash_Rat1N4_Rat3P4 = Dict @((N 1 :% 3) ~ ((N 1 :% 4) % (P 3 :% 4)))+_testSlash_Rat1N4_Rat1P1 = Dict @((N 1 :% 4) ~ ((N 1 :% 4) % (P 1 :% 1)))+_testSlash_Rat1N4_Rat4P3 = Dict @((N 3 :% 16) ~ ((N 1 :% 4) % (P 4 :% 3)))+_testSlash_Rat1N4_Rat3P2 = Dict @((N 1 :% 6) ~ ((N 1 :% 4) % (P 3 :% 2)))+_testSlash_Rat1N4_Rat2P1 = Dict @((N 1 :% 8) ~ ((N 1 :% 4) % (P 2 :% 1)))+_testSlash_Rat1N4_Rat3P1 = Dict @((N 1 :% 12) ~ ((N 1 :% 4) % (P 3 :% 1)))+_testSlash_Rat1N4_Rat4P1 = Dict @((N 1 :% 16) ~ ((N 1 :% 4) % (P 4 :% 1)))+_testSlash_Rat0P1_Nat1 = Dict @((Z :% 1) ~ ((Z :% 1) % 1))+_testSlash_Rat0P1_Nat2 = Dict @((Z :% 1) ~ ((Z :% 1) % 2))+_testSlash_Rat0P1_Nat3 = Dict @((Z :% 1) ~ ((Z :% 1) % 3))+_testSlash_Rat0P1_Nat4 = Dict @((Z :% 1) ~ ((Z :% 1) % 4))+_testSlash_Rat0P1_IntN4 = Dict @((Z :% 1) ~ ((Z :% 1) % (N 4)))+_testSlash_Rat0P1_IntN3 = Dict @((Z :% 1) ~ ((Z :% 1) % (N 3)))+_testSlash_Rat0P1_IntN2 = Dict @((Z :% 1) ~ ((Z :% 1) % (N 2)))+_testSlash_Rat0P1_IntN1 = Dict @((Z :% 1) ~ ((Z :% 1) % (N 1)))+_testSlash_Rat0P1_IntP1 = Dict @((Z :% 1) ~ ((Z :% 1) % (P 1)))+_testSlash_Rat0P1_IntP2 = Dict @((Z :% 1) ~ ((Z :% 1) % (P 2)))+_testSlash_Rat0P1_IntP3 = Dict @((Z :% 1) ~ ((Z :% 1) % (P 3)))+_testSlash_Rat0P1_IntP4 = Dict @((Z :% 1) ~ ((Z :% 1) % (P 4)))+_testSlash_Rat0P1_Rat4N1 = Dict @((Z :% 1) ~ ((Z :% 1) % (N 4 :% 1)))+_testSlash_Rat0P1_Rat3N1 = Dict @((Z :% 1) ~ ((Z :% 1) % (N 3 :% 1)))+_testSlash_Rat0P1_Rat2N1 = Dict @((Z :% 1) ~ ((Z :% 1) % (N 2 :% 1)))+_testSlash_Rat0P1_Rat3N2 = Dict @((Z :% 1) ~ ((Z :% 1) % (N 3 :% 2)))+_testSlash_Rat0P1_Rat4N3 = Dict @((Z :% 1) ~ ((Z :% 1) % (N 4 :% 3)))+_testSlash_Rat0P1_Rat1N1 = Dict @((Z :% 1) ~ ((Z :% 1) % (N 1 :% 1)))+_testSlash_Rat0P1_Rat3N4 = Dict @((Z :% 1) ~ ((Z :% 1) % (N 3 :% 4)))+_testSlash_Rat0P1_Rat2N3 = Dict @((Z :% 1) ~ ((Z :% 1) % (N 2 :% 3)))+_testSlash_Rat0P1_Rat1N2 = Dict @((Z :% 1) ~ ((Z :% 1) % (N 1 :% 2)))+_testSlash_Rat0P1_Rat1N3 = Dict @((Z :% 1) ~ ((Z :% 1) % (N 1 :% 3)))+_testSlash_Rat0P1_Rat1N4 = Dict @((Z :% 1) ~ ((Z :% 1) % (N 1 :% 4)))+_testSlash_Rat0P1_Rat1P4 = Dict @((Z :% 1) ~ ((Z :% 1) % (P 1 :% 4)))+_testSlash_Rat0P1_Rat1P3 = Dict @((Z :% 1) ~ ((Z :% 1) % (P 1 :% 3)))+_testSlash_Rat0P1_Rat1P2 = Dict @((Z :% 1) ~ ((Z :% 1) % (P 1 :% 2)))+_testSlash_Rat0P1_Rat2P3 = Dict @((Z :% 1) ~ ((Z :% 1) % (P 2 :% 3)))+_testSlash_Rat0P1_Rat3P4 = Dict @((Z :% 1) ~ ((Z :% 1) % (P 3 :% 4)))+_testSlash_Rat0P1_Rat1P1 = Dict @((Z :% 1) ~ ((Z :% 1) % (P 1 :% 1)))+_testSlash_Rat0P1_Rat4P3 = Dict @((Z :% 1) ~ ((Z :% 1) % (P 4 :% 3)))+_testSlash_Rat0P1_Rat3P2 = Dict @((Z :% 1) ~ ((Z :% 1) % (P 3 :% 2)))+_testSlash_Rat0P1_Rat2P1 = Dict @((Z :% 1) ~ ((Z :% 1) % (P 2 :% 1)))+_testSlash_Rat0P1_Rat3P1 = Dict @((Z :% 1) ~ ((Z :% 1) % (P 3 :% 1)))+_testSlash_Rat0P1_Rat4P1 = Dict @((Z :% 1) ~ ((Z :% 1) % (P 4 :% 1)))+_testSlash_Rat1P4_Nat1 = Dict @((P 1 :% 4) ~ ((P 1 :% 4) % 1))+_testSlash_Rat1P4_Nat2 = Dict @((P 1 :% 8) ~ ((P 1 :% 4) % 2))+_testSlash_Rat1P4_Nat3 = Dict @((P 1 :% 12) ~ ((P 1 :% 4) % 3))+_testSlash_Rat1P4_Nat4 = Dict @((P 1 :% 16) ~ ((P 1 :% 4) % 4))+_testSlash_Rat1P4_IntN4 = Dict @((N 1 :% 16) ~ ((P 1 :% 4) % (N 4)))+_testSlash_Rat1P4_IntN3 = Dict @((N 1 :% 12) ~ ((P 1 :% 4) % (N 3)))+_testSlash_Rat1P4_IntN2 = Dict @((N 1 :% 8) ~ ((P 1 :% 4) % (N 2)))+_testSlash_Rat1P4_IntN1 = Dict @((N 1 :% 4) ~ ((P 1 :% 4) % (N 1)))+_testSlash_Rat1P4_IntP1 = Dict @((P 1 :% 4) ~ ((P 1 :% 4) % (P 1)))+_testSlash_Rat1P4_IntP2 = Dict @((P 1 :% 8) ~ ((P 1 :% 4) % (P 2)))+_testSlash_Rat1P4_IntP3 = Dict @((P 1 :% 12) ~ ((P 1 :% 4) % (P 3)))+_testSlash_Rat1P4_IntP4 = Dict @((P 1 :% 16) ~ ((P 1 :% 4) % (P 4)))+_testSlash_Rat1P4_Rat4N1 = Dict @((N 1 :% 16) ~ ((P 1 :% 4) % (N 4 :% 1)))+_testSlash_Rat1P4_Rat3N1 = Dict @((N 1 :% 12) ~ ((P 1 :% 4) % (N 3 :% 1)))+_testSlash_Rat1P4_Rat2N1 = Dict @((N 1 :% 8) ~ ((P 1 :% 4) % (N 2 :% 1)))+_testSlash_Rat1P4_Rat3N2 = Dict @((N 1 :% 6) ~ ((P 1 :% 4) % (N 3 :% 2)))+_testSlash_Rat1P4_Rat4N3 = Dict @((N 3 :% 16) ~ ((P 1 :% 4) % (N 4 :% 3)))+_testSlash_Rat1P4_Rat1N1 = Dict @((N 1 :% 4) ~ ((P 1 :% 4) % (N 1 :% 1)))+_testSlash_Rat1P4_Rat3N4 = Dict @((N 1 :% 3) ~ ((P 1 :% 4) % (N 3 :% 4)))+_testSlash_Rat1P4_Rat2N3 = Dict @((N 3 :% 8) ~ ((P 1 :% 4) % (N 2 :% 3)))+_testSlash_Rat1P4_Rat1N2 = Dict @((N 1 :% 2) ~ ((P 1 :% 4) % (N 1 :% 2)))+_testSlash_Rat1P4_Rat1N3 = Dict @((N 3 :% 4) ~ ((P 1 :% 4) % (N 1 :% 3)))+_testSlash_Rat1P4_Rat1N4 = Dict @((N 1 :% 1) ~ ((P 1 :% 4) % (N 1 :% 4)))+_testSlash_Rat1P4_Rat1P4 = Dict @((P 1 :% 1) ~ ((P 1 :% 4) % (P 1 :% 4)))+_testSlash_Rat1P4_Rat1P3 = Dict @((P 3 :% 4) ~ ((P 1 :% 4) % (P 1 :% 3)))+_testSlash_Rat1P4_Rat1P2 = Dict @((P 1 :% 2) ~ ((P 1 :% 4) % (P 1 :% 2)))+_testSlash_Rat1P4_Rat2P3 = Dict @((P 3 :% 8) ~ ((P 1 :% 4) % (P 2 :% 3)))+_testSlash_Rat1P4_Rat3P4 = Dict @((P 1 :% 3) ~ ((P 1 :% 4) % (P 3 :% 4)))+_testSlash_Rat1P4_Rat1P1 = Dict @((P 1 :% 4) ~ ((P 1 :% 4) % (P 1 :% 1)))+_testSlash_Rat1P4_Rat4P3 = Dict @((P 3 :% 16) ~ ((P 1 :% 4) % (P 4 :% 3)))+_testSlash_Rat1P4_Rat3P2 = Dict @((P 1 :% 6) ~ ((P 1 :% 4) % (P 3 :% 2)))+_testSlash_Rat1P4_Rat2P1 = Dict @((P 1 :% 8) ~ ((P 1 :% 4) % (P 2 :% 1)))+_testSlash_Rat1P4_Rat3P1 = Dict @((P 1 :% 12) ~ ((P 1 :% 4) % (P 3 :% 1)))+_testSlash_Rat1P4_Rat4P1 = Dict @((P 1 :% 16) ~ ((P 1 :% 4) % (P 4 :% 1)))+_testSlash_Rat1P3_Nat1 = Dict @((P 1 :% 3) ~ ((P 1 :% 3) % 1))+_testSlash_Rat1P3_Nat2 = Dict @((P 1 :% 6) ~ ((P 1 :% 3) % 2))+_testSlash_Rat1P3_Nat3 = Dict @((P 1 :% 9) ~ ((P 1 :% 3) % 3))+_testSlash_Rat1P3_Nat4 = Dict @((P 1 :% 12) ~ ((P 1 :% 3) % 4))+_testSlash_Rat1P3_IntN4 = Dict @((N 1 :% 12) ~ ((P 1 :% 3) % (N 4)))+_testSlash_Rat1P3_IntN3 = Dict @((N 1 :% 9) ~ ((P 1 :% 3) % (N 3)))+_testSlash_Rat1P3_IntN2 = Dict @((N 1 :% 6) ~ ((P 1 :% 3) % (N 2)))+_testSlash_Rat1P3_IntN1 = Dict @((N 1 :% 3) ~ ((P 1 :% 3) % (N 1)))+_testSlash_Rat1P3_IntP1 = Dict @((P 1 :% 3) ~ ((P 1 :% 3) % (P 1)))+_testSlash_Rat1P3_IntP2 = Dict @((P 1 :% 6) ~ ((P 1 :% 3) % (P 2)))+_testSlash_Rat1P3_IntP3 = Dict @((P 1 :% 9) ~ ((P 1 :% 3) % (P 3)))+_testSlash_Rat1P3_IntP4 = Dict @((P 1 :% 12) ~ ((P 1 :% 3) % (P 4)))+_testSlash_Rat1P3_Rat4N1 = Dict @((N 1 :% 12) ~ ((P 1 :% 3) % (N 4 :% 1)))+_testSlash_Rat1P3_Rat3N1 = Dict @((N 1 :% 9) ~ ((P 1 :% 3) % (N 3 :% 1)))+_testSlash_Rat1P3_Rat2N1 = Dict @((N 1 :% 6) ~ ((P 1 :% 3) % (N 2 :% 1)))+_testSlash_Rat1P3_Rat3N2 = Dict @((N 2 :% 9) ~ ((P 1 :% 3) % (N 3 :% 2)))+_testSlash_Rat1P3_Rat4N3 = Dict @((N 1 :% 4) ~ ((P 1 :% 3) % (N 4 :% 3)))+_testSlash_Rat1P3_Rat1N1 = Dict @((N 1 :% 3) ~ ((P 1 :% 3) % (N 1 :% 1)))+_testSlash_Rat1P3_Rat3N4 = Dict @((N 4 :% 9) ~ ((P 1 :% 3) % (N 3 :% 4)))+_testSlash_Rat1P3_Rat2N3 = Dict @((N 1 :% 2) ~ ((P 1 :% 3) % (N 2 :% 3)))+_testSlash_Rat1P3_Rat1N2 = Dict @((N 2 :% 3) ~ ((P 1 :% 3) % (N 1 :% 2)))+_testSlash_Rat1P3_Rat1N3 = Dict @((N 1 :% 1) ~ ((P 1 :% 3) % (N 1 :% 3)))+_testSlash_Rat1P3_Rat1N4 = Dict @((N 4 :% 3) ~ ((P 1 :% 3) % (N 1 :% 4)))+_testSlash_Rat1P3_Rat1P4 = Dict @((P 4 :% 3) ~ ((P 1 :% 3) % (P 1 :% 4)))+_testSlash_Rat1P3_Rat1P3 = Dict @((P 1 :% 1) ~ ((P 1 :% 3) % (P 1 :% 3)))+_testSlash_Rat1P3_Rat1P2 = Dict @((P 2 :% 3) ~ ((P 1 :% 3) % (P 1 :% 2)))+_testSlash_Rat1P3_Rat2P3 = Dict @((P 1 :% 2) ~ ((P 1 :% 3) % (P 2 :% 3)))+_testSlash_Rat1P3_Rat3P4 = Dict @((P 4 :% 9) ~ ((P 1 :% 3) % (P 3 :% 4)))+_testSlash_Rat1P3_Rat1P1 = Dict @((P 1 :% 3) ~ ((P 1 :% 3) % (P 1 :% 1)))+_testSlash_Rat1P3_Rat4P3 = Dict @((P 1 :% 4) ~ ((P 1 :% 3) % (P 4 :% 3)))+_testSlash_Rat1P3_Rat3P2 = Dict @((P 2 :% 9) ~ ((P 1 :% 3) % (P 3 :% 2)))+_testSlash_Rat1P3_Rat2P1 = Dict @((P 1 :% 6) ~ ((P 1 :% 3) % (P 2 :% 1)))+_testSlash_Rat1P3_Rat3P1 = Dict @((P 1 :% 9) ~ ((P 1 :% 3) % (P 3 :% 1)))+_testSlash_Rat1P3_Rat4P1 = Dict @((P 1 :% 12) ~ ((P 1 :% 3) % (P 4 :% 1)))+_testSlash_Rat1P2_Nat1 = Dict @((P 1 :% 2) ~ ((P 1 :% 2) % 1))+_testSlash_Rat1P2_Nat2 = Dict @((P 1 :% 4) ~ ((P 1 :% 2) % 2))+_testSlash_Rat1P2_Nat3 = Dict @((P 1 :% 6) ~ ((P 1 :% 2) % 3))+_testSlash_Rat1P2_Nat4 = Dict @((P 1 :% 8) ~ ((P 1 :% 2) % 4))+_testSlash_Rat1P2_IntN4 = Dict @((N 1 :% 8) ~ ((P 1 :% 2) % (N 4)))+_testSlash_Rat1P2_IntN3 = Dict @((N 1 :% 6) ~ ((P 1 :% 2) % (N 3)))+_testSlash_Rat1P2_IntN2 = Dict @((N 1 :% 4) ~ ((P 1 :% 2) % (N 2)))+_testSlash_Rat1P2_IntN1 = Dict @((N 1 :% 2) ~ ((P 1 :% 2) % (N 1)))+_testSlash_Rat1P2_IntP1 = Dict @((P 1 :% 2) ~ ((P 1 :% 2) % (P 1)))+_testSlash_Rat1P2_IntP2 = Dict @((P 1 :% 4) ~ ((P 1 :% 2) % (P 2)))+_testSlash_Rat1P2_IntP3 = Dict @((P 1 :% 6) ~ ((P 1 :% 2) % (P 3)))+_testSlash_Rat1P2_IntP4 = Dict @((P 1 :% 8) ~ ((P 1 :% 2) % (P 4)))+_testSlash_Rat1P2_Rat4N1 = Dict @((N 1 :% 8) ~ ((P 1 :% 2) % (N 4 :% 1)))+_testSlash_Rat1P2_Rat3N1 = Dict @((N 1 :% 6) ~ ((P 1 :% 2) % (N 3 :% 1)))+_testSlash_Rat1P2_Rat2N1 = Dict @((N 1 :% 4) ~ ((P 1 :% 2) % (N 2 :% 1)))+_testSlash_Rat1P2_Rat3N2 = Dict @((N 1 :% 3) ~ ((P 1 :% 2) % (N 3 :% 2)))+_testSlash_Rat1P2_Rat4N3 = Dict @((N 3 :% 8) ~ ((P 1 :% 2) % (N 4 :% 3)))+_testSlash_Rat1P2_Rat1N1 = Dict @((N 1 :% 2) ~ ((P 1 :% 2) % (N 1 :% 1)))+_testSlash_Rat1P2_Rat3N4 = Dict @((N 2 :% 3) ~ ((P 1 :% 2) % (N 3 :% 4)))+_testSlash_Rat1P2_Rat2N3 = Dict @((N 3 :% 4) ~ ((P 1 :% 2) % (N 2 :% 3)))+_testSlash_Rat1P2_Rat1N2 = Dict @((N 1 :% 1) ~ ((P 1 :% 2) % (N 1 :% 2)))+_testSlash_Rat1P2_Rat1N3 = Dict @((N 3 :% 2) ~ ((P 1 :% 2) % (N 1 :% 3)))+_testSlash_Rat1P2_Rat1N4 = Dict @((N 2 :% 1) ~ ((P 1 :% 2) % (N 1 :% 4)))+_testSlash_Rat1P2_Rat1P4 = Dict @((P 2 :% 1) ~ ((P 1 :% 2) % (P 1 :% 4)))+_testSlash_Rat1P2_Rat1P3 = Dict @((P 3 :% 2) ~ ((P 1 :% 2) % (P 1 :% 3)))+_testSlash_Rat1P2_Rat1P2 = Dict @((P 1 :% 1) ~ ((P 1 :% 2) % (P 1 :% 2)))+_testSlash_Rat1P2_Rat2P3 = Dict @((P 3 :% 4) ~ ((P 1 :% 2) % (P 2 :% 3)))+_testSlash_Rat1P2_Rat3P4 = Dict @((P 2 :% 3) ~ ((P 1 :% 2) % (P 3 :% 4)))+_testSlash_Rat1P2_Rat1P1 = Dict @((P 1 :% 2) ~ ((P 1 :% 2) % (P 1 :% 1)))+_testSlash_Rat1P2_Rat4P3 = Dict @((P 3 :% 8) ~ ((P 1 :% 2) % (P 4 :% 3)))+_testSlash_Rat1P2_Rat3P2 = Dict @((P 1 :% 3) ~ ((P 1 :% 2) % (P 3 :% 2)))+_testSlash_Rat1P2_Rat2P1 = Dict @((P 1 :% 4) ~ ((P 1 :% 2) % (P 2 :% 1)))+_testSlash_Rat1P2_Rat3P1 = Dict @((P 1 :% 6) ~ ((P 1 :% 2) % (P 3 :% 1)))+_testSlash_Rat1P2_Rat4P1 = Dict @((P 1 :% 8) ~ ((P 1 :% 2) % (P 4 :% 1)))+_testSlash_Rat2P3_Nat1 = Dict @((P 2 :% 3) ~ ((P 2 :% 3) % 1))+_testSlash_Rat2P3_Nat2 = Dict @((P 1 :% 3) ~ ((P 2 :% 3) % 2))+_testSlash_Rat2P3_Nat3 = Dict @((P 2 :% 9) ~ ((P 2 :% 3) % 3))+_testSlash_Rat2P3_Nat4 = Dict @((P 1 :% 6) ~ ((P 2 :% 3) % 4))+_testSlash_Rat2P3_IntN4 = Dict @((N 1 :% 6) ~ ((P 2 :% 3) % (N 4)))+_testSlash_Rat2P3_IntN3 = Dict @((N 2 :% 9) ~ ((P 2 :% 3) % (N 3)))+_testSlash_Rat2P3_IntN2 = Dict @((N 1 :% 3) ~ ((P 2 :% 3) % (N 2)))+_testSlash_Rat2P3_IntN1 = Dict @((N 2 :% 3) ~ ((P 2 :% 3) % (N 1)))+_testSlash_Rat2P3_IntP1 = Dict @((P 2 :% 3) ~ ((P 2 :% 3) % (P 1)))+_testSlash_Rat2P3_IntP2 = Dict @((P 1 :% 3) ~ ((P 2 :% 3) % (P 2)))+_testSlash_Rat2P3_IntP3 = Dict @((P 2 :% 9) ~ ((P 2 :% 3) % (P 3)))+_testSlash_Rat2P3_IntP4 = Dict @((P 1 :% 6) ~ ((P 2 :% 3) % (P 4)))+_testSlash_Rat2P3_Rat4N1 = Dict @((N 1 :% 6) ~ ((P 2 :% 3) % (N 4 :% 1)))+_testSlash_Rat2P3_Rat3N1 = Dict @((N 2 :% 9) ~ ((P 2 :% 3) % (N 3 :% 1)))+_testSlash_Rat2P3_Rat2N1 = Dict @((N 1 :% 3) ~ ((P 2 :% 3) % (N 2 :% 1)))+_testSlash_Rat2P3_Rat3N2 = Dict @((N 4 :% 9) ~ ((P 2 :% 3) % (N 3 :% 2)))+_testSlash_Rat2P3_Rat4N3 = Dict @((N 1 :% 2) ~ ((P 2 :% 3) % (N 4 :% 3)))+_testSlash_Rat2P3_Rat1N1 = Dict @((N 2 :% 3) ~ ((P 2 :% 3) % (N 1 :% 1)))+_testSlash_Rat2P3_Rat3N4 = Dict @((N 8 :% 9) ~ ((P 2 :% 3) % (N 3 :% 4)))+_testSlash_Rat2P3_Rat2N3 = Dict @((N 1 :% 1) ~ ((P 2 :% 3) % (N 2 :% 3)))+_testSlash_Rat2P3_Rat1N2 = Dict @((N 4 :% 3) ~ ((P 2 :% 3) % (N 1 :% 2)))+_testSlash_Rat2P3_Rat1N3 = Dict @((N 2 :% 1) ~ ((P 2 :% 3) % (N 1 :% 3)))+_testSlash_Rat2P3_Rat1N4 = Dict @((N 8 :% 3) ~ ((P 2 :% 3) % (N 1 :% 4)))+_testSlash_Rat2P3_Rat1P4 = Dict @((P 8 :% 3) ~ ((P 2 :% 3) % (P 1 :% 4)))+_testSlash_Rat2P3_Rat1P3 = Dict @((P 2 :% 1) ~ ((P 2 :% 3) % (P 1 :% 3)))+_testSlash_Rat2P3_Rat1P2 = Dict @((P 4 :% 3) ~ ((P 2 :% 3) % (P 1 :% 2)))+_testSlash_Rat2P3_Rat2P3 = Dict @((P 1 :% 1) ~ ((P 2 :% 3) % (P 2 :% 3)))+_testSlash_Rat2P3_Rat3P4 = Dict @((P 8 :% 9) ~ ((P 2 :% 3) % (P 3 :% 4)))+_testSlash_Rat2P3_Rat1P1 = Dict @((P 2 :% 3) ~ ((P 2 :% 3) % (P 1 :% 1)))+_testSlash_Rat2P3_Rat4P3 = Dict @((P 1 :% 2) ~ ((P 2 :% 3) % (P 4 :% 3)))+_testSlash_Rat2P3_Rat3P2 = Dict @((P 4 :% 9) ~ ((P 2 :% 3) % (P 3 :% 2)))+_testSlash_Rat2P3_Rat2P1 = Dict @((P 1 :% 3) ~ ((P 2 :% 3) % (P 2 :% 1)))+_testSlash_Rat2P3_Rat3P1 = Dict @((P 2 :% 9) ~ ((P 2 :% 3) % (P 3 :% 1)))+_testSlash_Rat2P3_Rat4P1 = Dict @((P 1 :% 6) ~ ((P 2 :% 3) % (P 4 :% 1)))+_testSlash_Rat3P4_Nat1 = Dict @((P 3 :% 4) ~ ((P 3 :% 4) % 1))+_testSlash_Rat3P4_Nat2 = Dict @((P 3 :% 8) ~ ((P 3 :% 4) % 2))+_testSlash_Rat3P4_Nat3 = Dict @((P 1 :% 4) ~ ((P 3 :% 4) % 3))+_testSlash_Rat3P4_Nat4 = Dict @((P 3 :% 16) ~ ((P 3 :% 4) % 4))+_testSlash_Rat3P4_IntN4 = Dict @((N 3 :% 16) ~ ((P 3 :% 4) % (N 4)))+_testSlash_Rat3P4_IntN3 = Dict @((N 1 :% 4) ~ ((P 3 :% 4) % (N 3)))+_testSlash_Rat3P4_IntN2 = Dict @((N 3 :% 8) ~ ((P 3 :% 4) % (N 2)))+_testSlash_Rat3P4_IntN1 = Dict @((N 3 :% 4) ~ ((P 3 :% 4) % (N 1)))+_testSlash_Rat3P4_IntP1 = Dict @((P 3 :% 4) ~ ((P 3 :% 4) % (P 1)))+_testSlash_Rat3P4_IntP2 = Dict @((P 3 :% 8) ~ ((P 3 :% 4) % (P 2)))+_testSlash_Rat3P4_IntP3 = Dict @((P 1 :% 4) ~ ((P 3 :% 4) % (P 3)))+_testSlash_Rat3P4_IntP4 = Dict @((P 3 :% 16) ~ ((P 3 :% 4) % (P 4)))+_testSlash_Rat3P4_Rat4N1 = Dict @((N 3 :% 16) ~ ((P 3 :% 4) % (N 4 :% 1)))+_testSlash_Rat3P4_Rat3N1 = Dict @((N 1 :% 4) ~ ((P 3 :% 4) % (N 3 :% 1)))+_testSlash_Rat3P4_Rat2N1 = Dict @((N 3 :% 8) ~ ((P 3 :% 4) % (N 2 :% 1)))+_testSlash_Rat3P4_Rat3N2 = Dict @((N 1 :% 2) ~ ((P 3 :% 4) % (N 3 :% 2)))+_testSlash_Rat3P4_Rat4N3 = Dict @((N 9 :% 16) ~ ((P 3 :% 4) % (N 4 :% 3)))+_testSlash_Rat3P4_Rat1N1 = Dict @((N 3 :% 4) ~ ((P 3 :% 4) % (N 1 :% 1)))+_testSlash_Rat3P4_Rat3N4 = Dict @((N 1 :% 1) ~ ((P 3 :% 4) % (N 3 :% 4)))+_testSlash_Rat3P4_Rat2N3 = Dict @((N 9 :% 8) ~ ((P 3 :% 4) % (N 2 :% 3)))+_testSlash_Rat3P4_Rat1N2 = Dict @((N 3 :% 2) ~ ((P 3 :% 4) % (N 1 :% 2)))+_testSlash_Rat3P4_Rat1N3 = Dict @((N 9 :% 4) ~ ((P 3 :% 4) % (N 1 :% 3)))+_testSlash_Rat3P4_Rat1N4 = Dict @((N 3 :% 1) ~ ((P 3 :% 4) % (N 1 :% 4)))+_testSlash_Rat3P4_Rat1P4 = Dict @((P 3 :% 1) ~ ((P 3 :% 4) % (P 1 :% 4)))+_testSlash_Rat3P4_Rat1P3 = Dict @((P 9 :% 4) ~ ((P 3 :% 4) % (P 1 :% 3)))+_testSlash_Rat3P4_Rat1P2 = Dict @((P 3 :% 2) ~ ((P 3 :% 4) % (P 1 :% 2)))+_testSlash_Rat3P4_Rat2P3 = Dict @((P 9 :% 8) ~ ((P 3 :% 4) % (P 2 :% 3)))+_testSlash_Rat3P4_Rat3P4 = Dict @((P 1 :% 1) ~ ((P 3 :% 4) % (P 3 :% 4)))+_testSlash_Rat3P4_Rat1P1 = Dict @((P 3 :% 4) ~ ((P 3 :% 4) % (P 1 :% 1)))+_testSlash_Rat3P4_Rat4P3 = Dict @((P 9 :% 16) ~ ((P 3 :% 4) % (P 4 :% 3)))+_testSlash_Rat3P4_Rat3P2 = Dict @((P 1 :% 2) ~ ((P 3 :% 4) % (P 3 :% 2)))+_testSlash_Rat3P4_Rat2P1 = Dict @((P 3 :% 8) ~ ((P 3 :% 4) % (P 2 :% 1)))+_testSlash_Rat3P4_Rat3P1 = Dict @((P 1 :% 4) ~ ((P 3 :% 4) % (P 3 :% 1)))+_testSlash_Rat3P4_Rat4P1 = Dict @((P 3 :% 16) ~ ((P 3 :% 4) % (P 4 :% 1)))+_testSlash_Rat1P1_Nat1 = Dict @((P 1 :% 1) ~ ((P 1 :% 1) % 1))+_testSlash_Rat1P1_Nat2 = Dict @((P 1 :% 2) ~ ((P 1 :% 1) % 2))+_testSlash_Rat1P1_Nat3 = Dict @((P 1 :% 3) ~ ((P 1 :% 1) % 3))+_testSlash_Rat1P1_Nat4 = Dict @((P 1 :% 4) ~ ((P 1 :% 1) % 4))+_testSlash_Rat1P1_IntN4 = Dict @((N 1 :% 4) ~ ((P 1 :% 1) % (N 4)))+_testSlash_Rat1P1_IntN3 = Dict @((N 1 :% 3) ~ ((P 1 :% 1) % (N 3)))+_testSlash_Rat1P1_IntN2 = Dict @((N 1 :% 2) ~ ((P 1 :% 1) % (N 2)))+_testSlash_Rat1P1_IntN1 = Dict @((N 1 :% 1) ~ ((P 1 :% 1) % (N 1)))+_testSlash_Rat1P1_IntP1 = Dict @((P 1 :% 1) ~ ((P 1 :% 1) % (P 1)))+_testSlash_Rat1P1_IntP2 = Dict @((P 1 :% 2) ~ ((P 1 :% 1) % (P 2)))+_testSlash_Rat1P1_IntP3 = Dict @((P 1 :% 3) ~ ((P 1 :% 1) % (P 3)))+_testSlash_Rat1P1_IntP4 = Dict @((P 1 :% 4) ~ ((P 1 :% 1) % (P 4)))+_testSlash_Rat1P1_Rat4N1 = Dict @((N 1 :% 4) ~ ((P 1 :% 1) % (N 4 :% 1)))+_testSlash_Rat1P1_Rat3N1 = Dict @((N 1 :% 3) ~ ((P 1 :% 1) % (N 3 :% 1)))+_testSlash_Rat1P1_Rat2N1 = Dict @((N 1 :% 2) ~ ((P 1 :% 1) % (N 2 :% 1)))+_testSlash_Rat1P1_Rat3N2 = Dict @((N 2 :% 3) ~ ((P 1 :% 1) % (N 3 :% 2)))+_testSlash_Rat1P1_Rat4N3 = Dict @((N 3 :% 4) ~ ((P 1 :% 1) % (N 4 :% 3)))+_testSlash_Rat1P1_Rat1N1 = Dict @((N 1 :% 1) ~ ((P 1 :% 1) % (N 1 :% 1)))+_testSlash_Rat1P1_Rat3N4 = Dict @((N 4 :% 3) ~ ((P 1 :% 1) % (N 3 :% 4)))+_testSlash_Rat1P1_Rat2N3 = Dict @((N 3 :% 2) ~ ((P 1 :% 1) % (N 2 :% 3)))+_testSlash_Rat1P1_Rat1N2 = Dict @((N 2 :% 1) ~ ((P 1 :% 1) % (N 1 :% 2)))+_testSlash_Rat1P1_Rat1N3 = Dict @((N 3 :% 1) ~ ((P 1 :% 1) % (N 1 :% 3)))+_testSlash_Rat1P1_Rat1N4 = Dict @((N 4 :% 1) ~ ((P 1 :% 1) % (N 1 :% 4)))+_testSlash_Rat1P1_Rat1P4 = Dict @((P 4 :% 1) ~ ((P 1 :% 1) % (P 1 :% 4)))+_testSlash_Rat1P1_Rat1P3 = Dict @((P 3 :% 1) ~ ((P 1 :% 1) % (P 1 :% 3)))+_testSlash_Rat1P1_Rat1P2 = Dict @((P 2 :% 1) ~ ((P 1 :% 1) % (P 1 :% 2)))+_testSlash_Rat1P1_Rat2P3 = Dict @((P 3 :% 2) ~ ((P 1 :% 1) % (P 2 :% 3)))+_testSlash_Rat1P1_Rat3P4 = Dict @((P 4 :% 3) ~ ((P 1 :% 1) % (P 3 :% 4)))+_testSlash_Rat1P1_Rat1P1 = Dict @((P 1 :% 1) ~ ((P 1 :% 1) % (P 1 :% 1)))+_testSlash_Rat1P1_Rat4P3 = Dict @((P 3 :% 4) ~ ((P 1 :% 1) % (P 4 :% 3)))+_testSlash_Rat1P1_Rat3P2 = Dict @((P 2 :% 3) ~ ((P 1 :% 1) % (P 3 :% 2)))+_testSlash_Rat1P1_Rat2P1 = Dict @((P 1 :% 2) ~ ((P 1 :% 1) % (P 2 :% 1)))+_testSlash_Rat1P1_Rat3P1 = Dict @((P 1 :% 3) ~ ((P 1 :% 1) % (P 3 :% 1)))+_testSlash_Rat1P1_Rat4P1 = Dict @((P 1 :% 4) ~ ((P 1 :% 1) % (P 4 :% 1)))+_testSlash_Rat4P3_Nat1 = Dict @((P 4 :% 3) ~ ((P 4 :% 3) % 1))+_testSlash_Rat4P3_Nat2 = Dict @((P 2 :% 3) ~ ((P 4 :% 3) % 2))+_testSlash_Rat4P3_Nat3 = Dict @((P 4 :% 9) ~ ((P 4 :% 3) % 3))+_testSlash_Rat4P3_Nat4 = Dict @((P 1 :% 3) ~ ((P 4 :% 3) % 4))+_testSlash_Rat4P3_IntN4 = Dict @((N 1 :% 3) ~ ((P 4 :% 3) % (N 4)))+_testSlash_Rat4P3_IntN3 = Dict @((N 4 :% 9) ~ ((P 4 :% 3) % (N 3)))+_testSlash_Rat4P3_IntN2 = Dict @((N 2 :% 3) ~ ((P 4 :% 3) % (N 2)))+_testSlash_Rat4P3_IntN1 = Dict @((N 4 :% 3) ~ ((P 4 :% 3) % (N 1)))+_testSlash_Rat4P3_IntP1 = Dict @((P 4 :% 3) ~ ((P 4 :% 3) % (P 1)))+_testSlash_Rat4P3_IntP2 = Dict @((P 2 :% 3) ~ ((P 4 :% 3) % (P 2)))+_testSlash_Rat4P3_IntP3 = Dict @((P 4 :% 9) ~ ((P 4 :% 3) % (P 3)))+_testSlash_Rat4P3_IntP4 = Dict @((P 1 :% 3) ~ ((P 4 :% 3) % (P 4)))+_testSlash_Rat4P3_Rat4N1 = Dict @((N 1 :% 3) ~ ((P 4 :% 3) % (N 4 :% 1)))+_testSlash_Rat4P3_Rat3N1 = Dict @((N 4 :% 9) ~ ((P 4 :% 3) % (N 3 :% 1)))+_testSlash_Rat4P3_Rat2N1 = Dict @((N 2 :% 3) ~ ((P 4 :% 3) % (N 2 :% 1)))+_testSlash_Rat4P3_Rat3N2 = Dict @((N 8 :% 9) ~ ((P 4 :% 3) % (N 3 :% 2)))+_testSlash_Rat4P3_Rat4N3 = Dict @((N 1 :% 1) ~ ((P 4 :% 3) % (N 4 :% 3)))+_testSlash_Rat4P3_Rat1N1 = Dict @((N 4 :% 3) ~ ((P 4 :% 3) % (N 1 :% 1)))+_testSlash_Rat4P3_Rat3N4 = Dict @((N 16 :% 9) ~ ((P 4 :% 3) % (N 3 :% 4)))+_testSlash_Rat4P3_Rat2N3 = Dict @((N 2 :% 1) ~ ((P 4 :% 3) % (N 2 :% 3)))+_testSlash_Rat4P3_Rat1N2 = Dict @((N 8 :% 3) ~ ((P 4 :% 3) % (N 1 :% 2)))+_testSlash_Rat4P3_Rat1N3 = Dict @((N 4 :% 1) ~ ((P 4 :% 3) % (N 1 :% 3)))+_testSlash_Rat4P3_Rat1N4 = Dict @((N 16 :% 3) ~ ((P 4 :% 3) % (N 1 :% 4)))+_testSlash_Rat4P3_Rat1P4 = Dict @((P 16 :% 3) ~ ((P 4 :% 3) % (P 1 :% 4)))+_testSlash_Rat4P3_Rat1P3 = Dict @((P 4 :% 1) ~ ((P 4 :% 3) % (P 1 :% 3)))+_testSlash_Rat4P3_Rat1P2 = Dict @((P 8 :% 3) ~ ((P 4 :% 3) % (P 1 :% 2)))+_testSlash_Rat4P3_Rat2P3 = Dict @((P 2 :% 1) ~ ((P 4 :% 3) % (P 2 :% 3)))+_testSlash_Rat4P3_Rat3P4 = Dict @((P 16 :% 9) ~ ((P 4 :% 3) % (P 3 :% 4)))+_testSlash_Rat4P3_Rat1P1 = Dict @((P 4 :% 3) ~ ((P 4 :% 3) % (P 1 :% 1)))+_testSlash_Rat4P3_Rat4P3 = Dict @((P 1 :% 1) ~ ((P 4 :% 3) % (P 4 :% 3)))+_testSlash_Rat4P3_Rat3P2 = Dict @((P 8 :% 9) ~ ((P 4 :% 3) % (P 3 :% 2)))+_testSlash_Rat4P3_Rat2P1 = Dict @((P 2 :% 3) ~ ((P 4 :% 3) % (P 2 :% 1)))+_testSlash_Rat4P3_Rat3P1 = Dict @((P 4 :% 9) ~ ((P 4 :% 3) % (P 3 :% 1)))+_testSlash_Rat4P3_Rat4P1 = Dict @((P 1 :% 3) ~ ((P 4 :% 3) % (P 4 :% 1)))+_testSlash_Rat3P2_Nat1 = Dict @((P 3 :% 2) ~ ((P 3 :% 2) % 1))+_testSlash_Rat3P2_Nat2 = Dict @((P 3 :% 4) ~ ((P 3 :% 2) % 2))+_testSlash_Rat3P2_Nat3 = Dict @((P 1 :% 2) ~ ((P 3 :% 2) % 3))+_testSlash_Rat3P2_Nat4 = Dict @((P 3 :% 8) ~ ((P 3 :% 2) % 4))+_testSlash_Rat3P2_IntN4 = Dict @((N 3 :% 8) ~ ((P 3 :% 2) % (N 4)))+_testSlash_Rat3P2_IntN3 = Dict @((N 1 :% 2) ~ ((P 3 :% 2) % (N 3)))+_testSlash_Rat3P2_IntN2 = Dict @((N 3 :% 4) ~ ((P 3 :% 2) % (N 2)))+_testSlash_Rat3P2_IntN1 = Dict @((N 3 :% 2) ~ ((P 3 :% 2) % (N 1)))+_testSlash_Rat3P2_IntP1 = Dict @((P 3 :% 2) ~ ((P 3 :% 2) % (P 1)))+_testSlash_Rat3P2_IntP2 = Dict @((P 3 :% 4) ~ ((P 3 :% 2) % (P 2)))+_testSlash_Rat3P2_IntP3 = Dict @((P 1 :% 2) ~ ((P 3 :% 2) % (P 3)))+_testSlash_Rat3P2_IntP4 = Dict @((P 3 :% 8) ~ ((P 3 :% 2) % (P 4)))+_testSlash_Rat3P2_Rat4N1 = Dict @((N 3 :% 8) ~ ((P 3 :% 2) % (N 4 :% 1)))+_testSlash_Rat3P2_Rat3N1 = Dict @((N 1 :% 2) ~ ((P 3 :% 2) % (N 3 :% 1)))+_testSlash_Rat3P2_Rat2N1 = Dict @((N 3 :% 4) ~ ((P 3 :% 2) % (N 2 :% 1)))+_testSlash_Rat3P2_Rat3N2 = Dict @((N 1 :% 1) ~ ((P 3 :% 2) % (N 3 :% 2)))+_testSlash_Rat3P2_Rat4N3 = Dict @((N 9 :% 8) ~ ((P 3 :% 2) % (N 4 :% 3)))+_testSlash_Rat3P2_Rat1N1 = Dict @((N 3 :% 2) ~ ((P 3 :% 2) % (N 1 :% 1)))+_testSlash_Rat3P2_Rat3N4 = Dict @((N 2 :% 1) ~ ((P 3 :% 2) % (N 3 :% 4)))+_testSlash_Rat3P2_Rat2N3 = Dict @((N 9 :% 4) ~ ((P 3 :% 2) % (N 2 :% 3)))+_testSlash_Rat3P2_Rat1N2 = Dict @((N 3 :% 1) ~ ((P 3 :% 2) % (N 1 :% 2)))+_testSlash_Rat3P2_Rat1N3 = Dict @((N 9 :% 2) ~ ((P 3 :% 2) % (N 1 :% 3)))+_testSlash_Rat3P2_Rat1N4 = Dict @((N 6 :% 1) ~ ((P 3 :% 2) % (N 1 :% 4)))+_testSlash_Rat3P2_Rat1P4 = Dict @((P 6 :% 1) ~ ((P 3 :% 2) % (P 1 :% 4)))+_testSlash_Rat3P2_Rat1P3 = Dict @((P 9 :% 2) ~ ((P 3 :% 2) % (P 1 :% 3)))+_testSlash_Rat3P2_Rat1P2 = Dict @((P 3 :% 1) ~ ((P 3 :% 2) % (P 1 :% 2)))+_testSlash_Rat3P2_Rat2P3 = Dict @((P 9 :% 4) ~ ((P 3 :% 2) % (P 2 :% 3)))+_testSlash_Rat3P2_Rat3P4 = Dict @((P 2 :% 1) ~ ((P 3 :% 2) % (P 3 :% 4)))+_testSlash_Rat3P2_Rat1P1 = Dict @((P 3 :% 2) ~ ((P 3 :% 2) % (P 1 :% 1)))+_testSlash_Rat3P2_Rat4P3 = Dict @((P 9 :% 8) ~ ((P 3 :% 2) % (P 4 :% 3)))+_testSlash_Rat3P2_Rat3P2 = Dict @((P 1 :% 1) ~ ((P 3 :% 2) % (P 3 :% 2)))+_testSlash_Rat3P2_Rat2P1 = Dict @((P 3 :% 4) ~ ((P 3 :% 2) % (P 2 :% 1)))+_testSlash_Rat3P2_Rat3P1 = Dict @((P 1 :% 2) ~ ((P 3 :% 2) % (P 3 :% 1)))+_testSlash_Rat3P2_Rat4P1 = Dict @((P 3 :% 8) ~ ((P 3 :% 2) % (P 4 :% 1)))+_testSlash_Rat2P1_Nat1 = Dict @((P 2 :% 1) ~ ((P 2 :% 1) % 1))+_testSlash_Rat2P1_Nat2 = Dict @((P 1 :% 1) ~ ((P 2 :% 1) % 2))+_testSlash_Rat2P1_Nat3 = Dict @((P 2 :% 3) ~ ((P 2 :% 1) % 3))+_testSlash_Rat2P1_Nat4 = Dict @((P 1 :% 2) ~ ((P 2 :% 1) % 4))+_testSlash_Rat2P1_IntN4 = Dict @((N 1 :% 2) ~ ((P 2 :% 1) % (N 4)))+_testSlash_Rat2P1_IntN3 = Dict @((N 2 :% 3) ~ ((P 2 :% 1) % (N 3)))+_testSlash_Rat2P1_IntN2 = Dict @((N 1 :% 1) ~ ((P 2 :% 1) % (N 2)))+_testSlash_Rat2P1_IntN1 = Dict @((N 2 :% 1) ~ ((P 2 :% 1) % (N 1)))+_testSlash_Rat2P1_IntP1 = Dict @((P 2 :% 1) ~ ((P 2 :% 1) % (P 1)))+_testSlash_Rat2P1_IntP2 = Dict @((P 1 :% 1) ~ ((P 2 :% 1) % (P 2)))+_testSlash_Rat2P1_IntP3 = Dict @((P 2 :% 3) ~ ((P 2 :% 1) % (P 3)))+_testSlash_Rat2P1_IntP4 = Dict @((P 1 :% 2) ~ ((P 2 :% 1) % (P 4)))+_testSlash_Rat2P1_Rat4N1 = Dict @((N 1 :% 2) ~ ((P 2 :% 1) % (N 4 :% 1)))+_testSlash_Rat2P1_Rat3N1 = Dict @((N 2 :% 3) ~ ((P 2 :% 1) % (N 3 :% 1)))+_testSlash_Rat2P1_Rat2N1 = Dict @((N 1 :% 1) ~ ((P 2 :% 1) % (N 2 :% 1)))+_testSlash_Rat2P1_Rat3N2 = Dict @((N 4 :% 3) ~ ((P 2 :% 1) % (N 3 :% 2)))+_testSlash_Rat2P1_Rat4N3 = Dict @((N 3 :% 2) ~ ((P 2 :% 1) % (N 4 :% 3)))+_testSlash_Rat2P1_Rat1N1 = Dict @((N 2 :% 1) ~ ((P 2 :% 1) % (N 1 :% 1)))+_testSlash_Rat2P1_Rat3N4 = Dict @((N 8 :% 3) ~ ((P 2 :% 1) % (N 3 :% 4)))+_testSlash_Rat2P1_Rat2N3 = Dict @((N 3 :% 1) ~ ((P 2 :% 1) % (N 2 :% 3)))+_testSlash_Rat2P1_Rat1N2 = Dict @((N 4 :% 1) ~ ((P 2 :% 1) % (N 1 :% 2)))+_testSlash_Rat2P1_Rat1N3 = Dict @((N 6 :% 1) ~ ((P 2 :% 1) % (N 1 :% 3)))+_testSlash_Rat2P1_Rat1N4 = Dict @((N 8 :% 1) ~ ((P 2 :% 1) % (N 1 :% 4)))+_testSlash_Rat2P1_Rat1P4 = Dict @((P 8 :% 1) ~ ((P 2 :% 1) % (P 1 :% 4)))+_testSlash_Rat2P1_Rat1P3 = Dict @((P 6 :% 1) ~ ((P 2 :% 1) % (P 1 :% 3)))+_testSlash_Rat2P1_Rat1P2 = Dict @((P 4 :% 1) ~ ((P 2 :% 1) % (P 1 :% 2)))+_testSlash_Rat2P1_Rat2P3 = Dict @((P 3 :% 1) ~ ((P 2 :% 1) % (P 2 :% 3)))+_testSlash_Rat2P1_Rat3P4 = Dict @((P 8 :% 3) ~ ((P 2 :% 1) % (P 3 :% 4)))+_testSlash_Rat2P1_Rat1P1 = Dict @((P 2 :% 1) ~ ((P 2 :% 1) % (P 1 :% 1)))+_testSlash_Rat2P1_Rat4P3 = Dict @((P 3 :% 2) ~ ((P 2 :% 1) % (P 4 :% 3)))+_testSlash_Rat2P1_Rat3P2 = Dict @((P 4 :% 3) ~ ((P 2 :% 1) % (P 3 :% 2)))+_testSlash_Rat2P1_Rat2P1 = Dict @((P 1 :% 1) ~ ((P 2 :% 1) % (P 2 :% 1)))+_testSlash_Rat2P1_Rat3P1 = Dict @((P 2 :% 3) ~ ((P 2 :% 1) % (P 3 :% 1)))+_testSlash_Rat2P1_Rat4P1 = Dict @((P 1 :% 2) ~ ((P 2 :% 1) % (P 4 :% 1)))+_testSlash_Rat3P1_Nat1 = Dict @((P 3 :% 1) ~ ((P 3 :% 1) % 1))+_testSlash_Rat3P1_Nat2 = Dict @((P 3 :% 2) ~ ((P 3 :% 1) % 2))+_testSlash_Rat3P1_Nat3 = Dict @((P 1 :% 1) ~ ((P 3 :% 1) % 3))+_testSlash_Rat3P1_Nat4 = Dict @((P 3 :% 4) ~ ((P 3 :% 1) % 4))+_testSlash_Rat3P1_IntN4 = Dict @((N 3 :% 4) ~ ((P 3 :% 1) % (N 4)))+_testSlash_Rat3P1_IntN3 = Dict @((N 1 :% 1) ~ ((P 3 :% 1) % (N 3)))+_testSlash_Rat3P1_IntN2 = Dict @((N 3 :% 2) ~ ((P 3 :% 1) % (N 2)))+_testSlash_Rat3P1_IntN1 = Dict @((N 3 :% 1) ~ ((P 3 :% 1) % (N 1)))+_testSlash_Rat3P1_IntP1 = Dict @((P 3 :% 1) ~ ((P 3 :% 1) % (P 1)))+_testSlash_Rat3P1_IntP2 = Dict @((P 3 :% 2) ~ ((P 3 :% 1) % (P 2)))+_testSlash_Rat3P1_IntP3 = Dict @((P 1 :% 1) ~ ((P 3 :% 1) % (P 3)))+_testSlash_Rat3P1_IntP4 = Dict @((P 3 :% 4) ~ ((P 3 :% 1) % (P 4)))+_testSlash_Rat3P1_Rat4N1 = Dict @((N 3 :% 4) ~ ((P 3 :% 1) % (N 4 :% 1)))+_testSlash_Rat3P1_Rat3N1 = Dict @((N 1 :% 1) ~ ((P 3 :% 1) % (N 3 :% 1)))+_testSlash_Rat3P1_Rat2N1 = Dict @((N 3 :% 2) ~ ((P 3 :% 1) % (N 2 :% 1)))+_testSlash_Rat3P1_Rat3N2 = Dict @((N 2 :% 1) ~ ((P 3 :% 1) % (N 3 :% 2)))+_testSlash_Rat3P1_Rat4N3 = Dict @((N 9 :% 4) ~ ((P 3 :% 1) % (N 4 :% 3)))+_testSlash_Rat3P1_Rat1N1 = Dict @((N 3 :% 1) ~ ((P 3 :% 1) % (N 1 :% 1)))+_testSlash_Rat3P1_Rat3N4 = Dict @((N 4 :% 1) ~ ((P 3 :% 1) % (N 3 :% 4)))+_testSlash_Rat3P1_Rat2N3 = Dict @((N 9 :% 2) ~ ((P 3 :% 1) % (N 2 :% 3)))+_testSlash_Rat3P1_Rat1N2 = Dict @((N 6 :% 1) ~ ((P 3 :% 1) % (N 1 :% 2)))+_testSlash_Rat3P1_Rat1N3 = Dict @((N 9 :% 1) ~ ((P 3 :% 1) % (N 1 :% 3)))+_testSlash_Rat3P1_Rat1N4 = Dict @((N 12 :% 1) ~ ((P 3 :% 1) % (N 1 :% 4)))+_testSlash_Rat3P1_Rat1P4 = Dict @((P 12 :% 1) ~ ((P 3 :% 1) % (P 1 :% 4)))+_testSlash_Rat3P1_Rat1P3 = Dict @((P 9 :% 1) ~ ((P 3 :% 1) % (P 1 :% 3)))+_testSlash_Rat3P1_Rat1P2 = Dict @((P 6 :% 1) ~ ((P 3 :% 1) % (P 1 :% 2)))+_testSlash_Rat3P1_Rat2P3 = Dict @((P 9 :% 2) ~ ((P 3 :% 1) % (P 2 :% 3)))+_testSlash_Rat3P1_Rat3P4 = Dict @((P 4 :% 1) ~ ((P 3 :% 1) % (P 3 :% 4)))+_testSlash_Rat3P1_Rat1P1 = Dict @((P 3 :% 1) ~ ((P 3 :% 1) % (P 1 :% 1)))+_testSlash_Rat3P1_Rat4P3 = Dict @((P 9 :% 4) ~ ((P 3 :% 1) % (P 4 :% 3)))+_testSlash_Rat3P1_Rat3P2 = Dict @((P 2 :% 1) ~ ((P 3 :% 1) % (P 3 :% 2)))+_testSlash_Rat3P1_Rat2P1 = Dict @((P 3 :% 2) ~ ((P 3 :% 1) % (P 2 :% 1)))+_testSlash_Rat3P1_Rat3P1 = Dict @((P 1 :% 1) ~ ((P 3 :% 1) % (P 3 :% 1)))+_testSlash_Rat3P1_Rat4P1 = Dict @((P 3 :% 4) ~ ((P 3 :% 1) % (P 4 :% 1)))+_testSlash_Rat4P1_Nat1 = Dict @((P 4 :% 1) ~ ((P 4 :% 1) % 1))+_testSlash_Rat4P1_Nat2 = Dict @((P 2 :% 1) ~ ((P 4 :% 1) % 2))+_testSlash_Rat4P1_Nat3 = Dict @((P 4 :% 3) ~ ((P 4 :% 1) % 3))+_testSlash_Rat4P1_Nat4 = Dict @((P 1 :% 1) ~ ((P 4 :% 1) % 4))+_testSlash_Rat4P1_IntN4 = Dict @((N 1 :% 1) ~ ((P 4 :% 1) % (N 4)))+_testSlash_Rat4P1_IntN3 = Dict @((N 4 :% 3) ~ ((P 4 :% 1) % (N 3)))+_testSlash_Rat4P1_IntN2 = Dict @((N 2 :% 1) ~ ((P 4 :% 1) % (N 2)))+_testSlash_Rat4P1_IntN1 = Dict @((N 4 :% 1) ~ ((P 4 :% 1) % (N 1)))+_testSlash_Rat4P1_IntP1 = Dict @((P 4 :% 1) ~ ((P 4 :% 1) % (P 1)))+_testSlash_Rat4P1_IntP2 = Dict @((P 2 :% 1) ~ ((P 4 :% 1) % (P 2)))+_testSlash_Rat4P1_IntP3 = Dict @((P 4 :% 3) ~ ((P 4 :% 1) % (P 3)))+_testSlash_Rat4P1_IntP4 = Dict @((P 1 :% 1) ~ ((P 4 :% 1) % (P 4)))+_testSlash_Rat4P1_Rat4N1 = Dict @((N 1 :% 1) ~ ((P 4 :% 1) % (N 4 :% 1)))+_testSlash_Rat4P1_Rat3N1 = Dict @((N 4 :% 3) ~ ((P 4 :% 1) % (N 3 :% 1)))+_testSlash_Rat4P1_Rat2N1 = Dict @((N 2 :% 1) ~ ((P 4 :% 1) % (N 2 :% 1)))+_testSlash_Rat4P1_Rat3N2 = Dict @((N 8 :% 3) ~ ((P 4 :% 1) % (N 3 :% 2)))+_testSlash_Rat4P1_Rat4N3 = Dict @((N 3 :% 1) ~ ((P 4 :% 1) % (N 4 :% 3)))+_testSlash_Rat4P1_Rat1N1 = Dict @((N 4 :% 1) ~ ((P 4 :% 1) % (N 1 :% 1)))+_testSlash_Rat4P1_Rat3N4 = Dict @((N 16 :% 3) ~ ((P 4 :% 1) % (N 3 :% 4)))+_testSlash_Rat4P1_Rat2N3 = Dict @((N 6 :% 1) ~ ((P 4 :% 1) % (N 2 :% 3)))+_testSlash_Rat4P1_Rat1N2 = Dict @((N 8 :% 1) ~ ((P 4 :% 1) % (N 1 :% 2)))+_testSlash_Rat4P1_Rat1N3 = Dict @((N 12 :% 1) ~ ((P 4 :% 1) % (N 1 :% 3)))+_testSlash_Rat4P1_Rat1N4 = Dict @((N 16 :% 1) ~ ((P 4 :% 1) % (N 1 :% 4)))+_testSlash_Rat4P1_Rat1P4 = Dict @((P 16 :% 1) ~ ((P 4 :% 1) % (P 1 :% 4)))+_testSlash_Rat4P1_Rat1P3 = Dict @((P 12 :% 1) ~ ((P 4 :% 1) % (P 1 :% 3)))+_testSlash_Rat4P1_Rat1P2 = Dict @((P 8 :% 1) ~ ((P 4 :% 1) % (P 1 :% 2)))+_testSlash_Rat4P1_Rat2P3 = Dict @((P 6 :% 1) ~ ((P 4 :% 1) % (P 2 :% 3)))+_testSlash_Rat4P1_Rat3P4 = Dict @((P 16 :% 3) ~ ((P 4 :% 1) % (P 3 :% 4)))+_testSlash_Rat4P1_Rat1P1 = Dict @((P 4 :% 1) ~ ((P 4 :% 1) % (P 1 :% 1)))+_testSlash_Rat4P1_Rat4P3 = Dict @((P 3 :% 1) ~ ((P 4 :% 1) % (P 4 :% 3)))+_testSlash_Rat4P1_Rat3P2 = Dict @((P 8 :% 3) ~ ((P 4 :% 1) % (P 3 :% 2)))+_testSlash_Rat4P1_Rat2P1 = Dict @((P 2 :% 1) ~ ((P 4 :% 1) % (P 2 :% 1)))+_testSlash_Rat4P1_Rat3P1 = Dict @((P 4 :% 3) ~ ((P 4 :% 1) % (P 3 :% 1)))+_testSlash_Rat4P1_Rat4P1 = Dict @((P 1 :% 1) ~ ((P 4 :% 1) % (P 4 :% 1)))