home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 10 Tools
/
10-Tools.zip
/
lifeos2.zip
/
LIFE-1.02
/
TESTS
/
LF
/
COPY1.LF
< prev
next >
Wrap
Text File
|
1996-06-04
|
4KB
|
102 lines
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% As a (useful) programming exercise, it is interesting to write in LIFE a
% function that takes an arbitrary psi-term and returns a distinct clone
% copy of it. The only real complication comes from the necessity to
% respect faithfully all coreferences, including cycles. The point, of
% course, is to do it as `cleanly' as possible; i.e., without `assert' nor
% `retract' and neither in-place assignment.
% This solution -- one of many, I am sure -- is purely functional.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% The main function is called `copy'. It uses an auxiliary function
% `memo_copy' that does the actual copying with the necessary book
% keeping to enforce coreferences. It takes a pair of psi-term and a
% list of pairs of psi-terms (a table of correspondence between nodes
% that have been already copied and their actual copies), and returns a
% similar object. So, copy just projects out the correspondence table
% and keeps the first component of the pair (the fully copied x).
copy(X) -> memo_copy(X,[]).1.
% Another way of extracting a component of a structure is by unification
% using the `where' function trick [defined as where -> @.] and define
% `copy' as follows:
% copy(X) -> C:where((C , _):memo_copy(X,[])).
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% The function `memo_copy' takes a psi-term and a table of the copies that
% have already been made and returns a pair of the copy and updated table.
memo_copy(X,Table:list) ->
cond( deja_vu(X,Table) & bool(Copy)
, (Copy , Table)
, (Copy&root_sort(X)&bodify_list(B) , New_Table)
& where((B , New_Table)
& copy_body(listify_body(X),[(X , Copy)|Table]))
).
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% The function `deja_vu' checks whether its first argument has already being
% recorded as the left component of a pair in its second argument (a table in
% the form of a list of pairs). It returns `false' if it is nout found, and
% otherwise returns `true' augmented with feature 1 set to its corresponding
% copy.
deja_vu(@,[]) -> false.
deja_vu(X,[(Y , V)|T]) -> cond( X===Y
, true(V)
, deja_vu(X,T)
).
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% The function `copy_body' takes a list of pairs of the form
% (attribute,psi-term) and a table and returns a pair made up
% of a similar list and a new table.
copy_body([],Table:list) -> ([] , Table).
copy_body([(A , X)|T],Table:list) -> ([(A , CX)|CT] , New_Table)
& where( (CX , NT) & memo_copy(X,Table)
, (CT , New_Table) & copy_body(T,NT)
).
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% The function `bodify_list' rebuilds a psi-term body from a list of pairs of
% the form (attr,subterm).
bodify_list([]) -> @.
bodify_list([(A , X)|T]) -> Y : bodify_list(T)
| X = Y.A.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% The function `listify_body' does the opposite -- i.e., it returns the body
% of a psi-term in the form of a list of pairs (attr,subterm).
listify_body(X) -> map(feature_value(2=>X),features(X)).
feature_value(A,X) -> (A , X.A).
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%% STRUCTURELLE EQUALITY
str_eq0(X,Y)-> cond( copy(X)=copy(Y),
true,
false
).
str_eq1(X,Y) -> A=(copy(X) & copy(Y)).
str_eq2(X,Y) -> copy(X) & copy(Y).
where -> @.