fr.boreal.backward_chaining.homomorphism.QueryHomomorphism Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of integraal-backward-chaining Show documentation
Show all versions of integraal-backward-chaining Show documentation
InteGraal has been designed in a modular way, in order to facilitate
software reuse and extension.
It should make it easy to test new scenarios and techniques, in
particular by combining algorithms.
The main features of Graal are currently the following:
(1) internal storage to store data by using a SQL or RDF representation
(Postgres, MySQL, HSQL, SQLite, Remote SPARQL endpoints, Local in-memory
triplestores) as well as a native in-memory representation
(2) data-integration capabilities for exploiting federated heterogeneous
data-sources through mappings able to target systems such as SQL, RDF,
and black-box (e.g. Web-APIs)
(3) algorithms for query-answering over heterogeneous and federated data
based on query rewriting and/or forward chaining (or chase)
package fr.boreal.backward_chaining.homomorphism;
import com.google.common.collect.Sets;
import fr.boreal.model.formula.FOFormulas;
import fr.boreal.model.formula.api.FOFormula;
import fr.boreal.model.kb.api.FactBase;
import fr.boreal.model.logicalElements.api.Predicate;
import fr.boreal.model.logicalElements.api.Substitution;
import fr.boreal.model.logicalElements.api.Term;
import fr.boreal.model.logicalElements.api.Variable;
import fr.boreal.model.logicalElements.impl.SubstitutionImpl;
import fr.boreal.model.query.api.FOQuery;
import fr.boreal.model.ruleCompilation.NoRuleCompilation;
import fr.boreal.model.ruleCompilation.api.RuleCompilation;
import fr.boreal.query_evaluation.generic.GenericFOQueryEvaluator;
import fr.boreal.storage.natives.SimpleInMemoryGraphStore;
import java.util.Iterator;
import java.util.Set;
/**
* Homomorphism computing specialized for queries
* Takes into account answer variables and initial substitutions
* Use the fact that queries are small to perform some quick checks that would cost a lot on a whole factbase
* Also uses a rule compilation
*
* @author Florent Tornil
*/
public class QueryHomomorphism {
private final RuleCompilation compilation;
/**
* Default constructor.
* Uses no compilation
*/
public QueryHomomorphism() {
this(NoRuleCompilation.instance());
}
/**
* Constructor with compilation
* @param compilation the compilation to use
*/
public QueryHomomorphism(RuleCompilation compilation) {
this.compilation = compilation;
}
/**
* @param q1 a query
* @param q2 a query
* @return true iff there is a homomorphism from q1 to q2
*/
public boolean exists(FOQuery extends FOFormula> q1, FOQuery extends FOFormula> q2) {
// First failure point
// If the predicates of q1 are not compatible with the predicates of q2
Set q1Predicates = q1.getFormula().getPredicates();
Set q2Predicates = q2.getFormula().getPredicates();
boolean compatible = true;
for(Predicate q1Predicate : q1Predicates) {
compatible = compatible &&
!Sets.intersection(
compilation.getCompatiblePredicates(q1Predicate),
q2Predicates).isEmpty();
}
if(!compatible) {
return false;
}
// equalities on answer variables
Substitution preAffectation = new SubstitutionImpl();
Iterator qAnswerVariables = q1.getAnswerVariables().iterator();
Iterator q2AnswerVariables = q2.getAnswerVariables().iterator();
while(qAnswerVariables.hasNext()) {
Variable v1 = qAnswerVariables.next();
Term v1Image = q1.getVariableEqualities().getRepresentative(v1);
Variable v2 = q2AnswerVariables.next();
Term v2Image = q2.getVariableEqualities().getRepresentative(v2);
// Second failure point
// If v1 is affected to a Term and v2 is not
// Example :
// [Q1] ?(X) :- p(X) X=a
// [Q2] ?(Y) :- p(Y)
// [Q2'] ?(Y) :- p(Y) Y=b
if(v1Image.isFrozen(null) && !v1Image.equals(v2Image)) {
return false;
}
// Third failure point
// If v1 appear multiple times in the answer variables but with different v2
// Example :
// [Q1] ?(X, X) :- p(X, X)
// [Q2] ?(Y, Z) :- p(Y, Z)
// Note : Q2' must still work
// [Q2'] ?(Y, Z) :- p(Y, Z) Y=a, Z=a
// [Q2'] ?(Y, Z) :- p(Y, Z) Y=Z
if(preAffectation.keys().contains(v1)) {
if(! preAffectation.createImageOf(v1).equals(v2Image)) {
return false;
}
} else {
preAffectation.add(v1, v2Image);
}
}
// If no failure point have stopped the homomorphism
// Use the generic homomorphism to finish
FactBase q2AsFactBase = new SimpleInMemoryGraphStore(
FOFormulas.createImageWith(q2.getFormula(),
q2.getVariableEqualities().getAssociatedSubstitution(q2).orElseThrow())
.asAtomSet());
if(this.compilation.equals(NoRuleCompilation.instance())) {
return GenericFOQueryEvaluator.defaultInstance().existHomomorphism(q1, q2AsFactBase, preAffectation);
} else {
return GenericFOQueryEvaluator.defaultInstanceWithInfCompilation(this.compilation).existHomomorphism(q1, q2AsFactBase, preAffectation);
}
}
}