[mercury-users] Is DCG really appropriate, even for the things it does well?

Peter Driscoll peter_driscoll at bigpond.com
Wed Apr 3 16:34:21 AEST 2002


> I don't understand what you're suggesting.  Can you give an example of
> what you'd like to say, what it should translate into, and how the
> compiler might perform the transformation?

I am really suggesting that the compiler would see,

term(Factor ['*'] Term) :-
	factor(Factor), term(Term).

and translate it (internally) into,

term --> factor, ['*'], term.

How.  Sorry if this is a little informal.

Step 1:
	Identify that predicate is a candidate.
	-	Has a list(T) parameter.
	-	Formal parameter is like list(T) ++ list(T) ... (If space operator like
list(T) list(T) ...).
	-	Other checks?

Step 2:
	Change list(T) parameter to a DCG form.
	-	Replace the parameter with a list(T)::out parameter used to return the
text read from DCG.
	-	Add two parameters for DCG.

:- pred term(list(char)::out, list(char)::in, list(char)::out) is semidet.
term(Result) -->
	(
		Factor, ['*'], Term			%	The DCG bit.
	),
	(
		Result = Factor ++ ['*'] ++ Term	%	Calculate the result
	),
	(
		factor(Factor), term(Term)		%	The body.
	).

Step 3:
	For each variables in the DCG bit find an assertion in the body
(factor(Factor) and term(Term).
	If none found give up on the transformation.

Step 4:
	See if you can DCG the predicates called in the assertions factor and term
(if not already done).
	If you can't then give up on the transformation.

Step 5:
	Replace variables in the DCG bit with the assertions.

:- pred term(list(char)::out, list(char)::in, list(char)::out) is semidet.
term(Result) -->
	(
		factor(Factor), ['*'], term(Term)	%	The DCG bit.
	),
	(
		Result = Factor ++ ['*'] ++ Term	%	Calculate the result
	).

Step 6:
	See if the results are needed anywhere other than in creating other
results.
	If not optimise them away (removing the unnecessary parameters and their
calculation).

:- pred term(list(char)::in, list(char)::out) is semidet.
term -->
	(
		factor, ['*'], term			%	The DCG bit.
	).

This is a bit of simplification.  I am sure there are many situations I
haven't thought of here.

Kind regards

Peter Driscoll

-----Original Message-----
From: owner-mercury-users at cs.mu.OZ.AU
[mailto:owner-mercury-users at cs.mu.OZ.AU]On Behalf Of Ralph Becket
Sent: Wednesday, 3 April 2002 10:53 AM
To: mercury-users at cs.mu.OZ.AU
Subject: Re: [mercury-users] Is DCG really appropriate, even for the
things it does well?


Just from the subject line, DCGs are really appropriate for DCG-shaped
problems :)  In particular, DCGs are good when there may be several
different parse trees that match the input list.

However, for most parsing applications, where the parse tree should be
unique, you should really consider using moose or a monadic combinator
style (see, e.g., extras/xml).

Unfortunately, Mercury does not have lightweight syntax for monadic
programming and its lambda syntax (particularly for predicates) is still
a little cumbersome.  That said, you could always invent your own notation
and handle the conversion to Mercury with an awk script...

Peter Driscoll, Wednesday,  3 April 2002:
> With stronger compiler support for list appending could we do without DCG?
> Where we unify,
> 	InputList = FrontList ++ SomeOtherList
> could (or is) the compiler smart enougth to realise that it needs to unify
> FrontList with something, before trying to unify SomeOtherList.  In which
> case the ordering achieved by DCG is implicitly given by the compiler
> without the need for a special syntax.

(The compiler treats lists just the same as any other data type; see
library/list.m.)

I don't understand what you're suggesting.  Can you give an example of
what you'd like to say, what it should translate into, and how the
compiler might perform the transformation?

> It be nice to have greater freedom with modes for functions.

Things get rather confusing if you don't stick to the modes expected of
functions, at least in the forwards all-args-are-mode-in-and-the-result-
is-mode-out convention.  Putting in the reverse modes for functions is
occasionally useful (e.g. int:(+)); these modes are not expected to be
det or semidet in general.

> It would be nice to be able to use space as an operator,
> 	:- func list(T) list(T) = list(T).
> 	L1 L2 = list__append(L1, L2).

We did play around with this one a few months ago (search for
"juxtaposition" on the mailing lists), but decided it didn't win us
enough in terms of readability to be worthwhile.

Juxtaposition works well syntactically for functional languages where
function composition is an every-day staple.  With a fully relational
language like Mercury, where conjunction rather than composition is the
order of the day, it doesn't gain you nearly as much.

> Note: "Mercury using concatenation" below won't compile under mercury
> because
> 	mode list_append(in, in) = out.

You haven't specified the mode(s) you intend term/1 to have, so it's
unclear how to answer your question.

- Ralph
--------------------------------------------------------------------------
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
--------------------------------------------------------------------------

--------------------------------------------------------------------------
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