sets.scm 9.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358
  1. #| -*-Scheme-*-
  2. Copyright (C) 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994,
  3. 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
  4. 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Massachusetts
  5. Institute of Technology
  6. This file is part of MIT/GNU Scheme.
  7. MIT/GNU Scheme is free software; you can redistribute it and/or modify
  8. it under the terms of the GNU General Public License as published by
  9. the Free Software Foundation; either version 2 of the License, or (at
  10. your option) any later version.
  11. MIT/GNU Scheme is distributed in the hope that it will be useful, but
  12. WITHOUT ANY WARRANTY; without even the implied warranty of
  13. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  14. General Public License for more details.
  15. You should have received a copy of the GNU General Public License
  16. along with MIT/GNU Scheme; if not, write to the Free Software
  17. Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301,
  18. USA.
  19. |#
  20. ;;;; Sets -- Implementation as ordered lists of symbols
  21. (declare (usual-integrations))
  22. ;;; The arguments determine the type of the elements.
  23. (define (make-sets-package set-equal-elements? set-less-elements?)
  24. (define the-empty-set '())
  25. (define set-empty? null?)
  26. (define set-first car)
  27. (define set-rest cdr)
  28. (define (set-singleton? s)
  29. (if (null? s) false (null? (cdr s))))
  30. (define (set-singleton x)
  31. (list x))
  32. (define (set-adjoin x set)
  33. (cond ((null? set) (list x))
  34. ((set-equal-elements? x (car set)) set)
  35. ((set-less-elements? x (car set)) (cons x set))
  36. (else (cons (car set) (set-adjoin x (cdr set))))))
  37. (define (set-remove x set)
  38. (cond ((null? set) '())
  39. ((set-equal-elements? x (car set)) (cdr set))
  40. ((set-less-elements? x (car set)) set)
  41. (else (cons (car set) (set-remove x (cdr set))))))
  42. (define (set-element? x set)
  43. (cond ((null? set) false)
  44. ((set-equal-elements? x (car set)) true)
  45. ((set-less-elements? x (car set)) false)
  46. (else (set-element? x (cdr set)))))
  47. (define (set-intersection set1 set2)
  48. (cond ((null? set1) '())
  49. ((null? set2) '())
  50. ((set-equal-elements? (car set1) (car set2))
  51. (cons (car set1) (set-intersection (cdr set1) (cdr set2))))
  52. ((set-less-elements? (car set1) (car set2))
  53. (set-intersection (cdr set1) set2))
  54. (else (set-intersection set1 (cdr set2)))))
  55. (define (set-union set1 set2)
  56. (cond ((null? set1) set2)
  57. ((null? set2) set1)
  58. ((set-equal-elements? (car set1) (car set2))
  59. (cons (car set1) (set-union (cdr set1) (cdr set2))))
  60. ((set-less-elements? (car set1) (car set2))
  61. (cons (car set1) (set-union (cdr set1) set2)))
  62. (else (cons (car set2) (set-union set1 (cdr set2))))))
  63. (define (set-difference set1 set2)
  64. (cond ((null? set2) set1)
  65. ((null? set1) '())
  66. ((set-equal-elements? (car set1) (car set2))
  67. (set-difference (cdr set1) (cdr set2)))
  68. ((set-less-elements? (car set2) (car set1))
  69. (set-difference set1 (cdr set2)))
  70. (else (cons (car set1) (set-difference (cdr set1) set2)))))
  71. (define (set-subset? s1 s2)
  72. (cond ((null? s1) true)
  73. ((null? s2) false)
  74. ((set-equal-elements? (car s1) (car s2))
  75. (set-subset? (cdr s1) (cdr s2)))
  76. ((set-less-elements? (car s1) (car s2)) false)
  77. (else (set-subset? s1 (cdr s2)))))
  78. (define (list->set lst)
  79. (define (remove-duplicates lst)
  80. (cond ((null? lst) lst)
  81. ((null? (cdr lst)) lst)
  82. ((set-equal-elements? (car lst) (cadr lst))
  83. (remove-duplicates (cdr lst)))
  84. (else
  85. (cons (car lst)
  86. (remove-duplicates (cdr lst))))))
  87. (remove-duplicates (sort lst set-less-elements?)))
  88. (define (set->list set) set)
  89. (vector the-empty-set
  90. set-empty?
  91. set-singleton
  92. set-singleton?
  93. set-adjoin
  94. set-remove
  95. set-element?
  96. set-intersection
  97. set-union
  98. set-difference
  99. set-subset?
  100. list->set
  101. set->list))
  102. (define (empty-set set-type) (vector-ref set-type 0))
  103. (define (empty-set? set-type) (vector-ref set-type 1))
  104. (define (singleton-set set-type) (vector-ref set-type 2))
  105. (define (singleton-set? set-type) (vector-ref set-type 3))
  106. (define (adjoin-set set-type) (vector-ref set-type 4))
  107. (define (remove-set set-type) (vector-ref set-type 5))
  108. (define (element-set? set-type) (vector-ref set-type 6))
  109. (define (intersect-sets set-type) (vector-ref set-type 7))
  110. (define (union-sets set-type) (vector-ref set-type 8))
  111. (define (difference-sets set-type) (vector-ref set-type 9))
  112. (define (subset-sets? set-type) (vector-ref set-type 10))
  113. (define (list->set set-type) (vector-ref set-type 11))
  114. (define (set->list set-type) (vector-ref set-type 12))
  115. (define symbols (make-sets-package eq? variable<?))
  116. (define real-numbers (make-sets-package = <))
  117. ;;; There is no nice way to compare complex numbers,
  118. ;;; but a kludge is necessary to impose order for
  119. ;;; sets of them.
  120. (define (<numbers z1 z2)
  121. (if (real? z1)
  122. (if (real? z2)
  123. (< z1 z2)
  124. #t)
  125. (if (real? z2)
  126. #f
  127. (cond ((< (real-part z1) (real-part z2))
  128. #t)
  129. ((= (real-part z1) (real-part z2))
  130. (< (imag-part z1) (imag-part z2)))
  131. (else #f)))))
  132. (define numbers (make-sets-package = <numbers))
  133. #|
  134. ;;; For example
  135. ((set->list symbols)
  136. ((union-sets symbols)
  137. ((list->set symbols) '(a c e))
  138. ((list->set symbols) '(d e f))))
  139. ;Value: (a c d e f)
  140. |#
  141. ;;;; Sets represented as unsorted lists of elements
  142. ;;; elements are tested with equal?
  143. (define (list-adjoin item list)
  144. (if (member item list)
  145. list
  146. (cons item list)))
  147. (define (list-union l1 l2)
  148. (cond ((null? l1) l2)
  149. ((member (car l1) l2)
  150. (list-union (cdr l1) l2))
  151. (else (cons (car l1)
  152. (list-union (cdr l1) l2)))))
  153. (define (list-intersection l1 l2)
  154. (cond ((null? l1) '())
  155. ((member (car l1) l2)
  156. (cons (car l1)
  157. (list-intersection (cdr l1) l2)))
  158. (else (list-intersection (cdr l1) l2))))
  159. (define (list-difference l1 l2)
  160. (cond ((null? l1) '())
  161. ((member (car l1) l2)
  162. (list-difference (cdr l1) l2))
  163. (else
  164. (cons (car l1)
  165. (list-difference (cdr l1) l2)))))
  166. (define (duplications? lst)
  167. (cond ((null? lst) false)
  168. ((member (car lst) (cdr lst)) true)
  169. (else (duplications? (cdr lst)))))
  170. (define (remove-duplicates list)
  171. (if (null? list)
  172. '()
  173. (let ((rest (remove-duplicates (cdr list))))
  174. (if (member (car list) rest)
  175. rest
  176. (cons (car list) rest)))))
  177. (define (subset? s1 s2)
  178. (if (null? s1)
  179. true
  180. (and (member (car s1) s2)
  181. (subset? (cdr s1) s2))))
  182. (define (same-set? s1 s2)
  183. (and (subset? s1 s2)
  184. (subset? s2 s1)))
  185. ;;;; eq-set utilities from Jinx
  186. (define-integrable (eq-set/make-empty)
  187. '())
  188. (define-integrable (eq-set/empty? set)
  189. (null? set))
  190. (define-integrable (eq-set/member? element set)
  191. (memq element set))
  192. (define-integrable (eq-set/adjoin element set)
  193. (if (eq-set/member? element set)
  194. set
  195. (cons element set)))
  196. (define (eq-set/remove element set)
  197. (if (not (eq-set/member? element set))
  198. set
  199. (delq element set)))
  200. ;; Important: This will return set2 itself (rather than a copy) if the
  201. ;; union is set2. Thus eq? can be used on the return value to
  202. ;; determine whether the set has grown.
  203. (define (eq-set/union set1 set2)
  204. (define (loop set new-elements)
  205. (if (null? new-elements)
  206. set
  207. (loop (eq-set/adjoin (car new-elements) set)
  208. (cdr new-elements))))
  209. ;; If set2 is smaller than set1, the union is guaranteed not to be set2.
  210. (if (< (length set2) (length set1))
  211. (loop set1 set2)
  212. (loop set2 set1)))
  213. (define (eq-set/intersection set1 set2)
  214. (define (examine set1 set2)
  215. (let process ((set #| (reverse set1) |# set1)
  216. (result (eq-set/make-empty)))
  217. (if (null? set)
  218. result
  219. (process (cdr set)
  220. (if (eq-set/member? (car set) set2)
  221. (cons (car set) result)
  222. result)))))
  223. (if (< (length set2) (length set1))
  224. (examine set2 set1)
  225. (examine set1 set2)))
  226. (define (eq-set/difference set1 set2)
  227. (if (null? set2)
  228. set1
  229. (let process ((set set1) (result (eq-set/make-empty)))
  230. (cond ((null? set)
  231. result)
  232. ((eq-set/member? (car set) set2)
  233. (process (cdr set) result))
  234. (else
  235. (process (cdr set)
  236. (cons (car set) result)))))))
  237. (define (eq-set/subset? set1 set2)
  238. (or (eq-set/empty? set1)
  239. (and (eq-set/member? (car set1) set2)
  240. (eq-set/subset? (cdr set1) set2))))
  241. (define (eq-set/equal? set1 set2)
  242. (or (eq? set1 set2)
  243. (and (eq-set/subset? set1 set2)
  244. (eq-set/subset? set2 set1))))
  245. ;;;; multi-set utilities from Jinx
  246. (define-integrable (multi-set/empty)
  247. '())
  248. (define-integrable (multi-set/adjoin element set)
  249. (cons element set))
  250. (define-integrable (multi-set/empty? set)
  251. (null? set))
  252. (define-integrable (multi-set/first set)
  253. (car set))
  254. (define-integrable (multi-set/rest set)
  255. (cdr set))
  256. (define-integrable (multi-set/remove element set)
  257. (delq-once element set))
  258. (define-integrable (multi-set/element? element set)
  259. (memq element set))
  260. (define-integrable (multi-set/union set1 set2)
  261. (%reverse set1 set2))
  262. (define (multi-set/intersection set1 set2)
  263. (define (process set1 set2 result)
  264. (cond ((multi-set/empty? set1)
  265. result)
  266. ((not (multi-set/element? (multi-set/first set1) set2))
  267. (process (multi-set/rest set1) set2 result))
  268. (else
  269. (process (multi-set/rest set1)
  270. (multi-set/remove (multi-set/first set1)
  271. set2)
  272. (multi-set/adjoin (multi-set/first set1)
  273. result)))))
  274. (if (< (length set2) (length set1))
  275. (process set2 set1 (multi-set/empty))
  276. (process set1 set2 (multi-set/empty))))
  277. (define (multi-set/difference set1 set2)
  278. (define (process set1 set2 result)
  279. (cond ((multi-set/empty? set1)
  280. result)
  281. ((multi-set/element? (multi-set/first set1) set2)
  282. (process (multi-set/rest set1)
  283. (multi-set/remove (multi-set/first set1) set2)
  284. result))
  285. (else
  286. (process (multi-set/rest set1)
  287. set2
  288. (multi-set/adjoin (multi-set/first set1)
  289. result)))))
  290. (process set1 set2 (multi-set/empty)))