From 15db5b2569e351464a2f6762beb3f32456f98fa7 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Aur=C3=A9lien=20Lamercerie?=
 <aurelien.lamercerie@tetras-libre.fr>
Date: Wed, 15 Feb 2023 19:00:30 +0100
Subject: [PATCH] New module: naming_computer

---
 tenet/febTransduction/naming_computer.py      |  48 ++++++++
 tenet/febTransduction/net/net.py              |  14 ++-
 .../phenomena_application_or.py               |   8 +-
 tests/test_naming_computer.py                 | 109 ++++++++++++++++++
 tests/test_semantic_net_4.py                  |  89 ++++++++++++++
 5 files changed, 265 insertions(+), 3 deletions(-)
 create mode 100644 tenet/febTransduction/naming_computer.py
 create mode 100644 tests/test_naming_computer.py
 create mode 100644 tests/test_semantic_net_4.py

diff --git a/tenet/febTransduction/naming_computer.py b/tenet/febTransduction/naming_computer.py
new file mode 100644
index 00000000..7daa0939
--- /dev/null
+++ b/tenet/febTransduction/naming_computer.py
@@ -0,0 +1,48 @@
+#!/usr/bin/python3.10
+# -*-coding:Utf-8 -*
+
+#==============================================================================
+# TENET: Naming Computer
+#------------------------------------------------------------------------------
+# Class grouping methods to compute names and URI for semantic nets (and their 
+# attributes)
+#==============================================================================
+
+from rdflib import URIRef
+
+
+#==============================================================================
+# Naming Parameter
+#==============================================================================
+
+# Property Naming Variants
+PROPERTY_NAMING_0 = ''
+PROPERTY_NAMING_1 = 'ing'
+PROPERTY_NAMING_2 = '-by'
+PROPERTY_NAMING_3 = '-of'
+
+
+#==============================================================================
+# Method to compute names
+#==============================================================================
+
+def define_composite_naming_1(net_1, net_2, net_3, 
+                              property_naming=PROPERTY_NAMING_0):
+    
+    name_1 = f'{net_1.naming}'
+    name_2 = f'{net_2.naming}{property_naming}'
+    name_3 = f'{net_3.naming}'
+    
+    return f'{name_1}_{name_2}_{name_3}'
+
+
+#==============================================================================
+# Method to compute URI
+#==============================================================================
+
+def define_net_uri_1(target_net):    
+    uri = None
+    if target_net.naming is not None:
+        uri = URIRef(f'net:{target_net.type_name}_{target_net.naming}')
+    return uri
+    
\ No newline at end of file
diff --git a/tenet/febTransduction/net/net.py b/tenet/febTransduction/net/net.py
index 42f824f1..6c8d4552 100644
--- a/tenet/febTransduction/net/net.py
+++ b/tenet/febTransduction/net/net.py
@@ -7,6 +7,9 @@
 # Class to handle semantic nets 
 #==============================================================================
 
+import rdflib
+from rdflib import URIRef
+
 from febTransduction.net import SemanticNetReferenceHandle
 from febTransduction.query_builder import generate_select_query
 
@@ -108,11 +111,18 @@ class Net:
         
     @property
     def uri(self):
-        return self._uri
+        return self._uri       
+    
     
     @uri.setter
     def uri(self, new_value):
-        self._uri = new_value
+        control = (isinstance(new_value, rdflib.term.URIRef) or isinstance(new_value, str))
+        assert control, f'new_value does not a string or URIRef ({type(new_value)})'
+        
+        if isinstance(new_value, rdflib.term.URIRef):
+            self._uri = new_value
+        else:
+            self._uri = URIRef(new_value)
   
     
         
diff --git a/tenet/febTransduction/phenomena_application_or.py b/tenet/febTransduction/phenomena_application_or.py
index fe469053..02365322 100644
--- a/tenet/febTransduction/phenomena_application_or.py
+++ b/tenet/febTransduction/phenomena_application_or.py
@@ -21,6 +21,7 @@ if __name__ == '__main__':
 
 import febTransduction as transduction
 from febTransduction.query_builder import generate_select_query
+from febTransduction.naming_computer import *
 
 
 #==============================================================================
@@ -100,7 +101,7 @@ def analyze_phenomena_or_1(graph):
         composite_class_net.compose(class_net, property_net, phenomena_net)
     
         # -- Data Computation
-        composite_class_net.mother_class = class_net.uri
+        composite_class_net.mother_class_net = class_net.uri
         # etc
     
         # -- Restriction Computation
@@ -115,6 +116,11 @@ def analyze_phenomena_or_1(graph):
             # TODO: à voir si on veut d'autres relations
     
         # -- Finalization
