[mercury-users] more Mercury homework: "Mercuryfy" some simple Prolog

Peter Ross pro at missioncriticalit.com
Fri Sep 24 09:48:08 AEST 2010


On Fri, Sep 24, 2010 at 12:30 AM, Jean-Marc Vanel
<jeanmarc.vanel at gmail.com> wrote:
> Hi
> I'm in the middle of translating into Mercury some simple Prolog from the
> book "the Art Of Prolog" , namely Program 2.1:  Defining family
> relationships :
>
>         uncle(Uncle,Person) :-
>                 brother(Uncle,Parent), parent(Parent,Person).
> And, again, I do not find much help in the documentation.
> First , I put this is interface :
> :- type person.
> But, then, what to put in the implementation, which would the equivalent of
> an empty class in Java ?
>
The equivalent to the empty class is.

:- type person ---> person.

However this is not very useful in the code you have above as the only
queries you could make were

uncle(person, person), uncle(person, X), uncle(X, person) and uncle(X, Y)

and the only possible bindings for X and Y would person.

So I would use instead an equivalence type

:- type person == string.

as Tomas suggested.


> A 2nd problem is with pure database predicates (primitives), like brother. I
> put this :
> :- pred brother( person, person) is multi .
> :- mode brother( in, out ) is multi .
> :- mode brother( out, in ) is multi .
> But the compiler is not happy :
> Error: no clauses for predicate `brother'/2.
> Let's suppose that brother/2 is provided by external facts .

You can use the compiler option "--allow-stubs" which will
automatically generate clauses for undefined predicates.  These
automatically generated clauses will throw an exception if they are
called.

This gives you the following code

-------------------------------------------------------------------
:- module person.
:- interface.

:- type person.

:- pred uncle(person, person).
:- mode uncle(in, out) is nondet.
:- mode uncle(out, in) is nondet.

:- implementation.

:- type person == string.

uncle(Uncle, Person) :-
    brother(Uncle, Parent),
    parent(Parent, Person).

:- pred brother(person, person).
:- mode brother(in, out) is nondet.
:- mode brother(out, in) is nondet.

:- pred parent(person, person).
:- mode parent(in, out) is nondet.
:- mode parent(out, in) is nondet.
-------------------------------------------------------------------

and you call

# mmc -e --allow-stubs person.m
person.m:018: Warning: no clauses for predicate `brother'/2.
person.m:022: Warning: no clauses for predicate `parent'/2.

The -e option just does error-checking only, it doesn't generate any code.

To get rid of the warnings completely
# mmc -e --allow-stubs --no-warn-stubs person.m

Hope this helps

--------------------------------------------------------------------------
mercury-users mailing list
Post messages to:       mercury-users at csse.unimelb.edu.au
Administrative Queries: owner-mercury-users at csse.unimelb.edu.au
Subscriptions:          mercury-users-request at csse.unimelb.edu.au
--------------------------------------------------------------------------



More information about the users mailing list