Chapter 13: Talking to the Outside World
*The email from the Regional Veterinary Board was blunt:
Please submit your animal health records using the National Animal Health Ontology (NAHO) vocabulary. All concepts must use IRIs from
http://naho.gov/ontology/. All species must reference the FAO species classification athttp://fao.org/species/.Dr. Portbridge looked at her Dolfin file. Her concepts were called
AnimalandDog. The board expectedhttp://naho.gov/ontology/Animalandhttp://fao.org/species/CanineDomestic. She needed a way to map her clean, readable names to the bureaucratic world of IRIs.
The problem
Dolfin ontologies live in a clean, human-readable world. The semantic web lives in a world of IRIs (Internationalized Resource Identifiers), long URLs that uniquely identify every concept, property, and individual. To interoperate, we need to connect the two.
Prefixes
A prefix declares a short alias for an IRI namespace:
prefix <http://naho.gov/ontology/> as naho
prefix <http://fao.org/species/> as fao
A prefix is only an alias for qualified references, naho.Animal expands to
http://naho.gov/ontology/Animal. Declaring a prefix does not move your own
concepts into that namespace. This:
prefix <http://naho.gov/ontology/> as naho
concept Animal:
has name: one string
still defines Animal under your package’s own namespace. The naho prefix sits
unused. To bind one of your concepts to an external IRI you must say so
explicitly with @iri_name (see below).
Using prefixed references
Prefixes let you reference concepts from other ontologies:
prefix <http://schema.org/> as schema
concept Owner:
has firstName: one string
has lastName: one string
has phoneNumbers: at least 1 string
has email: optional string
has address: optional schema.PostalAddress
schema.PostalAddress refers to http://schema.org/PostalAddress, Schema.org’s definition of a postal address. You’re linking your clinic ontology to a globally recognized vocabulary.
The @iri_name annotation
This is how you actually bind a concept to an external IRI. The @iri_name
annotation sits inside the concept body and takes the complete IRI in
angle brackets. That IRI is used verbatim, it is not appended to your package
namespace:
concept DomesticDog:
@iri_name <http://fao.org/species/CanineDomestic>
sub Animal
has breed: optional string
has neutered: one boolean
Here the local name DomesticDog stays clean and readable in your code, but the
concept compiles to http://fao.org/species/CanineDomestic. Exactly the IRI the
external system expects. This is what the board’s request required: local names
mapped to bureaucratic IRIs. The annotation takes a full IRI in angle brackets
only. A prefixed qualified name is not accepted here.
Multiple prefixes
A real-world ontology often bridges multiple external vocabularies:
prefix <http://naho.gov/ontology/> as naho
prefix <http://fao.org/species/> as fao
prefix <http://schema.org/> as schema
prefix <http://purl.org/dc/elements/1.1/> as dc
Each prefix is independent. You can use as many as needed.
The complete clinic
package.dlf holds only the package declaration:
# package.dlf
package <http://happypaws.com/clinic>:
dolfin_version "1"
version "1.0.0"
author "Dr. Helen Portbridge"
description "The Happy Paws veterinary clinic data model"
The ontology goes in a second file, clinic.dlf. If it used prefixes, the prefix lines would sit at the top of that file, never in package.dlf. This listing declares none: @iri_name takes a full IRI, so DomesticDog does not need one.
# clinic.dlf
concept Species:
one of:
Dog
Cat
Bird
Rabbit
Reptile
Other
concept Urgency:
one of:
Routine
Urgent
Emergency
concept AppointmentStatus:
one of:
Scheduled
InProgress
Completed
Cancelled
concept Owner:
has firstName: one string
has lastName: one string
has phoneNumbers: at least 1 string
has email: optional string
has address: optional string
has preferredVet: optional Veterinarian
concept Veterinarian:
has name: one string
has licenseNumber: one string
has specialization: optional string
concept Surgeon:
sub Veterinarian
has surgeryCount: one int
has certifiedProcedures: at least 1 string
concept Dentist:
sub Veterinarian
has dentalCertification: one string
concept Intern:
sub Veterinarian
has university: one string
has year: one int
concept Vaccination:
has vaccineName: one string
has dateAdministered: one string
has batchNumber: optional string
concept Animal:
has name: one string
has species: one Species
has age: optional int
has weight: optional float
has owner: optional Owner
has vaccinations: Vaccination
has allergies: string
concept Dog:
sub Animal
has breed: optional string
has neutered: one boolean
concept Cat:
sub Animal
has indoor: one boolean
concept Bird:
sub Animal
has wingspan: optional float
has canFly: one boolean
concept Appointment:
has animal: one Animal
has scheduledFor: one date_time
has reason: one string
has urgency: one Urgency
has status: one AppointmentStatus
has diagnosis: optional string
has treatments: string
has notes: optional string
property treatedBy: Animal -> Veterinarian
# Binding to the outside world (this chapter)
concept DomesticDog:
@iri_name <http://fao.org/species/CanineDomestic>
sub Dog
# Flag concepts and inference rules (Chapter 10)
concept UnvaccinatedAnimal
concept UnsafeAssignment
concept OverweightAnimal
rule flag_unvaccinated:
match:
?animal a Animal
?animal vaccinations 0
then:
?animal a UnvaccinatedAnimal
rule flag_intern_emergency:
match:
?appt a Appointment
?appt urgency Emergency
?appt animal [ treatedBy [ a Intern ] ]
then:
?appt a UnsafeAssignment
rule assign_primary_vet:
match:
?animal a Animal
?animal owner [ preferred_vet ?vet ]
then:
?animal treatedBy ?vet
# Unit-aware weight thresholds (Chapter 11)
concept OverweightCat
rule flag_overweight_dog:
match:
?dog a Dog
?dog weight [ > quantity(40 kg) ]
then:
?dog a OverweightAnimal
rule flag_overweight_cat:
match:
?cat a Cat
?cat weight [ > quantity(6 kg) ]
then:
?cat a OverweightCat
# Guard rails (Chapter 12)
concept SeniorCat
concept InvalidSurgery
concept UnderVaccinatedDog
concept AtRiskAnimal
rule flag_senior_cat:
match:
?cat a Cat
?cat age [ >= 10 ]
then:
?cat a SeniorCat
rule validate_surgery_staff:
match:
?appt a Appointment
?appt reason "surgery"
?appt animal ?animal
none ?vet:
?animal treatedBy ?vet
?vet a Surgeon
then:
?appt a InvalidSurgery
rule check_dog_vaccines:
match:
?dog a Dog
?dog vaccinations 0
then:
?dog a UnderVaccinatedDog
rule flag_at_risk:
match:
?animal a Animal
?animal age [ > 15 ]
?animal weight [ < quantity(2 kg) ]
?animal vaccinations 0
then:
?animal a AtRiskAnimal
Try it
Add a prefix for Dublin Core (http://purl.org/dc/elements/1.1/) and FOAF (http://xmlns.com/foaf/0.1/):
prefix <http://naho.gov/ontology/> as naho
# Add Dublin Core and FOAF prefixes here
Dr. Portbridge submitted the data export. The board’s system accepted it without complaint, her concepts mapped cleanly to NAHO’s IRIs, and the species references aligned with FAO’s vocabulary. Her little clinic was speaking the same language as the national registry.
She leaned back in her chair and looked at the screen. What had started as a napkin sketch was now a complete data model: concepts with inheritance, cardinality constraints, enums for controlled vocabularies, rules for automated reasoning, constraints for validation, and prefixes for interoperability. Biscuit dozed at her feet. Pixel purred on the printer.