+        composite_class_net.uri = naming_computer.define_composite_uri_1(
+            composite_class_net,
+            class_net, property_net, phenomena_net,
+            naming_computer.PROPERTY_NAMING_1
+            )
         composite_class_net.finalize()
         new_triples = composite_class_net.generate_triple_definition()
         new_triple_list.append(new_triples)
diff --git a/tests/test_naming_computer.py b/tests/test_naming_computer.py
new file mode 100644
index 00000000..4577318e
--- /dev/null
+++ b/tests/test_naming_computer.py
@@ -0,0 +1,109 @@
+#!/usr/bin/python3.10
+# -*-coding:Utf-8 -*
+
+#==============================================================================
+# TENET: Semantic Net Class Test
+#------------------------------------------------------------------------------
+# Script to test the semantic net classes
+#==============================================================================
+
+import subprocess, os
+from rdflib import Graph
+from rdflib import Namespace
+from rdflib.namespace import NamespaceManager
+
+FILE_PATH = f'{os.path.dirname(os.path.abspath(__file__))}'
+INPUT_DIR_PATH = f'{FILE_PATH}/input/'
+OUTPUT_DIR_PATH = f'{FILE_PATH}/output/'
+TEST_GRAPH = f'{INPUT_DIR_PATH}testGraph1.ttl'
+
+from context import tenet
+
+
+from tenet.febTransduction.net import AtomClassNet
+from tenet.febTransduction.net import CompositeClassNet
+from tenet.febTransduction.net import AtomPropertyNet
+from tenet.febTransduction.net import PhenomenaNet
+from tenet.febTransduction import naming_computer
+
+
+
+#==============================================================================
+# Utilities
+#==============================================================================
+
+def test_attribute_access(net, *attr_set):
+    print(f'\n *** Net attributes ({net.type_id})) ***')
+    for attr in attr_set:
+        print(f' ----- {attr}: {eval(attr)}')    
+       
+
+
+#==============================================================================
+# Development Test
+#==============================================================================
+
+print('\n' + ' *** Development Test ***')
+print('\n *** TEST: Naming Computer ***')
+
+print(f'\n -- Test Graph Loading')
+graph = Graph()
+graph.bind('net', Namespace('https://tenet.tetras-libre.fr/semantic-net#'))
+graph.parse(TEST_GRAPH)
+print(f" ----- Graph Loaded ({len(graph)})")
+
+print('\n -- Test data: some semantic nets')
+net_1 = AtomClassNet(graph, uri='net:atomClass_object_o')
+print(f' ----- net_1: {net_1.uri} ({net_1.naming})') 
+net_2 = AtomPropertyNet(graph, uri='net:atomProperty_orbit_o2')
+print(f' ----- net_2: {net_2.uri} ({net_2.naming})') 
+net_3 = AtomClassNet(graph, uri='net:atomClass_sun_s2')
+print(f' ----- net_3: {net_3.uri} ({net_3.naming})') 
+net_4 = PhenomenaNet(graph, uri='net:phenomena_conjunction-AND_a')
+print(f' ----- net_4: {net_4.uri} ({net_4.naming})') 
+
+print('\n -- Test data: composite net')
+composite_net_1 = CompositeClassNet(graph)
+composite_net_1.compose(net_1, net_2, net_3)
+print(f' ----- composite_net_1: {composite_net_1.uri} ({composite_net_1.naming})') 
+
+
+print('\n -- URI definition')
+
+naming_0 = naming_computer.define_composite_naming_1(net_1, net_2, net_3)
+print(f' ----- Naming (0)): {naming_0}')
+
+naming_1 = naming_computer.define_composite_naming_1(net_1, net_2, net_3, 
+                                                     naming_computer.PROPERTY_NAMING_1)
+print(f' ----- Naming (1)): {naming_1}')
+
+naming_2 = naming_computer.define_composite_naming_1(net_1, net_2, net_3,
+                                                     naming_computer.PROPERTY_NAMING_2)
+print(f' ----- Naming (2)): {naming_2}')
+
+naming_3 = naming_computer.define_composite_naming_1(net_1, net_2, net_3,
+                                                     naming_computer.PROPERTY_NAMING_3)
+print(f' ----- Naming (3)): {naming_3}')
+
+
+print('\n -- Update composite net (with naming_1)')
+composite_net_1.naming = naming_1
+composite_net_1.uri = naming_computer.define_net_uri_1(composite_net_1)
+test_attribute_access(composite_net_1, 'net.uri', 
+                      'net.node', 'net.base_node', 'net.structure', 'net.naming',
+                      'net.class_name',
+                      'net.mother_class_net', 'net.restriction', 'net.restriction01')
+
+
+    
+print('\n -- Advanced Test(s)')
+composite_net_2 = CompositeClassNet(graph)
+composite_net_2.compose(net_1, net_2, net_4)
+composite_net_2.naming = naming_computer.define_composite_naming_1(net_1, net_2, net_4)
+composite_net_2.uri = naming_computer.define_net_uri_1(composite_net_2)
+test_attribute_access(composite_net_2, 'net.uri', 
+                      'net.node', 'net.base_node', 'net.structure', 'net.naming',
+                      'net.class_name',
+                      'net.mother_class_net', 'net.restriction', 'net.restriction01')
+
+print('\n' + ' *** - ***')
\ No newline at end of file
diff --git a/tests/test_semantic_net_4.py b/tests/test_semantic_net_4.py
new file mode 100644
index 00000000..1c558501
--- /dev/null
+++ b/tests/test_semantic_net_4.py
@@ -0,0 +1,89 @@
+#!/usr/bin/python3.10
+# -*-coding:Utf-8 -*
+
+#==============================================================================
+# TENET: Semantic Net Class Test
+#------------------------------------------------------------------------------
+# Script to test the semantic net classes
+#==============================================================================
+
+import subprocess, os
+from rdflib import Graph
+from rdflib import Namespace
+from rdflib.namespace import NamespaceManager
+
+FILE_PATH = f'{os.path.dirname(os.path.abspath(__file__))}'
+INPUT_DIR_PATH = f'{FILE_PATH}/input/'
+OUTPUT_DIR_PATH = f'{FILE_PATH}/output/'
+TEST_GRAPH = f'{INPUT_DIR_PATH}testGraph1.ttl'
+
+from context import tenet
+
+from tenet.febTransduction.net import Net
+
+from tenet.febTransduction.net import ClassNet
+from tenet.febTransduction.net import AtomClassNet
+from tenet.febTransduction.net import CompositeClassNet
+
+from tenet.febTransduction.net import PropertyNet
+from tenet.febTransduction.net import AtomPropertyNet
+from tenet.febTransduction.net import CompositePropertyNet
+
+from tenet.febTransduction.net import IndividualNet
+
+from tenet.febTransduction.net import ValueNet
+
+from tenet.febTransduction.net import PhenomenaNet
+
+from tenet.febTransduction.net import RestrictionNet
+
+
+
+#==============================================================================
+# Utilities
+#==============================================================================
+
+def test_attribute_access(net, *attr_set):
+    print(f'\n *** Net attributes ({net.type_id})) ***')
+    for attr in attr_set:
+        print(f' ----- {attr}: {eval(attr)}')        
+       
+
+
+#==============================================================================
+# Development Test
+#==============================================================================
+
+print('\n' + ' *** Development Test ***')
+print('\n *** TEST: Semantic Net Data Computation ***')
+
+print(f'\n -- Test Graph Loading')
+graph = Graph()
+graph.bind('net', Namespace('https://tenet.tetras-libre.fr/semantic-net#'))
+graph.parse(TEST_GRAPH)
+print(f" ----- Graph Loaded ({len(graph)})")
+
+print('\n -- Nets to compose')
+net_1 = AtomClassNet(graph, uri='net:atomClass_object_o')
+print(f' ----- net_1: {net_1.uri} ({net_1.naming})') 
+net_2 = PropertyNet(graph, uri='net:atomProperty_orbit_o2')
+print(f' ----- net_2: {net_2.uri} ({net_2.naming})') 
+net_3 = AtomClassNet(graph, uri='net:atomClass_sun_s2')
+print(f' ----- net_3: {net_3.uri} ({net_3.naming})') 
+
+print('\n -- New Net constructed by composition')
+new_net = CompositeClassNet(graph)
+new_net.compose(net_1, net_2, net_3)
+test_attribute_access(new_net, 'net.uri', 
+                      'net.node', 'net.base_node', 'net.structure', 'net.naming',
+                      'net.class_name',
+                      'net.mother_class_net', 'net.restriction', 'net.restriction01')
+
+print('\n -- Data compuation to update a new net')
+new_net.mother_class_net = net_1.uri
+test_attribute_access(new_net, 'net.uri', 
+                      'net.node', 'net.base_node', 'net.structure', 'net.naming',
+                      'net.class_name',
+                      'net.mother_class_net', 'net.restriction', 'net.restriction01')
+    
+print('\n' + ' *** - ***')
\ No newline at end of file
-- 
GitLab