; add
(assert (= (+ 1 2 3) 6))
(assert (= (+) 0))
(assert (= (+ 1) 1))

; sub
(assert (= (- 1) -1))
(assert (= (- 1 2) -1))

; mul
(assert (= (*) 1))
(assert (= (* 2) 2))
(assert (= (* 2 3 4) 24))

; div
(assert (= (/ 1 0) #inf))
(assert (= (/ -1 0) -#inf))
(assert (= (/ 6 2) 3))
(assert (= (/ 12 3 2) 2))
(assert (= (/ 6 4) (/ 3 2)))
(assert (= (/ 4) (/ 25 100))) ; reciprocal

; rem
(assert (= (% 6 2) 0))
(assert (= (% 6 4) 2))

;;;; NaN/infinity handling
(assert (≠ #nan #nan))
(assert (= #inf #inf))
(assert (≠ -#inf #inf))
(assert (> #inf 0 -#inf))

;;;; Ordering
(assert (< 1 2 3))
(assert (not (< 1 1 2 3)))
(assert (<= 1 1 2 3 3))
(assert (> 3 2 1))
(assert (not (> 3 3 2 1)))
(assert (>= 3 3 2 1))

(assert (= 1 1 1 1))
(assert (not (= 1 1 2 1)))

(assert (≠ 1 2 3 4))
(assert (not (≠ 1 2 2 3)))

;;;; Logic
(assert (and #t #t 1))
(assert (not (and #t #f 1)))
(assert (not (or nil 0 #f)))
; (and ...) and (or ...) must short-circuit
; (and ...) and (or ...) must not double-evaluate
(setq no-double-eval-and 0)
(setq no-double-eval-or 0)
(and
  #t
  (progn
    (setq no-double-eval-and (+ no-double-eval-and 1))
    #t
    )
  #f
  (error "(and ...) must short-circuit after #F"))
(or
  #f
  (progn
    (setq no-double-eval-or (+ no-double-eval-or 1))
    #t
    )
  #t
  (error "(or ...) must short-circuit after #T"))
(assert (= no-double-eval-and 1))
(assert (= no-double-eval-or 1))
