From a Knowledge Graph to B-UML

BESSER also enables the definition of a Structural model from a Knowledge Graph (KG). The KG to be imported can be either a tripple store in .ttl, an RDF file in .rdf, or a property graph exported in .json. For this we use OpenAI’s GPT4 and you must have an OpenAI token to implement this BESSER functionality.

The following example KG represents the relationship between a company, its employees and their acquanitances.

 1@prefix ex: <http://example.org/> .
 2@prefix foaf: <http://xmlns.com/foaf/0.1/> .
 3@prefix dbo: <http://dbpedia.org/ontology/> .
 4@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
 5
 6# Entities
 7ex:Alice a foaf:Person ;
 8    foaf:name "Alice" ;
 9    foaf:age "29"^^xsd:integer ;
10    foaf:knows ex:Bob ;
11    dbo:worksAt ex:CompanyX .
12
13ex:Bob a foaf:Person ;
14    foaf:name "Bob" ;
15    foaf:age "34"^^xsd:integer ;
16    dbo:worksAt ex:CompanyX ;
17    foaf:knows ex:Charlie .
18
19ex:Charlie a foaf:Person ;
20    foaf:name "Charlie" ;
21    foaf:age "41"^^xsd:integer .
22
23# Organization
24ex:CompanyX a dbo:Organization ;
25    foaf:name "Company X" ;
26    dbo:industry "Software" ;
27    dbo:location ex:Luxembourg .
28
29# Location
30ex:Luxembourg a dbo:Place ;
31    foaf:name "Luxembourg" ;
32    dbo:countryCode "LU" .

Warning

Please make sure your KG is below 20 MB in size and is of one the following formats: [‘ttl’, ‘json’, ‘rdf’]

To transform this KG into a Structural model you can use the following code.

from besser.BUML.metamodel.structural import DomainModel
from besser.utilities import kg_to_buml

structural_model: DomainModel = kg_to_buml(kg_path="kg_test.ttl", openai_token="****")

The function kg_to_buml() has as parameters the KG path and the OpenAI token, and returns a DomainModel object.

Note

By default, the gpt-4o model is used. If you wish to use another version of the GPT model, you can specify it using the openai_model parameter in the kg_to_buml() function. More details of the function in the API documentation

Additionally, one could use besser.utilities.buml_code_builder.domain_model_to_code() to automatically generate the source code from the obtained structural model. You could reuse that code to modify, enhance, and recreate your structural model. The structural model source code generated by the transformation from the kg.test.ttl model is as follows.

 1####################
 2# STRUCTURAL MODEL #
 3####################
 4
 5from besser.BUML.metamodel.structural import (
 6    Class, Property, Method, Parameter,
 7    BinaryAssociation, Generalization, DomainModel,
 8    Enumeration, EnumerationLiteral, Multiplicity,
 9    StringType, IntegerType, FloatType, BooleanType,
10    TimeType, DateType, DateTimeType, TimeDeltaType,
11    AnyType, Constraint, AssociationClass, Metadata
12)
13
14# Classes
15Person = Class(name="Person")
16Organization = Class(name="Organization")
17Place = Class(name="Place")
18
19# Person class attributes and methods
20Person_name: Property = Property(name="name", type=StringType)
21Person_age: Property = Property(name="age", type=IntegerType)
22Person_m_knows: Method = Method(name="knows", parameters={Parameter(name='person', type=Person)})
23Person.attributes={Person_age, Person_name}
24Person.methods={Person_m_knows}
25
26# Organization class attributes and methods
27Organization_name: Property = Property(name="name", type=StringType)
28Organization_industry: Property = Property(name="industry", type=StringType)
29Organization.attributes={Organization_industry, Organization_name}
30
31# Place class attributes and methods
32Place_name: Property = Property(name="name", type=StringType)
33Place_countryCode: Property = Property(name="countryCode", type=StringType)
34Place.attributes={Place_countryCode, Place_name}
35
36# Relationships
37worksAt: BinaryAssociation = BinaryAssociation(
38    name="worksAt",
39    ends={
40        Property(name="person", type=Person, multiplicity=Multiplicity(1, 1)),
41        Property(name="worksAt", type=Organization, multiplicity=Multiplicity(1, 1))
42    }
43)
44location: BinaryAssociation = BinaryAssociation(
45    name="location",
46    ends={
47        Property(name="organization", type=Organization, multiplicity=Multiplicity(1, 1)),
48        Property(name="location", type=Place, multiplicity=Multiplicity(1, 1))
49    }
50)
51
52# Domain Model
53domain_model = DomainModel(
54    name="KG_Imported_Diagram",
55    types={Person, Organization, Place},
56    associations={worksAt, location},
57    generalizations={}
58)

From a KG to PlantUML

Similarly, it is also possible to obtain the PlantUML code from a model in a KG, as follows.

from besser.utilities import kg_to_plantuml

plantUML_model: str = kg_to_plantuml(kg_path="kg_test.ttl", openai_token="****")
print(plantUML_model)

The result of this transformation is a string with the code specified in the PlantUML notation:

@startuml

    class Person {
        name : str
        age : int
        knows(person : Person)
        worksAt(company : Organization)
    }

    class Organization {
        name : str
        industry : str
        location : Place
    }

    class Place {
        name : str
        countryCode : str
    }

    Person "0..*" -- "0..*" Person : knows
    Person "0..*" -- "0..1" Organization : worksAt
    Organization "0..1" -- "0..1" Place : location

    @enduml