packages feed

tuple-gen-2.0: src/Data/Tuple/Enum.hs

module Data.Tuple.Enum (all2s, all3s, all4s, all5s, all6s, all7s, all8s, all9s, all10s,
                        all11s, all12s, all13s, all14s, all15s, hyperplaneSize, fe, te,
                        to2Tuple, to3Tuple, to4Tuple, to5Tuple, to6Tuple, to7Tuple, to8Tuple,
                        to9Tuple, to10Tuple, to11Tuple, to12Tuple, to13Tuple, to14Tuple, to15Tuple,
                        from2Tuple, from3Tuple, from4Tuple, from5Tuple, from6Tuple, from7Tuple, from8Tuple,
                        from9Tuple, from10Tuple, from11Tuple, from12Tuple, from13Tuple, from14Tuple, from15Tuple,
                        Enum (..)
                        )
where
import Data.Word
import Math.Combinat.Numbers

----------------------------------------------------------------------------------------------------
-- see the Monad Reader issue 20 as a documentation 
----------------------------------------------------------------------------------------------------

-- | generate all 2-tuples (of enumerable values) so that the sum of the 2 fromEnum-values is monotonic increasing
--   fromEnum :: a -> Int
all2s :: (Enum a, Enum b, Eq a, Eq b, Bounded a, Bounded b) => [(a,b)]
all2s = enumFrom (minBound,minBound)

-- | generate all 3-tuples (of enumerable values) so that the sum of the 3 fromEnum-values is monotonic increasing
--   fromEnum :: a -> Int
all3s :: (Enum a, Enum b, Enum c, Eq a, Eq b, Eq c, Bounded a, Bounded b, Bounded c) => [(a,b,c)]
all3s = enumFrom (minBound,minBound,minBound)

-- | generate all 4-tuples (of enumerable values) so that the sum of the 4 fromEnum-values is monotonic increasing
--   fromEnum :: a -> Int
all4s :: (Enum a, Enum b, Enum c, Enum d, Eq a, Eq b, Eq c, Eq d,
          Bounded a, Bounded b, Bounded c, Bounded d) => [(a,b,c,d)]
all4s = enumFrom (minBound,minBound,minBound,minBound)

-- | generate all 5-tuples (of enumerable values) so that the sum of the 5 fromEnum-values is monotonic increasing
--   fromEnum :: a -> Int
all5s :: (Enum a, Enum b, Enum c, Enum d, Enum e, Eq a, Eq b, Eq c, Eq d, Eq e, 
          Bounded a, Bounded b, Bounded c, Bounded d, Bounded e) => [(a,b,c,d,e)]
all5s = enumFrom (minBound,minBound,minBound,minBound,minBound)

-- | generate all 6-tuples (of enumerable values) so that the sum of the 6 fromEnum-values is monotonic increasing
--   fromEnum :: a -> Int
all6s :: (Enum a, Enum b, Enum c, Enum d, Enum e, Enum f, Eq a, Eq b, Eq c, Eq d, Eq e, Eq f,
          Bounded a, Bounded b, Bounded c, Bounded d, Bounded e, Bounded f) => [(a,b,c,d,e,f)]
all6s = enumFrom (minBound,minBound,minBound,minBound,minBound,minBound)

-- | generate all 7-tuples (of enumerable values) so that the sum of the 7 fromEnum-values is monotonic increasing
--   fromEnum :: a -> Int
all7s :: (Enum a, Enum b, Enum c, Enum d, Enum e, Enum f, Enum g, Eq a, Eq b, Eq c, Eq d, Eq e, Eq f, Eq g,
          Bounded a, Bounded b, Bounded c, Bounded d, Bounded e, Bounded f, Bounded g) => [(a,b,c,d,e,f,g)]
all7s = enumFrom (minBound,minBound,minBound,minBound,minBound,minBound,minBound)

-- | generate all 8-tuples (of enumerable values) so that the sum of the 8 fromEnum-values is monotonic increasing
--   fromEnum :: a -> Int
all8s :: (Enum a, Enum b, Enum c, Enum d, Enum e, Enum f, Enum g, Enum h, Eq a, Eq b, Eq c, Eq d, Eq e, Eq f, Eq g, Eq h,
          Bounded a, Bounded b, Bounded c, Bounded d,
          Bounded e, Bounded f, Bounded g, Bounded h) => [(a,b,c,d,e,f,g,h)]
all8s = enumFrom (minBound,minBound,minBound,minBound,minBound,minBound,minBound,minBound)

-- | generate all 9-tuples (of enumerable values) so that the sum of the 9 fromEnum-values is monotonic increasing
--   fromEnum :: a -> Int
all9s :: (Enum a,Enum b,Enum c,Enum d,Enum e,Enum f,Enum g,Enum h,Enum i,
          Eq a, Eq b, Eq c, Eq d, Eq e, Eq f, Eq g, Eq h, Eq i,
          Bounded a,Bounded b,Bounded c,Bounded d,
          Bounded e,Bounded f,Bounded g,Bounded h,Bounded i) => [(a,b,c,d,e,f,g,h,i)]
all9s = enumFrom (minBound,minBound,minBound,minBound,minBound,minBound,minBound,minBound,minBound)

-- | generate all 10-tuples (of enumerable values) so that the sum of the 10 fromEnum-values is monotonic increasing
--   fromEnum :: a -> Int
all10s :: (Enum a,Enum b,Enum c,Enum d,Enum e,Enum f,Enum g,Enum h,Enum i,Enum j,
           Eq a, Eq b, Eq c, Eq d, Eq e, Eq f, Eq g, Eq h, Eq i, Eq j,
           Bounded a,Bounded b,Bounded c,Bounded d,Bounded e,
           Bounded f,Bounded g,Bounded h,Bounded i,Bounded j) => [(a,b,c,d,e,f,g,h,i,j)]
all10s = enumFrom (minBound,minBound,minBound,minBound,minBound,minBound,minBound,minBound,minBound,minBound)

-- | generate all 11-tuples (of enumerable values) so that the sum of the 11 fromEnum-values is monotonic increasing
--   fromEnum :: a -> Int
all11s :: (Enum a,Enum b,Enum c,Enum d,Enum e,Enum f,Enum g,Enum h,Enum i,Enum j, Enum k,
           Eq a, Eq b, Eq c, Eq d, Eq e, Eq f, Eq g, Eq h, Eq i, Eq j, Eq k,
           Bounded a,Bounded b,Bounded c,Bounded d,Bounded e,
           Bounded f,Bounded g,Bounded h,Bounded i,Bounded j,Bounded k) => [(a,b,c,d,e,f,g,h,i,j,k)]
all11s = enumFrom (minBound,minBound,minBound,minBound,minBound,minBound,minBound,minBound,minBound,minBound,minBound)

-- | generate all 12-tuples (of enumerable values) so that the sum of the 12 fromEnum-values is monotonic increasing
--   fromEnum :: a -> Int
all12s :: (Enum a,Enum b,Enum c,Enum d,Enum e,Enum f,Enum g,Enum h,Enum i,Enum j, Enum k, Enum l,
           Eq a, Eq b, Eq c, Eq d, Eq e, Eq f, Eq g, Eq h, Eq i, Eq j, Eq k, Eq l,
           Bounded a,Bounded b,Bounded c,Bounded d,Bounded e,Bounded f,
           Bounded g,Bounded h,Bounded i,Bounded j,Bounded k,Bounded l) => [(a,b,c,d,e,f,g,h,i,j,k,l)]
all12s = enumFrom (minBound,minBound,minBound,minBound,minBound,minBound,minBound,minBound,minBound,minBound,minBound,minBound)

-- | generate all 13-tuples (of enumerable values) so that the sum of the 13 fromEnum-values is monotonic increasing
--   fromEnum :: a -> Int
all13s :: (Enum a,Enum b,Enum c,Enum d,Enum e,Enum f,Enum g,Enum h,Enum i,Enum j, Enum k, Enum l, Enum m,
           Eq a, Eq b, Eq c, Eq d, Eq e, Eq f, Eq g, Eq h, Eq i, Eq j, Eq k, Eq l, Eq m,
           Bounded a,Bounded b,Bounded c,Bounded d,Bounded e,Bounded f,
           Bounded g,Bounded h,Bounded i,Bounded j, Bounded k, Bounded l, Bounded m) => [(a,b,c,d,e,f,g,h,i,j,k,l,m)]
all13s = enumFrom (minBound,minBound,minBound,minBound,minBound,minBound,minBound,
                   minBound,minBound,minBound,minBound,minBound,minBound)

-- | generate all 14-tuples (of enumerable values) so that the sum of the 14 fromEnum-values is monotonic increasing
--   fromEnum :: a -> Int
all14s :: (Enum a,Enum b,Enum c,Enum d,Enum e,Enum f,Enum g,Enum h,Enum i,Enum j, Enum k, Enum l, Enum m, Enum n,
           Eq a, Eq b, Eq c, Eq d, Eq e, Eq f, Eq g, Eq h, Eq i, Eq j, Eq k, Eq l, Eq m, Eq n,
           Bounded a,Bounded b,Bounded c,Bounded d,Bounded e, Bounded f,Bounded g,
           Bounded h,Bounded i,Bounded j, Bounded k, Bounded l, Bounded m, Bounded n) => [(a,b,c,d,e,f,g,h,i,j,k,l,m,n)]
all14s = enumFrom (minBound,minBound,minBound,minBound,minBound,minBound,minBound,
                   minBound,minBound,minBound,minBound,minBound,minBound,minBound)

-- | generate all 15-tuples (of enumerable values) so that the sum of the 15 fromEnum-values is monotonic increasing
--   fromEnum :: a -> Int
all15s :: (Enum a,Enum b,Enum c,Enum d,Enum e,Enum f,Enum g,Enum h,Enum i,Enum j, Enum k, Enum l, Enum m, Enum n, Enum o,
           Eq a, Eq b, Eq c, Eq d, Eq e, Eq f, Eq g, Eq h, Eq i, Eq j, Eq k, Eq l, Eq m, Eq n, Eq o,
           Bounded a,Bounded b,Bounded c,Bounded d,Bounded e, Bounded f,Bounded g,
           Bounded h,Bounded i,Bounded j, Bounded k, Bounded l, Bounded m, Bounded n, Bounded o) => [(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o)]
all15s = enumFrom (minBound,minBound,minBound,minBound,minBound,minBound,minBound,
                   minBound,minBound,minBound,minBound,minBound,minBound,minBound,minBound)

------------------------------------------------------------------------------------------------------------
-- The size of enumeration hyperplanes
------------------------------------------------------------------------------------------------------------

polynomial :: Int -> [Rational] -> Rational
polynomial n coeffs = foldr (+) 0 (zipWith nPowerP coeffs [1..])
  where nPowerP a_j p = a_j * (fromIntegral (n^p))

sumOfPowers :: Int -> [Rational]
sumOfPowers p = reverse [ (bin j) * (ber j) / ((fromIntegral p)+1) | j <- [0..p] ]
  where bin j = fromIntegral (binomial (p+1) j)
        ber j | j == 1 = negate (bernoulli j) -- see wikipedia entry
              | otherwise = bernoulli j

hyperplaneSize :: Int -> Int -> Int
hyperplaneSize dim n | n == 0   = 0
                     | dim == 0 = 1
                     | otherwise = round (genPolynom 1 [1])
  where genPolynom :: Int -> [Rational] -> Rational
        genPolynom d coeffs | d == dim = polynomial n coeffs
                            | otherwise = genPolynom (d+1)
                              (merge coeffs (map sumOfPowers [1..(length coeffs)]))

merge coeffs ls = foldr myZip [] multiplied_ls
  where multiplied_ls = zipWith (\c l -> map (c*) l) coeffs ls
        myZip (l0:l0s) (l1:l1s) = (l0+l1) : (myZip l0s l1s)
        myZip a b = a ++ b

ssizes d = [ sum (take n sizes) | n <- [1..] ]
  where sizes = [ hyperplaneSize d i | i <- [0..] ]

summedSizes :: Int -> Int -> Int
summedSizes dim n = (ssizes dim) !! n

-- used in fromEnum
fe [x] = x
fe (x:xs) = ( summedSizes (length xs) (foldr (+) 0 (x:xs)) ) + (fe xs)

-- (summedSizes 4 (a1+b1+c1+d1+e1) ) +
-- (summedSizes 3    (b1+c1+d1+e1) ) +
-- (summedSizes 2       (c1+d1+e1) ) +
-- (summedSizes 1          (d1+e1) ) +
--                             e1

te :: Int -> Int -> [Int]
te dim n = differences $ reverse $ fst $ foldr hplanes ([],n) [1..dim]

differences :: [Int] -> [Int]
differences [x] = [x]
differences (x:y:ys) = (x-y) : (differences (y:ys))

hplanes :: Int -> ([Int],Int) -> ([Int],Int)
hplanes d (planes,rest) = ((fst hp):planes, snd hp)
  where hp = (hyperplane d rest)

hyperplane dim n = ( (length filtered) - 1, n - (if null filtered then 0 else last filtered) )
  where filtered = filterAndStop [ summedSizes (dim-1) i | i <- [0..] ]
        filterAndStop (x:xs) | x <= n     = x : (filterAndStop xs)
                             | otherwise = []

-----------------------------------------------------------------------------------------------

data J a = Jst a | I Int -- Just a value or an Int
           -- Usually a plain value is better than an Int because succ,pred is faster than doing toEnum.fromEnum
           -- If a boundary is reached there is no other way than to transform it into an Int.

instance Show a => Show (J a)
 where show (Jst x) = show x
       show (I i) = show i

