Graph
draftStatus of this Document
This report was published by the User Journal Graph Community Group . It is not a W3C Standard nor is it on the W3C Standards Track. Please note that under the W3C Community Contributor License Agreement (CLA) there is a limited opt-out and other conditions apply. Learn more about W3C Community and Business Groups .
1. Overview
This module defines the vocabulary for intended user flow. It extends [UJG Core] to support structured, interactive graphs with composition through one or more child-Journey references, exported exits from nested journeys, organization tags, and reusable outgoing navigation patterns. Graph describes intended topology and possible movement; it does not prescribe execution, scheduling, condition evaluation, or event processing.
2. Terminology
Journey: A named container for local traversable user flow topology.
JourneyEntry: An explicit entry contract for a Journey.
JourneyEntryIndex: A catalogue of addressable JourneyEntry contracts that does not define traversal.
LocalVertex: An abstract local topology vertex of a Journey.
State: A discrete node in the experience (e.g., a screen, modal).
State occurrence: A concrete experienced occurrence of a State during traversal.
Transition: A structural directed edge between local vertices of a Journey.
Command: A stable semantic identity of an intentional invocation in the modeled experience.
CompositeState: A state that contains one or more child Journeys. Multiple child Journeys define independent local flows within the same composite scope.
Composite scope: The set of child Journeys referenced by one CompositeState.
JourneyExit: A terminal local graph vertex and exported completion contract declared by a Journey.
OutgoingTransition: A navigational affordance pointing to a next possible State or CompositeState.
OutgoingTransitionGroup: A reusable set of outgoing transitions that a Consumer can treat as present on multiple states (e.g., global nav).
3. LocalVertex
A LocalVertex is the abstract topology node type for the local topology of a Journey.
State and JourneyExit are sibling kinds of LocalVertex. A CompositeState is a specialized State. A JourneyExit is not a State.
A State MUST be a LocalVertex.
A CompositeState MUST be a State.
A JourneyExit MUST be a LocalVertex.
A JourneyExit MUST NOT be a State.
classDiagram class LocalVertex class State class CompositeState class JourneyExit LocalVertex <|-- State State <|-- CompositeState LocalVertex <|-- JourneyExit
LocalVertex is abstract. Documents use concrete State, CompositeState, or
JourneyExit nodes rather than serializing ordinary LocalVertex nodes.
4. State
A State is the base graph node for a discrete point in an intended user experience, such as a page, screen, modal, or other user-visible step.
Later sections define navigation affordances that can be attached to eligible states. This section defines only the base state node.
classDiagram
class State {
id
label
tags
multiInstance
} Example JSON node:
{
"@type": "State",
"@id": "urn:ujg:state:search-form",
"label": "Search form",
"tags": [
"phase:search"
]
} {
"@type": "State",
"@id": "urn:ujg:state:search-form",
"label": "Search form",
"tags": [
"phase:search"
]
} 4.1. multiInstance
multiInstance is optional. If present, it MUST be a boolean. Absence of multiInstance, or
multiInstance: false, means that the State does not declare multiple concurrent concrete
occurrences.
multiInstance: true means that one canonical State may appear as multiple concrete occurrences
within one active Journey. It MUST NOT define an occurrence count, occurrence IDs, data
source, collection logic, domain entity mapping, query, expression, or rendering behavior.
Example multi-instance state:
{
"@type": "State",
"@id": "urn:ujg:state:workshop-teaser",
"label": "Workshop teaser",
"multiInstance": true
} {
"@type": "State",
"@id": "urn:ujg:state:workshop-teaser",
"label": "Workshop teaser",
"multiInstance": true
} A Graph with this node still contains one canonical Workshop teaser State. Runtime or
application data may present multiple concrete workshop teaser occurrences.
5. Transition
A Transition is a structural directed edge between local vertices of a Journey. It models ordinary progression inside the local topology of a Journey.
A Transition is not owned by either endpoint state. It is owned by a journey through transitionRefs.
When a Transition's from value references a State with multiInstance: true, the same
Transition applies to each concrete occurrence of that state. The Transition itself remains
one stable Graph node.
The presence of multiple child Journeys in one CompositeState does not create implicit Transitions between them.
A Transition MUST be identified by an IRI, declare exactly one
from, and declare exactly oneto.A Transition MAY declare one
label.A Transition MAY reference one Command with
commandRef.When listed in a Journey's
transitionRefs,fromMUST reference a State or CompositeState in that journey'sstateRefs.When listed in a Journey's
transitionRefs,toMUST reference a State or CompositeState in that journey'sstateRefs, or a JourneyExit in that journey'sexitRefs.Transition endpoints MUST stay local to the enclosing Journey.
toEntryRefMAY be used only on parent transitions into CompositeState nodes, as defined by the boundary mapping rules below.A Transition from a State with
multiInstance: trueMUST remain one Graph node; per-instance transition properties are outside Graph.A child Journey's Transition MUST NOT connect directly to a State, CompositeState, or JourneyExit owned only by another child Journey.
classDiagram
class State
class JourneyExit
class Command
class Transition {
id
label
from
to
commandRef
}
Transition --> State : from
Transition --> State : to
Transition --> JourneyExit : to
Transition --> Command : commandRef Example JSON node:
{
"@type": "Transition",
"@id": "urn:ujg:transition:search-form-to-results",
"label": "Submit search",
"from": "urn:ujg:state:search-form",
"to": "urn:ujg:state:results",
"commandRef": "urn:ujg:command:submit-search"
} {
"@type": "Transition",
"@id": "urn:ujg:transition:search-form-to-results",
"label": "Submit search",
"from": "urn:ujg:state:search-form",
"to": "urn:ujg:state:results",
"commandRef": "urn:ujg:command:submit-search"
} Example transition from a multi-instance state:
{
"@type": "Transition",
"@id": "urn:ujg:transition:open-workshop",
"label": "Open workshop",
"from": "urn:ujg:state:workshop-teaser",
"to": "urn:ujg:state:workshop-detail"
} {
"@type": "Transition",
"@id": "urn:ujg:transition:open-workshop",
"label": "Open workshop",
"from": "urn:ujg:state:workshop-teaser",
"to": "urn:ujg:state:workshop-detail"
} The open-workshop transition is declared once; it may be taken from any concrete Workshop teaser
occurrence.
6. Command
A Command identifies the stable semantic identity of an intentional invocation in the modeled experience.
A Command can be referenced by Transition and OutgoingTransition nodes through
commandRef. Multiple transitions may reference the same Command. Sharing a commandRef
establishes only common invocation identity. Graph does not assign branching, selection, ordering,
resolution, execution-result, or effect semantics to that relationship.
A Command is not a transition endpoint and does not replace Transition or
OutgoingTransition. Structural, automatic, expiry-driven, or otherwise non-invoked transitions
can remain without commandRef.
A Command MUST be identified by an IRI.
A Command MAY declare one
labeland one or moretags.A Command MUST NOT declare
from,to, branching, condition resolution, effect execution, visual representation, runtime execution, or execution-result semantics.commandRefMAY appear on a Transition or OutgoingTransition and MUST reference a Command.A Transition or OutgoingTransition MUST NOT reference more than one Command.
Absence of
commandRefmakes no claim that the transition represents an intentional invocation.
classDiagram
class Command {
id
label
tags
}
class Transition {
commandRef
}
class OutgoingTransition {
commandRef
}
Transition --> Command : commandRef
OutgoingTransition --> Command : commandRef Example JSON node:
{
"@type": "Command",
"@id": "urn:ujg:command:continue-registration",
"label": "Continue registration"
} {
"@type": "Command",
"@id": "urn:ujg:command:continue-registration",
"label": "Continue registration"
} Example transition associated with a command:
{
"@type": "Transition",
"@id": "urn:ujg:transition:start-registration",
"from": "urn:ujg:state:registration-open",
"to": "urn:ujg:state:registration-form",
"commandRef": "urn:ujg:command:start-registration"
} {
"@type": "Transition",
"@id": "urn:ujg:transition:start-registration",
"from": "urn:ujg:state:registration-open",
"to": "urn:ujg:state:registration-form",
"commandRef": "urn:ujg:command:start-registration"
} 7. Journey
A Journey is the local container for intended flow topology. It lists the experiential states that belong to the journey, the terminal exits exported by the journey, and, when present, the transitions that connect those local vertices.
Use Journey when the modeled object owns local traversal, progression, or structural order. If the model only needs to list known entry points into pages, surfaces, flows, or journeys, use JourneyEntryIndex instead.
A Journey MUST be identified by an IRI and declare at least one
entryRefsvalue and onestateRefsvalue.A Journey MAY declare one
defaultEntryRef; if present, it MUST also appear inentryRefs.entryRefs,stateRefs,transitionRefs,exitRefs, andoutgoingTransitionGroupRefsMUST reference nodes of the corresponding Graph classes.A Journey's local vertices are its
stateRefsplus itsexitRefs.stateRefsMUST describe local experiential topology, not destinations that are merely reachable through OutgoingTransition navigation.
classDiagram
class Journey {
id
label
defaultEntryRef
entryRefs
stateRefs
transitionRefs
exitRefs
}
class JourneyEntry {
id
stateRef
}
class State {
id
label
}
class JourneyExit {
id
label
}
class Transition {
id
from
to
}
Journey --> JourneyEntry : defaultEntryRef
Journey --> JourneyEntry : entryRefs
JourneyEntry --> State : stateRef
Journey --> State : stateRefs
Journey --> JourneyExit : exitRefs
Journey --> Transition : transitionRefs
Transition --> State : from
Transition --> State : to
Transition --> JourneyExit : to Example JSON node:
[
{
"@type": "Journey",
"@id": "urn:ujg:journey:site-search",
"label": "Site search",
"defaultEntryRef": "urn:ujg:entry:site-search-default",
"entryRefs": [
"urn:ujg:entry:site-search-default"
],
"stateRefs": [
"urn:ujg:state:search-form",
"urn:ujg:state:results"
],
"transitionRefs": [
"urn:ujg:transition:search-form-to-results"
]
},
{
"@type": "JourneyEntry",
"@id": "urn:ujg:entry:site-search-default",
"stateRef": "urn:ujg:state:search-form"
}
] [
{
"@type": "Journey",
"@id": "urn:ujg:journey:site-search",
"label": "Site search",
"defaultEntryRef": "urn:ujg:entry:site-search-default",
"entryRefs": [
"urn:ujg:entry:site-search-default"
],
"stateRefs": [
"urn:ujg:state:search-form",
"urn:ujg:state:results"
],
"transitionRefs": [
"urn:ujg:transition:search-form-to-results"
]
},
{
"@type": "JourneyEntry",
"@id": "urn:ujg:entry:site-search-default",
"stateRef": "urn:ujg:state:search-form"
}
] A single-state journey can omit transitionRefs:
[
{
"@type": "Journey",
"@id": "urn:ujg:journey:privacy-policy",
"label": "Privacy policy",
"defaultEntryRef": "urn:ujg:entry:privacy-policy-default",
"entryRefs": [
"urn:ujg:entry:privacy-policy-default"
],
"stateRefs": [
"urn:ujg:state:privacy-policy"
]
},
{
"@type": "JourneyEntry",
"@id": "urn:ujg:entry:privacy-policy-default",
"stateRef": "urn:ujg:state:privacy-policy"
}
] [
{
"@type": "Journey",
"@id": "urn:ujg:journey:privacy-policy",
"label": "Privacy policy",
"defaultEntryRef": "urn:ujg:entry:privacy-policy-default",
"entryRefs": [
"urn:ujg:entry:privacy-policy-default"
],
"stateRefs": [
"urn:ujg:state:privacy-policy"
]
},
{
"@type": "JourneyEntry",
"@id": "urn:ujg:entry:privacy-policy-default",
"stateRef": "urn:ujg:state:privacy-policy"
}
] A journey can also omit defaultEntryRef when no entry is semantically a general fallback. In that
case, entry selection is unresolved by Graph unless an execution or materialization context selects
exactly one listed JourneyEntry.
[
{
"@type": "Journey",
"@id": "urn:ujg:journey:workshop-detail",
"label": "Workshop detail",
"entryRefs": [
"urn:ujg:entry:workshop-registration-open",
"urn:ujg:entry:workshop-waitlist-open",
"urn:ujg:entry:workshop-registration-closed"
],
"stateRefs": [
"urn:ujg:state:workshop-registration-open",
"urn:ujg:state:workshop-waitlist-open",
"urn:ujg:state:workshop-registration-closed"
]
},
{
"@type": "JourneyEntry",
"@id": "urn:ujg:entry:workshop-registration-open",
"label": "Registration open",
"stateRef": "urn:ujg:state:workshop-registration-open"
},
{
"@type": "JourneyEntry",
"@id": "urn:ujg:entry:workshop-waitlist-open",
"label": "Waitlist open",
"stateRef": "urn:ujg:state:workshop-waitlist-open"
},
{
"@type": "JourneyEntry",
"@id": "urn:ujg:entry:workshop-registration-closed",
"label": "Registration closed",
"stateRef": "urn:ujg:state:workshop-registration-closed"
}
] [
{
"@type": "Journey",
"@id": "urn:ujg:journey:workshop-detail",
"label": "Workshop detail",
"entryRefs": [
"urn:ujg:entry:workshop-registration-open",
"urn:ujg:entry:workshop-waitlist-open",
"urn:ujg:entry:workshop-registration-closed"
],
"stateRefs": [
"urn:ujg:state:workshop-registration-open",
"urn:ujg:state:workshop-waitlist-open",
"urn:ujg:state:workshop-registration-closed"
]
},
{
"@type": "JourneyEntry",
"@id": "urn:ujg:entry:workshop-registration-open",
"label": "Registration open",
"stateRef": "urn:ujg:state:workshop-registration-open"
},
{
"@type": "JourneyEntry",
"@id": "urn:ujg:entry:workshop-waitlist-open",
"label": "Waitlist open",
"stateRef": "urn:ujg:state:workshop-waitlist-open"
},
{
"@type": "JourneyEntry",
"@id": "urn:ujg:entry:workshop-registration-closed",
"label": "Registration closed",
"stateRef": "urn:ujg:state:workshop-registration-closed"
}
] 8. JourneyEntry
A JourneyEntry is an explicit entry contract for a Journey. It identifies the local State or CompositeState where traversal begins without making that entry node part of the local transition topology.
A JourneyEntry MUST be identified by an IRI and declare exactly one
stateRef.stateRefMUST reference a State or CompositeState listed in the declaring Journey'sstateRefs.A JourneyEntry MUST be listed in exactly one Journey's
entryRefs.A JourneyEntry MUST NOT be used as a Transition endpoint.
A JourneyEntry MAY declare one
labeland one or moretags.
Top-level traversal of a Journey begins at an explicitly selected JourneyEntry. If no
entry is explicitly selected and the Journey declares defaultEntryRef, traversal begins at
the stateRef of that default entry. If neither applies, entry selection remains unresolved by
Graph.
When Graph leaves entry selection unresolved, a materialization or execution context may select one
listed entry. Consumers do not infer a default from entryRefs order, and contextual entry selection
does not change Graph topology. If no entry can be selected, traversal into that Journey remains
unresolved; that does not make the Graph invalid.
classDiagram
class Journey {
defaultEntryRef
entryRefs
stateRefs
}
class JourneyEntry {
id
stateRef
}
class State
class CompositeState
Journey --> JourneyEntry : defaultEntryRef
Journey --> JourneyEntry : entryRefs
JourneyEntry --> State : stateRef
JourneyEntry --> CompositeState : stateRef Example JSON node:
{
"@type": "JourneyEntry",
"@id": "urn:ujg:entry:site-search-default",
"label": "Default search entry",
"stateRef": "urn:ujg:state:search-form"
} {
"@type": "JourneyEntry",
"@id": "urn:ujg:entry:site-search-default",
"label": "Default search entry",
"stateRef": "urn:ujg:state:search-form"
} 9. JourneyEntryIndex
A JourneyEntryIndex is a Graph class and Core Node that acts as a catalogue of addressable JourneyEntry contracts. It is not a subclass of Journey and does not define traversal. A Consumer MUST NOT infer that indexed entries are reachable from one another, ordered as a path, or part of a parent-owned progression.
Use Journey when modeling local topology. Use JourneyEntryIndex when listing known entry points into modeled journeys. A root Journey should only be used when the root itself owns real traversal, progression, or structural order.
In common use, a JourneyEntryIndex lists default or named JourneyEntry contracts for modeled pages, surfaces, flows, or journeys. The referenced entries remain owned by their declaring Journey.
A JourneyEntryIndex MUST be identified by an IRI and declare at least one
entryRefsvalue.Each
entryRefsvalue MUST reference a JourneyEntry owned by exactly one Journey.A JourneyEntryIndex is a catalogue only: it MUST NOT own topology, entries, states, transitions, exits, outgoing groups, or child-journey mappings.
entryRefson a JourneyEntryIndex MUST NOT imply order, reachability, progression, a user path, or parent continuation.
JourneyEntryIndex is intended for top-level page maps, product surface indexes, search-result target indexes, documentation indexes, entry catalogues, and other collections of known journey entry points. Do not use JourneyEntryIndex to model page-segment order, local journey progression, child completion, runtime observations, or experience annotations.
classDiagram
class JourneyEntryIndex {
id
label
entryRefs
}
class JourneyEntry {
stateRef
}
class State
class CompositeState
JourneyEntryIndex --> JourneyEntry : entryRefs
JourneyEntry --> State : stateRef
JourneyEntry --> CompositeState : stateRef Example JSON node:
{
"@type": "JourneyEntryIndex",
"@id": "urn:ujg:index:site-pages",
"label": "Site page index",
"entryRefs": [
"urn:ujg:entry:home-page-default",
"urn:ujg:entry:search-page-default",
"urn:ujg:entry:profile-page-default"
]
} {
"@type": "JourneyEntryIndex",
"@id": "urn:ujg:index:site-pages",
"label": "Site page index",
"entryRefs": [
"urn:ujg:entry:home-page-default",
"urn:ujg:entry:search-page-default",
"urn:ujg:entry:profile-page-default"
]
} The indexed entries are known entry contracts. Their order above does not define a path from the home page to search to profile.
10. CompositeState
A CompositeState is a State that represents nested composition. It references one or more
child Journey resources through subjourneyRefs, allowing consumers to interpret those Journeys
as zoomable or nested local graphs.
The parent journey treats the CompositeState as one parent-local state. The parent journey does not list the child Journeys' states directly.
A CompositeState MUST be a State.
A CompositeState MUST declare at least one
subjourneyRefsvalue.Every
subjourneyRefsvalue MUST be an IRI that resolves to a Journey.subjourneyRefsis a set. Each resolved child Journey occurs at most once in the set.A CompositeState MUST NOT list child states directly with
stateRefs.The parent Journey MUST treat the CompositeState as one local vertex regardless of the number of child Journeys.
Every referenced child Journey defines an independent local topology scope.
The order in which
subjourneyRefsvalues are serialized MUST NOT imply priority, sequence, causality, activation order, or presentation order.A Consumer MUST NOT infer a Transition, dependency, condition, synchronization rule, or completion relationship between child Journeys from their common containment.
While an occurrence of the CompositeState is current, observations belonging to different child Journeys MAY overlap or interleave.
A child Journey's internal movement does not, by itself, change the current local position of another child Journey.
A CompositeState with one child Journey defines ordinary nested composition.
A CompositeState with more than one child Journey defines multi-Journey composition.
Each child Journey SHOULD represent one coherent behavioral concern that is independently understandable from its siblings.
Common containment of child Journeys MUST NOT by itself imply that they represent different domain entities, related domain entities, or parts of one domain aggregate.
classDiagram
class State
class CompositeState {
subjourneyRefs 1..*
}
class Journey {
stateRefs
transitionRefs
exitRefs
}
State <|-- CompositeState
Journey --> CompositeState : stateRefs
CompositeState --> Journey : subjourneyRefs Example JSON node:
{
"@type": "CompositeState",
"@id": "urn:ujg:state:checkout",
"label": "Checkout",
"subjourneyRefs": [
"urn:ujg:journey:shipping",
"urn:ujg:journey:payment"
]
} {
"@type": "CompositeState",
"@id": "urn:ujg:state:checkout",
"label": "Checkout",
"subjourneyRefs": [
"urn:ujg:journey:shipping",
"urn:ujg:journey:payment"
]
} The Shipping and Payment Journeys are separate local topology scopes. Graph permits their observations to interleave while Checkout is current. It does not assert that either Journey is entered first or that both must be visited.
10.1. Nested composition
A child Journey MAY contain a CompositeState in its own
stateRefs.Composition is interpreted recursively; child Journeys MUST NOT be flattened into the parent Journey's local vertex set.
A child JourneyExit leaves the directly containing CompositeState occurrence in the applicable containment path.
Leaving a nested CompositeState does not by itself leave an ancestor CompositeState. The ancestor is left only through movement that exits that ancestor's own composite scope.
10.2. Interaction with multiInstance
Multiple child Journeys and
multiInstancedescribe independent dimensions.More than one
subjourneyRefsvalue MUST NOT implymultiInstance: true.multiInstance: trueon a CompositeState means that multiple concrete occurrences of the same canonical CompositeState may coexist.Each concrete CompositeState occurrence has a distinct composite scope occurrence for Mapping purposes.
Child observations associated with one CompositeState occurrence MUST NOT be used as local predecessors for child observations associated with another occurrence.
Graph does not define occurrence identifiers or occurrence-association data.
11. JourneyExit
A JourneyExit is a terminal local graph vertex and exported completion contract declared by a Journey. It represents a terminal journey outcome that can be reached by a local Transition.
A parent journey can use exported exits to distinguish which outcome of a child journey was reached, without directly referencing child states.
A JourneyExit MUST be identified by an IRI and listed in exactly one Journey's
exitRefs.A JourneyExit MAY declare one
labeland one or moretags.A JourneyExit MAY be the
toendpoint of a Transition in the declaring Journey.A JourneyExit is terminal: it MUST NOT be a
fromendpoint or expose outgoing affordances.A JourneyExit MUST NOT model runtime facts, submitted values, analytics facts, or ordinary internal child movement.
If a completion point is an actual user-visible screen, page, modal, or step, it should remain a normal State. A journey can then transition from that state to a JourneyExit that represents the exported terminal outcome.
Informative pattern:
CheckoutForm -> SuccessScreen -> CheckoutCompleteExit CheckoutForm -> SuccessScreen -> CheckoutCompleteExit classDiagram
class Journey {
stateRefs
exitRefs
}
class State
class JourneyExit
class Transition
Journey --> State : stateRefs
Journey --> JourneyExit : exitRefs
Transition --> State : from
Transition --> JourneyExit : to Example JSON nodes:
{
"@type": "JourneyExit",
"@id": "urn:ujg:exit:checkout-complete",
"label": "Checkout complete"
} {
"@type": "JourneyExit",
"@id": "urn:ujg:exit:checkout-complete",
"label": "Checkout complete"
} {
"@type": "Transition",
"@id": "urn:ujg:transition:checkout-form-to-complete",
"label": "Submit checkout",
"from": "urn:ujg:state:checkout-form",
"to": "urn:ujg:exit:checkout-complete"
} {
"@type": "Transition",
"@id": "urn:ujg:transition:checkout-form-to-complete",
"label": "Submit checkout",
"from": "urn:ujg:state:checkout-form",
"to": "urn:ujg:exit:checkout-complete"
} 11.1. JourneyExit in a composite scope
A JourneyExit owned by any child Journey of a CompositeState is an exported exit from that CompositeState.
Reaching a child JourneyExit means that the containing CompositeState occurrence has been left.
Once the CompositeState has been left, none of its child Journeys remains in scope for that occurrence.
A child Journey's JourneyExit MUST NOT mean only that the child has locally completed while the containing CompositeState remains current.
A locally complete point that does not leave the containing CompositeState MUST be modeled as a State, not as a JourneyExit.
Graph MUST NOT infer that every child Journey must reach an exit.
Graph MUST NOT infer a joint, collective, or all-child completion outcome.
Graph MUST NOT infer an ordering among exits belonging to different child Journeys.
Informative pattern:
Payment Journey:
Authorizing -> Authorized
Shipping Journey:
Address -> DeliveryOption -> Confirmed Payment Journey:
Authorizing -> Authorized
Shipping Journey:
Address -> DeliveryOption -> Confirmed Authorized is a State when Payment may remain locally complete while Shipping continues.
Payment Journey:
Authorizing -> PaymentFailureExit Payment Journey:
Authorizing -> PaymentFailureExit PaymentFailureExit leaves the containing Checkout CompositeState.
11.2. Boundary Entry and Exit Mapping
toEntryRef and fromExitRef are mapping properties on parent Transition resources. They
describe how a parent-local CompositeState connects to entry and exit contracts belonging to its
child Journeys.
These properties are not transition endpoints. The transition's from and to values remain local to the enclosing journey.
11.3. Entry boundary
A Transition MAY declare at most one
toEntryRefwhen itstovalue references a CompositeState.The
toEntryRefvalue MUST reference a JourneyEntry listed in theentryRefsof exactly one Journey referenced by the target CompositeState'ssubjourneyRefs.toEntryRefidentifies the child entry represented by that parent boundary Transition.toEntryRefapplies only to the child Journey that owns the referenced JourneyEntry.toEntryRefMUST NOT select, initialize, or imply entries for the CompositeState's other child Journeys.Entry into a CompositeState without
toEntryRefdoes not select a child Journey or child entry at the parent boundary.When traversal of a particular child Journey is interpreted without an explicitly selected entry, that child Journey independently uses its
defaultEntryRef, otherwise a materialization or execution context may select exactly one of its listed entries.A Consumer MUST NOT infer that every child Journey's default entry is selected merely because the containing CompositeState was entered.
11.4. Exit boundary
A Transition MAY declare at most one
fromExitRefwhen itsfromvalue references a CompositeState.The
fromExitRefvalue MUST reference a JourneyExit listed in theexitRefsof exactly one Journey referenced by the source CompositeState'ssubjourneyRefs.Reaching that child JourneyExit means that the source CompositeState occurrence has been left.
Parent continuation for the child exit may use only a parent Transition whose
fromis the containing CompositeState and whosefromExitRefis that child exit.No matching parent Transition means that no parent continuation is inferred.
More than one parent Transition with the same
fromandfromExitRefpair is invalid.Taking a parent Transition from a CompositeState, whether or not it declares
fromExitRef, leaves the CompositeState and ends the composite scope for that occurrence.fromExitRefremains singular. It identifies one concrete exported child outcome and MUST NOT represent a conjunction, disjunction, set, or synchronization of exits.
toEntryRef and fromExitRef MUST NOT replace local from or to, point directly to child
States, or create hidden Graph edges.
classDiagram
class CompositeState {
subjourneyRefs 1..*
}
class Journey {
entryRefs
exitRefs
}
class JourneyEntry
class JourneyExit
class Transition {
to
toEntryRef
from
fromExitRef
}
CompositeState --> Journey : subjourneyRefs
Journey --> JourneyEntry : entryRefs
Journey --> JourneyExit : exitRefs
Transition --> CompositeState : to/from
Transition --> JourneyEntry : toEntryRef
Transition --> JourneyExit : fromExitRef Example child entry selection:
{
"@type": "Transition",
"@id": "urn:ujg:transition:cart-to-checkout",
"label": "Start checkout",
"from": "urn:ujg:state:cart",
"to": "urn:ujg:state:checkout",
"toEntryRef": "urn:ujg:entry:shipping-address"
} {
"@type": "Transition",
"@id": "urn:ujg:transition:cart-to-checkout",
"label": "Start checkout",
"from": "urn:ujg:state:cart",
"to": "urn:ujg:state:checkout",
"toEntryRef": "urn:ujg:entry:shipping-address"
} The selected toEntryRef applies to the Shipping child Journey. It does not select or initialize
entries for the Checkout CompositeState's other child Journeys.
Example parent continuation after a child exit:
{
"@type": "Transition",
"@id": "urn:ujg:transition:checkout-to-payment-error",
"label": "Show payment error",
"from": "urn:ujg:state:checkout",
"to": "urn:ujg:state:payment-error",
"fromExitRef": "urn:ujg:exit:payment-failed"
} {
"@type": "Transition",
"@id": "urn:ujg:transition:checkout-to-payment-error",
"label": "Show payment error",
"from": "urn:ujg:state:checkout",
"to": "urn:ujg:state:payment-error",
"fromExitRef": "urn:ujg:exit:payment-failed"
} 12. OutgoingTransition
An OutgoingTransition is a navigational affordance. It defines a possible effective target state but does not declare a structural transition in a journey's local topology.
An OutgoingTransition has no explicit from property. Its effective source comes from either a state-scoped outgoingTransitionRefs value or an injected OutgoingTransitionGroup.
An OutgoingTransition MUST be identified by an IRI and MAY declare one
label.An OutgoingTransition MUST use exactly one target mechanism: one
tovalue, ortoCurrentState: true.An OutgoingTransition MAY reference one Command with
commandRef.toMAY reference a resolvable State or CompositeState, including one outside the journey that contributes the affordance.toCurrentState: falseis equivalent to absence and does not satisfy the target requirement.An OutgoingTransition is a navigational affordance, not local topology: it MUST NOT target a JourneyExit, appear in
transitionRefs, or model ordinary internal progression.
If the to target belongs to a known page, surface, or flow entry, that entry should normally be listed in a JourneyEntryIndex. Do not list the target state in the source Journey's stateRefs unless it also belongs to the source journey's local topology.
classDiagram
class OutgoingTransition {
to
toCurrentState
commandRef
}
class State
class CompositeState
class Command
OutgoingTransition --> State : fixed target
OutgoingTransition --> CompositeState : fixed target
OutgoingTransition --> State : current-state target
OutgoingTransition --> CompositeState : current-state target
OutgoingTransition --> Command : commandRef
note for OutgoingTransition "target mechanism is either to or toCurrentState" Example JSON nodes:
Fixed target navigation:
{
"@type": "OutgoingTransition",
"@id": "urn:ujg:ot:go-home",
"label": "Home",
"to": "urn:ujg:state:home",
"commandRef": "urn:ujg:command:go-home"
} {
"@type": "OutgoingTransition",
"@id": "urn:ujg:ot:go-home",
"label": "Home",
"to": "urn:ujg:state:home",
"commandRef": "urn:ujg:command:go-home"
} 12.1. Relative Current-State Targeting
Use toCurrentState: true for affordances that keep the current graph state while changing a
non-topological dimension such as locale, presentation mode, or filter context. The target resolves
to the State or CompositeState where the affordance is available.
toCurrentState changes only Graph target resolution. It does not define runtime events, URLs,
payloads, locale metadata, or private extension behavior.
Current-state targeting:
{
"@type": "OutgoingTransition",
"@id": "urn:ujg:ot:keep-current-state",
"label": "Keep current state",
"toCurrentState": true
} {
"@type": "OutgoingTransition",
"@id": "urn:ujg:ot:keep-current-state",
"label": "Keep current state",
"toCurrentState": true
} 13. OutgoingTransitionGroup
An OutgoingTransitionGroup defines a reusable set of outgoing affordances, such as header or footer navigation, that a Consumer can treat as present on multiple eligible states.
Group injection does not add structural Transition resources to transitionRefs.
An OutgoingTransitionGroup MUST be identified by an IRI and declare at least one
outgoingTransitionRefsvalue.Each
outgoingTransitionRefsvalue MUST reference an OutgoingTransition.A Journey MAY attach a group through
outgoingTransitionGroupRefs.A journey-level group applies each referenced OutgoingTransition to each State or CompositeState in the journey's
stateRefs.toCurrentState: trueresolves at the state where the group is applied; groups MUST NOT create outgoing affordances from JourneyExit nodes.
Consumers SHOULD treat duplicate effective outgoing edges with the same source and target as one effective edge.
classDiagram
class Journey {
outgoingTransitionGroupRefs
}
class OutgoingTransitionGroup {
outgoingTransitionRefs
}
class OutgoingTransition {
to
toCurrentState
}
class State
class CompositeState
Journey --> OutgoingTransitionGroup : outgoingTransitionGroupRefs
OutgoingTransitionGroup --> OutgoingTransition : outgoingTransitionRefs
OutgoingTransition --> State : effective target
OutgoingTransition --> CompositeState : effective target
note for OutgoingTransition "target mechanism is either to or toCurrentState" Example JSON node:
{
"@type": "OutgoingTransitionGroup",
"@id": "urn:ujg:otg:global-header",
"outgoingTransitionRefs": [
"urn:ujg:ot:go-home",
"urn:ujg:ot:go-profile"
]
} {
"@type": "OutgoingTransitionGroup",
"@id": "urn:ujg:otg:global-header",
"outgoingTransitionRefs": [
"urn:ujg:ot:go-home",
"urn:ujg:ot:go-profile"
]
} 14. State-scoped Outgoing Affordances
A State can also declare outgoing affordances directly. These affordances apply only to that state and are not injected into other states.
Direct state-scoped affordances are for local navigational options, not for ordinary internal progression through a journey.
A State MAY declare
outgoingTransitionRefs.Each state-scoped
outgoingTransitionRefsvalue MUST reference an OutgoingTransition.The declaring State is the effective source of the referenced OutgoingTransition.
toCurrentState: trueresolves to the declaring State.State-scoped outgoing affordances are not members of the enclosing Journey's
transitionRefs.
Only ordinary State nodes declare state-scoped outgoing affordances. If navigation should be
available while a CompositeState is active, model it as an OutgoingTransitionGroup on the
enclosing journey or as direct outgoingTransitionRefs on states inside the child journey.
classDiagram
class State {
outgoingTransitionRefs
}
class CompositeState
class JourneyExit
class OutgoingTransition {
to
toCurrentState
}
State --> OutgoingTransition : outgoingTransitionRefs
OutgoingTransition --> State : effective target
OutgoingTransition --> CompositeState : effective target
note for OutgoingTransition "target mechanism is either to or toCurrentState" Example JSON nodes:
{
"@type": "State",
"@id": "urn:ujg:state:w3c-searchpage-form",
"label": "Search form",
"outgoingTransitionRefs": [
"urn:ujg:ot:w3c-searchpage-form-back-home"
]
} {
"@type": "State",
"@id": "urn:ujg:state:w3c-searchpage-form",
"label": "Search form",
"outgoingTransitionRefs": [
"urn:ujg:ot:w3c-searchpage-form-back-home"
]
} {
"@type": "OutgoingTransition",
"@id": "urn:ujg:ot:w3c-searchpage-form-back-home",
"label": "Back to home page",
"to": "urn:ujg:state:w3c-root-homepage"
} {
"@type": "OutgoingTransition",
"@id": "urn:ujg:ot:w3c-searchpage-form-back-home",
"label": "Back to home page",
"to": "urn:ujg:state:w3c-root-homepage"
} This is a local "Back to home page" navigation affordance, not an internal Transition. Its to
target can be outside the current journey's stateRefs.
15. Normative Artifacts
This module is published through the following artifacts:
graph.ttl: ontology, published athttps://ujg.specs.openuji.org/tr/1.0-rc2/ns/graphgraph.context.jsonld: JSON-LD term mappings, published athttps://ujg.specs.openuji.org/tr/1.0-rc2/ns/graph.context.jsonldgraph.shape.ttl: SHACL validation rules, published athttps://ujg.specs.openuji.org/tr/1.0-rc2/ns/graph.shape
Examples on this page use compact JSON-LD fragments. Complete documents can use the aggregate
context https://ujg.specs.openuji.org/tr/1.0-rc2/ns/context.jsonld, which preserves Graph's compact
stateRef term for JourneyEntry.
15.1. Ontology
The normative Graph ontology is defined below and is published at https://ujg.specs.openuji.org/tr/1.0-rc2/ns/graph. It is the authoritative structural definition for Graph classes and properties, including Journey, JourneyEntry, JourneyEntryIndex, LocalVertex, State, CompositeState, Transition, Command, JourneyExit, OutgoingTransition, OutgoingTransitionGroup, defaultEntryRef, entryRefs, stateRef, exitRefs, toEntryRef, fromExitRef, commandRef, subjourneyRefs, multiInstance, toCurrentState, and outgoingTransitionRefs.
@prefix ujg: <https://ujg.specs.openuji.org/tr/1.0-rc2/ns/core#> .
@prefix ujggraph: <https://ujg.specs.openuji.org/tr/1.0-rc2/ns/graph#> .
@prefix owl: <http://www.w3.org/2002/07/owl#> .
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
@prefix dct: <http://purl.org/dc/terms/> .
<https://ujg.specs.openuji.org/tr/1.0-rc2/ns/graph#> a owl:Ontology ;
rdfs:label "UJG Graph 1.0 Vocabulary"@en ;
dct:description "UJG Graph ontology declaration" .
### Classes
ujggraph:Journey a owl:Class ;
rdfs:subClassOf ujg:Node .
ujggraph:JourneyEntry a owl:Class ;
rdfs:subClassOf ujg:Node ;
rdfs:label "Journey Entry" ;
rdfs:comment "An explicit entry contract for a Journey. A JourneyEntry points to the local State or CompositeState where traversal begins." .
ujggraph:JourneyEntryIndex a owl:Class ;
rdfs:subClassOf ujg:Node ;
rdfs:label "Journey Index" ;
rdfs:comment "A catalogue of addressable JourneyEntry contracts. A JourneyEntryIndex does not define traversal, ordering, reachability, or parent-owned progression." .
ujggraph:LocalVertex a owl:Class ;
rdfs:subClassOf ujg:Node ;
rdfs:label "Local Vertex" ;
rdfs:comment "An abstract local topology vertex of a Journey. State, CompositeState, and JourneyExit are local vertex kinds." .
ujggraph:State a owl:Class ;
rdfs:subClassOf ujggraph:LocalVertex .
ujggraph:CompositeState a owl:Class ;
rdfs:subClassOf ujggraph:State .
ujggraph:Transition a owl:Class ;
rdfs:subClassOf ujg:Node .
ujggraph:Command a owl:Class ;
rdfs:subClassOf ujg:Node ;
rdfs:label "Command" ;
rdfs:comment "A stable semantic identity of an intentional invocation in the modeled experience." .
ujggraph:JourneyExit a owl:Class ;
rdfs:subClassOf ujggraph:LocalVertex ;
owl:disjointWith ujggraph:State ;
rdfs:label "Journey Exit" ;
rdfs:comment "A terminal local graph vertex and exported completion contract of a journey." .
ujggraph:OutgoingTransition a owl:Class ;
rdfs:subClassOf ujg:Node .
ujggraph:OutgoingTransitionGroup a owl:Class ;
rdfs:subClassOf ujg:Node .
### Properties
ujggraph:label a owl:DatatypeProperty ;
rdfs:domain ujg:Node ;
rdfs:range xsd:string .
ujggraph:tags a owl:DatatypeProperty ;
rdfs:domain ujg:Node ;
rdfs:range xsd:string .
ujggraph:multiInstance a owl:DatatypeProperty ;
rdfs:domain ujggraph:State ;
rdfs:range xsd:boolean ;
rdfs:label "multi instance" ;
rdfs:comment "Declares that multiple concrete occurrences of the same State may coexist within one active occurrence of its enclosing Journey. The number and identities of those occurrences are determined outside Graph topology." .
ujggraph:defaultEntryRef a owl:ObjectProperty ;
rdfs:domain ujggraph:Journey ;
rdfs:range ujggraph:JourneyEntry ;
rdfs:label "default entry ref" ;
rdfs:comment "References the JourneyEntry used, when declared, if traversal starts without a more specific entry selection." .
ujggraph:entryRefs a owl:ObjectProperty ;
rdfs:range ujggraph:JourneyEntry ;
rdfs:label "entry refs" ;
rdfs:comment "References explicit JourneyEntry contracts. On Journey, entryRefs declares entries owned by that journey. On JourneyEntryIndex, entryRefs lists addressable entries without traversal semantics." .
ujggraph:stateRef a owl:ObjectProperty ;
rdfs:domain ujggraph:JourneyEntry ;
rdfs:range ujggraph:State ;
rdfs:label "state ref" ;
rdfs:comment "References the local State or CompositeState where a JourneyEntry begins traversal." .
ujggraph:stateRefs a owl:ObjectProperty ;
rdfs:range ujggraph:State ;
rdfs:comment "References graph states. On Journey, stateRefs lists experiential local vertices." .
ujggraph:transitionRefs a owl:ObjectProperty ;
rdfs:domain ujggraph:Journey ;
rdfs:range ujggraph:Transition .
ujggraph:exitRefs a owl:ObjectProperty ;
rdfs:domain ujggraph:Journey ;
rdfs:range ujggraph:JourneyExit ;
rdfs:label "exit refs" ;
rdfs:comment "References the terminal exported local vertices declared by a journey." .
ujggraph:outgoingTransitionGroupRefs a owl:ObjectProperty ;
rdfs:domain ujggraph:Journey ;
rdfs:range ujggraph:OutgoingTransitionGroup .
ujggraph:from a owl:ObjectProperty ;
rdfs:domain ujggraph:Transition ;
rdfs:range ujggraph:State .
ujggraph:to a owl:ObjectProperty ;
rdfs:range ujggraph:LocalVertex .
ujggraph:toCurrentState a owl:DatatypeProperty ;
rdfs:domain ujggraph:OutgoingTransition ;
rdfs:range xsd:boolean .
ujggraph:fromExitRef a owl:ObjectProperty ;
rdfs:domain ujggraph:Transition ;
rdfs:range ujggraph:JourneyExit ;
rdfs:label "from exit ref" ;
rdfs:comment "Identifies the exported JourneyExit completed by one child journey of the CompositeState used as the transition's from value. This property is not a transition endpoint." .
ujggraph:toEntryRef a owl:ObjectProperty ;
rdfs:domain ujggraph:Transition ;
rdfs:range ujggraph:JourneyEntry ;
rdfs:label "to entry ref" ;
rdfs:comment "Identifies the JourneyEntry selected when entering one child journey of the CompositeState used as the transition's to value. This property is not a transition endpoint." .
ujggraph:commandRef a owl:ObjectProperty ;
rdfs:range ujggraph:Command ;
rdfs:label "command ref" ;
rdfs:comment "Associates a Transition or OutgoingTransition with the stable semantic identity of an intentional invocation." .
ujggraph:subjourneyRefs a owl:ObjectProperty ;
rdfs:domain ujggraph:CompositeState ;
rdfs:range ujggraph:Journey ;
rdfs:label "subjourney refs" ;
rdfs:comment "References one or more child Journeys contained by a CompositeState." .
ujggraph:outgoingTransitionRefs a owl:ObjectProperty ;
rdfs:domain [
a owl:Class ;
owl:unionOf (
ujggraph:State
ujggraph:OutgoingTransitionGroup
)
] ;
rdfs:range ujggraph:OutgoingTransition ;
rdfs:label "outgoing transition refs" ;
rdfs:comment "References outgoing navigational affordances. When used on an OutgoingTransitionGroup, the references define a reusable group. When used on a non-composite State, the references define outgoing affordances available from that specific state." . @prefix ujg: <https://ujg.specs.openuji.org/tr/1.0-rc2/ns/core#> .
@prefix ujggraph: <https://ujg.specs.openuji.org/tr/1.0-rc2/ns/graph#> .
@prefix owl: <http://www.w3.org/2002/07/owl#> .
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
@prefix dct: <http://purl.org/dc/terms/> .
<https://ujg.specs.openuji.org/tr/1.0-rc2/ns/graph#> a owl:Ontology ;
rdfs:label "UJG Graph 1.0 Vocabulary"@en ;
dct:description "UJG Graph ontology declaration" .
### Classes
ujggraph:Journey a owl:Class ;
rdfs:subClassOf ujg:Node .
ujggraph:JourneyEntry a owl:Class ;
rdfs:subClassOf ujg:Node ;
rdfs:label "Journey Entry" ;
rdfs:comment "An explicit entry contract for a Journey. A JourneyEntry points to the local State or CompositeState where traversal begins." .
ujggraph:JourneyEntryIndex a owl:Class ;
rdfs:subClassOf ujg:Node ;
rdfs:label "Journey Index" ;
rdfs:comment "A catalogue of addressable JourneyEntry contracts. A JourneyEntryIndex does not define traversal, ordering, reachability, or parent-owned progression." .
ujggraph:LocalVertex a owl:Class ;
rdfs:subClassOf ujg:Node ;
rdfs:label "Local Vertex" ;
rdfs:comment "An abstract local topology vertex of a Journey. State, CompositeState, and JourneyExit are local vertex kinds." .
ujggraph:State a owl:Class ;
rdfs:subClassOf ujggraph:LocalVertex .
ujggraph:CompositeState a owl:Class ;
rdfs:subClassOf ujggraph:State .
ujggraph:Transition a owl:Class ;
rdfs:subClassOf ujg:Node .
ujggraph:Command a owl:Class ;
rdfs:subClassOf ujg:Node ;
rdfs:label "Command" ;
rdfs:comment "A stable semantic identity of an intentional invocation in the modeled experience." .
ujggraph:JourneyExit a owl:Class ;
rdfs:subClassOf ujggraph:LocalVertex ;
owl:disjointWith ujggraph:State ;
rdfs:label "Journey Exit" ;
rdfs:comment "A terminal local graph vertex and exported completion contract of a journey." .
ujggraph:OutgoingTransition a owl:Class ;
rdfs:subClassOf ujg:Node .
ujggraph:OutgoingTransitionGroup a owl:Class ;
rdfs:subClassOf ujg:Node .
### Properties
ujggraph:label a owl:DatatypeProperty ;
rdfs:domain ujg:Node ;
rdfs:range xsd:string .
ujggraph:tags a owl:DatatypeProperty ;
rdfs:domain ujg:Node ;
rdfs:range xsd:string .
ujggraph:multiInstance a owl:DatatypeProperty ;
rdfs:domain ujggraph:State ;
rdfs:range xsd:boolean ;
rdfs:label "multi instance" ;
rdfs:comment "Declares that multiple concrete occurrences of the same State may coexist within one active occurrence of its enclosing Journey. The number and identities of those occurrences are determined outside Graph topology." .
ujggraph:defaultEntryRef a owl:ObjectProperty ;
rdfs:domain ujggraph:Journey ;
rdfs:range ujggraph:JourneyEntry ;
rdfs:label "default entry ref" ;
rdfs:comment "References the JourneyEntry used, when declared, if traversal starts without a more specific entry selection." .
ujggraph:entryRefs a owl:ObjectProperty ;
rdfs:range ujggraph:JourneyEntry ;
rdfs:label "entry refs" ;
rdfs:comment "References explicit JourneyEntry contracts. On Journey, entryRefs declares entries owned by that journey. On JourneyEntryIndex, entryRefs lists addressable entries without traversal semantics." .
ujggraph:stateRef a owl:ObjectProperty ;
rdfs:domain ujggraph:JourneyEntry ;
rdfs:range ujggraph:State ;
rdfs:label "state ref" ;
rdfs:comment "References the local State or CompositeState where a JourneyEntry begins traversal." .
ujggraph:stateRefs a owl:ObjectProperty ;
rdfs:range ujggraph:State ;
rdfs:comment "References graph states. On Journey, stateRefs lists experiential local vertices." .
ujggraph:transitionRefs a owl:ObjectProperty ;
rdfs:domain ujggraph:Journey ;
rdfs:range ujggraph:Transition .
ujggraph:exitRefs a owl:ObjectProperty ;
rdfs:domain ujggraph:Journey ;
rdfs:range ujggraph:JourneyExit ;
rdfs:label "exit refs" ;
rdfs:comment "References the terminal exported local vertices declared by a journey." .
ujggraph:outgoingTransitionGroupRefs a owl:ObjectProperty ;
rdfs:domain ujggraph:Journey ;
rdfs:range ujggraph:OutgoingTransitionGroup .
ujggraph:from a owl:ObjectProperty ;
rdfs:domain ujggraph:Transition ;
rdfs:range ujggraph:State .
ujggraph:to a owl:ObjectProperty ;
rdfs:range ujggraph:LocalVertex .
ujggraph:toCurrentState a owl:DatatypeProperty ;
rdfs:domain ujggraph:OutgoingTransition ;
rdfs:range xsd:boolean .
ujggraph:fromExitRef a owl:ObjectProperty ;
rdfs:domain ujggraph:Transition ;
rdfs:range ujggraph:JourneyExit ;
rdfs:label "from exit ref" ;
rdfs:comment "Identifies the exported JourneyExit completed by one child journey of the CompositeState used as the transition's from value. This property is not a transition endpoint." .
ujggraph:toEntryRef a owl:ObjectProperty ;
rdfs:domain ujggraph:Transition ;
rdfs:range ujggraph:JourneyEntry ;
rdfs:label "to entry ref" ;
rdfs:comment "Identifies the JourneyEntry selected when entering one child journey of the CompositeState used as the transition's to value. This property is not a transition endpoint." .
ujggraph:commandRef a owl:ObjectProperty ;
rdfs:range ujggraph:Command ;
rdfs:label "command ref" ;
rdfs:comment "Associates a Transition or OutgoingTransition with the stable semantic identity of an intentional invocation." .
ujggraph:subjourneyRefs a owl:ObjectProperty ;
rdfs:domain ujggraph:CompositeState ;
rdfs:range ujggraph:Journey ;
rdfs:label "subjourney refs" ;
rdfs:comment "References one or more child Journeys contained by a CompositeState." .
ujggraph:outgoingTransitionRefs a owl:ObjectProperty ;
rdfs:domain [
a owl:Class ;
owl:unionOf (
ujggraph:State
ujggraph:OutgoingTransitionGroup
)
] ;
rdfs:range ujggraph:OutgoingTransition ;
rdfs:label "outgoing transition refs" ;
rdfs:comment "References outgoing navigational affordances. When used on an OutgoingTransitionGroup, the references define a reusable group. When used on a non-composite State, the references define outgoing affordances available from that specific state." . 15.2. JSON-LD Context
The normative Graph JSON-LD context is defined below and is published at https://ujg.specs.openuji.org/tr/1.0-rc2/ns/graph.context.jsonld. It provides the compact JSON-LD term mappings for the Graph vocabulary used by the examples on this page.
{
"@context": {
"@version": 1.1,
"ujggraph": "https://ujg.specs.openuji.org/tr/1.0-rc2/ns/graph#",
"xsd": "http://www.w3.org/2001/XMLSchema#",
"Journey": "ujggraph:Journey",
"JourneyEntry": "ujggraph:JourneyEntry",
"JourneyEntryIndex": "ujggraph:JourneyEntryIndex",
"LocalVertex": "ujggraph:LocalVertex",
"State": "ujggraph:State",
"CompositeState": "ujggraph:CompositeState",
"Transition": "ujggraph:Transition",
"Command": "ujggraph:Command",
"JourneyExit": "ujggraph:JourneyExit",
"OutgoingTransition": "ujggraph:OutgoingTransition",
"OutgoingTransitionGroup": "ujggraph:OutgoingTransitionGroup",
"label": "ujggraph:label",
"tags": {
"@id": "ujggraph:tags",
"@container": "@set"
},
"multiInstance": {
"@id": "ujggraph:multiInstance",
"@type": "xsd:boolean"
},
"defaultEntryRef": {
"@id": "ujggraph:defaultEntryRef",
"@type": "@id"
},
"entryRefs": {
"@id": "ujggraph:entryRefs",
"@type": "@id",
"@container": "@set"
},
"stateRef": {
"@id": "ujggraph:stateRef",
"@type": "@id"
},
"stateRefs": {
"@id": "ujggraph:stateRefs",
"@type": "@id",
"@container": "@set"
},
"transitionRefs": {
"@id": "ujggraph:transitionRefs",
"@type": "@id",
"@container": "@set"
},
"exitRefs": {
"@id": "ujggraph:exitRefs",
"@type": "@id",
"@container": "@set"
},
"outgoingTransitionGroupRefs": {
"@id": "ujggraph:outgoingTransitionGroupRefs",
"@type": "@id",
"@container": "@set"
},
"from": {
"@id": "ujggraph:from",
"@type": "@id"
},
"to": {
"@id": "ujggraph:to",
"@type": "@id"
},
"toCurrentState": {
"@id": "ujggraph:toCurrentState",
"@type": "xsd:boolean"
},
"fromExitRef": {
"@id": "ujggraph:fromExitRef",
"@type": "@id"
},
"toEntryRef": {
"@id": "ujggraph:toEntryRef",
"@type": "@id"
},
"commandRef": {
"@id": "ujggraph:commandRef",
"@type": "@id"
},
"subjourneyRefs": {
"@id": "ujggraph:subjourneyRefs",
"@type": "@id",
"@container": "@set"
},
"outgoingTransitionRefs": {
"@id": "ujggraph:outgoingTransitionRefs",
"@type": "@id",
"@container": "@set"
}
}
} {
"@context": {
"@version": 1.1,
"ujggraph": "https://ujg.specs.openuji.org/tr/1.0-rc2/ns/graph#",
"xsd": "http://www.w3.org/2001/XMLSchema#",
"Journey": "ujggraph:Journey",
"JourneyEntry": "ujggraph:JourneyEntry",
"JourneyEntryIndex": "ujggraph:JourneyEntryIndex",
"LocalVertex": "ujggraph:LocalVertex",
"State": "ujggraph:State",
"CompositeState": "ujggraph:CompositeState",
"Transition": "ujggraph:Transition",
"Command": "ujggraph:Command",
"JourneyExit": "ujggraph:JourneyExit",
"OutgoingTransition": "ujggraph:OutgoingTransition",
"OutgoingTransitionGroup": "ujggraph:OutgoingTransitionGroup",
"label": "ujggraph:label",
"tags": {
"@id": "ujggraph:tags",
"@container": "@set"
},
"multiInstance": {
"@id": "ujggraph:multiInstance",
"@type": "xsd:boolean"
},
"defaultEntryRef": {
"@id": "ujggraph:defaultEntryRef",
"@type": "@id"
},
"entryRefs": {
"@id": "ujggraph:entryRefs",
"@type": "@id",
"@container": "@set"
},
"stateRef": {
"@id": "ujggraph:stateRef",
"@type": "@id"
},
"stateRefs": {
"@id": "ujggraph:stateRefs",
"@type": "@id",
"@container": "@set"
},
"transitionRefs": {
"@id": "ujggraph:transitionRefs",
"@type": "@id",
"@container": "@set"
},
"exitRefs": {
"@id": "ujggraph:exitRefs",
"@type": "@id",
"@container": "@set"
},
"outgoingTransitionGroupRefs": {
"@id": "ujggraph:outgoingTransitionGroupRefs",
"@type": "@id",
"@container": "@set"
},
"from": {
"@id": "ujggraph:from",
"@type": "@id"
},
"to": {
"@id": "ujggraph:to",
"@type": "@id"
},
"toCurrentState": {
"@id": "ujggraph:toCurrentState",
"@type": "xsd:boolean"
},
"fromExitRef": {
"@id": "ujggraph:fromExitRef",
"@type": "@id"
},
"toEntryRef": {
"@id": "ujggraph:toEntryRef",
"@type": "@id"
},
"commandRef": {
"@id": "ujggraph:commandRef",
"@type": "@id"
},
"subjourneyRefs": {
"@id": "ujggraph:subjourneyRefs",
"@type": "@id",
"@container": "@set"
},
"outgoingTransitionRefs": {
"@id": "ujggraph:outgoingTransitionRefs",
"@type": "@id",
"@container": "@set"
}
}
} 15.3. Validation
The normative Graph SHACL shape is defined below and is published at https://ujg.specs.openuji.org/tr/1.0-rc2/ns/graph.shape. It is the authoritative validation artifact for Graph structural constraints.
@prefix ujggraph: <https://ujg.specs.openuji.org/tr/1.0-rc2/ns/graph#> .
@prefix sh: <http://www.w3.org/ns/shacl#> .
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
@prefix ujggraphshape: <https://ujg.specs.openuji.org/tr/1.0-rc2/ns/graph.shape#> .
ujggraphshape:StateLikeShape a sh:NodeShape ;
sh:nodeKind sh:IRI ;
sh:or (
[ sh:class ujggraph:State ]
[ sh:class ujggraph:CompositeState ]
) .
ujggraphshape:LocalVertexShape a sh:NodeShape ;
sh:nodeKind sh:IRI ;
sh:or (
[ sh:class ujggraph:State ]
[ sh:class ujggraph:CompositeState ]
[ sh:class ujggraph:JourneyExit ]
) .
ujggraphshape:OutgoingTargetShape a sh:NodeShape ;
sh:nodeKind sh:IRI ;
sh:or (
[ sh:class ujggraph:State ]
[ sh:class ujggraph:CompositeState ]
) .
ujggraphshape:CommandShape a sh:NodeShape ;
sh:targetClass ujggraph:Command ;
sh:nodeKind sh:IRI ;
sh:property [
sh:path ujggraph:label ;
sh:datatype xsd:string ;
sh:maxCount 1 ;
] ;
sh:property [
sh:path ujggraph:tags ;
sh:datatype xsd:string ;
] ;
sh:property [
sh:path ujggraph:from ;
sh:maxCount 0 ;
sh:message "A Command must not declare from; use commandRef from a Transition or OutgoingTransition." ;
] ;
sh:property [
sh:path ujggraph:to ;
sh:maxCount 0 ;
sh:message "A Command must not declare to; use commandRef from a Transition or OutgoingTransition." ;
] ;
sh:property [
sh:path ujggraph:toEntryRef ;
sh:maxCount 0 ;
sh:message "A Command must not declare toEntryRef." ;
] ;
sh:property [
sh:path ujggraph:fromExitRef ;
sh:maxCount 0 ;
sh:message "A Command must not declare fromExitRef." ;
] ;
sh:property [
sh:path ujggraph:subjourneyRefs ;
sh:maxCount 0 ;
sh:message "A Command must not declare subjourneyRefs." ;
] ;
sh:property [
sh:path ujggraph:outgoingTransitionRefs ;
sh:maxCount 0 ;
sh:message "A Command must not declare outgoingTransitionRefs." ;
] .
ujggraphshape:JourneyShape a sh:NodeShape ;
sh:targetClass ujggraph:Journey ;
sh:nodeKind sh:IRI ;
sh:property [
sh:path ujggraph:defaultEntryRef ;
sh:maxCount 1 ;
sh:class ujggraph:JourneyEntry ;
sh:nodeKind sh:IRI ;
] ;
sh:property [
sh:path ujggraph:entryRefs ;
sh:minCount 1 ;
sh:class ujggraph:JourneyEntry ;
sh:nodeKind sh:IRI ;
] ;
sh:property [
sh:path ujggraph:stateRefs ;
sh:minCount 1 ;
sh:node ujggraphshape:StateLikeShape ;
] ;
sh:property [
sh:path ujggraph:transitionRefs ;
sh:class ujggraph:Transition ;
sh:nodeKind sh:IRI ;
] ;
sh:property [
sh:path ujggraph:exitRefs ;
sh:class ujggraph:JourneyExit ;
sh:nodeKind sh:IRI ;
] ;
sh:property [
sh:path ujggraph:outgoingTransitionGroupRefs ;
sh:class ujggraph:OutgoingTransitionGroup ;
sh:nodeKind sh:IRI ;
] ;
sh:property [
sh:path ujggraph:subjourneyRefs ;
sh:maxCount 0 ;
sh:message "A Journey must not declare subjourneyRefs; only CompositeState declares child Journey references." ;
] ;
sh:sparql [
a sh:SPARQLConstraint ;
sh:message "A journey's defaultEntryRef must be listed in the same journey's entryRefs." ;
sh:select """
SELECT $this ?entry
WHERE {
$this ujggraph:defaultEntryRef ?entry .
FILTER (NOT EXISTS {
$this ujggraph:entryRefs ?entry .
})
}
""" ;
] ;
sh:sparql [
a sh:SPARQLConstraint ;
sh:message "A JourneyEntry listed in entryRefs must have a stateRef listed in the same journey's stateRefs." ;
sh:select """
SELECT $this ?entry ?state
WHERE {
$this ujggraph:entryRefs ?entry .
?entry ujggraph:stateRef ?state .
FILTER (NOT EXISTS {
$this ujggraph:stateRefs ?state .
})
}
""" ;
] ;
sh:sparql [
a sh:SPARQLConstraint ;
sh:message "A JourneyEntry must be listed in the entryRefs of exactly one journey." ;
sh:select """
SELECT $this ?entry
WHERE {
$this ujggraph:entryRefs ?entry .
FILTER (
EXISTS {
?otherJourney a ujggraph:Journey ;
ujggraph:entryRefs ?entry .
FILTER ($this != ?otherJourney)
}
|| NOT EXISTS {
?declaringJourney a ujggraph:Journey ;
ujggraph:entryRefs ?entry .
}
)
}
""" ;
] ;
sh:sparql [
a sh:SPARQLConstraint ;
sh:message "A transition in transitionRefs has a from value that is not listed in this journey's stateRefs." ;
sh:select """
SELECT $this ?transition ?from
WHERE {
$this ujggraph:transitionRefs ?transition .
?transition ujggraph:from ?from .
FILTER (NOT EXISTS {
$this ujggraph:stateRefs ?from .
})
}
""" ;
] ;
sh:sparql [
a sh:SPARQLConstraint ;
sh:message "A transition in transitionRefs has a from value that references a JourneyExit." ;
sh:select """
SELECT $this ?transition ?from
WHERE {
$this ujggraph:transitionRefs ?transition .
?transition ujggraph:from ?from .
?from a ujggraph:JourneyExit .
}
""" ;
] ;
sh:sparql [
a sh:SPARQLConstraint ;
sh:message "A transition in transitionRefs has a to value that is not listed in this journey's stateRefs or exitRefs." ;
sh:select """
SELECT $this ?transition ?to
WHERE {
$this ujggraph:transitionRefs ?transition .
?transition ujggraph:to ?to .
FILTER (
NOT EXISTS { $this ujggraph:stateRefs ?to . }
&& NOT EXISTS { $this ujggraph:exitRefs ?to . }
)
}
""" ;
] ;
sh:sparql [
a sh:SPARQLConstraint ;
sh:message "A JourneyExit must be listed in the exitRefs of exactly one journey." ;
sh:select """
SELECT $this ?exit
WHERE {
$this ujggraph:exitRefs ?exit .
FILTER (
EXISTS {
?otherJourney ujggraph:exitRefs ?exit .
FILTER ($this != ?otherJourney)
}
|| NOT EXISTS {
?declaringJourney ujggraph:exitRefs ?exit .
}
)
}
""" ;
] ;
sh:sparql [
a sh:SPARQLConstraint ;
sh:message "A JourneyExit used as Transition.to must be listed in the same enclosing journey's exitRefs." ;
sh:select """
SELECT $this ?transition ?exit
WHERE {
$this ujggraph:transitionRefs ?transition .
?transition ujggraph:to ?exit .
?exit a ujggraph:JourneyExit .
FILTER (NOT EXISTS {
$this ujggraph:exitRefs ?exit .
})
}
""" ;
] ;
sh:sparql [
a sh:SPARQLConstraint ;
sh:message "A transition with fromExitRef must have a from value listed in the enclosing journey's stateRefs." ;
sh:select """
SELECT $this ?transition ?from
WHERE {
$this ujggraph:transitionRefs ?transition .
?transition ujggraph:fromExitRef ?exit ;
ujggraph:from ?from .
FILTER (NOT EXISTS {
$this ujggraph:stateRefs ?from .
})
}
""" ;
] ;
sh:sparql [
a sh:SPARQLConstraint ;
sh:message "A transition with toEntryRef must have a to value listed in the enclosing journey's stateRefs." ;
sh:select """
SELECT $this ?transition ?to
WHERE {
$this ujggraph:transitionRefs ?transition .
?transition ujggraph:toEntryRef ?entry ;
ujggraph:to ?to .
FILTER (NOT EXISTS {
$this ujggraph:stateRefs ?to .
})
}
""" ;
] ;
sh:sparql [
a sh:SPARQLConstraint ;
sh:message "A transition with toEntryRef must have a to value that references a CompositeState." ;
sh:select """
SELECT $this ?transition ?to
WHERE {
$this ujggraph:transitionRefs ?transition .
?transition ujggraph:toEntryRef ?entry ;
ujggraph:to ?to .
FILTER (NOT EXISTS {
?to a ujggraph:CompositeState .
})
}
""" ;
] ;
sh:sparql [
a sh:SPARQLConstraint ;
sh:message "The toEntryRef of a parent transition must be listed in the entryRefs of exactly one Journey referenced by the target CompositeState's subjourneyRefs." ;
sh:select """
SELECT $this ?transition ?to ?entry
WHERE {
$this ujggraph:transitionRefs ?transition .
?transition ujggraph:toEntryRef ?entry ;
ujggraph:to ?to .
FILTER (NOT EXISTS {
?to ujggraph:subjourneyRefs ?childJourney .
?childJourney ujggraph:entryRefs ?entry .
})
}
""" ;
] ;
sh:sparql [
a sh:SPARQLConstraint ;
sh:message "The toEntryRef of a parent transition must not be listed in more than one Journey referenced by the target CompositeState's subjourneyRefs." ;
sh:select """
SELECT $this ?transition ?to ?entry
WHERE {
$this ujggraph:transitionRefs ?transition .
?transition ujggraph:toEntryRef ?entry ;
ujggraph:to ?to .
?to ujggraph:subjourneyRefs ?childJourneyA, ?childJourneyB .
?childJourneyA ujggraph:entryRefs ?entry .
?childJourneyB ujggraph:entryRefs ?entry .
FILTER (?childJourneyA != ?childJourneyB)
}
""" ;
] ;
sh:sparql [
a sh:SPARQLConstraint ;
sh:message "A transition with fromExitRef must have a from value that references a CompositeState." ;
sh:select """
SELECT $this ?transition ?from
WHERE {
$this ujggraph:transitionRefs ?transition .
?transition ujggraph:fromExitRef ?exit ;
ujggraph:from ?from .
FILTER (NOT EXISTS {
?from a ujggraph:CompositeState .
})
}
""" ;
] ;
sh:sparql [
a sh:SPARQLConstraint ;
sh:message "The fromExitRef of a parent transition must be listed in the exitRefs of exactly one Journey referenced by the source CompositeState's subjourneyRefs." ;
sh:select """
SELECT $this ?transition ?from ?exit
WHERE {
$this ujggraph:transitionRefs ?transition .
?transition ujggraph:fromExitRef ?exit ;
ujggraph:from ?from .
FILTER (NOT EXISTS {
?from ujggraph:subjourneyRefs ?childJourney .
?childJourney ujggraph:exitRefs ?exit .
})
}
""" ;
] ;
sh:sparql [
a sh:SPARQLConstraint ;
sh:message "The fromExitRef of a parent transition must not be listed in more than one Journey referenced by the source CompositeState's subjourneyRefs." ;
sh:select """
SELECT $this ?transition ?from ?exit
WHERE {
$this ujggraph:transitionRefs ?transition .
?transition ujggraph:fromExitRef ?exit ;
ujggraph:from ?from .
?from ujggraph:subjourneyRefs ?childJourneyA, ?childJourneyB .
?childJourneyA ujggraph:exitRefs ?exit .
?childJourneyB ujggraph:exitRefs ?exit .
FILTER (?childJourneyA != ?childJourneyB)
}
""" ;
] ;
sh:sparql [
a sh:SPARQLConstraint ;
sh:message "A transition with fromExitRef must have a to value listed in the enclosing journey's stateRefs or exitRefs." ;
sh:select """
SELECT $this ?transition ?to
WHERE {
$this ujggraph:transitionRefs ?transition .
?transition ujggraph:fromExitRef ?exit ;
ujggraph:to ?to .
FILTER (
NOT EXISTS { $this ujggraph:stateRefs ?to . }
&& NOT EXISTS { $this ujggraph:exitRefs ?to . }
)
}
""" ;
] ;
sh:sparql [
a sh:SPARQLConstraint ;
sh:message "A journey must not contain more than one transition with the same from value and the same fromExitRef value." ;
sh:select """
SELECT $this ?from ?exit ?transition ?otherTransition
WHERE {
$this ujggraph:transitionRefs ?transition, ?otherTransition .
?transition ujggraph:from ?from ;
ujggraph:fromExitRef ?exit .
?otherTransition ujggraph:from ?from ;
ujggraph:fromExitRef ?exit .
FILTER (?transition != ?otherTransition)
}
""" ;
] ;
sh:sparql [
a sh:SPARQLConstraint ;
sh:severity sh:Warning ;
sh:message "A state in Journey.stateRefs is not an entry state or a local transition endpoint. Verify that it belongs to the journey's experiential local topology and is not only a linked destination." ;
sh:select """
SELECT $this ?state
WHERE {
$this ujggraph:stateRefs ?state .
FILTER (NOT EXISTS {
$this ujggraph:entryRefs ?entry .
?entry ujggraph:stateRef ?state .
})
FILTER (NOT EXISTS {
$this ujggraph:transitionRefs ?transition .
?transition ujggraph:from ?state .
})
FILTER (NOT EXISTS {
$this ujggraph:transitionRefs ?transition .
?transition ujggraph:to ?state .
})
}
""" ;
] .
ujggraphshape:JourneyEntryShape a sh:NodeShape ;
sh:targetClass ujggraph:JourneyEntry ;
sh:nodeKind sh:IRI ;
sh:property [
sh:path ujggraph:stateRef ;
sh:minCount 1 ;
sh:maxCount 1 ;
sh:node ujggraphshape:StateLikeShape ;
] ;
sh:property [
sh:path ujggraph:label ;
sh:datatype xsd:string ;
sh:maxCount 1 ;
] ;
sh:property [
sh:path ujggraph:tags ;
sh:datatype xsd:string ;
] ;
sh:property [
sh:path ujggraph:subjourneyRefs ;
sh:maxCount 0 ;
sh:message "A JourneyEntry must not declare subjourneyRefs." ;
] ;
sh:sparql [
a sh:SPARQLConstraint ;
sh:message "A JourneyEntry must be listed in the entryRefs of exactly one journey." ;
sh:select """
SELECT $this
WHERE {
FILTER (
NOT EXISTS {
?journey a ujggraph:Journey ;
ujggraph:entryRefs $this .
}
|| EXISTS {
?journeyA a ujggraph:Journey ;
ujggraph:entryRefs $this .
?journeyB a ujggraph:Journey ;
ujggraph:entryRefs $this .
FILTER (?journeyA != ?journeyB)
}
)
}
""" ;
] ;
sh:sparql [
a sh:SPARQLConstraint ;
sh:message "A JourneyEntry must not be used as the from or to value of a Transition." ;
sh:select """
SELECT $this ?transition
WHERE {
{
?transition ujggraph:from $this .
}
UNION
{
?transition ujggraph:to $this .
}
}
""" ;
] .
ujggraphshape:JourneyEntryIndexShape a sh:NodeShape ;
sh:targetClass ujggraph:JourneyEntryIndex ;
sh:nodeKind sh:IRI ;
sh:property [
sh:path ujggraph:entryRefs ;
sh:minCount 1 ;
sh:class ujggraph:JourneyEntry ;
sh:nodeKind sh:IRI ;
] ;
sh:property [
sh:path ujggraph:transitionRefs ;
sh:maxCount 0 ;
sh:message "A JourneyEntryIndex must not declare transitionRefs." ;
] ;
sh:property [
sh:path ujggraph:exitRefs ;
sh:maxCount 0 ;
sh:message "A JourneyEntryIndex must not declare exitRefs." ;
] ;
sh:property [
sh:path ujggraph:outgoingTransitionGroupRefs ;
sh:maxCount 0 ;
sh:message "A JourneyEntryIndex must not declare outgoingTransitionGroupRefs." ;
] ;
sh:property [
sh:path ujggraph:from ;
sh:maxCount 0 ;
sh:message "A JourneyEntryIndex must not declare from." ;
] ;
sh:property [
sh:path ujggraph:to ;
sh:maxCount 0 ;
sh:message "A JourneyEntryIndex must not declare to." ;
] ;
sh:property [
sh:path ujggraph:fromExitRef ;
sh:maxCount 0 ;
sh:message "A JourneyEntryIndex must not declare fromExitRef." ;
] ;
sh:property [
sh:path ujggraph:toEntryRef ;
sh:maxCount 0 ;
sh:message "A JourneyEntryIndex must not declare toEntryRef." ;
] ;
sh:property [
sh:path ujggraph:defaultEntryRef ;
sh:maxCount 0 ;
sh:message "A JourneyEntryIndex must not declare defaultEntryRef." ;
] ;
sh:property [
sh:path ujggraph:stateRefs ;
sh:maxCount 0 ;
sh:message "A JourneyEntryIndex must not declare stateRefs." ;
] ;
sh:property [
sh:path ujggraph:stateRef ;
sh:maxCount 0 ;
sh:message "A JourneyEntryIndex must not declare stateRef." ;
] ;
sh:property [
sh:path ujggraph:subjourneyRefs ;
sh:maxCount 0 ;
sh:message "A JourneyEntryIndex must not declare subjourneyRefs." ;
] ;
sh:property [
sh:path ujggraph:outgoingTransitionRefs ;
sh:maxCount 0 ;
sh:message "A JourneyEntryIndex must not declare outgoingTransitionRefs." ;
] .
ujggraphshape:StateShape a sh:NodeShape ;
sh:targetClass ujggraph:State ;
sh:nodeKind sh:IRI ;
sh:property [
sh:path ujggraph:label ;
sh:datatype xsd:string ;
sh:minCount 1 ;
sh:maxCount 1 ;
] ;
sh:property [
sh:path ujggraph:tags ;
sh:datatype xsd:string ;
] ;
sh:property [
sh:path ujggraph:multiInstance ;
sh:datatype xsd:boolean ;
sh:maxCount 1 ;
] ;
sh:property [
sh:path ujggraph:outgoingTransitionRefs ;
sh:class ujggraph:OutgoingTransition ;
sh:nodeKind sh:IRI ;
] .
ujggraphshape:CompositeStateShape a sh:NodeShape ;
sh:targetClass ujggraph:CompositeState ;
sh:nodeKind sh:IRI ;
sh:property [
sh:path ujggraph:label ;
sh:datatype xsd:string ;
sh:minCount 1 ;
sh:maxCount 1 ;
] ;
sh:property [
sh:path ujggraph:tags ;
sh:datatype xsd:string ;
] ;
sh:property [
sh:path ujggraph:multiInstance ;
sh:datatype xsd:boolean ;
sh:maxCount 1 ;
] ;
sh:property [
sh:path ujggraph:stateRefs ;
sh:maxCount 0 ;
sh:message "A CompositeState must not use stateRefs; use subjourneyRefs to reference one or more child Journeys." ;
] ;
sh:property [
sh:path ujggraph:outgoingTransitionRefs ;
sh:maxCount 0 ;
sh:message "A CompositeState must not declare outgoingTransitionRefs. Use an OutgoingTransitionGroup on the enclosing Journey, or attach outgoingTransitionRefs to concrete States inside a child Journey." ;
] ;
sh:property [
sh:path ujggraph:subjourneyRefs ;
sh:class ujggraph:Journey ;
sh:nodeKind sh:IRI ;
sh:minCount 1 ;
] .
ujggraphshape:TransitionShape a sh:NodeShape ;
sh:targetClass ujggraph:Transition ;
sh:nodeKind sh:IRI ;
sh:property [
sh:path ujggraph:from ;
sh:minCount 1 ;
sh:maxCount 1 ;
sh:node ujggraphshape:StateLikeShape ;
] ;
sh:property [
sh:path ujggraph:to ;
sh:minCount 1 ;
sh:maxCount 1 ;
sh:node ujggraphshape:LocalVertexShape ;
] ;
sh:property [
sh:path ujggraph:label ;
sh:datatype xsd:string ;
sh:maxCount 1 ;
] ;
sh:property [
sh:path ujggraph:fromExitRef ;
sh:class ujggraph:JourneyExit ;
sh:nodeKind sh:IRI ;
sh:maxCount 1 ;
] ;
sh:property [
sh:path ujggraph:toEntryRef ;
sh:class ujggraph:JourneyEntry ;
sh:nodeKind sh:IRI ;
sh:maxCount 1 ;
] ;
sh:property [
sh:path ujggraph:commandRef ;
sh:class ujggraph:Command ;
sh:nodeKind sh:IRI ;
sh:maxCount 1 ;
] ;
sh:property [
sh:path ujggraph:subjourneyRefs ;
sh:maxCount 0 ;
sh:message "A Transition must not declare subjourneyRefs." ;
] .
ujggraphshape:JourneyExitShape a sh:NodeShape ;
sh:targetClass ujggraph:JourneyExit ;
sh:nodeKind sh:IRI ;
sh:property [
sh:path ujggraph:label ;
sh:datatype xsd:string ;
sh:maxCount 1 ;
] ;
sh:property [
sh:path ujggraph:tags ;
sh:datatype xsd:string ;
] ;
sh:property [
sh:path ujggraph:outgoingTransitionRefs ;
sh:maxCount 0 ;
sh:message "A JourneyExit must not declare outgoingTransitionRefs." ;
] ;
sh:property [
sh:path ujggraph:subjourneyRefs ;
sh:maxCount 0 ;
sh:message "A JourneyExit must not declare subjourneyRefs." ;
] ;
sh:sparql [
a sh:SPARQLConstraint ;
sh:message "A JourneyExit must not also be typed State." ;
sh:select """
SELECT $this
WHERE {
$this a ujggraph:State .
}
""" ;
] ;
sh:sparql [
a sh:SPARQLConstraint ;
sh:message "A JourneyExit must be listed in the exitRefs of exactly one journey." ;
sh:select """
SELECT $this
WHERE {
FILTER (
NOT EXISTS { ?journey ujggraph:exitRefs $this . }
|| EXISTS {
?journeyA ujggraph:exitRefs $this .
?journeyB ujggraph:exitRefs $this .
FILTER (?journeyA != ?journeyB)
}
)
}
""" ;
] ;
sh:sparql [
a sh:SPARQLConstraint ;
sh:message "A JourneyExit must not be used as the from value of a Transition." ;
sh:select """
SELECT $this ?transition
WHERE {
?transition ujggraph:from $this .
}
""" ;
] .
ujggraphshape:OutgoingTransitionShape a sh:NodeShape ;
sh:targetClass ujggraph:OutgoingTransition ;
sh:nodeKind sh:IRI ;
sh:property [
sh:path ujggraph:to ;
sh:maxCount 1 ;
sh:node ujggraphshape:OutgoingTargetShape ;
] ;
sh:property [
sh:path ujggraph:toCurrentState ;
sh:datatype xsd:boolean ;
sh:maxCount 1 ;
] ;
sh:property [
sh:path ujggraph:label ;
sh:datatype xsd:string ;
sh:maxCount 1 ;
] ;
sh:property [
sh:path ujggraph:commandRef ;
sh:class ujggraph:Command ;
sh:nodeKind sh:IRI ;
sh:maxCount 1 ;
] ;
sh:property [
sh:path ujggraph:subjourneyRefs ;
sh:maxCount 0 ;
sh:message "An OutgoingTransition must not declare subjourneyRefs." ;
] ;
sh:sparql [
a sh:SPARQLConstraint ;
sh:message "An OutgoingTransition must declare exactly one effective target mechanism: either exactly one to value or toCurrentState true." ;
sh:select """
SELECT $this
WHERE {
FILTER (
NOT EXISTS { $this ujggraph:to ?to . }
&& NOT EXISTS { $this ujggraph:toCurrentState true . }
)
}
""" ;
] ;
sh:sparql [
a sh:SPARQLConstraint ;
sh:message "An OutgoingTransition with toCurrentState true must not also declare to." ;
sh:select """
SELECT $this ?to
WHERE {
$this ujggraph:to ?to ;
ujggraph:toCurrentState true .
}
""" ;
] .
ujggraphshape:OutgoingTransitionGroupShape a sh:NodeShape ;
sh:targetClass ujggraph:OutgoingTransitionGroup ;
sh:nodeKind sh:IRI ;
sh:property [
sh:path ujggraph:outgoingTransitionRefs ;
sh:class ujggraph:OutgoingTransition ;
sh:nodeKind sh:IRI ;
sh:minCount 1 ;
] ;
sh:property [
sh:path ujggraph:subjourneyRefs ;
sh:maxCount 0 ;
sh:message "An OutgoingTransitionGroup must not declare subjourneyRefs." ;
] . @prefix ujggraph: <https://ujg.specs.openuji.org/tr/1.0-rc2/ns/graph#> .
@prefix sh: <http://www.w3.org/ns/shacl#> .
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
@prefix ujggraphshape: <https://ujg.specs.openuji.org/tr/1.0-rc2/ns/graph.shape#> .
ujggraphshape:StateLikeShape a sh:NodeShape ;
sh:nodeKind sh:IRI ;
sh:or (
[ sh:class ujggraph:State ]
[ sh:class ujggraph:CompositeState ]
) .
ujggraphshape:LocalVertexShape a sh:NodeShape ;
sh:nodeKind sh:IRI ;
sh:or (
[ sh:class ujggraph:State ]
[ sh:class ujggraph:CompositeState ]
[ sh:class ujggraph:JourneyExit ]
) .
ujggraphshape:OutgoingTargetShape a sh:NodeShape ;
sh:nodeKind sh:IRI ;
sh:or (
[ sh:class ujggraph:State ]
[ sh:class ujggraph:CompositeState ]
) .
ujggraphshape:CommandShape a sh:NodeShape ;
sh:targetClass ujggraph:Command ;
sh:nodeKind sh:IRI ;
sh:property [
sh:path ujggraph:label ;
sh:datatype xsd:string ;
sh:maxCount 1 ;
] ;
sh:property [
sh:path ujggraph:tags ;
sh:datatype xsd:string ;
] ;
sh:property [
sh:path ujggraph:from ;
sh:maxCount 0 ;
sh:message "A Command must not declare from; use commandRef from a Transition or OutgoingTransition." ;
] ;
sh:property [
sh:path ujggraph:to ;
sh:maxCount 0 ;
sh:message "A Command must not declare to; use commandRef from a Transition or OutgoingTransition." ;
] ;
sh:property [
sh:path ujggraph:toEntryRef ;
sh:maxCount 0 ;
sh:message "A Command must not declare toEntryRef." ;
] ;
sh:property [
sh:path ujggraph:fromExitRef ;
sh:maxCount 0 ;
sh:message "A Command must not declare fromExitRef." ;
] ;
sh:property [
sh:path ujggraph:subjourneyRefs ;
sh:maxCount 0 ;
sh:message "A Command must not declare subjourneyRefs." ;
] ;
sh:property [
sh:path ujggraph:outgoingTransitionRefs ;
sh:maxCount 0 ;
sh:message "A Command must not declare outgoingTransitionRefs." ;
] .
ujggraphshape:JourneyShape a sh:NodeShape ;
sh:targetClass ujggraph:Journey ;
sh:nodeKind sh:IRI ;
sh:property [
sh:path ujggraph:defaultEntryRef ;
sh:maxCount 1 ;
sh:class ujggraph:JourneyEntry ;
sh:nodeKind sh:IRI ;
] ;
sh:property [
sh:path ujggraph:entryRefs ;
sh:minCount 1 ;
sh:class ujggraph:JourneyEntry ;
sh:nodeKind sh:IRI ;
] ;
sh:property [
sh:path ujggraph:stateRefs ;
sh:minCount 1 ;
sh:node ujggraphshape:StateLikeShape ;
] ;
sh:property [
sh:path ujggraph:transitionRefs ;
sh:class ujggraph:Transition ;
sh:nodeKind sh:IRI ;
] ;
sh:property [
sh:path ujggraph:exitRefs ;
sh:class ujggraph:JourneyExit ;
sh:nodeKind sh:IRI ;
] ;
sh:property [
sh:path ujggraph:outgoingTransitionGroupRefs ;
sh:class ujggraph:OutgoingTransitionGroup ;
sh:nodeKind sh:IRI ;
] ;
sh:property [
sh:path ujggraph:subjourneyRefs ;
sh:maxCount 0 ;
sh:message "A Journey must not declare subjourneyRefs; only CompositeState declares child Journey references." ;
] ;
sh:sparql [
a sh:SPARQLConstraint ;
sh:message "A journey's defaultEntryRef must be listed in the same journey's entryRefs." ;
sh:select """
SELECT $this ?entry
WHERE {
$this ujggraph:defaultEntryRef ?entry .
FILTER (NOT EXISTS {
$this ujggraph:entryRefs ?entry .
})
}
""" ;
] ;
sh:sparql [
a sh:SPARQLConstraint ;
sh:message "A JourneyEntry listed in entryRefs must have a stateRef listed in the same journey's stateRefs." ;
sh:select """
SELECT $this ?entry ?state
WHERE {
$this ujggraph:entryRefs ?entry .
?entry ujggraph:stateRef ?state .
FILTER (NOT EXISTS {
$this ujggraph:stateRefs ?state .
})
}
""" ;
] ;
sh:sparql [
a sh:SPARQLConstraint ;
sh:message "A JourneyEntry must be listed in the entryRefs of exactly one journey." ;
sh:select """
SELECT $this ?entry
WHERE {
$this ujggraph:entryRefs ?entry .
FILTER (
EXISTS {
?otherJourney a ujggraph:Journey ;
ujggraph:entryRefs ?entry .
FILTER ($this != ?otherJourney)
}
|| NOT EXISTS {
?declaringJourney a ujggraph:Journey ;
ujggraph:entryRefs ?entry .
}
)
}
""" ;
] ;
sh:sparql [
a sh:SPARQLConstraint ;
sh:message "A transition in transitionRefs has a from value that is not listed in this journey's stateRefs." ;
sh:select """
SELECT $this ?transition ?from
WHERE {
$this ujggraph:transitionRefs ?transition .
?transition ujggraph:from ?from .
FILTER (NOT EXISTS {
$this ujggraph:stateRefs ?from .
})
}
""" ;
] ;
sh:sparql [
a sh:SPARQLConstraint ;
sh:message "A transition in transitionRefs has a from value that references a JourneyExit." ;
sh:select """
SELECT $this ?transition ?from
WHERE {
$this ujggraph:transitionRefs ?transition .
?transition ujggraph:from ?from .
?from a ujggraph:JourneyExit .
}
""" ;
] ;
sh:sparql [
a sh:SPARQLConstraint ;
sh:message "A transition in transitionRefs has a to value that is not listed in this journey's stateRefs or exitRefs." ;
sh:select """
SELECT $this ?transition ?to
WHERE {
$this ujggraph:transitionRefs ?transition .
?transition ujggraph:to ?to .
FILTER (
NOT EXISTS { $this ujggraph:stateRefs ?to . }
&& NOT EXISTS { $this ujggraph:exitRefs ?to . }
)
}
""" ;
] ;
sh:sparql [
a sh:SPARQLConstraint ;
sh:message "A JourneyExit must be listed in the exitRefs of exactly one journey." ;
sh:select """
SELECT $this ?exit
WHERE {
$this ujggraph:exitRefs ?exit .
FILTER (
EXISTS {
?otherJourney ujggraph:exitRefs ?exit .
FILTER ($this != ?otherJourney)
}
|| NOT EXISTS {
?declaringJourney ujggraph:exitRefs ?exit .
}
)
}
""" ;
] ;
sh:sparql [
a sh:SPARQLConstraint ;
sh:message "A JourneyExit used as Transition.to must be listed in the same enclosing journey's exitRefs." ;
sh:select """
SELECT $this ?transition ?exit
WHERE {
$this ujggraph:transitionRefs ?transition .
?transition ujggraph:to ?exit .
?exit a ujggraph:JourneyExit .
FILTER (NOT EXISTS {
$this ujggraph:exitRefs ?exit .
})
}
""" ;
] ;
sh:sparql [
a sh:SPARQLConstraint ;
sh:message "A transition with fromExitRef must have a from value listed in the enclosing journey's stateRefs." ;
sh:select """
SELECT $this ?transition ?from
WHERE {
$this ujggraph:transitionRefs ?transition .
?transition ujggraph:fromExitRef ?exit ;
ujggraph:from ?from .
FILTER (NOT EXISTS {
$this ujggraph:stateRefs ?from .
})
}
""" ;
] ;
sh:sparql [
a sh:SPARQLConstraint ;
sh:message "A transition with toEntryRef must have a to value listed in the enclosing journey's stateRefs." ;
sh:select """
SELECT $this ?transition ?to
WHERE {
$this ujggraph:transitionRefs ?transition .
?transition ujggraph:toEntryRef ?entry ;
ujggraph:to ?to .
FILTER (NOT EXISTS {
$this ujggraph:stateRefs ?to .
})
}
""" ;
] ;
sh:sparql [
a sh:SPARQLConstraint ;
sh:message "A transition with toEntryRef must have a to value that references a CompositeState." ;
sh:select """
SELECT $this ?transition ?to
WHERE {
$this ujggraph:transitionRefs ?transition .
?transition ujggraph:toEntryRef ?entry ;
ujggraph:to ?to .
FILTER (NOT EXISTS {
?to a ujggraph:CompositeState .
})
}
""" ;
] ;
sh:sparql [
a sh:SPARQLConstraint ;
sh:message "The toEntryRef of a parent transition must be listed in the entryRefs of exactly one Journey referenced by the target CompositeState's subjourneyRefs." ;
sh:select """
SELECT $this ?transition ?to ?entry
WHERE {
$this ujggraph:transitionRefs ?transition .
?transition ujggraph:toEntryRef ?entry ;
ujggraph:to ?to .
FILTER (NOT EXISTS {
?to ujggraph:subjourneyRefs ?childJourney .
?childJourney ujggraph:entryRefs ?entry .
})
}
""" ;
] ;
sh:sparql [
a sh:SPARQLConstraint ;
sh:message "The toEntryRef of a parent transition must not be listed in more than one Journey referenced by the target CompositeState's subjourneyRefs." ;
sh:select """
SELECT $this ?transition ?to ?entry
WHERE {
$this ujggraph:transitionRefs ?transition .
?transition ujggraph:toEntryRef ?entry ;
ujggraph:to ?to .
?to ujggraph:subjourneyRefs ?childJourneyA, ?childJourneyB .
?childJourneyA ujggraph:entryRefs ?entry .
?childJourneyB ujggraph:entryRefs ?entry .
FILTER (?childJourneyA != ?childJourneyB)
}
""" ;
] ;
sh:sparql [
a sh:SPARQLConstraint ;
sh:message "A transition with fromExitRef must have a from value that references a CompositeState." ;
sh:select """
SELECT $this ?transition ?from
WHERE {
$this ujggraph:transitionRefs ?transition .
?transition ujggraph:fromExitRef ?exit ;
ujggraph:from ?from .
FILTER (NOT EXISTS {
?from a ujggraph:CompositeState .
})
}
""" ;
] ;
sh:sparql [
a sh:SPARQLConstraint ;
sh:message "The fromExitRef of a parent transition must be listed in the exitRefs of exactly one Journey referenced by the source CompositeState's subjourneyRefs." ;
sh:select """
SELECT $this ?transition ?from ?exit
WHERE {
$this ujggraph:transitionRefs ?transition .
?transition ujggraph:fromExitRef ?exit ;
ujggraph:from ?from .
FILTER (NOT EXISTS {
?from ujggraph:subjourneyRefs ?childJourney .
?childJourney ujggraph:exitRefs ?exit .
})
}
""" ;
] ;
sh:sparql [
a sh:SPARQLConstraint ;
sh:message "The fromExitRef of a parent transition must not be listed in more than one Journey referenced by the source CompositeState's subjourneyRefs." ;
sh:select """
SELECT $this ?transition ?from ?exit
WHERE {
$this ujggraph:transitionRefs ?transition .
?transition ujggraph:fromExitRef ?exit ;
ujggraph:from ?from .
?from ujggraph:subjourneyRefs ?childJourneyA, ?childJourneyB .
?childJourneyA ujggraph:exitRefs ?exit .
?childJourneyB ujggraph:exitRefs ?exit .
FILTER (?childJourneyA != ?childJourneyB)
}
""" ;
] ;
sh:sparql [
a sh:SPARQLConstraint ;
sh:message "A transition with fromExitRef must have a to value listed in the enclosing journey's stateRefs or exitRefs." ;
sh:select """
SELECT $this ?transition ?to
WHERE {
$this ujggraph:transitionRefs ?transition .
?transition ujggraph:fromExitRef ?exit ;
ujggraph:to ?to .
FILTER (
NOT EXISTS { $this ujggraph:stateRefs ?to . }
&& NOT EXISTS { $this ujggraph:exitRefs ?to . }
)
}
""" ;
] ;
sh:sparql [
a sh:SPARQLConstraint ;
sh:message "A journey must not contain more than one transition with the same from value and the same fromExitRef value." ;
sh:select """
SELECT $this ?from ?exit ?transition ?otherTransition
WHERE {
$this ujggraph:transitionRefs ?transition, ?otherTransition .
?transition ujggraph:from ?from ;
ujggraph:fromExitRef ?exit .
?otherTransition ujggraph:from ?from ;
ujggraph:fromExitRef ?exit .
FILTER (?transition != ?otherTransition)
}
""" ;
] ;
sh:sparql [
a sh:SPARQLConstraint ;
sh:severity sh:Warning ;
sh:message "A state in Journey.stateRefs is not an entry state or a local transition endpoint. Verify that it belongs to the journey's experiential local topology and is not only a linked destination." ;
sh:select """
SELECT $this ?state
WHERE {
$this ujggraph:stateRefs ?state .
FILTER (NOT EXISTS {
$this ujggraph:entryRefs ?entry .
?entry ujggraph:stateRef ?state .
})
FILTER (NOT EXISTS {
$this ujggraph:transitionRefs ?transition .
?transition ujggraph:from ?state .
})
FILTER (NOT EXISTS {
$this ujggraph:transitionRefs ?transition .
?transition ujggraph:to ?state .
})
}
""" ;
] .
ujggraphshape:JourneyEntryShape a sh:NodeShape ;
sh:targetClass ujggraph:JourneyEntry ;
sh:nodeKind sh:IRI ;
sh:property [
sh:path ujggraph:stateRef ;
sh:minCount 1 ;
sh:maxCount 1 ;
sh:node ujggraphshape:StateLikeShape ;
] ;
sh:property [
sh:path ujggraph:label ;
sh:datatype xsd:string ;
sh:maxCount 1 ;
] ;
sh:property [
sh:path ujggraph:tags ;
sh:datatype xsd:string ;
] ;
sh:property [
sh:path ujggraph:subjourneyRefs ;
sh:maxCount 0 ;
sh:message "A JourneyEntry must not declare subjourneyRefs." ;
] ;
sh:sparql [
a sh:SPARQLConstraint ;
sh:message "A JourneyEntry must be listed in the entryRefs of exactly one journey." ;
sh:select """
SELECT $this
WHERE {
FILTER (
NOT EXISTS {
?journey a ujggraph:Journey ;
ujggraph:entryRefs $this .
}
|| EXISTS {
?journeyA a ujggraph:Journey ;
ujggraph:entryRefs $this .
?journeyB a ujggraph:Journey ;
ujggraph:entryRefs $this .
FILTER (?journeyA != ?journeyB)
}
)
}
""" ;
] ;
sh:sparql [
a sh:SPARQLConstraint ;
sh:message "A JourneyEntry must not be used as the from or to value of a Transition." ;
sh:select """
SELECT $this ?transition
WHERE {
{
?transition ujggraph:from $this .
}
UNION
{
?transition ujggraph:to $this .
}
}
""" ;
] .
ujggraphshape:JourneyEntryIndexShape a sh:NodeShape ;
sh:targetClass ujggraph:JourneyEntryIndex ;
sh:nodeKind sh:IRI ;
sh:property [
sh:path ujggraph:entryRefs ;
sh:minCount 1 ;
sh:class ujggraph:JourneyEntry ;
sh:nodeKind sh:IRI ;
] ;
sh:property [
sh:path ujggraph:transitionRefs ;
sh:maxCount 0 ;
sh:message "A JourneyEntryIndex must not declare transitionRefs." ;
] ;
sh:property [
sh:path ujggraph:exitRefs ;
sh:maxCount 0 ;
sh:message "A JourneyEntryIndex must not declare exitRefs." ;
] ;
sh:property [
sh:path ujggraph:outgoingTransitionGroupRefs ;
sh:maxCount 0 ;
sh:message "A JourneyEntryIndex must not declare outgoingTransitionGroupRefs." ;
] ;
sh:property [
sh:path ujggraph:from ;
sh:maxCount 0 ;
sh:message "A JourneyEntryIndex must not declare from." ;
] ;
sh:property [
sh:path ujggraph:to ;
sh:maxCount 0 ;
sh:message "A JourneyEntryIndex must not declare to." ;
] ;
sh:property [
sh:path ujggraph:fromExitRef ;
sh:maxCount 0 ;
sh:message "A JourneyEntryIndex must not declare fromExitRef." ;
] ;
sh:property [
sh:path ujggraph:toEntryRef ;
sh:maxCount 0 ;
sh:message "A JourneyEntryIndex must not declare toEntryRef." ;
] ;
sh:property [
sh:path ujggraph:defaultEntryRef ;
sh:maxCount 0 ;
sh:message "A JourneyEntryIndex must not declare defaultEntryRef." ;
] ;
sh:property [
sh:path ujggraph:stateRefs ;
sh:maxCount 0 ;
sh:message "A JourneyEntryIndex must not declare stateRefs." ;
] ;
sh:property [
sh:path ujggraph:stateRef ;
sh:maxCount 0 ;
sh:message "A JourneyEntryIndex must not declare stateRef." ;
] ;
sh:property [
sh:path ujggraph:subjourneyRefs ;
sh:maxCount 0 ;
sh:message "A JourneyEntryIndex must not declare subjourneyRefs." ;
] ;
sh:property [
sh:path ujggraph:outgoingTransitionRefs ;
sh:maxCount 0 ;
sh:message "A JourneyEntryIndex must not declare outgoingTransitionRefs." ;
] .
ujggraphshape:StateShape a sh:NodeShape ;
sh:targetClass ujggraph:State ;
sh:nodeKind sh:IRI ;
sh:property [
sh:path ujggraph:label ;
sh:datatype xsd:string ;
sh:minCount 1 ;
sh:maxCount 1 ;
] ;
sh:property [
sh:path ujggraph:tags ;
sh:datatype xsd:string ;
] ;
sh:property [
sh:path ujggraph:multiInstance ;
sh:datatype xsd:boolean ;
sh:maxCount 1 ;
] ;
sh:property [
sh:path ujggraph:outgoingTransitionRefs ;
sh:class ujggraph:OutgoingTransition ;
sh:nodeKind sh:IRI ;
] .
ujggraphshape:CompositeStateShape a sh:NodeShape ;
sh:targetClass ujggraph:CompositeState ;
sh:nodeKind sh:IRI ;
sh:property [
sh:path ujggraph:label ;
sh:datatype xsd:string ;
sh:minCount 1 ;
sh:maxCount 1 ;
] ;
sh:property [
sh:path ujggraph:tags ;
sh:datatype xsd:string ;
] ;
sh:property [
sh:path ujggraph:multiInstance ;
sh:datatype xsd:boolean ;
sh:maxCount 1 ;
] ;
sh:property [
sh:path ujggraph:stateRefs ;
sh:maxCount 0 ;
sh:message "A CompositeState must not use stateRefs; use subjourneyRefs to reference one or more child Journeys." ;
] ;
sh:property [
sh:path ujggraph:outgoingTransitionRefs ;
sh:maxCount 0 ;
sh:message "A CompositeState must not declare outgoingTransitionRefs. Use an OutgoingTransitionGroup on the enclosing Journey, or attach outgoingTransitionRefs to concrete States inside a child Journey." ;
] ;
sh:property [
sh:path ujggraph:subjourneyRefs ;
sh:class ujggraph:Journey ;
sh:nodeKind sh:IRI ;
sh:minCount 1 ;
] .
ujggraphshape:TransitionShape a sh:NodeShape ;
sh:targetClass ujggraph:Transition ;
sh:nodeKind sh:IRI ;
sh:property [
sh:path ujggraph:from ;
sh:minCount 1 ;
sh:maxCount 1 ;
sh:node ujggraphshape:StateLikeShape ;
] ;
sh:property [
sh:path ujggraph:to ;
sh:minCount 1 ;
sh:maxCount 1 ;
sh:node ujggraphshape:LocalVertexShape ;
] ;
sh:property [
sh:path ujggraph:label ;
sh:datatype xsd:string ;
sh:maxCount 1 ;
] ;
sh:property [
sh:path ujggraph:fromExitRef ;
sh:class ujggraph:JourneyExit ;
sh:nodeKind sh:IRI ;
sh:maxCount 1 ;
] ;
sh:property [
sh:path ujggraph:toEntryRef ;
sh:class ujggraph:JourneyEntry ;
sh:nodeKind sh:IRI ;
sh:maxCount 1 ;
] ;
sh:property [
sh:path ujggraph:commandRef ;
sh:class ujggraph:Command ;
sh:nodeKind sh:IRI ;
sh:maxCount 1 ;
] ;
sh:property [
sh:path ujggraph:subjourneyRefs ;
sh:maxCount 0 ;
sh:message "A Transition must not declare subjourneyRefs." ;
] .
ujggraphshape:JourneyExitShape a sh:NodeShape ;
sh:targetClass ujggraph:JourneyExit ;
sh:nodeKind sh:IRI ;
sh:property [
sh:path ujggraph:label ;
sh:datatype xsd:string ;
sh:maxCount 1 ;
] ;
sh:property [
sh:path ujggraph:tags ;
sh:datatype xsd:string ;
] ;
sh:property [
sh:path ujggraph:outgoingTransitionRefs ;
sh:maxCount 0 ;
sh:message "A JourneyExit must not declare outgoingTransitionRefs." ;
] ;
sh:property [
sh:path ujggraph:subjourneyRefs ;
sh:maxCount 0 ;
sh:message "A JourneyExit must not declare subjourneyRefs." ;
] ;
sh:sparql [
a sh:SPARQLConstraint ;
sh:message "A JourneyExit must not also be typed State." ;
sh:select """
SELECT $this
WHERE {
$this a ujggraph:State .
}
""" ;
] ;
sh:sparql [
a sh:SPARQLConstraint ;
sh:message "A JourneyExit must be listed in the exitRefs of exactly one journey." ;
sh:select """
SELECT $this
WHERE {
FILTER (
NOT EXISTS { ?journey ujggraph:exitRefs $this . }
|| EXISTS {
?journeyA ujggraph:exitRefs $this .
?journeyB ujggraph:exitRefs $this .
FILTER (?journeyA != ?journeyB)
}
)
}
""" ;
] ;
sh:sparql [
a sh:SPARQLConstraint ;
sh:message "A JourneyExit must not be used as the from value of a Transition." ;
sh:select """
SELECT $this ?transition
WHERE {
?transition ujggraph:from $this .
}
""" ;
] .
ujggraphshape:OutgoingTransitionShape a sh:NodeShape ;
sh:targetClass ujggraph:OutgoingTransition ;
sh:nodeKind sh:IRI ;
sh:property [
sh:path ujggraph:to ;
sh:maxCount 1 ;
sh:node ujggraphshape:OutgoingTargetShape ;
] ;
sh:property [
sh:path ujggraph:toCurrentState ;
sh:datatype xsd:boolean ;
sh:maxCount 1 ;
] ;
sh:property [
sh:path ujggraph:label ;
sh:datatype xsd:string ;
sh:maxCount 1 ;
] ;
sh:property [
sh:path ujggraph:commandRef ;
sh:class ujggraph:Command ;
sh:nodeKind sh:IRI ;
sh:maxCount 1 ;
] ;
sh:property [
sh:path ujggraph:subjourneyRefs ;
sh:maxCount 0 ;
sh:message "An OutgoingTransition must not declare subjourneyRefs." ;
] ;
sh:sparql [
a sh:SPARQLConstraint ;
sh:message "An OutgoingTransition must declare exactly one effective target mechanism: either exactly one to value or toCurrentState true." ;
sh:select """
SELECT $this
WHERE {
FILTER (
NOT EXISTS { $this ujggraph:to ?to . }
&& NOT EXISTS { $this ujggraph:toCurrentState true . }
)
}
""" ;
] ;
sh:sparql [
a sh:SPARQLConstraint ;
sh:message "An OutgoingTransition with toCurrentState true must not also declare to." ;
sh:select """
SELECT $this ?to
WHERE {
$this ujggraph:to ?to ;
ujggraph:toCurrentState true .
}
""" ;
] .
ujggraphshape:OutgoingTransitionGroupShape a sh:NodeShape ;
sh:targetClass ujggraph:OutgoingTransitionGroup ;
sh:nodeKind sh:IRI ;
sh:property [
sh:path ujggraph:outgoingTransitionRefs ;
sh:class ujggraph:OutgoingTransition ;
sh:nodeKind sh:IRI ;
sh:minCount 1 ;
] ;
sh:property [
sh:path ujggraph:subjourneyRefs ;
sh:maxCount 0 ;
sh:message "An OutgoingTransitionGroup must not declare subjourneyRefs." ;
] . 16. Graph Integrity and Resolution
The rules below define additional graph integrity and resolution behavior beyond the structural constraints captured by the SHACL shape.
To ensure graph integrity, the following constraints MUST be met:
Every Graph reference MUST resolve within the current scope or imported modules.
References MUST resolve to the class expected by the property that uses them.
Local Transition endpoints MUST stay inside the declaring Journey's local vertex set.
toEntryRefandfromExitRefMUST resolve through one of the child Journeys referenced by the relevant CompositeState'ssubjourneyRefs. The referenced JourneyEntry or JourneyExit MUST be owned by exactly one such child Journey.Every
subjourneyRefsvalue MUST resolve to a Journey.A
subjourneyRefsset MUST contain at least one Journey.The same Journey MUST NOT occur more than once in the RDF set represented by
subjourneyRefs.Child Journey containment MUST NOT weaken Transition endpoint locality.
No edge between child Journeys is inferred from their common CompositeState.
Each OutgoingTransition MUST resolve to exactly one target mechanism: fixed
toortoCurrentState: true.Each
commandRefMUST resolve to a Command.