Module friendly

Predicates are brought into intermediate form before execution. The intermediate form determines how the head of a clause is unified and how the goals of the body of a clause are invoked. The intermediate form can be listed by the directives friendly/[0,1] and instrumented/[0,1]. The intermediate form consists of instructions of the following form:

instruction        --> integer [ level ] name [ operand { "," operand } ]
level --> { " " }
operand        --> "_" integer
| term.

An operand that is an argument of the currently invoked goal is denoted by an underscore ('_') followed by an integer, indicating the argument index starting from zero (0). Other operands are simply Prolog terms from within the Prolog clause. The predicate instrumented/[0,1] will also list the debugger instrumentation of the clause:

Here is a simple example of a clause and its intermediate form:

?- friendly(hello/1).
hello(X) :-
format('Hello %s\n', [X]).
0 unify_var _0, X
1 last_goal format('Hello %s\n', [X])

?- instrumented(hello/1).
hello(X) :-
format('Hello %s\n', [X]).
0 unify_var _0, X
1 call_goal sys_at
2 call_goal sys_in
3 last_goal format('Hello %s\n', [X])
4 call_goal sys_out

Our instruction set is not derived from the WAM architecture [5] since terms are represented by a display and a skeleton. Therefore, during unification in write mode we do not need to allocate compounds or lists. Instead, the space effort is bound by the number of variable placeholders that are created.

The optimization we implemented therefore tend to reduce the number of placeholder allocations or to provide the Java virtual machine an opportunity to reuse placeholders. The optimizations are not based on n-grams [6]. Instead we analyse the clause head for extra variables and inline disjunctions in the clause body.

The following instructions are part of the intermediate form:

new_bind V1, .., Vn:
Create place holders for the variable skeletons V1, .., Vn.
dispose_bind V1, .., Vn:
If deterministic dereference the place holders for the variable skeletons V1, .., Vn.
unify_term A, T:
Unify the argument A with the skeleton T.
unify_term A, B:
Unify the argument A with the argument B.
unify_var A, V:
Unify the argument A with the variable skeleton V.
call_goal T:
Invoke the skeleton T. 
call_meta V:
Validate and invoke the variable skeleton V.
last_goal T:
Check for leapfrogging the parent frame. Invoke the clause skeleton T.
last_meta V:
Check for leapfrogging the parent frame. Validate and invoke the variable skeleton V.
try_flow:
Indicates the beginning of a block for the first branch of a disjunction.
retry_flow:
Indicates the beginning of a block for an inner branch of a disjunction.
trust_flow:
Indicates the beginning of a block for the last branch of a disjunction.
then_flow:
Indicates the beginning of the then part inside a condition block.
soft_then_flow:
Indicates the beginning of the then part inside a soft condition block.

The following intermediate form predicates are provided:

friendly:
The predicate lists the intermediate form of the clauses of the user predicates.
friendly(P):
The predicate lists the intermediate form of the clauses of the user predicate P.
instrumented:
Works like the predicate friendly/0 except that the debugger instrumented variant of the clause is shown.
instrumented(P):
Works like the predicate friendly/1 except that the debugger instrumented variant of the clause is shown.

Kommentare