diff: quantification.m bug fixes

Fergus Henderson fjh at cs.mu.oz.au
Thu Jul 3 21:46:43 AEST 1997


Fix a couple of bugs in the handling of implicit quantification
for variables in lambda goals.

compiler/quantification.m:
	(1) When implicitly-quantifying a lambda goal, the "lambda-outsidevars"
	    should be set to the empty set, so that variables occurring
	    only inside disjoint lambda goals are locally quantified
	    inside those lambda goals. 
	(2) When quantifying conjunctions and if-then-elses, use both
	    the lambda outsidevars and the ordinary outsidevars when
	    computing the non-locals, rather than just using the
	    ordinary outsidevars.

tests/valid/lambda_quant.m:
	Add another test case for bug (1).
	There was already a tests in this module that was supposed to
	test this sort of stuff, but that test case happened to work,
	because the effects of bugs (1) and (2) cancelled out. :-(

tests/valid/Mmake:
tests/valid/lambda_quant_bug.m:
	Add a regression test for bug (2).

Index: quantification.m
===================================================================
RCS file: /home/staff/zs/imp/mercury/compiler/quantification.m,v
retrieving revision 1.49
diff -u -r1.49 quantification.m
--- quantification.m	1997/06/29 23:11:24	1.49
+++ quantification.m	1997/07/03 07:50:16
@@ -94,10 +94,11 @@
 	% `QuantVars' are the variables not in `OutsideVars' 
 	% that have been explicitly existentially quantified over a scope
 	% which includes the current goal in a positive (non-negated) context.
-	% `OutsideLambdaVars' are the variables
-	% that have occurred free in a lambda
-	% expression outside this goal, not counting occurrences in
-	% parallel goals.
+	% `OutsideLambdaVars' are the variables that have occurred free in
+	% a lambda expression outside this goal, not counting occurrences in
+	% parallel goals (and if this goal is itself inside a lambda
+	% expression, not counting occurrences outside that lambda
+	% expression).
 	%
 	% For example, for
 	%
@@ -283,7 +284,9 @@
 	quantification__get_nonlocals(NonLocalsElse),
 	{ set__union(NonLocalsCond, NonLocalsThen, NonLocalsIfThen) },
 	{ set__union(NonLocalsIfThen, NonLocalsElse, NonLocalsIfThenElse) },
-	{ set__intersect(NonLocalsIfThenElse, OutsideVars, NonLocals) },
+	{ set__intersect(NonLocalsIfThenElse, OutsideVars, NonLocalsO) },
+	{ set__intersect(NonLocalsIfThenElse, LambdaOutsideVars, NonLocalsL) },
+	{ set__union(NonLocalsO, NonLocalsL, NonLocals) },
 	quantification__set_nonlocals(NonLocals).
 
 implicitly_quantify_goal_2(call(A, B, HeadVars, D, E, F), _,
@@ -367,18 +370,26 @@
 		% and initialize the new quantified vars set to be empty.
 	quantification__get_quant_vars(QuantVars0),
 	{ set__union(OutsideVars0, QuantVars0, OutsideVars1) },
+	{ set__init(QuantVars) },
+	quantification__set_quant_vars(QuantVars),
 		% Add the lambda vars as outside vars, since they are
 		% outside of the lambda goal
 	{ set__insert_list(OutsideVars1, LambdaVars, OutsideVars) },
-	{ set__init(QuantVars) },
 	quantification__set_outside(OutsideVars),
-	quantification__set_quant_vars(QuantVars),
+		% Set the LambdaOutsideVars set to empty, because
+		% variables that occur outside this lambda expression
+		% only in other lambda expressions should not be
+		% considered non-local.
+	quantification__get_lambda_outside(LambdaOutsideVars0),
+	{ set__init(LambdaOutsideVars) },
+	quantification__set_lambda_outside(LambdaOutsideVars),
 	implicitly_quantify_goal(Goal1, Goal),
 	quantification__get_nonlocals(NonLocals0),
 		% lambda-quantified variables are local
 	{ set__delete_list(NonLocals0, LambdaVars, NonLocals) },
 	quantification__set_quant_vars(QuantVars0),
 	quantification__set_outside(OutsideVars0),
+	quantification__set_lambda_outside(LambdaOutsideVars0),
 	quantification__set_nonlocals(NonLocals).
 
 :- pred implicitly_quantify_conj(list(hlds_goal), list(hlds_goal), 
@@ -417,7 +428,9 @@
 				Goals),
 	quantification__get_nonlocals(NonLocalVars2),
 	{ set__union(NonLocalVars1, NonLocalVars2, NonLocalVarsConj) },
-	{ set__intersect(NonLocalVarsConj, OutsideVars, NonLocalVars) },
+	{ set__intersect(NonLocalVarsConj, OutsideVars, NonLocalVarsO) },
+	{ set__intersect(NonLocalVarsConj, LambdaOutsideVars, NonLocalVarsL) },
+	{ set__union(NonLocalVarsO, NonLocalVarsL, NonLocalVars) },
 	quantification__set_outside(OutsideVars),
 	quantification__set_nonlocals(NonLocalVars).
 
Index: Mmake
===================================================================
RCS file: /home/staff/zs/imp/tests/valid/Mmake,v
retrieving revision 1.43
diff -u -r1.43 Mmake
--- Mmake	1997/06/29 23:23:30	1.43
+++ Mmake	1997/07/03 08:10:55
@@ -37,6 +37,7 @@
 	lambda_inference.m\
 	lambda_instmap_bug.m \
 	lambda_quant.m \
+	lambda_quant_bug.m \
 	lambda_struct_bug.m \
 	lambda_switch.m \
 	lambda_type.m \
Index: lambda_quant.m
===================================================================
RCS file: /home/staff/zs/imp/tests/valid/lambda_quant.m,v
retrieving revision 1.1
diff -u -r1.1 lambda_quant.m
--- lambda_quant.m	1996/11/02 20:15:07	1.1
+++ lambda_quant.m	1997/07/03 08:01:23
@@ -3,12 +3,12 @@
 
 :- module lambda_quant.
 :- interface.
-:- import_module list, int.
 
 :- pred test(pred).
 :- mode test(out((pred) is semidet)) is nondet.
 
 :- implementation.
+:- import_module list, int.
 
 :- pred t is semidet.
 t.
@@ -21,5 +21,9 @@
 test(G) :-
 	G1 = ((pred) is semidet :- X = 0, X \= 1),
 	G2 = ((pred) is det :- X = [], X \= [_|_]),
+	G = ((pred) is semidet :- G1, G2).
+test(G) :-
+	G1 = ((pred) is semidet :- Y = 0),
+	G2 = ((pred) is det :- Y = []),
 	G = ((pred) is semidet :- G1, G2).
 

-- 
Fergus Henderson <fjh at cs.mu.oz.au>   |  "I have always known that the pursuit
WWW: <http://www.cs.mu.oz.au/~fjh>   |  of excellence is a lethal habit"
PGP: finger fjh at 128.250.37.3         |     -- the last words of T. S. Garp.



More information about the developers mailing list