feldspar-language-0.6.0.2: A functional embedded language for DSP and parallelism

Safe Haskell | Safe-Inferred

Feldspar.Range

Contents

- Definition
- Lattice operations
- Propagation
- Products of ranges

Description

Bounded integer ranges

Synopsis

- data Range a = Range {
  - lowerBound :: a
  - upperBound :: a
  }
- class (Ord a, Num a, Bounded a, Integral a, Bits a) => BoundedInt a
- handleSign :: forall a b. BoundedInt a => (Range a -> b) -> (Range a -> b) -> Range a -> b
- showBound :: (Show a, BoundedInt a) => a -> String
- showRange :: (Show a, BoundedInt a) => Range a -> String
- mapMonotonic :: (a -> b) -> Range a -> Range b
- mapMonotonic2 :: (a -> b -> c) -> Range a -> Range b -> Range c
- emptyRange :: BoundedInt a => Range a
- fullRange :: BoundedInt a => Range a
- range :: Ord a => a -> a -> Range a
- singletonRange :: a -> Range a
- naturalRange :: BoundedInt a => Range a
- negativeRange :: forall a. BoundedInt a => Range a
- rangeSize :: BoundedInt a => Range a -> a
- isEmpty :: BoundedInt a => Range a -> Bool
- isFull :: BoundedInt a => Range a -> Bool
- isSingleton :: BoundedInt a => Range a -> Bool
- isSubRangeOf :: BoundedInt a => Range a -> Range a -> Bool
- isNatural :: BoundedInt a => Range a -> Bool
- isNegative :: BoundedInt a => Range a -> Bool
- inRange :: BoundedInt a => a -> Range a -> Bool
- rangeOp :: BoundedInt a => (Range a -> Range a) -> Range a -> Range a
- rangeOp2 :: BoundedInt a => (Range a -> Range a -> Range a) -> Range a -> Range a -> Range a
- rangeUnion :: BoundedInt a => Range a -> Range a -> Range a
- rangeIntersection :: BoundedInt a => Range a -> Range a -> Range a
- disjoint :: BoundedInt a => Range a -> Range a -> Bool
- rangeGap :: BoundedInt a => Range a -> Range a -> Range a
- rangeLess :: BoundedInt a => Range a -> Range a -> Bool
- rangeLessEq :: BoundedInt a => Range a -> Range a -> Bool
- rangeByRange :: BoundedInt a => Range a -> Range a -> Range a
- rangeAbs :: BoundedInt a => Range a -> Range a
- rangeSignum :: BoundedInt a => Range a -> Range a
- rangeSignumSigned :: BoundedInt a => Range a -> Range a
- rangeSignumUnsigned :: BoundedInt a => Range a -> Range a
- rangeNeg :: BoundedInt a => Range a -> Range a
- rangeNegUnsigned :: BoundedInt a => Range a -> Range a
- rangeNegSigned :: BoundedInt a => Range a -> Range a
- rangeAdd :: BoundedInt a => Range a -> Range a -> Range a
- rangeAddUnsigned :: BoundedInt a => Range a -> Range a -> Range a
- rangeAddSigned :: BoundedInt a => Range a -> Range a -> Range a
- rangeSub :: BoundedInt a => Range a -> Range a -> Range a
- rangeSubUnsigned :: BoundedInt a => Range a -> Range a -> Range a
- rangeSubSigned :: BoundedInt a => Range a -> Range a -> Range a
- subSat :: BoundedInt a => a -> a -> a
- rangeSubSat :: BoundedInt a => Range a -> Range a -> Range a
- rangeMul :: BoundedInt a => Range a -> Range a -> Range a
- rangeMulSigned :: forall a. BoundedInt a => Range a -> Range a -> Range a
- rangeMulUnsigned :: forall a. BoundedInt a => Range a -> Range a -> Range a
- bits :: (Num b, Bits b) => b -> Int
- rangeExp :: BoundedInt a => Range a -> Range a -> Range a
- rangeExpUnsigned :: BoundedInt a => Range a -> Range a -> Range a
- rangeExpSigned :: BoundedInt a => Range a -> Range a -> Range a
- rangeOr :: forall a. BoundedInt a => Range a -> Range a -> Range a
- rangeOrUnsignedCheap :: BoundedInt a => Range a -> Range a -> Range a
- maxPlus :: BoundedInt a => a -> a -> a
- minOrUnsigned :: BoundedInt a => a -> a -> a -> a -> a
- maxOrUnsigned :: BoundedInt a => a -> a -> a -> a -> a
- rangeOrUnsignedAccurate :: BoundedInt a => Range a -> Range a -> Range a
- rangeAnd :: forall a. BoundedInt a => Range a -> Range a -> Range a
- rangeAndUnsignedCheap :: BoundedInt a => Range a -> Range a -> Range a
- rangeXor :: forall a. BoundedInt a => Range a -> Range a -> Range a
- rangeXorUnsigned :: BoundedInt a => Range a -> Range a -> Range a
- rangeShiftLU :: (BoundedInt a, BoundedInt b) => Range a -> Range b -> Range a
- rangeShiftLUUnsigned :: (Bounded a, Bits a, Integral a, Integral b) => Range a -> Range b -> Range a
- rangeShiftRU :: (BoundedInt a, BoundedInt b) => Range a -> Range b -> Range a
- rangeShiftRUUnsigned :: (Num a, Bits a, Ord a, Bounded b, Integral b, Bits b) => Range a -> Range b -> Range a
- correctShiftRU :: (Num a, Bits a, BoundedInt b) => a -> b -> a
- rangeComplement :: (Bits a, BoundedInt a) => Range a -> Range a
- rangeMax :: BoundedInt a => Range a -> Range a -> Range a
- rangeMin :: BoundedInt a => Range a -> Range a -> Range a
- rangeMod :: BoundedInt a => Range a -> Range a -> Range a
- rangeRem :: BoundedInt a => Range a -> Range a -> Range a
- predAbs :: (Bounded a, Eq a, Num a, Enum a) => a -> a
- rangeDiv :: BoundedInt a => Range a -> Range a -> Range a
- rangeDivU :: BoundedInt a => Range a -> Range a -> Range a
- rangeQuot :: BoundedInt a => Range a -> Range a -> Range a
- rangeQuotU :: BoundedInt a => Range a -> Range a -> Range a
- rangeLessAbs :: (Bounded a, Integral a, Bits a) => Range a -> Range a -> Bool
- absRangeLessAbs :: (Bounded a, Integral a, Bits a) => Range a -> Range a -> Bool
- liftR :: (BoundedInt b, BoundedInt c, BoundedInt d) => (forall a. BoundedInt a => Range a) -> (Range b, Range c, Range d)
- binopR :: (BoundedInt a, BoundedInt b, BoundedInt c) => (forall d. BoundedInt d => Range d -> Range d -> Range d) -> (Range a, Range b, Range c) -> (Range a, Range b, Range c) -> (Range a, Range b, Range c)
- mapR :: (BoundedInt a, BoundedInt b, BoundedInt c) => (forall d. BoundedInt d => Range d -> Range d) -> (Range a, Range b, Range c) -> (Range a, Range b, Range c)
- approx :: (BoundedInt a, BoundedInt b, BoundedInt c, BoundedInt d) => (Range a, Range b, Range c) -> Range d

# Definition

data Range a

A bounded range of values of type `a`

Constructors

Range |

Fields

lowerBound :: a
upperBound :: a

Instances

Eq a => Eq (Range a) |
BoundedInt a => Num (Range a) | Implements `fromInteger` as a `singletonRange`, and implements correct range propagation for arithmetic operations.
BoundedInt a => Ord (Range a) |
Show a => Show (Range a) |
BoundedInt a => Lattice (Range a) |
(BoundedInt a, BoundedInt b, BoundedInt c) => Num (Range a, Range b, Range c) |

class (Ord a, Num a, Bounded a, Integral a, Bits a) => BoundedInt a

Convenience alias for bounded integers

Instances

(Ord a, Num a, Bounded a, Integral a, Bits a) => BoundedInt a |

handleSign :: forall a b. BoundedInt a => (Range a -> b) -> (Range a -> b) -> Range a -> b

A convenience function for defining range propagation. `handleSign propU propS` chooses `propU` for unsigned types and `propS` for signed types.

showBound :: (Show a, BoundedInt a) => a -> String

Shows a bound.

showRange :: (Show a, BoundedInt a) => Range a -> String

A textual representation of ranges.

mapMonotonic :: (a -> b) -> Range a -> Range b

Requires a monotonic function

mapMonotonic2 :: (a -> b -> c) -> Range a -> Range b -> Range c

Requires a monotonic function

# Lattice operations

emptyRange :: BoundedInt a => Range a

The range containing no elements

fullRange :: BoundedInt a => Range a

The range containing all elements of a type

range :: Ord a => a -> a -> Range a

Construct a range

singletonRange :: a -> Range a

The range containing one element

naturalRange :: BoundedInt a => Range a

The range from `0` to the maximum element

negativeRange :: forall a. BoundedInt a => Range a

The range from the smallest negative element to `-1`. Undefined for unsigned types

rangeSize :: BoundedInt a => Range a -> a

The size of a range. Beware that the size may not always be representable for signed types. For instance `rangeSize (range minBound maxBound) :: Int` gives a nonsense answer.

