ChasingBottoms: For testing partial and infinite values.
Do you ever feel the need to test code involving bottoms (e.g. calls to
the error
function), or code involving infinite values? Then this
library could be useful for you.
It is usually easy to get a grip on bottoms by showing a value and waiting to see how much gets printed before the first exception is encountered. However, that quickly gets tiresome and is hard to automate using e.g. QuickCheck (http://www.cse.chalmers.se/~rjmh/QuickCheck/). With this library you can do the tests as simply as the following examples show.
Testing explicitly for bottoms:
> isBottom (head []) True
> isBottom bottom True
> isBottom (\_ -> bottom) False
> isBottom (bottom, bottom) False
Comparing finite, partial values:
> ((bottom, 3) :: (Bool, Int)) ==! (bottom, 2+5-4) True
> ((bottom, bottom) :: (Bool, Int)) <! (bottom, 8) True
Showing partial and infinite values (\/!
is join and /\!
is meet):
> approxShow 4 $ (True, bottom) \/! (bottom, 'b') "Just (True, 'b')"
> approxShow 4 $ (True, bottom) /\! (bottom, 'b') "(_|_, _|_)"
> approxShow 4 $ ([1..] :: [Int]) "[1, 2, 3, _"
> approxShow 4 $ (cycle [bottom] :: [Bool]) "[_|_, _|_, _|_, _"
Approximately comparing infinite, partial values:
> approx 100 [2,4..] ==! approx 100 (filter even [1..] :: [Int]) True
> approx 100 [2,4..] /=! approx 100 (filter even [bottom..] :: [Int]) True
The code above relies on the fact that bottom
, just as error
"..."
, undefined
and pattern match failures, yield
exceptions. Sometimes we are dealing with properly non-terminating
computations, such as the following example, and then it can be nice to
be able to apply a time-out:
> timeOut' 1 (reverse [1..5]) Value [5,4,3,2,1]
> timeOut' 1 (reverse [1..]) NonTermination
The time-out functionality can be used to treat "slow" computations as bottoms:
> let tweak = Tweak { approxDepth = Just 5, timeOutLimit = Just 2 } > semanticEq tweak (reverse [1..], [1..]) (bottom :: [Int], [1..] :: [Int]) True
> let tweak = noTweak { timeOutLimit = Just 2 } > semanticJoin tweak (reverse [1..], True) ([] :: [Int], bottom) Just ([],True)
This can of course be dangerous:
> let tweak = noTweak { timeOutLimit = Just 0 } > semanticEq tweak (reverse [1..100000000]) (bottom :: [Integer]) True
Timeouts can also be applied to IO
computations:
> let primes () = unfoldr (\(x:xs) -> Just (x, filter ((/= 0) . (`mod` x)) xs)) [2..] > timeOutMicro 100 (print $ primes ()) [2,NonTermination > timeOutMicro 10000 (print $ take 10 $ primes ()) [2,3,5,7,11,13,17,19,23,29] Value ()
For the underlying theory and a larger example involving use of QuickCheck, see the article "Chasing Bottoms, A Case Study in Program Verification in the Presence of Partial and Infinite Values" (http://www.cse.chalmers.se/~nad/publications/danielsson-jansson-mpc2004.html).
The code has been tested using GHC. Most parts can probably be
ported to other Haskell compilers, but this would require some work.
The TimeOut
functions require preemptive scheduling, and most of
the rest requires Data.Generics
; isBottom
only requires
exceptions, though.
Modules
[Index] [Quick Jump]
Downloads
- ChasingBottoms-1.3.1.15.tar.gz [browse] (Cabal source package)
- Package description (revised from the package)
Note: This package has metadata revisions in the cabal description newer than included in the tarball. To unpack the package including the revisions, use 'cabal get'.
Maintainer's Corner
For package maintainers and hackage trustees
Candidates
Versions [RSS] | 1.2.2, 1.2.4, 1.3.0, 1.3.0.1, 1.3.0.2, 1.3.0.3, 1.3.0.4, 1.3.0.5, 1.3.0.6, 1.3.0.7, 1.3.0.8, 1.3.0.9, 1.3.0.10, 1.3.0.11, 1.3.0.12, 1.3.0.13, 1.3.0.14, 1.3.1, 1.3.1.1, 1.3.1.2, 1.3.1.3, 1.3.1.4, 1.3.1.5, 1.3.1.6, 1.3.1.7, 1.3.1.8, 1.3.1.9, 1.3.1.10, 1.3.1.11, 1.3.1.12, 1.3.1.13, 1.3.1.14, 1.3.1.15 |
---|---|
Dependencies | base (>=4.2 && <4.22), containers (>=0.5 && <0.8), mtl (>=2 && <2.4), QuickCheck (>=2.10 && <2.16), random (>=1.0 && <1.3), syb (>=0.1.0.2 && <0.8) [details] |
Tested with | ghc ==8.0.2, ghc ==8.2.2, ghc ==8.4.4, ghc ==8.6.5, ghc ==8.8.4, ghc ==8.10.5, ghc ==9.0.2, ghc ==9.2.8, ghc ==9.4.8, ghc ==9.6.6, ghc ==9.8.2, ghc ==9.10.1 |
License | MIT |
Copyright | Copyright (c) Nils Anders Danielsson 2004-2022, 2024. |
Author | Nils Anders Danielsson |
Maintainer | http://www.cse.chalmers.se/~nad/ |
Revised | Revision 1 made by AndreasAbel at 2024-10-22T06:04:41Z |
Category | Testing |
Source repo | head: darcs get http://www.cse.chalmers.se/~nad/repos/ChasingBottoms/ |
Uploaded | by NilsAndersDanielsson at 2024-08-20T10:28:18Z |
Distributions | Arch:1.3.1.15, Debian:1.3.1.9, LTSHaskell:1.3.1.15, NixOS:1.3.1.14, Stackage:1.3.1.15 |
Reverse Dependencies | 2 direct, 0 indirect [details] |
Downloads | 34865 total (240 in the last 30 days) |
Rating | (no votes yet) [estimated by Bayesian average] |
Your Rating | |
Status | Docs available [build log] Last success reported on 2024-08-20 [all 1 reports] |