Adam Duvall
Adam Duvall

Reputation: 111

Prolog: fill list with n elements

Need to make a predicate, fill(L,X,N), where L is a list formed containing N elements X. If N <= 0 or N != length of L, L should be an empty list.

Here's what I've done, I've never been able to get the if, else.. structure working correctly in Prolog:

fill(L,X,N) :-
   ((N =< 0) -> 
   L = [];
   length(L,I),
   ((N =\+= I) -> 
   L = [];
   fill2(L,X,N))).
fill2([H|T],X,N2) :-
   NewN = N2 - 1,
   H = X,
   fill2(T,X,NewN).

I also have a simpler version, that works except when N != length of L

fill(L,_,N) :-
   N =< 0,
   L = [].
fill([H|T],X,N) :-
   NewN = N - 1,
   H = X,
   fill(T,X,NewN).

So, for example, fill(L,20,4) returns L = [20,20,20,20], but fill([20,20,20],X,2) doesn't return L = [].

Upvotes: 0

Views: 6272

Answers (1)

user1812457
user1812457

Reputation:

You are misunderstanding how Prolog is meant to be used. Predicates are not exactly functions, so they can't return. If you bind an argument to an instantiated variable:

?- fill([a,a,a], a, 4).
fail

the only sensible thing is that Prolog tells you, "this is not correct". Anyway, in this example:

?- fill([b,b], a, 3).

What should happen? Should the list be [a,a,a], or should the second and third argument be b and 2?

A very simple fill:

fill([], _, 0).
fill([X|Xs], X, N) :- succ(N0, N), fill(Xs, X, N0).

It will fail if not used properly, but you should make clear how it needs to be used.

A note: try to avoid explicit unification in the body of the predicate definition.

Upvotes: 6

Related Questions