Mentions légales du service

Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • rules/integraal
  • ulliana/integraal
2 results
Show changes
Commits on Source (4)
......@@ -11,7 +11,6 @@ import com.google.common.collect.Iterators;
import fr.boreal.backward_chaining.evaluators.QueryRewriter;
import fr.boreal.backward_chaining.evaluators.RewritingOutput;
import fr.boreal.backward_chaining.unfolding.UCQUnfolder;
import fr.boreal.component_builder.AlgorithmParameters;
import fr.boreal.component_builder.api.IComponentBuilder;
import fr.boreal.configuration.parameters.IGParameter;
import fr.boreal.configuration.parameters.IGParameterValueExtractor;
......@@ -61,990 +60,1037 @@ import org.slf4j.LoggerFactory;
public class EndUserAPI {
static final Logger LOG = LoggerFactory.getLogger(EndUserAPI.class);
/**
* Performs saturation on the {@link FactBase} and {@link RuleBase} using the
* given chaseType, rank, timeout, and TermFactory.
*
* @param chaseType The type of chase to use for saturation.
* @param fb The FactBase to saturate. This parameter will undergo
* modification upon completion of the method execution.
* @param rb The RuleBase to use for saturation.
* @param conds The list of external halting conditions ; optional
* @return the saturated factbase
*/
public static FactBase saturateOld(FactBase fb, RuleBase rb, Checker chaseType, ExternalHaltingCondition... conds) {
Chase chase = IComponentBuilder.buildAndGetChase(fb, rb, chaseType, conds);
chase.execute();
return fb;
}
/**
* Performs saturation on the {@link FactBase} and {@link RuleBase} using the
* given chaseType, rank, timeout, and TermFactory.
*
* @param fb The FactBase to saturate. This parameter will undergo
* modification upon completion of the method execution.
* @param rb The RuleBase to use for saturation.
* @param params The list of external halting conditions and chase parameters ;
* optional
* @return the saturated factbase
*/
@SafeVarargs
public static FactBase saturate(FactBase fb, RuleBase rb, IGParameter<InteGraalKeywords, ?>... params) {
Callable<FactBase> chaseTask = () -> {
/*
* wrapped method body
*/
Chase chase = IComponentBuilder.buildAndGetChase(fb, rb, params);
chase.execute();
return fb;
};
return executeWithOptionalTimeout(chaseTask, params);
}
/**
*
* Auxiliary method that runs a callable with a timeout if required.
*
* @param <T> return type
* @param task to execute
* @param params possibly containing the timeout value
* @return
*/
private static <T> T executeWithOptionalTimeout(Callable<T> task, IGParameter<InteGraalKeywords, ?>... params) {
Duration timeout = IGParameterValueExtractor.getTimeout(params);
try {
return timeout != null ? CallableWithTimeout.execute(task, timeout) : task.call();
} catch (Exception e) {
LOG.error("Error executing task", e);
//TODO handle timeout and return proper value
return null;
}
}
/**
*
* @param <T> the type of objects in the iterator
* @param unfilteredResul the unfiltered iterators
* @param params containg notably the max number of answers
* @return
*/
private static <T> Iterator<T> limitAnswersOf(Iterator<T> unfilteredResul,
IGParameter<InteGraalKeywords, ?>[] params) {
if(unfilteredResul==null){
return null;
}
Integer limitAnswers = IGParameterValueExtractor.getMax(params);
if (limitAnswers == null) {
return unfilteredResul;
} else {
return Iterators.limit(unfilteredResul, limitAnswers);
}
}
/**
* Performs rewriting of the queries with the {@link RuleBase}. For each query q
* in queries, calculate the set W(q, R) of rewritings of q with respect to the
* rules in R. The compilation is used to optimize the rewriting process by
* limiting the number of rewritings to explore and generating pivotal queries.
*
* @param rb The RuleBase to rewrite with.
* @param queries The queries to rewrite.
* @param ruleCompilationType The RuleCompilation to use for rewriting. Use
* NoCompilation.instance() in case of no compilation
* @param conds Conditions to enforce termination ; optional
* @return The rewritings of the queries obtained with compilation.
*/
public static Collection<Query> rewriteOld(RuleBase rb, Collection<Query> queries, Compilation ruleCompilationType,
ExternalHaltingCondition... conds) {
QueryRewriter rewriter = IComponentBuilder.buildAndGetOMQRewriter(rb, queries, ruleCompilationType, conds);
Iterable<RewritingOutput> it = rewriter.batchEvaluate();
return StreamSupport.stream(it.spliterator(), false).flatMap(out -> out.rewritings().getQueries().stream())
.collect(Collectors.toSet());
}
/**
* Performs rewriting of the queries with the {@link RuleBase}. For each query q
* in queries, calculate the set W(q, R) of rewritings of q with respect to the
* rules in R. The compilation is used to optimize the rewriting process by
* limiting the number of rewritings to explore and generating pivotal queries.
*
* @param rb The RuleBase to rewrite with.
* @param queries The queries to rewrite.
* @param params Conditions to enforce termination as well as the rewriting
* type ; optional
* @return The rewritings of the queries obtained with compilation.
*/
public static Collection<Query> rewrite(RuleBase rb, Collection<Query> queries,
IGParameter<InteGraalKeywords, ?>... params) {
Callable<Collection<Query>> rewriteTask = () -> {
/*
* wrapped method body
*/
QueryRewriter rewriter = IComponentBuilder.buildAndGetOMQRewriter(rb, queries, params);
Iterable<RewritingOutput> it = rewriter.batchEvaluate();
return StreamSupport.stream(it.spliterator(), false).map(out -> out.rewritings())
.collect(Collectors.toList());
};
return executeWithOptionalTimeout(rewriteTask, params);
}
/**
* Evaluates an {@link FOQuery} on a {@link FactBase} and returns an iterator
* over the resulting {@link Substitution}.
*
* @param fb The FactBase to query.
* @param query The queries to execute.
* @param conds Conditions to enforce termination ; optional
* @return an {@link Iterator} of {@link Substitution} over all the answers of
* the given query in the given factbase with respect to the query
* answer variables.
*/
public static Iterator<Substitution> evaluateOld(FactBase fb, Query query, ExternalHaltingCondition... conds) {
QueryEvaluatorWithMultiEvaluator queryEvaluator = IComponentBuilder.buildAndGetQueryEvaluator(fb, query, conds);
Iterable<QueryEvaluationOutput> results = queryEvaluator.batchEvaluate();
return results.iterator().next().answers();
}
/**
* Evaluates an {@link FOQuery} on a {@link FactBase} and returns an iterator
* over the resulting {@link Substitution}.
*
* @param fb The FactBase to query.
* @param query The queries to execute.
* @param params Conditions to enforce termination ; optional
* @return an {@link Iterator} of {@link Substitution} over all the answers of
* the given query in the given factbase with respect to the query
* answer variables.
*/
@SafeVarargs
public static Iterator<Substitution> evaluate(FactBase fb, Query query,
IGParameter<InteGraalKeywords, ?>... params) {
Callable<Iterator<Substitution>> evaluateTask = () -> {
/*
* wrapped method body
*/
QueryEvaluatorWithMultiEvaluator queryEvaluator = IComponentBuilder.buildAndGetQueryEvaluator(fb, query,
params);
Iterable<QueryEvaluationOutput> results = queryEvaluator.batchEvaluate();
return results.iterator().next().answers();
};
return limitAnswersOf(executeWithOptionalTimeout(evaluateTask, params), params);
}
/**
* Evaluates a collection of queries on a {@link FactBase} and returns an
* iterator over the resulting substitutions.
*
* @param fb The FactBase to query.
* @param queries The queries to execute.
* @param conds Conditions to enforce termination ; optional
* @return an {@link Iterator} of {@link Substitution} over all the answers of
* the given query in the given factbase with respect to the query
* answer variables.
*/
public static Iterator<Substitution> evaluateOld(FactBase fb, Collection<Query> queries,
ExternalHaltingCondition... conds) {
Collection<Substitution> resultSet = new HashSet<>();
for (Query query : queries) {
Iterator<Substitution> res = EndUserAPI.evaluateOld(fb, query);
res.forEachRemaining(resultSet::add);
}
return resultSet.iterator();
}
/**
* Evaluates a collection of queries on a {@link FactBase} and returns an
* iterator over the resulting substitutions.
*
* @param fb The FactBase to query.
* @param queries The queries to execute.
* @param params Conditions to enforce termination ; optional
* @return an {@link Iterator} of {@link Substitution} over all the answers of
* the given query in the given factbase with respect to the query
* answer variables.
*/
@SafeVarargs
public static Iterator<Substitution> evaluate(FactBase fb, Collection<Query> queries,
IGParameter<InteGraalKeywords, ?>... params) {
Callable<Iterator<Substitution>> evaluateTask = () -> {
/*
* wrapped method body
*/
Collection<Substitution> resultSet = new HashSet<>();
for (Query query : queries) {
Iterator<Substitution> res = EndUserAPI.evaluate(fb, query, params);
res.forEachRemaining(resultSet::add);
}
return resultSet.iterator();
};
return limitAnswersOf(executeWithOptionalTimeout(evaluateTask, params), params);
}
/**
* Evaluates a collection of UCQ (Union of Conjunctive Queries) on a
* {@link FactBase} and {@link RuleBase} via saturation and returns an iterator
* over the resulting substitutions.
*
* @param fb The FactBase to query.
* @param queries The queries to execute.
* @param rb
* @param conds Conditions to enforce termination ; optional
* @return an {@link Iterator} of {@link Substitution} over all the answers of
* the given query in the given factbase with respect to the query
* answer variables.
*/
public static Iterator<Substitution> evaluateSatOld(FactBase fb, Collection<Query> queries, RuleBase rb,
ExternalHaltingCondition... conds) {
FactBase saturatedFactbase = EndUserAPI.saturateOld(fb, rb, null);
return EndUserAPI.evaluateOld(saturatedFactbase, queries);
}
/**
* Evaluates a collection of UCQ (Union of Conjunctive Queries) on a
* {@link FactBase} and {@link RuleBase} via saturation and returns an iterator
* over the resulting substitutions.
*
* @param fb The FactBase to query.
* @param queries The queries to execute.
* @param rb
* @param params Conditions to enforce termination ; optional
* @return an {@link Iterator} of {@link Substitution} over all the answers of
* the given query in the given factbase with respect to the query
* answer variables.
*/
@SafeVarargs
public static Iterator<Substitution> evaluateSat(FactBase fb, Collection<Query> queries, RuleBase rb,
IGParameter<InteGraalKeywords, ?>... params) {
Callable<Iterator<Substitution>> evaluateSatTask = () -> {
/*
* wrapped method body
*/
FactBase saturatedFactbase = EndUserAPI.saturate(fb, rb, params);
return EndUserAPI.evaluateOld(saturatedFactbase, queries);
};
return executeWithOptionalTimeout(evaluateSatTask, params);
}
/**
* Evaluates a UCQ (Union of Conjunctive Queries) on a {@link FactBase} and
* {@link RuleBase} via rewriting and returns an iterator over the resulting
* substitutions.
*
* @param fb The FactBase to query.
* @param queries The queries to execute.
* @param rb
* @param conds Conditions to enforce termination ; optional
* @return an {@link Iterator} of {@link Substitution} over all the answers of
* the given query in the given factbase with respect to the query
* answer variables.
*/
public static Iterator<Substitution> evaluateRewOld(FactBase fb, Collection<Query> queries, RuleBase rb,
ExternalHaltingCondition... conds) {
Collection<Query> query_rewritings = EndUserAPI.rewriteOld(rb, queries, null);
return EndUserAPI.evaluateOld(fb, query_rewritings);
}
/**
* Evaluates a UCQ (Union of Conjunctive Queries) on a {@link FactBase} and
* {@link RuleBase} via rewriting and returns an iterator over the resulting
* substitutions.
*
* @param fb The FactBase to query.
* @param queries The queries to execute.
* @param rb
* @param params Conditions to enforce termination ; optional
* @return an {@link Iterator} of {@link Substitution} over all the answers of
* the given query in the given factbase with respect to the query
* answer variables.
*/
@SafeVarargs
public static Iterator<Substitution> evaluateRew(FactBase fb, Collection<Query> queries, RuleBase rb,
IGParameter<InteGraalKeywords, ?>... params) {
Callable<Iterator<Substitution>> evaluateRewTask = () -> {
/*
* wrapped method body
*/
Collection<Query> queryRewritings = EndUserAPI.rewrite(rb, queries, params);
return EndUserAPI.evaluate(fb, queryRewritings, params);
};
return executeWithOptionalTimeout(evaluateRewTask, params);
}
/**
* Evaluates a collection of UCQ (Union of Conjunctive Queries) on a
* {@link FactBase} and {@link RuleBase} via rewriting and returns an iterator
* over the resulting substitutions.
*
* @param fb The FactBase to query.
* @param rb_sat The rulebase to saturate the data
* @param rb_rew The rulebase to rewrite the queries
* @param queries The queries to execute.
* @param conds Conditions to enforce termination ; optional
* @return an {@link Iterator} of {@link Substitution} over all the answers of
* the given query in the given factbase with respect to the query
* answer variables.
*/
public static Iterator<Substitution> evaluateHybOld(FactBase fb, Collection<Query> queries, RuleBase rb_sat,
RuleBase rb_rew, ExternalHaltingCondition... conds) {
Collection<Query> query_rewritings = EndUserAPI.rewriteOld(rb_rew, queries, null);
FactBase semi_saturated_factbase = EndUserAPI.saturateOld(fb, rb_sat, null);
return EndUserAPI.evaluateOld(semi_saturated_factbase, query_rewritings);
}
/**
* Evaluates a collection of UCQ (Union of Conjunctive Queries) on a
* {@link FactBase} and {@link RuleBase} via rewriting and returns an iterator
* over the resulting substitutions.
*
* @param fb The FactBase to query.
* @param rb_sat The rulebase to saturate the data
* @param rb_rew The rulebase to rewrite the queries
* @param queries The queries to execute.
* @param params Conditions to enforce termination ; optional
* @return an {@link Iterator} of {@link Substitution} over all the answers of
* the given query in the given factbase with respect to the query
* answer variables.
*/
@SafeVarargs
public static Iterator<Substitution> evaluateHyb(FactBase fb, Collection<Query> queries, RuleBase rb_sat,
RuleBase rb_rew, IGParameter<InteGraalKeywords, ?>... params) {
Callable<Iterator<Substitution>> evaluateHybTask = () -> {
/*
* wrapped method body
*/
Collection<Query> queryRewritings = EndUserAPI.rewrite(rb_rew, queries, params);
FactBase semiSaturatedFactbase = EndUserAPI.saturate(fb, rb_sat, params);
return EndUserAPI.evaluate(semiSaturatedFactbase, queryRewritings);
};
return executeWithOptionalTimeout(evaluateHybTask, params);
}
/**
* Extracts the compilable rules by the {@link RuleCompilation} from the
* {@link RuleBase}.
*
* @param ruleBase The RuleBase to extract compilable rules from.
* @param ruleCompilation The RuleCompilation to use for extraction.
* @param conds Conditions to enforce termination ; optional
* @return The RuleBase containing only the compilable rules.
*/
public static RuleBase extractCompilableRulesOld(RuleBase ruleBase,
InteGraalKeywords.Algorithms.Parameters.Compilation ruleCompilation, ExternalHaltingCondition... conds) {
RuleCompilationResult compilationResult = IComponentBuilder.buildAndGetRuleCompilation(ruleBase,
ruleCompilation, conds);
return new RuleBaseImpl(compilationResult.compilableRules());
}
/**
* Extracts the compilable rules by the {@link RuleCompilation} from the
* {@link RuleBase}.
*
* @param ruleBase The RuleBase to extract compilable rules from.
* @param params Conditions to enforce termination and RuleCompilation to use
* for extraction ; optional
* @return The RuleBase containing only the compilable rules.
*/
public static RuleBase extractCompilableRules(RuleBase ruleBase,
InteGraalKeywords.Algorithms.Parameters.Compilation ruleCompilation,
IGParameter<InteGraalKeywords, ?>... params) {
Callable<RuleBase> extractTask = () -> {
/*
* wrapped method body
*/
RuleCompilationResult compilationResult = IComponentBuilder.buildAndGetRuleCompilation(ruleBase, params);
return new RuleBaseImpl(compilationResult.compilableRules());
};
return executeWithOptionalTimeout(extractTask, params);
}
/**
* Extracts the non-compilable rules by the {@link RuleCompilation} from the
* {@link RuleBase}.
*
* @param ruleBase The RuleBase to extract non-compilable rules from.
* @param ruleCompilation The RuleCompilation to use for extraction.
* @param conds Conditions to enforce termination ; optional
* @return The RuleBase containing only the non-compilable rules.
*/
public static RuleBase extractNonCompilableRulesOld(RuleBase ruleBase,
InteGraalKeywords.Algorithms.Parameters.Compilation ruleCompilation, ExternalHaltingCondition... conds) {
RuleCompilationResult compilationResult = IComponentBuilder.buildAndGetRuleCompilation(ruleBase,
ruleCompilation, conds);
return new RuleBaseImpl(compilationResult.nonCompilableRules());
}
/**
* Extracts the non-compilable rules by the {@link RuleCompilation} from the
* {@link RuleBase}.
*
* @param ruleBase The RuleBase to extract non-compilable rules from.
* @param params Conditions to enforce termination ; optional
* @return The RuleBase containing only the non-compilable rules.
*/
public static RuleBase extractNonCompilableRules(RuleBase ruleBase, IGParameter<InteGraalKeywords, ?>... params) {
Callable<RuleBase> extractTask = () -> {
/*
* wrapped method body
*/
RuleCompilationResult compilationResult = IComponentBuilder.buildAndGetRuleCompilation(ruleBase, params);
return new RuleBaseImpl(compilationResult.nonCompilableRules());
};
return executeWithOptionalTimeout(extractTask, params);
}
/**
* Unfolds the queries with respect to the compilable rules in the
* {@link RuleBase} according to the given {@link RuleCompilation}.
*
* @param ruleBase The RuleBase to compile.
* @param queries The queries to unfold.
* @param ruleCompilation The RuleCompilation to use for unfolding.
* @param conds Conditions to enforce termination ; optional
* @return The unfolding of the given queries.
*/
public static Collection<Query> unfoldOld(RuleBase ruleBase, Collection<Query> queries,
InteGraalKeywords.Algorithms.Parameters.Compilation ruleCompilation, ExternalHaltingCondition... conds) {
RuleCompilationResult compilationResult = IComponentBuilder.buildAndGetRuleCompilation(ruleBase,
ruleCompilation, conds);
UCQUnfolder unfolder = new UCQUnfolder(compilationResult.compilation());
return unfolder.unfold(queries);
}
/**
* Decompose the rules in the RuleBase to single piece rules.
*
* @param ruleBase The RuleBase to transform.
* @param params Conditions to enforce termination ; optional
* @return The transformed RuleBase with single piece rules.
*/
@SafeVarargs
public static RuleBase decompose(RuleBase ruleBase, IGParameter<InteGraalKeywords, ?>... params) {
Callable<RuleBase> decomposeTask = () -> {
/*
* wrapped method body
*/
Collection<FORule> singlePieceRules = new HashSet<>();
for (FORule r : ruleBase.getRules()) {
singlePieceRules.addAll(Rules.computeSinglePiece(r));
}
return new RuleBaseImpl(singlePieceRules);
};
return executeWithOptionalTimeout(decomposeTask, params);
}
/**
* Decompose the rules in the RuleBase to single piece rules.
*
* @param ruleBase The RuleBase to transform.
* @param conds Conditions to enforce termination ; optional
* @return The transformed RuleBase with single piece rules.
*/
public static RuleBase decomposeOld(RuleBase ruleBase, ExternalHaltingCondition... conds) {
Collection<FORule> singlePieceRules = new HashSet<>();
for (FORule r : ruleBase.getRules()) {
singlePieceRules.addAll(Rules.computeSinglePiece(r));
}
return new RuleBaseImpl(singlePieceRules);
}
// Constant for the properties of decidability explored by Kiabora
private static final Map<String, RuleSetProperty> propertyMap = RuleSetPropertyHierarchy.generatePropertyMap();
/**
* Tests whether the rule base is recognized as chase terminating rule base for
* any factbase. <br/>
* This test uses the Kiabora analyzer (see
* <a href="https://graphik-team.github.io/graal/downloads/kiabora">...</a>)
*
* @param ruleBase The RuleBase to test.
* @param conds Conditions to enforce termination ; optional
* @return true if the rulebase is a known subclass of FES, else false (caution,
* false doesn't say the rulebase is not FES).
*/
public static Boolean isFesOld(RuleBase ruleBase, ExternalHaltingCondition... conds) {
return createKiaboraAnalyserOld(ruleBaseConverterOld(ruleBase)).isFES();
}
/**
* Tests whether the rule base is recognized as chase terminating rule base for
* any factbase. <br/>
* This test uses the Kiabora analyzer (see
* <a href="https://graphik-team.github.io/graal/downloads/kiabora">...</a>)
*
* @param ruleBase The RuleBase to test.
* @param params Conditions to enforce termination ; optional
* @return true if the rulebase is a known subclass of FES, else false (caution,
* false doesn't say the rulebase is not FES).
*/
@SafeVarargs
public static Boolean isFes(RuleBase ruleBase, IGParameter<InteGraalKeywords, ?>... params) {
Callable<Boolean> isFesTask = () -> createKiaboraAnalyser(ruleBaseConverter(ruleBase)).isFES();
return executeWithOptionalTimeout(isFesTask, params);
}
/**
* Tests whether the rule base is recognized as finite rewriting rule base for
* any query. <br/>
* This test uses the Kiabora analyzer (see
* <a href="https://graphik-team.github.io/graal/downloads/kiabora">...</a>)
*
* @param ruleBase The RuleBase to test.
* @param conds Conditions to enforce termination ; optional
* @return true if the rulebase is a known subclass of FUS, else false (caution,
* false doesn't say the rulebase is not FUS).
*/
public static Boolean isFusOld(RuleBase ruleBase, ExternalHaltingCondition... conds) {
return createKiaboraAnalyserOld(ruleBaseConverterOld(ruleBase)).isFUS();
}
/**
* Tests whether the rule base is recognized as finite rewriting rule base for
* any query. <br/>
* This test uses the Kiabora analyzer (see
* <a href="https://graphik-team.github.io/graal/downloads/kiabora">...</a>)
*
* @param ruleBase The RuleBase to test.
* @param params Conditions to enforce termination ; optional
* @return true if the rulebase is a known subclass of FUS, else false (caution,
* false doesn't say the rulebase is not FUS).
*/
@SafeVarargs
public static Boolean isFus(RuleBase ruleBase, IGParameter<InteGraalKeywords, ?>... params) {
Callable<Boolean> isFusTask = () -> createKiaboraAnalyser(ruleBaseConverter(ruleBase)).isFUS();
return executeWithOptionalTimeout(isFusTask, params);
}
/**
* Tests whether the rule base is recognized as Query/Answering decidable for
* any factbase and any query. <br/>
* This test uses the Kiabora analyzer (see
* <a href="https://graphik-team.github.io/graal/downloads/kiabora">...</a>)
*
* @param ruleBase The RuleBase to test.
* @param params Conditions to enforce termination ; optional
* @return true if the rulebase is a known subclass of Q/A decidable, else false
* (caution, false doesn't say the rulebase is not Q/A decidable).
*/
@SafeVarargs
public static Boolean isDecidable(RuleBase ruleBase, IGParameter<InteGraalKeywords, ?>... params) {
Callable<Boolean> isDecidableTask = () -> createKiaboraAnalyser(ruleBaseConverter(ruleBase)).isDecidable();
return executeWithOptionalTimeout(isDecidableTask, params);
}
/**
* Tests whether the rule base is recognized as Query/Answering decidable for
* any factbase and any query. <br/>
* This test uses the Kiabora analyzer (see
* <a href="https://graphik-team.github.io/graal/downloads/kiabora">...</a>)
*
* @param ruleBase The RuleBase to test.
* @param conds Conditions to enforce termination ; optional
* @return true if the rulebase is a known subclass of Q/A decidable, else false
* (caution, false doesn't say the rulebase is not Q/A decidable).
*/
public static Boolean isDecidableOld(RuleBase ruleBase, ExternalHaltingCondition... conds) {
return createKiaboraAnalyserOld(ruleBaseConverterOld(ruleBase)).isDecidable();
}
/**
* Tests whether the rule base is recognized as hybridable. <br/>
* This test uses the Kiabora analyzer (see
* <a href="https://graphik-team.github.io/graal/downloads/kiabora">...</a>)
*
* @param ruleBase The RuleBase to test.
* @param conds Conditions to enforce termination ; optional
* @return true if the rulebase is a known subclass hybridable (i.e. a "good"
* FES/FUS partition), else false (caution, false doesn't say the
* rulebase is not hybridable).
*/
public static Boolean isHybridableOld(RuleBase ruleBase, ExternalHaltingCondition... conds) {
Analyser analyser = createKiaboraAnalyserOld(ruleBaseConverterOld(ruleBase));
if (analyser.isFES() || analyser.isFUS())
return true;
// Let's check the max FES combine solution
int[] combine = analyser.combineFES();
if (combine == null) {
return false;
}
// Let's check the solution doesn't contain a BTS component
for (int j : combine) {
if ((j & Analyser.COMBINE_BTS) != 0) {
return false;
}
}
return true;
}
/**
* Tests whether the rule base is recognized as hybridable. <br/>
* This test uses the Kiabora analyzer (see
* <a href="https://graphik-team.github.io/graal/downloads/kiabora">...</a>)
*
* @param ruleBase The RuleBase to test.
* @return true if the rulebase is a known subclass hybridable (i.e. a "good"
* FES/FUS partition), else false (caution, false doesn't say the
* rulebase is not hybridable).
*/
@SafeVarargs
public static Boolean isHybridable(RuleBase ruleBase, IGParameter<InteGraalKeywords, ?>... params) {
Callable<Boolean> isHybridableTask = () -> {
/*
* wrapped method body
*/
Analyser analyser = createKiaboraAnalyser(ruleBaseConverter(ruleBase));
if (analyser.isFES() || analyser.isFUS()) {
return true;
}
// Check the max FES combine solution
int[] combine = analyser.combineFES();
if (combine == null) {
return false;
}
// Check that the solution doesn't contain a BTS component
for (int j : combine) {
if ((j & Analyser.COMBINE_BTS) != 0) {
return false;
}
}
return true;
};
return executeWithOptionalTimeout(isHybridableTask, params);
}
/**
* Computes a HybridRuleBase maximizing Forward Chaining or Backward Chaining.
* <br/>
* An hybridRuleBase is composed of two ruleBases: one to saturate and the other
* to rewrite. Hybridize computes Rs and Rw from R such that: - {Rs,Rw} is a
* partition of R, - Rs is FES, - Rw is FUS, - Forall F, Q, chase(F,Rs) |=
* Rewrite(Q,Rw) iff F,R |= Q One can choose to maximize Rs or Rw. Caution, one
* can compute an empty Rs or Rw (then the other rule base is equal to R) This
* test uses the Kiabora analyser (see
* <a href="https://graphik-team.github.io/graal/downloads/kiabora">...</a>)
*
* @param ruleBase The RuleBase to hybridize
* @param hybridType The type of hybridisation: "max_fes" to maximise the part
* to saturate, or "max_fus" to maximise the part to rewrite.
* @param conds Conditions to enforce termination ; optional
* @return the hybrid rule base or an empty optional if an error occurs.
*/
public static Optional<HybridRuleBase> hybridizeOld(RuleBase ruleBase,
InteGraalKeywords.Algorithms.Parameters.HybridTypes hybridType, ExternalHaltingCondition... conds) {
AnalyserRuleSet ruleSet = ruleBaseConverterOld(ruleBase);
Analyser analyser = createKiaboraAnalyserOld(ruleSet);
int[] combine = switch (hybridType) {
case MAX_FUS -> analyser.combineFUS();
case MAX_FES -> analyser.combineFES();
};
// Checks the existence of combine solution
if (combine == null) {
return Optional.empty();
}
// Check that the solution found doesn't contain a BTS component
for (int j : combine) {
if ((j & Analyser.COMBINE_BTS) != 0) {
return Optional.empty();
}
}
// Generates the HybridRuleBase
RuleBase ruleBaseS = EndUserAPI.filterOld(ruleSet, Analyser.COMBINE_FES, combine, analyser);
RuleBase ruleBaseW = EndUserAPI.filterOld(ruleSet, Analyser.COMBINE_FUS, combine, analyser);
return Optional.of(new HybridRuleBase(ruleBaseS, ruleBaseW));
}
/**
* Computes a HybridRuleBase maximizing Forward Chaining or Backward Chaining.
* <br/>
* An hybridRuleBase is composed of two ruleBases: one to saturate and the other
* to rewrite. Hybridize computes Rs and Rw from R such that: - {Rs,Rw} is a
* partition of R, - Rs is FES, - Rw is FUS, - Forall F, Q, chase(F,Rs) |=
* Rewrite(Q,Rw) iff F,R |= Q One can choose to maximize Rs or Rw. Caution, one
* can compute an empty Rs or Rw (then the other rule base is equal to R) This
* test uses the Kiabora analyser (see
* <a href="https://graphik-team.github.io/graal/downloads/kiabora">...</a>)
*
* @param ruleBase The RuleBase to hybridize
* @param params The type of hybridisation: "max_fes" to maximise the part to
* saturate, or "max_fus" to maximise the part to rewrite as
* well as conditions to enforce termination and the reasoning
* algorithm configuration ; optional
*
* @return the hybrid rule base or an empty optional if an error occurs.
*/
@SafeVarargs
public static Optional<HybridRuleBase> hybridize(RuleBase ruleBase, IGParameter<InteGraalKeywords, ?>... params) {
Callable<Optional<HybridRuleBase>> hybridizeTask = () -> {
/*
* wrapped method body
*/
AnalyserRuleSet ruleSet = ruleBaseConverter(ruleBase);
Analyser analyser = createKiaboraAnalyser(ruleSet);
var hybridType = IGParameterValueExtractor.getHybridType(params);
int[] combine = switch (hybridType) {
case MAX_FUS -> analyser.combineFUS();
case MAX_FES -> analyser.combineFES();
};
// Checks the existence of combine solution
if (combine == null) {
return Optional.empty();
}
// Check that the solution found doesn't contain a BTS component
for (int j : combine) {
if ((j & Analyser.COMBINE_BTS) != 0) {
return Optional.empty();
}
}
// Generates the HybridRuleBase
RuleBase ruleBaseS = EndUserAPI.filter(ruleSet, Analyser.COMBINE_FES, combine, analyser, params);
RuleBase ruleBaseW = EndUserAPI.filter(ruleSet, Analyser.COMBINE_FUS, combine, analyser, params);
return Optional.of(new HybridRuleBase(ruleBaseS, ruleBaseW));
};
return executeWithOptionalTimeout(hybridizeTask, params);
}
/**
* Tests whether the two rule bases form a hybrid rule base. <br/>
* Checks the following conditions on the two base ruleBaseToSaturate (Rs) and
* ruleBaseToRewrite (Rw): - {Rs,Rw} is a partition of R, - Rs is FES, - Rw is
* FUS, - There is no dependency from a rule in Rw to a rule in Rs <br/>
* This test uses the Kiabora analyser (see
* <a href="https://graphik-team.github.io/graal/downloads/kiabora">...</a>)
*
* @param ruleBaseToSaturate The RuleBase to process in forward chaining
* @param ruleBaseToRewrite The RuleBase to process in backward chaining
* @return true if the (ruleBaseToSaturate,ruleBaseToRewrite) is recognized as
* hybridable, else false (caution, false doesn't say this partition is
* not hybridable).
*/
public static Boolean isHybrid(RuleBase ruleBaseToSaturate, RuleBase ruleBaseToRewrite) {
// TODO
throw new UnsupportedOperationException(
"Test to see if two rule bases form a hybrid rule base is not yet implemented");
}
/**
* Tests whether the two rule bases form a hybrid rule base. <br/>
* Checks the following conditions on the two base ruleBaseToSaturate (Rs) and
* ruleBaseToRewrite (Rw): - {Rs,Rw} is a partition of R, - Rs is FES, - Rw is
* FUS, - There is no dependency from a rule in Rw to a rule in Rs <br/>
* This test uses the Kiabora analyser (see
* <a href="https://graphik-team.github.io/graal/downloads/kiabora">...</a>)
*
* @param ruleBaseToSaturate The RuleBase to process in forward chaining
* @param ruleBaseToRewrite The RuleBase to process in backward chaining
* @param conds Conditions to enforce termination ; optional
* @return true if the (ruleBaseToSaturate,ruleBaseToRewrite) is recognized as
* hybridable, else false (caution, false doesn't say this partition is
* not hybridable).
*/
public static Boolean isHybridOld(RuleBase ruleBaseToSaturate, RuleBase ruleBaseToRewrite,
ExternalHaltingCondition... conds) {
// TODO
throw new UnsupportedOperationException(
"Test to see if two rule bases form a hybrid rule base is not yet implemented");
}
/**
* Converts an InteGraal rule base into a Kiabora rule set.
*
* @param ruleBase The RuleBase to convert.
* @param conds Conditions to enforce termination ; optional
* @return The converted AnalyserRuleSet.
*/
private static AnalyserRuleSet ruleBaseConverterOld(RuleBase ruleBase, ExternalHaltingCondition... conds) {
RuleSet graalRuleBase = new LinkedListRuleSet();
for (FORule r : ruleBase.getRules()) {
graalRuleBase.add(RuleConverter.convert(r));
}
return new AnalyserRuleSet(graalRuleBase);
}
/**
* Converts an InteGraal rule base into a Kiabora rule set.
*
* @param ruleBase The RuleBase to convert.
* @param params timeout
* @return The converted AnalyserRuleSet.
*/
private static AnalyserRuleSet ruleBaseConverter(RuleBase ruleBase, IGParameter<InteGraalKeywords, ?>... params) {
Callable<AnalyserRuleSet> ruleBaseConverterTask = () -> {
/*
* wrapped method body
*/
RuleSet graalRuleBase = ruleBase.getRules().stream().map(RuleConverter::convert)
.collect(Collectors.toCollection(LinkedListRuleSet::new));
return new AnalyserRuleSet(graalRuleBase);
};
return executeWithOptionalTimeout(ruleBaseConverterTask, params);
}
/**
* Creates a KiaboraAnalyser to perform all rule base analysis. <br/>
* This test uses the Kiabora analyzer (see
* <a href="https://graphik-team.github.io/graal/downloads/kiabora">...</a>)
*
* @param ruleSet The RuleBase for analysis. * @param conds Conditions to
* enforce termination ; optional
*
* @return the kiabora analyser
*/
private static Analyser createKiaboraAnalyserOld(AnalyserRuleSet ruleSet, ExternalHaltingCondition... conds) {
// TODO : what is the impact of the three following commands?
ruleSet.enableUnifiers(true);
ruleSet.removeDependencyChecker(ProductivityChecker.instance());
ruleSet.addDependencyChecker(RestrictedProductivityChecker.instance());
Map<String, RuleSetProperty> properties = new TreeMap<>(propertyMap);
RuleSetPropertyHierarchy hierarchy = new RuleSetPropertyHierarchy(properties.values());
Analyser analyser = new Analyser();
analyser.setProperties(hierarchy);
analyser.setRuleSet(ruleSet);
return analyser;
}
/**
* Creates a KiaboraAnalyser to perform all rule base analysis. <br/>
* This test uses the Kiabora analyzer (see
* <a href="https://graphik-team.github.io/graal/downloads/kiabora">...</a>)
*
* @param ruleSet The RuleBase for analysis
* @param params timeout
* @return the kiabora analyser
*/
private static Analyser createKiaboraAnalyser(AnalyserRuleSet ruleSet,
IGParameter<InteGraalKeywords, ?>... params) {
Callable<Analyser> createKiaboraAnalyserTask = () -> {
/*
* wrapped method body
*/
// TODO: Evaluate the impact of the following commands.
ruleSet.enableUnifiers(true);
ruleSet.removeDependencyChecker(ProductivityChecker.instance());
ruleSet.addDependencyChecker(RestrictedProductivityChecker.instance());
Map<String, RuleSetProperty> properties = new TreeMap<>(propertyMap);
RuleSetPropertyHierarchy hierarchy = new RuleSetPropertyHierarchy(properties.values());
Analyser analyser = new Analyser();
analyser.setProperties(hierarchy);
analyser.setRuleSet(ruleSet);
return analyser;
};
return executeWithOptionalTimeout(createKiaboraAnalyserTask, params);
}
/**
* Returns a rulebase corresponding to the extraction from the Kiabora RuleSet
* of the subset to saturate/rewrite
*
* @param ruleset the Kiabora AnalyzerRuleSet
* @param criterion precises if one extracts the to_saturate_ruleSet
* (Analyser.COMBINE_FES) or the to_rewrite_ruleSet
* (Analyser.COMBINE_FUS)
* @param combine the table of Kiabora combined SCC
* @param analyser the Kiabora analyzer
* @return the filtered Rulebase
*/
private static RuleBase filterOld(AnalyserRuleSet ruleset, int criterion, int[] combine, Analyser analyser,
ExternalHaltingCondition... conds) {
RuleBase rulebase = new RuleBaseImpl();
for (int i = 0; i < combine.length; ++i) {
if ((combine[i] & criterion) != 0) {
for (Rule r : ruleset.getStronglyConnectedComponentsGraph().getComponent(i)) {
rulebase.add(RuleConverter.reverse(r));
}
}
}
return rulebase;
}
/**
* Returns a rulebase corresponding to the extraction from the Kiabora RuleSet
* of the subset to saturate/rewrite
*
* @param ruleset the Kiabora AnalyzerRuleSet
* @param criterion precises if one extracts the to_saturate_ruleSet
* (Analyser.COMBINE_FES) or the to_rewrite_ruleSet
* (Analyser.COMBINE_FUS)
* @param combine the table of Kiabora combined SCC
* @param analyser the Kiabora analyzer
* @param params timeout
* @return the filtered Rulebase
*/
@SafeVarargs
private static RuleBase filter(AnalyserRuleSet ruleset, int criterion, int[] combine, Analyser analyser,
IGParameter<InteGraalKeywords, ?>... params) {
Callable<RuleBase> filterTask = () -> {
/*
* wrapped method body
*/
RuleBase rulebase = new RuleBaseImpl();
for (int i = 0; i < combine.length; ++i) {
if ((combine[i] & criterion) != 0) {
for (Rule r : ruleset.getStronglyConnectedComponentsGraph().getComponent(i)) {
rulebase.add(RuleConverter.reverse(r));
}
}
}
return rulebase;
};
return executeWithOptionalTimeout(filterTask, params);
}
static final Logger LOG = LoggerFactory.getLogger(EndUserAPI.class);
/**
* Wraps the result of the computation and adds information on execution errors.
*
* @param result
* @param error information
* @param <T> the type of the result
*/
public static record ExecutionOutput<T>(T result, Exception error) {
boolean success() {
return result != null && error==null;
}
boolean failed() {
return !success();
}
public T returnResultOrRaiseException() throws Exception {
if (success()) {
return result;
}
throw error;
}
public static ExecutionOutput success(Object result) {
return new ExecutionOutput<>(result, null);
}
public static ExecutionOutput failure(Exception error) {
return new ExecutionOutput<>(null, error);
}
}
/**
* Auxiliary method that runs a callable with a timeout if required.
*
* @param <T> return type
* @param task to execute
* @param params possibly containing the timeout value
* @return
*/
private static <T> ExecutionOutput<T> executeWithOptionalTimeoutAndHandleException(Callable<T> task, IGParameter<InteGraalKeywords, ?>... params) {
Duration timeout = IGParameterValueExtractor.getTimeout(params);
try {
T res = timeout != null ? CallableWithTimeout.execute(task, timeout) : task.call();
return ExecutionOutput.success(res);
} catch (Exception e) {
LOG.error("Error executing task", e);
return ExecutionOutput.failure(e);
}
}
/**
* @param <T> the type of objects in the iterator
* @param unfilteredResul the unfiltered iterators
* @param params containg notably the max number of answers
* @return
*/
private static <T> ExecutionOutput<Iterator<T>> limitAnswersOf(Iterator<T> unfilteredResul,
IGParameter<InteGraalKeywords, ?>[] params) {
if (unfilteredResul == null) {
return ExecutionOutput.failure(new NullPointerException("nothing to filter"));
}
Integer limitAnswers = IGParameterValueExtractor.getMax(params);
if (limitAnswers == null) {
return ExecutionOutput.success(unfilteredResul);
} else {
return ExecutionOutput.success(Iterators.limit(unfilteredResul, limitAnswers));
}
}
/**
* Performs saturation on the {@link FactBase} and {@link RuleBase} using the
* given chaseType, rank, timeout, and TermFactory.
*
* @param chaseType The type of chase to use for saturation.
* @param fb The FactBase to saturate. This parameter will undergo
* modification upon completion of the method execution.
* @param rb The RuleBase to use for saturation.
* @param conds The list of external halting conditions ; optional
* @return the saturated factbase
*/
public static FactBase saturateOld(FactBase fb, RuleBase rb, Checker chaseType, ExternalHaltingCondition... conds) {
Chase chase = IComponentBuilder.buildAndGetChase(fb, rb, chaseType, conds);
chase.execute();
return fb;
}
/**
* Performs saturation on the {@link FactBase} and {@link RuleBase} using the
* given chaseType, rank, timeout, and TermFactory.
*
* @param fb The FactBase to saturate. This parameter will undergo
* modification upon completion of the method execution.
* @param rb The RuleBase to use for saturation.
* @param params The list of external halting conditions and chase parameters ;
* optional
* @return the saturated factbase
*/
@SafeVarargs
public static ExecutionOutput<FactBase> saturate(FactBase fb, RuleBase rb, IGParameter<InteGraalKeywords, ?>... params) {
Callable<FactBase> chaseTask = () -> {
/*
* wrapped method body
*/
Chase chase = IComponentBuilder.buildAndGetChase(fb, rb, params);
chase.execute();
return fb;
};
return executeWithOptionalTimeoutAndHandleException(chaseTask, params);
}
/**
* Performs rewriting of the queries with the {@link RuleBase}. For each query q
* in queries, calculate the set W(q, R) of rewritings of q with respect to the
* rules in R. The compilation is used to optimize the rewriting process by
* limiting the number of rewritings to explore and generating pivotal queries.
*
* @param rb The RuleBase to rewrite with.
* @param queries The queries to rewrite.
* @param ruleCompilationType The RuleCompilation to use for rewriting. Use
* NoCompilation.instance() in case of no compilation
* @param conds Conditions to enforce termination ; optional
* @return The rewritings of the queries obtained with compilation.
*/
public static Collection<Query> rewriteOld(RuleBase rb, Collection<Query> queries, Compilation ruleCompilationType,
ExternalHaltingCondition... conds) {
QueryRewriter rewriter = IComponentBuilder.buildAndGetOMQRewriter(rb, queries, ruleCompilationType, conds);
Iterable<RewritingOutput> it = rewriter.batchEvaluate();
return StreamSupport.stream(it.spliterator(), false).flatMap(out -> out.rewritings().getQueries().stream())
.collect(Collectors.toSet());
}
/**
* Performs rewriting of the queries with the {@link RuleBase}. For each query q
* in queries, calculate the set W(q, R) of rewritings of q with respect to the
* rules in R. The compilation is used to optimize the rewriting process by
* limiting the number of rewritings to explore and generating pivotal queries.
*
* @param rb The RuleBase to rewrite with.
* @param queries The queries to rewrite.
* @param params Conditions to enforce termination as well as the rewriting
* type ; optional
* @return The rewritings of the queries obtained with compilation.
*/
public static ExecutionOutput<Collection<Query>> rewrite(RuleBase rb, Collection<Query> queries,
IGParameter<InteGraalKeywords, ?>... params) {
Callable<Collection<Query>> rewriteTask = () -> {
/*
* wrapped method body
*/
QueryRewriter rewriter = IComponentBuilder.buildAndGetOMQRewriter(rb, queries, params);
Iterable<RewritingOutput> it = rewriter.batchEvaluate();
return StreamSupport.stream(it.spliterator(), false).map(out -> out.rewritings())
.collect(Collectors.toList());
};
return executeWithOptionalTimeoutAndHandleException(rewriteTask, params);
}
/**
* Evaluates an {@link FOQuery} on a {@link FactBase} and returns an iterator
* over the resulting {@link Substitution}.
*
* @param fb The FactBase to query.
* @param query The queries to execute.
* @param conds Conditions to enforce termination ; optional
* @return an {@link Iterator} of {@link Substitution} over all the answers of
* the given query in the given factbase with respect to the query
* answer variables.
*/
public static Iterator<Substitution> evaluateOld(FactBase fb, Query query, ExternalHaltingCondition... conds) {
QueryEvaluatorWithMultiEvaluator queryEvaluator = IComponentBuilder.buildAndGetQueryEvaluator(fb, query, conds);
Iterable<QueryEvaluationOutput> results = queryEvaluator.batchEvaluate();
return results.iterator().next().answers();
}
/**
* Evaluates an {@link FOQuery} on a {@link FactBase} and returns an iterator
* over the resulting {@link Substitution}.
*
* @param fb The FactBase to query.
* @param query The queries to execute.
* @param params Conditions to enforce termination ; optional
* @return an {@link Iterator} of {@link Substitution} over all the answers of
* the given query in the given factbase with respect to the query
* answer variables.
*/
@SafeVarargs
public static ExecutionOutput<Iterator<Substitution>> evaluate(FactBase fb, Query query,
IGParameter<InteGraalKeywords, ?>... params) {
Callable<Iterator<Substitution>> evaluateTask = () -> {
/*
* wrapped method body
*/
QueryEvaluatorWithMultiEvaluator queryEvaluator = IComponentBuilder.buildAndGetQueryEvaluator(fb, query,
params);
Iterable<QueryEvaluationOutput> results = queryEvaluator.batchEvaluate();
return results.iterator().next().answers();
};
return limitAnswersOf(executeWithOptionalTimeoutAndHandleException(evaluateTask, params).result(), params);
}
/**
* Evaluates a collection of queries on a {@link FactBase} and returns an
* iterator over the resulting substitutions.
*
* @param fb The FactBase to query.
* @param queries The queries to execute.
* @param conds Conditions to enforce termination ; optional
* @return an {@link Iterator} of {@link Substitution} over all the answers of
* the given query in the given factbase with respect to the query
* answer variables.
*/
public static Iterator<Substitution> evaluateOld(FactBase fb, Collection<Query> queries,
ExternalHaltingCondition... conds) {
Collection<Substitution> resultSet = new HashSet<>();
for (Query query : queries) {
Iterator<Substitution> res = EndUserAPI.evaluateOld(fb, query);
res.forEachRemaining(resultSet::add);
}
return resultSet.iterator();
}
/**
* Evaluates a collection of queries on a {@link FactBase} and returns an
* iterator over the resulting substitutions.
*
* @param fb The FactBase to query.
* @param queries The queries to execute.
* @param params Conditions to enforce termination ; optional
* @return an {@link Iterator} of {@link Substitution} over all the answers of
* the given query in the given factbase with respect to the query
* answer variables.
*/
@SafeVarargs
public static ExecutionOutput<Iterator<Substitution>> evaluate(FactBase fb, Collection<Query> queries,
IGParameter<InteGraalKeywords, ?>... params) {
Callable<Iterator<Substitution>> evaluateTask = () -> {
/*
* wrapped method body
*/
Collection<Substitution> resultSet = new ArrayList<>();
for (Query query : queries) {
var res = EndUserAPI.evaluate(fb, query, params).returnResultOrRaiseException();
res.forEachRemaining(resultSet::add);
}
return resultSet.iterator();
};
return limitAnswersOf(executeWithOptionalTimeoutAndHandleException(evaluateTask, params).result(), params);
}
/**
* Evaluates a collection of UCQ (Union of Conjunctive Queries) on a
* {@link FactBase} and {@link RuleBase} via saturation and returns an iterator
* over the resulting substitutions.
*
* @param fb The FactBase to query.
* @param queries The queries to execute.
* @param rb
* @param conds Conditions to enforce termination ; optional
* @return an {@link Iterator} of {@link Substitution} over all the answers of
* the given query in the given factbase with respect to the query
* answer variables.
*/
public static Iterator<Substitution> evaluateSatOld(FactBase fb, Collection<Query> queries, RuleBase rb,
ExternalHaltingCondition... conds) {
FactBase saturatedFactbase = EndUserAPI.saturateOld(fb, rb, null);
return EndUserAPI.evaluateOld(saturatedFactbase, queries);
}
/**
* Evaluates a collection of UCQ (Union of Conjunctive Queries) on a
* {@link FactBase} and {@link RuleBase} via saturation and returns an iterator
* over the resulting substitutions.
*
* @param fb The FactBase to query.
* @param queries The queries to execute.
* @param rb
* @param params Conditions to enforce termination ; optional
* @return an {@link Iterator} of {@link Substitution} over all the answers of
* the given query in the given factbase with respect to the query
* answer variables.
*/
@SafeVarargs
public static ExecutionOutput<Iterator<Substitution>> evaluateSat(FactBase fb, Collection<Query> queries, RuleBase rb,
IGParameter<InteGraalKeywords, ?>... params) {
Callable<Iterator<Substitution>> evaluateSatTask = () -> {
/*
* wrapped method body
*/
var chaseResult = EndUserAPI.saturate(fb, rb, params).returnResultOrRaiseException();
return EndUserAPI.evaluate(chaseResult, queries, params).returnResultOrRaiseException();
};
return
executeWithOptionalTimeoutAndHandleException(evaluateSatTask, params);
}
/**
* Evaluates a UCQ (Union of Conjunctive Queries) on a {@link FactBase} and
* {@link RuleBase} via rewriting and returns an iterator over the resulting
* substitutions.
*
* @param fb The FactBase to query.
* @param queries The queries to execute.
* @param rb
* @param conds Conditions to enforce termination ; optional
* @return an {@link Iterator} of {@link Substitution} over all the answers of
* the given query in the given factbase with respect to the query
* answer variables.
*/
public static Iterator<Substitution> evaluateRewOld(FactBase fb, Collection<Query> queries, RuleBase rb,
ExternalHaltingCondition... conds) {
Collection<Query> query_rewritings = EndUserAPI.rewriteOld(rb, queries, null);
return EndUserAPI.evaluateOld(fb, query_rewritings);
}
/**
* Evaluates a UCQ (Union of Conjunctive Queries) on a {@link FactBase} and
* {@link RuleBase} via rewriting and returns an iterator over the resulting
* substitutions.
*
* @param fb The FactBase to query.
* @param queries The queries to execute.
* @param rb
* @param params Conditions to enforce termination ; optional
* @return an {@link Iterator} of {@link Substitution} over all the answers of
* the given query in the given factbase with respect to the query
* answer variables.
*/
@SafeVarargs
public static ExecutionOutput<Iterator<Substitution>> evaluateRew(FactBase fb, Collection<Query> queries, RuleBase rb,
IGParameter<InteGraalKeywords, ?>... params) {
Callable<Iterator<Substitution>> evaluateRewTask = () -> {
/*
* wrapped method body
*/
var queryRewritings = EndUserAPI.rewrite(rb, queries, params).returnResultOrRaiseException();
return EndUserAPI.evaluate(fb, queryRewritings, params).returnResultOrRaiseException();
};
return executeWithOptionalTimeoutAndHandleException(evaluateRewTask, params);
}
/**
* Evaluates a collection of UCQ (Union of Conjunctive Queries) on a
* {@link FactBase} and {@link RuleBase} via rewriting and returns an iterator
* over the resulting substitutions.
*
* @param fb The FactBase to query.
* @param rb_sat The rulebase to saturate the data
* @param rb_rew The rulebase to rewrite the queries
* @param queries The queries to execute.
* @param conds Conditions to enforce termination ; optional
* @return an {@link Iterator} of {@link Substitution} over all the answers of
* the given query in the given factbase with respect to the query
* answer variables.
*/
public static Iterator<Substitution> evaluateHybOld(FactBase fb, Collection<Query> queries, RuleBase rb_sat,
RuleBase rb_rew, ExternalHaltingCondition... conds) {
Collection<Query> query_rewritings = EndUserAPI.rewriteOld(rb_rew, queries, null);
FactBase semi_saturated_factbase = EndUserAPI.saturateOld(fb, rb_sat, null);
return EndUserAPI.evaluateOld(semi_saturated_factbase, query_rewritings);
}
/**
* Evaluates a collection of UCQ (Union of Conjunctive Queries) on a
* {@link FactBase} and {@link RuleBase} via rewriting and returns an iterator
* over the resulting substitutions.
*
* @param fb The FactBase to query.
* @param rb_sat The rulebase to saturate the data
* @param rb_rew The rulebase to rewrite the queries
* @param queries The queries to execute.
* @param params Conditions to enforce termination ; optional
* @return an {@link Iterator} of {@link Substitution} over all the answers of
* the given query in the given factbase with respect to the query
* answer variables.
*/
@SafeVarargs
public static ExecutionOutput<Iterator<Substitution>> evaluateHyb(FactBase fb, Collection<Query> queries, RuleBase rb_sat,
RuleBase rb_rew, IGParameter<InteGraalKeywords, ?>... params) {
Callable<Iterator<Substitution>> evaluateHybTask = () -> {
/*
* wrapped method body
*/
var queryRewritings = EndUserAPI.rewrite(rb_rew, queries, params).returnResultOrRaiseException();
var semiSaturatedFactbase = EndUserAPI.saturate(fb, rb_sat, params).returnResultOrRaiseException();
return EndUserAPI.evaluate(semiSaturatedFactbase, queryRewritings).returnResultOrRaiseException();
};
return executeWithOptionalTimeoutAndHandleException(evaluateHybTask, params);
}
/**
* Extracts the compilable rules by the {@link RuleCompilation} from the
* {@link RuleBase}.
*
* @param ruleBase The RuleBase to extract compilable rules from.
* @param ruleCompilation The RuleCompilation to use for extraction.
* @param conds Conditions to enforce termination ; optional
* @return The RuleBase containing only the compilable rules.
*/
public static RuleBase extractCompilableRulesOld(RuleBase ruleBase,
InteGraalKeywords.Algorithms.Parameters.Compilation ruleCompilation, ExternalHaltingCondition... conds) {
RuleCompilationResult compilationResult = IComponentBuilder.buildAndGetRuleCompilation(ruleBase,
ruleCompilation, conds);
return new RuleBaseImpl(compilationResult.compilableRules());
}
/**
* Extracts the compilable rules by the {@link RuleCompilation} from the
* {@link RuleBase}.
*
* @param ruleBase The RuleBase to extract compilable rules from.
* @param params Conditions to enforce termination and RuleCompilation to use
* for extraction ; optional
* @return The RuleBase containing only the compilable rules.
*/
public static ExecutionOutput<RuleBase> extractCompilableRules(RuleBase ruleBase,
InteGraalKeywords.Algorithms.Parameters.Compilation ruleCompilation,
IGParameter<InteGraalKeywords, ?>... params) {
Callable<RuleBase> extractTask = () -> {
/*
* wrapped method body
*/
RuleCompilationResult compilationResult = IComponentBuilder.buildAndGetRuleCompilation(ruleBase, params);
return new RuleBaseImpl(compilationResult.compilableRules());
};
return executeWithOptionalTimeoutAndHandleException(extractTask, params);
}
/**
* Extracts the non-compilable rules by the {@link RuleCompilation} from the
* {@link RuleBase}.
*
* @param ruleBase The RuleBase to extract non-compilable rules from.
* @param ruleCompilation The RuleCompilation to use for extraction.
* @param conds Conditions to enforce termination ; optional
* @return The RuleBase containing only the non-compilable rules.
*/
public static RuleBase extractNonCompilableRulesOld(RuleBase ruleBase,
InteGraalKeywords.Algorithms.Parameters.Compilation ruleCompilation, ExternalHaltingCondition... conds) {
RuleCompilationResult compilationResult = IComponentBuilder.buildAndGetRuleCompilation(ruleBase,
ruleCompilation, conds);
return new RuleBaseImpl(compilationResult.nonCompilableRules());
}
/**
* Extracts the non-compilable rules by the {@link RuleCompilation} from the
* {@link RuleBase}.
*
* @param ruleBase The RuleBase to extract non-compilable rules from.
* @param params Conditions to enforce termination ; optional
* @return The RuleBase containing only the non-compilable rules.
*/
public static ExecutionOutput<RuleBase> extractNonCompilableRules(RuleBase ruleBase, IGParameter<InteGraalKeywords, ?>... params) {
Callable<RuleBase> extractTask = () -> {
/*
* wrapped method body
*/
RuleCompilationResult compilationResult = IComponentBuilder.buildAndGetRuleCompilation(ruleBase, params);
return new RuleBaseImpl(compilationResult.nonCompilableRules());
};
return executeWithOptionalTimeoutAndHandleException(extractTask, params);
}
/**
* Unfolds the queries with respect to the compilable rules in the
* {@link RuleBase} according to the given {@link RuleCompilation}.
*
* @param ruleBase The RuleBase to compile.
* @param queries The queries to unfold.
* @param ruleCompilation The RuleCompilation to use for unfolding.
* @param conds Conditions to enforce termination ; optional
* @return The unfolding of the given queries.
*/
public static Collection<Query> unfoldOld(RuleBase ruleBase, Collection<Query> queries,
InteGraalKeywords.Algorithms.Parameters.Compilation ruleCompilation, ExternalHaltingCondition... conds) {
RuleCompilationResult compilationResult = IComponentBuilder.buildAndGetRuleCompilation(ruleBase,
ruleCompilation, conds);
UCQUnfolder unfolder = new UCQUnfolder(compilationResult.compilation());
return unfolder.unfold(queries);
}
/**
* Decompose the rules in the RuleBase to single piece rules.
*
* @param ruleBase The RuleBase to transform.
* @param params Conditions to enforce termination ; optional
* @return The transformed RuleBase with single piece rules.
*/
@SafeVarargs
public static ExecutionOutput<RuleBase> decompose(RuleBase ruleBase, IGParameter<InteGraalKeywords, ?>... params) {
Callable<RuleBase> decomposeTask = () -> {
/*
* wrapped method body
*/
Collection<FORule> singlePieceRules = new HashSet<>();
for (FORule r : ruleBase.getRules()) {
singlePieceRules.addAll(Rules.computeSinglePiece(r));
}
return new RuleBaseImpl(singlePieceRules);
};
return executeWithOptionalTimeoutAndHandleException(decomposeTask, params);
}
/**
* Decompose the rules in the RuleBase to single piece rules.
*
* @param ruleBase The RuleBase to transform.
* @param conds Conditions to enforce termination ; optional
* @return The transformed RuleBase with single piece rules.
*/
public static RuleBase decomposeOld(RuleBase ruleBase, ExternalHaltingCondition... conds) {
Collection<FORule> singlePieceRules = new HashSet<>();
for (FORule r : ruleBase.getRules()) {
singlePieceRules.addAll(Rules.computeSinglePiece(r));
}
return new RuleBaseImpl(singlePieceRules);
}
// Constant for the properties of decidability explored by Kiabora
private static final Map<String, RuleSetProperty> propertyMap = RuleSetPropertyHierarchy.generatePropertyMap();
/**
* Tests whether the rule base is recognized as chase terminating rule base for
* any factbase. <br/>
* This test uses the Kiabora analyzer (see
* <a href="https://graphik-team.github.io/graal/downloads/kiabora">...</a>)
*
* @param ruleBase The RuleBase to test.
* @param conds Conditions to enforce termination ; optional
* @return true if the rulebase is a known subclass of FES, else false (caution,
* false doesn't say the rulebase is not FES).
*/
public static Boolean isFesOld(RuleBase ruleBase, ExternalHaltingCondition... conds) {
return createKiaboraAnalyserOld(ruleBaseConverterOld(ruleBase)).isFES();
}
/**
* Tests whether the rule base is recognized as chase terminating rule base for
* any factbase. <br/>
* This test uses the Kiabora analyzer (see
* <a href="https://graphik-team.github.io/graal/downloads/kiabora">...</a>)
*
* @param ruleBase The RuleBase to test.
* @param params Conditions to enforce termination ; optional
* @return true if the rulebase is a known subclass of FES, else false (caution,
* false doesn't say the rulebase is not FES).
*/
@SafeVarargs
public static ExecutionOutput<Boolean> isFes(RuleBase ruleBase, IGParameter<InteGraalKeywords, ?>... params) {
Callable<Boolean> isFesTask = () -> createKiaboraAnalyser(
ruleBaseConverter(ruleBase).returnResultOrRaiseException()
).returnResultOrRaiseException()
.isFES();
return executeWithOptionalTimeoutAndHandleException(isFesTask, params);
}
/**
* Tests whether the rule base is recognized as finite rewriting rule base for
* any query. <br/>
* This test uses the Kiabora analyzer (see
* <a href="https://graphik-team.github.io/graal/downloads/kiabora">...</a>)
*
* @param ruleBase The RuleBase to test.
* @param conds Conditions to enforce termination ; optional
* @return true if the rulebase is a known subclass of FUS, else false (caution,
* false doesn't say the rulebase is not FUS).
*/
public static Boolean isFusOld(RuleBase ruleBase, ExternalHaltingCondition... conds) {
return createKiaboraAnalyserOld(ruleBaseConverterOld(ruleBase)).isFUS();
}
/**
* Tests whether the rule base is recognized as finite rewriting rule base for
* any query. <br/>
* This test uses the Kiabora analyzer (see
* <a href="https://graphik-team.github.io/graal/downloads/kiabora">...</a>)
*
* @param ruleBase The RuleBase to test.
* @param params Conditions to enforce termination ; optional
* @return true if the rulebase is a known subclass of FUS, else false (caution,
* false doesn't say the rulebase is not FUS).
*/
@SafeVarargs
public static ExecutionOutput<Boolean> isFus(RuleBase ruleBase, IGParameter<InteGraalKeywords, ?>... params) {
Callable<Boolean> isFusTask = () ->
createKiaboraAnalyser(
ruleBaseConverter(ruleBase).returnResultOrRaiseException()
).returnResultOrRaiseException().isFUS();
return executeWithOptionalTimeoutAndHandleException(isFusTask, params);
}
/**
* Tests whether the rule base is recognized as Query/Answering decidable for
* any factbase and any query. <br/>
* This test uses the Kiabora analyzer (see
* <a href="https://graphik-team.github.io/graal/downloads/kiabora">...</a>)
*
* @param ruleBase The RuleBase to test.
* @param params Conditions to enforce termination ; optional
* @return true if the rulebase is a known subclass of Q/A decidable, else false
* (caution, false doesn't say the rulebase is not Q/A decidable).
*/
@SafeVarargs
public static ExecutionOutput<Boolean> isDecidable(RuleBase ruleBase, IGParameter<InteGraalKeywords, ?>... params) {
Callable<Boolean> isDecidableTask = () ->
createKiaboraAnalyser(
ruleBaseConverter(ruleBase).returnResultOrRaiseException()
).returnResultOrRaiseException().isDecidable();
return executeWithOptionalTimeoutAndHandleException(isDecidableTask, params);
}
/**
* Tests whether the rule base is recognized as Query/Answering decidable for
* any factbase and any query. <br/>
* This test uses the Kiabora analyzer (see
* <a href="https://graphik-team.github.io/graal/downloads/kiabora">...</a>)
*
* @param ruleBase The RuleBase to test.
* @param conds Conditions to enforce termination ; optional
* @return true if the rulebase is a known subclass of Q/A decidable, else false
* (caution, false doesn't say the rulebase is not Q/A decidable).
*/
public static Boolean isDecidableOld(RuleBase ruleBase, ExternalHaltingCondition... conds) {
return createKiaboraAnalyserOld(ruleBaseConverterOld(ruleBase)).isDecidable();
}
/**
* Tests whether the rule base is recognized as hybridable. <br/>
* This test uses the Kiabora analyzer (see
* <a href="https://graphik-team.github.io/graal/downloads/kiabora">...</a>)
*
* @param ruleBase The RuleBase to test.
* @param conds Conditions to enforce termination ; optional
* @return true if the rulebase is a known subclass hybridable (i.e. a "good"
* FES/FUS partition), else false (caution, false doesn't say the
* rulebase is not hybridable).
*/
public static Boolean isHybridableOld(RuleBase ruleBase, ExternalHaltingCondition... conds) {
Analyser analyser = createKiaboraAnalyserOld(ruleBaseConverterOld(ruleBase));
if (analyser.isFES() || analyser.isFUS())
return true;
// Let's check the max FES combine solution
int[] combine = analyser.combineFES();
if (combine == null) {
return false;
}
// Let's check the solution doesn't contain a BTS component
for (int j : combine) {
if ((j & Analyser.COMBINE_BTS) != 0) {
return false;
}
}
return true;
}
/**
* Tests whether the rule base is recognized as hybridable. <br/>
* This test uses the Kiabora analyzer (see
* <a href="https://graphik-team.github.io/graal/downloads/kiabora">...</a>)
*
* @param ruleBase The RuleBase to test.
* @return true if the rulebase is a known subclass hybridable (i.e. a "good"
* FES/FUS partition), else false (caution, false doesn't say the
* rulebase is not hybridable).
*/
@SafeVarargs
public static ExecutionOutput<Boolean> isHybridable(RuleBase ruleBase, IGParameter<InteGraalKeywords, ?>... params) {
Callable<Boolean> isHybridableTask = () -> {
/*
* wrapped method body
*/
Analyser analyser = createKiaboraAnalyser(
ruleBaseConverter(ruleBase).returnResultOrRaiseException()
).returnResultOrRaiseException();
if (analyser.isFES() || analyser.isFUS()) {
return true;
}
// Check the max FES combine solution
int[] combine = analyser.combineFES();
if (combine == null) {
return false;
}
// Check that the solution doesn't contain a BTS component
for (int j : combine) {
if ((j & Analyser.COMBINE_BTS) != 0) {
return false;
}
}
return true;
};
return executeWithOptionalTimeoutAndHandleException(isHybridableTask, params);
}
/**
* Computes a HybridRuleBase maximizing Forward Chaining or Backward Chaining.
* <br/>
* An hybridRuleBase is composed of two ruleBases: one to saturate and the other
* to rewrite. Hybridize computes Rs and Rw from R such that: - {Rs,Rw} is a
* partition of R, - Rs is FES, - Rw is FUS, - Forall F, Q, chase(F,Rs) |=
* Rewrite(Q,Rw) iff F,R |= Q One can choose to maximize Rs or Rw. Caution, one
* can compute an empty Rs or Rw (then the other rule base is equal to R) This
* test uses the Kiabora analyser (see
* <a href="https://graphik-team.github.io/graal/downloads/kiabora">...</a>)
*
* @param ruleBase The RuleBase to hybridize
* @param hybridType The type of hybridisation: "max_fes" to maximise the part
* to saturate, or "max_fus" to maximise the part to rewrite.
* @param conds Conditions to enforce termination ; optional
* @return the hybrid rule base or an empty optional if an error occurs.
*/
public static Optional<HybridRuleBase> hybridizeOld(RuleBase ruleBase,
InteGraalKeywords.Algorithms.Parameters.HybridTypes hybridType, ExternalHaltingCondition... conds) {
AnalyserRuleSet ruleSet = ruleBaseConverterOld(ruleBase);
Analyser analyser = createKiaboraAnalyserOld(ruleSet);
int[] combine = switch (hybridType) {
case MAX_FUS -> analyser.combineFUS();
case MAX_FES -> analyser.combineFES();
};
// Checks the existence of combine solution
if (combine == null) {
return Optional.empty();
}
// Check that the solution found doesn't contain a BTS component
for (int j : combine) {
if ((j & Analyser.COMBINE_BTS) != 0) {
return Optional.empty();
}
}
// Generates the HybridRuleBase
RuleBase ruleBaseS = EndUserAPI.filterOld(ruleSet, Analyser.COMBINE_FES, combine, analyser);
RuleBase ruleBaseW = EndUserAPI.filterOld(ruleSet, Analyser.COMBINE_FUS, combine, analyser);
return Optional.of(new HybridRuleBase(ruleBaseS, ruleBaseW));
}
/**
* Computes a HybridRuleBase maximizing Forward Chaining or Backward Chaining.
* <br/>
* An hybridRuleBase is composed of two ruleBases: one to saturate and the other
* to rewrite. Hybridize computes Rs and Rw from R such that: - {Rs,Rw} is a
* partition of R, - Rs is FES, - Rw is FUS, - Forall F, Q, chase(F,Rs) |=
* Rewrite(Q,Rw) iff F,R |= Q One can choose to maximize Rs or Rw. Caution, one
* can compute an empty Rs or Rw (then the other rule base is equal to R) This
* test uses the Kiabora analyser (see
* <a href="https://graphik-team.github.io/graal/downloads/kiabora">...</a>)
*
* @param ruleBase The RuleBase to hybridize
* @param params The type of hybridisation: "max_fes" to maximise the part to
* saturate, or "max_fus" to maximise the part to rewrite as
* well as conditions to enforce termination and the reasoning
* algorithm configuration ; optional
* @return the hybrid rule base or an empty optional if an error occurs.
*/
@SafeVarargs
public static ExecutionOutput<Optional<HybridRuleBase>> hybridize(RuleBase ruleBase, IGParameter<InteGraalKeywords, ?>... params) {
Callable<Optional<HybridRuleBase>> hybridizeTask = () -> {
/*
* wrapped method body
*/
AnalyserRuleSet ruleSet = ruleBaseConverter(ruleBase).returnResultOrRaiseException();
Analyser analyser = createKiaboraAnalyser(ruleSet).returnResultOrRaiseException();
var hybridType = IGParameterValueExtractor.getHybridType(params);
int[] combine = switch (hybridType) {
case MAX_FUS -> analyser.combineFUS();
case MAX_FES -> analyser.combineFES();
};
// Checks the existence of combine solution
if (combine == null) {
return Optional.empty();
}
// Check that the solution found doesn't contain a BTS component
for (int j : combine) {
if ((j & Analyser.COMBINE_BTS) != 0) {
return Optional.empty();
}
}
// Generates the HybridRuleBase
RuleBase ruleBaseS = EndUserAPI.filter(ruleSet, Analyser.COMBINE_FES, combine, analyser, params).returnResultOrRaiseException();
RuleBase ruleBaseW = EndUserAPI.filter(ruleSet, Analyser.COMBINE_FUS, combine, analyser, params).returnResultOrRaiseException();
return Optional.of(new HybridRuleBase(ruleBaseS, ruleBaseW));
};
return executeWithOptionalTimeoutAndHandleException(hybridizeTask, params);
}
/**
* Tests whether the two rule bases form a hybrid rule base. <br/>
* Checks the following conditions on the two base ruleBaseToSaturate (Rs) and
* ruleBaseToRewrite (Rw): - {Rs,Rw} is a partition of R, - Rs is FES, - Rw is
* FUS, - There is no dependency from a rule in Rw to a rule in Rs <br/>
* This test uses the Kiabora analyser (see
* <a href="https://graphik-team.github.io/graal/downloads/kiabora">...</a>)
*
* @param ruleBaseToSaturate The RuleBase to process in forward chaining
* @param ruleBaseToRewrite The RuleBase to process in backward chaining
* @return true if the (ruleBaseToSaturate,ruleBaseToRewrite) is recognized as
* hybridable, else false (caution, false doesn't say this partition is
* not hybridable).
*/
public static ExecutionOutput<Boolean> isHybrid(RuleBase ruleBaseToSaturate, RuleBase ruleBaseToRewrite) {
// TODO
throw new UnsupportedOperationException(
"Test to see if two rule bases form a hybrid rule base is not yet implemented");
}
/**
* Tests whether the two rule bases form a hybrid rule base. <br/>
* Checks the following conditions on the two base ruleBaseToSaturate (Rs) and
* ruleBaseToRewrite (Rw): - {Rs,Rw} is a partition of R, - Rs is FES, - Rw is
* FUS, - There is no dependency from a rule in Rw to a rule in Rs <br/>
* This test uses the Kiabora analyser (see
* <a href="https://graphik-team.github.io/graal/downloads/kiabora">...</a>)
*
* @param ruleBaseToSaturate The RuleBase to process in forward chaining
* @param ruleBaseToRewrite The RuleBase to process in backward chaining
* @param conds Conditions to enforce termination ; optional
* @return true if the (ruleBaseToSaturate,ruleBaseToRewrite) is recognized as
* hybridable, else false (caution, false doesn't say this partition is
* not hybridable).
*/
public static Boolean isHybridOld(RuleBase ruleBaseToSaturate, RuleBase ruleBaseToRewrite,
ExternalHaltingCondition... conds) {
// TODO
throw new UnsupportedOperationException(
"Test to see if two rule bases form a hybrid rule base is not yet implemented");
}
/**
* Converts an InteGraal rule base into a Kiabora rule set.
*
* @param ruleBase The RuleBase to convert.
* @param conds Conditions to enforce termination ; optional
* @return The converted AnalyserRuleSet.
*/
private static AnalyserRuleSet ruleBaseConverterOld(RuleBase ruleBase, ExternalHaltingCondition... conds) {
RuleSet graalRuleBase = new LinkedListRuleSet();
for (FORule r : ruleBase.getRules()) {
graalRuleBase.add(RuleConverter.convert(r));
}
return new AnalyserRuleSet(graalRuleBase);
}
/**
* Converts an InteGraal rule base into a Kiabora rule set.
*
* @param ruleBase The RuleBase to convert.
* @param params timeout
* @return The converted AnalyserRuleSet.
*/
private static ExecutionOutput<AnalyserRuleSet> ruleBaseConverter(RuleBase ruleBase, IGParameter<InteGraalKeywords, ?>... params) {
Callable<AnalyserRuleSet> ruleBaseConverterTask = () -> {
/*
* wrapped method body
*/
RuleSet graalRuleBase = ruleBase.getRules().stream().map(RuleConverter::convert)
.collect(Collectors.toCollection(LinkedListRuleSet::new));
return new AnalyserRuleSet(graalRuleBase);
};
return executeWithOptionalTimeoutAndHandleException(ruleBaseConverterTask, params);
}
/**
* Creates a KiaboraAnalyser to perform all rule base analysis. <br/>
* This test uses the Kiabora analyzer (see
* <a href="https://graphik-team.github.io/graal/downloads/kiabora">...</a>)
*
* @param ruleSet The RuleBase for analysis. * @param conds Conditions to
* enforce termination ; optional
* @return the kiabora analyser
*/
private static Analyser createKiaboraAnalyserOld(AnalyserRuleSet ruleSet, ExternalHaltingCondition... conds) {
// TODO : what is the impact of the three following commands?
ruleSet.enableUnifiers(true);
ruleSet.removeDependencyChecker(ProductivityChecker.instance());
ruleSet.addDependencyChecker(RestrictedProductivityChecker.instance());
Map<String, RuleSetProperty> properties = new TreeMap<>(propertyMap);
RuleSetPropertyHierarchy hierarchy = new RuleSetPropertyHierarchy(properties.values());
Analyser analyser = new Analyser();
analyser.setProperties(hierarchy);
analyser.setRuleSet(ruleSet);
return analyser;
}
/**
* Creates a KiaboraAnalyser to perform all rule base analysis. <br/>
* This test uses the Kiabora analyzer (see
* <a href="https://graphik-team.github.io/graal/downloads/kiabora">...</a>)
*
* @param ruleSet The RuleBase for analysis
* @param params timeout
* @return the kiabora analyser
*/
private static ExecutionOutput<Analyser> createKiaboraAnalyser(AnalyserRuleSet ruleSet,
IGParameter<InteGraalKeywords, ?>... params) {
Callable<Analyser> createKiaboraAnalyserTask = () -> {
/*
* wrapped method body
*/
// TODO: Evaluate the impact of the following commands.
ruleSet.enableUnifiers(true);
ruleSet.removeDependencyChecker(ProductivityChecker.instance());
ruleSet.addDependencyChecker(RestrictedProductivityChecker.instance());
Map<String, RuleSetProperty> properties = new TreeMap<>(propertyMap);
RuleSetPropertyHierarchy hierarchy = new RuleSetPropertyHierarchy(properties.values());
Analyser analyser = new Analyser();
analyser.setProperties(hierarchy);
analyser.setRuleSet(ruleSet);
return analyser;
};
return executeWithOptionalTimeoutAndHandleException(createKiaboraAnalyserTask, params);
}
/**
* Returns a rulebase corresponding to the extraction from the Kiabora RuleSet
* of the subset to saturate/rewrite
*
* @param ruleset the Kiabora AnalyzerRuleSet
* @param criterion precises if one extracts the to_saturate_ruleSet
* (Analyser.COMBINE_FES) or the to_rewrite_ruleSet
* (Analyser.COMBINE_FUS)
* @param combine the table of Kiabora combined SCC
* @param analyser the Kiabora analyzer
* @return the filtered Rulebase
*/
private static RuleBase filterOld(AnalyserRuleSet ruleset, int criterion, int[] combine, Analyser analyser,
ExternalHaltingCondition... conds) {
RuleBase rulebase = new RuleBaseImpl();
for (int i = 0; i < combine.length; ++i) {
if ((combine[i] & criterion) != 0) {
for (Rule r : ruleset.getStronglyConnectedComponentsGraph().getComponent(i)) {
rulebase.add(RuleConverter.reverse(r));
}
}
}
return rulebase;
}
/**
* Returns a rulebase corresponding to the extraction from the Kiabora RuleSet
* of the subset to saturate/rewrite
*
* @param ruleset the Kiabora AnalyzerRuleSet
* @param criterion precises if one extracts the to_saturate_ruleSet
* (Analyser.COMBINE_FES) or the to_rewrite_ruleSet
* (Analyser.COMBINE_FUS)
* @param combine the table of Kiabora combined SCC
* @param analyser the Kiabora analyzer
* @param params timeout
* @return the filtered Rulebase
*/
@SafeVarargs
private static ExecutionOutput<RuleBase> filter(AnalyserRuleSet ruleset, int criterion, int[] combine, Analyser analyser,
IGParameter<InteGraalKeywords, ?>... params) {
Callable<RuleBase> filterTask = () -> {
/*
* wrapped method body
*/
RuleBase rulebase = new RuleBaseImpl();
for (int i = 0; i < combine.length; ++i) {
if ((combine[i] & criterion) != 0) {
for (Rule r : ruleset.getStronglyConnectedComponentsGraph().getComponent(i)) {
rulebase.add(RuleConverter.reverse(r));
}
}
}
return rulebase;
};
return executeWithOptionalTimeoutAndHandleException(filterTask, params);
}
}
\ No newline at end of file
......@@ -3,8 +3,10 @@ package api;
import java.nio.file.Path;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.stream.Stream;
import org.hsqldb.jdbc.JDBCDataSource;
......@@ -38,182 +40,185 @@ import fr.lirmm.boreal.util.keywords.InteGraalKeywords;
@RunWith(Parameterized.class)
class EndUserAPITest {
private static final Path viewDefinitionFile = Path.of("src", "test", "resources", "mapping.vd");
private static final Path dlgpFile = Path.of("src", "test", "resources", "data.dlgp");
private static FederatedFactBase federation;
private static FactBase memory;
private static Collection<Atom> memory_save;
private static RuleBase rulebase;
private static Collection<Query> queries;
@BeforeAll
public static void loadData() throws ViewBuilder.ViewBuilderException, SQLException {
JDBCDataSource sqlDataSource = new JDBCDataSource();
sqlDataSource.setUrl("jdbc:hsqldb:mem:test");
Connection c = sqlDataSource.getConnection();
c.createStatement().execute("SET DATABASE SQL SYNTAX MYS TRUE;");
c.createStatement().execute("CREATE TABLE IF NOT EXISTS p(label varchar(32), name varchar(32));");
c.createStatement().execute("INSERT INTO p VALUES('a', 'a');");
c.createStatement().execute("INSERT INTO p VALUES('a', 'b');");
c.createStatement().execute("INSERT INTO p VALUES('b', 'a');");
c.createStatement().execute("INSERT INTO p VALUES('b', 'c');");
c.createStatement().execute("INSERT INTO p VALUES('c', 'd');");
c.createStatement().execute("INSERT INTO p VALUES('d', 'c');");
c.createStatement().execute("INSERT INTO p VALUES('e', 'e');");
federation = new FederatedFactBase(StorageBuilder.defaultStorage(),
ViewBuilder.createFactBases(viewDefinitionFile.toString()));
ParserResult parserResult = DlgpParser.parseFile(dlgpFile.toString());
memory_save = parserResult.atoms();
memory = new SimpleInMemoryGraphStore(memory_save);
rulebase = new RuleBaseImpl(parserResult.rules());
queries = parserResult.queries();
}
@AfterEach
public void backupFactBase() {
memory = new SimpleInMemoryGraphStore(memory_save);
federation.setDefaultStorage(new SimpleInMemoryGraphStore());
}
@Parameterized.Parameters
static Stream<Arguments> saturationData() {
return Stream.of(Arguments.of("federation", federation, rulebase, 27),
Arguments.of("memory", memory, rulebase, 34));
}
@Parameterized.Parameters
static Stream<Arguments> rewritingData() {
return Stream.of(Arguments.of(rulebase, queries, 5));
}
@Parameterized.Parameters
static Stream<Arguments> evaluationData() {
return Stream.of(Arguments.of("memory", memory, queries, 7),
Arguments.of("federation", federation, queries, 7));
}
@Parameterized.Parameters
static Stream<Arguments> evaluationWithReasoningData() {
return Stream.of(Arguments.of("memory", memory, rulebase, queries, 9),
Arguments.of("federation", federation, rulebase, queries, 9));
}
@DisplayName("Test EndUSerAPI#saturate")
@ParameterizedTest(name = "{index}: Saturation on {0} with EndUserAPI should leave {3} atoms in the local storage")
@MethodSource("saturationData")
public void apiSaturationTest(String desc, FactBase fb, RuleBase rb, long expected_fb_size) {
EndUserAPI.saturateOld(fb, rb, InteGraalKeywords.Algorithms.Parameters.Chase.Checker.SEMI_OBLIVIOUS);
Assert.assertEquals(expected_fb_size, fb.size());
}
@DisplayName("Test EndUSerAPI#saturate")
@ParameterizedTest(name = "{index}: Saturation on {0} with EndUserAPI should leave {3} atoms in the local storage")
@MethodSource("saturationData")
public void apiSaturationNewTest(String desc, FactBase fb, RuleBase rb, long expected_fb_size) {
EndUserAPI.saturate(fb, rb, new IGParameter(InteGraalKeywords.CHECKER,
InteGraalKeywords.Algorithms.Parameters.Chase.Checker.SEMI_OBLIVIOUS));
Assert.assertEquals(expected_fb_size, fb.size());
}
@DisplayName("Test EndUSerAPI#rewrite")
@ParameterizedTest(name = "{index}: Rewriting with EndUserAPI should give {2} rewritings")
@MethodSource("rewritingData")
public void apiRewritingTest(RuleBase rb, Collection<Query> qs, long expected_rewritings_size) {
Collection<Query> rewritings = EndUserAPI.rewriteOld(rb, qs,
InteGraalKeywords.Algorithms.Parameters.Compilation.NO_COMPILATION);
rewritings.forEach(System.out::println);
Assert.assertEquals(expected_rewritings_size, rewritings.size());
}
@DisplayName("Test EndUSerAPI#rewrite")
@ParameterizedTest(name = "{index}: Rewriting with EndUserAPI should give {2} rewritings")
@MethodSource("rewritingData")
public void apiRewritingNewTest(RuleBase rb, Collection<Query> qs, long expected_ucq_in_the_rewritings) {
Collection<UnionFOQuery> rewritings = EndUserAPI.rewrite(rb, qs, new IGParameter(InteGraalKeywords.COMPILATION,
InteGraalKeywords.Algorithms.Parameters.Compilation.NO_COMPILATION));
rewritings.forEach(System.out::println);
int count = 0;
for(var r:rewritings) {
count+=r.getQueries().size();
}
Assert.assertEquals(expected_ucq_in_the_rewritings, count);
}
@DisplayName("Test EndUSerAPI#evaluate")
@ParameterizedTest(name = "{index}: Query evaluation on {0} with EndUserAPI should give {3} answers")
@MethodSource("evaluationData")
public void apiEvaluationTest(String desc, FactBase fb, Collection<Query> qs, long expected_answer_size) {
Iterator<Substitution> query_answers = EndUserAPI.evaluateOld(fb, qs);
long count = 0;
while (query_answers.hasNext()) {
query_answers.next();
count++;
}
Assert.assertEquals(expected_answer_size, count);
}
@DisplayName("Test EndUSerAPI#evaluate")
@ParameterizedTest(name = "{index}: Query evaluation on {0} with EndUserAPI should give {3} answers")
@MethodSource("evaluationData")
public void apiEvaluationNewTest(String desc, FactBase fb, Collection<Query> qs, long expected_answer_size) {
Iterator<Substitution> query_answers = EndUserAPI.evaluate(fb, qs);
long count = 0;
while (query_answers.hasNext()) {
query_answers.next();
count++;
}
Assert.assertEquals(expected_answer_size, count);
}
@DisplayName("Test EndUSerAPI#evaluate with reasoning")
@ParameterizedTest(name = "{index}: Query evaluation with reasoning on {0} with EndUserAPI should give {4} answers")
@MethodSource("evaluationWithReasoningData")
public void apiEvaluationWithReasoningTest(String desc, FactBase fb, RuleBase rb, Collection<Query> qs,
long expected_answer_size) {
Iterator<Substitution> rewriting_query_answers = EndUserAPI.evaluateRewOld(fb, qs, rb);
long rewriting_count = 0;
while (rewriting_query_answers.hasNext()) {
rewriting_query_answers.next();
rewriting_count++;
}
Assert.assertEquals(expected_answer_size, rewriting_count);
Iterator<Substitution> saturation_query_answers = EndUserAPI.evaluateSatOld(fb, qs, rb);
long saturation_count = 0;
while (saturation_query_answers.hasNext()) {
saturation_query_answers.next();
saturation_count++;
}
Assert.assertEquals(expected_answer_size, saturation_count);
}
@DisplayName("Test EndUSerAPI#evaluate with reasoning")
@ParameterizedTest(name = "{index}: Query evaluation with reasoning on {0} with EndUserAPI should give {4} answers")
@MethodSource("evaluationWithReasoningData")
public void apiEvaluationWithReasoningNewTest(String desc, FactBase fb, RuleBase rb, Collection<Query> qs,
long expected_answer_size) {
Iterator<Substitution> rewriting_query_answers = EndUserAPI.evaluateRew(fb, qs, rb);
long rewriting_count = 0;
while (rewriting_query_answers.hasNext()) {
rewriting_query_answers.next();
rewriting_count++;
}
Assert.assertEquals(expected_answer_size, rewriting_count);
Iterator<Substitution> saturation_query_answers = EndUserAPI.evaluateSatOld(fb, qs, rb);
long saturation_count = 0;
while (saturation_query_answers.hasNext()) {
saturation_query_answers.next();
saturation_count++;
}
Assert.assertEquals(expected_answer_size, saturation_count);
}
private static final Path viewDefinitionFile = Path.of("src", "test", "resources", "mapping.vd");
private static final Path dlgpFile = Path.of("src", "test", "resources", "data.dlgp");
private static FederatedFactBase federation;
private static FactBase memory;
private static Collection<Atom> memory_save;
private static RuleBase rulebase;
private static Collection<Query> queries;
@BeforeAll
public static void loadData() throws ViewBuilder.ViewBuilderException, SQLException {
JDBCDataSource sqlDataSource = new JDBCDataSource();
sqlDataSource.setUrl("jdbc:hsqldb:mem:test");
Connection c = sqlDataSource.getConnection();
c.createStatement().execute("SET DATABASE SQL SYNTAX MYS TRUE;");
c.createStatement().execute("CREATE TABLE IF NOT EXISTS p(label varchar(32), name varchar(32));");
c.createStatement().execute("INSERT INTO p VALUES('a', 'a');");
c.createStatement().execute("INSERT INTO p VALUES('a', 'b');");
c.createStatement().execute("INSERT INTO p VALUES('b', 'a');");
c.createStatement().execute("INSERT INTO p VALUES('b', 'c');");
c.createStatement().execute("INSERT INTO p VALUES('c', 'd');");
c.createStatement().execute("INSERT INTO p VALUES('d', 'c');");
c.createStatement().execute("INSERT INTO p VALUES('e', 'e');");
federation = new FederatedFactBase(StorageBuilder.defaultStorage(),
ViewBuilder.createFactBases(viewDefinitionFile.toString()));
ParserResult parserResult = DlgpParser.parseFile(dlgpFile.toString());
memory_save = parserResult.atoms();
memory = new SimpleInMemoryGraphStore(memory_save);
rulebase = new RuleBaseImpl(parserResult.rules());
queries = parserResult.queries();
}
@AfterEach
public void backupFactBase() {
memory = new SimpleInMemoryGraphStore(memory_save);
federation.setDefaultStorage(new SimpleInMemoryGraphStore());
}
@Parameterized.Parameters
static Stream<Arguments> saturationData() {
return Stream.of(Arguments.of("federation", federation, rulebase, 27),
Arguments.of("memory", memory, rulebase, 34));
}
@Parameterized.Parameters
static Stream<Arguments> rewritingData() {
return Stream.of(Arguments.of(rulebase, queries, 5));
}
@Parameterized.Parameters
static Stream<Arguments> evaluationData() {
return Stream.of(Arguments.of("memory", memory, queries, 7),
Arguments.of("federation", federation, queries, 7));
}
@Parameterized.Parameters
static Stream<Arguments> evaluationWithReasoningData() {
return Stream.of(Arguments.of("memory", memory, rulebase, queries, 9),
Arguments.of("federation", federation, rulebase, queries, 9));
}
@DisplayName("Test EndUSerAPI#saturate")
@ParameterizedTest(name = "{index}: Saturation on {0} with EndUserAPI should leave {3} atoms in the local storage")
@MethodSource("saturationData")
public void apiSaturationTest(String desc, FactBase fb, RuleBase rb, long expected_fb_size) {
EndUserAPI.saturateOld(fb, rb, InteGraalKeywords.Algorithms.Parameters.Chase.Checker.SEMI_OBLIVIOUS);
Assert.assertEquals(expected_fb_size, fb.size());
}
@DisplayName("Test EndUSerAPI#saturate")
@ParameterizedTest(name = "{index}: Saturation on {0} with EndUserAPI should leave {3} atoms in the local storage")
@MethodSource("saturationData")
public void apiSaturationNewTest(String desc, FactBase fb, RuleBase rb, long expected_fb_size) {
EndUserAPI.saturate(fb, rb, new IGParameter(InteGraalKeywords.CHECKER,
InteGraalKeywords.Algorithms.Parameters.Chase.Checker.SEMI_OBLIVIOUS));
Assert.assertEquals(expected_fb_size, fb.size());
}
@DisplayName("Test EndUSerAPI#rewrite")
@ParameterizedTest(name = "{index}: Rewriting with EndUserAPI should give {2} rewritings")
@MethodSource("rewritingData")
public void apiRewritingTest(RuleBase rb, Collection<Query> qs, long expected_rewritings_size) {
Collection<Query> rewritings = EndUserAPI.rewriteOld(rb, qs,
InteGraalKeywords.Algorithms.Parameters.Compilation.NO_COMPILATION);
rewritings.forEach(System.out::println);
Assert.assertEquals(expected_rewritings_size, rewritings.size());
}
@DisplayName("Test EndUSerAPI#rewrite")
@ParameterizedTest(name = "{index}: Rewriting with EndUserAPI should give {2} rewritings")
@MethodSource("rewritingData")
public void apiRewritingNewTest(RuleBase rb, Collection<Query> qs, long expected_ucq_in_the_rewritings) {
Collection<UnionFOQuery> rewritings = (Collection<UnionFOQuery>) EndUserAPI.rewrite(rb, qs, new IGParameter(InteGraalKeywords.COMPILATION,
InteGraalKeywords.Algorithms.Parameters.Compilation.NO_COMPILATION)).result();
rewritings.forEach(System.out::println);
int count = 0;
for (var r : rewritings) {
count += r.getQueries().size();
}
Assert.assertEquals(expected_ucq_in_the_rewritings, count);
}
@DisplayName("Test EndUSerAPI#evaluate")
@ParameterizedTest(name = "{index}: Query evaluation on {0} with EndUserAPI should give {3} answers")
@MethodSource("evaluationData")
public void apiEvaluationTest(String desc, FactBase fb, Collection<Query> qs, long expected_answer_size) {
Iterator<Substitution> query_answers = EndUserAPI.evaluateOld(fb, qs);
long count = 0;
while (query_answers.hasNext()) {
query_answers.next();
count++;
}
Assert.assertEquals(expected_answer_size, count);
}
@DisplayName("Test EndUSerAPI#evaluate")
@ParameterizedTest(name = "{index}: Query evaluation on {0} with EndUserAPI should give {3} answers")
@MethodSource("evaluationData")
public void apiEvaluationNewTest(String desc, FactBase fb, Collection<Query> qs, long expected_answer_size) {
Iterator<Substitution> query_answers = EndUserAPI.evaluate(fb, qs).result();
long count = 0;
while (query_answers.hasNext()) {
query_answers.next();
count++;
}
Assert.assertEquals(expected_answer_size, count);
}
@DisplayName("Test EndUSerAPI#evaluate with reasoning")
@ParameterizedTest(name = "{index}: Query evaluation with reasoning on {0} with EndUserAPI should give {4} answers")
@MethodSource("evaluationWithReasoningData")
public void apiEvaluationWithReasoningTest(String desc, FactBase fb, RuleBase rb, Collection<Query> qs,
long expected_answer_size) {
Iterator<Substitution> rewriting_query_answers = EndUserAPI.evaluateRewOld(fb, qs, rb);
long rewriting_count = 0;
while (rewriting_query_answers.hasNext()) {
rewriting_query_answers.next();
rewriting_count++;
}
Assert.assertEquals(expected_answer_size, rewriting_count);
Iterator<Substitution> saturation_query_answers = EndUserAPI.evaluateSatOld(fb, qs, rb);
long saturation_count = 0;
while (saturation_query_answers.hasNext()) {
saturation_query_answers.next();
saturation_count++;
}
Assert.assertEquals(expected_answer_size, saturation_count);
}
@DisplayName("Test EndUSerAPI#evaluate with reasoning")
@ParameterizedTest(name = "{index}: Query evaluation with reasoning on {0} with EndUserAPI should give {4} answers")
@MethodSource("evaluationWithReasoningData")
public void apiEvaluationWithReasoningNewTest(String desc, FactBase fb, RuleBase rb, Collection<Query> qs,
long expected_answer_size) {
Iterator<Substitution> rewriting_query_answers = EndUserAPI.evaluateRew(fb, qs, rb).result();
List<Substitution> resSubs = new ArrayList<>();
while (rewriting_query_answers.hasNext()) {
var nextAns = rewriting_query_answers.next();
if (!resSubs.contains(nextAns)) {
resSubs.add(nextAns);
}
}
Assert.assertEquals(expected_answer_size, resSubs.size());
Iterator<Substitution> saturation_query_answers = EndUserAPI.evaluateSatOld(fb, qs, rb);
long saturation_count = 0;
while (saturation_query_answers.hasNext()) {
saturation_query_answers.next();
saturation_count++;
}
Assert.assertEquals(expected_answer_size, saturation_count);
}
}
......@@ -111,7 +111,7 @@ public class OMQAViaEndUserAPITest {
Assertions.assertFalse(computedAnswerSat.hasNext());
}
var computedAnswerRew = EndUserAPI.evaluateRew(fb, parser.queries(), rb);
var computedAnswerRew = EndUserAPI.evaluateRew(fb, parser.queries(), rb).result();
if (expectedAnswer.equals("true")) {
Assertions.assertTrue(computedAnswerRew.hasNext());
......
package api;
import java.time.Duration;
import java.util.Iterator;
import java.util.stream.Stream;
import fr.boreal.model.logicalElements.api.Substitution;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.params.ParameterizedTest;
......@@ -79,7 +81,7 @@ public class QueryAnsweringViaEndUserAPITest {
var paramTimeout = new IGParameter(InteGraalKeywords.TIMEOUT, Duration.parse("PT100s"));
var paramImage = new IGParameter(InteGraalKeywords.IMAGES, InteGraalKeywords.Algorithms.Images.CONSTANT);
var computedAnswer = EndUserAPI.evaluate(fb, parser.queries(), paramTimeout, paramImage);
Iterator<Substitution> computedAnswer = (Iterator<Substitution>) EndUserAPI.evaluate(fb, parser.queries(), paramTimeout, paramImage).result();
Assertions.assertEquals(expectedAnswer, computedAnswer.hasNext());
......@@ -99,9 +101,9 @@ public class QueryAnsweringViaEndUserAPITest {
FactBase fb = new SimpleInMemoryGraphStore(parser.atoms());
var paramMaxAnswers = new IGParameter(InteGraalKeywords.MAX,0);
var computedAnswerUnfiltered = EndUserAPI.evaluate(fb, parser.queries());
var computedAnswerFiltered = EndUserAPI.evaluate(fb, parser.queries(), paramMaxAnswers);
Iterator<Substitution> computedAnswerUnfiltered = EndUserAPI.evaluate(fb, parser.queries()).result();
Iterator<Substitution> computedAnswerFiltered = (Iterator<Substitution>) EndUserAPI.evaluate(fb, parser.queries(), paramMaxAnswers).result();
int filteredAns=0;
int unfilteredAns=0;
......
......@@ -176,7 +176,7 @@ public class RewritingViaEndUserAPITest {
var nocompilParam = new IGParameter(InteGraalKeywords.COMPILATION,
InteGraalKeywords.Algorithms.Parameters.Compilation.NO_COMPILATION);
Collection<UnionFOQuery> result = EndUserAPI.rewrite(rb, queries, nocompilParam);
Collection<UnionFOQuery> result = (Collection<UnionFOQuery>) EndUserAPI.rewrite(rb, queries, nocompilParam).result();
int ucq_size;
if (result.stream().findAny().isEmpty()) {
......
......@@ -99,7 +99,7 @@ public class SaturationViaEndUserAPITest {
var paramRank = new IGParameter(InteGraalKeywords.RANK, 1);
var paramChecker = new IGParameter(InteGraalKeywords.CHECKER, Algorithms.Parameters.Chase.Checker.RESTRICTED);
var saturatedFactbase = EndUserAPI.saturate(fb, rb, paramTimeout, paramChecker, paramRank);
FactBase saturatedFactbase = (FactBase) EndUserAPI.saturate(fb, rb, paramTimeout, paramChecker, paramRank).result();
Collection<Atom> expectedSaturation = new ArrayList<>(dlgpExpected_parser.atoms());
......@@ -151,7 +151,7 @@ public class SaturationViaEndUserAPITest {
var paramRank = new IGParameter(InteGraalKeywords.RANK, 1);
var paramChecker = new IGParameter(InteGraalKeywords.CHECKER, Algorithms.Parameters.Chase.Checker.RESTRICTED);
var saturatedFactbase = EndUserAPI.saturate(fb, rb, paramTimeout, paramChecker, paramRank);
FactBase saturatedFactbase = (FactBase) EndUserAPI.saturate(fb, rb, paramTimeout, paramChecker, paramRank).result();
Collection<Atom> expectedSaturation = new ArrayList<>(dlgpExpected_parser.atoms());
......