add stub for enumeration support to Redex
This commit is contained in:
parent
62a207a71f
commit
c9045abf4d
21
collects/redex/private/enum.rkt
Normal file
21
collects/redex/private/enum.rkt
Normal 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)
|
|
@ -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)))
|
||||||
|
|
11
collects/redex/private/lang-struct.rkt
Normal file
11
collects/redex/private/lang-struct.rkt
Normal 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)
|
|
@ -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
|
||||||
|
|
|
@ -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 '())))
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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"
|
||||||
|
|
|
@ -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.
|
||||||
|
|
||||||
|
|
|
@ -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)))
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user