--------------------------------------------------------
-- various helper functions
--------------------------------------------------------

-- Is it a minimum value
minB (Jst x) | x == minBound = True
             | otherwise     = False
minB (I i) = i == 0

-- predecessor with catching of errors
pre :: (Enum a, Eq a, Bounded a) => J a -> J a
pre (Jst x) | x == minBound = error "predecessor of minBound in enumeration"
            | otherwise     = Jst (pred x)

pre (I i)  | i == 0    = error "predecessor of 0 in enumeration"
           | otherwise = I (i-1)

-- successor, replacing everything that goes beyond a Border with an Int
suc :: (Enum a, Eq a, Bounded a) => J a -> J a
suc (Jst x) | x == maxBound = I ((fromEnum x)+1)
            | otherwise     = Jst (succ x)

suc (I i) | i == maxBound = error "successor of maxBound in enumeration"
          | otherwise     = I (i+1)

isJst (Jst a) = True
isJst   _     = False

fJ (Jst a) = a

getInt :: Enum a => J a -> Int
getInt (Jst a) = fromEnum a
getInt (I i)   = i

-- maximum boundary of value
mb :: Bounded a => (J a) -> a
mb (Jst x) = maxBound

-- is it below boudary? then toEnum else return an Int
ib :: (Enum a, Eq a, Bounded a) => J a -> Int -> J a
ib (Jst x) boundary = Jst x
ib (I i)   boundary | i <= boundary = Jst (toEnum i)
                    | otherwise     = I i

v :: (Enum a, Enum b, Eq a, Eq b, Bounded a, Bounded b) => Int -> J a -> J b
v fz z = if (isJst z) && (toEnum fz) /= (mb z) then Jst (toEnum fz) else I fz

------------------------------------------------------------------------------------------------------------
-- The following functions build up a similar pattern like the pred-functions later, but with added support for reaching boundaries
-- (assuming that one usually enumerates beginning with 0)
-- example for reaching the boundary (True,True,True) :  enumFrom (False,False,False)
------------------------------------------------------------------------------------------------------------

succ2 :: ( Enum a, Enum b, Eq a, Eq b, Bounded a, Bounded b) =>
         Int -> Bool -> (J a,J b) -> (J a,J b)
succ2 fz s (y,z)
  | (minB y) && (minB z) = (Jst (succ minBound), Jst minBound) -- (1,0) starting with an asymmetry
  | (minB y) && (not (minB z)) = ( if ((isJst z) && (toEnum fz) == (mb z)) || not (isJst z)
                                   then I (fz+1) else Jst (toEnum (fz+1))             , Jst minBound)
  | otherwise = (pre y, suc z)


succ3 :: ( Enum a, Enum b, Enum c, Eq a, Eq b, Eq c, Bounded a, Bounded b, Bounded c) =>
         Int -> Bool -> ((J a,J b),J c) -> ((J a,J b),J c)
succ3 fz start ((x,y),z)
  | not (minB y) && (minB z) = ((x, (pre y)), suc z)
  |     (minB y) && (minB z) = (succ2 fz False (x,y), z)
  | not (minB y) && not (minB z) = ((x, (pre y)), if start then suc z else v (fz+1) z)
  | (minB y) && not (minB z) = (succ2 fz False (x, v fz z), Jst minBound)


succ4 :: ( Enum a, Enum b, Enum c, Enum d, Eq a, Eq b, Eq c, Eq d,
           Bounded a, Bounded b, Bounded c, Bounded d) =>
         Int -> Bool -> (((J a,J b),J c),J d) -> (((J a,J b),J c),J d)
succ4 fz start ((x,y),z)
  | not (minB y) && (minB z) = ((x, (pre y)), suc z)
  |     (minB y) && (minB z) = (succ3 fz False (x,y), z)
  | not (minB y) && not (minB z) = ((x, (pre y)), if start then suc z else v (fz+1) z)
  | (minB y) && not (minB z) = (succ3 fz False (x, v fz z), Jst minBound)


succ5 :: ( Enum a, Enum b, Enum c, Enum d,Enum e, Eq a, Eq b, Eq c, Eq d, Eq e,
           Bounded a, Bounded b, Bounded c, Bounded d, Bounded e) =>
         Int -> Bool -> ((((J a,J b),J c),J d),J e) -> ((((J a,J b),J c),J d),J e)
succ5 fz start ((x,y),z)
  | not (minB y) && (minB z) = ((x, (pre y)), suc z)
  |     (minB y) && (minB z) = (succ4 fz False (x,y), z)
  | not (minB y) && not (minB z) = ((x, (pre y)), if start then suc z else v (fz+1) z)
  | (minB y) && not (minB z) = (succ4 fz False (x, v fz z), Jst minBound)


succ6 :: ( Enum a, Enum b,Enum c, Enum d, Enum e, Enum f, Eq a, Eq b, Eq c, Eq d,
           Eq e, Eq f, Bounded a, Bounded b, Bounded c, Bounded d, Bounded e, Bounded f) =>
         Int -> Bool -> (((((J a,J b),J c),J d),J e),J f) -> (((((J a,J b),J c),J d),J e),J f)
succ6 fz start ((x,y),z)
  | not (minB y) && (minB z) = ((x, (pre y)), suc z)
  |     (minB y) && (minB z) = (succ5 fz False (x,y), z)
  | not (minB y) && not (minB z) = ((x, (pre y)), if start then suc z else v (fz+1) z)
  | (minB y) && not (minB z) = (succ5 fz False (x, v fz z), Jst minBound)


succ7 :: ( Enum a, Enum b, Enum c, Enum d, Enum e, Enum f, Enum g,
            Eq a, Eq b, Eq c, Eq d, Eq e, Eq f, Eq g, Bounded a, Bounded b,
            Bounded c, Bounded d, Bounded e, Bounded f, Bounded g ) =>
         Int -> Bool -> ((((((J a,J b),J c),J d),J e),J f),J g) -> ((((((J a,J b),J c),J d),J e),J f),J g)
succ7 fz start ((x,y),z)
  | not (minB y) && (minB z) = ((x, (pre y)), suc z)
  |     (minB y) && (minB z) = (succ6 fz False (x,y), z)
  | not (minB y) && not (minB z) = ((x, (pre y)), if start then suc z else v (fz+1) z)
  | (minB y) && not (minB z) = (succ6 fz False (x, v fz z), Jst minBound)


succ8 :: ( Enum a, Enum b, Enum c, Enum d, Enum e, Enum f, Enum g, Enum h,
            Eq a, Eq b, Eq c, Eq d, Eq e, Eq f, Eq g, Eq h, Bounded a, Bounded b,
            Bounded c, Bounded d, Bounded e, Bounded f, Bounded g, Bounded h ) =>
         Int -> Bool -> (((((((J a,J b),J c),J d),J e),J f),J g),J h)
                     -> (((((((J a,J b),J c),J d),J e),J f),J g),J h)
succ8 fz start ((x,y),z)
  | not (minB y) && (minB z) = ((x, (pre y)), suc z)
  |     (minB y) && (minB z) = (succ7 fz False (x,y), z)
  | not (minB y) && not (minB z) = ((x, (pre y)), if start then suc z else v (fz+1) z)
  | (minB y) && not (minB z) = (succ7 fz False (x, v fz z), Jst minBound)


succ9 :: ( Enum a, Enum b, Enum c, Enum d, Enum e, Enum f, Enum g, Enum h, Enum i,
            Eq a, Eq b, Eq c, Eq d, Eq e, Eq f, Eq g, Eq h, Eq i, Bounded a, Bounded b,
            Bounded c, Bounded d, Bounded e, Bounded f, Bounded g, Bounded h, Bounded i ) =>
          Int -> Bool -> ((((((((J a,J b),J c),J d),J e),J f),J g),J h),J i)
                      -> ((((((((J a,J b),J c),J d),J e),J f),J g),J h),J i)
succ9 fz start ((x,y),z)
  | not (minB y) && (minB z) = ((x, (pre y)), suc z)
  |     (minB y) && (minB z) = (succ8 fz False (x,y), z)
  | not (minB y) && not (minB z) = ((x, (pre y)), if start then suc z else v (fz+1) z)
  | (minB y) && not (minB z) = (succ8 fz False (x, v fz z), Jst minBound)


succ10 :: ( Enum a, Enum b, Enum c, Enum d, Enum e, Enum f, Enum g, Enum h, Enum i, Enum j,
            Eq a, Eq b, Eq c, Eq d, Eq e, Eq f, Eq g, Eq h, Eq i, Eq j, Bounded a, Bounded b,
            Bounded c, Bounded d, Bounded e, Bounded f, Bounded g, Bounded h, Bounded i, Bounded j ) =>
          Int -> Bool -> (((((((((J a,J b),J c),J d),J e),J f),J g),J h),J i),J j)
                      -> (((((((((J a,J b),J c),J d),J e),J f),J g),J h),J i),J j)
succ10 fz start ((x,y),z)
  | not (minB y) && (minB z) = ((x, (pre y)), suc z)
  |     (minB y) && (minB z) = (succ9 fz False (x,y), z)
  | not (minB y) && not (minB z) = ((x, (pre y)), if start then suc z else v (fz+1) z)
  | (minB y) && not (minB z) = (succ9 fz False (x, v fz z), Jst minBound)


succ11 :: ( Enum a, Enum b, Enum c, Enum d, Enum e, Enum f, Enum g, Enum h, Enum i, Enum j, Enum k,
            Eq a, Eq b, Eq c, Eq d, Eq e, Eq f, Eq g, Eq h, Eq i, Eq j, Eq k, Bounded a, Bounded b,
            Bounded c, Bounded d, Bounded e, Bounded f, Bounded g, Bounded h, Bounded i, Bounded j, Bounded k ) =>
          Int -> Bool -> ((((((((((J a,J b),J c),J d),J e),J f),J g),J h),J i),J j),J k)
                      -> ((((((((((J a,J b),J c),J d),J e),J f),J g),J h),J i),J j),J k)
succ11 fz start ((x,y),z)
  | not (minB y) && (minB z) = ((x, (pre y)), suc z)
  |     (minB y) && (minB z) = (succ10 fz False (x,y), z)
  | not (minB y) && not (minB z) = ((x, (pre y)), if start then suc z else v (fz+1) z)
  | (minB y) && not (minB z) = (succ10 fz False (x, v fz z), Jst minBound)


succ12 :: ( Enum a, Enum b, Enum c, Enum d, Enum e, Enum f, Enum g, Enum h, Enum i, Enum j, Enum k, Enum l,
            Eq a, Eq b, Eq c, Eq d, Eq e, Eq f, Eq g, Eq h, Eq i, Eq j, Eq k, Eq l, Bounded a, Bounded b,
            Bounded c, Bounded d, Bounded e, Bounded f, Bounded g, Bounded h, Bounded i, Bounded j, Bounded k, Bounded l ) =>
      Int -> Bool -> (((((((((((J a,J b),J c),J d),J e),J f),J g),J h),J i),J j),J k), J l)
                  -> (((((((((((J a,J b),J c),J d),J e),J f),J g),J h),J i),J j),J k), J l)
succ12 fz start ((x,y),z)
  | not (minB y) && (minB z) = ((x, (pre y)), suc z)
  |     (minB y) && (minB z) = (succ11 fz False (x,y), z)
  | not (minB y) && not (minB z) = ((x, (pre y)), if start then suc z else v (fz+1) z)
  | (minB y) && not (minB z) = (succ11 fz False (x, v fz z), Jst minBound)


succ13 :: ( Enum a, Enum b, Enum c, Enum d, Enum e, Enum f, Enum g, Enum h, Enum i, Enum j, Enum k, Enum l, Enum m,
            Eq a, Eq b, Eq c, Eq d, Eq e, Eq f, Eq g, Eq h, Eq i, Eq j, Eq k, Eq l, Eq m, Bounded a, Bounded b, Bounded c,
            Bounded d, Bounded e, Bounded f, Bounded g, Bounded h, Bounded i, Bounded j, Bounded k, Bounded l, Bounded m) =>
      Int -> Bool -> ((((((((((((J a,J b),J c),J d),J e),J f),J g),J h),J i),J j),J k),J l),J m)
                  -> ((((((((((((J a,J b),J c),J d),J e),J f),J g),J h),J i),J j),J k),J l),J m)
succ13 fz start ((x,y),z)
  | not (minB y) && (minB z) = ((x, (pre y)), suc z)
  |     (minB y) && (minB z) = (succ12 fz False (x,y), z)
  | not (minB y) && not (minB z) = ((x, (pre y)), if start then suc z else v (fz+1) z)
  | (minB y) && not (minB z) = (succ12 fz False (x, v fz z), Jst minBound)


succ14 :: ( Enum a, Enum b, Enum c, Enum d, Enum e, Enum f, Enum g, Enum h, Enum i, Enum j, Enum k, Enum l, Enum m, Enum n,
            Eq a, Eq b, Eq c, Eq d, Eq e, Eq f, Eq g, Eq h, Eq i, Eq j, Eq k, Eq l, Eq m, Eq n,
            Bounded a, Bounded b, Bounded c, Bounded d, Bounded e, Bounded f, Bounded g, Bounded h, Bounded i, 
            Bounded j, Bounded k, Bounded l, Bounded m, Bounded n) =>
      Int -> Bool -> (((((((((((((J a,J b),J c),J d),J e),J f),J g),J h),J i),J j),J k),J l),J m),J n)
                  -> (((((((((((((J a,J b),J c),J d),J e),J f),J g),J h),J i),J j),J k),J l),J m),J n)
