} else if (node instanceof Node_ANY) { return null; } else if (Functor.isFunctor(node)) { Functor functor = (Functor)node.getLiteralValue(); if (functor.isGround()) return node; Node[] args = functor.getArgs(); List<Node> boundargs = new ArrayList<>(args.length); for ( Node arg : args ) Functor newf = new Functor(functor.getName(), boundargs, functor.getImplementor()); return Functor.makeFunctorNode( newf ); } else { return node;
/** * Clone a functor, cloning any embedded variables. */ private Functor cloneFunctor(Functor f, Map<Node_RuleVariable, Node> vmap, BindingEnvironment env) { Node[] args = f.getArgs(); Node[] cargs = new Node[args.length]; for (int i = 0; i < args.length; i++) { cargs[i] = cloneNode(args[i], vmap, env); } Functor fn = new Functor(f.getName(), cargs, f.getImplementor()); fn.setImplementor(f.getImplementor()); return fn; }
/** * Check if a rule from the conflict set is still OK to fire. * Just checks the non-monotonic guards such as noValue. */ public boolean shouldStillFire() { // Check any non-pattern clauses for (int i = 0; i < rule.bodyLength(); i++) { Object clause = rule.getBodyElement(i); if (clause instanceof Functor) { Builtin builtin = ((Functor)clause).getImplementor(); if (builtin != null && !builtin.isMonotonic()) { if (!((Functor)clause).evalAsBodyClause(this)) { return false; } } } } return true; }
/** * Create a functor and wrap it up as a Literal node * @param name the name of the functor * @param args an array of nodes defining the arguments, this will not be copied so beware of * accidental structure sharing */ public static Node makeFunctorNode(String name, Node[] args) { return makeFunctorNode( new Functor( name, args, BuiltinRegistry.theRegistry ) ); }
private static Functor makePropertyAssertionFunctor(final Node p) { final Functor f = new Functor("isNotSubClass", new Node[] { p, PRED_SUB }); f.setImplementor(NOT_EQUAL); return f; }
/** * Check that the object of a triple match corresponds to the given functor pattern. * Side effects the variable bindings. */ public boolean functorMatch(Triple t, LPInterpreter interpreter) { Node o = t.getObject(); if (!Functor.isFunctor(o)) return false; Functor f = (Functor)o.getLiteralValue(); if ( ! f.getName().equals(objectFunctor.getName())) return false; if ( f.getArgLength() != objectFunctor.getArgLength()) return false; Node[] fargs = f.getArgs(); Node[] oFargs = objectFunctor.getArgs(); for (int i = 0; i < fargs.length; i++) { if (!interpreter.unify(oFargs[i], fargs[i])) return false; } return true; }
/** * Emit code for a call to a built-in predicate (functor). * @param functor the built-in to be invoked. */ void emitBody(Functor functor) { Node[] fargs = functor.getArgs(); Builtin builtin = functor.getImplementor(); if (builtin == null) { throw new LPRuleSyntaxException("Unknown builtin operation " + functor.getName(), rule); } if (builtin.getArgLength() != 0 && builtin.getArgLength() != fargs.length) { throw new LPRuleSyntaxException("Wrong number of arguments to functor " + functor.getName() + " : got " + functor.getArgLength() + " : expected " + builtin.getArgLength(), rule); } for (int i = 0; i < fargs.length; i++) { Node node = fargs[i]; // We optionally force an eager dereference of variables here. // We used to force this but the current builtin implementations // now robust against it (the do a deref themselves anyway). emitBodyPut(node, i, true); } code[p++] = CALL_BUILTIN; code[p++] = (byte)fargs.length; args.add(builtin); }
/** * Test if a pattern is just a variant of this pattern. I.e. it is the same * up to variable renaming. This takes into account multiple occurances * of the same variable. */ public boolean variantOf(TriplePattern pattern) { Map<Node, Node> vmap = CollectionFactory.createHashedMap(); if ( ! variantOf(subject, pattern.subject, vmap) ) return false; if ( ! variantOf(predicate, pattern.predicate, vmap) ) return false; if (Functor.isFunctor(object) && Functor.isFunctor(pattern.object)) { Functor functor = (Functor)object.getLiteralValue(); Functor pFunctor = (Functor)pattern.object.getLiteralValue(); if ( ! functor.getName().equals(pFunctor.getName()) ) return false; Node[] args = functor.getArgs(); Node[] pargs = pFunctor.getArgs(); if ( args.length != pargs.length ) return false; for (int i = 0; i < args.length; i++) { if ( ! variantOf(args[i], pargs[i], vmap) ) return false; } return true; } else { return variantOf(object, pattern.object, vmap); } }
if (clause instanceof Functor) { if (!((Functor)clause).evalAsBodyClause(context)) { return false; // guard failed Builtin imp = f.getImplementor(); if (imp != null) { imp.headAction(f.getBoundArgs(env), f.getArgLength(), context); } else { throw new ReasonerException("Invoking undefined Functor " + f.getName() +" in " + rule.toShortString()); TriplePattern clause = (TriplePattern) clausesCopy.remove(index); Node objPattern = env.getBinding(clause.getObject()); if (Functor.isFunctor(objPattern)) {
throw new ParserException("Triple with " + nodes.size() + " nodes!", this); if (Functor.isFunctor(nodes.get(0))) { throw new ParserException("Functors not allowed in subject position of pattern", this); if (Functor.isFunctor(nodes.get(1))) { throw new ParserException("Functors not allowed in predicate position of pattern", this); String name = nextToken(); List<Node> args = parseNodeList(); Functor clause = new Functor(name, args, registry); if (clause.getImplementor() == null) {
/** * Test functor usage. */ public void testFunctors1() { String ruleSrc = "[r1: (?x s ?y) <- (?x p foo(?z, ?y))] "; Triple[] triples = new Triple[] { new Triple(a, p, Functor.makeFunctorNode("foo", new Node[] {C1, C2})), new Triple(a, p, Functor.makeFunctorNode("bar", new Node[] {C1, D1})), new Triple(b, p, Functor.makeFunctorNode("foo", new Node[] {C1, C2})), new Triple(a, p, Functor.makeFunctorNode("foo", new Node[] {C1, C3})), new Triple(a, p, D1), }; doTest(ruleSrc, triples, new Triple(Node.ANY, s, Node.ANY), new Object[] { new Triple(a, s, C2), new Triple(b, s, C2), new Triple(a, s, C3) } ); }
/** * Execute the given built in as a body clause. * @param context an execution context giving access to other relevant data * @return true if the functor has an implementation and that implementation returns true when evaluated */ public boolean evalAsBodyClause(RuleContext context) { if (getImplementor() == null) { logger.warn("Invoking undefined functor " + getName() + " in " + context.getRule().toShortString()); return false; } return implementor.bodyCall(getBoundArgs(context.getEnv()), args.length, context); }
/** * Check a pattern to see if it is legal, used to exclude backchaining goals that * could never be satisfied. A legal pattern cannot have literals in the subject or * predicate positions and is not allowed nested functors in the object. */ public boolean isLegal() { if (subject.isLiteral() || predicate.isLiteral()) return false; if (Functor.isFunctor(subject)) return false; if (Functor.isFunctor(object)) { Node[] args = ((Functor)object.getLiteralValue()).getArgs(); for ( Node arg : args ) { if ( Functor.isFunctor( arg ) ) { return false; } } } return true; }
if (Functor.isFunctor(gObj)) { Functor gFunctor = (Functor)gObj.getLiteralValue(); if (Functor.isFunctor(hObj)) { Functor hFunctor = (Functor)hObj.getLiteralValue(); if ( ! gFunctor.getName().equals(hFunctor.getName()) ) { return null; Node[] gArgs = gFunctor.getArgs(); Node[] hArgs = hFunctor.getArgs(); if ( gArgs.length != hArgs.length ) return null; for (int i = 0; i < gArgs.length; i++) { if (gFunctor.isGround(new BindingVector(gEnv))) { if (!unify(gObj, hObj, gEnv, hEnv)) return null;
Builtin imp = f.getImplementor(); if (imp != null) { imp.headAction(f.getBoundArgs(env), f.getArgLength(), context); } else { throw new ReasonerException("Invoking undefined Functor " + f.getName() +" in " + rule.toShortString());
/** * Register an RDF predicate as one whose presence in a goal should force * the goal to be tabled. This is better done directly in the rule set. */ public synchronized void tablePredicate(Node predicate) { // Create a dummy rule which tables the predicate ... Rule tablePredicateRule = new Rule("", new ClauseEntry[]{ new Functor("table", new Node[] { predicate },BuiltinRegistry.theRegistry) }, new ClauseEntry[]{}); // ... end append the rule to the ruleset rules.add(tablePredicateRule); }
/** * Close a single node. */ private Node cloneNode(Node nIn, Map<Node_RuleVariable, Node> vmap, BindingEnvironment env) { Node n = (env == null) ? nIn : env.getGroundVersion(nIn); if (n instanceof Node_RuleVariable) { Node_RuleVariable nv = (Node_RuleVariable)n; Node c = vmap.get(nv); if (c == null) { c = ((Node_RuleVariable)n).cloneNode(); vmap.put(nv, c); } return c; } else if (Functor.isFunctor(n)) { Functor f = (Functor)n.getLiteralValue(); return Functor.makeFunctorNode(cloneFunctor(f, vmap, env)); } else { return n; } }
if (term instanceof Functor) { Functor f = (Functor)term; if (f.getArgLength() != 1) break; int ai = aIndex(f.getArgs()[0]); if (ai >= 0) { if (f.getName().equals("bound")) { code[p++] = TEST_BOUND; code[p++] = (byte)ai; } else if (f.getName().equals("unbound")) { code[p++] = TEST_UNBOUND; code[p++] = (byte)ai;
private boolean allMonotonic(ClauseEntry[] elts) { for ( ClauseEntry elt : elts ) { if ( elt instanceof Functor ) { Builtin b = ( (Functor) elt ).getImplementor(); if ( b != null ) { if ( !b.isMonotonic() ) { return false; } } else { throw new ReasonerException( "(allMonotonic) Undefined Functor " + ( (Functor) elt ).getName() + " in " + toShortString() ); } } } return true; }
/** * Check whether the rule should fire in this context. */ public boolean shouldFire(boolean allowUnsafe) { // Check any non-pattern clauses for (int i = 0; i < rule.bodyLength(); i++) { Object clause = rule.getBodyElement(i); if (clause instanceof Functor) { // Fire a built in if (allowUnsafe) { if (!((Functor)clause).evalAsBodyClause(this)) { // Failed guard so just discard and return return false; } } else { // Don't re-run side-effectful clause on a re-run if (!((Functor)clause).safeEvalAsBodyClause(this)) { // Failed guard so just discard and return return false; } } } } return true; }