Copyright | (c) Joel Burget Levent Erkok |
---|---|
License | BSD3 |
Maintainer | erkokl@gmail.com |
Stability | experimental |
Safe Haskell | None |
Language | Haskell2010 |
A collection of list utilities, useful when working with symbolic lists.
To the extent possible, the functions in this module follow those of Data.List
so importing qualified is the recommended workflow. Also, it is recommended
you use the OverloadedLists
extension to allow literal lists to
be used as symbolic-lists.
Synopsis
- length :: SymVal a => SList a -> SInteger
- null :: SymVal a => SList a -> SBool
- head :: SymVal a => SList a -> SBV a
- tail :: SymVal a => SList a -> SList a
- uncons :: SymVal a => SList a -> (SBV a, SList a)
- init :: SymVal a => SList a -> SList a
- singleton :: SymVal a => SBV a -> SList a
- listToListAt :: SymVal a => SList a -> SInteger -> SList a
- elemAt :: forall a. SymVal a => SList a -> SInteger -> SBV a
- (.!!) :: SymVal a => SList a -> SInteger -> SBV a
- implode :: SymVal a => [SBV a] -> SList a
- concat :: SymVal a => SList a -> SList a -> SList a
- (.:) :: SymVal a => SBV a -> SList a -> SList a
- snoc :: SymVal a => SList a -> SBV a -> SList a
- nil :: SymVal a => SList a
- (.++) :: SymVal a => SList a -> SList a -> SList a
- elem :: (Eq a, SymVal a) => SBV a -> SList a -> SBool
- notElem :: (Eq a, SymVal a) => SBV a -> SList a -> SBool
- isInfixOf :: (Eq a, SymVal a) => SList a -> SList a -> SBool
- isSuffixOf :: (Eq a, SymVal a) => SList a -> SList a -> SBool
- isPrefixOf :: (Eq a, SymVal a) => SList a -> SList a -> SBool
- take :: SymVal a => SInteger -> SList a -> SList a
- drop :: SymVal a => SInteger -> SList a -> SList a
- subList :: SymVal a => SList a -> SInteger -> SInteger -> SList a
- replace :: (Eq a, SymVal a) => SList a -> SList a -> SList a -> SList a
- indexOf :: (Eq a, SymVal a) => SList a -> SList a -> SInteger
- offsetIndexOf :: (Eq a, SymVal a) => SList a -> SList a -> SInteger -> SInteger
Length, emptiness
length :: SymVal a => SList a -> SInteger Source #
Length of a list.
>>>
sat $ \(l :: SList Word16) -> length l .== 2
Satisfiable. Model: s0 = [0,0] :: [Word16]>>>
sat $ \(l :: SList Word16) -> length l .< 0
Unsatisfiable>>>
prove $ \(l1 :: SList Word16) (l2 :: SList Word16) -> length l1 + length l2 .== length (l1 .++ l2)
Q.E.D.
null :: SymVal a => SList a -> SBool Source #
is True iff the list is emptynull
s
>>>
prove $ \(l :: SList Word16) -> null l .<=> length l .== 0
Q.E.D.>>>
prove $ \(l :: SList Word16) -> null l .<=> l .== []
Q.E.D.
Deconstructing/Reconstructing
head :: SymVal a => SList a -> SBV a Source #
returns the first element of a list. Unspecified if the list is empty.head
>>>
prove $ \c -> head (singleton c) .== (c :: SInteger)
Q.E.D.
tail :: SymVal a => SList a -> SList a Source #
returns the tail of a list. Unspecified if the list is empty.tail
>>>
prove $ \(h :: SInteger) t -> tail (singleton h .++ t) .== t
Q.E.D.>>>
prove $ \(l :: SList Integer) -> length l .> 0 .=> length (tail l) .== length l - 1
Q.E.D.>>>
prove $ \(l :: SList Integer) -> sNot (null l) .=> singleton (head l) .++ tail l .== l
Q.E.D.
uncons :: SymVal a => SList a -> (SBV a, SList a) Source #
@uncons
returns the pair of the head and tail. Unspecified if the list is empty.
init :: SymVal a => SList a -> SList a Source #
returns all but the last element of the list. Unspecified if the list is empty.init
>>>
prove $ \(h :: SInteger) t -> init (t .++ singleton h) .== t
Q.E.D.
singleton :: SymVal a => SBV a -> SList a Source #
is the list of length 1 that contains the only value singleton
xx
.
>>>
prove $ \(x :: SInteger) -> head (singleton x) .== x
Q.E.D.>>>
prove $ \(x :: SInteger) -> length (singleton x) .== 1
Q.E.D.
listToListAt :: SymVal a => SList a -> SInteger -> SList a Source #
. List of length 1 at listToListAt
l offsetoffset
in l
. Unspecified if
index is out of bounds.
>>>
prove $ \(l1 :: SList Integer) l2 -> listToListAt (l1 .++ l2) (length l1) .== listToListAt l2 0
Q.E.D.>>>
sat $ \(l :: SList Word16) -> length l .>= 2 .&& listToListAt l 0 ./= listToListAt l (length l - 1)
Satisfiable. Model: s0 = [0,0,2] :: [Word16]
elemAt :: forall a. SymVal a => SList a -> SInteger -> SBV a Source #
is the value stored at location elemAt
l ii
. Unspecified if
index is out of bounds.
>>>
prove $ \i -> i `inRange` (0, 4) .=> [1,1,1,1,1] `elemAt` i .== (1::SInteger)
Q.E.D.>>>
prove $ \(l :: SList Integer) i e -> i `inRange` (0, length l - 1) .&& l `elemAt` i .== e .=> indexOf l (singleton e) .<= i
Q.E.D.
implode :: SymVal a => [SBV a] -> SList a Source #
is the list of length implode
es|es|
containing precisely those
elements. Note that there is no corresponding function explode
, since
we wouldn't know the length of a symbolic list.
>>>
prove $ \(e1 :: SInteger) e2 e3 -> length (implode [e1, e2, e3]) .== 3
Q.E.D.>>>
prove $ \(e1 :: SInteger) e2 e3 -> map (elemAt (implode [e1, e2, e3])) (map literal [0 .. 2]) .== [e1, e2, e3]
Q.E.D.
(.:) :: SymVal a => SBV a -> SList a -> SList a infixr 5 Source #
Prepend an element, the traditional cons
.
nil :: SymVal a => SList a Source #
Empty list. This value has the property that it's the only list with length 0:
>>>
prove $ \(l :: SList Integer) -> length l .== 0 .<=> l .== nil
Q.E.D.
(.++) :: SymVal a => SList a -> SList a -> SList a infixr 5 Source #
Short cut for concat
.
>>>
sat $ \x y z -> length x .== 5 .&& length y .== 1 .&& x .++ y .++ z .== [1 .. 12]
Satisfiable. Model: s0 = [1,2,3,4,5] :: [Integer] s1 = [6] :: [Integer] s2 = [7,8,9,10,11,12] :: [Integer]
Containment
elem :: (Eq a, SymVal a) => SBV a -> SList a -> SBool Source #
. Does elem
e ll
contain the element e
?
notElem :: (Eq a, SymVal a) => SBV a -> SList a -> SBool Source #
. Does notElem
e ll
not contain the element e
?
isInfixOf :: (Eq a, SymVal a) => SList a -> SList a -> SBool Source #
. Does isInfixOf
sub ll
contain the subsequence sub
?
>>>
prove $ \(l1 :: SList Integer) l2 l3 -> l2 `isInfixOf` (l1 .++ l2 .++ l3)
Q.E.D.>>>
prove $ \(l1 :: SList Integer) l2 -> l1 `isInfixOf` l2 .&& l2 `isInfixOf` l1 .<=> l1 .== l2
Q.E.D.
isSuffixOf :: (Eq a, SymVal a) => SList a -> SList a -> SBool Source #
. Is isSuffixOf
suf lsuf
a suffix of l
?
>>>
prove $ \(l1 :: SList Word16) l2 -> l2 `isSuffixOf` (l1 .++ l2)
Q.E.D.>>>
prove $ \(l1 :: SList Word16) l2 -> l1 `isSuffixOf` l2 .=> subList l2 (length l2 - length l1) (length l1) .== l1
Q.E.D.
isPrefixOf :: (Eq a, SymVal a) => SList a -> SList a -> SBool Source #
. Is isPrefixOf
pre lpre
a prefix of l
?
>>>
prove $ \(l1 :: SList Integer) l2 -> l1 `isPrefixOf` (l1 .++ l2)
Q.E.D.>>>
prove $ \(l1 :: SList Integer) l2 -> l1 `isPrefixOf` l2 .=> subList l2 0 (length l1) .== l1
Q.E.D.
Sublists
subList :: SymVal a => SList a -> SInteger -> SInteger -> SList a Source #
is the sublist of subList
s offset lens
at offset offset
with length len
.
This function is under-specified when the offset is outside the range of positions in s
or len
is negative or offset+len
exceeds the length of s
.
>>>
prove $ \(l :: SList Integer) i -> i .>= 0 .&& i .< length l .=> subList l 0 i .++ subList l i (length l - i) .== l
Q.E.D.>>>
sat $ \i j -> subList [1..5] i j .== ([2..4] :: SList Integer)
Satisfiable. Model: s0 = 1 :: Integer s1 = 3 :: Integer>>>
sat $ \i j -> subList [1..5] i j .== ([6..7] :: SList Integer)
Unsatisfiable
replace :: (Eq a, SymVal a) => SList a -> SList a -> SList a -> SList a Source #
. Replace the first occurrence of replace
l src dstsrc
by dst
in s
>>>
prove $ \l -> replace [1..5] l [6..10] .== [6..10] .=> l .== ([1..5] :: SList Word8)
Q.E.D.>>>
prove $ \(l1 :: SList Integer) l2 l3 -> length l2 .> length l1 .=> replace l1 l2 l3 .== l1
Q.E.D.
indexOf :: (Eq a, SymVal a) => SList a -> SList a -> SInteger Source #
. Retrieves first position of indexOf
l subsub
in l
, -1
if there are no occurrences.
Equivalent to
.offsetIndexOf
l sub 0
>>>
prove $ \(l :: SList Int8) i -> i .> 0 .&& i .< length l .=> indexOf l (subList l i 1) .<= i
Q.E.D.>>>
prove $ \(l1 :: SList Word16) l2 -> length l2 .> length l1 .=> indexOf l1 l2 .== -1
Q.E.D.
offsetIndexOf :: (Eq a, SymVal a) => SList a -> SList a -> SInteger -> SInteger Source #
. Retrieves first position of offsetIndexOf
l sub offsetsub
at or
after offset
in l
, -1
if there are no occurrences.
>>>
prove $ \(l :: SList Int8) sub -> offsetIndexOf l sub 0 .== indexOf l sub
Q.E.D.>>>
prove $ \(l :: SList Int8) sub i -> i .>= length l .&& length sub .> 0 .=> offsetIndexOf l sub i .== -1
Q.E.D.>>>
prove $ \(l :: SList Int8) sub i -> i .> length l .=> offsetIndexOf l sub i .== -1
Q.E.D.