From 1b39f6239a7311bdb9938acd2afa243df9047c8c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Aur=C3=A9lien=20Lamercerie?=
 <aurelien.lamercerie@tetras-libre.fr>
Date: Fri, 4 Aug 2023 12:50:07 +0200
Subject: [PATCH] Update library and add a main script

---
 README.md                                     |  34 +++---
 data/generated_ontology.ttl                   | 104 +++++++++++++++++
 data/reference_ontology.ttl                   | 109 ++++++++++++++++++
 main.py                                       |  30 +++++
 ontoScorer/__init__.py                        |  15 +--
 .../__pycache__/__init__.cpython-311.pyc      | Bin 0 -> 607 bytes
 .../__pycache__/metrics.cpython-311.pyc       | Bin 0 -> 1704 bytes
 .../__pycache__/ontology.cpython-311.pyc      | Bin 0 -> 1930 bytes
 ontoScorer/__pycache__/report.cpython-311.pyc | Bin 0 -> 2283 bytes
 ontoScorer/__pycache__/scorer.cpython-311.pyc | Bin 0 -> 1726 bytes
 ontoScorer/metrics.py                         |  20 +++-
 ontoScorer/ontology.py                        |  27 ++++-
 ontoScorer/report.py                          |  34 +++++-
 ontoScorer/scorer.py                          |  26 ++++-
 tests/__init__.py                             |  10 --
 15 files changed, 367 insertions(+), 42 deletions(-)
 create mode 100644 data/generated_ontology.ttl
 create mode 100644 data/reference_ontology.ttl
 create mode 100644 main.py
 create mode 100644 ontoScorer/__pycache__/__init__.cpython-311.pyc
 create mode 100644 ontoScorer/__pycache__/metrics.cpython-311.pyc
 create mode 100644 ontoScorer/__pycache__/ontology.cpython-311.pyc
 create mode 100644 ontoScorer/__pycache__/report.cpython-311.pyc
 create mode 100644 ontoScorer/__pycache__/scorer.cpython-311.pyc

diff --git a/README.md b/README.md
index d295f3e..8e95455 100644
--- a/README.md
+++ b/README.md
@@ -21,27 +21,27 @@ All dependencies are listed in **requirements.txt**.
 
 We recommend creating a virtual environment before proceeding:
 
-1. Create a virtual environment:
-> python3 -m venv env
+1. Create a virtual environment: `python3 -m venv env`
 
-2. Activate the virtual environment:
-> source env/bin/activate
+2. Activate the virtual environment: `source env/bin/activate`
 
 
 ## Usage
 
 Here's an example of how to use ontoScorer:
 
