128 4 Logic Programming Languages
by means of the run-time function trail(). The calls to the function trail() store
variables in a dedicated data structure, the trail (Fig. 4.25). The trail is an extra stack
0
T
TP
Fig. 4.25. The WIM data structure trail
T where heap addresses of reference objects are recorded that have received a new
binding. One immediate optimization is to store an address a only if its reference
objects
(R, b) contain bindings to too-young heap objects, that is where a < b.For
maintaining the trail, we introduce a further register, the Trail Pointer TP. The trail
pointer always points to the topmost used trail location.
Additionally, we require a new register BP,theBacktrack Pointer. It points to
the current backtrack point, that is, to the last stack frame that contains a further
alternative still left unexplored (Fig. 4.26).
0
S
F
S
B
Fig. 4.26. The register BP of the WIM
Within each stack frame, we have so far saved the previous PC value, that is,
the positive continuation address, as well as the previous FP value. This is the link
to the stack frame of the caller, that is, the dynamic predecessor (Fig. 4.27). In the
stackframeofabacktrack point, we additionally requirethecode address for the next
alternative, that is, the negative continuation address, as well as the previous value
of BP. These two required organizational cells have the relative addresses
−5 and
−4. At a backtrack point, we additionally save the previous values of the registers
TP and HP. The corresponding organizational cells receive the relative addresses
−3 and −2.
A call to the run-time function void backtrack
() returns to the current back-
track point and continues with the negative continuation address found there (Fig.
4.28). Before the next alternative can be tried, the variable bindings that have been
established since the selection of the last alternative must first be undone. This is