generalizer.lf |
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % FILE. . . . . /home/hak/d/life/generalizer.lf % EDIT BY . . . Hassan Ait-Kaci % ON MACHINE. . Latitude407 % STARTED ON. . Fri Dec 26 10:12:08 2003 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Last modified on Tue Jan 13 13:25:18 2004 by hak@ilog.com %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % This code computes the generalizer of two psi-terms. This essentially % means that it computes the least general term of which the two given % terms are substitution instances. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % function and predicate forms of the generalizer
generalize_f(Term1, Term2) -> Term_Gen | generalize_p(Term1, Term2, Term_Gen).
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % set up the auxiliary predicate "generalize_p" which starts with the empty % substitution list "Subst_Init". "Subst_Final" is the collected set of % substitutions. this list is a set of triples [u,x1,x2] which simply means % that u is the term in the generalizer that corresponds to the generalization % of the terms x1 and x2.
generalize_p(Term1, Term2, Term_Gen) :- Subst_Init = [], gen_aux(Term1, Term2, Subst_Init, Subst_Final, Term_Gen).
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % the auxiliary function "gen_aux" % - gets the LUB of the rootsorts % - keeps track of this generalization step by updating the % substitution list. % - generalizes recursively for each of the features common to the two % terms
gen_aux(Term1, Term2, Subst_Init, Subst_Final, Term_Gen) :- Term_Gen = lub(root_sort(Term1), root_sort(Term2)), Subst_New = [[Term_Gen, Term1, Term2]|Subst_Init], Features = common_features(features(Term1), features(Term2)), add_features(Term1, Term2, Subst_New, Subst_Final, Features, Term_Gen).
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % "add_feature" iteratively builds the generalizers of the features that were % common to the two terms. so it takes a list of features, picks out the first % one and gets the attributes corresponding to that feature. if these are both % cross-references, it makes the cross-reference in the generalizer also, else % it generalizes the two attributes and adds the result as the attribute of % the feature in the generalizer. it then moves on to the rest of the list of % features, terminating when there are none left.
add_features(_, _, Subst, Subst, [], _). add_features(Term1, Term2, Subst_Init, Subst_Final, [Feature|Rest], Term_Gen) :- SubTerm1 = project(Feature, Term1), SubTerm2 = project(Feature, Term2), ( already_seen([Var, SubTerm1, SubTerm2], Subst_Init ),!, project(Feature, Term_Gen) = Var, Subst_Tmp = Subst_Init ; gen_aux(SubTerm1, SubTerm2, Subst_Init, Subst_Tmp, SubTerm_Gen), project(Feature, Term_Gen) = SubTerm_Gen ), add_features(Term1, Term2, Subst_Tmp, Subst_Final, Rest, Term_Gen).
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % "common_features" is a simple function that takes two lists of % lexicographically ordered features and returns a list of all the common % features. it is used by the predicate "add_features". % note: an assumption being made here is that the built-in "features" always % returns sorted lists. if that changes, then so will this function!!
common_features([],_) -> []. common_features(_,[]) -> []. common_features([First1|Rest1], [First2|Rest2]) -> ComF | Str1 = psi2str(First1), Str2 = psi2str(First2), ( Str1 $< Str2, ComF = common_features(Rest1, [First2|Rest2]) ; Str1 $> Str2, ComF = common_features([First1|Rest1], Rest2) ; Str1 $== Str2, ComF = [First1 | common_features(Rest1, Rest2)] ).
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % "already_seen" checks whether the generalizer of two particular terms has % already been (or is in the process of being) computed. % used by "add_features" to take care of cross-references
already_seen( [Gen, Term1, Term2], [ [Gen, T1, T2] | List ] ) :- T1 === Term1, T2 === Term2. already_seen( Triple, [ _ | List ]) :- already_seen( Triple, List).