improve judgment form performance in some situations when
ambiguous judgment forms lead to exponential blowup
This commit is contained in:
parent
41175d74be
commit
0416b8403d
|
@ -6,6 +6,7 @@
|
||||||
"error.rkt"
|
"error.rkt"
|
||||||
"search.rkt"
|
"search.rkt"
|
||||||
racket/trace
|
racket/trace
|
||||||
|
racket/list
|
||||||
racket/stxparam
|
racket/stxparam
|
||||||
"term-fn.rkt"
|
"term-fn.rkt"
|
||||||
"rewrite-side-conditions.rkt"
|
"rewrite-side-conditions.rkt"
|
||||||
|
@ -332,15 +333,30 @@
|
||||||
(apply trace-call form-name wrapped (assemble mode input spacers))
|
(apply trace-call form-name wrapped (assemble mode input spacers))
|
||||||
outputs)
|
outputs)
|
||||||
(form-proc form-proc input derivation-init)))
|
(form-proc form-proc input derivation-init)))
|
||||||
|
(remove-duplicates
|
||||||
(for/list ([v (in-list vecs)])
|
(for/list ([v (in-list vecs)])
|
||||||
(define subs (derivation-with-output-only-subs v))
|
(define subs (derivation-with-output-only-subs v))
|
||||||
(define rulename (derivation-with-output-only-name v))
|
(define rulename (derivation-with-output-only-name v))
|
||||||
(define this-output (derivation-with-output-only-output v))
|
(define this-output (derivation-with-output-only-output v))
|
||||||
(derivation-subs-acc
|
(derivation-subs-acc
|
||||||
(and subs (derivation (cons form-name (assemble mode input this-output))
|
(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
|
rulename
|
||||||
(reverse subs)))
|
"")
|
||||||
this-output)))
|
(if (include-entire-derivation)
|
||||||
|
(reverse subs)
|
||||||
|
'())))
|
||||||
|
this-output))))
|
||||||
|
|
||||||
|
(define include-entire-derivation (make-parameter #f))
|
||||||
|
|
||||||
(define (verify-name-ok orig-name the-name)
|
(define (verify-name-ok orig-name the-name)
|
||||||
(unless (symbol? the-name)
|
(unless (symbol? the-name)
|
||||||
|
@ -797,12 +813,13 @@
|
||||||
id-or-not)])
|
id-or-not)])
|
||||||
(check-judgment-arity stx judgment)
|
(check-judgment-arity stx judgment)
|
||||||
(syntax-property
|
(syntax-property
|
||||||
(if id-or-not
|
#`(parameterize ([include-entire-derivation #,derivation?])
|
||||||
|
#,(if id-or-not
|
||||||
#`(let ([#,id-or-not '()])
|
#`(let ([#,id-or-not '()])
|
||||||
#,main-stx)
|
#,main-stx)
|
||||||
#`(sort #,main-stx
|
#`(sort #,main-stx
|
||||||
string<=?
|
string<=?
|
||||||
#:key (λ (x) (format "~s" x))))
|
#:key (λ (x) (format "~s" x)))))
|
||||||
'disappeared-use
|
'disappeared-use
|
||||||
(syntax-local-introduce #'form-name)))]
|
(syntax-local-introduce #'form-name)))]
|
||||||
[(_ stx-name derivation? (not-form-name . _) . _)
|
[(_ stx-name derivation? (not-form-name . _) . _)
|
||||||
|
|
|
@ -2767,6 +2767,33 @@
|
||||||
(test (judgment-holds (Q (3 4) number_1) number_1)
|
(test (judgment-holds (Q (3 4) number_1) number_1)
|
||||||
'(14)))
|
'(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)])
|
(parameterize ([current-namespace (make-base-namespace)])
|
||||||
(eval '(require errortrace))
|
(eval '(require errortrace))
|
||||||
|
|
Loading…
Reference in New Issue
Block a user