packages feed

copilot-core 0.2 → 0.2.1

raw patch · 6 files changed

+280/−194 lines, 6 filesPVP: major bump suggested

API removals or changes: PVP suggests a major version bump

API changes (from Hackage documentation)

+ Copilot.Core.Interpret.Eval: type Env nm = [(nm, DynamicF [] Type)]
+ Copilot.Core.Random: randomExtVals :: Int -> Spec -> Weights -> StdGen -> ExtEnv
+ Copilot.Core.Random.Gen: randomReplicate :: Int -> Type a -> Gen [a]
+ Copilot.Core.Random.Weights: extVarFreq :: Weights -> Int
+ Copilot.Core.Random.Weights: maxExtVars :: Weights -> Int
+ Copilot.Core.Type.Dynamic: DynamicF :: f a -> t a -> DynamicF f t
- Copilot.Core.Random.Weights: Weights :: Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Bool -> Weights
+ Copilot.Core.Random.Weights: Weights :: Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Bool -> Weights

Files

copilot-core.cabal view
@@ -1,6 +1,6 @@ cabal-version:       >=1.10 name:                copilot-core-version:             0.2+version:             0.2.1 synopsis:            An intermediate representation for Copilot. description:         Intermediate representation for Copilot.                      Strictly follows Haskell 2010 except for universal
src/Copilot/Core/Interpret/Eval.hs view
@@ -8,6 +8,7 @@  module Copilot.Core.Interpret.Eval   ( ExtEnv (..)+  , Env    , Output   , ExecTrace (..)   , eval
src/Copilot/Core/Random.hs view
@@ -6,20 +6,20 @@  module Copilot.Core.Random   ( randomSpec-  ) where+  , randomExtVals ) where -import Control.Monad-import Copilot.Core (UExpr (..))-import qualified Copilot.Core as E-import Copilot.Core.Spec+import Copilot.Core +import Copilot.Core.Interpret.Eval (ExtEnv (..), Env) import Copilot.Core.Random.Gen import Copilot.Core.Random.Weights-import Copilot.Core.Type-import Copilot.Core.Type.Equality-import Data.Int-import Data.Word+import Copilot.Core.Type.Dynamic+import Copilot.Core.Type.Equality ((=~=))++import Control.Monad+import Data.List (foldl', nubBy) import Prelude hiding (id) import System.Random (StdGen)+import Control.Monad.Reader  -------------------------------------------------------------------------------- @@ -29,28 +29,41 @@ --------------------------------------------------------------------------------  genSpec :: Gen Spec-genSpec =-  do-    ws <- weights-    numTriggers <- choose (1, maxTriggers ws)-    ss <- genStreamInfo's-    streams  <- mapM (genStream ss) ss-    triggers <- mapM (genTrigger ss) (map mkTriggerName [0..numTriggers-1])-    return-      Spec-        { specStreams   = streams-        , specObservers = []-        , specTriggers  = triggers }-+genSpec = do+  ws          <- weights+  numTriggers <- choose (1, maxTriggers ws)+  ss          <- genStreamInfo's+  extVars     <- genExtVars+  streams     <- runReaderT (mapM (genStream ss) ss) extVars+  triggers    <- +    runReaderT (mapM (genTrigger ss) (map mkTriggerName [0..numTriggers-1]))+               extVars+  return Spec { specStreams   = streams+              , specObservers = []+              , specTriggers  = triggers }   where--  mkTriggerName :: Int -> E.Name+  mkTriggerName :: Int -> Name   mkTriggerName k = "f" ++ show k +  -- Possibly generate external variables to be shared among streams.+  genExtVars :: Gen [DynExtVar]+  genExtVars = do+    ws <- weights+    n  <- choose (0, maxExtVars ws)+    let lst = [1..n] -- empty list if n == 0+    mapM genExtVar lst+    where+    genExtVar :: Int -> Gen DynExtVar+    genExtVar i = do +      ws <- weights                 +      WrapType t <- genType ws+      let expr = ExternVar t ("ext" ++ show i)+      return $ toDynF t expr+ --------------------------------------------------------------------------------  data StreamInfo = forall a . (Eq a, Ord a) => StreamInfo-  { streamInfoId         :: E.Id+  { streamInfoId         :: Id   , streamInfoType       :: Type a   , streamInfoBufferSize :: Int } @@ -78,129 +91,141 @@ --------------------------------------------------------------------------------  genStreamInfo's :: Gen [StreamInfo]-genStreamInfo's =-  do-    let-      s0 = StreamInfo 0 (typeOf :: Type Bool) 1-    ws <- weights-    ss <- mapM genStreamInfo [1 .. numStreams ws - 1]-    return (s0 : ss)+genStreamInfo's = do+  let s0 = StreamInfo 0 (typeOf :: Type Bool) 1+  ws      <- weights+  ss      <- mapM genStreamInfo [1 .. numStreams ws - 1]+  return (s0 : ss)    where   genStreamInfo :: Int -> Gen StreamInfo-  genStreamInfo id =-    do-      ws <- weights-      k  <- choose (1, maxBuffSize ws)-      WrapType t <- genType ws-      return-        StreamInfo-          { streamInfoId         = id-          , streamInfoType       = t-          , streamInfoBufferSize = k }+  genStreamInfo id = do+    ws <- weights+    k  <- choose (1, maxBuffSize ws)+    WrapType t <- genType ws+    return+      StreamInfo+        { streamInfoId         = id+        , streamInfoType       = t+        , streamInfoBufferSize = k }  -------------------------------------------------------------------------------- -genStream :: [StreamInfo] -> StreamInfo -> Gen Stream+-- External variables+type DynExtVar = DynamicF Expr Type++type StreamEnv = ReaderT [DynExtVar] Gen++--------------------------------------------------------------------------------++genStream :: [StreamInfo] -> StreamInfo -> StreamEnv Stream genStream ss   StreamInfo     { streamInfoId         = id     , streamInfoType       = t-    , streamInfoBufferSize = k } =-  do-    xs <- replicateM k (randomFromType t)-    w  <- genExpr ss t-    return+    , streamInfoBufferSize = k } +  = do+  xs <- lift $ replicateM k (randomFromType t)+  extVars <- ask+  w  <- lift $ genExpr extVars ss t+  return        Stream         { streamId       = id         , streamBuffer   = xs-        , streamGuard    = E.Const (typeOf :: Type Bool) True+        , streamGuard    = Const (typeOf :: Type Bool) True         , streamExpr     = w         , streamExprType = t }  -------------------------------------------------------------------------------- -genTrigger :: [StreamInfo] -> E.Name -> Gen Trigger-genTrigger ss name =-  do-    w  <- genExpr ss (typeOf :: Type Bool)-    ws <- weights-    i  <- choose (1, maxTrigArgs ws)-    args <- replicateM i genArg-    return-      Trigger-        { triggerName  = name-        , triggerGuard = w-        , triggerArgs  = args }+genTrigger :: [StreamInfo] -> Name -> StreamEnv Trigger+genTrigger ss name = do+  extVars <- ask+  w  <- lift $ genExpr extVars ss (typeOf :: Type Bool)+  ws <- lift $ weights+  i  <- lift $ choose (1, maxTrigArgs ws)+  args <- replicateM i genArg+  return+    Trigger+      { triggerName  = name+      , triggerGuard = w+      , triggerArgs  = args }    where--  genArg :: Gen UExpr-  genArg =-    do-      WrapType t <- genTypeFromStreamInfo's ss-      w <- genExpr ss t-      return-        UExpr-          { uExprExpr = w-          , uExprType = t }+  genArg :: StreamEnv UExpr+  genArg = do+    WrapType t <- lift $ genTypeFromStreamInfo's ss+    extVars <- ask+    w <- lift $ genExpr extVars ss t+    return+      UExpr+        { uExprExpr = w+        , uExprType = t }  -------------------------------------------------------------------------------- -genExpr :: [StreamInfo] -> Type a -> Gen (E.Expr a)-genExpr ss t =-  do-    dp <- depth-    ws <- weights-    if dp >= maxExprDepth ws-      then freq-        [ (constFreq ws, genConst)-        , (dropFreq  ws, genDrop) ]-      else freq-        [ (constFreq ws, genConst)-        , (dropFreq  ws, genDrop)-        , (op1Freq   ws, genOp1)-        , (op2Freq   ws, genOp2)-        , (op3Freq   ws, genOp3) ]+genExpr :: [DynExtVar] -> [StreamInfo] -> Type a -> Gen (Expr a)+genExpr extVars ss t = do+  dp <- depth+  ws <- weights+  if dp >= maxExprDepth ws+    then freq (terminalLst ws)+    else freq $ +      terminalLst ws +++      [ (op1Freq   ws, genOp1)+      , (op2Freq   ws, genOp2)+      , (op3Freq   ws, genOp3) ]    where-  genConst =-    do-      x <- randomFromType t-      return $ E.Const t x-  genDrop =-    do-      s <- findStreamInfoWithMatchingType-      k <- choose (0, streamInfoBufferSize s - 1)-      return $ E.Drop t (fromIntegral k) (streamInfoId s)+  terminalLst ws = +    (extVarFreq' ws, genExtVar) : [ (constFreq ws, genConst)+                                  , (dropFreq  ws, genDrop) ]  +  extVarFreq' ws = if null typedExtVars then 0 else extVarFreq ws+  +  genExtVar = do+    let vars = typedExtVars+    r <- choose (0, length vars - 1)+    return (vars !! r)++  typedExtVars = foldl' typedExtVar [] extVars+    where typedExtVar vars dyn = +            case fromDynF t dyn of+                   Nothing   -> vars+                   Just expr -> expr:vars++  genConst = do +    x <- randomFromType t +    return $ Const t x++  genDrop = do+    s <- findStreamInfoWithMatchingType+    k <- choose (0, streamInfoBufferSize s - 1)+    return $ Drop t (fromIntegral k) (streamInfoId s)     where     findStreamInfoWithMatchingType =-      let-        p (StreamInfo _ t1 _) =-          case t =~= t1 of-            Just _ -> True-            _      -> False-      in-        elements (filter p ss)+      let p (StreamInfo _ t1 _) = case t =~= t1 of+                                    Just _ -> True+                                    _      -> False+      in  elements (filter p ss)    genOp1 = incDepth $ case t of-    Bool   -> genOp1Bool ss-    Int8   -> genOp1Num  ss t-    Int16  -> genOp1Num  ss t-    Int32  -> genOp1Num  ss t-    Int64  -> genOp1Num  ss t-    Word8  -> genOp1Num  ss t-    Word16 -> genOp1Num  ss t-    Word32 -> genOp1Num  ss t-    Word64 -> genOp1Num  ss t-    Float  -> genOp1Num  ss t-    Double -> genOp1Num  ss t+    Bool   -> genOp1Bool extVars ss+    Int8   -> genOp1Num  extVars ss t+    Int16  -> genOp1Num  extVars ss t+    Int32  -> genOp1Num  extVars ss t+    Int64  -> genOp1Num  extVars ss t+    Word8  -> genOp1Num  extVars ss t+    Word16 -> genOp1Num  extVars ss t+    Word32 -> genOp1Num  extVars ss t+    Word64 -> genOp1Num  extVars ss t+    Float  -> genOp1Num  extVars ss t+    Double -> genOp1Num  extVars ss t    genOp2 = incDepth $ case t of -- XXX  --    Bool    -> oneOf [genOp2Bool ss, genOp2Eq ss, genOp2Ord ss]-    Bool    -> oneOf [genOp2Bool ss, genOp2Eq ss]+    Bool    -> oneOf [genOp2Bool extVars ss, genOp2Eq extVars ss]     Int8    -> intOrWord NumWit IntegralWit     Int16   -> intOrWord NumWit IntegralWit     Int32   -> intOrWord NumWit IntegralWit@@ -217,95 +242,149 @@       intOrWord numWit integralWit = do          ws <- weights          if divModFreq ws -          then oneOf $ num ++ [genOp2Integral ss t integralWit ]+          then oneOf $ num ++ [ genOp2Integral extVars ss t integralWit ]           else oneOf num-        where num = [ genOp2Num ss t numWit ]+        where num = [ genOp2Num extVars ss t numWit ]        floatOrDouble numWit = oneOf-        [ genOp2Num ss t numWit ]+        [ genOp2Num extVars ss t numWit ] -  genOp3 = incDepth (genOp3Mux ss t)+  genOp3 = incDepth (genOp3Mux extVars ss t)      -------------------------------------------------------------------------------- -genOp1Bool :: [StreamInfo] -> Gen (E.Expr Bool)-genOp1Bool ss =+genOp1Bool :: [DynExtVar] -> [StreamInfo] -> Gen (Expr Bool)+genOp1Bool extVars ss =   do-    ew <- genExpr ss (typeOf :: Type Bool)-    return $ E.Op1 E.Not ew+    ew <- genExpr extVars ss (typeOf :: Type Bool)+    return $ Op1 Not ew -genOp1Num :: Num a => [StreamInfo] -> Type a -> Gen (E.Expr a)-genOp1Num ss t =+genOp1Num :: Num a => [DynExtVar] -> [StreamInfo] -> Type a -> Gen (Expr a)+genOp1Num extVars ss t =   do-    ew  <- genExpr ss t-    opw <- elements [E.Abs t, E.Sign t]-    return $ E.Op1 opw ew+    ew  <- genExpr extVars ss t+    opw <- elements [Abs t, Sign t]+    return $ Op1 opw ew -genOp2Bool :: [StreamInfo] -> Gen (E.Expr Bool)-genOp2Bool ss =+genOp2Bool :: [DynExtVar] -> [StreamInfo] -> Gen (Expr Bool)+genOp2Bool extVars ss =   do-    ew1 <- genExpr ss (typeOf :: Type Bool)-    ew2 <- genExpr ss (typeOf :: Type Bool)-    opw <- elements [E.And, E.Or]-    return $ E.Op2 opw ew1 ew2+    ew1 <- genExpr extVars ss (typeOf :: Type Bool)+    ew2 <- genExpr extVars ss (typeOf :: Type Bool)+    opw <- elements [And, Or]+    return $ Op2 opw ew1 ew2 -genOp2Eq :: [StreamInfo] -> Gen (E.Expr Bool)-genOp2Eq ss =+genOp2Eq :: [DynExtVar] -> [StreamInfo] -> Gen (Expr Bool)+genOp2Eq extVars ss =   do     WrapType t <- genTypeFromStreamInfo's ss-    ew1 <- genExpr ss t-    ew2 <- genExpr ss t-    opw <- elements [E.Eq t, E.Ne t]-    return $ E.Op2 opw ew1 ew2+    ew1 <- genExpr extVars ss t+    ew2 <- genExpr extVars ss t+    opw <- elements [Eq t, Ne t]+    return $ Op2 opw ew1 ew2  -- XXX -- Figure out how to ensure t comes from a Numeric Class--- genOp2Ord :: [StreamInfo] -> Gen (E.Expr Bool)+-- genOp2Ord :: [StreamInfo] -> Gen (Expr Bool) -- genOp2Ord ss = --   do --     WrapType t <- genTypeFromStreamInfo's ss---     ew1 <- genExpr ss t---     ew2 <- genExpr ss t+--     ew1 <- genExpr extVars ss t+--     ew2 <- genExpr extVars ss t --     opw <- elements---       [ (E.Lt t)---       , (E.Gt t)---       , (E.Le t)---       , (E.Ge t) ]---     return $ E.Op2 opw ew1 ew2+--       [ (Lt t)+--       , (Gt t)+--       , (Le t)+--       , (Ge t) ]+--     return $ Op2 opw ew1 ew2 -genOp2Num :: [StreamInfo] -> Type a -> NumWit a -> Gen (E.Expr a)-genOp2Num ss t NumWit =+genOp2Num :: [DynExtVar] -> [StreamInfo] -> Type a -> NumWit a -> Gen (Expr a)+genOp2Num extVars ss t NumWit =   do-    ew1 <- genExpr ss t-    ew2 <- genExpr ss t-    opw <-+    ew1 <- genExpr extVars ss t+    ew2 <- genExpr extVars ss t+    opw <-        elements-        [ (E.Add t)-        , (E.Sub t)-        , (E.Mul t) ]+        [ (Add t)+        , (Sub t)+        , (Mul t) ]     return-      $ E.Op2 opw ew1 ew2+      $ Op2 opw ew1 ew2 -genOp2Integral :: [StreamInfo] -> Type a -> IntegralWit a -> Gen (E.Expr a)-genOp2Integral ss t IntegralWit =+genOp2Integral :: +  [DynExtVar] -> [StreamInfo] -> Type a -> IntegralWit a -> Gen (Expr a)+genOp2Integral extVars ss t IntegralWit =   do-    ew1 <- genExpr ss t-    ew2 <- genExpr ss t-    opw <-+    ew1 <- genExpr extVars ss t+    ew2 <- genExpr extVars ss t+    opw <-        elements-        [ (E.Div t)-        , (E.Mod t) ]+        [ (Div t)+        , (Mod t) ]     return-      $ E.Op2 opw ew1 ew2+      $ Op2 opw ew1 ew2 -genOp3Mux :: [StreamInfo] -> Type a -> Gen (E.Expr a)-genOp3Mux ss t =+genOp3Mux :: [DynExtVar] -> [StreamInfo] -> Type a -> Gen (Expr a)+genOp3Mux extVars ss t =   do-    ew1 <- genExpr ss (typeOf :: Type Bool)-    ew2 <- genExpr ss t-    ew3 <- genExpr ss t-    return $ E.Op3 (E.Mux t) ew1 ew2 ew3+    ew1 <- genExpr extVars ss (typeOf :: Type Bool)+    ew2 <- genExpr extVars ss t+    ew3 <- genExpr extVars ss t+    return $ Op3 (Mux t) ew1 ew2 ew3  data NumWit a = Num a => NumWit  data IntegralWit a = Integral a => IntegralWit++--------------------------------------------------------------------------------++randomExtVals :: Int -> Spec -> Weights -> StdGen -> ExtEnv+randomExtVals rnds spec = runGen env 0+  where env = do vars <- extVals rnds spec+                 return ExtEnv { varEnv = vars+                               , arrEnv = []+                               , funcEnv = []+                               }++--------------------------------------------------------------------------------++-- Extract the external variables, returning randomly-generated lists for their+-- values.+extVals :: Int -> Spec -> Gen (Env Name)+extVals rnds Spec { specStreams = strms+                  , specTriggers = triggers } +  = +  let vars = nubBy (\a b -> fst a == fst b) $ +               concatMap strmExts strms ++ +               concatMap triggerExts triggers  in+  mapM randomLst vars++  where +  randomLst :: (Name, UType) -> Gen (Name, DynamicF [] Type)+  randomLst (nm, UType { uTypeType = t }) = do+    rnd <- randomReplicate rnds t+    return $ (nm, toDynF t rnd)++  strmExts Stream { streamExpr = expr } = extsFromExpr expr++  triggerExts Trigger { triggerGuard = grd+                      , triggerArgs = args } = +    extsFromExpr grd ++ concatMap getExpr args+      where getExpr UExpr { uExprExpr = expr } = extsFromExpr expr+  +  extsFromExpr :: Expr a -> [(Name, UType)]+  extsFromExpr expr =+    case expr of+      Const _ _              -> []+      Drop _ _ _             -> []+      Local _ _ _ e1 e2      -> extsFromExpr e1 ++ extsFromExpr e2+      Var _ _                -> []+      ExternVar t name       -> [(name, UType { uTypeType = t })]+      ExternFun _ _ _ _      -> []+      ExternArray _ _ _ _ _  -> []+      Op1 _ e                -> extsFromExpr e+      Op2 _ e1 e2            -> extsFromExpr e1 ++ extsFromExpr e2+      Op3 _ e1 e2 e3         -> extsFromExpr e1 ++ extsFromExpr e2+                                  ++ extsFromExpr e3++--------------------------------------------------------------------------------
src/Copilot/Core/Random/Gen.hs view
@@ -15,11 +15,13 @@   , depth   , weights   , incDepth+  , randomReplicate   ) where  import Copilot.Core.Random.Weights import Copilot.Core.Error import Copilot.Core.Type+ import System.Random (StdGen, Random, random, randomR, split)  --------------------------------------------------------------------------------@@ -28,14 +30,11 @@ -- the standard random generator. newtype Gen a = MkGen { runGen :: Depth -> Weights -> StdGen -> a } ---------------------------------------------------------------------------------- instance Functor Gen where   fmap f (MkGen h) = MkGen (\ d ws r -> f (h d ws r))  instance Monad Gen where   return x = MkGen (\ _ _ _ -> x)-   MkGen m >>= k = MkGen $ \ d ws r ->     let (r1, r2) = split r       in     let MkGen m' = k (m d ws r1) in@@ -75,31 +74,35 @@   where    genBool :: Gen Bool-  genBool =-    do-      g <- stdGen-      return $ fst (random g)+  genBool = do+    g <- stdGen+    return $ fst (random g)    genBoundedIntegral :: (Bounded a, Integral a) => Gen a-  genBoundedIntegral =-    do let mn = minBound-           mx = maxBound `asTypeOf` mn-       n <- choose (toInteger mn, toInteger mx)-       return (fromInteger n `asTypeOf` mn)+  genBoundedIntegral = do+    let mn = minBound+        mx = maxBound `asTypeOf` mn+    n <- choose (toInteger mn, toInteger mx)+    return (fromInteger n `asTypeOf` mn)    genFractional :: (Random a, Fractional a) => Gen a-  genFractional =-    do-      g <- stdGen-      return $ fst (random g)+  genFractional = do+    g <- stdGen+    return $ fst (random g)  -------------------------------------------------------------------------------- +-- Given an int i and type t, make a list of length i containing random values+-- over the type.+randomReplicate :: Int -> Type a -> Gen [a]+randomReplicate i t = mapM (\_ -> randomFromType t) [1..i]++--------------------------------------------------------------------------------+ choose :: Random a => (a, a) -> Gen a-choose rng =-  do-    g <- stdGen-    return $ fst (randomR rng g)+choose rng = do+  g <- stdGen+  return $ fst (randomR rng g)  oneOf :: [Gen a] -> Gen a oneOf [] = impossible "oneof" "copilot-core" @@ -112,8 +115,7 @@ freq :: [(Int, Gen a)] -> Gen a freq [] = impossible "feq" "copilot-core"  freq xs0 = choose (1, tot) >>= (`pick` xs0)-- where+  where   tot = sum (map fst xs0)   pick n ((k,x):xs)     | n <= k    = x
src/Copilot/Core/Random/Weights.hs view
@@ -14,10 +14,12 @@   , maxBuffSize  :: Int   , maxTriggers  :: Int   , maxTrigArgs  :: Int+  , maxExtVars   :: Int   , maxObservers :: Int   , numStreams   :: Int   -- Expression frequencies:   , constFreq    :: Int+  , extVarFreq   :: Int   , drop0Freq    :: Int   , dropFreq     :: Int   , externFreq   :: Int@@ -44,10 +46,12 @@   , maxBuffSize  = 8   , maxTriggers  = 5   , maxTrigArgs  = 5+  , maxExtVars   = 5   , maxObservers = 8   , numStreams   = 10   -- Expression frequencies:   , constFreq    = 1+  , extVarFreq   = 1   , drop0Freq    = 1   , dropFreq     = 1   , externFreq   = 1
src/Copilot/Core/Type/Dynamic.hs view
@@ -16,7 +16,7 @@  module Copilot.Core.Type.Dynamic   ( Dynamic-  , DynamicF+  , DynamicF (..)   , toDyn   , fromDyn   , toDynF