From 7b36b97230e1c714bf77b21ef133228267971f5e Mon Sep 17 00:00:00 2001 From: Jochen Christ Date: Wed, 3 Jun 2026 09:59:52 +0200 Subject: [PATCH 1/7] Add custom_properties for carrying data not covered by the spec Importing an ontology from an external format such as OWL/RDF loses any data that the core OSI spec does not model (IRIs, rdfs:label, owl:equivalentClass, annotations, provenance, ...), because every ontology object is locked down with additionalProperties: false. Add an open `custom_properties` object to the ontology root, concepts, relationships, and roles. Keys are free-form and values may be any JSON, so tools can preserve foreign data and round-trip it. CURIEs like `owl:equivalentClass` are recommended for semantic-web sources. The rest of each object keeps additionalProperties: false, so custom_properties is the single, explicit escape hatch. Includes a FOAF/OWL import example and documents the field in the spec. Co-Authored-By: Claude Opus 4.8 (1M context) --- examples/foaf_owl_import.yaml | 37 ++++++++++++++++++++++++++++++++++ ontology/ontology.json | 17 ++++++++++++++++ ontology/ontology.md | 38 +++++++++++++++++++++++++++++++++++ 3 files changed, 92 insertions(+) create mode 100644 examples/foaf_owl_import.yaml diff --git a/examples/foaf_owl_import.yaml b/examples/foaf_owl_import.yaml new file mode 100644 index 00000000..831469e3 --- /dev/null +++ b/examples/foaf_owl_import.yaml @@ -0,0 +1,37 @@ +version: 0.2.0.dev0 +name: foaf +description: > + Small ontology imported from the FOAF (Friend of a Friend) OWL vocabulary, + demonstrating how custom_properties preserves OWL/RDF data (IRIs, labels, and + axioms) that the core OSI spec does not model, so the source can be round-tripped. +custom_properties: + owl:Ontology: "http://xmlns.com/foaf/0.1/" + dc:title: "Friend of a Friend (FOAF) vocabulary" +ontology: + - concept: + name: Person + type: EntityType + custom_properties: + iri: "http://xmlns.com/foaf/0.1/Person" + rdfs:label: "Person" + rdfs:comment: "A person." + owl:equivalentClass: "https://schema.org/Person" + relationships: + - name: name + roles: + - concept: String + verbalizes: [ "{Person} has name {String}" ] + multiplicity: ManyToOne + custom_properties: + iri: "http://xmlns.com/foaf/0.1/name" + rdfs:label: "name" + - name: knows + roles: + - concept: Person + name: acquaintance + custom_properties: + rdfs:range: "http://xmlns.com/foaf/0.1/Person" + verbalizes: [ "{Person} knows {Person:acquaintance}" ] + custom_properties: + iri: "http://xmlns.com/foaf/0.1/knows" + owl:inverseOf: "http://xmlns.com/foaf/0.1/knows" diff --git a/ontology/ontology.json b/ontology/ontology.json index 473f69b3..c56c0f70 100644 --- a/ontology/ontology.json +++ b/ontology/ontology.json @@ -35,11 +35,19 @@ "items": { "$ref": "#/$defs/OntologyMap" } + }, + "custom_properties": { + "$ref": "#/$defs/CustomProperties" } }, "required": ["version", "name", "ontology"], "additionalProperties": false, "$defs": { + "CustomProperties": { + "type": "object", + "description": "Open set of custom properties for carrying data that is not covered by the core ontology spec, for example when importing an ontology from an external format such as OWL/RDF. Keys are free-form; CURIEs such as 'owl:equivalentClass' or 'rdfs:label' are recommended when round-tripping semantic-web sources. Values may be any JSON.", + "additionalProperties": true + }, "OntologyComponent": { "type": "object", "description": "Ontology component that defines a single concept and any relationships that are keyed primarily by that concept", @@ -101,6 +109,9 @@ "type": "string" }, "description": "Natural language expressions that verbalize this relationship" + }, + "custom_properties": { + "$ref": "#/$defs/CustomProperties" } }, "required": ["name", "verbalizes"], @@ -148,6 +159,9 @@ "$ref": "#/$defs/Expression" }, "description": "Expressions that constrain the population of this concept" + }, + "custom_properties": { + "$ref": "#/$defs/CustomProperties" } }, "required": ["name", "type"], @@ -216,6 +230,9 @@ "name": { "type": "string", "description": "Optional name of this role, used when the same concept plays multiple roles in the same relationship" + }, + "custom_properties": { + "$ref": "#/$defs/CustomProperties" } }, "required": ["concept"], diff --git a/ontology/ontology.md b/ontology/ontology.md index 921e061d..ff663a3c 100644 --- a/ontology/ontology.md +++ b/ontology/ontology.md @@ -69,6 +69,7 @@ hierarchically, grouping each relationship under the concept that plays its firs | `description` | string | No | Human-readable description | | `ai_context` | string/object | No | Additional context for AI tools | | `ontology` | list | Yes | Concepts and relationships they group that form this ontology | +| `custom_properties` | object | No | Open set of custom properties not covered by this spec (see [Custom properties](#custom-properties)) | Each component of an ontology defines a concept and a list of relationships where that concept plays the first role: @@ -95,6 +96,7 @@ Concepts have the following schema: | `derived_by` | list | No | Expressions that derive this concept's population | | `identify_by` | list | No | Names of relationships that uniquely reference objects of this concept | | `requires` | list | No | Expressions that constrain this concept's population | +| `custom_properties` | object | No | Open set of custom properties not covered by this spec (see [Custom properties](#custom-properties)) | Each concept is either an entity type or a value type. @@ -141,6 +143,7 @@ Each relationship that is declared under a concept conforms to the following sch | `derived_by` | list | No | Expressions that derive links of this relationship | | `requires` | list | No | Expressions that constrain this relationship's population | | `verbalizes` | list | Yes | Patterns describing how to verbalize links | +| `custom_properties` | object | No | Open set of custom properties not covered by this spec (see [Custom properties](#custom-properties)) | Each relationship is uniquely identified by a prepending its declared name with that of the containing concept. For instance, in: @@ -185,6 +188,7 @@ using this schema: |-------|------|----------|-------------| | `concept` | string | Yes | Name of the concept that plays this role | | `name` | string | No | Optional role name | +| `custom_properties` | object | No | Open set of custom properties not covered by this spec (see [Custom properties](#custom-properties)) | For instance, in: @@ -372,6 +376,38 @@ ontology: the first expression requires any value that plays the `Amount` role to be positive while the second requires any item that has sales in some store to be offered in that store. +### Custom properties + +The ontology root, concepts, relationships, and roles may each carry a `custom_properties` object: an +open set of key-value pairs for data that the core spec does not model. This gives tools a place to +preserve information that would otherwise be lost, which is especially useful when importing an ontology +from an external format such as OWL/RDF and round-tripping it back out. + +Keys are free-form, and values may be any JSON. When carrying data from a semantic-web source, CURIEs +such as `owl:equivalentClass` or `rdfs:label` are recommended so the origin of each property stays clear. +Tools that do not understand a given property should preserve it as-is. For example, an OWL importer might +map an `owl:Class` to a concept while retaining its IRI and annotations: + +```yaml +ontology: + - concept: + name: Person + type: EntityType + custom_properties: + iri: "http://xmlns.com/foaf/0.1/Person" + rdfs:label: "Person" + owl:equivalentClass: "https://schema.org/Person" + relationships: + - name: knows + roles: + - concept: Person + name: acquaintance + verbalizes: [ "{Person} knows {Person:acquaintance}" ] + custom_properties: + iri: "http://xmlns.com/foaf/0.1/knows" + owl:inverseOf: "http://xmlns.com/foaf/0.1/knows" +``` + ## Ontology mappings Ontology mappings declare how to map the values of fields at the logical level to objects and links @@ -585,6 +621,8 @@ though `Store` plays a role in three of the relationships. - **0.2.0.dev0** (2026-05-29): Basic support for ontologies and logical schema mappings - Core ontology structure: Concepts, relationships, and business rules (requires and derived_by) - Schema mappings from one or more logical models into an ontology + - `custom_properties` on the ontology root, concepts, relationships, and roles for carrying + data not covered by the core spec (e.g. when importing from OWL/RDF) --- From 9388fec10a054458d8ea19ad09dba312971c89a5 Mon Sep 17 00:00:00 2001 From: Jochen Christ Date: Wed, 3 Jun 2026 10:10:18 +0200 Subject: [PATCH 2/7] Document language-tagged literals in custom_properties RDF labels and comments are usually language-tagged and the previous example used a plain string, which is lossy. Recommend the readable `prefix:local@lang` key convention for language-tagged literals (the `@` cannot appear in a CURIE local name, so it parses unambiguously), and point at the JSON-LD value-object form for the multi-value and typed literal cases that the flat form cannot express. Co-Authored-By: Claude Opus 4.8 (1M context) --- examples/foaf_owl_import.yaml | 8 +++++--- ontology/ontology.md | 30 +++++++++++++++++++++++++++++- 2 files changed, 34 insertions(+), 4 deletions(-) diff --git a/examples/foaf_owl_import.yaml b/examples/foaf_owl_import.yaml index 831469e3..beb0ef9d 100644 --- a/examples/foaf_owl_import.yaml +++ b/examples/foaf_owl_import.yaml @@ -13,8 +13,9 @@ ontology: type: EntityType custom_properties: iri: "http://xmlns.com/foaf/0.1/Person" - rdfs:label: "Person" - rdfs:comment: "A person." + rdfs:label@en: "Person" + rdfs:label@fr: "Personne" + rdfs:comment@en: "A person." owl:equivalentClass: "https://schema.org/Person" relationships: - name: name @@ -24,7 +25,7 @@ ontology: multiplicity: ManyToOne custom_properties: iri: "http://xmlns.com/foaf/0.1/name" - rdfs:label: "name" + rdfs:label@en: "name" - name: knows roles: - concept: Person @@ -34,4 +35,5 @@ ontology: verbalizes: [ "{Person} knows {Person:acquaintance}" ] custom_properties: iri: "http://xmlns.com/foaf/0.1/knows" + rdfs:label@en: "knows" owl:inverseOf: "http://xmlns.com/foaf/0.1/knows" diff --git a/ontology/ontology.md b/ontology/ontology.md index ff663a3c..0ab092d7 100644 --- a/ontology/ontology.md +++ b/ontology/ontology.md @@ -395,7 +395,8 @@ ontology: type: EntityType custom_properties: iri: "http://xmlns.com/foaf/0.1/Person" - rdfs:label: "Person" + rdfs:label@en: "Person" + rdfs:label@fr: "Personne" owl:equivalentClass: "https://schema.org/Person" relationships: - name: knows @@ -408,6 +409,33 @@ ontology: owl:inverseOf: "http://xmlns.com/foaf/0.1/knows" ``` +#### Language-tagged literals + +RDF literals often carry a language tag (for example `rdfs:label` with values `"Person"@en` and +`"Personne"@fr`). The recommended convention is to append the [BCP 47](https://www.rfc-editor.org/info/bcp47) +language tag to the key after an `@`, giving keys of the form `prefix:local@lang`: + +```yaml +custom_properties: + rdfs:label@en: "Person" + rdfs:label@fr: "Personne" +``` + +`@` is not a legal character in a CURIE local name, so `prefix:local@lang` parses unambiguously into the +property and its language. This form holds at most one value per language per key. When a property needs +multiple values in the same language, or carries a non-language datatype such as `xsd:date`, use the +[JSON-LD](https://www.w3.org/TR/json-ld11/) value-object form instead, which is lossless: + +```yaml +custom_properties: + rdfs:label: + - { "@value": "Person", "@language": "en" } + - { "@value": "Persona", "@language": "en" } + dcterms:created: + "@value": "2020-01-01" + "@type": "xsd:date" +``` + ## Ontology mappings Ontology mappings declare how to map the values of fields at the logical level to objects and links From 118776ebafeb8c79bae41946a59d5304c4a6bb39 Mon Sep 17 00:00:00 2001 From: Jochen Christ Date: Wed, 3 Jun 2026 10:12:29 +0200 Subject: [PATCH 3/7] Move root custom_properties below the ontology key in example Co-Authored-By: Claude Opus 4.8 (1M context) --- examples/foaf_owl_import.yaml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/examples/foaf_owl_import.yaml b/examples/foaf_owl_import.yaml index beb0ef9d..0e822814 100644 --- a/examples/foaf_owl_import.yaml +++ b/examples/foaf_owl_import.yaml @@ -4,9 +4,6 @@ description: > Small ontology imported from the FOAF (Friend of a Friend) OWL vocabulary, demonstrating how custom_properties preserves OWL/RDF data (IRIs, labels, and axioms) that the core OSI spec does not model, so the source can be round-tripped. -custom_properties: - owl:Ontology: "http://xmlns.com/foaf/0.1/" - dc:title: "Friend of a Friend (FOAF) vocabulary" ontology: - concept: name: Person @@ -37,3 +34,6 @@ ontology: iri: "http://xmlns.com/foaf/0.1/knows" rdfs:label@en: "knows" owl:inverseOf: "http://xmlns.com/foaf/0.1/knows" +custom_properties: + owl:Ontology: "http://xmlns.com/foaf/0.1/" + dc:title: "Friend of a Friend (FOAF) vocabulary" From ebe5e896a0ef0be3d6c7e6e5014c2dbc404ce129 Mon Sep 17 00:00:00 2001 From: jochen Date: Tue, 18 Aug 2026 19:43:22 +0200 Subject: [PATCH 4/7] Flatten concept declaration in foaf example --- examples/foaf_owl_import.yaml | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/examples/foaf_owl_import.yaml b/examples/foaf_owl_import.yaml index 0e822814..b060955d 100644 --- a/examples/foaf_owl_import.yaml +++ b/examples/foaf_owl_import.yaml @@ -5,15 +5,14 @@ description: > demonstrating how custom_properties preserves OWL/RDF data (IRIs, labels, and axioms) that the core OSI spec does not model, so the source can be round-tripped. ontology: - - concept: - name: Person - type: EntityType - custom_properties: - iri: "http://xmlns.com/foaf/0.1/Person" - rdfs:label@en: "Person" - rdfs:label@fr: "Personne" - rdfs:comment@en: "A person." - owl:equivalentClass: "https://schema.org/Person" + - concept: Person + type: EntityType + custom_properties: + iri: "http://xmlns.com/foaf/0.1/Person" + rdfs:label@en: "Person" + rdfs:label@fr: "Personne" + rdfs:comment@en: "A person." + owl:equivalentClass: "https://schema.org/Person" relationships: - name: name roles: From 7856958f1fd02f60e91753055d361e9e635b94f6 Mon Sep 17 00:00:00 2001 From: jochen Date: Sat, 19 Sep 2026 09:22:58 +0200 Subject: [PATCH 5/7] ontology: drop language-tag and CURIE conventions from custom_properties custom_properties is an opaque, free-form object. Remove the recommended CURIE key naming and the rdfs:label@lang / JSON-LD value-object guidance from the schema description, docs, and example so the spec makes no assumptions about the structure of its contents. --- examples/foaf_owl_import.yaml | 19 ++++++++-------- ontology/ontology.json | 2 +- ontology/ontology.md | 41 +++++------------------------------ 3 files changed, 16 insertions(+), 46 deletions(-) diff --git a/examples/foaf_owl_import.yaml b/examples/foaf_owl_import.yaml index b060955d..d5bd7dfb 100644 --- a/examples/foaf_owl_import.yaml +++ b/examples/foaf_owl_import.yaml @@ -9,10 +9,9 @@ ontology: type: EntityType custom_properties: iri: "http://xmlns.com/foaf/0.1/Person" - rdfs:label@en: "Person" - rdfs:label@fr: "Personne" - rdfs:comment@en: "A person." - owl:equivalentClass: "https://schema.org/Person" + label: "Person" + comment: "A person." + equivalent_class: "https://schema.org/Person" relationships: - name: name roles: @@ -21,18 +20,18 @@ ontology: multiplicity: ManyToOne custom_properties: iri: "http://xmlns.com/foaf/0.1/name" - rdfs:label@en: "name" + label: "name" - name: knows roles: - concept: Person name: acquaintance custom_properties: - rdfs:range: "http://xmlns.com/foaf/0.1/Person" + range: "http://xmlns.com/foaf/0.1/Person" verbalizes: [ "{Person} knows {Person:acquaintance}" ] custom_properties: iri: "http://xmlns.com/foaf/0.1/knows" - rdfs:label@en: "knows" - owl:inverseOf: "http://xmlns.com/foaf/0.1/knows" + label: "knows" + inverse_of: "http://xmlns.com/foaf/0.1/knows" custom_properties: - owl:Ontology: "http://xmlns.com/foaf/0.1/" - dc:title: "Friend of a Friend (FOAF) vocabulary" + ontology_iri: "http://xmlns.com/foaf/0.1/" + title: "Friend of a Friend (FOAF) vocabulary" diff --git a/ontology/ontology.json b/ontology/ontology.json index bd4e7b87..59d8f320 100644 --- a/ontology/ontology.json +++ b/ontology/ontology.json @@ -60,7 +60,7 @@ "$defs": { "CustomProperties": { "type": "object", - "description": "Open set of custom properties for carrying data that is not covered by the core ontology spec, for example when importing an ontology from an external format such as OWL/RDF. Keys are free-form; CURIEs such as 'owl:equivalentClass' or 'rdfs:label' are recommended when round-tripping semantic-web sources. Values may be any JSON.", + "description": "Open set of custom properties for carrying data that is not covered by the core ontology spec, for example when importing an ontology from an external format such as OWL/RDF. Keys are free-form and values may be any JSON; the spec does not interpret their structure.", "additionalProperties": true }, "OntologyComponent": { diff --git a/ontology/ontology.md b/ontology/ontology.md index 68c8939f..36c87b7e 100644 --- a/ontology/ontology.md +++ b/ontology/ontology.md @@ -390,10 +390,9 @@ open set of key-value pairs for data that the core spec does not model. This giv preserve information that would otherwise be lost, which is especially useful when importing an ontology from an external format such as OWL/RDF and round-tripping it back out. -Keys are free-form, and values may be any JSON. When carrying data from a semantic-web source, CURIEs -such as `owl:equivalentClass` or `rdfs:label` are recommended so the origin of each property stays clear. -Tools that do not understand a given property should preserve it as-is. For example, an OWL importer might -map an `owl:Class` to a concept while retaining its IRI and annotations: +Keys are free-form, and values may be any JSON. The spec does not interpret or constrain the structure of +`custom_properties`; tools that do not understand a given property should preserve it as-is. For example, +an OWL importer might map an `owl:Class` to a concept while retaining its IRI and annotations: ```yaml ontology: @@ -401,9 +400,8 @@ ontology: type: EntityType custom_properties: iri: "http://xmlns.com/foaf/0.1/Person" - rdfs:label@en: "Person" - rdfs:label@fr: "Personne" - owl:equivalentClass: "https://schema.org/Person" + label: "Person" + equivalent_class: "https://schema.org/Person" relationships: - name: knows roles: @@ -412,34 +410,7 @@ ontology: verbalizes: [ "{Person} knows {Person:acquaintance}" ] custom_properties: iri: "http://xmlns.com/foaf/0.1/knows" - owl:inverseOf: "http://xmlns.com/foaf/0.1/knows" -``` - -#### Language-tagged literals - -RDF literals often carry a language tag (for example `rdfs:label` with values `"Person"@en` and -`"Personne"@fr`). The recommended convention is to append the [BCP 47](https://www.rfc-editor.org/info/bcp47) -language tag to the key after an `@`, giving keys of the form `prefix:local@lang`: - -```yaml -custom_properties: - rdfs:label@en: "Person" - rdfs:label@fr: "Personne" -``` - -`@` is not a legal character in a CURIE local name, so `prefix:local@lang` parses unambiguously into the -property and its language. This form holds at most one value per language per key. When a property needs -multiple values in the same language, or carries a non-language datatype such as `xsd:date`, use the -[JSON-LD](https://www.w3.org/TR/json-ld11/) value-object form instead, which is lossless: - -```yaml -custom_properties: - rdfs:label: - - { "@value": "Person", "@language": "en" } - - { "@value": "Persona", "@language": "en" } - dcterms:created: - "@value": "2020-01-01" - "@type": "xsd:date" + inverse_of: "http://xmlns.com/foaf/0.1/knows" ``` ## Ontology mappings From 412e557bd844d0e9623fd72542558a676bc28692 Mon Sep 17 00:00:00 2001 From: jochen Date: Sat, 19 Sep 2026 09:27:42 +0200 Subject: [PATCH 6/7] ontology: use the uri field instead of an iri custom property in examples Concepts and relationships already have a first-class uri field, so the custom_properties examples no longer duplicate it under an iri key. --- examples/foaf_owl_import.yaml | 12 ++++++------ ontology/ontology.md | 6 +++--- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/examples/foaf_owl_import.yaml b/examples/foaf_owl_import.yaml index d5bd7dfb..9fcc7e18 100644 --- a/examples/foaf_owl_import.yaml +++ b/examples/foaf_owl_import.yaml @@ -2,26 +2,28 @@ version: 0.2.0.dev0 name: foaf description: > Small ontology imported from the FOAF (Friend of a Friend) OWL vocabulary, - demonstrating how custom_properties preserves OWL/RDF data (IRIs, labels, and - axioms) that the core OSI spec does not model, so the source can be round-tripped. + demonstrating how custom_properties preserves OWL/RDF data (labels, comments, + and axioms) that the core OSI spec does not model, so the source can be + round-tripped. ontology: - concept: Person type: EntityType + uri: "http://xmlns.com/foaf/0.1/Person" custom_properties: - iri: "http://xmlns.com/foaf/0.1/Person" label: "Person" comment: "A person." equivalent_class: "https://schema.org/Person" relationships: - name: name + uri: "http://xmlns.com/foaf/0.1/name" roles: - concept: String verbalizes: [ "{Person} has name {String}" ] multiplicity: ManyToOne custom_properties: - iri: "http://xmlns.com/foaf/0.1/name" label: "name" - name: knows + uri: "http://xmlns.com/foaf/0.1/knows" roles: - concept: Person name: acquaintance @@ -29,9 +31,7 @@ ontology: range: "http://xmlns.com/foaf/0.1/Person" verbalizes: [ "{Person} knows {Person:acquaintance}" ] custom_properties: - iri: "http://xmlns.com/foaf/0.1/knows" label: "knows" inverse_of: "http://xmlns.com/foaf/0.1/knows" custom_properties: - ontology_iri: "http://xmlns.com/foaf/0.1/" title: "Friend of a Friend (FOAF) vocabulary" diff --git a/ontology/ontology.md b/ontology/ontology.md index 36c87b7e..39129839 100644 --- a/ontology/ontology.md +++ b/ontology/ontology.md @@ -392,24 +392,24 @@ from an external format such as OWL/RDF and round-tripping it back out. Keys are free-form, and values may be any JSON. The spec does not interpret or constrain the structure of `custom_properties`; tools that do not understand a given property should preserve it as-is. For example, -an OWL importer might map an `owl:Class` to a concept while retaining its IRI and annotations: +an OWL importer might map an `owl:Class` to a concept while retaining its annotations and axioms: ```yaml ontology: - concept: Person type: EntityType + uri: "http://xmlns.com/foaf/0.1/Person" custom_properties: - iri: "http://xmlns.com/foaf/0.1/Person" label: "Person" equivalent_class: "https://schema.org/Person" relationships: - name: knows + uri: "http://xmlns.com/foaf/0.1/knows" roles: - concept: Person name: acquaintance verbalizes: [ "{Person} knows {Person:acquaintance}" ] custom_properties: - iri: "http://xmlns.com/foaf/0.1/knows" inverse_of: "http://xmlns.com/foaf/0.1/knows" ``` From 8ec0f51cc7d21c8d2f6673fc489bc07f3691cbc7 Mon Sep 17 00:00:00 2001 From: jochen Date: Sat, 19 Sep 2026 09:34:51 +0200 Subject: [PATCH 7/7] ontology: metrics-style custom_properties example; QName keys in FOAF import The docs now show custom_properties on a ContributionMargin value type (abbreviation, formula, unit, better_when, owner) so the free-form nature of the keys is clear. The FOAF example declares a prefixes map and keys its properties by the source predicate's QName, noted as the importer's own convention rather than a spec requirement. --- examples/foaf_owl_import.yaml | 30 +++++++++++++++++------------- ontology/ontology.md | 33 ++++++++++++++++----------------- 2 files changed, 33 insertions(+), 30 deletions(-) diff --git a/examples/foaf_owl_import.yaml b/examples/foaf_owl_import.yaml index 9fcc7e18..371cc28a 100644 --- a/examples/foaf_owl_import.yaml +++ b/examples/foaf_owl_import.yaml @@ -4,34 +4,38 @@ description: > Small ontology imported from the FOAF (Friend of a Friend) OWL vocabulary, demonstrating how custom_properties preserves OWL/RDF data (labels, comments, and axioms) that the core OSI spec does not model, so the source can be - round-tripped. + round-tripped. This importer keys custom properties by the source predicate's + qualified name; that is the importer's convention, not a requirement of the spec. +prefixes: + foaf: "http://xmlns.com/foaf/0.1/" + rdfs: "http://www.w3.org/2000/01/rdf-schema#" + owl: "http://www.w3.org/2002/07/owl#" + dc: "http://purl.org/dc/elements/1.1/" ontology: - concept: Person type: EntityType - uri: "http://xmlns.com/foaf/0.1/Person" + uri: foaf:Person custom_properties: - label: "Person" - comment: "A person." - equivalent_class: "https://schema.org/Person" + rdfs:label: "Person" + rdfs:comment: "A person." + owl:equivalentClass: "https://schema.org/Person" relationships: - name: name - uri: "http://xmlns.com/foaf/0.1/name" + uri: foaf:name roles: - concept: String verbalizes: [ "{Person} has name {String}" ] multiplicity: ManyToOne custom_properties: - label: "name" + rdfs:label: "name" - name: knows - uri: "http://xmlns.com/foaf/0.1/knows" + uri: foaf:knows roles: - concept: Person name: acquaintance - custom_properties: - range: "http://xmlns.com/foaf/0.1/Person" verbalizes: [ "{Person} knows {Person:acquaintance}" ] custom_properties: - label: "knows" - inverse_of: "http://xmlns.com/foaf/0.1/knows" + rdfs:label: "knows" + owl:inverseOf: foaf:knows custom_properties: - title: "Friend of a Friend (FOAF) vocabulary" + dc:title: "Friend of a Friend (FOAF) vocabulary" diff --git a/ontology/ontology.md b/ontology/ontology.md index 39129839..4013ed16 100644 --- a/ontology/ontology.md +++ b/ontology/ontology.md @@ -387,32 +387,31 @@ requires any item that has sales in some store to be offered in that store. The ontology root, concepts, relationships, and roles may each carry a `custom_properties` object: an open set of key-value pairs for data that the core spec does not model. This gives tools a place to -preserve information that would otherwise be lost, which is especially useful when importing an ontology -from an external format such as OWL/RDF and round-tripping it back out. +attach their own metadata, or to preserve information when importing an ontology from an external +format so that it can be round-tripped. Keys are free-form, and values may be any JSON. The spec does not interpret or constrain the structure of `custom_properties`; tools that do not understand a given property should preserve it as-is. For example, -an OWL importer might map an `owl:Class` to a concept while retaining its annotations and axioms: +a metrics tool might annotate a value type with how it is computed and displayed: ```yaml ontology: - - concept: Person - type: EntityType - uri: "http://xmlns.com/foaf/0.1/Person" + - concept: ContributionMargin + type: ValueType + extends: [Decimal] + description: Revenue remaining after variable costs custom_properties: - label: "Person" - equivalent_class: "https://schema.org/Person" - relationships: - - name: knows - uri: "http://xmlns.com/foaf/0.1/knows" - roles: - - concept: Person - name: acquaintance - verbalizes: [ "{Person} knows {Person:acquaintance}" ] - custom_properties: - inverse_of: "http://xmlns.com/foaf/0.1/knows" + abbreviation: CM + formula: revenue - variable_costs + unit: EUR + better_when: higher + owner: finance-analytics ``` +An importer from a semantic-web format might instead use the source vocabulary's qualified names as keys, +as in the [FOAF example](../examples/foaf_owl_import.yaml). Both are valid; the choice of keys belongs to +the tool that writes them. + ## Ontology mappings Ontology mappings declare how to map the values of fields at the logical level to objects and links