I’ve been trying to split a Prolog at a given element. I’ve come close but I can’t get the left part of the list.
split(X,[Y|L]) :- split(X,[Y|L],[Y|K],M).
split(_,[],[],[]).
split(X,[Y|L],K,[Y|M]) :- X < Y, split(X,L,K,M).
split(X,[Y|L],[Y|K],M) :- X >= Y, split(X,L,K,M).
split(X,[Y|L],[Y|K],M) :- X = Y, write(Y), write(' '), write(L).
Input:
split(2,[1,2,3,4,5]).
Returns:
2 [3,4,5]
I want it to return
[1,2] [3,4,5].
I’m not altogether sure what you want to do here. For example, what is
split(5, [1,2,3,4,5])supposed to do? For that matter, is it safe to assume the input list is sorted? I’m going to assume so.The basic problem with your rule
split/2is that you don’t have any out parameters. Prolog works differently than most programming languages; there is no such thing asreturn. At first this feels like a crippling limitation, but Prolog actually allows you to “return” as many results as you like. Looking at this code it seems to me you’re about halfway to this understanding, because you havesplit/2which doesn’t seem to have any out parameters, but it callssplit/4which has both of the out parameters you need.For starters, I’d abandon the idea of
split/2and try to getsplit/4to work. What you have doesn’t look too insane there:This suggests that most of your rules are correct. Where you get into trouble is with the additional solutions:
You can see from the writing going on there that these additional solutions were generated by your last rule,
X = Y, write(Y)...etc. Simply removing that rule produces the desired behavior insplit/4.Moving on, I think probably rather than
split/2what you actually want issplit/3with one output parameter, a list of lists. It would not be terribly hard to generate based on what we have so far:Running it we see we get the desired result you mentioned:
Hope this helps!