@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 obs:   <https://w3id.org/fm/observable#> .
@prefix dep:   <https://w3id.org/fm/dependency#> .
@prefix match: <https://w3id.org/fm/match#> .

#################################################################
#    Match ontology
#################################################################

<https://w3id.org/fm/match> 
    rdf:type owl:Ontology ;
    owl:versionIRI <https://w3id.org/fm/match/1.0.1>;
    owl:versionInfo "1.0.1" ;
    rdfs:label "The Match Ontology"@en ;
    rdfs:comment "An ontology of Matches, allowing to specify and qualify associations"@en;
    vann:preferredNamespaceUri    "https://w3id.org/fm/match#" ;
    vann:preferredNamespacePrefix "match" ;
    dct:created  "2025-10-10"^^xsd:date ;
    dct:modified "2025-10-29"^^xsd:date ;
    dct:issued   "2024-10-29"^^xsd:date ;
    dce:title "The Match Ontology"@en ;
    rdfs:label "The Match Ontology"@en ;
    dct:license <https://creativecommons.org/licenses/by/4.0/>;
    dct:subject "upper"@en;
    dct:subject "meta"@en;

    dce:abstract '''
The Match ontology allows to describe matches between classes, or, equivalently, to define derived associations. 
A Match Definition specifies 2 or more Roles.
A Role defines a participant in the Match, by specifying a Class and a Property. 
A participant of a Match in a Role
must belong to the Class specified by the Role, and is
associated to the match instance by the property specified by the Role.
A Match defines conditions (Constraints) that must be satisfied by the match participants. 
These conditions use
as context a Match instance, and therefore all properties available on the instance. 
Extra derived properties can be specified by Dependencies.
'''@en;

    widoco:introduction '''
The Match ontology is a vocabulary for describing derived associations, or matches 
between classes, as for instance capabilities of manufacturing resources for manufacturing 
processes.

A Match defines roles for evey participant in the Match, conditions that the participants 
must satisfy, and optionally derived properties that will be calculated for every match instance.
'''@en;

    dce:description '''
The Match Ontology allows to specify Matches between set of Classes.

A Match is defined by 2 or more Roles. A Role of a participant in a Match defines a Class
to which the participant must belong and a Property, that will be used to associate the 
participant to the match instace.

A Match defines 0 or more conditions that the participants of the Match must fulfill. 
These conditions are Constraints applied to a match instance, that will take as inputs
the participants using the role properties.

A Match defines 0 or more derived properties. These properties will be calculated for every
match instance and can be used, either as intermediary result in the condition logic, or for 
qualifying the match with extra (derived) information.

The following concepts are formalized:
- **Role**: a participant definition 
- **MatchDefinition**: a match definition
- **Match** the base class of all match definitions

```mermaid
classDiagram 
  direction BT
  
  namespace UpperOntology {
    class Class:::owl
    class Property:::owl 
    class Dependency
    class Constraint
    class MatchDefinition
    class Role
  }  

  Class <-- Property : range
  Class <-- Property : domain
  Constraint --|> Dependency
  MatchDefinition --> Role: roles
  MatchDefinition --> Constraint: condition
  MatchDefinition --> Dependency: derived
  Role --> Class: roleType
  Role --> Property: roleProperty

  namespace DomainOntology{
    class Match
    class aMatchDef:::user

  }
  aMatchDef --|> Match
  aMatchDef --> MatchDefinition : definition

  namespace DomainData{
    class aMatch:::user
  }
  aMatch --> aMatchDef : type

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

```
'''@en.
  

#################################################################
#    MatchDefinition Role
#################################################################

match:Role
    rdf:type rdfs:Class ;
    rdfs:comment "A Role is a participant (type) in the Match definition"@en.

match:roleType 
    rdf:type    rdf:Property ;
    rdfs:domain match:Role ;
    rdfs:range  owl:Class;
    rdfs:comment "The Class of the Participant instance in that role"@en. 

match:roleProperty 
    rdf:type    rdf:Property ;
    rdfs:domain match:Role ;
    rdfs:range  owl:ObjectProperty;
    rdfs:comment "The property used for associating a participant of that role to match instance"@en. 

match:Roles
    rdf:type rdfs:Class ;
    rdfs:subClassOf rdf:List.

match:firstRole
    rdf:type rdf:Property;
    rdfs:subPropertyOf rdf:first;
    rdfs:domain match:Roles;
    rdfs:range match:Role.    

match:restRoles
    rdf:type rdf:Property;
    rdfs:subPropertyOf rdf:rest;
    rdfs:domain match:Roles;
    rdfs:range match:Roles.    

match:rolesParticipants
    rdf:type rdf:Property;
    rdfs:domain match:Roles;
    rdfs:range rdf:List;
    rdfs:comment '''The extension of a list of Role's. Associate to a subject list of Roles's matching object lists of participants; 
an object list of participants will have a matching entry for every role in the subject list; An entry in the object list matches an 
entry in the subject list if 1) it has the same index or position and 2) if the entry is in the role of the corresponding entry in the
subject list.
'''@en.    

#################################################################
#    MatchDefinition
# a match is defined
#   by a list of roles (the role of a participant in the match, associated with a property and a class)
#   by constraints  (that the match must satisfy)
#   by dependencies (1 for each derived property)
# the match will then look for associations satisfying the constraints
# when match, an instance is created and associated to the ParticipantElement
#################################################################

match:Definition
    rdf:type rdfs:Class ;
    rdfs:comment "A Match Definition specifies an association between a set of Classes"@en.

match:roles 
    rdf:type    rdf:Property ;
    rdfs:domain match:Definition ;
    rdfs:range  match:Roles;
    rdfs:comment "The list of Roles in the Match Definition"@en. 

match:condition
    rdf:type    rdf:Property ;
    rdfs:subPropertyOf obs:observableObservation;
    rdfs:domain match:Definition ;
    rdfs:range  dep:Constraint;
    rdfs:comment "The necessary conditions for the participants to have a match"@en. 

match:derived
    rdf:type    rdf:Property ;
    rdfs:subPropertyOf obs:observableObservation;
    rdfs:domain match:Definition ;
    rdfs:range  dep:Dependency;
    rdfs:comment "The dependencies in the Match Definition, specifying derived fields"@en. 

#################################################################
#    Match
#################################################################

# elements of MatchDefinitions are subclasses of Match
match:Definition rdfs:subClassOf [
    rdf:type owl:Restriction ;
    owl:onProperty rdfs:subClassOf;
    owl:hasValue match:Match;
    rdfs:comment "The set of owl classes that are subclassess of Match"@en 
].

match:Match
    rdf:type rdfs:Class ;
    rdfs:comment "A Match is a n-ary association of instances satisfying some matching logic"@en.

match:definition
    rdf:type owl:ObjectProperty;
    rdfs:subPropertyOf rdf:type;
    rdfs:range match:Definition;
    rdfs:comment '''The specialization of rdf:type for matches between an actual match element
    (a match:Match) and its type (a match:Definition).
    '''@en.

# Q: do we need the participants relation?
# A: this list is used when creating the instances
#    for every instance of participant lists, 1 match is created
# Q: can we do without the list instances?
match:participants
    rdf:type owl:ObjectProperty;
    rdfs:domain match:Match;
    rdfs:range match:Participants;
    rdfs:comment ''' The participants in a match, stored in a rdf:list, in the sequence of the 
    roles of the match:Defintion
    '''@en.

# Q: do we need a types list?
match:Participants
    rdf:type rdfs:Class ;
    rdfs:subClassOf rdf:List;
    rdfs:comment "A participant in a match, with a role, corresponding to a Role of the Definition"@en.

match:firstParticipant
    rdf:type rdf:Property;
    rdfs:subPropertyOf rdf:first;
    rdfs:domain match:Participants.    

match:restParticipants
    rdf:type rdf:Property;
    rdfs:subPropertyOf rdf:rest;
    rdfs:domain match:Participants;
    rdfs:range match:Participants.    


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