I have a question about the some built-in primitives. Is possible to use the built-ins: difference, min, max, sum also for DateTime types or it is better to create custom built-ins for this purpose? They work fine with integer and float but it seems not for DateTime types (or maybe the syntax I have used is wrong).
1 Answers
Your syntax isn't incorrect. First, we can jump over to Builtin
's javadoc in order to identify what Builtin
s exist.
Selecting Max
, as per your mention of it, can we go ahead and look up it's fully qualified class name on GrepCode. Once we get there, we notice that the parimary method that it implements is bodyCall(Node[], int, RuleContext)
, so let's take a look at it's implementation (as of 2.11.0
) and see why it's behaving the way it is:
@Override
public boolean bodyCall(Node[] args, int length, RuleContext context) {
checkArgs(length, context);
BindingEnvironment env = context.getEnv();
Node n1 = getArg(0, args, context);
Node n2 = getArg(1, args, context);
if (n1.isLiteral() && n2.isLiteral()) {
Object v1 = n1.getLiteralValue();
Object v2 = n2.getLiteralValue();
Node res = null;
if (v1 instanceof Number && v2 instanceof Number) {
Number nv1 = (Number)v1;
Number nv2 = (Number)v2;
if (v1 instanceof Float || v1 instanceof Double
|| v2 instanceof Float || v2 instanceof Double) {
res = (nv1.doubleValue() > nv2.doubleValue()) ? n1 : n2;
} else {
res = (nv1.longValue() > nv2.longValue()) ? n1 : n2;
}
return env.bind(args[2], res);
}
}
// Doesn't (yet) handle partially bound cases
return false;
}
The important thing to note here is that the method will only bind a value if once of the instances are a derivative of java.lang.Number
.
Note that if we look at the implementation (as of 2.11.0
) of LessThan#bodyCall(Node[], int, RuleContext)
, we can trace it's behavior to use of Util
that is sensitive to date/time objects.
If you have a rule that uses max(?a ?b ?c)
to bind the maximum value to ?c
, you can sometimes (if your rule has nice symmetry) use lessThan(?a ?b)
to just limit the ways in which the rule gets bound (thus, achieving the same result). In the lessThan
case, the rest of the rule can go on assuming that ?b
was the greater value, all along. Again, this requires that your rule have a nice symmetry that, elsewhere, allows the binding of ?a
and ?b
without other constraints.
If you need an equivalent of Max
that can use XSDDateTime
literals, then you, indeed, may have to make some yourself. Thankfully, as the code for these Builtin
s show, it can actually be quite easy to create them.
On a more philosohpical note, I am uncertain whether this was a conscious decision by the developers or if it was, perhaps, a small oversight. I imagine that the comparison utilities (Util
) used by LessThan
may actually be newer than the Max
builtin, so Max
wasn't implemented in terms of it.

- 2,693
- 16
- 22