All Downloads are FREE. Search and download functionalities are using the official Maven repository.

fr.boreal.backward_chaining.homomorphism.QueryHomomorphism Maven / Gradle / Ivy

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 q1, FOQuery 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);
		}

	}

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy