[m-dev.] for review: allow separate mode decls for zero arity preds

Simon Taylor stayl at cs.mu.OZ.AU
Mon Aug 30 12:21:09 AEST 1999


Estimated hours taken: 2

Allow separate mode declarations for predicates with no arguments
(previously they were considered to be duplicate mode declarations).
This avoids the need to special case such predicates when writing
out declarations for inter-module optimization. 

If there is no mode declaration and the `:- pred' declaration does
not include the determinism, a default mode `:- mode foo.' is added.

Compilation of the browser directory with --intermodule-optimization
fails with a duplicate mode error without this change.

compiler/make_hlds.m:
	Handle default modes for zero arity predicates using a similar
	method to that used for the `in, in, ..., out' modes for functions,
	except that there will still be an error message if determinism
	inference is not enabled.

compiler/clause_to_proc.m:
	Rename `add_default_modes' to `add_default_func_modes',
	to avoid confusion with `add_default_zero_arity_pred_modes' 
	in make_hlds.m.

compiler/modecheck_call.m:
compiler/post_typecheck.m:
	Remove some unnecessary calls to `add_default_mode'.
	Default modes are added in make_hlds.m.

tests/valid/Mmakefile:
tests/valid/zero_arity.m:
	Test case.

tests/invalid/Mmakefile:
	Use `--no-infer-det' when compiling missing_det_decls.m so that
	error messages for missing determinism declarations for local
	predicates are reported (one of the local predicates in that test
	case has no arguments).

tests/invalid/bigtest.err_exp:
	Remove the error message for a missing mode declaration for a zero
	arity predicate.

tests/invalid/duplicate_modes.err_exp:
	Remove a duplicate mode error for a zero arity predicate with
	a separate mode declaration.

Index: compiler/clause_to_proc.m
===================================================================
RCS file: /home/staff/zs/imp/mercury/compiler/clause_to_proc.m,v
retrieving revision 1.25
diff -u -u -r1.25 clause_to_proc.m
--- clause_to_proc.m	1999/06/30 17:12:16	1.25
+++ clause_to_proc.m	1999/08/26 05:39:32
@@ -35,14 +35,14 @@
 :- mode copy_clauses_to_proc(in, in, in, out) is det.
 
 	% Before copying the clauses to the procs, we need to add
-	% a default mode of `:- mode foo(in, in, ..., in) = out.'
+	% a default mode of `:- mode foo(in, in, ..., in) = out is det.'
 	% for functions that don't have an explicit mode declaration.
 
-:- pred maybe_add_default_modes(list(pred_id), pred_table, pred_table).
-:- mode maybe_add_default_modes(in, in, out) is det.
+:- pred maybe_add_default_func_modes(list(pred_id), pred_table, pred_table).
+:- mode maybe_add_default_func_modes(in, in, out) is det.
 
-:- pred maybe_add_default_mode(pred_info, pred_info, maybe(proc_id)).
-:- mode maybe_add_default_mode(in, out, out) is det.
+:- pred maybe_add_default_func_mode(pred_info, pred_info, maybe(proc_id)).
+:- mode maybe_add_default_func_mode(in, out, out) is det.
 
 %-----------------------------------------------------------------------------%
 
@@ -52,14 +52,14 @@
 :- import_module globals.
 :- import_module bool, int, set, map.
 
-maybe_add_default_modes([], Preds, Preds).
-maybe_add_default_modes([PredId | PredIds], Preds0, Preds) :-
+maybe_add_default_func_modes([], Preds, Preds).
+maybe_add_default_func_modes([PredId | PredIds], Preds0, Preds) :-
 	map__lookup(Preds0, PredId, PredInfo0),
-	maybe_add_default_mode(PredInfo0, PredInfo, _),
+	maybe_add_default_func_mode(PredInfo0, PredInfo, _),
 	map__det_update(Preds0, PredId, PredInfo, Preds1),
-	maybe_add_default_modes(PredIds, Preds1, Preds).
+	maybe_add_default_func_modes(PredIds, Preds1, Preds).
 
-maybe_add_default_mode(PredInfo0, PredInfo, MaybeProcId) :-
+maybe_add_default_func_mode(PredInfo0, PredInfo, MaybeProcId) :-
 	pred_info_procedures(PredInfo0, Procs0),
 	pred_info_get_is_pred_or_func(PredInfo0, PredOrFunc),
 	( 
Index: compiler/make_hlds.m
===================================================================
RCS file: /home/staff/zs/imp/mercury/compiler/make_hlds.m,v
retrieving revision 1.300
diff -u -u -r1.300 make_hlds.m
--- make_hlds.m	1999/07/14 14:56:11	1.300
+++ make_hlds.m	1999/08/26 06:34:43
@@ -511,7 +511,7 @@
 			FuncName, Arity, PredIds) }
 	->
 		{ predicate_table_get_preds(PredTable0, Preds0) },
-		{ maybe_add_default_modes(PredIds, Preds0, Preds) },
+		{ maybe_add_default_func_modes(PredIds, Preds0, Preds) },
 		{ predicate_table_set_preds(PredTable0, Preds, PredTable) },
 		{ module_info_set_predicate_table(Module0, PredTable, Module) }
 	;
@@ -527,8 +527,34 @@
 		--> [].
 add_item_decl_pass_2(mode_defn(_, _, _), _, Status, Module, Status, Module)
 		--> [].
-add_item_decl_pass_2(pred(_, _, _, _, _, _, _, _, _), _, Status, Module, Status,
-		Module) --> [].
+add_item_decl_pass_2(pred(_, _, _, PredName, TypesAndModes, MaybeDet, _, _, _),
+		_, Status, Module0, Status, Module) -->
+	%
+	% Add a mode for a predicate with no arguments
+	% for which the determinism is not declared.
+	%
+	( { TypesAndModes = [], MaybeDet = no } ->
+		{ module_info_get_predicate_table(Module0, PredTable0) },
+		(
+			{ predicate_table_search_pred_sym_arity(PredTable0,
+				PredName, 0, [PredId]) }
+		->
+			{ module_info_pred_info(Module0, PredId, PredInfo0) },
+			maybe_add_default_zero_arity_pred_mode(PredInfo0,
+				PredInfo, MaybeProcId),
+			{ MaybeProcId = yes(_) ->
+				module_info_set_pred_info(Module0, PredId,
+					PredInfo, Module)
+			;
+				Module = Module0
+			}
+		;
+			{ error("make_hlds.m: can't find pred declaration") }
+		)
+	;
+		{ Module = Module0 }
+	).
+
 add_item_decl_pass_2(pred_mode(_, _, _, _, _), _, Status, Module, Status,
 		Module) --> [].
 add_item_decl_pass_2(func_mode(_, _, _, _, _, _), _, Status, Module, Status,
@@ -1998,7 +2024,16 @@
 		Purity, ClassContext, Markers, Context, DeclStatus, NeedQual, 
 		predicate, Module1),
 	(
-		{ MaybeModes = yes(Modes) }
+		{ MaybeModes = yes(Modes) },
+
+		% For predicates with no arguments, if the determinism
+		% is not declared a mode is not added. If there is no separate
+		% mode declaration for the predicate, one will be added by
+		% add_item_list_decls_pass_2.
+		\+ {
+			Modes = [],
+			MaybeDet = no
+		}	
 	->
 		module_add_mode(Module1, InstVarSet, PredName, Modes, MaybeDet,
 			Cond, Status, Context, predicate, PredProcId, Module),
@@ -2199,6 +2234,9 @@
 
 	% Go through the list of class methods, looking for functions without
 	% mode declarations.
+	% 
+	% Default modes are not added for zero arity class method predicates
+	% because the determinism must be specified for class methods.
 :- pred add_default_class_method_func_modes(class_interface, 
 	list(maybe(pair(pred_id, proc_id))), 
 	list(maybe(pair(pred_id, proc_id))), module_info, module_info).
@@ -2228,7 +2266,8 @@
 				ModuleName, Func, FuncArity, [PredId])
 		->
 			module_info_pred_info(Module0, PredId, PredInfo0),
-			maybe_add_default_mode(PredInfo0, PredInfo, MaybeProc),
+			maybe_add_default_func_mode(PredInfo0,
+				PredInfo, MaybeProc),
 			(
 				MaybeProc = no,
 				PredProcIds1 = PredProcIds0,
@@ -2650,20 +2689,38 @@
 	{ predicate_table_get_preds(PredicateTable1, Preds0) },
 	{ map__lookup(Preds0, PredId, PredInfo0) },
 
+	module_do_add_mode(PredInfo0, Arity, Modes, MaybeDet, MContext,
+		PredInfo, ProcId),
+	{ map__det_update(Preds0, PredId, PredInfo, Preds) },
+	{ predicate_table_set_preds(PredicateTable1, Preds, PredicateTable) },
+	{ module_info_set_predicate_table(ModuleInfo0, PredicateTable,
+		ModuleInfo) },
+	{ PredProcId = PredId - ProcId }.
+
+:- pred module_do_add_mode(pred_info, arity, list(mode), maybe(determinism),
+		prog_context, pred_info, proc_id, io__state, io__state).
+:- mode module_do_add_mode(in, in, in, in, in, out, out, di, uo) is det.
+
+module_do_add_mode(PredInfo0, Arity, Modes, MaybeDet, MContext,
+		PredInfo, ProcId) -->
 		% check that the determinism was specified
 	(
 		{ MaybeDet = no }
 	->
 		{ pred_info_import_status(PredInfo0, ImportStatus) },
+		{ pred_info_get_is_pred_or_func(PredInfo0, PredOrFunc) },
+		{ pred_info_module(PredInfo0, PredModule) },
+		{ pred_info_name(PredInfo0, PredName) },
+		{ PredSymName = qualified(PredModule, PredName) },
 		( { status_is_exported(ImportStatus, yes) } ->
-			unspecified_det_for_exported(PredName, Arity,
+			unspecified_det_for_exported(PredSymName, Arity,
 				PredOrFunc, MContext)
 		;
 			globals__io_lookup_bool_option(infer_det, InferDet),
 			(
 				{ InferDet = no }
 			->
-				unspecified_det_for_local(PredName, Arity,
+				unspecified_det_for_local(PredSymName, Arity,
 					PredOrFunc, MContext)
 			;
 				[]
@@ -2676,12 +2733,7 @@
 		% add the mode declaration to the pred_info for this procedure.
 	{ ArgLives = no },
 	{ add_new_proc(PredInfo0, Arity, Modes, yes(Modes), ArgLives,
-		MaybeDet, MContext, address_is_not_taken, PredInfo, ProcId) },
-	{ map__det_update(Preds0, PredId, PredInfo, Preds) },
-	{ predicate_table_set_preds(PredicateTable1, Preds, PredicateTable) },
-	{ module_info_set_predicate_table(ModuleInfo0, PredicateTable,
-		ModuleInfo) },
-	{ PredProcId = PredId - ProcId }.
+		MaybeDet, MContext, address_is_not_taken, PredInfo, ProcId) }.
 
 	% Whenever there is a clause or mode declaration for an undeclared
 	% predicate, we add an implicit declaration
@@ -2738,6 +2790,27 @@
 	list__length(List, ModeInt),
 	proc_id_to_int(ModeId, ModeInt).
 
+:- pred maybe_add_default_zero_arity_pred_mode(pred_info, pred_info,
+		maybe(proc_id), io__state, io__state).
+:- mode maybe_add_default_zero_arity_pred_mode(in, out, out, di, uo) is det.
+
+maybe_add_default_zero_arity_pred_mode(PredInfo0, PredInfo, MaybeProcId) -->
+	(
+		{ pred_info_arity(PredInfo0, 0) },
+		{ pred_info_procedures(PredInfo0, Procs0) },
+		{ map__is_empty(Procs0) }
+	->
+		{ Modes = [] },
+		{ MaybeDet = no },
+		{ pred_info_context(PredInfo0, MContext) },
+		module_do_add_mode(PredInfo0, 0, Modes, MaybeDet, MContext,
+			PredInfo, ProcId), 
+		{ MaybeProcId = yes(ProcId) }
+	;
+		{ PredInfo = PredInfo0 },
+		{ MaybeProcId = no }
+	).
+
 %-----------------------------------------------------------------------------%
 
 :- pred module_add_pred_clause(module_info, prog_varset, sym_name,
@@ -2870,13 +2943,13 @@
 		{ ModuleInfo = ModuleInfo0 },
 		{ Info = Info0 }
 	;
-		{
-		pred_info_clauses_info(PredInfo1, Clauses0),
-		pred_info_typevarset(PredInfo1, TVarSet0),
-		maybe_add_default_mode(PredInfo1, PredInfo2, _),
-		pred_info_procedures(PredInfo2, Procs),
-		map__keys(Procs, ModeIds)
-		},
+		{ pred_info_clauses_info(PredInfo1, Clauses0) },
+		{ pred_info_typevarset(PredInfo1, TVarSet0) },
+		{ maybe_add_default_func_mode(PredInfo1, PredInfo2a, _) },
+		maybe_add_default_zero_arity_pred_mode(PredInfo2a,
+			PredInfo2, _),
+		{ pred_info_procedures(PredInfo2, Procs) },
+		{ map__keys(Procs, ModeIds) },
 		clauses_info_add_clause(Clauses0, PredId, ModeIds,
 			ClauseVarSet, TVarSet0, Args, Body, Context,
 			IsAssertion, Goal,
Index: compiler/modecheck_call.m
===================================================================
RCS file: /home/staff/zs/imp/mercury/compiler/modecheck_call.m,v
retrieving revision 1.33
diff -u -u -r1.33 modecheck_call.m
--- modecheck_call.m	1999/07/16 06:41:55	1.33
+++ modecheck_call.m	1999/08/24 02:25:10
@@ -181,8 +181,7 @@
 
 	mode_info_get_preds(ModeInfo0, Preds),
 	mode_info_get_module_info(ModeInfo0, ModuleInfo),
-	map__lookup(Preds, PredId, PredInfo0),
-	maybe_add_default_mode(PredInfo0, PredInfo, _),
+	map__lookup(Preds, PredId, PredInfo),
 	pred_info_procedures(PredInfo, Procs),
 
 	( MayChangeCalledProc = may_not_change_called_proc ->
Index: compiler/post_typecheck.m
===================================================================
RCS file: /home/staff/zs/imp/mercury/compiler/post_typecheck.m,v
retrieving revision 1.12
diff -u -u -r1.12 post_typecheck.m
--- post_typecheck.m	1999/07/29 07:51:47	1.12
+++ post_typecheck.m	1999/08/24 02:24:54
@@ -567,14 +567,12 @@
 %-----------------------------------------------------------------------------%
 
 	% 
-	% Add a default mode for functions if none was specified, and
-	% ensure that all constructors occurring in predicate mode 
+	% Ensure that all constructors occurring in predicate mode 
 	% declarations are module qualified.
 	% 
 post_typecheck__finish_pred(ModuleInfo, PredId, PredInfo0, PredInfo) -->
-	{ maybe_add_default_mode(PredInfo0, PredInfo1, _) },
 	post_typecheck__propagate_types_into_modes(ModuleInfo, PredId,
-		PredInfo1, PredInfo).
+		PredInfo0, PredInfo).
 
 	%
 	% For ill-typed preds, we just need to set the modes up correctly
Index: tests/invalid/Mmakefile
===================================================================
RCS file: /home/staff/zs/imp/tests/invalid/Mmakefile,v
retrieving revision 1.45
diff -u -u -r1.45 Mmakefile
--- Mmakefile	1999/07/14 17:03:30	1.45
+++ Mmakefile	1999/08/30 01:56:46
@@ -79,10 +80,11 @@
 
 MCFLAGS-aditi_update_errors =	--aditi
 MCFLAGS-aditi_update_mode_errors = --aditi
-MCFLAGS-multisoln_func	=	--infer-types
 MCFLAGS-any_mode	=	--infer-types
 MCFLAGS-duplicate_modes	=	--verbose-error-messages
+MCFLAGS-missing_det_decls = --no-infer-det
 MCFLAGS-missing_interface_import = --make-interface
+MCFLAGS-multisoln_func	=	--infer-types
 MCFLAGS-no_exports = 		--halt-at-warn
 MCFLAGS-sub_c = 		--verbose-error-messages
 
Index: tests/invalid/bigtest.err_exp
===================================================================
RCS file: /home/staff/zs/imp/tests/invalid/bigtest.err_exp,v
retrieving revision 1.3
diff -u -u -r1.3 bigtest.err_exp
--- bigtest.err_exp	1998/10/30 04:38:41	1.3
+++ bigtest.err_exp	1999/08/26 05:24:55
@@ -11,5 +11,4 @@
 bigtest.m:005:   without preceding `pred' declaration.
 bigtest.m:005: Inferred :- pred fact.
 bigtest.m:010: Error: no mode declaration for predicate `bigtest:p/1'.
-bigtest.m:005: Error: no mode declaration for predicate `bigtest:fact/0'.
 For more information, try recompiling with `-E'.
Index: tests/invalid/duplicate_modes.err_exp
===================================================================
RCS file: /home/staff/zs/imp/tests/invalid/duplicate_modes.err_exp,v
retrieving revision 1.3
diff -u -u -r1.3 duplicate_modes.err_exp
--- duplicate_modes.err_exp	1998/10/30 04:38:42	1.3
+++ duplicate_modes.err_exp	1999/08/26 05:26:25
@@ -4,12 +4,6 @@
 		`:- import_module' in its interface section(s).
 		This would normally be a `:- pred', `:- func', `:- type',
 		`:- inst' or `:- mode' declaration.
