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:
Robby Findler 2014-03-29 20:20:12 -05:00
parent d722fa42df
commit 72b5010744
2 changed files with 42 additions and 37 deletions

View File

@ -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)])
(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))]
[found-exact-var? #f]
[nums (let loop ([sexp sexp]
[nums null])
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 (eq? sexp var)
(when (equal? sexp var)
(set! found-exact-var? #t))
(let* ([str (symbol->string sexp)]
[match (regexp-match re:gen-d str)])
(define str (symbol->string sexp))
(define match (regexp-match #rx"([0-9]+)$" str))
(if (and match
(is-prefix? var-prefix str))
(cons (string->number (cadr match)) nums)
nums))]
[else nums]))])
(set-add nums (string->number (list-ref match 1)))
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)))])))
[(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)])
(define fst (car sorted))
(cond
[(< i fst) i]
[(> i fst) (loop (cdr sorted) i)]
[(= i fst) (loop (cdr sorted) (+ i 1))]))])))
[(= 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))])
(define new-var (variable-not-in sexp (car vars)))
(cons new-var
(loop (cdr vars)
(cons new-var sexp))))])))
(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?)]

View File

@ -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))