BY FROM SOME (Goat Milk)

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 Node ID_999 lokale Graph vor dem Inferencing

  • g2: Dieser Graph nach dem Inferencing, also nach der vollständigen Ausmaterialisierung durch owlrl.

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> .