[m-rev.] diff: avoid spurious infinite recursion warning
Fergus Henderson
fjh at cs.mu.OZ.AU
Mon Oct 13 12:29:32 AEST 2003
Estimated hours taken: 1
Branches: main
compiler/simplify.m:
Avoid issuing warnings about infinite recursion in the case
when the recursive call involves input arguments whose inst
is `any', since such warnings may be spurious.
tests/valid/Mmakefile:
tests/valid/Mercury.options:
tests/valid/solv.m:
Regression test.
Workspace: /home/ceres/fjh/mercury
Index: compiler/simplify.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/simplify.m,v
retrieving revision 1.119
diff -u -d -r1.119 simplify.m
--- compiler/simplify.m 29 May 2003 18:17:15 -0000 1.119
+++ compiler/simplify.m 13 Oct 2003 02:20:56 -0000
@@ -1282,6 +1282,29 @@
simplify__input_args_are_equiv(Args, HeadVars, ArgModes,
CommonInfo1, ModuleInfo1),
+ %
+ % Don't warn if the input arguments' modes initial insts
+ % contain `any' insts, since the arguments might have become
+ % more constrained before the recursive call, in which case
+ % the recursion might eventually terminate.
+ %
+ % XXX The following check will only warn if the inputs are
+ % all fully ground; i.e. we won't warn in the case of
+ % partially instantiated insts such as list_skel(free).
+ % Still, it is better to miss warnings in that rare and
+ % unsupported case rather than to issue spurious warnings
+ % in cases involving `any' insts. We should only warn about
+ % definite nontermination here, not possible nontermination;
+ % warnings about possible nontermination should only be given
+ % if the termination analysis pass is enabled.
+ %
+ all [ArgMode] (
+ (list__member(ArgMode, ArgModes),
+ mode_is_input(ModuleInfo1, ArgMode))
+ =>
+ mode_is_fully_input(ModuleInfo1, ArgMode)
+ ),
+
%
% Don't count procs using minimal evaluation as they
% should always terminate if they have a finite number
Index: tests/valid/Mercury.options
===================================================================
RCS file: /home/mercury1/repository/tests/valid/Mercury.options,v
retrieving revision 1.9
diff -u -d -r1.9 Mercury.options
--- tests/valid/Mercury.options 26 Jul 2003 07:19:08 -0000 1.9
+++ tests/valid/Mercury.options 13 Oct 2003 02:23:49 -0000
@@ -84,6 +84,7 @@
MCFLAGS-simplify_bug = -O-1
MCFLAGS-simplify_bug2 = -O3
MCFLAGS-spurious_purity_warning = --halt-at-warn
+MCFLAGS-solv = --halt-at-warn
MCFLAGS-tuple_eqv = --smart-recompilation
MCFLAGS-two_way_unif = -O-1
MCFLAGS-type_inf_ambig_test = --infer-all
Index: tests/valid/Mmakefile
===================================================================
RCS file: /home/mercury1/repository/tests/valid/Mmakefile,v
retrieving revision 1.130
diff -u -d -r1.130 Mmakefile
--- tests/valid/Mmakefile 25 Jul 2003 02:27:37 -0000 1.130
+++ tests/valid/Mmakefile 13 Oct 2003 02:22:58 -0000
@@ -164,6 +164,7 @@
simplify_bug \
simplify_bug2 \
soln_context \
+ solv \
some_switch \
spurious_purity_warning \
stack_alloc \
Index: tests/valid/solv.m
===================================================================
RCS file: tests/valid/solv.m
diff -N tests/valid/solv.m
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ tests/valid/solv.m 13 Oct 2003 02:28:39 -0000
@@ -0,0 +1,118 @@
+%-----------------------------------------------------------------------------%
+
+% This test case is a regression test to check that we don't
+% issue a spurious warning about infinite recursion in recursive
+% procedures such as label/1 whose inputs initial inst contains `any'.
+
+%-----------------------------------------------------------------------------%
+
+% This module is an example of how to write a finite domain solver.
+
+:- module solv.
+:- interface.
+:- import_module io, list, int.
+
+% :- type fd_var. % For Mercury versions < rotd-25-07-03
+:- solver type fd_var. % For Mercury versions > rotd-25-07-03
+
+ % initialize an unconstrained fd_var
+:- pred init_any(fd_var).
+:- mode init_any(free >> any) is det.
+
+ % unify an fd_var with an int
+:- pred fd_var == int.
+:- mode in == out is det.
+:- mode (any >> ground) == in is semidet.
+
+ % constrain an fd_var to be greater than the specified int
+:- pred fd_var > int.
+:- mode in(any) > in is semidet.
+
+ % constrain an fd_var to be less than the specified int
+:- pred fd_var < int.
+:- mode in(any) < in is semidet.
+
+ % Given a list of constrained fd_vars, nondeterminstically
+ % find bindings for the variables that meet those constraints.
+ % The output list here will be the same as the input list,
+ % but with ground values for all the variables.
+:- pred labeling(list(fd_var), list(fd_var)).
+:- mode labeling(in(list_skel(any)), out) is nondet.
+
+ % Given a list of constrained fd_vars,
+ % print out all possible bindings for the variables
+ % that meet those constraints. The order in which
+ % the solutions will be printed is unspecified.
+:- pred print_labeling(list(fd_var), io__state, io__state).
+:- mode print_labeling(in(list_skel(any)), di, uo) is cc_multi.
+
+%-----------------------------------------------------------------------------%
+
+:- implementation.
+:- import_module std_util.
+
+:- solver type fd_var
+ ---> fd_var(c_pointer).
+
+print_labeling(Vars) -->
+ unsorted_aggregate(labeling(Vars), print_solution).
+
+:- pred print_solution(list(fd_var), io__state, io__state).
+:- mode print_solution(in, di, uo) is det.
+
+print_solution(Vars) -->
+ io__print("Here's a solution: "),
+ io__write_list(Vars, ", ", print_var),
+ io__nl.
+
+:- pred print_var(fd_var, io__state, io__state).
+:- mode print_var(in, di, uo) is det.
+print_var(Var) -->
+ { Var == Val }, % convert ground fd_var to int
+ io__write_int(Val).
+
+labeling([], []).
+labeling([V | Vs0], [V | Vs]) :-
+ label(V),
+ labeling(Vs0, Vs).
+
+:- pred label(fd_var).
+:- mode label(any >> ground) is nondet.
+:- pragma promise_pure(label/1).
+
+label(V) :-
+ impure solver_min_domain(V, Min),
+ impure solver_max_domain(V, Max),
+ (if Min = Max then
+ promise_ground(V)
+ else
+ ( V == Min
+ ; V > Min,
+ label(V)
+ )
+ ).
+
+:- pred promise_ground(fd_var).
+:- mode promise_ground(any >> ground) is det.
+
+:- pragma foreign_proc("C", promise_ground(X :: any >> ground),
+ [promise_pure, will_not_call_mercury, thread_safe],
+ "/* assert(X->min == X->max); */").
+
+:- impure pred solver_min_domain(fd_var, int).
+:- mode solver_min_domain(in(any), out) is det.
+
+:- impure pred solver_max_domain(fd_var, int).
+:- mode solver_max_domain(in(any), out) is det.
+
+%-----------------------------------------------------------------------------%
+
+% Implementing the following is left as an exercise for the reader...
+:- external(init_any/1).
+:- external(solver_min_domain/2).
+:- external(solver_max_domain/2).
+:- external((==)/2).
+:- external((>)/2).
+:- external((<)/2).
+
+%-----------------------------------------------------------------------------%
--
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