/** * Find all the variables in a Functor. */ private int findVars(Functor f, int maxIn) { int max = maxIn; Node[] args = f.getArgs(); for ( Node arg : args ) { if ( arg.isVariable() ) { max = maxVarIndex( arg, max ); } } return max; }
/** * Find all the variables in a Functor. */ private int findVars(Functor f, int maxIn) { int max = maxIn; Node[] args = f.getArgs(); for ( Node arg : args ) { if ( arg.isVariable() ) { max = maxVarIndex( arg, max ); } } return max; }
/** Return an list of variables or nodes in a ClauseEntry, in flattened order */ private List<Node> termVars(ClauseEntry term) { List<Node> result = new ArrayList<>(); if (term instanceof TriplePattern) { TriplePattern goal = (TriplePattern)term; result.add(goal.getSubject()); result.add(goal.getPredicate()); Node obj = goal.getObject(); if (Functor.isFunctor(obj)) { result.add(obj); result.addAll(termVars((Functor)obj.getLiteralValue())); } else { result.add(obj); } } else if (term instanceof Functor) { Node[] args = ((Functor)term).getArgs(); for ( Node arg : args ) { result.add( arg ); } } return result; } }
/** Return an list of variables or nodes in a ClauseEntry, in flattened order */ private List<Node> termVars(ClauseEntry term) { List<Node> result = new ArrayList<>(); if (term instanceof TriplePattern) { TriplePattern goal = (TriplePattern)term; result.add(goal.getSubject()); result.add(goal.getPredicate()); Node obj = goal.getObject(); if (Functor.isFunctor(obj)) { result.add(obj); result.addAll(termVars((Functor)obj.getLiteralValue())); } else { result.add(obj); } } else if (term instanceof Functor) { Node[] args = ((Functor)term).getArgs(); for ( Node arg : args ) { result.add( arg ); } } return result; } }
/** * Helpful function. Return the node from the argument triple * corresponding to the byte code address. */ private Node getTripleValue(Triple triple, byte address, Functor lastFunctor) { switch (address & 0xf0) { case ADDRSubject: return triple.getSubject(); case ADDRPredicate: return triple.getPredicate(); case ADDRObject: return triple.getObject(); case ADDRFunctorNode: return lastFunctor.getArgs()[address & 0x0f]; } return null; }
/** * Helpful function. Return the node from the argument triple * corresponding to the byte code address. */ private Node getTripleValue(Triple triple, byte address, Functor lastFunctor) { switch (address & 0xf0) { case ADDRSubject: return triple.getSubject(); case ADDRPredicate: return triple.getPredicate(); case ADDRObject: return triple.getObject(); case ADDRFunctorNode: return lastFunctor.getArgs()[address & 0x0f]; } return null; }
/** * 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; }
/** * 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; }
Functor f = (Functor)term; if (f.getArgLength() != 1) break; int ai = aIndex(f.getArgs()[0]); if (ai >= 0) { if (f.getName().equals("bound")) {
/** * 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; }
/** * 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; }
/** * 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); } }
/** * 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); } }
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 )
/** * 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; }
/** * 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; }
/** * Compare two patterns for compatibility - i.e. potentially unifiable. * Two patterns are "compatible" in the sense we mean here * if all their ground terms match. A variable in either pattern * can match a ground term or a variable in the other. We are not, * currently, checking for multiple occurances of the same variable. * Functor-valued object literals are treated as a special case which * are only checked for name/arity matching. */ public boolean compatibleWith(TriplePattern pattern) { boolean ok = subject.isVariable() || pattern.subject.isVariable() || subject.equals(pattern.subject); if (!ok) return false; ok = predicate.isVariable() || pattern.predicate.isVariable() || predicate.equals(pattern.predicate); if (!ok) return false; if (object.isVariable() || pattern.object.isVariable()) return true; // Left with checking compatibility of ground literals if (Functor.isFunctor(object) && Functor.isFunctor(pattern.object)) { Functor functor = (Functor)object.getLiteralValue(); Functor pFunctor = (Functor)pattern.object.getLiteralValue(); return (functor.getName().equals(pFunctor.getName()) && functor.getArgs().length == pFunctor.getArgs().length); } else { return object.sameValueAs(pattern.object); } }
/** * Compare two patterns for compatibility - i.e. potentially unifiable. * Two patterns are "compatible" in the sense we mean here * if all their ground terms match. A variable in either pattern * can match a ground term or a variable in the other. We are not, * currently, checking for multiple occurances of the same variable. * Functor-valued object literals are treated as a special case which * are only checked for name/arity matching. */ public boolean compatibleWith(TriplePattern pattern) { boolean ok = subject.isVariable() || pattern.subject.isVariable() || subject.equals(pattern.subject); if (!ok) return false; ok = predicate.isVariable() || pattern.predicate.isVariable() || predicate.equals(pattern.predicate); if (!ok) return false; if (object.isVariable() || pattern.object.isVariable()) return true; // Left with checking compatibility of ground literals if (Functor.isFunctor(object) && Functor.isFunctor(pattern.object)) { Functor functor = (Functor)object.getLiteralValue(); Functor pFunctor = (Functor)pattern.object.getLiteralValue(); return (functor.getName().equals(pFunctor.getName()) && functor.getArgs().length == pFunctor.getArgs().length); } else { return object.sameValueAs(pattern.object); } }
/** * 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); }
/** * 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); }