0

I need to initialize some lists with a finite number of elements, all the same.

fill( 0, [], _ ) :- !.
fill( Index, [Value|List], Value ) :-
    NextIndex is Index - 1,
    fill( NextIndex, List, Value ).

The cut is mandatory to avoid infinite recursion and a fail result.

I tried to modify the rule #2 but after giving the expected solution, goal fails :

fill( Index, [Value|List], Value ) :-
    Index > 0,
    NextIndex is Index - 1,
    fill( NextIndex, List, Value ).

How it works:

?- fill( 7, AllFalse, false ).
AllFalse = [false, false, false, false, false, false, false].

?-
Aubin
  • 14,617
  • 9
  • 61
  • 84

2 Answers2

0
eq(X, Y) :- X = Y.
fill(N, Xs, V) :-
    length(Xs, N), maplist(eq(V), Xs).

While this has no external cuts, length/2 has them in generative mode.

You are destructuring a integer value, when checking it's value you always create a choicepoint. If there was a natural number mathematically implemented as follows then you can have a deterministic fill predicate.

nat(0).
nat(suc(X)) :- nat(X).

fill_nat(0, [], _).
fill_nat(suc(N), [V|Xs], V) :-
    fill_nat(N, Xs, V).

?- fill_nat(suc(suc(suc(0))), Xs, a).
Xs = [a, a, a].
rajashekar
  • 3,460
  • 11
  • 27
0

I believe this works correctly:

fill(0, [], _).
fill(N, [Val|Tail], Val) :- 
    N > 0,
    N2 is N-1,
    fill(N2, Tail, Val).

(This is equivalent to your second version, and without the cut)

?- fill(2, X, 33).
X = [33, 33] .

?-

but after giving the expected solution, goal fails

It gives you one solution, and if you want more solutions, then it says "there aren't any".

?- fill(2, X, 33).
X = [33, 33] ;
false.

?-
MWB
  • 11,740
  • 6
  • 46
  • 91