tarjan_tree.rb revision 6e461d816d0ef4b4fcb576a94d8745eec62d176d
89a126810703c666309310d0f3189e9834d70b5bTimo Sirainen# Class for using the Tarjan algorithm to remove cycles in the entity trees.
a24665de9d5c773115a5918e60ed587aafe67d5cTimo Sirainenclass TarjanTree
a24665de9d5c773115a5918e60ed587aafe67d5cTimo Sirainen include TSort
a24665de9d5c773115a5918e60ed587aafe67d5cTimo Sirainen
687d1dee0e92229232aa8be416897b640df67d07Timo Sirainen def initialize(ontology)
a24665de9d5c773115a5918e60ed587aafe67d5cTimo Sirainen @hashed_entities = Hash.new
a24665de9d5c773115a5918e60ed587aafe67d5cTimo Sirainen subclasses = inheritance_sentences ontology
a24665de9d5c773115a5918e60ed587aafe67d5cTimo Sirainen subclasses.each do |s|
a24665de9d5c773115a5918e60ed587aafe67d5cTimo Sirainen c1, c2 = s.hierarchical_class_names
a24665de9d5c773115a5918e60ed587aafe67d5cTimo Sirainen
a24665de9d5c773115a5918e60ed587aafe67d5cTimo Sirainen child = ontology.entities.where('name = ? OR iri = ?', c1, c1).first!.id
a24665de9d5c773115a5918e60ed587aafe67d5cTimo Sirainen parent = ontology.entities.where('name = ? OR iri = ?', c2, c2).first!.id
a24665de9d5c773115a5918e60ed587aafe67d5cTimo Sirainen if @hashed_entities[parent]
a24665de9d5c773115a5918e60ed587aafe67d5cTimo Sirainen @hashed_entities[parent] << child
a24665de9d5c773115a5918e60ed587aafe67d5cTimo Sirainen else
a24665de9d5c773115a5918e60ed587aafe67d5cTimo Sirainen @hashed_entities[parent] = [child]
a24665de9d5c773115a5918e60ed587aafe67d5cTimo Sirainen end
a24665de9d5c773115a5918e60ed587aafe67d5cTimo Sirainen end
a24665de9d5c773115a5918e60ed587aafe67d5cTimo Sirainen create_tree ontology
2de709376eddc50ec5fa470358bb57cf0a87bb1fTimo Sirainen end
2de709376eddc50ec5fa470358bb57cf0a87bb1fTimo Sirainen
2de709376eddc50ec5fa470358bb57cf0a87bb1fTimo Sirainen def tsort_each_node(&block)
2de709376eddc50ec5fa470358bb57cf0a87bb1fTimo Sirainen @hashed_entities.each_key(&block)
2de709376eddc50ec5fa470358bb57cf0a87bb1fTimo Sirainen end
2de709376eddc50ec5fa470358bb57cf0a87bb1fTimo Sirainen
2de709376eddc50ec5fa470358bb57cf0a87bb1fTimo Sirainen def tsort_each_child(node, &block)
2de709376eddc50ec5fa470358bb57cf0a87bb1fTimo Sirainen @hashed_entities[node].try(:each, &block)
2de709376eddc50ec5fa470358bb57cf0a87bb1fTimo Sirainen end
2de709376eddc50ec5fa470358bb57cf0a87bb1fTimo Sirainen
a24665de9d5c773115a5918e60ed587aafe67d5cTimo Sirainen # Get SubClassOf Strings without explicit Thing
a24665de9d5c773115a5918e60ed587aafe67d5cTimo Sirainen # Only sentences with 4 words are the right sentences for the Tree
2de709376eddc50ec5fa470358bb57cf0a87bb1fTimo Sirainen # so we have to ignore the other.
2de709376eddc50ec5fa470358bb57cf0a87bb1fTimo Sirainen def inheritance_sentences(ontology)
5bbce06405dd5fc0d67411e48856953785f109f5Timo Sirainen ontology.sentences
a24665de9d5c773115a5918e60ed587aafe67d5cTimo Sirainen .where("text LIKE '%SubClassOf%' AND text NOT LIKE '%Thing%'")
a24665de9d5c773115a5918e60ed587aafe67d5cTimo Sirainen .select do |sentence|
2de709376eddc50ec5fa470358bb57cf0a87bb1fTimo Sirainen sentence.text.split(' ').size == 4
2de709376eddc50ec5fa470358bb57cf0a87bb1fTimo Sirainen end
a24665de9d5c773115a5918e60ed587aafe67d5cTimo Sirainen end
a24665de9d5c773115a5918e60ed587aafe67d5cTimo Sirainen
a24665de9d5c773115a5918e60ed587aafe67d5cTimo Sirainen def create_tree(ontology)
a24665de9d5c773115a5918e60ed587aafe67d5cTimo Sirainen create_groups ontology
a24665de9d5c773115a5918e60ed587aafe67d5cTimo Sirainen create_edges
a24665de9d5c773115a5918e60ed587aafe67d5cTimo Sirainen end
a24665de9d5c773115a5918e60ed587aafe67d5cTimo Sirainen
a24665de9d5c773115a5918e60ed587aafe67d5cTimo Sirainen def create_groups(ontology)
a24665de9d5c773115a5918e60ed587aafe67d5cTimo Sirainen groups = self.strongly_connected_components
a24665de9d5c773115a5918e60ed587aafe67d5cTimo Sirainen groups.each do |entity_group|
a24665de9d5c773115a5918e60ed587aafe67d5cTimo Sirainen entities = Entity.find(entity_group)
a24665de9d5c773115a5918e60ed587aafe67d5cTimo Sirainen name = determine_group_name(entities)
a24665de9d5c773115a5918e60ed587aafe67d5cTimo Sirainen EntityGroup.create!(ontology: ontology, entities: entities, name: name)
a24665de9d5c773115a5918e60ed587aafe67d5cTimo Sirainen end
a24665de9d5c773115a5918e60ed587aafe67d5cTimo Sirainen end
a24665de9d5c773115a5918e60ed587aafe67d5cTimo Sirainen
a24665de9d5c773115a5918e60ed587aafe67d5cTimo Sirainen def create_edges
a24665de9d5c773115a5918e60ed587aafe67d5cTimo Sirainen @hashed_entities.each do |parent, children|
a24665de9d5c773115a5918e60ed587aafe67d5cTimo Sirainen parent_group = Entity.find(parent).entity_group
a24665de9d5c773115a5918e60ed587aafe67d5cTimo Sirainen children.each do |child|
a24665de9d5c773115a5918e60ed587aafe67d5cTimo Sirainen child_group = Entity.find(child).entity_group
a24665de9d5c773115a5918e60ed587aafe67d5cTimo Sirainen unless parent_group == child_group
a24665de9d5c773115a5918e60ed587aafe67d5cTimo Sirainen EEdge.find_or_create_by_parent_id_and_child_id(parent_group.id, child_group.id)
a24665de9d5c773115a5918e60ed587aafe67d5cTimo Sirainen end
a24665de9d5c773115a5918e60ed587aafe67d5cTimo Sirainen end
a24665de9d5c773115a5918e60ed587aafe67d5cTimo Sirainen end
a24665de9d5c773115a5918e60ed587aafe67d5cTimo Sirainen end
a24665de9d5c773115a5918e60ed587aafe67d5cTimo Sirainen
a24665de9d5c773115a5918e60ed587aafe67d5cTimo Sirainen def determine_group_name(entities)
a24665de9d5c773115a5918e60ed587aafe67d5cTimo Sirainen entities.join(" ☰ ")
a24665de9d5c773115a5918e60ed587aafe67d5cTimo Sirainen end
a24665de9d5c773115a5918e60ed587aafe67d5cTimo Sirainenend
a24665de9d5c773115a5918e60ed587aafe67d5cTimo Sirainen