isEmpty :: BoundedInt a => Range a -> Bool

Checks if the range is empty

isFull :: BoundedInt a => Range a -> Bool

Checks if the range contains all values of the type

isSingleton :: BoundedInt a => Range a -> Bool

Checks is the range contains exactly one element

isSubRangeOf :: BoundedInt a => Range a -> Range a -> Bool

`r1 `isSubRangeOf` r2` checks is all the elements in `r1` are included in `r2`

isNatural :: BoundedInt a => Range a -> Bool

Checks whether a range is a sub-range of the natural numbers.

isNegative :: BoundedInt a => Range a -> Bool

Checks whether a range is a sub-range of the negative numbers.

inRange :: BoundedInt a => a -> Range a -> Bool

`a `inRange` r` checks is `a` is an element of the range `r`.

rangeOp :: BoundedInt a => (Range a -> Range a) -> Range a -> Range a

A convenience function for defining range propagation. If the input range is empty then the result is also empty.

rangeOp2 :: BoundedInt a => (Range a -> Range a -> Range a) -> Range a -> Range a -> Range a

See `rangeOp`.

rangeUnion :: BoundedInt a => Range a -> Range a -> Range a

Union on ranges.

rangeIntersection :: BoundedInt a => Range a -> Range a -> Range a

Intersection on ranges.

disjoint :: BoundedInt a => Range a -> Range a -> Bool

`disjoint r1 r2` returns true when `r1` and `r2` have no elements in common.

rangeGap :: BoundedInt a => Range a -> Range a -> Range a

`rangeGap r1 r2` returns a range of all the elements between `r1` and `r2` including the boundary elements. If `r1` and `r2` have elements in common the result is an empty range.

rangeLess :: BoundedInt a => Range a -> Range a -> Bool

    r1 `rangeLess` r2:

Checks if all elements of `r1` are less than all elements of `r2`.

rangeLessEq :: BoundedInt a => Range a -> Range a -> Bool

    r1 `rangeLessEq` r2:

Checks if all elements of `r1` are less than or equal to all elements of `r2`.

# Propagation

rangeByRange :: BoundedInt a => Range a -> Range a -> Range a

`rangeByRange ra rb`: Computes the range of the following set

     {x | a <- ra, b <- rb, x <- Range a b}

rangeAbs :: BoundedInt a => Range a -> Range a

Propagates range information through `abs`.

rangeSignum :: BoundedInt a => Range a -> Range a

Propagates range information through `signum`.

rangeSignumSigned :: BoundedInt a => Range a -> Range a

Signed case for `rangeSignum`.

rangeSignumUnsigned :: BoundedInt a => Range a -> Range a

Unsigned case for `rangeSignum`.

rangeNeg :: BoundedInt a => Range a -> Range a

Propagates range information through negation.

rangeNegUnsigned :: BoundedInt a => Range a -> Range a

Unsigned case for `rangeNeg`.

rangeNegSigned :: BoundedInt a => Range a -> Range a

Signed case for `rangeNeg`.

rangeAdd :: BoundedInt a => Range a -> Range a -> Range a

Propagates range information through addition.

rangeAddUnsigned :: BoundedInt a => Range a -> Range a -> Range a

Unsigned case for `rangeAdd`.

rangeAddSigned :: BoundedInt a => Range a -> Range a -> Range a

Signed case for `rangeAdd`.

rangeSub :: BoundedInt a => Range a -> Range a -> Range a

Propagates range information through subtraction.

rangeSubUnsigned :: BoundedInt a => Range a -> Range a -> Range a

Unsigned case for `rangeSub`.

rangeSubSigned :: BoundedInt a => Range a -> Range a -> Range a

subSat :: BoundedInt a => a -> a -> a

Saturating unsigned subtraction

rangeSubSat :: BoundedInt a => Range a -> Range a -> Range a

Range propagation for `subSat`

rangeMul :: BoundedInt a => Range a -> Range a -> Range a

Propagates range information through multiplication

rangeMulSigned :: forall a. BoundedInt a => Range a -> Range a -> Range a

Signed case for `rangeMul`.

rangeMulUnsigned :: forall a. BoundedInt a => Range a -> Range a -> Range a

Unsigned case for `rangeMul`.

bits :: (Num b, Bits b) => b -> Int

Returns the position of the highest bit set to 1. Counting starts at 1. Beware! It doesn't terminate for negative numbers.

rangeExp :: BoundedInt a => Range a -> Range a -> Range a

Propagates range information through exponentiation.

rangeExpUnsigned :: BoundedInt a => Range a -> Range a -> Range a

Unsigned case for `rangeExp`.

rangeExpSigned :: BoundedInt a => Range a -> Range a -> Range a

Sigend case for `rangeExp`

