clause_tree1(true) :- !.     
clause_tree1((G,R)) :- !,
   clause_tree1(G),
   clause_tree1(R).           /* search each branch */ 
clause_tree1(G) :- 
   clause(G,Body),
   clause_tree1(Body).        /* grow branches */ 


member(X,[X|_]). 
member(X,[_|R]) :- member(X,R). 

clause_tree2(true) :- !.
clause_tree2((G,R)) :-
   !,
   clause_tree2(G), 
   clause_tree2(R).
clause_tree2(G) :- 
   (predicate_property(G,built_in) ;  
     predicate_property(G,compiled) ), 
   call(G).              %% let Prolog do it
clause_tree2(G) :- clause(G,Body), clause_tree2(Body). 

p :- q.
p :- r.
q :- p.
r.

clause_tree3(true,_) :- !. 
clause_tree3((G,R),Trail) :-
   !, 
   clause_tree3(G,Trail),
   clause_tree3(R,Trail). 
clause_tree3(G,Trail) :-
   loop_detect(G,Trail),
   !, 
   fail.
clause_tree3(G,Trail) :- 
   clause(G,Body), 
   clause_tree3(Body,[G|Trail]).

loop_detect(G,[G1|_]) :- G == G1.
loop_detect(G,[_|R])  :- loop_detect(G,R). 

connected(X,Y) :- connected(X,Z), connected(Z,Y).
connected(1,2).
connected(2,3).
connected(3,4).
connected(4,5).


clause_tree4(true,_) :- !.  % not necessary. "true" is a built-in
clause_tree4((A,B),D) :- !, 
    clause_tree4(A,D), 
    clause_tree4(B,D).
clause_tree4(A,_) :- 
	predicate_property(A,built_in),
    !,
   	call(A).
clause_tree4(A,D) :- 
	D > 0,
    clause(A,B),
    clause_tree4(B,D - 1).

iterative_deepening(G,Max) :-
	between(1,Max,D), 	
	clause_tree4(G,D),
	print(foundAt(D)),nl.

