@prefix : <https://ontology.inferal.com/modules/versioning/> .
@prefix dcterms: <http://purl.org/dc/terms/> .
@prefix mod: <https://w3id.org/mod#> .
@prefix ord: <https://ontology.inferal.com/modules/ordering/> .
@prefix owl: <http://www.w3.org/2002/07/owl#> .
@prefix pubacc: <https://ontology.inferal.com/modules/publication-access/> .
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
@prefix rng: <https://ontology.inferal.com/modules/range/> .
@prefix spdx-sw: <https://spdx.org/rdf/3.0.1/terms/Software/> .
@prefix swrl: <http://www.w3.org/2003/11/swrl#> .
@prefix swrlb: <http://www.w3.org/2003/11/swrlb#> .
@prefix vann: <http://purl.org/vocab/vann/> .
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .

:
    a owl:Ontology, pubacc:PublicationManagedOntology ;
    dcterms:accessRights pubacc:PublicAccess ;
    owl:imports ord: ;
    owl:imports rng: ;
    dcterms:title "Versioning Ontology" ;
    dcterms:description "Terms for version identifiers, version ordering contexts, version ranges, component-based comparison, and range membership." ;
    dcterms:license <https://creativecommons.org/licenses/by/4.0/> ;
    dcterms:source ord:, rng: ;
    vann:preferredNamespacePrefix "ver" ;
    vann:preferredNamespaceUri "https://ontology.inferal.com/modules/versioning/" ;
    mod:status "draft" ;
    rdfs:comment "This module specializes the Inferal ordering and range modules for version identifiers. It remains independent from statement metadata while providing version-specific lexical fields, component fields, comparison rules, and version range aliases." ;
    owl:versionInfo "0.1.0" .

:VersionIdentifier
    a rdfs:Class ;
    rdfs:subClassOf ord:Comparable ;
    rdfs:label "Version identifier" ;
    rdfs:comment "A comparable version token in a specific ordering scheme, such as numeric component versions, calendar versions, SPDX spec versions, or a project-defined release order." ;
    rdfs:seeAlso spdx-sw:packageVersion .

:ComponentVersionIdentifier
    a rdfs:Class ;
    rdfs:subClassOf :VersionIdentifier ;
    rdfs:label "component version identifier" ;
    rdfs:comment "A version identifier normalized into numeric major, minor, and patch components. This class covers X.Y and X.Y.Z forms by treating X.Y as patch 0. Suffixes can be retained for display or provenance, but the supplied component ordering rules ignore suffix values." .

:VersionOrdering
    a rdfs:Class ;
    rdfs:subClassOf ord:Ordering ;
    rdfs:label "version ordering" ;
    rdfs:comment "A named ordering scheme that gives version identifiers a shared comparison context. Comparison edges must stay inside one ordering context." .

:NumericComponentOrdering
    a rdfs:Class ;
    rdfs:subClassOf :VersionOrdering ;
    rdfs:label "numeric component ordering" ;
    rdfs:comment "An ordering over numeric major, minor, and patch components. It is intentionally not full SemVer precedence: optional suffixes after a hyphen are ignored." .

:VersionRange
    a rdfs:Class ;
    rdfs:subClassOf rng:Range ;
    rdfs:label "version range" ;
    rdfs:comment "A possibly open-ended interval over version identifiers. Missing lower or upper bounds represent unbounded sides; inclusivity flags state whether present bounds are included." .

:versionText
    a rdf:Property ;
    rdfs:label "version text" ;
    rdfs:comment "The lexical version string as supplied by the source system." ;
    rdfs:domain :VersionIdentifier ;
    rdfs:range xsd:string .

:versionMajor
    a rdf:Property ;
    rdfs:label "version major component" ;
    rdfs:comment "Numeric major component for component-based version comparison." ;
    rdfs:domain :ComponentVersionIdentifier ;
    rdfs:range xsd:integer .

