@prefix geom-coord: <https://comp-rob2b.github.io/metamodels/geometry/coordinates#> .
@prefix geom-path: <https://secorolab.github.io/metamodels/geometry/path#> .
@prefix qkind: <http://qudt.org/vocab/quantitykind/> .
@prefix qudt: <http://qudt.org/schema/qudt/> .
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
@prefix sh: <http://www.w3.org/ns/shacl#> .

# Geometry only: no path parameter, no timing. Traversal is geom-op-ext:PathEvaluator.

geom-path:Path
    a rdfs:Class ;
    rdfs:comment "A curve the state is constrained to follow, with no timing imposed along it (Bruyninckx, Composable and Explainable Systems of Systems, sec. 8.6). An instance carries this class alongside its kind, so that operators can require a path without enumerating the kinds." .

geom-path:LinearPath
    a rdfs:Class, sh:NodeShape ;
    rdfs:subClassOf geom-path:Path ;
    sh:targetClass geom-path:LinearPath ;
    sh:message "A linear path runs between one start and one goal pose coordinate." ;
    sh:property [ sh:path geom-path:start ; sh:minCount 1 ; sh:maxCount 1 ; sh:class geom-coord:PoseCoordinate ] ;
    sh:property [ sh:path geom-path:goal ; sh:minCount 1 ; sh:maxCount 1 ; sh:class geom-coord:PoseCoordinate ] .

geom-path:Circle
    a rdfs:Class, sh:NodeShape ;
    rdfs:subClassOf geom-path:Path ;
    sh:targetClass geom-path:Circle ;
    sh:message "A circle needs a start pose, a centre position, and the normal of its plane." ;
    sh:property [ sh:path geom-path:start ; sh:minCount 1 ; sh:maxCount 1 ; sh:class geom-coord:PoseCoordinate ] ;
    sh:property [ sh:path geom-path:center ; sh:minCount 1 ; sh:maxCount 1 ; sh:class geom-coord:PositionCoordinate ] ;
    sh:property [ sh:path geom-path:plane-normal ; sh:minCount 1 ; sh:maxCount 1 ; sh:class geom-coord:DirectionCoordinate ] .

geom-path:Arc
    a rdfs:Class, sh:NodeShape ;
    rdfs:subClassOf geom-path:Path ;
    sh:targetClass geom-path:Arc ;
    sh:message "An arc needs start and end poses, a bulge amplitude, and the normal of its plane." ;
    sh:property [ sh:path geom-path:start ; sh:minCount 1 ; sh:maxCount 1 ; sh:class geom-coord:PoseCoordinate ] ;
    sh:property [ sh:path geom-path:end ; sh:minCount 1 ; sh:maxCount 1 ; sh:class geom-coord:PoseCoordinate ] ;
    sh:property [ sh:path geom-path:amplitude ; sh:minCount 1 ; sh:maxCount 1 ; sh:node geom-path:DistanceShape ] ;
    sh:property [ sh:path geom-path:plane-normal ; sh:minCount 1 ; sh:maxCount 1 ; sh:class geom-coord:DirectionCoordinate ] .

geom-path:Helix
    a rdfs:Class, sh:NodeShape ;
    rdfs:subClassOf geom-path:Path ;
    sh:targetClass geom-path:Helix ;
    sh:message "A helix needs a start pose, a centre position, an axis, a pitch, and a revolution count." ;
    sh:property [ sh:path geom-path:start ; sh:minCount 1 ; sh:maxCount 1 ; sh:class geom-coord:PoseCoordinate ] ;
    sh:property [ sh:path geom-path:center ; sh:minCount 1 ; sh:maxCount 1 ; sh:class geom-coord:PositionCoordinate ] ;
    sh:property [ sh:path geom-path:axis ; sh:minCount 1 ; sh:maxCount 1 ; sh:class geom-coord:DirectionCoordinate ] ;
    sh:property [ sh:path geom-path:pitch ; sh:minCount 1 ; sh:maxCount 1 ; sh:node geom-path:DistanceShape ] ;
    sh:property [ sh:path geom-path:revolutions ; sh:minCount 1 ; sh:maxCount 1 ; sh:node geom-path:PositiveDimensionlessShape ] .

geom-path:Figure8
    a rdfs:Class, sh:NodeShape ;
    rdfs:subClassOf geom-path:Path ;
    sh:targetClass geom-path:Figure8 ;
    sh:message "A figure eight needs an anchor pose, a radius, the normal of its plane, and a supported form." ;
    sh:property [ sh:path geom-path:anchor ; sh:minCount 1 ; sh:maxCount 1 ; sh:class geom-coord:PoseCoordinate ] ;
    sh:property [ sh:path geom-path:radius ; sh:minCount 1 ; sh:maxCount 1 ; sh:node geom-path:PositiveDistanceShape ] ;
    sh:property [ sh:path geom-path:plane-normal ; sh:minCount 1 ; sh:maxCount 1 ; sh:class geom-coord:DirectionCoordinate ] ;
    sh:property [ sh:path geom-path:form ; sh:minCount 1 ; sh:maxCount 1 ; sh:nodeKind sh:IRI ; sh:in ( geom-path:gerono geom-path:bernoulli ) ] .

geom-path:DistanceShape
    a sh:NodeShape ;
    sh:message "This value must be a quantity whose quantity kind is distance." ;
    sh:class qudt:Quantity ;
    sh:property [ sh:path qudt:hasQuantityKind ; sh:hasValue qkind:Distance ] ;
    sh:property [ sh:path qudt:value ; sh:maxCount 1 ; sh:minInclusive 0 ] .

geom-path:DimensionlessShape
    a sh:NodeShape ;
    sh:message "This value must be a dimensionless quantity." ;
    sh:class qudt:Quantity ;
    sh:property [ sh:path qudt:hasQuantityKind ; sh:hasValue qkind:Dimensionless ] .

geom-path:PositiveDistanceShape
    a sh:NodeShape ;
    sh:node geom-path:DistanceShape ;
    sh:property [ sh:path qudt:value ; sh:minCount 1 ; sh:maxCount 1 ; sh:minExclusive 0 ] .

geom-path:PositiveDimensionlessShape
    a sh:NodeShape ;
    sh:node geom-path:DimensionlessShape ;
    sh:property [ sh:path qudt:value ; sh:minCount 1 ; sh:maxCount 1 ; sh:minExclusive 0 ] .
