{-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE TypeFamilies #-} {-# LANGUAGE TypeOperators #-} -- Test that rule application does not lead to capturing import System.Exit import Data.Comp -- import Data.Comp.Render import Data.Patch -- Could use partial type signatures instead (on GHC >= 7.10) import Data.Rewriting.Rules import Data.Rewriting.FirstOrder hiding (applyFirst) import Data.Rewriting.HigherOrder import Feldspar lamm :: (LAM :<: PF rep, Rep rep) => Name -> rep b -> rep (a -> b) lamm v body = toRep $ inject $ Lam v $ fromRep body dvar :: Name -> Data a dvar = Data . inject . Var rule_strange1 aa bb = meta aa + meta bb ===> forLoop 1 0 (\x y -> meta bb + var x + meta aa + var y) -- Strange rule with a free variable on the RHS rule_strange2 = __ - __ ===> forLoop_ 1 0 (lamm 0 $ lamm 0 $ (var 0 + (var 1 -:: tCon tInt))) simplify' :: Data a -> Data a simplify' = Data . rewriteWith (bottomUp (applyFirst app rulesStrange)) . unData where rulesStrange = [ quantify (rule_strange1 -:: tCon tInt >-> id) , quantify (rule_strange2) ] testFun1 :: Data (Int -> Int -> Int) testFun1 = lam $ \v1 -> lam $ \v0 -> v1 + v0 testFun2 :: Data (Int -> Int -> Int) testFun2 = lam $ \v1 -> lam $ \v0 -> v1 - v0 testFun1_simp_golden :: Data (Int -> Int -> Int) testFun1_simp_golden = lamm 1 $ lamm 0 $ forLoop_ 1 0 $ lamm 2 $ lamm 3 $ dvar 0 + dvar 2 + dvar 1 + dvar 3 testFun2_simp_golden :: Data (Int -> Int -> Int) testFun2_simp_golden = lamm 1 $ lamm 0 $ forLoop_ 1 0 $ lamm 0 $ lamm 2 $ dvar 2 + dvar 1 tests = [ unData (simplify' testFun1) == unData testFun1_simp_golden , unData (simplify' testFun2) == unData testFun2_simp_golden ] main = if and tests then putStrLn "All tests passed" else do putStrLn $ "Tests " ++ show [i | (i,False) <- zip [0..] tests] ++ " failed" exitFailure