packages feed

feldspar-language 0.1 → 0.2

raw patch · 18 files changed

+1898/−1254 lines, 18 filesdep +QuickCheckdep −directorydep −processdep −tfpPVP ok

version bump matches the API change (PVP)

Dependencies added: QuickCheck

Dependencies removed: directory, process, tfp

API changes (from Hackage documentation)

- Feldspar.Core: class (Storable a) => Primitive a
- Feldspar.Core.Expr: GetTuple :: T n -> Data a -> Expr (Part n a)
- Feldspar.Core.Expr: Info :: NodeId -> Map Unique NodeId -> Info
- Feldspar.Core.Expr: buildGraph :: Data a -> GraphBuilder ()
- Feldspar.Core.Expr: buildSubFun :: (Typeable a, Typeable b) => (Data a -> Data b) -> GraphBuilder Interface
- Feldspar.Core.Expr: checkNode :: Data a -> GraphBuilder (Maybe NodeId)
- Feldspar.Core.Expr: class Program a
- Feldspar.Core.Expr: data Info
- Feldspar.Core.Expr: deref :: Data a -> Expr a
- Feldspar.Core.Expr: functionFold :: (Storable a, Storable b) => String -> (a -> b) -> (Data a -> Data b)
- Feldspar.Core.Expr: functionFold2 :: (Storable a, Storable b, Storable c) => String -> (a -> b -> c) -> (Data a -> Data b -> Data c)
- Feldspar.Core.Expr: functionFold3 :: (Storable a, Storable b, Storable c, Storable d) => String -> (a -> b -> c -> d) -> (Data a -> Data b -> Data c -> Data d)
- Feldspar.Core.Expr: functionFold4 :: (Storable a, Storable b, Storable c, Storable d, Storable e) => String -> (a -> b -> c -> d -> e) -> (Data a -> Data b -> Data c -> Data d -> Data e)
- Feldspar.Core.Expr: hasArg :: (Program a) => T a -> Bool
- Feldspar.Core.Expr: index :: Info -> NodeId
- Feldspar.Core.Expr: instance [incoherent] (Computable a) => Program a
- Feldspar.Core.Expr: instance [incoherent] (Computable a, Computable b) => Computable (a, b)
- Feldspar.Core.Expr: instance [incoherent] (Computable a, Computable b) => Program (a -> b)
- Feldspar.Core.Expr: instance [incoherent] (Computable a, Computable b, Computable c) => Computable (a, b, c)
- Feldspar.Core.Expr: instance [incoherent] (Computable a, Computable b, Computable c) => Program (a -> b -> c)
- Feldspar.Core.Expr: instance [incoherent] (Computable a, Computable b, Computable c, Computable d) => Computable (a, b, c, d)
- Feldspar.Core.Expr: instance [incoherent] (Computable a, Computable b, Computable c, Computable d) => Program (a -> b -> c -> d)
- Feldspar.Core.Expr: instance [incoherent] (Computable a, Computable b, Computable c, Computable d, Computable e) => Program (a -> b -> c -> d -> e)
- Feldspar.Core.Expr: instance [incoherent] (NaturalT n, Storable a) => RandomAccess (Data (n :> a))
- Feldspar.Core.Expr: instance [incoherent] (Num n, Primitive n) => Num (Data n)
- Feldspar.Core.Expr: instance [incoherent] (Primitive a) => Show (Data a)
- Feldspar.Core.Expr: instance [incoherent] (Storable a) => Computable (Data a)
- Feldspar.Core.Expr: instance [incoherent] Eq (Data a)
- Feldspar.Core.Expr: instance [incoherent] Fractional (Data Float)
- Feldspar.Core.Expr: instance [incoherent] Ord (Data a)
- Feldspar.Core.Expr: newIndex :: GraphBuilder NodeId
- Feldspar.Core.Expr: node :: (Typeable a) => Data a -> Function -> Tuple Source -> Tuple StorableType -> GraphBuilder ()
- Feldspar.Core.Expr: printCore :: (Program a) => a -> IO ()
- Feldspar.Core.Expr: ref :: (Typeable a) => Expr a -> Data a
- Feldspar.Core.Expr: refId :: Data a -> Unique
- Feldspar.Core.Expr: remember :: Data a -> NodeId -> GraphBuilder ()
- Feldspar.Core.Expr: runGraph :: GraphBuilder a -> Info -> (a, ([Node], Info))
- Feldspar.Core.Expr: showCore :: (Program a) => a -> String
- Feldspar.Core.Expr: source :: [Int] -> Data a -> GraphBuilder Source
- Feldspar.Core.Expr: sourceNode :: Data a -> Function -> GraphBuilder ()
- Feldspar.Core.Expr: startInfo :: Info
- Feldspar.Core.Expr: toGraph :: (Program a) => a -> Graph
- Feldspar.Core.Expr: toGraphD :: (Typeable a, Typeable b) => (Data a -> Data b) -> Graph
- Feldspar.Core.Expr: traceTuple :: Data a -> GraphBuilder (Tuple Source)
- Feldspar.Core.Expr: tupleBind :: (Typeable a) => NodeId -> T a -> Tuple Variable
- Feldspar.Core.Expr: type GraphBuilder a = WriterT [Node] (State Info) a
- Feldspar.Core.Expr: typeOfData :: (Typeable a) => Data a -> Tuple StorableType
- Feldspar.Core.Expr: unwrap :: (Computable a, Computable b) => (Data (Internal a) -> Data (Internal b)) -> (a -> b)
- Feldspar.Core.Expr: value_ :: (Storable a) => a -> Data a
- Feldspar.Core.Expr: visited :: Info -> Map Unique NodeId
- Feldspar.Core.Expr: wrap :: (Computable a, Computable b) => (a -> b) -> (Data (Internal a) -> Data (Internal b))
- Feldspar.Core.Haskell: (-$-) :: (HaskellValue a) => String -> a -> String
- Feldspar.Core.Haskell: (-=-) :: (HaskellValue patt, HaskellValue def) => patt -> def -> String
- Feldspar.Core.Haskell: ifThenElse :: (HaskellValue c, HaskellValue t, HaskellValue e) => c -> t -> e -> String
- Feldspar.Core.Haskell: indent :: Int -> String -> String
- Feldspar.Core.Haskell: local :: String -> String -> String
- Feldspar.Core.Haskell: newline :: String
- Feldspar.Core.Haskell: opApp :: (HaskellValue a, HaskellValue b) => String -> a -> b -> String
- Feldspar.Core.Haskell: unlinesNoTrail :: [String] -> String
- Feldspar.Core.Types: ArrayList :: [a] -> :> n a
- Feldspar.Core.Types: class (NaturalT n) => GetTuple n a where { type family Part n a; }
- Feldspar.Core.Types: class HaskellType a
- Feldspar.Core.Types: class HaskellValue a
- Feldspar.Core.Types: fromList :: (Storable a) => ListBased a -> a
- Feldspar.Core.Types: getTup :: (GetTuple n a) => T n -> a -> Part n a
- Feldspar.Core.Types: haskellType :: (HaskellType a) => a -> String
- Feldspar.Core.Types: haskellValue :: (HaskellValue a) => a -> String
- Feldspar.Core.Types: instance [overlap ok] (NaturalT n, Storable a) => Storable (n :> a)
- Feldspar.Core.Types: instance [overlap ok] (NaturalT n, Storable a) => Typeable (n :> a)
- Feldspar.Core.Types: instance [overlap ok] (NaturalT n, Storable a, Eq a) => Eq (n :> a)
- Feldspar.Core.Types: instance [overlap ok] (NaturalT n, Storable a, Ord a) => Ord (n :> a)
- Feldspar.Core.Types: instance [overlap ok] (NaturalT n, Storable a, Show (ListBased a)) => Show (n :> a)
- Feldspar.Core.Types: instance [overlap ok] GetTuple D0 (a, b)
- Feldspar.Core.Types: instance [overlap ok] GetTuple D0 (a, b, c)
- Feldspar.Core.Types: instance [overlap ok] GetTuple D0 (a, b, c, d)
- Feldspar.Core.Types: instance [overlap ok] GetTuple D1 (a, b)
- Feldspar.Core.Types: instance [overlap ok] GetTuple D1 (a, b, c)
- Feldspar.Core.Types: instance [overlap ok] GetTuple D1 (a, b, c, d)
- Feldspar.Core.Types: instance [overlap ok] GetTuple D2 (a, b, c)
- Feldspar.Core.Types: instance [overlap ok] GetTuple D2 (a, b, c, d)
- Feldspar.Core.Types: instance [overlap ok] GetTuple D3 (a, b, c, d)
- Feldspar.Core.Types: instance [overlap ok] HaskellValue Int
- Feldspar.Core.Types: instance [overlap ok] HaskellValue String
- Feldspar.Core.Types: isPrimitive :: (Typeable a) => T a -> Bool
- Feldspar.Core.Types: isRectangular :: (Storable a) => a -> Bool
- Feldspar.Core.Types: mapArray :: (NaturalT n, Storable a, Storable b) => (a -> b) -> (n :> a) -> (n :> b)
- Feldspar.Core.Types: numberT :: (IntegerT n) => T n -> Int
- Feldspar.Core.Types: replicateArray :: (Storable a) => Element a -> a
- Feldspar.Core.Types: toData :: (Storable a) => a -> StorableData
- Feldspar.Core.Types: toList :: (Storable a) => a -> ListBased a
- Feldspar.Vector: Unfold :: Data Size -> (s -> (a, s)) -> s -> Seq n :>> a
- Feldspar.Vector: class AccessPattern t
- Feldspar.Vector: data (:>>) n a
- Feldspar.Vector: data Par n
- Feldspar.Vector: data Seq n
- Feldspar.Vector: genericVector :: (AccessPattern t) => (Par n :>> a) -> (Seq n :>> a) -> (t n :>> a)
- Feldspar.Vector: instance [overlap ok] (NaturalT n, Storable a, AccessPattern t) => Computable (t n :>> Data a)
- Feldspar.Vector: instance [overlap ok] (NaturalT n1, NaturalT n2, Storable a, AccessPattern t1, AccessPattern t2) => Computable (t1 n1 :>> (t2 n2 :>> Data a))
- Feldspar.Vector: instance [overlap ok] AccessPattern Par
- Feldspar.Vector: instance [overlap ok] AccessPattern Seq
- Feldspar.Vector: instance [overlap ok] RandomAccess (Par n :>> a)
- Feldspar.Vector: resize :: (NaturalT n) => (t m :>> a) -> (t n :>> a)
- Feldspar.Vector: scan1 :: (Computable a) => (a -> a -> a) -> (t n :>> a) -> (Seq n :>> a)
- Feldspar.Vector: toPar :: (NaturalT n, Storable a) => (t n :>> Data a) -> VectorP n a
- Feldspar.Vector: toSeq :: (t n :>> a) -> (Seq n :>> a)
- Feldspar.Vector: type Size = Int
- Feldspar.Vector: type VectorP n a = Par n :>> Data a
- Feldspar.Vector: type VectorS n a = Seq n :>> Data a
+ Feldspar.Core: (:>) :: a -> b -> :> a b
+ Feldspar.Core: Range :: Maybe a -> Maybe a -> Range a
+ Feldspar.Core: arrayLen :: (Storable a) => Data Length -> [a] -> Data [a]
+ Feldspar.Core: cap :: (Storable a, (Size a) ~ (Range b), Ord b) => Range b -> Data a -> Data a
+ Feldspar.Core: class (Num a, Primitive a, Num (Size a)) => Numeric a
+ Feldspar.Core: class Set a
+ Feldspar.Core: data (Ord a) => Range a
+ Feldspar.Core: dataSize :: Data a -> Size a
+ Feldspar.Core: lowerBound :: Range a -> Maybe a
+ Feldspar.Core: printCoreWithSize :: (Program a) => a -> IO ()
+ Feldspar.Core: showCoreWithSize :: (Program a) => a -> String
+ Feldspar.Core: type Length = Int
+ Feldspar.Core: universal :: (Set a) => a
+ Feldspar.Core: upperBound :: Range a -> Maybe a
+ Feldspar.Core.Expr: Get21 :: Data (a, b) -> Expr a
+ Feldspar.Core.Expr: Get22 :: Data (a, b) -> Expr b
+ Feldspar.Core.Expr: Get31 :: Data (a, b, c) -> Expr a
+ Feldspar.Core.Expr: Get32 :: Data (a, b, c) -> Expr b
+ Feldspar.Core.Expr: Get33 :: Data (a, b, c) -> Expr c
+ Feldspar.Core.Expr: Get41 :: Data (a, b, c, d) -> Expr a
+ Feldspar.Core.Expr: Get42 :: Data (a, b, c, d) -> Expr b
+ Feldspar.Core.Expr: Get43 :: Data (a, b, c, d) -> Expr c
+ Feldspar.Core.Expr: Get44 :: Data (a, b, c, d) -> Expr d
+ Feldspar.Core.Expr: SubFunction :: (Data a -> Data b) -> (Data a) -> (Data b) -> :-> a b
+ Feldspar.Core.Expr: arrayLen :: (Storable a) => Data Length -> [a] -> Data [a]
+ Feldspar.Core.Expr: cap :: (Storable a, (Size a) ~ (Range b), Ord b) => Range b -> Data a -> Data a
+ Feldspar.Core.Expr: data (:->) a b
+ Feldspar.Core.Expr: dataId :: Data a -> Unique
+ Feldspar.Core.Expr: dataSize :: Data a -> Size a
+ Feldspar.Core.Expr: dataToExpr :: Data a -> Expr a
+ Feldspar.Core.Expr: dataType :: Data a -> Tuple StorableType
+ Feldspar.Core.Expr: exprSize :: (Typeable a) => Expr a -> Size a
+ Feldspar.Core.Expr: exprToData :: (Typeable a) => Expr a -> Data a
+ Feldspar.Core.Expr: externalizeE :: (Computable a) => Expr (Internal a) -> a
+ Feldspar.Core.Expr: instance [overlap ok] (Computable a, Computable b) => Computable (a, b)
+ Feldspar.Core.Expr: instance [overlap ok] (Computable a, Computable b, Computable c) => Computable (a, b, c)
+ Feldspar.Core.Expr: instance [overlap ok] (Computable a, Computable b, Computable c, Computable d) => Computable (a, b, c, d)
+ Feldspar.Core.Expr: instance [overlap ok] (Numeric a) => Num (Data a)
+ Feldspar.Core.Expr: instance [overlap ok] (Storable a) => Computable (Data a)
+ Feldspar.Core.Expr: instance [overlap ok] (Storable a) => RandomAccess (Data [a])
+ Feldspar.Core.Expr: instance [overlap ok] Eq (Data a)
+ Feldspar.Core.Expr: instance [overlap ok] Fractional (Data Float)
+ Feldspar.Core.Expr: instance [overlap ok] Ord (Data a)
+ Feldspar.Core.Expr: instance [overlap ok] Show (Data a)
+ Feldspar.Core.Expr: liftFun :: (Computable a, Computable b) => (Data (Internal a) -> Data (Internal b)) -> (a -> b)
+ Feldspar.Core.Expr: lowerFun :: (Computable a, Computable b) => (a -> b) -> (Data (Internal a) -> Data (Internal b))
+ Feldspar.Core.Expr: mkSubFun :: (Typeable a) => Size a -> (Data a -> Data b) -> (a :-> b)
+ Feldspar.Core.Expr: subAp :: (a :-> b) -> (Data a -> Data b)
+ Feldspar.Core.Expr: subFunSize :: (a :-> b) -> Size b
+ Feldspar.Core.Expr: whileSized :: (Computable state) => Size (Internal state) -> (state -> Data Bool) -> (state -> state) -> (state -> state)
+ Feldspar.Core.Functions: (.&.) :: (Bits a) => Data a -> Data a -> Data a
+ Feldspar.Core.Functions: (.|.) :: (Bits a) => Data a -> Data a -> Data a
+ Feldspar.Core.Functions: (<<) :: (Bits a) => Data a -> Data Int -> Data a
+ Feldspar.Core.Functions: (<<<) :: Data Int -> Data Int -> Data Bool
+ Feldspar.Core.Functions: (>>) :: (Bits a) => Data a -> Data Int -> Data a
+ Feldspar.Core.Functions: (>>>) :: Data Int -> Data Int -> Data Bool
+ Feldspar.Core.Functions: (⊕) :: (Bits a) => Data a -> Data a -> Data a
+ Feldspar.Core.Functions: bit :: (Bits a) => Data Int -> Data a
+ Feldspar.Core.Functions: bitSize :: (Bits a) => Data a -> Data Int
+ Feldspar.Core.Functions: class (Bits a, Storable a) => Bits a
+ Feldspar.Core.Functions: clearBit :: (Bits a) => Data a -> Data Int -> Data a
+ Feldspar.Core.Functions: complement :: (Bits a) => Data a -> Data a
+ Feldspar.Core.Functions: complementBit :: (Bits a) => Data a -> Data Int -> Data a
+ Feldspar.Core.Functions: instance [overlap ok] Bits Int
+ Feldspar.Core.Functions: isSigned :: (Bits a) => Data a -> Data Bool
+ Feldspar.Core.Functions: maxX :: Data Int -> Data Int -> Data Int
+ Feldspar.Core.Functions: minX :: Data Int -> Data Int -> Data Int
+ Feldspar.Core.Functions: noSizeProp :: a -> ()
+ Feldspar.Core.Functions: noSizeProp2 :: a -> b -> ()
+ Feldspar.Core.Functions: rotateL :: (Bits a) => Data a -> Data Int -> Data a
+ Feldspar.Core.Functions: rotateR :: (Bits a) => Data a -> Data Int -> Data a
+ Feldspar.Core.Functions: setBit :: (Bits a) => Data a -> Data Int -> Data a
+ Feldspar.Core.Functions: shiftL :: (Bits a) => Data a -> Data Int -> Data a
+ Feldspar.Core.Functions: shiftR :: (Bits a) => Data a -> Data Int -> Data a
+ Feldspar.Core.Functions: testBit :: (Bits a) => Data a -> Data Int -> Data Bool
+ Feldspar.Core.Functions: unfoldCore :: (Computable state, Storable a) => Data Length -> state -> (Data Int -> state -> (Data a, state)) -> (Data [a], state)
+ Feldspar.Core.Functions: xor :: (Bits a) => Data a -> Data a -> Data a
+ Feldspar.Core.Reify: class Program a
+ Feldspar.Core.Reify: instance [overlap ok] (Computable a) => Program a
+ Feldspar.Core.Reify: instance [overlap ok] (Computable a, Computable b) => Program (a -> b)
+ Feldspar.Core.Reify: instance [overlap ok] (Computable a, Computable b) => Program (a, b)
+ Feldspar.Core.Reify: instance [overlap ok] (Computable a, Computable b, Computable c) => Program (a -> b -> c)
+ Feldspar.Core.Reify: instance [overlap ok] (Computable a, Computable b, Computable c) => Program (a, b, c)
+ Feldspar.Core.Reify: instance [overlap ok] (Computable a, Computable b, Computable c, Computable d) => Program (a -> b -> c -> d)
+ Feldspar.Core.Reify: instance [overlap ok] (Computable a, Computable b, Computable c, Computable d) => Program (a, b, c, d)
+ Feldspar.Core.Reify: instance [overlap ok] (Computable a, Computable b, Computable c, Computable d, Computable e) => Program (a -> b -> c -> d -> e)
+ Feldspar.Core.Reify: numArgs :: (Program a) => T a -> Int
+ Feldspar.Core.Reify: printCore :: (Program a) => a -> IO ()
+ Feldspar.Core.Reify: printCoreWithSize :: (Program a) => a -> IO ()
+ Feldspar.Core.Reify: reify :: (Program a) => a -> Graph
+ Feldspar.Core.Reify: showCore :: (Program a) => a -> String
+ Feldspar.Core.Reify: showCoreWithSize :: (Program a) => a -> String
+ Feldspar.Core.Show: sizeComment :: Tuple StorableType -> String
+ Feldspar.Core.Types: (:>) :: a -> b -> :> a b
+ Feldspar.Core.Types: bitSize :: PrimitiveType -> Int
+ Feldspar.Core.Types: class (Num a, Primitive a, Num (Size a)) => Numeric a
+ Feldspar.Core.Types: class Set a
+ Feldspar.Core.Types: instance [overlap ok] (Eq a, Eq b) => Eq (a :> b)
+ Feldspar.Core.Types: instance [overlap ok] (Monoid a, Monoid b) => Monoid (a :> b)
+ Feldspar.Core.Types: instance [overlap ok] (Ord a) => Set (Range a)
+ Feldspar.Core.Types: instance [overlap ok] (Ord a, Ord b) => Ord (a :> b)
+ Feldspar.Core.Types: instance [overlap ok] (Set a, Set b) => Set (a :> b)
+ Feldspar.Core.Types: instance [overlap ok] (Set a, Set b) => Set (a, b)
+ Feldspar.Core.Types: instance [overlap ok] (Set a, Set b, Set c) => Set (a, b, c)
+ Feldspar.Core.Types: instance [overlap ok] (Set a, Set b, Set c, Set d) => Set (a, b, c, d)
+ Feldspar.Core.Types: instance [overlap ok] (Show a, Show b) => Show (a :> b)
+ Feldspar.Core.Types: instance [overlap ok] (Storable a) => Storable [a]
+ Feldspar.Core.Types: instance [overlap ok] (Storable a) => Typeable [a]
+ Feldspar.Core.Types: instance [overlap ok] Numeric Float
+ Feldspar.Core.Types: instance [overlap ok] Numeric Int
+ Feldspar.Core.Types: instance [overlap ok] Set ()
+ Feldspar.Core.Types: listSize :: (Storable a) => T a -> Size a -> [Range Length]
+ Feldspar.Core.Types: mkT :: a -> T a
+ Feldspar.Core.Types: primitiveData :: (Primitive a) => a -> PrimitiveData
+ Feldspar.Core.Types: primitiveType :: (Primitive a) => Size a -> T a -> PrimitiveType
+ Feldspar.Core.Types: showStorableSize :: StorableType -> String
+ Feldspar.Core.Types: signed :: PrimitiveType -> Bool
+ Feldspar.Core.Types: storableData :: (Storable a) => a -> StorableData
+ Feldspar.Core.Types: storableSize :: (Storable a) => a -> Size a
+ Feldspar.Core.Types: storableType :: (Storable a) => Size a -> T a -> StorableType
+ Feldspar.Core.Types: type Length = Int
+ Feldspar.Core.Types: typeOfStorable :: (Storable a) => Size a -> T a -> Tuple StorableType
+ Feldspar.Core.Types: universal :: (Set a) => a
+ Feldspar.Core.Types: valueSet :: PrimitiveType -> (Range Integer)
+ Feldspar.Haskell: (-$-) :: (HaskellValue a) => String -> a -> String
+ Feldspar.Haskell: (-=-) :: (HaskellValue patt, HaskellValue def) => patt -> def -> String
+ Feldspar.Haskell: class HaskellType a
+ Feldspar.Haskell: class HaskellValue a
+ Feldspar.Haskell: haskellType :: (HaskellType a) => a -> String
+ Feldspar.Haskell: haskellValue :: (HaskellValue a) => a -> String
+ Feldspar.Haskell: ifThenElse :: (HaskellValue c, HaskellValue t, HaskellValue e) => c -> t -> e -> String
+ Feldspar.Haskell: indent :: Int -> String -> String
+ Feldspar.Haskell: instance [overlap ok] HaskellValue Int
+ Feldspar.Haskell: instance [overlap ok] HaskellValue String
+ Feldspar.Haskell: local :: String -> String -> String
+ Feldspar.Haskell: newline :: String
+ Feldspar.Haskell: opApp :: (HaskellValue a, HaskellValue b) => String -> a -> b -> String
+ Feldspar.Haskell: unlinesNoTrail :: [String] -> String
+ Feldspar.Range: (/\) :: (Ord a) => Range a -> Range a -> Range a
+ Feldspar.Range: (\/) :: (Ord a) => Range a -> Range a -> Range a
+ Feldspar.Range: Range :: Maybe a -> Maybe a -> Range a
+ Feldspar.Range: data (Ord a) => Range a
+ Feldspar.Range: disjoint :: (Ord a, Num a) => Range a -> Range a -> Bool
+ Feldspar.Range: emptyRange :: (Ord a, Num a) => Range a
+ Feldspar.Range: fullRange :: (Ord a) => Range a
+ Feldspar.Range: inRange :: (Ord a) => a -> Range a -> Bool
+ Feldspar.Range: instance [overlap ok] (Arbitrary a, Ord a, Num a) => Arbitrary (Range a)
+ Feldspar.Range: instance [overlap ok] (Ord a) => Eq (Range a)
+ Feldspar.Range: instance [overlap ok] (Ord a, Num a) => Monoid (Range a)
+ Feldspar.Range: instance [overlap ok] (Ord a, Num a) => Num (Range a)
+ Feldspar.Range: instance [overlap ok] (Ord a, Show a) => Show (Range a)
+ Feldspar.Range: isBounded :: (Ord a) => Range a -> Bool
+ Feldspar.Range: isEmpty :: (Ord a) => Range a -> Bool
+ Feldspar.Range: isFull :: (Ord a) => Range a -> Bool
+ Feldspar.Range: isNatural :: (Ord a, Num a) => Range a -> Bool
+ Feldspar.Range: isNegative :: (Ord a, Num a) => Range a -> Bool
+ Feldspar.Range: isSingleton :: (Ord a) => Range a -> Bool
+ Feldspar.Range: isSubRangeOf :: (Ord a) => Range a -> Range a -> Bool
+ Feldspar.Range: liftMaybe2 :: (a -> a -> a) -> Maybe a -> Maybe a -> Maybe a
+ Feldspar.Range: lowerBound :: Range a -> Maybe a
+ Feldspar.Range: mapMonotonic :: (Ord a, Ord b) => (a -> b) -> Range a -> Range b
+ Feldspar.Range: naturalRange :: (Ord a, Num a) => Range a
+ Feldspar.Range: negativeRange :: (Ord a, Num a) => Range a
+ Feldspar.Range: prop_arith1 :: (forall a. (Num a) => a -> a) -> Int -> Range Int -> Property
+ Feldspar.Range: prop_arith2 :: (forall a. (Num a) => a -> a -> a) -> Int -> Int -> Range Int -> Range Int -> Property
+ Feldspar.Range: range :: (Ord a) => a -> a -> Range a
+ Feldspar.Range: rangeByRange :: (Ord a) => Range a -> Range a -> Range a
+ Feldspar.Range: rangeGap :: (Ord a, Num a) => Range a -> Range a -> Range a
+ Feldspar.Range: rangeLess :: (Ord a) => Range a -> Range a -> Bool
+ Feldspar.Range: rangeLessEq :: (Ord a) => Range a -> Range a -> Bool
+ Feldspar.Range: rangeMul :: (Ord a, Num a) => Range a -> Range a -> Range a
+ Feldspar.Range: rangeOp :: (Ord a) => (Range a -> Range a) -> (Range a -> Range a)
+ Feldspar.Range: rangeOp2 :: (Ord a) => (Range a -> Range a -> Range a) -> (Range a -> Range a -> Range a)
+ Feldspar.Range: rangeSize :: (Ord a, Num a) => Range a -> Maybe a
+ Feldspar.Range: showBound :: (Show a) => Maybe a -> String
+ Feldspar.Range: showRange :: (Show a, Ord a) => Range a -> String
+ Feldspar.Range: singletonRange :: (Ord a) => a -> Range a
+ Feldspar.Range: upperBound :: Range a -> Maybe a
+ Feldspar.Utils: appendFirstLine :: String -> String -> String
+ Feldspar.Vector: (...) :: Data Int -> Data Int -> Vector (Data Int)
+ Feldspar.Vector: boundVector :: Int -> Vector a -> Vector a
+ Feldspar.Vector: data Vector a
+ Feldspar.Vector: inits1 :: Vector a -> Vector (Vector a)
+ Feldspar.Vector: instance [overlap ok] (Storable a) => Computable (Vector (Data a))
+ Feldspar.Vector: instance [overlap ok] (Storable a) => Computable (Vector (Vector (Data a)))
+ Feldspar.Vector: instance [overlap ok] RandomAccess (Vector a)
+ Feldspar.Vector: mapAccum :: (Storable a, Computable acc, Storable b) => (acc -> Data a -> (acc, Data b)) -> acc -> Vector (Data a) -> (acc, Vector (Data b))
+ Feldspar.Vector: memorize :: (Storable a) => Vector (Data a) -> Vector (Data a)
+ Feldspar.Vector: modifyLength :: (Data Length -> Data Length) -> Vector a -> Vector a
+ Feldspar.Vector: setLength :: Data Length -> Vector a -> Vector a
+ Feldspar.Vector: type DVector a = Vector (Data a)
+ Feldspar.Vector: unfoldVec :: (Computable state, Storable a) => Data Length -> state -> (Data Int -> state -> (Data a, state)) -> (Vector (Data a), state)
- Feldspar.Core: (!) :: (RandomAccess a) => a -> Data Int -> Elem a
+ Feldspar.Core: (!) :: (RandomAccess a) => a -> Data Int -> Element a
- Feldspar.Core: array :: (NaturalT n, Storable a) => ListBased (n :> a) -> Data (n :> a)
+ Feldspar.Core: array :: (Storable a) => Size a -> a -> Data a
- Feldspar.Core: class RandomAccess a where { type family Elem a; }
+ Feldspar.Core: class RandomAccess a where { type family Element a; }
- Feldspar.Core: class (Typeable a) => Storable a where { type family ListBased a :: *; }
+ Feldspar.Core: class (Typeable a) => Storable a
- Feldspar.Core: data (:>) n a
+ Feldspar.Core: data (:>) a b
- Feldspar.Core: getIx :: (NaturalT n, Storable a) => Data (n :> a) -> Data Int -> Data a
+ Feldspar.Core: getIx :: (Storable a) => Data [a] -> Data Int -> Data a
- Feldspar.Core: parallel :: (NaturalT n, Storable a) => Data Int -> (Data Int -> Data a) -> Data (n :> a)
+ Feldspar.Core: parallel :: (Storable a) => Data Length -> (Data Int -> Data a) -> Data [a]
- Feldspar.Core: setIx :: (NaturalT n, Storable a) => Data (n :> a) -> Data Int -> Data a -> Data (n :> a)
+ Feldspar.Core: setIx :: (Storable a) => Data [a] -> Data Int -> Data a -> Data [a]
- Feldspar.Core: size :: (NaturalT n, Storable a) => Data (n :> a) -> [Int]
+ Feldspar.Core: size :: (Storable a) => Data [a] -> [Range Length]
- Feldspar.Core: value :: (Primitive a) => a -> Data a
+ Feldspar.Core: value :: (Storable a) => a -> Data a
- Feldspar.Core: while :: (Computable a) => (a -> Data Bool) -> (a -> a) -> (a -> a)
+ Feldspar.Core: while :: (Computable state) => (state -> Data Bool) -> (state -> state) -> (state -> state)
- Feldspar.Core.Expr: (!) :: (RandomAccess a) => a -> Data Int -> Elem a
+ Feldspar.Core.Expr: (!) :: (RandomAccess a) => a -> Data Int -> Element a
- Feldspar.Core.Expr: Data :: (Ref (Expr a)) -> Data a
+ Feldspar.Core.Expr: Data :: (Size a) -> (Ref (Expr a)) -> Data a
- Feldspar.Core.Expr: Function :: String -> (a -> b) -> Data a -> Expr b
+ Feldspar.Core.Expr: Function :: String -> Size b -> (a -> b) -> Data a -> Expr b
- Feldspar.Core.Expr: IfThenElse :: Data Bool -> (Data a -> Data b) -> (Data a -> Data b) -> Data a -> Expr b
+ Feldspar.Core.Expr: IfThenElse :: Data Bool -> (a :-> b) -> (a :-> b) -> Data a -> Expr b
- Feldspar.Core.Expr: Input :: Expr a
+ Feldspar.Core.Expr: Input :: Size a -> Expr a
- Feldspar.Core.Expr: NoInline :: String -> Ref (Data a -> Data b) -> Data a -> Expr b
+ Feldspar.Core.Expr: NoInline :: String -> Ref (a :-> b) -> Data a -> Expr b
- Feldspar.Core.Expr: Parallel :: Data Int -> (Data Int -> Data a) -> Expr (n :> a)
+ Feldspar.Core.Expr: Parallel :: Data Length -> (Int :-> a) -> Expr [a]
- Feldspar.Core.Expr: Value :: a -> Expr a
+ Feldspar.Core.Expr: Value :: Size a -> a -> Expr a
- Feldspar.Core.Expr: While :: (Data a -> Data Bool) -> (Data a -> Data a) -> Data a -> Expr a
+ Feldspar.Core.Expr: While :: (a :-> Bool) -> (a :-> a) -> Data a -> Expr a
- Feldspar.Core.Expr: array :: (NaturalT n, Storable a) => ListBased (n :> a) -> Data (n :> a)
+ Feldspar.Core.Expr: array :: (Storable a) => Size a -> a -> Data a
- Feldspar.Core.Expr: class RandomAccess a where { type family Elem a; }
+ Feldspar.Core.Expr: class RandomAccess a where { type family Element a; }
- Feldspar.Core.Expr: function :: (Storable a, Storable b) => String -> (a -> b) -> (Data a -> Data b)
+ Feldspar.Core.Expr: function :: (Storable a, Storable b) => String -> (Size a -> Size b) -> (a -> b) -> (Data a -> Data b)
- Feldspar.Core.Expr: function2 :: (Storable a, Storable b, Storable c) => String -> (a -> b -> c) -> (Data a -> Data b -> Data c)
+ Feldspar.Core.Expr: function2 :: (Storable a, Storable b, Storable c) => String -> (Size a -> Size b -> Size c) -> (a -> b -> c) -> (Data a -> Data b -> Data c)
- Feldspar.Core.Expr: function3 :: (Storable a, Storable b, Storable c, Storable d) => String -> (a -> b -> c -> d) -> (Data a -> Data b -> Data c -> Data d)
+ Feldspar.Core.Expr: function3 :: (Storable a, Storable b, Storable c, Storable d) => String -> (Size a -> Size b -> Size c -> Size d) -> (a -> b -> c -> d) -> (Data a -> Data b -> Data c -> Data d)
- Feldspar.Core.Expr: function4 :: (Storable a, Storable b, Storable c, Storable d, Storable e) => String -> (a -> b -> c -> d -> e) -> (Data a -> Data b -> Data c -> Data d -> Data e)
+ Feldspar.Core.Expr: function4 :: (Storable a, Storable b, Storable c, Storable d, Storable e) => String -> (Size a -> Size b -> Size c -> Size d -> Size e) -> (a -> b -> c -> d -> e) -> (Data a -> Data b -> Data c -> Data d -> Data e)
- Feldspar.Core.Expr: getIx :: (NaturalT n, Storable a) => Data (n :> a) -> Data Int -> Data a
+ Feldspar.Core.Expr: getIx :: (Storable a) => Data [a] -> Data Int -> Data a
- Feldspar.Core.Expr: parallel :: (NaturalT n, Storable a) => Data Int -> (Data Int -> Data a) -> Data (n :> a)
+ Feldspar.Core.Expr: parallel :: (Storable a) => Data Length -> (Data Int -> Data a) -> Data [a]
- Feldspar.Core.Expr: setIx :: (NaturalT n, Storable a) => Data (n :> a) -> Data Int -> Data a -> Data (n :> a)
+ Feldspar.Core.Expr: setIx :: (Storable a) => Data [a] -> Data Int -> Data a -> Data [a]
- Feldspar.Core.Expr: size :: (NaturalT n, Storable a) => Data (n :> a) -> [Int]
+ Feldspar.Core.Expr: size :: (Storable a) => Data [a] -> [Range Length]
- Feldspar.Core.Expr: value :: (Primitive a) => a -> Data a
+ Feldspar.Core.Expr: value :: (Storable a) => a -> Data a
- Feldspar.Core.Expr: while :: (Computable a) => (a -> Data Bool) -> (a -> a) -> (a -> a)
+ Feldspar.Core.Expr: while :: (Computable state) => (state -> Data Bool) -> (state -> state) -> (state -> state)
- Feldspar.Core.Graph: Parallel :: Int -> Interface -> Function
+ Feldspar.Core.Graph: Parallel :: Interface -> Function
- Feldspar.Core.Show: showGraph :: String -> Bool -> Graph -> String
+ Feldspar.Core.Show: showGraph :: Bool -> String -> Bool -> Graph -> String
- Feldspar.Core.Show: showNode :: Node -> [Hierarchy] -> String
+ Feldspar.Core.Show: showNode :: Bool -> Node -> [Hierarchy] -> String
- Feldspar.Core.Show: showSF :: (HaskellValue inp, HaskellValue outp) => Hierarchy -> String -> inp -> outp -> String
+ Feldspar.Core.Show: showSF :: (HaskellValue inp, HaskellValue outp) => Bool -> Hierarchy -> String -> inp -> outp -> String
- Feldspar.Core.Show: showSubFun :: (HaskellValue inp, HaskellValue outp) => Hierarchy -> String -> Maybe inp -> outp -> String
+ Feldspar.Core.Show: showSubFun :: (HaskellValue inp, HaskellValue outp) => Bool -> Hierarchy -> String -> Maybe inp -> outp -> String
- Feldspar.Core.Types: FloatType :: PrimitiveType
+ Feldspar.Core.Types: FloatType :: (Range Float) -> PrimitiveType
- Feldspar.Core.Types: IntData :: Int -> PrimitiveData
+ Feldspar.Core.Types: IntData :: Integer -> PrimitiveData
- Feldspar.Core.Types: IntType :: PrimitiveType
+ Feldspar.Core.Types: IntType :: Bool -> Int -> (Range Integer) -> PrimitiveType
- Feldspar.Core.Types: StorableData :: Int -> [StorableData] -> StorableData
+ Feldspar.Core.Types: StorableData :: [StorableData] -> StorableData
- Feldspar.Core.Types: StorableType :: [Int] -> PrimitiveType -> StorableType
+ Feldspar.Core.Types: StorableType :: [Range Length] -> PrimitiveType -> StorableType
- Feldspar.Core.Types: UnitData :: PrimitiveData
+ Feldspar.Core.Types: UnitData :: () -> PrimitiveData
- Feldspar.Core.Types: class (Typeable a) => Storable a where { type family ListBased a :: *; type family Element a :: *; }
+ Feldspar.Core.Types: class (Typeable a) => Storable a
- Feldspar.Core.Types: class (Eq a, Ord a) => Typeable a
+ Feldspar.Core.Types: class (Eq a, Ord a, Monoid (Size a), Set (Size a)) => Typeable a where { type family Size a; }
- Feldspar.Core.Types: data (:>) n a
+ Feldspar.Core.Types: data (:>) a b
- Feldspar.Core.Types: typeOf :: (Typeable a) => T a -> Tuple StorableType
+ Feldspar.Core.Types: typeOf :: (Typeable a) => Size a -> T a -> Tuple StorableType
- Feldspar.Matrix: diagonal :: Matrix n n a -> VectorP n a
+ Feldspar.Matrix: diagonal :: Matrix a -> Vector (Data a)
- Feldspar.Matrix: flatten :: Matrix m n a -> VectorP (m :* n) a
+ Feldspar.Matrix: flatten :: Matrix a -> Vector (Data a)
- Feldspar.Matrix: freezeMatrix :: (NaturalT m, NaturalT n, Storable a) => Matrix m n a -> Data (m :> (n :> a))
+ Feldspar.Matrix: freezeMatrix :: (Storable a) => Matrix a -> Data [[a]]
- Feldspar.Matrix: matrix :: (NaturalT m, NaturalT n, Storable a, (ListBased a) ~ a) => [[a]] -> Matrix m n a
+ Feldspar.Matrix: matrix :: (Storable a) => [[a]] -> Matrix a
- Feldspar.Matrix: mul :: (Primitive a, Num a) => Matrix m n a -> Matrix n p a -> Matrix m p a
+ Feldspar.Matrix: mul :: (Numeric a) => Matrix a -> Matrix a -> Matrix a
- Feldspar.Matrix: transpose :: Matrix m n a -> Matrix n m a
+ Feldspar.Matrix: transpose :: Matrix a -> Matrix a
- Feldspar.Matrix: type Matrix m n a = Par m :>> (Par n :>> Data a)
+ Feldspar.Matrix: type Matrix a = Vector (Vector (Data a))
- Feldspar.Matrix: unfreezeMatrix :: (NaturalT m, NaturalT n, Storable a) => Data Int -> Data Int -> Data (m :> (n :> a)) -> Matrix m n a
+ Feldspar.Matrix: unfreezeMatrix :: (Storable a) => Data Length -> Data Length -> Data [[a]] -> Matrix a
- Feldspar.Vector: (++) :: (Computable a) => (t m :>> a) -> (t n :>> a) -> (t (m :+ n) :>> a)
+ Feldspar.Vector: (++) :: (Computable a) => Vector a -> Vector a -> Vector a
- Feldspar.Vector: Indexed :: Data Size -> (Data Ix -> a) -> Par n :>> a
+ Feldspar.Vector: Indexed :: Data Length -> (Data Ix -> a) -> Vector a
- Feldspar.Vector: drop :: Data Int -> (t n :>> a) -> (t n :>> a)
+ Feldspar.Vector: drop :: Data Int -> Vector a -> Vector a
- Feldspar.Vector: dropWhile :: (a -> Data Bool) -> (t n :>> a) -> (t n :>> a)
+ Feldspar.Vector: dropWhile :: (a -> Data Bool) -> Vector a -> Vector a
- Feldspar.Vector: enumFromTo :: (AccessPattern t) => Data Int -> Data Int -> (t n :>> Data Int)
+ Feldspar.Vector: enumFromTo :: Data Int -> Data Int -> Vector (Data Int)
- Feldspar.Vector: fold :: (Computable a) => (a -> b -> a) -> a -> (t n :>> b) -> a
+ Feldspar.Vector: fold :: (Computable a) => (a -> b -> a) -> a -> Vector b -> a
- Feldspar.Vector: fold1 :: (Computable a) => (a -> a -> a) -> (t n :>> a) -> a
+ Feldspar.Vector: fold1 :: (Computable a) => (a -> a -> a) -> Vector a -> a
- Feldspar.Vector: freezeVector :: (NaturalT n, Storable a) => (t n :>> Data a) -> Data (n :> a)
+ Feldspar.Vector: freezeVector :: (Storable a) => Vector (Data a) -> Data [a]
- Feldspar.Vector: head :: (t n :>> a) -> a
+ Feldspar.Vector: head :: Vector a -> a
- Feldspar.Vector: index :: (t :>> a) -> Data Ix -> a
+ Feldspar.Vector: index :: Vector a -> Data Ix -> a
- Feldspar.Vector: indexed :: Data Size -> (Data Ix -> a) -> (Par n :>> a)
+ Feldspar.Vector: indexed :: Data Length -> (Data Ix -> a) -> Vector a
- Feldspar.Vector: init :: (t n :>> a) -> (t n :>> a)
+ Feldspar.Vector: init :: Vector a -> Vector a
- Feldspar.Vector: inits :: (AccessPattern u) => (t n :>> a) -> (u n :>> (t n :>> a))
+ Feldspar.Vector: inits :: Vector a -> Vector (Vector a)
- Feldspar.Vector: last :: (t n :>> a) -> a
+ Feldspar.Vector: last :: Vector a -> a
- Feldspar.Vector: length :: (t n :>> a) -> Data Size
+ Feldspar.Vector: length :: Vector a -> Data Length
- Feldspar.Vector: map :: (a -> b) -> ((t n :>> a) -> (t n :>> b))
+ Feldspar.Vector: map :: (a -> b) -> Vector a -> Vector b
- Feldspar.Vector: maximum :: (Storable a) => (t n :>> Data a) -> Data a
+ Feldspar.Vector: maximum :: (Storable a) => Vector (Data a) -> Data a
- Feldspar.Vector: minimum :: (Storable a) => (t n :>> Data a) -> Data a
+ Feldspar.Vector: minimum :: (Storable a) => Vector (Data a) -> Data a
- Feldspar.Vector: permute :: (Data Size -> Data Ix -> Data Ix) -> ((Par n :>> a) -> (Par n :>> a))
+ Feldspar.Vector: permute :: (Data Length -> Data Ix -> Data Ix) -> (Vector a -> Vector a)
- Feldspar.Vector: replicate :: (AccessPattern t) => Data Int -> a -> (t n :>> a)
+ Feldspar.Vector: replicate :: Data Int -> a -> Vector a
- Feldspar.Vector: reverse :: (Par n :>> a) -> (Par n :>> a)
+ Feldspar.Vector: reverse :: Vector a -> Vector a
- Feldspar.Vector: scalarProd :: (Primitive a, Num a) => (t n :>> Data a) -> (t n :>> Data a) -> Data a
+ Feldspar.Vector: scalarProd :: (Numeric a) => Vector (Data a) -> Vector (Data a) -> Data a
- Feldspar.Vector: scan :: (Computable a) => (a -> b -> a) -> a -> (t n :>> b) -> (Seq n :>> a)
+ Feldspar.Vector: scan :: (Storable a, Computable b) => (Data a -> b -> Data a) -> Data a -> Vector b -> Vector (Data a)
- Feldspar.Vector: splitAt :: Data Int -> (t n :>> a) -> (t n :>> a, t n :>> a)
+ Feldspar.Vector: splitAt :: Data Int -> Vector a -> (Vector a, Vector a)
- Feldspar.Vector: sum :: (Num a, Computable a) => (t n :>> a) -> a
+ Feldspar.Vector: sum :: (Num a, Computable a) => Vector a -> a
- Feldspar.Vector: tail :: (t n :>> a) -> (t n :>> a)
+ Feldspar.Vector: tail :: Vector a -> Vector a
- Feldspar.Vector: tails :: (AccessPattern u) => (t n :>> a) -> (u n :>> (t n :>> a))
+ Feldspar.Vector: tails :: Vector a -> Vector (Vector a)
- Feldspar.Vector: take :: Data Int -> (t n :>> a) -> (t n :>> a)
+ Feldspar.Vector: take :: Data Int -> Vector a -> Vector a
- Feldspar.Vector: unfold :: (Computable s) => Data Size -> (s -> (a, s)) -> s -> (Seq n :>> a)
+ Feldspar.Vector: unfold :: (Computable state, Storable a) => Data Length -> state -> (state -> (Data a, state)) -> Vector (Data a)
- Feldspar.Vector: unfreezeVector :: (NaturalT n, Storable a, AccessPattern t) => Data Size -> Data (n :> a) -> (t n :>> Data a)
+ Feldspar.Vector: unfreezeVector :: (Storable a) => Data Length -> Data [a] -> Vector (Data a)
- Feldspar.Vector: unzip :: (t n :>> (a, b)) -> (t n :>> a, t n :>> b)
+ Feldspar.Vector: unzip :: Vector (a, b) -> (Vector a, Vector b)
- Feldspar.Vector: vector :: (NaturalT n, Storable a, AccessPattern t, (ListBased a) ~ a) => [a] -> (t n :>> Data a)
+ Feldspar.Vector: vector :: (Storable a) => [a] -> Vector (Data a)
- Feldspar.Vector: zip :: (t n :>> a) -> (t n :>> b) -> (t n :>> (a, b))
+ Feldspar.Vector: zip :: Vector a -> Vector b -> Vector (a, b)
- Feldspar.Vector: zipWith :: (a -> b -> c) -> (t n :>> a) -> (t n :>> b) -> (t n :>> c)
+ Feldspar.Vector: zipWith :: (a -> b -> c) -> Vector a -> Vector b -> Vector c

