Okay, now that we know what Term Expansion is, let's see how we can use it. In XSB (and I think in every other commercial Prolog compiler), there's a
term_expansion/2
builtin, which describes how the first argument should be transformed into the second before it gets fed into the compiler. That means that we won't have access into the old version of our code after term expansion, and that's fine. If we need the old form of the code as well, we can always assert it dynamically :)I usually start off my term-expansion-preprocessors with the following assertion:
:- assertz((term_expansion(X,Y) :- !, do_term_expansion(X,Y))).
That means that this rule will be asserted last (in the end of the database). So,
term_expansion/2
will automatically be called while loading the file, and control will be handed to our do_term_expansion/2
routines. Next, let's handle the "end of file" case. Luckily, XSB has a builtin predicate end_of_file/1
which we can write at any point of our program, and will signal...well...the end of the file :) We want our preprocessing to stop when the end of the file is reached, so voila:do_term_expansion(end_of_file,_) :- !, (import member/2 from basics),
writeln('end of file!'), fail.
In this case, I just want to import something from the basics module, write that the file has ended, and fail. Now for the interesting part. Firstly, suppose the original program contains static facts of the form
uses(A,B)
and distr(A,B)
. Let's just assert them in our post-processed version: do_term_expansion((uses(A,B)),_) :- !, assert(uses(A,B)).
do_term_expansion((distr(A,B,C)),_) :- !, assert(distr(A,B,C)).
Now these will be available to the post-processed version. Finally, let's say we want to just throw away the body of each clause (not a very useful transformation huh? :) ); that's easily done as follows:
do_term_expansion((Head :- Body), (Head :- true)) :- !,
And that should work :) You can do a bunch of helpful things with Term Expansion; like DCG argument-adding (that I mentioned before). I used Term Expansion in a project for adding probabilities in Well-Founded Semantics (where we wanted to add extra arguments in each predicate - sounds familiar? :) ).
Moral of the day: Use term expansion. It's (sometimes) easier than writing regular expressions in Perl or sed!
No comments:
Post a Comment