Created
August 12, 2019 12:24
-
-
Save christopheralcock/ec235d8e361c25797b77fb4281b04f4f to your computer and use it in GitHub Desktop.
ontology-authoring-patterns.txt
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| The following is a set of rules/guidance about ontology authoring patterns that I shared with my colleagues as part of my handover from working in Parliament, published here for their reference | |
| Booleans suck. Most of the time when you see a Boolean, what you’re really dealing with is a subclass | |
| We classify by use, not by explicit statements, wherever possible. This helps Wojciech write nicer code when orchestrating | |
| We use rdfs:isDefinedBy so that the schema query - api.parliament.uk/query/schema has something to work with | |
| We add sentence-case rdfs:label to our ontology for readability on the html browser | |
| The build process for the ontology repo has tests, such as checking that object properties and datatype properties both have domains and ranges | |
| Domains and ranges should be defined as narrowly as possible, aiding usage-based classification | |
| All object properties have inverse properties, to make SPARQL queries as easy to write and as directional as possible | |
| We fundamentally optimise for ease of access to the data, via easy-as-possible SPARQL and speed of return of data. For this increase in read speed we sacrifice write speed and work harder on structure and explicit ontology | |
| If it’s not obvious (subjective, I know) what something does, add an rdfs:comment | |
| When naming object properties, default to [domain]Has[Range] | |
| When more than one relationship can exist between a domain and a range, you cannot use [domain]Has[Range]. Consider whether the domain or range is actually a sub property of what you’re currently going with. If all else fails, breaking with [domain]Has[Range] as a pattern is acceptable, replacing “has” with something more specific, or augementing has with something that clarifies use - parliamentPeriodHasImmediatelyPreviousParliamentPeriod | |
| Whilst on some level long names like parliamentPeriodHasImmediatelyPreviousParliamentPeriod make writing SPARQL harder, consistency and the Path Of Least Surprise are more important than terseness of human-reading prettiness | |
| If you get the naming wrong it’s not the end the world, the shape and utility is most important | |
| Where possible, use subclasses rather than Classes with “type” in their name. Engender types as ontology-level classes where possible, making the ontology as descriptive of the work of parliament as possible. Eg instead of FormalBody having a FormalBodyType, and then you having to go to the instance data to find out what types of formal bodies there are, it can be expressed in the ontology – FormalBody has a subclass SelectCommittee | |
| Owl Restrictions can be used to take Classes with “type” Classes of them and make classes of them | |
| It is paramount that everything Michael et al’s work can express, ours can express, and “better” | |
| When orchestrating from an external source, we need the external ID to manage orchestration. If a Member has a MNIS id, they are a MnisMember, and also a MnisThing. Follow this pattern for externals | |
| For the purpose of capitalisation, treat initalisms as words. MnisMember, not MNISMember. mnisMemberHasMembership not mNISMemberHasMembership | |
| Even if an ID is numerical, it is a string, not an integer. If there is no value in performing mathematics on something made of numbers (as in the case of a count on a petition or whatever), it is not an integer. | |
| Make properties functional when we are certain they are. Do not make them functional if we are not sure that they are functional. | |
| Do not use owl:sameAs, we like to keep that for identifying bugs | |
| Be careful with vague terms – was asked to add a barely modelled “Publication” class recently. “Publication” is very broad and could easily be used again in a parliamentary context. Specified the Publication as a ProcedureStepPublication to avoid name clashing. Maybe if other Publications are added in future, they can all be subclasses of a Publication superclass | |
| Put end dates on Past subclasses of the class – eg pastIncumbencyHasEndDate. Expect that an end date will not be added until the thing has happened | |
| If in doubt, and you can wait a day or two, email me and I will try and answer as well as explain my answer |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment