Check if a list is made up of N instances of X (repeat X N times)

余生颓废 提交于 2020-01-30 08:58:04

问题


Given a query such as:

containsN(4,2,Z).

I should get: Z = [2,2,2,2].

or

containsN(4,W,[3,3,3,3])

I should get: W = 3.

So in other words, for the first example I need 4 instances of 2 in a list bound to Z.

For the second example I need the element in the list applied 4 times bound to W.

My attempt so far results in an infinite loop:

containsN(Y,W,Z) :- contains_helper(Y,W,Z).

contains_helper(0,_,_).
contains_helper(Y,W,[H|T]) :- W = H, Y0 is Y - 1, contains_helper(Y0,W,T).

The idea is, I call a helper function so that I can check the elements of Z one by one. When the counter reaches 0 I know the list is true because for each iteration H = W. However, I'm getting an infinite loop.


回答1:


If you want the predicate to be as general as possible (and I renamed it to repeat/3)

?- repeat(X, N, L).
N = 0, L = [] ;
N = 1, L = [X] ;
...

You can use the nice properties of length/2, like this:

% True when L is a list with N repeats of X
repeat(X, N, L) :-
    length(L, N),
    maplist(=(X), L).

Here, length(L, N) can check for the list's length, or generate a list of the desired length, or generate lists of increasing length upon backtracking.

The maplist(=(X), L) will succeed if each element of the list L unifies with the variable X. You could have written it as:

foo([], _).
foo([X|Xs], X) :-
    foo(Xs, X).

but I don't think this is necessary.



来源:https://stackoverflow.com/questions/27310855/check-if-a-list-is-made-up-of-n-instances-of-x-repeat-x-n-times

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!