🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Article View: comp.lang.prolog
Article #563

Re: general PROLOG questions

#563
From: Fernando Pereira
Date: Sat, 09 Dec 1989 06:43
61 lines
2821 bytes
In article <793@fs1.ee.ubc.ca> vincel@fs0.ee.ubc.ca writes:
>What about:
>nth([],_,[]) :- !.
>nth([Item|List],1,Item) :- !.
>nth([H|T],N,Item) :- NN is N-1,nth(T,NN,Item).
>
>Works for any length list. We don't even have to know anything about listsize!

Richard O'Keefe's temporary absence from the net is sorely felt in cases
like this one. I'll try my inadequate best to replace him here (-:). Anyway,
the short example above suffers from several problems:

1. Unnecessary cuts: the cut in the first clause is not needed, since its head
is incompatible with those of the other to clauses, and in the intended use of
the predicate the first two arguments are instantiated.

2. Unclear specification, datatype incoherence: the commonsensical definition
of nth has no solutions for the empty list, so the first clause should not
be there. Furthermore, using [] as some kind of 'null' value is a bad idea.
[] should be used only for the empty list (I'm becoming more and more taken
by strong typing...). In the example above, confusion would follow it the
Item returned from one of the lower clauses were [] (it can be a list element
too!)

3. The program will loop if called with N < 1 (a standard programming
error not restricted to Prolog)

4. In predicates where one argument is used to select a component of another
argument, it is better style (as well as more efficient in most Prolog systems)
to have the selector as the first argument.

Here's a cleaner version


nth(1, [Elem|_], Elem).
nth(I, [_|Rest], Elem) :-
   I > 0,
   J is I - 1,
   nth(J, Rest, Elem).

If your Prolog leaves an extraneous choice point when succeeding at the
base case (as unfortunately most will), a cut may be used for efficiency

nth(1, [Elem|_], Elem) :- !.
nth(I, [_|Rest], Elem) :-
   I > 0,
   J is I - 1,
   nth(J, Rest, Elem).

or a conditional used instead.

And now a plea: please apply simple style checks like the above to your
Prolog code. It pays off in efficency, robustness and clarity. Programming
(and logic programming in particular) will not be respected as an
engineering discipline (as opposed to a black art) if simple principles
of quality keep being ignored.

Fernando Pereira
AT&T Bell Laboratories
Murray Hill, NJ
pereira@research.att.com
Technical Details
Message-ID: <10231@alice.UUCP>
Path: arc1-ca.pugleaf.net!utzoo!attcan!utgpu!jarvis.csri.toronto.edu!clyde.concordia.ca!uunet!cs.utexas.edu!tut.cis.ohio-state.edu!att!dptg!ulysses!andante!alice!pereira
References: <5631@uhccux.uhcc.hawaii.edu> <2898@munnari.oz.au> <793@fs1.ee.ubc.ca>

Show Full Headers
Complete Article Headers
Path: arc1-ca.pugleaf.net!utzoo!attcan!utgpu!jarvis.csri.toronto.edu!clyde.concordia.ca!uunet!cs.utexas.edu!tut.cis.ohio-state.edu!att!dptg!ulysses!andante!alice!pereira
From: pereira@alice.UUCP (Fernando Pereira)
Newsgroups: comp.lang.prolog
Subject: Re: general PROLOG questions
Keywords: new user..
Message-ID: <10231@alice.UUCP>
Date: 9 Dec 89 06:43:33 GMT
References: <5631@uhccux.uhcc.hawaii.edu> <2898@munnari.oz.au> <793@fs1.ee.ubc.ca>
Reply-To: pereira@alice.UUCP ()
Organization: AT&T, Bell Labs
Lines: 64