From 9b166e927f6002f248ea9717edc68685234fdbe0 Mon Sep 17 00:00:00 2001 From: Barry Nouwt Date: Fri, 3 Jul 2026 15:23:57 +0200 Subject: [PATCH] Modified unit test to test finding knowledge gaps in loop scenarios. Also: - Unit test modified: GeneralizeIfNecessaryTest --- .../smartconnector/impl/ReasonerProcessor.java | 16 +++++++++------- .../api/GeneralizeIfNecessaryTest.java | 18 ++++++++++++++++-- 2 files changed, 25 insertions(+), 9 deletions(-) diff --git a/smart-connector/src/main/java/eu/knowledge/engine/smartconnector/impl/ReasonerProcessor.java b/smart-connector/src/main/java/eu/knowledge/engine/smartconnector/impl/ReasonerProcessor.java index 77a747c8c..c1aa1b9d9 100644 --- a/smart-connector/src/main/java/eu/knowledge/engine/smartconnector/impl/ReasonerProcessor.java +++ b/smart-connector/src/main/java/eu/knowledge/engine/smartconnector/impl/ReasonerProcessor.java @@ -194,7 +194,7 @@ public CompletableFuture executeAskInteraction(BindingSet someBinding return this.finalBindingSetFuture.thenApply((bs) -> { if (myKnowledgeInteraction.getKnowledgeInteraction().knowledgeGapsEnabled()) { - this.knowledgeGaps = bs.isEmpty() ? getKnowledgeGaps(this.reasonerPlan.getStartNode()) + this.knowledgeGaps = bs.isEmpty() ? getKnowledgeGaps(this.reasonerPlan.getStartNode(), new HashSet<>()) : new HashSet(); } @@ -666,15 +666,17 @@ public ReasonerPlan getReasonerPlan() { * {@code A} AND {@code B} need to be added to solve the * gap. */ - public Set getKnowledgeGaps(RuleNode plan) { + public Set getKnowledgeGaps(RuleNode node, Set someVisitedNodes) { - assert plan instanceof AntSide; + assert node instanceof AntSide; Set existingOrGaps = new HashSet<>(); + someVisitedNodes.add(node); + // TODO do we need to include the parent if we are not backward chaining? - Map> nodeCoverage = plan - .findAntecedentCoverage(((AntSide) plan).getAntecedentNeighbours()); + Map> nodeCoverage = node + .findAntecedentCoverage(((AntSide) node).getAntecedentNeighbours()); // collect triple patterns that have an empty set Set collectedOrGaps, someGaps = new HashSet<>(); @@ -689,7 +691,7 @@ public Set getKnowledgeGaps(RuleNode plan) { for (RuleNode neighbor : entry.getValue()) { LOG.trace("Neighbor is {}", neighbor); - if (!neighbor.getRule().getAntecedent().isEmpty()) { + if (!someVisitedNodes.contains(neighbor) && !neighbor.getRule().getAntecedent().isEmpty()) { // make sure neighbor has no knowledge gaps LOG.trace("Neighbor has antecedents, so check if the neighbor has gaps"); @@ -699,7 +701,7 @@ public Set getKnowledgeGaps(RuleNode plan) { boolean isMeta = isMetaKI(neighbor); // TODO what if the graph contains loops? - if (!isMeta && (someGaps = getKnowledgeGaps(neighbor)).isEmpty()) { + if (!isMeta && (someGaps = getKnowledgeGaps(neighbor, someVisitedNodes)).isEmpty()) { // found neighbor without knowledge gaps for the current triple, so current // triple is covered. LOG.trace("Neighbor has no gaps"); diff --git a/smart-connector/src/test/java/eu/knowledge/engine/smartconnector/api/GeneralizeIfNecessaryTest.java b/smart-connector/src/test/java/eu/knowledge/engine/smartconnector/api/GeneralizeIfNecessaryTest.java index b440b7442..453356280 100644 --- a/smart-connector/src/test/java/eu/knowledge/engine/smartconnector/api/GeneralizeIfNecessaryTest.java +++ b/smart-connector/src/test/java/eu/knowledge/engine/smartconnector/api/GeneralizeIfNecessaryTest.java @@ -1,6 +1,7 @@ package eu.knowledge.engine.smartconnector.api; import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; import java.util.Arrays; import java.util.HashSet; @@ -61,6 +62,7 @@ public void test() throws InterruptedException, ExecutionException { BindingSet argument = new BindingSet(); Binding binding = new Binding(); + binding.put("b", ""); argument.add(binding); AskPlan pp = appKb.planAsk(appKbAsk, new RecipientSelector()); @@ -72,22 +74,34 @@ public void test() throws InterruptedException, ExecutionException { BindingSet expectedBS = new BindingSet(); Binding expectedB = new Binding(); expectedB.put("s", ""); + expectedB.put("b", ""); expectedB.put("value", "\"10\"^^"); expectedBS.add(expectedB); expectedB = new Binding(); expectedB.put("s", ""); + expectedB.put("b", ""); expectedB.put("value", "\"20\"^^"); expectedBS.add(expectedB); assertEquals(expectedBS, result.getBindings()); + // test again, but now trigger knowledge gaps detection (in loop scenario's like + // this test contains) + BindingSet bs = new BindingSet(); + Binding b = new Binding(); + b.put("b", ""); + bs.add(b); + AskResult ar = appKb.ask(appKbAsk, bs).get(); + assertNotNull(ar); + } private AskKnowledgeInteraction configureAppKb() { GraphPattern appGP = new GraphPattern(prefixes, - "?s rdf:type ex:Sensor . ?s ex:isPartOf ex:building1 . ?s ex:hasLatestValue ?value ."); - AskKnowledgeInteraction appKbAsk = new AskKnowledgeInteraction(new CommunicativeAct(), appGP); + "?s rdf:type ex:Sensor . ?s ex:isPartOf ?b . ?s ex:hasLatestValue ?value ."); + AskKnowledgeInteraction appKbAsk = new AskKnowledgeInteraction(new CommunicativeAct(), appGP, "askLatestValue", + true); appKb.register(appKbAsk); HashSet rule1ant = new HashSet<>(