# AFMRO — Aircraft Fleet Mission Readiness Ontology (CLEAN reference)
# Workshop: AI-Assisted Ontology Engineering — KGC 2026
# Author: Dougal Watt, Graph Research Labs
#
# This is the CLEAN reference ontology used in the workshop demonstration.
# Aligned to gist 14.1.0.
#
# Style conventions (team standard):
#   - Constraints are expressed as OWL property restrictions on the
#     bearing class, NOT as rdfs:domain / rdfs:range on the property.
#   - Use Qualified Cardinality Restrictions (owl:onClass +
#     owl:qualifiedCardinality / owl:minQualifiedCardinality /
#     owl:maxQualifiedCardinality) for class-typed constraints.
#   - Annotations use SKOS (skos:prefLabel, skos:definition).
#   - IRIs use slash-style separation, never #.
#
# gist 14 alignment notes:
#   - gist 14 reverses several partonomy and categorisation properties
#     compared to earlier vintages. We use gist:isDirectPartOf and
#     gist:isCategorizedBy as published.
#   - For the natural reading "an Aircraft has at least one Component"
#     we declare afmro:hasDirectPart as the owl:inverseOf
#     gist:isDirectPartOf so restrictions on Aircraft read naturally.
#   - gist 14 has no Place class; afmro:Base is a gist:GeoRegion.
#   - gist 14 has no Group class for groups of people; afmro:Crew is
#     a gist:Composite (a thing made up of independently identifiable
#     parts).
#   - gist 14 has no Document class; gist:Content is used for
#     MaintenanceRecord.
#
# Licence: CC-BY-SA-4.0.

@prefix afmro: <https://example.org/afmro/> .
@prefix gist:  <https://w3id.org/semanticarts/ns/ontology/gist/> .
@prefix owl:   <http://www.w3.org/2002/07/owl#> .
@prefix rdf:   <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix rdfs:  <http://www.w3.org/2000/01/rdf-schema#> .
@prefix skos:  <http://www.w3.org/2004/02/skos/core#> .
@prefix xsd:   <http://www.w3.org/2001/XMLSchema#> .
@prefix dct:   <http://purl.org/dc/terms/> .

#####################################################################
# Ontology header
#####################################################################

<https://example.org/afmro> a owl:Ontology ;
  owl:versionIRI <https://example.org/afmro/0.5.2> ;
  dct:title "Aircraft Fleet Mission Readiness Ontology (AFMRO)" ;
  dct:description "A small gist 14-aligned exemplar covering aircraft fleet capability, mission tasking, configuration, and maintenance state. Designed as a teaching exemplar for the KGC 2026 workshop on AI-assisted ontology engineering." ;
  dct:creator "Dougal Watt" ;
  dct:license <https://creativecommons.org/licenses/by-sa/4.0/> ;
  owl:imports <https://w3id.org/semanticarts/ontology/gistCore> ;
  rdfs:comment "This is the CLEAN reference. The flawed parallel file demonstrates three LLM modelling anti-patterns plus the misattachment of planning-time properties to the conflated Mission class." .

#####################################################################
# Categories — gist 14 idiom: types are gist:Category instances and
# things are categorised via gist:isCategorizedBy.
#####################################################################

afmro:AircraftCategory a owl:Class ;
  rdfs:subClassOf gist:Category ;
  skos:prefLabel "Aircraft Category"@en ;
  skos:definition "A Category whose members categorise specific aircraft by design type."@en .

afmro:F-35A     a afmro:AircraftCategory ; skos:prefLabel "F-35A Lightning II"@en .
afmro:F-22      a afmro:AircraftCategory ; skos:prefLabel "F-22 Raptor"@en .
afmro:C-130J    a afmro:AircraftCategory ; skos:prefLabel "C-130J Super Hercules"@en .

afmro:CapabilityCategory a owl:Class ;
  rdfs:subClassOf gist:Category ;
  skos:prefLabel "Capability Category"@en ;
  skos:definition "A Category for the kinds of operational capability an aircraft may bear."@en .

afmro:AirToGround        a afmro:CapabilityCategory ; skos:prefLabel "Air-to-ground engagement"@en .
afmro:AirToAir           a afmro:CapabilityCategory ; skos:prefLabel "Air-to-air engagement"@en .
afmro:HeavyLift          a afmro:CapabilityCategory ; skos:prefLabel "Heavy lift transport"@en .
afmro:ISR                a afmro:CapabilityCategory ; skos:prefLabel "Intelligence, surveillance, reconnaissance"@en .
afmro:AerialRefuelling   a afmro:CapabilityCategory ; skos:prefLabel "Aerial refuelling"@en .

