Module expand [preloaded]

Clauses and goals are automatically expanded for the Prolog session queries, for the Prolog text clauses and for the Prolog text directives. The effect can be seen by the following example. The first goal_expansion/2 fact defines a new expansion for the predicate writeln/2. The next rule for the predicate hello/0 already makes use of the expansion in the body:

Example:
?- [user].
goal_expansion(writeln(X), (write(X), nl)).
hello :- writeln('Hello World!').
^D
?- listing(hello/0).
hello :-
write('Hello World!'), nl.

The clauses are expanded with the help of the system predicate expand_term/2, which in turn expands the goals of the bodies via the system predicate expand_goal/2. The two system predicates are customizable by the end-user via additional rules for the multi-file predicates term_expansion/2 and goal_expansion/2. If the additional multi-file rules fail, the system predicates will simply leave the term respectively the goal unchanged.

The predicate property sys_noexpand/0 allows excluding a meta-predicate from the goal or term traversal. Closures are currently not expanded. If the term or goal expansion steps into the colon notation (:)/2 or the double colon notation (::)/2 with a sufficiently instantiated first argument it will look up the meta-declarations for the qualified predicate name.

The result of the expansion can be no clause, a single clause or multiple clauses. No clause is indicated by unit/0 as a result. A single clause is simply returned by itself. Multiple clauses can be conjoined by the operator (/\)/2 and returned this way. Expansion is also performed along the existential quantifier (^)/2 second argument.

Example:
?- op(500,yfx,++).
Yes
?- [user].
rest_expansion(X++Y,sys_cond(Z,append(X,Y,Z))).
^D
?- Y = [1,2]++[3].
Y = [1,2,3]

It is also possible to define rest expansion via the predicate rest_expansion/2 and to invoke rest expansion via the predicate expand_rest/2. Rest expansion is applied to goal or term ar-guments that are not goals or terms. Rest expansion is driven by meta function declarations and can be block by the predicate property sys_nomacro.

Rest expansion might return a result of the form sys_cond(R, C) where C is the so-called side condition. In the context of rest arguments, the side conditions are merged via conjunction to give a new side condition. In the context of a goal G, the condition C is prepended as (C,G), in the context of a term T, the condition C is appended as (T:-C).

The following expansion results are recognized:

unit:
An empty clause list.
C /\ D:
A clause list of two clause lists C and D.
sys_cond(T, C):
This result during rest expansion indicates rest T and a side condition C.

The following expansion predicates are provided:

term_expansion(C, D):
This predicate can be used to define custom term expansion rules.
expand_term(C, D):
The system predicate succeeds if the expansion of the term C unifies with D.
goal_expansion(C, D):
This predicate can be used to define custom goal expansion rules.
expand_goal(C, D):
The system predicate succeeds if the expansion of the goal C unifies with D.
rest_expansion(C, D):
This predicate can be used to define custom rest expansion rules.
expand_rest(C, D):
The system predicate succeeds if the expansion of the rest C unifies with D.

The following predicate properties for clause expansion are provided:

sys_noexpand:
The property indicates that the meta-predicate should not be traversed in goal or term expansion. The property can be changed for user predicates.
sys_nomacro:
The property indicates that the meta-function should not be traversed in rest expansion. The property can be changed for user predicates.

Kommentare