/** * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information regarding * copyright ownership. The ASF licenses this file to you under * the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may * obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, * either express or implied. * * See the License for the specific language governing permissions * and limitations under the License. */ package dnars.siebog.agents.dbpedia; import java.util.ArrayList; import java.util.HashSet; import java.util.Set; import javax.ejb.Remote; import javax.ejb.Stateful; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import scala.collection.Iterator; import siebog.agents.Agent; import siebog.agents.XjafAgent; import siebog.interaction.ACLMessage; import siebog.interaction.Performative; import dnars.base.AtomicTerm; import dnars.base.CompoundTerm; import dnars.base.Copula; import dnars.base.Statement; import dnars.base.Truth; import dnars.graph.DNarsGraph; import dnars.graph.DNarsGraphFactory; import dnars.inference.forward.ForwardInferenceEngine; /** * * @author <a href="mitrovic.dejan@gmail.com">Dejan Mitrovic</a> */ @Stateful @Remote(Agent.class) public class Learner extends XjafAgent { private static final long serialVersionUID = 1L; private static final Logger LOG = LoggerFactory.getLogger(Learner.class); private QueryDesc query; @Override protected void onMessage(ACLMessage msg) { if (msg.performative == Performative.REQUEST) { query = (QueryDesc) msg.contentObj; DNarsGraph allProps = DNarsGraphFactory.create(query.getAllProperties(), null); try { Set<Statement> relevant = getRelevantStatements(query.getQuestion(), allProps); LOG.info("Retrieved {} relevant statements for {}.", relevant.size(), query.getQuestion()); if (relevant.size() > 0) { ArrayList<Statement> intermediary = deriveNewConclusions(relevant); LOG.info("Derived {} intermediary statements for {}.", intermediary.size(), query.getQuestion()); if (intermediary.size() > 0) { Statement[] newKnowledge = null; DNarsGraph knownProps = DNarsGraphFactory.create( query.getKnownProperties(), null); try { newKnowledge = new ForwardInferenceEngine(knownProps) .conclusions(intermediary.toArray(new Statement[0])); } finally { knownProps.shutdown(); } LOG.info("Derived {} new statements for {}.", newKnowledge.length, query.getQuestion()); for (Statement st : newKnowledge) { st = st.allImages().head(); if (!allProps.hasAnswer(st)) { knownProps = DNarsGraphFactory.create(query.getKnownProperties(), null); try { knownProps.add(st); } finally { knownProps.shutdown(); } } } } } } finally { allProps.shutdown(); } ACLMessage reply = msg.makeReply(Performative.CONFIRM); msm().post(reply); } } @SuppressWarnings("unused") private Set<Statement> getRelevantStatements(String uri, DNarsGraph graph) { Set<Statement> set = new HashSet<>(); AtomicTerm uriTerm = new AtomicTerm(uri); Truth truth = new Truth(1.0, 0.9); // uri -> ? Statement st = new Statement(uriTerm, Copula.Inherit(), AtomicTerm.Question(), truth); // Statement[] relevant = graph.answer(st, Integer.MAX_VALUE); // set.addAll(Arrays.asList(relevant)); // ? -> uri st = new Statement(AtomicTerm.Question(), Copula.Inherit(), uriTerm, truth); // relevant = graph.answer(st, Integer.MAX_VALUE); // set.addAll(Arrays.asList(relevant)); return set; } private ArrayList<Statement> deriveNewConclusions(Set<Statement> relevant) { ArrayList<Statement> conclusions = new ArrayList<>(); DNarsGraph graph = DNarsGraphFactory.create(query.getKnownProperties(), null); try { Statement[] derived = new ForwardInferenceEngine(graph).conclusions(relevant .toArray(new Statement[0])); for (Statement d : derived) { if (d.subj() instanceof CompoundTerm && d.pred() instanceof CompoundTerm) { CompoundTerm subj = (CompoundTerm) d.subj(); CompoundTerm pred = (CompoundTerm) d.pred(); Iterator<AtomicTerm> si = subj.comps().iterator(); Iterator<AtomicTerm> pi = pred.comps().iterator(); while (si.hasNext() && pi.hasNext()) { AtomicTerm sterm = si.next(); AtomicTerm pterm = pi.next(); if (!sterm.equals(pterm)) conclusions.add(new Statement(sterm, d.copula(), pterm, d.truth())); } } else conclusions.add(d); } } finally { graph.shutdown(); } return conclusions; } }