afmro:ReadinessLevel a owl:Class ;
  rdfs:subClassOf gist:Category ;
  skos:prefLabel "Readiness Level"@en ;
  skos:definition "A Category enumerating the readiness levels of an aircraft at a point in time."@en .

afmro:MissionReady    a afmro:ReadinessLevel ; skos:prefLabel "Mission Ready"@en .
afmro:MissionCapable  a afmro:ReadinessLevel ; skos:prefLabel "Mission Capable (with limits)"@en .
afmro:NonMissionReady a afmro:ReadinessLevel ; skos:prefLabel "Non-Mission Ready"@en .

afmro:MissionOutcome a owl:Class ;
  rdfs:subClassOf gist:Category ;
  skos:prefLabel "Mission Outcome"@en ;
  skos:definition "A Category enumerating the outcome of a completed Mission."@en .

afmro:Successful   a afmro:MissionOutcome ; skos:prefLabel "Successful"@en .
afmro:Aborted      a afmro:MissionOutcome ; skos:prefLabel "Aborted"@en .
afmro:Diverted     a afmro:MissionOutcome ; skos:prefLabel "Diverted"@en .
afmro:Failed       a afmro:MissionOutcome ; skos:prefLabel "Failed"@en .

afmro:PlanStatus a owl:Class ;
  rdfs:subClassOf gist:Category ;
  skos:prefLabel "Plan Status"@en ;
  skos:definition "A Category enumerating the lifecycle state of a MissionPlan."@en .

afmro:Draft        a afmro:PlanStatus ; skos:prefLabel "Draft"@en .
afmro:Approved     a afmro:PlanStatus ; skos:prefLabel "Approved"@en .
afmro:Cancelled    a afmro:PlanStatus ; skos:prefLabel "Cancelled"@en .
afmro:Executed     a afmro:PlanStatus ; skos:prefLabel "Executed"@en .
afmro:Superseded   a afmro:PlanStatus ; skos:prefLabel "Superseded"@en .

afmro:RiskLevel a owl:Class ;
  rdfs:subClassOf gist:Category ;
  skos:prefLabel "Risk Level"@en ;
  skos:definition "A Category enumerating the assessed risk level of a planned Mission."@en .

afmro:LowRisk       a afmro:RiskLevel ; skos:prefLabel "Low"@en .
afmro:ModerateRisk  a afmro:RiskLevel ; skos:prefLabel "Moderate"@en .
afmro:HighRisk      a afmro:RiskLevel ; skos:prefLabel "High"@en .
afmro:CriticalRisk  a afmro:RiskLevel ; skos:prefLabel "Critical"@en .

#####################################################################
# Domain classes — extending gist 14's upper-level distinctions.
#####################################################################

afmro:Aircraft a owl:Class ;
  rdfs:subClassOf gist:Equipment ;
  rdfs:subClassOf [ a owl:Restriction ;
    owl:onProperty gist:isCategorizedBy ;
    owl:onClass afmro:AircraftCategory ;
    owl:qualifiedCardinality "1"^^xsd:nonNegativeInteger ] ;
  rdfs:subClassOf [ a owl:Restriction ;
    owl:onProperty afmro:operatedBy ;
    owl:onClass afmro:Squadron ;
    owl:qualifiedCardinality "1"^^xsd:nonNegativeInteger ] ;
  rdfs:subClassOf [ a owl:Restriction ;
    owl:onProperty afmro:stationedAt ;
    owl:onClass afmro:Base ;
    owl:qualifiedCardinality "1"^^xsd:nonNegativeInteger ] ;
  rdfs:subClassOf [ a owl:Restriction ;
    owl:onProperty afmro:hasReadiness ;
    owl:onClass afmro:ReadinessState ;
    owl:minQualifiedCardinality "1"^^xsd:nonNegativeInteger ] ;
  rdfs:subClassOf [ a owl:Restriction ;
    owl:onProperty afmro:hasDirectPart ;
    owl:onClass afmro:Component ;
    owl:minQualifiedCardinality "1"^^xsd:nonNegativeInteger ] ;
  skos:prefLabel "Aircraft"@en ;
  skos:definition "A piece of Equipment designed for atmospheric flight, identified by an individual airframe registration. The aircraft's design type is captured through gist:isCategorizedBy pointing to an AircraftCategory instance, not through subclassing."@en .

afmro:Component a owl:Class ;
  rdfs:subClassOf gist:Component ;
  skos:prefLabel "Component"@en ;
  skos:definition "A constituent part of an Aircraft. Related to its parent Aircraft via gist:isDirectPartOf (or its inverse afmro:hasDirectPart from the Aircraft side). Examples include engines, radar sets, hardpoints, and avionics modules."@en .

