[m-rev.] for review: fix state var bug

Fergus Henderson fjh at cs.mu.OZ.AU
Thu Nov 6 20:58:11 AEDT 2003


For review by Ralph.

Estimated hours taken: 4
Branches: main

compiler/make_hlds.m:
	Fix a bug where the state variable transformation was not
	correctly handling the case where the condition of an if-then-else
	referred to a state variable, but the "then" part didn't.

	(Also, fix some incorrect comments for get_rev_conj and get_rev_disj,
	and rearrange some misleading whitespace in the comments for the
	svar_info type.)

tests/valid/Mmakefile:
tests/valid/state_var_bug.m:
	Add a regression test.

----------

The crucial part of this diff is the following lines,
which fix a bug in `add_then_arm_specific_unifiers':

-		new_dot_state_var(StateVar, Dot, VarSet0, VarSet1,
-			SInfoT0, SInfoT1),
+		new_colon_state_var(StateVar, Dot, !VarSet, !SInfoT),
+		prepare_for_next_conjunct(set__make_singleton_set(StateVar),
+			!VarSet, !SInfoT)

If I understand the code correctly, this fixes two problems:
	- since we are appending a new unification, i.e. a new atomic goal,
	  we need to call prepare_for_next_conjunct after we're done.
	- we should be calling new_colon_state_var to get the new version
	  of the state variable, not new_dot_state_var.  I guess previously
	  we were doing it that odd way since the right way didn't work
	  because of the missing call to prepare_for_next_conjunct.

Workspace: /home/jupiter/fjh/ws-jupiter/mercury
Index: compiler/make_hlds.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/make_hlds.m,v
retrieving revision 1.450
diff -u -d -r1.450 make_hlds.m
--- compiler/make_hlds.m	5 Nov 2003 03:17:39 -0000	1.450
+++ compiler/make_hlds.m	6 Nov 2003 09:35:30 -0000
@@ -8191,9 +8191,9 @@
 
 %-----------------------------------------------------------------------------%
 
-% get_rev_conj(Goal, Conj0, Subst, Conj) :
+% get_rev_conj(Goal, Subst, RevConj0, RevConj) :
 % 	Goal is a tree of conjuncts.  Flatten it into a list (applying Subst),
-%	append Conj0, and return the result in reverse order in Conj.
+%	reverse it, append RevConj0, and return the result in RevConj.
 
 :- pred get_rev_conj(goal::in, prog_substitution::in, list(hlds_goal)::in,
 	list(hlds_goal)::out, prog_varset::in, prog_varset::out,
@@ -8213,9 +8213,9 @@
 		RevConj = list__reverse(ConjList) ++ RevConj0
 	).
 
-% get_rev_par_conj(Goal, ParConj0, Subst, ParConj) :
+% get_rev_par_conj(Goal, Subst, RevParConj0, RevParConj) :
 % 	Goal is a tree of conjuncts.  Flatten it into a list (applying Subst),
-%	append ParConj0, and return the result in reverse order in ParConj.
+%	reverse it, append RevParConj0, and return the result in RevParConj.
 
 :- pred get_rev_par_conj(goal::in, prog_substitution::in, list(hlds_goal)::in,
 	list(hlds_goal)::out, prog_varset::in, prog_varset::out,
@@ -9016,20 +9016,20 @@
 :- type svar_info
 	--->	svar_info(
 			ctxt		::	svar_ctxt,
+
 			num		::	int,
-				%
 				% This is used to number state variables and
 				% is incremented for each source-level
 				% conjunct.
+
 			external_dot	::	svar_map,
-				%
 				% The "read only" state variables in
 				% scope (e.g. external state variables
 				% visible from within a lambda body or
 				% condition of an if-then-else expression.)
+
 			dot		::	svar_map,
 			colon		::	svar_map
-				%
 				% The "read/write" state variables in scope.
 		).
 
@@ -9430,24 +9430,22 @@
 		Thens, Thens, VarSet, VarSet).
 
 add_then_arm_specific_unifiers(Context, [StateVar | StateVars],
-		SInfo0, SInfoC, SInfoT0, SInfoT,
-		Thens0, Thens, VarSet0, VarSet) :-
-	( if /* the condition refers to !:X, but the then-goal doesn't */
+		SInfo0, SInfoC, !SInfoT, !Thens, !VarSet) :-
+	( if % the condition refers to !:X, but the then-goal doesn't
 	     SInfoC  ^ dot ^ elem(StateVar) \= SInfo0 ^ dot ^ elem(StateVar),
-	     SInfoT0 ^ dot ^ elem(StateVar)  = SInfoC ^ dot ^ elem(StateVar)
+	     !.SInfoT ^ dot ^ elem(StateVar)  = SInfoC ^ dot ^ elem(StateVar)
 	  then
-	  	Dot0    = SInfoT0 ^ dot ^ det_elem(StateVar),
-		new_dot_state_var(StateVar, Dot, VarSet0, VarSet1,
-			SInfoT0, SInfoT1),
-		Thens1  = [svar_unification(Context, Dot, Dot0) | Thens0]
+	  	% add a new unifier !:X = !.X
+	  	Dot0    = !.SInfoT ^ dot ^ det_elem(StateVar),
+		new_colon_state_var(StateVar, Dot, !VarSet, !SInfoT),
+		!:Thens = [svar_unification(Context, Dot, Dot0) | !.Thens],
+		prepare_for_next_conjunct(set__make_singleton_set(StateVar),
+			!VarSet, !SInfoT)
 	  else
-	  	SInfoT1 = SInfoT0,
-		Thens1  = Thens0,
-		VarSet1 = VarSet0
+	  	true
 	),
 	add_then_arm_specific_unifiers(Context, StateVars,
-		SInfo0, SInfoC, SInfoT1, SInfoT,
-		Thens1, Thens, VarSet1, VarSet).
+		SInfo0, SInfoC, !SInfoT, !Thens, !VarSet).
 
 %------------------------------------------------------------------------------%
 
Index: tests/valid/Mmakefile
===================================================================
RCS file: /home/mercury1/repository/tests/valid/Mmakefile,v
retrieving revision 1.134
diff -u -d -r1.134 Mmakefile
--- tests/valid/Mmakefile	27 Oct 2003 05:59:48 -0000	1.134
+++ tests/valid/Mmakefile	6 Nov 2003 09:43:54 -0000
@@ -168,6 +168,7 @@
 	spurious_purity_warning \
 	stack_alloc \
 	static \
+	state_var_bug \
 	subtype_switch \
 	switch_detection_bug \
 	switch_detection_bug2 \
Index: tests/valid/state_var_bug.m
===================================================================
RCS file: tests/valid/state_var_bug.m
diff -N tests/valid/state_var_bug.m
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tests/valid/state_var_bug.m	6 Nov 2003 09:41:07 -0000
@@ -0,0 +1,23 @@
+% This is a regression test for a bug with the state variable transformation.
+% It was not correctly handling the case where the condition of an if-then-else
+% referred to a state variable, but the "then" part didn't.
+% This lead to a determinism error in the following code.
+
+:- module state_var_bug.
+:- interface.
+
+:- pred foo(int::in, int::out) is det.
+
+:- implementation.
+
+foo(!X) :-
+	( copy(!X) ->
+		true
+	;
+		true
+	),
+	(
+		fail
+	;
+		copy(!X)
+	).

-- 
Fergus Henderson <fjh at cs.mu.oz.au>  |  "I have always known that the pursuit
The University of Melbourne         |  of excellence is a lethal habit"
WWW: <http://www.cs.mu.oz.au/~fjh>  |     -- the last words of T. S. Garp.
--------------------------------------------------------------------------
mercury-reviews mailing list
post:  mercury-reviews at cs.mu.oz.au
administrative address: owner-mercury-reviews at cs.mu.oz.au
unsubscribe: Address: mercury-reviews-request at cs.mu.oz.au Message: unsubscribe
subscribe:   Address: mercury-reviews-request at cs.mu.oz.au Message: subscribe
--------------------------------------------------------------------------



More information about the reviews mailing list