What is the logic behind this prolog code? -
i have short prolog code finds last element of given list.
last_of([_|tail], x) :- last_of(tail, x), !. last_of([x], x).
but have question logic of program. why use last_of([x], x).
, couldn't understand this. can explain?
there several comments program:
1st, name misnomer. first argument list, second last element. name suggests otherwise. better name list_last/2
or last/2
.
2nd, cut misplaced. in fact, exchanging rules , removing cut, more efficient, , more declarative:
last([x] , x). last([_|xs], x) :- last(xs,x).
now question. when starting programming in prolog, best imagine ground queries first. let's make several examples relation should succeed.
?- last([a],a).
for true, fact last([a],a).
sufficient. can generalize fact last([x],x).
. after that, might consider list 2 elements fact last([_,x],x).
cover lists of length 2. etc.
last([x],x). last([_,x],x). last([_,_,x],x). ...
now, let's generalize pattern! lets reduce case of longer list shorter list. this, assume know last element of xs
:
???? :- last(xs, x).
what can conclude when know x
last element of xs
? can conclude list longer 1 element have same x
last element, too! thus:
last([_|xs], x) :- list(xs, x).
so rule, can make list longer , longer. if there case can start from! reason need list([x],x).
best add fact first, because find answers goal list(xs, a)
, too.
please note particular way how looked @ :-
. read right-to-left arrow implying new: if goals on right true, goals on left true.
frequently, people try understand prolog rules in way how prolog executes them. , not right-to-left did, left-to-right. however, reading unintuitive humans, since prolog uses quite unusual way execute: on 1 hand uses unification far more complex pattern matching , backtracking. both notions not present in traditional programming languages, thereby confusing more help.
Comments
Post a Comment