OWL#

Example Output#

personinfo.owl.ttl

Overview#

Web Ontology Language OWL is a modeling language used to author ontologies.

OWL is used for building ontologies, whereas LinkML is a schema language. Nevertheless, it can be useful to render Schemas as OWL (and in fact many semantic web schemas such as PROV have an OWL or RDFS rendering)

See also

The linkml-owl maps between LinkML data and OWL

Note

The OWL is rendered as RDF/turtle. We recommend the suffix .owl.ttl to distinguish from the direct RDF mapping

Mapping#

  • Each LinkML class maps to an OWL class

  • Each LinkML slot maps to an OWL property

    • if the range of the slot is class, then an ObjectProperty is used

    • otherwise DataProperty is used

    • Exception to the above: if type_objects is set then ObjectProperties are always used; instead of having ranges of type be mapped to literals, these map to class-shadows of literals, that have a data property value. This can be useful in some scenarios - for example, if you want to use the same property and allow either literals or objects as values.

  • OWL restrictions are used for cardinality and range constraints

    • only (universal restrictions) is used for ranges

    • If a slot is not multivalued then max 1 cardinality restrictions are used

    • required non-multivalued slots have an exactly 1 cardinality restriction

    • required slots have a min 1 cardinality restriction

    • non-required slots have a min 0 cardinality restriction. Note that formally this is tautological and not necessary. However, adding this axiom helps make the intention explicit.

    • it should be understood that OWL follows the Open World Assumption, thus OWL reasoners enforce a weaker model

  • By default both is_a and mixins are mapped to rdfs:subClassOf

    • Use --mixins-as-expressions to treat mixins as existential axioms

  • Each LinkML element is rendered as an instance of the relevant metamodel class

    • This means punning is used

    • Set --no-metaclasses if you do not want this behavior

    • Set --add-root-classes to add a root class for each metamodel class

Note

The current default settings for metaclasses and type-objects may change in the future

Enums and PermissibleValues#

Enums and PermissibleValues are treated as classes by default. An enum has a definition added using an OWL UnionOf construct.

  • Use --default-permissible-value-type to change the default type

  • Use --enum-iri-separator to change the separator character in the enum IRI which is # by default

You can make an enum represent individuals by adding an implements slot assignment:

enums:
  HomePlanetType:
    implements:
     - owl:NamedIndividual
    description: The type of home planet
    permissible_values:
      Earth:
      Venus:

Tips#

If you wish to produce an OWL file that is primarily for browsing or release on an ontology portal such as the Ontology Lookup Service (OLS) or OntoPortal/BioPortal, then consider using the --add-root-classes option to make the ontology more navigable.

If gen-owl is run on PersonInfo without this option it results in a flat structure that is faithful and isomorphic to the existing schema:

* GenderType
* FamilialRelationshipType
    * CHILD_OF
    * PARENT_OF
    * ...
* Relationship
    * FamilialRelationship
* Event
    * EmploymentEvent
    * MedicalEvent
* NamedThing
    * Concept
* HasAliases

Running with the option:

* EnumDefinition
    * GenderType
    * FamilialRelationshipType
* ClassDefinition
    * Relationship
        * FamilialRelationship
    * Event
        * EmploymentEvent
        * MedicalEvent
    * NamedThing
        * Concept
    * HasAliases
* PermissibleValue
    * CHILD_OF
    * ...

If your schema is heavy on mixins, the resulting polyhierarchy can be hard to navigate. In this case, using --mixins-as-expressions will restrict the main subClassOf backbone to be purely is_a relationships. Mixin relationships will be modeled using existential restrictions (some values from). OWL General Class Inclusion (GCI) axioms will be used to preserve semantics.

For example, on PersonInfo the default conversion yields:

Class: Person
  SubClassOf: NamedThing, HasAlias, ...
Class: HasAlias
  SubClassOf: aliases only xsd:string, ...
...

Using --mixins-as-expressions gives:

Class: Person
  SubClassOf: NamedThing, mixins some HasAlias, ...
Class: HasAlias
GCIs:
  (mixins some HasAlias) SubClassOf: aliases only xsd:string, ...
...

Semantics of mapping from LinkML#

Generated OWL should be a faithful open-world rendering of the LinkML schema. This means that it may not be complete for the purposes of data validation. If a slot is not required, then an OWL reasoner will infer the presence of a slot value, even if not explicitly stated. However, it does not treat this as an error.

Nevertheless, it can be informative to translate schemas with rich logical information to OWL, combine these with data converted to RDF, and then perform reasoning. If you use an ontology development environment like Protege, this can be an intuitive way of debugging errors with your schema.

Note that currently only a subset of LinkML rules can be expressed as OWL. In future, we may add support to generate auxhiliary SWRL files including rules.

Pitfalls#

