Module 5 , Part 2
Termination criteria
 
- Terminate when a specific point is reached

 

 
The pattern for this is:
     % 1 terminating condition
     rule(1, Elem, [Elem|_]).
     % 2 recursive
     rule(Cnt, Elem, [_|Tail]) :-
          Cnt1 is Cnt - 1,
          rule(Cnt1, Elem, Tail).
Now, this is only a pattern: the procedures we'll see in this section will all have this pattern as part of them, although there may be additions.
position/3

position/3 is really just the basic pattern with no additions. The idea is that we know we have got to a particular position when the counter has been reduced to '1':
     % 1 terminating condition
     position(1, Elem, [Elem|_]).
     % 2 recursive
     position(Cnt, Elem, [_|Tail]) :-
          Cnt1 is Cnt - 1,
          position(Cnt1, Elem, Tail).
Try the following goals:
     | ?- position(0, Elem, [a,b,c]).
     | ?- position(1, Elem, [a,b,c]).
     | ?- position(2, Elem, [a,b,c]).
     | ?- position(3, Elem, [a,b,c]).
     | ?- position(4, Elem, [a,b,c]).

 
delete_nth/3

This procedure is true if one list is the same as a second list, except that the nth element is deleted. As with count_elem/2, values to be passed back (such as the second list with the element deleted) have to be included in the argument list.
     % 1 terminating condition
     delete_nth(1, [Elem|Tail], Tail).
     % 2 recursive
     delete_nth(Cnt, [Head|Tail1], [Head|Tail2]) :-
          Cnt1 is Cnt - 1,
          delete_nth(Cnt1, Tail1, Tail2).
Notice in the recursive clause how the Head of the first list is unified with the Head of the second list. You could use the Prolog tracer to follow how the variables are instantiated or add your own write/1 clauses to display variables during recursion.

Try the following goals:

     | ?- delete_nth(0,[a,b,c], List).
     | ?- delete_nth(1, [a,b,c], List).
     | ?- delete_nth(2, [a,b,c], List).
     | ?- delete_nth(3, [a,b,c], List).
     | ?- delete_nth(4, [a,b,c], List).

 
Take time to work through the Self-Test 6