On 15/02/12 17:29, benjamin jailly wrote:
Thank you for your reply Dave.
based on your advice, I'm trying to create a builtin in the form:
isNext(?seq, ?X, ?Y) that returns true if Y is the element right after X
in the rdf:seq seq.
So I extended the BaseBuiltin class and wrote my functions like this :
@Override
public boolean bodyCall(Node[] args, int length, RuleContext context) {
checkArgs(length, context);
Node seq = getArg(0, args, context);
Node n1 = getArg(1, args, context);
Node n2 = getArg(2, args, context);
return isNext(seq, n1, n2, context);
}
/**
* Return true if element2 is right after element1 in the seq
*/
protected static boolean isNext(Node node, Node element1, Node
element2, RuleContext context ) {
Model m = ModelFactory.createDefaultModel();
RDFNode seq = m.asRDFNode(node);
RDFNode elt1 = m.asRDFNode(element1);
RDFNode elt2 = m.asRDFNode(element2);
Creating a new model for each call to the builtin is a little expensive,
better to just work at the Node level.
if (seq == null || seq.equals(RDF.Nodes.nil) ||
!seq.canAs(Seq.class) ) {
m.close();
return false;
} else {
// get indexes of elt1 and elt2
int i1 = seq.as <http://seq.as>(Seq.class).indexOf(elt1);
int i2 = seq.as <http://seq.as>(Seq.class).indexOf(elt2);
System.out.println("res: " + i1 + "," + i2);
That won't work because the new empty model in which those RDFNodes sits
has no statements in it to support the indexOf operations.
It would be better to do the test by extracting the sequence number from
the URI of the Nodes.
[Note that one of the many complications with Seq is that the sequence
numbers need not be contiguous. That doesn't affect your builtin and
might not affect your rules if you have control over the data but if you
are expecting to process data "from the wild" then it will be something
to bear in mind.]
Dave