@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
@prefix owl: <http://www.w3.org/2002/07/owl#> .

@prefix vann:   <http://purl.org/vocab/vann/> .
@prefix voaf:   <http://purl.org/vocommons/voaf#> .
@prefix dce:    <http://purl.org/dc/elements/1.1/> .
@prefix dct:    <http://purl.org/dc/terms/> .
@prefix widoco:	<https://w3id.org/widoco/vocab#>.

@prefix thing: <https://w3id.org/fm/thing#> .
@prefix resource: <https://w3id.org/fm/resource#> .
@prefix product: <https://w3id.org/fm/product#> .

@base            <https://w3id.org/fm/routing#> .
@prefix :        <https://w3id.org/fm/routing#> .
@prefix routing: <https://w3id.org/fm/routing#> .

<https://w3id.org/fm/routing> 
    rdf:type owl:Ontology ;
    vann:preferredNamespaceUri    "https://w3id.org/fm/routing#" ;
    vann:preferredNamespacePrefix "routing" ;
    owl:versionIRI <https://w3id.org/fm/routing/1.0.1>;
    owl:versionInfo "1.0.1" ;
    rdfs:label "The Routing ontology"@en ;
    rdfs:comment "An ontology of Routings, representing production and logistics decisions"@en;
    dct:created  "2026-01-21"^^xsd:date ;
    dct:modified "2026-01-21"^^xsd:date ;
    dct:issued   "2026-01-21"^^xsd:date ;
    dce:title "The Routing ontology"@en ;
    dct:license <https://creativecommons.org/licenses/by/4.0/>;
    dct:subject "top"@en;
    dct:subject "manufacturing"@en;

    dce:abstract '''
A Routing is a decision involving Prouducts and Resources. Products are either consumed
or produced by a Routing. Resources are reserved by a Routing.
A routing can be a production process, a logistics action. A routing can also be an aggregation
of actions at some level (company, region) involving aggregated products and resources.
Routing can have an hierarchical structure. Routing can be defined and instantiated
'''@en;

    widoco:introduction '''
A production process (a bill of process) defines the production of 1 or several products. Its
execution requires input products that will be consumed and resources that will be reserved. 
A production process is a Routing.

A product transport will reserve resources (vehicle, personal), will make product unavailabe at 
the start location (read: consume), and will make product availabe that the end location (read 
product). A transport is a Routing.
'''@en;

    dce:description '''
## Concept Routing

A Routing is an activity (to be decided)
- that is executed at some level
- that consumes Products at some level (number of units)
- that produces Products at some level (number of units)
- that uses (or reserves) Resources at some level (number of hours)
     
A Routing may have an hierarchical structure:
- subelements are other activities to be executed

A collection of identical Routings will share a common Definition:
- the Routing definition is the description of what is about to be executed
- the Routing entity is a particular execution, planned or executed

The following concepts are defined in this ontology:
- a **Routing** is an activity 
  - generating Product consumption
  - generating Product production
  - generating Resource reservation
- a **Flow** is a quantity of Product consumed or produced by a Routing
- a **Reservation** is a capacity of Resource reserved by a Routing

```mermaid
classDiagram
    class Routing
    class Flow {
        flowQuantity: real
        flowSense: -1, +1
    }
    class Reservation {
        reservedQuantity: real
    }

    Reservation --> Resource: reservedResource
    Flow --> Product: flowProduct

    Routing o--> Flow : inputFlow
    Routing o--> Flow : outputFlow
    Routing o--> Reservation: reservation

    class  Product:::other
    class  Resource:::other

    classDef default fill:#f96,color:black
    classDef other fill:#e9edc9,color:black
    classDef user fill:white,color:black
```

## Concept Capability

A capability is an effect to be performed that is necessary for the execution of the activity (routing), as for instance painting, milling, lifting, moving. The expression of the activity is independent of the provider of the resource.

The following concepts are defined in this ontology:
- a **Capability** is some effect to be performed for the execution of the activity
  - a capability is required by a Routing
  - a capability is provided by a Resource
- a **CapabilityProvider** is an entity providing capability
  - e.g. a manufacturing resource
  - e.g. a supplier offering that capability
- a **CapabilityImplementation** is an implementation of a capability by a Provider
  - does not depend on the Routing, but only on the Resource
  - qualifies the Capability provided by the Resource
    - so reifies the association 'provides(Provider Capability)'
  - e.g. a supplier recommendation for a given capability request
  - e.g. a Resource capable of providing the capability

```mermaid
classDiagram
    class Routing

    class Capability {
        kind: Capability
    }
    Routing o--> Capability : capabilityRequired
    CapabilityProvider o--> CapabilityImplementation : capabilityImplementation

    class  Resource:::other
    Resource --|> CapabilityProvider
    class CapabilityImplementation {
        reservedQuantity: real
    }

    Capability "1" <-- CapabilityImplementation: capabilityProvided

    classDef default fill:#f96,color:black
    classDef other fill:#e9edc9,color:black
    classDef user fill:white,color:black
```

## Concept Location (draft, not implemented)

Concepts:
- a Location is somewhere, more or less specified
  - it can  be an area (e.g. Belgium) or a class of Locations (e.g. Harbour)
  - it cant be a concrete location, at the granularity required by the domain (e.g. an area or a gps coordinated)
  - here the distinction between definition and entity is not that clear cut
  - this is not a problem: not everything must be defined
- a flow is a creation or a destruction of Product at some Location
- a reservation is the usage of a Resource (or a loss of availability), 
  - starting at some location (where it is no longer available)
  - ending at some location (where it is available again)
- a LocatedProduct is some Product located at some Location  

```mermaid
classDiagram
    class Routing
    Routing --> Location : routingStart
    Routing --> Location : routingEnd

    Routing o--> Flow : inputFlow
    Routing o--> Flow : outputFlow
    Routing o--> Reservation: reservation

    class Flow {
        flowQuantity: real
        flowSense: -1, +1
    }
    class Reservation {
        reservedQuantity: real
    }

    Reservation --> Resource: reservedResource
    Reservation --> Location : reservationStart
    Reservation --> Location : reservationEnd
    Flow --> Product: flowProduct
    Flow --> Location: flowLocation
    Flow --> LocatedProduct: flowLocatedProduct

    class  Product:::other
    class  Resource:::other
    class  Location:::other
    class  LocatedProduct:::other
    LocatedProduct --> Location: location
    LocatedProduct --> Product: product

    classDef default fill:#f96,color:black
    classDef other fill:#e9edc9,color:black
    classDef user fill:white,color:black
```

With the invariants
- the input flow location is the routing start location, if set
- the output flow location is the routing end location, if set
- the reservation start location is the routing start location, if set
- the reservation end location is the routing end location, if set
- the flow LocatedProduct Product is the flow Product
- the flow LocatedProduct Location is the flow Location

We have:
- either the routing start/end location is set and all the rest can be inferred
- or the routing start/end is not set (nor inferred)
  - either the flow location and product are set and the LocatedProduct is inferred
  - or the LocatedProduct is set and the flow Product/Location are inferred
- this holds for the start of for the end or for both

We would have the rules.

Invariant flow routing start location 
```n3
{
  ?routing :routingStart ?location
  ?routing :inputFlow ?inputflow
}=>{
  ?inputFlow :flowLocation ?location
}
```

Invariant reservation routing start location 
```n3
{
  ?routing :routingStart ?location
  ?routing :reservation ?reservation
}=>{
  ?reservation :reservationStart ?location
}
```

Invariant flow located product

```n3
{
  ?flow :flowLocatedProduct ?locatedProduct
  ?locatedProduct :product ?product
  ?locatedProduct :location ?location
}=>{
  ?flow :flowLocation ?location
  ?flow :flowProduct ?product
}
```

```n3
{
  ?flow :flowLocation ?location
  ?flow :flowProduct ?product
  ?locatedProduct :product ?product
  ?locatedProduct :location ?location
}=>{
  ?flow :flowLocatedProduct ?locatedProduct
}
```

Alternatively, all these rules (but the last one) can be expressed by OWL statements, using owl:propertyChainAxiom.

This ontology allows:
- to work with locations at routing or at flow/reservation level.
- to work with LocatedProduct or not
'''@en.  

###############################################################################
# Routing entities
###############################################################################
routing:Entity
    rdf:type owl:Class;
    rdfs:subClassOf thing:Entity;
    rdfs:comment '''A Routing is something executed, consuming and producing Products, reserving Resources'''@en.

routing:SubEntity
    rdf:type owl:Class;
    rdfs:subClassOf thing:SubEntity.

routing:subEntity
    rdf:type owl:ObjectProperty;
    rdfs:domain routing:Entity;
    rdfs:range routing:SubEntity.

routing:subEntityEntity
    rdf:type owl:ObjectProperty;
    rdfs:subPropertyOf thing:subEntityEntity;
    rdf:type owl:FunctionalProperty;
    rdfs:domain routing:SubEntity;
    rdfs:range routing:Entity.

routing:hasSubEntity
    rdf:type owl:ObjectProperty;
    rdfs:subPropertyOf thing:hasSubEntity;
    rdfs:domain routing:Entity;
    rdfs:range routing:Entity;
    owl:propertyChainAxiom (
         routing:subEntity 
         routing:subEntityEntity
    ).

###############################################################################
# Routing definitions
###############################################################################
routing:entityDefinition 
    rdf:type owl:ObjectProperty;
    rdfs:subPropertyOf thing:entityDefinition;
    rdfs:domain routing:Entity;
    rdfs:range routing:Definition.

routing:Definition
    rdf:type owl:Class;
    rdfs:subClassOf routing:Entity;
    rdfs:subClassOf thing:Definition.

routing:subEntityDefinition 
    rdf:type owl:ObjectProperty;
    rdfs:subPropertyOf thing:subEntityDefinition;
    rdfs:domain routing:SubEntity;
    rdfs:range routing:SubDefinition.

routing:SubDefinition
    rdf:type owl:Class;
    rdfs:subClassOf routing:SubEntity;
    rdfs:subClassOf thing:SubDefinition.

