fix a very very old bug in Redex uncovered by the new enumerator
The new test case in this commit shows the bad behavior; the fix was to replace the regexp #rx".*[^0-9]([0-9]+)$" with #rx"([0-9]+)$", ie make the regexp work properly in the empty case (since regexps promise to find longest matches anyway). Also, Rackety
This commit is contained in:
parent
d722fa42df
commit
72b5010744
|
@ -1,44 +1,46 @@
|
|||
#lang racket/base
|
||||
(require racket/contract)
|
||||
(require racket/contract
|
||||
racket/set)
|
||||
|
||||
(define re:gen-d #rx".*[^0-9]([0-9]+)$")
|
||||
(define (variable-not-in sexp var)
|
||||
(let* ([var-str (symbol->string var)]
|
||||
[var-prefix (let ([m (regexp-match #rx"^(.*[^0-9])[0-9]+$" var-str)])
|
||||
(if m
|
||||
(cadr m)
|
||||
var-str))]
|
||||
[found-exact-var? #f]
|
||||
[nums (let loop ([sexp sexp]
|
||||
[nums null])
|
||||
(cond
|
||||
[(pair? sexp) (loop (cdr sexp) (loop (car sexp) nums))]
|
||||
[(symbol? sexp)
|
||||
(when (eq? sexp var)
|
||||
(set! found-exact-var? #t))
|
||||
(let* ([str (symbol->string sexp)]
|
||||
[match (regexp-match re:gen-d str)])
|
||||
(if (and match
|
||||
(is-prefix? var-prefix str))
|
||||
(cons (string->number (cadr match)) nums)
|
||||
nums))]
|
||||
[else nums]))])
|
||||
(cond
|
||||
[(not found-exact-var?) var]
|
||||
[(null? nums) (string->symbol (format "~a1" var))]
|
||||
[else (string->symbol (format "~a~a" var-prefix (find-best-number nums)))])))
|
||||
(define var-str (symbol->string var))
|
||||
(define var-prefix
|
||||
(let ([m (regexp-match #rx"^(.*[^0-9])[0-9]+$" var-str)])
|
||||
(if m
|
||||
(cadr m)
|
||||
var-str)))
|
||||
(define found-exact-var? #f)
|
||||
(define nums
|
||||
(let loop ([sexp sexp]
|
||||
[nums (set)])
|
||||
(cond
|
||||
[(pair? sexp) (loop (cdr sexp) (loop (car sexp) nums))]
|
||||
[(symbol? sexp)
|
||||
(when (equal? sexp var)
|
||||
(set! found-exact-var? #t))
|
||||
(define str (symbol->string sexp))
|
||||
(define match (regexp-match #rx"([0-9]+)$" str))
|
||||
(if (and match
|
||||
(is-prefix? var-prefix str))
|
||||
(set-add nums (string->number (list-ref match 1)))
|
||||
nums)]
|
||||
[else nums])))
|
||||
(cond
|
||||
[(not found-exact-var?) var]
|
||||
[(set-empty? nums) (string->symbol (format "~a1" var))]
|
||||
[else (string->symbol (format "~a~a" var-prefix (find-best-number nums)))]))
|
||||
|
||||
(define (find-best-number nums)
|
||||
(let loop ([sorted (sort nums <)]
|
||||
(let loop ([sorted (sort (set->list nums) <)]
|
||||
[i 1])
|
||||
(cond
|
||||
[(null? sorted) i]
|
||||
[else
|
||||
(let ([fst (car sorted)])
|
||||
(cond
|
||||
[(< i fst) i]
|
||||
[(> i fst) (loop (cdr sorted) i)]
|
||||
[(= i fst) (loop (cdr sorted) (+ i 1))]))])))
|
||||
(define fst (car sorted))
|
||||
(cond
|
||||
[(< i fst) i]
|
||||
[(> i fst) (loop (cdr sorted) i)]
|
||||
[(= i fst) (loop (cdr sorted) (+ i 1))])])))
|
||||
|
||||
(define (variables-not-in sexp vars)
|
||||
(let loop ([vars vars]
|
||||
|
@ -46,14 +48,16 @@
|
|||
(cond
|
||||
[(null? vars) null]
|
||||
[else
|
||||
(let ([new-var (variable-not-in sexp (car vars))])
|
||||
(cons new-var
|
||||
(loop (cdr vars)
|
||||
(cons new-var sexp))))])))
|
||||
(define new-var (variable-not-in sexp (car vars)))
|
||||
(cons new-var
|
||||
(loop (cdr vars)
|
||||
(cons new-var sexp)))])))
|
||||
|
||||
(define (is-prefix? str1 str2)
|
||||
(and (<= (string-length str1) (string-length str2))
|
||||
(equal? str1 (substring str2 0 (string-length str1)))))
|
||||
(for/and ([c1 (in-string str1)]
|
||||
[c2 (in-string str2)])
|
||||
(equal? c1 c2))))
|
||||
|
||||
(provide/contract
|
||||
[variable-not-in (any/c symbol? . -> . symbol?)]
|
||||
|
|
|
@ -2820,6 +2820,7 @@
|
|||
(term x4))
|
||||
(test (variable-not-in (term (x x1 x1 x2 x2)) 'x)
|
||||
(term x3))
|
||||
(test (variable-not-in (term (|| |1|)) '||) '|2|)
|
||||
|
||||
(test (variables-not-in (term (x y z)) '(x))
|
||||
'(x1))
|
||||
|
|
Loading…
Reference in New Issue
Block a user