improve judgment form performance in some situations when

ambiguous judgment forms lead to exponential blowup
This commit is contained in:
Robby Findler 2014-07-25 18:37:14 -05:00
parent 41175d74be
commit 0416b8403d
2 changed files with 59 additions and 15 deletions

View File

@ -6,6 +6,7 @@
"error.rkt"
"search.rkt"
racket/trace
racket/list
racket/stxparam
"term-fn.rkt"
"rewrite-side-conditions.rkt"
@ -332,15 +333,30 @@
(apply trace-call form-name wrapped (assemble mode input spacers))
outputs)
(form-proc form-proc input derivation-init)))
(for/list ([v (in-list vecs)])
(define subs (derivation-with-output-only-subs v))
(define rulename (derivation-with-output-only-name v))
(define this-output (derivation-with-output-only-output v))
(derivation-subs-acc
(and subs (derivation (cons form-name (assemble mode input this-output))
rulename
(reverse subs)))
this-output)))
(remove-duplicates
(for/list ([v (in-list vecs)])
(define subs (derivation-with-output-only-subs v))
(define rulename (derivation-with-output-only-name v))
(define this-output (derivation-with-output-only-output v))
(derivation-subs-acc
(and subs (derivation (cons form-name (assemble mode input this-output))
;; just drop the subderivations
;; and the name when we know we
;; won't be using them.
;; this lets the remove-duplicates
;; call just above do something
;; and possibly avoid exponential blowup
(if (include-entire-derivation)
rulename
"")
(if (include-entire-derivation)
(reverse subs)
'())))
this-output))))
(define include-entire-derivation (make-parameter #f))
(define (verify-name-ok orig-name the-name)
(unless (symbol? the-name)
@ -797,12 +813,13 @@
id-or-not)])
(check-judgment-arity stx judgment)
(syntax-property
(if id-or-not
#`(let ([#,id-or-not '()])
#,main-stx)
#`(sort #,main-stx
string<=?
#:key (λ (x) (format "~s" x))))
#`(parameterize ([include-entire-derivation #,derivation?])
#,(if id-or-not
#`(let ([#,id-or-not '()])
#,main-stx)
#`(sort #,main-stx
string<=?
#:key (λ (x) (format "~s" x)))))
'disappeared-use
(syntax-local-introduce #'form-name)))]
[(_ stx-name derivation? (not-form-name . _) . _)

View File

@ -2767,6 +2767,33 @@
(test (judgment-holds (Q (3 4) number_1) number_1)
'(14)))
(let ()
(define-judgment-form empty-language
#:mode (J I)
[(D any_x) ...
--------------
(J (any_x ...))])
(define-judgment-form empty-language
#:mode (D I)
[----------- nat
(D natural)]
[----------- num
(D number)])
;; this test is designed to check to see if we are
;; avoiding an exponential blow up. On my laptop,
;; a list of length 14 was taking 2 seconds before
;; the fix and 1 msec afterwards. After the fix,
;; a list of length 100 (as below) was also taking
;; no time.
(define-values (_ cpu real gc)
(time-apply
(λ ()
(judgment-holds (J ,(build-list 100 add1))))))
(test (< cpu 1000) #t))
(parameterize ([current-namespace (make-base-namespace)])
(eval '(require errortrace))