packages feed

squeeze 1.0.4.2 → 1.0.4.4

raw patch · 15 files changed

+82/−77 lines, 15 filessetup-changed

Files

Setup.hs view
@@ -1,5 +1,5 @@ #!/usr/bin/env runhaskell -import qualified	Distribution.Simple+import qualified Distribution.Simple -main	= Distribution.Simple.defaultMain+main = Distribution.Simple.defaultMain
changelog view
@@ -93,5 +93,9 @@ 1.0.4.2 	* Improved the syntax of 'verbosity' in the usage-message. 	* Tested with 'haskell-platform-2013.2.0.0'.-	* Added a function 'Data.CommandOptions.subtractFile' to adjust 'Data.CommandOptions.CommandOptions', after removing a file from the problem; previously done incorrectly.-+	* Added a function 'Data.CommandOptions.subtractFile' to adjust 'Data.CommandOptions.CommandOptions' after removing a file from the problem; previously done incorrectly, causing an error when running with '+RTS -N2'.+1.0.4.3+	* Changed the value of '0/0' to '0' rather than '1' in 'Data.CommandOptions.subtractFile'.+1.0.4.4+	* Either replaced instances of '(<$>)' with 'fmap' to avoid ambiguity between "Control.Applicative" & "Prelude" which (from 'base-4.8') also exports this symbol, or hid the symbol when importing the "Prelude"..+	* In module "Main", redirected version-message to stderr.
debian/DEBIAN/control view
@@ -1,10 +1,11 @@ Package:	squeeze-Version:	1.0.4.2-1+Version:	1.0.4.4-1 Section:	utils Priority:	optional-Architecture:	i386+#Architecture:	i386+Architecture:	amd64 Depends:	libc6-Installed-size:	1825+Installed-size:	2448 Maintainer:	Dr. Alistair Ward <squeeze at functionalley dot eu> Provides: Homepage:	http://functionalley.eu
makefile view
@@ -1,4 +1,4 @@-# Copyright (C) 2010 Dr. Alistair Ward+# Copyright (C) 2010-2014 Dr. Alistair Ward # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by@@ -45,7 +45,7 @@ 	@$@ -i 'Reduce duplication' src/ +RTS -N  sdist:-	runhaskell Setup $@+	TAR_OPTIONS='--format=ustar' runhaskell Setup $@  check: sdist 	cabal upload --check --verbose=3 dist/*.tar.gz;
squeeze.cabal view
@@ -1,8 +1,8 @@ -- Package-properties Name:			squeeze-Version:		1.0.4.2+Version:		1.0.4.4 Cabal-Version:		>= 1.6-Copyright:		(C) 2010-2014 Dr. Alistair Ward+Copyright:		(C) 2010-2015 Dr. Alistair Ward License:		GPL License-file:		LICENSE Author:			Dr. Alistair Ward@@ -11,7 +11,7 @@ Build-Type:		Simple Description:		Returns progressively better subsets of the specified files, selected to fit into a limited space, without wasting more than the specific ratio. Category:		Utils-Tested-With:		GHC == 7.4, GHC == 7.6+Tested-With:		GHC == 7.4, GHC == 7.6, GHC == 7.10 Homepage:		http://functionalley.eu Maintainer:		squeeze <at> functionalley <dot> eu Bug-reports:		squeeze <at> functionalley <dot> eu@@ -56,7 +56,7 @@         toolshed >= 0.14,         unix -    GHC-options:	-Wall -O2+    GHC-options:	-Wall -O2 -fno-warn-tabs      if impl(ghc >= 7.4.1)         GHC-prof-options:	-prof -fprof-auto -fprof-cafs
squeeze.spec view
@@ -1,4 +1,4 @@-# Copyright (C) 2012-2013 Dr. Alistair Ward+# Copyright (C) 2012-2014 Dr. Alistair Ward # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by@@ -22,7 +22,7 @@  Summary:	Finds the optimal subset of the specified files, to fit into a limited space, with minimal wastage Name:		squeeze-Version:	1.0.4.2+Version:	1.0.4.4 Release:	1 License:	GPLv3 #From '/usr/share/doc/packages/rpm/GROUPS'.
src/Main.hs view
@@ -1,5 +1,5 @@ {--	Copyright (C) 2010-2013 Dr. Alistair Ward+	Copyright (C) 2010-2015 Dr. Alistair Ward  	This program is free software: you can redistribute it and/or modify 	it under the terms of the GNU General Public License as published by@@ -28,6 +28,7 @@  module Main(main) where +import Prelude hiding ((<$>), (<*>))	-- The "Prelude" from 'base-4.8' exports this symbol. import			Control.Applicative((<*>), (<$>)) import qualified	Control.Monad import qualified	Control.Monad.Writer@@ -39,7 +40,7 @@ import qualified	Distribution.Verbosity import qualified	Distribution.Version import qualified	Factory.Math.Probability-import qualified	Paths_squeeze			as Paths	--Either local stub, or package-instance autogenerated by 'Setup.hs build'.+import qualified	Paths_squeeze			as Paths	-- Either local stub, or package-instance autogenerated by 'Setup.hs build'. import qualified	Squeeze.Data.CommandOptions	as Data.CommandOptions import qualified	Squeeze.Data.File		as Data.File import qualified	Squeeze.Squeeze			as Squeeze@@ -58,10 +59,10 @@ import qualified	ToolShed.System.TimeAction  -- | Coerce the polymorphic data-type to concrete instance, in order that it's fields may be read from the command-line.-type CommandOptions'	= Data.CommandOptions.CommandOptions Rational	--'Double' would also be a suitable type-parameter.+type CommandOptions'	= Data.CommandOptions.CommandOptions Rational	-- 'Double' would also be a suitable type-parameter.  -- | Used to thread user-defined command-line options, though the list of functions which implement them.-type CommandLineAction	= CommandOptions' -> IO CommandOptions'	--Supplied as the type-argument to 'G.OptDescr'.+type CommandLineAction	= CommandOptions' -> IO CommandOptions'	-- Supplied as the type-argument to 'G.OptDescr'.  -- | On failure to parse the specified string, returns an explanatory error. read' :: Read a => String -> String -> a@@ -164,16 +165,15 @@ 			runQuickChecks _	= Test.QuickChecks.run >> System.Exit.exitWith System.Exit.ExitSuccess  			printVersion, printUsage :: IO (Data.CommandOptions.CommandOptions f)-			printVersion	= Text.Printf.printf "%s\n\n%s %s.\n%s.\n%s.\n%s %s.\n" packageName "Copyright (C) 2010-2013" author "This program comes with ABSOLUTELY NO WARRANTY" "This is free software, & you are welcome to redistribute it under certain conditions" "Written by" author >> System.Exit.exitWith System.Exit.ExitSuccess	where+			printVersion	= System.IO.hPutStrLn System.IO.stderr (Distribution.Text.display packageIdentifier ++ "\n\nCopyright (C) 2010-2015 " ++ author ++ ".\nThis program comes with ABSOLUTELY NO WARRANTY.\nThis is free software, and you are welcome to redistribute it under certain conditions.\n\nWritten by " ++ author ++ ".")	>> System.Exit.exitWith System.Exit.ExitSuccess	where 				packageIdentifier :: Distribution.Package.PackageIdentifier 				packageIdentifier	= Distribution.Package.PackageIdentifier {-					Distribution.Package.pkgName	= Distribution.Package.PackageName progName,	--CAVEAT: coincidentally.+					Distribution.Package.pkgName	= Distribution.Package.PackageName progName,	-- CAVEAT: coincidentally. 					Distribution.Package.pkgVersion	= Distribution.Version.Version (Data.Version.versionBranch Paths.version) [] 				} -				packageName, author :: String-				packageName	= Distribution.Text.display packageIdentifier-				author		= "Dr. Alistair Ward"+				author :: String+				author	= "Dr. Alistair Ward"  			printUsage	= Text.Printf.hPrintf System.IO.stderr "Usage:\t%s  %s\n\nEBNF argument-format:\n\t%-22s = %s;\n\t%-22s = %s;\n\t%-22s = %s;\n\t%-22s = %s;\n\t%-22s = %s;\n\t%-22s = %s;\n\t%-22s = %s;\n\t%-22s = %s;\n\t%-22s = %s;\n\nE.g.\n\t%s\n\t%s\n\t%s\n" ( 				G.usageInfo progName optDescrList@@ -194,7 +194,7 @@ 		(commandLineActions, nonOptions, [{-errors-}])	-> do 			commandOptions	<- Data.List.foldl' (>>=) ( 				return {-to IO-monad-} ToolShed.Defaultable.defaultValue-			 ) {-transform using CommandLineAction-mutators-} commandLineActions	--ie: do o1 <- CommandLineAction[0] commandOptions[0]; o2 <- CommandLineAction[1] o1; ...+			 ) {-transform using CommandLineAction-mutators-} commandLineActions	-- ie: do o1 <- CommandLineAction[0] commandOptions[0]; o2 <- CommandLineAction[1] o1; ...  			if not $ ToolShed.SelfValidate.isValid commandOptions 				then fail $ ToolShed.SelfValidate.getFirstError commandOptions
src/Squeeze/Control/Concurrent/DivideAndConquer.hs view
@@ -1,5 +1,5 @@ {--	Copyright (C) 2013 Dr. Alistair Ward+	Copyright (C) 2013-2015 Dr. Alistair Ward  	This program is free software: you can redistribute it and/or modify 	it under the terms of the GNU General Public License as published by@@ -33,6 +33,7 @@ 	divideAndConquer ) where +import Prelude hiding ((<$>), (<*>))	-- The "Prelude" from 'base-4.8' exports this symbol. import			Control.Applicative((<*>), (<$>)) import qualified	Control.Concurrent import qualified	Control.Concurrent.Chan
src/Squeeze/Data/CommandOptions.hs view
@@ -1,5 +1,5 @@ {--	Copyright (C) 2010 Dr. Alistair Ward+	Copyright (C) 2010-2014 Dr. Alistair Ward  	This program is free software: you can redistribute it and/or modify 	it under the terms of the GNU General Public License as published by@@ -64,9 +64,9 @@ instance Fractional f => ToolShed.Defaultable.Defaultable (CommandOptions f)	where 	defaultValue	= MkCommandOptions { 		getIncludeEmpty		= False,-		getMaximumBytes		= 4700000000,	--DVD-size; just under 4.4GiB.+		getMaximumBytes		= 4700000000,	-- DVD-size; just under 4.4GiB. 		getMaybeRandomSeed	= Nothing,-		getMinimumUsageRatio	= 99 / 100,	--99% full.+		getMinimumUsageRatio	= 99 / 100,	-- 99% full. 		getVerbosity		= Distribution.Verbosity.normal 	} @@ -80,8 +80,8 @@ -- | Smart constructor. mkCommandOptions 	:: (-		Ord ratio,-		Real ratio+		Ord	ratio,+		Real	ratio 	) 	=> Bool 	-> Data.File.FileSize@@ -108,14 +108,13 @@ subtractFile fileSize commandOptions 	| fileSize < 0		= error $ "Squeeze.Data.CommandOptions.subtractFile:\tnegative file-size=" ++ show fileSize 	| maximumBytes' < 0	= error $ "Squeeze.Data.CommandOptions.subtractFile:\tfile-size=" ++ show fileSize  ++ " > maximum=" ++ show maximumBytes-	| maximumBytes' == 0	= commandOptions {-		getMaximumBytes		= 0,-		getMinimumUsageRatio	= 1	-- CAVEAT: calculation below would yield 0 / 0.-	} 	| otherwise		= commandOptions { 		getMaximumBytes		= maximumBytes',-		getMinimumUsageRatio	= fromIntegral (max 0 $ deriveMinimumBytes commandOptions - fromIntegral fileSize) / fromIntegral maximumBytes'+		getMinimumUsageRatio	= if maximumBytes' == 0+			then 0	-- CAVEAT: the calculation below would otherwise attempt to evaluate 0 / 0.+			else fromIntegral (max 0 $ deriveMinimumBytes commandOptions - fileSize) / fromIntegral maximumBytes' 	} where+		maximumBytes, maximumBytes' :: Data.File.FileSize 		maximumBytes	= getMaximumBytes commandOptions 		maximumBytes'	= maximumBytes - fileSize 
src/Squeeze/Data/File.hs view
@@ -1,5 +1,5 @@ {--	Copyright (C) 2010-2013 Dr. Alistair Ward+	Copyright (C) 2010-2015 Dr. Alistair Ward  	This program is free software: you can redistribute it and/or modify 	it under the terms of the GNU General Public License as published by@@ -44,7 +44,6 @@ 	hasSizeBy ) where -import			Control.Applicative((<$>)) import			Control.Arrow((&&&)) import qualified	Control.Monad import qualified	Control.Monad.Writer@@ -61,7 +60,7 @@ type FilePathList	= [System.IO.FilePath]  -- | A type-synonym specifically to hold file-sizes (in bytes).-type FileSize		= Integer	--Matches the return-type of 'IO.hFileSize'.+type FileSize		= Integer	-- Matches the return-type of 'IO.hFileSize'.  -- | A type suitable for containing a file-path, qualified by the corresponding 'FileSize'. type FileSizeAndPath	= (FileSize, System.IO.FilePath)@@ -93,15 +92,15 @@ -} expandDirectory :: System.IO.FilePath -> IO FilePathList expandDirectory filePath	= do-	stat	<- System.Posix.Files.getFileStatus filePath	--CAVEAT: throws if the user is unauthorised, or the file is non-existent.+	stat	<- System.Posix.Files.getFileStatus filePath	-- CAVEAT: throws if the user is unauthorised, or the file is non-existent.  	if System.Posix.Files.isDirectory stat 		then System.Directory.getDirectoryContents filePath >>= fmap concat . mapM ( 			expandDirectory {-recurse-} . (filePath </>) {-qualify the path-} 		) . filter (-			`notElem` [".", ".."]	--Prevent infinite recursion.+			`notElem` [".", ".."]	-- Prevent infinite recursion. 		)-		else {-non-directory-} return {-to IO-monad-} [filePath]	--CAVEAT: this could include devices, pipes, sockets, symlinks ...+		else {-non-directory-} return {-to IO-monad-} [filePath]	-- CAVEAT: this could include devices, pipes, sockets, symlinks ...  {- | 	* Finds any file-paths which have been specified more than once.@@ -117,11 +116,11 @@ 	* CAVEAT: the size of a symlink, is that of the file to which it refers. -} findSize :: System.IO.FilePath -> IO FileSize-findSize filePath	= expandDirectory filePath >>= fmap aggregateSize . mapM (\f -> flip (,) f <$> System.IO.withFile f System.IO.ReadMode System.IO.hFileSize)+findSize filePath	= expandDirectory filePath >>= fmap aggregateSize . mapM (\f -> flip (,) f `fmap` System.IO.withFile f System.IO.ReadMode System.IO.hFileSize)  -- | Finds file-sizes. findSizes :: FilePathList -> IO [FileSizeAndPath]-findSizes	= uncurry (<$>) . (flip zip &&& mapM findSize)+findSizes	= uncurry fmap . (flip zip &&& mapM findSize)  -- | Sorts a list of 'FileSizeAndPath' by increasing size; ie. smallest first. orderByIncreasingSize :: [FileSizeAndPath] -> [FileSizeAndPath]
src/Squeeze/Squeeze.hs view
@@ -1,5 +1,5 @@ {--	Copyright (C) 2010-2013 Dr. Alistair Ward+	Copyright (C) 2010-2015 Dr. Alistair Ward  	This program is free software: you can redistribute it and/or modify 	it under the terms of the GNU General Public License as published by@@ -35,7 +35,6 @@ 	partitionEmptyFilesAndDistributeAndFindBestFit ) where -import			Control.Applicative((<$>)) import qualified	Control.Arrow import			Control.Arrow((&&&)) import qualified	Control.Concurrent@@ -70,16 +69,16 @@  ) . ( 	Data.FileCombination.nullFileCombination :  ) . nonEmptyCombinations minimumCombinationSize . uncurry zip . (-	id &&& Data.File.accumulateSize			--Associate the list of possible files with its accumulating size.+	id &&& Data.File.accumulateSize			-- Associate the list of possible files with its accumulating size.  ) . dropWhile (-	Data.File.hasSizeBy (> maximumCombinationSize)	--Remove files which individually exceed the maximum permissible; assuming they've been sorted by decreasing size.+	Data.File.hasSizeBy (> maximumCombinationSize)	-- Remove files which individually exceed the maximum permissible; assuming they've been sorted by decreasing size.  ) where 	nonEmptyCombinations :: Data.File.FileSize -> [(Data.File.FileSizeAndPath, Data.File.FileSize)] -> [Data.FileCombination.FileCombination] 	nonEmptyCombinations _ []	= [] 	nonEmptyCombinations minimumBytes ((fileSizeAndPath, aggregateSize) : remainder)-		| aggregateSize < minimumBytes	= []	--Even if all the files are selected, the minimum-size criterion won't be satisfied.+		| aggregateSize < minimumBytes	= []	-- Even if all the files are selected, the minimum-size criterion won't be satisfied. 		| otherwise			= Data.FileCombination.singleton fileSizeAndPath : foldr binaryChoice [] (-			nonEmptyCombinations (minimumBytes - Data.File.getSize fileSizeAndPath) remainder	--Recurse.+			nonEmptyCombinations (minimumBytes - Data.File.getSize fileSizeAndPath) remainder	-- Recurse. 		) 		where 			binaryChoice :: Data.FileCombination.FileCombination -> [Data.FileCombination.FileCombination] -> [Data.FileCombination.FileCombination]@@ -120,22 +119,22 @@ 	 in do 		Control.Monad.when (Data.CommandOptions.getVerbosity commandOptions' == maxBound) . System.IO.hPutStrLn System.IO.stderr $ "INFO: acceptable file-size interval " ++ show solutionSizeBounds ++ " bytes." -		return {-to IO-monad-} $ findBestFit solutionSizeBounds increasingFileSizeAndPathList	--Delegate the task to the single-threaded algorithm.+		return {-to IO-monad-} $ findBestFit solutionSizeBounds increasingFileSizeAndPathList	-- Delegate the task to the single-threaded algorithm. 	slave numCapabilities' commandOptions' (selectedFileSizeAndPath {-the smallest-} : remainingFileSizeAndPaths)	= let-		recurse	= slave $ numCapabilities' `div` 2	--Partially apply.+		recurse	= slave $ numCapabilities' `div` 2	-- Partially apply. 	 in do 		Control.Monad.when (Data.CommandOptions.getVerbosity commandOptions' == maxBound) . System.IO.hPutStrLn System.IO.stderr $ "INFO: " ++ show numCapabilities' ++ " CPU-cores => bisecting task into those, with & without " ++ show selectedFileSizeAndPath ++ "." -		fileCombinationsExcludingSelected	<- recurse commandOptions' {-i.e the original space-} remainingFileSizeAndPaths	--This is about half the total task.+		fileCombinationsExcludingSelected	<- recurse commandOptions' {-i.e the original space-} remainingFileSizeAndPaths	-- This is about half the total task. -		let	-			commandOptions''	= Data.CommandOptions.subtractFile (Data.File.getSize selectedFileSizeAndPath) commandOptions' --Reduce the requirements by the size of the selected file.+		let+			commandOptions''	= Data.CommandOptions.subtractFile (Data.File.getSize selectedFileSizeAndPath) commandOptions' -- Reduce the requirements by the size of the selected file.  		if Data.CommandOptions.getMaximumBytes commandOptions'' < 0-			then return {-to IO-monad-} fileCombinationsExcludingSelected	--The selected file won't fit.+			then return {-to IO-monad-} fileCombinationsExcludingSelected	-- The selected file won't fit. 			else map (-				Data.FileCombination.prepend selectedFileSizeAndPath	--Prepend the selected file to all file-combinations.-			) <$> recurse commandOptions'' remainingFileSizeAndPaths >>= Control.Concurrent.DivideAndConquer.divideAndConquer Data.FileCombination.risingMergeByAggregateFileSize fileCombinationsExcludingSelected	--Merge the part-solutions.+				Data.FileCombination.prepend selectedFileSizeAndPath	-- Prepend the selected file to all file-combinations.+			) `fmap` recurse commandOptions'' remainingFileSizeAndPaths >>= Control.Concurrent.DivideAndConquer.divideAndConquer Data.FileCombination.risingMergeByAggregateFileSize fileCombinationsExcludingSelected	-- Merge the part-solutions.  in Control.Concurrent.getNumCapabilities >>= (\numCapabilities -> slave numCapabilities commandOptions $ Data.File.orderByIncreasingSize fileSizeAndPathList)  {- |@@ -161,7 +160,7 @@ 					Data.FileCombination.getFilePathList	= emptyFilePathCombination ++ Data.FileCombination.getFilePathList fileCombination 				} 			) $ Data.List.subsequences {-find all combinations-} emptyFiles-		 ) <$> nonEmptyFileCombinations+		 ) `fmap` nonEmptyFileCombinations 	| otherwise {-exclude empty files-}			= do 		Control.Monad.unless (Data.CommandOptions.getVerbosity commandOptions == minBound || null emptyFiles) . System.IO.hPutStrLn System.IO.stderr $ "WARNING: rejecting empty files; " ++ show emptyFiles ++ "." @@ -173,5 +172,5 @@ 	where 		printStatistics l				= Control.Monad.unless (Data.CommandOptions.getVerbosity commandOptions == minBound || null l) . System.IO.hPutStrLn System.IO.stderr $ "INFO: file-(count, aggregate size, mean, standard-deviation); " ++ show (Data.File.getFileSizeStatistics l :: (Int, Data.File.FileSize, Float, Float)) ++ "." 		(emptyFiles, nonEmptyFilePathAndSizeList)	= Control.Arrow.first (map Data.File.getPath) $ Data.List.partition (Data.File.hasSizeBy (== 0)) fileSizeAndPathList-		nonEmptyFileCombinations			= distributeAndFindBestFit commandOptions nonEmptyFilePathAndSizeList	--Delegate.+		nonEmptyFileCombinations			= distributeAndFindBestFit commandOptions nonEmptyFilePathAndSizeList	-- Delegate. 
src/Squeeze/Test/Data/CommandOptions.hs view
@@ -1,6 +1,6 @@ {-# OPTIONS_GHC -fno-warn-orphans #-} {--	Copyright (C) 2013 Dr. Alistair Ward+	Copyright (C) 2013-2015 Dr. Alistair Ward  	This program is free software: you can redistribute it and/or modify 	it under the terms of the GNU General Public License as published by@@ -27,6 +27,7 @@ 	CommandOptions ) where +import Prelude hiding ((<$>), (<*>))	-- The "Prelude" from 'base-4.8' exports this symbol. import			Control.Applicative((<$>), (<*>)) import qualified	Test.QuickCheck import qualified	Squeeze.Data.CommandOptions	as Data.CommandOptions@@ -40,9 +41,9 @@ 	Test.QuickCheck.Arbitrary	ratio  ) => Test.QuickCheck.Arbitrary (Data.CommandOptions.CommandOptions ratio)	where 	arbitrary	= Data.CommandOptions.mkCommandOptions <$> Test.QuickCheck.arbitrary {-includeEmpty-} <*> (-		abs <$> Test.QuickCheck.arbitrary			--maximumBytes.+		abs <$> Test.QuickCheck.arbitrary			-- maximumBytes. 	 ) <*> Test.QuickCheck.arbitrary {-maybeRandomSeed-} <*> (-		recip . succ . abs <$> Test.QuickCheck.arbitrary	--minimumUsageRatio.+		recip . succ . abs <$> Test.QuickCheck.arbitrary	-- minimumUsageRatio. 	 ) <*> Test.QuickCheck.arbitrary {-verbosity-}  -- | Defines a concrete type for testing.
src/Squeeze/Test/Data/FileCombinations.hs view
@@ -1,6 +1,6 @@ {-# OPTIONS_GHC -fno-warn-orphans #-} {--	Copyright (C) 2010 Dr. Alistair Ward+	Copyright (C) 2010-2015 Dr. Alistair Ward  	This program is free software: you can redistribute it and/or modify 	it under the terms of the GNU General Public License as published by@@ -26,7 +26,6 @@ 	quickChecks ) where -import			Control.Applicative((<$>)) import			Control.Arrow((&&&)) import qualified	Data.List import qualified	Squeeze.Data.FileCombination	as Data.FileCombination@@ -34,8 +33,8 @@  instance Test.QuickCheck.Arbitrary Data.FileCombination.FileCombination	where 	arbitrary	= do-		filePathList		<- Data.List.nub <$> (Test.QuickCheck.elements [0 .. 99] >>= Test.QuickCheck.vector)-		aggregateFileSize	<- Test.QuickCheck.elements [0 .. Data.List.genericLength filePathList]	--Assume files of size either zero or one byte.+		filePathList		<- Data.List.nub `fmap` (Test.QuickCheck.elements [0 .. 99] >>= Test.QuickCheck.vector)+		aggregateFileSize	<- Test.QuickCheck.elements [0 .. Data.List.genericLength filePathList]	-- Assume files of size either zero or one byte.  		return $ Data.FileCombination.mkFileCombination aggregateFileSize filePathList @@ -46,4 +45,6 @@ 	prop_risingFilter	= Test.QuickCheck.label "prop_risingFilter" . uncurry (==) . (id &&& Data.List.sort) . map Data.FileCombination.getAggregateFileSize . Data.FileCombination.risingFilter 0 	prop_risingFilter'	= Test.QuickCheck.label "prop_risingFilter'" . uncurry (==) . (id &&& Data.FileCombination.risingFilter 0) . Data.List.sortBy Data.FileCombination.comparingAggregateFileSize -	prop_risingMergeByAggregateFileSize	= Test.QuickCheck.label "prop_risingMergeByAggregateFileSize" . uncurry (==) . (id &&& map head . Data.List.group . uncurry Data.FileCombination.risingMergeByAggregateFileSize . (id &&& id)) . Data.FileCombination.risingFilter 0+	prop_risingMergeByAggregateFileSize	= Test.QuickCheck.label "prop_risingMergeByAggregateFileSize" . uncurry (==) . (+		id &&& map head . Data.List.group . uncurry Data.FileCombination.risingMergeByAggregateFileSize . (id &&& id)+	 ) . Data.FileCombination.risingFilter 0
src/Squeeze/Test/Performance.hs view
@@ -53,18 +53,18 @@ 	-> IO [Data.FileCombination.FileCombination] run commandOptions fileCount probabilityDistribution	= do 	randomGen	<- Data.Maybe.maybe System.Random.getStdGen {-use the global random-number generator-} (-		return {-to IO-monad-} . System.Random.mkStdGen	--Seed the random-number generator as specified.-	 ) $ Data.CommandOptions.getMaybeRandomSeed commandOptions	--Select a random-number generator.+		return {-to IO-monad-} . System.Random.mkStdGen	-- Seed the random-number generator as specified.+	 ) $ Data.CommandOptions.getMaybeRandomSeed commandOptions	-- Select a random-number generator.  	let 		(acceptedFileSizeAndPathList, logFile)	= Control.Monad.Writer.runWriter . Data.File.selectSuitableFileSizes (-			<= Data.CommandOptions.getMaximumBytes commandOptions	--This may reduce the requested number of files, but compensating distorts the requested distribution.+			<= Data.CommandOptions.getMaximumBytes commandOptions	-- This may reduce the requested number of files, but compensating distorts the requested distribution. 		 ) . (-			`zip` map show [0 :: Int ..]	--Construct a Data.File.FileSizeAndPath, by using a counter as the file-name.+			`zip` map show [0 :: Int ..]	-- Construct a Data.File.FileSizeAndPath, by using a counter as the file-name. 		 ) . take fileCount . filter (-			>= 0				--A suitable distribution shouldn't generate negative file-sizes.+			>= 0				-- A suitable distribution shouldn't generate negative file-sizes. 		 ) . map (-			ceiling :: Double -> Integer	--File-sizes are integral.+			ceiling :: Double -> Integer	-- File-sizes are integral. 		 ) $ Factory.Math.Probability.generatePopulation probabilityDistribution randomGen  	Control.Monad.when (Data.CommandOptions.getVerbosity commandOptions > minBound) . System.IO.hPutStrLn System.IO.stderr $ Data.List.intercalate "\n" logFile
src/Squeeze/Test/Squeeze.hs view
@@ -39,7 +39,7 @@ quickChecks :: IO () quickChecks	= Test.QuickCheck.quickCheck `mapM_` [prop_totalCombinations, prop_fileSizeBounds, prop_allFiles, prop_monotonicFileSize, prop_uniqueFileNames]	where 	mkFileSizeAndPathList :: (Integral i, Show i) => [i] -> [Data.File.FileSizeAndPath]-	mkFileSizeAndPathList	= take 12 . Data.List.nubBy (ToolShed.Data.List.equalityBy snd) . map (toInteger . abs &&& show)	--CAVEAT: may be shorter than requested.+	mkFileSizeAndPathList	= take 12 . Data.List.nubBy (ToolShed.Data.List.equalityBy snd) . map (toInteger . abs &&& show)	-- CAVEAT: may be shorter than requested.  	prop_totalCombinations, prop_fileSizeBounds, prop_allFiles, prop_monotonicFileSize, prop_uniqueFileNames :: [Integer] -> Test.QuickCheck.Property 	prop_totalCombinations integers =  Test.QuickCheck.label "prop_totalCombinations" $ (length . Data.List.nub . Squeeze.findCombinations (0, fromIntegral (maxBound :: Int)) $ Data.File.orderByDecreasingSize fileSizeAndPathList) == 2 ^ length fileSizeAndPathList where@@ -51,8 +51,8 @@ 		fileSizeBounds :: Factory.Data.Interval.Interval Data.File.FileSize 		fileSizeBounds	= (minimumBytes, maximumBytes)	where 			maximumBytes, minimumBytes :: Data.File.FileSize-			maximumBytes	= round $ fromIntegral (Data.File.aggregateSize fileSizeAndPathList) / (4.0 :: Double)	--Arbitrarily.-			minimumBytes	= maximumBytes `div` 2	--Arbitrarily.+			maximumBytes	= round $ fromIntegral (Data.File.aggregateSize fileSizeAndPathList) / (4.0 :: Double)	-- Arbitrarily.+			minimumBytes	= maximumBytes `div` 2	-- Arbitrarily.  	prop_allFiles integers	= Test.QuickCheck.label "prop_allFiles" . (== aggregateSize) . last . map Data.FileCombination.getAggregateFileSize $ Squeeze.findBestFit (Factory.Data.Interval.precisely aggregateSize) fileSizeAndPathList	where 		fileSizeAndPathList	= mkFileSizeAndPathList integers