When a subject-matter-expert (SME) describes their data domain they use English language. In response we give them visually beautiful, but often undecipherable, diagrams. Here we propose an alternative: a ‘word-model’ that describes the model in structured English without loss of accuracy or completeness.
Creating an ontological model invariably involves a subject-matter-expert (SME) who has an in-depth knowledge of the domain to be modelled working together with a data modeler or ontologist who will translate the domain into an ontological model.
When a subject-matter-expert (SME) is in discussion with a data modeler, they will be describing their information using English language:
“I have customers who are assigned to regions, and they create orders with a salesperson who prepares the order-details and assigns a shipper that operates in that region”
In response a data modeler will offer the subject-matter-expert (SME) an E-R diagram or an ontology graph!
Figure 1: Geek Model Diagrams
No wonder we are regarded as geeks! Although visually appealing, they are difficult for an untrained user to verify the model that the diagram is describing.
Instead we could document the model in a more easily consumed way with a ‘word-model’. This captures the same details of the model that are present in the various diagrams, but uses structured English and careful formatting as shown below.
aCustomer
- places anOrder
- made by anEmployee
- who reports to anotherEmployee
- and who operates in aTerritory
- and contains anOrderDetail
- refers to aProduct
- which is supplied by aSupplier
- and which categorized as aCategory
- and is shipped by aShipper
- and is assigned to aRegion
- which has aTerritory
- and belongs to aRegion
The basic principle is that we start at any entity, in this case ‘Customer’ and traverse the edges of the graph that describe that entity. At each new node we indent. Each line is a combination of the predicate and range class. No rules regarding order in which we visit the nodes and edges. No rules regarding depth. The only rule should be that, if we want a complete word-model, the description traverses all edges in one direction or the other.
These word-models are useful in the model design phase, as they are easy to document using any editor. Since the word-model is in ‘plain English’, it is easy for a SME to verify the accuracy of the model, and mark up with comments and edits. However word-models are also easy to generate from an RDF/OWL model.
Enhancements to Word-Model
We can refine the contents of the word-model as we develop the model with the SME. We can also enhance the readability by decorating the word-model text with the following fonts:
Word-Model Legend
Italics indicate an instance of a class, a thing
Bold indicates a class
Underline is a predicate or property that relates instances of classes
BoldItalic is used for cardinality expressions
Level 1a: Add the categorization of entities
Rather than using an example of an entity, we can qualify with the class to which the sample entity belongs.
aCustomer, a Customer
- places anOrder, an Order
- made by anEmployee, an Employee
- who reports to anotherEmployee, an Employee
- and who operates in aTerritory, a Territory
- and contains anOrderDetail, an OrderDetail
- and refers to aProduct, a Product
- which is supplied by aSupplier, a Supplier
- and which is categorized as aCategory, a Category
- and is shipped by aShipper, a Shipper
- and is assigned to aRegion, a Region
- which has aTerritory, a Territory
- and belongs to aRegion, a Region
Level 1b: Add cardinality of predicates
We can also add the cardinality as a modifier between the predicate and the entity:
aCustomer
- who places zero, one or more orders
- each made by one anEmployee
- who reports to zero or one anotherEmployee
- and who operates in one or more aTerritorys
- and each contains one or more anOrderDetails
- which refers to one aProduct
- which is supplied by one aSupplier
- and which is categorized as one aCategory
- and is shipped by one aShipper
- and is assigned to one aRegion
- which has one or more aTerritorys
- and belongs to one aRegion
Level 2: Add categorization and cardinality
Of course we can combine these extensions into a single word-modol as shown below.
aCustomer, a Customer
- who places zero, one or more orders, each an Order
- each made by one anEmployee, an Employee
- who reports to zero or one anotherEmployee, an Employee
- and who operates in one or more aTerritorys, each a Territory
- and each contains one or more anOrderDetails, each an OrderDetail
- which refers to one aProduct, a Product
- which is supplied by one aSupplier, a Supplier
- and which is categorized as one aCategory, a Category
- and is shipped by one aShipper, a Shipper
- and is assigned to one aRegion, a Region
- which has one or more aTerritorys, each a Territory
- and belongs to one aRegion, a Region
Despite the completeness of what is being described by this word-model, it is still easy to read by SMEs.
Auto-generation of Word-Model
Once the word-model has been formally documented in RDF/OWL, we can still use a word-model to document the RDF/OWL by auto-generating a word-model from the underlying RDF/OWL ontology as shown below.
Figure 2: Word-Model
This was generated using a SPIN magic-property as follows:
select ?modelDefinition { (model:Customer 4 false) :modelDefinition ?modelDefinition . }
This auto-generation can go further by including the datatype properties associated with each entity as shown below:
Figure 3: Word-Model including datatype properties
This was generated using a SPIN magic-property as follows:
select ?modelDefinition { (model:Customer 4 true) :modelDefinition ?modelDefinition . }
Appendix
SPIN Magic Properties:
The following SPIN properties were defined for auto generation of the word-model in HTML format:
classProperties
SELECT ?classProperties WHERE { {SELECT ?arg1 ( IF(?arg2, CONCAT("(",?properties,")"),"") as ?classProperties) WHERE { SELECT ?arg1 ((GROUP_CONCAT(CONCAT("<i>", ?dataPropertyLabel, "</i>"); SEPARATOR=', ')) AS ?properties) WHERE { # BIND (model:Product AS ?arg1) . ?arg1 a ?class . FILTER (?class IN (rdfs:Class, owl:Class)) . ?arg1 rdfs:label ?classLabel . ?dataProperty a owl:DatatypeProperty . ?dataProperty rdfs:domain ?arg1 . ?dataProperty rdfs:label ?dataPropertyLabel . } GROUP BY ?arg1 } } }
classDefinition
SELECT ?classDefinition ?priorPath WHERE { { SELECT ?arg1 ?arg2 ((GROUP_CONCAT( ?definition; SEPARATOR='<br/>and that ')) AS ?classDefinition) ((GROUP_CONCAT( ?pastPath; SEPARATOR='\t')) AS ?priorPath) WHERE { ?arg1 a ?class . FILTER( ?class in (rdfs:Class, owl:Class )) ?arg1 rdfs:label ?classLabel . ?objectProperty a owl:ObjectProperty . { ?objectProperty rdfs:domain ?arg1 . ?objectProperty rdfs:label ?objectPropertyLabel . ?objectProperty rdfs:range ?nextClass . ?nextClass rdfs:label ?nextClassLabel . BIND(?objectProperty as ?property) }UNION{ ?objectProperty owl:inverseOf ?inverseObjectProperty . ?objectProperty rdfs:domain ?nextClass. ?inverseObjectProperty rdfs:label ?objectPropertyLabel . ?objectProperty rdfs:range ?arg1 . ?nextClass rdfs:label ?nextClassLabel . BIND(?inverseObjectProperty as ?property) }UNION{ ?inverseObjectProperty owl:inverseOf ?objectProperty . ?objectProperty rdfs:domain ?nextClass. ?inverseObjectProperty rdfs:label ?objectPropertyLabel . ?objectProperty rdfs:range ?arg1 . ?nextClass rdfs:label ?nextClassLabel . BIND(?inverseObjectProperty as ?property) } #Stop from going too deep BIND(?arg2 -1 as ?span) FILTER(?span>0). ?nextClass a ?nextClassClass. FILTER( ?nextClassClass in (rdfs:Class, owl:Class )) #, odata4sparql:Operation)) . #Do not process an already processed arc (objectProperty) BIND(CONCAT(?arg4,"\t",?objectPropertyLabel) as ?forwardPath) FILTER( !CONTAINS(?arg4, ?objectPropertyLabel )) (?nextClass ?span ?arg3 ?forwardPath ) :classDefinition (?nextClassDefinition ?nextPath). #Do not include if arc (objectProperty) appears already FILTER( !CONTAINS(?nextPath, ?objectPropertyLabel )) BIND(CONCAT( ?objectPropertyLabel, IF(?nextPath="","",CONCAT("\t",?nextPath))) as ?pastPath) (?nextClass ?arg3) :classProperties ?nextClassProperties . BIND (CONCAT("<u>",?objectPropertyLabel , "</u> <b>", ?nextClassLabel, "</b>", ?nextClassProperties, IF ((?nextClassDefinition!=""), CONCAT("<br/><blockquote>that ", ?nextClassDefinition, "</blockquote>"), "") ) as ?definition) } GROUP BY ?arg1 ?arg2 } . }
modelDefintion
SELECT ?modelDefinition WHERE { { SELECT ?arg1 ?arg2 ?arg3 ((CONCAT("<b>", ?classLabel, "</b>", ?nextClassProperties, "<blockquote>that ", ?classDefinition, "</blockquote>")) AS ?modelDefinition) WHERE { # BIND (model:Order AS ?arg1) . BIND (4 AS ?arg2) . BIND (false AS ?arg3) . ( ?arg1 ?arg2 ?arg3 "") :classDefinition (?classDefinition "") . ( ?arg1 ?arg3 ) :classProperties ?nextClassProperties . ?arg1 rdfs:label ?classLabel . } } . }
Usage
The following will return the HTML description of the model, starting with model:Customer, stopping at a depth of 4 in any direction, and not including the datatypeproperty definition.
select ?modelDefinition { (model:Customer 4 false) :modelDefinition ?modelDefinition . }