@@ -14,17 +14,12 @@ import Control.Monad ( guard )
1414import Control.Monad.ST ( runST )
1515
1616import Data.Constraint
17−#if __GLASGOW_HASKELL__ < 800
18−import Data.Proxy
19−#endif
2017import qualified Data.Vector.Storable as VS
2118import qualified Data.Vector.Storable.Mutable as VS ( write )
2219import Data.Singletons
2320import Data.Singletons.Prelude.List
2421import Data.Singletons.TypeLits
2522
26−-- import Data.Type.Equality
27−
2823import Hedgehog
2924import qualified Hedgehog.Gen as Gen
3025import Hedgehog.Internal.Source
@@ -32,7 +27,15 @@ import Hedgehog.Internal.Property ( failWith )
3227
3328import Grenade
3429
30+#if MIN_VERSION_base(4,11,0)
31+import GHC.TypeLits hiding (natVal)
32+#else
3533import GHC.TypeLits
34+#endif
35+#if MIN_VERSION_base(4,9,0)
36+import Data.Kind (Type)
37+#endif
38+
3639import GHC.TypeLits.Witnesses
3740import Test.Hedgehog.Compat
3841import Test.Hedgehog.TypeLits
@@ -43,7 +46,7 @@ import Numeric.LinearAlgebra ( flatten )
4346import Numeric.LinearAlgebra.Static ( extract, norm_Inf )
4447import Unsafe.Coerce
4548
46−data SomeNetwork :: * where
49+data SomeNetwork :: Type where
4750 SomeNetwork :: ( SingI shapes, SingI (Head shapes), SingI (Last shapes), Show (Network layers shapes) ) => Network layers shapes -> SomeNetwork
4851
4952instance Show SomeNetwork where
@@ -53,7 +56,7 @@ instance Show SomeNetwork where
5356--
5457-- This is slightly insane for a few reasons. Everything must be wrapped up
5558-- in a SomeNetwork.
56−genNetwork :: Monad m => Gen.Gen m SomeNetwork
59+genNetwork :: Gen SomeNetwork
5760genNetwork =
5861 Gen.recursive Gen.choice [
5962 do SomeSing ( r :: Sing final ) <- genShape
@@ -74,8 +77,9 @@ genNetwork =
7477 , pure (SomeNetwork (Elu :~> rest :: Network ( Elu ': layers ) ( h ': h ': hs )))
7578 , pure (SomeNetwork (Softmax :~> rest :: Network ( Softmax ': layers ) ( h ': h ': hs )))
7679 , do -- Reshape to two dimensions
77− let divisors n = 1 : [x | x <- [2..(n-1)], n `rem` x == 0]
78− let len = natVal l
80+ let divisors :: Integer -> [Integer]
81+ divisors n = 1 : [x | x <- [2..(n-1)], n `rem` x == 0]
82+ let len = fromIntegral $ natVal l
7983 rs <- Gen.element $ divisors len
8084 let cs = len `quot` rs
8185 case ( someNatVal rs, someNatVal cs, someNatVal len ) of
@@ -96,8 +100,8 @@ genNetwork =
96100 , do -- Build a convolution layer with one filter output
97101 -- Figure out some kernel sizes which work for this layer
98102 -- There must be a better way than this...
99− let output_r = natVal r
100− let output_c = natVal c
103+ let output_r = fromIntegral $ natVal r
104+ let output_c = fromIntegral $ natVal c
101105
102106 let ok extent kernel = [stride | stride <- [ 1 .. extent ], (extent - kernel) `mod` stride == 0]
103107
@@ -136,8 +140,8 @@ genNetwork =
136140 , do -- Build a convolution layer with one filter output
137141 -- Figure out some kernel sizes which work for this layer
138142 -- There must be a better way than this...
139− let output_r = natVal r
140− let output_c = natVal c
143+ let output_r = fromIntegral $ natVal r
144+ let output_c = fromIntegral $ natVal c
141145
142146 let ok extent kernel = [stride | stride <- [ 1 .. extent ], (extent - kernel) `mod` stride == 0]
143147
@@ -178,8 +182,8 @@ genNetwork =
178182 pure (SomeNetwork (conv :~> rest :: Network ( Convolution channels 1 kernelRows kernelCols strideRows strideCols ': layers ) ( ('D3 inRows inCols channels) ': h ': hs )))
179183 _ -> Gen.discard -- Can't occur
180184 , do -- Build a Pooling layer
181− let output_r = natVal r
182− let output_c = natVal c
185+ let output_r = fromIntegral $ natVal r
186+ let output_c = fromIntegral $ natVal c
183187
184188 let ok extent kernel = [stride | stride <- [ 1 .. extent ], (extent - kernel) `mod` stride == 0]
185189
@@ -215,8 +219,8 @@ genNetwork =
215219 pure (SomeNetwork (Pooling :~> rest :: Network ( Pooling kernelRows kernelCols strideRows strideCols ': layers ) ( ('D2 inRows inCols) ': h ': hs )))
216220 _ -> Gen.discard -- Can't occur
217221 , do -- Build a Pad layer
218− let output_r = natVal r
219− let output_c = natVal c
222+ let output_r = fromIntegral $ natVal r
223+ let output_c = fromIntegral $ natVal c
220224
221225 pad_left <- choose 0 (output_r - 1)
222226 pad_right <- choose 0 (output_r - 1 - pad_left)
@@ -242,8 +246,8 @@ genNetwork =
242246 pure (SomeNetwork (Pad :~> rest :: Network ( Pad padLeft padTop padRight padBottom ': layers ) ( ('D2 inputRows inputColumns) ': h ': hs )))
243247 _ -> Gen.discard -- Can't occur
244248 , do -- Build a Crop layer
245− let output_r = natVal r
246− let output_c = natVal c
249+ let output_r = fromIntegral $ natVal r
250+ let output_c = fromIntegral $ natVal c
247251
248252 crop_left <- choose 0 10
249253 crop_right <- choose 0 10
@@ -275,9 +279,9 @@ genNetwork =
275279 , do -- Build a convolution layer with one filter output
276280 -- Figure out some kernel sizes which work for this layer
277281 -- There must be a better way than this...
278− let output_r = natVal r
279− let output_c = natVal c
280− let output_f = natVal f
282+ let output_r = fromIntegral $ natVal r
283+ let output_c = fromIntegral $ natVal c
284+ let output_f = fromIntegral $ natVal f
281285
282286 let ok extent kernel = [stride | stride <- [ 1 .. extent ], (extent - kernel) `mod` stride == 0]
283287
@@ -318,9 +322,9 @@ genNetwork =
318322 pure (SomeNetwork (conv :~> rest :: Network ( Convolution channels filters kernelRows kernelCols strideRows strideCols ': layers ) ( ('D3 inRows inCols channels) ': h ': hs )))
319323 _ -> Gen.discard -- Can't occur
320324 , do -- Build a Pooling layer
321− let output_r = natVal r
322− let output_c = natVal c
323− let output_f = natVal f
325+ let output_r = fromIntegral $ natVal r
326+ let output_c = fromIntegral $ natVal c
327+ let output_f = fromIntegral $ natVal f
324328
325329 let ok extent kernel = [stride | stride <- [ 1 .. extent ], (extent - kernel) `mod` stride == 0]
326330
@@ -359,9 +363,9 @@ genNetwork =
359363 pure (SomeNetwork (Pooling :~> rest :: Network ( Pooling kernelRows kernelCols strideRows strideCols ': layers ) ( ('D3 inRows inCols filters) ': h ': hs )))
360364 _ -> Gen.discard -- Can't occur
361365 , do -- Build a Pad layer
362− let output_r = natVal r
363− let output_c = natVal c
364− let output_f = natVal f
366+ let output_r = fromIntegral $ natVal r
367+ let output_c = fromIntegral $ natVal c
368+ let output_f = fromIntegral $ natVal f
365369
366370 pad_left <- choose 0 (output_r - 1)
367371 pad_right <- choose 0 (output_r - 1 - pad_left)
@@ -389,9 +393,9 @@ genNetwork =
389393 pure (SomeNetwork (Pad :~> rest :: Network ( Pad padLeft padTop padRight padBottom ': layers ) ( ('D3 inputRows inputColumns filters) ': h ': hs )))
390394 _ -> Gen.discard -- Can't occur
391395 , do -- Build a Crop layer
392− let output_r = natVal r
393− let output_c = natVal c
394− let output_f = natVal f
396+ let output_r = fromIntegral $ natVal r
397+ let output_c = fromIntegral $ natVal c
398+ let output_f = fromIntegral $ natVal f
395399
396400 crop_left <- choose 0 10
397401 crop_right <- choose 0 10
@@ -438,13 +442,13 @@ prop_auto_diff = withDiscards 1000 . withTests 10000 . property $ do
438442 result ~~~ expected
439443
440444-- Make a shape where all are 0 except for 1 value, which is 1.
441−oneUp :: forall shape m. ( Monad m, SingI shape ) => Gen.Gen m (S shape)
445+oneUp :: forall shape. ( SingI shape ) => Gen (S shape)
442446oneUp =
443447 case ( sing :: Sing shape ) of
444448 D1Sing SNat ->
445449 let x = 0 :: S ( shape )
446450 in case x of
447− ( S1D x' ) -> do
451+ ( S1D x' ) -> do
448452 let ex = extract x'
449453 let len = VS.length ex
450454 ix <- choose 0 (len - 1)
@@ -456,7 +460,7 @@ oneUp =
456460 D2Sing SNat SNat ->
457461 let x = 0 :: S ( shape )
458462 in case x of
459− ( S2D x' ) -> do
463+ ( S2D x' ) -> do
460464 let ex = flatten ( extract x' )
461465 let len = VS.length ex
462466 ix <- choose 0 (len - 1)
@@ -468,7 +472,7 @@ oneUp =
468472 D3Sing SNat SNat SNat ->
469473 let x = 0 :: S ( shape )
470474 in case x of
471− ( S3D x' ) -> do
475+ ( S3D x' ) -> do
472476 let ex = flatten ( extract x' )
473477 let len = VS.length ex
474478 ix <- choose 0 (len - 1)
@@ -482,7 +486,7 @@ maxVal ( S1D x ) = norm_Inf x
482486maxVal ( S2D x ) = norm_Inf x
483487maxVal ( S3D x ) = norm_Inf x
484488
485−(~~~) :: (Monad m, HasCallStack) => Double -> Double -> Test m ()
489+(~~~) :: (Monad m, HasCallStack) => Double -> Double -> PropertyT m ()
486490(~~~) x y =
487491 if abs (x - y) < 2e-5 then
488492 success