-> from ontoScorer import OntoScorer
->
-> # Initialize the scorer
-> scorer = OntoScorer("path/to/reference_ontology.ttl", "path/to/generated_ontology.ttl")
->
-> # Compare the ontologies
-> scorer.compare()
->
-> # Print the scores
-> scorer.print_scores()
->
-> # Generate a report
-> scorer.generate_report("path/to/report.txt")
+```python
+from ontoScorer import OntoScorer
+
+# Initialize the scorer
+scorer = OntoScorer("path/to/reference_ontology.ttl", "path/to/generated_ontology.ttl")
+
+# Compare the ontologies
+scorer.compare()
+
+# Print the scores
+scorer.print_scores()
+
+# Generate a report
+scorer.generate_report("path/to/report.txt")
+```
diff --git a/data/generated_ontology.ttl b/data/generated_ontology.ttl
new file mode 100644
index 0000000..2b5ee47
--- /dev/null
+++ b/data/generated_ontology.ttl
@@ -0,0 +1,104 @@
+@prefix ns1: <https://tenet.tetras-libre.fr/base-ontology#> .
+@prefix owl: <http://www.w3.org/2002/07/owl#> .
+@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
+
+<https://tenet.tetras-libre.fr/extract-result#SolarSystem> a owl:Individual,
+        <https://tenet.tetras-libre.fr/extract-result#system>,
+        <https://tenet.tetras-libre.fr/extract-result#system-hasPart-object>,
+        <https://tenet.tetras-libre.fr/extract-result#system-hasPart-sun> ;
+    rdfs:label "SolarSystem" ;
+    ns1:fromStructure "unknown" .
+
+<https://tenet.tetras-libre.fr/extract-result#direct> a owl:ObjectProperty ;
+    rdfs:label "direct" ;
+    rdfs:subPropertyOf ns1:Out_ObjectProperty ;
+    ns1:fromStructure "unknown" .
+
+<https://tenet.tetras-libre.fr/extract-result#gravitation-bind-system> a owl:Class ;
+    rdfs:subClassOf [ a owl:Restriction ;
+            owl:onProperty <https://tenet.tetras-libre.fr/extract-result#bind> ;
+            owl:someValuesFrom <https://tenet.tetras-libre.fr/extract-result#system> ],
+        <https://tenet.tetras-libre.fr/extract-result#gravitation> ;
+    ns1:fromStructure "unknown" .
+
+<https://tenet.tetras-libre.fr/extract-result#hasManner> a owl:ObjectProperty ;
+    rdfs:label "hasManner" ;
+    rdfs:subPropertyOf ns1:Out_ObjectProperty ;
+    ns1:fromStructure "unknown" .
+
+<https://tenet.tetras-libre.fr/extract-result#not-direct> a owl:ObjectProperty ;
+    rdfs:subPropertyOf ns1:Out_ObjectProperty ;
+    ns1:fromStructure "unknown" .
+
+<https://tenet.tetras-libre.fr/extract-result#object-orbit-hasManner-direct-sun> a owl:Class ;
+    rdfs:subClassOf [ a owl:Restriction ;
+            owl:onProperty <https://tenet.tetras-libre.fr/extract-result#orbit-hasManner-direct> ;
+            owl:someValuesFrom <https://tenet.tetras-libre.fr/extract-result#sun> ],
+        <https://tenet.tetras-libre.fr/extract-result#object> ;
+    ns1:fromStructure "unknown" .
+
+<https://tenet.tetras-libre.fr/extract-result#object-orbit-hasManner-not-direct-sun> a owl:Class ;
+    rdfs:subClassOf [ a owl:Restriction ;
+            owl:onProperty <https://tenet.tetras-libre.fr/extract-result#orbit-hasManner-not-direct> ;
+            owl:someValuesFrom <https://tenet.tetras-libre.fr/extract-result#sun> ],
+        <https://tenet.tetras-libre.fr/extract-result#object> ;
+    ns1:fromStructure "unknown" .
+
+<https://tenet.tetras-libre.fr/extract-result#bind> a owl:ObjectProperty ;
+    rdfs:label "bind" ;
+    rdfs:subPropertyOf ns1:Out_ObjectProperty ;
+    ns1:fromStructure "unknown" .
+
+<https://tenet.tetras-libre.fr/extract-result#gravitation> a owl:Class ;
+    rdfs:label "gravitation" ;
+    rdfs:subClassOf ns1:Entity ;
+    ns1:fromStructure "unknown" .
+
+<https://tenet.tetras-libre.fr/extract-result#orbit-hasManner-direct> a owl:ObjectProperty ;
+    rdfs:subPropertyOf <https://tenet.tetras-libre.fr/extract-result#orbit> ;
+    ns1:fromStructure "unknown" .
+
+<https://tenet.tetras-libre.fr/extract-result#orbit-hasManner-not-direct> a owl:ObjectProperty ;
+    rdfs:subPropertyOf <https://tenet.tetras-libre.fr/extract-result#orbit> ;
+    ns1:fromStructure "unknown" .
+
+<https://tenet.tetras-libre.fr/extract-result#system-hasPart-object> a owl:Class ;
+    rdfs:subClassOf [ a owl:Restriction ;
+            owl:onProperty <https://tenet.tetras-libre.fr/extract-result#hasPart> ;
+            owl:someValuesFrom <https://tenet.tetras-libre.fr/extract-result#object> ],
+        <https://tenet.tetras-libre.fr/extract-result#system> ;
+    ns1:fromStructure "unknown" .
+
+<https://tenet.tetras-libre.fr/extract-result#system-hasPart-sun> a owl:Class ;
+    rdfs:subClassOf [ a owl:Restriction ;
+            owl:onProperty <https://tenet.tetras-libre.fr/extract-result#hasPart> ;
+            owl:someValuesFrom <https://tenet.tetras-libre.fr/extract-result#sun> ],
+        <https://tenet.tetras-libre.fr/extract-result#system> ;
+    ns1:fromStructure "unknown" .
+
+<https://tenet.tetras-libre.fr/extract-result#hasPart> a owl:ObjectProperty ;
+    rdfs:label "hasPart" ;
+    rdfs:subPropertyOf ns1:Out_ObjectProperty ;
+    ns1:fromStructure "unknown" .
+
+<https://tenet.tetras-libre.fr/extract-result#orbit> a owl:ObjectProperty ;
+    rdfs:label "orbit" ;
+    rdfs:subPropertyOf ns1:Out_ObjectProperty ;
+    ns1:fromStructure "unknown" .
+
+<https://tenet.tetras-libre.fr/extract-result#object> a owl:Class ;
+    rdfs:label "object" ;
+    rdfs:subClassOf ns1:Entity ;
+    ns1:fromStructure "unknown" .
+
+<https://tenet.tetras-libre.fr/extract-result#sun> a owl:Class ;
+    rdfs:label "sun" ;
+    rdfs:subClassOf ns1:Entity ;
+    ns1:fromStructure "unknown" .
+
+<https://tenet.tetras-libre.fr/extract-result#system> a owl:Class ;
+    rdfs:label "system" ;
+    rdfs:subClassOf ns1:Entity,
+        ns1:Undetermined_Thing ;
+    ns1:fromStructure "unknown" .
+
diff --git a/data/reference_ontology.ttl b/data/reference_ontology.ttl
new file mode 100644
index 0000000..2b97132
--- /dev/null
+++ b/data/reference_ontology.ttl
@@ -0,0 +1,109 @@
+@prefix base: <https://reference.tetras-libre.fr/base-ontology#> .
+@prefix owl: <http://www.w3.org/2002/07/owl#> .
+@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
+@prefix result: <https://reference.tetras-libre.fr/expected-result#> .
+
+result:SolarSystem a owl:Individual,
+        result:system,
+        result:system-isBindBy-gravitation,
+        result:system-hasPart-object-orbit-sun,
+        result:system-hasPart-sun ;
+    rdfs:label "SolarSystem" .
+
+result:direct a owl:ObjectProperty ;
+    rdfs:label "direct" ;
+    rdfs:subPropertyOf base:Out_ObjectProperty .
+
+result:gravitation-bind-system a owl:Class ;
+    rdfs:subClassOf [ a owl:Restriction ;
+            owl:onProperty result:bind ;
+            owl:someValuesFrom result:system ],
+        result:gravitation .
+
+result:hasManner a owl:ObjectProperty ;
+    rdfs:label "hasManner" ;
+    rdfs:subPropertyOf base:Out_ObjectProperty .
+
+result:not-direct a owl:ObjectProperty ;
+    rdfs:subPropertyOf base:Out_ObjectProperty .
+
+result:object-orbit-sun a owl:Class ;
+    rdfs:subClassOf [ a owl:Restriction ;
+            owl:onProperty result:orbit ;
+            owl:someValuesFrom result:sun ],
+        result:object .
+
+result:object-orbit-hasManner-direct-sun a owl:Class ;
+    rdfs:subClassOf [ a owl:Restriction ;
+            owl:onProperty result:orbit-hasManner-direct ;
+            owl:someValuesFrom result:sun ],
+        result:object-orbit-sun .
+
+result:object-orbit-hasManner-not-direct-sun a owl:Class ;
+    rdfs:subClassOf [ a owl:Restriction ;
+            owl:onProperty result:orbit-hasManner-not-direct ;
+            owl:someValuesFrom result:sun ],
+        result:object-orbit-sun .
+
+result:gravitation a owl:Class ;
+    rdfs:label "gravitation" ;
+    rdfs:subClassOf base:Entity .
+
+result:system-isBindBy-gravitation a owl:Class ;
+    rdfs:subClassOf [ a owl:Restriction ;
+            owl:onProperty result:isBindBy ;
+            owl:someValuesFrom result:gravitation ],
+        result:system .
+
+result:system-hasPart-object a owl:Class ;
+    rdfs:subClassOf [ a owl:Restriction ;
+            owl:onProperty result:hasPart ;
+            owl:someValuesFrom result:object ],
+        result:system .
+
+result:system-hasPart-object-orbit-sun a owl:Class ;
+    rdfs:subClassOf [ a owl:Restriction ;
+            owl:onProperty result:hasPart ;
+            owl:someValuesFrom result:object-orbit-sun ],
+        result:system-hasPart-object .
+
+result:system-hasPart-sun a owl:Class ;
+    rdfs:subClassOf [ a owl:Restriction ;
+            owl:onProperty result:hasPart ;
+            owl:someValuesFrom result:sun ],
+        result:system .
+
+result:bind a owl:ObjectProperty ;
+    rdfs:label "bind" ;
+    rdfs:subPropertyOf base:Out_ObjectProperty .
+
+result:isBindBy owl:inverseOf result:bind ;
+    rdfs:label "isBindBy" ;
+    rdfs:subPropertyOf base:Out_ObjectProperty .
+
+result:orbit a owl:ObjectProperty ;
+    rdfs:label "orbit" ;
+    rdfs:subPropertyOf base:Out_ObjectProperty .
+
+result:orbit-hasManner-direct a owl:ObjectProperty ;
+    rdfs:subPropertyOf result:orbit .
+
+result:orbit-hasManner-not-direct a owl:ObjectProperty ;
+    rdfs:subPropertyOf result:orbit .
+
+result:hasPart a owl:ObjectProperty ;
+    rdfs:label "hasPart" ;
+    rdfs:subPropertyOf base:Out_ObjectProperty .
+
+result:object a owl:Class ;
+    rdfs:label "object" ;
+    rdfs:subClassOf base:Entity .
+
+result:system a owl:Class ;
+    rdfs:label "system" ;
+    rdfs:subClassOf base:Entity.
+
+result:sun a owl:Class ;
+    rdfs:label "sun" ;
+    rdfs:subClassOf base:Entity .
+
diff --git a/main.py b/main.py
new file mode 100644
index 0000000..fe59030
--- /dev/null
+++ b/main.py
@@ -0,0 +1,30 @@
+#!/usr/bin/python3.10
+# -*-coding:Utf-8 -*
+
+#==============================================================================
+# ontoScorer: [brief description of the module]
+#------------------------------------------------------------------------------
+# Detailed module description, if needed
+#==============================================================================
+
+from ontoScorer.scorer import OntoScorer
+
+def main():
+    # Define the path to the data folder
+    DATA_FOLDER_PATH = "data"
+
+    # Define paths to the ontology files
+    REFERENCE_ONTOLOGY_PATH = f"{DATA_FOLDER_PATH}/reference_ontology.ttl"
+    GENERATED_ONTOLOGY_PATH = f"{DATA_FOLDER_PATH}/generated_ontology.ttl"
+
+    # Initialize the scorer
+    scorer = OntoScorer(REFERENCE_ONTOLOGY_PATH, GENERATED_ONTOLOGY_PATH)
+
+    # Compare the ontologies
+    scorer.compare()
+
+    # Generate a report
+    scorer.generate_report()
+
+if __name__ == "__main__":
+    main()
\ No newline at end of file
diff --git a/ontoScorer/__init__.py b/ontoScorer/__init__.py
index 4415d78..162f653 100644
--- a/ontoScorer/__init__.py
+++ b/ontoScorer/__init__.py
@@ -1,10 +1,5 @@
-#!/usr/bin/python3.10
-# -*-coding:Utf-8 -*
-
-#==============================================================================
-# ontoScorer: [brief description of the module]
-#------------------------------------------------------------------------------
-# Detailed module description, if needed
-#==============================================================================
-
-# TODO
+# -- Update System Path
+import os, sys
+LIB_PATH = os.path.dirname(os.path.abspath(__file__)) + '/'
+os.chdir(LIB_PATH)
+sys.path.insert(0, os.path.abspath(LIB_PATH))
diff --git a/ontoScorer/__pycache__/__init__.cpython-311.pyc b/ontoScorer/__pycache__/__init__.cpython-311.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..15c9d4b5e58309a39ad2614703ebff6ad3759740
GIT binary patch
literal 607
zcmZ3^%ge>Uz`*eQ%$bxW3=9m9K^z!ngEBs|F)}brXGmd4Va#EOg3ydnjHwJ+Oi&dJ
z3z%UnWEw>U3$hH1oyxk5k%3_~BaDyAOJS;FU|@)1V`4~U$YO`7No7M-#mJD#h~yFu
zm^x%S1!Mxkwb<Q)X6`a328PveJ&X(~jKK_=%r8O4`u$?m*W|p#lwW*{xwx|U7E3{5
zNyaVql+2>M#N5<d?1@RmU=fb^__WNN)cE*Y96p{-@d1t@9=BMNGg2~(Zn0(N6{i-J
ztYr8MGVqs!enx(7s(wylZfagurha&SQFd`bVsff}NNPz@VzGXHUP*p&a(+>25ttba
zVaCU2=4F<|$LkeT{^GF7%}*)KNwq5yU|?VXg=ldF0|UbcW=2NF2Ml}-DDVb1Z;yGu
zeV6?VqdDgD?PuAqu(&8~az)zYBDd)kZqpsi7rCt)IBqa-G%&SrbVyue5W2!3bb&$W
u1_N^oM>~HL{{+SfMpMkE+fTAzU~y4c=Zdh-MF!m~47wL!sECh&fdK$ee}YB;

literal 0
HcmV?d00001

diff --git a/ontoScorer/__pycache__/metrics.cpython-311.pyc b/ontoScorer/__pycache__/metrics.cpython-311.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..b3d7b0f5b4273d827168b62f4a05c4bc64426e93
GIT binary patch
literal 1704
zcmZ3^%ge>Uz`zi8@l47!W(J1GAPx+(KpCG+7#J9)Go&!2Fy=7iGDb1xGDR`vGDk5p
zGB7c?Go&!JFr+XqV`5-f%>>oK5XF+h63n2<`Vu6d$$X2ypeQvtvp6$9FTOZAzbN$<
zPf==eVonZ}$B||TVI_mq!!RS1@mUINe=0*1V+unQQwn1XLliT})+m+~=3oX*mRsz;
zsU=03$;HVqEg+pB$1pQ6Fnl%uYfoXUVTcEbgE5!~R}JQY)I;PLf*CZK{E9#Vn#{L2
z;cmah266Q*rZhuM##=1KsX1xIAVU;>+3RQI=celCB<7~(Wo7Dz=NDxc7bGU9>W8G3
z6eSkx=jWB=gMD5EW(I=-p-4X$;%vQw%3B=q@tJv<CGqi90#MKB!9;i&7#NDB85kHE
z7;Z>Pb+GjC-4GM+VCmt$Atc<v(!<`t-ogGE<nm;YcR>sg2E`tT|M?XI14BDwJJWQA
zPR0cw84TRXw2YB~VKvAnV7Xf64#qUb6vh^g8fF)UWef}qtHI(RqL!tDDUC6O39B4y
z3CKo}G6n{Q8kQPX)KpQ!5DyAduzU$Sm;w`6Rf60PmM!51Q(ywCN;a?*0|P?}DB_s?
zP*MTN7-3K<P+(wSn94YvA)TRyA(pF_v4*jesf?kBDTN`AF@<p=QxA7A!%C)?pg;h}
z{7ME*=37j92Dg}#bBb>X7Nw@87NzDTr^YAeBo-H^78irOs-VzN1d5(tTsAqG#U;u4
zxdnDrs;~%5PRvOz%}Fdt)w9XTPfpA!w$no>69G9&gMoqJM+3tJK|cuEVLYMuf}H*Z
zaS)oII6-kkAVlJVpkEO`0|Nv3ek&4UU|=W$*{aE0Bno1SF)%RP5=>9cOD#$)Nln4(
zu_6fu1_mO11U6I>WHQL5n(Vh&OY<`G^NK(LRm2Gr2Sr8^sK6;=1#v+UtI1Zx17eGV
z2v8!w#SJPKpn-ggtunr(s5BKs7ZjzY6ocYgAt6CQK>-}@w>aTpTqTGR>>wW(H-dur
zM+3tRG4<<Wx|hUsFX-7{6mz&D=Fq`?0~YQV1pN+ZUl8=WDCl=Z(656Hr^Hi9jTK@W
z#4bu&T#>W@WyQN<N(;<Zm|YYzx*}!-%9MA7q-K~cFuN$Ebwx-EmOa67=cmaE%I0~A
zxvBB-x47ctbMsS5b3kmK`1r!o#2koB5g#ZhK*<#xTVSnV&lZ8Q4443gSg{efL}*}u
zzz<B!tRf#6-~<;ttM&&5OafvY$Rv<+_=~f1QWJ~v^q?gXB(A{G1dbt)Iy6`O;;@0Z
z+pb8Jfq?;(Uy36b7#Kb<Gcq!M5Mf|+VZ6ZLj0=5W;bqkRz<^171c`kC5ooet2Lk}{
Cx{7uH

literal 0
HcmV?d00001

diff --git a/ontoScorer/__pycache__/ontology.cpython-311.pyc b/ontoScorer/__pycache__/ontology.cpython-311.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..aafe00e11d0aad998e8c002a193da51608e8d62d
GIT binary patch
literal 1930
zcmZ3^%ge>Uz`$_s!kLsR76yjLAPx+(KpCHH7#J9)Go&!2Fy=7iGDb1xGDR^lg7{21
z%(*O4EQ}0H4DJjm%q<KlEX$Y}7*;bubuvV;rmzMxXtKQo31~9iVs$S{EXcUU>>uu<
z$#{#ixF9F9B)+sLGZ`cg!;DbIXEm_BsSHt!DGX6eDU2-)QOqe!EeugCAiJViQ&?IU
zqSzod+~V-hE6LBvPp?dd+s?qizzoHotH5T}FxD`{Lyc!(s9{(DvkNW;V$?7$V`N}h
z4VSB7h=-e5!>|BkCP*0yUdF({uo^B>!w?S(J%$v9V1|{9ewwVeSPBwLGH&ta<R_-Y
z=R;k4i!~h_B;4t#CGp8QiN(dK#kbg@3{9q6EXAogX}5S`%Hu&s6oXu&pzzB<KO;Xk
zRX-;&H#ILSQ$IYvD7&~IF*#K~B(<a{u~;9ZsW>^mD76U83`Q_P;iOkkd5a@HJ~J<~
zBtE`M5EguTFd;q$28Lo&1_p)(h8rS^9V|VZH$)|`i>hA|RbRn-QPk{;s96U~57!NG
z>FeU^m&DaCifdjG*X&^F;pyP%;Q0&+3zVn;1qdkUJ_mrKq68ki3=F7&SIbnxgeziF
z7}qeNCNV~a8m3?dO=iDa%q1l`nvA#D((;RP6H7Fiia@sAVl7B4Do)j8F5+ikU?>8m
z_FIhU#ULpK1%)C(kRUe$14ES<JOEJQM;H_epoG}KaF<80)4j*NgYgCjXFq!v`vjI5
zp&jfOIh3z(C|}@EzQHfh!BGTKpN!-+2DrB$5b`!-3S%u(4MP@O_X1EngTfI7r!b+W
zP8Wt)rx<1ihFa!YmRi;trWEEXUIvC*rW)1~HiX73kUPNKY_O?C>Lnm=gGCq^YM4>Y
zjA3G6sAa2VuVGw(WCm0*0|P@1JF0p{h92h{#$X0b7QZ5p@tVwjets`O9?@jK#ax_P
zQpCf+z;KJbq$sl>C$+c;<d|Em&Y<L8#0rvOPE1MB<bcExDB<1WgD5R2j!(`n%`3UZ
zSbU4I;1*;4Eynm;T;S{xpO=`MTFk+~z@PvHkl5q}#ij^6Hj(m`1Sl?xz$yB!kmy9!
zDXJapHzcJx_-=?xPpP^tu6apZ^MaPmMRD6J;<g_cSU5GnM5lX)V@Kfx#Tz_QGZHWI
z$anbN;1`(cJjJuCuA}a*g60avg*;1mCh|^ToM3fBKzus)B<>kr7X{R>2&i8WQ2%j*
zU#x=<k}g0&0}DhD8<Yw^%YoBH4MP@8hM|TL!A@feW+>uhU|`T>ECL0LCKEW2Zt>-p
zWTY0sixFs%01km$T*>*l1&Kwe@g@0H!tj7V2r7ZXK?ocUH~58nYG%Y;ku|=+Z+wBn
z80=0zO?FVp01Dsu_*-1@@wxdar8%kb@wa&5;|og@b09KBAR~%Esi+7P=0)lZ3=At7
zz$Sp*QN#|)Tp$7@T@1?h4Gb{&fr*(_>jMLv;9_PK1aYAR7YD2O2L?DH!pLg!fdP|%
zSO&7fPm}EyTTx0{PG%A~-$Rm^07OI&<X~{o2u^JfhiQXc2g<Hs$Nu85f%wv{NRNSm
z0hDx$LABBcW=2NF4<ZbVau*n6G0_bMwF{`|1B)1=$p;2Z;v-1x3y46I1$zPjzzn7q

literal 0
HcmV?d00001

diff --git a/ontoScorer/__pycache__/report.cpython-311.pyc b/ontoScorer/__pycache__/report.cpython-311.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..3ac64f032d3c2903f9d0664b49ed1fe36c6d71ac
GIT binary patch
literal 2283
zcmZ3^%ge>Uz`(Hl!kLt<><kQ#K^z!nfigZTFfcGoXJBG*XGmdaVMt+I#>Bv|nh7e)
z5XF$f6wIK>oD35H(TpI1fq~((6j*O6Llk2QLljdAV+%tRa|%-nLljF2b1;J@%PqE`
z)Pnq?l4Mq>4iE)0n;E3r4y?O|v4$ZYBo4+kOf?MgF!LE|m}?l~LFyrLEHw=AAe~@d
z3PUi1CZnGw%Ppaz)U?#1)V$=>`24(*{G9ys%3DI|sd=eIi6yBi2r<Fr{M>@XqRis_
zy!fKj;?kUwTkN^1B}JLZ#hR?QSc+3~(uzP1En;I}U?^e-5gZH*48<TZ1rYdUr=O9Z
zo2s9an46lHm8l<|UzA;3keHmRACg*9lvu0}vc5PuzbLf`%nXJwi@;%^S5SG2BR)Pe
zFS8^*zKS0bFnTZnZjeQ)3=9kn3^$ZaI#{l7$irzxBM@KihPYe@OAk*6PY2IuPzWT$
zgNcEG0pvzd(0q1a0!3#EV=ZG1V+vCZLl#IW7-zxN&t{m*RK?4{09M0X0@4ds!N7o`
z9%LR^d>JDH!)olhS!x)vU`dGqhYhS~HXzg!V*?w+rD$e=-321DaF~Ino}iuCU=>Ad
zHH<0j5F7LC(aZo@2gX#h6KopTP7bJ@tTl`&oDg;mV+t3X#a+XY1&^mJPyz+(MTtos
z6g8mqi>ZbeMGYu<W2gyc(B$*0Qnt0VRq%&qCk5BC#GKN^lFa-(1xUhGu(h@2suJZ2
zf@M9pS}TPrEiS*(+@#bZh5R&y<ebFf;?!b=Ops1!Hbqt|#>M3h%c{uYILyGRR+Nj&
z8J@Kjg1}kZN}<X%BqLP;UJfXLGAF2PP{>FuR!B=NPc4Ewt|TKdPoX3uRRLa-z*Xy2
zx!^G-H@_&AI8%afn39;6g2QHojKs23uv~FsZmL2adXVZ>iE?ovMT{?`D6^{K;R+~9
zP0lRN%+Iq@sN&=bN=;78$+1$X;^uNQQ~(!BRtlP&;Ii%(OF?2u#x3TY)Vy2l(71w>
zf1tE+i?aY`(k-?kuraro(hN13iZ~e<7;bSvO1AjolA>ZzDXpMT1gdaualir{Ud+J+
z1VP1IFeA8_6SeN(dcYxcLCkkW$rXLKEBf9S#C$J^`CjDk?cllrlE^yhe1heQNBk9!
z^ouSTS6nhKh-F<6%eu&s1=Z=lLF9^|#}z~03u68k#QZOE_!FV?0~-UU@C7mbiyZnL
zTz9$oI!dnat6kyOyU4A7g<F5C@`jWvX1-U<LN6MHT`>x~#2t2lJM0FJ*afM?i#&-P
zUL9U{c?BkjToKf`B4}`t*YFCj;a2AzELSZ2uULd%G>N!k5^;$);sS33SWm)5o&=Dd
z2OtCTF7o7cc!B*4u^sG7y9Fsra;~V^ToALnAZB-w!w%{Piv=c2Y_2GqT@bUlAZBrq
z!vZR9wjg9l%#!#EVrCb_%r0`6b#Oi4m%P9sS;WJ@z~HCJ3aVxD5_41I<8N`r$LHp!
zl;(igJn`{`rHMHZnIceqQzXj3z_5}5tPdP<MWC`2On{=X*a%!5H84Qn2PPI)`40?m
zf=8TH>H`BN0Wl6_lAk6c*svl=P*n<Y9oUv%95xU~*%g7>51@Lb*qniZ;R7=xBjX1V
VIYy}u44A}6kk}UxfhG&K4*(zdK6n5C

literal 0
HcmV?d00001

diff --git a/ontoScorer/__pycache__/scorer.cpython-311.pyc b/ontoScorer/__pycache__/scorer.cpython-311.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..15863905c230a177ffba8eb4a80f491d1fd94ecb
GIT binary patch
literal 1726
zcmZ3^%ge>Uz`*eQ;+YgaRtAR0APx+(KpCH17#J9)Go&!2Fy=7iGDa~ng4j$sOu5Wa
z%wRTi4ofa;6e}YG6N5WL3QG$^3hOc^28Pv4P!kxU*izVn88q2nf&?@fZ*lnNmE`B-
zr&nq+-eL<%Eyyn_(PX^E?weXtl$l(d3{nNdj8MjB1+Xhp8KM|d7^0X`7+V;km{XWq
z7@}BGm|Ga4SW{Sn88lgMae<5uPR=h%ElOsF>IG3CHVA*N0h?0-GnavZp@wl8BLl-~
zxJV5{Je-Z9jtN5@+=nIXAWI;483O~uY6uf#Izv1xBpFf|f*Dpa`f0Kjft+$ns3<ip
zwJ0?&IW;~X8X&iX(o^$NixNvxQ{ZAntPBhcx7c$bp`*!si={X<C+(IvrtbKH#FC6#
z;+RH&C5l0oDkv!YveVDV&rQ|ONz6^n%gWRb&o9a@E=WvH)elK6DM~EX2RWt~9E4yd
zBsBFQB6<atw>aYCGxIV_;^V7?5uvRI6Xa)LU??_bU|?uqxT~afLEGt~lJgZM=MI)D
z9P*d~;&Kx!r&M;Z^zd}>bntuz1zR#a^cff!KyC)%&t>3vt6|6jDFNdJ$m+l%AfkpL
z3mz*N@dYvoq=<oup@ty~9xqv-5C)6aFl52i^f7=^cQ8W{Cj$e6CR-5~C>pqu^K%Ol
zi&EoD@{71Z0)h~M%;NmK_@dO}(wvea9*{U^a$-($X-;BEswQI*FDOhv&Q&N907<e#
zG^JJvAq5~*Oa!FX5*&Uv6jiS%T3lCjzNF}Uz~zcd^hL#(D~d6opp?78AqNVzD;#nQ
zSgt6TUEnZ>qaq;&1_qQ+WP^s}=PBS&L`l^QSs;hOd=C#h<d8rPt7R+<46ETGSIbxe
z3I(ukP)=F^vI)vVP^dWqHCB+rn7s&OFgT#Wfm<ZXz`y_rPS%2=%)F9Y9I&*l$pjA6
zTWm$(;-eVkZUt!Q^1~FxLnN!DkU|+vP68C#?%>eAD=0pL<%)#<4G9?-sdqy{W)9Cs
zc4i^9FAU5=Y8`A}IT$$kI@0>{yYesc$zS1<zsR9*g+t*241vSmPm>LlN%9hNQ{&@r
zamB~y=BJeAfY?0o@r9*{IS`p5L6G;vL4*tg1H(!Nux4-yDFT%zV1f_iKu53x8yFz)
z0~0f=;s*ve!NtUC@qqzOaIk`8F$sw2AcOrh*>7=xayh6B2A4%e(jZrWLm!lS!9@<(
z`XW%d3(*NmxxYAUAbzncQet3W0HvJbd<F)F56p~=j2}c8809W7$ReW~43Za6(G3Ra
a3#jM=3qPac2L?>yBS`EEh(MDCI|u-6DS9mc

literal 0
HcmV?d00001

diff --git a/ontoScorer/metrics.py b/ontoScorer/metrics.py
index 4415d78..e905353 100644
--- a/ontoScorer/metrics.py
+++ b/ontoScorer/metrics.py
@@ -4,7 +4,23 @@
 #==============================================================================
 # ontoScorer: [brief description of the module]
 #------------------------------------------------------------------------------
-# Detailed module description, if needed
+# Detailed module description
 #==============================================================================
 
-# TODO
+from sklearn.metrics import precision_score, recall_score, f1_score
+
+class Metrics:
+    def __init__(self):
+        self.precision = 0
+        self.recall = 0
+        self.f1 = 0
+
+    def calculate(self, reference_classes, generated_classes):
+        all_classes = reference_classes.union(generated_classes)
+        y_true = [1 if cls in reference_classes else 0 for cls in all_classes]
+        y_pred = [1 if cls in generated_classes else 0 for cls in all_classes]
+
+        self.precision = precision_score(y_true, y_pred)
+        self.recall = recall_score(y_true, y_pred)
+        self.f1 = f1_score(y_true, y_pred)
+
diff --git a/ontoScorer/ontology.py b/ontoScorer/ontology.py
index 4415d78..f9403cb 100644
--- a/ontoScorer/ontology.py
+++ b/ontoScorer/ontology.py
@@ -7,4 +7,29 @@
 # Detailed module description, if needed
 #==============================================================================
 
-# TODO
+from rdflib import Graph, OWL
+from rdflib.namespace import split_uri
+
+class Ontology:
+    def __init__(self, ontology_path):
+        self.path = ontology_path
+        self.graph = self.load_ontology(ontology_path)
+        self.classes = self.get_classes()
+
+    def load_ontology(self, path):
+        g = Graph()
+        g.parse(path, format="ttl")
+        return g
+
+    def get_classes(self):
+        classes = set()
+        triplets_count = 0
+        for s, p, o in self.graph.triples((None, None, None)):
+            triplets_count += 1
+            if o == OWL.Class:
+                _, class_name = split_uri(s)
+                classes.add(class_name)
+        return classes
+
+    def compare_to(self, other_ontology):
+        return self.classes, other_ontology.classes
\ No newline at end of file
diff --git a/ontoScorer/report.py b/ontoScorer/report.py
index 4415d78..30f7659 100644
--- a/ontoScorer/report.py
+++ b/ontoScorer/report.py
@@ -7,4 +7,36 @@
 # Detailed module description, if needed
 #==============================================================================
 
-# TODO
+class Report:
+    def __init__(self, reference_ontology, generated_ontology, comparison_result, metrics):
+        self.reference_ontology = reference_ontology
+        self.generated_ontology = generated_ontology
+        self.comparison_result = comparison_result
+        self.metrics = metrics
+
+    def generate(self):
+        report_str = "=== Ontology Evaluation Report ===\n"
+
+        report_str += f"\nReference Ontology: {self.reference_ontology.path}"
+        report_str += f"\nNumber of classes in Reference Ontology: {len(self.reference_ontology.classes)}"
+
+        report_str += f"\n\nGenerated Ontology: {self.generated_ontology.path}"
+        report_str += f"\nNumber of classes in Generated Ontology: {len(self.generated_ontology.classes)}"
+
+        # Comparison of the number of classes
+        report_str += "\n\nComparison Result: "
+        if len(self.reference_ontology.classes) > len(self.generated_ontology.classes):
+            report_str += "The generated ontology has fewer classes than the reference ontology."
+        elif len(self.reference_ontology.classes) < len(self.generated_ontology.classes):
+            report_str += "The generated ontology has more classes than the reference ontology."
+        else:
+            report_str += "The generated ontology and the reference ontology have the same number of classes."
+
+        report_str += "\n\nEvaluation Metrics:"
+        report_str += f"\nPrecision: {self.metrics.precision}"
+        report_str += f"\nRecall: {self.metrics.recall}"
+        report_str += f"\nF1 Score: {self.metrics.f1}"
+
+        return report_str
+
+
diff --git a/ontoScorer/scorer.py b/ontoScorer/scorer.py
index 4415d78..2ed8085 100644
--- a/ontoScorer/scorer.py
+++ b/ontoScorer/scorer.py
@@ -7,4 +7,28 @@
 # Detailed module description, if needed
 #==============================================================================
 
-# TODO
+from ontology import Ontology
+from report import Report
+from metrics import Metrics
+
+class OntoScorer:
+    def __init__(self, reference_ontology_path, generated_ontology_path):
+        self.reference_ontology = Ontology(reference_ontology_path)
+        self.generated_ontology = Ontology(generated_ontology_path)
+        self.metrics = Metrics()
+
+    def compare(self):
+        self.comparison_result = self.reference_ontology.compare_to(self.generated_ontology)
+        self.metrics.calculate(*self.comparison_result)
+
+    def generate_report(self):
+        report = Report(self.reference_ontology,
+                        self.generated_ontology,
+                        self.comparison_result, 
+                        self.metrics)
+        print(report.generate())
+
+
+    # def generate_report(self, report_path):
+    #     report = Report(self.comparison_result, self.metrics)
+    #     report.generate(report_path)
diff --git a/tests/__init__.py b/tests/__init__.py
index 4415d78..e69de29 100644
--- a/tests/__init__.py
+++ b/tests/__init__.py
@@ -1,10 +0,0 @@
-#!/usr/bin/python3.10
-# -*-coding:Utf-8 -*
-
-#==============================================================================
-# ontoScorer: [brief description of the module]
-#------------------------------------------------------------------------------
-# Detailed module description, if needed
-#==============================================================================
-
-# TODO
-- 
GitLab