cisco / ChezScheme

Chez Scheme
Apache License 2.0
6.97k stars 984 forks source link

Bug in fixnum arithmetic #814

Closed olopierpa closed 7 months ago

olopierpa commented 7 months ago

Hello,

the following function works at every optimization level:

(define (problem-2018-08a)
  (with-open-advent-data-file (in 2018 8)
    (define (eval-subtree)
      (let* ((childs (read in))
             (metadata (read in)))
        (+ (let ((sum 0))   ;; this + to fx+
             (dotimes (i childs sum)
               (fxincvar! sum (eval-subtree))))
           (let ((sum 0))
             (dotimes (i metadata sum)
               (fxincvar! sum (read in)))))))
    (eval-subtree)))

if I replace the + at line 6 with fx+ then the function continues to work at optimization-level 0, but fails at level 3. All the numbers involved are surely fixnums. The macros dotimes and fxincvar! are defined in the obvious way[1], the macro with-open-advent-data-file just binds in to an open port.

I will try to reduce the code to a make it smaller and runnable. In the meantime: maybe the problem is already known? Suggestions about how to be more helpful?

If I change the define in line 3 to trace-define, at level 0 I get the correct: ... | | |(eval-subtree) | | | (eval-subtree) | | | 39 | | |47 | | |(eval-subtree) | | | (eval-subtree) | | | 37 | | |48 | | 147 | |851 | 4902 |46829 46829

at level 3 the function loops forever with trace: ... | | 24911 | | 24912 | | 24913 | | 24914 break>

Thanks!

;; (scheme-version "Chez Scheme Version 10.0.0") ;; (machine-type ta6nt)

==== [1]

(define-syntax dotimes
    (syntax-rules ()
      ((_ (var times) body ...)
       (dotimes (var times (void)) body ...))
      ((_ (var times result) body ...)
       (let ((t times))
         (let loop ((var 0))
           (cond ((fx< var t)
                  body ...
                  (loop (fx1+ var)))
                 (else result)))))))

  (define-syntax fxincvar!
    (syntax-rules ()
      ((_ var incr)
       (set! var (fx+ var incr)))
      ((_ var)
       (fxincvar! var 1))))
olopierpa commented 7 months ago

OK. I realized my mistake 1 minute after posting this.

Side effects and undefined evaluation order don't mix well.

Sorry :)