[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