Say I need a predicate rep(?List, ?Times, ?TList) which is true iff List is repeated Times times in TList (for example, rep([a,c],2,[a,c,a,c])). It should work as long as two of the arguments are instantiated. Here a somewhat working version:
rep(_,0,[]).
rep(List,1,List).
rep(List,Times,TList) :- integer(Times), Times>1,
succ(RemTimes,Times), append(List,RemList,TList),
rep(List,RemTimes,RemList).
rep(List,Times,TList) :- var(Times),
append(List,RemList,TList),
rep(List,RemTimes,RemList), !,
succ(RemTimes,Times).
Two questions:
- Isn’t there some built-in (that I am unable to find) that does that?
- Is there a more straight-forward way of doing this? Like getting rid of the last clause? It is necessary because I couldn’t find a way to express the relationship between Times and RemTimes when Times is not instantiated.
I don’t know about a specialized builtin. Here a procedure using the generative capability of length/2
the final cut avoid looping when any list is free.