[mercury-users] =/2 used as a goal, not as an expression

Ralph Becket rafe at cs.mu.OZ.AU
Tue May 27 09:55:13 AEST 2003


Goncalo Jorge Coelho e Silva, Monday, 26 May 2003:
> 
>  What's wrong here? According to the compiler message,
> this should work.

No, the compiler message gives advice *if* you want to use a goal (i.e.
something that succeeds or fails) as a boolean expression (i.e.
something that returns a value of `yes' or `no'.)

> (with ":-import bool." on)
> --------------------------
> 
> :- pred test(int).
> :- mode test(in) is det.
> test(Input):- if {Input = 0} then yes else no.

test/1 is a predicate, not a function.

The if-then-else you have there is an if-then-else *expression*, not an
if-then-else goal.

The compiler is expecting a goal on the right hand side of the `:-'.

The { braces } around `Input = 0' should not be there.

Again, these are BASIC SYNTAX ISSUES.  The compiler is even telling you
exactly what's going on here:

> inter.m:660: In clause for predicate `inter:test/1':
> inter.m:660:   in argument 1 of call to predicate `{}/1':
> inter.m:660:   error: the language construct =/2 should be
> inter.m:660:   used as a goal, not as an expression.
> inter.m:660:   If you are trying to use a goal as a boolean function,
> inter.m:660:   you should write `if <goal> then yes else no' instead.
> inter.m:660: In clause for predicate `inter:test/1':
> inter.m:660:   error: undefined predicate `{}/1'.

The compiler sees `{Input = 0}' as `{}(Input = 0)' -- i.e. a call to a
predicate {}/1 with an argument computed from the expression `Input = 0'.
It then tells you that =/2 can't be used as an expression, but offers a
suggestion if you really want to know the result of the test.

It would help if you gave the specification for test/1.

I *think* what you mean is

	% test(Input) succeeds iff Input = 0
	%
test(0).

If you want something more complicated than that, just write

test(Input) :- ...a *GOAL* testing Input...

The *only* reason you'd want to use an if-then-else the way you have
above is if you need to turn the result of a test into a boolean value,
e.g.

	% test(Input) = yes if Input = 0
	%             = no  otherwise
	%
test(Input) = ( if Input = 0 then yes else no ).

> inter.m:660: In clause for predicate `inter:test/1':
> inter.m:660:   error: undefined predicate `yes/0'.
> inter.m:660: In clause for predicate `inter:test/1':
> inter.m:660:   error: undefined predicate `no/0'.

If you look at the interface for bool.m you'll see that `yes' and `no'
are data constructors (i.e. values i.e. expressions) and not predicates.

PLEASE STOP USING {}s AND DCG NOTATION.

> make: *** [run] Error 1
> 
> 
> or using DCGs:
> --------------
> 
> inter.m:658: Error: no clauses for predicate `inter:test/1'.
> inter.m:661: In clause for predicate `inter:test/3':
> inter.m:661:   error: undefined predicate `yes/2'.
> inter.m:661: In clause for predicate `inter:test/3':
> inter.m:661:   error: undefined predicate `no/2'.
> make: *** [run] Error 1
> 
> 
> :- pred test(int).
> :- mode test(in) is det.
> test(Input)--> if {Input = 0} then yes else no.

Please, tell us exactly what you think this DCG code desugars to.  If
you can't then STOP USING IT.

I apologise for losing my temper, but if you persist in ignoring the
advice given to you (i.e. stop using DCGs, read the syntax section of
the Reference Manual, post code that is syntactically correct, etc.)
then people will get fed up.

>  I took some parts of the last sample code off, to 
> show the least non-relevant code possible. So, yes,
> it was a DCG predicate and yes, I made a mistake on
> using {..} on IO io__write_string. I use DCG code 
> with IO because, originaly, most of it is written
> with no IO code at all. Eventually I have to pop
> some in to test some aspects of it.

This is a really bad idea.  It's better to either (a) compile in a
debugging grade and trace your program with mdb or (b) insert sanity
check calls to require__require/1 or (c) get your predicate to also
collect information about what it's doing in a list or something and
print that out at the top-level - don't pollute non-IO based code with
IO.

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



More information about the users mailing list