succ14 fz start ((x,y),z)
  | not (minB y) && (minB z) = ((x, (pre y)), suc z)
  |     (minB y) && (minB z) = (succ13 fz False (x,y), z)
  | not (minB y) && not (minB z) = ((x, (pre y)), if start then suc z else v (fz+1) z)
  | (minB y) && not (minB z) = (succ13 fz False (x, v fz z), Jst minBound)


succ15 :: ( Enum a, Enum b, Enum c, Enum d, Enum e, Enum f, Enum g, Enum h, Enum i, Enum j, Enum k, Enum l, 
            Enum m, Enum n, Enum o,
            Eq a, Eq b, Eq c, Eq d, Eq e, Eq f, Eq g, Eq h, Eq i, Eq j, Eq k, Eq l, Eq m, Eq n, Eq o,
            Bounded a, Bounded b, Bounded c, Bounded d, Bounded e, Bounded f, Bounded g, Bounded h, Bounded i, 
            Bounded j, Bounded k, Bounded l, Bounded m, Bounded n, Bounded o) =>
      Int -> Bool -> ((((((((((((((J a,J b),J c),J d),J e),J f),J g),J h),J i),J j),J k),J l),J m),J n),J o)
                  -> ((((((((((((((J a,J b),J c),J d),J e),J f),J g),J h),J i),J j),J k),J l),J m),J n),J o)
succ15 fz start ((x,y),z)
  | not (minB y) && (minB z) = ((x, (pre y)), suc z)
  |     (minB y) && (minB z) = (succ14 fz False (x,y), z)
  | not (minB y) && not (minB z) = ((x, (pre y)), if start then suc z else v (fz+1) z)
  | (minB y) && not (minB z) = (succ14 fz False (x, v fz z), Jst minBound)


to2Tuple  (Jst a, Jst b) =
          (a,b)
to3Tuple  ((Jst a, Jst b), Jst c) =
          (a,b,c)
to4Tuple  (((Jst a,Jst b),Jst c),Jst d) =
          (a,b,c,d)
to5Tuple  ((((Jst a,Jst b),Jst c),Jst d),Jst e) =
          (a,b,c,d,e)
to6Tuple  (((((Jst a,Jst b),Jst c),Jst d),Jst e),Jst f) =
          (a,b,c,d,e,f)
to7Tuple  ((((((Jst a,Jst b),Jst c),Jst d),Jst e),Jst f),Jst g) =
          (a,b,c,d,e,f,g)
to8Tuple  (((((((Jst a,Jst b),Jst c),Jst d),Jst e),Jst f),Jst g),Jst h) =
          (a,b,c,d,e,f,g,h)
to9Tuple  ((((((((Jst a,Jst b),Jst c),Jst d),Jst e),Jst f),Jst g),Jst h),Jst i) =
          (a,b,c,d,e,f,g,h,i)
to10Tuple (((((((((Jst a,Jst b),Jst c),Jst d),Jst e),Jst f),Jst g),Jst h),Jst i),Jst j) =
          (a,b,c,d,e,f,g,h,i,j)
to11Tuple ((((((((((Jst a,Jst b),Jst c),Jst d),Jst e),Jst f),Jst g),Jst h),Jst i),Jst j),Jst k) =
          (a,b,c,d,e,f,g,h,i,j,k)
to12Tuple (((((((((((Jst a,Jst b),Jst c),Jst d),Jst e),Jst f),Jst g),Jst h),Jst i),Jst j),Jst k),Jst l) =
          (a,b,c,d,e,f,g,h,i,j,k,l)
to13Tuple ((((((((((((Jst a,Jst b),Jst c),Jst d),Jst e),Jst f),Jst g),Jst h),Jst i),Jst j),Jst k),Jst l),Jst m) =
          (a,b,c,d,e,f,g,h,i,j,k,l,m)
to14Tuple (((((((((((((Jst a,Jst b),Jst c),Jst d),Jst e),Jst f),Jst g),Jst h),Jst i),Jst j),Jst k),Jst l),Jst m),Jst n) =
          (a,b,c,d,e,f,g,h,i,j,k,l,m,n)
to15Tuple
  ((((((((((((((Jst a,Jst b),Jst c),Jst d),Jst e),Jst f),Jst g),Jst h),Jst i),Jst j),Jst k),Jst l),Jst m),Jst n),Jst o) =
          (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o)


from2Tuple (a,b) = (Jst a, Jst b)
from3Tuple (a,b,c) = ((Jst a, Jst b), Jst c)
from4Tuple (a,b,c,d) = (((Jst a,Jst b),Jst c),Jst d)
from5Tuple (a,b,c,d,e) = ((((Jst a,Jst b),Jst c),Jst d),Jst e)
from6Tuple (a,b,c,d,e,f) = (((((Jst a,Jst b),Jst c),Jst d),Jst e),Jst f)
from7Tuple (a,b,c,d,e,f,g) = ((((((Jst a,Jst b),Jst c),Jst d),Jst e),Jst f),Jst g)
from8Tuple (a,b,c,d,e,f,g,h) = (((((((Jst a,Jst b),Jst c),Jst d),Jst e),Jst f),Jst g),Jst h)
from9Tuple (a,b,c,d,e,f,g,h,i) = ((((((((Jst a,Jst b),Jst c),Jst d),Jst e),Jst f),Jst g),Jst h),Jst i)
from10Tuple (a,b,c,d,e,f,g,h,i,j) = (((((((((Jst a,Jst b),Jst c),Jst d),Jst e),Jst f),Jst g),Jst h),Jst i),Jst j)
from11Tuple (a,b,c,d,e,f,g,h,i,j,k) = ((((((((((Jst a,Jst b),Jst c),Jst d),Jst e),Jst f),Jst g),Jst h),Jst i),Jst j),Jst k)
from12Tuple (a,b,c,d,e,f,g,h,i,j,k,l) =
            (((((((((((Jst a,Jst b),Jst c),Jst d),Jst e),Jst f),Jst g),Jst h),Jst i),Jst j),Jst k),Jst l)
from13Tuple (a,b,c,d,e,f,g,h,i,j,k,l,m) =
            ((((((((((((Jst a,Jst b),Jst c),Jst d),Jst e),Jst f),Jst g),Jst h),Jst i),Jst j),Jst k),Jst l),Jst m)
from14Tuple (a,b,c,d,e,f,g,h,i,j,k,l,m,n) =
            (((((((((((((Jst a,Jst b),Jst c),Jst d),Jst e),Jst f),Jst g),Jst h),Jst i),Jst j),Jst k),Jst l),Jst m),Jst n)
from15Tuple (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o) =
  ((((((((((((((Jst a,Jst b),Jst c),Jst d),Jst e),Jst f),Jst g),Jst h),Jst i),Jst j),Jst k),Jst l),Jst m),Jst n),Jst o)

--------------------------------------------------------------------------------
instance (Enum a, Enum b, Eq a, Eq b, Bounded a, Bounded b) => Enum (a, b) where 
--------------------------------------------------------------------------------
-- Enum instance for 2-tuples

  succ (x,y) | (x,y) == maxBound
                = error "Enum.succ{(a,b)}: tried to take `succ' of maxBound"
             | otherwise = to2Tuple $
                           findNext (fromEnum (mb (Jst x)), fromEnum (mb (Jst y))) $
                             succ2 (fromEnum y) True (from2Tuple (x,y))
   where
    findNext :: ( Enum a, Enum b, Eq a, Eq b, Bounded a, Bounded b)
                => (Int,Int) -> (J a, J b) -> (J a, J b)
    findNext (bx,by) (x,y) = if (not (isJst x)) || (not (isJst y))
                             then findNext (bx,by) $ toBounded (bx,by) $ succ2 (getInt y) True (x,y)
                             else (x,y)
    toBounded (bx,by) (jx,jy) = ( ib jx bx, ib jy by )

  pred (x,y) | (x,y) == (minBound,minBound) = error "Enum.pred{(a,b)}: tried to take `pred' of minBound"
             |    y  ==           minBound  = (minBound, toEnum (fx-1))
             | otherwise                    = (succ x  , pred y)
    where
      fx = fromEnum x

  toEnum n = (\[a,b] -> (toEnum a, toEnum b)) (te 2 n)

  fromEnum (a,b) = fe [fromEnum a, fromEnum b]

  enumFrom t2 | t2 == (maxBound,maxBound) = [(maxBound,maxBound)]
              | otherwise                 = t2 : (enumFrom (succ t2))

  enumFromTo t0 t1 = take l $ enumFrom t0
    where l = (fromEnum t1) - (fromEnum t0) + 1

------------------------------------------------------------------
instance (Enum a, Enum b, Enum c,
          Eq a, Eq b, Eq c,
          Bounded a, Bounded b, Bounded c) => Enum (a, b, c) where
------------------------------------------------------------------
-- 3
  succ (x,y,z) | (x,y,z) == maxBound
                 = error "Enum.succ{(x,y,z)}: tried to take `succ' of maxBound"
               | otherwise = to3Tuple $
                             findNext (fromEnum (mb (Jst x)), fromEnum (mb (Jst y)), fromEnum (mb (Jst z))) $
                             succ3 (fromEnum z) True (from3Tuple (x,y,z))
   where
    findNext :: ( Enum a, Enum b, Enum c, Eq a, Eq b, Eq c, Bounded a, Bounded b, Bounded c)
                => (Int,Int,Int) -> ((J a, J b), J c) -> ((J a, J b), J c)
    findNext (bx,by,bz) ((x,y),z) = if (not (isJst x)) || (not (isJst y)) || (not (isJst z))
                               then findNext (bx,by,bz) $ toBounded (bx,by,bz) $ succ3 (getInt z) True ((x,y),z)
                               else ((x,y),z)
    toBounded (bx,by,bz) ((jx,jy),jz) = ( ( ib jx bx, ib jy by ), ib jz bz )


  pred (x,y,z) = if z == minBound then
                   if y == minBound then
                     if x == minBound then error "Enum.pred{(x,y,z)}: tried to take `pred' of minBound"
                                      else (minBound, minBound, toEnum (fx-1)) -- (fy,fz) == (0,0)
                                    else   (succ x  , minBound, toEnum (fy-1)) --     fz  ==    0
                                  else     (x       , succ y  , pred z       )
    where
      fx = fromEnum x
      fy = fromEnum y

  toEnum n = (\[a,b,c] -> (toEnum a, toEnum b, toEnum c)) (te 3 n)

  fromEnum (a,b,c) = fe [fromEnum a, fromEnum b, fromEnum c]

  enumFrom t3 | t3 == (maxBound,maxBound,maxBound) = [(maxBound,maxBound,maxBound)]
              | otherwise                          = t3 : (enumFrom (succ t3))

  enumFromTo t0 t1 = take l $ enumFrom t0
    where l = (fromEnum t1) - (fromEnum t0) + 1

---------------------------------------------------------------------------------
instance (Enum a, Enum b, Enum c, Enum d,
          Eq a, Eq b, Eq c, Eq d,
          Bounded a, Bounded b, Bounded c, Bounded d) => Enum (a, b, c, d) where
--------------------------------------------------------------------------------
-- 4
  succ (a,b,c,d) | (a,b,c,d) == maxBound
                   = error "Enum.succ{(a,b,c,d)}: tried to take `succ' of maxBound"
                 | otherwise = to4Tuple $
                               findNext (fromEnum (mb (Jst a)), fromEnum (mb (Jst b)),
                                         fromEnum (mb (Jst c)), fromEnum (mb (Jst c))) $
                               succ4 (fromEnum d) True (from4Tuple (a,b,c,d))
   where
    findNext :: ( Enum a, Enum b, Enum c, Enum d, Eq a, Eq b, Eq c, Eq d, Bounded a, Bounded b, Bounded c, Bounded d)
                => (Int,Int,Int,Int) -> (((J a, J b), J c), J d) -> (((J a, J b), J c), J d)
    findNext (ba,bb,bc,bd) (((a,b),c),d) = if (not (isJst a)) || (not (isJst b)) || (not (isJst c)) || (not (isJst d))
                               then findNext (ba,bb,bc,bd) $ toBounded (ba,bb,bc,bd) $ succ4 (getInt d) True (((a,b),c),d)
                               else (((a,b),c),d)
    toBounded (ba,bb,bc,bd) (((ja,jb),jc),jd) = (((ib ja ba,ib jb bb),ib jc bc), ib jd bd)


  pred (a,b,c,d) =
      if d==minBound then
        if c==minBound then
          if fb==minBound then
            if fa==minBound then error "Enum.pred{(a,b,c,d)}: tried to take `pred' of minBound"
                            else (minBound, minBound, minBound, toEnum (fa-1)) -- (b,c,d) == (0,0,0)
                          else   (succ a  , minBound, minBound, toEnum (fb-1)) --   (c,d) ==   (0,0)
                        else     (a       , succ b  , minBound, toEnum (fc-1)) --       d ==      0
                      else       (a       , b       , succ c  , pred d       )
    where
      fa = fromEnum a
      fb = fromEnum b
      fc = fromEnum c

  toEnum n = (\[a,b,c,d] -> (toEnum a, toEnum b, toEnum c, toEnum d)) (te 4 n)

  fromEnum (a,b,c,d) = fe [fromEnum a, fromEnum b, fromEnum c, fromEnum d]

  enumFrom t4 | t4 == (maxBound,maxBound,maxBound,maxBound) = [(maxBound,maxBound,maxBound,maxBound)]
              | otherwise                                   = t4 : (enumFrom (succ t4))

  enumFromTo t0 t1 = take l $ enumFrom t0
    where l = (fromEnum t1) - (fromEnum t0) + 1

--------------------------------------------------------------------------------------------------------
instance (Enum a, Enum b, Enum c, Enum d, Enum e,
          Eq a, Eq b, Eq c, Eq d, Eq e,
          Bounded a, Bounded b, Bounded c, Bounded d, Bounded e) => Enum (a, b, c, d, e) where
--------------------------------------------------------------------------------------------------------
-- 5
  succ (a,b,c,d,e) | (a,b,c,d,e) == maxBound
                     = error "Enum.succ{(a,b,c,d,e)}: tried to take `succ' of maxBound"
                   | otherwise = to5Tuple $
                               findNext (fromEnum (mb (Jst a)), fromEnum (mb (Jst b)), fromEnum (mb (Jst c)),
                                         fromEnum (mb (Jst d)), fromEnum (mb (Jst e))) $
                               succ5 (fromEnum e) True (from5Tuple (a,b,c,d,e))
   where
    findNext :: ( Enum a, Enum b, Enum c, Enum d, Enum e,
                  Eq a, Eq b, Eq c, Eq d, Eq e, Bounded a, Bounded b, Bounded c, Bounded d, Bounded e)
                => (Int,Int,Int,Int,Int) -> ((((J a,J b),J c),J d),J e) -> ((((J a,J b),J c),J d),J e)
    findNext (ba,bb,bc,bd,be) ((((a,b),c),d),e) =
       if (not (isJst a)) || (not (isJst b)) || (not (isJst c)) || (not (isJst d)) || (not (isJst e))
       then findNext (ba,bb,bc,bd,be) $ toBounded (ba,bb,bc,bd,be) $ succ5 (getInt e) True ((((a,b),c),d),e)
       else ((((a,b),c),d),e)
    toBounded (ba,bb,bc,bd,be) ((((ja,jb),jc),jd),je) = ((((ib ja ba,ib jb bb),ib jc bc), ib jd bd), ib je be)


  pred (a,b,c,d,e) =
       if e == minBound then
         if d == minBound then
           if c == minBound then
             if b == minBound then
               if a == minBound then error "Enum.pred{(a,b,c,d,e)}: tried to take `pred' of minBound"
                                else (minBound, minBound, minBound, minBound, toEnum (fa-1))
                              else   (succ a  , minBound, minBound, minBound, toEnum (fb-1))
                            else     (a       , succ b  , minBound, minBound, toEnum (fc-1))
                          else       (a       , b       , succ c  , minBound, toEnum (fd-1))
                        else         (a       , b       , c       , succ d  , pred e)
    where

      fa = fromEnum a
      fb = fromEnum b
      fc = fromEnum c
      fd = fromEnum d

  toEnum n = (\[a,b,c,d,e] -> (toEnum a, toEnum b, toEnum c, toEnum d, toEnum e)) (te 5 n)

  fromEnum (a,b,c,d,e) = fe [fromEnum a, fromEnum b, fromEnum c, fromEnum d, fromEnum e]

  enumFrom t5 | t5 == (maxBound,maxBound,maxBound,maxBound,maxBound)
                   = [(maxBound,maxBound,maxBound,maxBound,maxBound)]
              | otherwise  = t5 : (enumFrom (succ t5))

  enumFromTo t0 t1 = take l $ enumFrom t0
    where l = (fromEnum t1) - (fromEnum t0) + 1

------------------------------------------------------------------------------------------------------------
instance (Enum a, Enum b, Enum c, Enum d, Enum e, Enum f,
          Eq a, Eq b, Eq c, Eq d, Eq e, Eq f,
          Bounded a, Bounded b, Bounded c, Bounded d, Bounded e, Bounded f) => Enum (a, b, c, d, e, f) where 
------------------------------------------------------------------------------------------------------------
-- 6
  succ (a,b,c,d,e,f) | (a,b,c,d,e,f) == maxBound
                       = error "Enum.succ{(a,b,c,d,e,f)}: tried to take `succ' of maxBound"
                     | otherwise = to6Tuple $
                               findNext (fromEnum (mb (Jst a)), fromEnum (mb (Jst b)), fromEnum (mb (Jst c)),
                                         fromEnum (mb (Jst d)), fromEnum (mb (Jst e)), fromEnum (mb (Jst f))) $
                               succ6 (fromEnum f) True (from6Tuple (a,b,c,d,e,f))
   where
    findNext :: ( Enum a, Enum b, Enum c, Enum d, Enum e, Enum f,
                  Eq a, Eq b, Eq c, Eq d, Eq e, Eq f, 
                  Bounded a, Bounded b, Bounded c, Bounded d, Bounded e, Bounded f)
                => (Int,Int,Int,Int,Int,Int) -> (((((J a,J b),J c),J d),J e),J f) -> (((((J a,J b),J c),J d),J e),J f)
    findNext (ba,bb,bc,bd,be,bf) (((((a,b),c),d),e),f) =
       if (not (isJst a)) || (not (isJst b)) || (not (isJst c)) ||
          (not (isJst d)) || (not (isJst e)) || (not (isJst f))
       then findNext (ba,bb,bc,bd,be,bf) $ toBounded (ba,bb,bc,bd,be,bf) $ succ6 (getInt f) True (((((a,b),c),d),e),f)
       else (((((a,b),c),d),e),f)
    toBounded (ba,bb,bc,bd,be,bf) (((((ja,jb),jc),jd),je),jf) =
       (((((ib ja ba,ib jb bb),ib jc bc), ib jd bd), ib je be), ib jf bf)


  pred (a,b,c,d,e,f) =
       if f == minBound then
         if e == minBound then
           if d == minBound then
             if c == minBound then
               if b == minBound then
                 if a == minBound then error "Enum.pred{(a,b,c,d,e,f)}: tried to take `pred' of minBound"
                                  else (minBound, minBound, minBound, minBound, minBound, toEnum (fa-1))
                                else   (succ a  , minBound, minBound, minBound, minBound, toEnum (fb-1))
                              else     (a       , succ b  , minBound, minBound, minBound, toEnum (fc-1))
                            else       (a       , b       , succ c  , minBound, minBound, toEnum (fd-1))
                          else         (a       , b       , c       , succ d  , minBound, toEnum (fe-1))
                        else           (a       , b       , c       , d       , succ e  , pred f)
    where
      fa = fromEnum a
      fb = fromEnum b
      fc = fromEnum c

      fd = fromEnum d
      fe = fromEnum e

  toEnum n = (\[a,b,c,d,e,f] -> (toEnum a, toEnum b, toEnum c, toEnum d, toEnum e, toEnum f)) (te 6 n)

  fromEnum (a,b,c,d,e,f) = fe [fromEnum a, fromEnum b, fromEnum c,
                               fromEnum d, fromEnum e, fromEnum f]

  enumFrom t6 | t6 == (maxBound,maxBound,maxBound,maxBound,maxBound,maxBound) =
                     [(maxBound,maxBound,maxBound,maxBound,maxBound,maxBound)]
              | otherwise                                                     = t6 : (enumFrom (succ t6))

  enumFromTo t0 t1 = take l $ enumFrom t0
    where l = (fromEnum t1) - (fromEnum t0) + 1

--------------------------------------------------------------------------------------------------------------------
instance (Enum a, Enum b, Enum c, Enum d, Enum e, Enum f, Enum g,
          Eq a, Eq b, Eq c, Eq d, Eq e, Eq f, Eq g,
          Bounded a, Bounded b, Bounded c, Bounded d, Bounded e, Bounded f, Bounded g) => Enum (a,b,c,d,e,f,g) where
--------------------------------------------------------------------------------------------------------------------
-- 7
  succ (a,b,c,d,e,f,g) | (a,b,c,d,e,f,g) == maxBound
                         = error "Enum.succ{(a,b,c,d,e,f,g)}: tried to take `succ' of maxBound"
                       | otherwise = to7Tuple $
                            findNext (fromEnum (mb (Jst a)), fromEnum (mb (Jst b)), fromEnum (mb (Jst c)),
                                      fromEnum (mb (Jst d)), fromEnum (mb (Jst d)), fromEnum (mb (Jst e)),
                                      fromEnum (mb (Jst f))) $
                           succ7 (fromEnum g) True (from7Tuple (a,b,c,d,e,f,g))
   where
    findNext :: ( Enum a, Enum b, Enum c, Enum d, Enum e, Enum f,Enum g,
                  Eq a, Eq b, Eq c, Eq d, Eq e, Eq f, Eq g,
                  Bounded a, Bounded b, Bounded c, Bounded d, Bounded e, Bounded f, Bounded g)
                => (Int,Int,Int,Int,Int,Int,Int) -> ((((((J a,J b),J c),J d),J e),J f),J g) ->
                                                    ((((((J a,J b),J c),J d),J e),J f),J g)
    findNext (ba,bb,bc,bd,be,bf,bg) ((((((a,b),c),d),e),f),g) =
       if (not (isJst a)) || (not (isJst b)) || (not (isJst c)) ||
          (not (isJst d)) || (not (isJst e)) || (not (isJst f)) || (not (isJst g))
       then findNext (ba,bb,bc,bd,be,bf,bg) $
                     toBounded (ba,bb,bc,bd,be,bf,bg) $ succ7 (getInt g) True ((((((a,b),c),d),e),f),g)
       else ((((((a,b),c),d),e),f),g)
    toBounded (ba,bb,bc,bd,be,bf,bg) ((((((ja,jb),jc),jd),je),jf),jg) =
       ((((((ib ja ba,ib jb bb),ib jc bc), ib jd bd), ib je be), ib jf bf), ib jg bg)


  pred (a,b,c,d,e,f,g) =
    if g == minBound then
      if f == minBound then
        if e == minBound then
          if d == minBound then
            if c == minBound then
              if b == minBound then
                if a == minBound then error "Enum.pred{(a,b,c,d,e,f,g)}: tried to take `pred' of minBound"
                                 else (minBound, minBound, minBound, minBound, minBound, minBound, toEnum (fa-1))
                               else   (succ a  , minBound, minBound, minBound, minBound, minBound, toEnum (fb-1))
                             else     (a       , succ b  , minBound, minBound, minBound, minBound, toEnum (fc-1))
                           else       (a       , b       , succ c  , minBound, minBound, minBound, toEnum (fd-1))
                         else         (a       , b       , c       , succ d  , minBound, minBound, toEnum (fe-1))
                       else           (a       , b       , c       , d       , succ e  , minBound, toEnum (ff-1))
                     else             (a       , b       , c       , d       , e       , succ f  , pred g)

    where
      fa = fromEnum a
      fb = fromEnum b
      fc = fromEnum c
      fd = fromEnum d
      fe = fromEnum e
      ff = fromEnum f

  enumFrom t7 | t7 == (maxBound,maxBound,maxBound,maxBound,maxBound,maxBound,maxBound) =
                     [(maxBound,maxBound,maxBound,maxBound,maxBound,maxBound,maxBound)]
              | otherwise = t7 : (enumFrom (succ t7))

  enumFromTo t0 t1 = take l $ enumFrom t0
    where l = (fromEnum t1) - (fromEnum t0) + 1

  toEnum n = (\[a,b,c,d,e,f,g] ->
              (toEnum a, toEnum b, toEnum c, toEnum d, toEnum e, toEnum f, toEnum g)) (te 7 n)

  fromEnum (a,b,c,d,e,f,g) = fe [fromEnum a, fromEnum b, fromEnum c,
                                 fromEnum d, fromEnum e, fromEnum f, fromEnum g]

-------------------------------------------------------------------------------------
instance (Enum a, Enum b, Enum c, Enum d, Enum e, Enum f, Enum g, Enum h,
          Eq a, Eq b, Eq c, Eq d, Eq e, Eq f, Eq g, Eq h,
          Bounded a, Bounded b, Bounded c, Bounded d,
          Bounded e, Bounded f, Bounded g, Bounded h) => Enum (a,b,c,d,e,f,g,h) where
-------------------------------------------------------------------------------------
-- 8
  succ (a,b,c,d,e,f,g,h) | (a,b,c,d,e,f,g,h) == maxBound
                           = error "Enum.succ{(a,b,c,d,e,f,g,h)}: tried to take `succ' of maxBound"
                         | otherwise = to8Tuple $
                            findNext (fromEnum (mb (Jst a)), fromEnum (mb (Jst b)), fromEnum (mb (Jst c)),
                                      fromEnum (mb (Jst d)), fromEnum (mb (Jst e)), fromEnum (mb (Jst f)),
                                      fromEnum (mb (Jst g)), fromEnum (mb (Jst h)) ) $
                           succ8 (fromEnum h) True (from8Tuple (a,b,c,d,e,f,g,h))
   where
    findNext :: ( Enum a, Enum b, Enum c, Enum d, Enum e, Enum f, Enum g, Enum h,
                  Eq a, Eq b, Eq c, Eq d, Eq e, Eq f, Eq g, Eq h,
                  Bounded a, Bounded b, Bounded c, Bounded d, Bounded e, Bounded f, Bounded g, Bounded h)
                => (Int,Int,Int,Int,Int,Int,Int,Int) -> (((((((J a,J b),J c),J d),J e),J f),J g),J h) ->
                                                        (((((((J a,J b),J c),J d),J e),J f),J g),J h)
    findNext (ba,bb,bc,bd,be,bf,bg,bh) (((((((a,b),c),d),e),f),g),h) =
       if (not (isJst a)) || (not (isJst b)) || (not (isJst c)) || (not (isJst d)) ||
          (not (isJst e)) || (not (isJst f)) || (not (isJst g)) || (not (isJst h))
       then findNext (ba,bb,bc,bd,be,bf,bg,bh) $
                     toBounded (ba,bb,bc,bd,be,bf,bg,bh) $ succ8 (getInt h) True (((((((a,b),c),d),e),f),g),h)
       else (((((((a,b),c),d),e),f),g),h)
    toBounded (ba,bb,bc,bd,be,bf,bg,bh) (((((((ja,jb),jc),jd),je),jf),jg),jh) =
       (((((((ib ja ba,ib jb bb),ib jc bc), ib jd bd), ib je be), ib jf bf), ib jg bg), ib jh bh)


  pred (a,b,c,d,e,f,g,h) =
   if f == minBound then
    if g == minBound then
     if f == minBound then
      if e == minBound then
       if d == minBound then
        if c == minBound then
         if b == minBound then
          if a == minBound then error "Enum.pred{(a,b,c,d,e,f,g,h)}: tried to take `pred' of minBound"
                           else (minBound, minBound, minBound, minBound, minBound, minBound, minBound, toEnum (fa-1))
                          else  (succ a  , minBound, minBound, minBound, minBound, minBound, minBound, toEnum (fb-1))
                         else   ( a      , succ b  , minBound, minBound, minBound, minBound, minBound, toEnum (fc-1))
                        else    ( a      , b       , succ c  , minBound, minBound, minBound, minBound, toEnum (fd-1))
                       else     ( a      , b       , c       , succ d  , minBound, minBound, minBound, toEnum (fe-1))
                      else      ( a      , b       , c       , d       , succ e  , minBound, minBound, toEnum (ff-1))
                     else       ( a      , b       , c       , d       , e       , succ f  , minBound, toEnum (fg-1))
                    else        ( a      , b       , c       , d       , e       , f       , succ g  , pred h)
    where
      fa = fromEnum a
      fb = fromEnum b
      fc = fromEnum c
      fd = fromEnum d
      fe = fromEnum e
      ff = fromEnum f
      fg = fromEnum g
      fh = fromEnum h

  enumFrom t8 | t8 == (maxBound,maxBound,maxBound,maxBound,maxBound,maxBound,maxBound,maxBound) =
                     [(maxBound,maxBound,maxBound,maxBound,maxBound,maxBound,maxBound,maxBound)]
              | otherwise = t8 : (enumFrom (succ t8))

  enumFromTo t0 t1 = take l $ enumFrom t0
    where l = (fromEnum t1) - (fromEnum t0) + 1

  toEnum n = (\[a,b,c,d,e,f,g,h] ->
              (toEnum a, toEnum b, toEnum c, toEnum d,
               toEnum e, toEnum f, toEnum g, toEnum h)) (te 8 n)

  fromEnum (a,b,c,d,e,f,g,h) = fe [fromEnum a, fromEnum b, fromEnum c, fromEnum d,
                                   fromEnum e, fromEnum f, fromEnum g, fromEnum h]

---------------------------------------------------------------------------------------------------
instance (Enum a,Enum b,Enum c,Enum d,Enum e,Enum f,Enum g,Enum h,Enum i,
          Eq a, Eq b, Eq c, Eq d, Eq e, Eq f, Eq g, Eq h, Eq i,
          Bounded a, Bounded b, Bounded c, Bounded d,
          Bounded e, Bounded f, Bounded g, Bounded h, Bounded i)  => Enum (a,b,c,d,e,f,g,h,i) where
---------------------------------------------------------------------------------------------------
-- 9
  succ (a,b,c,d,e,f,g,h,i) | (a,b,c,d,e,f,g,h,i) == maxBound
                             = error "Enum.succ{(a,b,c,d,e,f,g,h,i)}: tried to take `succ' of maxBound"
                           | otherwise = to9Tuple $
                            findNext (fromEnum (mb (Jst a)), fromEnum (mb (Jst b)), fromEnum (mb (Jst c)),
                                      fromEnum (mb (Jst d)), fromEnum (mb (Jst e)), fromEnum (mb (Jst f)),
                                      fromEnum (mb (Jst g)), fromEnum (mb (Jst h)), fromEnum (mb (Jst i))) $
                           succ9 (fromEnum i) True (from9Tuple (a,b,c,d,e,f,g,h,i))
   where
    findNext :: ( Enum a, Enum b, Enum c, Enum d, Enum e, Enum f, Enum g, Enum h, Enum i,
                  Eq a, Eq b, Eq c, Eq d, Eq e, Eq f, Eq g, Eq h, Eq i,
                  Bounded a, Bounded b, Bounded c, Bounded d, Bounded e, Bounded f, Bounded g, Bounded h, Bounded i)
                => (Int,Int,Int,Int,Int,Int,Int,Int,Int) ->
                   ((((((((J a,J b),J c),J d),J e),J f),J g),J h),J i) ->
                   ((((((((J a,J b),J c),J d),J e),J f),J g),J h),J i)
    findNext (ba,bb,bc,bd,be,bf,bg,bh,bi) ((((((((a,b),c),d),e),f),g),h),i) =
       if (not (isJst a)) || (not (isJst b)) || (not (isJst c)) || (not (isJst d)) ||
          (not (isJst e)) || (not (isJst f)) || (not (isJst g)) || (not (isJst h)) || (not (isJst i))
       then findNext (ba,bb,bc,bd,be,bf,bg,bh,bi) $
                     toBounded (ba,bb,bc,bd,be,bf,bg,bh,bi) $ succ9 (getInt i) True ((((((((a,b),c),d),e),f),g),h),i)
       else ((((((((a,b),c),d),e),f),g),h),i)
    toBounded (ba,bb,bc,bd,be,bf,bg,bh,bi) ((((((((ja,jb),jc),jd),je),jf),jg),jh),ji) =
       ((((((((ib ja ba,ib jb bb),ib jc bc), ib jd bd), ib je be), ib jf bf), ib jg bg), ib jh bh), ib ji bi)


  pred (a,b,c,d,e,f,g,h,i) =
    if i==minBound then
    if h==minBound then
    if g==minBound then
    if f==minBound then
    if e==minBound then
    if d==minBound then
    if c==minBound then
    if b==minBound then
    if a==minBound then error "Enum.pred{(a,b,c,d,e,f,g,h,i)}: tried to take `pred' of minBound"
    else ( minBound, minBound, minBound, minBound, minBound, minBound, minBound, minBound, toEnum (fa-1))
    else ( succ a  , minBound, minBound, minBound, minBound, minBound, minBound, minBound, toEnum (fb-1))
    else ( a       , succ b  , minBound, minBound, minBound, minBound, minBound, minBound, toEnum (fc-1))
    else ( a       , b       , succ c  , minBound, minBound, minBound, minBound, minBound, toEnum (fd-1))
    else ( a       , b       , c       , succ d  , minBound, minBound, minBound, minBound, toEnum (fe-1))
    else ( a       , b       , c       , d       , succ e  , minBound, minBound, minBound, toEnum (ff-1))
    else ( a       , b       , c       , d       , e       , succ f  , minBound, minBound, toEnum (fg-1))
    else ( a       , b       , c       , d       , e       , f       , succ g  , minBound, toEnum (fh-1))
    else ( a       , b       , c       , d       , e       , f       ,      g  ,  succ h , pred i)
    where
      fa = fromEnum a
      fb = fromEnum b
      fc = fromEnum c
      fd = fromEnum d
      fe = fromEnum e
      ff = fromEnum f
      fg = fromEnum g
      fh = fromEnum h

  enumFrom t9 | t9 == (maxBound,maxBound,maxBound,maxBound,maxBound,maxBound,maxBound,maxBound,maxBound) =
                     [(maxBound,maxBound,maxBound,maxBound,maxBound,maxBound,maxBound,maxBound,maxBound)]
              | otherwise = t9 : (enumFrom (succ t9))

  enumFromTo t0 t1 = take l $ enumFrom t0
    where l = (fromEnum t1) - (fromEnum t0) + 1

  toEnum n = (\[a,b,c,d,e,f,g,h,i] ->
              (toEnum a, toEnum b, toEnum c, toEnum d,
               toEnum e, toEnum f, toEnum g, toEnum h, toEnum i)) (te 9 n)

  fromEnum (a,b,c,d,e,f,g,h,i) = fe [fromEnum a, fromEnum b, fromEnum c, fromEnum d,
                                     fromEnum e, fromEnum f, fromEnum g, fromEnum h, fromEnum i]

----------------------------------------------------------------------------------------------------
instance (Enum a,Enum b,Enum c,Enum d,Enum e,Enum f,Enum g,Enum h,Enum i,Enum j,
          Eq a, Eq b, Eq c, Eq d, Eq e, Eq f, Eq g, Eq h, Eq i, Eq j,
          Bounded a, Bounded b, Bounded c, Bounded d, Bounded e, 
          Bounded f, Bounded g, Bounded h, Bounded i, Bounded j) => Enum (a,b,c,d,e,f,g,h,i,j) where
----------------------------------------------------------------------------------------------------
-- 10
  succ (a,b,c,d,e,f,g,h,i,j)
     | (a,b,c,d,e,f,g,h,i,j) == maxBound
        = error "Enum.succ{(a,b,c,d,e,f,g,h,i,j)}: tried to take `succ' of maxBound"
     | otherwise = to10Tuple $
                      findNext (fromEnum (mb (Jst a)), fromEnum (mb (Jst b)), fromEnum (mb (Jst c)),
                                fromEnum (mb (Jst d)), fromEnum (mb (Jst e)), fromEnum (mb (Jst f)),
                                fromEnum (mb (Jst g)), fromEnum (mb (Jst h)), fromEnum (mb (Jst i)),
                                fromEnum (mb (Jst j)) ) $
                      succ10 (fromEnum j) True (from10Tuple (a,b,c,d,e,f,g,h,i,j))
   where
    findNext :: ( Enum a, Enum b, Enum c, Enum d, Enum e, Enum f, Enum g, Enum h, Enum i, Enum j,
                  Eq a, Eq b, Eq c, Eq d, Eq e, Eq f, Eq g, Eq h, Eq i, Eq j,
                  Bounded a, Bounded b, Bounded c, Bounded d, Bounded e, Bounded f, Bounded g,
                  Bounded h, Bounded i, Bounded j)
                => (Int,Int,Int,Int,Int,Int,Int,Int,Int,Int) ->
                   (((((((((J a,J b),J c),J d),J e),J f),J g),J h),J i),J j) ->
                   (((((((((J a,J b),J c),J d),J e),J f),J g),J h),J i),J j)
    findNext (ba,bb,bc,bd,be,bf,bg,bh,bi,bj) (((((((((a,b),c),d),e),f),g),h),i),j) =
       if (not (isJst a)) || (not (isJst b)) || (not (isJst c)) || (not (isJst d)) || (not (isJst e)) ||
          (not (isJst f)) || (not (isJst g)) || (not (isJst h)) || (not (isJst i)) || (not (isJst j))
       then findNext (ba,bb,bc,bd,be,bf,bg,bh,bi,bj) $
            toBounded (ba,bb,bc,bd,be,bf,bg,bh,bi,bj) $ succ10 (getInt j) True (((((((((a,b),c),d),e),f),g),h),i),j)
       else (((((((((a,b),c),d),e),f),g),h),i),j)
    toBounded (ba,bb,bc,bd,be,bf,bg,bh,bi,bj) (((((((((ja,jb),jc),jd),je),jf),jg),jh),ji),jj) =
       (((((((((ib ja ba,ib jb bb),ib jc bc), ib jd bd), ib je be), ib jf bf), ib jg bg), ib jh bh), ib ji bi), ib jj bj)


  pred (a,b,c,d,e,f,g,h,i,j) =
   if j == minBound then
   if i == minBound then
   if h == minBound then
   if g == minBound then
   if f == minBound then
   if e == minBound then
   if d == minBound then
   if c == minBound then
   if b == minBound then
   if a == minBound then error "Enum.pred{(a,b,c,d,e,f,g,h,i,j)}: tried to take `pred' of minBound"
   else (minBound,minBound,minBound,minBound,minBound,minBound,minBound,minBound,minBound,toEnum (fa-1))
   else (succ a  ,minBound,minBound,minBound,minBound,minBound,minBound,minBound,minBound,toEnum (fb-1))
   else ( a      , succ b, minBound,minBound,minBound,minBound,minBound,minBound,minBound,toEnum (fc-1))
   else ( a      , b     , succ c  ,minBound,minBound,minBound,minBound,minBound,minBound,toEnum (fd-1))
   else ( a      , b     , c       , succ d ,minBound,minBound,minBound,minBound,minBound,toEnum (fe-1))
   else ( a      , b     , c       , d      , succ e ,minBound,minBound,minBound,minBound,toEnum (ff-1))
   else ( a      , b     , c       , d      , e      , succ f ,minBound,minBound,minBound,toEnum (fg-1))
   else ( a      , b     , c       , d      , e      , f      , succ g ,minBound,minBound,toEnum (fh-1))
   else ( a      , b     , c       , d      , e      , f      , g      , succ h ,minBound,toEnum (fi-1))
   else ( a      , b     , c       , d      , e      , f      , g      ,       h, succ i ,  pred j)
    where
      fa = fromEnum a
      fb = fromEnum b
      fc = fromEnum c
      fd = fromEnum d
      fe = fromEnum e
      ff = fromEnum f
      fg = fromEnum g
      fh = fromEnum h
      fi = fromEnum i

  enumFrom t10 | t10 == (maxBound,maxBound,maxBound,maxBound,maxBound,
                         maxBound,maxBound,maxBound,maxBound,maxBound) =
                       [(maxBound,maxBound,maxBound,maxBound,maxBound,
                         maxBound,maxBound,maxBound,maxBound,maxBound)]
               | otherwise = t10 : (enumFrom (succ t10))

  enumFromTo t0 t1 = take l $ enumFrom t0
    where l = (fromEnum t1) - (fromEnum t0) + 1

  toEnum n = (\[a,b,c,d,e,f,g,h,i,j] ->
              (toEnum a, toEnum b, toEnum c, toEnum d, toEnum e,
               toEnum f, toEnum g, toEnum h, toEnum i, toEnum j)) (te 10 n)

  fromEnum (a,b,c,d,e,f,g,h,i,j) = fe [fromEnum a, fromEnum b, fromEnum c, fromEnum d, fromEnum e,
                                       fromEnum f, fromEnum g, fromEnum h, fromEnum i, fromEnum j]

