[m-rev.] for review: improve checking of `any' in negated context

David Overton dmo at cs.mu.OZ.AU
Thu May 29 11:20:26 AEST 2003


On Wed, May 28, 2003 at 11:37:43PM +1000, David Overton wrote:
> On Wed, May 28, 2003 at 02:19:25PM +1000, Fergus Henderson wrote:
> > I'm still struggling to convince myself that this change is safe,
> > i.e. that it doesn't allow any cases which ought to be mode errors.
> 
> Actually, I'm not convinced now either.  I'll need to think about it a
> bit more.

The change change wasn't safe.  It allowed the test case below which
should be a mode error.  Here is the interdiff for the fix.


diff -u compiler/inst_match.m compiler/inst_match.m
--- compiler/inst_match.m	28 May 2003 03:30:46 -0000
+++ compiler/inst_match.m	29 May 2003 00:00:36 -0000
@@ -155,6 +155,13 @@
 	%	 that `any' does not match itself.  It is used to check
 	%	 whether variables get bound in negated contexts.
 
+:- pred inst_matches_binding_allow_any_any(inst, inst, type, module_info).
+:- mode inst_matches_binding_allow_any_any(in, in, in, in) is semidet.
+
+	% inst_matches_binding_allow_any_any is the same as
+	% inst_matches_binding except that it also allows `any' to
+	% match `any'.
+
 %-----------------------------------------------------------------------------%
 
 	% pred_inst_matches(PredInstA, PredInstB, ModuleInfo)
@@ -333,16 +340,26 @@
 
 :- type expansions == set(pair(inst)).
 
+	% The uniqueness_comparison type is used by the predicate
+	% compare_uniqueness to determine what order should be used for
+	% comparing two uniqueness annotations.
+
 :- type uniqueness_comparison
 	--->	match
+			% We are doing a "matches" comparison, e.g. at a
+			% predicate call or the end of a procedure body.
 	;	instantiated.
+			% We are comparing two insts for how "instantiated" they
+			% are.  The uniqueness order here should be the reverse
+			% of the order used for matching.
 
 :- type inst_match_info
 	--->	inst_match_info(
 			module_info	:: module_info,
 			expansions	:: expansions,
 			maybe_sub	:: maybe(inst_var_sub),
-			uniqueness_comparison	:: uniqueness_comparison
+			uniqueness_comparison	:: uniqueness_comparison,
+			any_matches_any	:: bool
 		).
 
 :- func sub(inst_match_info) = inst_var_sub is semidet.
@@ -357,8 +374,8 @@
 
 :- func init_inst_match_info(module_info) = inst_match_info.
 
