find_common_subexpressions2(TExpr,InStores,SkipSimple,OuterFunctor,NTExpr,OutStores,Stripped,UsedIds,UsedCSEIds) :-
% decompose the typed expression into its components (Subs), look up the newly introduced
% identifiers (NewIds) and create a new typed expression (NTExpr) with the modified components
% (NSubs) and the new Info field (Info)
fc_parts(TExpr,Expr,Type,Subs,NewQuantifiedIds,InvalidatedIds,NSubs,OldInfos,NewInfos,NTExpr),
% introduce a map from expression to reference that is only visible to this node
% and it subnodes if new identifiers (NewIds) are introduced
% OutStores1 and OutStores contain a pattern such that if OutStores1 is set,
% OutStores is exactly like OutStores1 but without visibility of the newly introduced
% identifiers.
append(InvalidatedIds,NewQuantifiedIds,NewIds),
create_substore(NewIds,ID,InStores,SubStores),
% apply subexpression detection on the subexpressions
functor(Expr,OuterExprFunctor,_), % memorise functor for sub-expressions (allows deciding if sharing makes sense)
find_common_subexpressions_l(Subs,SubStores,SkipSimple,OuterExprFunctor,1,
NSubs,SubStores1,StrippedSubs,UsedSubIds,SubUsedCSEIds),
% create a stripped (i.e. no info field, no types) version of the syntax node for look ups
(Type==subst -> Stripped=not_relevant % substitions are never shared (and everything containing a subst is a subst itself)
; create_stripped(Expr,StrippedSubs,Stripped)),
LookupKey = cse_lookup_key(Stripped,Type), % we also store the type along with the stripped AST (avoid sharing, e.g., two prj1/2 functions with different types, see test 255 !)
% merge the used ids of the subnodes with the used ids in this node,
% subtract newly introduced quantified identifiers because they are not visible from outside
update_used_ids(Expr,NewQuantifiedIds,UsedSubIds,UsedIds),
% if a substore was introduced due to newly introduced identifiers, remove it
%%(OuterExprFunctor=while -> portray_stores(SubStores1) ; true),
remove_last_substore(NewIds,SubStores1,Stores1,References),
% try to find the expression in the stores
(do_not_share_this(SkipSimple,Stripped,UsedIds,OuterFunctor,Type,OldInfos) ->
OutStores = Stores1,
add_cse_used_ids_info(SubUsedCSEIds,OldInfos,NewInfos),
UsedCSEIds = SubUsedCSEIds,
store_expression(LookupKey,UsedIds,Stores1,_,_,ID) /* just ground ID; used for Sub expressions */
%, print(not_sharing(ID))
; lookup_cse(Type,LookupKey,UsedIds,Stores1,OutStores,SharingInfo,Negated,ID) ->
/* it is shared */
% print(looked_up(ID,Negated,used(UsedIds,sub(UsedSubIds)),Stores1)),nl,
(Negated=negated_cse
-> NewInfos=[Negated,SharingInfo|OldInfos1]
; NewInfos=[SharingInfo|OldInfos1]),
add_cse_used_ids_info(SubUsedCSEIds,OldInfos,OldInfos1),
ord_union([ID],SubUsedCSEIds,UsedCSEIds),
set_references(References,SharingInfo)
% In this case we do not need to look for sharing in the sub-expressions !!
%,check_sharing_info(lookup,SharingInfo)
;
% if not found, store the expression: it will be shared if we use it again later
store_expression(LookupKey,UsedIds,Stores1,OutStores,SharingInfo,ID),
ord_union([ID],SubUsedCSEIds,UsedCSEIds),
% print(new_id(ID,UsedIds,SubUsedCSEIds,OutStores)),nl,
% TO DO: what if later we find out that it is shared after all -> we should remove sub-expression counts
add_cse_used_ids_info(SubUsedCSEIds,OldInfos,OldInfos1),
NewInfos=[SharingInfo|OldInfos1],
set_references(References,SharingInfo)
%,check_sharing_info(new,SharingInfo)
). % print(done_find(NTExpr,OutStores,UsedIds,UsedCSEIds)),nl.