-------------------------------------------------------------------------------------------------------------
instance (Enum a,Enum b,Enum c,Enum d,Enum e,Enum f,Enum g,Enum h,Enum i,Enum j,Enum k,
          Eq a, Eq b, Eq c, Eq d, Eq e, Eq f, Eq g, Eq h, Eq i, Eq j, Eq k,
          Bounded a, Bounded b, Bounded c, Bounded d, Bounded e, Bounded f,
          Bounded g, Bounded h, Bounded i, Bounded j, Bounded k)        => Enum (a,b,c,d,e,f,g,h,i,j,k) where
-------------------------------------------------------------------------------------------------------------
-- 11
  succ (a,b,c,d,e,f,g,h,i,j,k)
     | (a,b,c,d,e,f,g,h,i,j,k) == maxBound
        = error "Enum.succ{(a,b,c,d,e,f,g,h,i,j,k)}: tried to take `succ' of maxBound"
     | otherwise = to11Tuple $
                      findNext (fromEnum (mb (Jst a)), fromEnum (mb (Jst b)), fromEnum (mb (Jst c)),
                                fromEnum (mb (Jst d)), fromEnum (mb (Jst e)), fromEnum (mb (Jst f)),
                                fromEnum (mb (Jst g)), fromEnum (mb (Jst h)), fromEnum (mb (Jst i)),
                                fromEnum (mb (Jst j)), fromEnum (mb (Jst k))) $
                      succ11 (fromEnum k) True (from11Tuple (a,b,c,d,e,f,g,h,i,j,k))
   where
    findNext :: ( Enum a, Enum b, Enum c, Enum d, Enum e, Enum f, Enum g, Enum h, Enum i, Enum j, Enum k,
                  Eq a, Eq b, Eq c, Eq d, Eq e, Eq f, Eq g, Eq h, Eq i, Eq j, Eq k,
                  Bounded a, Bounded b, Bounded c, Bounded d, Bounded e, Bounded f, Bounded g,
                  Bounded h, Bounded i, Bounded j, Bounded k)
                => (Int,Int,Int,Int,Int,Int,Int,Int,Int,Int,Int) ->
                   ((((((((((J a,J b),J c),J d),J e),J f),J g),J h),J i),J j),J k) ->
                   ((((((((((J a,J b),J c),J d),J e),J f),J g),J h),J i),J j),J k)
    findNext (ba,bb,bc,bd,be,bf,bg,bh,bi,bj,bk) ((((((((((a,b),c),d),e),f),g),h),i),j),k) =
       if (not (isJst a)) || (not (isJst b)) || (not (isJst c)) || (not (isJst d)) || (not (isJst e)) ||
          (not (isJst f)) || (not (isJst g)) || (not (isJst h)) || (not (isJst i)) || (not (isJst j)) ||
          (not (isJst k))
       then findNext (ba,bb,bc,bd,be,bf,bg,bh,bi,bj,bk) $
            toBounded (ba,bb,bc,bd,be,bf,bg,bh,bi,bj,bk) $
            succ11 (getInt k) True ((((((((((a,b),c),d),e),f),g),h),i),j),k)
       else ((((((((((a,b),c),d),e),f),g),h),i),j),k)
    toBounded (ba,bb,bc,bd,be,bf,bg,bh,bi,bj,bk)
              ((((((((((ja,jb),jc),jd),je),jf),jg),jh),ji),jj),jk) =
              ((((((((((ib ja ba,ib jb bb),ib jc bc), ib jd bd), ib je be),ib jf bf), ib jg bg),
                       ib jh bh), ib ji bi), ib jj bj), ib jk bk)


  pred (a,b,c,d,e,f,g,h,i,j,k) =
   if k == minBound then
   if j == minBound then
   if i == minBound then
   if h == minBound then
   if g == minBound then
   if f == minBound then
   if e == minBound then
   if d == minBound then
   if c == minBound then
   if b == minBound then
   if a == minBound then error "Enum.pred{(a,b,c,d,e,f,g,h,i,j,k)}: tried to take `pred' of minBound"
   else (minBound,minBound,minBound,minBound,minBound,minBound,minBound,minBound,minBound,minBound,toEnum (fa-1))
   else (succ a  ,minBound,minBound,minBound,minBound,minBound,minBound,minBound,minBound,minBound,toEnum (fb-1))
   else ( a      , succ b, minBound,minBound,minBound,minBound,minBound,minBound,minBound,minBound,toEnum (fc-1))
   else ( a      , b     , succ c  ,minBound,minBound,minBound,minBound,minBound,minBound,minBound,toEnum (fd-1))
   else ( a      , b     , c       , succ d ,minBound,minBound,minBound,minBound,minBound,minBound,toEnum (fe-1))
   else ( a      , b     , c       , d      , succ e ,minBound,minBound,minBound,minBound,minBound,toEnum (ff-1))
   else ( a      , b     , c       , d      , e      , succ f ,minBound,minBound,minBound,minBound,toEnum (fg-1))
   else ( a      , b     , c       , d      , e      , f      , succ g ,minBound,minBound,minBound,toEnum (fh-1))
   else ( a      , b     , c       , d      , e      , f      , g      , succ h ,minBound,minBound,toEnum (fi-1))
   else ( a      , b     , c       , d      , e      , f      , g      , h      , succ i ,minBound,toEnum (fj-1))
   else ( a      , b     , c       , d      , e      , f      , g      , h      , i      , succ j ,  pred k)
    where
      fa = fromEnum a
      fb = fromEnum b
      fc = fromEnum c
      fd = fromEnum d
      fe = fromEnum e
      ff = fromEnum f
      fg = fromEnum g
      fh = fromEnum h
      fi = fromEnum i
      fj = fromEnum j

  enumFrom t11 | t11 == (maxBound,maxBound,maxBound,maxBound,maxBound,
                         maxBound,maxBound,maxBound,maxBound,maxBound,maxBound) =
                       [(maxBound,maxBound,maxBound,maxBound,maxBound,
                         maxBound,maxBound,maxBound,maxBound,maxBound,maxBound)]
               | otherwise = t11 : (enumFrom (succ t11))

  enumFromTo t0 t1 = take l $ enumFrom t0
    where l = (fromEnum t1) - (fromEnum t0) + 1

  toEnum n = (\[a,b,c,d,e,f,g,h,i,j,k] ->
              (toEnum a, toEnum b, toEnum c, toEnum d, toEnum e,
               toEnum f, toEnum g, toEnum h, toEnum i, toEnum j, toEnum k)) (te 11 n)

  fromEnum (a,b,c,d,e,f,g,h,i,j,k) = fe [fromEnum a, fromEnum b, fromEnum c, fromEnum d, fromEnum e,
                                         fromEnum f, fromEnum g, fromEnum h, fromEnum i, fromEnum j, fromEnum k]

------------------------------------------------------------------------------------------------------------
instance (Enum a,Enum b,Enum c,Enum d,Enum e,Enum f,Enum g,Enum h,Enum i,Enum j,Enum k,Enum l,
          Eq a, Eq b, Eq c, Eq d, Eq e, Eq f, Eq g, Eq h, Eq i, Eq j, Eq k, Eq l,
          Bounded a, Bounded b, Bounded c, Bounded d, Bounded e, Bounded f, Bounded g, Bounded h, Bounded i,
          Bounded j, Bounded k, Bounded l)
          => Enum (a,b,c,d,e,f,g,h,i,j,k,l) where
------------------------------------------------------------------------------------------------------------
-- 12
  succ (a,b,c,d,e,f,g,h,i,j,k,l)
     | (a,b,c,d,e,f,g,h,i,j,k,l) == maxBound
        = error "Enum.succ{(a,b,c,d,e,f,g,h,i,j,k,l)}: tried to take `succ' of maxBound"
     | otherwise = to12Tuple $
                      findNext (fromEnum (mb (Jst a)), fromEnum (mb (Jst b)), fromEnum (mb (Jst c)),
                                fromEnum (mb (Jst d)), fromEnum (mb (Jst e)), fromEnum (mb (Jst f)),
                                fromEnum (mb (Jst g)), fromEnum (mb (Jst h)), fromEnum (mb (Jst i)),
                                fromEnum (mb (Jst j)), fromEnum (mb (Jst k)), fromEnum (mb (Jst l))) $
                      succ12 (fromEnum l) True (from12Tuple (a,b,c,d,e,f,g,h,i,j,k,l))
   where
    findNext :: ( Enum a, Enum b, Enum c, Enum d, Enum e, Enum f, Enum g, Enum h, Enum i, Enum j, Enum k, Enum l,
                  Eq a, Eq b, Eq c, Eq d, Eq e, Eq f, Eq g, Eq h, Eq i, Eq j, Eq k, Eq l,
                  Bounded a, Bounded b, Bounded c, Bounded d, Bounded e, Bounded f, Bounded g,
                  Bounded h, Bounded i, Bounded j, Bounded k, Bounded l)
                => (Int,Int,Int,Int,Int,Int,Int,Int,Int,Int,Int,Int) ->
                   (((((((((((J a,J b),J c),J d),J e),J f),J g),J h),J i),J j),J k),J l) ->
                   (((((((((((J a,J b),J c),J d),J e),J f),J g),J h),J i),J j),J k),J l)
    findNext (ba,bb,bc,bd,be,bf,bg,bh,bi,bj,bk,bl) (((((((((((a,b),c),d),e),f),g),h),i),j),k),l) =
       if (not (isJst a)) || (not (isJst b)) || (not (isJst c)) || (not (isJst d)) || (not (isJst e)) ||
          (not (isJst f)) || (not (isJst g)) || (not (isJst h)) || (not (isJst i)) || (not (isJst j)) ||
          (not (isJst k)) || (not (isJst l))
       then findNext (ba,bb,bc,bd,be,bf,bg,bh,bi,bj,bk,bl) $
            toBounded (ba,bb,bc,bd,be,bf,bg,bh,bi,bj,bk,bl) $
            succ12 (getInt l) True (((((((((((a,b),c),d),e),f),g),h),i),j),k),l)
       else (((((((((((a,b),c),d),e),f),g),h),i),j),k),l)
    toBounded (ba,bb,bc,bd,be,bf,bg,bh,bi,bj,bk,bl)
              (((((((((((ja,jb),jc),jd),je),jf),jg),jh),ji),jj),jk),jl) =
              (((((((((((ib ja ba,ib jb bb),ib jc bc), ib jd bd), ib je be),ib jf bf), ib jg bg),
                       ib jh bh), ib ji bi), ib jj bj), ib jk bk), ib jl bl)


  pred (a,b,c,d,e,f,g,h,i,j,k,l) =
   if l == minBound then
   if k == minBound then
   if j == minBound then
   if i == minBound then
   if h == minBound then
   if g == minBound then
   if f == minBound then
   if e == minBound then
   if d == minBound then
   if c == minBound then
   if b == minBound then
   if a == minBound then error "Enum.pred{(a,b,c,d,e,f,g,h,i,j,k)}: tried to take `pred' of minBound"
               else (minBound,minBound,minBound,minBound,minBound,
                     minBound,minBound,minBound,minBound,minBound,minBound,toEnum (fa-1))
               else (succ a  ,minBound,minBound,minBound,minBound,
                     minBound,minBound,minBound,minBound,minBound,minBound,toEnum (fb-1))
               else ( a      , succ b, minBound,minBound,minBound,
                     minBound,minBound,minBound,minBound,minBound,minBound,toEnum (fc-1))
               else ( a      , b     , succ c  ,minBound,minBound,
                     minBound,minBound,minBound,minBound,minBound,minBound,toEnum (fd-1))
               else ( a      , b     , c       , succ d ,minBound,
                     minBound,minBound,minBound,minBound,minBound,minBound,toEnum (fe-1))
               else ( a      , b     , c       , d      , succ e ,
                     minBound,minBound,minBound,minBound,minBound,minBound,toEnum (ff-1))
               else ( a      , b     , c       , d      , e      ,
                     succ f ,minBound,minBound,minBound,minBound,minBound,toEnum (fg-1))
               else ( a      , b     , c       , d      , e      ,
                     f      , succ g ,minBound,minBound,minBound,minBound,toEnum (fh-1))
               else ( a      , b     , c       , d      , e      ,
                     f      , g      , succ h ,minBound,minBound,minBound,toEnum (fi-1))
               else ( a      , b     , c       , d      , e      ,
                     f      , g      , h      , succ i ,minBound,minBound,toEnum (fj-1))
               else ( a      , b     , c       , d      , e      ,
                     f      , g      , h      , i      , succ j ,minBound,toEnum (fk-1))
               else ( a      , b     , c       , d      , e      ,
                     f      , g      , h      , i      , j      , succ k , pred l)
    where
      fa = fromEnum a
      fb = fromEnum b
      fc = fromEnum c
      fd = fromEnum d
      fe = fromEnum e
      ff = fromEnum f
      fg = fromEnum g
      fh = fromEnum h
      fi = fromEnum i
      fj = fromEnum j
      fk = fromEnum k

  enumFrom t12 | t12 == (maxBound,maxBound,maxBound,maxBound,maxBound,maxBound,
                         maxBound,maxBound,maxBound,maxBound,maxBound,maxBound) =
                       [(maxBound,maxBound,maxBound,maxBound,maxBound,maxBound,
                         maxBound,maxBound,maxBound,maxBound,maxBound,maxBound)]
               | otherwise = t12 : (enumFrom (succ t12))

  enumFromTo t0 t1 = take l $ enumFrom t0
    where l = (fromEnum t1) - (fromEnum t0) + 1

  toEnum n = (\[a,b,c,d,e,f,g,h,i,j,k,l] ->
              (toEnum a, toEnum b, toEnum c, toEnum d, toEnum e, toEnum f,
               toEnum g, toEnum h, toEnum i, toEnum j, toEnum k, toEnum l)) (te 12 n)

  fromEnum (a,b,c,d,e,f,g,h,i,j,k,l) =
                     fe [fromEnum a, fromEnum b, fromEnum c, fromEnum d, fromEnum e, fromEnum f,
                         fromEnum g, fromEnum h, fromEnum i, fromEnum j, fromEnum k, fromEnum l]

