83 lines
No EOL
4.3 KiB
Text
83 lines
No EOL
4.3 KiB
Text
module namespace set = "http://qt4cg.org/atomic-set";
|
|
|
|
(:
|
|
This package defines a type set:atomic-set which represents
|
|
a set of distinct atomic items. Atomic items are considered
|
|
distinct based on the comparison function fn:atomic-equal.
|
|
|
|
An instance of an atomic set can be constructed using a function
|
|
call such as set:build((1, 3, 5, 7, 9)).
|
|
|
|
If $A and $B are instances of set:atomic-set, then they
|
|
can be manipulated using methods including:
|
|
|
|
$A=?>size() - returns the number of items in the set
|
|
$A=?>empty() - returns true if the set is empty
|
|
$A=?>contains($k) - determines whether $k is a member of the set
|
|
$A=?>contains-all($B) - returns true if $B is a subset of $A
|
|
$A=?>values() - returns the items in $A, as a sequence
|
|
$A=?>add($k) - returns a new atomic set containing an additional item
|
|
$A=?>remove($k) - returns a new atomic set in which the given item is absent
|
|
$A=?>union($B) - returns a new atomic set holding the union of $A and $B
|
|
$A=?>intersect($B) - returns a new atomic set holding the intersection of $A and $B
|
|
$A=?>except($B) - returns a new atomic set holding the difference of $A and $B
|
|
:)
|
|
|
|
declare %public record set:atomic-set (
|
|
_data as map(xs:anyAtomicType, xs:boolean),
|
|
size as fn($set as set:atomic-set) as xs:integer,
|
|
empty as fn($set as set:atomic-set) as xs:boolean,
|
|
contains as fn($set as set:atomic-set, $value as xs:anyAtomicType) as xs:boolean,
|
|
contains-all as fn($set as set:atomic-set, $value as set:atomic-set) as xs:boolean,
|
|
add as fn($set as set:atomic-set, $item as xs:anyAtomicType) as set:atomic-set,
|
|
remove as fn($set as set:atomic-set, $item as xs:anyAtomicType) as set:atomic-set,
|
|
union as fn($set as set:atomic-set, $value as set:atomic-set) as set:atomic-set,
|
|
intersect as fn($set as set:atomic-set, $value as set:atomic-set) as set:atomic-set,
|
|
except as fn($set as set:atomic-set, $value as set:atomic-set) as set:atomic-set,
|
|
* );
|
|
|
|
declare %private variable $DATA := "'_data'";
|
|
|
|
(:
|
|
The private function set:replaceData processes the internal map
|
|
by applying a supplied function, and returns a new atomic set
|
|
with the resulting internal map
|
|
:)
|
|
|
|
declare %private function set:replaceData (
|
|
$input as set:atomic-set,
|
|
$update as fn(map(*)) as map(*)) as map(xs:anyAtomicType, xs:boolean) {
|
|
|
|
map:put($input, $DATA, $update($input?$DATA))
|
|
}
|
|
|
|
declare %public function set:build (
|
|
$values as xs:anyAtomicType* := ()) {
|
|
|
|
{
|
|
_data:
|
|
map:build($values, values:=true#0, {'duplicates': 'use-first'}),
|
|
size: fn($set as set:atomic-set) as xs:integer
|
|
{ map:size($set?$DATA) },
|
|
empty: fn($set as set:atomic-set) as xs:boolean
|
|
{ map:empty($set?$DATA) },
|
|
contains: fn($set as set:atomic-set, $value as xs:anyAtomicType) as xs:boolean
|
|
{ map:contains($set?$DATA, $value) },
|
|
contains-all: fn($set as set:atomic-set, $other as set:atomic-set) as xs:boolean
|
|
{ every($other, map:contains($set?$DATA, ?)) },
|
|
values: fn($set as set:atomic-set) as xs:anyAtomicType*
|
|
{ keys($set?$DATA) },
|
|
add: fn($set as set:atomic-set, $value as xs:anyAtomicType) as xs:anyAtomicType*
|
|
{ set:replaceData($set, map:put(?, $value, true())) },
|
|
remove: fn($set as set:atomic-set, $value as xs:anyAtomicType) as xs:anyAtomicType*
|
|
{ set:replaceData($set, map:remove(?, $value)) },
|
|
union: fn($set as set:atomic-set, $other as set:atomic-set) as set:atomic-set
|
|
{ set:replaceData($set, fn($this) {map:merge(($this, $other?$DATA),
|
|
{'duplicates': 'use-first'})})
|
|
},
|
|
intersect: fn($set as set:atomic-set, $other as set:atomic-set) as set:atomic-set
|
|
{ set:replaceData($set, map:filter(?, $other?contains)) },
|
|
except: fn($set as set:atomic-set, $other as set:atomic-set) as set:atomic-set
|
|
{ set:replaceData($set, map:remove(?, $other?values())) }
|
|
}
|
|
}; |