[m-rev.] Re: [m-dev.] for review : quickcheck

Mark Anthony BROWN dougl at cs.mu.OZ.AU
Fri Mar 30 16:07:56 AEST 2001


Hi,

First a couple of general remarks.

	- A "human readable" diff would be far better for reviews (i.e.,
	  one in unified format with some context).
	- You still have not addressed my comment about the assumptions
	  in gen_arg that should be documented in the interface of the
	  module.

After you have addressed the points below, please post a relative diff.
Note that the mailing lists have changed slightly, and you should post
it to mercury-reviews.  (I have CC'd this to you just in case.)

Cheers,
Mark.

Xiao Chun Simon MEI writes:
> Hi,
> 
> qcheck.m was the only file I modify this round, so below
> is diff between the 2 versions of qcheck.m. But I did paste 
> over the log message, and changed the comment for rnd.m as David 
> suggested.
> 
> I've attached the new version of qcheck.m just in case the 
> relative diff is not enough.
> 
> For Mark to review.
> 
> 
> 
> Estimated hours taken : 185
> 
> qcheck is an autotesting tool similar to Haskell's Quickcheck.
> 
> RELEASE_NOTES:
> compiler/notes/authors.html:
> extras/README:
>         Modified to mention quickcheck.
> 
> extras/quickcheck/qcheck.m:
>         New file that contains the source code for qcheck.
> 
> extras/quickcheck/rnd.m:
>         New file written by conway. Its functions are similar 
>         to those in library random.m. The random numbers generated
> 	with random.m functions show strong correlation in lower
> 	bits; rnd.m does not seem have such problems.
> 
> 
> 
> 
> 
> 40,42c40,42
> < 	% Each distribution store the value in univ and it's number of 
> < 	% occurences in the second element.
> < :- type distribution == {univ, int}.
> ---
> > 	% Each distributions store the value in univ and its number of 

s/distributions store/distribution stores/

> > 	% occurences in the first element.
> > :- type distribution == {int, univ}.
> 78c78
> < 	%	followed by a Specific Frequency, a list of Generanl frequency,
> ---
> > 	%	followed by a Specific Frequency, a list of General frequency,
> 157a158,168
> > 	%	
> > 	% Quickcheck is able to generate random values for each input 
> > 	% argument of the invariant function at run time, provided 
> > 	% that there is a default/custom generator for that type. 
> > 	% The default generator is able to generate type int, char, 
> > 	% float, string, string, discriminated union and certain functions.
> > 	% Details are explained in the tutorials.
> > 	%
> > 	% Quickcheck makes the assumption that the distincation between
> > 	% a function and a discriminated union is that num_functors(FuncType) 
> > 	% is -1, while num_functors(UnionType) is not -1.
> 197c208
> < 	% functions with arity 0 to 10, it will throw an error is unable to
> ---
> > 	% functions with arity 0 to 10, it will throw an error if unable to
> 277c288
> < 	% qcheck//6 first seed the random number on local time, then it  
> ---
> > 	% qcheck/8 first seed the random number on local time, then it  
> 282,287c293,294
> < 	time__time(Sometime),
> <         { tm(Seconds, Minutes, Hours, _Weekday, Yearday, _Month, Year, _DST) 
> < 	  = time__localtime(Sometime) },
> < 	{ TotalSecs = ((( Year * 365 + Yearday ) * 24 + Hours ) * 60 + Minutes ) * 60 
> < 			 + Seconds },
> < 	{ init_setup(TotalSecs, RS0) },
> ---
> > 	time__time(CurrentTime),
> > 	{ init_setup(generate_seed_from_time(CurrentTime), RS0) },
> 305,306c312,313
> < 	    	{ list__sort(rev_field(Distributions), Distributions_Sorted) },
> < 	    	show_dist(rev_field(Distributions_Sorted)),
> ---
> > 	    	{ list__sort(Distributions, Distributions_Sorted) },
> > 	    	show_dist(Distributions_Sorted),

Are you sure this does what you meant it to?  I thought you wanted a
different ordering than the default, which means that you should call
the other version of list__sort, and pass a comparison predicate as the
first argument.  The comparison predicate that you write should compare
the second tuple argument before comparing the first argument if
necessary.

Oh, I see below that you have changed the representation so that the
default ordering does the intended thing.  This should be ok, then.

> 310d316
> < 
> 312a319,333
> > 	% generate_seed_from_time/1 converts the input time in calendar time
> > 	% format to the number of seconds from the beginning of current year.
> > 	% The numbers of seconds is reduced to an appropriate range for int to
> > 	% avoid overflow.
> > :- func generate_seed_from_time(time_t) = int.
> > :- mode generate_seed_from_time(in) = out.
> > generate_seed_from_time(CurrentTime) =  Seed :-
> >         tm(Seconds, Minutes, Hours, _Weekday, Yearday, _Month, Year, _DST) 
> > 	  = time__localtime(CurrentTime),
> > 	TotalSecs = ((( integer(Year) * integer(365) + integer(Yearday)) 
> > 		      * integer(24) + integer(Hours)) 
> > 		      * integer(60) + integer(Minutes)) 
> > 		      * integer(60) + integer(Seconds),
> > 	Seed = int( TotalSecs mod integer(max_int + 1) ).

Unfortunately, this won't work either, because (max_int + 1) is
undefined due to an overflow.  Is there a bug in the suggested code I
posted in the previous review?  If so, please tell me what it is!

> > 
> 388,389c409,410
> < 	% update_dist/3 recursively exacts the 'flag:info(univ)' from property i
> < 	% iand adds it to the master list of distribution.
> ---
> > 	% update_dist/3 recursively exacts the 'flag:info(univ)' from property
> > 	% and adds it to the master list of distribution.
> 407c428
> < update_dist_2(Univ, [], [{Univ, 1}]).
> ---
> > update_dist_2(Univ, [], [{1, Univ}]).
> 409c430
> < 	Distribution = {Patten, Counter},
> ---
> > 	Distribution = {Counter, Patten},
> 412c433
> < 	 	Output = [{Univ, Counter + 1} | Distributions]
> ---
> > 	 	Output = [{Counter + 1, Univ} | Distributions]
> 427c448
> < 	% test//5 then calls gen//4 to generate the arguments, the invariant
> ---
> > 	% test/7 then calls gen/6 to generate the arguments, the invariant
> 429,430c450
> < 	% the invariant test funtion with the 
> < 
> ---
> > 	% The test result is returned along with the arguments generated.
> 738c758
> < 	(if	find_user_gen(Datatype, UserGenerators, User_generator)
> ---
> > 	(if	find_user_gen(Datatype, UserGenerators, UserGenerator)
> 740,741c760,761
> < 		Univ = User_generator(Datatype, Frequencys, GF, UserGenerators,
> < 				      RS0,RS)
> ---
> > 		Univ = UserGenerator(Datatype, Frequencys, GF, UserGenerators,
> > 				      RS0, RS)
> 871,881c891,901
> < 	rnd__irange(1, const_million, X0,  RS0, RS1),
> < 	rnd__irange(1, const_million, X1,  RS1, RS2),
> < 	rnd__irange(1, const_million, X2,  RS2, RS3),
> < 	rnd__irange(1, const_million, X3,  RS3, RS4),
> < 	rnd__irange(1, const_million, X4,  RS4, RS5),
> < 	rnd__irange(1, const_million, X5,  RS5, RS6),
> < 	rnd__irange(1, const_million, X6,  RS6, RS7),
> < 	rnd__irange(1, const_million, X7,  RS7, RS8),
> < 	rnd__irange(1, const_million, X8,  RS8, RS9),
> < 	rnd__irange(1, const_million, X9,  RS9, RS10),
> < 	rnd__irange(1, const_million, X10, RS10, RS),
> ---
> > 	rnd__irange(1, max_int_argument, X0,  RS0, RS1),
> > 	rnd__irange(1, max_int_argument, X1,  RS1, RS2),
> > 	rnd__irange(1, max_int_argument, X2,  RS2, RS3),
> > 	rnd__irange(1, max_int_argument, X3,  RS3, RS4),
> > 	rnd__irange(1, max_int_argument, X4,  RS4, RS5),
> > 	rnd__irange(1, max_int_argument, X5,  RS5, RS6),
> > 	rnd__irange(1, max_int_argument, X6,  RS6, RS7),
> > 	rnd__irange(1, max_int_argument, X7,  RS7, RS8),
> > 	rnd__irange(1, max_int_argument, X8,  RS8, RS9),
> > 	rnd__irange(1, max_int_argument, X9,  RS9, RS10),
> > 	rnd__irange(1, max_int_argument, X10, RS10, RS),
> 1079,1089c1099,1109
> < 	rnd__irange(1, const_million, Seed_initial,      RS0, RS1),
> < 	rnd__irange(1, const_million, Seed_any_to_int1,  RS1, RS2),
> < 	rnd__irange(1, const_million, Seed_any_to_int2,  RS2, RS3),
> < 	rnd__irange(1, const_million, Seed_any_to_int3,  RS3, RS4),
> < 	rnd__irange(1, const_million, Seed_any_to_int4,  RS4, RS5),
> < 	rnd__irange(1, const_million, Seed_any_to_int5,  RS5, RS6),
> < 	rnd__irange(1, const_million, Seed_any_to_int6,  RS6, RS7),
> < 	rnd__irange(1, const_million, Seed_any_to_int7,  RS7, RS8),
> < 	rnd__irange(1, const_million, Seed_any_to_int8,  RS8, RS9),
> < 	rnd__irange(1, const_million, Seed_any_to_int9,  RS9, RS10),
> < 	rnd__irange(1, const_million, Seed_any_to_int10, RS10, _),
> ---
> > 	rnd__irange(1, max_int_argument, Seed_initial,      RS0, RS1),
> > 	rnd__irange(1, max_int_argument, Seed_any_to_int1,  RS1, RS2),
> > 	rnd__irange(1, max_int_argument, Seed_any_to_int2,  RS2, RS3),
> > 	rnd__irange(1, max_int_argument, Seed_any_to_int3,  RS3, RS4),
> > 	rnd__irange(1, max_int_argument, Seed_any_to_int4,  RS4, RS5),
> > 	rnd__irange(1, max_int_argument, Seed_any_to_int5,  RS5, RS6),
> > 	rnd__irange(1, max_int_argument, Seed_any_to_int6,  RS6, RS7),
> > 	rnd__irange(1, max_int_argument, Seed_any_to_int7,  RS7, RS8),
> > 	rnd__irange(1, max_int_argument, Seed_any_to_int8,  RS8, RS9),
> > 	rnd__irange(1, max_int_argument, Seed_any_to_int9,  RS9, RS10),
> > 	rnd__irange(1, max_int_argument, Seed_any_to_int10, RS10, _),
> 1196c1216
> < 	% prints out the elements in that tuple.
> ---
> > 	% print out the elements in that tuple.
> 1219c1239
> < 	{ Dist = {Univ, Freq} },
> ---
> > 	{ Dist = {Freq, Univ} },
> 1242c1262
> < 			error("sum_freq/6 : get_functor_ordinal/3 failed")
> ---
> > 			error("get_freq/5 : get_functor_ordinal/3 failed")
> 1362,1369c1382,1384
> < :- func rev_field(list({T1, T2})) = list({T2, T1}).
> < :- mode rev_field(in) = out is det.
> < rev_field([]) =  [].
> < rev_field([{A, B} | Xs]) = [{B, A} | rev_field(Xs) ]. 
> < 
> < :- func (const_million) = int.
> < :- mode (const_million) = out is det.
> < (const_million) = 1000000.
> ---
> > :- func (max_int_argument) = int.
> > :- mode (max_int_argument) = out is det.
> > (max_int_argument) = 1000000.
> 
> 
> 
> 
> 
> 
Content-Description: 

[Attachment, skipping...]

--------------------------------------------------------------------------
mercury-reviews mailing list
post:  mercury-reviews at cs.mu.oz.au
administrative address: owner-mercury-reviews at cs.mu.oz.au
unsubscribe: Address: mercury-reviews-request at cs.mu.oz.au Message: unsubscribe
subscribe:   Address: mercury-reviews-request at cs.mu.oz.au Message: subscribe
--------------------------------------------------------------------------



More information about the reviews mailing list