Set Literals
Empty Set
The empty set is a literal:
lisb=> #{} ;; B: {}
#{}
Enumeration Set
Sets can contain one or more elements. Note that in B, you may write duplicates that are removed (by putting them into a set). lisb, on the other hand, uses Clojure sets to represent a set, so duplicates yield an error in the reader.
lisb=> #{1 3 2} ;; B: {1, 3, 2}
#{1 3 2}
Comprehension Sets
Sets can also be created by providing a predicate that shall be fulfilled by the elements:
lisb=> (comprehension-set [:x] (and (< 0 :x 10) (= 0 (mod :x 2)))) ;; B: {x|0 < x & x < 10 & 0=x mod 2}
#{4 6 2 8}
lisb=> #{[:x] | (and (< 0 :x 10) (= 0 (mod :x 2)))} ;; B: {x|0 < x & x < 10 & 0=x mod 2}
#{4 6 2 8}
Subset Operators
The powerset POW
is the set of all subsets of the argument.
The POW1
operator does not include the empty set.
lisb=> (pow #{1 3 2}) ;; B: POW({1, 3, 2})
#{#{} #{3} #{2} #{1} #{1 3 2} #{1 3} #{1 2} #{3 2}}
lisb=> (pow1 #{1 3 2}) ;; B: POW1({1, 3, 2})
#{#{3} #{2} #{1} #{1 3 2} #{1 3} #{1 2} #{3 2}}
Similarly, all finite subsets are generated with the FIN
operator,
while FIN1
does also not include the empty set.
lisb=> (pow #{1 3 2}) ;; B: POW({1, 3, 2})
#{#{} #{3} #{2} #{1} #{1 3 2} #{1 3} #{1 2} #{3 2}}
lisb=> (pow1 #{1 3 2}) ;; B: POW1({1, 3, 2})
#{#{3} #{2} #{1} #{1 3 2} #{1 3} #{1 2} #{3 2}}
Cardinality / Size of Set
You can get the number of elements contained in a set by using card
:
lisb=> (card #{1 3 2}) ;; B: card({1, 3, 2})
3
Set Union, Intersection, Difference
lisb=> (union #{1 2} #{1 3}) ;; B: {1, 2}\/{1, 3}
#{1 3 2}
lisb=> (intersection #{1 3 2} #{4 3}) ;; B: {1, 3, 2}/\{4, 3}
#{3}
lisb=> (set- #{1 3 2} #{4 3}) ;; B: {1, 3, 2}\{4, 3}
#{1 2}
Membership Test
lisb=> (member? 1 #{1 3 2}) ;; B: 1:{1, 3, 2}
{} ;; TRUE, no bindings
lisb=> (member? 0 #{1 3 2}) ;; B: 0:{1, 3, 2}
nil ;; FALSE
lisb=> (contains? #{1 3 2} 1) ;; B: 1:{1, 3, 2}
{} ;; TRUE, no bindings
lisb=> (contains? #{1 3 2} 1 2) ;; B: 1:{1, 3, 2} & 2:{1, 3, 2}
{} ;; TRUE, no bindings
lisb=> (contains? #{1 3 2} 1 2 3 4) ;; B: 1:{1, 3, 2} & 2:{1, 3, 2} & 3:{1, 3, 2} & 4:{1, 3, 2}
nil ;; FALSE
B also has an operator to check that an element is not contained set.
In lisb, you wrap the member?
predicate in (not ...)
.
lisb=> (not (member? 42 #{1 3 2})) ;; B: 42/:{1, 3, 2}
{} ;; TRUE, no bindings
Subset Test
lisb=> (subset? #{1 2} nat-set) ;; B: {1, 2}<:NAT
{} ;; TRUE, no bindings
lisb=> (subset? #{1 4 3 2 5} nat-set) ;; B: {1, 4, 3, 2, 5}<:NAT
nil ;; FALSE
lisb=> (not (subset? #{1 4 3 2 5} nat-set)) ;; B: {1, 4, 3, 2, 5}/<:NAT
{} ;; TRUE, no bindings
lisb=> (superset? #{0 1 4 3 2 5} nat-set) ;; B: NAT<:{0, 1, 4, 3, 2, 5}
{} ;; TRUE, no bindings
lisb=> (strict-subset? #{0 1 3 2} nat-set) ;; B: {0, 1, 3, 2}<<:NAT
nil ;; FALSE
Generalised Operators
lisb=> (unite-sets #{#{4 3} #{1 2}}) ;; B: union({{4, 3}, {1, 2}})
#{1 4 3 2}
lisb=> (intersect-sets #{#{4 3 2} #{1 3 2}}) ;; B: inter({{4, 3, 2}, {1, 3, 2}})
#{3 2}
lisb=> (union-pe [:x] (subset? :x #{7 9 8}) #{(card :x)}) ;; B: UNION(x).(x<:{7, 9, 8}|{card(x)})
#{0 1 3 2}
lisb=> (intersection-pe [:x] (subset? :x #{7 9 8}) #{(card :x)}) ;; B: INTER(x).(x<:{7, 9, 8}|{card(x)})
#{}
Cartesian Product
lisb=> (cartesian-product #{1 2} #{4 3}) ;; B: {1, 2}*{4, 3}
#{[2 -> 4] [1 -> 4] [2 -> 3] [1 -> 3]}
Interval
lisb=> (interval 1 5) ;; B: 1..5
#{1 4 3 2 5}
lisb=> (range 1 5) ;; B: 1..pred(5)
#{1 4 3 2}