afmro:Squadron a owl:Class ;
  rdfs:subClassOf gist:Organization ;
  rdfs:subClassOf [ a owl:Restriction ;
    owl:onProperty afmro:operates ;
    owl:onClass afmro:Aircraft ;
    owl:minQualifiedCardinality "1"^^xsd:nonNegativeInteger ] ;
  skos:prefLabel "Squadron"@en ;
  skos:definition "An Organization that operates one or more Aircraft."@en .

afmro:Base a owl:Class ;
  rdfs:subClassOf gist:GeoRegion ;
  skos:prefLabel "Base"@en ;
  skos:definition "A GeoRegion at which Aircraft are stationed and Squadrons are based. A military base is a defined geographic area governed by a service organisation; gist:GeoRegion (a geographical region with defined or contested boundaries) is the appropriate gist 14 alignment."@en .

afmro:Crew a owl:Class ;
  rdfs:subClassOf gist:Composite ;
  skos:prefLabel "Crew"@en ;
  skos:definition "A Composite of Persons assigned to operate an Aircraft for a specified period. gist:Composite (\"something which is made up of various parts or elements that are independently identifiable\") fits a crew well: the crew is a single addressable thing made up of independently identifiable Persons. gist:Organization was rejected because it implies structural permanence that crews do not carry."@en .

#####################################################################
# Specifications — capabilities, configurations, readiness.
#####################################################################

afmro:Capability a owl:Class ;
  rdfs:subClassOf gist:Specification ;
  rdfs:subClassOf [ a owl:Restriction ;
    owl:onProperty gist:isCategorizedBy ;
    owl:onClass afmro:CapabilityCategory ;
    owl:qualifiedCardinality "1"^^xsd:nonNegativeInteger ] ;
  skos:prefLabel "Capability"@en ;
  skos:definition "A Specification borne by an Aircraft expressing what it can do. Each Capability has a CapabilityCategory (via gist:isCategorizedBy) and may have a temporal extent."@en .

afmro:Configuration a owl:Class ;
  rdfs:subClassOf gist:Specification ;
  skos:prefLabel "Configuration"@en ;
  skos:definition "A Specification describing how an Aircraft is currently equipped — its loadout, its mission systems, its external stores. A Configuration has a temporal extent."@en .

afmro:ReadinessState a owl:Class ;
  rdfs:subClassOf gist:Specification ;
  rdfs:subClassOf [ a owl:Restriction ;
    owl:onProperty gist:isCategorizedBy ;
    owl:onClass afmro:ReadinessLevel ;
    owl:qualifiedCardinality "1"^^xsd:nonNegativeInteger ] ;
  rdfs:subClassOf [ a owl:Restriction ;
    owl:onProperty gist:occursIn ;
    owl:onClass gist:TimeInterval ;
    owl:qualifiedCardinality "1"^^xsd:nonNegativeInteger ] ;
  skos:prefLabel "Readiness State"@en ;
  skos:definition "A Specification describing an Aircraft's readiness at a moment in time. Always carries a ReadinessLevel (via gist:isCategorizedBy) and a temporal extent (via gist:occursIn)."@en .

#####################################################################
# Events and Tasks — gist's distinction between plan and occurrence.
#####################################################################

afmro:Mission a owl:Class ;
  rdfs:subClassOf gist:Event ;

  rdfs:subClassOf [ a owl:Restriction ;
    owl:onProperty gist:hasParticipant ;
    owl:onClass afmro:Aircraft ;
    owl:minQualifiedCardinality "1"^^xsd:nonNegativeInteger ] ;
  rdfs:subClassOf [ a owl:Restriction ;
    owl:onProperty gist:occursIn ;
    owl:onClass gist:TimeInterval ;
    owl:qualifiedCardinality "1"^^xsd:nonNegativeInteger ] ;
  rdfs:subClassOf [ a owl:Restriction ;
    owl:onProperty gist:hasPhysicalLocation ;
    owl:onClass afmro:Base ;
    owl:maxQualifiedCardinality "1"^^xsd:nonNegativeInteger ] ;
  rdfs:subClassOf [ a owl:Restriction ;
    owl:onProperty afmro:implementsPlan ;
    owl:onClass afmro:MissionPlan ;
    owl:maxQualifiedCardinality "1"^^xsd:nonNegativeInteger ] ;
  rdfs:subClassOf [ a owl:Restriction ;
    owl:onProperty afmro:missionCallsign ;
    owl:maxCardinality "1"^^xsd:nonNegativeInteger ] ;
  rdfs:subClassOf [ a owl:Restriction ;
    owl:onProperty afmro:missionOutcome ;
    owl:onClass afmro:MissionOutcome ;
    owl:maxQualifiedCardinality "1"^^xsd:nonNegativeInteger ] ;

  skos:prefLabel "Mission"@en ;
  skos:definition "An Event in which one or more Aircraft execute a tasked objective. A Mission is the OCCURRENCE; its plan is captured separately as a MissionPlan (a Task)."@en .

