159
% We want it in order from the initial change, to the leaf change.
dest_path(X, Y) :-
destinations(X, Z),
reverse(Z, Y).
% we can then calculate the addresses in the common lower bound of both
changes.
% We calculate the greatest common change in both histories, and then
return the
% result of tracing each address to that particular change on it's
destination
% chain.
% These must exist, and must have different indices.
dest_llb(address([I1 | T1], Index1), address([I2 | T2], Index2), X1,
X2) :-
dest_path(I1, P1),
dest_path(I2, P2),
last_common(P1, P2, R),
dest_trace(address([I1 | T1], Index1), R, X1),
dest_trace(address([I2 | T2], Index2), R, X2).
% This function traces an address up to a particular change in the
destination
% chain, returning it's final position within that change.
dest_trace(address([I|T], Index), I, address([I|T], Index)) :- !.
dest_trace(address([I|T], _), I2, X) :-
dest(I, D),
dest_trace(D, I2, X).
% Find the last common element in a pair of lists with a common prefix.
last_common([A], [A|T], A).
last_common([A|T], [A], A).
last_common([R, B1 | T1], [R, B2 |T2], R) :-
B1 \= B2, !.
last_common([A | T1], [A | T2], R) :-
last_common(T1, T2, R).
% well_defined_for checks that a set of changes is error free. It
checks that all
% pairs of addresses are totally ordered, and that the minimal element
is NIL. This
% doesn't guarantee that some other set of changes is _not_ well-
defined, but it
% We want it in order from the initial change, to the leaf change.
dest_path(X, Y) :-
destinations(X, Z),
reverse(Z, Y).
% we can then calculate the addresses in the common lower bound of both
changes.
% We calculate the greatest common change in both histories, and then
return the
% result of tracing each address to that particular change on it's
destination
% chain.
% These must exist, and must have different indices.
dest_llb(address([I1 | T1], Index1), address([I2 | T2], Index2), X1,
X2) :-
dest_path(I1, P1),
dest_path(I2, P2),
last_common(P1, P2, R),
dest_trace(address([I1 | T1], Index1), R, X1),
dest_trace(address([I2 | T2], Index2), R, X2).
% This function traces an address up to a particular change in the
destination
% chain, returning it's final position within that change.
dest_trace(address([I|T], Index), I, address([I|T], Index)) :- !.
dest_trace(address([I|T], _), I2, X) :-
dest(I, D),
dest_trace(D, I2, X).
% Find the last common element in a pair of lists with a common prefix.
last_common([A], [A|T], A).
last_common([A|T], [A], A).
last_common([R, B1 | T1], [R, B2 |T2], R) :-
B1 \= B2, !.
last_common([A | T1], [A | T2], R) :-
last_common(T1, T2, R).
% well_defined_for checks that a set of changes is error free. It
checks that all
% pairs of addresses are totally ordered, and that the minimal element
is NIL. This
% doesn't guarantee that some other set of changes is _not_ well-
defined, but it