routing:subDefinition
    rdf:type owl:ObjectProperty;
    rdfs:subPropertyOf thing:subDefinition;
    rdfs:domain routing:Definition;
    rdfs:range routing:SubDefinition.

routing:subDefinitionDefinition
    rdf:type owl:ObjectProperty;
    rdfs:subPropertyOf thing:subDefinitionDefinition;
    rdf:type owl:FunctionalProperty;
    rdfs:domain routing:SubDefinition;
    rdfs:range routing:Definition.

routing:subDefinitionQuantity
    rdf:type owl:ObjectProperty;
    rdfs:domain routing:SubDefinition;
    rdfs:range xsd:decimal.

routing:hasSubDefinition
    rdf:type owl:ObjectProperty;
    rdfs:subPropertyOf thing:hasSubDefinition;
    rdfs:domain routing:Definition;
    rdfs:range routing:Definition;
    owl:propertyChainAxiom (
         routing:subDefinition 
         routing:subDefinitionDefinition
    ).

###############################################################################
# Routing products
###############################################################################
routing:flowDefinition
    rdf:type owl:ObjectProperty;
    rdfs:domain routing:Definition;
    rdfs:range routing:FlowDefinition.

routing:inputDefinition
    rdf:type owl:ObjectProperty;
    rdfs:subPropertyOf routing:flowDefinition.

routing:outputDefinition
    rdf:type owl:ObjectProperty;
    rdfs:subPropertyOf routing:flowDefinition.

routing:FlowDefinition
    rdf:type owl:Class;
    rdfs:comment '''A flow of Products created by a unit execution of this routing'''@en.

routing:flowProduct
    rdf:type owl:ObjectProperty;
    rdfs:domain routing:FlowDefinition;
    rdfs:range product:Definition.

routing:flowQuantity
    rdf:type owl:DatatypeProperty;
    rdfs:domain routing:FlowDefinition;
    rdfs:range xsd:decimal.

routing:flowSense
    rdf:type owl:DatatypeProperty;
    rdfs:domain routing:FlowDefinition;
    rdfs:range [ 
        owl:oneOf (
            "1.0"^^xsd:decimal 
            "-1.0"^^xsd:decimal 
        ) 
    ].

###############################################################################
# Routing resources
###############################################################################
routing:reservationDefinition
    rdf:type owl:ObjectProperty;
    rdfs:domain routing:Definition;
    rdfs:range routing:ReservationDefinition.

routing:ReservationDefinition
    rdf:type owl:Class;
    rdfs:comment '''A resource reservation created by a unit execution of this routing'''@en.

routing:reservationResource
    rdf:type owl:ObjectProperty;
    rdfs:domain routing:ReservationDefinition;
    rdfs:label "reservedResource";
    rdfs:range resource:Definition.

routing:reservationQuantity
    rdf:type owl:DatatypeProperty;
    rdfs:domain routing:RoutingReservationDefinition;
    rdfs:range xsd:decimal;
    rdfs:label "reservedQuantity";
    rdfs:comment '''Quantity of the Resource reserved of a unit execution of the Routing'''@en.

###############################################################################
# Capabilities
###############################################################################

resource:Definition 
    rdfs:subClassOf routing:CapabilityProvider.

routing:CapabilityProvider
    rdf:type owl:Class;
    rdfs:comment '''An entity (defintion) capable of providing capabilities'''@en.

routing:capabilityRequired
    rdf:type owl:ObjectProperty;
    rdfs:domain routing:Definition;
    rdfs:range routing:Capability;
    rdfs:comment '''A capability required by the Routing for a unit execution'''@en.

routing:Capability
    rdf:type owl:Class;
    rdfs:comment '''An effect required by a Routing and provided by a Resource (or some other provider)'''@en.

routing:capabilityImplementation
    rdf:type owl:ObjectProperty;
    rdfs:domain routing:CapabilityProvider;
    rdfs:range routing:CapabilityImplementation;
    rdfs:comment '''A capability provided by the Resource'''@en.

routing:CapabilityImplementation
    rdf:type owl:Class;
    rdfs:comment '''An implementation providing capability for this Resource (a reified provided capability)'''@en.

routing:capabilityProvided
    rdf:type owl:ObjectProperty;
    rdfs:domain routing:CapabilityImplementation;
    rdfs:range routing:Capability;
    rdfs:comment '''The capability provided by the Resource for this implementation'''@en.

routing:capabilityImplementationQuantity
    rdf:type owl:ObjectProperty;
    rdfs:domain routing:CapabilityImplementation;
    rdfs:range xsd:decimal;
    rdfs:label "reservedQuantity";
    rdfs:comment '''The amount of Resource reserved (a duration) for a unit execution of the Routing'''@en.

# Serialization annotations added by generate_docs.py
<https://w3id.org/fm/routing>
    <https://w3id.org/widoco/vocab#turtleSerialization> "routing.ttl" ;
    <https://w3id.org/widoco/vocab#rdfxmlSerialization> "routing.rdf" ;
    <https://w3id.org/widoco/vocab#ntSerialization> "routing.nt" ;
    <https://w3id.org/widoco/vocab#jsonldSerialization> "routing.jsonld" .