-duplicate_modes.m:003: In mode declarations for predicate `duplicate_modes:p/0':
-duplicate_modes.m:003:   error: duplicate mode declaration.
-duplicate_modes.m:003:   Modes `p is det'
-duplicate_modes.m:003:   and `p'
-duplicate_modes.m:003:   are indistinguishable.
-duplicate_modes.m:004:   Here is the conflicting mode declaration.
 duplicate_modes.m:008: In mode declarations for predicate `duplicate_modes:q/2':
 duplicate_modes.m:008:   error: duplicate mode declaration.
 duplicate_modes.m:008:   Modes `q(in, out) is det'
Index: tests/invalid/missing_det_decls.err_exp
===================================================================
RCS file: /home/staff/zs/imp/tests/invalid/missing_det_decls.err_exp,v
retrieving revision 1.1
diff -u -u -r1.1 missing_det_decls.err_exp
--- missing_det_decls.err_exp	1996/11/04 07:14:54	1.1
+++ missing_det_decls.err_exp	1999/08/30 02:15:03
@@ -1,7 +1,11 @@
-missing_det_decls.m:004: Error: no determinism declaration for exported
-missing_det_decls.m:004:   predicate `missing_det_decls:exp1/0'.
 missing_det_decls.m:007: Error: no determinism declaration for exported
 missing_det_decls.m:007:   predicate `missing_det_decls:exp2/1'.
+missing_det_decls.m:014: Error: no determinism declaration for local
+missing_det_decls.m:014:   predicate `missing_det_decls:loc2/1'.
+missing_det_decls.m:004: Error: no determinism declaration for exported
+missing_det_decls.m:004:   predicate `missing_det_decls:exp1/0'.
+missing_det_decls.m:011: Error: no determinism declaration for local
+missing_det_decls.m:011:   predicate `missing_det_decls:loc1/0'.
 missing_det_decls.m:004: Error: no clauses for predicate `missing_det_decls:exp1/0'
 missing_det_decls.m:006: Error: no clauses for predicate `missing_det_decls:exp2/1'
 missing_det_decls.m:011: Error: no clauses for predicate `missing_det_decls:loc1/0'
Index: tests/valid/Mmakefile
===================================================================
RCS file: /home/staff/zs/imp/tests/valid/Mmakefile,v
retrieving revision 1.40
diff -u -u -r1.40 Mmakefile
--- Mmakefile	1999/08/25 06:11:17	1.40
+++ Mmakefile	1999/08/25 06:13:36
@@ -113,7 +113,8 @@
 	uniq_mode_inf_bug.m \
 	unreachable_code.m \
 	unused_args_test2.m \
-	vn_float.m
+	vn_float.m \
+	zero_arity.m
 
 # Code generation is not yet implemented for Aditi updates,
 # so don't attempt to compile to C.
Index: tests/valid/zero_arity.m
===================================================================
RCS file: zero_arity.m
diff -N zero_arity.m
--- /dev/null	Mon Aug 30 12:05:00 1999
+++ zero_arity.m	Wed Aug 25 16:14:52 1999
@@ -0,0 +1,23 @@
+% Test separate `:- pred' and `:- mode' declarations
+% for predicates with no arguments.
+% The compiler of 25/8/1999 reported a spurious duplicate
+% mode error for this test case.
+:- module zero_arity.
+
+:- interface.
+
+:- pred use_asm_labels.
+:- mode use_asm_labels is semidet.
+
+:- implementation.
+
+:- pragma c_code(use_asm_labels, [will_not_call_mercury, thread_safe], "
+
+#ifdef USE_ASM_LABELS
+	SUCCESS_INDICATOR = TRUE;
+#else
+	SUCCESS_INDICATOR = FALSE;
+#endif
+").
+
+
--------------------------------------------------------------------------
mercury-developers mailing list
Post messages to:       mercury-developers at cs.mu.oz.au
Administrative Queries: owner-mercury-developers at cs.mu.oz.au
Subscriptions:          mercury-developers-request at cs.mu.oz.au
--------------------------------------------------------------------------



More information about the developers mailing list