Aggregation predicates for µkanren

Groups, window functions, sets and enumerations

test/project°: pass

(define (test/project° _)
  (⊦= '(4700 6500 5000 5700 5700 4400 4000 5500 5300 5300)
      (°->list/ground
        (fresh°
          (r)
          (fresh°
            (d e s)
            (empsalary° d e s)
            (project° ((s* s)) (=° r (+ s* 500))))))))
((eta 0.001) (memory #(12582912 2203064 1048576)) (stdout "") (stderr ""))

test/groupby°/empty: pass

The following table has been kept from the PostgreSQL documentation example on window functions PostgreSQL Window Functions:

  depname  | empno | salary |          avg
-----------+-------+--------+-----------------------
 develop   |    11 |   5200 | 5020.0000000000000000
 develop   |     7 |   4200 | 5020.0000000000000000
 develop   |     9 |   4500 | 5020.0000000000000000
 develop   |     8 |   6000 | 5020.0000000000000000
 develop   |    10 |   5200 | 5020.0000000000000000
 personnel |     5 |   3500 | 3700.0000000000000000
 personnel |     2 |   3900 | 3700.0000000000000000
 sales     |     3 |   4800 | 4866.6666666666666667
 sales     |     1 |   5000 | 4866.6666666666666667
 sales     |     4 |   4800 | 4866.6666666666666667
(10 rows)

with respect to the following query:

SELECT depname, empno, salary, avg(salary) OVER (PARTITION BY depname) FROM empsalary;
(define (test/groupby°/empty _)
  (⊦= '(47100)
      (°->list/ground
        (fresh°
          (r)
          (fresh°
            (d e s)
            (groupby°
              (((s* foldr/add) s))
              over
              ()
              from
              (empsalary° d e s)
              =>
              (=° r s*)))))))
((eta 0.001) (memory #(12582912 2216976 1048576)) (stdout "") (stderr ""))

test/groupby°/one-column: pass

(define (test/groupby°/one-column _)
  (⊦= '((personnel 7400) (sales 14600) (develop 25100))
      (sort (°->list/ground
              (fresh°
                (r)
                (fresh°
                  (d e s)
                  (groupby°
                    (((s* foldr/add) s))
                    over
                    (d)
                    from
                    (empsalary° d e s)
                    =>
                    (=° r `(,d ,s*))))))
            (λ (a b) (< (cadr a) (cadr b))))))
((eta 0.0) (memory #(12582912 2206368 1048576)) (stdout "") (stderr ""))

test/set°: pass

(define (test/set° _)
  (⊦= '((personnel 2) (sales 3) (develop 5))
      (sort (°->list/ground
              (fresh°
                (r)
                (fresh°
                  (d e s)
                  (set° (c (λ (k v) (add1 v)) 0)
                        over
                        ((d* d))
                        from
                        (empsalary° d e s)
                        =>
                        (=° r `(,d* ,c))))))
            (λ (a b) (< (cadr a) (cadr b))))))
((eta 0.001) (memory #(12582912 2208264 1048576)) (stdout "") (stderr ""))

test/enumerate°: pass

(define (test/enumerate° _)
  (⊦= '(((0 (develop))
         (1 (develop))
         (2 (develop))
         (3 (develop))
         (4 (develop))
         (5 (personnel))
         (6 (personnel))
         (7 (sales))
         (8 (sales))
         (9 (sales))))
      (°->list/ground
        (fresh°
          (r)
          (fresh°
            (d e s)
            (enumerate°
              (c (λ (i k) (list i (list k))))
              over
              (d)
              from
              (empsalary° d e s)
              =>
              (=° r c)))))))
((eta 0.001) (memory #(12582912 2222744 1048576)) (stdout "") (stderr ""))

test/window°: pass

(define (test/window° _)
  (⊦= '((develop 7 4200 5020)
        (develop 8 6000 5020)
        (develop 9 4500 5020)
        (develop 10 5200 5020)
        (develop 11 5200 5020)
        (personnel 2 3900 3700)
        (personnel 5 3500 3700)
        (sales 1 5000 14600/3)
        (sales 3 4800 14600/3)
        (sales 4 4800 14600/3))
      (°->list/ground
        (fresh°
          (r)
          (fresh°
            (d e s)
            (window°
              (((s* foldr/avg) s))
              over
              (d)
              from
              (empsalary° d e s)
              =>
              (=° r `(,d ,e ,s ,s*)))))))
  (⊦= '((develop 7 4200 4710)
        (develop 8 6000 4710)
        (develop 9 4500 4710)
        (develop 10 5200 4710)
        (develop 11 5200 4710)
        (personnel 2 3900 4710)
        (personnel 5 3500 4710)
        (sales 1 5000 4710)
        (sales 3 4800 4710)
        (sales 4 4800 4710))
      (°->list/ground
        (fresh°
          (r)
          (fresh°
            (d e s)
            (window°
              (((s* foldr/avg) s))
              over
              ()
              from
              (empsalary° d e s)
              =>
              (=° r `(,d ,e ,s ,s*))))))))
((eta 0.003) (memory #(12582912 2212208 1048576)) (stdout "") (stderr ""))