[mercury-users] Thanks, and a concrete question

Fergus Henderson fjh at cs.mu.OZ.AU
Tue Jun 3 15:43:17 AEST 2003


On 02-Jun-2003, Keith Braithwaite <keith at keithbraithwaite.demon.co.uk> wrote:
> 
> On Monday, June 2, 2003, at 09:16  pm, Fergus Henderson wrote:
> 
> >On 02-Jun-2003, Keith Braithwaite <keith at keithbraithwaite.demon.co.uk> 
> >wrote:
> >>Many thanks for the earlier comments on my code. I've a definite
> >>question new about instantiatedness.
> >
> >You didn't give quite enough context information.
> >I suspect that the problem lies with the mode declaration for
> >`mtest__run_tests/3', which you did not include in your post.
> >However, I can hazard some guesses...
> 
> OK, the interface of mtest looks like this:
> :- module mtest.
> :- interface.
> 
> :- import_module io.
> :- import_module list.
> 
> :- type case
> 	--->	case(
> 			test :: (pred),
> 			test_name :: string
> 		).
> 
> :- inst case
> 	--->	case(
> 			(pred) is semidet,
> 			ground
> 		).
> 
> :- type suite_tests == list(case).
> :- inst suite_tests == list_skel(case).
> 
> :- type suite_name == string.
> 
> :- type named_suite
> 	---> named_suite(
> 			name :: string,
> 			tests :: suite_tests
> 		).
> 
> :- inst named_suite
> 	---> named_suite(
> 			ground,
> 			suite_tests
> 		).
> 
> :- pred run_tests(named_suite::in(named_suite), io::di, io::uo) is det.
> 
> :- func named_suite ++ named_suite = named_suite.
> 
> I must admit that the form of the inst declarations comes from David 
> Overton's suggestions in answer to my last question, and I don't yet 
> fully understand what all that's about.

What I wrote in my earlier mail was correct, but I can tell you more now.
The problem is due to the higher-order pred inst "(pred) is semidet" in
the case/0 inst.  Since the inst of the argument that you are passing
is just "ground", the compiler can't be sure that the higher-order term
that you pass in refers to a semidet procedure.  Since we use a different
calling convention for det procedures, it needs to reject this program.

There are two possible solutions.  One is to change all the places where
a `named_suite' is passed with mode `in' or `out' to instead use mode
`in(named_suite)' and `out(named_suite)' respectively.  In particular,
the "++" and "suite_append" functions need to be declared with the modes
shown below.  This will ensure that the subtype information is preserved,
so the compiler doesn't "forget" that the predicates referred to are
semidet.

	:- func named_suite ++ named_suite = named_suite.  %interface
	:- mode in(named_suite) ++ in(named_suite) = out(named_suite) is det.

	:- func suite_append(named_suite, named_suite) = named_suite.
	:- mode suite_append(in(named_suite),in(named_suite)) =
			out(named_suite) is det.

The other alternative is to use `(func) = bool' instead of `(pred) is semidet';
in Mercury 0.11 and later, if you use functions, you don't need use
higher-order insts like you do with predicates.

-- 
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-users mailing list
post:  mercury-users at cs.mu.oz.au
administrative address: owner-mercury-users at cs.mu.oz.au
unsubscribe: Address: mercury-users-request at cs.mu.oz.au Message: unsubscribe
subscribe:   Address: mercury-users-request at cs.mu.oz.au Message: subscribe
--------------------------------------------------------------------------



More information about the users mailing list