|
389 | 389 | name)])) |
390 | 390 |
|
391 | 391 | ; make hash table |
392 | | - (define rules (make-hasheq)) |
393 | | - (define count 0) |
| 392 | + (define rules '()) |
| 393 | + (define rule-names (make-hasheq)) |
394 | 394 | (define commutes? #f) |
395 | 395 | (when identities |
396 | | - (for ([ident (in-list identities)]) |
397 | | - (match ident |
398 | | - [(list ident-name lhs-expr rhs-expr) |
399 | | - (cond |
400 | | - [(hash-has-key? rules ident-name) |
401 | | - (raise-herbie-syntax-error "Duplicate identity ~a" ident-name)] |
402 | | - [else |
403 | | - (hash-set! rules |
404 | | - (string->symbol (format "~a-~a" (symbol->string ident-name) name)) |
405 | | - (list lhs-expr |
406 | | - rhs-expr |
407 | | - (remove-duplicates (append (free-variables lhs-expr) |
408 | | - (free-variables rhs-expr)))))])] |
409 | | - [(list 'exact expr) |
410 | | - (hash-set! rules |
411 | | - (gensym (string->symbol (format "~a-exact-~a" name count))) |
412 | | - (list expr expr (free-variables expr))) |
413 | | - (set! count (+ count 1))] |
414 | | - [(list 'commutes) |
415 | | - (cond |
416 | | - [commutes? (raise-herbie-syntax-error "Commutes identity already defined")] |
417 | | - [(hash-has-key? rules (string->symbol (format "~a-commutes" name))) |
418 | | - (raise-herbie-syntax-error "Commutes identity already manually defined")] |
419 | | - [(not (equal? (length vars) 2)) |
420 | | - (raise-herbie-syntax-error "Cannot commute a non 2-ary operator")] |
421 | | - [else |
422 | | - (set! commutes? #t) |
423 | | - (hash-set! rules |
424 | | - (string->symbol (format "~a-commutes" name)) |
425 | | - (list `(,name ,@vars) `(,name ,@(reverse vars)) vars))])]))) |
| 396 | + (set! rules |
| 397 | + (for/list ([ident (in-list identities)] |
| 398 | + [i (in-naturals)]) |
| 399 | + (match ident |
| 400 | + [(list ident-name lhs-expr rhs-expr) |
| 401 | + (cond |
| 402 | + [(hash-has-key? rule-names ident-name) |
| 403 | + (raise-herbie-syntax-error "Duplicate identity ~a" ident-name)] |
| 404 | + [(not (well-formed? lhs-expr)) |
| 405 | + (raise-herbie-syntax-error "Ill-formed identity expression ~a" lhs-expr)] |
| 406 | + [(not (well-formed? rhs-expr)) |
| 407 | + (raise-herbie-syntax-error "Ill-formed identity expression ~a" rhs-expr)] |
| 408 | + [else |
| 409 | + (define rule-name (string->symbol (format "~a-~a" ident-name name))) |
| 410 | + (hash-set! rule-names rule-name #f) |
| 411 | + (list 'directed rule-name lhs-expr rhs-expr)])] |
| 412 | + [(list 'exact expr) |
| 413 | + (cond |
| 414 | + [(not (well-formed? expr)) |
| 415 | + (raise-herbie-syntax-error "Ill-formed identity expression ~a" expr)] |
| 416 | + [else |
| 417 | + (define rule-name (gensym (string->symbol (format "~a-exact-~a" name i)))) |
| 418 | + (hash-set! rule-names rule-name #f) |
| 419 | + (list 'exact rule-name expr)])] |
| 420 | + [(list 'commutes) |
| 421 | + (cond |
| 422 | + [commutes? (error "Commutes identity already defined")] |
| 423 | + [(hash-has-key? rule-names (string->symbol (format "~a-commutes" name))) |
| 424 | + (error "Commutes identity already manually defined")] |
| 425 | + [(not (equal? (length vars) 2)) |
| 426 | + (raise-herbie-syntax-error "Cannot commute a non 2-ary operator")] |
| 427 | + [else |
| 428 | + (set! commutes? #t) |
| 429 | + (define rule-name (string->symbol (format "~a-commutes" name))) |
| 430 | + (hash-set! rule-names rule-name #f) |
| 431 | + (list 'commutes rule-name `(,name ,@vars) `(,name ,@(reverse vars)))])])))) |
426 | 432 |
|
427 | 433 | ; update tables |
428 | 434 | (define impl (operator-impl name ctx spec fpcore* fl-proc* rules)) |
429 | 435 | (hash-set! operator-impls name impl)) |
430 | 436 |
|
431 | | -(define (free-variables prog) |
432 | | - (match prog |
433 | | - [(? literal?) '()] |
434 | | - [(? number?) '()] |
435 | | - [(? variable?) (list prog)] |
436 | | - [(approx _ impl) (free-variables impl)] |
437 | | - [(list _ args ...) (remove-duplicates (append-map free-variables args))])) |
| 437 | +(define (well-formed? expr) |
| 438 | + (match expr |
| 439 | + [(? number?) #t] |
| 440 | + [(? variable?) #t] |
| 441 | + [`(,impl ,args ...) (andmap well-formed? args)] |
| 442 | + [_ #f])) |
438 | 443 |
|
439 | 444 | (define-syntax (define-operator-impl stx) |
440 | 445 | (define (oops! why [sub-stx #f]) |
|
0 commit comments