BY FROM SOME (Goat Milk)#
Diese Seite: Detail-Diskussion des Kernkonstruktes von GenDifS “unter dem Mikroskop”. Wir formalisieren die Aussage:
Ziegenmilch ist eine Milch, die von einer Ziege kommt.
Knoten im Focus: SOME Goat
mit der id ID_999
.
Ausgangspunkt ist eine freemind oder freeplane-Mindmap, die so aussieht:
(Der Fettdruck ist nicht relevant und dient ausschließlich der besseren Lesbarkeit.)
Diese Mindmap kann in freemind einfach erzeugt werden: Den folgenden Text mit CTRL-C kopieren, in freeplane mit CTRL-V einfügen, fertig!
goat-milk-BY-FROM-SOME
TAXONOMY by_some
Milk
BY has_source FROME Animal
Goat Milk
SOME Goat
Cow Milk
SOME Cow
Um für die nachfolgende Diskussion einen eindeutigen Ausgangspunkt zu haben, erzeugen wir diese Mindmap allerdings programmatisch. Um die Code-Beispiele besser lesbar zu halten und auf definierte IDs zugreifen zu können, haben wir fast alle von freeplane automatisch generierten langen IDs manuell durch kurze IDs ersetzt.
In dem vorliegenden Beispiel interessiert uns vor allem der Knoten SOME Goat
mit der id ID_999
, weiter unten dann auch der Knoten mit ID_003
.
xml_by_some = """<map version="freeplane 1.7.0">
<!--To view this file, download free mind mapping software Freeplane from http://freeplane.sourceforge.net -->
<node TEXT="goat milk by some" ID="ID_0" STYLE="oval" FOLDED="false">
<node TEXT="TAXONOMY by_some" ID="ID_001">
<node TEXT="Milk" ID="ID_002">
<font BOLD="true"/>
<node TEXT="BY has_source FROM Animal" ID="ID_003">
<node TEXT="Goat Milk" ID="ID_004" >
<font BOLD="true"/> <!-- layout only, no semantics -->
<node TEXT="SOME Goat" ID="ID_999" /> <!-- this is our FOCUS -->
</node>
<node TEXT="Cow Milk" ID="ID_1466284350">
<font BOLD="true"/>
<node TEXT="SOME Cow" ID="ID_396346079"/>
</node>
</node>
</node>
</node>
</node>
</map>
"""
with open("goat-milk-BY-FROM-SOME.mm", "w") as goatmilkfile_by_some:
goatmilkfile_by_some.write(xml_by_some)
import os
import glob
print(f"""Mindmaps in directory {os.getcwd()}:\n {glob.glob('*.mm')}""" )
Mindmaps in directory /media/sf_abc123/l/LA_2024_ws/gendifs07/md:
['goat-milk-BY-FROM-SOME.mm', 'milk1.mm', 'white-horse-SUP.mm', 'semantics_bysome.png.mm', 'texttree.mm', 'semantics_bysome.mm', 'goat-milk-ISA.mm', 'semantics_isa.mm', 'goat-milk-ISA-SOME.mm']
Standard-Prozess#
from gd07 import GenDifS
Mindmap einlesen:
m = GenDifS("goat-milk-BY-FROM-SOME.mm", verb=2)
Sichtbar machen, was wir eingelesen haben:
m.describe_mindmap()
self.mindmap_topnode.get('TEXT')='goat milk by some'
len(self.mindmap_xml.getroot().xpath('.//node'))=8 nodes
Übersetzen der Mindmap in verschiedene Sprachen:
m.compile(language_list_list=['RDFStest', 'OWLtest', 'OWL', 'RDFS']) # alles außer SKOS; SKOS siehe unten
Welche Taxonomien haben wir unserer Mindmap?
m.taxonomies_by_name.keys()
dict_keys(['by_some'])
Taxonomy by_some#
Wir haben in unserer Mindmap nur eine einzige Taxonomie, hier mit dem Namen by_some
. Wir weisen diese der gleichnamigen Variablen zu.
by_some = m.taxonomies_by_name["by_some"]
Uns interessiert der Knoten ID_999
ID_999 = by_some.dict_of_all_gdn['ID_999']
type(ID_999)
gd07.gdn_differentia
Ein Knoten vom Typ gd07.gdn_differentia
hat ein Dictionary molecule_dict
, das für jede Sprache den erzeugten ttl-Code als String enthält:
ID_999.molecule_dict
{'DE': '# ID_999 DE\n:Goat_Milk :explanation "*:Goat_Milk* ist eine Subklasse der Klasse *:Milk* ." . \n:Goat :explanation "*Goat* ist eine Subklasse der Klasse *Animal* ." . \n:Milk :explanation "Ein *:Milk*, das für das Attribut *has_source* einen Wert aus *Goat* hat, ist ein *{ species.c(reverse = True) }*." . ',
'RDFS': '# ID_999 RDFS\n:Goat_Milk a owl:Class;\n rdfs:subClassOf :Milk .\n:Goat rdfs:subClassOf :Animal .',
'OWL': '# ID_999 OWL\n:has_source rdf:type owl:ObjectProperty .\n:BY_SOME_ID_999_restriction a owl:class ;\n a owl:Restriction ;\n rdfs:label "BY_ex:has_source_FROM_ex:Animal_SOME_ex:Goat" ;\n owl:onProperty :has_source ;\n owl:someValuesFrom :Goat .\n:BY_SOME_ID_999_intersection a owl:class ;\n rdfs:label "(BY_ex:has_source_FROM_ex:Animal_SOME_ex:Goat)_INTERSECT_ex:Milk" ;\n rdfs:subClassOf :Goat_Milk ;\n owl:intersectionOf (:BY_SOME_ID_999_restriction :Milk ) .',
'OWLtest': '# ID_999 OWLtest\nex:Goat_Milk_ID_999 a :Goat_Milk .\nex:Milk_ID_999 a :Milk ;\n :has_source ex:Goat_ID_999 ;\n gendifs:classify_similar ex:Goat_Milk_ID_999 .\nex:Goat_ID_999 a :Goat .',
'SKOS': '# ID_999 SKOS\ncpt:Milk a skos:Concept .\ncpt:Goat_Milk a skos:Concept ;\n skos:broader cpt:Milk .\ncpt:Animal a skos:Concept .\ncpt:Goat a skos:Concept ;\n skos:broader cpt:Animal .\ncpt:has_source a rdfs:Property ;\n rdfs:subPropertyOf skos:related .'}
Diese Code-Snippets werden erzeugt in der Klasse ID_999.molecule_per_language
:
type(ID_999.molecule_per_language)
gd07.GenDifS_molecule_per_language
Die Klasse molecule_per_language
enthält alle Detailinformationen aus der Code-Generierung.
entity_context
repräsentiert alle Informationen, die zur Codegenerierung verwendet wurden:
ID_999.molecule_per_language.entity_context
{'id': 'ID_999',
'codeclass': 'BY_SOME',
'genus': Entity(self.source_gdn.id='ID_002', self.text='Milk'),
'by': Entity(self.source_gdn.id='ID_003', self.text='has_source'),
'frm': Entity(self.source_gdn.id='ID_003', self.text='Animal'),
'some': Entity(self.source_gdn.id='ID_999', self.text='Goat'),
'species': Entity(self.source_gdn.id='ID_004', self.text='Goat_Milk')}
Die Klasse inspect_inferencing
gibt Zugriff auf die Ergebnisse des Selbsttests, insbesondere test_results
:
type( ID_999.molecule_per_language.inspect_inferencing )
gd07.Test_classify_similar
ID_999.molecule_per_language.inspect_inferencing.test_results
{(b'urn:ex#Milk_ID_999', b'urn:ex#Goat_Milk_ID_999'): {'cat1 not empty': True,
'cat2 not empty': True,
'disjoint before': True,
'subset after': True,
'ok': True}}
In dieser Klasse sind 2 Graphen enthalten:
g1
: Der aus der NodeID_999
lokale Graph vor dem Inferencingg2
: Dieser Graph nach dem Inferencing, also nach der vollständigen Ausmaterialisierung durchowlrl
.
print(g2_ttl)
würde sehr viel uninteressanten Code zeigen. Praktischerweise gruppiert die Serialisierungsfnktion von rdflib die Tripel zu sinnvollen Records (Molekülen, im ttl-Text: Absätzen). Wir definieren uns eine kleine Hilfsfunktion focus()
.
def focus(focus_curie_list, ttl):
return "\n\n".join( [ paragraph for paragraph in ttl.split("\n\n") \
if any( [ focus_curie in paragraph for focus_curie in focus_curie_list ] ) ] )
Vor dem Inferencing: Alle Absätze aus g1
, in denen der String :Milk_ID_999
vorkommt:
g1_ttl = ID_999.molecule_per_language.inspect_inferencing.g1.serialize()
print( focus( [":Milk_ID_999"], g1_ttl) )
ex:Milk_ID_999 a :Milk ;
:has_source ex:Goat_ID_999 ;
gendifs:classify_similar ex:Goat_Milk_ID_999 .
Nach dem Inferencing: Alle Absätze aus g2
, in denen der String ex:Milk_ID_999
vorkommt:
g2_ttl = ID_999.molecule_per_language.inspect_inferencing.g2.serialize()
print( focus( ["ex:Milk_ID_999"], g2_ttl ) )
ex:Milk_ID_999 a owl:Thing,
:BY_SOME_ID_999_intersection,
:BY_SOME_ID_999_restriction,
:Goat_Milk,
:Milk ;
owl:sameAs ex:Milk_ID_999 ;
:has_source ex:Goat_ID_999 ;
gendifs:classify_similar ex:Goat_Milk_ID_999 .
Wir sehen, dass ex:Milk_ID_999
nun auch eine Instanz von :Goat_Milk
ist: Voila, das Top-Down-Inferencing hat funktioniert!
QED
SKOS#
from gd07 import GenDifS
m2 = GenDifS("goat-milk-BY-FROM-SOME.mm", verb=2)
m2.compile(language_list_list=['SKOS'])
print(m2.taxonomies_by_name["by_some"].rdf_graphs["SKOS"].serialize())
@prefix cpt: <http://example.net/namespace/cpt#> .
@prefix owl: <http://www.w3.org/2002/07/owl#> .
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
@prefix skos: <http://www.w3.org/2004/02/skos/core#> .
cpt:BY_ID_003_intersection a skos:Collection ;
rdfs:label "cpt:Milk BY cpt:has_source FROM cpt:Animal" ;
skos:member cpt:Cow_Milk,
cpt:Goat_Milk .
cpt:Cow a skos:Concept ;
skos:broader cpt:Animal .
cpt:Goat a skos:Concept ;
skos:broader cpt:Animal .
cpt:has_source a rdfs:Property ;
rdfs:subPropertyOf skos:related .
cpt:Cow_Milk a skos:Concept ;
skos:broader cpt:Milk .
cpt:Goat_Milk a skos:Concept ;
skos:broader cpt:Milk .
cpt:by_some a skos:ConceptScheme .
cpt:Animal a skos:Concept .
cpt:Milk a skos:Concept ;
skos:inScheme cpt:by_some .
[] owl:imports <http://www.w3.org/TR/skos-reference/skos-owl1-dl.rdf> .