[m-rev.] Re: for review: default modes for higher-order func insts
David Overton
dmo at cs.mu.OZ.AU
Wed Oct 10 16:53:05 AEST 2001
On Wed, Oct 10, 2001 at 03:19:46PM +1000, Fergus Henderson wrote:
> On 10-Oct-2001, David Overton <dmo at cs.mu.OZ.AU> wrote:
> > +:- pred inst_contains_nonstandard_func_mode(inst, module_info).
> > +:- mode inst_contains_nonstandard_func_mode(in, in) is semidet.
>
> I don't understand that part of the relative diff;
> why was that predicate added?
> I don't see any calls to it in the relative diff.
>
Sorry, it seems I missed out a few files. This predicate is used in
by normalise_inst in compiler/mode_utils.m. The complete relative diff
is below.
diff -u compiler/inst_match.m compiler/inst_match.m
--- compiler/inst_match.m
+++ compiler/inst_match.m
@@ -145,12 +145,18 @@
% succeed if the inst is fully ground (i.e. contains only
% `ground', `bound', and `not_reached' insts, with no `free'
% or `any' insts).
+ % This predicate succeeds for non-standard function insts so some care
+ % needs to be taken since these insts may not be replaced by a less
+ % precise inst that uses the higher-order mode information.
:- pred inst_is_ground(module_info, inst).
:- mode inst_is_ground(in, in) is semidet.
% succeed if the inst is not partly free (i.e. contains only
% `any', `ground', `bound', and `not_reached' insts, with no
% `free' insts).
+ % This predicate succeeds for non-standard function insts so some care
+ % needs to be taken since these insts may not be replaced by a less
+ % precise inst that uses the higher-order mode information.
:- pred inst_is_ground_or_any(module_info, inst).
:- mode inst_is_ground_or_any(in, in) is semidet.
diff -u compiler/inst_util.m compiler/inst_util.m
--- compiler/inst_util.m
+++ compiler/inst_util.m
@@ -99,24 +99,33 @@
%-----------------------------------------------------------------------------%
- % Succeed iff the first argument is a function pred_inst_info
- % with non-standard mode.
+:- pred inst_contains_nonstandard_func_mode(inst, module_info).
+:- mode inst_contains_nonstandard_func_mode(in, in) is semidet.
+
+ % inst_contains_nonstandard_func_mode(Inst, ModuleInfo) succeeds iff the
+ % inst contains a higher-order function inst that does not match the
+ % standard function mode `(in, ..., in) = out is det'.
+ % E.g. this predicate fails for "func(in) = uo" because that matches the
+ % standard func mode "func(in) = out", even though it isn't the same as
+ % the standard func mode.
:- pred pred_inst_info_is_nonstandard_func_mode(pred_inst_info, module_info).
:- mode pred_inst_info_is_nonstandard_func_mode(in, in) is semidet.
- % Succeed iff the first argument is a function ground_inst_info
- % with non-standard mode.
+ % Succeed iff the first argument is a function pred_inst_info
+ % whose mode does not match the standard func mode.
:- pred ground_inst_info_is_nonstandard_func_mode(ground_inst_info,
module_info).
:- mode ground_inst_info_is_nonstandard_func_mode(in, in) is semidet.
-
- % Return the standard mode for a function of the given arity.
+ % Succeed iff the first argument is a function ground_inst_info
+ % whose mode does not match the standard func mode.
:- func pred_inst_info_standard_func_mode(arity) = pred_inst_info.
+ % Return the standard mode for a function of the given arity.
+
%-----------------------------------------------------------------------------%
:- implementation.
@@ -1633,11 +1642,37 @@
%-----------------------------------------------------------------------------%
%-----------------------------------------------------------------------------%
+inst_contains_nonstandard_func_mode(Inst, ModuleInfo) :-
+ set__init(Expansions0),
+ inst_contains_nonstandard_func_mode_2(Inst, ModuleInfo, Expansions0).
+
+:- pred inst_contains_nonstandard_func_mode_2(inst, module_info, set(inst)).
+:- mode inst_contains_nonstandard_func_mode_2(in, in, in) is semidet.
+
+inst_contains_nonstandard_func_mode_2(ground(_, GroundInstInfo), ModuleInfo,
+ _Expansions) :-
+ ground_inst_info_is_nonstandard_func_mode(GroundInstInfo, ModuleInfo).
+inst_contains_nonstandard_func_mode_2(bound(_, BoundInsts), ModuleInfo,
+ Expansions) :-
+ list__member(functor(_, Insts), BoundInsts),
+ list__member(Inst, Insts),
+ inst_contains_nonstandard_func_mode_2(Inst, ModuleInfo, Expansions).
+inst_contains_nonstandard_func_mode_2(inst_var(_), _, _) :-
+ error("internal error: uninstantiated inst parameter").
+inst_contains_nonstandard_func_mode_2(Inst, ModuleInfo, Expansions0) :-
+ Inst = defined_inst(InstName),
+ \+ set__member(Inst, Expansions0),
+ set__insert(Expansions0, Inst, Expansions1),
+ inst_lookup(ModuleInfo, InstName, Inst2),
+ inst_contains_nonstandard_func_mode_2(Inst2, ModuleInfo, Expansions1).
+
+%-----------------------------------------------------------------------------%
+
pred_inst_info_is_nonstandard_func_mode(PredInstInfo, ModuleInfo) :-
PredInstInfo = pred_inst_info(function, ArgModes, _),
Arity = list__length(ArgModes),
- \+ pred_inst_matches(pred_inst_info_standard_func_mode(Arity),
- PredInstInfo, ModuleInfo).
+ \+ pred_inst_matches(PredInstInfo,
+ pred_inst_info_standard_func_mode(Arity), ModuleInfo).
ground_inst_info_is_nonstandard_func_mode(GroundInstInfo, ModuleInfo) :-
GroundInstInfo = higher_order(PredInstInfo),
diff -u tests/hard_coded/ho_func_default_inst.exp tests/hard_coded/ho_func_default_inst.exp
--- tests/hard_coded/ho_func_default_inst.exp
+++ tests/hard_coded/ho_func_default_inst.exp
@@ -1,2 +1,2 @@
-hello
-world
+1
+2
diff -u tests/hard_coded/ho_func_default_inst.m tests/hard_coded/ho_func_default_inst.m
--- tests/hard_coded/ho_func_default_inst.m
+++ tests/hard_coded/ho_func_default_inst.m
@@ -17,27 +17,44 @@
{ Map = map },
{ F1 = Map ^ det_elem(1) },
{ F2 = Map ^ det_elem(2) },
- io__write_string(F1(1)),
+ io__write_int(F1(1)),
io__nl,
write_func(F2).
-:- type t == (func(int) = string).
+:- type t == (func(int) = int).
+
+:- inst one == bound(1).
:- func map = map(int, t).
-map = (map__init ^ elem(1) := hello) ^ elem(2) := world.
+map = (((map__init
+ ^ elem(1) := foo1)
+ ^ elem(2) := foo2)
+ ^ elem(3) := foo3)
+ ^ elem(4) := foo4.
:- pred write_func(t, io, io) is det.
:- mode write_func(func(in) = out is det, di, uo) is det.
write_func(F) -->
- io__write_string(F(1)),
+ io__write_int(F(1)),
io__nl.
-:- func hello(int) = string.
+:- func foo1(int) = int.
-hello(_) = "hello".
+foo1(_) = 1.
-:- func world(int) = string.
+:- func foo2(int) = int.
+:- mode foo2(in) = uo is det.
+
+foo2(_) = 2.
+
+:- func foo3(int) = int.
+:- mode foo3(in) = out(one) is det.
+
+foo3(_) = 1.
+
+:- func foo4(int) = int.
+:- mode foo4(in(one)) = out is det.
-world(_) = "world".
+foo4(1) = 4.
diff -u tests/invalid/Mmakefile tests/invalid/Mmakefile
--- tests/invalid/Mmakefile
+++ tests/invalid/Mmakefile
@@ -47,6 +47,7 @@
func_errors.m \
funcs_as_preds.m \
ho_default_func_1.m \
+ ho_default_func_3.m \
ho_type_mode_bug.m \
ho_unique_error.m \
impure_method_impl.m \
only in patch2:
--- tests/invalid/ho_default_func_3.m 1 Jan 1970 00:00:00 -0000
+++ tests/invalid/ho_default_func_3.m 9 Oct 2001 06:18:13 -0000
@@ -0,0 +1,34 @@
+% Compiling this module should generate an error message since
+% it tries to cast a non-standard func inst to ground.
+
+:- module ho_default_func_3.
+
+:- interface.
+:- import_module io.
+
+:- pred main(io__state, io__state).
+:- mode main(di, uo) is det.
+
+:- implementation.
+
+:- import_module int, std_util.
+
+main -->
+ { baz(foo, F) },
+ io__write_int(F(42)), nl.
+
+:- func foo(int) = int.
+foo(X) = X + 1.
+
+:- func bar(int) = int.
+:- mode bar(di) = uo is det.
+bar(X) = X.
+
+:- pred baz(T::in, T::out) is det.
+baz(X, Y) :-
+ ( univ_to_type(univ(bar), Y0) ->
+ Y = Y0
+ ;
+ Y = X
+ ).
+
only in patch2:
--- tests/invalid/ho_default_func_3.err_exp 1 Jan 1970 00:00:00 -0000
+++ tests/invalid/ho_default_func_3.err_exp 9 Oct 2001 06:19:43 -0000
@@ -0,0 +1,6 @@
+ho_default_func_3.m:029: In clause for `baz(in, out)':
+ho_default_func_3.m:029: in call to function `std_util:univ/1':
+ho_default_func_3.m:029: mode error: arguments `TypeInfo_13, V_7, V_6'
+ho_default_func_3.m:029: have insts `unique(private_builtin:type_info(unique(<type_ctor_info for :func/0>), unique(2), unique(<type_ctor_info for :int/0>), unique(<type_ctor_info for :int/0>))), /* unique */(func((unique -> clobbered)) = (free -> unique) is det), free',
+ho_default_func_3.m:029: which does not match any of the modes for function `std_util:univ/1'.
+For more information, try recompiling with `-E'.
only in patch2:
--- compiler/mode_util.m 13 Sep 2001 23:18:12 -0000 1.137
+++ compiler/mode_util.m 9 Oct 2001 02:33:58 -0000
@@ -1793,7 +1793,8 @@
% don't infer unique modes for introduced type_infos
% arguments, because that leads to an increase
% in the number of inferred modes without any benefit
- \+ is_introduced_type_info_type(Type)
+ \+ is_introduced_type_info_type(Type),
+ \+ inst_contains_nonstandard_func_mode(Inst, ModuleInfo)
->
NormalisedInst = ground(unique, none)
;
@@ -1802,12 +1803,14 @@
% don't infer unique modes for introduced type_infos
% arguments, because that leads to an increase
% in the number of inferred modes without any benefit
- \+ is_introduced_type_info_type(Type)
+ \+ is_introduced_type_info_type(Type),
+ \+ inst_contains_nonstandard_func_mode(Inst, ModuleInfo)
->
NormalisedInst = ground(mostly_unique, none)
;
inst_is_ground(ModuleInfo, Inst),
- \+ inst_is_clobbered(ModuleInfo, Inst)
+ \+ inst_is_clobbered(ModuleInfo, Inst),
+ \+ inst_contains_nonstandard_func_mode(Inst, ModuleInfo)
->
NormalisedInst = ground(shared, none)
;
--
David Overton Department of Computer Science & Software Engineering
PhD Student The University of Melbourne, Victoria 3010, Australia
+61 3 8344 9159 http://www.cs.mu.oz.au/~dmo
--------------------------------------------------------------------------
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