name = 'pivoting/4' slug = 'split a list according to the pivot' description = '''\

pivoting(P, L, S, G): the list S contains the elements of L smaller or equal to P, and the list G contains the elements of L greater than P. The order of elements in S and G should be the same as in L.

?- pivoting(4, [1,4,5,8,6,4,2], S, G).
  S = [1,4,4,2], G = [5,8,6].
''' plan = ['''\

A pretty standard recursive exercise: you take care of the current head, and the tail is handled by the recursion. There are two branches, of course, as the head can be either smaller or greater than the pivot.

''', '''\

Go through the list and put the current head into either the smaller elements list or the greater elements list when returning from recursion.

''', '''\

If head H of list L is smaller than or equal to pivot P and if we assume that the recursion returns the elements in tail T appropriately divided into lists SmallerElems and GreaterElems and if we insert H at the start of the list SmallerElems, then we correctly split all the elements in L into smaller and greater ones. It's analogous if head H is greater than pivot P.

'''] hint = { 'eq_instead_of_equ': '''\

The operator == is "stricter" than operator = in the sense that for the latter it is enough to be able to make the two operands equal (unification).

Of course, you can also solve the exercise without explicit use of either of these two operators, just remember that unification is implicitly performed with the predicate's arguments (head of clause).

''', 'eq_instead_of_equ_markup': '''\

Perhaps the operator for unification (=) would be better?

''', 'base_case': '''\

Did you think of a base case? Which list can you split without any effort whatsoever?

''', 'recursive_case': '''\

The base case is ok. However, what about the general recursive case?

''', 'predicate_always_false': '''\

It seems your predicate is always "false". Did you give it the correct name, or is it perhaps misspelled?

If the name is correct, check whether something else is misspelled, perhaps there is a full stop instead of a comma or vice versa, or maybe you typed a variable name in lowercase?

It is, of course, also possible that your conditions are too restrictive, or even impossible to satisfy (as would be, for example, the condition that X is simultaneously smaller and greater than Y, or something similarly impossible).

''', 'timeout': '''\

Is there an infinite recursion at work here? How will it ever stop?

Or perhaps is there a missing, faulty, or simply incompatible (with the general recursive case) base case?

''', '>_and_<_mixed_up': '''\

Did you mix up the comparison? The smaller elements list contains large elements and vice versa. I did that, too! ;)

?- pivoting(4, [1,4,5,8,6,4,2], SmallerElems, GreaterElems).

''', 'duplicates_not_considered': '''\

Did you forget that some element can also be equal to the pivot? Where do you put such an element? Currently you don't put it anywhere, that's why prolog's answer is a happy (and logical, of course)... yes, you've guessed it... "false"!

''', 'all_elements_in_either_S_or_G': '''\

How come all the elements end up in either smaller or greater element list? A wrong comparison operator or a copy/paste error?

''', 'arbitrary_solution': '''\

Oh, this is a nasty little mistake. You took care of one of the lists you're returning, but not of the other one. If, for example, you put head H into a smaller elements list [H|SmallerElems] that's ok, but don't forget to specify what happens to the greater elements list (even if it stays exactly the same as returned from recursion).

''', 'unprotected_branch': '''\

Did you "protect" (with a condition) both options (branches)? Be careful, if one branch doesn't have a condition, the first solution returned will probably be correct, but it will leave the door open for other solutions which will not be correct. The semicolon stands for logical OR, not logical XOR. This means that prolog can still search for solutions in the other branch even if the first branch's condition is satisfied! That's why you need both conditions.

Try the following query and ask for more solutions.

?- pivoting(4, [1,4,5,8,6,4,2], SmallerElems, GreaterElems).

''', 'forcing_result_onto_recursion': '''

Don't force the result onto recursion, don't tell it what it should return. Just assume it will do its job. If this assumption is correct, then the rule will work for a larger case.

Is your recursive call of the form pivoting(P, T, [H|SmallerElems], GreaterElems)? This forces the recursive call to return also head H which it doesn't even know of, because you took it away before the recursive call. Inserting the head into the result, returned by the recursive call, is your job. To put it shortly, insert H outside of the recursive call.

''', 'no_recursion_in_one_branch': '''\

This is a very typical mistake when using a semicolon. Read every OR block (branch) carefully. Don't you think that you forgot something in one of the branches, usually the second one? Perhaps a recursive call? Do not forget: both/all branches are independent of one another! Either one block will be executed, or the other, but never both! And the results will not be transferred between blocks/branches; remember the scope of variables in prolog.

''', }