add 'side-condition' to define-judgment-form (it does not have an implicit

unquote like the other side-condition's do, but it is still useful
for typesetting purposes)
This commit is contained in:
Robby Findler 2012-01-14 14:50:25 -06:00
parent 599dda4745
commit b3c450ffc9
3 changed files with 60 additions and 23 deletions

View File

@ -273,6 +273,9 @@
(define-for-syntax (where-keyword? id) (define-for-syntax (where-keyword? id)
(or (free-identifier=? id #'where) (or (free-identifier=? id #'where)
(free-identifier=? id #'where/hidden))) (free-identifier=? id #'where/hidden)))
(define-for-syntax (side-condition-keyword? id)
(or (free-identifier=? id #'side-condition)
(free-identifier=? id #'side-condition/hidden)))
(define-for-syntax (split-by-mode xs mode) (define-for-syntax (split-by-mode xs mode)
(for/fold ([ins '()] [outs '()]) (for/fold ([ins '()] [outs '()])
@ -317,7 +320,7 @@
(free-identifier=? stx (quote-syntax ...)))) (free-identifier=? stx (quote-syntax ...))))
;; the withs, freshs, and side-conditions come in backwards order ;; the withs, freshs, and side-conditions come in backwards order
(define-for-syntax (bind-withs orig-name main lang lang-nts stx where-mode body names w/ellipses) (define-for-syntax (bind-withs orig-name main lang lang-nts stx where-mode body names w/ellipses side-condition-unquoted?)
(with-disappeared-uses (with-disappeared-uses
(let loop ([stx stx] (let loop ([stx stx]
[to-not-be-in main] [to-not-be-in main]
@ -356,9 +359,10 @@
(term-let ([names/ellipses x] ...) (term-let ([names/ellipses x] ...)
#,rest-body))))))))] #,rest-body))))))))]
[((-side-condition s ...) y ...) [((-side-condition s ...) y ...)
(or (free-identifier=? #'-side-condition #'side-condition) (side-condition-keyword? #'-side-condition)
(free-identifier=? #'-side-condition #'side-condition/hidden)) (if side-condition-unquoted?
#`(and s ... #,(loop #'(y ...) to-not-be-in env))] #`(and s ... #,(loop #'(y ...) to-not-be-in env))
#`(and (term s) ... #,(loop #'(y ...) to-not-be-in env)))]
[((fresh x) y ...) [((fresh x) y ...)
(identifier? #'x) (identifier? #'x)
#`(term-let ([x (variable-not-in #,to-not-be-in 'x)]) #`(term-let ([x (variable-not-in #,to-not-be-in 'x)])
@ -951,7 +955,8 @@
#`(list (cons #,(or computed-name #'none) #`(list (cons #,(or computed-name #'none)
(term #,to))) (term #,to)))
(syntax->list #'(names ...)) (syntax->list #'(names ...))
(syntax->list #'(names/ellipses ...)))) (syntax->list #'(names/ellipses ...))
#t))
(define test-case-body-code (define test-case-body-code
;; this contains some redundant code ;; this contains some redundant code
(bind-withs orig-name (bind-withs orig-name
@ -962,7 +967,8 @@
'predicate 'predicate
#'#t #'#t
(syntax->list #'(names ...)) (syntax->list #'(names ...))
(syntax->list #'(names/ellipses ...)))) (syntax->list #'(names/ellipses ...))
#t))
(with-syntax ([(lhs-w/extras (w/extras-names ...) (w/extras-names/ellipses ...)) (with-syntax ([(lhs-w/extras (w/extras-names ...) (w/extras-names/ellipses ...))
(rw-sc #`(side-condition #,from #,test-case-body-code))] (rw-sc #`(side-condition #,from #,test-case-body-code))]
[lhs-source (format "~a:~a:~a" [lhs-source (format "~a:~a:~a"
@ -1045,8 +1051,7 @@
(syntax->list #'(var ...))) (syntax->list #'(var ...)))
(loop (cdr extras)))] (loop (cdr extras)))]
[(-side-condition exp ...) [(-side-condition exp ...)
(or (free-identifier=? #'-side-condition #'side-condition) (side-condition-keyword? #'-side-condition)
(free-identifier=? #'-side-condition #'side-condition/hidden))
(cons (car extras) (loop (cdr extras)))] (cons (car extras) (loop (cdr extras)))]
[(-where x e) [(-where x e)
(where-keyword? #'-where) (where-keyword? #'-where)
@ -1496,7 +1501,8 @@
sc/b 'flatten sc/b 'flatten
#`(list (term #,rhs)) #`(list (term #,rhs))
(syntax->list names) (syntax->list names)
(syntax->list names/ellipses))) (syntax->list names/ellipses)
#t))
(syntax->list #'((stuff ...) ...)) (syntax->list #'((stuff ...) ...))
(syntax->list #'(rhs ...)) (syntax->list #'(rhs ...))
(syntax->list #'(lhs-names ...)) (syntax->list #'(lhs-names ...))
@ -1509,7 +1515,8 @@
sc/b 'predicate sc/b 'predicate
#`#t #`#t
(syntax->list names) (syntax->list names)
(syntax->list names/ellipses))) (syntax->list names/ellipses)
#t))
(syntax->list #'((stuff ...) ...)) (syntax->list #'((stuff ...) ...))
(syntax->list #'(rhs ...)) (syntax->list #'(rhs ...))
(syntax->list #'(lhs-names ...)) (syntax->list #'(lhs-names ...))
@ -1587,7 +1594,8 @@
((stuff ...) ...) ((stuff ...) ...)
#,(if relation? #,(if relation?
#'((raw-rhses ...) ...) #'((raw-rhses ...) ...)
#'(rhs ...))) #'(rhs ...))
#t)
lang lang
#t ;; multi-args? #t ;; multi-args?
'name 'name
@ -1877,7 +1885,7 @@
[judgment (syntax-case stx () [(_ judgment _) #'judgment])]) [judgment (syntax-case stx () [(_ judgment _) #'judgment])])
(check-judgment-arity stx judgment) (check-judgment-arity stx judgment)
#`(sort #,(bind-withs syn-err-name '() lang nts (list judgment) #`(sort #,(bind-withs syn-err-name '() lang nts (list judgment)
'flatten #`(list (term #,#'tmpl)) '() '()) 'flatten #`(list (term #,#'tmpl)) '() '() #f)
string<=? string<=?
#:key (λ (x) (format "~s" x))))] #:key (λ (x) (format "~s" x))))]
[(_ (not-form-name . _) . _) [(_ (not-form-name . _) . _)
@ -1911,7 +1919,8 @@
(bind-withs syn-error-name '() lang nts (syntax->list #'prems) (bind-withs syn-error-name '() lang nts (syntax->list #'prems)
'flatten #`(list (term (#,@output-pats))) 'flatten #`(list (term (#,@output-pats)))
(syntax->list #'(names ...)) (syntax->list #'(names ...))
(syntax->list #'(names/ellipses ...)))) (syntax->list #'(names/ellipses ...))
#f))
#`(let ([compiled-lhs (compile-pattern #,lang `lhs #t)] #`(let ([compiled-lhs (compile-pattern #,lang `lhs #t)]
[compiled-input-ctcs #,(contracts-compilation input-contracts)] [compiled-input-ctcs #,(contracts-compilation input-contracts)]
[compiled-output-ctcs #,(contracts-compilation output-contracts)]) [compiled-output-ctcs #,(contracts-compilation output-contracts)])
@ -1956,7 +1965,7 @@
(for/list ([prems (syntax->list #'(prems ...))]) (for/list ([prems (syntax->list #'(prems ...))])
(reverse (syntax->list prems)))] (reverse (syntax->list prems)))]
[no-rhss (map (λ (_) '()) clauses)]) [no-rhss (map (λ (_) '()) clauses)])
#`(generate-lws #t (conc-body ...) #,(lhs-lws clauses) #,rev-premss #,no-rhss))])) #`(generate-lws #t (conc-body ...) #,(lhs-lws clauses) #,rev-premss #,no-rhss #f))]))
(define (check-judgment-form-contract form-name terms contracts mode modes) (define (check-judgment-form-contract form-name terms contracts mode modes)
(define description (define description
@ -2025,6 +2034,10 @@
(begin (begin
(tmpl-pos #'tmpl acc) (tmpl-pos #'tmpl acc)
(pat-pos #'pat acc))] (pat-pos #'pat acc))]
[(-side-condition tmpl)
(side-condition-keyword? #'-side-condition)
(begin (tmpl-pos #'tmpl acc)
acc)]
[(form-name . _) [(form-name . _)
(if (judgment-form-id? #'form-name) (if (judgment-form-id? #'form-name)
(let-values ([(prem-in prem-out) (split-body prem)]) (let-values ([(prem-in prem-out) (split-body prem)])
@ -2036,14 +2049,14 @@
(for ([pos conc-out]) (tmpl-pos pos acc-out)) (for ([pos conc-out]) (tmpl-pos pos acc-out))
acc-out)])) acc-out)]))
(for ([clause clauses]) (for ([clause clauses])
(define do-tmpl (define do-tmpl
(check-template (check-template
(fold-clause (bind 'rhs-only) void (make-immutable-free-id-table) clause))) (fold-clause (bind 'rhs-only) void (make-immutable-free-id-table) clause)))
(fold-clause (bind 'rhs-only) do-tmpl (make-immutable-free-id-table) clause))) (fold-clause (bind 'rhs-only) do-tmpl (make-immutable-free-id-table) clause)))
(define-syntax (generate-lws stx) (define-syntax (generate-lws stx)
(syntax-case stx () (syntax-case stx ()
[(_ relation? seq-of-lhs seq-of-lhs-for-lw seq-of-tl-side-cond/binds seq-of-rhs) [(_ relation? seq-of-lhs seq-of-lhs-for-lw seq-of-tl-side-cond/binds seq-of-rhs side-condition-unquoted?)
(with-syntax (with-syntax
([(rhs/lw ...) ([(rhs/lw ...)
(syntax-case #'relation? () (syntax-case #'relation? ()
@ -2082,7 +2095,9 @@
#,(to-lw/proc #'pat) #,(to-lw/proc #'exp))] #,(to-lw/proc #'pat) #,(to-lw/proc #'exp))]
[(side-condition x) [(side-condition x)
#`(make-metafunc-extra-side-cond #`(make-metafunc-extra-side-cond
#,(to-lw/uq/proc #'x))] #,(if (syntax-e #'side-condition-unquoted?)
(to-lw/uq/proc #'x)
(to-lw/proc #'x)))]
[maybe-ellipsis [maybe-ellipsis
(ellipsis? #'maybe-ellipsis) (ellipsis? #'maybe-ellipsis)
(to-lw/proc #'maybe-ellipsis)])) (to-lw/proc #'maybe-ellipsis)]))

View File

@ -1101,7 +1101,7 @@ legtimate inputs according to @racket[metafunction-name]'s contract,
and @racket[#f] otherwise. and @racket[#f] otherwise.
} }
@defform/subs[#:literals (I O where where/hidden etc.) @defform/subs[#:literals (I O where where/hidden side-condition side-condition/hidden etc.)
(define-judgment-form language (define-judgment-form language
option ... option ...
rule ...) rule ...)
@ -1121,7 +1121,9 @@ and @racket[#f] otherwise.
[conclusion (form-id pat/term ...)] [conclusion (form-id pat/term ...)]
[premise (code:line (judgment-form-id pat/term ...) maybe-ellipsis) [premise (code:line (judgment-form-id pat/term ...) maybe-ellipsis)
(where @#,ttpattern @#,tttterm) (where @#,ttpattern @#,tttterm)
(where/hidden @#,ttpattern @#,tttterm)] (where/hidden @#,ttpattern @#,tttterm)
(side-condition @#,tttterm)
(side-condition/hidden @#,tttterm)]
[pat/term @#,ttpattern [pat/term @#,ttpattern
@#,tttterm] @#,tttterm]
[maybe-ellipsis (code:line) [maybe-ellipsis (code:line)
@ -1205,6 +1207,12 @@ A rule's @racket[where] and @racket[where/hidden] premises behave as in
(judgment-holds (gt (s (s z)) (s z))) (judgment-holds (gt (s (s z)) (s z)))
(judgment-holds (gt (s z) (s z)))] (judgment-holds (gt (s z) (s z)))]
A rule's @racket[side-condition] and @racket[side-condition/hidden] premises are similar
to those in @racket[reduction-relation] and @racket[define-metafunction], except that
they do not implicitly unquote their right-hand sides. In other words, a premise
of the form @racket[(side-condition exp)] is equivalent to the premise
@racket[(where #t exp)], except it does not typeset with the ``#t = '', as that would.
A literal ellipsis may follow a judgment premise when a template in one of the A literal ellipsis may follow a judgment premise when a template in one of the
judgment's input positions contains a pattern variable bound at ellipsis-depth judgment's input positions contains a pattern variable bound at ellipsis-depth
one. one.
@ -2311,7 +2319,7 @@ This function sets @racket[dc-for-text-size]. See also
Like @racket[render-metafunction] but for judgment forms. Like @racket[render-metafunction] but for judgment forms.
This function sets @racket[dc-for-text-size]. See also This function sets @racket[dc-for-text-size]. See also
@racket[relation->pict]. @racket[judgment-form->pict].
} }
@defform[(relation->pict relation-name)]{ @defform[(relation->pict relation-name)]{

View File

@ -2215,6 +2215,20 @@
}))) })))
(let ()
(define-judgment-form empty-language
#:mode (R I I)
[(side-condition (different any_a any_b))
-----
(R any_a any_b)])
(define-metafunction empty-language
[(different any_a any_a) #f]
[(different any_a any_b) #t])
(test (judgment-holds (R 1 2)) #t)
(test (judgment-holds (R 1 1)) #f))
(parameterize ([current-namespace (make-base-namespace)]) (parameterize ([current-namespace (make-base-namespace)])
(eval '(require errortrace)) (eval '(require errortrace))
(eval '(require redex/reduction-semantics)) (eval '(require redex/reduction-semantics))