Using FsCheck I get different results on tests, once 100% passed and the other time error - testing

I created a generator to generate lists of int with the same lenght and to test the property of zip and unzip.
Running the test I get once in a while the error
Error: System.ArgumentException: list2 is 1 element shorter than list1
but it shouldn't happen because of my generator.
I got three times the test 100% passed and then the error above. Why?
It seems my generator is not working properly.
let samelength (x, y) =
List.length x = List.length y
let arbMyGen2 = Arb.filter samelength Arb.from<int list * int list>
type MyGenZ =
static member genZip() =
{
new Arbitrary<int list * int list>() with
override x.Generator = arbMyGen2 |> Arb.toGen
override x.Shrinker t = Seq.empty
}
let _ = Arb.register<MyGenZ>()
let pro_zip (xs: int list, ys: int list) =
(xs, ys) = List.unzip(List.zip xs ys)
|> Prop.collect (List.length xs = List.length ys)
do Check.Quick pro_zip

Your code, as written, works for me. So I'm not sure what exactly is wrong, but I can give you a few helpful (hopefully!) hints.
In the first instance, try not using the registrating mechanism, but instead using Prop.forAll, as follows:
let pro_zip =
Prop.forAll arbMyGen2 (fun (xs,ys) ->
(xs, ys) = List.unzip(List.zip xs ys)
|> Prop.collect (List.length xs))
do Check.Quick pro_zip
Note I've also changed your Prop.collect call to collect the length of the list(s), which gives somewhat more interesting output. In fact your property already checks that the lists are the same length (albeit implicitly) so the test will fail with a counterexample if they are not.
Arb.filter transforms an existing Arbitrary (i.e. generator and filter) to a new Arbitrary. In other words, arbMyGen2 has a shrinking function that'll work (i.e. only returns smaller pairs of lists that are of equal length), while in genZip() you throw the shrinker away. It would be fine to simply write
type MyGenZ =
static member genZip() = arbMyGen2
instead.

Related

Why are preconditions failing to work in this FsCheck example?

I am trying to use the FsCheck library. I can do some tests but preconditions do not seem to work. The code below provides an example:
let sortEven (xs: int list) =
xs
|> List.filter (fun x -> x % 2 = 0)
|> List.sort
let lengthGT0 (xs: int list) = (List.length xs) > 0
[<Property>]
let checkSortEven (xs: int list) =
lengthGT0 xs ==>
((xs |> sortEven |> List.sum) = (xs |> List.rev |> sortEven |> List.max))
Calling the function checkSortEven with an empty list as its argument generates an exception because List.rev does the same. So, in the code above, I tried to use a precondition, using the ==> operator, to prevent the FsCheck from trying empty lists. However, whether the first list tested is empty or a shrunk list is empty checkSortEven is called an exception is generated:
Falsifiable, after 1 test (0 shrinks) (StdGen (843297067,296354622)):
Original:
[]
with exception:
System.ArgumentException: The input sequence was empty.
Falsifiable, after 1 test (1 shrink) (StdGen (1296284131,296354622)):
Original:
[-1]
Shrunk:
[]
with exception:
System.ArgumentException: The input sequence was empty.
Falsifiable, after 1 test (2 shrinks) (StdGen (1865393009,296354622)):
Original:
[-1; 1]
Shrunk:
[]
with exception:
System.ArgumentException: The input sequence was empty.
There is a related question on SO at Why is my precondition being ignored on my Property-based test? but it seems to be a different case (nested functions).
I also tried Check.QuickThrowOnFailure instead of Check.Quick with basically the same results.
Any ideas on why preconditions are not working in this example?

Why does map throw away type information when operating on DataArrays?

I'm trying to understand why this is happening even given the limitations of DataArrays. Suppose you want to map over a DataArray of Int64s:
da = DataArray([1,2,3,4])
println(typeof(da))
println(typeof(map(a -> a^2, da))) # Returns an int for this input
println(typeof(map(a -> int(a^2), da))) # Cast the piecewise result to int
println(typeof(int(map(a -> a^2, da)))) # Cast the output DataArray{Any,1} to int
which results in
DataArray{Int64,1}
DataArray{Any,1}
DataArray{Any,1}
Array{Int64,1}
For an array, a = [1,2,3,4], map(a -> a^2, da) returns an Array of Int64s as expected. What is it about map and/or DataArrays that's causing type information to be lost here? Is there any solution to preserve type information when you're working with a type which doesn't have a constructor that converts DataArray{Any,1} to DataArray{ThatType,1}, like Dates.DateTime?
Edit: convert works fine to make a DataArray{Any,1} a DataArray{ThatType,1} (well at least for DateTime).
#which map(a -> a^2, da::DataArray{Int64, 1})
map(f::Function,dv::DataArray{T,1}) at /home/omer/.julia/v0.3/DataArrays/src/datavector.jl:114
Checking the source;
https://github.com/JuliaStats/DataArrays.jl/blob/master/src/datavector.jl
# TODO: should this be an AbstractDataVector, so it works with PDV's?
function Base.map(f::Function, dv::DataVector)
n = length(dv)
res = DataArray(Any, n)
for i in 1:n
res[i] = f(dv[i])
end
return res
end
It's creating the type DataArray{Any,1} to return.
res = DataArray(Any, n)
You can check the answer given by James Fairbanks (1 Apr 04:12 2015)
http://blog.gmane.org/gmane.comp.lang.julia.user/month=20150401