Many OWL tools such as those based on the OWL API are intended to consume a [profile](https://www.w3.org/TR/owl2-profiles/) of OWL called OWL-DL. It’s relatively easy to create LinkML that can’t be directly expressed in OWL-DL, and the resulting RDF triples are said to be [OWL Full](https://www.w3.org/TR/owl2-overview/#Semantics).

For example, if you have slots in your schema that have an Any range, then there is no direct translation of that slot to an OWL-DL property, since each property needs to explicitly commit to being a DatatypeProperty or ObjectProperty in OWL-DL.

Other examples#

  • Biolink : translation of Biolink schema to OWL

Docs#

Command Line#

gen-owl#

Generate an OWL representation of a LinkML model

Generate OWL using default parameters:

gen-owl my_schema.yaml

Note that in previous versions of this generator, the default was to use type objects and to include metaclasses. To restore this behavior:

gen-owl –metaclasses –type-objects my_schema.yaml

For more info, see: https://linkml.io/linkml/generators/owl

gen-owl [OPTIONS] YAMLFILE

Options

-o, --output <output>#

Output file name

--metadata-profile <metadata_profile>#

What kind of metadata profile to use for annotations on generated OWL objects

Default:

'linkml'

Options:

linkml | rdfs | ols

--type-objects, --no-type-objects#

If true, will model linkml types as objects, not literals

Default:

False

--metaclasses, --no-metaclasses#

If true, include linkml metamodel classes as metaclasses. Note this introduces punning in OWL-DL

Default:

False

--add-root-classes, --no-add-root-classes#

If true, include linkml metamodel classes as superclasses.

Default:

False

--add-ols-annotations, --no-add-ols-annotations#

If true, auto-include annotations from https://www.ebi.ac.uk/ols/docs/installation-guide

Default:

True

--ontology-uri-suffix <ontology_uri_suffix>#

Suffix to append to schema id to generate OWL Ontology IRI

Default:

'.owl.ttl'

--assert-equivalent-classes, --no-assert-equivalent-classes#

If true, add owl:equivalentClass between a class and a class_uri

Default:

False

--mixins-as-expressions, --no-mixins-as-expressions#

If true, then mixins are represented as existential expressions

Default:

False

--use-native-uris, --no-use-native-uris#

Use model URIs rather than class/slot URIs

Default:

True

--default-permissible-value-type <default_permissible_value_type>#

Default OWL type for permissible values

Default:

'http://www.w3.org/2002/07/owl#Class'

--enum-iri-separator <enum_iri_separator>#

IRI separator for enums.

Default:

'#'

-V, --version#

Show the version and exit.

-f, --format <format>#

Output format

Default:

'owl'

Options:

owl | ttl | json-ld | xml | n3 | turtle | ttl | ntriples | nt | nt11 | nquads | trix | trig | hext | patch

--metadata, --no-metadata#

Include metadata in output

Default:

True

--useuris, --metauris#

Use class and slot URIs over model uris

Default:

True

-im, --importmap <importmap>#

Import mapping file

--log_level <log_level>#

Logging level

Default:

'WARNING'

Options:

CRITICAL | ERROR | WARNING | INFO | DEBUG

-v, --verbose#

Verbosity. Takes precedence over –log_level.

--mergeimports, --no-mergeimports#

Merge imports into source file (default=mergeimports)

--stacktrace, --no-stacktrace#

Print a stack trace when an error occurs

Default:

False

Arguments

YAMLFILE#

Required argument

Code#

class linkml.generators.owlgen.OwlSchemaGenerator(schema: str | ~typing.TextIO | ~linkml_runtime.linkml_model.meta.SchemaDefinition | ~linkml.utils.generator.Generator | ~pathlib.Path, schemaview: ~linkml_runtime.utils.schemaview.SchemaView | None = None, format: str | None = None, metadata: bool = True, useuris: bool | None = None, log_level: int | None = 30, mergeimports: bool | None = True, source_file_date: str | None = None, source_file_size: int | None = None, logger: ~logging.Logger | None = None, verbose: bool | None = None, output: str | None = None, namespaces: ~linkml_runtime.utils.namespaces.Namespaces | None = None, directory_output: bool = False, base_dir: str | None = None, metamodel_name_map: ~typing.Dict[str, str] | None = None, importmap: str | ~typing.Mapping[str, str] | None = None, emit_prefixes: ~typing.Set[str] = <factory>, metamodel: ~linkml.utils.schemaloader.SchemaLoader | None = None, stacktrace: bool = False, include: str | ~pathlib.Path | ~linkml_runtime.linkml_model.meta.SchemaDefinition | None = None, ontology_uri_suffix: str | None = None, metadata_profile: ~linkml.generators.owlgen.MetadataProfile | None = None, metadata_profiles: ~typing.List[~linkml.generators.owlgen.MetadataProfile] = <factory>, metaclasses: bool = True, add_root_classes: bool = False, add_ols_annotations: bool = True, graph: ~rdflib.graph.Graph | None = None, top_value_uri: ~rdflib.term.URIRef | None = None, type_objects: bool = True, assert_equivalent_classes: bool = False, use_native_uris: bool = True, mixins_as_expressions: bool | None = None, default_permissible_value_type: str | ~rdflib.term.URIRef = <factory>, slot_is_literal_map: ~typing.Mapping[str, ~typing.Set[bool]] = <factory>, node_owltypes: ~typing.Mapping[~rdflib.term.BNode | ~rdflib.term.URIRef, ~typing.Set[~rdflib.term.URIRef]] = <factory>, simplify: bool = True, use_swrl: bool = False, target_profile: ~linkml.generators.owlgen.OWLProfile = <factory>, metamodel_schemaview: ~linkml_runtime.utils.schemaview.SchemaView = <factory>, enum_iri_separator: str = '#', **_kwargs)[source]#

Generates a schema-oriented OWL representation of a LinkML model

OWL Generator Docs

.

  • LinkML ClassDefinitions are translated to OWL Classes

  • LinkML SlotDefinitions are translated to OWL Properties

  • LinkML Enumerations are translated to OWL Classes

  • LinkML TypeDefinitions are translated to OWL Datatypes

The translation aims to be as faithful as possible. But note that OWL is open-world, whereas LinkML is closed-world

serialize(**kwargs) str[source]#

Serialize the OWL triple graph to a standard RDF serialization format.

Parameters:

kwargs

Returns: