Xcerpt Tutorial - Chapter 4 (Rule Chaining)

This document is (c)2003 Sebastian Schaffert and the Xcerpt Team.
Please contact schaffer@informatik.uni-muenchen.de on any questions.

Rule Chaining

Xcerpt programs may not only contain a single goal, but consist of several goals and rules. An Xcerpt rule is similar to a goal, but it has no output resource associated with it and there are cases in which a rule is never evaluated. Rules are similar to functions in other programming languages. Rules are of the following form:
CONSTRUCT
  <construct part>
FROM
  <query part>
END
      

Query parts that are not associated with resources always query the construct parts of the rules in the program. If the unification of a query term with the construct term of a rule does not fail, then this rule is evaluated and the resulting variable bindings are "chained" with those resulting from the unification.

We illustrate rule chaining by a small example (in a Prolog-like syntax; X,Y,Z are variables, a,b are labels):

p(X,Y) ← q(X) and r(Y)
q(Z) ← r(Z)
q(a)
r(b)
	

Valid answers for p(X,Y) are p(b,b) and p(a,b), as the query for q(X) can be satisfied either by q(a) or by satisfying the rule q(Z) ← r(Z) which in turn can be satisifed by r(b).

Rule Chaining in Xcerpt can be used to build very complex, also recursive query programs. An example follows in the next section.

Separation of Presentation and Logic

An important paradigm for good program design is the separation of content generation (logic) and content presentation (stylesheets), as it allows for easier maintanance and extension of the program. This example combines the rule for generating a summary of prices in two bookstores from Chapter 3 (content generation) with two different "stylesheets" for generating HTML and WML output for rendering in a browser and on a mobile device respectively:
GOAL
  out {
    resource {"stdout:", "html"},
    html [
      head [ title [ "Output of Query-5-Extended" ] ],
      body [
        h1 [ "Example Query-5-Extended Results:" ],
        table [
          tr [ td [ "Title" ], td [ "Price at A" ], td [ "Price at B" ] ],
          all tr [ td [ var Title ], td [ var PriceA ], td [ var PriceB ] ]
        ]
      ]
    ]
  }
FROM
  books-with-prices [[
    book-with-prices [
      title   [ var Title  ],
      price-a [ var PriceA ],
      price-b [ var PriceB ]
    ]
  ]]
END

GOAL
  out {
    resource {"stdout:", "xml"},
    wml [
      all card [
        "Title: ", var Title ,
        "Price A: ", var PriceA,
        "Price B: ", var PriceB
      ]
    ]
  }
FROM
  books-with-prices [[
    book-with-prices [
      title   [ var Title  ],
      price-a [ var PriceA ],
      price-b [ var PriceB ]
    ]
  ]]
END

CONSTRUCT
  books-with-prices [
    all book-with-prices [
      title [ var T ],
      price-a [ var Pa ],
      price-b [ var Pb ]
    ]
  ]
FROM
  and {
    in { 
      resource {"file:bib.xml"},
      bib {{
        book {{
          title { var T  },
          price { var Pa }
        }}
      }}
    },
    in {
      resource {"file:reviews.xml"},
      reviews {{
        entry {{
          title { var T },
          price { var Pb }
        }}
      }}
    }
  }
END
      

Sebastian Schaffert
Last modified: Wed Mar 12 12:49:34 CET 2003