diff --git a/integraal/integraal-configuration/src/main/java/fr/boreal/configuration/keywords/InteGraalKeywords.java b/integraal/integraal-configuration/src/main/java/fr/boreal/configuration/keywords/InteGraalKeywords.java index 21ea5f11bb632f1c52b7721e8d5179e451d6ab03..5fb5f66de34cd98f092fcc5a728fad3d8db775f1 100644 --- a/integraal/integraal-configuration/src/main/java/fr/boreal/configuration/keywords/InteGraalKeywords.java +++ b/integraal/integraal-configuration/src/main/java/fr/boreal/configuration/keywords/InteGraalKeywords.java @@ -350,7 +350,8 @@ public enum InteGraalKeywords { /** * GRD Scheduler */ - GRD + GRD, + BY_PREDICATE } /** diff --git a/integraal/integraal-explanation/src/main/java/fr/boreal/explanation/configuration/DefaultChaseForExplanations.java b/integraal/integraal-explanation/src/main/java/fr/boreal/explanation/configuration/DefaultChaseForExplanations.java index bdbe4772cde8e46ae5f708ee34bd4857859db8f1..54986fbe027b7ea29eacd8e55e9a3ac4ed3b3b2f 100644 --- a/integraal/integraal-explanation/src/main/java/fr/boreal/explanation/configuration/DefaultChaseForExplanations.java +++ b/integraal/integraal-explanation/src/main/java/fr/boreal/explanation/configuration/DefaultChaseForExplanations.java @@ -19,10 +19,9 @@ public class DefaultChaseForExplanations { public static Chase chase(FactBase fb, RuleBase rb) { Chase chase = ChaseBuilder.defaultBuilder(fb, rb) - .useSemiObliviousChecker() + .useObliviousChecker() .useNaiveComputer() - //.useGRDRuleScheduler() - .useNaiveRuleScheduler() + .useByPredicateRuleScheduler() .useMultiThreadRuleApplier() .build().get(); chase.execute(); diff --git a/integraal/integraal-explanation/src/test/java/fr/boreal/test/explanation/TestData.java b/integraal/integraal-explanation/src/test/java/fr/boreal/test/explanation/TestData.java index c73144ba65b88751d4d6a0707d85957c444b4696..beb3a9ec43a760d1f66ee7e433fca48f6ec48065 100644 --- a/integraal/integraal-explanation/src/test/java/fr/boreal/test/explanation/TestData.java +++ b/integraal/integraal-explanation/src/test/java/fr/boreal/test/explanation/TestData.java @@ -125,8 +125,8 @@ public class TestData { "Ontology1260916270538", // "platformOntology", // "snoopy", - "transitive-ancestor", -// "catalogue", +// "transitive-ancestor", +// "catalogue" "ddex" // "ncbi_rank", // "oil", diff --git a/integraal/integraal-explanation/src/test/java/fr/boreal/test/explanation/check_has_explanation/MowlOntologyTest.java b/integraal/integraal-explanation/src/test/java/fr/boreal/test/explanation/check_has_explanation/MowlOntologyTest.java index 8b3d766e84dc834ac85e216df5b18831a21441d2..2181b865baa440466bb50556dd30e07c06b04325 100644 --- a/integraal/integraal-explanation/src/test/java/fr/boreal/test/explanation/check_has_explanation/MowlOntologyTest.java +++ b/integraal/integraal-explanation/src/test/java/fr/boreal/test/explanation/check_has_explanation/MowlOntologyTest.java @@ -30,7 +30,7 @@ import java.util.stream.Stream; public class MowlOntologyTest { static String mowl_bench_path = "./src/test/resources/mowl-bench-main/"; - static List<String> mowl_bench_datasets = TestData.all_mowl_bench_datasets; + static List<String> mowl_bench_datasets = TestData.hard_mowl_bench_datasets; enum AtomicQueryExplainerType { STATIC_GRI_FB_MARCO, diff --git a/integraal/integraal-explanation/src/test/java/fr/boreal/test/explanation/check_same_explanation/FactSupport_MowlOntologyTest.java b/integraal/integraal-explanation/src/test/java/fr/boreal/test/explanation/check_same_explanation/FactSupport_MowlOntologyTest.java index 78a85f7bf159db8d8e2529de9433988cdf4bcbd0..7957b425d074f4171a7c7629075ad4d8c87f58c2 100644 --- a/integraal/integraal-explanation/src/test/java/fr/boreal/test/explanation/check_same_explanation/FactSupport_MowlOntologyTest.java +++ b/integraal/integraal-explanation/src/test/java/fr/boreal/test/explanation/check_same_explanation/FactSupport_MowlOntologyTest.java @@ -2,6 +2,7 @@ package fr.boreal.test.explanation.check_same_explanation; import fr.boreal.explanation.InternalDLGPParser; import fr.boreal.explanation.api.explainers.AtomicQueryExplainer; +import fr.boreal.explanation.kb_gri.explainers.incremental_gri.FactSupportExplainer_IncrementalKBGRI; import fr.boreal.explanation.kb_gri.explainers.static_gri.FactSupportExplainer_KBGRI; import fr.boreal.explanation.solving_enumerating.sat4j.Sat4JSolver; import fr.boreal.explanation.tracker_gri.explainers.FactSupportExplainer_TrackerGRI; @@ -30,7 +31,8 @@ public class FactSupport_MowlOntologyTest { STATIC_GRI_FACT_MARCO, STATIC_GRI_FACT_S4J, TRACKER_STATIC_GRI_FACT_MARCO, - TRACKER_STATIC_GRI_FACT_S4J + TRACKER_STATIC_GRI_FACT_S4J, + INCREMENTAL_GRI_FACT_MARCO } static private Map<Atom,Integer> nbExplanations = new HashMap<>(); @@ -44,6 +46,7 @@ public class FactSupport_MowlOntologyTest { case STATIC_GRI_FACT_S4J -> new FactSupportExplainer_KBGRI(kb, new Sat4JSolver()); case TRACKER_STATIC_GRI_FACT_MARCO -> new FactSupportExplainer_TrackerGRI(kb); case TRACKER_STATIC_GRI_FACT_S4J -> new FactSupportExplainer_TrackerGRI(kb, new Sat4JSolver()); + case INCREMENTAL_GRI_FACT_MARCO -> new FactSupportExplainer_IncrementalKBGRI(kb); }; } diff --git a/integraal/integraal-explanation/src/test/java/fr/boreal/test/explanation/check_same_explanation/KBSupport_MowlOntologyTest.java b/integraal/integraal-explanation/src/test/java/fr/boreal/test/explanation/check_same_explanation/KBSupport_MowlOntologyTest.java index 5ddc1472792266b3d5206fdfc670946a4d04444d..79da30fde405d0547ca68ac2b345fee70e182773 100644 --- a/integraal/integraal-explanation/src/test/java/fr/boreal/test/explanation/check_same_explanation/KBSupport_MowlOntologyTest.java +++ b/integraal/integraal-explanation/src/test/java/fr/boreal/test/explanation/check_same_explanation/KBSupport_MowlOntologyTest.java @@ -26,18 +26,18 @@ import java.util.stream.Stream; public class KBSupport_MowlOntologyTest { static String mowl_bench_path = TestData.mowl_bench_path; - static List<String> mowl_bench_datasets = TestData.default_mowl_bench_datasets; + static List<String> mowl_bench_datasets = TestData.hard_mowl_bench_datasets; enum AtomicQueryExplainerType { STATIC_GRI_KB_MARCO, - STATIC_GRI_KB_S4J, - TRACKER_STATIC_GRI_KB_MARCO, - TRACKER_STATIC_GRI_KB_S4J, - INCREMENTAL_GRI_KB_MARCO + STATIC_GRI_KB_S4J//, +// TRACKER_STATIC_GRI_KB_MARCO, +// TRACKER_STATIC_GRI_KB_S4J, +// INCREMENTAL_GRI_KB_MARCO } static private Map<Pair<String,Atom>,Integer> nbExplanations = new HashMap<>(); - static private Map<Atom, Set<?>> queryToExplanations = new HashMap<>(); + static private Map<Pair<String,Atom>, Set<?>> queryToExplanations = new HashMap<>(); static AtomicQueryExplainer<?> getExplainer( AtomicQueryExplainerType type, @@ -45,9 +45,9 @@ public class KBSupport_MowlOntologyTest { return switch (type) { case STATIC_GRI_KB_MARCO -> new KBSupportExplainer_KBGRI(kb); case STATIC_GRI_KB_S4J -> new KBSupportExplainer_KBGRI(kb, new Sat4JSolver()); - case TRACKER_STATIC_GRI_KB_MARCO -> new KBSupportExplainer_TrackerGRI(kb); - case TRACKER_STATIC_GRI_KB_S4J -> new KBSupportExplainer_TrackerGRI(kb, new Sat4JSolver()); - case INCREMENTAL_GRI_KB_MARCO -> new KBSupportExplainer_IncrementalKBGRI(kb); +// case TRACKER_STATIC_GRI_KB_MARCO -> new KBSupportExplainer_TrackerGRI(kb); +// case TRACKER_STATIC_GRI_KB_S4J -> new KBSupportExplainer_TrackerGRI(kb, new Sat4JSolver()); +// case INCREMENTAL_GRI_KB_MARCO -> new KBSupportExplainer_IncrementalKBGRI(kb); }; } @@ -92,12 +92,18 @@ public class KBSupport_MowlOntologyTest { var key = Pair.of(ontology_name,query); if (nbExplanations.containsKey(key)) { + System.out.println(queryToExplanations); + System.out.println(nbExplanations); + Assertions.assertTrue(explanations.size() == nbExplanations.get(key), "Explainer "+explainerType+" gives "+explanations.size()+" explanations whereas Marco gives "+nbExplanations.get(key)+" for query: " + query + - "\nMarco:" + queryToExplanations.get(query) + "\n" + explainerType + explanations); + "\nMarco:" + queryToExplanations.get(key) + "\n" + explainerType + explanations); } else { nbExplanations.put(key, explanations.size()); - queryToExplanations.put(query,explanations); + queryToExplanations.put(key, new HashSet<>(explanations)); + + System.out.println("Explanations: "+queryToExplanations); + System.out.println("Expl number: "+nbExplanations); } } diff --git a/integraal/integraal-forward-chaining/src/main/java/fr/boreal/forward_chaining/chase/ChaseBuilder.java b/integraal/integraal-forward-chaining/src/main/java/fr/boreal/forward_chaining/chase/ChaseBuilder.java index 9b31c6f8a2dc1b84243f2ae6839e60f1df227cfd..d7c648c2aa7ba0ec08ccb265450bc31905bc9a4a 100644 --- a/integraal/integraal-forward-chaining/src/main/java/fr/boreal/forward_chaining/chase/ChaseBuilder.java +++ b/integraal/integraal-forward-chaining/src/main/java/fr/boreal/forward_chaining/chase/ChaseBuilder.java @@ -26,6 +26,7 @@ import fr.boreal.forward_chaining.chase.rule_applier.trigger_computer.NaiveTrigg import fr.boreal.forward_chaining.chase.rule_applier.trigger_computer.SemiNaiveComputer; import fr.boreal.forward_chaining.chase.rule_applier.trigger_computer.TriggerComputer; import fr.boreal.forward_chaining.chase.rule_applier.trigger_computer.TwoStepComputer; +import fr.boreal.forward_chaining.chase.rule_scheduler.ByPredicateScheduler; import fr.boreal.forward_chaining.chase.rule_scheduler.GRDScheduler; import fr.boreal.forward_chaining.chase.rule_scheduler.NaiveScheduler; import fr.boreal.forward_chaining.chase.rule_scheduler.RuleScheduler; @@ -208,6 +209,9 @@ public class ChaseBuilder { case GRD: this.setRuleScheduler(new GRDScheduler(this.rb)); break; + case BY_PREDICATE: + this.setRuleScheduler(new ByPredicateScheduler(this.rb)); + break; } } if (this.eval == null) { @@ -393,6 +397,11 @@ public class ChaseBuilder { return this; } + public ChaseBuilder useByPredicateRuleScheduler() { + this.scheduler = InteGraalKeywords.Algorithms.Parameters.Chase.Scheduler.BY_PREDICATE; + return this; + } + // Body To Query transformers // /** diff --git a/integraal/integraal-forward-chaining/src/main/java/fr/boreal/forward_chaining/chase/rule_scheduler/ByPredicateScheduler.java b/integraal/integraal-forward-chaining/src/main/java/fr/boreal/forward_chaining/chase/rule_scheduler/ByPredicateScheduler.java new file mode 100644 index 0000000000000000000000000000000000000000..79764a9d786a2df1eddab512982aee50b37e711b --- /dev/null +++ b/integraal/integraal-forward-chaining/src/main/java/fr/boreal/forward_chaining/chase/rule_scheduler/ByPredicateScheduler.java @@ -0,0 +1,54 @@ +package fr.boreal.forward_chaining.chase.rule_scheduler; + +import java.util.Collection; +import java.util.stream.Collectors; + +import fr.boreal.configuration.parameters.IGParameter; +import fr.boreal.grd.api.GraphOfFORuleDependencies; +import fr.boreal.grd.impl.GRDImpl; +import fr.boreal.model.kb.api.RuleBase; +import fr.boreal.model.rule.api.FORule; +import fr.boreal.configuration.keywords.InteGraalKeywords; + +/** + * Schedules all the rules that can be triggered by rules applied at the previous step + * according to the graph of rule dependencies + */ +public class ByPredicateScheduler implements RuleScheduler { + + private RuleBase rb; + + /** + * @param rb the rulebase + */ + public ByPredicateScheduler(RuleBase rb) { + this.init(rb); + } + + @Override + public void init(RuleBase rb) { + this.rb = rb; + } + + @Override + public Collection<FORule> getRulesToApply(Collection<FORule> last_applied_rules) { + // first call -> should use an optional instead of null + if(last_applied_rules == null) { + return this.rb.getRules(); + } + return last_applied_rules.parallelStream() + .flatMap(rule -> rule.getHead().getPredicates().parallelStream()) + .distinct() + .flatMap(p -> this.rb.getRulesByBodyPredicate(p).parallelStream()) + .collect(Collectors.toSet()); + } + + public String describe(){ + return getCorrespondingParameter().value().toString(); + } + + public IGParameter<InteGraalKeywords,?> getCorrespondingParameter(){ + return new IGParameter<>(InteGraalKeywords.SCHEDULER,InteGraalKeywords.Algorithms.Parameters.Chase.Scheduler.GRD); + } + +} diff --git a/integraal/integraal-forward-chaining/src/main/java/module-info.java b/integraal/integraal-forward-chaining/src/main/java/module-info.java index da7ffc9984c03c1351761ecd00408f06a0646230..13aed1ca9f1e1e96768df0316cc4bb33d1ea3ff9 100644 --- a/integraal/integraal-forward-chaining/src/main/java/module-info.java +++ b/integraal/integraal-forward-chaining/src/main/java/module-info.java @@ -32,5 +32,6 @@ module fr.boreal.forward_chaining { exports fr.boreal.forward_chaining.chase.rule_scheduler; exports fr.boreal.forward_chaining.chase.treatment; exports fr.boreal.forward_chaining.chase.lineage; - exports fr.boreal.forward_chaining.chase.rule_applier.trigger_applier.tracking; + exports fr.boreal.forward_chaining.chase.rule_applier.trigger_applier.tracking; + exports fr.boreal.forward_chaining.chase.metachase.stratified; } \ No newline at end of file diff --git a/integraal/integraal-grd/src/main/java/fr/boreal/grd/impl/GRDImpl.java b/integraal/integraal-grd/src/main/java/fr/boreal/grd/impl/GRDImpl.java index 23f5396ebf165c2eb99024d40fe0225fc59685f3..ed478db9122bd2a22c7e71d233da79a80c88508a 100644 --- a/integraal/integraal-grd/src/main/java/fr/boreal/grd/impl/GRDImpl.java +++ b/integraal/integraal-grd/src/main/java/fr/boreal/grd/impl/GRDImpl.java @@ -312,8 +312,11 @@ public class GRDImpl extends DirectedPseudograph<FORule, GRDEdge> implements Gra this.computeDependency(r1, r2); } }*/ - this.vertexSet().parallelStream() - .flatMap(r1 -> this.vertexSet().parallelStream().map(r2 -> Pair.of(r1, r2))) + this.rulebase.getRules().parallelStream() + .flatMap(r1 -> r1.getHead().getPredicates().parallelStream() + .flatMap(p -> this.rulebase.getRulesByBodyPredicate(p).parallelStream()) + .distinct() + .map(r2 -> Pair.of(r1, r2))) .forEach(pair -> this.computeDependency(pair.getLeft(), pair.getRight())); } diff --git a/integraal/integraal-model/src/main/java/fr/boreal/model/kb/impl/RuleBaseImpl.java b/integraal/integraal-model/src/main/java/fr/boreal/model/kb/impl/RuleBaseImpl.java index 79ee5f88350f1bb81d774457e28096c467aba502..4778923faeb495b2e8617c396d98c1532c2d396b 100644 --- a/integraal/integraal-model/src/main/java/fr/boreal/model/kb/impl/RuleBaseImpl.java +++ b/integraal/integraal-model/src/main/java/fr/boreal/model/kb/impl/RuleBaseImpl.java @@ -82,7 +82,7 @@ public class RuleBaseImpl implements RuleBase { } @Override - public Collection<FORule> getRulesByBodyPredicate(Predicate p) { + public synchronized Collection<FORule> getRulesByBodyPredicate(Predicate p) { if(this.rules_by_body_predicate == null) { this.rules_by_body_predicate = new HashMap<>(); for(FORule rule : this.rules) { diff --git a/integraal/integraal-views/src/main/java/fr/boreal/views/FederatedFactBase.java b/integraal/integraal-views/src/main/java/fr/boreal/views/FederatedFactBase.java index 37f769c4ce5eaae10a2e1ee20a8f26c71763607e..ea524706098888f58c65ef373ff0bda86fd2d879 100644 --- a/integraal/integraal-views/src/main/java/fr/boreal/views/FederatedFactBase.java +++ b/integraal/integraal-views/src/main/java/fr/boreal/views/FederatedFactBase.java @@ -12,10 +12,7 @@ import fr.boreal.model.logicalElements.api.Substitution; import fr.boreal.model.logicalElements.api.Term; import fr.boreal.views.datasource.AbstractViewWrapper; -import java.util.Collection; -import java.util.HashMap; -import java.util.Iterator; -import java.util.Map; +import java.util.*; import java.util.stream.Stream; /** @@ -218,6 +215,52 @@ public class FederatedFactBase implements FactBase { return FactBaseType.GRAAL; } + private Readable getReadable(Predicate viewPredicate) { + Readable r = this.facts_by_storage.get(viewPredicate); + if (r == null) { + r = this.default_storage; + } + return r; + } + + private Optional<FactBase> getReadableFactbase(Predicate viewPredicate) { + Readable r = this.facts_by_storage.get(viewPredicate); + if (r == null) { + r = this.default_storage; + } + return r instanceof FactBase ? Optional.of((FactBase) r) : Optional.empty(); + } + + @Override + public Optional<Long> estimateMatchCount(Atom atom) { + Optional<FactBase> fb = getReadableFactbase(atom.getPredicate()); + if (fb.isPresent()) { + return fb.get().estimateMatchCount(atom); + } + return Optional.empty(); + } + + @Override + public Optional<Long> estimateMatchCount(Atom atom, Substitution substitution) { + Optional<FactBase> fb = getReadableFactbase(atom.getPredicate()); + if (fb.isPresent()) { + return fb.get().estimateMatchCount(atom, substitution); + } + return Optional.empty(); + } + + @Override + public boolean canPerformIndexedMatch(Atom atom) { + Optional<FactBase> fb = getReadableFactbase(atom.getPredicate()); + return fb.map(factBase -> factBase.canPerformIndexedMatch(atom)).orElse(false); + } + + @Override + public boolean canPerformIndexedMatch(Atom atom, Substitution substitution) { + Optional<FactBase> fb = getReadableFactbase(atom.getPredicate()); + return fb.map(factBase -> factBase.canPerformIndexedMatch(atom, substitution)).orElse(false); + } + ///////////////////////////////////////////////// // Private methods /////////////////////////////////////////////////