:versionMinor
    a rdf:Property ;
    rdfs:label "version minor component" ;
    rdfs:comment "Numeric minor component for component-based version comparison." ;
    rdfs:domain :ComponentVersionIdentifier ;
    rdfs:range xsd:integer .

:versionPatch
    a rdf:Property ;
    rdfs:label "version patch component" ;
    rdfs:comment "Numeric patch component for component-based version comparison. Authors should normalize X.Y to patch 0." ;
    rdfs:domain :ComponentVersionIdentifier ;
    rdfs:range xsd:integer .

:versionSuffix
    a rdf:Property ;
    rdfs:label "version suffix" ;
    rdfs:comment "Optional suffix after a hyphen in a version string, retained for provenance or display but ignored by the supplied numeric component comparison SWRL rules." ;
    rdfs:domain :ComponentVersionIdentifier ;
    rdfs:range xsd:string .

:inVersionOrdering
    a rdf:Property ;
    rdfs:subPropertyOf ord:inOrdering ;
    rdfs:label "in version ordering" ;
    rdfs:comment "Associates a version identifier with the ordering scheme in which it can be compared." ;
    rdfs:domain :VersionIdentifier ;
    rdfs:range :VersionOrdering .

:greaterThanVersion
    a rdf:Property ;
    rdfs:subPropertyOf ord:greaterThan ;
    rdfs:label "greater than version" ;
    rdfs:comment "States that the subject version identifier sorts after the object version identifier in the same ordering scheme. Transitivity covers: if B > A and C > B, then C > A." ;
    rdfs:domain :VersionIdentifier ;
    rdfs:range :VersionIdentifier .

:lessThanVersion
    a rdf:Property ;
    rdfs:subPropertyOf ord:lessThan ;
    rdfs:label "less than version" ;
    rdfs:comment "States that the subject version identifier sorts before the object version identifier in the same ordering scheme." ;
    rdfs:domain :VersionIdentifier ;
    rdfs:range :VersionIdentifier .

:lowerBound
    a rdf:Property ;
    rdfs:subPropertyOf rng:lowerBound ;
    rdfs:label "lower bound" ;
    rdfs:comment "Lower version bound for a version range. If omitted, the range has no lower bound." ;
    rdfs:domain :VersionRange ;
    rdfs:range :VersionIdentifier .

:upperBound
    a rdf:Property ;
    rdfs:subPropertyOf rng:upperBound ;
    rdfs:label "upper bound" ;
    rdfs:comment "Upper version bound for a version range. If omitted, the range has no upper bound." ;
    rdfs:domain :VersionRange ;
    rdfs:range :VersionIdentifier .

:lowerInclusive
    a rdf:Property ;
    rdfs:subPropertyOf rng:lowerInclusive ;
    rdfs:label "lower inclusive" ;
    rdfs:comment "True when the lower bound is included in the version range." ;
    rdfs:domain :VersionRange ;
    rdfs:range xsd:boolean .

:upperInclusive
    a rdf:Property ;
    rdfs:subPropertyOf rng:upperInclusive ;
    rdfs:label "upper inclusive" ;
    rdfs:comment "True when the upper bound is included in the version range." ;
    rdfs:domain :VersionRange ;
    rdfs:range xsd:boolean .

:includesVersion
    a rdf:Property ;
    rdfs:subPropertyOf rng:includesValue ;
    rdfs:label "includes version" ;
    rdfs:comment "Materialized or queried relation from a version range to a version identifier that falls inside the range. The Versioning specification defines the reference membership query for open, closed, and half-open ranges." ;
    rdfs:domain :VersionRange ;
    rdfs:range :VersionIdentifier .

:swrlNewer a swrl:Variable .
:swrlOlder a swrl:Variable .
:swrlOrdering a swrl:Variable .
:swrlNewerMajor a swrl:Variable .
:swrlOlderMajor a swrl:Variable .
:swrlNewerMinor a swrl:Variable .
:swrlOlderMinor a swrl:Variable .
:swrlNewerPatch a swrl:Variable .
:swrlOlderPatch a swrl:Variable .

:componentMajorGreaterRule
    a swrl:Imp ;
    rdfs:label "major component version ordering rule" ;
    rdfs:comment "SWRL rule template for numeric component comparison: when two version identifiers share an ordering and the newer major component is greater, infer ver:greaterThanVersion." ;
    swrl:body (
        [ a swrl:ClassAtom ; swrl:classPredicate :ComponentVersionIdentifier ; swrl:argument1 :swrlNewer ]
        [ a swrl:ClassAtom ; swrl:classPredicate :ComponentVersionIdentifier ; swrl:argument1 :swrlOlder ]
        [ a swrl:IndividualPropertyAtom ; swrl:propertyPredicate :inVersionOrdering ; swrl:argument1 :swrlNewer ; swrl:argument2 :swrlOrdering ]
        [ a swrl:IndividualPropertyAtom ; swrl:propertyPredicate :inVersionOrdering ; swrl:argument1 :swrlOlder ; swrl:argument2 :swrlOrdering ]
        [ a swrl:ClassAtom ; swrl:classPredicate :NumericComponentOrdering ; swrl:argument1 :swrlOrdering ]
        [ a swrl:DatavaluedPropertyAtom ; swrl:propertyPredicate :versionMajor ; swrl:argument1 :swrlNewer ; swrl:argument2 :swrlNewerMajor ]
        [ a swrl:DatavaluedPropertyAtom ; swrl:propertyPredicate :versionMajor ; swrl:argument1 :swrlOlder ; swrl:argument2 :swrlOlderMajor ]
        [ a swrl:BuiltinAtom ; swrl:builtin swrlb:greaterThan ; swrl:arguments ( :swrlNewerMajor :swrlOlderMajor ) ]
    ) ;
    swrl:head (
        [ a swrl:IndividualPropertyAtom ; swrl:propertyPredicate :greaterThanVersion ; swrl:argument1 :swrlNewer ; swrl:argument2 :swrlOlder ]
    ) .

:componentMinorGreaterRule
    a swrl:Imp ;
    rdfs:label "minor component version ordering rule" ;
    rdfs:comment "SWRL rule template for numeric component comparison: when major components are equal and the newer minor component is greater, infer ver:greaterThanVersion." ;
    swrl:body (
        [ a swrl:ClassAtom ; swrl:classPredicate :ComponentVersionIdentifier ; swrl:argument1 :swrlNewer ]
        [ a swrl:ClassAtom ; swrl:classPredicate :ComponentVersionIdentifier ; swrl:argument1 :swrlOlder ]
        [ a swrl:IndividualPropertyAtom ; swrl:propertyPredicate :inVersionOrdering ; swrl:argument1 :swrlNewer ; swrl:argument2 :swrlOrdering ]
        [ a swrl:IndividualPropertyAtom ; swrl:propertyPredicate :inVersionOrdering ; swrl:argument1 :swrlOlder ; swrl:argument2 :swrlOrdering ]
        [ a swrl:ClassAtom ; swrl:classPredicate :NumericComponentOrdering ; swrl:argument1 :swrlOrdering ]
        [ a swrl:DatavaluedPropertyAtom ; swrl:propertyPredicate :versionMajor ; swrl:argument1 :swrlNewer ; swrl:argument2 :swrlNewerMajor ]
        [ a swrl:DatavaluedPropertyAtom ; swrl:propertyPredicate :versionMajor ; swrl:argument1 :swrlOlder ; swrl:argument2 :swrlOlderMajor ]
        [ a swrl:DatavaluedPropertyAtom ; swrl:propertyPredicate :versionMinor ; swrl:argument1 :swrlNewer ; swrl:argument2 :swrlNewerMinor ]
        [ a swrl:DatavaluedPropertyAtom ; swrl:propertyPredicate :versionMinor ; swrl:argument1 :swrlOlder ; swrl:argument2 :swrlOlderMinor ]
        [ a swrl:BuiltinAtom ; swrl:builtin swrlb:equal ; swrl:arguments ( :swrlNewerMajor :swrlOlderMajor ) ]
        [ a swrl:BuiltinAtom ; swrl:builtin swrlb:greaterThan ; swrl:arguments ( :swrlNewerMinor :swrlOlderMinor ) ]
    ) ;
    swrl:head (
        [ a swrl:IndividualPropertyAtom ; swrl:propertyPredicate :greaterThanVersion ; swrl:argument1 :swrlNewer ; swrl:argument2 :swrlOlder ]
    ) .

