user6262188
user6262188

Reputation:

Prolog. Difficult beginnings

At the beginning: I am beginner in Prolog but I have to admit, the language is curious because of the fact other paradigm.

find_kth_e(X, [X|_], 1).
find_kth_e(X, [_|T], K) :- K > 1, K1 is K-1, find_kth_e(X, T, K1). 

?-  find_kth_e(X, [1,2,3,4,5], 3).
X = 3 ;
false.
  1. What is find_kth_e? Function? Relation? ( Yeah, I know that a function is a relation).
  2. The result is 3. And it is ok. But why the second result is false?

Let's consider a modified version:

find_kth_e(X, [X|_], 1).
find_kth_e(X, [_|T], K) :- K > 1, K1 is K-1, find_kth_e(_, T, K1). 

?-  find_kth_e(X, [1,2,3,4,5], 3).
X = 3 ;
false.

The only difference is in line: find_kth_e(X, [_|T], K) :- K > 1, K1 is K-1, find_kth_e(_, T, K1).. I replaced X with _. And now:

?-  find_kth_e(X, [1,2,3,4,5], 3).

true ;
false.

The answer is true and false. Why there is no 3? After all, the result should be returned by first version of function- I mean find_kth_e(X, [X|_], 1). So, the fact that I replaced X with _ should doesn't matter.

Please explain .

Upvotes: 0

Views: 225

Answers (1)

lurker
lurker

Reputation: 58254

As @EugeneSh. says, Prolog has predicates. A predicate may have one or more predicate clauses (yours has two). A predicate defines a relation between its arguments.

?-  find_kth_e(X, [1,2,3,4,5], 3).
X = 3 ;
false.

In this example, you queried whether X is the 3rd argument of list [1,2,3,4,5]. Prolog succeeded with X = 3. But there was a choice point in your predicate, meaning Prolog encountered a place in the code before it succeeded where an alternative decision could be explored. When you pressed ;, you told Prolog to explore that alternative (Prolog backtracks). Prolog found there were no more solutions after X = 3, so Prolog says "false".

When you replaced X with _ you indicated that you didn't care what the first argument is:

?-  find_kth_e(_, [1,2,3,4,5], 3).
true ;
false.

As in the first query, Prolog succeeded in finding a 3rd element, but you indicated that you didn't care what that element is. So Prolog succeeds and says only "true". And, as before, the choice point is there. Your ; tells Prolog to backtrack to the choice point and it found no more solutions, so ultimately shows "false".

Here's another little test you can do to show success versus failure:

?- find_kth_e(X, [a,b,c,d,e], 3), write('Success!'), nl.
Success!
X = c ;
false.

Since the find_kth_e/3 succeeded, Prolog continued to the write/1 statement which wrote "Success!" and then showed X = c (Prolog shows all the variables that result in success after the entire clause finishes executing).

Here's a failure case:

?- find_kth_e(X, [a,b,c,d,e], 6), write('Success!'), nl.
false.

?-

find_kth_e/3 could not find a 6th element, so it failed. Prolog did not continue and do the write/1 due to the failure of the prior statement, and you can see "Success!" was not displayed.

Upvotes: 1

Related Questions