[m-rev.] Re: [m-dev.] question about exception.m and also mode-specific clauses
Fergus Henderson
fjh at cs.mu.OZ.AU
Sun Aug 19 02:31:34 AEST 2001
On 17-Aug-2001, Tyson Dowd <trd at cs.mu.OZ.AU> wrote:
> The diff is a good idea. I have but one comment:
>
> > +get_determinism(_Pred::(pred(out) is det), Det::out(bound(det))) :-
> > + ( Det = det
> > + ; error("get_determinism")
> > + ).
> > +get_determinism(_Pred::(pred(out) is semidet), Det::out(bound(semidet))) :-
> > + ( Det = det
> > + ; error("get_determinism")
> > + ).
>
> This isn't right, Det = semidet should be here.
>
> Did the compiler accept this?
No. I made the mistake of not compiling before I posted the diff.
(I knew that I'd need a compiler with Simon's changes in it to get
the diff to compile, and being in a bit of a hurry... well never mind,
obviously not compiling it *was* a mistake. Clearly I need a holiday! ;-)
As well as that one, there were a couple of other errors that the compiler
picked up (I had omitted the `pragma promise_pure' declarations for
get_determinism/2 and get_determinism_2/2; also I had clauses for `erroneous'
and `failure' in get_determinism/2. but there weren't declared modes for them).
Unfortunately after all these errors are corrected, the compiler still
issues the same warnings about "declared `cc_multi', inferred `det'"
for all of these clauses. I had thought that determinism inference
would infer these disjunctions as `cc_multi', but in fact it notices
that error/1 has determinism `erroneous', i.e. cannot succeed, and hence
infers that the disjunction has at most one solution...
The solution is to go back to the usual workaround for determinism
warnings, use semidet_succeed/semidet_fail/cc_multi_equal,
in this case cc_multi_equal:
get_determinism(_Pred::(pred(out) is det), Det::out(bound(det))) :-
( cc_multi_equal(det, Det)
; error("get_determinism")
).
There was also a problem in my change to library/Mmakefile:
it should use `MCFLAGS +=' rather than `MCFLAGS =',
since MCFLAGS is set earlier by Mmake.common.
I am going to compound my earlier mistake and post another diff without having
run a full bootcheck yet. Hopefully I will get away with it this time ;-)
I've attached a relative diff and a new full diff.
--
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.
-------------- next part --------------
diff -u library/exception.m library/exception.m
--- library/exception.m
+++ library/exception.m
@@ -229,49 +229,45 @@
% it will pick the first disjunct and discard the call to error/1.
% This relies on --no-reorder-disj.
+:- pragma promise_pure(get_determinism/2).
+
get_determinism(_Pred::(pred(out) is det), Det::out(bound(det))) :-
- ( Det = det
+ ( cc_multi_equal(det, Det)
; error("get_determinism")
).
get_determinism(_Pred::(pred(out) is semidet), Det::out(bound(semidet))) :-
- ( Det = det
+ ( cc_multi_equal(semidet, Det)
; error("get_determinism")
).
get_determinism(_Pred::(pred(out) is cc_multi), Det::out(bound(cc_multi))) :-
- ( Det = cc_multi
+ ( cc_multi_equal(cc_multi, Det)
; error("get_determinism")
).
get_determinism(_Pred::(pred(out) is cc_nondet), Det::out(bound(cc_nondet))) :-
- ( Det = cc_nondet
+ ( cc_multi_equal(cc_nondet, Det)
; error("get_determinism")
).
get_determinism(_Pred::(pred(out) is multi), Det::out(bound(multi))) :-
- ( Det = multi
+ ( cc_multi_equal(multi, Det)
; error("get_determinism")
).
get_determinism(_Pred::(pred(out) is nondet), Det::out(bound(nondet))) :-
- ( Det = nondet
- ; error("get_determinism")
- ).
-get_determinism(_Pred::(pred(out) is erroneous), Det::out(bound(erroneous))) :-
- ( Det = erroneous
- ; error("get_determinism")
- ).
-get_determinism(_Pred::(pred(out) is failure), Det::out(bound(failure))) :-
- ( Det = failure
+ ( cc_multi_equal(nondet, Det)
; error("get_determinism")
).
+:- pragma promise_pure(get_determinism_2/2).
+
get_determinism_2(
_Pred::pred(out, di, uo) is det,
Det::out(bound(det))) :-
- ( Det = det
+ ( cc_multi_equal(det, Det)
; error("get_determinism_2")
).
get_determinism_2(
- _Pred::pred(out, di, uo) is det,
+ _Pred::pred(out, di, uo) is cc_multi,
Det::out(bound(cc_multi))) :-
- ( Det = cc_multi
+ ( cc_multi_equal(cc_multi, Det)
; error("get_determinism_2")
).
diff -u library/Mmakefile library/Mmakefile
--- library/Mmakefile
+++ library/Mmakefile
@@ -30,7 +30,7 @@
# that's not worth it.)
# (2) The code for get_determinism in library/exception.m relies on it
# (in particular it relies on --no-reorder-disj).
-MCFLAGS = --strict-sequential
+MCFLAGS += --strict-sequential
# XXX The following is needed only for bootstrapping
# the new modes of int__xor.
-------------- next part --------------
Estimated hours taken: 1
Branches: main
library/exception.m:
Use mode-specific Mercury code rather than C code.
library/Mmakefile:
Compile the library with --strict-sequential.
This is needed by the new code in exception.m
and is a good idea anyway.
Workspace: /home/venus/fjh/ws-venus4/mercury
Index: library/Mmakefile
===================================================================
RCS file: /home/mercury1/repository/mercury/library/Mmakefile,v
retrieving revision 1.76
diff -u -d -r1.76 Mmakefile
--- library/Mmakefile 3 Aug 2001 12:30:50 -0000 1.76
+++ library/Mmakefile 18 Aug 2001 16:23:55 -0000
@@ -22,11 +22,18 @@
VPATH=.
#-----------------------------------------------------------------------------#
-#
+
+# We need to compile the library with --strict-sequential for two reasons:
+# (1) Otherwise Mercury code that is compiled with --strict-sequential
+# might do the wrong thing, because the standard library wasn't compiled
+# with --strict-sequential. (We could make it a separate grade, but
+# that's not worth it.)
+# (2) The code for get_determinism in library/exception.m relies on it
+# (in particular it relies on --no-reorder-disj).
+MCFLAGS += --strict-sequential
+
# XXX The following is needed only for bootstrapping
# the new modes of int__xor.
-#
-
MCFLAGS-int = --no-halt-at-warn
# Modules which use user-guided type specialization need to be
Index: library/exception.m
===================================================================
RCS file: /home/mercury1/repository/mercury/library/exception.m,v
retrieving revision 1.49
diff -u -d -r1.49 exception.m
--- library/exception.m 3 Jul 2001 08:16:25 -0000 1.49
+++ library/exception.m 18 Aug 2001 16:21:34 -0000
@@ -196,9 +196,6 @@
:- mode try_all(in(bound(nondet)), pred(out) is nondet,
out(try_all_nondet)) is cc_multi.
-% The functors in this type must be in the same order as the
-% enumeration constants in the foreign language enums `ML_Determinism'
-% defined below.
:- type determinism
---> det
; semidet
@@ -225,159 +222,54 @@
:- mode get_determinism_2(pred(out, di, uo) is cc_multi, out(bound(cc_multi)))
is cc_multi.
-% Unfortunately the only way to implement get_determinism/2 is to use
-% the C interface, since Mercury doesn't allow different code for different
-% modes.
-
-:- pragma foreign_decl("C", "
-/* The `#ifndef ... #define ... #endif' guards against multiple inclusion */
-#ifndef ML_DETERMINISM_GUARD
-#define ML_DETERMINISM_GUARD
- /*
- ** The enumeration constants in this enum must be in the same
- ** order as the functors in the Mercury type `determinism'
- ** defined above.
- */
- typedef enum {
- ML_DET,
- ML_SEMIDET,
- ML_CC_MULTI,
- ML_CC_NONDET,
- ML_MULTI,
- ML_NONDET,
- ML_ERRONEOUS,
- ML_FAILURE
- } ML_Determinism;
-#endif
-").
-
-:- pragma foreign_proc("C",
- get_determinism(_Pred::pred(out) is det,
- Det::out(bound(det))),
- will_not_call_mercury,
- "Det = ML_DET"
-).
-:- pragma foreign_proc("C",
- get_determinism(_Pred::pred(out) is semidet,
- Det::out(bound(semidet))),
- will_not_call_mercury,
- "Det = ML_SEMIDET"
-).
-:- pragma foreign_proc("C",
- get_determinism(_Pred::pred(out) is cc_multi,
- Det::out(bound(cc_multi))),
- will_not_call_mercury,
- "Det = ML_CC_MULTI"
-).
-:- pragma foreign_proc("C",
- get_determinism(_Pred::pred(out) is cc_nondet,
- Det::out(bound(cc_nondet))),
- will_not_call_mercury,
- "Det = ML_CC_NONDET"
-).
-:- pragma foreign_proc("C",
- get_determinism(_Pred::pred(out) is multi,
- Det::out(bound(multi))),
- will_not_call_mercury,
- "Det = ML_MULTI"
-).
-:- pragma foreign_proc("C",
- get_determinism(_Pred::pred(out) is nondet,
- Det::out(bound(nondet))),
- will_not_call_mercury,
- "Det = ML_NONDET"
-).
-
-:- pragma foreign_proc("C",
- get_determinism_2(_Pred::pred(out, di, uo) is det,
- Det::out(bound(det))),
- will_not_call_mercury,
- "Det = ML_DET"
-).
-
-:- pragma foreign_proc("C",
- get_determinism_2(_Pred::pred(out, di, uo) is cc_multi,
- Det::out(bound(cc_multi))),
- will_not_call_mercury,
- "Det = ML_CC_MULTI"
-).
-
-:- pragma foreign_decl("MC++", "
-/* The `#ifndef ... #define ... #endif' guards against multiple inclusion */
-#ifndef ML_DETERMINISM_GUARD
-#define ML_DETERMINISM_GUARD
-
- /*
- ** The constants in these #defines must be in the same
- ** order as the functors in the Mercury type `determinism'
- ** defined above.
- ** XXX It would be nice to use an enum here, but at the moment
- ** I can't convince the MC++ compiler to accept the syntax for it.
- */
-
-#define ML_DET 0
-#define ML_SEMIDET 1
-#define ML_CC_MULTI 2
-#define ML_CC_NONDET 3
-#define ML_MULTI 4
-#define ML_NONDET 5
-#define ML_ERRONEOUS 6
-#define ML_FAILURE 7
-
-#endif
-").
+% The calls to error/1 here are needed to ensure that the
+% declarative semantics of each clause is equivalent,
+% but operationally they are unreachable;
+% since each mode has determinism cc_multi,
+% it will pick the first disjunct and discard the call to error/1.
+% This relies on --no-reorder-disj.
-:- pragma foreign_proc("MC++",
- get_determinism(_Pred::pred(out) is det,
- Det::out(bound(det))),
- will_not_call_mercury,
- "MR_newenum(Det, ML_DET);"
-).
-:- pragma foreign_proc("MC++",
- get_determinism(_Pred::pred(out) is semidet,
- Det::out(bound(semidet))),
- will_not_call_mercury,
- "MR_newenum(Det, ML_SEMIDET);"
-).
-:- pragma foreign_proc("MC++",
- get_determinism(_Pred::pred(out) is cc_multi,
- Det::out(bound(cc_multi))),
- will_not_call_mercury,
- "MR_newenum(Det, ML_CC_MULTI);"
-).
-:- pragma foreign_proc("MC++",
- get_determinism(_Pred::pred(out) is cc_nondet,
- Det::out(bound(cc_nondet))),
- will_not_call_mercury,
- "MR_newenum(Det, ML_CC_NONDET);"
-).
-:- pragma foreign_proc("MC++",
- get_determinism(_Pred::pred(out) is multi,
- Det::out(bound(multi))),
- will_not_call_mercury,
- "MR_newenum(Det, ML_MULTI);"
-).
-:- pragma foreign_proc("MC++",
- get_determinism(_Pred::pred(out) is nondet,
- Det::out(bound(nondet))),
- will_not_call_mercury,
- "MR_newenum(Det, ML_NONDET);"
-).
+:- pragma promise_pure(get_determinism/2).
-:- pragma foreign_proc("MC++",
- get_determinism_2(_Pred::pred(out, di, uo) is det,
- Det::out(bound(det))),
- will_not_call_mercury,
- "MR_newenum(Det, ML_DET);"
-).
+get_determinism(_Pred::(pred(out) is det), Det::out(bound(det))) :-
+ ( cc_multi_equal(det, Det)
+ ; error("get_determinism")
+ ).
+get_determinism(_Pred::(pred(out) is semidet), Det::out(bound(semidet))) :-
+ ( cc_multi_equal(semidet, Det)
+ ; error("get_determinism")
+ ).
+get_determinism(_Pred::(pred(out) is cc_multi), Det::out(bound(cc_multi))) :-
+ ( cc_multi_equal(cc_multi, Det)
+ ; error("get_determinism")
+ ).
+get_determinism(_Pred::(pred(out) is cc_nondet), Det::out(bound(cc_nondet))) :-
+ ( cc_multi_equal(cc_nondet, Det)
+ ; error("get_determinism")
+ ).
+get_determinism(_Pred::(pred(out) is multi), Det::out(bound(multi))) :-
+ ( cc_multi_equal(multi, Det)
+ ; error("get_determinism")
+ ).
+get_determinism(_Pred::(pred(out) is nondet), Det::out(bound(nondet))) :-
+ ( cc_multi_equal(nondet, Det)
+ ; error("get_determinism")
+ ).
-:- pragma foreign_proc("MC++",
- get_determinism_2(_Pred::pred(out, di, uo) is cc_multi,
- Det::out(bound(cc_multi))),
- will_not_call_mercury,
- "MR_newenum(Det, ML_CC_MULTI);"
-).
+:- pragma promise_pure(get_determinism_2/2).
+get_determinism_2(
+ _Pred::pred(out, di, uo) is det,
+ Det::out(bound(det))) :-
+ ( cc_multi_equal(det, Det)
+ ; error("get_determinism_2")
+ ).
+get_determinism_2(
+ _Pred::pred(out, di, uo) is cc_multi,
+ Det::out(bound(cc_multi))) :-
+ ( cc_multi_equal(cc_multi, Det)
+ ; error("get_determinism_2")
+ ).
% These are not worth inlining, since they will
% (presumably) not be called frequently, and so
More information about the reviews
mailing list