afmro:MissionPlan a owl:Class ;
  rdfs:subClassOf gist:Task ;

  rdfs:subClassOf [ a owl:Restriction ;
    owl:onProperty afmro:planFor ;
    owl:onClass afmro:Mission ;
    owl:qualifiedCardinality "1"^^xsd:nonNegativeInteger ] ;
  rdfs:subClassOf [ a owl:Restriction ;
    owl:onProperty afmro:requiresCapability ;
    owl:onClass afmro:CapabilityCategory ;
    owl:minQualifiedCardinality "1"^^xsd:nonNegativeInteger ] ;
  rdfs:subClassOf [ a owl:Restriction ;
    owl:onProperty afmro:plannedTimeWindow ;
    owl:onClass gist:TimeInterval ;
    owl:qualifiedCardinality "1"^^xsd:nonNegativeInteger ] ;
  rdfs:subClassOf [ a owl:Restriction ;
    owl:onProperty afmro:plannedParticipantType ;
    owl:onClass afmro:AircraftCategory ;
    owl:minQualifiedCardinality "1"^^xsd:nonNegativeInteger ] ;
  rdfs:subClassOf [ a owl:Restriction ;
    owl:onProperty afmro:authorisedBy ;
    owl:cardinality "1"^^xsd:nonNegativeInteger ] ;
  rdfs:subClassOf [ a owl:Restriction ;
    owl:onProperty afmro:planStatus ;
    owl:onClass afmro:PlanStatus ;
    owl:qualifiedCardinality "1"^^xsd:nonNegativeInteger ] ;
  rdfs:subClassOf [ a owl:Restriction ;
    owl:onProperty afmro:plannedOperatingArea ;
    owl:onClass afmro:Base ;
    owl:maxQualifiedCardinality "1"^^xsd:nonNegativeInteger ] ;
  rdfs:subClassOf [ a owl:Restriction ;
    owl:onProperty afmro:planRiskLevel ;
    owl:onClass afmro:RiskLevel ;
    owl:maxQualifiedCardinality "1"^^xsd:nonNegativeInteger ] ;

  skos:prefLabel "Mission Plan"@en ;
  skos:definition "A Task specifying the planned objectives, resources, routing, and required capabilities for a Mission. Distinct from the Mission itself: the plan exists before the occurrence, may exist without the occurrence, and may be revised independently."@en .

afmro:Sortie a owl:Class ;
  rdfs:subClassOf afmro:Mission ;
  skos:prefLabel "Sortie"@en ;
  skos:definition "A single mission-flight by a single Aircraft. A Mission may consist of one or more Sorties."@en .

afmro:TrainingExercise a owl:Class ;
  rdfs:subClassOf afmro:Mission ;
  skos:prefLabel "Training Exercise"@en ;
  skos:definition "A Mission whose primary purpose is the training or qualification of Crew, rather than direct operational effect."@en .

afmro:MaintenanceEvent a owl:Class ;
  rdfs:subClassOf gist:Event ;
  rdfs:subClassOf [ a owl:Restriction ;
    owl:onProperty afmro:affectsAircraft ;
    owl:onClass afmro:Aircraft ;
    owl:minQualifiedCardinality "1"^^xsd:nonNegativeInteger ] ;
  rdfs:subClassOf [ a owl:Restriction ;
    owl:onProperty gist:occursIn ;
    owl:onClass gist:TimeInterval ;
    owl:qualifiedCardinality "1"^^xsd:nonNegativeInteger ] ;
  skos:prefLabel "Maintenance Event"@en ;
  skos:definition "An Event in which a Component is repaired, replaced, inspected, or otherwise affected for sustainment purposes. Affects the ReadinessState of the parent Aircraft."@en .

afmro:MaintenanceRecord a owl:Class ;
  rdfs:subClassOf gist:Content ;
  skos:prefLabel "Maintenance Record"@en ;
  skos:definition "A Content recording the details of a MaintenanceEvent, including the technician, the parts used, and the outcome."@en .

#####################################################################
# Object properties — pure declarations (no rdfs:domain or rdfs:range).
# All cardinality and class constraints live on the bearing classes.
#####################################################################

