{- $Id: AFRPTestsPSwitch.hs,v 1.2 2003/11/10 21:28:58 antony Exp $ ****************************************************************************** * A F R P * * * * Module: AFRPTestsPSwitch * * Purpose: Test cases for pSwitchB and dpSwitchB * * Authors: Antony Courtney and Henrik Nilsson * * * * Copyright (c) Yale University, 2003 * * * ****************************************************************************** -} module AFRPTestsPSwitch ( pswitch_tr, pswitch_trs, pswitch_st0, pswitch_st0r, pswitch_st1, pswitch_st1r ) where import Data.List (findIndex) import FRP.Yampa import FRP.Yampa.Internals (Event(NoEvent, Event)) import AFRPTestsCommon ------------------------------------------------------------------------------ -- Test cases for pSwitchB and dpSwitchB ------------------------------------------------------------------------------ pswitch_inp1 = deltaEncode 0.1 [0.0, 0.5 ..] whenFstGE :: Ord a => a -> c -> SF (a, b) (Event c) whenFstGE a c = arr fst >>> arr (>= a) >>> edge >>> arr (`tag` c) pswitch_t0 :: [[Double]] pswitch_t0 = take 20 $ embed sf pswitch_inp1 where sf = pSwitchB [] (whenFstGE 1.25 10.0) $ \sfs x -> pSwitchB (integral:sfs) (whenFstGE 3.75 10.0) $ \sfs x -> pSwitchB ((integral>>>arr(+x)):sfs)(whenFstGE 5.25 20.0) $ \sfs x-> pSwitchB ((integral>>>arr(+x)):sfs)(whenFstGE 7.25 20.0) $ \sfs _-> parB (take 2 sfs) pswitch_t0r = [[], -- 0.0 [], -- 0.5 [], -- 1.0 [0.0], -- 1.5 [0.15], -- 2.0 [0.35], -- 2.5 [0.60], -- 3.0 [0.90], -- 3.5 [10.00, 1.25], -- 4.0 [10.40, 1.65], -- 4.5 [10.85, 2.10], -- 5.0 [20.00, 11.35, 2.60], -- 5.5 [20.55, 11.90, 3.15], -- 6.0 [21.15, 12.50, 3.75], -- 6.5 [21.80, 13.15, 4.40], -- 7.0 [22.50, 13.85], -- 7.5 [23.25, 14.60], -- 8.0 [24.05, 15.40], -- 8.5 [24.90, 16.25], -- 9.0 [25.80, 17.15]] -- 9.5 pswitch_t1 :: [[Double]] pswitch_t1 = take 20 $ embed sf pswitch_inp1 where sf = dpSwitchB [] (whenFstGE 1.25 10.0) $ \sfs x -> dpSwitchB (integral:sfs) (whenFstGE 3.75 10.0) $ \sfs x -> dpSwitchB ((integral>>>arr(+x)):sfs)(whenFstGE 5.25 20.0)$ \sfs x-> dpSwitchB ((integral>>>arr(+x)):sfs)(whenFstGE 7.25 20.0)$ \sfs _-> parB (take 2 sfs) pswitch_t1r = [[], -- 0.0 [], -- 0.5 [], -- 1.0 [], -- 1.5 [0.15], -- 2.0 [0.35], -- 2.5 [0.60], -- 3.0 [0.90], -- 3.5 [1.25], -- 4.0 [10.40, 1.65], -- 4.5 [10.85, 2.10], -- 5.0 [11.35, 2.60], -- 5.5 [20.55, 11.90, 3.15], -- 6.0 [21.15, 12.50, 3.75], -- 6.5 [21.80, 13.15, 4.40], -- 7.0 [22.50, 13.85, 5.10], -- 7.5 [23.25, 14.60], -- 8.0 [24.05, 15.40], -- 8.5 [24.90, 16.25], -- 9.0 [25.80, 17.15]] -- 9.5 pswitch_t2 :: [[Double]] pswitch_t2 = take 20 $ embed sf pswitch_inp1 where sf = pSwitchB [] (now 10.0) $ \sfs x -> pSwitchB (integral:sfs) (whenFstGE 3.75 10.0) $ \sfs x -> pSwitchB ((integral>>>arr(+x)):sfs)(whenFstGE 5.25 20.0) $ \sfs x-> pSwitchB ((integral>>>arr(+x)):sfs)(now 20.0) $ \sfs _-> parB (take 2 sfs) pswitch_t2r = [[0.00], -- 0.0 [0.00], -- 0.5 [0.05], -- 1.0 [0.15], -- 1.5 [0.30], -- 2.0 [0.50], -- 2.5 [0.75], -- 3.0 [1.05], -- 3.5 [10.00, 1.40], -- 4.0 [10.40, 1.80], -- 4.5 [10.85, 2.25], -- 5.0 [20.00, 11.35], -- 5.5 [20.55, 11.90], -- 6.0 [21.15, 12.50], -- 6.5 [21.80, 13.15], -- 7.0 [22.50, 13.85], -- 7.5 [23.25, 14.60], -- 8.0 [24.05, 15.40], -- 8.5 [24.90, 16.25], -- 9.0 [25.80, 17.15]] -- 9.5 pswitch_t3 :: [[Double]] pswitch_t3 = take 20 $ embed sf pswitch_inp1 where sf = dpSwitchB [] (now 10.0) $ \sfs x -> dpSwitchB (integral:sfs) (whenFstGE 3.75 10.0) $ \sfs x -> dpSwitchB ((integral>>>arr(+x)):sfs)(whenFstGE 5.25 20.0)$ \sfs x-> dpSwitchB ((integral>>>arr(+x)):sfs) (now 20.0) $ \sfs _-> parB (take 2 sfs) pswitch_t3r = [[], -- 0.0 [0.00], -- 0.5 [0.05], -- 1.0 [0.15], -- 1.5 [0.30], -- 2.0 [0.50], -- 2.5 [0.75], -- 3.0 [1.05], -- 3.5 [1.40], -- 4.0 [10.40, 1.80], -- 4.5 [10.85, 2.25], -- 5.0 [11.35, 2.75], -- 5.5 [20.55, 11.90], -- 6.0 [21.15, 12.50], -- 6.5 [21.80, 13.15], -- 7.0 [22.50, 13.85], -- 7.5 [23.25, 14.60], -- 8.0 [24.05, 15.40], -- 8.5 [24.90, 16.25], -- 9.0 [25.80, 17.15]] -- 9.5 -- Starts three "ramps" with different phase. As soon as one exceeds a -- threshold, it's restarted, while the others are left alone. The -- observaton of the output is done via the loop (rather than the directly -- from the outputs of the signal functions in the collection), thus the -- use of a delayed switch is essential. pswitch_ramp :: Double -> SF a Double pswitch_ramp phase = constant 2.0 >>> integral >>> arr (+phase) -- We assume that only one signal function will reach the limit at a time. pswitch_limit :: Double -> SF ((a, [Double]), b) (Event Int) pswitch_limit x = arr (snd . fst) >>> arr (findIndex (>=x)) >>> edgeJust pswitch_t4 :: [[Double]] pswitch_t4 = take 30 $ embed (loop sf) (deltaEncode 0.1 (repeat ())) where sf :: SF (a, [Double]) ([Double],[Double]) sf = dpSwitchB [pswitch_ramp 0.0, pswitch_ramp 1.0, pswitch_ramp 2.0] (pswitch_limit 2.99) pswitch_t4rec >>> arr dup pswitch_t4rec :: [SF (a, [Double]) Double] -> Int -> SF (a, [Double]) [Double] pswitch_t4rec sfs n = dpSwitchB (take n sfs ++ [pswitch_ramp 0.0] ++ drop (n+1) sfs) (pswitch_limit 2.99) pswitch_t4rec pswitch_t4r = [[0.0, 1.0, 2.0], [0.2, 1.2, 2.2], [0.4, 1.4, 2.4], [0.6, 1.6, 2.6], [0.8, 1.8, 2.8], [1.0, 2.0, 3.0], [1.2, 2.2, 0.2], [1.4, 2.4, 0.4], [1.6, 2.6, 0.6], [1.8, 2.8, 0.8], [2.0, 3.0, 1.0], [2.2, 0.2, 1.2], [2.4, 0.4, 1.4], [2.6, 0.6, 1.6], [2.8, 0.8, 1.8], [3.0, 1.0, 2.0], [0.2, 1.2, 2.2], [0.4, 1.4, 2.4], [0.6, 1.6, 2.6], [0.8, 1.8, 2.8], [1.0, 2.0, 3.0], [1.2, 2.2, 0.2], [1.4, 2.4, 0.4], [1.6, 2.6, 0.6], [1.8, 2.8, 0.8], [2.0, 3.0, 1.0], [2.2, 0.2, 1.2], [2.4, 0.4, 1.4], [2.6, 0.6, 1.6], [2.8, 0.8, 1.8]] -- Variation of the test above, with direct observation (not via loop) and -- immediate switch. -- We assume that only one signal function will reach the limit at a time. pswitch_limit2 :: Double -> SF (a, [Double]) (Event Int) pswitch_limit2 x = arr snd >>> arr (findIndex (>=x)) >>> edgeJust pswitch_t5 :: [([Double], Double)] pswitch_t5 = take 30 $ embed (loop sf) (deltaEncode 0.1 (repeat ())) where sf :: SF (a, [Double]) (([Double], Double), [Double]) sf = ((pSwitchB [pswitch_ramp 0.0, pswitch_ramp 1.0, pswitch_ramp 2.0] (pswitch_limit2 2.99) pswitch_t5rec) &&& (arr snd >>> arr sum)) >>> arr (\(xs, y) -> ((xs, y), xs)) pswitch_t5rec :: [SF (a, [Double]) Double] -> Int -> SF (a, [Double]) [Double] pswitch_t5rec sfs n = pSwitchB (take n sfs ++ [pswitch_ramp 0.0] ++ drop (n+1) sfs) (pswitch_limit2 2.99) pswitch_t5rec pswitch_t5r = [([0.0, 1.0, 2.0], 3.0), ([0.2, 1.2, 2.2], 3.6), ([0.4, 1.4, 2.4], 4.2), ([0.6, 1.6, 2.6], 4.8), ([0.8, 1.8, 2.8], 5.4), ([1.0, 2.0, 0.0], 3.0), ([1.2, 2.2, 0.2], 3.6), ([1.4, 2.4, 0.4], 4.2), ([1.6, 2.6, 0.6], 4.8), ([1.8, 2.8, 0.8], 5.4), ([2.0, 0.0, 1.0], 3.0), ([2.2, 0.2, 1.2], 3.6), ([2.4, 0.4, 1.4], 4.2), ([2.6, 0.6, 1.6], 4.8), ([2.8, 0.8, 1.8], 5.4), ([0.0, 1.0, 2.0], 3.0), ([0.2, 1.2, 2.2], 3.6), ([0.4, 1.4, 2.4], 4.2), ([0.6, 1.6, 2.6], 4.8), ([0.8, 1.8, 2.8], 5.4), ([1.0, 2.0, 0.0], 3.0), ([1.2, 2.2, 0.2], 3.6), ([1.4, 2.4, 0.4], 4.2), ([1.6, 2.6, 0.6], 4.8), ([1.8, 2.8, 0.8], 5.4), ([2.0, 0.0, 1.0], 3.0), ([2.2, 0.2, 1.2], 3.6), ([2.4, 0.4, 1.4], 4.2), ([2.6, 0.6, 1.6], 4.8), ([2.8, 0.8, 1.8], 5.4)] pswitch_trs = [ pswitch_t0 ~= pswitch_t0r, pswitch_t1 ~= pswitch_t1r, pswitch_t2 ~= pswitch_t2r, pswitch_t3 ~= pswitch_t3r, pswitch_t4 ~= pswitch_t4r, pswitch_t5 ~= pswitch_t5r ] pswitch_tr = and pswitch_trs pswitch_st0 = testSFSpaceLeak 1000000 (loop sf) where sf :: SF (a, [Double]) ([Double],[Double]) sf = dpSwitchB [pswitch_ramp 0.0, pswitch_ramp 1.0, pswitch_ramp 2.0] (pswitch_limit 2.99) pswitch_t4rec >>> arr dup pswitch_st0r = [1.5,2.5,0.5] pswitch_st1 = testSFSpaceLeak 1000000 (loop sf) where sf :: SF (a, [Double]) (([Double], Double), [Double]) sf = ((pSwitchB [pswitch_ramp 0.0, pswitch_ramp 1.0, pswitch_ramp 2.0] (pswitch_limit2 2.99) pswitch_t5rec) &&& (arr snd >>> arr sum)) >>> arr (\(xs, y) -> ((xs, y), xs)) pswitch_st1r = ([1.5,2.5,0.5],4.5)