-- -- (C) Susumu Katayama -- module MagicHaskeller.RunAnalytical( -- | This module provides analytically-generate-and-test synthesis, i.e. synthesis by filtration of analytically generated (many) expressions. -- Actions whose name ends with F use random testing filter (like 'MagicHaskeller.filterThenF') in order to reduce the number of expressions. -- -- ATTENTION: This module is supposed to be used under GHCi environment. Currently it is known not to work when executed as an a.out. -- Also, this module is tested only on Linux, and does not work with Windows. Another point is that currently functions in this module only -- work with known types appearing in 'MagicHaskeller.CoreLang.defaultPrimitives'. -- ** Re-exported modules module MagicHaskeller, module MagicHaskeller.ExecuteAPI610, module MagicHaskeller.Analytical, {- -- ** Synthesizers which will be able to be used with any types but currently do not work with unknown types. -- *** All in one actions quickStartC, quickStartCF, -- | 'filterGet1' and its friends can be used to synthesize one expression satisfying the given condition. For example, -- >>> session <- prepareAPI [] -- >>> filterGet1_ session $(c [d| f [] = 0; f [a] = 1; f [a,b] = 2 |]) (\f -> f "foobar" == 6) -- > \a -> let fa (b@([])) = 0 -- > fa (b@(_ : d)) = succ (fa d) -- > in fa a filterGet1_, filterGet1, filterGet1BK, -- | Unlike 'filterGet1' and its friends, the following three functions do not print anything but only return results silently. getFilt, getFiltF, getAll, -} {- -- ** Synthesizers which are easier to use that can be used only with types appearing in 'MagicHaskeller.CoreLang.defaultPrimitives' -} -- | All in one actions quickStart, quickStartF, -- | 'filterGet1' and its friends can be used to synthesize one expression satisfying the given condition. For example, {- -- *** counterparts to 'filterGet1_', 'filterGet1', and 'filterGet1BK' -} filterGetOne_, filterGetOne, filterGetOneBK, -- | Unlike 'filterGetOne' and its friends, the following three functions do not print anything but only return results silently. {- -- *** counterparts to 'getFilt', 'getFiltF', and 'getAll' -} synthFilt, synthFiltF, synthAll, {- -- *** counterpart to 'noBK' -} -- | 'noBKQ' can be used as the background knowledge for showing that no background knowledge functions are used. noBKQ ) where import MagicHaskeller import MagicHaskeller.ExecuteAPI610 -- use ExecuteAPI for GHC 6.8.* and below import MagicHaskeller.Analytical import Language.Haskell.TH import HscTypes(HscEnv) import MagicHaskeller.Classification(Filtrable) import System.IO.Unsafe import MagicHaskeller.GetTime import System.IO prepare = prepareAPI [] ["MagicHaskeller.RunAnalytical"] quickStartC :: (Typeable a) => SplicedPrims -- ^ target I/O pairs -> SplicedPrims -- ^ I/O pairs for background knowledge functions -> (a -> Bool) -- ^ test function -> IO () quickStartC tgt bk pred = do session <- prepare tss <- getFilt session tgt bk pred pprs tss quickStartCF :: (Filtrable a, Typeable a) => SplicedPrims -- ^ target I/O pairs -> SplicedPrims -- ^ I/O pairs for background knowledge functions -> (a -> Bool) -- ^ test function -> IO () quickStartCF tgt bk pred = do session <- prepare tss <- getFiltF session tgt bk pred pprs tss filterGet1_ :: (Typeable a) => HscEnv -- ^ session in which synthesized expressions are run -> SplicedPrims -- ^ target I/O pairs -> (a -> Bool) -- ^ test function -> IO () filterGet1_ s t p = filterGet1 s t p >> return () filterGet1 :: (Typeable a) => HscEnv -- ^ session in which synthesized expressions are run -> SplicedPrims -- ^ target I/O pairs -> (a -> Bool) -- ^ test function -> IO (Every a) filterGet1 session tgt = filterGet1BK session tgt noBK filterGet1BK :: (Typeable a) => HscEnv -- ^ session in which synthesized expressions are run -> SplicedPrims -- ^ target I/O pairs -> SplicedPrims -- ^ I/O pairs for background knowledge functions -> (a -> Bool) -- ^ test function -> IO (Every a) filterGet1BK session tgt bk predicate = do tss <- getFilt session tgt bk predicate putStrLn $ pprint $ fst $ head $ concat tss return tss getFilt :: (Typeable a) => HscEnv -- ^ session in which synthesized expressions are run -> SplicedPrims -- ^ target I/O pairs -> SplicedPrims -- ^ I/O pairs for background knowledge functions -> (a -> Bool) -- ^ test function -> IO (Every a) getFilt session tgt bk pred = filterThen pred =<< getAll session tgt bk getFiltF :: (Filtrable a, Typeable a) => HscEnv -- ^ session in which synthesized expressions are run -> SplicedPrims -- ^ target I/O pairs -> SplicedPrims -- ^ I/O pairs for background knowledge functions -> (a -> Bool) -- ^ test function -> IO (Every a) getFiltF session tgt bk pred = filterThenF pred =<< getAll session tgt bk getAll :: (Typeable a) => HscEnv -- ^ session in which synthesized expressions are run -> SplicedPrims -- ^ target I/O pairs -> SplicedPrims -- ^ I/O pairs for background knowledge functions -> IO (Every a) getAll session tgt bk = thExpssToEvery session (getManyTyped tgt bk) -- Functions appearing from here are easier to use, but they work only for limited types, included in 'defaultPrimitives'. noBKQ :: Q [Dec] noBKQ = return [] -- main = quickStart (return [rev]) noBKQ (\f -> f "abcdef" == "fedcba") {- main = quickStart [d| f :: Int->Int; f 0 = 0; f 1 = 3; f 2 = 6 |] noBKQ (\f -> f (10::Int) == (30::Int)) -} {- main = quickStart [d| f::[a] -> Int; f [] = 0; f [a] = 3; f [a,b] = 6 |] noBKQ (\f -> f "hogehoge" == (24::Int)) -} {- main = quickStart [d| f::[a] -> a; f [a] = a; f [a,b] = b; f [a,b,c] = c |] noBKQ (\f -> f "hogehoge" == 'e') -} -- | Example of 'quickStart' -- -- >>> quickStart [d| f [] = 0; f [a] = 1 |] noBKQ (\f -> f "12345" == 5) -- > \a -> let fa (b@([])) = 0 -- > fa (b@(c : d)) = succ (fa d) -- > in fa a :: forall t2 . [t2] -> Int -- > ^CInterrupted. quickStart :: (Typeable a) => Q [Dec] -- ^ target I/O pairs -> Q [Dec] -- ^ I/O pairs for background knowledge functions -> (a -> Bool) -- ^ test function -> IO () quickStart iops bk pred = do session <- prepare tss <- synthFilt session iops bk pred pprs tss quickStartF :: (Filtrable a, Typeable a) => Q [Dec] -- ^ target I/O pairs -> Q [Dec] -- ^ I/O pairs for background knowledge functions -> (a -> Bool) -- ^ test function -> IO () quickStartF iops bk pred = do session <- prepare tss <- synthFiltF session iops bk pred pprs tss batchExample = do session <- prepare let f = filterGetOne_ session batchWrite "example.dat" [ f [d| reverse [] = []; reverse [a] = [a]; reverse [a,b] = [b,a]; reverse [a,b,c] = [c,b,a] |] (\r -> r "abcd" == "dcba") , f [d| switch [] = []; switch [a] = [a]; switch [a,b] = [b,a]; switch [a,b,c] = [c,b,a]; switch [a,b,c,d] = [d,b,c,a]; |] (\s -> s "abcde" == "ebcda") ] filterGetOne_ s t p = filterGetOne s t p >> return () filterGetOne :: (Typeable a) => HscEnv -- ^ session in which synthesized expressions are run -> Q [Dec] -- ^ target I/O pairs -> (a -> Bool) -- ^ test function -> IO (Every a) filterGetOne session tgt = filterGetOneBK session tgt [d| {} |] filterGetOneBK :: (Typeable a) => HscEnv -- ^ session in which synthesized expressions are run -> Q [Dec] -- ^ target I/O pairs -> Q [Dec] -- ^ I/O pairs for background knowledge functions -> (a -> Bool) -- ^ test function -> IO (Every a) filterGetOneBK session tgt bk predicate = do tss <- synthFilt session tgt bk predicate putStrLn $ pprint $ fst $ head $ concat tss return tss synthFilt :: (Typeable a) => HscEnv -- ^ session in which synthesized expressions are run -> Q [Dec] -- ^ target I/O pairs -> Q [Dec] -- ^ I/O pairs for background knowledge functions -> (a -> Bool) -- ^ test function -> IO (Every a) synthFilt session tgt bk pred = filterThen pred =<< synthAll session tgt bk synthFiltF :: (Filtrable a, Typeable a) => HscEnv -- ^ session in which synthesized expressions are run -> Q [Dec] -- ^ target I/O pairs -> Q [Dec] -- ^ I/O pairs for background knowledge functions -> (a -> Bool) -- ^ test function -> IO (Every a) synthFiltF session tgt bk pred = filterThenF pred =<< synthAll session tgt bk synthAll :: (Typeable a) => HscEnv -- ^ session in which synthesized expressions are run -> Q [Dec] -- ^ target I/O pairs -> Q [Dec] -- ^ I/O pairs for background knowledge functions -> IO (Every a) synthAll session tgt bk = do tgtdecs <- runQ tgt bkdecs <- runQ bk thExpssToEvery session (synthTyped tgtdecs bkdecs) thExpssToEvery :: HscEnv -> [[Exp]] -> IO (Every a) thExpssToEvery session ess = return $ map (map (\e -> (e, unsafePerformIO $ executeTHExp session e))) ess -- thExpssToEvery session ess = mapM (mapM (\e -> fmap ((,) e) $ executeTHExp session e)) ess -- これだとダメ. unsafeInterleaveIOをうまく使う手もあるのかも.