Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 23s
Sum and product over a list of ground integers via fold + intarith. Empty list yields the identity (0 for sum, 1 for product). Recurse combines the head with the recursively-computed tail value via pluso-i / *o-i. 9 new tests, 481/481 cumulative.
112 lines
2.5 KiB
Plaintext
112 lines
2.5 KiB
Plaintext
;; lib/minikanren/intarith.sx — fast integer arithmetic via project.
|
|
;;
|
|
;; These are ground-only escapes into host arithmetic. They run at native
|
|
;; speed (host ints) but require their arguments to walk to actual numbers
|
|
;; — they are not relational the way `pluso` (Peano) is. Use them when
|
|
;; the puzzle size makes Peano impractical.
|
|
;;
|
|
;; Naming: `-i` suffix marks "integer-only" goals.
|
|
|
|
(define
|
|
pluso-i
|
|
(fn
|
|
(a b c)
|
|
(project
|
|
(a b)
|
|
(if (and (number? a) (number? b)) (== c (+ a b)) fail))))
|
|
|
|
(define
|
|
minuso-i
|
|
(fn
|
|
(a b c)
|
|
(project
|
|
(a b)
|
|
(if (and (number? a) (number? b)) (== c (- a b)) fail))))
|
|
|
|
(define
|
|
*o-i
|
|
(fn
|
|
(a b c)
|
|
(project
|
|
(a b)
|
|
(if (and (number? a) (number? b)) (== c (* a b)) fail))))
|
|
|
|
(define
|
|
lto-i
|
|
(fn
|
|
(a b)
|
|
(project
|
|
(a b)
|
|
(if (and (number? a) (and (number? b) (< a b))) succeed fail))))
|
|
|
|
(define
|
|
lteo-i
|
|
(fn
|
|
(a b)
|
|
(project
|
|
(a b)
|
|
(if (and (number? a) (and (number? b) (<= a b))) succeed fail))))
|
|
|
|
(define
|
|
neqo-i
|
|
(fn
|
|
(a b)
|
|
(project
|
|
(a b)
|
|
(if (and (number? a) (and (number? b) (not (= a b)))) succeed fail))))
|
|
|
|
(define numbero (fn (x) (project (x) (if (number? x) succeed fail))))
|
|
|
|
(define stringo (fn (x) (project (x) (if (string? x) succeed fail))))
|
|
|
|
(define symbolo (fn (x) (project (x) (if (symbol? x) succeed fail))))
|
|
|
|
(define
|
|
even-i
|
|
(fn (n) (project (n) (if (and (number? n) (even? n)) succeed fail))))
|
|
|
|
(define
|
|
odd-i
|
|
(fn (n) (project (n) (if (and (number? n) (odd? n)) succeed fail))))
|
|
|
|
(define
|
|
sortedo
|
|
(fn
|
|
(l)
|
|
(conde
|
|
((nullo l))
|
|
((fresh (a) (== l (list a))))
|
|
((fresh (a b rest mid) (conso a mid l) (conso b rest mid) (lteo-i a b) (sortedo mid))))))
|
|
|
|
(define
|
|
mino
|
|
(fn
|
|
(l m)
|
|
(conde
|
|
((fresh (a) (== l (list a)) (== m a)))
|
|
((fresh (a d rest-min) (conso a d l) (mino d rest-min) (conde ((lteo-i a rest-min) (== m a)) ((lto-i rest-min a) (== m rest-min))))))))
|
|
|
|
(define
|
|
maxo
|
|
(fn
|
|
(l m)
|
|
(conde
|
|
((fresh (a) (== l (list a)) (== m a)))
|
|
((fresh (a d rest-max) (conso a d l) (maxo d rest-max) (conde ((lteo-i rest-max a) (== m a)) ((lto-i a rest-max) (== m rest-max))))))))
|
|
|
|
(define
|
|
sumo
|
|
(fn
|
|
(l total)
|
|
(conde
|
|
((nullo l) (== total 0))
|
|
((fresh (a d rest-sum) (conso a d l) (sumo d rest-sum) (pluso-i a rest-sum total))))))
|
|
|
|
(define
|
|
producto
|
|
(fn
|
|
(l total)
|
|
(conde
|
|
((nullo l) (== total 1))
|
|
((fresh (a d rest-prod) (conso a d l) (producto d rest-prod) (*o-i a rest-prod total))))))
|