DSH-0.10.0.0: tests/DSHComprehensions.hs
{-# LANGUAGE RebindableSyntax #-}
{-# LANGUAGE ViewPatterns #-}
{-# LANGUAGE MonadComprehensions #-}
-- | This module contains testcases for monad comprehensions. We store them in a
-- separate module because they rely on RebindableSyntax and hidden Prelude.
module DSHComprehensions where
import qualified Prelude as P
import Database.DSH
---------------------------------------------------------------
-- Comprehensions for quickcheck tests
cartprod :: Q ([Integer], [Integer]) -> Q [(Integer, Integer)]
cartprod (view -> (xs, ys)) =
[ tup2 x y
| x <- xs
, y <- ys
]
eqjoin :: Q ([Integer], [Integer]) -> Q [(Integer, Integer)]
eqjoin (view -> (xs, ys)) =
[ tup2 x y
| x <- xs
, y <- ys
, x == y
]
eqjoinproj :: Q ([Integer], [Integer]) -> Q [(Integer, Integer)]
eqjoinproj (view -> (xs, ys)) =
[ tup2 x y
| x <- xs
, y <- ys
, (2 * x) == y
]
eqjoinpred :: Q (Integer, [Integer], [Integer]) -> Q [(Integer, Integer)]
eqjoinpred (view -> (x', xs, ys)) =
[ tup2 x y
| x <- xs
, y <- ys
, x == y
, x > x'
]
eqjointuples :: Q ([(Integer, Integer)], [(Integer, Integer)]) -> Q [(Integer, Integer, Integer)]
eqjointuples (view -> (xs, ys)) =
[ tup3 (x1 * x2) y1 y2
| (view -> (x1, x2)) <- xs
, (view -> (y1, y2)) <- ys
, x1 == y2
]
thetajoin_eq :: Q ([(Integer, Integer)], [(Integer, Integer)]) -> Q [(Integer, Integer, Integer)]
thetajoin_eq (view -> (xs, ys)) =
[ tup3 (x1 * x2) y1 y2
| (view -> (x1, x2)) <- xs
, (view -> (y1, y2)) <- ys
, x1 == y2
, y1 == x2
]
thetajoin_neq :: Q ([(Integer, Integer)], [(Integer, Integer)]) -> Q [(Integer, Integer, Integer)]
thetajoin_neq (view -> (xs, ys)) =
[ tup3 (x1 * x2) y1 y2
| (view -> (x1, x2)) <- xs
, (view -> (y1, y2)) <- ys
, x1 == y2
, y1 /= x2
]
eqjoin3 :: Q ([Integer], [Integer], [Integer]) -> Q [(Integer, Integer, Integer)]
eqjoin3 (view -> (xs, ys, zs)) =
[ tup3 x y z
| x <- xs
, y <- ys
, z <- zs
, x == y
, y == z
]
eqjoin_nested_left :: Q ([(Integer, [Integer])], [Integer]) -> Q [((Integer, [Integer]), Integer)]
eqjoin_nested_left args =
[ pair x y
| x <- fst args
, y <- snd args
, fst x == y
]
eqjoin_nested_right :: Q ([Integer], [(Integer, [Integer])]) -> Q [(Integer, (Integer, [Integer]))]
eqjoin_nested_right args =
[ pair x y
| x <- fst args
, y <- snd args
, x == fst y
]
eqjoin_nested_both :: Q ([(Integer, [Integer])], [(Integer, [Integer])])
-> Q [((Integer, [Integer]), (Integer, [Integer]))]
eqjoin_nested_both args =
[ pair x y
| x <- fst args
, y <- snd args
, fst x == fst y
]
nestjoin :: Q ([Integer], [Integer]) -> Q [(Integer, [Integer])]
nestjoin (view -> (xs, ys)) =
[ tup2 x [ y | y <- ys, x == y]
| x <- xs
]
nestjoin3 :: Q ([Integer], [Integer], [Integer]) -> Q [[[(Integer, Integer, Integer)]]]
nestjoin3 (view -> (xs, ys, zs)) =
[ [ [ tup3 x y z | z <- zs, y == z ]
| y <- ys
, x == y
]
| x <- xs
]
--------------------------------------------------------------
-- Comprehensions for HUnit tests
eqjoin_nested1 :: Q [((Integer, [Char]), Integer)]
eqjoin_nested1 =
[ pair x y
| x <- (toQ ([(10, ['a']), (20, ['b']), (30, ['c', 'd']), (40, [])] :: [(Integer, [Char])]))
, y <- (toQ [20, 30, 30, 40, 50])
, fst x == y
]
semijoin :: Q [Integer]
semijoin =
let xs = (toQ [1, 2, 3, 4, 5, 6, 7] :: Q [Integer])
ys = (toQ [2, 4, 6, 7] :: Q [Integer])
in [ x | x <- xs , x `elem` ys ]
semijoin_range :: Q [Integer]
semijoin_range =
let xs = (toQ [1, 2, 3, 4, 5, 6, 7] :: Q [Integer])
ys = (toQ [2, 4, 6] :: Q [Integer])
in [ x | x <- xs , x `elem` [ y | y <- ys, y < 6 ] ]
semijoin_quant :: Q [Integer]
semijoin_quant =
let xs = (toQ [1, 2, 3, 4, 5, 6, 7] :: Q [Integer])
ys = (toQ [2, 4, 6, 7] :: Q [Integer])
in [ x | x <- xs, or [ y > 5 | y <- ys, x == y ] ]
semijoin_not_null :: Q [Integer]
semijoin_not_null =
let xs = (toQ [1, 2, 3, 4, 5, 6, 7] :: Q [Integer])
ys = (toQ [2, 4, 6, 7] :: Q [Integer])
in [ x | x <- xs, not $ null [ y | y <- ys, x == y] ]
antijoin :: Q [Integer]
antijoin =
let xs = (toQ [1, 2, 3, 4, 5, 6, 7] :: Q [Integer])
ys = (toQ [2, 4, 6, 7] :: Q [Integer])
in [ x | x <- xs , not $ x `elem` ys ]
antijoin_null :: Q [Integer]
antijoin_null =
let xs = (toQ [1, 2, 3, 4, 5, 6, 7] :: Q [Integer])
ys = (toQ [2, 4, 6, 7] :: Q [Integer])
in [ x | x <- xs, null [ y | y <- ys, x == y] ]
antijoin_range :: Q [Integer]
antijoin_range =
let xs = (toQ [1, 2, 3, 4, 5, 6, 7] :: Q [Integer])
ys = (toQ [2, 4, 6, 7] :: Q [Integer])
in [ x | x <- xs , not $ x `elem` [ y | y <- ys, y < 5 ] ]
antijoin_class12 :: Q [Integer]
antijoin_class12 =
let xs = toQ ([6,7,8,9,10,12] :: [Integer])
ys = toQ ([8,9,12,13,15,16] :: [Integer])
in [ x | x <- xs, and [ x < y | y <- ys, y > 10 ]]
antijoin_class15 :: Q [Integer]
antijoin_class15 =
let xs = toQ ([3,4,5,6,7,8] :: [Integer])
ys = toQ ([4,5,8,16] :: [Integer])
in [ x | x <- xs, and [ y `mod` 4 == 0 | y <- ys, x < y ]]
antijoin_class16 :: Q [Integer]
antijoin_class16 =
let xs = toQ ([3,4,5,6] :: [Integer])
ys = toQ ([1,2,3,4,5,6,7,8] :: [Integer])
in [ x | x <- xs, and [ y <= 2 * x | y <- ys, x < y ]]
frontguard :: Q [[Integer]]
frontguard =
[ [ y | x > 13, y <- toQ ([1,2,3,4] :: [Integer]), y < 3 ]
| x <- toQ ([10, 20, 30] :: [Integer])
]
----------------------------------------------------------------------
-- Comprehensions for HUnit NestJoin/NestProduct tests
nj1 :: [Integer] -> [Integer] -> Q [[Integer]]
nj1 njxs njys =
[ [ y | y <- toQ njys, x == y ]
| x <- toQ njxs
]
nj2 :: [Integer] -> [Integer] -> Q [(Integer, [Integer])]
nj2 njxs njys =
[ pair x [ y | y <- toQ njys, x == y ]
| x <- toQ njxs
]
nj3 :: [Integer] -> [Integer] -> Q [(Integer, [Integer])]
nj3 njxs njys =
[ pair x ([ y | y <- toQ njys, x == y ] ++ (toQ [100, 200, 300]))
| x <- toQ njxs
]
nj4 :: [Integer] -> [Integer] -> Q [(Integer, [Integer])]
nj4 njxs njys =
[ pair x ([ y | y <- toQ njys, x == y ] ++ [ z | z <- toQ njys, x == z ])
| x <- toQ njxs
]
-- Code incurs DistSeg for the literal 15.
nj5 :: [Integer] -> [Integer] -> Q [(Integer, [Integer])]
nj5 njxs njys =
[ pair x [ y | y <- toQ njys, x + y > 15 ]
| x <- toQ njxs
]
nj6 :: [Integer] -> [Integer] -> Q [(Integer, [Integer])]
nj6 njxs njys =
[ pair x [ y | y <- toQ njys, x + y > 10, y < 7 ]
| x <- toQ njxs
]
nj7 :: [Integer] -> [Integer] -> Q [[Integer]]
nj7 njxs njys =
[ [ x + y | y <- toQ njys, x + 2 == y ] | x <- toQ njxs ]
nj8 :: [Integer] -> [Integer] -> Q [[Integer]]
nj8 njxs njys = [ [ x + y | y <- toQ njys, x == y, y < 5 ] | x <- toQ njxs, x > 3 ]
nj9 :: [Integer] -> [Integer] -> Q [[Integer]]
nj9 njxs njys = [ [ x + y | y <- toQ njys, x + 1 == y, y > 2, x < 6 ] | x <- toQ njxs ]
nj10 :: [Integer] -> [Integer] -> Q [Integer]
nj10 njxs njys = [ x + sum [ x * y | y <- toQ njys, x == y ] | x <- toQ njxs ]
nj11 :: [Integer] -> [Integer] -> Q [[Integer]]
nj11 njxs njys = [ [ x + y | y <- toQ njys, x > y, x < y * 2 ] | x <- toQ njxs ]
nj12 :: [Integer] -> [Integer] -> [Integer] -> Q [[[(Integer, Integer, Integer)]]]
nj12 njxs njys njzs =
[ [ [ tup3 x y z | z <- toQ njzs, y == z ]
| y <- toQ njys
, x == y
]
| x <- toQ njxs
]
np1 :: [Integer] -> [Integer] -> Q [[Integer]]
np1 njxs njys = [ [ x * y * 2 | y <- toQ njys ] | x <- toQ njxs ]
np2 :: [Integer] -> [Integer] -> Q [(Integer, [Integer])]
np2 njxs njys = [ pair x [ y * 2 | y <- toQ njys ] | x <- toQ njxs ]
np3 :: [Integer] -> [Integer] -> Q [[Integer]]
np3 njxs njys = [ [ x + y | y <- toQ njys ] | x <- toQ njxs ]
np4 :: [Integer] -> [Integer] -> Q [[Integer]]
np4 njxs njys = [ [ y | y <- toQ njys, x > y ] | x <- toQ njxs ]
njg1 :: [Integer] -> [(Integer, Integer)] -> Q [Integer]
njg1 njgxs njgzs =
[ x
| x <- toQ njgxs
, x < 8
, sum [ snd z | z <- toQ njgzs, fst z == x ] > 100
]
njg2 :: [Integer] -> [Integer] -> Q [Integer]
njg2 njgxs njgys =
[ x
| x <- toQ njgxs
, and [ y > 1 | y <- toQ njgys, x == y ]
, x < 8
]
njg3 :: [Integer] -> [Integer] -> [(Integer, Integer)] -> Q [(Integer, Integer)]
njg3 njgxs njgys njgzs =
[ pair x y
| x <- toQ njgxs
, y <- toQ njgys
, length [ toQ () | z <- toQ njgzs, fst z == x ] > 2
]
njg4 :: [Integer] -> [Integer] -> [(Integer, Integer)] -> Q [Integer]
njg4 njgxs njgys njgzs =
[ x
| x <- toQ njgxs
, length [ toQ () | y <- toQ njgys, x == y ]
> length [ toQ () | z <- toQ njgzs, fst z == x ]
]
njg5 :: [Integer] -> [Integer] -> Q [Integer]
njg5 njgxs njgys =
[ x
| x <- toQ njgxs
, sum [ y | y <- toQ njgys, x < y, y > 5 ] < 10
]
--------------------------------------------------------------------------------
-- Comprehensions for QuickCheck antijoin/semijoin tests
aj_class12 :: Q ([Integer], [Integer]) -> Q [Integer]
aj_class12 (view -> (xs, ys)) =
[ x
| x <- xs
, and [ x == y | y <- ys, y > 10 ]
]
aj_class15 :: Q ([Integer], [Integer]) -> Q [Integer]
aj_class15 (view -> (xs, ys)) =
[ x
| x <- xs
, and [ y `mod` 4 == 0 | y <- ys, x < y ]
]
aj_class16 :: Q ([Integer], [Integer]) -> Q [Integer]
aj_class16 (view -> (xs, ys)) =
[ x
| x <- xs
, and [ y <= 2 * x | y <- ys, x < y ]
]
--------------------------------------------------------------------------------
-- Comprehensions for
backdep :: Q [[Integer]] -> Q [Integer]
backdep xss = [ x | xs <- xss, x <- xs ]
backdep_filter :: Q [[Integer]] -> Q [Integer]
backdep_filter xss = [ x | xs <- xss, x <- xs, length xs > x ]
backdep2 :: Q [[Integer]] -> Q [[Integer]]
backdep2 xss = [ [ x * 42 | x <- xs ] | xs <- xss ]
backdep3 :: Q [[Integer]] -> Q [[Integer]]
backdep3 xss = [ [ x + length xs | x <- xs ] | xs <- xss ]
backdep4 :: Q [[[Integer]]] -> Q [[[Integer]]]
backdep4 xsss = [ [ [ x + length xs + length xss
| x <- xs
]
| xs <- xss
]
| xss <- xsss
]
backdep5 :: Q [[Integer]] -> Q [[Integer]]
backdep5 xss = [ [ x + length xs | x <- take (length xs - 3) xs ] | xs <- xss ]
deep_iter :: Q ([Integer], [Integer], [Integer], [Integer], [Integer]) -> Q [[[[Integer]]]]
deep_iter (view -> (ws1, ws2, xs, ys, zs)) =
[ [ [ [ w1 * 23 - y | w1 <- ws1 ]
++
[ w2 + 42 - y | w2 <- ws2 ]
| z <- zs
, z > x
]
| y <- ys
]
| x <- xs
]