-init_inst_match_info(ModuleInfo) = inst_match_info(ModuleInfo, Exp, no, match)
-		:-
+init_inst_match_info(ModuleInfo) =
+		inst_match_info(ModuleInfo, Exp, no, match, yes) :-
 	set__init(Exp).
 
 :- pred inst_matches_initial_2(inst, inst, maybe(type), 
@@ -416,7 +433,7 @@
 	% occur in `Expansions'.
 
 inst_matches_initial_4(any(UniqA), any(UniqB), _, I, I) :-
-	I ^ uniqueness_comparison = match,
+	I ^ any_matches_any = yes,
 	compare_uniqueness(I ^ uniqueness_comparison, UniqA, UniqB).
 inst_matches_initial_4(any(_), free, _, I, I).
 inst_matches_initial_4(free, any(_), _, I, I).
@@ -1016,11 +1033,17 @@
 	).
 
 inst_is_at_least_as_instantiated(InstA, InstB, Type, ModuleInfo) :-
-	Info = init_inst_match_info(ModuleInfo) ^ 
-			uniqueness_comparison := instantiated,
+	Info = (init_inst_match_info(ModuleInfo)
+			^ uniqueness_comparison := instantiated)
+			^ any_matches_any := no,
 	inst_matches_initial_2(InstA, InstB, yes(Type), Info, _).
 
 inst_matches_binding(InstA, InstB, Type, ModuleInfo) :-
+	Info0 = init_inst_match_info(ModuleInfo)
+		^ any_matches_any := no,
+	inst_matches_binding_2(InstA, InstB, yes(Type), Info0, _).
+
+inst_matches_binding_allow_any_any(InstA, InstB, Type, ModuleInfo) :-
 	Info0 = init_inst_match_info(ModuleInfo),
 	inst_matches_binding_2(InstA, InstB, yes(Type), Info0, _).
 
@@ -1046,8 +1069,11 @@
 		inst_match_info).
 :- mode inst_matches_binding_3(in, in, in, in, out) is semidet.
 
-% Note that `any' is *not* considered to match `any'.
+% Note that `any' is *not* considered to match `any' unless 
+% Info ^ any_matches_any = yes.
 inst_matches_binding_3(free, free, _, I, I).
+inst_matches_binding_3(any(_), any(_), _, I, I) :-
+	I ^ any_matches_any = yes.
 inst_matches_binding_3(bound(_UniqA, ListA), bound(_UniqB, ListB), MaybeType,
 		Info0, Info) :-
 	bound_inst_list_matches_binding(ListA, ListB, MaybeType, Info0, Info).
diff -u compiler/modes.m compiler/modes.m
--- compiler/modes.m	28 May 2003 03:30:46 -0000
+++ compiler/modes.m	29 May 2003 00:00:36 -0000
@@ -2043,7 +2043,9 @@
 				% with a free variable.
 				MaybeUInst = yes(UInst),
 				inst_is_at_least_as_instantiated(Inst, UInst,
-					Type, ModuleInfo)
+					Type, ModuleInfo),
+				inst_matches_binding_allow_any_any(Inst,
+					Inst0, Type, ModuleInfo)
 			)
 		->
 			set__singleton_set(WaitingVars, Var0),
only in patch2:
unchanged:
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tests/invalid/bind_in_negated.m	29 May 2003 00:00:37 -0000
@@ -0,0 +1,20 @@
+:- module bind_in_negated.
+:- interface.
+
+:- type foo ---> f(int, int).
+
+:- pred p(foo, foo, foo).
+:- mode p(bound(f(free, ground)) >> ground,
+	  bound(f(ground, free)) >> ground,
+	  out) is det.
+
+:- implementation.
+
+p(A, B, C) :-
+	( A = B ->
+		C = A
+	;
+		C = f(1, 1),
+		A = f(1, _),
+		B = f(_, 1)
+	).
only in patch2:
unchanged:
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tests/invalid/bind_in_negated.err_exp	29 May 2003 00:00:37 -0000
@@ -0,0 +1,6 @@
+bind_in_negated.m:014: In clause for `p((bound(f(free, ground)) -> ground), (bound(f(ground, free)) -> ground), out)':
+bind_in_negated.m:014:   scope error: attempt to bind a non-local variable
+bind_in_negated.m:014:   inside the condition of an if-then-else.
+bind_in_negated.m:014:   Variable `A' has instantiatedness `bound(bind_in_negated.f(free, ground))',
+bind_in_negated.m:014:   expected instantiatedness was `bound(bind_in_negated.f(ground, ground))'.
+For more information, try recompiling with `-E'.
only in patch2:
unchanged:
--- tests/invalid/Mmakefile	19 May 2003 14:24:35 -0000	1.136
+++ tests/invalid/Mmakefile	29 May 2003 00:00:37 -0000
@@ -33,6 +33,7 @@
 	any_mode \
 	assert_in_interface \
 	bigtest \
+	bind_in_negated \
 	bind_var_errors \
 	builtin_int \
 	builtin_proc \

-- 
David Overton                  Uni of Melbourne     +61 3 8344 1354
dmo at cs.mu.oz.au                Monash Uni (Clayton) +61 3 9905 5779
http://www.cs.mu.oz.au/~dmo    Mobile Phone         +61 4 0337 4393
--------------------------------------------------------------------------
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