[m-dev.] for review: handle if_then_else and disj for acc introduction
Peter Ross
petdr at cs.mu.OZ.AU
Mon Jun 28 12:25:11 AEST 1999
Hi,
Simon could you please review this.
===================================================================
Estimated hours taken: 10
compiler/accumulator.m:
Add the ability to add accumulators to if/then/else and disjunctions.
Index: compiler/accumulator.m
===================================================================
RCS file: /home/staff/zs/imp/mercury/compiler/accumulator.m,v
retrieving revision 1.1
diff -u -b -r1.1 accumulator.m
--- accumulator.m 1999/06/15 07:09:50 1.1
+++ accumulator.m 1999/06/28 02:16:57
@@ -108,6 +108,8 @@
:- type rec_goal
---> recursive(
+ a_goals, % Goals inside the condition of an
+ % if/then/else
a_goals, % Decompose, Process
a_goal, % Recursive call
a_goals % Compose calls
@@ -311,12 +313,14 @@
->
(
accumulator__split_recursive_case(PredId, ProcId,
+ InitialInstMap, [],
InitialInstMap, ModuleInfo, FullyStrict,
GoalAList, Rec0),
% Make sure that the base case doesn't
% contain a recursive call.
\+ accumulator__split_recursive_case(PredId, ProcId,
+ InitialInstMap, [],
InitialInstMap, ModuleInfo, FullyStrict,
GoalBList, _)
->
@@ -325,12 +329,14 @@
Rec = Rec0
;
accumulator__split_recursive_case(PredId, ProcId,
+ InitialInstMap, [],
InitialInstMap, ModuleInfo, FullyStrict,
GoalBList, Rec0),
% Make sure that the base case doesn't
% contain a recursive call.
\+ accumulator__split_recursive_case(PredId, ProcId,
+ InitialInstMap, [],
InitialInstMap, ModuleInfo, FullyStrict,
GoalAList, _)
->
@@ -341,7 +347,96 @@
fail
)
;
+ Goal = disj(Goals, _SM) - _GoalInfo,
+ Goals = [GoalA, GoalB],
+ goal_to_conj_list(GoalA, GoalAList),
+ goal_to_conj_list(GoalB, GoalBList)
+ ->
+ (
+ accumulator__split_recursive_case(PredId, ProcId,
+ InitialInstMap, [],
+ InitialInstMap, ModuleInfo, FullyStrict,
+ GoalAList, Rec0),
+
+ % Make sure that the base case doesn't
+ % contain a recursive call.
+ \+ accumulator__split_recursive_case(PredId, ProcId,
+ InitialInstMap, [],
+ InitialInstMap, ModuleInfo, FullyStrict,
+ GoalBList, _)
+ ->
+ Type = disj_rec_base,
+ Base = base(GoalBList),
+ Rec = Rec0
+ ;
+ accumulator__split_recursive_case(PredId, ProcId,
+ InitialInstMap, [],
+ InitialInstMap, ModuleInfo, FullyStrict,
+ GoalBList, Rec0),
+
+ % Make sure that the base case doesn't
+ % contain a recursive call.
+ \+ accumulator__split_recursive_case(PredId, ProcId,
+ InitialInstMap, [],
+ InitialInstMap, ModuleInfo, FullyStrict,
+ GoalAList, _)
+ ->
+ Type = disj_base_rec,
+ Base = base(GoalAList),
+ Rec = Rec0
+ ;
+ fail
+ )
+ ;
+ Goal = if_then_else(_Vars, If, Then, Else, _SM) - _GoalInfo,
+
+ If = _ - IfGoalInfo,
+ goal_info_get_instmap_delta(IfGoalInfo, IMDelta),
+ instmap__apply_instmap_delta(InitialInstMap, IMDelta,
+ BeforeThenInstMap),
+
+ goal_to_conj_list(If, IfList),
+ goal_to_conj_list(Then, ThenList),
+ goal_to_conj_list(Else, ElseList)
+ ->
+ (
+ accumulator__split_recursive_case(PredId, ProcId,
+ InitialInstMap, IfList,
+ BeforeThenInstMap, ModuleInfo,
+ FullyStrict, ThenList, Rec0),
+
+ % Make sure that the base case doesn't
+ % contain a recursive call.
+ \+ accumulator__split_recursive_case(PredId, ProcId,
+ InitialInstMap, [],
+ InitialInstMap, ModuleInfo, FullyStrict,
+ ElseList, _)
+ ->
+ Type = ite_rec_base,
+ Base = base(ElseList),
+ Rec = Rec0
+ ;
+ accumulator__split_recursive_case(PredId, ProcId,
+ InitialInstMap, [],
+ InitialInstMap, ModuleInfo, FullyStrict,
+ ElseList, Rec0),
+
+ % Make sure that the base case doesn't
+ % contain a recursive call.
+ \+ accumulator__split_recursive_case(PredId, ProcId,
+ InitialInstMap, [],
+ InitialInstMap, ModuleInfo, FullyStrict,
+ ThenList, _)
+ ->
+ Type = ite_base_rec,
+ Base = base(ThenList),
+ Rec = Rec0
+ ;
fail
+ )
+
+ ;
+ fail
).
%-----------------------------------------------------------------------------%
@@ -385,7 +480,7 @@
:- pred accumulator__acc_proc_info(rec_goal::in, instmap::in, proc_info::in,
subst::out, list(type)::out, proc_info::out) is det.
-accumulator__acc_proc_info(recursive(DP, _R, C), InstMap0,
+accumulator__acc_proc_info(recursive(PreDP, DP, _R, C), InstMap0,
ProcInfo, HstoAs_Subst, NewTypes, NewProcInfo) :-
% ProcInfo Stuff that must change.
@@ -401,7 +496,7 @@
proc_info_typeclass_info_varmap(ProcInfo, TCVarsMap),
proc_info_is_address_taken(ProcInfo, IsAddressTaken),
- accumulator__extra_vars_for_recursive_call(DP, C, Vars),
+ accumulator__extra_vars_for_recursive_call(PreDP, DP, C, Vars),
DP = goal(DPGoals, _DPInstMap),
goal_list_instmap_delta(DPGoals, InstMapDelta),
@@ -508,7 +603,7 @@
proc_id::in, sym_name::in,
hlds_goal::out, hlds_goal::out) is semidet.
-accumulator__transform(switch_rec_base, base(BaseGoalList), recursive(DP, R, C),
+accumulator__transform(TopLevel, base(BaseGoalList), recursive(PreDP, DP, R, C),
Goal, DoLCO, FullyStrict, ModuleInfo, HeadVars, HstoAs_Subst,
NewPredId, NewProcId, NewPredName, OrigGoal, NewGoal) :-
@@ -516,7 +611,7 @@
accumulator__orig_base_case(BaseGoalList, OrigBaseGoal),
- accumulator__extra_vars_for_recursive_call(DP, C, Vars),
+ accumulator__extra_vars_for_recursive_call(PreDP, DP, C, Vars),
accumulator__orig_recursive_case(DP, R, HeadVars, NewPredId, NewProcId,
NewPredName, Vars, Y0stoYs_Subst, OrigRecGoal),
@@ -527,19 +622,97 @@
Vars, HeadVars,
Y0stoYs_Subst, HstoAs_Subst, NewRecGoal),
+ accumulator__top_level(TopLevel, Goal, OrigBaseGoal, OrigRecGoal,
+ NewBaseGoal, NewRecGoal, OrigGoal, NewGoal).
+
+
+:- pred accumulator__top_level(top_level::in, hlds_goal::in,
+ hlds_goal::in, hlds_goal::in, hlds_goal::in,
+ hlds_goal::in, hlds_goal::out, hlds_goal::out) is det.
+
+accumulator__top_level(switch_base_rec, Goal, OrigBaseGoal, OrigRecGoal,
+ NewBaseGoal, NewRecGoal, OrigGoal, NewGoal) :-
(
Goal = switch(Var, CanFail, Cases0, StoreMap) - GoalInfo,
Cases0 = [case(IdA, _), case(IdB, _)]
->
+ OrigCases = [case(IdA, OrigBaseGoal), case(IdB, OrigRecGoal)],
+ OrigGoal = switch(Var, CanFail, OrigCases, StoreMap) - GoalInfo,
+
+ NewCases = [case(IdA, NewBaseGoal), case(IdB, NewRecGoal)],
+ NewGoal = switch(Var, CanFail, NewCases, StoreMap) - GoalInfo
+ ;
+ error("accumulator__top_level: not the correct top level")
+ ).
+accumulator__top_level(switch_rec_base, Goal, OrigBaseGoal, OrigRecGoal,
+ NewBaseGoal, NewRecGoal, OrigGoal, NewGoal) :-
+ (
+ Goal = switch(Var, CanFail, Cases0, StoreMap) - GoalInfo,
+ Cases0 = [case(IdA, _), case(IdB, _)]
+ ->
OrigCases = [case(IdA, OrigRecGoal), case(IdB, OrigBaseGoal)],
OrigGoal = switch(Var, CanFail, OrigCases, StoreMap) - GoalInfo,
NewCases = [case(IdA, NewRecGoal), case(IdB, NewBaseGoal)],
NewGoal = switch(Var, CanFail, NewCases, StoreMap) - GoalInfo
;
- fail
+ error("accumulator__top_level: not the correct top level")
).
+accumulator__top_level(disj_base_rec, Goal, OrigBaseGoal,
+ OrigRecGoal, NewBaseGoal, NewRecGoal, OrigGoal, NewGoal) :-
+ (
+ Goal = disj(Goals, StoreMap) - GoalInfo,
+ Goals = [_, _]
+ ->
+ OrigGoals = [OrigBaseGoal, OrigRecGoal],
+ OrigGoal = disj(OrigGoals, StoreMap) - GoalInfo,
+ NewGoals = [NewBaseGoal, NewRecGoal],
+ NewGoal = disj(NewGoals, StoreMap) - GoalInfo
+ ;
+ error("accumulator__top_level: not the correct top level")
+ ).
+accumulator__top_level(disj_rec_base, Goal, OrigBaseGoal,
+ OrigRecGoal, NewBaseGoal, NewRecGoal, OrigGoal, NewGoal) :-
+ (
+ Goal = disj(Goals, StoreMap) - GoalInfo,
+ Goals = [_, _]
+ ->
+ OrigGoals = [OrigRecGoal, OrigBaseGoal],
+ OrigGoal = disj(OrigGoals, StoreMap) - GoalInfo,
+
+ NewGoals = [NewRecGoal, NewBaseGoal],
+ NewGoal = disj(NewGoals, StoreMap) - GoalInfo
+ ;
+ error("accumulator__top_level: not the correct top level")
+ ).
+accumulator__top_level(ite_base_rec, Goal, OrigBaseGoal,
+ OrigRecGoal, NewBaseGoal, NewRecGoal, OrigGoal, NewGoal) :-
+ (
+ Goal = if_then_else(Vars, If, _, _, StoreMap) - GoalInfo
+ ->
+ OrigGoal = if_then_else(Vars, If,
+ OrigBaseGoal, OrigRecGoal, StoreMap) - GoalInfo,
+
+ NewGoal = if_then_else(Vars, If,
+ NewBaseGoal, NewRecGoal, StoreMap) - GoalInfo
+ ;
+ error("accumulator__top_level: not the correct top level")
+ ).
+accumulator__top_level(ite_rec_base, Goal, OrigBaseGoal,
+ OrigRecGoal, NewBaseGoal, NewRecGoal, OrigGoal, NewGoal) :-
+ (
+ Goal = if_then_else(Vars, If, _, _, StoreMap) - GoalInfo
+ ->
+ OrigGoal = if_then_else(Vars, If,
+ OrigRecGoal, OrigBaseGoal, StoreMap) - GoalInfo,
+
+ NewGoal = if_then_else(Vars, If,
+ NewRecGoal, NewBaseGoal, StoreMap) - GoalInfo
+ ;
+ error("accumulator__top_level: not the correct top level")
+ ).
+
%-----------------------------------------------------------------------------%
%-----------------------------------------------------------------------------%
@@ -572,10 +745,12 @@
% structure, R.
%
:- pred accumulator__split_recursive_case(pred_id::in, proc_id::in,
+ instmap::in, hlds_goals::in,
instmap::in, module_info::in, bool::in,
hlds_goals::in, rec_goal::out) is semidet.
accumulator__split_recursive_case(PredId, ProcId,
+ PreInstMap, PreGoals,
InitialInstMap, ModuleInfo, FullyStrict, Goals, RecGoal) :-
solutions(accumulator__split_goals(Goals, PredId, ProcId), Solns),
Solns = [recursive(DP0, R, C0)],
@@ -594,11 +769,12 @@
calculate_instmap(DP, InitialInstMap, InstMapBeforeR),
calculate_instmap([R], InstMapBeforeR, InstMapBeforeC),
+ Pre = goal(PreGoals, PreInstMap),
DecomposeProcess = goal(DP, InitialInstMap),
Recursive = goal(R, InstMapBeforeR),
Compose = goal(C, InstMapBeforeC),
- RecGoal = recursive(DecomposeProcess, Recursive, Compose).
+ RecGoal = recursive(Pre, DecomposeProcess, Recursive, Compose).
:- pred accumulator__split_goals(hlds_goals::in, pred_id::in, proc_id::in,
split_result::out) is nondet.
@@ -728,15 +904,21 @@
% value will need to be passed via the introduced recursive
% call. This predicate identifies these variables, Hs.
%
-:- pred accumulator__extra_vars_for_recursive_call(a_goals::in,
+:- pred accumulator__extra_vars_for_recursive_call(a_goals::in, a_goals::in,
a_goals::in, prog_vars::out) is det.
accumulator__extra_vars_for_recursive_call(
+ goal(PreDecomposeProcess, _InstMapBeforePreDecomposeProcess),
goal(DecomposeProcess, _InstMapBeforeDecomposeProcess),
goal(Compose, _InstMapBeforeCompose), Vars) :-
+
+ goal_list_nonlocals(PreDecomposeProcess, PreDPNonLocalsSet),
goal_list_nonlocals(DecomposeProcess, DPNonLocalsSet),
+ set__union(PreDPNonLocalsSet, DPNonLocalsSet, NonLocals),
+
goal_list_nonlocals(Compose, CNonLocalsSet),
- set__intersect(DPNonLocalsSet, CNonLocalsSet, VarsSet),
+
+ set__intersect(NonLocals, CNonLocalsSet, VarsSet),
set__to_sorted_list(VarsSet, Vars).
%-----------------------------------------------------------------------------%
@@ -864,7 +1046,11 @@
accumulator__new_base_case(Base, C, Y0stoYs_Subst, HstoAs_Subst, Goal) :-
C = goal(Compose, _InstMapBeforeCompose),
- reverse_subst(Y0stoYs_Subst, YstoY0s_Subst),
+
+ reverse_subst(Y0stoYs_Subst, YstoY0s_Subst0),
+
+ goal_list_nonlocals(Compose, NonLocals),
+ map__select(YstoY0s_Subst0, NonLocals, YstoY0s_Subst),
goal_util__rename_vars_in_goals(Base, no, YstoY0s_Subst, NewBase),
goal_util__rename_vars_in_goals(Compose, no, HstoAs_Subst, NewCompose),
@@ -1512,8 +1698,8 @@
use user-defined equality (set__equals), not structural equality
for S.
- p(A, S0, SA), p(B, SA, S) <=>
- p(B, S0, SB), p(A, SB, S)
+ some [SA] (p(A, S0, SA), p(B, SA, S)) <=>
+ some [SB] (p(B, S0, SB), p(A, SB, S))
My previous attempt at this transformation handled this case
and I thought the current one did as well. I was wrong. I need
----
+----------------------------------------------------------------------+
| Peter Ross M Sci/Eng Melbourne Uni |
| petdr at cs.mu.oz.au WWW: www.cs.mu.oz.au/~petdr/ ph: +61 3 9344 9158 |
+----------------------------------------------------------------------+
--------------------------------------------------------------------------
mercury-developers mailing list
Post messages to: mercury-developers at cs.mu.oz.au
Administrative Queries: owner-mercury-developers at cs.mu.oz.au
Subscriptions: mercury-developers-request at cs.mu.oz.au
--------------------------------------------------------------------------
More information about the developers
mailing list