rangeOr :: forall a. BoundedInt a => Range a -> Range a -> Range a

Propagates range information through `.|.`.

rangeOrUnsignedCheap :: BoundedInt a => Range a -> Range a -> Range a

Cheap and inaccurate range propagation for `.|.` on unsigned numbers.

maxPlus :: BoundedInt a => a -> a -> a

`a `maxPlus` b` adds `a` and `b` but if the addition overflows then `maxBound` is returned.

minOrUnsigned :: BoundedInt a => a -> a -> a -> a -> a

Accurate lower bound for `.|.` on unsigned numbers.

maxOrUnsigned :: BoundedInt a => a -> a -> a -> a -> a

Accurate upper bound for `.|.` on unsigned numbers.

rangeOrUnsignedAccurate :: BoundedInt a => Range a -> Range a -> Range a

Accurate range propagation through `.|.` for unsigned types.

rangeAnd :: forall a. BoundedInt a => Range a -> Range a -> Range a

Propagating range information through `.&.`.

rangeAndUnsignedCheap :: BoundedInt a => Range a -> Range a -> Range a

Cheap and inaccurate range propagation for `.&.` on unsigned numbers.

rangeXor :: forall a. BoundedInt a => Range a -> Range a -> Range a

Propagating range information through `xor`.

rangeXorUnsigned :: BoundedInt a => Range a -> Range a -> Range a

Unsigned case for `rangeXor`.

rangeShiftLU :: (BoundedInt a, BoundedInt b) => Range a -> Range b -> Range a

Propagating range information through `shiftLU`.

rangeShiftLUUnsigned :: (Bounded a, Bits a, Integral a, Integral b) => Range a -> Range b -> Range a

Unsigned case for `rangeShiftLU`.

rangeShiftRU :: (BoundedInt a, BoundedInt b) => Range a -> Range b -> Range a

Propagating range information through `shiftRU`.

rangeShiftRUUnsigned :: (Num a, Bits a, Ord a, Bounded b, Integral b, Bits b) => Range a -> Range b -> Range a

Unsigned case for `rangeShiftRU`.

correctShiftRU :: (Num a, Bits a, BoundedInt b) => a -> b -> a

This is a replacement fror Haskell's shiftR. If we carelessly use Haskell's variant then we will get left shifts for very large shift values.

rangeComplement :: (Bits a, BoundedInt a) => Range a -> Range a

Propagating range information through `complement`

rangeMax :: BoundedInt a => Range a -> Range a -> Range a

Propagates range information through `max`.

rangeMin :: BoundedInt a => Range a -> Range a -> Range a

Analogous to `rangeMax`

rangeMod :: BoundedInt a => Range a -> Range a -> Range a

Propagates range information through `mod`. Note that we assume Haskell semantics for `mod`.

rangeRem :: BoundedInt a => Range a -> Range a -> Range a

Propagates range information through `rem`. Note that we assume Haskell semantics for `rem`.

predAbs :: (Bounded a, Eq a, Num a, Enum a) => a -> a

rangeDiv :: BoundedInt a => Range a -> Range a -> Range a

Propagates range information through `div`

rangeDivU :: BoundedInt a => Range a -> Range a -> Range a

Unsigned case for `rangeDiv`

rangeQuot :: BoundedInt a => Range a -> Range a -> Range a

Propagates range information through `quot`.

rangeQuotU :: BoundedInt a => Range a -> Range a -> Range a

Unsigned case for `rangeQuot`.

rangeLessAbs :: (Bounded a, Integral a, Bits a) => Range a -> Range a -> Bool

Writing `d `rangeLess` abs r` doesn't mean what you think it does because `r` may contain minBound which doesn't have a positive representation. Instead, this function should be used.

absRangeLessAbs :: (Bounded a, Integral a, Bits a) => Range a -> Range a -> Bool

Similar to `rangeLessAbs` but replaces the expression `abs d `rangeLess` abs r` instead.

# Products of ranges

liftR :: (BoundedInt b, BoundedInt c, BoundedInt d) => (forall a. BoundedInt a => Range a) -> (Range b, Range c, Range d)

binopR :: (BoundedInt a, BoundedInt b, BoundedInt c) => (forall d. BoundedInt d => Range d -> Range d -> Range d) -> (Range a, Range b, Range c) -> (Range a, Range b, Range c) -> (Range a, Range b, Range c)

mapR :: (BoundedInt a, BoundedInt b, BoundedInt c) => (forall d. BoundedInt d => Range d -> Range d) -> (Range a, Range b, Range c) -> (Range a, Range b, Range c)

approx :: (BoundedInt a, BoundedInt b, BoundedInt c, BoundedInt d) => (Range a, Range b, Range c) -> Range d