[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

another operation

This page is part of the web mail archives of SRFI 60 from before July 7th, 2015. The new archives for SRFI 60 contain all messages, not just those from before July 7th, 2015.




Hello Aubrey,

Recently, I have been using bit-twiddling extensively for representing and manipulating
subsets of finite sets---one of the purposes you mention in the SRFI document.

Two remarks:

1. As it turns out, I frequently need the following operation missing in SRFI-60:

        (FOO x) ==> i         ; this is not my proposal for the procedure's name ;-)

        i >= 0 is the index of the least significant bit set in integer x in case x > 0,
        or in -x-1 if x < 0. If x = 0 then [choose: i = -1 OR (error ...) OR i = #f OR ...]
           In other words, i = max {k >= 0 : 2^k divides x} for x > 0.

Note that FOO can be terribly slow when implemented representation-agnostic,
while being lightning fast if the implementor has access to the actual machine words.

2. When scanning different libraries of bit-twiddling, I had stumbled across an implicit
design decision that is worth mentioning because it might swiftly break portability's neck:

        "What is the value of (LOGAND)?"

In my application I define (LOGAND) := 0 because the subsets my numbers represent
are finite from way back, their parents are finite, they stay finite and vote finite. However,
(LOGAND) := -1 also makes a lot of sense because -1 (= all bits set) is the neutral element
for bitwise AND---and one can even interpret negative numbers as the complements of
finite sets. (A concept that I later abandonned because the saved case distinctions do
not make up for the confusion this creates.)

Sebastian.


P.S. Just for information, here is the specification of the Bitset (BSET) data type I use.
It turned out to be useful, convenient, and complete for its purpose (which is of course
only one of the potential applications of bit-twiddling):

; Bitsets (BSET)
; ==============
;
; A bset s represents a subset S of a fixed set X = {x[0], .., x[n-1]}.
; The set X, called the universe, is implicit in the context and is
; only passed explicitly when bsets are constructed and the subsets
; they represent are accessed.
;
; For convenience, we even identify X with {0..n-1} and delegate the
; bijection between a general finite set of cardinality n and {0..n-1}
; to other data structures, e.g. search trees. A bset s is a non-negative
; integer of which the x-th bit is set if and only if x is an element of
; the set being represented by s.
;
; Naming convention:
;   n        : cardinality of the universe, exact integer, n >= 0
;   s, t, .. : bsets, i.e. exact integers in {0..2^n-1}
;   x, y, .. : elements of {0..n-1}
;
; Procedures:
;
; (bset? obj)               test if obj is exact non-negative integer
; (bset x ...)              smallest set containing the given elements
; (bset-full n)             the set {0..n-1}, n >= 0
; (bset-empty? s)           test if s = {}
; (bset-in? x s)            test if x in s
; (bset-equal? s t)         test if s = t
; (bset-compare s t)        -1 if s < t, 0 if s = t, 1 if s > t
; (bset-subset? s t)        test if s is a subset of t
; (bset-disjoint? s t)      test if s and t are disjoint
; (bset-size s)             number of elements of s
; (bset-min s)              minimal element of s, or #f if s is empty
; (bset-max s)              maximal element of s, or #f if s is empty
; (bset-union s ...)        union of the sets, (bset-union) = 0
; (bset-intersection s ...) intersection of the sets, (bset-intersection) = 0
; (bset-difference s t ...) difference of s and union of the t's
; (bset->list s)            list of elements in s in increasing order
;
; Macros using and extending SRFI-42 'Eager comprehensions':
;
; (bset-ec <qualifier>^* <element>)
;    the bset of the elements obtained by evaluating <element> for
;    each binding in the sequence defined by <qualifier>^*.
;
; (bset-union-ec <qualifier>^* <bset>)
;    the union of the bsets obtained by evaluating <bset> for each
;    binding in the sequence defined by the <qualifier>^*.
;
; (:bset <x> [ (index <i>) ] <bset>)
;    binds <x> in turn to each element in <bset>. The elements
;    of <bset> are enumerated in strictly increasing order.
;
; (:bset-in? <in?> [ (index <x>) ] [ <n> ] <bset>)
;    binds <in?> to #t if x is in <bset> and to #f otherwise.
;    The sequence enumerates all elements x in {0..<n>-1},
;    or in {0..max(<bset>)} if n is not provided, in strictly
;    increasing order.

----
Dr. Sebastian Egner
Senior Scientist
Philips Research Laboratories
Prof. Holstlaan 4 (postbox WY63, kamer WY 6-55)
5656 AA Eindhoven
The Netherlands
tel:       +31 40 27-42069
fax:      +31 40 27-42566
email: sebastian.egner@xxxxxxxxxxx