normalize_body2(assign_single_id(LHS,EXPR),I,Par,Pre,Body,Info) :- normalizing_mode(asm),
LHS = b(function(FunID,Arg),_,_), % f(Arg) := EXPR
get_texpr_id(FunID,FID), get_texpr_type(FunID,FunType),
print(update_fun(FID,FunType,Arg)),nl,
!,
fresh_update_bool_id(FID,IDB),
IDBT = b(identifier(IDB),boolean,[]), % boolean variable : TRUE if update performed
Par = [IDBT],
generate_update_function(Arg,EXPR,FunType,IDBT,UpdateFunction),
construct_function_update3(FunID,UpdateFunction,Info, Body), % TO DO: add UpdateFunction as parameter
Info = [fun_modifies([update(FID,IDB)]),modifies([])|I],
boolean_true(BTRUE),
Pre = b(equal(IDBT, BTRUE),pred,[]).
normalize_body2(assign_single_id(LHS,EXPR),I,Par,Pre,Body,Info) :-
LHS = b(function(FunID,Arg),ET,_),
!,
% rewrite f(A) := E into f := f <+ {A|->E}
get_texpr_type(Arg,AT),
Override = b(overwrite(FunID,CSET),set(couple(AT,ET)),[]),
CSET = b(set_extension([Update]),set(couple(AT,ET)),[]),
Update = b(couple(Arg,EXPR),couple(AT,ET),[]),
normalize_body2(assign_single_id(FunID,Override),I,Par,Pre,Body,Info).
normalize_body2(assign_single_id(LHS,EXPR),I,Par,Pre,Body,Info) :- normalizing_mode(asm),
!,
%get_texpr_id(LHS,ID),
LHS = b(identifier(ID),Type,IDInfo),
prime_id(ID,IDP), update_bool_id(ID,IDB),
IDPT = b(identifier(IDP),Type,IDInfo), % new potential value for Identifier
IDBT = b(identifier(IDB),boolean,IDInfo), % boolean variable : TRUE if update performed
Par = [IDPT,IDBT],
boolean_true(BTRUE),
conjunct_predicates([b(equal(IDPT, EXPR),pred,[]),
b(equal(IDBT, BTRUE),pred,[])], Pre),
Info = [modifies([ID])|I],
bool_choice(IDPT,LHS,IDBT,RHS),
% Body = x := {TRUE|->x', FALSE |->x}(x@)
Body = b(assign_single_id(LHS,RHS),subst,I).
normalize_body2(assign_single_id(LHS,EXPR),I,Par,Pre,Body,Info) :- !,
%get_texpr_id(LHS,ID),
LHS = b(identifier(ID),Type,IDInfo),
prime_id(ID,IDP),
IDPT = b(identifier(IDP),Type,IDInfo),
Par = [IDPT],
Pre = b(equal(IDPT, EXPR),pred,[]),
Info = [modifies([ID])|I],
Body = b(assign_single_id(LHS,IDPT),subst,I).
normalize_body2(assign([LHS],[EXPR]),I,Par,Pre,Body,Info) :- !,
normalize_body2(assign_single_id(LHS,EXPR),I,Par,Pre,Body,Info).
normalize_body2(assign([LHS|ET],[EXPR|LT]),I,Par,Pre,Body,Info) :-
normalize_body2(assign_single_id(LHS,EXPR),I,Par1,Pre1,Body1,Info1),
normalize_body2(assign(ET,LT),I,Par2,Pre2,Body2,Info2),
!,
join_parameters(Par1,Par2,Par,no_errors), % to do: rename apart
conjunct_predicates([Pre1,Pre2],Pre),
get_modifies(Info1,M1),
get_modifies(Info2,M2),
union(M1,M2,M12),
% TO DO: check intersection
par_subst(Body1,Body2,Body),
get_fun_modifies(Info1,Info2,U12), % always distinct variables; nothing needs to be done
Info = [modifies(M12),fun_modifies(U12)|I].
normalize_body2(parallel([A]),_I,Par,Pre,Body,Info) :- !,
normalize_body_aux(A,Par,Pre,Body,Info).
normalize_body2(parallel([A|B]),I,Par,Pre,Body,Info) :-
normalize_body_aux(A,Par1,Pre1,Body1,Info1),
normalize_body2(parallel(B),I,Par2,Pre2,Body2,Info2),
!,
join_parameters(Par1,Par2,Par12,no_errors),
get_modifies(Info1,M1),
get_modifies(Info2,M2),
union(M1,M2,M12),
% TO DO: check intersection ?
get_fun_modifies(Info1,Info2,U12), % always distinct variables; nothing needs to be done
Info = [modifies(M12),fun_modifies(U12)|I],
intersection(M1,M2,Both),
gen_update_eq(Both,Pre1,NewPre1,Pre2,NewPre2,NewIDs,NewPreds),
append(Par12,NewIDs,Par),
conjunct_predicates([NewPre1,NewPre2|NewPreds],Pre),
par_subst(Body1,Body2,Body).
normalize_body2(if([]),I,Par,Pre,Body,Info) :-
normalize_body2(skip,I,Par,Pre,Body,Info).
normalize_body2(IF,_I,Par,Pre,Body,Info) :-
if_then_else(IF,TRUTH,Body0,_),
is_truth(TRUTH),!,
normalize_body_aux(Body0,Par,Pre,Body,Info).
normalize_body2(IF,I,Par,Pre,Body,Info) :-
if_then_else(IF,Cond,Body0,ELSE),!,
% if with else:
normalize_body_aux(Body0,Par1,Pre1,Body1,Info1),
normalize_body2(if(ELSE),I,Par2,Pre2,Body2,Info2),
join_parameters(Par1,Par2,Par,no_errors), % to do: rename apart
get_modifies(Info1,M1),
get_fun_modifies(Info1,U1),
get_modifies(Info2,M2),
get_fun_modifies(Info2,U2),
subtract(M1,M2,M1only),
maplist(construct_skip_eq,M1only,SkipM1EQList),
maplist(construct_skip_fun_eq,U1,SkipU1EQList), % U1 and U2 necessarily distinct
append(SkipM1EQList,SkipU1EQList,Skip1),
conjunct_predicates([Pre2|Skip1],NewPre2),
subtract(M2,M1,M2only),
maplist(construct_skip_eq,M2only,SkipM2EQList),
maplist(construct_skip_fun_eq,U2,SkipU2EQList), % U1 and U2 necessarily distinct
append(SkipM2EQList,SkipU2EQList,Skip2),
conjunct_predicates([Pre1|Skip2],NewPre1),
create_implication(Cond,NewPre1,IMP1),
create_negation(Cond,NCond),
create_implication(NCond,NewPre2,IMP2),
conjunct_predicates([IMP1,IMP2],Pre),
par_subst(Body1,Body2,Body),
%print(if(U1,U2,M1,M2)),nl,translate:print_subst(Body),nl,
union(M1,M2,M12),
get_fun_modifies(Info1,Info2,U12),
Info=[modifies(M12),fun_modifies(U12)|I].
normalize_body2(if(IfList),_I,_Par,_Pre,_Body,_Info) :-
print(uncovered_if(IfList)),nl,fail.
normalize_body2(let(Parameters,Defs,Body1),I,Par,Pre,Body,Info) :-
conjunct_predicates(Defs,Pre1),
normalize_body2(any(Parameters,Pre1,Body1),I,Par,Pre,Body,Info).
normalize_body2(any(Par1,Pre1,Body1),I,Par,Pre,Body,Info) :-
normalize_body_aux(Body1,Par2,Pre2,Body2,Info2),
join_parameters(Par1,Par2,Par,raise_error), % to do: rename apart
conjunct_predicates([Pre1,Pre2],Pre),
Body=Body2, append(I,Info2,Info).
normalize_body2(skip,Info,[],Truth,Body,[modifies([])|Info]) :-
Truth=b(truth,pred,[]),
Body=b(skip,subst,[]).