% $Id: XPathWadler.lsl,v 1.8 2000/01/17 21:33:41 connolly Exp $ % %html A formal semantics of patterns in XSLT %html 16 July 1999 %html by Philip Wadler XPathWadler: trait includes XMLWadler % sections 2, 3 of the paper introduces % 5 A semantics for Patterns __ | __: Pattern, Pattern -> Pattern % default larch config doesn't have / as an op char, so we use ! ! __ : Pattern -> Pattern !! __ : Pattern -> Pattern __ ! __ : Pattern, Pattern -> Pattern __ !! __ : Pattern, Pattern -> Pattern __ [__] : Pattern, Qualifier -> Pattern [__] : String -> Pattern % Wadler's notation doesn't need [] % @@isName: where does the Name set comefrom? % is it a subset of String? star : -> Pattern % * @ __ : String -> Pattern % isName@@ atStar : -> Pattern text : -> Pattern comment : -> Pattern pi: String -> Pattern % isName pi: -> Pattern id: Pattern -> Pattern id: String -> Pattern ancestor: Pattern -> Pattern ancestor_or_self: Pattern -> Pattern dot : -> Pattern dotdot : -> Pattern and: Qualifier, Qualifier -> Qualifier or: Qualifier, Qualifier -> Qualifier notq: Qualifier -> Qualifier first_of_type: -> Qualifier last_of_type: -> Qualifier first_of_any: -> Qualifier last_of_any: -> Qualifier __ \equal __ : Pattern, String -> Qualifier [ __ ] : Pattern -> Qualifier % wadler's notation doesn't need [] M: Pattern, Node -> Bool % Wadler's formulation is M : Pattern -> Node -> Boolean % but larch is 1st order, so I (un?)curried it. S: Pattern -> R[Node] Q: Qualifier, Node -> Bool % again, curried siblingElements: Node -> FiniteSet[Node] ancAux: Pattern, Node -> FiniteSet[Node] ancSelfAux: Pattern, Node -> FiniteSet[Node] firstAux: Node -> FiniteSet[Node] asserts Pattern generated by | , !__, __ ! __ , !! __, __!!__, __ [__], [__], star, @, atStar, text, comment, pi:String->Pattern, pi:->Pattern, id:Pattern->Pattern, id:String->Pattern, ancestor, ancestor_or_self, dot, dotdot Qualifier generated by and, or, notq, first_of_type, last_of_type, first_of_any, last_of_any, \equal, [__] \forall p, p1, p2: Pattern, x, y, x1, x2, x3: Node, q, q1, q2: Qualifier, n, s, s1: String, ns: FiniteSet[Node] % Figure 1: Semantics of patterns ... M(p, x) = \E x1 (x1 \in (subnodes\superstar)[root(x)] /\ x \in S(p)[x1]); S(p1 | p2)[x] = S(p1)[x] \U S(p2)[x]; S(!p)[x] = S(p)[root(x)]; % where wadler writes S ::= { x | P(x) } % we write x \in S = P(x) % @@c.f. comp.specification.larch discussion x2 \in S(!!p)[x] = \E x1 (x1 \in (subnodes\superstar)[root(x)] /\ x2 \in S(p)[x1]); x2 \in S(p1!p2)[x] = \E x1 (x1 \in S(p1)[x] /\ x2 \in S(p2)[x1]); x3 \in S(p1!!p2)[x] = \E x1 \E x2 (x1 \in S(p1)[x] /\ x2 \in (subnodes\superstar)[x1] /\ x3 \in S(p2)[x2]); x1 \in S(p[q])[x] = x1 \in S(p)[x] /\ Q(q, x1); x1 \in S([n])[x] = x1 \in subnodes[x] /\ isElement(x1) /\ name(x1) = n; x1 \in S(star)[x] = x1 \in subnodes[x] /\ isElement(x1); x1 \in S(@ n)[x] = x1 \in subnodes[x] /\ isAttribute(x1) /\ name(x1) = n; x1 \in S(atStar)[x] = x1 \in subnodes[x] /\ isAttribute(x1); x1 \in S(text)[x] = x1 \in subnodes[x] /\ isText(x1); x1 \in S(comment)[x] = x1 \in subnodes[x] /\ isComment(x1); x1 \in S(pi(n))[x] = x1 \in subnodes[x] /\ isPI(x1) /\ name(x1) = n; x1 \in S(pi)[x] = x1 \in subnodes[x] /\ isPI(x1); x2 \in S(id(p))[x] = \E x1 (x1 \in S(p)[x] /\ \E s (s \in split(value(x1)) /\ x2 \in id(s))); x1 \in S(id(s))[x] = \E s1 (s1 \in split(s) /\ x1 \in id(s1)); S(ancestor(p))[x] = last(ancAux(p, x)); x1 \in ancAux(p, x) = x1 \in (parent\superplus)[x] /\ M(p, x1); S(ancestor_or_self(p))[x] = last(ancSelfAux(p, x)); x1 \in ancSelfAux(p, x) = x1 \in (parent\superstar)[x] /\ M(p, x1); S(dot)[x] = {x}; S(dotdot)[x] = parent[x]; Q(and(q1, q2), x) = Q(q1, x) /\ Q(q2, x); Q(or(q1, q2), x) = Q(q1, x) \/ Q(q2, x); Q(notq(q), x) = ~ Q(q, x); Q(first_of_type, x) = x \in first(firstAux(x)); x1 \in firstAux(x) = x1 \in siblingElements(x) /\ name(x1) = name(x); % Wadler paper missing x1 \in before siblingElements??? Q(last_of_type, x) = x \in last(firstAux(x)); Q(first_of_any, x) = x \in first(siblingElements(x)); Q(last_of_any, x) = x \in last(siblingElements(x)); Q(p \equal s, x) = \E x1 (x1 \in S(p)[x] /\ value(x1) = s); Q([p], x) = (S(p)[x] \neq {}); x2 \in siblingElements(x) = \E x1 (x1 \in parent[x] /\ x2 \in subnodes[x] /\ isElement(x2)); implies converts siblingElements, ancAux, ancSelfAux, firstAux, M, S, Q