package edu.isi.karma.modeling.alignment;
import java.io.File;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;
import java.util.TreeSet;
import org.jgrapht.graph.DirectedWeightedMultigraph;
import org.jgrapht.graph.WeightedMultigraph;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import edu.isi.karma.modeling.Uris;
import edu.isi.karma.modeling.alignment.learner.SemanticTypeMapping;
import edu.isi.karma.modeling.alignment.learner.SteinerNodes;
import edu.isi.karma.modeling.ontology.OntologyManager;
import edu.isi.karma.modeling.steiner.topk.CustomizedBANKS;
import edu.isi.karma.modeling.steiner.topk.Fact;
import edu.isi.karma.modeling.steiner.topk.ResultGraph;
import edu.isi.karma.modeling.steiner.topk.SteinerEdge;
import edu.isi.karma.modeling.steiner.topk.SteinerNode;
import edu.isi.karma.rep.alignment.CompactObjectPropertyLink;
import edu.isi.karma.rep.alignment.DefaultLink;
import edu.isi.karma.rep.alignment.InternalNode;
import edu.isi.karma.rep.alignment.Label;
import edu.isi.karma.rep.alignment.LabeledLink;
import edu.isi.karma.rep.alignment.LinkStatus;
import edu.isi.karma.rep.alignment.Node;
import edu.isi.karma.rep.alignment.ObjectPropertyLink;
import edu.isi.karma.rep.alignment.ObjectPropertyType;
import edu.isi.karma.util.EncodingDetector;
import edu.isi.karma.webserver.ContextParametersRegistry;
import edu.isi.karma.webserver.ServletContextParameterMap;
import edu.isi.karma.webserver.ServletContextParameterMap.ContextParameter;
public class GraphBuilderTopK extends GraphBuilder {
static Logger logger = LoggerFactory.getLogger(GraphBuilderTopK.class);
private HashMap<SteinerNode, TreeSet<SteinerEdge>> topKGraph;
private HashMap<String, SteinerNode> topKGraphNodes;
public GraphBuilderTopK(OntologyManager ontologyManager, boolean addThingNode) {
super(ontologyManager, addThingNode);
if (topKGraph == null) topKGraph = new HashMap<>();
if (topKGraphNodes == null) topKGraphNodes = new HashMap<>();
}
public GraphBuilderTopK(OntologyManager ontologyManager, DirectedWeightedMultigraph<Node, DefaultLink> graph) {
super(ontologyManager, graph, true);
if (topKGraph == null) topKGraph = new HashMap<>();
if (topKGraphNodes == null) topKGraphNodes = new HashMap<>();
}
public HashMap<SteinerNode, TreeSet<SteinerEdge>> getTopKGraph() {
if (topKGraph == null)
topKGraph = new HashMap<>();
return topKGraph;
}
public HashMap<String, SteinerNode> getTopKGraphNodes() {
if (topKGraphNodes == null)
topKGraphNodes = new HashMap<>();
return topKGraphNodes;
}
public boolean addNode(Node node) {
if (super.addNode(node)) {
SteinerNode n = new SteinerNode(node.getId());
getTopKGraphNodes().put(n.getNodeId(), n);
getTopKGraph().put(n, new TreeSet<SteinerEdge>());
return true;
} else
return false;
}
public boolean addLink(Node source, Node target, DefaultLink link) {
if (super.addLink(source, target, link)) {
SteinerNode n1 = new SteinerNode(source.getId());
SteinerNode n2 = new SteinerNode(target.getId());
SteinerEdge e = new SteinerEdge(n1, link.getId(), n2, (float)link.getWeight());
if (link instanceof LabeledLink) {
e.setModelIds(((LabeledLink)link).getModelIds());
e.setForced(((LabeledLink)link).getStatus() == LinkStatus.ForcedByUser);
}
// getTopKGraph().get(n1).add(e);
getTopKGraph().get(n2).add(e); // each node only stores its incoming links
return true;
} else
return false;
}
public boolean addLink(Node source, Node target, DefaultLink link, Double weight) {
if (super.addLink(source, target, link, weight)) {
SteinerNode n1 = new SteinerNode(source.getId());
SteinerNode n2 = new SteinerNode(target.getId());
SteinerEdge e = new SteinerEdge(n1, link.getId(), n2, (float)weight.doubleValue());
if (link instanceof LabeledLink) {
e.setModelIds(((LabeledLink)link).getModelIds());
}
// getTopKGraph().get(n1).add(e);
getTopKGraph().get(n2).add(e); // each node only stores its incoming links
return true;
} else
return false;
}
public boolean removeLink(DefaultLink link) {
if (super.removeLink(link)) {
SteinerNode n1 = new SteinerNode(link.getSource().getId());
SteinerNode n2 = new SteinerNode(link.getTarget().getId());
SteinerEdge e = new SteinerEdge(n1, link.getId(), n2, (float)link.getWeight());
// getTopKGraph().get(n1).remove(e);
getTopKGraph().get(n2).remove(e);
return true;
} else
return false;
}
public void changeLinkStatus(LabeledLink link, LinkStatus status) {
super.changeLinkStatus(link, status);
if (status == LinkStatus.PreferredByUI)
return;
SteinerNode n1 = new SteinerNode(link.getSource().getId());
SteinerNode n2 = new SteinerNode(link.getTarget().getId());
SteinerEdge e = new SteinerEdge(n1, link.getId(), n2, (float)link.getWeight());
if (getTopKGraph().get(n2).remove(e)) {
if (link instanceof LabeledLink) {
e.setModelIds(((LabeledLink)link).getModelIds());
e.setForced(status == LinkStatus.ForcedByUser);
}
getTopKGraph().get(n2).add(e);
}
}
public void changeLinkWeight(DefaultLink link, double weight) {
super.changeLinkWeight(link, weight);
SteinerNode n1 = new SteinerNode(link.getSource().getId());
SteinerNode n2 = new SteinerNode(link.getTarget().getId());
SteinerEdge e = new SteinerEdge(n1, link.getId(), n2, (float)weight);
if (getTopKGraph().get(n2).remove(e)) {
if (link instanceof LabeledLink) {
e.setModelIds(((LabeledLink)link).getModelIds());
e.setForced(((LabeledLink)link).getStatus() == LinkStatus.ForcedByUser);
}
getTopKGraph().get(n2).add(e);
}
}
public List<DirectedWeightedMultigraph<Node, LabeledLink>> getTopKSteinerTrees(Set<Node> steinerNodes,
int k,
Integer recursiveLevel,
Integer maxPermutations,
boolean onlyAddInternalNodes)
throws Exception {
if (steinerNodes == null) {
logger.error("no steiner node specified!");
return null;
}
// for (Node n : steinerNodes)
// System.out.println(n instanceof ColumnNode ? ((ColumnNode)n).getColumnName() : n.getId());
TreeSet<SteinerNode> terminals= new TreeSet<>();
for (Node n : steinerNodes) {
if (onlyAddInternalNodes && !(n instanceof InternalNode)) {
continue;
}
terminals.add(new SteinerNode(n.getId()));
}
// for (Node n : steinerNodes) {
// if (!(n instanceof InternalNode)) {
// Set<DefaultLink> incomingLinks = this.getGraph().incomingEdgesOf(n);
// if (incomingLinks != null && incomingLinks.size() == 1) {
// DefaultLink l = incomingLinks.iterator().next();
// if (l instanceof LabeledLink) {
// LabeledLink labeledLink = (LabeledLink)l;
// Node domain = labeledLink.getSource();
// if (domain != null && steinerNodes.contains(domain)) {
// Set<String> linkModelIds = labeledLink.getModelIds();
// Set<String> nodeModelIds = domain.getModelIds();
// if (nodeModelIds == null) {
// nodeModelIds = new HashSet<String>();
// domain.setModelIds(nodeModelIds);
// }
// if (linkModelIds != null)
// nodeModelIds.addAll(linkModelIds);
// }
// }
// }
// }
// terminals.add(new SteinerNode(n.getId()));
// }
// BANKSfromMM N = new BANKSfromMM(terminals, recursiveLevel, maxPermutations, ontologyManager.getContextId());
// BANKSfromMM.graph = this.getTopKGraph();
// BANKSfromMM.nodes = this.getTopKGraphNodes();
CustomizedBANKS N = new CustomizedBANKS(terminals, recursiveLevel, maxPermutations, ontologyManager.getContextId());
CustomizedBANKS.graph = this.getTopKGraph();
CustomizedBANKS.nodes = this.getTopKGraphNodes();
List<DirectedWeightedMultigraph<Node, LabeledLink>> results = new
LinkedList<>();
N.getTopKTrees(k);
DirectedWeightedMultigraph<Node, LabeledLink> processedTree = null;
if (!terminals.isEmpty() && N.getResultQueue().isEmpty()) {
// No edge in the tree, we still want to return a graph with only nodes
// no solution found! --> return a tree with just terminal nodes
// ResultGraph emptyTree = new ResultGraph();
// processedTree = getLabeledSteinerTree(emptyTree, terminals);
// if (processedTree != null) results.add(processedTree);
}
for(ResultGraph tree: N.getResultQueue()){
// System.out.println(tree.getScore());
processedTree = getLabeledSteinerTree(tree, terminals);
if (processedTree != null) results.add(processedTree);
}
return results;
}
public List<DirectedWeightedMultigraph<Node, LabeledLink>> getTopKSteinerTrees(
SteinerNodes steinerNodes,
int k,
Integer recursiveLevel,
Integer maxPermutations,
boolean onlyAddInternalNodes)
throws Exception {
List<DirectedWeightedMultigraph<Node, LabeledLink>> results =
getTopKSteinerTrees(steinerNodes.getNodes(), k, recursiveLevel, maxPermutations, onlyAddInternalNodes);
// adding data property links
if (results != null && onlyAddInternalNodes) {
for (DirectedWeightedMultigraph<Node, LabeledLink> tree : results) {
if (steinerNodes.getColumnNodeInfo() != null) {
for (SemanticTypeMapping stm : steinerNodes.getColumnNodeInfo().values()) {
LabeledLink dataPropertyLink = stm.getLink();
tree.addVertex(stm.getTarget());
if (tree.vertexSet().contains(stm.getSource())) {
tree.addEdge(stm.getSource(), stm.getTarget(), dataPropertyLink);
tree.setEdgeWeight(dataPropertyLink, stm.getLink().getWeight());
} else {
logger.error("this should not conceptually happen, there should be a bug in the code!");
}
}
}
}
}
return results;
}
public DirectedWeightedMultigraph<Node, LabeledLink> getLabeledSteinerTree(ResultGraph initialTree, Set<SteinerNode> terminals) {
if (initialTree == null ||
initialTree.getFacts() == null)
return null;
WeightedMultigraph<Node, DefaultLink> tree =
new WeightedMultigraph<>(DefaultLink.class);
if (initialTree.getFacts().isEmpty()) { //add all terminal nodes
for (SteinerNode t : terminals) {
tree.addVertex(this.getIdToNodeMap().get(t.name()));
}
}
HashSet<Node> visitedNodes = new HashSet<>();
Node source, target;
DefaultLink l;
double weight;
for (Fact f : initialTree.getFacts()) {
source = this.getIdToNodeMap().get(f.source().name());
target = this.getIdToNodeMap().get(f.destination().name());
if (LinkIdFactory.getLinkUri(f.label().name).equals(Uris.DEFAULT_LINK_URI)) {
String id = LinkIdFactory.getLinkId(Uris.DEFAULT_LINK_URI, source.getId(), target.getId());
l = new CompactObjectPropertyLink(id, ObjectPropertyType.None);
}
else l = this.getIdToLinkMap().get(f.label().name);
if (l == null) {
logger.error("this should not happen! there is a bug!");
}
weight = f.weight();
if (!visitedNodes.contains(source)) {
tree.addVertex(source);
visitedNodes.add(source);
}
if (!visitedNodes.contains(target)) {
tree.addVertex(target);
visitedNodes.add(target);
}
// System.out.println(f.toString());
tree.addEdge(source, target, l);
tree.setEdgeWeight(l, weight);
}
TreePostProcess treePostProcess = new TreePostProcess(this, tree);
return treePostProcess.getTree();
}
public static void main(String[] args) throws Exception {
ServletContextParameterMap contextParameters = ContextParametersRegistry.getInstance().getContextParameters("/Users/mohsen/karma");
contextParameters.setParameterValue(ContextParameter.USER_CONFIG_DIRECTORY, "/Users/mohsen/karma/config");
/** Check if any ontology needs to be preloaded **/
String preloadedOntDir = "/Users/mohsen/karma/preloaded-ontologies/";
File ontDir = new File(preloadedOntDir);
OntologyManager mgr = null;
if (ontDir.exists()) {
File[] ontologies = ontDir.listFiles();
mgr = new OntologyManager(contextParameters.getId());
for (File ontology: ontologies) {
System.out.println(ontology.getName());
if (ontology.getName().endsWith(".owl") ||
ontology.getName().endsWith(".rdf") ||
ontology.getName().endsWith(".n3") ||
ontology.getName().endsWith(".ttl") ||
ontology.getName().endsWith(".xml")) {
logger.info("Loading ontology file: " + ontology.getAbsolutePath());
try {
String encoding = EncodingDetector.detect(ontology);
mgr.doImport(ontology, encoding);
} catch (Exception t) {
// logger.error("Error loading ontology: " + ontology.getAbsolutePath(), t);
}
} else {
logger.error ("the file: " + ontology.getAbsolutePath() + " does not have proper format: xml/rdf/n3/ttl/owl");
}
}
// update the cache at the end when all files are added to the model
mgr.updateCache();
}
GraphBuilderTopK gbtk = new GraphBuilderTopK(mgr, false);
Node n1 = new InternalNode("n1", new Label("http://erlangen-crm.org/current/E55_Type"));
Node n2 = new InternalNode("n2", new Label("http://erlangen-crm.org/current/E70_Thing"));
Node n3 = new InternalNode("n3", new Label("http://erlangen-crm.org/current/E39_Actor"));
Node n4 = new InternalNode("n4", new Label("http://erlangen-crm.org/current/E74_Group"));
gbtk.addNode(n1);
gbtk.addNode(n2);
gbtk.addNode(n3);
gbtk.addNode(n4);
ObjectPropertyLink e1 = new ObjectPropertyLink(LinkIdFactory.getLinkId("e1", n1.getId(), n2.getId()),
new Label("http://erlangen-crm.org/current/P104i_applies_to"), ObjectPropertyType.Direct);
ObjectPropertyLink e2 = new ObjectPropertyLink(LinkIdFactory.getLinkId("e2", n1.getId(), n4.getId()),
new Label("http://erlangen-crm.org/current/P105i_has_right_on"), ObjectPropertyType.Direct);
ObjectPropertyLink e3 = new ObjectPropertyLink(LinkIdFactory.getLinkId("e3", n1.getId(), n3.getId()),
new Label("http://erlangen-crm.org/current/P31_has_modified"), ObjectPropertyType.Direct);
ObjectPropertyLink e4 = new ObjectPropertyLink(LinkIdFactory.getLinkId("e4", n2.getId(), n3.getId()),
new Label("http://erlangen-crm.org/current/P106i_forms_part_of"), ObjectPropertyType.Direct);
ObjectPropertyLink e5 = new ObjectPropertyLink(LinkIdFactory.getLinkId("e5", n2.getId(), n4.getId()),
new Label("http://erlangen-crm.org/current/P92_brought_into_existence"), ObjectPropertyType.Direct);
ObjectPropertyLink e6 = new ObjectPropertyLink(LinkIdFactory.getLinkId("e6", n4.getId(), n3.getId()),
new Label("http://erlangen-crm.org/current/P108_has_produced"), ObjectPropertyType.Direct);
ObjectPropertyLink e7 = new ObjectPropertyLink(LinkIdFactory.getLinkId("e7", n2.getId(), n3.getId()),
new Label("http://erlangen-crm.org/current/P92_brought_into_existence"), ObjectPropertyType.Direct);
gbtk.addLink(n1, n2, e1, 0.6);
gbtk.addLink(n1, n4, e2, 0.9);
gbtk.addLink(n1, n3, e3, 0.2);
gbtk.addLink(n2, n3, e4, 0.7);
gbtk.addLink(n2, n4, e5, 0.4);
gbtk.addLink(n4, n3, e6, 0.3);
gbtk.addLink(n2, n3, e7, 0.5);
Set<Node> steinerNodes = new HashSet<>();
steinerNodes.add(n2);
steinerNodes.add(n3);
List<DirectedWeightedMultigraph<Node, LabeledLink>> trees = gbtk.getTopKSteinerTrees(steinerNodes, 10, null, null, false);
for (DirectedWeightedMultigraph<Node, LabeledLink> tree : trees) {
System.out.println(GraphUtil.labeledGraphToString(tree));
}
// DPBFfromMM N = new DPBFfromMM(terminals);
// N.graph = gbtk.getTopKGraph();
// N.nodes = gbtk.getTopKGraphNodes();
//
// long startTime=System.currentTimeMillis();
// N.getTopKTrees(3);
// for(ResultGraph tree: N.getResultQueue()){
// for (Fact f : tree.getFacts()) {
// System.out.println(f.toString());
// }
// System.out.println(tree.getScore());
// }
// long end= System.currentTimeMillis();
//
// System.out.println("done ...");
}
}