def test_variable_graph_properties_are_transferred_to_graph(self): variable_graph = nx.MultiDiGraph() variable_graph.add_node('x', input=1, solution=1) variable_graph.add_node('y', input=1, solution=1) variable_graph.add_edge('y', 'x', type='employee', input=0, solution=1) person = Thing('V123', 'person', 'entity') employment = Thing('V456', 'employment', 'relation') concept_dict = {'x': person, 'y': employment} typedb_graph = concept_dict_to_graph(concept_dict, variable_graph) expected_typedb_graph = nx.MultiDiGraph() expected_typedb_graph.add_node(person, type='person', input=1, solution=1) expected_typedb_graph.add_node(employment, type='employment', input=1, solution=1) expected_typedb_graph.add_edge(employment, person, type='employee', input=0, solution=1) self.assertGraphsEqual(expected_typedb_graph, typedb_graph)
def test_query_made_only_if_relation_wins(self): graph = nx.MultiDiGraph() graph.add_node(0, concept=Thing('V123', 'person', 'entity'), probabilities=np.array([1.0, 0.0, 0.0]), prediction=0) graph.add_node(1, concept=Thing('V1235', 'disease', 'entity'), probabilities=np.array([1.0, 0.0, 0.0]), prediction=0) graph.add_node(2, concept=Thing('V6543', 'diagnosis', 'relation'), probabilities=np.array([0.0, 0.0, 1.0]), prediction=1) graph.add_edge(2, 0) graph.add_edge(2, 1) graphs = [graph] tx = MagicMock(TypeDBTransaction) tx.commit = MagicMock() tx.query = MagicMock(QueryManager) write_predictions_to_typedb(graphs, tx) tx.query.assert_not_called() tx.commit.assert_called()
def test_edges_are_duplicated_as_expected(self): graph = nx.MultiDiGraph(name=0) p0 = Thing('V123', 'person', 'entity') p1 = Thing('V456', 'person', 'entity') par0 = Thing('V789', 'parentship', 'relation') # people graph.add_node(p0, type='person', solution=1) graph.add_node(p1, type='person', solution=1) # parentships graph.add_node(par0, type='parentship', solution=1) graph.add_edge(par0, p0, type='parent', solution=1) graph.add_edge(par0, p1, type='child', solution=1) duplicate_edges_in_reverse(graph) expected_graph = nx.MultiDiGraph(name=0) # people expected_graph.add_node(p0, type='person', solution=1) expected_graph.add_node(p1, type='person', solution=1) # parentships expected_graph.add_node(par0, type='parentship', solution=1) expected_graph.add_edge(par0, p0, type='parent', solution=1) expected_graph.add_edge(par0, p1, type='child', solution=1) # Duplicates expected_graph.add_edge(p0, par0, type='parent', solution=1) expected_graph.add_edge(p1, par0, type='child', solution=1) self.assertGraphsEqual(expected_graph, graph)
def test_same_thing_occurs_in_two_different_variables(self): variable_graph = nx.MultiDiGraph() variable_graph.add_node('x') variable_graph.add_node('y') person = Thing('V123', 'person', 'entity') person2 = Thing('V123', 'person', 'entity') concept_dict = {'x': person, 'y': person2} typedb_graph = concept_dict_to_graph(concept_dict, variable_graph) expected_typedb_graph = nx.MultiDiGraph() expected_typedb_graph.add_node(person, type='person') self.assertGraphsEqual(expected_typedb_graph, typedb_graph)
def test_edge_starting_from_entity_throws_exception(self): variable_graph = nx.MultiDiGraph() variable_graph.add_node('x') variable_graph.add_node('y') variable_graph.add_edge('x', 'y', type='employee') person = Thing('V123', 'person', 'entity') employment = Thing('V456', 'employment', 'relation') concept_dict = {'x': person, 'y': employment} with self.assertRaises(ValueError) as context: _ = concept_dict_to_graph(concept_dict, variable_graph) self.assertEqual( 'An edge in the variable_graph originates from a non-relation, check the variable_graph!', str(context.exception))
def test_concept_dicts_are_built_as_expected_with_2_concepts(self): concept_map = MockConceptMap({ 'x': MockThing('V123', MockType('V456', 'person', 'ENTITY')), 'y': MockThing('V789', MockType('V765', 'employment', 'RELATION')), }) concept_dicts = concept_dict_from_concept_map(concept_map) expected_concept_dict = { 'x': Thing('V123', 'person', 'entity'), 'y': Thing('V789', 'employment', 'relation'), } self.assertEqual(expected_concept_dict, concept_dicts)
def test_single_entity_single_relation_graph_is_as_expected(self): variable_graph = nx.MultiDiGraph() variable_graph.add_node('x') variable_graph.add_node('y') variable_graph.add_edge('y', 'x', type='employee') person = Thing('V123', 'person', 'entity') employment = Thing('V456', 'employment', 'relation') concept_dict = {'x': person, 'y': employment} typedb_graph = concept_dict_to_graph(concept_dict, variable_graph) expected_typedb_graph = nx.MultiDiGraph() expected_typedb_graph.add_node(person, type='person') expected_typedb_graph.add_node(employment, type='employment') expected_typedb_graph.add_edge(employment, person, type='employee') self.assertGraphsEqual(expected_typedb_graph, typedb_graph)
def test_concept_dicts_are_built_as_expected(self): concept_map = MockConceptMap( {'x': MockThing('V123', MockType('V456', 'person', 'ENTITY'))}) concept_dicts = concept_dict_from_concept_map(concept_map) expected_concept_dicts = {'x': Thing('V123', 'person', 'entity')} self.assertEqual(expected_concept_dicts, concept_dicts)
def test_when_graph_edge_properties_are_mismatched_exception_is_raised( self): person_a = Thing('V123', 'person', 'entity') name_a = Thing('V1234', 'name', 'attribute', value_type='string', value='Bob') typedb_graph_a = nx.MultiDiGraph(name='a') typedb_graph_a.add_node(person_a, input=1, solution=1) typedb_graph_a.add_node(name_a, input=1, solution=1) typedb_graph_a.add_edge(person_a, name_a, type='has', input=0, solution=1) person_b = Thing('V123', 'person', 'entity') name_b = Thing('V1234', 'name', 'attribute', value_type='string', value='Bob') typedb_graph_b = nx.MultiDiGraph(name='b') typedb_graph_b.add_node(person_b, input=1, solution=1) typedb_graph_b.add_node(name_b, input=1, solution=1) typedb_graph_b.add_edge(person_b, name_b, type='has', input=1, solution=0) with self.assertRaises(ValueError) as context: combine_n_graphs([typedb_graph_a, typedb_graph_b]) self.assertEqual(( 'Found non-matching edge properties for edge (<person, V123>, <name, V1234: Bob>, 0) ' 'between graphs a and b:\n' 'In graph a: {\'type\': \'has\', \'input\': 0, \'solution\': 1}\n' 'In graph b: {\'type\': \'has\', \'input\': 1, \'solution\': 0}'), str(context.exception))
def test_query_made_as_expected(self): graph = nx.MultiDiGraph() graph.add_node(0, concept=Thing('V123', 'person', 'entity'), probabilities=np.array([1.0, 0.0, 0.0]), prediction=0) graph.add_node(1, concept=Thing('V1235', 'disease', 'entity'), probabilities=np.array([1.0, 0.0, 0.0]), prediction=0) graph.add_node(2, concept=Thing('V6543', 'diagnosis', 'relation'), probabilities=np.array([0.0, 0.0071, 0.9927]), prediction=2) graph.add_edge(2, 0) graph.add_edge(2, 1) graphs = [graph] tx = MagicMock(TypeDBTransaction) tx.commit = MagicMock() tx.query.return_value = query = MagicMock(QueryManager) write_predictions_to_typedb(graphs, tx) expected_query = ( f'match ' f'$p iid V123;' f'$d iid V1235;' f'$kgcn isa kgcn;' f'insert ' f'$pd(patient: $p, diagnosed-disease: $d, diagnoser: $kgcn) isa diagnosis,' f'has probability-exists 0.993,' f'has probability-non-exists 0.007,' f'has probability-preexists 0.000;') query.insert.assert_called_with(expected_query) tx.commit.assert_called()
def test_single_entity_graph_is_as_expected(self): variable_graph = nx.MultiDiGraph() variable_graph.add_node('x') person = Thing('V123', 'person', 'entity') concept_dict = {'x': person} typedb_graph = concept_dict_to_graph(concept_dict, variable_graph) expected_typedb_graph = nx.MultiDiGraph() expected_typedb_graph.add_node(person, type='person') self.assertGraphsEqual(expected_typedb_graph, typedb_graph)
def test_exception_if_sets_of_variables_differ(self): variable_graph = nx.MultiDiGraph() variable_graph.add_node('x') variable_graph.add_node('y') variable_graph.add_node('z') thing = Thing('V123', 'person', 'entity') concept_dict = {'x': thing, 'y': thing, 'a': thing} with self.assertRaises(ValueError) as context: _ = concept_dict_to_graph(concept_dict, variable_graph) self.assertEqual( 'The variables in the variable_graph must match those in the concept_dict\n' 'In the variable graph but not in the concept dict: {\'z\'}\n' 'In the concept dict but not in the variable graph: {\'a\'}', str(context.exception))
def test_single_attribute_graph_is_as_expected(self): variable_graph = nx.MultiDiGraph() variable_graph.add_node('x') name = Thing('V123', 'name', 'attribute', value_type='string', value='Bob') concept_dict = {'x': name} typedb_graph = concept_dict_to_graph(concept_dict, variable_graph) expected_typedb_graph = nx.MultiDiGraph() expected_typedb_graph.add_node(name, type='name', value_type='string', value='Bob') self.assertGraphsEqual(expected_typedb_graph, typedb_graph)
def test_graph_combined_as_expected(self): person = Thing('V123', 'person', 'entity') employment = Thing('V567', 'employment', 'relation') typedb_graph_a = nx.MultiDiGraph() typedb_graph_a.add_node(person) typedb_graph_a.add_node(employment) typedb_graph_a.add_edge(employment, person, type='employee') person_b = Thing('V123', 'person', 'entity') name = Thing('V1234', 'name', 'attribute', value_type='string', value='Bob') typedb_graph_b = nx.MultiDiGraph() typedb_graph_b.add_node(person_b) typedb_graph_b.add_node(name) typedb_graph_b.add_edge(person_b, name, type='has') combined_graph = combine_n_graphs([typedb_graph_a, typedb_graph_b]) person_ex = Thing('V123', 'person', 'entity') employment_ex = Thing('V567', 'employment', 'relation') name_ex = Thing('V1234', 'name', 'attribute', value_type='string', value='Bob') expected_combined_graph = nx.MultiDiGraph() expected_combined_graph.add_node(person_ex) expected_combined_graph.add_node(name_ex) expected_combined_graph.add_node(employment_ex) expected_combined_graph.add_edge(employment_ex, person_ex, type='employee') expected_combined_graph.add_edge(person_ex, name_ex, type='has') self.assertGraphsEqual(expected_combined_graph, combined_graph)
def test_graph_is_built_as_expected(self): g1 = nx.MultiDiGraph() g1.add_node('x') g2 = nx.MultiDiGraph() g2.add_node('x') g2.add_node('n') g2.add_edge('x', 'n', type='has') g3 = nx.MultiDiGraph() g3.add_node('x') g3.add_node('r') g3.add_node('y') g3.add_edge('r', 'x', type='child') g3.add_edge('r', 'y', type='parent') query_sampler_variable_graph_tuples = [ ('match $x iid V123;', mock_sampler, g1), ('match $x iid V123, has name $n;', mock_sampler, g2), ('match $x iid V123; $r(child: $x, parent: $y);', mock_sampler, g3), # TODO Add functionality for loading schema at a later date # ('match $x sub person; $x sub $type;', g4), # ('match $x sub $y;', g5), ] class MockTransaction: def query(self): return MockQueryManager() class MockQueryManager: def match(self, query): if query == 'match $x iid V123;': return [ MockConceptMap({ 'x': MockThing('V123', MockType('V4123', 'person', 'ENTITY')) }) ] elif query == 'match $x iid V123, has name $n;': return [ MockConceptMap({ 'x': MockThing('V123', MockType('V4123', 'person', 'ENTITY')), 'n': MockAttribute( 'V987', 'Bob', MockAttributeType( 'V555', 'name', 'ATTRIBUTE', AttributeType.ValueType.STRING)) }) ] elif query == 'match $x iid V123; $r(child: $x, parent: $y);': return [ MockConceptMap({ 'x': MockThing('V123', MockType('V4123', 'person', 'ENTITY')), 'y': MockThing('V123', MockType('V4123', 'person', 'ENTITY')), 'r': MockThing( 'V567', MockType('V9876', 'parentship', 'RELATION')) }) ] else: raise NotImplementedError mock_tx = MockTransaction() combined_graph = build_graph_from_queries( query_sampler_variable_graph_tuples, mock_tx) person_exp = Thing('V123', 'person', 'entity') parentship_exp = Thing('V567', 'parentship', 'relation') name_exp = Thing('V987', 'name', 'attribute', value_type=AttributeType.ValueType.STRING, value='Bob') expected_combined_graph = nx.MultiDiGraph() expected_combined_graph.add_node(person_exp, type='person') expected_combined_graph.add_node( name_exp, type='name', value_type=AttributeType.ValueType.STRING, value='Bob') expected_combined_graph.add_node(parentship_exp, type='parentship') expected_combined_graph.add_edge(parentship_exp, person_exp, type='child') expected_combined_graph.add_edge(parentship_exp, person_exp, type='parent') expected_combined_graph.add_edge(person_exp, name_exp, type='has') self.assertGraphsEqual(expected_combined_graph, combined_graph)