add stub for enumeration support to Redex

This commit is contained in:
Robby Findler 2013-05-01 09:37:28 -05:00
parent 62a207a71f
commit c9045abf4d
9 changed files with 96 additions and 27 deletions

View File

@ -0,0 +1,21 @@
#lang racket/base
(require racket/contract
"lang-struct.rkt")
(provide
(contract-out
[lang-enumerators (-> (listof nt?) (hash/c symbol? enum?))]
[pat-enumerator (-> (hash/c symbol? enum?)
any/c ;; pattern
enum?)]
[enum-ith (-> enum? exact-nonnegative-integer? any/c)]
[enum? (-> any/c boolean?)]))
(struct enum ())
(define (lang-enumerators nts) (make-hash))
(define (pat-enumerator li p)
(unless (equal? p '(name natural natural))
(error 'enum.rkt "not yet implemented"))
(enum))
(define (enum-ith e i) i)

View File

@ -2,6 +2,7 @@
(require "rg.rkt" (require "rg.rkt"
"jdg-gen.rkt" "jdg-gen.rkt"
"error.rkt" "error.rkt"
"enum.rkt"
"reduction-semantics.rkt" "reduction-semantics.rkt"
"struct.rkt" "struct.rkt"
"term.rkt" "term.rkt"
@ -326,9 +327,20 @@
(for ([x (in-list l)]) (for ([x (in-list l)])
(define k (syntax-e x)) (define k (syntax-e x))
(when (keyword? k) (when (keyword? k)
(unless (member k '(#:satisfying #:source #:attempt-num #:retries)) (unless (member k '(#:satisfying #:source #:attempt-num #:retries #:i-th))
(raise-syntax-error 'generate-term "unknown keyword" stx x)))))) (raise-syntax-error 'generate-term "unknown keyword" stx x))))))
(define form-name (syntax-e #'orig-name))
(syntax-case stx () (syntax-case stx ()
[(_ orig-name lang pat #:i-th . rest)
(with-syntax ([(pattern (vars ...) (vars/ellipses ...))
(rewrite-side-conditions/check-errs
(language-id-nts #'lang form-name)
form-name #t #'pat)])
(syntax-case #'rest ()
[()
#'(generate-ith/proc lang `pattern)]
[(i-expr)
#'((generate-ith/proc lang `pattern) i-expr)]))]
[(_ orig-name language #:satisfying (jf/mf-id . args) . rest) [(_ orig-name language #:satisfying (jf/mf-id . args) . rest)
(cond (cond
[(metafunc #'jf/mf-id) [(metafunc #'jf/mf-id)
@ -379,7 +391,6 @@
#'jf/mf-id)])] #'jf/mf-id)])]
[(_ orig-name actual-stx ...) [(_ orig-name actual-stx ...)
(let () (let ()
(define form-name (syntax-e #'orig-name))
(define-values (raw-generators args) (define-values (raw-generators args)
(syntax-case #'(actual-stx ...) () (syntax-case #'(actual-stx ...) ()
[(#:source src . rest) [(#:source src . rest)
@ -416,6 +427,16 @@
(quasisyntax/loc stx (quasisyntax/loc stx
(#,generator-syntax size . kw-args))]))])) (#,generator-syntax size . kw-args))]))]))
(define (generate-ith/proc lang pat)
(define enum-lang (compiled-lang-enum-table lang))
(define enum (pat-enumerator enum-lang pat))
(λ (i)
(unless (exact-nonnegative-integer? i)
(raise-argument-error 'generate-term
"exact-nonnegative-integer?"
i))
(enum-ith enum i)))
(define (check-cases name cases) (define (check-cases name cases)
(when (null? cases) (when (null? cases)
(raise-gen-fail 'generate-term (format "from ~a metafunction (it has no clauses)" name) 1))) (raise-gen-fail 'generate-term (format "from ~a metafunction (it has no clauses)" name) 1)))

View File

@ -0,0 +1,11 @@
#lang racket/base
(provide (struct-out nt)
(struct-out rhs))
;; lang = (listof nt)
;; nt = (make-nt sym (listof rhs))
;; rhs = (make-rhs single-pattern)
;; single-pattern = sexp
(define-struct nt (name rhs) #:transparent)
(define-struct rhs (pattern) #:transparent)

View File

@ -47,19 +47,14 @@ See match-a-pattern.rkt for more details
racket/performance-hint racket/performance-hint
(for-syntax racket/base) (for-syntax racket/base)
"underscore-allowed.rkt" "underscore-allowed.rkt"
"match-a-pattern.rkt") "match-a-pattern.rkt"
"lang-struct.rkt"
"enum.rkt")
(define-struct compiled-pattern (cp binds-names? skip-dup-check?) #:transparent) (define-struct compiled-pattern (cp binds-names? skip-dup-check?) #:transparent)
(define caching-enabled? (make-parameter #t)) (define caching-enabled? (make-parameter #t))
;; lang = (listof nt)
;; nt = (make-nt sym (listof rhs))
;; rhs = (make-rhs single-pattern)
;; single-pattern = sexp
(define-struct nt (name rhs) #:transparent)
(define-struct rhs (pattern) #:transparent)
;; var = (make-var sym sexp) ;; var = (make-var sym sexp)
;; patterns are sexps with `var's embedded ;; patterns are sexps with `var's embedded
;; in them. It means to match the ;; in them. It means to match the
@ -117,12 +112,14 @@ See match-a-pattern.rkt for more details
;; hash[sexp[pattern] -o> (cons compiled-pattern boolean)] ;; hash[sexp[pattern] -o> (cons compiled-pattern boolean)]
;; pict-builder ;; pict-builder
;; (listof symbol) ;; (listof symbol)
;; (listof (listof symbol))) -- keeps track of `primary' non-terminals ;; (listof (listof symbol)) -- keeps track of `primary' non-terminals
;; hash[sym -o> pattern] ;; hash[sym -o> pattern]
;; (hash/c symbol? enum?)) ;; see enum.rkt
(define-struct compiled-lang (lang delayed-cclang ht list-ht raw-across-ht raw-across-list-ht (define-struct compiled-lang (lang delayed-cclang ht list-ht raw-across-ht raw-across-list-ht
has-hole-or-hide-hole-ht cache bind-names-cache pict-builder has-hole-or-hide-hole-ht cache bind-names-cache pict-builder
literals nt-map collapsible-nts)) literals nt-map collapsible-nts
enum-table))
(define (compiled-lang-cclang x) (force (compiled-lang-delayed-cclang x))) (define (compiled-lang-cclang x) (force (compiled-lang-delayed-cclang x)))
(define (compiled-lang-across-ht x) (define (compiled-lang-across-ht x)
(compiled-lang-cclang x) ;; ensure this is computed (compiled-lang-cclang x) ;; ensure this is computed
@ -164,7 +161,8 @@ See match-a-pattern.rkt for more details
pict-info pict-info
literals literals
nt-map nt-map
collapsible-nts)] collapsible-nts
(lang-enumerators lang))]
[non-list-nt-table (build-non-list-nt-label lang)] [non-list-nt-table (build-non-list-nt-label lang)]
[list-nt-table (build-list-nt-label lang)] [list-nt-table (build-list-nt-label lang)]
[do-compilation [do-compilation
@ -2034,9 +2032,7 @@ See match-a-pattern.rkt for more details
(struct-out mismatch-bind) (struct-out mismatch-bind)
(struct-out compiled-pattern)) (struct-out compiled-pattern))
(provide (struct-out nt) (provide (struct-out compiled-lang)
(struct-out rhs)
(struct-out compiled-lang)
compiled-lang-cclang compiled-lang-cclang
lookup-binding lookup-binding

View File

@ -6,7 +6,9 @@
racket/match racket/match
"match-a-pattern.rkt" "match-a-pattern.rkt"
"matcher.rkt" "matcher.rkt"
"lang-struct.rkt"
"extract-conditions.rkt" "extract-conditions.rkt"
"enum.rkt"
(for-syntax "rewrite-side-conditions.rkt" (for-syntax "rewrite-side-conditions.rkt"
racket/base)) racket/base))
@ -754,4 +756,5 @@
(define empty-lang (define empty-lang
(compiled-lang (compiled-lang
#f #f #f #f #f #f #f #f #f #f '() #f (hash))) #f #f #f #f #f #f #f #f #f #f '() #f (hash)
(lang-enumerators '())))

View File

@ -9,6 +9,7 @@
"judgment-form.rkt" "judgment-form.rkt"
"term-fn.rkt" "term-fn.rkt"
"search.rkt" "search.rkt"
"lang-struct.rkt"
(for-syntax "cycle-check.rkt" (for-syntax "cycle-check.rkt"
setup/path-to-relative) setup/path-to-relative)
racket/trace racket/trace

View File

@ -1,6 +1,7 @@
#lang racket/base #lang racket/base
(require "matcher.rkt" (require "matcher.rkt"
"lang-struct.rkt"
"reduction-semantics.rkt" "reduction-semantics.rkt"
"underscore-allowed.rkt" "underscore-allowed.rkt"
"error.rkt" "error.rkt"

View File

@ -1693,9 +1693,10 @@ metafunctions or unnamed reduction-relation cases) to application counts.}
(values (covered-cases equals-coverage) (values (covered-cases equals-coverage)
(covered-cases plus-coverage))))] (covered-cases plus-coverage))))]
@defform*/subs[[(generate-term term-spec size-expr kw-args ...) @defform*/subs[[(generate-term term-spec size-or-index-expr kw-args ...)
(generate-term term-spec)] (generate-term term-spec)]
([term-spec (code:line language @#,ttpattern) ([term-spec (code:line language @#,ttpattern)
(code:line language @#,ttpattern #:i-th)
(code:line language #:satisfying (judgment-form-id @#,ttpattern ...)) (code:line language #:satisfying (judgment-form-id @#,ttpattern ...))
(code:line language #:satisfying (metafunction-id @#,ttpattern ...) = @#,ttpattern) (code:line language #:satisfying (metafunction-id @#,ttpattern ...) = @#,ttpattern)
(code:line #:source metafunction) (code:line #:source metafunction)
@ -1706,15 +1707,22 @@ metafunctions or unnamed reduction-relation cases) to application counts.}
[attempt-num-expr natural-number/c] [attempt-num-expr natural-number/c]
[retries-expr natural-number/c])]{ [retries-expr natural-number/c])]{
In its first form, @racket[generate-term] produces a random term according In its first form, @racket[generate-term] produces a term according
to @racket[term-spec]: to @racket[term-spec]:
@itemlist[@item{In the first @racket[term-spec] case, the produced @itemlist[@item{In the first @racket[term-spec] case, the produced
term matches the given pattern (interpreted term is generated randomly and matches the given pattern (interpreted
according to the definition of the given language).} according to the definition of the given language). The
@item{In the second case, @racket[size-or-index-expr] is treated as a size bound
the expression produced is the quoted form of a use of the judgment-form or on the generated term, as it is for all of the cases when
@racket[#f], if Redex cannot find one.} @racket[generate-term] generates a random term.}
@item{The third cases generates a random term that satsifies @item{In the second case, the produced
term is selected from an enumeration of terms matching the given pattern
(also interpreted according to the definition of the given language), using
the value of @racket[size-or-index-expr] to choose which element of the
enumeration.}
@item{In the third case, the term generated is a random instance of the quoted
form of a use of the judgment-form or @racket[#f], if Redex cannot find one.}
@item{The fourth case generates a random term that satisfies
the call to the metafunction with the given result the call to the metafunction with the given result
or @racket[#f], if Redex cannot find one.} or @racket[#f], if Redex cannot find one.}
@item{In the last two cases, @item{In the last two cases,
@ -1723,7 +1731,7 @@ to @racket[term-spec]:
In @racket[generate-term]'s second form, it produces a procedure for constructing In @racket[generate-term]'s second form, it produces a procedure for constructing
terms according to @racket[term-spec]. terms according to @racket[term-spec].
This procedure expects @racket[size-expr] (below) as its sole positional This procedure expects @racket[size-or-index-expr] (below) as its sole positional
argument and allows the same optional keyword arguments as the first form. argument and allows the same optional keyword arguments as the first form.
The second form may be more efficient when generating many terms. The second form may be more efficient when generating many terms.

View File

@ -772,3 +772,10 @@
#:satisfying #:satisfying
(not-mem b (a (b (c ())))) (not-mem b (a (b (c ()))))
+inf.0))) +inf.0)))
(let ()
(test (generate-term L0 natural #:i-th 0) 0)
(let ([gen-ith (generate-term L0 natural #:i-th)])
(test (gen-ith 0) 0)
(test (gen-ith 1) 1)))