Rule processing

The if-then-else behaviour of rules, whereby no further rules are processed once one has fired, is implemented using simple tail recursion:

declare function eval:rules(
  $rules as element(sch:rule)*,
  $prolog as xs:string?,
  $context as map(*)
)
as element()*
{
  if(empty($rules))
  then ()
  else
    let $result := eval:rule(head($rules), $prolog, $context)
    return if($result)
    then $result
    else eval:rules(tail($rules), $prolog, $context)
};

where the result of the eval:rule() call will be the empty sequence if no matching rule context exists.