/** * *@param sigma * A set of ABox dependencies */ public CQContainmentCheckUnderLIDs(ImmutableList<LinearInclusionDependency> dependencies, DatalogFactory datalogFactory, UnifierUtilities unifierUtilities, SubstitutionUtilities substitutionUtilities, TermFactory termFactory) { // index dependencies this.dependencies = dependencies.stream() .collect(ImmutableCollectors.toMultimap( d -> d.getHead().getFunctionSymbol(), d -> d)); this.datalogFactory = datalogFactory; this.unifierUtilities = unifierUtilities; this.substitutionUtilities = substitutionUtilities; this.termFactory = termFactory; }
/** * This method is used to chase foreign key constraint rule in which the rule * has only one atom in the body. * * IMPORTANT: each rule is applied only ONCE to each atom * * @param atoms * @return set of atoms */ private Set<Function> chaseAtoms(Collection<Function> atoms) { Set<Function> derivedAtoms = new HashSet<>(); for (Function fact : atoms) { derivedAtoms.add(fact); for (LinearInclusionDependency d : dependencies.get(fact.getFunctionSymbol())) { CQIE rule = datalogFactory.getFreshCQIECopy(datalogFactory.getCQIE(d.getHead(), d.getBody())); Function ruleBody = rule.getBody().get(0); Substitution theta = unifierUtilities.getMGU(ruleBody, fact); if (theta != null && !theta.isEmpty()) { Function ruleHead = rule.getHead(); Function newFact = (Function)ruleHead.clone(); // unify to get fact is needed because the dependencies are not necessarily full // (in other words, they may contain existentials in the head) substitutionUtilities.applySubstitution(newFact, theta); derivedAtoms.add(newFact); } } } return derivedAtoms; }
private LinearInclusionDependency getLinearInclusionDependency(ForeignKeyConstraint fk) { DatabaseRelationDefinition def = fk.getRelation(); DatabaseRelationDefinition def2 = fk.getReferencedRelation(); // create variables for the current table int len1 = def.getAttributes().size(); List<Term> terms1 = new ArrayList<>(len1); for (int i = 1; i <= len1; i++) terms1.add(termFactory.getVariable("t" + i)); // create variables for the referenced table int len2 = def2.getAttributes().size(); List<Term> terms2 = new ArrayList<>(len2); for (int i = 1; i <= len2; i++) terms2.add(termFactory.getVariable("p" + i)); for (ForeignKeyConstraint.Component comp : fk.getComponents()) { // indexes start at 1 int pos1 = comp.getAttribute().getIndex() - 1; // current column (1) int pos2 = comp.getReference().getIndex() - 1; // referenced column (2) terms1.set(pos1, terms2.get(pos2)); } Function head = termFactory.getFunction(def2.getAtomPredicate(), terms2); Function body = termFactory.getFunction(def.getAtomPredicate(), terms1); return new LinearInclusionDependency(head, body); }