[m-rev.] for review: fix mode-specific clauses bug
Simon Taylor
stayl at cs.mu.OZ.AU
Fri Aug 17 16:27:42 AEST 2001
Estimated hours taken: 0.5
Branches: main
compiler/hlds_out.m:
When writing a mode-specific clause in a `.opt' file, get the modes
of the procedure using proc_info_declared_argmodes rather than
proc_info_argmodes. This is necessary because the test in
make_hlds.m to work out whether a clause matches a mode declaration
uses syntactic equality on the modes, but the modes returned by
proc_info_argmodes may have been expanded by
propagate_types_into_modes.
compiler/intermod.m:
Tell hlds_out.m to use the declared modes when writing clauses.
tests/hard_coded/multimode.m:
tests/hard_coded/multimode_main.exp:
Test case.
Index: compiler/hlds_out.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/hlds_out.m,v
retrieving revision 1.268
diff -u -u -r1.268 hlds_out.m
--- compiler/hlds_out.m 2001/08/12 08:16:24 1.268
+++ compiler/hlds_out.m 2001/08/17 06:14:58
@@ -147,16 +147,21 @@
:- pred hlds_out__write_hlds(int, module_info, io__state, io__state).
:- mode hlds_out__write_hlds(in, in, di, uo) is det.
+ % hlds_out__write_clause(Indent, ModuleInfo, PredId, VarSet,
+ % AppendVarNums, HeadVars, PredOrFunc, Clauses, MaybeVarTypes).
:- pred hlds_out__write_clauses(int, module_info, pred_id, prog_varset, bool,
list(prog_var), pred_or_func, list(clause), maybe_vartypes,
io__state, io__state).
:- mode hlds_out__write_clauses(in, in, in, in, in, in, in, in, in, di, uo)
is det.
+ % hlds_out__write_clause(Indent, ModuleInfo, PredId, VarSet,
+ % AppendVarNums, HeadTerms, PredOrFunc, Clause,
+ % UseDeclaredModes, MaybeVarTypes).
:- pred hlds_out__write_clause(int, module_info, pred_id, prog_varset, bool,
- list(prog_term), pred_or_func, clause, maybe_vartypes,
+ list(prog_term), pred_or_func, clause, bool, maybe_vartypes,
io__state, io__state).
-:- mode hlds_out__write_clause(in, in, in, in, in, in, in, in, in, di, uo)
+:- mode hlds_out__write_clause(in, in, in, in, in, in, in, in, in, in, di, uo)
is det.
:- pred hlds_out__write_assertion(int, module_info, pred_id, prog_varset, bool,
@@ -933,9 +938,10 @@
{ Clauses0 = [Clause|Clauses] }
->
{ term__var_list_to_term_list(HeadVars, HeadTerms) },
+ { UseDeclaredModes = no },
hlds_out__write_clause(Indent, ModuleInfo, PredId, VarSet,
AppendVarnums, HeadTerms, PredOrFunc,
- Clause, TypeQual),
+ Clause, UseDeclaredModes, TypeQual),
hlds_out__write_clauses(Indent, ModuleInfo, PredId, VarSet,
AppendVarnums, HeadVars, PredOrFunc, Clauses, TypeQual)
;
@@ -943,7 +949,8 @@
).
hlds_out__write_clause(Indent, ModuleInfo, PredId, VarSet,
- AppendVarnums, HeadTerms, PredOrFunc, Clause, TypeQual) -->
+ AppendVarnums, HeadTerms, PredOrFunc, Clause,
+ UseDeclaredModes, TypeQual) -->
{
Clause = clause(
Modes,
@@ -984,7 +991,7 @@
% than a compiler abort during the dumping process.
hlds_out__write_annotated_clause_heads(ModuleInfo, Context,
PredId, Modes, VarSet, AppendVarnums, HeadTerms,
- PredOrFunc)
+ PredOrFunc, UseDeclaredModes)
),
( { Goal = conj([]) - _GoalInfo } ->
io__write_string(".\n")
@@ -996,29 +1003,53 @@
:- pred hlds_out__write_annotated_clause_heads(module_info::in,
term__context::in, pred_id::in, list(proc_id)::in, prog_varset::in,
- bool::in, list(prog_term)::in, pred_or_func::in,
+ bool::in, list(prog_term)::in, pred_or_func::in, bool::in,
io__state::di, io__state::uo) is det.
-hlds_out__write_annotated_clause_heads(_, _, _, [], _, _, _, _) --> [].
+hlds_out__write_annotated_clause_heads(_, _, _, [], _, _, _, _, _) --> [].
hlds_out__write_annotated_clause_heads(ModuleInfo, Context, PredId,
[ProcId | ProcIds], VarSet, AppendVarnums, HeadTerms,
- PredOrFunc) -->
+ PredOrFunc, UseDeclaredModes) -->
hlds_out__write_annotated_clause_head(ModuleInfo, Context, PredId,
- ProcId, VarSet, AppendVarnums, HeadTerms, PredOrFunc),
+ ProcId, VarSet, AppendVarnums, HeadTerms,
+ PredOrFunc, UseDeclaredModes),
hlds_out__write_annotated_clause_heads(ModuleInfo, Context, PredId,
- ProcIds, VarSet, AppendVarnums, HeadTerms, PredOrFunc).
+ ProcIds, VarSet, AppendVarnums, HeadTerms,
+ PredOrFunc, UseDeclaredModes).
:- pred hlds_out__write_annotated_clause_head(module_info::in,
term__context::in, pred_id::in, proc_id::in, prog_varset::in,
- bool::in, list(prog_term)::in, pred_or_func::in,
+ bool::in, list(prog_term)::in, pred_or_func::in, bool::in,
io__state::di, io__state::uo) is det.
hlds_out__write_annotated_clause_head(ModuleInfo, Context, PredId, ProcId,
- VarSet, AppendVarnums, HeadTerms, PredOrFunc) -->
+ VarSet, AppendVarnums, HeadTerms,
+ PredOrFunc, UseDeclaredModes) -->
{ module_info_pred_info(ModuleInfo, PredId, PredInfo) },
{ pred_info_procedures(PredInfo, Procedures) },
( { map__search(Procedures, ProcId, ProcInfo) } ->
- { proc_info_argmodes(ProcInfo, ArgModes) },
+ %
+ % When writing `.opt' files, use the declared
+ % argument modes so that the modes are guaranteed
+ % to be syntactically identical to those in the
+ % original program. The test in make_hlds.m to
+ % check whether a clause matches a procedure
+ % tests for syntactic identity (roughly).
+ % The modes returned by proc_info_argmodes may have
+ % been slightly expanded by propagate_types_into_modes.
+ %
+ % We can't use the declared argument modes when writing
+ % HLDS dumps because the modes of the type-infos will
+ % not have been added, so the call to
+ % assoc_list__from_corresponding_lists below
+ % will abort. `.opt' files are written before
+ % the polymorphism pass.
+ %
+ { UseDeclaredModes = yes ->
+ proc_info_declared_argmodes(ProcInfo, ArgModes)
+ ;
+ proc_info_argmodes(ProcInfo, ArgModes)
+ },
{ assoc_list__from_corresponding_lists(HeadTerms, ArgModes,
AnnotatedPairs) },
{ AnnotatedHeadTerms = list__map(add_mode_qualifier(Context),
Index: compiler/intermod.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/intermod.m,v
retrieving revision 1.106
diff -u -u -r1.106 intermod.m
--- compiler/intermod.m 2001/08/12 08:13:09 1.106
+++ compiler/intermod.m 2001/08/17 05:12:38
@@ -1437,8 +1437,11 @@
% where the added arguments for a DCG pred expression
% are named the same as variables in the enclosing clause.
{ AppendVarNums = yes },
+ { ForIntermod = yes },
+ { MaybeVarTypes = no },
hlds_out__write_clause(1, ModuleInfo, PredId, VarSet, AppendVarNums,
- ClauseHeadVars, PredOrFunc, Clause, no).
+ ClauseHeadVars, PredOrFunc, Clause, ForIntermod,
+ MaybeVarTypes).
intermod__write_clause(ModuleInfo, PredId, VarSet, _HeadVars,
PredOrFunc, SymName, Clause) -->
Index: tests/hard_coded/intermod_multimode.m
===================================================================
RCS file: /home/mercury1/repository/tests/hard_coded/intermod_multimode.m,v
retrieving revision 1.1
diff -u -u -r1.1 intermod_multimode.m
--- tests/hard_coded/intermod_multimode.m 2001/05/27 09:57:58 1.1
+++ tests/hard_coded/intermod_multimode.m 2001/08/17 05:22:50
@@ -29,6 +29,24 @@
:- impure pred puts(string::in) is det.
+:- type determinism
+ ---> det
+ ; semidet
+ ; cc_multi
+ ; cc_nondet
+ ; multi
+ ; nondet
+ ; erroneous
+ ; failure.
+
+:- pred get_determinism(pred(T), determinism).
+:- mode get_determinism(pred(out) is det, out(bound(det))) is det.
+:- mode get_determinism(pred(out) is semidet, out(bound(semidet))) is det.
+:- mode get_determinism(pred(out) is multi, out(bound(multi))) is det.
+:- mode get_determinism(pred(out) is nondet, out(bound(nondet))) is det.
+:- mode get_determinism(pred(out) is cc_multi, out(bound(cc_multi))) is det.
+:- mode get_determinism(pred(out) is cc_nondet, out(bound(cc_nondet))) is det.
+
:- implementation.
func0 = ("func0 = out" :: out).
@@ -65,3 +83,12 @@
impure puts("test2(out, out)").
:- pragma c_code(puts(S::in), [will_not_call_mercury], "puts(S)").
+
+:- pragma promise_pure(get_determinism/2).
+get_determinism(_Pred::(pred(out) is det), det::out(bound(det))).
+get_determinism(_Pred::(pred(out) is semidet), semidet::out(bound(semidet))).
+get_determinism(_Pred::(pred(out) is cc_multi), cc_multi::out(bound(cc_multi))).
+get_determinism(_Pred::(pred(out) is cc_nondet), cc_nondet::out(bound(cc_nondet))).
+get_determinism(_Pred::(pred(out) is multi), multi::out(bound(multi))).
+get_determinism(_Pred::(pred(out) is nondet), nondet::out(bound(nondet))).
+
Index: tests/hard_coded/intermod_multimode_main.exp
===================================================================
RCS file: /home/mercury1/repository/tests/hard_coded/intermod_multimode_main.exp,v
retrieving revision 1.1
diff -u -u -r1.1 intermod_multimode_main.exp
--- tests/hard_coded/intermod_multimode_main.exp 2001/05/27 09:57:58 1.1
+++ tests/hard_coded/intermod_multimode_main.exp 2001/08/17 05:26:09
@@ -12,3 +12,4 @@
test2(in, out)
test2(out, in)
test2(out, out)
+semidet
Index: tests/hard_coded/intermod_multimode_main.m
===================================================================
RCS file: /home/mercury1/repository/tests/hard_coded/intermod_multimode_main.m,v
retrieving revision 1.1
diff -u -u -r1.1 intermod_multimode_main.m
--- tests/hard_coded/intermod_multimode_main.m 2001/05/27 09:57:58 1.1
+++ tests/hard_coded/intermod_multimode_main.m 2001/08/17 05:25:21
@@ -31,5 +31,9 @@
{ impure test2(In, In) },
{ impure test2(In, _Out11) },
{ impure test2(_Out12, In) },
- { impure test2(_Out13, _Out14) }.
+ { impure test2(_Out13, _Out14) },
+
+ { get_determinism((pred(1::out) is semidet), Det) },
+ io__write(Det),
+ io__nl.
--------------------------------------------------------------------------
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