bitset.lisp 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364
  1. "This module implements bit sets"
  2. (import core/base (set-idx!))
  3. (import data/struct ())
  4. (import lua/math (ceil floor min max))
  5. (import math/bit32 ())
  6. (import lua/string (format))
  7. ;; This is questionable but 32 bits seems like a safe assumption
  8. (define bits-per-int :hidden 32)
  9. (defun bit->element (bit)
  10. :hidden
  11. (floor (/ bit bits-per-int)))
  12. (defun bit->element-index (bit)
  13. :hidden
  14. (mod bit bits-per-int))
  15. (defun ensure-bit-exists! (bs bit)
  16. :hidden
  17. (let* [(data (bitset-data bs))
  18. (need (- (+ (bit->element bit) 1) (n data)))]
  19. (when (> need 0)
  20. (for i 1 need 1
  21. (push! data 0)))))
  22. (defstruct (bitset make-bitset bitset?)
  23. "Creates a new, empty bitset"
  24. (fields
  25. (immutable (hide data)))
  26. (constructor new
  27. (lambda (other)
  28. (if (bitset? other)
  29. (new (map id (bitset-data other)))
  30. (new '())))))
  31. (defmethod (eq? bitset bitset) (x y)
  32. (let* [(dx (bitset-data x))
  33. (dy (bitset-data y))
  34. (ldx (n dx))
  35. (ldy (n dy))]
  36. (if (= ldx ldy)
  37. (with (result true)
  38. (for i 1 ldx 1
  39. (when (/= (nth dx i) (nth dy i))
  40. (set! result false)))
  41. result)
  42. false)))
  43. (defmethod (pretty bitset) (bs)
  44. (.. "«bitset: " (concat (map (lambda (x) (format "%08x" x)) (bitset-data bs)) " ") "»"))
  45. (defun get-bit (bs bit)
  46. "Returns the value of the bit in the bitset BS with the specified index BIT
  47. ### Example:
  48. ```cl
  49. > (define bs (make-bitset))
  50. out = «bitset: »
  51. > (set-bit! bs 5)
  52. out = nil
  53. > (get-bit bs 5)
  54. out = true
  55. ```"
  56. (assert-type! bs bitset)
  57. (let* [(data (bitset-data bs))
  58. (eindex (+ (bit->element bit) 1))]
  59. (if (<= eindex (n data))
  60. (bit-test (nth data eindex) (shl 1 (bit->element-index bit)))
  61. false)))
  62. (defun set-bit! (bs bit)
  63. "Sets the bit in the bitset BS with the specified index BIT
  64. ### Example:
  65. ```cl
  66. > (define bs (make-bitset))
  67. out = «bitset: »
  68. > (set-bit! bs 5)
  69. out = nil
  70. > bs
  71. out = «bitset: 00000020»
  72. ```"
  73. (assert-type! bs bitset)
  74. (ensure-bit-exists! bs bit)
  75. (let* [(data (bitset-data bs))
  76. (eindex (+ (bit->element bit) 1))
  77. (orig (nth data eindex))]
  78. (set-idx! data eindex (bit-or orig (shl 1 (bit->element-index bit))))))
  79. (defun clear-bit! (bs bit)
  80. "Clears the bit in the bitset BS with the specified index BIT
  81. ```cl
  82. > (define bs (make-bitset))
  83. out = «bitset: »
  84. > (set-bit! bs 5)
  85. out = nil
  86. > bs
  87. out = «bitset: 00000020»
  88. > (clear-bit! bs 5)
  89. out = nil
  90. > bs
  91. out = «bitset: 00000000»
  92. ```"
  93. (assert-type! bs bitset)
  94. (ensure-bit-exists! bs bit)
  95. (let* [(data (bitset-data bs))
  96. (eindex (+ (bit->element bit) 1))]
  97. (when (<= eindex (n data))
  98. (set-idx! data eindex (bit-and (nth data eindex) (bit-not (shl 1 (bit->element-index bit))))))))
  99. (defun set-bit-value! (bs bit value)
  100. "Sets the value of the bit in the bitset BS with the specified index BIT to VALUE
  101. ```cl
  102. > (define bs (make-bitset))
  103. out = «bitset: »
  104. > (set-bit-value! bs 2 true)
  105. out = nil
  106. > bs
  107. out = «bitset: 00000004»
  108. > (set-bit-value! bs 2 false)
  109. out = nil
  110. > bs
  111. out = «bitset: 00000000»"
  112. (if value
  113. (set-bit! bs bit)
  114. (clear-bit! bs bit)))
  115. (defun flip-bit! (bs bit)
  116. "Inverts the value of the bit in the bitset BS with the specified index BIT
  117. ### Example:
  118. ```cl
  119. > (define bs (make-bitset))
  120. out = «bitset: »
  121. > (flip-bit! bs 2)
  122. out = nil
  123. > bs
  124. out = «bitset: 00000004»
  125. > (flip-bit! bs 2)
  126. out = nil
  127. > bs
  128. out = «bitset: 00000000»
  129. ```"
  130. (assert-type! bs bitset)
  131. (ensure-bit-exists! bs bit)
  132. (let* [(data (bitset-data bs))
  133. (eindex (+ (bit->element bit) 1))
  134. (orig (nth data eindex))]
  135. (set-idx! data eindex (bit-xor orig (shl 1 (bit->element-index bit))))))
  136. (defun next-set-bit (bs start)
  137. "Finds the next set bit in the bitset BS at or after the index START. If no set bit is found, -1 is returned
  138. ### Example:
  139. ```cl
  140. > (define bs (make-bitset))
  141. out = «bitset: »
  142. > (set-bit! bs 5)
  143. out = nil
  144. > (next-set-bit bs 2)
  145. out = 5
  146. > (set-bit! bs 0)
  147. out = nil
  148. > (next-set-bit bs 0)
  149. out = 0
  150. ```"
  151. (assert-type! bs bitset)
  152. (let* [(data (bitset-data bs))
  153. (len (n data))
  154. (eindex (bit->element start))
  155. (result -1)]
  156. (demand (< eindex len))
  157. (while (and (= result -1) (< eindex len))
  158. (for i 0 (- bits-per-int 1) 1
  159. (with (j (+ (* eindex bits-per-int) i))
  160. (when (and (= result -1) (get-bit bs j) (>= j start))
  161. (set! result j))))
  162. (inc! eindex))
  163. result))
  164. (defun next-clear-bit (bs start)
  165. "Finds the next clear bit in the bitset BS at or after the index START. If no clear bit is found, -1 is returned
  166. ### Example:
  167. ```cl
  168. > (define bs (make-bitset))
  169. out = «bitset: »
  170. > (set-bit! bs 0)
  171. out = nil
  172. > (set-bit! bs 1)
  173. out = nil
  174. > (next-clear-bit bs 0)
  175. out = 2
  176. > (clear-bit! bs 0)
  177. out = nil
  178. > (next-clear-bit bs 0)
  179. out = 0
  180. ```"
  181. (assert-type! bs bitset)
  182. (let* [(data (bitset-data bs))
  183. (len (n data))
  184. (eindex (bit->element start))
  185. (result -1)]
  186. (demand (< eindex len))
  187. (while (and (= result -1) (< eindex len))
  188. (for i 0 (- bits-per-int 1) 1
  189. (with (j (+ (* eindex bits-per-int) i))
  190. (when (and (= result -1) (not (get-bit bs j)) (>= j start))
  191. (set! result j))))
  192. (inc! eindex))
  193. result))
  194. (defun cardinality (bs)
  195. "Returns the number of set bits in the bitset BS
  196. ### Example:
  197. ```cl
  198. > (define bs (make-bitset))
  199. out = «bitset: »
  200. > (set-bit! bs 1)
  201. out = nil
  202. > (set-bit! bs 4)
  203. out = nil
  204. > (cardinality bs)
  205. out = 2
  206. ```"
  207. (assert-type! bs bitset)
  208. (let* [(data (bitset-data bs))
  209. (count 0)]
  210. (for-each elem data
  211. (for i 0 (- bits-per-int 1) 1
  212. (when (bit-test elem (shl 1 i))
  213. (inc! count))))
  214. count))
  215. (defun intersects (x y)
  216. "Tests if two bitsets share any of the same set bits
  217. ### Example:
  218. ```cl
  219. > (define a (make-bitset))
  220. out = «bitset: »
  221. > (define b (make-bitset))
  222. out = «bitset: »
  223. > (set-bit! a 2)
  224. out = nil
  225. > (set-bit! b 2)
  226. out = nil
  227. > (intersects a b)
  228. out = true
  229. ```"
  230. (assert-type! x bitset)
  231. (assert-type! y bitset)
  232. (let* [(dx (bitset-data x))
  233. (dy (bitset-data y))
  234. (len (min (n dx) (n dy)))
  235. (result false)]
  236. (for i 1 len 1
  237. (when (bit-test (nth dx i) (nth dy i))
  238. (set! result true)))
  239. result))
  240. (defun bitsets-and (x y)
  241. "Performs a logical AND between two bitsets and returns the result as a new bitset
  242. ### Example:
  243. ```cl
  244. > (define a (make-bitset))
  245. out = «bitset: »
  246. > (define b (make-bitset))
  247. out = «bitset: »
  248. > (set-bit! a 2)
  249. out = nil
  250. > (set-bit! b 2)
  251. out = nil
  252. > (bitsets-and a b)
  253. out = «bitset: 00000004»
  254. ```"
  255. (assert-type! x bitset)
  256. (assert-type! y bitset)
  257. (let* [(result '())
  258. (dx (bitset-data x))
  259. (dy (bitset-data y))
  260. (len (min (n dx) (n dy)))]
  261. (for i 1 len 1
  262. (push! result (bit-and (nth dx i) (nth dy i))))
  263. (with (rbs (make-bitset))
  264. (.<! rbs :data result)
  265. rbs)))
  266. (defun bitsets-or (x y)
  267. "Performs a logical OR between two bitsets and returns the result as a new bitset
  268. ### Example:
  269. ```cl
  270. > (define a (make-bitset))
  271. out = «bitset: »
  272. > (define b (make-bitset))
  273. out = «bitset: »
  274. > (set-bit! a 0)
  275. out = nil
  276. > (set-bit! b 1)
  277. out = nil
  278. > (bitsets-or a b)
  279. out = «bitset: 00000003»
  280. ```"
  281. (assert-type! x bitset)
  282. (assert-type! y bitset)
  283. (let* [(result '())
  284. (dx (bitset-data x))
  285. (dy (bitset-data y))
  286. (xlen (n dx))
  287. (ylen (n dy))
  288. (len (max xlen ylen))]
  289. (for i 1 len 1
  290. (if (and (<= i xlen) (<= i ylen))
  291. (push! result (bit-or (nth dx i) (nth dy i)))
  292. (if (<= i xlen)
  293. (push! result (nth dx i))
  294. (push! result (nth dy i)))))
  295. (with (rbs (make-bitset))
  296. (.<! rbs :data result)
  297. rbs)))
  298. (defun bitsets-xor (x y)
  299. "Performs a logical XOR between two bitsets and returns the result as a new bitset
  300. ### Example:
  301. ```cl
  302. > (define a (make-bitset))
  303. out = «bitset: »
  304. > (define b (make-bitset))
  305. out = «bitset: »
  306. > (set-bit! a 0)
  307. out = nil
  308. > (set-bit! a 1)
  309. out = nil
  310. > (set-bit! b 1)
  311. out = nil
  312. > (bitsets-xor a b)
  313. out = «bitset: 00000001»
  314. ```"
  315. (assert-type! x bitset)
  316. (assert-type! y bitset)
  317. (let* [(result '())
  318. (dx (bitset-data x))
  319. (dy (bitset-data y))
  320. (xlen (n dx))
  321. (ylen (n dy))
  322. (len (max xlen ylen))]
  323. (for i 1 len 1
  324. (if (and (<= i xlen) (<= i ylen))
  325. (push! result (bit-xor (nth dx i) (nth dy i)))
  326. (if (<= i xlen)
  327. (push! result (nth dx i))
  328. (push! result (nth dy i)))))
  329. (with (rbs (make-bitset))
  330. (.<! rbs :data result)
  331. rbs)))