------------------------------------------------------------------------------------------------------------
instance (Enum a,Enum b,Enum c,Enum d,Enum e,Enum f,Enum g,Enum h,Enum i,Enum j,Enum k,Enum l,Enum m,
          Eq a, Eq b, Eq c, Eq d, Eq e, Eq f, Eq g, Eq h, Eq i, Eq j, Eq k, Eq l, Eq m,
          Bounded a, Bounded b, Bounded c, Bounded d, Bounded e, Bounded f, Bounded g, Bounded h, Bounded i,
          Bounded j, Bounded k, Bounded l, Bounded m)
          => Enum (a,b,c,d,e,f,g,h,i,j,k,l,m) where
------------------------------------------------------------------------------------------------------------
-- 13
  succ (a,b,c,d,e,f,g,h,i,j,k,l,m)
     | (a,b,c,d,e,f,g,h,i,j,k,l,m) == maxBound
        = error "Enum.succ{(a,b,c,d,e,f,g,h,i,j,k,l,m)}: tried to take `succ' of maxBound"
     | otherwise = to13Tuple $
                      findNext (fromEnum (mb (Jst a)), fromEnum (mb (Jst b)), fromEnum (mb (Jst c)),
                                fromEnum (mb (Jst d)), fromEnum (mb (Jst e)), fromEnum (mb (Jst f)),
                                fromEnum (mb (Jst g)), fromEnum (mb (Jst h)), fromEnum (mb (Jst i)),
                                fromEnum (mb (Jst j)), fromEnum (mb (Jst k)), fromEnum (mb (Jst l)),
                                fromEnum (mb (Jst m)) ) $
                      succ13 (fromEnum m) True (from13Tuple (a,b,c,d,e,f,g,h,i,j,k,l,m))
   where
    findNext :: ( Enum a, Enum b, Enum c, Enum d, Enum e, Enum f, Enum g, Enum h, Enum i, Enum j, Enum k, Enum l, Enum m,
                  Eq a, Eq b, Eq c, Eq d, Eq e, Eq f, Eq g, Eq h, Eq i, Eq j, Eq k, Eq l, Eq m,
                  Bounded a, Bounded b, Bounded c, Bounded d, Bounded e, Bounded f, Bounded g,
                  Bounded h, Bounded i, Bounded j, Bounded k, Bounded l, Bounded m)
                => (Int,Int,Int,Int,Int,Int,Int,Int,Int,Int,Int,Int,Int) ->
                   ((((((((((((J a,J b),J c),J d),J e),J f),J g),J h),J i),J j),J k),J l),J m) ->
                   ((((((((((((J a,J b),J c),J d),J e),J f),J g),J h),J i),J j),J k),J l),J m)
    findNext (ba,bb,bc,bd,be,bf,bg,bh,bi,bj,bk,bl,bm) ((((((((((((a,b),c),d),e),f),g),h),i),j),k),l),m) =
       if (not (isJst a)) || (not (isJst b)) || (not (isJst c)) || (not (isJst d)) || (not (isJst e)) ||
          (not (isJst f)) || (not (isJst g)) || (not (isJst h)) || (not (isJst i)) || (not (isJst j)) ||
          (not (isJst k)) || (not (isJst l)) || (not (isJst m))
       then findNext (ba,bb,bc,bd,be,bf,bg,bh,bi,bj,bk,bl,bm) $
            toBounded (ba,bb,bc,bd,be,bf,bg,bh,bi,bj,bk,bl,bm) $
            succ13 (getInt m) True ((((((((((((a,b),c),d),e),f),g),h),i),j),k),l),m)
       else ((((((((((((a,b),c),d),e),f),g),h),i),j),k),l),m)
    toBounded (ba,bb,bc,bd,be,bf,bg,bh,bi,bj,bk,bl,bm)
              ((((((((((((ja,jb),jc),jd),je),jf),jg),jh),ji),jj),jk),jl),jm) =
              ((((((((((((ib ja ba,ib jb bb),ib jc bc), ib jd bd), ib je be),ib jf bf), ib jg bg),
                       ib jh bh), ib ji bi), ib jj bj), ib jk bk), ib jl bl), ib jm bm)

  pred (a,b,c,d,e,f,g,h,i,j,k,l,m) =
   if m == minBound then
   if l == minBound then
   if k == minBound then
   if j == minBound then
   if i == minBound then
   if h == minBound then
   if g == minBound then
   if f == minBound then
   if e == minBound then
   if d == minBound then
   if c == minBound then
   if b == minBound then
   if a == minBound then error "Enum.pred{(a,b,c,d,e,f,g,h,i,j,k)}: tried to take `pred' of minBound"
      else (minBound,minBound,minBound,minBound,minBound,minBound,
            minBound,minBound,minBound,minBound,minBound,minBound,toEnum (fa-1))
      else (succ a  ,minBound,minBound,minBound,minBound,minBound,
            minBound,minBound,minBound,minBound,minBound,minBound,toEnum (fb-1))
      else ( a      , succ b, minBound,minBound,minBound,minBound,
            minBound,minBound,minBound,minBound,minBound,minBound,toEnum (fc-1))
      else ( a      , b     , succ c  ,minBound,minBound,minBound,
            minBound,minBound,minBound,minBound,minBound,minBound,toEnum (fd-1))
      else ( a      , b     , c       , succ d ,minBound,minBound,
            minBound,minBound,minBound,minBound,minBound,minBound,toEnum (fe-1))
      else ( a      , b     , c       , d      , succ e ,minBound,
            minBound,minBound,minBound,minBound,minBound,minBound,toEnum (ff-1))
      else ( a      , b     , c       , d      , e      , succ f ,
            minBound,minBound,minBound,minBound,minBound,minBound,toEnum (fg-1))
      else ( a      , b     , c       , d      , e      , f      ,
            succ g ,minBound,minBound,minBound,minBound,minBound,toEnum (fh-1))
      else ( a      , b     , c       , d      , e      , f      ,
             g      , succ h ,minBound,minBound,minBound,minBound,toEnum (fi-1))
      else ( a      , b     , c       , d      , e      , f      ,
             g      , h      , succ i ,minBound,minBound,minBound,toEnum (fj-1))
      else ( a      , b     , c       , d      , e      , f      ,
             g      , h      , i      , succ j ,minBound,minBound,toEnum (fk-1))
      else ( a      , b     , c       , d      , e      , f      ,
             g      , h      , i      , j      , succ k ,minBound,toEnum (fl-1))
      else ( a      , b     , c       , d      , e      , f      ,
             g      , h      , i      , j      , k      , succ l , pred m)
    where
      fa = fromEnum a
      fb = fromEnum b
      fc = fromEnum c
      fd = fromEnum d
      fe = fromEnum e
      ff = fromEnum f
      fg = fromEnum g
      fh = fromEnum h
      fi = fromEnum i
      fj = fromEnum j
      fk = fromEnum k
      fl = fromEnum l

  enumFrom t13
     | t13 == (maxBound,maxBound,maxBound,maxBound,maxBound,maxBound,
               maxBound,maxBound,maxBound,maxBound,maxBound,maxBound,maxBound) =
             [(maxBound,maxBound,maxBound,maxBound,maxBound,maxBound,
               maxBound,maxBound,maxBound,maxBound,maxBound,maxBound,maxBound)]
     | otherwise = t13 : (enumFrom (succ t13))

  enumFromTo t0 t1 = take l $ enumFrom t0
    where l = (fromEnum t1) - (fromEnum t0) + 1

  toEnum n = (\[a,b,c,d,e,f,g,h,i,j,k,l,m] ->
              (toEnum a, toEnum b, toEnum c, toEnum d, toEnum e, toEnum f,
               toEnum g, toEnum h, toEnum i, toEnum j, toEnum k, toEnum l, toEnum m)) (te 13 n)

  fromEnum (a,b,c,d,e,f,g,h,i,j,k,l,m) =
                     fe [fromEnum a, fromEnum b, fromEnum c, fromEnum d, fromEnum e, fromEnum f,
                         fromEnum g, fromEnum h, fromEnum i, fromEnum j, fromEnum k, fromEnum l, fromEnum m]

------------------------------------------------------------------------------------------------------------
instance (Enum a,Enum b,Enum c,Enum d,Enum e,Enum f,Enum g,Enum h,Enum i,Enum j,Enum k,Enum l,Enum m,Enum n,
          Eq a, Eq b, Eq c, Eq d, Eq e, Eq f, Eq g, Eq h, Eq i, Eq j, Eq k, Eq l, Eq m, Eq n,
          Bounded a, Bounded b, Bounded c, Bounded d, Bounded e, Bounded f, Bounded g, Bounded h, Bounded i,
          Bounded j, Bounded k, Bounded l, Bounded m, Bounded n)
          => Enum (a,b,c,d,e,f,g,h,i,j,k,l,m,n) where
