The arguments are not detailed enough due to two examples

This is a very frequently asked question, but I would like to present it in relation to two examples that seem very similar to my eyes, yet some are correct and some are not.

Correct example:

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

      

Wrong example

length2(1,[_]).  
length2(X,[_|Ys]) :- X>1, X1 is (X-1), length(X1,Ys).

      

Why is the prologue complaining or not appropriate for every occasion?

Update . I think I get it. I couldn't figure out that it doesn't matter what the predicate is, but what you call it. so this is correct: k_th_element (X, [1,2,3,4,5], 3) because you have a value for K which is the right variable of the "is" operator. But at the same time k_th_element (3, [1,2,3,4,5], Y) won't work because Y is a variable, our "target" and we can't have it on the right side of "is" operator. Correct me if I am wrong.

+3


source to share


2 answers


as a suggested layout, there is a more flexible way to achieve the same:



:- use_module(library(clpfd)).

length2(0,[]).  
length2(X,[_|Ys]) :- X#>0, X1#=X-1, length2(X1,Ys).

      

+3


source


First, the order of the arguments. For length/2

this rather length(List, Length)

.

In the case of a given list and unknown length, your version is relatively ineffective, due to all the constraints X1 #= X-1

that bounded variables imply N

. The version length3/2

has a single limited variable. (This is about 7x faster. I still wonder it is not faster than it might be, can someone help with a different answer?)



:- use_module(library(clpfd)).

length2([], 0).
length2([_E|Es], N0) :-
   N0 #> 0,
   N1 #= N0-1,
   length2(Es, N1).

length3(Es, N) :-
   length3(Es, 0, N).

length3([], N,N).
length3([_E|Es], N0,N) :-
   N1 is N0+1,
   N #>= N1,
   length3(Es, N1,N).

/*

?- length(L,1000), time(length2(L,N)).
% 783,606 inferences, 0.336 CPU in 0.347 seconds (97% CPU, 2332281 Lips)
L = [_G23, _G26, _G29, _G32, _G35, _G38, _G41, _G44, _G47|...],
N = 1000.

?- length(L,1000), time(length3(L,N)).
% 127,006 inferences, 0.047 CPU in 0.058 seconds (81% CPU, 2719603 Lips)
L = [_G23, _G26, _G29, _G32, _G35, _G38, _G41, _G44, _G47|...],
N = 1000.

*/

      

+3


source







All Articles