Code Prolog décrivant le CSP des mariages stables

/* On décrit une instance du problème des mariages en définissant le prédicat preferences/2 tel que le premier argument de ce prédicat est une personne X, et le deuxième argument est une liste de couples Rg:Y donnant pour chaque personne Y choisie par X son rang Rg. */

preferences(1,[1:8, 2:10, 2:12]).
preferences(2,[1:8, 1:11, 2:12]).
preferences(3,[1:7, 2:9, 3:12]).
preferences(4,[1:12, 2:9]).
preferences(5,[1:8, 2:7, 3:11]).
preferences(6,[1:12, 2:10, 2:8, 3:11, 4:7]).
preferences(7,[1:5, 1:3, 2:6]).
preferences(8,[1:2, 2:5, 3:1, 4:6]).
preferences(9,[1:3, 1:4]).
preferences(10,[1:6, 2:1]).
preferences(11,[1:5, 2:2, 3:6]).
preferences(12,[1:1, 2:4, 2:6, 3:2, 4:3]).

/* A partir du prédicat preferences/2 on définit le prédicat prefere/3 tel que prefere(I,J,K) est vrai si I préfère J à K, c'est-à-dire si le rang de J est inférieur au rang de K dans la liste des préférences de I */

prefere(I,J,K) :-
preferences(I,L),
member(RangJ:J,L),
member(RangK:K,L),
RangJ < RangK.

/* Le prédicat domaine/2 associe à une personne I la liste L des personnes qu'elle veut bien épouser et, réciproquement, qui veulent bien l'épouser */

domaine(I,L) :-
findall(J,(preferences(I,PrefI), member(_:J,PrefI), preferences(J,PrefJ), member(_:I,PrefJ)),L).

/* On construit la liste des variables suivies de leurs domaines en cherchant, pour chaque homme I appartenant à la liste des hommes, son domaine de valeurs DI */

variables(L) :-
findall(femmeDe(I):DI,(member(I,[1,2,3,4,5,6]),domaine(I,DI)),L).

/* consistants((femmeDe(I),XI),(femmeDe(J),XJ)) vérifie que I peut se marier avec XI en même temps que J se marie avec XJ */

consistants((femmeDe(I),XI),(femmeDe(J),XJ)) :-
/* une femme ne peut pas être mariée à 2 hommes différents */
XI \= XJ,
/* il ne faut pas qu'à la fois I préfère XJ à XI et XJ préfère I à J */
\+ (prefere(I,XJ,XI), prefere(XJ,I,J)),
/* il ne faut pas qu'à la fois J préfère XI à XJ et XI préfère J à I */
\+ (prefere(J,XI,XJ), prefere(XI,J,I)).