Skip to content

Commit b2c4e74

Browse files
committed
add R4=I40 to all relations
1 parent f986478 commit b2c4e74

4 files changed

Lines changed: 58 additions & 24 deletions

File tree

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,3 +12,4 @@ dist
1212
build
1313
.aider*
1414
.env*
15+
/graph_site/*

src/pyirk/builtin_entities.py

Lines changed: 24 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -304,20 +304,43 @@ def instance_of(
304304
R2,
305305
"specifies that for each subject there is at most one 'R30-Statement' for a given language tag (e.g. en)",
306306
)
307+
R18 = create_builtin_relation(
308+
"R18", R1="has usage hint", R2="specifies a hint (str) on how this relation should be used"
309+
)
307310

308311
R22 = create_builtin_relation(
309312
key_str="R22",
310313
R1="is functional",
311314
R2="specifies that the subject entity is a relation which has at most one value per item",
312315
)
313316

317+
I40 = create_builtin_item(
318+
key_str="I40",
319+
R1__has_label="general relation",
320+
R2__has_description="proxy item for a relation",
321+
R18__has_usage_hint=(
322+
"This item (which is in no direct relation to I1__general_item) can be used as a placeholder for any relation. "
323+
"In other words: this can be interpreted as the common superclass for all relations"
324+
),
325+
)
326+
314327
R22["is functional"].set_relation(R22["is functional"], True)
315328
R32["is functional for each language"].set_relation(R22["is functional"], True)
316329

317330
# Note that R1, R22, and R32 are used extensively to control the behavior in pyirk.core
318331

319332
R3 = create_builtin_relation("R3", R1="is subclass of", R22__is_functional=True)
320333
R4 = create_builtin_relation("R4", R1="is instance of", R22__is_functional=True)
334+
335+
# update type of relations before automatic was possible (in create_relation())
336+
R32.set_relation(R4["is instance of"], I40["general relation"])
337+
R1.set_relation(R4["is instance of"], I40["general relation"])
338+
R2.set_relation(R4["is instance of"], I40["general relation"])
339+
R18.set_relation(R4["is instance of"], I40["general relation"])
340+
R22.set_relation(R4["is instance of"], I40["general relation"])
341+
R3.set_relation(R4["is instance of"], I40["general relation"])
342+
R4.set_relation(R4["is instance of"], I40["general relation"])
343+
321344
R5 = create_builtin_relation("R5", R1="is part of")
322345
R6 = create_builtin_relation("R6", R1="has defining mathematical relation", R22__is_functional=True)
323346
R7 = create_builtin_relation("R7", R1="has arity", R22__is_functional=True)
@@ -351,9 +374,7 @@ def instance_of(
351374
R17 = create_builtin_relation(
352375
key_str="R17", R1="is subproperty of", R2="specifies that arg1 (subj) is a subproperty of arg2 (obj)"
353376
)
354-
R18 = create_builtin_relation(
355-
"R18", R1="has usage hint", R2="specifies a hint (str) on how this relation should be used"
356-
)
377+
357378

358379
R16.set_relation(
359380
R18["has usage hint"], "this relation should be used on concrete instances, not on generic types"
@@ -370,15 +391,6 @@ def instance_of(
370391
)
371392

372393

373-
I40 = create_builtin_item(
374-
key_str="I40",
375-
R1__has_label="general relation",
376-
R2__has_description="proxy item for a relation",
377-
R18__has_usage_hint=(
378-
"This item (which is in no direct relation to I1__general_item) can be used as a placeholder for any relation. "
379-
"In other words: this can be interpreted as the common superclass for all relations"
380-
),
381-
)
382394

383395

384396
R68 = create_builtin_relation(

src/pyirk/core.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2209,6 +2209,12 @@ def create_relation(key_str: str = "", **kwargs) -> Relation:
22092209
}
22102210

22112211
new_kwargs, lang_related_kwargs = process_kwargs_for_entity_creation(rel_key, kwargs)
2212+
if "R4" not in new_kwargs.keys() and "irk:/builtins#R4" in ds.relations.keys():
2213+
try:
2214+
new_kwargs["R4"] = ds.items["irk:/builtins#I40"]
2215+
except KeyError:
2216+
pass
2217+
22122218

22132219
rel = Relation(mod_uri, rel_key, **new_kwargs)
22142220
if rel.uri in ds.relations:

src/pyirk/visualization.py

Lines changed: 27 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -445,6 +445,7 @@ def create_complete_graph(
445445
url_template="",
446446
limit: Optional[int] = None,
447447
skip_auto_items: bool = False,
448+
vis_relations: bool = False,
448449
) -> nx.DiGraph:
449450
"""
450451
:param url_template: template to insert links based on uris
@@ -466,8 +467,14 @@ def create_complete_graph(
466467
# this is the case for some statements which are subject of a qualifier relation
467468
assert item_uri in p.ds.statement_uri_map
468469
continue
469-
if not isinstance(item, p.Item) or item.short_key in ["I000"]:
470+
if item.short_key in ["I000"]:
470471
continue
472+
if vis_relations:
473+
if (not isinstance(item, p.Item) and not isinstance(item, p.Relation)):
474+
continue # what possible type could item have to get here?
475+
else:
476+
if not isinstance(item, p.Item):
477+
continue
471478
if skip_auto_items and "Ia" in item.short_key:
472479
continue
473480
# count only items
@@ -643,7 +650,7 @@ def svg_replace(self, raw_svg_data: str, REPLACEMENTS: dict) -> str:
643650
return svg_data1
644651

645652

646-
def visualize_entity(self, uri: str, url_template="", write_tmp_files: Union[bool, str] = False, radius=1, graph=None) -> str:
653+
def visualize_entity(self, uri: str, url_template="", write_tmp_files: Union[bool, str] = False, radius=1, graph=None, vis_relations=False) -> str:
647654
"""
648655
649656
:param uri: entity uri (like "irk:/my/module#I0123")
@@ -653,7 +660,7 @@ def visualize_entity(self, uri: str, url_template="", write_tmp_files: Union[boo
653660
:return: svg_data as string
654661
"""
655662
if graph is None:
656-
big_G = self.create_complete_graph(url_template)
663+
big_G = self.create_complete_graph(url_template, vis_relations=vis_relations)
657664
else:
658665
big_G = graph
659666
try:
@@ -696,7 +703,7 @@ def visualize_entity(self, uri: str, url_template="", write_tmp_files: Union[boo
696703
# for interactive graph, we need hyperlinks. these mess up the svg with <> inside attributes -> remove
697704
svg_data1 = re.sub(r'(?<=xlink:title=").+?(?=" target=)', "", svg_data1)
698705

699-
if 1:
706+
if 0:
700707
# add legend
701708
svg_data1 = self.add_legend(svg_data1, relation_color_map, list_of_relations)
702709

@@ -778,7 +785,7 @@ def get_label(self, entity):
778785
return res
779786

780787

781-
def visualize_all_entities(self, url_template="", write_tmp_files: Union[bool, str] = False, skip_auto_items: bool = False) -> str:
788+
def visualize_all_entities(self, url_template="", write_tmp_files: Union[bool, str] = False, skip_auto_items: bool = False, vis_relations=False) -> str:
782789
"""visualize all entities loaded in datastore. output svg graph.
783790
784791
Args:
@@ -789,7 +796,7 @@ def visualize_all_entities(self, url_template="", write_tmp_files: Union[bool, s
789796
Returns:
790797
str: svg graph
791798
"""
792-
G = self.create_complete_graph(url_template, skip_auto_items=skip_auto_items)
799+
G = self.create_complete_graph(url_template, skip_auto_items=skip_auto_items, vis_relations=vis_relations)
793800

794801
print(f"Visualizing {len(G.nodes)} nodes and {len(G.edges)} edges.")
795802
ecm = self.build_edge_color_map(G)
@@ -883,10 +890,10 @@ def render_label(self, label: str):
883890

884891
return res.format(**REPLACEMENTS)
885892

886-
def create_interactive_graph(self, url_template="", output_dir="graph_site", radius=1, skip_auto_items=True, skip_existing=False):
893+
def create_interactive_graph(self, url_template="", output_dir="graph_site", radius=1, skip_auto_items=True, skip_existing=False, vis_relations=False):
887894
os.makedirs(output_dir, exist_ok=True)
888895

889-
G = self.create_complete_graph(url_template, skip_auto_items=skip_auto_items)
896+
G = self.create_complete_graph(url_template, skip_auto_items=skip_auto_items, vis_relations=vis_relations)
890897
print(f"Visualizing {len(G.nodes)} nodes and {len(G.edges)} edges.")
891898

892899
for node in G.nodes:
@@ -914,9 +921,17 @@ def create_interactive_graph(self, url_template="", output_dir="graph_site", rad
914921
# to trick graphviz to render rect and then replace href and title to create tooltip
915922
image_map = re.sub(r'(?<=shape="rect")(.+?)(href=")(.+?)(" title=")(.+?)(?=")', lambda mo: mo.group(1)+mo.group(2)+""+mo.group(4)+mo.group(3), image_map)
916923

917-
desc = p.ds.items[node.uri].R2.value if p.ds.items[node.uri].R2 else ""
924+
if node_name.startswith("I"):
925+
item = p.ds.items[node.uri]
926+
else:
927+
item = p.ds.relations[node.uri]
928+
929+
desc = item.R2.value if item.R2 else ""
930+
# add usage hint, sometimes more expressive than R2
931+
desc += "<br>" + " ".join(item.R18) if item.R18 else ""
932+
918933
context = {
919-
"title": node_name + " " + p.ds.items[node.uri].R1.value,
934+
"title": node_name + " " + item.R1.value,
920935
"img_source": f"{node_name}.svg",
921936
"map": image_map,
922937
"desc": desc
@@ -927,7 +942,7 @@ def create_interactive_graph(self, url_template="", output_dir="graph_site", rad
927942

928943
# Index page
929944
dot_path = os.path.join(output_dir, "index.dot")
930-
self.visualize_all_entities(write_tmp_files=dot_path, skip_auto_items=skip_auto_items)
945+
self.visualize_all_entities(write_tmp_files=dot_path, skip_auto_items=skip_auto_items, vis_relations=vis_relations)
931946

932947
# create map
933948
cmapx_path = os.path.join(output_dir, f"index.map")
@@ -961,6 +976,6 @@ def create_interactive_graph(self, url_template="", output_dir="graph_site", rad
961976

962977
if __name__ == "__main__":
963978
# visualize_all_entities(write_tmp_files=True, skip_auto_items=True)
964-
vm.create_interactive_graph()
979+
vm.create_interactive_graph(vis_relations=True)
965980
# nl = p.irkloader.load_mod_from_path("output.py", "nl", "nonlinear")
966981
# visualize_entity("irk:/builtins#I31", write_tmp_files=True, radius=1)

0 commit comments

Comments
 (0)