First quickcheck test.

Test that the ++alter:mp family is a ++valid treap after a large number of
random actions.
This commit is contained in:
Elliot Glaysher 2017-09-28 23:05:23 -07:00
parent fc651af8aa
commit 08962cfd63
2 changed files with 101 additions and 4 deletions

View File

@ -71,8 +71,8 @@
:: todo: wrap generator in mule so it can crash.
=+ sample=(generator eny)
:: todo: wrap test in mule so it can crash.
=+ test=(test sample)
?: test
=+ ret=(test sample)
?: ret
%= $
eny (shaf %huh eny) :: xxx: better random?
current-iteration (add current-iteration 1)
@ -94,6 +94,22 @@
^- @
(add min (~(rad og c) (sub max min)))
::
++ generate-map
:> generator which will produce a map with {count} random pairs.
|= count/@u
:> generate a map with entropy {c}.
|= c/@uvJ
=/ gen (random:new-hoon c)
=| i/@u
=| m/(map @ud @ud)
|-
^- (map @ud @ud)
?: =(i count)
m
=^ first gen (rads:gen 100)
=^ second gen (rads:gen 100)
$(m (insert:mp:new-hoon m first second), i +(i))
::
:: || %test
::
:: +|
@ -583,6 +599,33 @@
(from-list [[1 "one"] [2 "dos"] [3 "three"] [4 "four"] ~])
"alter (as change)"
::
++ check-alter
:: check random maps of 50 items with 40 random operations done on them
:: for validity.
%+ check
(generate-map 50)
|= a/(map @ud @ud)
:: this is dumb, but use {a} as entropy?
=/ gen (random:new-hoon (jam a))
=| i/@u
|-
?: =(i 40)
%.y
=^ key gen (rads:gen 100)
=^ value gen (rads:gen 100)
=. a %^ alter-with-key a key
|= {key/@ud current/(maybe @ud)}
^- (maybe @ud)
=+ action=(mod key 2)
?: =(action 0) :: return nothing
~
?: =(action 1) :: add/set value
`value
~ :: impossible
?. (valid a)
%.n
$(i +(i))
::
++ test-union
%^ expect-eq
%+ union
@ -801,6 +844,12 @@
|=({a/* b/*} =(a b))
%.y
"is-submap"
::
++ test-valid
%^ expect-eq
(valid (from-list [[1 1] [2 2] [3 3] [4 4] [5 5] [6 6] [7 7] [8 8] [9 9] ~]))
%.y
"valid"
--
:: ----------------------------------------------------------------------
:: Stays in the generator.
@ -882,5 +931,5 @@
:: (perform-test-suite:local "test-thr" !>(test-thr) eny)
:: (perform-test-suite:local "test-myb" !>(test-myb) eny)
(perform-test-suite:local "test-ls" !>(test-ls) eny)
::(perform-test-suite:local "test-mp" !>(test-mp) eny)
::(perform-test-suite:local "test-ls" !>(test-ls) eny)
(perform-test-suite:local "test-mp" !>(test-mp) eny)

View File

@ -1418,5 +1418,53 @@
?: (vor p.n.l.a p.n.r.a)
[n.l.a l.l.a $(l.a r.l.a)]
[n.r.a $(r.a l.r.a) r.r.a]
::
++ valid
:> returns %.y if {a} is a valid treap map.
|* a/(map)
=| {l/(unit) r/(unit)}
|- ^- ?
?~ a &
?& ?~(l & (gor p.n.a u.l))
?~(r & (gor u.r p.n.a))
?~(l.a & ?&((vor p.n.a p.n.l.a) $(a l.a, l `p.n.a)))
?~(r.a & ?&((vor p.n.a p.n.r.a) $(a r.a, r `p.n.a)))
==
--
++ random
:> produces a core which produces random numbers.
:: todo: think hard about whether this interface really makes any sense;
:: this is marginally better than ++og for rads usage, but still isn't good.
|= a/@
:: note: interior was copied verbatim from ++og.
|%
++ rad :: random in range
|= b/@ ^- @
=+ c=(raw (met 0 b))
?:((lth c b) c $(a +(a)))
::
++ rads :: random continuation
|= b/@
=+ r=(rad b)
[r +>.$(a (shas %og-s (mix a r)))]
::
++ raw :: random bits
:: ~/ %raw
|= b/@ ^- @
%+ can
0
=+ c=(shas %og-a (mix b a))
|- ^- (list {@ @})
?: =(0 b)
~
=+ d=(shas %og-b (mix b (mix a c)))
?: (lth b 256)
[[b (end 0 b d)] ~]
[[256 d] $(c d, b (sub b 256))]
::
++ raws :: random bits
|= b/@ :: continuation
=+ r=(raw b)
[r +>.$(a (shas %og-s (mix a r)))]
--
--