Conceptually, a path is a function, from object to object collection, that returns some of the objects reachable along a specified set of associations. The term "anchor" denotes the initial object (the parameter of a path). In general, a path in Q can be any arbitrary directed graph. This path is a linear representation of a directed graph for the syntax of paths.
Here is an example of a simple path:
model->[project]->[containedPackages]->[classes]->[operation]
This path describes a simple linear traversal of three associations. This path says that, starting from the object model, follow the association "project" and then "containedPackages" and then "classes" and then "operation." The result of applying this path to the anchor model is a collection of all instances of the metaclass Operation that belong to some class in the package at the end of the association "project." The following illustration shows the portion of the metamodel that this path traverses.
For example, Project has the role "project" in an association with Model, and Class has the role "classes" in an association with Package.
The following illustration shows an object structure to which you can apply this path. In this case, the path would evaluate to a collection of the objects opA1, opA2, opA3, and opC1

So, in the syntax of paths, a node (such as [project]) represents an association to traverse, and an edge (->) between two nodes specifies the order of traversal. In the syntax, the symbol -> also separates the anchor from the actual path, and the anchor is optional. When an anchor is omitted, the implied anchor is the object currently bound to the variable current. So the path [project] is a shorthand for current->[project].
The following example shows a path with a cycle:
model->[project]->[containedPackages]->top:^[nestedPackages]->@top
This example introduces three new syntactical elements. These are node labels (top:), add-to-result annotations (^), and reference nodes (@top). Labels and reference nodes provide a way of encoding the two-dimensional structure of cycles, and other nonlinear structures, of complex paths. In this example, there is a cycle from the node labeled "top" to itself. This cycle corresponds to the reflexive association nestedPackages of Package, which is an association to all the immediate nested packages of a Package.
The purpose of this cycle is to traverse all nested packages of a package, including those packages in the nestedPackages of a package. The result of applying this path to model is a collection of all instances of Package that are nested packages, directly and indirectly, of the package at the end of the association containedPackages of project in model. But in order for this path to work in this way, we have to use the add-to-result annotation ^. This annotation on the node [nestedPackages] means that all objects found at the end of the association nestedPackages must be added to the result set. All nodes that do not have any outgoing edges have the add-to-result annotation implicitly. So in our first example, the node [operation] has the add-to-result annotation implicitly. In the case of the second example, however, all nodes have outgoing edges because of the cycle. Therefore, no node has the add-to-result annotation implicitly.
[Project]->containedPackages]->top:^
[nestedPackages]->@top

This next example shows a node with more than one outgoing edge:
model->[project]->[containedPackages]->top:[]->([classes]; [nestedPackages]->@top)
In this example, the node labeled "top" has two successors, the nodes [classes] and [nestedPackages]. In this case, the node "top" is also an empty association ([]). So "top" only serves to structure the nodes in the path. The node [classes] does not have any outgoing edges (the arrow to Result in Node with More that One Outgoing Edge is not related to the structure of the path), so it has the add-to-result annotation implicitly.
top:[ ]->([classes]); [nestedPackages]->@top

Therefore, the result of applying this path to model is a collection of all instances of Class that belong either to the package at the end of the association containedPackage of project in model or to a nested package of that package.
This example shows two nodes with conditions:
aPackage->[nestedPackages]{$name="PkgA"}->[classes]{$name~="*Impl"}
Any node in a path might be accompanied by a condition. The condition, which appears in curly braces after the association name, specifies a predicate that objects in an association must satisfy before such objects are allowed to pass through a node. In this example, the condition {$name="PkgA"} allows only the objects named "PkgA" to reach the node [classes], and the condition {$name~="*Impl"} allows only the objects that have a name matching the regular expression "*Impl" to appear in the result set. The effect of [nestedPackages]{$name="PkgA"} is exactly that of filter {$name="PkgA"} over [nestedPackages]. See the documentation of filter for the details of how the condition expression is evaluated.
Paths are functions from object to object collection. They yield the objects reachable along a set of associations. Paths encode this computation in their graph structure—in essence, the structure is the computation. To be more precise, paths are data flow graphs, and they resemble data flow in their execution. So in the data flow view, paths now consist of data links and operations. Data links correspond to edges, and operations correspond to nodes. Data links are conduits along which objects flow, and operations are basic computations that accept objects from incoming data links and produce objects on outgoing data links.
Consider, for instance, the following path:
model->[project]->[containedPackages]->[classes]->[operation]
This path consists of the operations [project], [containedPackages], [classes], and [operation] linked together linearly. When the object model flows into [project], all the objects in the association "project" of model flow out. Then all these objects flow into [containedPackages], which causes the objects in the association containedPackages to flow out. Then all these objects flow into [classes], and the objects in the association "classes" flow out. Then all these objects flow into [operation], and the objects in the association "operation" flow out. Finally, these objects flow into the (implicit) result node for the complete path. All objects produced by leaf nodes implicitly flow into the result node, which collects the objects produced by the complete path.
The evaluation of a path ends when the flow of objects ceases. Hence, some care is needed to ensure that a path terminates. Stated precisely, a path does not terminate if, and only if, an object revisits an operation, either because the object itself completes a cycle or because a cascade of objects completes a cycle.
There are some boundary cases in the behavior of operations. First, the operation [] is the identity operation. All objects simply flow through. Second, an operation [α] does not produce any output if the input object does not have any objects in the association α. Third, an operation [α] also does not produce any output if the metaclass of the input object does not have the association α. So, for example, the operation [nestedPackages] would not produce any output if the input object is an instance of Class rather than Package.