compile_body(X,_F,_XARGS,_DEFS,_DC,Res) :- var(X),!, Res=X.
compile_body(lambda(Args,Body),F,XARGS,DEFS,DC,Res) :- !, %nl,print(lambda1(Args,Body)),nl,
l_compile_head_para(Args,CArgs,Constraints,lambda(Args,Body),unknown_span),
(Constraints=true -> true
; add_error(compile_body,'ProB does not (yet) support complicated patterns inside lambda: ',lambda(Args,Body))),
mynumbervars(CArgs), % note: important that compilation of body does detect $VAR
% otherwise will fail to add necessary parameters
Res = lambda(CArgs,ResBody),
append(Args,XARGS,NewXARGS),
compile_body(Body,F,NewXARGS,DEFS,DC,ResBody).
compile_body(val_of(X,Span),_F,_XARGS,DEFS,_DC,Res) :- !, /* we do not need to compile X itself !? */
% haskell_csp:get_symbol_span(X,Span), % does this work for local lets ???
(is_local_let2(X,0,[],DEFS,NX,NPar,_)
-> Res = agent_call(Span,NX,NPar)
; Res=agent_call(Span,X,[])).
compile_body(agent_call(_Span,TFun,[Arg]),F,XARGS,DEFS,DC,Res) :-
cspTransparent([TFun]), !,
compile_body(Arg,F,XARGS,DEFS,DC,Res).
compile_body(agent_call_curry(X,Paras),F,XARGS,DEFS,DC,Res) :- !,
/* translate agent_call_curry into nested agent_calls : */
(Paras=[Paras1|RestParas]
-> compile_body(agent_call_curry(agent_call(no_loc_info_available,X,Paras1),RestParas),F,XARGS,DEFS,DC,Res)
; compile_body(X,F,XARGS,DEFS,DC,Res)
).
compile_body(agent_call(_Span,X,Para),F,XARGS,DEFS,DC,Res) :- atomic(X),
Term=..[X|Para], length(Para,N), length(NPara,N), Fun=..[X|NPara],
(\+ agent(Fun,_Body,_Src), is_builtin_agent(Term), \+is_local_let(Fun,DEFS,_NewFun,_FXArgs,_)),!,
compile_body(builtin_call(Term),F,XARGS,DEFS,DC,Res).
compile_body(agent_call(Span,X,Para),F,XARGS,DEFS,_DC,Res) :- atomic(X),
CX=X, %%%%compile_body(X,F,XARGS,DEFS,true,CX),
l_compile_body(Para,F,XARGS,DEFS,true,CPara),
(is_local_let2(CX,_Arity,CPara,DEFS,NX,NPara,_) -> Res = agent_call(Span,NX,NPara) ; Res=agent_call(Span,CX,CPara)).
compile_body(prefix(Span,Values,ChannelExpr,CSP,Span2),F,XARGS,DEFS,DC,Res) :- !,
compile_body(ChannelExpr,F,XARGS,DEFS,DC,NewChExpr),
l_compile_channel_value(Values,F,XARGS,DEFS,NewVals,NewXARGS,Span),
%print(comp_channel(Values,NewVals)),nl,
compile_body(CSP,F,NewXARGS,DEFS,DC,NewCSP),
ResBody = prefix(Span,NewVals,NewChExpr,NewCSP,Span2),
(NewXARGS \= XARGS %,DC = true always lift out so that states are ground and that we need no variant/instance checks !
-> /* need to lift prefix */
gensym('->',GSF), debug_println(5,generating_agent_for_prefix(F,GSF, ResBody)),
string_concatenate(F,GSF,PrefixName),
Call =.. [PrefixName|XARGS],
Res = agent_call(Span,PrefixName,XARGS),
% portray_clause( prefix_agent(Call,ResBody) ),
assert_agent(Call, ResBody,Span),
functor(Call,CF,CN), functor(CallSkel,CF,CN),
assertz( is_csp_process(CallSkel) )
; %print(not_lifting_prefix(Values,F,XARGS,DC, NewXARGS),nl,
Res = ResBody
).
compile_body(X,F,XARGS,DEFS,DC,Res) :-
replicated_or_comprehension(X,Op,Vars,OutsideOfScope,InScope,NewDC,ISCSP,Span),!,
% print(repl(X,Op,Vars)),nl,print(inscope(InScope)),nl, print(outofscope(OutsideOfScope)),nl,
(var(Vars)
-> add_error(haskell_csp_analyzer,'Replicated variables var: ',X),fail ; true),
%%print(compiling_set(OutsideOfScope,XARGS)),nl,
% This part does not need the extra variables Vars as parameters
compile_body(OutsideOfScope,F,XARGS,DEFS,DC,NewOutsideOfScope),
% print(done_outside(NewOutsideOfScope)),nl,
append(Vars,XARGS,NewXARGS), % add the variables of the comprehension as additional parameters to nested calls
%%print(compiling_csp(InScope,NewXARGS)),nl,
compile_body(InScope,F,NewXARGS,DEFS,NewDC,NewInScope),
% print(done_csp(InScope,NewInScope)),nl,
replicated_or_comprehension(ResBody,Op,Vars,NewOutsideOfScope,NewInScope,_,ISCSP,Span),
(true %DC = true always lift out so that states are ground and that we need no variant/instance checks !
-> gensym('@',GSF), debug_println(5,generating_agent_for_repOp(F,GSF, ResBody)),
string_concatenate(F,GSF,PrefixName),
Call =.. [PrefixName|XARGS],
Res = agent_call(Span,PrefixName,XARGS), % use Span ?? or no_loc_info_available
% portray_clause( replicated(Call,ResBody) ),
assert_agent(Call, ResBody, unknown_span),
functor(Call,CF,CN), functor(CallSkel,CF,CN),
(ISCSP=true -> assertz( is_csp_process(CallSkel) ) ; true)
; Res = ResBody
).
compile_body(let(LIST,Body),F,XARGS,DEFS,DC,Res) :- !, %print(let(LIST)),nl,
expand_let_definitions(LIST,ExpLIST), %print(extracting(ExpLIST)),nl,
extract_new_funs_from_lets(ExpLIST,F,XARGS,[],LetDefs),
append(LetDefs,DEFS,NDEFS),
debug_println(5,new_funs(NDEFS)),
compile_lets(ExpLIST,F,XARGS,NDEFS,DC),
debug_println(5,nested_let_compile(Body,NDEFS)),
compile_body(Body,F,XARGS,NDEFS,DC,Res). % check builtin calls in let declarations list
compile_body(builtin_call(X),F,XARGS,DEFS,DC,Res) :- !,
translate_builtin_call(X,TX),
%(translate_builtin_call(X,TX) -> true ; TX=X),
compile_body(TX,F,XARGS,DEFS,DC,Res).
compile_body([H|T],F,XARGS,DEFS,DC,Res) :- !, l_compile_body([H|T],F,XARGS,DEFS,DC,Res).
compile_body(FunName,_F,_XARGS,DEFS,_DC,Res) :- atomic(FunName),
%(FunName=getPrio -> print(compile(FunName,DEFS)),nl ; true),
is_local_let2(FunName,OriginalArity,[],DEFS,NewF,_,LLXARGS) ,!, %% append(LLXARGS,_,_XARGS) ??
%print(replacing(FunName,NewF,LLXARGS)),nl,
% We have a local function whose function name is used: replace by a lambda closure which hides
% the additional parameters required to call the lifted version NewF
length(OrigArgs,OriginalArity),
mynumbervars(OrigArgs),
(LLXARGS=[]
-> Res = NewF
; (append(OrigArgs,LLXARGS,FullArgs),
haskell_csp:get_symbol_span(FunName,Span),
Res = lambda(OrigArgs,agent_call(Span,NewF,FullArgs))
% ,print(generated(Res)),nl
)
). %% ,print(res(Res)),nl.
compile_body(NV,F,XARGS,DEFS,DC,Res) :- nonvar(NV), NV=..[FN|Args], !, /* TO DO: IMPROVE ! */
l_compile_body(Args,F,XARGS,DEFS,DC,ResArgs),
Res =.. [FN|ResArgs] %%,print(compiled(NV,Res)),nl
.
compile_body(X,_F,_X,_D,_DC,X).