Mentions légales du service

Skip to content
Snippets Groups Projects
Commit b034046f authored by Guillaume Kihli's avatar Guillaume Kihli
Browse files

Updated the NaiveDynamicScheduler so that it takes into account mandatory...

Updated the NaiveDynamicScheduler so that it takes into account mandatory parameters and the estimation of the bound for the number of matches to an atom.
parent 438394f3
No related branches found
No related tags found
1 merge request!64Draft: New views
Pipeline #1142257 failed
Showing
with 195 additions and 91 deletions
......@@ -56,7 +56,9 @@ public interface TermCompound {
return this.getTerms()
.flatMap(t -> {
if (t instanceof TermCompound tc) {
return tc.getAllNestedTerms();
return Stream.concat(
tc.getAllNestedTerms(),
Stream.of(t));
}
return Stream.of(t);
})
......@@ -70,15 +72,8 @@ public interface TermCompound {
* class type filters the terms by type
*/
default <T extends Term> Stream<T> getNestedTerms(Class<T> classType) {
return (Stream<T>) this.getTerms()
.flatMap(t -> {
if (t instanceof TermCompound tc) {
return tc.getNestedTerms(classType);
} else if (classType.isInstance(t)) {
return Stream.of(t);
}
return Stream.empty();
})
return (Stream<T>) this.getAllNestedTerms()
.filter(t -> classType.isInstance(t))
.distinct();
}
}
......@@ -5,14 +5,16 @@ import fr.boreal.model.data.readable.exception.EvaluationException;
import fr.boreal.model.kb.api.FactBase;
import fr.boreal.model.logicalElements.api.Substitution;
import fr.boreal.model.logicalElements.api.Variable;
import fr.boreal.model.logicalElements.functional.AllVariablesInSubstitutionMapToConstant;
import fr.boreal.model.logicalElements.functional.SpecificVariablesInSubstitutionMapToConstant;
import fr.boreal.model.logicalElements.impl.SubstitutionImpl;
import fr.boreal.model.query.api.Query;
import org.apache.commons.collections4.Predicate;
import org.apache.commons.collections4.iterators.FilterIterator;
import java.util.*;
import java.util.Collection;
import java.util.Iterator;
import java.util.Set;
import java.util.Spliterators;
import java.util.stream.Stream;
import java.util.stream.StreamSupport;
......@@ -32,12 +34,17 @@ public interface QueryEvaluator<Q extends Query, QD extends QueryableData> {
* @param query query to evaluate
* @param queryableData readable data source in which atoms are stored
* @param variablesThatMustBeMappedToConstants the set of variables that must be mapped to constants
* @param preHomomorphism a partial homomorphism from var(query) to terms(readable data source) to extend
* @param preHomomorphism a partial homomorphism from var(query) to terms(readable data source)
* to extend
* @return an {@link Iterator} of {@link Substitution} over all the answers of
* the given query in the given readable data source with respect to the query
* answer variables.
*/
Stream<Substitution> evaluate(Q query, QD queryableData, Collection<Variable> variablesThatMustBeMappedToConstants, Substitution preHomomorphism) throws EvaluationException;
Stream<Substitution> evaluate(
Q query,
QD queryableData,
Collection<Variable> variablesThatMustBeMappedToConstants,
Substitution preHomomorphism) throws EvaluationException;
/**
* @param query query to evaluate
......@@ -58,7 +65,8 @@ public interface QueryEvaluator<Q extends Query, QD extends QueryableData> {
* homomorphisms of the given query in the given readable data source with respect
* to the query answer variables.
*/
default Stream<Substitution> homomorphism(Q query, QD queryableData, Substitution preHomomorphism) throws EvaluationException {
default Stream<Substitution> homomorphism(Q query, QD queryableData, Substitution preHomomorphism)
throws EvaluationException {
return evaluate(query, queryableData, Set.of(), preHomomorphism);
}
......@@ -81,7 +89,8 @@ public interface QueryEvaluator<Q extends Query, QD extends QueryableData> {
* answers of the given query in the given readable data source with respect
* to the query answer variables.
*/
default Stream<Substitution> evaluate(Q query, QD queryableData, Substitution preHomomorphism) throws EvaluationException {
default Stream<Substitution> evaluate(Q query, QD queryableData, Substitution preHomomorphism)
throws EvaluationException {
return evaluate(query, queryableData, query.getAnswerVariables(), preHomomorphism);
}
......@@ -91,7 +100,7 @@ public interface QueryEvaluator<Q extends Query, QD extends QueryableData> {
* @return true iff there exist a substitution s that is a homomorphism of the query on the readable data source
*/
default boolean existHomomorphism(Q query, QD queryableData) throws EvaluationException {
return this.homomorphism(query, queryableData).findAny().isPresent();
return this.homomorphism(query, queryableData).parallel().findAny().isPresent();
}
/**
......@@ -100,8 +109,9 @@ public interface QueryEvaluator<Q extends Query, QD extends QueryableData> {
* @param preHomomorphism a partial homomorphism to extend
* @return true iff there exist a substitution s that is a homomorphism of the query on the readable data source
*/
default boolean existHomomorphism(Q query, QD queryableData, Substitution preHomomorphism) throws EvaluationException {
return this.homomorphism(query, queryableData, preHomomorphism).findAny().isPresent();
default boolean existHomomorphism(Q query, QD queryableData, Substitution preHomomorphism)
throws EvaluationException {
return this.homomorphism(query, queryableData, preHomomorphism).parallel().findAny().isPresent();
}
/**
......@@ -110,7 +120,7 @@ public interface QueryEvaluator<Q extends Query, QD extends QueryableData> {
* @return true iff there exist a substitution s that is an answer to the query on the readable data source
*/
default boolean existAnswer(Q query, QD queryableData) throws EvaluationException {
return this.evaluate(query, queryableData).findAny().isPresent();
return this.evaluate(query, queryableData).parallel().findAny().isPresent();
}
/**
......@@ -120,7 +130,7 @@ public interface QueryEvaluator<Q extends Query, QD extends QueryableData> {
* @return true iff there exist a substitution s that is an answer to the query on the readable data source
*/
default boolean existAnswer(Q query, QD queryableData, Substitution preHomomorphism) throws EvaluationException {
return this.evaluate(query, queryableData, preHomomorphism).findAny().isPresent();
return this.evaluate(query, queryableData, preHomomorphism).parallel().findAny().isPresent();
}
/**
......@@ -151,7 +161,9 @@ public interface QueryEvaluator<Q extends Query, QD extends QueryableData> {
* filtered by retaining only substitutions mapping to constants if
* required
*/
default Stream<Substitution> postprocessResult(Stream<Substitution> unfilteredSubstitutions, Collection<Variable> variablesThatMustBeMappedToConstants) {
default Stream<Substitution> postprocessResult(
Stream<Substitution> unfilteredSubstitutions,
Collection<Variable> variablesThatMustBeMappedToConstants) {
if (variablesThatMustBeMappedToConstants.isEmpty()) {
return unfilteredSubstitutions;
} else {
......@@ -160,24 +172,6 @@ public interface QueryEvaluator<Q extends Query, QD extends QueryableData> {
}
}
/**
* Filters the result of a query by removing substitutions which map a variable
* to some other variable of the active domain.
*
* @param unfilteredSubstitutions the unfiltered substitution
* @param constantsOnly true iff all variables must be mapped to constants
* @return the post-processed query result where results have been possibly
* filtered by retaining only substitutions mapping to constants if
* required
*/
default Stream<Substitution> postprocessResult(Stream<Substitution> unfilteredSubstitutions, boolean constantsOnly) {
if (constantsOnly) {
return postprocessResult(unfilteredSubstitutions, new AllVariablesInSubstitutionMapToConstant());
} else {
return unfilteredSubstitutions;
}
}
/**
* Filters the result of a query according to a predicate.
*
......@@ -187,7 +181,9 @@ public interface QueryEvaluator<Q extends Query, QD extends QueryableData> {
* filtered by retaining only substitutions mapping to constants if
* required
*/
default Stream<Substitution> postprocessResult(Stream<Substitution> unfilteredSubstitutions, Predicate<Substitution> predicate) {
default Stream<Substitution> postprocessResult(
Stream<Substitution> unfilteredSubstitutions,
Predicate<Substitution> predicate) {
return StreamSupport.stream(
Spliterators.spliteratorUnknownSize(
new FilterIterator<>(unfilteredSubstitutions.iterator(), predicate), 0),
......
......@@ -2,6 +2,7 @@ package fr.boreal.query_evaluation;
import fr.boreal.model.formula.FOFormulas;
import fr.boreal.model.formula.api.FOFormula;
import fr.boreal.model.logicalElements.api.Atom;
import fr.boreal.model.logicalElements.api.Substitution;
import fr.boreal.model.logicalElements.api.Term;
import fr.boreal.model.logicalElements.api.Variable;
......@@ -99,4 +100,21 @@ public class FOQueryEvaluators {
return FOQueryEvaluators.rebuildAnswer(this.initialQuery, this.partialAnswers.next());
}
}
public static Map<Integer, Term> computeAtomicPositionsAssignation(
Atom atom,
Substitution preHomomorphism) {
Map<Integer, Term> positions = new HashMap<>();
for (int i = 0; i < atom.getTermSequence().size(); i++) {
Term t = atom.getTermSequence().get(i);
if (t.isGround()) {
positions.put(i, t);
} else if (preHomomorphism.keys().contains(t)) {
positions.put(i, preHomomorphism.createImageOf(t));
}
}
return positions;
}
}
......@@ -10,6 +10,7 @@ import fr.boreal.model.logicalElements.impl.SubstitutionImpl;
import fr.boreal.model.partition.TermPartition;
import fr.boreal.model.query.api.FOQuery;
import fr.boreal.model.queryEvaluation.api.FOQueryEvaluator;
import fr.boreal.query_evaluation.FOQueryEvaluators;
import fr.boreal.query_evaluation.utils.filters.GroundTermAtPositionFilter;
import fr.boreal.query_evaluation.utils.filters.PositionsAssignationFilter;
import fr.boreal.query_evaluation.utils.transformers.TermSequenceToSubstitutionTransformer;
......@@ -67,7 +68,8 @@ public class AtomicFOQueryEvaluator<QD extends QueryableData> implements FOQuery
return t;
}}).toList());
Map<Integer, Term> positionsAffectation = computePositionsAssignation(atom, preHomomorphism);
Map<Integer, Term> positionsAffectation =
FOQueryEvaluators.computeAtomicPositionsAssignation(atom, preHomomorphism);
BasicQuery bq = selectBasicQuery(queryableData, atom.getPredicate(), positionsAffectation).orElseThrow(
() -> new EvaluationException(String.format(
"The query %s is unsupported by the QueryableData %s",
......@@ -95,23 +97,6 @@ public class AtomicFOQueryEvaluator<QD extends QueryableData> implements FOQuery
.map(s -> makeSubstitutionOnAnswerVariables(s, query.getAnswerVariables(), query.getVariableEqualities()));
}
private Map<Integer, Term> computePositionsAssignation(
Atom atom,
Substitution preHomomorphism) {
Map<Integer, Term> positions = new HashMap<>();
for (int i = 0; i < atom.getTermSequence().size(); i++) {
Term t = atom.getTermSequence().get(i);
if (t.isGround()) {
positions.put(i, t);
} else if (preHomomorphism.keys().contains(t)) {
positions.put(i, preHomomorphism.createImageOf(t));
}
}
return positions;
}
private static Substitution makeSubstitutionOnAnswerVariables (
Substitution result,
Collection<Variable> answerVariables,
......
......@@ -218,7 +218,9 @@ public class BacktrackEvaluator<QD extends QueryableData> implements FOQueryEval
} else {
// going down
if (this.scheduler.hasNext(this.level)) {
FOFormula element = this.scheduler.next(this.level, this.solutionManager.getCurrentSolution());
FOFormula element = this.scheduler.next(
this.level,
this.solutionManager.getCurrentSolution());
// answer variables = (general U join) \ already affected
Collection<Variable> subquery_vars = new HashSet<>();
subquery_vars.addAll(this.query.getAnswerVariables());
......@@ -227,13 +229,19 @@ public class BacktrackEvaluator<QD extends QueryableData> implements FOQueryEval
// keep variables from (1) the formula and (2) the equalities with an element of the formula
Set<Variable> variables = element.getVariables().collect(Collectors.toSet());
subquery_vars.removeIf(v -> variables.contains(v) &&
this.query.getVariableEqualities().getClass(v).stream().noneMatch(variables::contains));
this.query.getVariableEqualities().getClass(v).stream()
.noneMatch(variables::contains));
subquery_vars.retainAll(variables);
Optional<Substitution> previous_step_subst_opt = this.preHomomorphism.merged(this.solutionManager.getCurrentSolution());
Optional<Substitution> previous_step_subst_opt =
this.preHomomorphism.merged(this.solutionManager.getCurrentSolution());
if (previous_step_subst_opt.isPresent()) {
Substitution subquery_subst = previous_step_subst_opt.get();
FOQuery<? extends FOFormula> subquery = FOQueryFactory.instance().createOrGetQuery(element, subquery_vars, this.query.getVariableEqualities());
Iterator<Substitution> sub_results = this.evaluator.evaluate(subquery, this.queryableData, this.vars, subquery_subst).iterator();
FOQuery<? extends FOFormula> subquery =
FOQueryFactory.instance().createOrGetQuery(
element, subquery_vars, this.query.getVariableEqualities());
Iterator<Substitution> sub_results =
this.evaluator.evaluate(subquery, this.queryableData, this.vars, subquery_subst)
.iterator();
if (sub_results.hasNext()) {
this.solutionManager.add(this.level, sub_results);
if (this.solutionManager.next(this.level)) {
......
package fr.boreal.query_evaluation.conjunction.backtrack;
import com.sun.jdi.InvalidLineNumberException;
import fr.boreal.model.data.readable.QueryableData;
import fr.boreal.model.data.readable.query.AtomicPattern;
import fr.boreal.model.data.readable.query.BasicQuery;
import fr.boreal.model.formula.api.FOFormula;
import fr.boreal.model.formula.api.FOFormulaConjunction;
import fr.boreal.model.formula.api.FOFormulaDisjunction;
import fr.boreal.model.formula.api.FOFormulaNegation;
import fr.boreal.model.logicalElements.api.*;
import fr.boreal.model.query.api.FOQuery;
import fr.boreal.query_evaluation.FOQueryEvaluators;
import org.eclipse.rdf4j.query.algebra.Var;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;
public class NaiveDynamicScheduler implements Scheduler {
......@@ -19,6 +25,8 @@ public class NaiveDynamicScheduler implements Scheduler {
private final Map<FormulaWrapper, Set<Variable>> sharedVariables;
private final Map<FormulaWrapper, Boolean> containsFunctionalTerm;
private final Map<FormulaWrapper, Set<Variable>> functionalTermVariables;
private final Map<FormulaWrapper, Set<Variable>> mandatoryVariables;
private final Set<Predicate> predicateWithTermFilter;
/**
* Creates a new scheduler over the given query and fact base
......@@ -27,11 +35,14 @@ public class NaiveDynamicScheduler implements Scheduler {
*/
public NaiveDynamicScheduler(FOQuery<? extends FOFormulaConjunction> query, QueryableData queryableData) {
this.queryableData = queryableData;
this.notOrdered = new ArrayList<>();
this.ordered = new ArrayList<>();
int numberSubElements = query.getFormula().getSubElements().size();
this.notOrdered = new ArrayList<>(numberSubElements);
this.ordered = new ArrayList<>(numberSubElements);
this.sharedVariables = new HashMap<>();
this.containsFunctionalTerm = new HashMap<>();
this.functionalTermVariables = new HashMap<>();
this.mandatoryVariables = new HashMap<>();
this.predicateWithTermFilter = new HashSet<>();
// Populate notOrdered list with initial formulas
for (FOFormula formula : query.getFormula().getSubElements()) {
......@@ -42,6 +53,10 @@ public class NaiveDynamicScheduler implements Scheduler {
if (containsFunctionalTerm.get(formulaWrapper)) {
functionalTermVariables.put(formulaWrapper, computeFunctionalTermVariables(formula));
}
mandatoryVariables.put(formulaWrapper, computeMandatoryVariables(formula));
if (formula instanceof Atom a && computePredicateWithTermFilter(a.getPredicate())) {
this.predicateWithTermFilter.add(a.getPredicate());
}
}
// Perform static sorting
......@@ -91,21 +106,18 @@ public class NaiveDynamicScheduler implements Scheduler {
}
private boolean computeContainsFunctionalTerm(FOFormula formula) {
return formula.getNestedTerms(EvaluableFunction.class).findAny().isPresent();
boolean result = formula
.getNestedTerms(EvaluableFunction.class)
.findAny()
.isPresent();
return result;
}
private Set<Variable> computeFunctionalTermVariables(FOFormula formula) {
return switch (formula) {
case Atom atom -> {
Set<Variable> variables = new HashSet<>();
for (Term term : atom.getTermSequence()) {
if (term.isEvaluableFunction()) {
EvaluableFunction fterm = (EvaluableFunction) term;
fterm.getNestedTerms(Variable.class).forEach(variables::add);
}
}
yield variables;
}
case Atom atom -> atom.getNestedTerms(EvaluableFunction.class)
.flatMap(ef -> ef.getNestedTerms(Variable.class))
.collect(Collectors.toSet());
case FOFormulaNegation neg -> computeFunctionalTermVariables(neg.element());
case FOFormulaConjunction conj -> conj.getSubElements().stream()
.flatMap(f -> this.computeFunctionalTermVariables(f).stream()).collect(Collectors.toSet());
......@@ -115,8 +127,25 @@ public class NaiveDynamicScheduler implements Scheduler {
};
}
private Set<Variable> computeMandatoryVariables(FOFormula formula) {
Set<Variable> variables = new HashSet<>();
for (Atom a : formula.asAtomSet()) {
Set<Integer> mandatoryPositions =
this.queryableData.getBasicPattern(a.getPredicate()).getMandatoryPositions();
for (Integer mandatoryPosition : mandatoryPositions) {
Term t = a.getTerm(mandatoryPosition);
if (t instanceof Variable v) {
variables.add(v);
} else if (t instanceof TermCompound tc) {
tc.getNestedTerms(Variable.class).forEach(variables::add);
}
}
}
return variables;
}
private boolean containsFunctionalTerm(Atom atom) {
//return Arrays.stream(atom.getTerms()).anyMatch(Term::isEvaluableFunction);
return containsFunctionalTerm.get(new FormulaWrapper(atom));
}
......@@ -124,6 +153,34 @@ public class NaiveDynamicScheduler implements Scheduler {
return formula.getConstants().count();
}
private Optional<Long> estimateBound(Atom atom, Substitution currentSolution) {
long minBound = Long.MAX_VALUE;
AtomicPattern atomicPattern = queryableData.getBasicPattern(atom.getPredicate());
Map<Integer, Term> positionsAffectation =
FOQueryEvaluators.computeAtomicPositionsAssignation(atom, currentSolution);
for (BasicQuery bq: (Iterable<BasicQuery>)
atomicPattern.createQueries(positionsAffectation)::iterator) {
Optional<Long> estimation = queryableData.estimateBound(bq);
if (estimation.isPresent()) {
if (estimation.get() < minBound) {
minBound = estimation.get();
}
}
}
return minBound == Long.MAX_VALUE ? Optional.empty() : Optional.of(minBound);
}
private boolean canFilterWithTerms(Predicate p) {
return predicateWithTermFilter.contains(p);
}
private boolean computePredicateWithTermFilter(Predicate p) {
return this.queryableData.getBasicPattern(p).getIndexablePatterns().stream()
.anyMatch(s -> !s.equals(Set.of()));
}
@Override
public FOFormula next(int level, Substitution currentSolution) {
// Ensure previous levels are cleared
......@@ -131,13 +188,21 @@ public class NaiveDynamicScheduler implements Scheduler {
notOrdered.addLast(ordered.removeLast());
}
// If there is only one element to order, we directly return it
if (notOrdered.size() == 1) {
ordered.add(notOrdered.removeLast());
return ordered.getLast();
}
// Prioritize evaluable computed atoms
// Prioritize evaluable computed atoms and atomic negation.
// The idea is that we could backtrack quicker if the evaluation is false
for (FOFormula formula : notOrdered) {
// Consider only formulas where all mandatory variables are assigned
if (!areAllMandatoryVariablesAssigned(formula, currentSolution)) {
continue;
}
// If formula is an instance of an evaluable computed atom, return it directly
if (formula instanceof ComputedAtom computedAtom) {
if (isEvaluable(computedAtom, currentSolution)) {
notOrdered.remove(formula);
......@@ -145,6 +210,9 @@ public class NaiveDynamicScheduler implements Scheduler {
return formula;
}
} else if (formula instanceof FOFormulaNegation negation && negation.element() instanceof Atom atom) {
// Otherwise, if the formula is an atomic negation
// If it is an atomic negation of an evaluable computed atom, return it
if (atom instanceof ComputedAtom computedAtom) {
if (isEvaluable(computedAtom, currentSolution)) {
notOrdered.remove(formula);
......@@ -152,45 +220,58 @@ public class NaiveDynamicScheduler implements Scheduler {
return formula;
}
} else {
// If it is not a computed atom
// First check if there are evaluable functional terms and if so, are there evaluable?
if (containsFunctionalTerm(atom) && !areFunctionalTermsEvaluable(atom, currentSolution)) {
continue;
}
// TODO: redo this part to take basic patterns into account
/*Optional<Long> estimate = queryableData.estimateMatchCount(atom, currentSolution);
// Do an estimate to know if the subquery has an answer
// If so, we return the negation so that the algorithm will backtrack
Optional<Long> estimate = estimateBound(atom, currentSolution);
if (estimate.isPresent() && estimate.get() > 0) {
notOrdered.remove(formula);
ordered.add(formula);
return formula;
}*/
}
}
}
}
// Dynamic sorting based on fact base information
// TODO: redo this part to take basic patterns into account
// Dynamic sorting based on the estimation of the bound
FOFormula bestFormula = null;
/*long bestEstimate = Long.MAX_VALUE;
long bestEstimate = Long.MAX_VALUE;
for (FOFormula formula : notOrdered) {
// Consider only formulas where all mandatory variables are assigned
if (!areAllMandatoryVariablesAssigned(formula, currentSolution)) {
continue;
}
// We consider atomic formulas that are not computed atoms (they are already treated)
if (formula instanceof Atom atom && !(atom instanceof ComputedAtom)) {
if (containsFunctionalTerm(atom) && !areFunctionalTermsEvaluable(atom, currentSolution)) {
continue;
}
Optional<Long> estimate = queryableData.estimateMatchCount(atom, currentSolution);
// Try to estimate the bound
Optional<Long> estimate = estimateBound(atom, currentSolution);
// If we have a bound, and we know there is no answer, return the atom so that we backtrack
if (estimate.isPresent() && estimate.get() == 0) {
notOrdered.remove(formula);
ordered.add(formula);
return formula;
}
if (!queryableData.canPerformIndexedMatch(atom, currentSolution)) {
// If we know that it is not possible to filter the results with the assignations of terms,
// we directly return the atom
if (!canFilterWithTerms(atom.getPredicate())) {
notOrdered.remove(formula);
ordered.add(formula);
return formula;
}
// If the estimation for this atom is better than for the previous one, we update the best formula
long currentEstimate = estimate.orElse(Long.MAX_VALUE);
if (currentEstimate < bestEstimate) {
bestEstimate = currentEstimate;
......@@ -199,12 +280,22 @@ public class NaiveDynamicScheduler implements Scheduler {
}
}
// If we have an estimation, we return the best atom
if (bestFormula != null) {
notOrdered.remove(bestFormula);
ordered.add(bestFormula);
return bestFormula;
} else*/ if (!notOrdered.isEmpty()) {
bestFormula = notOrdered.removeLast();
}
// Otherwise, we select any formula that has its mandatory variables assigned
if (!notOrdered.isEmpty()) {
bestFormula = notOrdered.stream()
.filter(f -> areAllMandatoryVariablesAssigned(f, currentSolution))
.findAny()
.orElseThrow(() -> new RuntimeException(String.format(
"There are no subquery with all mandatory variables assigned: \n" +
"ordered: %s, notOrdered: %s, currentSolution: %s",
ordered, notOrdered, currentSolution)));
ordered.add(bestFormula);
return bestFormula;
} else {
......@@ -238,6 +329,10 @@ public class NaiveDynamicScheduler implements Scheduler {
return currentSolution.keys().containsAll(functionalVars);
}
private boolean areAllMandatoryVariablesAssigned(FOFormula formula, Substitution currentSolution) {
return currentSolution.keys().containsAll(mandatoryVariables.get(new FormulaWrapper(formula)));
}
// Wrapper class to use default hashCode and equals based on object reference
private record FormulaWrapper(FOFormula formula) {
@Override
......
......@@ -19,6 +19,7 @@ module fr.boreal.query_evaluation {
requires org.slf4j;
requires org.hsqldb;
requires rdf4j.queryalgebra.model;
requires jdk.jdi;
exports fr.boreal.query_evaluation.atomic;
exports fr.boreal.query_evaluation.conjunction;
......
......@@ -9,8 +9,10 @@ import fr.boreal.model.formula.factory.FOFormulaFactory;
import fr.boreal.model.kb.api.FactBase;
import fr.boreal.model.logicalElements.api.Atom;
import fr.boreal.model.logicalElements.api.Substitution;
import fr.boreal.model.logicalElements.factory.impl.SameObjectTermFactory;
import fr.boreal.model.logicalElements.impl.AtomImpl;
import fr.boreal.model.logicalElements.impl.SubstitutionImpl;
import fr.boreal.model.logicalElements.impl.VariableImpl;
import fr.boreal.model.partition.TermPartition;
import fr.boreal.model.query.api.FOQuery;
import fr.boreal.model.query.factory.FOQueryFactory;
......@@ -117,7 +119,11 @@ class NaiveDynamicSchedulerTest {
Assertions.assertTrue(scheduler.hasNext(1));
substitution = GenericFOQueryEvaluator.defaultInstance().evaluate(
FOQueryFactory.instance().createOrGetQuery(firstFormula, List.of()),
FOQueryFactory.instance().createOrGetQuery(
firstFormula,
List.of(
SameObjectTermFactory.instance().createOrGetVariable("X"),
SameObjectTermFactory.instance().createOrGetVariable("Y"))),
factBase).iterator().next();
secondFormula = scheduler.next(1, substitution);
Assertions.assertTrue(ssumxy.equals(secondFormula) || ssumx.equals(secondFormula));
......@@ -134,7 +140,7 @@ class NaiveDynamicSchedulerTest {
@Test
void testComputedAtom() throws Exception {
String dlgpFacts = "p(a, b). q(4).";
String dlgpQuery = "@prefix ig: <stdfct> ? :- p(X, Y), ig:isEven(ig:sum(X, Y, 7)).";
String dlgpQuery = "@computed ig: <stdfct> ? :- p(X, Y), ig:isEven(ig:sum(X, Y, 7)).";
FactBase factBase = new SimpleInMemoryGraphStore(DlgpUtil.parseFacts(dlgpFacts));
FOQuery<FOFormulaConjunction> query = (FOQuery<FOFormulaConjunction>) DlgpUtil.parseQueries(dlgpQuery).iterator().next();
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment