have been re-implemented to make use of the mechanism.  We have experimentally evaluated these re-implementations, and the results of these experiments confirm that large speedups may be obtained in this way. We conjecture that the query pack execution mechanism can be incorporated in other ILP systems and that similar speedups can be expected.

The problem setting in which query pack execution was introduced is very general, and alows the tenique to be used for any kind of task where many queries are to be executed on the same data, as long as the queries can be organised in a hierarchy.

Future work includes further improvements to the ILPROLOG engine and the implementation of techniques that will increase the suitability of the engine to handle large data sets.

In the best case one might hope to combine techniques known from database optimisation and program analysis with our pack execution mechanism to further improve the speed of ILP systems.

## Acknow Ledgements

Hendrik Blockeel is a post-doctoral fellow of the Fund for Scientific Research (FWO) of Flanders.  Jan Ramon is funded by the Flemish Institute for the Promotion of Scientific Research in Industry (IWT). Henk Vandecasteele was funded in part by the FWO project G.0246.99, "Query languages for database mining". The authors thank Luc De Raedt for his influence on this work, Ashwin Srinivasan for suggesting the term "query packs", the anonymous reviewers for their useful comments, and Kurt Driessens for proofreading this text. This work was motivated in part by the Esprit project 28623, Aladin.

## Appendix A. Preparing The Query For The Meta-Interpreter

Note that the following preprocessor assumes that the pack of the form a, (b, (c or d or e) or f or g, (h or i or j)) was already transformed to the form a , or([(b, or([c,d,e])), f, (g, or([h,i,j]))]).

preprocess((A,B),(A,NewB),PrevNode,NodeNr0,LeafNr0,BranchNr,NodeNr1,LeafNr1):- !,
preprocess(B,NewB,PrevNode,NodeNr0,LeafNr0,BranchNr,NodeNr1,LeafNr1).

preprocess(or(Querys),or(NQuerys,PrevNode,NodeNr0,BranchNr,Length),
PrevNode,NodeNr0,LeafNr0,BranchNr, NodeNr1,LeafNr1):- !,
NodeNr2 is NodeNr0 + 1, preprocessbranches(Querys,NQuerys,NodeNr0,NodeNr2,LeafNr0, 1, NodeNr1, LeafNr1, Length).

preprocess(A,(A,leaf(PrevNode,BranchNr,LeafNr0)),
PrevNode,NodeNr0,LeafNr0, BranchNr,NodeNr0,LeafNr1):-
LeafNr1 is LeafNr0 + 1.

preprocessbranches([],[],=,NodeNr,LeafNr,BranchNr, NodeNr,LeafNr,BranchNr).

preprocessbranches([Query|Querys],[NewQuery|NewQuerys],PrevNode, NodeNr0,LeafNr0,BranchNr, NodeNr1,LeafNr1,Length):-
preprocess(Query,NewQuery, PrevNode,NodeNr0,LeafNr0,BranchNr, NodeNr2,LeafNr2),
BranchNr1 is BranchNr + 1, preprocessbranches(Querys,NewQuerys, PrevNode, NodeNr2,LeafNr2,BranchNr1, NodeNr1,LeafNr1,Length).