Files

Feldspar.hs view
@@ -1,4 +1,4 @@--- Copyright (c) 2009, ERICSSON AB+-- Copyright (c) 2009-2010, ERICSSON AB -- All rights reserved. -- -- Redistribution and use in source and binary forms, with or without@@ -24,7 +24,7 @@ -- OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -- OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. --- | Exports everything necessary for ordinary use of the Feldspar language.+-- | Interface to the Feldspar language.  module Feldspar   ( module Feldspar.Prelude@@ -34,6 +34,10 @@   ) where  ++import qualified Prelude+  -- In order to be able to play with the Feldspar module in GHCi without+  -- getting name clashes.  import Feldspar.Prelude import Feldspar.Core
Feldspar/Core.hs view
@@ -1,4 +1,4 @@--- Copyright (c) 2009, ERICSSON AB+-- Copyright (c) 2009-2010, ERICSSON AB -- All rights reserved. -- -- Redistribution and use in source and binary forms, with or without@@ -24,42 +24,49 @@ -- OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -- OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. --- | The user interface to the core language+-- | The user interface of the core language  module Feldspar.Core-  ( module Types.Data.Num-  , Primitive-  , (:>)+  ( Range (..)+  , (:>) (..)+  , Set (..)+  , Length   , Storable-  , ListBased+  , Size   , Data+  , dataSize   , Computable   , Internal   , eval   , value+  , array+  , arrayLen   , unit   , true   , false-  , array   , size+  , cap   , getIx   , setIx   , RandomAccess (..)+  , Numeric   , noInline   , ifThenElse   , while   , parallel   , Program   , showCore+  , showCoreWithSize   , printCore+  , printCoreWithSize   , module Feldspar.Core.Functions   ) where   -import Types.Data.Num-+import Feldspar.Range import Feldspar.Core.Types import Feldspar.Core.Expr+import Feldspar.Core.Reify import Feldspar.Core.Functions 
Feldspar/Core/Expr.hs view
@@ -1,4 +1,4 @@--- Copyright (c) 2009, ERICSSON AB+-- Copyright (c) 2009-2010, ERICSSON AB -- All rights reserved. -- -- Redistribution and use in source and binary forms, with or without@@ -24,120 +24,182 @@ -- OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -- OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -{-# LANGUAGE IncoherentInstances #-}+{-# LANGUAGE UndecidableInstances #-} --- | This module represents core programs as typed expressions (see 'Expr' /--- 'Data'). The idea is for programmers to use an interface based on 'Data',--- while back-end tools use the 'Graph' representation. The function 'toGraph'--- is used to convert between the two representations.+-- | This module gives a representation core programs as typed expressions (see+-- 'Expr' / 'Data').  module Feldspar.Core.Expr where   -import Control.Monad.State-import Control.Monad.Writer-import Data.Map (Map)-import qualified Data.Map as Map-import Data.Maybe+import Data.Monoid import Data.Unique -import Types.Data.Num--import Feldspar.Core.Ref (Ref)-import qualified Feldspar.Core.Ref as Ref+import Feldspar.Range import Feldspar.Core.Types-import Feldspar.Core.Graph hiding (function, Function (..))-import qualified Feldspar.Core.Graph as Graph-import Feldspar.Core.Show+import Feldspar.Core.Ref   --- * Expressions+-- | Typed core language expressions. A value of type @`Expr` a@ is a+-- representation of a program that computes a value of type @a@.+data Expr a+  where+    Input :: Size a -> Expr a+      -- XXX Risky to rely on observable sharing? +    Value :: Storable a => Size a -> a -> Expr a++    Tuple2 :: Data a -> Data b -> Expr (a,b)+    Tuple3 :: Data a -> Data b -> Data c -> Expr (a,b,c)+    Tuple4 :: Data a -> Data b -> Data c -> Data d -> Expr (a,b,c,d)+      -- XXX Tuple construction should be generalized.++    Get21 :: Data (a,b) -> Expr a+    Get22 :: Data (a,b) -> Expr b++    Get31 :: Data (a,b,c) -> Expr a+    Get32 :: Data (a,b,c) -> Expr b+    Get33 :: Data (a,b,c) -> Expr c++    Get41 :: Data (a,b,c,d) -> Expr a+    Get42 :: Data (a,b,c,d) -> Expr b+    Get43 :: Data (a,b,c,d) -> Expr c+    Get44 :: Data (a,b,c,d) -> Expr d+      -- XXX Tuple projection should be generalized.++    Function :: String -> Size b -> (a -> b) -> (Data a -> Expr b)++    NoInline :: String -> Ref (a :-> b) -> (Data a -> Expr b)++    IfThenElse+      :: Data Bool           -- Condition+      -> (a :-> b)           -- If branch+      -> (a :-> b)           -- Else branch+      -> (Data a -> Expr b)++    While+      :: (a :-> Bool)  -- Continue?+      -> (a :-> a)     -- Body+      -> Data a        -- Initial state+      -> Expr a        -- Final state++    Parallel+      :: Storable a+      => Data Length+      -> (Int :-> a)  -- Index mapping+      -> Expr [a]     -- Result vector++++data a :-> b = SubFunction (Data a -> Data b) (Data a) (Data b)+++ -- | A wrapper around 'Expr' to allow observable sharing (see--- "Feldspar.Core.Ref").-data Data a = Typeable a => Data (Ref (Expr a))+-- "Feldspar.Core.Ref") and for memoizing size information.+data Data a = Typeable a => Data (Size a) (Ref (Expr a))  instance Eq (Data a)   where-    Data a == Data b = a==b+    Data _ a == Data _ b = a==b+      -- Reference equality  instance Ord (Data a)   where-    Data a `compare` Data b = a `compare` b+    Data _ a `compare` Data _ b = a `compare` b+      -- Reference comparison   -ref :: Typeable a => Expr a -> Data a-ref = Data . Ref.ref+dataSize :: Data a -> Size a+dataSize (Data sz _) = sz -refId :: Data a -> Unique-refId (Data r) = Ref.refId r+dataType :: forall a . Data a -> Tuple StorableType+dataType a@(Data _ _) = typeOf (dataSize a) (T::T a) -deref :: Data a -> Expr a-deref (Data r) = Ref.deref r+dataId :: Data a -> Unique+dataId (Data _ r) = refId r -typeOfData :: forall a . Typeable a => Data a -> Tuple StorableType-typeOfData _ = typeOf (T::T a)+dataToExpr :: Data a -> Expr a+dataToExpr (Data _ r) = deref r +subFunSize :: (a :-> b) -> Size b+subFunSize (SubFunction _ _ outp) = dataSize outp +subAp :: (a :-> b) -> (Data a -> Data b)+subAp (SubFunction f _ _) = f --- | Typed core language expressions. A value of type @Expr a@ can be thought of--- as a representation of a program that computes a value of type @a@.-data Expr a+exprToData :: Typeable a => Expr a -> Data a+exprToData a = Data (exprSize a) (ref a)++++exprSize :: forall a . Typeable a => Expr a -> Size a++exprSize (Input sz)   = sz+exprSize (Value sz _) = sz++exprSize (Tuple2 a b)     = (dataSize a, dataSize b)+exprSize (Tuple3 a b c)   = (dataSize a, dataSize b, dataSize c)+exprSize (Tuple4 a b c d) = (dataSize a, dataSize b, dataSize c, dataSize d)++exprSize (Get21 ab) = da   where-    Input :: Expr a  -- XXX Risky to rely on observable sharing?-    Value :: Storable a => a -> Expr a+    (da,db) = dataSize ab -    Tuple2   :: Data a -> Data b -> Expr (a,b)-    Tuple3   :: Data a -> Data b -> Data c -> Expr (a,b,c)-    Tuple4   :: Data a -> Data b -> Data c -> Data d -> Expr (a,b,c,d)-    GetTuple :: GetTuple n a => T n -> Data a -> Expr (Part n a)+exprSize (Get22 ab) = db+  where+    (da,db) = dataSize ab -    Function :: String -> (a -> b) -> (Data a -> Expr b)+exprSize (Get31 abc) = da+  where+    (da,db,dc) = dataSize abc -    NoInline-      :: (Typeable a, Typeable b)-      => String -> Ref.Ref (Data a -> Data b) -> (Data a -> Expr b)+exprSize (Get32 abc) = db+  where+    (da,db,dc) = dataSize abc -    IfThenElse-      :: (Typeable a, Typeable b)-      => Data Bool           -- Condition-      -> (Data a -> Data b)  -- If branch-      -> (Data a -> Data b)  -- Else branch-      -> (Data a -> Expr b)+exprSize (Get33 abc) = dc+  where+    (da,db,dc) = dataSize abc -    While-      :: Typeable a-      => (Data a -> Data Bool)  -- Continue?-      -> (Data a -> Data a)     -- Body-      -> Data a                 -- Initial state-      -> Expr a                 -- Final state+exprSize (Get41 abcd) = da+  where+    (da,db,dc,dd) = dataSize abcd -    Parallel-      :: (NaturalT n, Storable a)-      => Data Int              -- Dynamic size (must be <= array size)-      -> (Data Int -> Data a)  -- Index mapping-      -> Expr (n :> a)         -- Result vector+exprSize (Get42 abcd) = db+  where+    (da,db,dc,dd) = dataSize abcd -  -- XXX Some Typeable constraints are needed because the sub-functions need to-  --     be applied to input. Perhaps it's better to scrap the hidden context in-  --     Data and put Typeable context on all Expr constructors instead?+exprSize (Get43 abcd) = dc+  where+    (da,db,dc,dd) = dataSize abcd +exprSize (Get44 abcd) = dd+  where+    (da,db,dc,dd) = dataSize abcd +exprSize (Function _ sz _ _)  = sz+exprSize (NoInline _ f a)     = subFunSize (deref f)+exprSize (IfThenElse _ t e a) = subFunSize t `mappend` subFunSize e+exprSize (While _ b i)        = dataSize i   `mappend` subFunSize b+exprSize (Parallel l ixf)     = mapMonotonic fromIntegral (dataSize l)+                                :> subFunSize ixf ++ -- | Computable types. A computable value completely represents a core program,--- in such a way that @internalize . externalize@ preserves semantics, but not--- necessarily syntax.+-- in such a way that @`internalize` `.` `externalize`@ preserves semantics, but+-- not necessarily syntax. -- -- The terminology used in this class comes from thinking of the 'Data' type as--- the \"internal core language\" and the core API as the \"external core--- language\".+-- the \"internal\" core language and the "Feldspar.Core" API as the+-- \"external\" core language. class Typeable (Internal a) => Computable a   where-    -- | The internal representation of the type @a@ (without the 'Data'-    -- constructor).+    -- | @`Data` (`Internal` a)@ is the internal representation of the type @a@.     type Internal a      -- | Convert to internal representation@@ -157,26 +219,26 @@   where     type Internal (a,b) = (Internal a, Internal b) -    internalize (a,b) = ref $ Tuple2 (internalize a) (internalize b)+    internalize (a,b) = exprToData $ Tuple2 (internalize a) (internalize b)      externalize ab =-        ( externalize $ ref $ GetTuple (T::T D0) ab-        , externalize $ ref $ GetTuple (T::T D1) ab+        ( externalizeE $ Get21 ab+        , externalizeE $ Get22 ab         )  instance (Computable a, Computable b, Computable c) => Computable (a,b,c)   where     type Internal (a,b,c) = (Internal a, Internal b, Internal c) -    internalize (a,b,c) = ref $ Tuple3+    internalize (a,b,c) = exprToData $ Tuple3       (internalize a)       (internalize b)       (internalize c)      externalize abc =-        ( externalize $ ref $ GetTuple (T::T D0) abc-        , externalize $ ref $ GetTuple (T::T D1) abc-        , externalize $ ref $ GetTuple (T::T D2) abc+        ( externalizeE $ Get31 abc+        , externalizeE $ Get32 abc+        , externalizeE $ Get33 abc         )  instance@@ -189,102 +251,139 @@   where     type Internal (a,b,c,d) = (Internal a, Internal b, Internal c, Internal d) -    internalize (a,b,c,d) = ref $ Tuple4+    internalize (a,b,c,d) = exprToData $ Tuple4       (internalize a)       (internalize b)       (internalize c)       (internalize d)      externalize abcd =-        ( externalize $ ref $ GetTuple (T::T D0) abcd-        , externalize $ ref $ GetTuple (T::T D1) abcd-        , externalize $ ref $ GetTuple (T::T D2) abcd-        , externalize $ ref $ GetTuple (T::T D3) abcd+        ( externalizeE $ Get41 abcd+        , externalizeE $ Get42 abcd+        , externalizeE $ Get43 abcd+        , externalizeE $ Get44 abcd         )   -wrap :: (Computable a, Computable b) =>+externalizeE :: Computable a => Expr (Internal a) -> a+externalizeE = externalize . exprToData++-- | Lower a function to operate on internal representation.+lowerFun :: (Computable a, Computable b) =>     (a -> b) -> (Data (Internal a) -> Data (Internal b))-wrap f = internalize . f . externalize+lowerFun f = internalize . f . externalize -unwrap :: (Computable a, Computable b) =>+-- | Lift a function to operate on external representation.+liftFun :: (Computable a, Computable b) =>     (Data (Internal a) -> Data (Internal b)) -> (a -> b)-unwrap f = externalize . f . internalize+liftFun f = externalize . f . internalize    -- | The semantics of expressions evalE :: Expr a -> a -evalE Input     = error "evaluating Input"-evalE (Value a) = a+evalE (Input _)   = error "evaluating Input"+evalE (Value _ a) = a  evalE (Tuple2 a b)     = (evalD a, evalD b) evalE (Tuple3 a b c)   = (evalD a, evalD b, evalD c) evalE (Tuple4 a b c d) = (evalD a, evalD b, evalD c, evalD d)-evalE (GetTuple n a)   = getTup n (evalD a) -evalE (Function _ f a)     = f (evalD a)-evalE (NoInline _ f a)     = evalD (Ref.deref f a)-evalE (IfThenElse c t e a) = if evalD c then evalD (t a) else evalD (e a)+evalE (Get21 ab) = a+  where+    (a,b) = evalD ab -evalE (While continue body init) = loop init+evalE (Get22 ab) = b   where-    loop s-        | done      = evalD s-        | otherwise = loop (body s)-      where-        done = not $ evalD $ continue s+    (a,b) = evalD ab -evalE (Parallel sz ixf) =-    mapArray (evalD . ixf . value) $ fromList [(0::Int) .. n-1]+evalE (Get31 abc) = a   where-    n = evalD sz+    (a,b,c) = evalD abc +evalE (Get32 abc) = b+  where+    (a,b,c) = evalD abc +evalE (Get33 abc) = c+  where+    (a,b,c) = evalD abc --- | Evaluation of 'Data'-evalD :: Data a -> a-evalD = evalE . deref+evalE (Get41 abcd) = a+  where+    (a,b,c,d) = evalD abcd --- | Evaluation of any 'Computable' type-eval :: Computable a => a -> Internal a-eval = evalD . internalize+evalE (Get42 abcd) = b+  where+    (a,b,c,d) = evalD abcd +evalE (Get43 abcd) = c+  where+    (a,b,c,d) = evalD abcd +evalE (Get44 abcd) = d+  where+    (a,b,c,d) = evalD abcd -instance Primitive a => Show (Data a)+evalE (Function _ _ f a)   = f (evalD a)+evalE (NoInline _ f a)     = evalD $ subAp (deref f) a+evalE (IfThenElse c t e a) = if evalD c+    then evalD (subAp t a)+    else evalD (subAp e a)++evalE (While continue body init) = loop init   where-    show a = "... :: Data a"-  -- Needed for the @Num@ instance.+    loop s = if done+        then evalD s+        else loop (subAp body s)+      where+        done = not $ evalD $ subAp continue s -instance (Num n, Primitive n) => Num (Data n)+evalE (Parallel l ixf) = map (evalD . subAp ixf . value) [0 .. n-1]   where-    fromInteger = value . fromInteger-    abs         = functionFold "abs" abs-    signum      = functionFold "signum" signum-    (+)         = functionFold2 "(+)" (+)-    (-)         = functionFold2 "(-)" (-)-    (*)         = functionFold2 "(*)" (*)+    n = evalD l   -instance Fractional (Data Float)-  where-    fromRational = value . fromRational-    (/)          = functionFold2 "(/)" (/)+-- | The semantics of 'Data'+evalD :: Data a -> a+evalD = evalE . dataToExpr +-- | The semantics of any 'Computable' type+eval :: Computable a => a -> Internal a+eval = evalD . internalize  --- | Internal function for constructing storable values.-value_ :: Storable a => a -> Data a-value_ = ref . Value --- | A primitive value (a program that computes a constant value)-value :: Primitive a => a -> Data a-value = value_+-- | A program that computes a constant value+value :: Storable a => a -> Data a+value a = exprToData (Value (storableSize a) a) +-- | Like 'value' but with an extra 'Size' argument that can be used to increase+-- the size beyond the given data.+--+-- Example 1:+--+-- > array (10 :> 20 :> universal) [] :: Data [[Int]]+--+-- gives an uninitialized 10x20 array of 'Int' elements.+--+-- Example 2:+--+-- > array (10 :> 20 :> universal) [[1,2,3]] :: Data [[Int]]+--+-- gives a 10x20 array whose first row is initialized to @[1,2,3]@.+array :: Storable a => Size a -> a -> Data a+array sz a = exprToData $ Value (sz `mappend` storableSize a) a++arrayLen :: Storable a => Data Length -> [a] -> Data [a]+arrayLen len = array sz+  where+    sz = mapMonotonic fromInteger (dataSize len) :> universal+  -- XXX This function is a temporary solution.+ unit :: Data () unit = value () @@ -294,58 +393,82 @@ false :: Data Bool false = value False --- | For example,------ > array [[1,2,3],[4,5]] :: Data (D2 :> D4 :> Int)------ is a 2x4-element array of @Int@s, with the first row initialized to @[1,2,3]@--- and the second row to @[4,5]@.-array :: (NaturalT n, Storable a) => ListBased (n :> a) -> Data (n :> a)-array = value_ . fromList- -- | Returns the size of each level of a multi-dimensional array, starting with -- the outermost level.-size :: (NaturalT n, Storable a) => Data (n :> a) -> [Int]-size arr = szs-  where-    One (StorableType szs _) = typeOfData arr+size :: forall a . Storable a => Data [a] -> [Range Length]+size = listSize (T::T [a]) . dataSize +cap :: (Storable a, Size a ~ Range b, Ord b) => Range b -> Data a -> Data a+cap szb (Data sz a) = Data (sz /\ szb) a+  -- XXX Should really have the type+  --       cap :: Storable a => Size a -> Data a -> Data a  --- | A one-argument primitive function. The first argument is the name of the--- function, and the second argument gives its evaluation semantics.-function :: (Storable a, Storable b) => String -> (a -> b) -> (Data a -> Data b)-function fun f = ref . Function fun f +-- | Constructs a one-argument primitive function.+--+-- @`function` fun szf f@:+--+--   * @fun@ is the name of the function.+--+--   * @szf@ computes the output size from the input size.+--+--   * @f@   gives the evaluation semantics.+function+    :: (Storable a, Storable b)+    => String -> (Size a -> Size b) -> (a -> b) -> (Data a -> Data b) +function fun sizeProp f a = case dataToExpr a of+    Value _ a' -> Data s (ref $ Value s $ f a')+    _          -> exprToData $ Function fun s f a+  where+    s = sizeProp (dataSize a) --- | A two-argument function+++-- | A two-argument primitive function function2     :: ( Storable a        , Storable b        , Storable c        )-    => String -> (a -> b -> c) -> (Data a -> Data b -> Data c)+    => String+    -> (Size a -> Size b -> Size c)+    -> (a -> b -> c)+    -> (Data a -> Data b -> Data c) -function2 fun f a b = ref $ Function fun (\(a,b) -> f a b) (ref $ Tuple2 a b)+function2 fun sizeProp f a b = case (dataToExpr a, dataToExpr b) of+    (Value _ a', Value _ b') -> Data s (ref $ Value s $ f a' b')+    _ -> exprToData $ Function fun s f' $ exprToData $ Tuple2 a b+  where+    s = sizeProp (dataSize a) (dataSize b)+    f' (a,b) = f a b   --- | A three-argument function+-- | A three-argument primitive function function3     :: ( Storable a        , Storable b        , Storable c        , Storable d        )-    => String -> (a -> b -> c -> d) -> (Data a -> Data b -> Data c -> Data d)+    => String+    -> (Size a -> Size b -> Size c -> Size d)+    -> (a -> b -> c -> d)+    -> (Data a -> Data b -> Data c -> Data d) -function3 fun f a b c =-    ref $ Function fun (\(a,b,c) -> f a b c) (ref $ Tuple3 a b c)+function3 fun sizeProp f a b c = case (d2e a, d2e b, d2e c) of+    (Value _ a', Value _ b', Value _ c') -> Data s (ref $ Value s $ f a' b' c')+    _ -> exprToData $ Function fun s f' $ exprToData $ Tuple3 a b c+  where+    d2e = dataToExpr+    s = sizeProp (dataSize a) (dataSize b) (dataSize c)+    f' (a,b,c) = f a b c   --- | A four-argument function+-- | A four-argument primitive function function4     :: ( Storable a        , Storable b@@ -354,119 +477,98 @@        , Storable e        )     => String+    -> (Size a -> Size b -> Size c -> Size d -> Size e)     -> (a -> b -> c -> d -> e)     -> (Data a -> Data b -> Data c -> Data d -> Data e) -function4 fun f a b c d =-    ref $ Function fun (\(a,b,c,d) -> f a b c d) (ref $ Tuple4 a b c d)------ | A one-argument function with constant folding-functionFold-    :: (Storable a, Storable b) => String -> (a -> b) -> (Data a -> Data b)--functionFold fun f a = case deref a of-    Value a' -> value_ (f a')-    _        -> function fun f a------ | A two-argument function with constant folding-functionFold2-    :: ( Storable a-       , Storable b-       , Storable c-       )-    => String -> (a -> b -> c) -> (Data a -> Data b -> Data c)--functionFold2 fun f a b = case (deref a, deref b) of-    (Value a', Value b') -> value_ (f a' b')-    _ -> function2 fun f a b+function4 fun sizeProp f a b c d = case (d2e a, d2e b, d2e c, d2e d) of+    (Value _ a', Value _ b', Value _ c', Value _ d') -> Data s (ref $ Value s $ f a' b' c' d')+    _ -> exprToData $ Function fun s f' $ exprToData $ Tuple4 a b c d+  where+    d2e = dataToExpr+    s = sizeProp (dataSize a) (dataSize b) (dataSize c) (dataSize d)+    f' (a,b,c,d) = f a b c d   --- | A three-argument function with constant folding-functionFold3-    :: ( Storable a-       , Storable b-       , Storable c-       , Storable d-       )-    => String -> (a -> b -> c -> d) -> (Data a -> Data b -> Data c -> Data d)--functionFold3 fun f a b c = case (deref a, deref b, deref c) of-    (Value a', Value b', Value c') -> value_ (f a' b' c')-    _ -> function3 fun f a b c--+instance Show (Data a)+  where+    show _ = "... :: Data a"+  -- Needed for the 'Num' instance. --- | A four-argument function with constant folding-functionFold4-    :: ( Storable a-       , Storable b-       , Storable c-       , Storable d-       , Storable e-       )-    => String -> (a -> b -> c -> d -> e)-    -> (Data a -> Data b -> Data c -> Data d -> Data e)+instance Numeric a => Num (Data a)+  where+    fromInteger = value . fromInteger+    abs         = function  "abs"    abs    abs+    signum      = function  "signum" signum signum+    (+)         = function2 "(+)"    (+)    (+)+    (-)         = function2 "(-)"    (-)    (-)+    (*)         = function2 "(*)"    (*)    (*) -functionFold4 fun f a b c d = case (deref a, deref b, deref c, deref d) of-    (Value a', Value b', Value c', Value d') -> value_ (f a' b' c' d')-    _ -> function4 fun f a b c d+instance Fractional (Data Float)+  where+    fromRational = value . fromRational+    (/)          = function2 "(/)" (\_ _ -> fullRange) (/)  -- XXX Improve range   --- | Look up an index in an array-getIx :: forall n a . (NaturalT n, Storable a) =>-    Data (n :> a) -> Data Int -> Data a--getIx = functionFold2 "(!)" f+-- | Look up an index in an array (see also '!')+getIx :: Storable a => Data [a] -> Data Int -> Data a+getIx arr = function2 "(!)" sizeProp f arr   where-    f (ArrayList as) i-        | i >= n || i < 0 = error "getIx: index out of bounds"-        | i >= l          = error "getIx: reading garbage"-        | otherwise       = as !! i+    sizeProp (_:>aSize) _ = aSize++    f as i+        | not (i `inRange` r) = error "getIx: index out of bounds"+        | i >= la             = error "getIx: reading garbage"+        | otherwise           = as !! i       where-        n = fromIntegerT (undefined :: n)-        l = length as+        l :> _ = dataSize arr+        r      = rangeByRange 0 (l-1)+        la     = length as   --- | @setIx arr i a@:+-- | @`setIx` arr i a@: -- -- Replaces the value at index @i@ in the array @arr@ with the value @a@.-setIx :: forall n a . (NaturalT n, Storable a) =>-    Data (n :> a) -> Data Int -> Data a -> Data (n :> a)--setIx = functionFold3 "setIx" f+setIx :: Storable a => Data [a] -> Data Int -> Data a -> Data [a]+setIx arr = function3 "setIx" sizeProp f arr   where-    f :: (n :> a) -> Int -> a -> (n :> a)-    f (ArrayList as) i a-        | i >= n || i < 0 = error "setIx: index out of bounds"-        | i > l           = error "setIx: writing past initialized area"-        | otherwise       = ArrayList $ take i as ++ [a] ++ drop (i+1) as-      where-        n = fromIntegerT (undefined :: n)-        l = length as+    sizeProp (l:>aSize) _ aSize' = l :> (aSize `mappend` aSize') +    f as i a+        | not (i `inRange` r) = error "setIx: index out of bounds"+        | i > la              = error "setIx: writing past initialized area"+        | otherwise           = take i as ++ [a] ++ drop (i+1) as+      where+        l:>_ = dataSize arr+        r    = rangeByRange 0 (l-1)+        la   = length as +infixl 9 !  class RandomAccess a   where-    type Elem a+    -- | The type of elements in a random access structure+    type Element a -    -- | Index lookup in random access structures-    (!) :: a -> Data Int -> Elem a+    -- | Index lookup in a random access structure+    (!) :: a -> Data Int -> Element a -instance (NaturalT n, Storable a) => RandomAccess (Data (n :> a))+instance Storable a => RandomAccess (Data [a])   where-    type Elem (Data (n :> a)) = Data a+    type Element (Data [a]) = Data a     (!) = getIx   +mkSubFun :: Typeable a => Size a -> (Data a -> Data b) -> (a :-> b)+mkSubFun sz f = SubFunction f inp (f inp)+  where+    inp = exprToData $ Input sz++ -- | Constructs a non-primitive, non-inlined function. -- -- The normal way to make a non-primitive function is to use an ordinary Haskell@@ -482,11 +584,13 @@ -- at the moment this does not work. Every application of a @noInline@ function -- results in a new copy of the function in the core program. noInline :: (Computable a, Computable b) => String -> (a -> b) -> (a -> b)-noInline fun = unwrap . (ref .) . NoInline fun . Ref.ref . wrap+noInline fun f a = liftFun (exprToData . NoInline fun (ref subFun)) a+  where+    subFun = mkSubFun (dataSize $ internalize a) (lowerFun f)   --- | @ifThenElse cond thenFunc elseFunc@:+-- | @`ifThenElse` cond thenFunc elseFunc@: -- -- Selects between the two functions @thenFunc@ and @elseFunc@ depending on -- whether the condition @cond@ is true or false.@@ -494,273 +598,68 @@     :: (Computable a, Computable b)     => Data Bool -> (a -> b) -> (a -> b) -> (a -> b) -ifThenElse cond t e = case deref cond of-    Value True         -> t-    Value False        -> e+ifThenElse cond t e a = case dataToExpr cond of+    Value _ True       -> t a+    Value _ False      -> e a --     Function "not" _ c -> ifThenElse c e t -- XXX Not possible...-    _ -> unwrap $ (ref .) $ IfThenElse cond (wrap t) (wrap e)------ | @while cont body@:------ A while-loop. The condition @cont@ determines whether the loop should--- continue one more iteration. @body@ computes the next state. The result is a--- function from initial state to final state.-while-    :: Computable a-    => (a -> Data Bool)-    -> (a -> a)-    -> (a -> a)--while cont = unwrap . (ref .) . While (cont . externalize) . wrap------ | @parallel sz ixf@:------ Parallel tiling. Computes the elements of a vector. @sz@ is the dynamic size,--- i.e. how many of the allocated elements that should be computed. The function--- @ixf@ maps each index to its value.------ Since there are no dependencies between the elements, the compiler is free to--- compute the elements in parallel (or any other order).-parallel :: (NaturalT n, Storable a) =>-    Data Int -> (Data Int -> Data a) -> Data (n :> a)-parallel sz = ref . Parallel sz------ * Graph conversion--data Info = Info-  { -- | Next id-    index   :: NodeId-    -- | Visited references mapped to their id-  , visited :: Map Unique NodeId-  }---- | Monad for making graph building easier-type GraphBuilder a = WriterT [Node] (State Info) a--startInfo :: Info-startInfo = Info 0 Map.empty--runGraph :: GraphBuilder a -> Info -> (a, ([Node], Info))-runGraph graph info = (a, (nodes, info'))+    _ -> liftFun (exprToData . IfThenElse cond thenSub elseSub) a   where-    ((a,nodes),info') = runState (runWriterT graph) info--newIndex :: GraphBuilder NodeId-newIndex = do-    info <- get-    put (info {index = succ (index info)})-    return (index info)--remember :: Data a -> NodeId -> GraphBuilder ()-remember dat i = modify $ \info ->-    info {visited = Map.insert (refId dat) i (visited info)}--checkNode :: Data a -> GraphBuilder (Maybe NodeId)-checkNode dat = gets ((Map.lookup (refId dat)) . visited)--tupleBind :: Typeable a => NodeId -> T a -> Tuple Variable-tupleBind i = fmap (\path -> (i,path)) . tuplePath . typeOf------ | Declare a node-node-    :: forall a . Typeable a-    => Data a-    -> Graph.Function-    -> Tuple Source-    -> Tuple StorableType-    -> GraphBuilder ()--node dat fun inTup inType = do-    i <- newIndex-    remember dat i-    let outType = typeOf (T::T a)-    tell [Node i fun inTup inType outType]------ | Declare a source node (one with no inputs)-sourceNode :: Data a -> Graph.Function -> GraphBuilder ()-sourceNode dat@(Data _) fun = node dat fun (Tup []) (Tup [])------ Creates a source. The node must have been visited.-source :: forall a . [Int] -> Data a -> GraphBuilder Source-source path a = case deref a of--    GetTuple n tup -> source (numberT n : path) tup--    Value a | isPrimitive (T::T a) ->-      let PrimitiveData a' = toData a-       in return $ Constant a'--    _ -> do-      Just i <- checkNode a-      return $ Variable (i,path)+    sz      = dataSize $ internalize a+    thenSub = mkSubFun sz $ lowerFun t+    elseSub = mkSubFun sz $ lowerFun e   -traceTuple :: Data a -> GraphBuilder (Tuple Source)-traceTuple a = case deref a of--    Tuple2 b c -> do-      b' <- traceTuple b-      c' <- traceTuple c-      return (Tup [b',c'])--    Tuple3 b c d -> do-      b' <- traceTuple b-      c' <- traceTuple c-      d' <- traceTuple d-      return (Tup [b',c',d'])--    Tuple4 b c d e -> do-      b' <- traceTuple b-      c' <- traceTuple c-      d' <- traceTuple d-      e' <- traceTuple e-      return (Tup [b',c',d',e'])--    _ -> liftM One (source [] a)--+whileSized+    :: Computable state+    => Size (Internal state)+    -> (state -> Data Bool)+    -> (state -> state)+    -> (state -> state) -buildGraph :: forall a . Data a -> GraphBuilder ()-buildGraph dat@(Data _) = do-    idat <- checkNode dat-    unless (isJust idat) $ list (deref dat)+whileSized sz cont body init = liftFun (exprToData . While contSub bodySub) init   where-    funcNode fun inp@(Data _) = do-      buildGraph inp-      inTup <- traceTuple inp-      node dat fun inTup (typeOfData inp)--    list :: Expr a -> GraphBuilder ()--    list Input = sourceNode dat Graph.Input--    list (Value a)-      | isPrimitive (T::T a) = return ()-      | otherwise            = sourceNode dat $ Graph.Array $ toData a--    list (Tuple2 a b)     = buildGraph a >> buildGraph b-    list (Tuple3 a b c)   = buildGraph a >> buildGraph b >> buildGraph c-    list (Tuple4 a b c d) =-        buildGraph a >> buildGraph b >> buildGraph c >> buildGraph d--    list (GetTuple _ a) = buildGraph a--    list (Function fun _ a) = funcNode (Graph.Function fun) a--    list (NoInline fun f a) = do-      iface <- buildSubFun (Ref.deref f)-      funcNode (Graph.NoInline fun iface) a-      -- XXX Sub-graph is not shared at the moment.--    list (IfThenElse cond t e a) = do-      ifaceThen <- buildSubFun t-      ifaceElse <- buildSubFun e-      funcNode (Graph.IfThenElse ifaceThen ifaceElse) (ref $ Tuple2 cond a)--    list (While cont body a) = do-      ifaceCont <- buildSubFun cont-      ifaceBody <- buildSubFun body-      funcNode (Graph.While ifaceCont ifaceBody) a--    list (Parallel sz ixf) = do-        iface <- buildSubFun ixf-        funcNode (Graph.Parallel n iface) sz-      where-        One (StorableType (n:_) _) = typeOfData dat+    contSub = mkSubFun sz $ lowerFun cont+    bodySub = mkSubFun sz $ lowerFun body   -buildSubFun :: forall a b . (Typeable a, Typeable b) =>-    (Data a -> Data b) -> GraphBuilder Interface--buildSubFun f = do-    let inp  = ref Input :: Data a-        outp = f inp-    buildGraph inp  -- Needed in case input is not used-    buildGraph outp-    outTup <- traceTuple outp-    info   <- get-    let inId    = visited info Map.! refId inp-        inType  = typeOf (T::T a)-        outType = typeOf (T::T b)-    return (Interface inId outTup inType outType)--+-- | While-loop+--+-- @while cont body :: state -> state@:+--+--   * @state@ is the type of the state.+--+--   * @cont@ determines whether or not to continue based on the current state.+--+--   * @body@ computes the next state from the current state.+--+--   * The result is a function from initial state to final state.+while+    :: Computable state+    => (state -> Data Bool)+    -> (state -> state)+    -> (state -> state) -toGraphD :: (Typeable a, Typeable b) => (Data a -> Data b) -> Graph-toGraphD f = Graph nodes iface-  where-    (iface,(nodes,_)) = runGraph (buildSubFun f) startInfo+while = whileSized universal   --- | Types that represents core language programs-class Program a-  where-    -- | Converts a program to a Graph-    toGraph :: a -> Graph--    -- | Returns whether or not the program has an argument. This is needed-    -- because the 'Graph' type always assumes the existence of an input. So-    -- for programs without input, the 'Graph' representation will have a-    -- \"dummy\" input, which is indistinguishable from a real input.-    hasArg :: T a -> Bool--instance Computable a => Program a-  where-    toGraph a = toGraphD (const (internalize a) :: Data () -> Data (Internal a))-    hasArg    = const False--instance (Computable a, Computable b) => Program (a -> b)-  where-    toGraph = toGraphD . wrap-    hasArg  = const True--instance (Computable a, Computable b, Computable c)-      => Program (a -> b -> c)-  where-    toGraph = toGraph . uncurry-    hasArg  = const True--instance (Computable a, Computable b, Computable c, Computable d)-      => Program (a -> b -> c -> d)-  where-    toGraph f = toGraph (\(a,b,c) -> f a b c)-    hasArg    = const True--instance-    ( Computable a-    , Computable b-    , Computable c-    , Computable d-    , Computable e-    ) =>-      Program (a -> b -> c -> d -> e)+-- | Parallel array+--+-- @parallel l ixf@:+--+--   * @l@ is the length of the resulting array (outermost level).+--+--   * @ifx@ is a function that maps each index in the range @[0 .. l-1]@ to its+--     element.+--+-- Since there are no dependencies between the elements, the compiler is free to+-- compute the elements in any order, or even in parallel.+parallel :: Storable a => Data Length -> (Data Int -> Data a) -> Data [a]+parallel l ixf = exprToData $ Parallel l ixfSub   where-    toGraph f = toGraph (\(a,b,c,d) -> f a b c d)-    hasArg    = const True------ | Shows the core code generated by program.-showCore :: forall a . Program a => a -> String-showCore = showGraph "program" (hasArg (T::T a)) . toGraph---- | @printCore = putStrLn . showCore@-printCore :: Program a => a -> IO ()-printCore = putStrLn . showCore+    szl    = dataSize l+    ixfSub = mkSubFun (rangeByRange 0 (szl-1)) ixf 
Feldspar/Core/Functions.hs view
@@ -1,4 +1,4 @@--- Copyright (c) 2009, ERICSSON AB+-- Copyright (c) 2009-2010, ERICSSON AB -- All rights reserved. -- -- Redistribution and use in source and binary forms, with or without@@ -32,11 +32,12 @@  import qualified Prelude -import Feldspar.Prelude+import Feldspar.Range import Feldspar.Core.Types import Feldspar.Core.Expr-+import Feldspar.Prelude +import qualified Data.Bits as B  infix 4 == infix 4 /=@@ -48,70 +49,232 @@   +-- * Misc.++noSizeProp :: a -> ()+noSizeProp _ = ()++noSizeProp2 :: a -> b -> ()+noSizeProp2 _ _ = ()+++ (==) :: Storable a => Data a -> Data a -> Data Bool-(==) = functionFold2 "(==)" (Prelude.==)+a == b+  | a Prelude.== b = true+  | otherwise      = function2 "(==)" noSizeProp2 (Prelude.==) a b+  -- XXX Partial evaluation  (/=) :: Storable a => Data a -> Data a -> Data Bool-(/=) = functionFold2 "(/=)" (Prelude./=)+a /= b+  | a Prelude.== b = false+  | otherwise      = function2 "(/=)" noSizeProp2 (Prelude./=) a b+  -- XXX Partial evaluation  (<) :: Storable a => Data a -> Data a -> Data Bool-(<) = functionFold2 "(<)" (Prelude.<)+a < b+  | a Prelude.== b = false+  | otherwise      = function2 "(<)" noSizeProp2 (Prelude.<) a b  (>) :: Storable a => Data a -> Data a -> Data Bool-(>) = functionFold2 "(>)" (Prelude.>)+a > b+  | a Prelude.== b = false+  | otherwise      = function2 "(>)" noSizeProp2 (Prelude.>) a b +(<<<) :: Data Int -> Data Int -> Data Bool+a <<< b+  | a Prelude.== b      = false+  | sa `rangeLess`   sb = true+  | sb `rangeLessEq` sa = false+  | otherwise           = function2 "(<)" noSizeProp2 (Prelude.<) a b+  where+    sa = dataSize a+    sb = dataSize b+  -- XXX Enables more partial evaluation than (<). This function should be+  --     generalized and then replace (<).++(>>>) :: Data Int -> Data Int -> Data Bool+a >>> b+  | a Prelude.== b      = false+  | sb `rangeLess`   sa = true+  | sa `rangeLessEq` sb = false+  | otherwise           = function2 "(>)" noSizeProp2 (Prelude.>) a b+  where+    sa = dataSize a+    sb = dataSize b+  -- XXX Enables more partial evaluation than (>). This function should be+  --     generalized and then replace (>).+ (<=) :: Storable a => Data a -> Data a -> Data Bool-(<=) = functionFold2 "(<=)" (Prelude.<=)+a <= b+  | a Prelude.== b = true+  | otherwise      = function2 "(<=)" noSizeProp2 (Prelude.<=) a b+  -- XXX Partial evaluation  (>=) :: Storable a => Data a -> Data a -> Data Bool-(>=) = functionFold2 "(>=)" (Prelude.>=)+a >= b+  | a Prelude.== b = true+  | otherwise      = function2 "(>=)" noSizeProp2 (Prelude.>=) a b+  -- XXX Partial evaluation  not :: Data Bool -> Data Bool-not = functionFold "not" Prelude.not+not = function "not" noSizeProp Prelude.not  -- | Selects the elements of the pair depending on the condition (?) :: Computable a => Data Bool -> (a,a) -> a cond ? (a,b) = ifThenElse cond (const a) (const b) unit  (&&) :: Data Bool -> Data Bool -> Data Bool-(&&) = functionFold2 "(&&)" (Prelude.&&)+(&&) = function2 "(&&)" noSizeProp2 (Prelude.&&)  (||) :: Data Bool -> Data Bool -> Data Bool-(||) = functionFold2 "(||)" (Prelude.||)+(||) = function2 "(||)" noSizeProp2 (Prelude.||)  -- | Lazy conjunction, second argument only run if necessary (&&*) :: Computable a =>     (a -> Data Bool) -> (a -> Data Bool) -> (a -> Data Bool)-(f &&* g) a = let fa = f a in ifThenElse fa g (const false) a+(f &&* g) a = ifThenElse (f a) g (const false) a  -- | Lazy disjunction, second argument only run if necessary (||*) :: Computable a =>     (a -> Data Bool) -> (a -> Data Bool) -> (a -> Data Bool)-(f ||* g) a = let fa = f a in ifThenElse fa (const true) g a+(f ||* g) a = ifThenElse (f a) (const true) g a  min :: Storable a => Data a -> Data a -> Data a-min a b = a<=b ? (a,b)+min a b = a<b ? (a,b)  max :: Storable a => Data a -> Data a -> Data a-max a b = a>=b ? (a,b)+max a b = a>b ? (a,b) +minX :: Data Int -> Data Int -> Data Int+minX a b = case dataToExpr cond1 of+    Value _ _ -> cond1 ? (a,b)+    _         -> cond2 ? (b,a)+  where+    cond1 = a<<<b+    cond2 = b<<<a+  -- XXX Enables more partial evaluation than min. This function should be+  --     generalized and then replace min.++maxX :: Data Int -> Data Int -> Data Int+maxX a b = case dataToExpr cond1 of+    Value _ _ -> cond1 ? (a,b)+    _         -> cond2 ? (b,a)+  where+    cond1 = a>>>b+    cond2 = b>>>a+  -- XXX Enables more partial evaluation than max. This function should be+  --     generalized and then replace max.+ div :: Data Int -> Data Int -> Data Int-div = functionFold2 "div" (Prelude.div)+div = function2 "div" (\_ _ -> fullRange) Prelude.div  -- XXX Improve size propagation  mod :: Data Int -> Data Int -> Data Int-mod = functionFold2 "mod" (Prelude.mod)+mod = function2 "mod" (\_ _ -> fullRange) Prelude.mod  -- XXX Improve size propagation  (^) :: Data Int -> Data Int -> Data Int-(^) = functionFold2 "(^)" (Prelude.^)+(^) = function2 "(^)" (\_ _ -> fullRange) (Prelude.^)  -- XXX Improve size propagation --- | @for start end init body@:+++-- * Loops++-- | For-loop ----- A for-loop ranging over @[start .. end]@. @init@ is the starting state. The--- @body@ computes the next state given the current state and the current loop--- index.+-- @`for` start end init body@:+--+--   * @start@\/@end@ are the start\/end indexes.+--+--   * @init@ is the starting state.+--+--   * @body@ computes the next state given the current loop index (ranging over+--     @[start .. end]@) and the current state. for :: Computable a => Data Int -> Data Int -> a -> (Data Int -> a -> a) -> a-for start end init body = snd $ while cont body' (start,init)+for start end init body = snd $ whileSized sz cont body' (start,init)   where+    szi = rangeByRange (dataSize start) (dataSize end)+    sz  = (szi,universal)+     cont  (i,s) = i <= end     body' (i,s) = (i+1, body i s) +++-- | A sequential \"unfolding\" of an vector+--+-- @`unfoldCore` l init step@:+--+--   * @l@ is the length of the resulting vector.+--+--   * @init@ is the initial state.+--+--   * @step@ is a function computing a new element and the next state from the+--     current index and current state. The index is the position of the new+--     element in the output vector.+unfoldCore+    :: (Computable state, Storable a)+    => Data Length+    -> state+    -> (Data Int -> state -> (Data a, state))+    -> (Data [a], state)++unfoldCore l init step = for 0 (l-1) (outp,init) $ \i (o,state) ->+    let (a,state') = step i state+     in (setIx o i a, state')+  where+    outp = array (mapMonotonic fromIntegral (dataSize l) :> universal) []+++-- * Bit manipulation++infixl 5 <<,>>+infixl 4 ⊕++-- | The following class provides functions for bit level manipulation+class (B.Bits a, Storable a) => Bits a+  where+  -- Logical operations+  (.&.)         :: Data a -> Data a -> Data a+  (.&.)         =  function2 "(.&.)" (\_ _ -> universal) (B..&.)+  (.|.)         :: Data a -> Data a -> Data a+  (.|.)         =  function2 "(.|.)" (\_ _ -> universal) (B..|.)+  xor           :: Data a -> Data a -> Data a+  xor           =  function2 "xor" (\_ _ -> universal) B.xor+  (⊕)           :: Data a -> Data a -> Data a+  (⊕)           = xor+  complement    :: Data a -> Data a+  complement    =  function "complement" (const universal) B.complement++  -- Operations on individual bits+  bit           :: Data Int -> Data a+  bit           =  function "bit" (const universal) B.bit+  setBit        :: Data a -> Data Int -> Data a+  setBit        =  function2 "setBit" (\_ _ -> universal) B.setBit+  clearBit      :: Data a -> Data Int -> Data a+  clearBit      =  function2 "clearBit" (\_ _ -> universal) B.clearBit+  complementBit :: Data a -> Data Int -> Data a+  complementBit =  function2 "complementBit" (\_ _ -> universal) B.complementBit+  testBit       :: Data a -> Data Int -> Data Bool+  testBit       =  function2 "testBit" noSizeProp2 B.testBit++  -- Moving bits around+  shiftL        :: Data a -> Data Int -> Data a+  shiftL        =  function2 "shiftL" (\_ _ -> universal) B.shiftL+  (<<)          :: Data a -> Data Int -> Data a+  (<<)          =  shiftL+  shiftR        :: Data a -> Data Int -> Data a+  shiftR        =  function2 "shiftR" (\_ _ -> universal) B.shiftR+  (>>)          :: Data a -> Data Int -> Data a+  (>>)          =  shiftR+  rotateL       :: Data a -> Data Int -> Data a+  rotateL       =  function2 "rotateL" (\_ _ -> universal) B.rotateL+  rotateR       :: Data a -> Data Int -> Data a+  rotateR       =  function2 "rotateR" (\_ _ -> universal) B.rotateR++  -- Queries about the type+  bitSize       :: Data a -> Data Int+  bitSize       =  function "bitSize" (const naturalRange) B.bitSize+  isSigned      :: Data a -> Data Bool+  isSigned      =  function "isSigned" noSizeProp B.isSigned++instance Bits Int
Feldspar/Core/Graph.hs view
@@ -1,4 +1,4 @@--- Copyright (c) 2009, ERICSSON AB+-- Copyright (c) 2009-2010, ERICSSON AB -- All rights reserved. -- -- Redistribution and use in source and binary forms, with or without@@ -93,6 +93,8 @@ -- >     intType     = result (typeOf :: Res [[[Int]]] (Tuple StorableType)) -- >     intPairType = result (typeOf :: Res (Int,Int) (Tuple StorableType)) --+-- XXX Check above code again+-- -- which corresponds to the following flat program -- -- > main v0 = v4@@ -290,7 +292,7 @@     -- | While-loop   | While Interface Interface     -- | Parallel tiling-  | Parallel Int Interface+  | Parallel Interface     deriving (Eq, Show)  -- | A graph is a list of unique nodes with an interface.@@ -381,7 +383,7 @@     subFun i (NoInline _ f)    = [sub i 0 f]     subFun i (IfThenElse t e)  = [sub i 0 t, sub i 1 e]     subFun i (While cont body) = [sub i 0 cont, sub i 1 body]-    subFun i (Parallel _ ixf)  = [sub i 0 ixf]+    subFun i (Parallel ixf)    = [sub i 0 ixf]     subFun _ _                 = []  @@ -471,7 +473,7 @@     subHierarchies (Node i (NoInline _ _) _ _ _)   = map (subFunHier i) [0]     subHierarchies (Node i (IfThenElse _ _) _ _ _) = map (subFunHier i) [0,1]     subHierarchies (Node i (While _ _) _ _ _)      = map (subFunHier i) [0,1]-    subHierarchies (Node i (Parallel _ _) _ _ _)   = map (subFunHier i) [0]+    subHierarchies (Node i (Parallel _) _ _ _)     = map (subFunHier i) [0]     subHierarchies _ = []      topLevel :: [Node]
− Feldspar/Core/Haskell.hs
@@ -1,77 +0,0 @@--- Copyright (c) 2009, ERICSSON AB--- All rights reserved.------ Redistribution and use in source and binary forms, with or without--- modification, are permitted provided that the following conditions are met:------     * Redistributions of source code must retain the above copyright notice,---       this list of conditions and the following disclaimer.---     * Redistributions in binary form must reproduce the above copyright---       notice, this list of conditions and the following disclaimer in the---       documentation and/or other materials provided with the distribution.---     * Neither the name of the ERICSSON AB nor the names of its contributors---       may be used to endorse or promote products derived from this software---       without specific prior written permission.------ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"--- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE--- IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE--- DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE--- FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL--- DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR--- SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER--- CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,--- OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE--- OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.---- | Helper functions for producing Haskell code--module Feldspar.Core.Haskell where----import Data.List--import Feldspar.Core.Types------ | No trailing @\'\\n\'@.-unlinesNoTrail :: [String] -> String-unlinesNoTrail = intercalate "\n"---- | Indents a string the given amount of columns.-indent :: Int -> String -> String-indent n = unlinesNoTrail . map (spc ++) . lines-  where-    spc = replicate n ' '--newline :: String-newline = "\n"---- | Application-(-$-) :: HaskellValue a => String -> a -> String-fun -$- inp = unwords [fun, haskellValue inp]---- | Binary operator application-opApp :: (HaskellValue a, HaskellValue b) => String -> a -> b -> String-opApp op a b = unwords [haskellValue a, op, haskellValue b]---- | Definition-(-=-) :: (HaskellValue patt, HaskellValue def) => patt -> def -> String-patt -=- def = unwords [haskellValue patt, "=", haskellValue def]---- Places the second string as a local block to the first string.-local :: String -> String -> String-local def ""   = def-local def defs = def ++ newline ++ indent 2 "where" ++ newline ++ indent 4 defs--infixl 8 -$--infix  7 -=--infixr 6 `local`--ifThenElse-    :: (HaskellValue c, HaskellValue t, HaskellValue e) => c -> t -> e -> String-ifThenElse c t e = unwords-    ["if", haskellValue c, "then", haskellValue t, "else", haskellValue e]-
Feldspar/Core/Ref.hs view
@@ -1,4 +1,4 @@--- Copyright (c) 2009, ERICSSON AB+-- Copyright (c) 2009-2010, ERICSSON AB, Koen Claessen -- All rights reserved. -- -- Redistribution and use in source and binary forms, with or without@@ -27,8 +27,6 @@ {-# OPTIONS_GHC -O0 #-}  -- |--- Copyright : Copyright (c) 2009, Koen Claessen--- -- A simple implementation of \"observable sharing\". See -- -- * Koen Claessen, David Sands,
+ Feldspar/Core/Reify.hs view
@@ -0,0 +1,316 @@+-- Copyright (c) 2009-2010, ERICSSON AB+-- All rights reserved.+--+-- Redistribution and use in source and binary forms, with or without+-- modification, are permitted provided that the following conditions are met:+--+--     * Redistributions of source code must retain the above copyright notice,+--       this list of conditions and the following disclaimer.+--     * Redistributions in binary form must reproduce the above copyright+--       notice, this list of conditions and the following disclaimer in the+--       documentation and/or other materials provided with the distribution.+--     * Neither the name of the ERICSSON AB nor the names of its contributors+--       may be used to endorse or promote products derived from this software+--       without specific prior written permission.+--+-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"+-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE+-- IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE+-- DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE+-- FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL+-- DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR+-- SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER+-- CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,+-- OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE+-- OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.++{-# LANGUAGE OverlappingInstances, UndecidableInstances #-}++-- | Functions for reifying expressions ('Data' / 'Expr') to graphs ('Graph')+-- and to textual format.++module Feldspar.Core.Reify+  ( Program (..)+  , showCore+  , showCoreWithSize+  , printCore+  , printCoreWithSize+  ) where++++import Control.Monad.State+import Control.Monad.Writer+import Data.Map (Map)+import qualified Data.Map as Map+import Data.Maybe+import Data.Unique++import Feldspar.Core.Types+import Feldspar.Core.Ref+import Feldspar.Core.Expr+import Feldspar.Core.Graph hiding (function, Function (..), SubFunction)+import qualified Feldspar.Core.Graph as Graph+import Feldspar.Core.Show++++data Info = Info+  { -- | Next id+    index :: NodeId+    -- | Visited references mapped to their id+  , visited :: Map Unique NodeId+  }++-- | Monad for making graph building easier+type Reify a = WriterT [Node] (State Info) a++startInfo :: Info+startInfo = Info 0 Map.empty++runGraph :: Reify a -> Info -> (a, ([Node], Info))+runGraph graph info = (a, (nodes, info'))+  where+    ((a,nodes),info') = runState (runWriterT graph) info++newIndex :: Reify NodeId+newIndex = do+    info <- get+    put (info {index = succ (index info)})+    return (index info)++remember :: Data a -> NodeId -> Reify ()+remember a i = modify $ \info ->+    info {visited = Map.insert (dataId a) i (visited info)}++checkNode :: Data a -> Reify (Maybe NodeId)+checkNode a = gets ((Map.lookup (dataId a)) . visited)++++-- | Declare a node+node ::+    Data a -> Graph.Function -> Tuple Source -> Tuple StorableType -> Reify ()++node a@(Data _ _) fun inTup inType = do+    i <- newIndex+    remember a i+    tell [Node i fun inTup inType (dataType a)]++++-- | Declare a source node (one with no inputs)+sourceNode :: Data a -> Graph.Function -> Reify ()+sourceNode a fun = node a fun (Tup []) (Tup [])++isPrimitive :: Data a -> Bool+isPrimitive a@(Data _ _) = case dataType a of+    One (StorableType [] _) -> True+    _ -> False++++-- Creates a source. The node must have been visited.+source :: [Int] -> Data a -> Reify Source+source path a = case dataToExpr a of++    Get21 tup -> source (0:path) tup+    Get22 tup -> source (1:path) tup+    Get31 tup -> source (0:path) tup+    Get32 tup -> source (1:path) tup+    Get33 tup -> source (2:path) tup+    Get41 tup -> source (0:path) tup+    Get42 tup -> source (1:path) tup+    Get43 tup -> source (2:path) tup+    Get44 tup -> source (3:path) tup++    Value _ b | isPrimitive a ->+      let PrimitiveData b' = storableData b+       in return $ Constant b'++    _ -> do+      Just i <- checkNode a+      return $ Variable (i,path)++++traceTuple :: Data a -> Reify (Tuple Source)+traceTuple a = case dataToExpr a of++    Tuple2 b c -> do+      b' <- traceTuple b+      c' <- traceTuple c+      return (Tup [b',c'])++    Tuple3 b c d -> do+      b' <- traceTuple b+      c' <- traceTuple c+      d' <- traceTuple d+      return (Tup [b',c',d'])++    Tuple4 b c d e -> do+      b' <- traceTuple b+      c' <- traceTuple c+      d' <- traceTuple d+      e' <- traceTuple e+      return (Tup [b',c',d',e'])++    _ -> liftM One (source [] a)++++buildGraph :: forall a . Data a -> Reify ()+buildGraph a@(Data _ _) = do+    ia <- checkNode a+    unless (isJust ia) $ list (dataToExpr a)+  where+    funcNode fun inp = do+      buildGraph inp+      inTup <- traceTuple inp+      node a fun inTup (dataType inp)++    list :: Expr a -> Reify ()++    list (Input _) = sourceNode a Graph.Input++    list (Value _ b)+      | isPrimitive a = return ()+      | otherwise     = sourceNode a $ Graph.Array $ storableData b++    list (Tuple2 b c)     = buildGraph b >> buildGraph c+    list (Tuple3 b c d)   = buildGraph b >> buildGraph c >> buildGraph d+    list (Tuple4 b c d e) =+        buildGraph b >> buildGraph c >> buildGraph d >> buildGraph e++    list (Get21 b) = buildGraph b+    list (Get22 b) = buildGraph b+    list (Get31 b) = buildGraph b+    list (Get32 b) = buildGraph b+    list (Get33 b) = buildGraph b+    list (Get41 b) = buildGraph b+    list (Get42 b) = buildGraph b+    list (Get43 b) = buildGraph b+    list (Get44 b) = buildGraph b++    list (Function fun _ _ b) = funcNode (Graph.Function fun) b++    list (NoInline fun f b@(Data _ _)) = do+      iface <- buildSubFun (deref f)+      funcNode (Graph.NoInline fun iface) b+      -- XXX Sub-graph is not shared at the moment.++    list (IfThenElse c t e b@(Data _ _)) = do+      ifaceThen <- buildSubFun t+      ifaceElse <- buildSubFun e+      funcNode (Graph.IfThenElse ifaceThen ifaceElse) (exprToData $ Tuple2 c b)++    list (While cont body b@(Data _ _)) = do+      ifaceCont <- buildSubFun cont+      ifaceBody <- buildSubFun body+      funcNode (Graph.While ifaceCont ifaceBody) b++    list (Parallel l ixf) = do+      iface <- buildSubFun ixf+      funcNode (Graph.Parallel iface) l++++buildSubFun :: forall a b . (Typeable a, Typeable b) =>+    (a :-> b) -> Reify Interface++buildSubFun (SubFunction _ inp outp) = do+    let inType  = typeOf (dataSize inp) (T::T a)+        outType = typeOf (dataSize outp) (T::T b)+    buildGraph inp  -- Needed in case input is not used+    buildGraph outp+    outTup <- traceTuple outp+    info   <- get+    let inId = visited info Map.! dataId inp+    return (Interface inId outTup inType outType)++++reifyD :: (Typeable a, Typeable b) => (Data a -> Data b) -> Graph+reifyD f = Graph nodes iface+  where+    subFun            = mkSubFun universal f+    (iface,(nodes,_)) = runGraph (buildSubFun subFun) startInfo++++-- | Types that represent core language programs+class Program a+  where+    -- | Converts a program to a Graph+    reify :: a -> Graph++    -- | Returns whether or not the program has an argument. This is needed+    -- because the 'Graph' type always assumes the existence of an input. So+    -- for programs without input, the 'Graph' representation will have a+    -- \"dummy\" input, which is indistinguishable from a real input.+    numArgs :: T a -> Int++instance Computable a => Program a+  where+    reify     = reify_computable+    numArgs _ = 0++instance (Computable a, Computable b) => Program (a,b)+  where+    reify     = reify_computable+    numArgs _ = 0++instance (Computable a, Computable b, Computable c) => Program (a,b,c)+  where+    reify     = reify_computable+    numArgs _ = 0++instance (Computable a, Computable b, Computable c, Computable d) => Program (a,b,c,d)+  where+    reify     = reify_computable+    numArgs _ = 0++instance (Computable a, Computable b) => Program (a -> b)+  where+    reify   = reifyD . lowerFun+    numArgs = const 1++instance (Computable a, Computable b, Computable c) => Program (a -> b -> c)+  where+    reify f = reifyD $ lowerFun $ \(a,b) -> f a b+    numArgs = const 2++instance (Computable a, Computable b, Computable c, Computable d) => Program (a -> b -> c -> d)+  where+    reify f = reifyD $ lowerFun $ \(a,b,c) -> f a b c+    numArgs = const 3++instance (Computable a, Computable b, Computable c, Computable d, Computable e) => Program (a -> b -> c -> d -> e)+  where+    reify f = reifyD $ lowerFun $ \(a,b,c,d) -> f a b c d+    numArgs = const 4++++reify_computable :: forall a . Computable a => a -> Graph+reify_computable a =+    reifyD (const (internalize a) :: Data () -> Data (Internal a))++++-- | Shows the core code generated by the program.+showCore :: forall a . Program a => a -> String+showCore = showGraph False "program" (numArgs (T::T a) > 0) . reify++-- | Shows the core code with size information as comments.+showCoreWithSize :: forall a . Program a => a -> String+showCoreWithSize = showGraph True "program" (numArgs (T::T a) > 0) . reify++-- | @printCore = putStrLn . showCore@+printCore :: Program a => a -> IO ()+printCore = putStrLn . showCore++-- | @printCoreWithSize = putStrLn . showCoreWithSize@+printCoreWithSize :: Program a => a -> IO ()+printCoreWithSize = putStrLn . showCoreWithSize+
Feldspar/Core/Show.hs view
@@ -1,4 +1,4 @@--- Copyright (c) 2009, ERICSSON AB+-- Copyright (c) 2009-2010, ERICSSON AB -- All rights reserved. -- -- Redistribution and use in source and binary forms, with or without@@ -34,8 +34,9 @@ import Control.Monad import Data.List +import Feldspar.Utils+import Feldspar.Haskell import Feldspar.Core.Types-import Feldspar.Core.Haskell import Feldspar.Core.Graph  @@ -65,14 +66,28 @@   --- | Shows a single node. The first argument associates each sub-function with--- the nodes it owns.-showNode :: Node -> [Hierarchy] -> String+sizeComment :: Tuple StorableType -> String+sizeComment typ = case size of+    "" -> ""+    _  -> "  -- Size: " ++ size+  where+    size = showTuple (fmap showStorableSize typ) -showNode (Node i fun inp inType outType) subHiers = showNd fun+++-- | Shows a single node.+showNode :: Bool -> Node -> [Hierarchy] -> String++showNode _ (Node i Input inp inType outType) subHiers = ""++showNode showSize (Node i fun inp inType outType) subHiers+    | showSize  = appendFirstLine (sizeComment outType) (showNd fun)+    | otherwise = showNd fun   where     outp = tupPatt outType i +    showSF' = showSF showSize+     showNd Input     = ""     showNd (Array a) = ((i,[])::Variable) -=- a @@ -86,7 +101,7 @@     showNd (NoInline fun iface) =         outp -=- fun -$- inp           `local`-        showSF (head subHiers) fun subInp subOutp+        showSF' (head subHiers) fun subInp subOutp       where         subInp  = tupPatt inType $ interfaceInput iface         subOutp = interfaceOutput iface@@ -109,8 +124,8 @@         subOutpThen = interfaceOutput ifaceThen         subOutpElse = interfaceOutput ifaceElse -        thenBranch = showSF thenHier "thenBranch" subInpThen subOutpThen-        elseBranch = showSF elseHier "elseBranch" subInpElse subOutpElse+        thenBranch = showSF' thenHier "thenBranch" subInpThen subOutpThen+        elseBranch = showSF' elseHier "elseBranch" subInpElse subOutpElse      showNd (While ifaceCont ifaceBody) =         outp -=- "while" -$- "cont" -$- "body" -$- inp@@ -124,51 +139,54 @@         subOutpCont = interfaceOutput ifaceCont         subOutpBody = interfaceOutput ifaceBody -        contBranch = showSF contHier "cont" subInpCont subOutpCont-        bodyBranch = showSF bodyHier "body" subInpBody subOutpBody+        contBranch = showSF' contHier "cont" subInpCont subOutpCont+        bodyBranch = showSF' bodyHier "body" subInpBody subOutpBody -    showNd (Parallel szs iface) =-        outp -=- "parallel" -$- szs -$- inp -$- "ixf"+    showNd (Parallel iface) =+        outp -=- "parallel" -$- inp -$- "ixf"           `local`-        showSF (head subHiers) "ixf" subInp subOutp+        showSF' (head subHiers) "ixf" subInp subOutp       where         subInp  = tupPatt inType $ interfaceInput iface         subOutp = interfaceOutput iface   --- | @showSubFun hier name inp outp@:+-- | @showSubFun showSize hier name inp outp@: -- -- Shows a sub-function named @name@ represented by the hierarchy @hier@. If -- @inp@ is @Nothing@, it will be shown as a definition without an argument.+-- @showSize@ decides whether or not to show size comments. showSubFun     :: (HaskellValue inp, HaskellValue outp)-    => Hierarchy+    => Bool+    -> Hierarchy     -> String     -> Maybe inp     -> outp     -> String -showSubFun (Hierarchy nodes) name inp outp =+showSubFun showSize (Hierarchy nodes) name inp outp =     funHead inp -=- outp       `local`-    unlinesNoTrail (filter (not.null) $ map (uncurry showNode) nodes)+    unlinesNoTrail (filter (not.null) $ map (uncurry (showNode showSize)) nodes)   where     funHead Nothing    = name     funHead (Just inp) = name -$- inp   --- | @showSF hier name inp = showSubFun hier name (Just inp)@+-- | @showSF showSize hier name inp = showSubFun showSize hier name (Just inp)@ showSF     :: (HaskellValue inp, HaskellValue outp)-    => Hierarchy+    => Bool+    -> Hierarchy     -> String     -> inp     -> outp     -> String -showSF hier name inp = showSubFun hier name (Just inp)+showSF showSize hier name inp = showSubFun showSize hier name (Just inp)   @@ -176,8 +194,9 @@ -- Boolean tells whether the graph has a real or a dummy argument. A graphs with -- that has a dummy argument will be shown as a definition without an argument. -- Of course, this assumes that a dummy argument is not used within the graph.-showGraph :: String -> Bool -> Graph -> String-showGraph name hasArg graph@(Graph nodes iface) = showSubFun hier name inp' outp+showGraph :: Bool -> String -> Bool -> Graph -> String+showGraph showSize name hasArg graph@(Graph nodes iface) =+    showSubFun showSize hier name inp' outp   where     hier = graphHierarchy $ makeHierarchical graph     inp  = tupPatt (interfaceInputType iface) (interfaceInput iface)
Feldspar/Core/Types.hs view
@@ -1,4 +1,4 @@--- Copyright (c) 2009, ERICSSON AB+-- Copyright (c) 2009-2010, ERICSSON AB -- All rights reserved. -- -- Redistribution and use in source and binary forms, with or without@@ -24,6 +24,8 @@ -- OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -- OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +{-# LANGUAGE UndecidableInstances #-}+ -- | Defines types and classes for the data computed by "Feldspar" programs.  module Feldspar.Core.Types where@@ -31,117 +33,80 @@   import Control.Applicative-import Control.Monad import Data.Char import Data.Foldable (Foldable) import qualified Data.Foldable as Fold-import Data.Maybe+import Data.Monoid import Data.Traversable (Traversable, traverse) -import Types.Data.Num+import Data.Int+import Data.Word+import Data.Bits  import Feldspar.Utils+import Feldspar.Haskell+import Feldspar.Range   --- * Types as arguments+-- * Misc.  -- | Used to pass a type to a function without using 'undefined'. data T a = T -numberT :: forall n . IntegerT n => T n -> Int-numberT _ = fromIntegerT (undefined :: n)+mkT :: a -> T a+mkT _ = T   --- * Haskell source code+-- | Heterogeneous list+data a :> b = a :> b+    deriving (Eq, Ord, Show) --- | Types that can represent Haskell types (as source code strings)-class HaskellType a-  where-    -- | Gives the Haskell type denoted by the argument.-    haskellType :: a -> String+infixr 5 :> -instance HaskellType a => HaskellType (Tuple a)+instance (Monoid a, Monoid b) => Monoid (a :> b)   where-    haskellType = showTuple . fmap haskellType+    mempty = mempty :> mempty +    (a1:>b1) `mappend` (a2:>b2) = (a1 `mappend` a2) :> (b1 `mappend` b2)  --- | Types that can represent Haskell values (as source code strings)-class HaskellValue a-  where-    -- | Gives the Haskell code denoted by the argument.-    haskellValue :: a -> String -instance HaskellValue String+class Set a   where-    haskellValue = id+    universal :: a -instance HaskellValue Int+instance Set ()   where-    haskellValue = show+    universal     = () -instance HaskellValue a => HaskellValue (Tuple a)+instance Ord a => Set (Range a)   where-    haskellValue = showTuple . fmap haskellValue------ * Tuples+    universal = fullRange --- | General tuple projection-class NaturalT n => GetTuple n a+instance (Set a, Set b) => Set (a :> b)   where-    type Part n a-    getTup :: T n -> a -> Part n a+    universal = universal :> universal -instance GetTuple D0 (a,b)+instance (Set a, Set b) => Set (a,b)   where-    type Part D0 (a,b) = a-    getTup _ (a,b) = a+    universal = (universal,universal) -instance GetTuple D1 (a,b)+instance (Set a, Set b, Set c) => Set (a,b,c)   where-    type Part D1 (a,b) = b-    getTup _ (a,b) = b+    universal = (universal,universal,universal) -instance GetTuple D0 (a,b,c)+instance (Set a, Set b, Set c, Set d) => Set (a,b,c,d)   where-    type Part D0 (a,b,c) = a-    getTup _ (a,b,c) = a+    universal = (universal,universal,universal,universal) -instance GetTuple D1 (a,b,c)-  where-    type Part D1 (a,b,c) = b-    getTup _ (a,b,c) = b -instance GetTuple D2 (a,b,c)-  where-    type Part D2 (a,b,c) = c-    getTup _ (a,b,c) = c -instance GetTuple D0 (a,b,c,d)-  where-    type Part D0 (a,b,c,d) = a-    getTup _ (a,b,c,d) = a--instance GetTuple D1 (a,b,c,d)-  where-    type Part D1 (a,b,c,d) = b-    getTup _ (a,b,c,d) = b--instance GetTuple D2 (a,b,c,d)-  where-    type Part D2 (a,b,c,d) = c-    getTup _ (a,b,c,d) = c--instance GetTuple D3 (a,b,c,d)-  where-    type Part D3 (a,b,c,d) = d-    getTup _ (a,b,c,d) = d+type Length = Int  +-- * Tuples  -- | Untyped representation of nested tuples data Tuple a@@ -153,20 +118,31 @@   where     fmap f (One a)  = One (f a)     fmap f (Tup as) = Tup $ map (fmap f) as+  -- XXX Can be derived in GHC 6.12  instance Foldable Tuple   where     foldr f x (One a)  = f a x     foldr f x (Tup as) = Fold.foldr (flip $ Fold.foldr f) x as+  -- XXX Can be derived in GHC 6.12  instance Traversable Tuple   where     traverse f (One a)  = pure One <*> f a     traverse f (Tup as) = pure Tup <*> traverse (traverse f) as+  -- XXX Can be derived in GHC 6.12 +instance HaskellType a => HaskellType (Tuple a)+  where+    haskellType = showTuple . fmap haskellType +instance HaskellValue a => HaskellValue (Tuple a)+  where+    haskellValue = showTuple . fmap haskellValue --- | Shows a nested tuple in Haskell's tuple syntax (e.g @\"(a,(b,c))\"@)+++-- | Shows a nested tuple in Haskell's tuple syntax (e.g @\"(a,(b,c))\"@). showTuple :: Tuple String -> String showTuple (One a)  = a showTuple (Tup as) = showSeq "(" (map showTuple as) ")"@@ -186,267 +162,237 @@  -- * Data --- | Representation of primitive types-data PrimitiveType-  = UnitType-  | BoolType-  | IntType-  | FloatType-    deriving (Eq, Show)- -- | Untyped representation of primitive data data PrimitiveData-  = UnitData+  = UnitData  ()   | BoolData  Bool-  | IntData   Int+  | IntData   Integer   | FloatData Float     deriving (Eq, Show) --- | Representation of storable types (arrays of primitive data). Array--- dimensions are given as a list of integers, starting with outermost array--- level. Primitive types are treated as zero-dimensional arrays.-data StorableType = StorableType [Int] PrimitiveType-    deriving (Eq, Show)---- | Untyped representation of storable data. Arrays have a length argument that--- gives the number of elements on the outermost array level. If the data list--- is shorter than this length, the missing elements are taken to have--- undefined value. If the data list is longer, the excessive elements are just--- ignored.+-- | Untyped representation of storable data (arrays of primitive data) data StorableData   = PrimitiveData PrimitiveData-  | StorableData Int [StorableData]+  | StorableData [StorableData]     deriving (Eq, Show) -instance HaskellType PrimitiveType-  where-    haskellType UnitType  = "()"-    haskellType BoolType  = "Bool"-    haskellType IntType   = "Int"-    haskellType FloatType = "Float"- instance HaskellValue PrimitiveData   where-    haskellValue UnitData      = "()"+    haskellValue (UnitData  a) = show a     haskellValue (BoolData  a) = map toLower (show a)     haskellValue (IntData   a) = show a     haskellValue (FloatData a) = show a -instance HaskellType StorableType-  where-    haskellType (StorableType dim t) = arrType ++ dimComment-      where-        l       = length dim-        arrType = replicate l '[' ++ haskellType t ++ replicate l ']'-        dimComment-          | [] <- dim = ""-          | otherwise = showSeq "{-" (map haskellValue dim) "-}"- instance HaskellValue StorableData   where-    haskellValue (PrimitiveData a)   = haskellValue a-    haskellValue (StorableData _ as) = showSeq "[" (map haskellValue as) "]"+    haskellValue (PrimitiveData a) = haskellValue a+    haskellValue (StorableData as) = showSeq "[" (map haskellValue as) "]"   --- | Primitive types-class Storable a => Primitive a+-- * Types -instance Primitive ()-instance Primitive Bool-instance Primitive Int-instance Primitive Float+-- | Representation of primitive types+data PrimitiveType+  = UnitType+  | BoolType+  | IntType { signed :: Bool, bitSize :: Int, valueSet :: (Range Integer) }+  | FloatType (Range Float)+    deriving (Eq, Show) +-- | Representation of storable types (arrays of primitive types). Array size is+-- given as a list of ranged lengths, starting with outermost array level.+-- Primitive types are treated as zero-dimensional arrays.+data StorableType = StorableType [Range Length] PrimitiveType+    deriving (Eq, Show) +instance HaskellType PrimitiveType+  where+    haskellType UnitType        = "()"+    haskellType BoolType        = "Bool"+    haskellType (IntType _ _ _) = "Int"+    haskellType (FloatType _)   = "Float" --- | Array represented as (nested) list. If @a@ is a storable type and @n@ is a--- type-level natural number, @n :> a@ represents an array of @n@ elements of--- type @a@. For example, @D3:>D10:>Int@ is a 3 by 10 array of integers. Arrays--- constructed using 'fromList' are guaranteed not to contain too many elements--- in any dimension. If there are too few elements in any dimension, the missing--- ones are taken to have undefined value.-data n :> a = (NaturalT n, Storable a) => ArrayList [a]+instance HaskellType StorableType+  where+    haskellType (StorableType ls t) = arrType+      where+        d       = length ls+        arrType = replicate d '[' ++ haskellType t ++ replicate d ']' -infixr 5 :>+showPrimitiveRange UnitType        = ""+showPrimitiveRange BoolType        = ""+showPrimitiveRange (IntType _ _ r) = showRange r+showPrimitiveRange (FloatType r)   = showRange r -instance (NaturalT n, Storable a, Eq a) => Eq (n :> a)-  where-    ArrayList a == ArrayList b = a == b+-- | Shows the size of a storable type.+showStorableSize :: StorableType -> String+showStorableSize (StorableType ls t) =+    showSeq "" (map (showBound . upperBound) ls) "" ++ showPrimitiveRange t -instance (NaturalT n, Storable a, Show (ListBased a)) => Show (n :> a)-  where-    show = show . toList -instance (NaturalT n, Storable a, Ord a) => Ord (n :> a)++-- | Primitive types+class Storable a => Primitive a   where-    ArrayList a `compare` ArrayList b = a `compare` b+    -- | Converts a primitive value to its untyped representation.+    primitiveData :: a -> PrimitiveData +    -- | Gives the type representation of a primitive value.+    primitiveType :: Size a -> T a -> PrimitiveType +instance Primitive ()+  where+    primitiveData     = UnitData+    primitiveType _ _ = UnitType -mapArray ::-    (NaturalT n, Storable a, Storable b) => (a -> b) -> (n :> a) -> (n :> b)+instance Primitive Bool+  where+    primitiveData     = BoolData+    primitiveType _ _ = BoolType -mapArray f (ArrayList as) = ArrayList $ map f as-  -- Couldn't use Functor because of the extra class constraints.+-- Assumes 32 bits which is not necessarily correct+instance Primitive Int+  where+    primitiveData     = IntData . toInteger+    primitiveType s _ = IntType True 32 s +instance Primitive Float+  where+    primitiveData     = FloatData+    primitiveType s _ = FloatType s  --- | Storable types (zero- or higher-level arrays of primitive data). Should be--- the same set of types as 'Storable', but this class has no 'Typeable'--- context, so it doesn't cause a cycle.------ Example:------ > *Feldspar.Core.Types> toList (replicateArray 3 :: D4 :> D2 :> Int)--- > [[3,3],[3,3],[3,3],[3,3]]++-- | Storable types (zero- or higher-level arrays of primitive data). class Typeable a => Storable a   where-    -- | List-based representation of a storable type-    type ListBased a :: *-    -- | The innermost element of a storable type-    type Element a :: *--    -- | Constructs an array filled with the given element. For primitive types,-    -- this is just the identity function.-    replicateArray :: Element a -> a+    -- | Converts a storable value to its untyped representation.+    storableData :: a -> StorableData -    -- | Converts a storable type to a (zero- or higher-level) nested list.-    toList :: a -> ListBased a+    -- | Gives the type representation of a storable value.+    storableType :: Size a -> T a -> StorableType -    -- | Constructs a storable type from a (zero- or higher-level) nested list.-    -- The resulting value is guaranteed not to have too many elements in any-    -- dimension. Excessive elements are simply cut away.-    fromList :: ListBased a -> a+    -- | Gives the size of a storable value.+    storableSize :: a -> Size a -    -- | Converts a storable value to its untyped representation.-    toData :: a -> StorableData+    listSize :: T a -> Size a -> [Range Length]+      -- XXX Could be put in a separate class without the (T a).  instance Storable ()   where-    type ListBased () = ()-    type Element   () = ()--    replicateArray = id-    toList         = id-    fromList       = id--    toData a = PrimitiveData $ case a of-      () -> UnitData+    storableData    = PrimitiveData . primitiveData+    storableType s  = StorableType [] . primitiveType s+    storableSize _  = ()+    listSize _ _    = []  instance Storable Bool   where-    type ListBased Bool = Bool-    type Element   Bool = Bool--    replicateArray = id-    toList         = id-    fromList       = id-    toData         = PrimitiveData . BoolData+    storableData   = PrimitiveData . primitiveData+    storableType s = StorableType [] . primitiveType s+    storableSize _ = ()+    listSize _ _   = []  instance Storable Int   where-    type ListBased Int = Int-    type Element   Int = Int--    replicateArray = id-    toList         = id-    fromList       = id-    toData         = PrimitiveData . IntData+    storableData   = PrimitiveData . primitiveData+    storableType s = StorableType [] . primitiveType s+    storableSize a = singletonRange $ toInteger a+    listSize _ _   = []  instance Storable Float   where-    type ListBased Float = Float-    type Element   Float = Float--    replicateArray = id-    toList         = id-    fromList       = id-    toData         = PrimitiveData . FloatData+    storableData   = PrimitiveData . primitiveData+    storableType s = StorableType [] . primitiveType s+    storableSize a = singletonRange a+    listSize _ _   = [] -instance (NaturalT n, Storable a) => Storable (n :> a)+instance Storable a => Storable [a]   where-    type ListBased (n :> a) = [ListBased a]-    type Element   (n :> a) = Element a+    storableData = StorableData . map storableData -    replicateArray = ArrayList . replicate n . replicateArray+    storableType (l:>ls) _ = StorableType (l:ls') t       where-        n = fromIntegerT (undefined :: n)--    toList (ArrayList as) = map toList as+        StorableType ls' t = storableType ls (T::T a) -    fromList as = ArrayList $ take n $ map fromList as-      where-        n = fromIntegerT (undefined :: n)+    storableSize as =+        singletonRange (length as) :> mconcat (map storableSize as) -    toData (ArrayList a) = StorableData n $ map toData a-      where-        n = fromIntegerT (undefined :: n)+    listSize _ (l:>ls) = l : listSize (T::T a) ls   -isRectangular :: Storable a => a -> Bool-isRectangular = isJust . checkRect . toData+class (Eq a, Ord a, Monoid (Size a), Set (Size a)) => Typeable a   where-    checkRect (PrimitiveData _)   = return []-    checkRect (StorableData _ []) = return []-    checkRect (StorableData _ as) = do-        dims <- mapM checkRect as-        guard $ allEqual dims-        return (length as : head dims)--+    -- | This type provides the necessary extra information to compute a type+    -- representation @`Tuple` `StorableType`@ from a type @a@. This is needed+    -- because the type @a@ is missing information about sizes of arrays and+    -- primitive values.+    type Size a --- | All supported types of data (nested tuples of storable data)-class (Eq a, Ord a) => Typeable a-  where-    -- | Gives the representation of the indexing type.-    typeOf :: T a -> Tuple StorableType+    -- | Gives the type representation of a storable value.+    typeOf :: Size a -> T a -> Tuple StorableType  instance Typeable ()   where-    typeOf = const $ One $ StorableType [] UnitType+    type Size () = ()+    typeOf       = typeOfStorable  instance Typeable Bool   where-    typeOf = const $ One $ StorableType [] BoolType+    type Size Bool = ()+    typeOf         = typeOfStorable  instance Typeable Int   where-    typeOf = const $ One $ StorableType [] IntType+    type Size Int = Range Integer+    typeOf        = typeOfStorable  instance Typeable Float   where-    typeOf = const $ One $ StorableType [] FloatType+    type Size Float = Range Float+    typeOf          = typeOfStorable -instance (NaturalT n, Storable a) => Typeable (n :> a)+instance Storable a => Typeable [a]   where-    typeOf = const $ One $ StorableType (n:dim) t-     where-       n = fromIntegerT (undefined :: n)-       One (StorableType dim t) = typeOf (T::T a)+    type Size [a] = Range Length :> Size a+    typeOf        = typeOfStorable  instance (Typeable a, Typeable b) => Typeable (a,b)   where-    typeOf = const $ Tup [typeOf (T::T a), typeOf (T::T b)]+    type Size (a,b) = (Size a, Size b) +    typeOf (sa,sb) _ = Tup [typeOf sa (T::T a), typeOf sb (T::T b)]+ instance (Typeable a, Typeable b, Typeable c) => Typeable (a,b,c)   where-    typeOf = const $ Tup [typeOf (T::T a), typeOf (T::T b), typeOf (T::T c)]+    type Size (a,b,c) = (Size a, Size b, Size c) +    typeOf (sa,sb,sc) _ = Tup+        [ typeOf sa (T::T a)+        , typeOf sb (T::T b)+        , typeOf sc (T::T c)+        ]+ instance (Typeable a, Typeable b, Typeable c, Typeable d) => Typeable (a,b,c,d)   where-    typeOf = const $ Tup-      [ typeOf (T::T a)-      , typeOf (T::T b)-      , typeOf (T::T c)-      , typeOf (T::T d)-      ]+    type Size (a,b,c,d) = (Size a, Size b, Size c, Size d) +    typeOf (sa,sb,sc,sd) _ = Tup+        [ typeOf sa (T::T a)+        , typeOf sb (T::T b)+        , typeOf sc (T::T c)+        , typeOf sd (T::T d)+        ]  --- | Checks if the given type is primitive.-isPrimitive :: Typeable a => T a -> Bool-isPrimitive a = case typeOf a of-    One (StorableType [] _) -> True-    _                       -> False +-- | Default implementation of 'typeOf' for 'Storable' types.+typeOfStorable :: Storable a => Size a -> T a -> Tuple StorableType+typeOfStorable sz = One . storableType sz++class (Num a, Primitive a, Num (Size a)) => Numeric a++instance Numeric Int++instance Numeric Float
+ Feldspar/Haskell.hs view
@@ -0,0 +1,99 @@+-- Copyright (c) 2009-2010, ERICSSON AB+-- All rights reserved.+--+-- Redistribution and use in source and binary forms, with or without+-- modification, are permitted provided that the following conditions are met:+--+--     * Redistributions of source code must retain the above copyright notice,+--       this list of conditions and the following disclaimer.+--     * Redistributions in binary form must reproduce the above copyright+--       notice, this list of conditions and the following disclaimer in the+--       documentation and/or other materials provided with the distribution.+--     * Neither the name of the ERICSSON AB nor the names of its contributors+--       may be used to endorse or promote products derived from this software+--       without specific prior written permission.+--+-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"+-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE+-- IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE+-- DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE+-- FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL+-- DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR+-- SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER+-- CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,+-- OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE+-- OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.++-- | Helper functions for producing Haskell code++module Feldspar.Haskell where++++import Data.List++++-- | Types that can represent Haskell types (as source code strings)+class HaskellType a+  where+    -- | Gives the Haskell type denoted by the argument.+    haskellType :: a -> String++++-- | Types that can represent Haskell values (as source code strings)+class HaskellValue a+  where+    -- | Gives the Haskell code denoted by the argument.+    haskellValue :: a -> String++instance HaskellValue String+  where+    haskellValue = id++instance HaskellValue Int+  where+    haskellValue = show++++-- | Like 'Data.List.unlines', but no trailing @\'\\n\'@.+unlinesNoTrail :: [String] -> String+unlinesNoTrail = intercalate "\n"++-- | Indents a string the given number of columns.+indent :: Int -> String -> String+indent n = unlinesNoTrail . map (spc ++) . lines+  where+    spc = replicate n ' '++newline :: String+newline = "\n"++-- | Application+(-$-) :: HaskellValue a => String -> a -> String+fun -$- inp = unwords [fun, haskellValue inp]++-- | Binary operator application+opApp :: (HaskellValue a, HaskellValue b) => String -> a -> b -> String+opApp op a b = unwords [haskellValue a, op, haskellValue b]++-- | Definition+(-=-) :: (HaskellValue patt, HaskellValue def) => patt -> def -> String+patt -=- def = unwords [haskellValue patt, "=", haskellValue def]++-- Places the second string as a local block to the first string.+local :: String -> String -> String+local def ""   = def+local def defs = def ++ newline ++ indent 2 "where" ++ newline ++ indent 4 defs++infixl 8 -$-+infix  7 -=-+infixr 6 `local`++ifThenElse+    :: (HaskellValue c, HaskellValue t, HaskellValue e) => c -> t -> e -> String+ifThenElse c t e = unwords+    ["if", haskellValue c, "then", haskellValue t, "else", haskellValue e]+
Feldspar/Matrix.hs view
@@ -1,4 +1,4 @@--- Copyright (c) 2009, ERICSSON AB+-- Copyright (c) 2009-2010, ERICSSON AB -- All rights reserved. -- -- Redistribution and use in source and binary forms, with or without@@ -24,8 +24,8 @@ -- OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -- OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. --- | Operations on matrices (nested parallel vectors). All operations in this--- module assume rectangular matrices.+-- | Operations on matrices (doubly-nested parallel vectors). All operations in+-- this module assume rectangular matrices.  module Feldspar.Matrix where @@ -33,58 +33,54 @@  import qualified Prelude as P -import Types.Data.Ord- import Feldspar.Prelude import Feldspar.Utils-import Feldspar.Core.Types import Feldspar.Core import Feldspar.Vector   -type Matrix m n a = Par m :>> Par n :>> Data a+type Matrix a = Vector (Vector (Data a))    -- | Converts a matrix to a core array.-freezeMatrix :: (NaturalT m, NaturalT n, Storable a) =>-    Matrix m n a -> Data (m :> n :> a)-+freezeMatrix :: Storable a => Matrix a -> Data [[a]] freezeMatrix = freezeVector . map freezeVector ----- | Converts a core array to a matrix.-unfreezeMatrix :: (NaturalT m, NaturalT n, Storable a) =>-    Data Int -> Data Int -> Data (m :> n :> a) -> Matrix m n a-+-- | Converts a core array to a matrix. The first length argument is the number+-- of rows (outer vector), and the second argument is the number of columns+-- (inner argument).+unfreezeMatrix :: Storable a => Data Length -> Data Length -> Data [[a]] -> Matrix a unfreezeMatrix y x = map (unfreezeVector x) . (unfreezeVector y) ----- | Constructs a matrix.-matrix :: (NaturalT m, NaturalT n, Storable a, ListBased a ~ a) =>-    [[a]] -> Matrix m n a-+-- | Constructs a matrix. The elements are stored in a core array.+matrix :: Storable a => [[a]] -> Matrix a matrix as-    | allEqual xs = unfreezeMatrix y x $ array as+    | allEqual xs = unfreezeMatrix y x (value as)     | otherwise   = error "matrix: Not rectangular"   where-    y  = value $ P.length as     xs = P.map P.length as+    y  = value $ P.length as     x  = value $ P.head (xs P.++ [0])    -- | Transpose of a matrix-transpose :: Matrix m n a -> Matrix n m a+transpose :: Matrix a -> Matrix a transpose a = Indexed (length $ head a) ixf   where-    ixf y = Indexed (length a) (\x -> a ! x ! y)+    ixf y = Indexed (length a) $ \x -> a ! x ! y+  -- XXX This assumes that (head a) can be used even if a is empty. Might this+  --     violate size constraints on the index?+  --     See the conditional in 'flatten'. +  -- XXX Should be written using indexMat.+++ -- | Matrix multiplication-mul :: (Primitive a, Num a) => Matrix m n a -> Matrix n p a -> Matrix m p a+mul :: Numeric a => Matrix a -> Matrix a -> Matrix a mul a b = map (\aRow -> map (scalarProd aRow) b') a   where     b' = transpose b@@ -92,7 +88,7 @@   -- | Concatenates the rows of a matrix.-flatten :: Matrix m n a -> VectorP (m :* n) a+flatten :: Matrix a -> Vector (Data a) flatten matr = Indexed (m*n) ixf   where     m = length matr@@ -100,14 +96,15 @@      ixf i = matr ! y ! x       where-        y = i `div` m-        x = i `mod` m+        y = i `div` n+        x = i `mod` n+  -- XXX Should use "linear indexing"    -- | The diagonal vector of a square matrix. It happens to work if the number of -- rows is less than the number of columns, but not the other way around (this -- would require some overhead).-diagonal :: Matrix n n a -> VectorP n a-diagonal m = map (uncurry (!)) $ zip m $ enumFromTo 0 (length m - 1)+diagonal :: Matrix a -> Vector (Data a)+diagonal m = zipWith (!) m (0 ... (length m - 1)) 
Feldspar/Prelude.hs view
@@ -1,4 +1,4 @@--- Copyright (c) 2009, ERICSSON AB+-- Copyright (c) 2009-2010, ERICSSON AB -- All rights reserved. -- -- Redistribution and use in source and binary forms, with or without@@ -38,6 +38,9 @@   , (<), (>), (<=), (>=)   , not, (&&), (||)   , min, max+  , (^)+  , div, mod+  , (>>)   , maximum, minimum   , length   , (++)@@ -52,7 +55,5 @@   , map   , zipWith   , sum-  , (^)-  , div, mod   ) 
+ Feldspar/Range.hs view
@@ -0,0 +1,403 @@+-- Copyright (c) 2009-2010, ERICSSON AB+-- All rights reserved.+--+-- Redistribution and use in source and binary forms, with or without+-- modification, are permitted provided that the following conditions are met:+--+--     * Redistributions of source code must retain the above copyright notice,+--       this list of conditions and the following disclaimer.+--     * Redistributions in binary form must reproduce the above copyright+--       notice, this list of conditions and the following disclaimer in the+--       documentation and/or other materials provided with the distribution.+--     * Neither the name of the ERICSSON AB nor the names of its contributors+--       may be used to endorse or promote products derived from this software+--       without specific prior written permission.+--+-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"+-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE+-- IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE+-- DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE+-- FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL+-- DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR+-- SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER+-- CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,+-- OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE+-- OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.++{-# LANGUAGE NoMonomorphismRestriction #-}++-- | Ranged values++module Feldspar.Range where++++import Control.Monad+import Data.Maybe+import Data.Monoid+import Test.QuickCheck++++data Ord a => Range a = Range+  { lowerBound :: Maybe a+  , upperBound :: Maybe a+  }+    deriving (Eq, Show)++++instance (Ord a, Num a) => Num (Range a)+  where+    fromInteger = singletonRange . fromInteger++    negate = rangeOp neg+      where+        neg (Range l u) = Range (liftM negate u) (liftM negate l)++    (+) = rangeOp2 add+      where+        add (Range l1 u1) (Range l2 u2) =+          Range (liftM2 (+) l1 l2) (liftM2 (+) u1 u2)++    (*) = rangeMul++    abs = rangeOp abs'+      where+        abs' (Range l u) =+          Range (Just 0) (liftM2 max (liftM abs l) (liftM abs u))++    signum = rangeOp sign+      where+        sign r+          | range (-1) 1     `isSubRangeOf` r = range (-1) 1+          | range (-1) 0     `isSubRangeOf` r = range (-1) 0+          | range 0 1        `isSubRangeOf` r = range 0 1+          | singletonRange 0 `isSubRangeOf` r = singletonRange 0+          | isNatural r                       = singletonRange 1+          | isNegative r                      = singletonRange (-1)++instance (Ord a, Num a) => Monoid (Range a)+  where+    mempty  = emptyRange+    mappend = (\/)++++rangeOp :: Ord a => (Range a -> Range a) -> (Range a -> Range a)+rangeOp f r = if isEmpty r then r else f r++rangeOp2 :: Ord a =>+    (Range a -> Range a -> Range a) -> (Range a -> Range a -> Range a)+rangeOp2 f r1 r2+  | isEmpty r1 = r1+  | isEmpty r2 = r2+  | otherwise  = f r1 r2++mapMonotonic :: (Ord a, Ord b) => (a -> b) -> Range a -> Range b+mapMonotonic f (Range l u) = Range (liftM f l) (liftM f u)++rangeMul :: (Ord a, Num a) => Range a -> Range a -> Range a+rangeMul r1 r2 = p1 \/ p2 \/ p3 \/ p4+  where+    split r = (r /\ negativeRange, r /\ naturalRange)++    (r1neg,r1pos) = split r1+    (r2neg,r2pos) = split r2++    p1 = mul (negate r1neg) (negate r2neg)+    p2 = negate $ mul (negate r1neg) r2pos+    p3 = negate $ mul r1pos (negate r2neg)+    p4 = mul r1pos r2pos++    mul = rangeOp2 mul'+      where+        mul' (Range l1 u1) (Range l2 u2) =+          Range (liftM2 (*) l1 l2) (liftM2 (*) u1 u2)++++emptyRange :: (Ord a, Num a) => Range a+emptyRange = Range (Just 0) (Just (-1))++fullRange :: Ord a => Range a+fullRange = Range Nothing Nothing++range :: Ord a => a -> a -> Range a+range l u = Range (Just l) (Just u)++rangeByRange :: Ord a => Range a -> Range a -> Range a+rangeByRange r1 r2 = Range (lowerBound r1) (upperBound r2)++singletonRange :: Ord a => a -> Range a+singletonRange a = Range (Just a) (Just a)++naturalRange :: (Ord a, Num a) => Range a+naturalRange = Range (Just 0) Nothing++negativeRange :: (Ord a, Num a) => Range a+negativeRange = Range Nothing (Just (-1))++rangeSize :: (Ord a, Num a) => Range a -> Maybe a+rangeSize (Range l u) = do+    l' <- l+    u' <- u+    return (u'-l'+1)++isEmpty :: Ord a => Range a -> Bool+isEmpty (Range Nothing _)         = False+isEmpty (Range _ Nothing)         = False+isEmpty (Range (Just l) (Just u)) = u < l++isFull :: Ord a => Range a -> Bool+isFull (Range Nothing Nothing) = True+isFull _                       = False++isBounded :: Ord a => Range a -> Bool+isBounded (Range Nothing _) = False+isBounded (Range _ Nothing) = False+isBounded (Range _ _)       = True++isSingleton :: Ord a => Range a -> Bool+isSingleton (Range (Just l) (Just u)) = l==u+isSingleton _                         = False++isSubRangeOf :: Ord a => Range a -> Range a -> Bool+isSubRangeOf r1@(Range l1 u1) r2@(Range l2 u2)+    | isEmpty r1 = True+    | isEmpty r2 = False+    | otherwise+         = (isNothing l2 || (isJust l1 && l1>=l2))+        && (isNothing u2 || (isJust u1 && u1<=u2))++-- | Checks whether a range is a sub-range of the natural numbers.+isNatural :: (Ord a, Num a) => Range a -> Bool+isNatural = (`isSubRangeOf` naturalRange)++-- | Checks whether a range is a sub-range of the negative numbers.+isNegative :: (Ord a, Num a) => Range a -> Bool+isNegative = (`isSubRangeOf` negativeRange)++inRange :: Ord a => a -> Range a -> Bool+inRange a r = singletonRange a `isSubRangeOf` r++rangeGap :: (Ord a, Num a) => Range a -> Range a -> Range a+rangeGap = rangeOp2 gap+  where+    gap (Range _ (Just u1)) (Range (Just l2) _)+      | u1 < l2 = Range (Just u1) (Just l2)+    gap (Range (Just l1) _) (Range _ (Just u2))+      | u2 < l1 = Range (Just u2) (Just l1)+    gap _ _ = emptyRange+  -- If the result is non-empty, it will include the boundary elements from the+  -- two ranges.++++(\/) :: Ord a => Range a -> Range a -> Range a+r1 \/ r2+    | isEmpty r1 = r2+    | isEmpty r2 = r1+    | otherwise  = or r1 r2+  where+    or (Range l1 u1) (Range l2 u2) =+      Range (liftM2 min l1 l2) (liftM2 max u1 u2)++liftMaybe2 :: (a -> a -> a) -> Maybe a -> Maybe a -> Maybe a+liftMaybe2 f Nothing b         = b+liftMaybe2 f a Nothing         = a+liftMaybe2 f (Just a) (Just b) = Just (f a b)++(/\) :: Ord a => Range a -> Range a -> Range a+(/\) = rangeOp2 and+  where+    and (Range l1 u1) (Range l2 u2) =+        Range (liftMaybe2 max l1 l2) (liftMaybe2 min u1 u2)++disjoint :: (Ord a, Num a) => Range a -> Range a -> Bool+disjoint r1 r2 = isEmpty (r1 /\ r2)++-- | @r1 \`rangeLess\` r2:@+--+-- Checks if all elements of @r1@ are less than all elements of @r2@.+rangeLess :: Ord a => Range a -> Range a -> Bool+rangeLess r1 r2+  | isEmpty r1 || isEmpty r2 = True+rangeLess (Range _ (Just u1)) (Range (Just l2) _) = u1 < l2+rangeLess _ _                                     = False++-- | @r1 \`rangeLessEq\` r2:@+--+-- Checks if all elements of @r1@ are less than or equal to all elements of+-- @r2@.+rangeLessEq :: Ord a => Range a -> Range a -> Bool+rangeLessEq (Range _ (Just u1)) (Range (Just l2) _) = u1 <= l2+rangeLessEq _ _                                     = False++showBound :: Show a => Maybe a -> String+showBound (Just a) = show a+showBound _        = "*"++showRange :: (Show a, Ord a) => Range a -> String+showRange r@(Range l u)+  | isEmpty r     = "[]"+  | isSingleton r = let Just a = upperBound r in show [a]+  | otherwise     = "[" ++ showBound l ++ "," ++ showBound u ++ "]"++++instance (Arbitrary a, Ord a, Num a) => Arbitrary (Range a)+  where+    coarbitrary = error "coarbitrary not defined for (Range a)"++    arbitrary = do+        lower <- arbitrary+        size  <- liftM abs arbitrary+        upper <- frequency [(6, return (lower+size)), (1, return (lower-size))]+        liftM2 Range (arbMaybe lower) (arbMaybe upper)+      where+        arbMaybe a = frequency [(5, return (Just a)), (1, return Nothing)]++++prop_arith1 :: (forall a . Num a => a -> a) -> Int -> Range Int -> Property+prop_arith1 op x r = (x `inRange` r) ==> (op x `inRange` op r)++++prop_arith2+    :: (forall a . Num a => a -> a -> a)+    -> Int -> Int -> Range Int -> Range Int -> Property++prop_arith2 op x y r1 r2 =+    (inRange x r1 && inRange y r2) ==> (op x y `inRange` op r1 r2)++++prop_fromInteger = isSingleton . fromInteger++prop_neg  = prop_arith1 negate+prop_add  = prop_arith2 (+)+prop_sub  = prop_arith2 (-)+prop_mul  = prop_arith2 (*)+prop_abs  = prop_arith1 abs+prop_sign = prop_arith1 signum++prop_abs2 (r::Range Int) = isNatural (abs r)++prop_empty = isEmpty (emptyRange :: Range Int)++prop_full = isFull (fullRange :: Range Int)++prop_isEmpty1 (r::Range Int) = isEmpty r ==> isBounded r+prop_isEmpty2 (r::Range Int) = isEmpty r ==> (upperBound r < lowerBound r)++prop_isFull (r::Range Int) = isFull r ==> not (isBounded r)++prop_fullRange = not $ isBounded (fullRange :: Range Int)++prop_range (a::Int) (b::Int) = isBounded $ range a b++prop_rangeByRange (r1::Range Int) (r2::Range Int) =+    (rangeLess r1 r2 && not (isEmpty (r1/\r2))) ==> isEmpty (rangeByRange r1 r2)++prop_singletonRange1 (a::Int) = isSingleton (singletonRange a)+prop_singletonRange2 (a::Int) = isBounded   (singletonRange a)++prop_singletonSize (r::Range Int) = isSingleton r ==> (rangeSize r == Just 1)++prop_subRange (r1::Range Int) (r2::Range Int) =+    ((r1 < r2) && (r2 < r1) && not (isEmpty r1)) ==> r1==r2+  where+    (<) = isSubRangeOf++prop_emptySubRange1 (r1::Range Int) (r2::Range Int) =+    isEmpty r1 ==> (not (isEmpty r2) ==> not (r2 `isSubRangeOf` r1))++prop_emptySubRange2 (r1::Range Int) (r2::Range Int) =+    isEmpty r1 ==> (not (isEmpty r2) ==> (r1 `isSubRangeOf` r2))++prop_isNegative (r::Range Int) =+    not (isEmpty r) ==> (isNegative r ==> not (isNegative $ negate r))++prop_rangeGap (r1::Range Int) (r2::Range Int) =+    (isEmpty gap1 && isEmpty gap2) || (gap1 == gap2)+  where+    gap1 = rangeGap r1 r2+    gap2 = rangeGap r2 r1++prop_union1 x (r1::Range Int) (r2::Range Int) =+    ((x `inRange` r1) || (x `inRange` r2)) ==> (x `inRange` (r1\/r2))++prop_union2 x (r1::Range Int) (r2::Range Int) =+    (x `inRange` (r1\/r2)) ==>+        ((x `inRange` r1) || (x `inRange` r2) || (x `inRange` rangeGap r1 r2))++prop_union3 (r1::Range Int) (r2::Range Int) = r1 `isSubRangeOf` (r1\/r2)+prop_union4 (r1::Range Int) (r2::Range Int) = r2 `isSubRangeOf` (r1\/r2)++prop_intersect1 x (r1::Range Int) (r2::Range Int) =+    ((x `inRange` r1) && (x `inRange` r2)) ==> (x `inRange` (r1/\r2))++prop_intersect2 x (r1::Range Int) (r2::Range Int) =+    (x `inRange` (r1/\r2)) ==> ((x `inRange` r1) && (x `inRange` r2))++prop_intersect3 (r1::Range Int) (r2::Range Int) = (r1/\r2) `isSubRangeOf` r1+prop_intersect4 (r1::Range Int) (r2::Range Int) = (r1/\r2) `isSubRangeOf` r2++prop_disjoint x (r1::Range Int) (r2::Range Int) =+    disjoint r1 r2 ==> (x `inRange` r1) ==> not (x `inRange` r2)++prop_rangeLess1 (r1::Range Int) (r2::Range Int) =+    rangeLess r1 r2 ==> disjoint r1 r2++prop_rangeLess2 x y (r1::Range Int) (r2::Range Int) =+    (rangeLess r1 r2 && inRange x r1 && inRange y r2) ==> x < y++prop_rangeLessEq x y (r1::Range Int) (r2::Range Int) =+    (rangeLessEq r1 r2 && inRange x r1 && inRange y r2) ==> x <= y++++testAll = do+    myCheck prop_neg+    myCheck prop_add+    myCheck prop_sub+    myCheck prop_mul+    myCheck prop_abs+    myCheck prop_sign+    myCheck prop_abs2+    myCheck prop_fromInteger+    myCheck prop_empty+    myCheck prop_full+    myCheck prop_isEmpty1+    myCheck prop_isEmpty2+    myCheck prop_isFull+    myCheck prop_fullRange+    myCheck prop_range+    -- myCheck prop_rangeByRange+    -- XXX "Arguments exhausted after 0 test"+    --     Something must be wrong with generator...+    myCheck prop_singletonRange1+    myCheck prop_singletonRange2+    myCheck prop_singletonSize+    myCheck prop_subRange+    myCheck prop_emptySubRange1+    myCheck prop_emptySubRange2+    myCheck prop_isNegative+    myCheck prop_rangeGap+    myCheck prop_union1+    myCheck prop_union2+    myCheck prop_union3+    myCheck prop_union4+    myCheck prop_intersect1+    myCheck prop_intersect2+    myCheck prop_intersect3+    myCheck prop_intersect4+    myCheck prop_disjoint+    myCheck prop_rangeLess1+    myCheck prop_rangeLess2+    myCheck prop_rangeLessEq+  where+    myCheck = check defaultConfig {configMaxFail = 100000}+
Feldspar/Utils.hs view
@@ -1,4 +1,4 @@--- Copyright (c) 2009, ERICSSON AB+-- Copyright (c) 2009-2010, ERICSSON AB -- All rights reserved. -- -- Redistribution and use in source and binary forms, with or without@@ -42,12 +42,18 @@ allEqual []     = True allEqual (a:as) = all (==a) as --- | @showSeq open strs close@:+-- | @`showSeq` open strs close@: -- -- Shows the strings @strs@ separated by commas and enclosed within the @open@ -- and @close@ strings. showSeq :: String -> [String] -> String -> String showSeq open strs close = open ++ intercalate "," strs ++ close++-- | Append the first argument to the first line of the second argument.+appendFirstLine :: String -> String -> String+appendFirstLine extra str = str1 ++ extra ++ str2+  where+    (str1,str2) = break (=='\n') str   
Feldspar/Vector.hs view
@@ -1,4 +1,4 @@--- Copyright (c) 2009, ERICSSON AB+-- Copyright (c) 2009-2010, ERICSSON AB -- All rights reserved. -- -- Redistribution and use in source and binary forms, with or without@@ -28,198 +28,144 @@ -- ("Feldspar.Core"). Many of the functions defined here are imitations of -- Haskell's list operations, and to a first approximation they behave -- accordingly.+--+-- A symbolic vector ('Vector') can be thought of as a representation of a+-- 'parallel' core array. This view is made precise by the function+-- 'freezeVector', which converts a symbolic vector to a core vector using+-- 'parallel'.+--+-- 'Vector' is instantiated under the 'Computable' class, which means that+-- symbolic vectors can be used quite seamlessly with the interface in+-- "Feldspar.Core".+--+-- Note that the only operations in this module that introduce storage (through+-- core arrays) are+--+--   * 'freezeVector'+--+--   * 'memorize'+--+--   * 'vector'+--+--   * 'unfoldVec'+--+--   * 'unfold'+--+--   * 'scan'+--+--   * 'mapAccum'+--+-- This means that vector operations not involving these operations will be+-- completely \"fused\" without using any intermediate storage.+--+-- Note also that most operations only introduce a small constant overhead on+-- the vector. The exceptions are+--+--   * 'dropWhile'+--+--   * 'fold'+--+--   * 'fold1'+--+--   * Functions that introduce storage (see above)+--+--   * \"Folding\" functions: 'sum', 'maximum', etc.+--+-- These functions introduce overhead that is linear in the length of the+-- vector.+--+-- Finally, note that 'freezeVector' can be introduced implicitly by functions+-- overloaded by the 'Computable' class. This means that, for example,+-- @`printCore` f@, where @f :: Vector (Data Int) -> Vector (Data Int)@, will+-- introduce storage for the input and output of @f@.  module Feldspar.Vector where    import qualified Prelude-import Control.Arrow ((***),(&&&))-import Data.List (unfoldr)+import Control.Arrow ((&&&))+import qualified Data.List  -- Only for documentation of 'unfold'  import Feldspar.Prelude-import Feldspar.Core.Types-import Feldspar.Core.Expr hiding (index)+import Feldspar.Range+import Feldspar.Core.Expr import Feldspar.Core    -- * Types --- | Dynamic size of a vector-type Size = Int- -- | Vector index type Ix = Int --- | Empty type denoting a parallel (random) access pattern for elements in a--- vector. The argument denotes the static size of the vector.-data Par n---- | Empty type denoting a sequential access pattern for elements in a vector.--- The argument denotes the static size of the vector.-data Seq n---- | Symbolic vector. For example,------ > Seq D10 :>> Par D5 :>> Data Int------ is a sequential (symbolic) vector of parallel vectors of integers. The type--- numbers @D10@ and @D5@ denote the /static size/ of the vector, i.e. the--- allocated size of the array used if and when the vector gets written to--- memory (e.g. by 'toPar').------ If it is known that the vector will never be written to memory, it is--- not needed to specify a static size. In that case, it is possible to use @()@--- as the static size type. This way, attempting to write to memory will--- result in a type error.------ The 'Size' argument to the 'Indexed' and 'Unfold' constructors is called the--- /dynamic/ size, since it can vary freely during execution.-data n :>> a-  where-    Indexed  -- Constructor for parallel vectors-      :: Data Size-      -> (Data Ix -> a)  -- A mapping from indexes to elements-      -> (Par n :>> a)--    Unfold  -- Constructor for sequential vectors-      :: Computable s-      => Data Size-      -> (s -> (a,s))  -- "Step function"-      -> s             -- Initial state-      -> (Seq n :>> a)--infixr 5 :>>---- | Non-nested parallel vector-type VectorP n a = Par n :>> Data a---- | Non-nested sequential vector-type VectorS n a = Seq n :>> Data a------ | Addition for static vector size-type family (:+) a b--type instance (:+) (Dec a) (Dec b) = Dec a :+: Dec b-type instance (:+) ()      ()      = ()------ | Multiplication for static vector size-type family (:*) a b+-- | Symbolic vector+data Vector a = Indexed+  { length :: Data Length+  , index  :: Data Ix -> a+  } -type instance (:*) (Dec a) (Dec b) = Dec a :*: Dec b-type instance (:*) ()      ()      = ()+-- | Short-hand for non-nested parallel vector+type DVector a = Vector (Data a)    -- * Construction/conversion --- | A class for generalizing over parallel and sequential vectors.-class AccessPattern t-  where-    genericVector :: (Par n :>> a) -> (Seq n :>> a) -> (t n :>> a)--instance AccessPattern Par-  where-    genericVector vecP _ = vecP--instance AccessPattern Seq-  where-    genericVector _ vecS = vecS---- | Constructs a parallel vector from an index function. The function is--- assumed to be defined for the domain @[0 .. n-1]@, were @n@ is the dynamic--- size.-indexed :: Data Size -> (Data Ix -> a) -> (Par n :>> a)-indexed = Indexed---- | Constructs a sequential vector from a \"step\" function and an initial--- state.-unfold :: Computable s => Data Size -> (s -> (a,s)) -> s -> (Seq n :>> a)-unfold = Unfold--- -- | Converts a non-nested vector to a core vector.-freezeVector :: forall t n a . (NaturalT n, Storable a) =>-    (t n :>> Data a) -> Data (n :> a)--freezeVector (Indexed sz ixf) = parallel sz ixf--freezeVector (Unfold sz step s) = snd $ for 0 end (s,arr) body-  where-    end = value $ fromIntegerT (undefined :: n) - 1-    arr = array [] :: Data (n :> a)--    body i (s, arr :: Data (n :> a)) = (s', setIx arr i a)-      where-        (a,s') = step s+freezeVector :: Storable a => Vector (Data a) -> Data [a]+freezeVector (Indexed l ixf) = parallel l ixf +-- | Converts a non-nested core vector to a parallel vector.+unfreezeVector :: Storable a => Data Length -> Data [a] -> Vector (Data a)+unfreezeVector l arr = Indexed l (getIx arr) +-- | Optimizes vector lookup by computing all elements and storing them in a+-- core array.+memorize :: Storable a => Vector (Data a) -> Vector (Data a)+memorize vec = unfreezeVector (length vec) $ freezeVector vec+  -- XXX Should be generalized to arbitrary dimensions. --- | Converts a non-nested core vector to a parallel vector.-unfreezeVector :: (NaturalT n, Storable a, AccessPattern t) =>-    Data Size -> Data (n :> a) -> (t n :>> Data a)+indexed :: Data Length -> (Data Ix -> a) -> Vector a+indexed = Indexed -unfreezeVector sz arr = genericVector vec (toSeq vec)+-- | Constructs a non-nested vector. The elements are stored in a core vector.+vector :: Storable a => [a] -> Vector (Data a)+vector as = unfreezeVector l (value as)   where-    vec = Indexed sz (getIx arr)-+    l = value $ Prelude.length as+  -- XXX Should be generalized to arbitrary dimensions. +modifyLength :: (Data Length -> Data Length) -> Vector a -> Vector a+modifyLength f vec = vec {length = f (length vec)} --- | Constructs a non-nested vector.-vector :: (NaturalT n, Storable a, AccessPattern t, ListBased a ~ a) =>-    [a] -> (t n :>> Data a)-  -- (ListBased a ~ a) means no nesting.+setLength :: Data Length -> Vector a -> Vector a+setLength = modifyLength . const -vector as = unfreezeVector sz $ array as+boundVector :: Int -> Vector a -> Vector a+boundVector maxLen = modifyLength (cap r)   where-    sz = value $ Prelude.length as+    r = negativeRange + singletonRange (fromIntegral maxLen) + 1+      -- XXX fromIntegral might not be needed in future.   --- instance (NaturalT n, Storable (Internal a), Computable a) =>---     Computable (Par n :>> a)---   where---     type Internal (Par n :>> a) = (Int, n :> Internal a)----     internalize vec =---      internalize (length vec, freezeVector $ map internalize vec)----     externalize sz_a = map externalize $ unfreezeVector sz a---       where---         sz = externalize $ ref $ GetTuple (T::T D0) sz_a---         a  = externalize $ ref $ GetTuple (T::T D1) sz_a-  -- XXX This would require first class tuples.--instance (NaturalT n, Storable a, AccessPattern t)-      => Computable (t n :>> Data a)+instance Storable a => Computable (Vector (Data a))   where-    type Internal (t n :>> Data a) = (Int, n :> Internal (Data a))+    type Internal (Vector (Data a)) = (Length, [Internal (Data a)])      internalize vec =       internalize (length vec, freezeVector $ map internalize vec) -    externalize sz_a = map externalize $ unfreezeVector sz a+    externalize l_a = map externalize $ unfreezeVector l a       where-        sz = externalize $ ref $ GetTuple (T::T D0) sz_a-        a  = externalize $ ref $ GetTuple (T::T D1) sz_a+        l = externalize $ exprToData $ Get21 l_a+        a = externalize $ exprToData $ Get22 l_a -instance-    ( NaturalT n1-    , NaturalT n2-    , Storable a-    , AccessPattern t1-    , AccessPattern t2-    ) =>-      Computable (t1 n1 :>> t2 n2 :>> Data a)+instance Storable a => Computable (Vector (Vector (Data a)))   where-    type Internal (t1 n1 :>> t2 n2 :>> Data a) =-           (Int, n1 :> Int, n1 :> n2 :> Internal (Data a))+    type Internal (Vector (Vector (Data a))) =+           (Length, [Length], [[Internal (Data a)]])      internalize vec = internalize       ( length vec@@ -229,257 +175,169 @@      externalize inp         = map (map externalize . uncurry unfreezeVector)-        $ zip sz2sV (unfreezeVector sz1 a)+        $ zip l2sV (unfreezeVector l1 a)       where-        sz1   = externalize $ ref $ GetTuple (T::T D0) inp-        sz2s  = externalize $ ref $ GetTuple (T::T D1) inp-        a     = externalize $ ref $ GetTuple (T::T D2) inp-        sz2sV = unfreezeVector sz1 sz2s :: t1 n1 :>> Data Int------ | Convert any vector to a sequential one. This operation is always \"cheap\".-toSeq :: (t n :>> a) -> (Seq n :>> a)-toSeq (Indexed sz ixf)   = Unfold sz (\i -> (ixf i, i+1)) 0-toSeq (Unfold sz step s) = Unfold sz step s---- | Changes the static size of a vector.-resize :: NaturalT n => (t m :>> a) -> (t n :>> a)-resize (Indexed sz ixf)   = Indexed sz ixf-resize (Unfold sz step s) = Unfold sz step s-  -- The NaturalT constraint is needed because otherwise it would be possible to-  -- make an existing NaturalT constraint disappear. That would ruin the-  -- property that vectors with fully polymorphic sizes do not represent their-  -- elements in memory.---- | Convert any non-nested vector to a parallel one with cheap lookups.--- Internally, this is done by writing the vector to memory.-toPar :: (NaturalT n, Storable a) => (t n :>> Data a) -> VectorP n a-toPar vec = unfreezeVector (length vec) $ freezeVector vec+        l1   = externalize $ exprToData $ Get31 inp+        l2s  = externalize $ exprToData $ Get32 inp+        a    = externalize $ exprToData $ Get33 inp+        l2sV = unfreezeVector l1 l2s    -- * Operations --- | Look up an index in a vector. This operation takes linear time for--- sequential vectors.-index :: (t :>> a) -> Data Ix -> a-index (Indexed _ ixf)   i = ixf i-index (Unfold _ step s) i = fst $ step $ fst $ while cont body (s,0)-  where-    cont = (<i) . snd-    body = ((snd . step) *** (+1))--instance RandomAccess (Par n :>> a)+instance RandomAccess (Vector a)   where-    type Elem (Par n :>> a) = a+    type Element (Vector a) = a     (!) = index   --- | The dynamic size of a vector-length :: (t n :>> a) -> Data Size-length (Indexed sz _)   = sz-length (Unfold  sz _ _) = sz----(++) :: Computable a => (t m :>> a) -> (t n :>> a) -> (t (m :+ n) :>> a)--Indexed sz1 ixf1 ++ Indexed sz2 ixf2 = Indexed (sz1+sz2) ixf-  where-    ixf i = ifThenElse (i < sz1) ixf1 (ixf2 . subtract sz1) i--Unfold sz1 step1 s1 ++ Unfold sz2 step2 s2 = Unfold (sz1+sz2) step (0, (s1,s2))+-- | Introduces an 'ifThenElse' for each element; use with care!+(++) :: Computable a => Vector a -> Vector a -> Vector a+Indexed l1 ixf1 ++ Indexed l2 ixf2 = Indexed (l1+l2) ixf   where-    step (n, (s1',s2')) = n<sz1 ?-      ( let (a,s1'') = step1 s1' in (a, (n+1, (s1'', s2')))-      , let (a,s2'') = step2 s2' in (a, (n+1, (s1', s2'')))-      )+    ixf i = ifThenElse (i < l1) ixf1 (ixf2 . subtract l1) i  infixr 5 ++ ---take :: Data Int -> (t n :>> a) -> (t n :>> a)--take n (Indexed sz ixf) = Indexed sz' ixf-  where-    sz' = min sz n--take n (Unfold sz step s) = Unfold sz' step s-  where-    sz' = min sz n----drop :: Data Int -> (t n :>> a) -> (t n :>> a)--drop n (Indexed sz ixf) = Indexed sz' (\x -> ixf (x+n))-  where-    sz' = max 0 (sz-n)--drop n (Unfold sz step s) = Unfold sz' step s'-  where-    sz' = max 0 (sz-n)-    s'  = for 0 (n-1) s (\_ -> snd . step)--+take :: Data Int -> Vector a -> Vector a+take n (Indexed l ixf) = Indexed (minX n l) ixf -dropWhile :: (a -> Data Bool) -> (t n :>> a) -> (t n :>> a)+drop :: Data Int -> Vector a -> Vector a+drop n (Indexed l ixf) = Indexed (maxX 0 (l-n)) (\x -> ixf (x+n)) -dropWhile cont vec@(Indexed _ _) = drop i vec+dropWhile :: (a -> Data Bool) -> Vector a -> Vector a+dropWhile cont vec = drop i vec   where     i = while ((< length vec) &&* (cont . (vec !))) (+1) 0 -dropWhile cont vec@(Unfold sz step s) = Unfold (sz-i) step s'-  where-    (s',i) = while condition (\(s,i) -> (snd $ step s, i+1)) (s,0)-      where-        condition = ((\(s,i) -> i <= length vec) &&* (cont.fst.step.fst))----splitAt :: Data Int -> (t n :>> a) -> (t n :>> a, t n :>> a)+splitAt :: Data Int -> Vector a -> (Vector a, Vector a) splitAt n vec = (take n vec, drop n vec) -head :: (t n :>> a) -> a-head = flip index 0+head :: Vector a -> a+head = (!0) -last :: (t n :>> a) -> a-last vec = index vec (length vec - 1)+last :: Vector a -> a+last vec = vec ! (length vec - 1) -tail :: (t n :>> a) -> (t n :>> a)+tail :: Vector a -> Vector a tail = drop 1 -init :: (t n :>> a) -> (t n :>> a)+init :: Vector a -> Vector a init vec = take (length vec - 1) vec --- | Like Haskell's 'tails', but does not include the empty vector. This is--- actually just to make the types simpler (the result is square).-tails :: AccessPattern u => (t n :>> a) -> (u n :>> t n :>> a)-tails vec = genericVector vecP vecS-  where-    sz   = length vec-    vecP = Indexed sz (\n -> drop n vec)-    vecS = Unfold sz (\n -> (drop n vec, n+1)) 0+tails :: Vector a -> Vector (Vector a)+tails vec = Indexed (length vec + 1) (\n -> drop n vec) --- | Like Haskell's 'inits', but does not include the empty vector. This is--- actually just to make the types simpler (the result is square).-inits :: AccessPattern u => (t n :>> a) -> (u n :>> t n :>> a)-inits vec = genericVector vecP vecS-  where-    sz   = length vec-    vecP = Indexed sz (\n -> take n vec)-    vecS = Unfold sz (\n -> (take n vec, n+1)) 0+inits :: Vector a -> Vector (Vector a)+inits vec = Indexed (length vec + 1) (\n -> take n vec) -permute :: (Data Size -> Data Ix -> Data Ix) -> ((Par n :>> a) -> (Par n :>> a))-permute perm (Indexed sz ixf) = Indexed sz (ixf . perm sz)+inits1 :: Vector a -> Vector (Vector a)+inits1 = tail . inits -reverse :: (Par n :>> a) -> (Par n :>> a)-reverse = permute $ \sz i -> sz-1-i+permute :: (Data Length -> Data Ix -> Data Ix) -> (Vector a -> Vector a)+permute perm (Indexed l ixf) = Indexed l (ixf . perm l) -replicate :: AccessPattern t => Data Int -> a -> (t n :>> a)-replicate n a = genericVector vecP vecS-  where-    vecP = Indexed n (const a)-    vecS = Unfold n (const (a, unit)) unit+reverse :: Vector a -> Vector a+reverse = permute $ \l i -> l-1-i -enumFromTo :: AccessPattern t => Data Int -> Data Int -> (t n :>> Data Int)-enumFromTo m n = genericVector vecP vecS-  where-    sz   = n-m+1-    vecP = indexed sz (+m)-    vecS = unfold sz (\x -> (x,x+1)) m+replicate :: Data Int -> a -> Vector a+replicate n a = Indexed n (const a) +enumFromTo :: Data Int -> Data Int -> Vector (Data Int)+enumFromTo m n = Indexed (n-m+1) (+m)+  -- XXX Type should be generalized. +(...) :: Data Int -> Data Int -> Vector (Data Int)+(...) = enumFromTo -zip :: (t n :>> a) -> (t n :>> b) -> (t n :>> (a,b))+zip :: Vector a -> Vector b -> Vector (a,b)+zip (Indexed l1 ixf1) (Indexed l2 ixf2) = Indexed (min l1 l2) (ixf1 &&& ixf2) -zip (Indexed sz1 ixf1) (Indexed sz2 ixf2) =-    Indexed (min sz1 sz2) (ixf1 &&& ixf2)+unzip :: Vector (a,b) -> (Vector a, Vector b)+unzip (Indexed l ixf) = (Indexed l (fst.ixf), Indexed l (snd.ixf)) -zip (Unfold sz1 step1 s1) (Unfold sz2 step2 s2) = Unfold sz step (s1, s2)-  where-    sz = min sz1 sz2-    step (s1,s2) = ((a,b), (s1',s2'))-      where-        (a,s1') = step1 s1-        (b,s2') = step2 s2+map :: (a -> b) -> Vector a -> Vector b+map f (Indexed l ixf) = Indexed l (f . ixf) +zipWith :: (a -> b -> c) -> Vector a -> Vector b -> Vector c+zipWith f aVec bVec = map (uncurry f) $ zip aVec bVec +-- | Corresponds to 'foldl'.+fold :: Computable a => (a -> b -> a) -> a -> Vector b -> a+fold f x (Indexed l ixf) = for 0 (l-1) x (\i s -> f s (ixf i)) -unzip :: (t n :>> (a,b)) -> (t n :>> a, t n :>> b)+-- | Corresponds to 'foldl1'.+fold1 :: Computable a => (a -> a -> a) -> Vector a -> a+fold1 f a = fold f (head a) a -unzip (Indexed sz ixf) = (Indexed sz (fst.ixf), Indexed sz (snd.ixf)) -unzip (Unfold sz step s) =-    (Unfold sz ((fst***id).step) s, Unfold sz ((snd***id).step) s) +-- | Like 'unfoldCore', but for symbolic vectors. The output elements are stored+-- in a core vector.+unfoldVec+    :: (Computable state, Storable a)+    => Data Length+    -> state+    -> (Data Int -> state -> (Data a, state))+    -> (Vector (Data a), state) +unfoldVec l init step = (unfreezeVector l arr, final)+  where+    (arr,final) = unfoldCore l init step -map :: (a -> b) -> ((t n :>> a) -> (t n :>> b))-map f (Indexed sz ixf)   = Indexed sz (f . ixf)-map f (Unfold sz step s) = Unfold sz ((f *** id) . step) s -zipWith :: (a -> b -> c) -> (t n :>> a) -> (t n :>> b) -> (t n :>> c)-zipWith f aVec bVec = map (uncurry f) $ zip aVec bVec +-- | Somewhat similar to Haskell's 'Data.List.unfoldr'. The output elements are+-- stored in a core vector.+--+-- @`unfold` l init step@:+--+--   * @l@ is the length of the resulting vector.+--+--   * @init@ is the initial state.+--+--   * @step@ is a function computing a new element and the next state from the+--     current state.+unfold :: (Computable state, Storable a) =>+    Data Length -> state -> (state -> (Data a, state)) -> Vector (Data a) +unfold l init = fst . unfoldVec l init . const --- | Corresponds to Haskell's @foldl@.-fold :: Computable a => (a -> b -> a) -> a -> (t n :>> b) -> a -fold f x (Unfold sz step s) = fst $ for 0 (sz-1) (x,s) body-  where-    body i (m,n) = (f m m', n')-      where-        (m',n') = step n -fold f x (Indexed sz ixf) = for 0 (sz-1) x (\i s -> f s (ixf i))--+-- | Corresponds to 'scanl'. The output elements are stored in a core vector.+scan :: (Storable a, Computable b) =>+    (Data a -> b -> Data a) -> Data a -> Vector b -> Vector (Data a) --- | Corresponds to Haskell's @foldl1@.-fold1 :: Computable a => (a -> a -> a) -> (t n :>> a) -> a-fold1 f a = fold f (head a) a+scan f a vec = fst $ unfoldVec (length vec + 1) a $ \i a -> (a, f a (vec!i))   --- | Corresponds to Haskell's @scanl@.-scan :: Computable a => (a -> b -> a) -> a -> (t n :>> b) -> (Seq n :>> a)--scan f a (Indexed sz ixf) = Unfold sz step (0,a)-  where-    step (i,a) = let a' = f a (ixf i) in (a', (i+1, a'))+-- | Corresponds to 'Data.List.mapAccumL'. The output elements are stored in a+-- core vector.+mapAccum :: (Storable a, Computable acc, Storable b)+    => (acc -> Data a -> (acc, Data b))+    -> acc -> Vector (Data a) -> (acc, Vector (Data b)) -scan f a (Unfold sz step s) = Unfold sz step' (s,a)+mapAccum f init vecA = (final,vecB)   where-    step' (s,a) = (a', (s',a'))-      where-        (b,s') = step s-        a'     = f a b+    (vecB,final) = unfoldVec (length vecA) init $ \i acc ->+      let (acc',b) = f acc (vecA!i) in (b,acc')   --- | Corresponds to Haskell's @scanl1@.-scan1 :: Computable a => (a -> a -> a) -> (t n :>> a) -> (Seq n :>> a)-scan1 f vec = scan f (head vec) (tail vec)--sum :: (Num a, Computable a) => (t n :>> a) -> a+sum :: (Num a, Computable a) => Vector a -> a sum = fold (+) 0 -maximum :: Storable a => (t n :>> Data a) -> Data a+maximum :: Storable a => Vector (Data a) -> Data a maximum = fold1 max -minimum :: Storable a => (t n :>> Data a) -> Data a+minimum :: Storable a => Vector (Data a) -> Data a minimum = fold1 min -- -- | Scalar product of two vectors-scalarProd :: (Primitive a, Num a) =>-    (t n :>> Data a) -> (t n :>> Data a) -> Data a-+scalarProd :: Numeric a => Vector (Data a) -> Vector (Data a) -> Data a scalarProd a b = sum (zipWith (*) a b) 
LICENSE view
@@ -1,4 +1,4 @@-Copyright (c) 2009, ERICSSON AB+Copyright (c) 2009-2010, ERICSSON AB All rights reserved.  Redistribution and use in source and binary forms, with or without
feldspar-language.cabal view
@@ -1,12 +1,12 @@ name:           feldspar-language-version:        0.1+version:        0.2 synopsis:       A functional embedded language for DSP and parallelism description:    Feldspar (Functional Embedded Language for DSP and PARallelism)                 is an embedded DSL for describing digital signal processing                 algorithms. This package contains the language front-end and an                 interpreter. category:       Language-copyright:      Copyright (c) 2009, ERICSSON AB+copyright:      Copyright (c) 2009-2010, ERICSSON AB author:         Functional programming group at Chalmers University of Technology maintainer:     Emil Axelsson <emax@chalmers.se> license:        BSD3@@ -21,32 +21,35 @@   exposed-modules:     Feldspar.Prelude     Feldspar.Utils+    Feldspar.Haskell+    Feldspar.Range     Feldspar.Core.Types-    Feldspar.Core.Haskell-    Feldspar.Core.Graph-    Feldspar.Core.Show     Feldspar.Core.Ref     Feldspar.Core.Expr+    Feldspar.Core.Graph+    Feldspar.Core.Show+    Feldspar.Core.Reify     Feldspar.Core.Functions     Feldspar.Core     Feldspar.Vector     Feldspar.Matrix     Feldspar -  build-depends: base >= 3 && < 4, containers, directory, mtl, process, tfp+  build-depends:+    base >= 3 && < 4,+    containers,+    mtl,+    QuickCheck >= 1.2 && < 2    extensions:-    EmptyDataDecls     FlexibleInstances     FlexibleContexts     GADTs-    MultiParamTypeClasses     NoMonomorphismRestriction     OverlappingInstances     PatternGuards     Rank2Types     ScopedTypeVariables-    StandaloneDeriving     TypeFamilies     TypeOperators     TypeSynonymInstances