From 053e9b34a7b440f919594033eb255eec1397c75b Mon Sep 17 00:00:00 2001 From: Akira <akira.charoensit@inria.fr> Date: Wed, 26 Mar 2025 21:51:45 +0100 Subject: [PATCH] (build pass) added estimation method to federated fb --- .../keywords/InteGraalKeywords.java | 3 +- .../DefaultChaseForExplanations.java | 5 +- .../fr/boreal/test/explanation/TestData.java | 4 +- .../MowlOntologyTest.java | 2 +- .../FactSupport_MowlOntologyTest.java | 5 +- .../KBSupport_MowlOntologyTest.java | 28 ++++++---- .../forward_chaining/chase/ChaseBuilder.java | 9 ++++ .../rule_scheduler/ByPredicateScheduler.java | 54 +++++++++++++++++++ .../src/main/java/module-info.java | 3 +- .../main/java/fr/boreal/grd/impl/GRDImpl.java | 7 ++- .../fr/boreal/model/kb/impl/RuleBaseImpl.java | 2 +- .../fr/boreal/views/FederatedFactBase.java | 51 ++++++++++++++++-- 12 files changed, 146 insertions(+), 27 deletions(-) create mode 100644 integraal/integraal-forward-chaining/src/main/java/fr/boreal/forward_chaining/chase/rule_scheduler/ByPredicateScheduler.java 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 21ea5f11b..5fb5f66de 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 bdbe4772c..54986fbe0 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 c73144ba6..beb3a9ec4 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 8b3d766e8..2181b865b 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 78a85f7bf..7957b425d 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 5ddc14727..79da30fde 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 9b31c6f8a..d7c648c2a 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 000000000..79764a9d7 --- /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 da7ffc998..13aed1ca9 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 23f5396eb..ed478db91 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 79ee5f883..4778923fa 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 37f769c4c..ea5247060 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 ///////////////////////////////////////////////// -- GitLab