From ec0e904af8aeeb228783e5a87e70e71f9836b4cb Mon Sep 17 00:00:00 2001 From: Barry Nouwt Date: Tue, 28 May 2024 09:59:09 +0200 Subject: [PATCH 1/2] Trying to reproduce the behavior described in this issue. Not successful yet. --- .../engine/smartconnector/api/TestAskAnswer4.java | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/smart-connector/src/test/java/eu/knowledge/engine/smartconnector/api/TestAskAnswer4.java b/smart-connector/src/test/java/eu/knowledge/engine/smartconnector/api/TestAskAnswer4.java index a0f530b4..36cdd3ca 100644 --- a/smart-connector/src/test/java/eu/knowledge/engine/smartconnector/api/TestAskAnswer4.java +++ b/smart-connector/src/test/java/eu/knowledge/engine/smartconnector/api/TestAskAnswer4.java @@ -47,7 +47,7 @@ public void testAskAnswer() throws InterruptedException { kb1.setReasonerEnabled(true); kn.addKB(kb2); - GraphPattern gp1 = new GraphPattern(prefixes, "?a \"test\"."); + GraphPattern gp1 = new GraphPattern(prefixes, "?a ?c ."); AnswerKnowledgeInteraction aKI = new AnswerKnowledgeInteraction(new CommunicativeAct(), gp1); kb1.register(aKI, (AnswerHandler) (anAKI, anAnswerExchangeInfo) -> { assertTrue( @@ -58,7 +58,7 @@ public void testAskAnswer() throws InterruptedException { BindingSet bindingSet = new BindingSet(); Binding binding = new Binding(); binding.put("a", ""); - binding.put("c", ""); + binding.put("c", "\"true\"^^"); bindingSet.add(binding); return bindingSet; @@ -76,6 +76,11 @@ public void testAskAnswer() throws InterruptedException { LOG.trace("Before ask."); AskResult result = kb2.ask(askKI, new BindingSet()).get(); bindings = result.getBindings(); + + System.out.println("Bindings: " + bindings); + System.out + .println("Bindings2: " + result.getExchangeInfoPerKnowledgeBase().iterator().next().getBindings()); + LOG.trace("After ask."); } catch (InterruptedException | ExecutionException e) { fail(); From 2911abb74d861b6813c8af240dadc9347ad60f7f Mon Sep 17 00:00:00 2001 From: Barry Nouwt Date: Fri, 31 May 2024 15:18:25 +0200 Subject: [PATCH 2/2] Make sure typed literals are not converted into plain literals. Adding a SerializationContext to Apache's parse methods where the usePlainLiterals is set to false ensures this. --- .../impl/ReasonerProcessor.java | 17 +++-- .../impl/TestBindingSetConversions.java | 68 +++++++++++++++++++ 2 files changed, 80 insertions(+), 5 deletions(-) create mode 100644 smart-connector/src/test/java/eu/knowledge/engine/smartconnector/impl/TestBindingSetConversions.java 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 7518d363..973b7d40 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 @@ -14,6 +14,7 @@ import org.apache.jena.sparql.core.TriplePath; import org.apache.jena.sparql.core.Var; import org.apache.jena.sparql.graph.PrefixMappingZero; +import org.apache.jena.sparql.serializer.SerializationContext; import org.apache.jena.sparql.syntax.ElementPathBlock; import org.apache.jena.sparql.util.FmtUtils; import org.slf4j.Logger; @@ -265,13 +266,17 @@ private void continueReasoningForward(eu.knowledge.engine.reasoner.api.BindingSe * @param bs a reasoner bindingset * @return a ke bindingset */ - private BindingSet translateBindingSetFrom(eu.knowledge.engine.reasoner.api.BindingSet bs) { + protected BindingSet translateBindingSetFrom(eu.knowledge.engine.reasoner.api.BindingSet bs) { BindingSet newBS = new BindingSet(); Binding newB; + + SerializationContext context = new SerializationContext(); + context.setUsePlainLiterals(false); + for (eu.knowledge.engine.reasoner.api.Binding b : bs) { newB = new Binding(); for (Map.Entry entry : b.entrySet()) { - newB.put(entry.getKey().getName(), FmtUtils.stringForNode(entry.getValue())); + newB.put(entry.getKey().getName(), FmtUtils.stringForNode(entry.getValue(), context)); } newBS.add(newB); } @@ -284,7 +289,7 @@ private BindingSet translateBindingSetFrom(eu.knowledge.engine.reasoner.api.Bind * @param bs a ke bindingset * @return a reasoner bindingset */ - private eu.knowledge.engine.reasoner.api.BindingSet translateBindingSetTo(BindingSet someBindings) { + protected eu.knowledge.engine.reasoner.api.BindingSet translateBindingSetTo(BindingSet someBindings) { eu.knowledge.engine.reasoner.api.BindingSet newBindingSet = new eu.knowledge.engine.reasoner.api.BindingSet(); eu.knowledge.engine.reasoner.api.Binding newBinding; @@ -432,7 +437,8 @@ public CompletableFuture handle( }); } catch (IOException e) { - LOG.warn("Errors like '{}' should not occur while sending: {}", e.getMessage(), askMessage.getMessageId()); + LOG.warn("Errors like '{}' should not occur while sending: {}", e.getMessage(), + askMessage.getMessageId()); LOG.debug("", e); bsFuture = new CompletableFuture(); bsFuture.complete(new eu.knowledge.engine.reasoner.api.BindingSet()); @@ -494,7 +500,8 @@ public CompletableFuture handle( }); } catch (IOException e) { - LOG.warn("Errors like '{}' should not occur while sending: {}", e.getMessage(), postMessage.getMessageId()); + LOG.warn("Errors like '{}' should not occur while sending: {}", e.getMessage(), + postMessage.getMessageId()); LOG.debug("", e); bsFuture = new CompletableFuture(); bsFuture.complete(new eu.knowledge.engine.reasoner.api.BindingSet()); diff --git a/smart-connector/src/test/java/eu/knowledge/engine/smartconnector/impl/TestBindingSetConversions.java b/smart-connector/src/test/java/eu/knowledge/engine/smartconnector/impl/TestBindingSetConversions.java new file mode 100644 index 00000000..fff0ba72 --- /dev/null +++ b/smart-connector/src/test/java/eu/knowledge/engine/smartconnector/impl/TestBindingSetConversions.java @@ -0,0 +1,68 @@ +package eu.knowledge.engine.smartconnector.impl; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import java.util.HashSet; +import java.util.Set; + +import org.apache.jena.datatypes.xsd.XSDDatatype; +import org.apache.jena.graph.Node; +import org.apache.jena.graph.NodeFactory; +import org.apache.jena.graph.Node_Concrete; +import org.apache.jena.sparql.core.Var; +import org.junit.jupiter.api.Test; + +import eu.knowledge.engine.reasoner.Rule; +import eu.knowledge.engine.smartconnector.api.Binding; +import eu.knowledge.engine.smartconnector.api.BindingSet; + +class TestBindingSetConversions { + + private OpenReasonerProcessor rp = new OpenReasonerProcessor(new HashSet<>(), null, new HashSet<>()); + + /** + * Test whether converting typed literals between reasoner and knowledge engine + * binding sets works correctly. + */ + @Test + void testTypedLiteral() { + + String varStringVersion = "a"; + Var varNodeVersion = Var.alloc(varStringVersion); + Node literalNodeVersion = NodeFactory.createLiteral("true", XSDDatatype.XSDboolean); + var literalStringVersion = "\"true\"^^"; + + BindingSet bs = new BindingSet(); + Binding b = new Binding(); + b.put(varStringVersion, literalStringVersion); + bs.add(b); + eu.knowledge.engine.reasoner.api.BindingSet reasonerBS = rp.testerTo(bs); + assertEquals(literalNodeVersion, reasonerBS.iterator().next().get(varStringVersion)); + + eu.knowledge.engine.reasoner.api.BindingSet bsR = new eu.knowledge.engine.reasoner.api.BindingSet(); + eu.knowledge.engine.reasoner.api.Binding bR = new eu.knowledge.engine.reasoner.api.Binding(); + bR.put(varNodeVersion, (Node_Concrete) literalNodeVersion); + bsR.add(bR); + BindingSet otherBS = rp.testerFrom(bsR); + assertEquals(literalStringVersion, otherBS.iterator().next().get(varStringVersion)); + } + + /** + * Make some binding set translation methods available. + */ + public static class OpenReasonerProcessor extends ReasonerProcessor { + public OpenReasonerProcessor(Set knowledgeInteractions, MessageRouter messageRouter, + Set someDomainKnowledge) { + super(knowledgeInteractions, messageRouter, someDomainKnowledge); + } + + public eu.knowledge.engine.reasoner.api.BindingSet testerTo(BindingSet bs) { + return this.translateBindingSetTo(bs); + } + + public BindingSet testerFrom(eu.knowledge.engine.reasoner.api.BindingSet bs) { + return this.translateBindingSetFrom(bs); + } + } + +}