diff --git a/src/pyirk/builtin_entities.py b/src/pyirk/builtin_entities.py index 23513bc..720b110 100644 --- a/src/pyirk/builtin_entities.py +++ b/src/pyirk/builtin_entities.py @@ -1898,6 +1898,8 @@ def new_tuple(*args, **kwargs) -> Item: R3__is_subclass_of=I38["non-negative integer"], ) +I39["positive integer"].R1__has_label = "positive Ganzzahl" @ de + R36 = create_builtin_relation( key_str="R36", diff --git a/src/pyirk/ruleengine.py b/src/pyirk/ruleengine.py index 9604d17..45798f2 100644 --- a/src/pyirk/ruleengine.py +++ b/src/pyirk/ruleengine.py @@ -483,12 +483,71 @@ def repl(m): res.apply_time = time.time() - t0 return res + + def _resolve_local_node(self, node=None, uri=None): + """ + return item or literal + """ + + assert not (node is None and uri is None) + + if uri is None: + uri = self.local_nodes.b.get(node) + else: + assert node is None + assert uri is not None + lit = self.parent.literals.a.get(uri) + if lit is not None: + return lit + else: + item = p.ds.get_entity_by_uri(uri) + return item + + def _get_understandable_local_nodes(self): + """ + Generate a humand understandable version of self.local_nodes.a + It is intendend for debugging only. + """ + res = {} + for k_uri, v in self.local_nodes.a.items(): + + item_or_lit = self._resolve_local_node(uri=k_uri) + res[str(item_or_lit)] = v + return res + + + def _get_understandable_result_maps(self, result_maps: List[dict]) -> List[list]: + """ + Generate a humand understandable version of the result_map-dicts which are returned by + self.match_subgraph_P() + It is intendend for debugging only. + """ + p.check_type(result_maps, List[dict]) + res = [] + + # result_maps looks like [ {6: , ... }, ...] + + for result_map in result_maps: + res_pairs = [] + for k, v_item in result_map.items(): + k_item_or_lit = self._resolve_local_node(k) + # v_item = p.ds.get_entity_by_uri(v) + res_pairs.append((k_item_or_lit, v_item)) + res.append(res_pairs) + return res + def apply_graph_premise(self) -> core.RuleResult: t0 = time.time() result_maps = self.match_subgraph_P() - # TODO: for debugging the result_maps data structure the following things might be helpful: - # - a mapping like self.local_nodes.a but with labels instead of uris + # Note: useful for debugging: + # - self._get_understandable_local_nodes() + # - self._get_understandable_result_maps() + # + # TODO: to debug the result_maps data structure the following things might be helpful: # - a visualization of the prototype graph self.P + dbg = self._get_understandable_result_maps(result_maps) + + # now apply condition funcs (to filter the results) and consequent funcs (to do something) res = self._process_result_map(result_maps) res.apply_time = time.time() - t0 @@ -851,6 +910,7 @@ def match_subgraph_P(self) -> List[dict]: # 2: # }, ... ] + # IPS() return new_res def _get_by_uri(self, uri): @@ -888,6 +948,9 @@ def _node_matcher(self, n1d: dict, n2d: dict) -> bool: see also: function edge_matcher """ + # cond = not n1d["is_literal"] and n1d["itm"].R4 is not None and "square matrix" in str(n1d["itm"].R4) + cond = not n1d["is_literal"] and n1d["itm"].short_key == "Ia7720" + if n1d["is_literal"]: if n2d.get("is_variable_literal"): return True @@ -1204,6 +1267,8 @@ def edge_matcher(e1d: AtlasView, e2d: AtlasView) -> bool: e2d = e2d[0] + # IPS("R5938" in str(e1d) + str(e2d)) + if e2d["rel_uri"] == wildcard_relation_uri: # wildcard relations matches any relation which has the required relation properties diff --git a/tests/test_core.py b/tests/test_core.py index 24ebfe0..17d5e24 100644 --- a/tests/test_core.py +++ b/tests/test_core.py @@ -1239,30 +1239,27 @@ def tearDown(self) -> None: def setup_data1(self): with p.uri_context(uri=TEST_BASE_URI): - self.rule1 = p.create_item( - key_str="I400", + I4731 = p.create_item( R1__has_label="subproperty rule 1", - R2__has_description=( - # "specifies the 'transitivity' of I54_mathematical_property-instances via R17_issubproperty_of" - "specifies the 'transitivity' of R17_is_subproperty_of" - ), + R2__has_description=("specifies the 'transitivity' of R17_is_subproperty_of"), R4__is_instance_of=p.I41["semantic rule"], ) - with self.rule1["subproperty rule 1"].scope("setting") as cm: + with I4731["subproperty rule 1"].scope("setting") as cm: cm.new_var(P1=p.instance_of(p.I54["mathematical property"])) cm.new_var(P2=p.instance_of(p.I54["mathematical property"])) cm.new_var(P3=p.instance_of(p.I54["mathematical property"])) - # # A = cm.new_var(sys=instance_of(I1["general item"])) - # - with self.rule1["subproperty rule 1"].scope("premise") as cm: + + with I4731["subproperty rule 1"].scope("premise") as cm: cm.new_rel(cm.P2, p.R17["is subproperty of"], cm.P1) cm.new_rel(cm.P3, p.R17["is subproperty of"], cm.P2) # todo: state that all variables are different from each other - with self.rule1["subproperty rule 1"].scope("assertion") as cm: + with I4731["subproperty rule 1"].scope("assertion") as cm: cm.new_rel(cm.P3, p.R17["is subproperty of"], cm.P1) + self.rule1 = I4731 + def test_a01__basics(self): self.setup_data1() @@ -1340,11 +1337,14 @@ def test_c05__ruleengine04(self): mod1 = p.irkloader.load_mod_from_path(TEST_DATA_PATH2, prefix="ct", modname=TEST_MOD_NAME) self.assertEqual(len(mod1.I9642["local exponential stability"].get_relations("R17__is_subproperty_of")), 1) + + IPS() ra = p.ruleengine.RuleApplicator(self.rule1, mod_context_uri=TEST_BASE_URI) res = ra.apply() # ensure that after rule application there new relations self.assertEqual(len(mod1.I9642["local exponential stability"].get_relations("R17__is_subproperty_of")), 3) + IPS() def test_c06__ruleengine05(self): self.setup_data1() @@ -1373,6 +1373,8 @@ def test_a01__label(self): # (it would need some further work to make it independent of the concrete default lang) self.assertEqual(p.settings.DEFAULT_DATA_LANGUAGE, "en") + self.assertEqual(p.I39["positive integer"], p.I39["positive Ganzzahl"@p.de]) + with p.uri_context(uri=TEST_BASE_URI): with self.assertRaises(p.aux.MultilingualityError):