/** * Constructor. * * @param engine the engine which is calling this interpreter * @param goal the query to be satisfied * @param clauses the set of code blocks needed to implement this goal * @param isTop true if this is a top level call from the outside iterator, false means it is an * internal generator call which means we don't need to insert an tabled call */ public LPInterpreter( LPBRuleEngine engine, TriplePattern goal, List<RuleClauseCode> clauses, boolean isTop) { this.engine = engine; this.goal = goal; // Used for debug only // Construct dummy top environemnt which is a call into the clauses for this goal if (engine.getDerivationLogging()) { envFrame = new EnvironmentFrameWithDerivation(RuleClauseCode.returnCodeBlock); } else { envFrame = new EnvironmentFrame(RuleClauseCode.returnCodeBlock); } envFrame.allocate(RuleClauseCode.MAX_PERMANENT_VARS); HashMap<Node, Node> mappedVars = new HashMap<>(); envFrame.pVars[0] = argVars[0] = standardize(goal.getSubject(), mappedVars); envFrame.pVars[1] = argVars[1] = standardize(goal.getPredicate(), mappedVars); envFrame.pVars[2] = argVars[2] = standardize(goal.getObject(), mappedVars); if (engine.getDerivationLogging()) { ((EnvironmentFrameWithDerivation) envFrame).initDerivationRecord(argVars); } if (clauses != null && clauses.size() > 0) { if (isTop && engine.getRuleStore().isTabled(goal)) { setupTabledCall(0, 0); // setupClauseCall(0, 0, clauses); } else { setupClauseCall(0, 0, clauses, goal.isGround()); } } // TripleMatchFrame tmFrame = new TripleMatchFrame(this); topTMFrame = new TopLevelTripleMatchFrame(this, goal); topTMFrame.linkTo(cpFrame); topTMFrame.setContinuation(0, 0); cpFrame = topTMFrame; }
/** * Compile all the rules in a table. initially just indexed on predicate but want to add better * indexing for the particular cases of wildcard rules and type rules. */ protected void compileAll() { isCompiled = true; predicateToCodeMap = new HashMap<>(); allRuleClauseCodes = new ArrayList<>(); indexPredicateToCodeMap = new HashMap<>(); for (Rule r : getAllRules()) { ClauseEntry term = r.getHeadElement(0); if (term instanceof TriplePattern) { RuleClauseCode code = new RuleClauseCode(r); allRuleClauseCodes.add(code); Node predicate = ((TriplePattern) term).getPredicate(); if (predicate.isVariable()) { predicate = Node_RuleVariable.WILD; } List<RuleClauseCode> predicateCode = predicateToCodeMap.get(predicate); if (predicateCode == null) { predicateCode = new ArrayList<>(); predicateToCodeMap.put(predicate, predicateCode); } predicateCode.add(code); if (predicateCode.size() > INDEX_THRESHOLD) { indexPredicateToCodeMap.put(predicate, new HashMap<Node, List<RuleClauseCode>>()); } } } // Now add the wild card rules into the list for each non-wild predicate) List<RuleClauseCode> wildRules = predicateToCodeMap.get(Node_RuleVariable.WILD); if (wildRules != null) { for (Map.Entry<Node, List<RuleClauseCode>> entry : predicateToCodeMap.entrySet()) { Node predicate = entry.getKey(); List<RuleClauseCode> predicateCode = entry.getValue(); if (predicate != Node_RuleVariable.WILD) { predicateCode.addAll(wildRules); } } } indexPredicateToCodeMap.put(Node_RuleVariable.WILD, new HashMap<Node, List<RuleClauseCode>>()); // Now built any required two level indices for (Map.Entry<Node, Map<Node, List<RuleClauseCode>>> entry : indexPredicateToCodeMap.entrySet()) { Node predicate = entry.getKey(); Map<Node, List<RuleClauseCode>> predicateMap = entry.getValue(); List<RuleClauseCode> wildRulesForPredicate = new ArrayList<>(); List<RuleClauseCode> allRulesForPredicate = predicate.isVariable() ? allRuleClauseCodes : predicateToCodeMap.get(predicate); for (Iterator<RuleClauseCode> j = allRulesForPredicate.iterator(); j.hasNext(); ) { RuleClauseCode code = j.next(); ClauseEntry head = code.getRule().getHeadElement(0); boolean indexed = false; if (head instanceof TriplePattern) { Node objectPattern = ((TriplePattern) head).getObject(); if (!objectPattern.isVariable() && !Functor.isFunctor(objectPattern)) { // Index against object List<RuleClauseCode> indexedCode = predicateMap.get(objectPattern); if (indexedCode == null) { indexedCode = new ArrayList<>(); predicateMap.put(objectPattern, indexedCode); } indexedCode.add(code); indexed = true; } } if (!indexed) { wildRulesForPredicate.add(code); } } // Now fold the rules that apply to any index entry into all the indexed entries for (Iterator<Map.Entry<Node, List<RuleClauseCode>>> k = predicateMap.entrySet().iterator(); k.hasNext(); ) { Map.Entry<Node, List<RuleClauseCode>> ent = k.next(); List<RuleClauseCode> predicateCode = ent.getValue(); predicateCode.addAll(wildRulesForPredicate); } } // Now compile all the clauses for (RuleClauseCode code : allRuleClauseCodes) { code.compile(this); } }