afmro:hasDirectPart a owl:ObjectProperty ;
  owl:inverseOf gist:isDirectPartOf ;
  skos:prefLabel "has direct part"@en ;
  skos:definition "Inverse of gist:isDirectPartOf, declared so that AFMRO restrictions can read in their natural direction (\"an Aircraft has at least one Component\") rather than requiring an anonymous inverse property expression."@en .

afmro:operatedBy a owl:ObjectProperty ;
  skos:prefLabel "operated by"@en ;
  skos:definition "Relates an Aircraft to the Squadron that operates it."@en .

afmro:operates a owl:ObjectProperty ;
  owl:inverseOf afmro:operatedBy ;
  skos:prefLabel "operates"@en ;
  skos:definition "Relates a Squadron to an Aircraft it operates. Inverse of operatedBy."@en .

afmro:stationedAt a owl:ObjectProperty ;
  skos:prefLabel "stationed at"@en ;
  skos:definition "Relates an Aircraft to the Base at which it is currently stationed."@en .

afmro:hasReadiness a owl:ObjectProperty ;
  skos:prefLabel "has readiness"@en ;
  skos:definition "Relates an Aircraft to its current ReadinessState."@en .

afmro:hasCapability a owl:ObjectProperty ;
  skos:prefLabel "has capability"@en ;
  skos:definition "Relates an Aircraft to a Capability it currently bears."@en .

afmro:hasConfiguration a owl:ObjectProperty ;
  skos:prefLabel "has configuration"@en ;
  skos:definition "Relates an Aircraft to its current Configuration."@en .

afmro:planFor a owl:ObjectProperty ;
  skos:prefLabel "plan for"@en ;
  skos:definition "Relates a MissionPlan to the Mission it plans."@en .

afmro:implementsPlan a owl:ObjectProperty ;
  owl:inverseOf afmro:planFor ;
  skos:prefLabel "implements plan"@en ;
  skos:definition "Relates a Mission (the occurrence) to the MissionPlan it implements. Inverse of planFor."@en .

afmro:requiresCapability a owl:ObjectProperty ;
  skos:prefLabel "requires capability"@en ;
  skos:definition "Relates a MissionPlan to the categories of Capability the planned Mission requires."@en .

afmro:plannedTimeWindow a owl:ObjectProperty ;
  skos:prefLabel "planned time window"@en ;
  skos:definition "Relates a MissionPlan to the planned TimeInterval for the mission. Distinct from the Mission's actual gist:occursIn."@en .

afmro:plannedOperatingArea a owl:ObjectProperty ;
  skos:prefLabel "planned operating area"@en ;
  skos:definition "Relates a MissionPlan to the Base where the mission is intended to take place. May differ from the Mission's actual gist:hasPhysicalLocation."@en .

afmro:plannedParticipantType a owl:ObjectProperty ;
  skos:prefLabel "planned participant type"@en ;
  skos:definition "Relates a MissionPlan to the AircraftCategory instances representing the types of aircraft committed to the mission."@en .

afmro:authorisedBy a owl:ObjectProperty ;
  skos:prefLabel "authorised by"@en ;
  skos:definition "Relates a MissionPlan to the Person or Organization authorising the plan."@en .

afmro:planStatus a owl:ObjectProperty ;
  skos:prefLabel "plan status"@en ;
  skos:definition "Relates a MissionPlan to a PlanStatus category instance."@en .

afmro:planRiskLevel a owl:ObjectProperty ;
  skos:prefLabel "plan risk level"@en ;
  skos:definition "Relates a MissionPlan to a RiskLevel category instance."@en .

afmro:missionOutcome a owl:ObjectProperty ;
  skos:prefLabel "mission outcome"@en ;
  skos:definition "Relates a Mission to a MissionOutcome category instance representing the result of the mission."@en .

afmro:affectsAircraft a owl:ObjectProperty ;
  skos:prefLabel "affects aircraft"@en ;
  skos:definition "Relates a MaintenanceEvent to the Aircraft it affects."@en .

afmro:assignedTo a owl:ObjectProperty ;
  skos:prefLabel "assigned to"@en ;
  skos:definition "Relates a Crew to the Aircraft it is assigned to operate for a given period. Custom AFMRO property because gist 14 has no isAffiliatedWith equivalent."@en .

#####################################################################
# Datatype properties
#####################################################################

afmro:missionCallsign a owl:DatatypeProperty ;
  rdfs:range xsd:string ;
  skos:prefLabel "mission callsign"@en ;
  skos:definition "An operational identifier used in voice and data communications during the mission. Note: rdfs:range is acceptable for datatype properties because the surprising-inference concern with rdfs:range applies to classes, not XSD datatypes."@en .
