1) Expliquer ... 
   Voir trace de l'execution

2) Adapter ... 

simplify_sum(Sum,Simplified) :-
	simplify_sum(Sum,TopOfTree,HoleAtBottom,0,N),
	simplify_sum1(Simplified,TopOfTree,HoleAtBottom,N).	
simplify_sum1(Simplified,TopOfTree,HoleAtBottom,N):-
	N \== 0,
	HoleAtBottom=N,
	Simplified=TopOfTree,
	!.
simplify_sum1(Simplified,TopOfTree,HoleAtBottom,N):-
	N == 0, 
	var(TopOfTree),
	Simplified=0,
	!.
simplify_sum1(Simplified,TopOfTree,HoleAtBottom,N):-
	N == 0, 
	nonvar(TopOfTree),
	TopOfTree=Simplified+HoleAtBottom ; 
		TopOfTree=Simplified-Last, HoleAtBottom = -Last.
	% H + expression = S + H.	
simplify_sum(A-B,Hole0,Hole,N0,N):-!,
	simplify_sum(+(A,-B),Hole0,Hole,N0,N).
simplify_sum(A+B,Hole0,Hole,N0,N):-!,
	simplify_sum(B,Hole0,Hole1,N0,N1),
	simplify_sum(A,Hole1,Hole,N1,N).
simplify_sum(C,Hole,Hole,N0,N):- number1(C), !,
	N is N0 + C.
simplify_sum(-X,Hole - X,Hole,N,N):- !.
simplify_sum(X,Hole + X,Hole,N,N):- !.
number1(C):- number(C).
number1(-C):- number(C).
/* Exemples
| ?- simplify_sum(3+5,S).
  S = 8
| ?- simplify_sum(3+5+b+6+c,S).
  S = 14+b+c
| ?- simplify_sum((3+5)+b+6+c,14+b+c).
  true
| ?- simplify_sum(3+5+b+6+c,S).
S = 14+b+c
| ?-  simplify_sum(3+5+b-6+c,S).

S = 2+b+c

true
| ?-  simplify_sum(3+5+b-6-c,S).

S = 2+b-c
true
| ?-  simplify_sum(3-5+b-6+c,S).

S = -8+b+c
| ?-  simplify_sum(-3-b-c+3,S).

S = -c-b
*/

3) D\'efinir  ..

Les fameuses huit reines
 Version naive:

% eight_queens([X1,X2,X3,X4,X5,X6,X7,X8]) : the  Xi are the positions (on 
% columns) of eight queens on a chessboard so that no two queens attack each other

eight_queens([X1,X2,X3,X4,X5,X6,X7,X8]) :-
	perm([5,4,6,3,7,2,1,8],[X1,X2,X3,X4,X5,X6,X7,X8]),
	verify([X1,X2,X3,X4,X5,X6,X7,X8]).

verify([]).
verify([X1|X_s]) :-
	noattack(X1,X_s,1),
	verify(X_s).

noattack(X,[],N).
noattack(X_i,[X_j|X_s],N) :-
	 D1 is X_j - N,
	 D2 is X_j + N,
	 X_i \== D1,
	 X_i \== D2,
	 N1 is N+1,
	 noattack(X_i,X_s,N1).

% perm(L1,L2) : L1 is a permutation of L2
perm([],[]) .
perm([H|T],L):-
	select(H,L,R_est),
	perm(T,R_est).

select(H,[H|R_est],R_est) .
select(X,[H|T],[H|R]) :-
	select(X,T,R).

 Version un peu plus efficace:

% eight_queens([X1,X2,X3,X4,X5,X6,X7,X8]) : the  Xi are the positions (on 
% columns) of eight queens on a chessboard so that no two queens attack each other

eight_queens([X1,X2,X3,X4,X5,X6,X7,X8]) :-
	label_and_check([X1,X2,X3,X4,X5,X6,X7,X8],[1,2,3,4,5,6,7,8],T-T,1).

label_and_check([],[],_,N).
label_and_check([X1|XR],Row_Values,Placed-T,N) :-
	select(X1,Row_Values,Rest_Row),
	T=[X1|T1],
	verify(Placed-T1,X1,N,1),
	N1 is N+1,
	label_and_check(XR,Rest_Row,Placed-T1,N1).

verify(_,_,N,N).
verify([X1|X_s]-T,X,N,M) :-
	D is N-M,
	noattack(X1,X,D),
	M1 is M+1,
	verify(X_s-T,X,N,M1).

noattack(X_i,X,D) :-
	 D1 is X - D,
	 D2 is X + D,
	 X_i \== D1,
	 X_i \== D2.

select(H,[H|R_est],R_est) .
select(X,[H|T],[H|R]) :-
	select(X,T,R).



/* eight_queens([X1,X2,X3,X4,X5,X6,X7,X8]). 
 [-'queens2'].
| ?- eight_queens(L).

L = [1,5,8,6,3,7,2,4]

L = [1,6,8,3,7,4,2,5]

L = [1,7,4,6,8,2,5,3]
...
*/
Le fameux 'self'

/* From: udi@WISDOM.WEIZMANN.AC.IL (Ehud Shapiro)
A Prolog program that returns itself (up to renaming): */

self((self(_14):-_15)) :- clause(self(_14),_15).

/*
| -? self(X).

X = self((self(_14):-_15)):-clause(self(_14),_15) */


