Different code for different modes

Peter Schachte pets at students.cs.mu.OZ.AU
Thu Jan 22 11:56:29 AEDT 1998


Very occasionally, it is desirable or even necessary to have different code
for different modes of a predicate.  Currently the only way to do that is to
implement it as pragma c_code, which can then call back into Mercury if
it must.  But this is rather inconvenient.  With the advent of impure
predicates, it makes even more sense to have different code for different
modes of a predicate implemented in Mercury.

I'd like to propose an extension to the Mercury language to allow different
code for different modes of a predicate which seems pretty attractive to me.
The syntax is largely due to Bart Demoen, and has been adopted as part of
the HAL language.  I think this idea effectively answers the question of
syntax for such a feature, but of course it leaves the question of whether
or not it's a good idea.  I'd like to vote that I think it is a good idea,
having recently needed just this feature.  It also leaves the question of
implemention difficulty, but that's entirely another bag of fish. 

The idea is that one writes `implemented_by' [predname, predname, ...] at
the end of a pred declaration in lieu of mode declarations and
implementation.  For example:

	:- impure pred min_solutions(pred, int) implemented_by [
		min_solutions_det, min_solutions_semidet,
		min_solutions_multi, min_solutions_nondet].

	:- impure pred min_solutions_det(pred::pred is det, 
		int::out(bound(1)) is det.
	min_solutions_det(_, 1).

	:- impure pred min_solutions_semidet(pred::pred is semidet,
		int::out(bound(0)) is det.
	min_solutions_semidet(_, 0).

	...

This may cause some problems with Mercury's module system (since part of
this information belongs in the implementation section and part in the
interface), so you might want to change it a bit to something like

	:- interface.
	:- impure min_solutions(pred, int).
	:- mode min_solutions(pred is det, out).
	:- mode min_solutions(pred is semidet, out).
	:- mode min_solutions(pred is multi, out).
	:- mode min_solutions(pred is nondet, out).

	:- implementation.

	:- pragma min_solutions/2 implemented_by [
		min_solutions_det, min_solutions_semidet,
		min_solutions_multi, min_solutions_nondet].

	:- impure pred min_solutions_det(pred::pred is det, 
		int::out(bound(1)) is det.
	min_solutions_det(_, 1).

	:- impure pred min_solutions_semidet(pred::pred is semidet,
		int::out(bound(0)) is det.
	min_solutions_semidet(_, 0).

	...


In either case the idea is that the arg types of all the predicates have to
be the same, and modes of the implementing predicates must be disjoint.  In
the second proposal, the set of modes of all the implementing predicates
must be a superset of the modes of the implemented pred; in the first, the
set of modes of the implemented pred is the union of the modes
of the implementing preds.  Each implementing pred may supply multiple
modes.  Effectively, we're saying that each proc of the implemented pred is
actually the corresponding proc of the single implementing pred that
supports that mode.

Comments?


-Peter Schachte			| Ultimately, there's no such thing as
pets at cs.mu.OZ.AU		| "organizational behavior"; it's all behavior
http://www.cs.mu.oz.au/~pets/	| of the people in the organization.
PGP key available on request	| -- Stephen Covey, et al.





More information about the developers mailing list