:componentPatchGreaterRule
    a swrl:Imp ;
    rdfs:label "patch component version ordering rule" ;
    rdfs:comment "SWRL rule template for numeric component comparison: when major and minor components are equal and the newer patch component is greater, infer ver:greaterThanVersion." ;
    swrl:body (
        [ a swrl:ClassAtom ; swrl:classPredicate :ComponentVersionIdentifier ; swrl:argument1 :swrlNewer ]
        [ a swrl:ClassAtom ; swrl:classPredicate :ComponentVersionIdentifier ; swrl:argument1 :swrlOlder ]
        [ a swrl:IndividualPropertyAtom ; swrl:propertyPredicate :inVersionOrdering ; swrl:argument1 :swrlNewer ; swrl:argument2 :swrlOrdering ]
        [ a swrl:IndividualPropertyAtom ; swrl:propertyPredicate :inVersionOrdering ; swrl:argument1 :swrlOlder ; swrl:argument2 :swrlOrdering ]
        [ a swrl:ClassAtom ; swrl:classPredicate :NumericComponentOrdering ; swrl:argument1 :swrlOrdering ]
        [ a swrl:DatavaluedPropertyAtom ; swrl:propertyPredicate :versionMajor ; swrl:argument1 :swrlNewer ; swrl:argument2 :swrlNewerMajor ]
        [ a swrl:DatavaluedPropertyAtom ; swrl:propertyPredicate :versionMajor ; swrl:argument1 :swrlOlder ; swrl:argument2 :swrlOlderMajor ]
        [ a swrl:DatavaluedPropertyAtom ; swrl:propertyPredicate :versionMinor ; swrl:argument1 :swrlNewer ; swrl:argument2 :swrlNewerMinor ]
        [ a swrl:DatavaluedPropertyAtom ; swrl:propertyPredicate :versionMinor ; swrl:argument1 :swrlOlder ; swrl:argument2 :swrlOlderMinor ]
        [ a swrl:DatavaluedPropertyAtom ; swrl:propertyPredicate :versionPatch ; swrl:argument1 :swrlNewer ; swrl:argument2 :swrlNewerPatch ]
        [ a swrl:DatavaluedPropertyAtom ; swrl:propertyPredicate :versionPatch ; swrl:argument1 :swrlOlder ; swrl:argument2 :swrlOlderPatch ]
        [ a swrl:BuiltinAtom ; swrl:builtin swrlb:equal ; swrl:arguments ( :swrlNewerMajor :swrlOlderMajor ) ]
        [ a swrl:BuiltinAtom ; swrl:builtin swrlb:equal ; swrl:arguments ( :swrlNewerMinor :swrlOlderMinor ) ]
        [ a swrl:BuiltinAtom ; swrl:builtin swrlb:greaterThan ; swrl:arguments ( :swrlNewerPatch :swrlOlderPatch ) ]
    ) ;
    swrl:head (
        [ a swrl:IndividualPropertyAtom ; swrl:propertyPredicate :greaterThanVersion ; swrl:argument1 :swrlNewer ; swrl:argument2 :swrlOlder ]
    ) .
