// If the comparand might be an empty sequence, do the base rewrite and then wrap the
// rewritten expression EXP in "let $n := comparand if exists($n) then EXP else ()
if (Cardinality.allowsZero(card)) {
LetExpression let = new LetExpression();
let.setRequiredType(SequenceType.makeSequenceType(comparand.getItemType(th), card));
let.setVariableQName(new StructuredQName("pp", NamespaceConstant.SAXON, "pp" + let.hashCode()));
let.setSequence(comparand);
comparand = new LocalVariableReference(let);
LocalVariableReference existsArg = new LocalVariableReference(let);
Exists exists = (Exists)SystemFunction.makeSystemFunction("exists", new Expression[]{existsArg});
Expression rewrite = tryToRewritePositionalFilterSupport(start, comparand, operator, th);
if (rewrite == null) {
return null;
}
Expression choice = Choose.makeConditional(exists, rewrite);
let.setAction(choice);
return let;
} else {
return tryToRewritePositionalFilterSupport(start, comparand, operator, th);
}
} else if (filter instanceof IntegerRangeTest) {
// rewrite SEQ[position() = N to M]
// => let $n := N return subsequence(SEQ, $n, (M - ($n - 1))
// (precise form is optimized for the case where $n is a literal, especially N = 1)
Expression val = ((IntegerRangeTest)filter).getValueExpression();
if (!(val instanceof Position)) {
return null;
}
Expression min = ((IntegerRangeTest)filter).getMinValueExpression();
Expression max = ((IntegerRangeTest)filter).getMaxValueExpression();
if (ExpressionTool.dependsOnFocus(min)) {
return null;
}
if (ExpressionTool.dependsOnFocus(max)) {
if (max instanceof Last) {
return SystemFunction.makeSystemFunction("subsequence", new Expression[]{start, min});
} else {
return null;
}
}
LetExpression let = new LetExpression();
let.setRequiredType(SequenceType.SINGLE_INTEGER);
let.setVariableQName(new StructuredQName("nn", NamespaceConstant.SAXON, "nn" + let.hashCode()));
let.setSequence(min);
min = new LocalVariableReference(let);
LocalVariableReference min2 = new LocalVariableReference(let);
Expression minMinusOne = new ArithmeticExpression(
min2, Token.MINUS, new Literal(IntegerValue.makeIntegerValue(1)));