Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

template-based predicate generation?

0 views
Skip to first unread message

Terrence Brannon

unread,
Oct 26, 2009, 2:02:59 PM10/26/09
to
I'm working through the Amzi prolog tutorial and wrote a couple of
predicates which describe what a grandmother and grandfather are:

grandparent(G,G1) :- parent(X, _), parent(G, X).
grandmother(G,G1) :- grandparent(G,G1), female(G).
grandfather(G,G1) :- grandparent(G,G1), male(G).

but the last 2 predicates bother me because they are the same save for
the gender of the grandparent.

I'm wondering if there are advanced Prolog features which allow for
generating the grandmother/2 and grandfather/2 predicates from a
common template.

E.g. Here is a Perl progam that does what I want:

sub make_grandparent {
my ($grandparent_type)=@_;

my %map = (
grandmother => 'female',
grandfather => 'male'
);

my $predicate = $map{$grandparent_type};

sprintf 'grandparent(G,G1) :- grandparent(G,G1), %s(G).',
$predicate;
}

for my $grandparent qw(grandmother grandfather) {
print make_grandparent($grandparent) . "\n" ;
}

/* Transcript */

[tbrannon@Ghostdc7600] [~/prg/prolog] perl mkgp.pl
grandparent(G,G1) :- grandparent(G,G1), female(G).
grandparent(G,G1) :- grandparent(G,G1), male(G).


Markus Triska

unread,
Oct 26, 2009, 2:47:55 PM10/26/09
to
Terrence Brannon <meta...@gmail.com> writes:

> I'm working through the Amzi prolog tutorial and wrote a couple of
> predicates which describe what a grandmother and grandfather are:
>
> grandparent(G,G1) :- parent(X, _), parent(G, X).
> grandmother(G,G1) :- grandparent(G,G1), female(G).
> grandfather(G,G1) :- grandparent(G,G1), male(G).
>
> but the last 2 predicates bother me because they are the same save for
> the gender of the grandparent.

In addition, consider using predicate names that make clear which
argument is what, like grandparent_of/2, grandmother_of/2 etc. Also, G1
occurs only once in the first clause.

> I'm wondering if there are advanced Prolog features which allow for
> generating the grandmother/2 and grandfather/2 predicates from a
> common template.

Consider for example:

?- member(Functor-Constraint, [grandmother_of-female, grandfather_of-male]),
Head =.. [Functor,X,Y],
Goal =.. [Constraint,X],
portray_clause((Head :- grandparent_of(X, Y), Goal)),
false.

yielding:

grandmother_of(A, B) :-
grandparent_of(A, B),
female(A).
grandfather_of(A, B) :-
grandparent_of(A, B),
male(A).

> E.g. Here is a Perl progam that does what I want:
>

> [tbrannon@Ghostdc7600] [~/prg/prolog] perl mkgp.pl
> grandparent(G,G1) :- grandparent(G,G1), female(G).
> grandparent(G,G1) :- grandparent(G,G1), male(G).

This only creates additional clauses for grandparent/2, and none for
grandmother_of/2 and grandfather_of/2.

--
comp.lang.prolog FAQ: http://www.logic.at/prolog/faq/

Markus Triska

unread,
Oct 26, 2009, 2:55:43 PM10/26/09
to

In addition, here is a version with format/2, with which you have to
take care of indentation yourself:

?- member(F-C, [grandmother_of-female, grandfather_of-male]),
format("~w(X, Y) :- grandparent(X, Y), ~w(X).\n", [F,C]),
false.

it yields:

grandmother_of(X, Y) :- grandparent(X, Y), female(X).
grandfather_of(X, Y) :- grandparent(X, Y), male(X).

Terrence Brannon

unread,
Oct 27, 2009, 9:29:54 AM10/27/09
to
On Oct 26, 2:47 pm, Markus Triska <tri...@logic.at> wrote:

