module namespace band ="http://www.cems.uwe.ac.uk/xmlwiki/band";
(: functions to define the behaviour of a BandMap structure :)
declare function band:band-for($bandmap as element(),$v as xs:decimal ) {
($bandmap/band[ $v >= xs:decimal(@min) ])[last()]
};
declare function band:is-bandMap($bandmap as element()) as xs:boolean {
(: invariant for a bandMap :)
(: there are at least 2 band elements :)
count($bandmap/band) >= 2 and
(: all band elements have an attribute 'min' castable to xs:decimal :)
(every $band in $bandmap/band satisfies $band/@min castable as xs:decimal )
and
(: the band mins are strictly ascending :)
(every $i in (1 to count($bandmap/band) -1 ) satisfies
(xs:decimal($bandmap/band[$i]/@min) < xs:decimal($bandmap/band[xs:integer($i )+ 1]/@min))
)
};
declare function band:safe-band-for($bandmap as element(), $v as item()) {
(: wrapper for band:band-for which checks pre-conditions and post-conditions,
returning an error if a violation has occured
:)
if ( band:is-bandMap($bandmap)
and $v castable as xs:decimal
and xs:decimal($v) >= xs:decimal( $bandmap/band[1]/@min))
then
let $band := band:band-for($bandmap,$v)
return
if ($band = $bandmap/band and xs:decimal($v) >= xs:decimal($band/@min)
and (every $higher in $bandmap/band[. is $band]/following-sibling::band
satisfies xs:decimal($v) < xs:decimal($higher/@min) )
and (every $lower in $bandmap/band[. is $band]/preceding-sibling::band
satisfies xs:decimal($v) > xs:decimal($lower/@min) ) )
then $band
else Post-condition failed
else Pre-condition failed
};