Arbres en Prolog Un arbre binaire est une structure pouvant contenir des données. Chaque élément de l'arbre contient une donnée et a au plus un 'parent' et deux 'enfants'. 1 / \ 2 3 / \ / \ 4 5 6 7 CSI2520, Hiver 2007
Arbres en Prolog On peut representer les arbres avec une structure t(elem, gauche, droit) ou 'elem' est la valeur de la racine, et gauche et droit sont les sous-arbres à gauche/droite de la racine. Un arbre vide sera represente par 'nil'. Ainsi, un arbre à un seul élément 1: t(1,nil,nil): 1 / \ 2 3 t(1,t(2,nil,nil),t(3,nil,nil)). CSI2520, Hiver 2007
Un arbre binaire CSI2520, Hiver 2007
Parcours inordre printInfo(nul). printInfo(t(RootInfo,LeftSubtr,RightSubtr)) :- printInfo(LeftSubtr), write(RootInfo), write(' '), printInfo(RightSubtr). ?- printInfo(t(73, t(31, t(5, nul, nul), nul), t(101, t(83, nul, t(97, nul, nul)), nul))). 5 31 73 83 97 101 Yes CSI2520, Hiver 2007
Recherche dans un arbre search(Info, t(Info, _, _)). search(Info, t(RootInfo, Left, _Right)) :- precedes(Info, RootInfo), search(Info, Left). search(Info, t(RootInfo, _Left, Right)) :- precedes(RootInfo, Info), search(Info, Right). precedes(Info1, Info2) :- Info1 < Info2 . CSI2520, Hiver 2007
Insertion dans un arbre insert(Info, nul, t(Info, nul, nul)). insert(Info, t(RootInfo, Left, Right), t(RootInfo, LeftPlus, Right)) :- precedes(Info, RootInfo), insert(Info, Left, LeftPlus). t(RootInfo, Left, RightPlus)) :- precedes(RootInfo, Info), insert(Info, Right, RightPlus). CSI2520, Hiver 2007
Retrait à la racine d’un arbre delete(Info, t(Info, nul, Right), Right). delete(Info, t(Info, Left, nul), Left). delete(Info, t(Info, Left, Right), t(NewRoot, NewLeft, Right)) :- removeMax(Left, NewLeft, NewRoot). % removeMax(Tree,NewTree,Max) CSI2520, Hiver 2007
Retrait dans un arbre delete(Info, t(RootInfo, Left, Right), t(RootInfo, LeftSmaller, Right)) :- precedes(Info, RootInfo), delete(Info, Left, LeftSmaller). t(RootInfo, Left, RightSmaller)) :- precedes(RootInfo, Info), delete(Info, Right, RightSmaller). CSI2520, Hiver 2007
Retrait du max élément removeMax(t(Max, Left, nul), Left, Max). removeMax(t(Root, Left, Right), t(Root, Left, RightSmaller), Max) :- removeMax(Right, RightSmaller, Max). CSI2520, Hiver 2007
Recherche en profondeur resoudre(N,[N]) :- but(N). resoudre(N,[N | Solution]) :- successeur(N,Nsuivant), resoudre(Nsuivant,Solution). Il faut donc définir le but et définir les noeuds successeurs. CSI2520, Hiver 2007
Les tours de Hanoi État initial: [A,B,C] = [[1,2,3],[],[]] but([[],[],_]). CSI2520, Hiver 2007
Les tours de Hanoi (mouvements) legal(_,[]). legal(D1,[D2|_]):- D1<D2. successeur([[T|L1],L2,L3],[L1,[T|L2],L3]) :- legal(T,L2). successeur([[T|L1],L2,L3],[L1,L2,[T|L3]]) :- legal(T,L3). successeur([L1,[T|L2],L3],[[T|L1],L2,L3]) :- legal(T,L1). successeur([L1,[T|L2],L3],[L1,L2,[T|L3]]) :- legal(T,L3). successeur([L1,L2,[T|L3]],[[T|L1],L2,L3]) :- legal(T,L1). successeur([L1,L2,[T|L3]],[L1,[T|L2],L3]) :- legal(T,L2). CSI2520, Hiver 2007
Les tours de Hanoi (version 1) but([[],[],_]). resoudre(E,[E]) :- but(E). resoudre(E,[E|Solution]) :- successeur(E,Esuivant), resoudre(Esuivant,Solution). ?! CSI2520, Hiver 2007
Les tours de Hanoi (version 2) resoudre(Noeud,Solution) :- profondeur([], Noeud,Solution). profondeur(Chemin, Noeud,[Noeud | Chemin]) :- but(Noeud). profondeur(Chemin, Noeud,Sol) :- successeur(Chemin, Noeud1), \+member(Chemin1,Path), profondeur([Chemin | Path], Chemin1, Sol). CSI2520, Hiver 2007
Les tours de Hanoi (version 3) resoudre(E,[E],Pmax) :- but(E). resoudre(E,[E|Solution],Pmax) :- Pmax>0, successeur(E,Esuivant), Pmax1 is Pmax-1, resoudre(Esuivant,Solution,Pmax1), write(Esuivant), nl. CSI2520, Hiver 2007
Recherche en largeur resoudre(Racine, Solution):- largeur ([[Racine]],Solution). % largeur(liste de chemin, solution) largeur([[Noeud | Chemin] | _],[Noeud | Chemin]):- but(Noeud). largeur([Chemin | Chemins], Solution):- etendre(Chemin,NChemins), conc(Chemins,NChemins,Chemins1), largeur(Chemins1,Solution). etendre([Noeud | Chemin],NChemins):- bagof([NNoeud,Noeud | Chemin], (successeur(Noeud,NNoeud), \+member(NNoeud,[Noeud | Chemin])), NChemins), !. etendre(Chemin,[]). CSI2520, Hiver 2007
Les tours de Hanoi (version 4) ?- successeur([[1,2,3],[],[]],S). S = [[2, 3], [1], []] ; S = [[2, 3], [], [1]] ; ?- etendre([[[1,2,3],[],[]]],S). S = [[[[2, 3], [1], []], [[1, 2, 3], [], []]], [[[2, 3], [], [1]], [[1, 2, 3], [], []]]]. CSI2520, Hiver 2007
Les tours de Hanoi (version 4) resoudre(Racine, Solution):- largeur([[Racine]],Solution), voir(Solution). voir([]). voir([Noeud|Chemin]) :- voir(Chemin), nl, write(Noeud). . ?- resoudre([[1,2,3],[],[]],S). [[1,2,3],[],[]] [[2,3],[],[1]] [[3],[2],[1]] [[3],[1,2],[]] [[],[1,2],[3]] [[1],[2],[3]] [[1],[],[2,3]] [[],[],[1,2,3]] CSI2520, Hiver 2007
Les graphes Représentation: g([Noeud, ...],[arc(Noeud1,Noeud2,Valeur), ...]). arc(g(Ns,Arcs),N1,N2,Valeur):- member(arc(N1,N2,Valeur),Arcs). % pour un graphe non-dirigé member(arc(N1,N2,Valeur),Arcs); member(arc(N2,N1,Valeur),Arcs). CSI2520, Hiver 2007
Voisins dans un graphe voisins(Graphe,Noeud,Voisins):- setof((N,Arc),arc(Graphe,Noeud,N,Arc),Voisins). ?- voisins(g([a,b,c,d,e,f], [arc(a,b,3),arc(a,c,5),arc(a,d,7),arc(e,f,1),arc(d,f,6)]),c,V). V = [ (a, 5)]. [arc(a,b,3),arc(a,c,5),arc(a,d,7),arc(e,f,1),arc(d,f,6)]),a,V). V = [ (b, 3), (c, 5), (d, 7)]. CSI2520, Hiver 2007
Coloriage de graphe coloriage(g(Ns,Arcs),Couleurs,Coloriage):- genere(Ns,Couleurs,Coloriage), test(Arcs,Coloriage). genere([],_,[]). genere([N|Ns],Couleurs,[(N,C)|Q]):- member(C,Couleurs), genere(Ns,Couleurs,Q). test([],_). test([arc(N1,N2,_)|Ns],Coloriage):- member((N1,C1),Coloriage), member((N2,C2),Coloriage), C1\=C2, test(Ns,Coloriage). CSI2520, Hiver 2007
Coloriage de graphe ?- coloriage(g([a,b,c,d,e,f], [arc(a,b,3),arc(a,c,5),arc(a,d,7),arc(e,f,1),arc(d,f,6)]), [rouge,bleu,blanc,vert],V). V = [ (a, rouge), (b, bleu), (c, bleu), (d, bleu), (e, rouge), (f, blanc)] ; V = [ (a, rouge), (b, bleu), (c, bleu), (d, bleu), (e, rouge), (f, vert)] ; V = [ (a, rouge), (b, bleu), (c, bleu), (d, bleu), (e, bleu), (f, rouge)]; … CSI2520, Hiver 2007
Labyrinthe connecte(0,1). % depart = 0 connecte(1,2). connecte(2,6). connecte(6,5). connecte(6,7). connecte(5,4). connecte(5,9). connecte(9,8). connecte(8,12). connecte(9,10). connecte(10,11). connecte(9,13). connecte(13,14). connecte(14,15). %fin = 15 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 CSI2520, Hiver 2007
Labyrinthe successeur(A,B):-connecte(A,B). successeur(A,B):-connecte(B,A). but(15). resoudre([Fin|Chemin],[Fin|Chemin]):-but(Fin). resoudre([Courant|Chemin],Solution):- successeur(Courant,Suivant), \+member(Suivant,Chemin),write(Suivant),nl, resoudre([Suivant,Courant|Chemin],Solution). CSI2520, Hiver 2007
Labyrinthe ?- resoudre([0],S). 1 2 6 5 9 8 12 10 11 13 14 15 7 4 false. CSI2520, Hiver 2007