> In addition, consider using predicate names that make clear which
> argument is what, like grandparent_of/2, grandmother_of/2 etc. Also, G1
> occurs only once in the first clause.

I see. I suppose as long as you enforce the convention that
predicate(A,B) is interpreted as

A 'is' predicate 'of' B

then you can get rid of the extra _of.

>
> > I'm wondering if there are advanced Prolog features which allow for
> > generating the grandmother/2 and grandfather/2 predicates from a
> > common template.
>
> Consider for example:
>
>    ?- member(Functor-Constraint, [grandmother_of-female, grandfather_of-male]),
>       Head =.. [Functor,X,Y],
>       Goal =.. [Constraint,X],
>       portray_clause((Head :- grandparent_of(X, Y), Goal)),
>       false.


It seems there are 3 things here that I dont understand. Where can I
read on:
1 - What function is the dash serving in member(Functor-Constraint,
[grandmother_of-female, grandfather_of-male])?
2 - the "=.." syntax?
3 - portray_clause/2. I'm using SWI Prolog and dont know if that is
built in.

>
> yielding:

very nice.

>
> This only creates additional clauses for grandparent/2, and none for
> grandmother_of/2 and grandfather_of/2.

OK, fixed:

/* PROGRAM */

sub make_grandparent {
my ($grandparent_type)=@_;

my %map = (
grandmother => 'female',
grandfather => 'male'
);

my $predicate = $map{$grandparent_type};

sprintf '%s(G,G1) :- grandparent(G,G1), %s(G).',
$grandparent_type,
$predicate;

}

for my $grandparent qw(grandmother grandfather) {
print make_grandparent($grandparent) . "\n" ;
}

/* TRANSCRIPT */

[tbrannon@Ghostdc7600] [~/prg/prolog] perl mkgp.pl


grandmother(G,G1) :- grandparent(G,G1), female(G).
grandfather(G,G1) :- grandparent(G,G1), male(G).

[tbrannon@Ghostdc7600] [~/prg/prolog]

Terrence Brannon

unread,
Oct 27, 2009, 9:31:16 AM10/27/09
to
On Oct 27, 9:29 am, Terrence Brannon <metap...@gmail.com> wrote:

> 1 - What function is the dash serving in member(Functor-Constraint,

It seems to be doing something like 'unzip' would do in a functional
programming language.

Markus Triska

unread,
Oct 27, 2009, 12:52:55 PM10/27/09
to
Terrence Brannon <meta...@gmail.com> writes:

> I see. I suppose as long as you enforce the convention that
> predicate(A,B) is interpreted as
>
> A 'is' predicate 'of' B
>
> then you can get rid of the extra _of.

Consider using a more descriptive name, like parent_child/2.

> 1 - What function is the dash serving in member(Functor-Constraint,

Any functor will do; it is customary to use -/2 for pairs.

> 2 - the "=.." syntax?

http://www.swi-prolog.org/pldoc/doc_for?object=%28%3d..%29%2f2

> 3 - portray_clause/2.

I used portray_clause/1, not .../2, see:

http://www.swi-prolog.org/pldoc/doc_for?object=portray_clause%2f1

The Quiet Center

unread,
Oct 28, 2009, 2:05:25 PM10/28/09
to
On Oct 27, 12:52 pm, Markus Triska <tri...@logic.at> wrote:
> Terrence Brannon <metap...@gmail.com> writes:

>
> > 1 - What function is the dash serving in member(Functor-Constraint,
>
> Any functor will do; it is customary to use -/2 for pairs.
>

I do not see -/2 listed in the predicate reference:
http://www.swi-prolog.org/pldoc/doc_for?object=section%282%2c%20%27F.1%27%2c%20swi%28%27%2fdoc%2fManual%2fpredsummary.html%27%29%29

Also I do not see a member/2 listed there either.

I'm sorry if I'm asking too many questions, but I almost have this
figured out.

0 new messages