-
Notifications
You must be signed in to change notification settings - Fork 7
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Change shrinking algorithm from flat streams to lazy trees. #7
Conversation
I've skimmed this and think it looks fine. I'm going to want to try to see exactly how much stuff this is going to break in the wild and do a deeper review. Do you think you'll want to make more changes here or can I go ahead and review this tomorrow? |
I think I definitely want to change the shrink tree structure from a promise of a list of shrink trees to a stream of shrink trees, because I've run into issues shrinking larger generated programs. That should be backwards compatible with what I already have since lists are implicitly streams, but I'm not sure when I'll have time to implement that, and it could be a separate pr too since it should be backwards compatible |
OK, cool. In that case, I'll wait until you make those changes. I don't think there's any rush to merge. I've looked at my projects, and none of them use |
Changed the shrink-trees to use streams! |
Thanks! This is great. I made some of my own changes on top in this branch. Would you mind giving that branch a spin to make sure I haven't broken anything for your use case? Mostly, the changes are organizational and I've kept most of your additions except for If everything looks good to you, I'll squash and merge that branch. Thanks again! |
Those changes look good, except for some reason it takes noticeably longer to sample using |
That's strange. When I test it against your
And with mine:
Where the test program looks like this: #lang racket/base
(require rackcheck
"lang-gen.rkt")
(define gen:expr
(lang-generator
#:values 'integers 'booleans 'characters 'eof
#:forms 'app 'if 'cond 'case 'let1 'let 'let* 'begin
#:ops 'add1 'sub1 'abs 'not 'zero? 'integer?))
(collect-garbage)
(collect-garbage)
(random-seed 1337)
(time
(for ([_ (in-range 100)])
(sample (gen:expr '() (TAny))))) Were you testing against some other kind of generator? |
Oh sorry, the most recent branch is |
Ah, OK, in that case, I will go ahead and squash and merge these changes. Thanks again! |
This changes the shrinking algorithm used from flat ordered streams of a term and it's shrinks to a lazily evaluated tree of shrinks. This change allows the algorithm used to find a shrunken counterexample to use the structural information of a term and vastly improves the performance of shrinking terms like lists and programs. This PR also adds a new
gen:with-shrinks
combinator that takes a generator and a shrink function, and replaces the shrink tree for the generated value with recursive applications of the provided shrinking function.This PR is currently missing is thehash
generators, but other than that is complete.hash
generators have been implemented.The new shrinking method means that any generators made with
make-gen
are not compatible with this PR, however all generators built from generator combinators should be compatible.I am also considering changing the lazy list inside the
shrink-tree
structure to a stream of subtrees.Closes #5