Generalizing functions in F#

I need a function that produces primes in F#. I found this:
let primesSeq =
let rec nextPrime n p primes =
if primes |> Map.containsKey n then
nextPrime (n + p) p primes
else
primes.Add(n, p)
let rec prime n primes =
seq {
if primes |> Map.containsKey n then
let p = primes.Item n
yield! prime (n + 1) (nextPrime (n + p) p (primes.Remove n))
else
yield n
yield! prime (n + 1) (primes.Add(n * n, n))
}
prime 2 Map.empty
This works very well, but sometimes I need to work with int64/BigInts as well. Is there a more clever way of reusing this code than providing another sequences like these:
let primesSeq64 = Seq.map int64 primesSeq
let primesBigInts = Seq.map (fun (x : int) -> BigInteger(x)) primesSeq
I've heard about modifying a code using "inline" and "LanguagePrimitives", but all I've found was connected with function while my problem is related to a value.
Moreover - I'd like to have a function that works with integer types and computes a floor of a square root.
let inline sqRoot arg = double >> Math.Sqrt >> ... ?
but I can't see a way of returning the same type as "arg" is, as Math.Sqrt returns a double. Again - is there anything better than reimplementing the logic that computes a square root by myself ?
So the general way to do this requires a function and languageprimitives - in your case everywhere you have 1 you write LanguagePrimitives.GenericOne which will produce 1 or 1.0 etc depending on what is required.
To get this to work, you need to create a function value - you can avoid this by doing something like:
let inline primesSeq() = ...
let primesintSeq = primesSeq() //if you use this as an int seq later the compiler will figure it out, otherwise you use
let specified : int seq = primesSeq()
I am not so sure about the sqrt case though - it probably depends on how hacky you are willing to make the solution.
A naïve implementation of generic sqRoot may go along these lines:
let sqRoot arg =
let inline sqrtd a = (double >> sqrt) a
let result = match box(arg) with
| :? int64 as i -> (sqrtd i) |> int64 |> box
| :? int as i -> (sqrtd i) |> int |> box
// cases for other relevant integral types
| _ -> failwith "Unsupported type"
unbox result
and then, checking in FSI:
> let result: int = sqRoot 4;;
val result : int = 2
> let result: int64 = sqRoot 9L;;
val result : int64 = 3L

Is there a way to get a Curried form of the binary operators in SML/NJ?

For example, instead of
- op =;
val it = fn : ''a * ''a -> bool
I would rather have
- op =;
val it = fn : ''a -> ''a -> bool
for use in
val x = getX()
val l = getList()
val l' = if List.exists ((op =) x) l then l else x::l
Obviously I can do this on my own, for example,
val l' = if List.exists (fn y => x = y) l then l else x::l
but I want to make sure I'm not missing a more elegant way.
You could write a helper function that curries a function:
fun curry f x y = f (x, y)
Then you can do something like
val curried_equals = curry (op =)
val l' = if List.exists (curried_equals x) l then l else x::l
My knowledge of SML is scant, but I looked through the Ullman book and couldn't find an easy way to convert a function that accepts a tuple to a curried function. They have two different signatures and aren't directly compatible with one another.
I think you're going to have to roll your own.
Or switch to Haskell.
Edit: I've thought about it, and now know why one isn't the same as the other. In SML, nearly all of the functions you're used to actually accept only one parameter. It just so happens that most of the time you're actually passing it a tuple with more than one element. Still, a tuple is a single value and is treated as such by the function. You can't pass such function a partial tuple. It's either the whole tuple or nothing.
Any function that accepts more than one parameter is, by definition, curried. When you define a function that accepts multiple parameters (as opposed to a single tuple with multiple elements), you can partially apply it and use its return value as the argument to another function.

Make Test.QuickCheck.Batch use a default type for testing list functions

I am testing a function called extractions that operates over any list.
extractions :: [a] -> [(a,[a])]
extractions [] = []
extractions l = extract l []
where extract [] _ = []
extract (x:xs) prev = (x, prev++xs) : extract xs (x : prev)
I want to test it, for example, with
import Test.QuickCheck.Batch
prop_len l = length l == length (extractions l)
main = runTests "extractions" defOpt [run prop_len]
But this won't compile; I have to supply a type either for run or prop_len, because QuickCheck can't generate [a], it has to generate something concrete. So I chose Int:
main = runTests "extractions" defOpt [r prop_len]
where r = run :: ([Int] -> Bool) -> TestOptions -> IO TestResult
Is there any way to get QuickCheck to choose a for me instead of having it specified in the type of run?
The quickcheck manual says "no":
Properties must have monomorphic types. `Polymorphic' properties, such as the one above, must be restricted to a particular type to be used for testing. It is convenient to do so by stating the types of one or more arguments in a
where types = (x1 :: t1, x2 :: t2, ...)
clause...