23 Path Tails

A path tail is any expression that can appear to the right of a dot in a Predica path expression. Path tails include attribute access, filters, tuple constructions, scalar expressions, and nested combinations of these.

We use the term path tail to highlight that such an expression has meaning in the context of a full path expression in which it appears.

For example, if there is no program variable named course, then an expression like course.session is a path tail rather than a complete path expression by itself. It is meaningful as the tail of a larger path expression such as:


u.course.session

Given a variable s of type ShipmentsSystem, consider the path expression:


s.supplier.[city = "London"].(name,status)

This expression contains the following path tails:


    •  supplier
    •  city
    •  name
    •  status
    •  (name,status)
    •  [city = "London"]
    •  supplier.[city = "London"]
    •  supplier.[city = "London"].(name,status)
    •  [city = "London"].(name,status)

Path tails can also include:

  • renamed tails (e.g., name as n)
  • universal tails (e.g., supplier⇒order)
  • logical combinations (e.g., named ⊓ status)
  • scalar expressions (e.g., qty * price)
  • constants (e.g., 42, "London" )
  • nested tuples (e.g., (name,(status,city)) )
  • deeper chains (e.g., shipment.part.name )

Square brackets are the filter form. A round tail constructs a tuple or scalar projection even when the projected item is Boolean, so document.(kind = DocumentKind.customsEntry) is not the same path as document.[kind = DocumentKind.customsEntry].

To catch this common mistake, a single predicate-shaped round projection followed directly by Σexists is rejected by the source language. Predicate-shaped projections include comparisons, logical connectives, cardinality tests, type tests, and logical negation. Write:


document.[kind = DocumentKind.customsEntry].Σexists

rather than:


document.(kind = DocumentKind.customsEntry).Σexists