change redex-check's default strategy to do both
enumeration and random generation in a manner supported by our study
This commit is contained in:
parent
89ef6f831e
commit
494f32084a
|
@ -2027,8 +2027,15 @@ using the @racket[match-bindings] produced by @racket[match]ing
|
||||||
@math{t} against @racket[pattern]. The form of @racket[template] controls
|
@math{t} against @racket[pattern]. The form of @racket[template] controls
|
||||||
how @math{t} is generated:
|
how @math{t} is generated:
|
||||||
@itemlist[@item{@racket[language @#,ttpattern]:
|
@itemlist[@item{@racket[language @#,ttpattern]:
|
||||||
In this case, @racket[redex-check] randomly generates terms that match
|
In this case, @racket[redex-check] uses an ad hoc strategy for
|
||||||
@racket[_pattern].}
|
generating @racket[_pattern]. For the first 10 seconds, it uses
|
||||||
|
in-order enumeration to pick terms. After that, it
|
||||||
|
alternates back and forth between in-order enumeration
|
||||||
|
and the ad hoc random generator. After the 10 minute mark,
|
||||||
|
it switches over to using just the ad hoc random generator.}
|
||||||
|
@item{@racket[language @#,ttpattern #:ad-hoc]:
|
||||||
|
In this case, @racket[redex-check] uses an ad hoc random generator
|
||||||
|
to generate terms that match @racket[_pattern].}
|
||||||
@item{@racket[language @#,ttpattern #:in-order]:
|
@item{@racket[language @#,ttpattern #:in-order]:
|
||||||
In this case, @racket[redex-check] uses an enumeration
|
In this case, @racket[redex-check] uses an enumeration
|
||||||
of @racket[_pattern], checking each @math{t} one at a time}
|
of @racket[_pattern], checking each @math{t} one at a time}
|
||||||
|
|
|
@ -93,6 +93,7 @@
|
||||||
(define-syntax (redex-check stx)
|
(define-syntax (redex-check stx)
|
||||||
(define valid-kws
|
(define valid-kws
|
||||||
(list* '#:satisfying
|
(list* '#:satisfying
|
||||||
|
'#:ad-hoc
|
||||||
'#:enum
|
'#:enum
|
||||||
'#:uniform-at-random
|
'#:uniform-at-random
|
||||||
'#:in-order
|
'#:in-order
|
||||||
|
@ -126,13 +127,15 @@
|
||||||
[(form lang #:satisfying . rest)
|
[(form lang #:satisfying . rest)
|
||||||
(raise-syntax-error 'redex-check "#:satisfying expected judgment form or metafunction syntax followed by a property" stx #'rest)]
|
(raise-syntax-error 'redex-check "#:satisfying expected judgment form or metafunction syntax followed by a property" stx #'rest)]
|
||||||
[(form lang pat #:enum biggest-e property . kw-args)
|
[(form lang pat #:enum biggest-e property . kw-args)
|
||||||
(redex-check/pat stx #'form #'lang #'pat #'property #'biggest-e #f #f #'kw-args)]
|
(redex-check/pat stx #'form #'lang #'pat #'property #'biggest-e #f #f #f #'kw-args)]
|
||||||
[(form lang pat #:uniform-at-random p-value property . kw-args)
|
[(form lang pat #:uniform-at-random p-value property . kw-args)
|
||||||
(redex-check/pat stx #'form #'lang #'pat #'property #f #'p-value #f #'kw-args)]
|
(redex-check/pat stx #'form #'lang #'pat #'property #f #'p-value #f #f #'kw-args)]
|
||||||
[(form lang pat #:in-order property . kw-args)
|
[(form lang pat #:in-order property . kw-args)
|
||||||
(redex-check/pat stx #'form #'lang #'pat #'property #f #f #t #'kw-args)]
|
(redex-check/pat stx #'form #'lang #'pat #'property #f #f #t #f #'kw-args)]
|
||||||
|
[(form lang pat #:ad-hoc property . kw-args)
|
||||||
|
(redex-check/pat stx #'form #'lang #'pat #'property #f #f #f #t #'kw-args)]
|
||||||
[(form lang pat property . kw-args)
|
[(form lang pat property . kw-args)
|
||||||
(redex-check/pat stx #'form #'lang #'pat #'property #f #f #f #'kw-args)]))
|
(redex-check/pat stx #'form #'lang #'pat #'property #f #f #f #f #'kw-args)]))
|
||||||
|
|
||||||
(define-struct gen-fail ())
|
(define-struct gen-fail ())
|
||||||
|
|
||||||
|
@ -217,7 +220,7 @@
|
||||||
#,keep-going-stx)))))))
|
#,keep-going-stx)))))))
|
||||||
|
|
||||||
(define-for-syntax (redex-check/pat orig-stx form lang pat property
|
(define-for-syntax (redex-check/pat orig-stx form lang pat property
|
||||||
enum-bound-e enum-p-value in-order?
|
enum-bound-e enum-p-value in-order? ad-hoc?
|
||||||
kw-args)
|
kw-args)
|
||||||
(with-syntax ([(syncheck-exp pattern (name ...) (name/ellipses ...))
|
(with-syntax ([(syncheck-exp pattern (name ...) (name/ellipses ...))
|
||||||
(rewrite-side-conditions/check-errs
|
(rewrite-side-conditions/check-errs
|
||||||
|
@ -290,12 +293,59 @@
|
||||||
(ith-generator #,lang `pattern #,enum-bound-e #,enum-p-value)
|
(ith-generator #,lang `pattern #,enum-bound-e #,enum-p-value)
|
||||||
property att ret (and print? show) (or fix (λ (x) x)) term-match
|
property att ret (and print? show) (or fix (λ (x) x)) term-match
|
||||||
keep-going?)]
|
keep-going?)]
|
||||||
[else
|
[ad-hoc?
|
||||||
#`(check-one
|
#`(check-one
|
||||||
#,(term-generator lang #'pattern 'redex-check)
|
#,(term-generator lang #'pattern 'redex-check)
|
||||||
property att ret (and print? show) fix (and fix term-match)
|
property att ret (and print? show) fix (and fix term-match)
|
||||||
|
keep-going?)]
|
||||||
|
[else
|
||||||
|
#`(check-one
|
||||||
|
(default-generator #,lang `pattern)
|
||||||
|
property att ret (and print? show) (or fix (λ (x) x)) term-match
|
||||||
keep-going?)])])))))))
|
keep-going?)])])))))))
|
||||||
|
|
||||||
|
(define (default-generator lang pat)
|
||||||
|
(define ad-hoc-generator ((compile lang 'redex-check) pat))
|
||||||
|
(define enum (with-handlers ([exn:fail? (λ (x) #f)])
|
||||||
|
;; would be better if the pat-enumerator were to
|
||||||
|
;; return something to indicate failure instead of
|
||||||
|
;; raising an exception so that bugs in there wouldn't
|
||||||
|
;; turn into #f here
|
||||||
|
(pat-enumerator (compiled-lang-enum-table lang) pat)))
|
||||||
|
(cond
|
||||||
|
[enum
|
||||||
|
(define in-bounds (if (= +inf.0 (enum-size enum))
|
||||||
|
(λ (x) x)
|
||||||
|
(λ (x) (modulo x (enum-size enum)))))
|
||||||
|
(define start-time (current-inexact-milliseconds))
|
||||||
|
(define interleave-start-attempt #f)
|
||||||
|
(define interleave-time (+ start-time (* 1000 10))) ;; 10 seconds later
|
||||||
|
(define pure-random-start-attempt #f)
|
||||||
|
(define pure-random-time (+ start-time (* 1000 60 10))) ;; 10 minutes later
|
||||||
|
(λ (_size _attempt _retries)
|
||||||
|
(define now (current-inexact-milliseconds))
|
||||||
|
(cond
|
||||||
|
[(<= now interleave-time)
|
||||||
|
(values (enum-ith enum (in-bounds (- _attempt 1))) 'ignored)]
|
||||||
|
[(<= now pure-random-time)
|
||||||
|
(unless interleave-start-attempt (set! interleave-start-attempt _attempt))
|
||||||
|
(define interleave-attempt (- _attempt interleave-start-attempt))
|
||||||
|
(cond
|
||||||
|
[(odd? interleave-attempt)
|
||||||
|
(ad-hoc-generator _size (/ (- interleave-attempt 1) 2) _retries)]
|
||||||
|
[else
|
||||||
|
(define enum-id (in-bounds (+ interleave-start-attempt (/ interleave-attempt 2) -1)))
|
||||||
|
(values (enum-ith enum enum-id) 'ignored)])]
|
||||||
|
[else
|
||||||
|
(unless pure-random-start-attempt (set! pure-random-start-attempt _attempt))
|
||||||
|
(ad-hoc-generator _size
|
||||||
|
(+ (- _attempt pure-random-start-attempt)
|
||||||
|
(quotient (- pure-random-start-attempt pure-random-start-attempt)
|
||||||
|
2))
|
||||||
|
_retries)]))]
|
||||||
|
[else
|
||||||
|
ad-hoc-generator]))
|
||||||
|
|
||||||
(define (ith-generator lang pat enum-bound enum-p-value)
|
(define (ith-generator lang pat enum-bound enum-p-value)
|
||||||
(define enum-lang (compiled-lang-enum-table lang))
|
(define enum-lang (compiled-lang-enum-table lang))
|
||||||
(define enum (pat-enumerator enum-lang pat))
|
(define enum (pat-enumerator enum-lang pat))
|
||||||
|
|
|
@ -803,7 +803,7 @@
|
||||||
(test (let/ec k
|
(test (let/ec k
|
||||||
(parameterize ([generation-decisions
|
(parameterize ([generation-decisions
|
||||||
(decisions #:nt (list (λ _ (k #t))))])
|
(decisions #:nt (list (λ _ (k #t))))])
|
||||||
(redex-check lang d #t #:attempts 1 #:print? #f #:attempt-size add1)
|
(redex-check lang d #:ad-hoc #t #:attempts 1 #:print? #f #:attempt-size add1)
|
||||||
#f))
|
#f))
|
||||||
#t)
|
#t)
|
||||||
|
|
||||||
|
@ -893,6 +893,13 @@
|
||||||
#rx"^redex-check: unable to generate LHS of impossible in 42")))
|
#rx"^redex-check: unable to generate LHS of impossible in 42")))
|
||||||
|
|
||||||
|
|
||||||
|
(test (let ([checked 0])
|
||||||
|
(redex-check lang n #:ad-hoc (set! checked (add1 checked))
|
||||||
|
#:print? #f
|
||||||
|
#:attempts 10)
|
||||||
|
checked)
|
||||||
|
10)
|
||||||
|
|
||||||
(test (let ([checked 0])
|
(test (let ([checked 0])
|
||||||
(redex-check lang n #:enum 100 (set! checked (add1 checked))
|
(redex-check lang n #:enum 100 (set! checked (add1 checked))
|
||||||
#:print? #f
|
#:print? #f
|
||||||
|
|
Loading…
Reference in New Issue
Block a user