------------------------------------------------------------------------------------------------------------
-- 14
  succ (a,b,c,d,e,f,g,h,i,j,k,l,m,n)
     | (a,b,c,d,e,f,g,h,i,j,k,l,m,n) == maxBound
        = error "Enum.succ{(a,b,c,d,e,f,g,h,i,j,k,l,m,n)}: tried to take `succ' of maxBound"
     | otherwise = to14Tuple $
                      findNext (fromEnum (mb (Jst a)), fromEnum (mb (Jst b)), fromEnum (mb (Jst c)),
                                fromEnum (mb (Jst d)), fromEnum (mb (Jst e)), fromEnum (mb (Jst f)),
                                fromEnum (mb (Jst g)), fromEnum (mb (Jst h)), fromEnum (mb (Jst i)),
                                fromEnum (mb (Jst j)), fromEnum (mb (Jst k)), fromEnum (mb (Jst l)),
                                fromEnum (mb (Jst m)), fromEnum (mb (Jst n)) ) $
                      succ14 (fromEnum m) True (from14Tuple (a,b,c,d,e,f,g,h,i,j,k,l,m,n))
   where
    findNext :: ( Enum a, Enum b, Enum c, Enum d, Enum e, Enum f, Enum g, Enum h, Enum i, Enum j,
                  Enum k, Enum l, Enum m, Enum n,
                  Eq a, Eq b, Eq c, Eq d, Eq e, Eq f, Eq g, Eq h, Eq i, Eq j, Eq k, Eq l, Eq m, Eq n,
                  Bounded a, Bounded b, Bounded c, Bounded d, Bounded e, Bounded f, Bounded g,
                  Bounded h, Bounded i, Bounded j, Bounded k, Bounded l, Bounded m, Bounded n)
                => (Int,Int,Int,Int,Int,Int,Int,Int,Int,Int,Int,Int,Int,Int) ->
                   (((((((((((((J a,J b),J c),J d),J e),J f),J g),J h),J i),J j),J k),J l),J m),J n) ->
                   (((((((((((((J a,J b),J c),J d),J e),J f),J g),J h),J i),J j),J k),J l),J m),J n)
    findNext (ba,bb,bc,bd,be,bf,bg,bh,bi,bj,bk,bl,bm,bn) (((((((((((((a,b),c),d),e),f),g),h),i),j),k),l),m),n) =
       if (not (isJst a)) || (not (isJst b)) || (not (isJst c)) || (not (isJst d)) || (not (isJst e)) ||
          (not (isJst f)) || (not (isJst g)) || (not (isJst h)) || (not (isJst i)) || (not (isJst j)) ||
          (not (isJst k)) || (not (isJst l)) || (not (isJst m)) || (not (isJst n))
       then findNext (ba,bb,bc,bd,be,bf,bg,bh,bi,bj,bk,bl,bm,bn) $
            toBounded (ba,bb,bc,bd,be,bf,bg,bh,bi,bj,bk,bl,bm,bn) $
            succ14 (getInt n) True (((((((((((((a,b),c),d),e),f),g),h),i),j),k),l),m),n)
       else (((((((((((((a,b),c),d),e),f),g),h),i),j),k),l),m),n)
    toBounded (ba,bb,bc,bd,be,bf,bg,bh,bi,bj,bk,bl,bm,bn)
              (((((((((((((ja,jb),jc),jd),je),jf),jg),jh),ji),jj),jk),jl),jm),jn) =
              (((((((((((((ib ja ba,ib jb bb),ib jc bc), ib jd bd), ib je be),ib jf bf), ib jg bg),
                       ib jh bh), ib ji bi), ib jj bj), ib jk bk), ib jl bl), ib jm bm), ib jn bn)


  pred (a,b,c,d,e,f,g,h,i,j,k,l,m,n) =
   if n == minBound then
   if m == minBound then
   if l == minBound then
   if k == minBound then
   if j == minBound then
   if i == minBound then
   if h == minBound then
   if g == minBound then
   if f == minBound then
   if e == minBound then
   if d == minBound then
   if c == minBound then
   if b == minBound then
   if a == minBound then error "Enum.pred{(a,b,c,d,e,f,g,h,i,j,k)}: tried to take `pred' of minBound"
   else (minBound,minBound,minBound,minBound,minBound,minBound,
         minBound,minBound,minBound,minBound,minBound,minBound,minBound,toEnum (fa-1))
   else (succ a  ,minBound,minBound,minBound,minBound,minBound,
         minBound,minBound,minBound,minBound,minBound,minBound,minBound,toEnum (fb-1))
   else ( a      , succ b, minBound,minBound,minBound,minBound,
         minBound,minBound,minBound,minBound,minBound,minBound,minBound,toEnum (fc-1))
   else ( a      , b     , succ c  ,minBound,minBound,minBound,
         minBound,minBound,minBound,minBound,minBound,minBound,minBound,toEnum (fd-1))
   else ( a      , b     , c       , succ d ,minBound,minBound,
         minBound,minBound,minBound,minBound,minBound,minBound,minBound,toEnum (fe-1))
   else ( a      , b     , c       , d      , succ e ,minBound,
         minBound,minBound,minBound,minBound,minBound,minBound,minBound,toEnum (ff-1))
   else ( a      , b     , c       , d      , e      , succ f ,
         minBound,minBound,minBound,minBound,minBound,minBound,minBound,toEnum (fg-1))
   else ( a      , b     , c       , d      , e      , f      ,
         succ g ,minBound,minBound,minBound,minBound,minBound,minBound,toEnum (fh-1))
   else ( a      , b     , c       , d      , e      , f      ,
          g      , succ h ,minBound,minBound,minBound,minBound,minBound,toEnum (fi-1))
   else ( a      , b     , c       , d      , e      , f      ,
          g      , h      , succ i ,minBound,minBound,minBound,minBound,toEnum (fj-1))
   else ( a      , b     , c       , d      , e      , f      ,
          g      , h      , i      , succ j ,minBound,minBound,minBound,toEnum (fk-1))
   else ( a      , b     , c       , d      , e      , f      ,
          g      , h      , i      , j      , succ k ,minBound,minBound,toEnum (fl-1))
   else ( a      , b     , c       , d      , e      , f      ,
          g      , h      , i      , j      , k      , succ l ,minBound,toEnum (fm-1))
   else ( a      , b     , c       , d      , e      , f      ,
          g      , h      , i      , j      , k      , l      , succ m , pred n)
    where
      fa = fromEnum a
      fb = fromEnum b
      fc = fromEnum c
      fd = fromEnum d
      fe = fromEnum e
      ff = fromEnum f
      fg = fromEnum g
      fh = fromEnum h
      fi = fromEnum i
      fj = fromEnum j
      fk = fromEnum k
      fl = fromEnum l
      fm = fromEnum m

  enumFrom t14
     | t14 == (maxBound,maxBound,maxBound,maxBound,maxBound,maxBound,maxBound,
               maxBound,maxBound,maxBound,maxBound,maxBound,maxBound,maxBound) =
             [(maxBound,maxBound,maxBound,maxBound,maxBound,maxBound,maxBound,
               maxBound,maxBound,maxBound,maxBound,maxBound,maxBound,maxBound)]
     | otherwise = t14 : (enumFrom (succ t14))

  enumFromTo t0 t1 = take l $ enumFrom t0
    where l = (fromEnum t1) - (fromEnum t0) + 1

  toEnum n = (\[a,b,c,d,e,f,g,h,i,j,k,l,m,n] ->
              (toEnum a, toEnum b, toEnum c, toEnum d, toEnum e, toEnum f, toEnum g,
               toEnum h, toEnum i, toEnum j, toEnum k, toEnum l, toEnum m, toEnum n)) (te 14 n)

  fromEnum (a,b,c,d,e,f,g,h,i,j,k,l,m,n) =
                     fe [fromEnum a, fromEnum b, fromEnum c, fromEnum d, fromEnum e, fromEnum f, fromEnum g,
                         fromEnum h, fromEnum i, fromEnum j, fromEnum k, fromEnum l, fromEnum m, fromEnum m]

-------------------------------------------------------------------------------------------------------------------
instance (Enum a,Enum b,Enum c,Enum d,Enum e,Enum f,Enum g,Enum h,Enum i,Enum j,Enum k,Enum l,Enum m,Enum n,Enum o,
          Eq a, Eq b, Eq c, Eq d, Eq e, Eq f, Eq g, Eq h, Eq i, Eq j, Eq k, Eq l, Eq m, Eq n, Eq o,
          Bounded a, Bounded b, Bounded c, Bounded d, Bounded e, Bounded f, Bounded g, Bounded h, Bounded i,
          Bounded j, Bounded k, Bounded l, Bounded m, Bounded n, Bounded o)
          => Enum (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o) where
-------------------------------------------------------------------------------------------------------------------
-- 15  (we stop at this number beacause it is the official number of braces supported by the Prelude)
  succ (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o)
     | (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o) == maxBound
        = error "Enum.succ{(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o)}: tried to take `succ' of maxBound"
     | otherwise = to15Tuple $
                      findNext (fromEnum (mb (Jst a)), fromEnum (mb (Jst b)), fromEnum (mb (Jst c)),
                                fromEnum (mb (Jst d)), fromEnum (mb (Jst e)), fromEnum (mb (Jst f)),
                                fromEnum (mb (Jst g)), fromEnum (mb (Jst h)), fromEnum (mb (Jst i)),
                                fromEnum (mb (Jst j)), fromEnum (mb (Jst k)), fromEnum (mb (Jst l)),
                                fromEnum (mb (Jst m)), fromEnum (mb (Jst n)), fromEnum (mb (Jst o)) ) $
                      succ15 (fromEnum m) True (from15Tuple (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o))
   where
    findNext :: ( Enum a, Enum b, Enum c, Enum d, Enum e, Enum f, Enum g, Enum h, Enum i, Enum j,
                  Enum k, Enum l, Enum m, Enum n, Enum o,
                  Eq a, Eq b, Eq c, Eq d, Eq e, Eq f, Eq g, Eq h, Eq i, Eq j, Eq k, Eq l, Eq m, Eq n, Eq o,
                  Bounded a, Bounded b, Bounded c, Bounded d, Bounded e, Bounded f, Bounded g,
                  Bounded h, Bounded i, Bounded j, Bounded k, Bounded l, Bounded m, Bounded n, Bounded o)
                => (Int,Int,Int,Int,Int,Int,Int,Int,Int,Int,Int,Int,Int,Int,Int) ->
                   ((((((((((((((J a,J b),J c),J d),J e),J f),J g),J h),J i),J j),J k),J l),J m),J n),J o) ->
                   ((((((((((((((J a,J b),J c),J d),J e),J f),J g),J h),J i),J j),J k),J l),J m),J n),J o)
    findNext (ba,bb,bc,bd,be,bf,bg,bh,bi,bj,bk,bl,bm,bn,bo) ((((((((((((((a,b),c),d),e),f),g),h),i),j),k),l),m),n),o) =
       if (not (isJst a)) || (not (isJst b)) || (not (isJst c)) || (not (isJst d)) || (not (isJst e)) ||
          (not (isJst f)) || (not (isJst g)) || (not (isJst h)) || (not (isJst i)) || (not (isJst j)) ||
          (not (isJst k)) || (not (isJst l)) || (not (isJst m)) || (not (isJst n)) || (not (isJst o))
       then findNext (ba,bb,bc,bd,be,bf,bg,bh,bi,bj,bk,bl,bm,bn,bo) $
            toBounded (ba,bb,bc,bd,be,bf,bg,bh,bi,bj,bk,bl,bm,bn,bo) $
            succ15 (getInt o) True ((((((((((((((a,b),c),d),e),f),g),h),i),j),k),l),m),n),o)
       else ((((((((((((((a,b),c),d),e),f),g),h),i),j),k),l),m),n),o)
    toBounded (ba,bb,bc,bd,be,bf,bg,bh,bi,bj,bk,bl,bm,bn,bo)
              ((((((((((((((ja,jb),jc),jd),je),jf),jg),jh),ji),jj),jk),jl),jm),jn),jo) =
              ((((((((((((((ib ja ba,ib jb bb),ib jc bc), ib jd bd), ib je be),ib jf bf), ib jg bg),
                       ib jh bh), ib ji bi), ib jj bj), ib jk bk), ib jl bl), ib jm bm), ib jn bn), ib jo bo)


  pred (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o) =
   if o == minBound then
   if n == minBound then
   if m == minBound then
   if l == minBound then
   if k == minBound then
   if j == minBound then
   if i == minBound then
   if h == minBound then
   if g == minBound then
   if f == minBound then
   if e == minBound then
   if d == minBound then
   if c == minBound then
   if b == minBound then
   if a == minBound then error "Enum.pred{(a,b,c,d,e,f,g,h,i,j,k)}: tried to take `pred' of minBound"
   else (minBound,minBound,minBound,minBound,minBound,minBound,minBound,
         minBound,minBound,minBound,minBound,minBound,minBound,minBound,toEnum (fa-1))
   else (succ a  ,minBound,minBound,minBound,minBound,minBound,minBound,
         minBound,minBound,minBound,minBound,minBound,minBound,minBound,toEnum (fb-1))
   else ( a      , succ b, minBound,minBound,minBound,minBound,minBound,
         minBound,minBound,minBound,minBound,minBound,minBound,minBound,toEnum (fc-1))
   else ( a      , b     , succ c  ,minBound,minBound,minBound,minBound,
         minBound,minBound,minBound,minBound,minBound,minBound,minBound,toEnum (fd-1))
   else ( a      , b     , c       , succ d ,minBound,minBound,minBound,
         minBound,minBound,minBound,minBound,minBound,minBound,minBound,toEnum (fe-1))
   else ( a      , b     , c       , d      , succ e ,minBound,minBound,
         minBound,minBound,minBound,minBound,minBound,minBound,minBound,toEnum (ff-1))
   else ( a      , b     , c       , d      , e      , succ f ,minBound,
         minBound,minBound,minBound,minBound,minBound,minBound,minBound,toEnum (fg-1))
   else ( a      , b     , c       , d      , e      , f      , succ g ,
         minBound,minBound,minBound,minBound,minBound,minBound,minBound,toEnum (fh-1))
   else ( a      , b     , c       , d      , e      , f      , g      ,
          succ h ,minBound,minBound,minBound,minBound,minBound,minBound,toEnum (fi-1))
   else ( a      , b     , c       , d      , e      , f      , g      ,
          h      ,succ i  ,minBound,minBound,minBound,minBound,minBound,toEnum (fj-1))
   else ( a      , b     , c       , d      , e      , f      , g      ,
          h      ,i       , succ j ,minBound,minBound,minBound,minBound,toEnum (fk-1))
   else ( a      , b     , c       , d      , e      , f      , g      ,
          h      ,i      , j      , succ k ,minBound,minBound,minBound,toEnum (fl-1))
   else ( a      , b     , c       , d      , e      , f      , g      ,
          h      ,i      , j      , k       , succ l ,minBound,minBound,toEnum (fm-1))
   else ( a      , b     , c       , d      , e      , f      , g      ,
          h      ,i      , j      , k       , l      , succ m ,minBound,toEnum (fn-1))
   else ( a      , b     , c       , d      , e      , f      , g      ,
          h      ,i      , j      , k       , l      , m      , succ n , pred o)
    where
      fa = fromEnum a
      fb = fromEnum b
      fc = fromEnum c
      fd = fromEnum d
      fe = fromEnum e
      ff = fromEnum f
      fg = fromEnum g
      fh = fromEnum h
      fi = fromEnum i
      fj = fromEnum j
      fk = fromEnum k
      fl = fromEnum l
      fm = fromEnum m
      fn = fromEnum n

  enumFrom t15
     | t15 == (maxBound,maxBound,maxBound,maxBound,maxBound,maxBound,maxBound,maxBound,
               maxBound,maxBound,maxBound,maxBound,maxBound,maxBound,maxBound) =
             [(maxBound,maxBound,maxBound,maxBound,maxBound,maxBound,maxBound,maxBound,
               maxBound,maxBound,maxBound,maxBound,maxBound,maxBound,maxBound)]
     | otherwise = t15 : (enumFrom (succ t15))

  enumFromTo t0 t1 = take l $ enumFrom t0
    where l = (fromEnum t1) - (fromEnum t0) + 1

  toEnum n = (\[a,b,c,d,e,f,g,h,i,j,k,l,m,n,o] ->
              (toEnum a, toEnum b, toEnum c, toEnum d, toEnum e, toEnum f, toEnum g,
               toEnum h, toEnum i, toEnum j, toEnum k, toEnum l, toEnum m, toEnum n, toEnum o)) (te 15 n)

  fromEnum (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o) =
         fe [fromEnum a, fromEnum b, fromEnum c, fromEnum d, fromEnum e, fromEnum f, fromEnum g,
             fromEnum h, fromEnum i, fromEnum j, fromEnum k, fromEnum l, fromEnum m, fromEnum n, fromEnum o]