Self-Test 11

Templates, determinism and non-determinism
 
This question includes a partial program. You are advised to copy and paste this into a file. You should develop your solution on a machine and test it before looking at the solution.
 
  A version of membership that allowed a built-in to be passed was given as:
 
 

     % 1
     memb_ext(Elem, List, Relation) :-
          atom(Relation),
          memb_ext1(Elem, List, Relation).

     % 1 terminating
     memb_ext1(Elem, [Head|_], Relation) :-
          functor(Relation1, Relation, 2),
          arg(1, Relation1, Elem),
          arg(2, Relation1, Head),
          call(Relation1).
     % 2 recursive
     memb_ext1(Elem, [_|List], Relation) :-
          memb_ext1(Elem, List, Relation).
   
  Extend these procedures so that it is possible to pass a parameter (either det or non) that will make the procedure work either deterministically or non-determinsitically. For instance, the following queries would produce these behaviours:
   
 
     | ?- Elem = a, memb_ext(a, [a,b,a,b], =, non), Elem = Output.

     Elem = a 
     Output = a ? ;

     Elem = a 
     Output = a ? ;

     no
     | ?- Elem = a, memb_ext(a, [a,b,a,b], =, det), Elem = Output.

     Elem = a 
     Output = a ? ;

     no