460 likes | 617 Views
Une (gentle?) introduction à ASP (Programmation par ensembles réponses). Jacques Nicolas INRIA /IRISA Rennes. Answer Set Programming. Approche déclarative : modélisation du problème à résoudre sous formes d’axiomes et de contraintes exprimées dans un langage logique;
E N D
Une (gentle?) introduction à ASP(Programmation par ensembles réponses) Jacques Nicolas INRIA /IRISA Rennes
Answer Set Programming • Approche déclarative : modélisation du problème à résoudre sous formes d’axiomes et de contraintes exprimées dans un langage logique; • Les modèles logiques solutions de l’ensemble de formules, les ensembles réponses, sont les résultats du programme. • Des solveurs associés effectuent la recherche d’une, de plusieurs, ou de l’ensemble des solutions.
Résolution en programmation classique Problème Solutions Spécification programmation Interprétation Compilation du programme (binaire) Sorties Programme : Comment résoudre compilateur exécution
Résolution à base de modèles (et ASP) Problème Solutions Interprétation Modélisation Compilation du problème (formules booléennes) Modèles (ensembles réponses) Représentation du problème (langage logique) Instancieur Solveur
Le langage Prolog, c’est différent d’ASP ? • Prolog= Programmation en Logique, même domaine, approche « déclarative » (on décrit des relations, pas des procédures). • Syntaxiquement, il y a des ressemblances évidentes Terme • Constante : entier, mot de {a-z, A-Z,0-9,_}* débutant par une minuscule. • Variable : mot de {a-z,A-Z,0-9,_}* débutant par une majuscule. • Fonction : constante(terme,… terme), opérateurs infixes (a+b) ou notations de liste - L=[a,b,c]=[a|U], U =[b,c], [c]=[c|[ ]]=‘.’(c,[]) - Clause • Fait : p(2,a). • Règle : q(X) :- p(X,Y), q(Y). • But : :- q(2). p(2,a) est vrai. Si p(X,Y) est vrai et q(Y) est vrai, alors q(X) est vrai aussi. Est-ce que q(2) est vrai?
Un premier programme Prolog • Spécification du problème : définir member(X,L) qui est vérifié si X est un élément de la liste L x,L1, member(x,L1) L2,y L1=[y|L2] (x=y member(x,L2)) • En Prolog : member(X,[X|L]). member(X,[Y|L]):- member(X,L). Purement déclaratif ? Presque… member(a,[a]). member(b,[a,b,c]).
La négation : négation par échec domino_chain(L):- domino_chain(L, []). domino_chain([X,Y|L], D):- domino(X,Y), admissible(X,Y,D), domino_chain(L,[[X,Y]|D]). domino_chain([], _D). admissible(X,Y,L):- not_member([X,Y], L). admissible(X,Y,L):- not_member([Y,X], L). not_member(P, L):- member(P,L),!, fail. not_member(P, L).
ASP vs Prolog • Une approche plus déclarative: l’ordre des clauses n’a aucune importance. • Le langage inclut l’opérateur de négation. • On peut écrire des termes quelconques mais par contre, tout doit se ramener à du propositionnel. • Les solutions sont des modèles de l’ensemble des clauses: des ensembles d’atomes vrais dans la théorie décrite. • Le langage inclut l’expression de critères à optimiser. Le solveur propose différents modes de raisonnement.
Les dominos en ASP : définir les domaines • Définition de domaine par un fait : • Définition de domaine par une règle : odomino(d(X,Y), croissant, left, X) :- domino(d(X,Y)). odomino(d(X,Y), croissant, right, Y) :- domino(d(X,Y)). odomino(d(X,Y),decroissant, left, Y) :- domino(d(X,Y)). odomino(d(X,Y),decroissant, right,X) :- domino(d(X,Y)). • Paramètres : place(1.. chain_size). . • dir(left). dir(right). dice(0..6). sens(croissant; decroissant). • domino(d(X,Y)) :- dice(X), dice(Y), X<=Y. #constchain_size=28.
Utiliser les programmes de Potassco • Installation : http://potassco.sourceforge.net/ • Une version binaire linux/windows/mac : http://www.cs.uni-potsdam.de/~sthiele/bioasp/downloads/bin/ • Appel : (liste des options avec option –help) gringo domino1.lp -t Pour voir le modèle instancié généré gringo input.lpmodel.lp–c chain_size=28 | clasp –stats1 solution clingo domino1.lp –n 10 10 solutions gringo domino1.lp | clasp–n 0 Toutes les solutions clingo
Un peu de syntaxe (gringo 3) • Langage simple mais très expressif (très différent de la prog. linéaire, contient aussi la disjonction). • Même base que Prolog (termes, clauses). Commentaires% ou %* *% Alternatives a;b 1..3 a,b;;c,d • Littéral : p not q X<Y U!=V X+Y<5 - built-in - 1{r(X):q(X)}2 2{r(U):q(U)=U, s(V):t(V)=2} –condition, agrégat- • Contrainte : :- p(X),q(X).:-not M-1{r(U+1):q(U)}, max(M). • Optimisation :#maximize [ p=1@2, q(X,Y):X>0:Y<0=2@2].#minimize [ t(X):s(X)=X-1@1 ]. • Sorties : #hide.#show p(X). #show p/1. #show s(X):r(X).
Un premier programme ASP : plus petit et plus grand élément d’un domaine • Il n’y a pas de notion de liste, on écrit directement les domaines comme vu précédemment. ville(brest;rennes;nantes;paris;lille). • Plus grande ville de France : • Plus petite ville de France : • On dispose en fait de la donnée du nombre d’habitants des villes dans le fichier france.lp, prédicat ville(Nom, Population). Ecrire les mêmes prédicats sur le critère de la taille de la population. plusgrandeville(V):- ville(V), U<=V:ville(U). pluspetiteville(V):- ville(V), not ville(U):ville(U):U<V.
domino1.lp : chaînage complet correct • Choix d’une chaine de dominos complète: Un domino a 1 orientation et 1 place, chaque place 1 domino orienté • A écrire : • Les doubles sont arbitrairement orientés dans le sens croissant; • On veut commencer la chaîne par un double zéro; • Les dominos doivent avoir les bords qui se touchent égaux. • 1{ domino_chain(D,K,S) : place(K):sens(S)}1 :- domino(D). • :- 2{domino_chain(D,K,S) : domino(D):sens(S)}, place(K).
Une solution pour le chaînage de dominos • %Les doubles sont arbitrairement orientés dans le sens croissant • %On veut commencer la chaîne par un double zéro • % Les dominos doivent avoir les bords qui se touchent égaux :- domino_chain ( d(X,X), K, decroissant ). :- not domino_chain(d(0,0),1,croissant). :- domino_chain(D1,K,O1), domino_chain(D2,K+1,O2), odomino(D1,O1,right,X), not odomino(D2,O2,left,X).
Un puzzle sur les dominos… • Placer correctement tous les dominos en 4 super-dominos (rectangles); • Les dominos s’apparient en chaine ainsi que les coins des super-dominos; • Total décroissant des points des super-dominos de gauche à droite. On ne considèrera que les solutions à une symétrie horizontale près • Optimisation :Total maximal pour le 1er puis le 4ème superdomino ? • Quelles sont toutes les solutions optimales possibles ? • Y-a-t-il un pattern commun a l’ensemble des solutions ?
Modélisation des super-dominos • Chaque place de domino à l’intérieur du super-domino est numérotée (de 1 à 7) dans l’ordre des aiguilles d’une montre; • Hint : On n’a besoin de préciser que la valeur à gauche d’un domino, l’autre s’en déduit automatiquement par chaînage… • Ecrire d’abord le programme générant comme ensembles réponses tous les super-dominos possibles (vérifier que les dominos diffèrent tous dans un deuxième temps)… • …puis étendre pour choisir 4 super-dominos, chacun étant numéroté (de 1 à 4).
Générer tous les super-dominos possibles Générer l’espace des possibles sans se soucier des dominos utilisés plusieurs fois Eliminer les configurations avec des dominos égaux #constnb_places=7. sdomino_place(1..nb_places). dice(0..6). 1{ldom_place(K,D):dice(D)}1:- sdomino_place(K). domino(K1,DA,DB):- ldom_place(K1,DA), next_place(K1,K2),ldom_place(K2,DB), DA<=DB. domino(K1,DB,DA):- ldom_place(K1,DA), next_place(K1,K2), ldom_place(K2,DB), DB<DA. next_place(K,K1):- sdomino_place(K), K1=(K #modnb_places)+1. :-2 [ domino(K,DA,DB) : sdomino_place(K) ], dice(DA),dice(DB).
domino2.lp : début de résolution du puzzle %Constants #constnb_sdominos=4. #constnb_places=7. dice(0..6). %The superdomino frames and the 2 associatedchainingrelations. sdomino_number(1..nb_sdominos). sdomino_place(1..nb_places). next_sdomino(1,2;;2,3;;3,4). next_place(K,K1):- sdomino_place(K), K1=(K #modnb_places)+1. %Choose the left part of dominos in the superdomino 1{ldom_place(I,K,D):dice(D)}1:- sdomino_number(I), sdomino_place(K). % Horizontal symetrybreaking : domino(1,2) < domino(7,6) :- ldom_place(1,1,T1), ldom_place(1,7,T7), T7<T1. :- ldom_place(1,1,T), ldom_place(1,7,T), ldom_place(1,2,T2), ldom_place(1,6,T6), T6<T2.
domino2.lp : contraintes sur le puzzle %Infer dominos from ldom_place and check they are all different domino(I,K1,DA,DB):- ldom_place(I,K1,DA), next_place(K1,K2),ldom_place(I,K2,DB), DA<=DB. domino(I,K1,DB,DA):- ldom_place(I,K1,DA), next_place(K1,K2), ldom_place(I,K2,DB), DB<DA. :-2[domino(I,K,DA,DB):sdomino_number(I):sdomino_place(K)], dice(DA),dice(DB). %Chain the sdominos so that corners are matching :- ldom_place(I,3,T3), ldom_place(I,4,T4), ldom_place(I,5,T5), next_sdomino(I,J), [ ldom_place(J,1,T3),ldom_place(J,7,T5) ] 1. %The sum of dices of superdominosmust decreasefromleft to right total(I,Sum):- Sum=[ldom_place(I,K,T):sdomino_place(K)=T], sdomino_number(I). :- total(I,SumI), total(J,SumJ), next_sdomino(I,J), SumI<=SumJ.
domino2.lp : optimisation %The sum of all dices must be maximal %#maximize[total(1,Sum)=Sum @2]. %#maximize[total(4,Sum)=Sum @1]. #maximize[ldom_place(1,K,T)=T @2]. #maximize[ldom_place(4,K,T)=T @1]. %Alternative if using cautious mode %:- [ldom_place(1,K,T)=T]32. %:- [ldom_place(4,K,T)=T]15. #hide. #show total/2.
Réponses pour le puzzle des dominos • Meilleurs totaux 1 et 4 : 33 et 16 (utilisation heuristique Vsids). • 22 solutions avec 33 et 16 (options --opt-all --opt-value=114,131). • Intersection des solutions ldom_place(1,4,3) total(4,16) total(3,17) total(2,18) total(1,33)
Remarque sur l’expressivité dans gringo • Les possibilités du langage sont en fait plus complexes mais au-delà des possibilités d’un cours d’introduction. • On peut écrire des programmes disjonctifs, ce qui signifie qu’il peut y avoir une alternative au niveau de la tête des clauses (e.g. p|q. ou p|q:-r.). Il faut alors faire appel à un solveur spécifique (claspD) et la complexité explose… • Notons qu’il est possible d’utiliser la négation classique en utilisant le moins (e.g –p:-q.)
ASP, c’est utile dans quels cas ? • Techniquement, ASP offre un cadre unifié où sont intégrés des aspects bases de données, bases de connaissances, résolution de contraintes et programmation logique. • Il est possible de faire de l’optimisation et d’utiliser différents modes de raisonnement pour chercher une solution, toutes, les meilleures, leur intersection ou leur union. • La résolution des problèmes combinatoires est le cœur de cible d’ASP. En particulier c’est un candidat de choix pour attaquer des problèmes NP-complets et NP-difficiles (graphes, raisonnement,…) du fait de la facilité de mettre au point et tester différents modèles et différentes heuristiques .
ASP ne doit pas être utilisé pour… • remplacer des algorithmes classiques maîtrisés : pour faire du tri, du calcul ou du traitement de séquences, il faut revenir à un langage de programmation classique. Le langage de script Lua est inclus dans gringo pour les pré et post-traitements; • travailler dans des espaces peu structurés et peu contraints ou des espaces difficiles à discrétiser. • résoudre un problème qui nécessiterait de nombreuses étapes successives qui communiquent : un programme ASP ne permet pas d’écrire des procédures.
Et la sémantique ? Programmes positifs • Un programme positif est constitué d’un ensemble de règles (clauses définies) A:-B1,B2,…Bmou A (la tête de la règle) et les B (le corps) sont des atomes (variables booléennes).A:-B1,B2,…Bmcorrespond à la formule B1 B2 … Bm A • Un ensemble d’atomes X est clos pour un programme positif si pour l’ensemble de ses règles r, corps(r)X tête(r)X(C’est un modèle du programme vu comme une formule). • L’ensemble réponse (answer set) d’un programme positif P est le plus petit ensemble d’atomes qui soit clos pour P. Il existe et est unique.
Et la sémantique ? Programmes avec not • Un programme est constitué de manière plus générale d’un ensemble de règles A:-B1,B2,…Bm, not Bm+1, not Bm+2,… not Bm+n • Le réduit d’un programme par rapport à un ensemble d’atomes X est l’ensemble des règles A:-B1,B2,…Bmtelles qu’aucun des Bm+1, Bm+2,… Bm+nn’appartient à X. • Un ensemble réponse (on dit aussi modèle stable) d’un programme P est un plus petit ensemble d’atomes clos pour le réduit de P (il peut y en avoir 0, 1 ou plusieurs).Autrement dit, on ne met dans un modèle l’atome d’une tête de règle que si la règle est un fait (règle réduite à une tête) après en avoir enlevé les littéraux négatifs qui ne sont pas dans le modèle ou si tous les littéraux positifs du corps sont dans le modèle et aucun des littéraux négatifs.
Où l’on teste si la sémantique de base est comprise… • p:- p. q:- not p.interprétations possibles : {p,q}, {p}, {q}, (stable si en réduisant le programme avec et par clôture, on retombe sur le même ensemble…) • p:- not q. q:- not p.interprétations possibles : {p,q}, {p}, {q}, Autre écriture 1{p,q}1. • p:- not p.interprétations possibles : {p},
Sémantique : solutions… • p:- p. q:- not p.{p,q} : dans ce cas, le programme réduit est p:- p. dont l’ensemble clos minimal associé est , pas de stabilité{p} : dans ce cas, le programme réduit est p:- p. dont l’ensemble clos minimal associé est, pas de stabilité{q}: dans ce cas, le programme réduit est p:- p. q. dont l’ensemble clos minimal associé est{q}. OK : dans ce cas, le programme réduit est p:- p. q. dont l’ensemble clos minimal associé est {q},pas de stabilité • p:- not q. q:- not p.ensembles réponses : {p}, {q} • p:- not p.pas d’ensemble réponse Un ensemble réponse contient des atomes du programme. Tout élément d’un ensemble réponse est supporté par une règle
Et les variables ? • C’est le rôle de l’instancieur (grounder), qui agit comme une base de données déductive, de les traiter. • Etant donné un programme P, on peut distinguer • L’ensemble des termes sans variables H (univers de Herbrand); • Pour une règle r l’ensemble des variables de r var(r). • On définit le programme instancié ground(P) en remplaçant toutes les règles r par des règles instanciées ground(r) où les variables sont remplacées par des termes de H: ground(r) = { rq | q : var(r) H} • gringo est un instancieur intelligent réduisant au mieux le nombre d’instances produites. C’est en fait un véritable solveur qui s’occupe des aspects purement déterministes du calcul. Au total, un ensemble réponse est un ensemble minimal sur le réduit du programme instancié
Exemple de grounding… • p(X,Y) :- q(X,Y). q(a,b). q(b,c). • {a, b, c} • { p(a,a):-q(a,a), p(a,b):-q(a,b), p(a,c):-q(a,c), p(b,a):-q(b,a), p(b,b):-q(b,b), p(b,c):-q(b,c),p(c,a):-q(c,a), p(c,b):-q(c,b), p(c,c):-q(c,c), q(a,b), q(b,c) } • { p(a,b), p(b,c), q(a,b), q(b,c) }
Extension à d’autres constructeurs… {A1,A2,…Am} :- Bm+1,Bm+2,…Bn, notBn+1, not Bn+2,… not Bp • Intuitivement : tout sous ensemble de {A1,A2,…Am} peut être inclus dans l’ensemble réponse lors de la clôture. • Règle équivalente au programme suivant :B:- Bm+1,Bm+2,…Bn, not Bn+1, not Bn+2,… not Bp.A1:- B, not C1. C1:- B, not A1. A2:- B, not C2. C2:- B, not A2. …Am:- B, not Cm. Cm:- B, not Am. • Ensembles réponses de : p. {q}:-p. ?
Et pour les contraintes d’intégrité et les contraintes de cardinalité? • :- Bm+1,Bm+2,…Bn, not Bn+1, not Bn+2,… not Bp. équivaut à new :- Bm+1,Bm+2,…Bn, not Bn+1, not Bn+2,… not Bp, not new. • p :- k{A1,A2,…Am}l équivaut à p :- q, not r.q :- cc(A1, k). r :- cc(A1, l+1). cc(A1,I+1):- cc(A2,I), A1. cc(A1,I):- cc(A2,I), A1.
Toutes les logiques se valent-elles ? • En logique classique, si on fait croître une théorie, on ne peut qu’en déduire plus de faits : {p, p q, (q r) s} permet de conclure {p, p q, (q r) s, q } Ajouter r à la théorie permet de conclure {p, p q, (q r) s, q, r } • La réalité de la science exprime des besoins un peu différents : lorsqu’on dispose de plus de faits, une théorie peut être remise en question partiellement pour aboutir à un ensemble de conclusions réduite… • ASP utilise une logique non monotone: {p, p q, (q r) s} permet de conclure {p, p q, (q r) s, q, s } Ajouter r à la théorie permet de conclure {p, p q, (q r) s, q, r }
Méthodologie de programmation de base • Prétraitement des données par un script Lua pour produire les faits de l’instance du problème traité; • Définition des domaines des variables; • Génération des choix d’ensembles réponse possible pour la classe de problèmes; • Test et filtrage des ensembles admissibles par contraintes d’intégrité; Réduction des solutions symétriques; • Optimisation hiérarchisée selon différents critères.
L’art de la modélisation : Warning ! • On peut sans problème générer un programme instancié avec quelques millions de variables. Cependant, cette limite est facilement atteinte par produits cartésiens : il faut limiter au maximum le nombre de variables différentes dans une clause. • Il y a un compromis à équilibrer entre les parties résolues par gringo et par clasp. • Gringo dépense de la mémoire, il précalcule (tabule) tout ce qui peut être instancié à l’avance de manière déterministe. • Clasp dépense du CPU, il effectue les choix et élague dynamiquement l’espace de recherche • Le solveur va être d’autant plus efficace qu’il pourra apprendre des nouvelles contraintes en cours de résolution : avoir un programme croisant des contraintes génériques mais redondantes peut être intéressant.
De la complexité… • On n’échappe pas à la complexité, on peut juste tirer parti des particularités d’une instance de problème à résoudre : paramétrer l’espace de recherche de façon à faire dépendre la complexité d’un paramètre qui garde des valeurs raisonnable (penser à iclingo). • ASP permet d’exprimer facilement des propriétés mathématiques sur un espace de recherche : plus vous aurez de propriétés, mieux ça marchera ! • Il reste actuellement difficile de tracer un programme ASP pour savoir où se cache la partie complexe. Le découpage très modulaire en clauses indépendantes facilite cependant la mise aux points : procéder par étapes ! Il existe un prototype de profileur de l’exécution d’un programme mais qui n’est pas encore public.
Exemple de la recherche de circuit hamiltonien minimum • Etant donné un graphe pondéré non orienté décrit par des faits trouver un circuit hamiltonien minimum sur ce graphe, c’est-à-dire un chemin en boucle qui passe une et une seule fois par tous les nœuds et minimise la somme des poids des arcs qu’il emprunte. • Application à un circuit sur une carte routière de la France : france.lp. edge(Sommet1, Sommet2, Poids).
Programme du circuit hamiltonien Définir les domaines edge(X,Y,C):- edge(Y,X,C). edge(X,Y):- edge(X,Y,_). node(X;Y):- edge(X,Y). min_node(X):- node(X), not node(Y): node(Y):Y<X. 1{cycle(X,Y):edge(X,Y)}1:-node(X). 1{cycle(X,Y):edge(X,Y)}1:-node(Y). reached(Y):- cycle(X,Y), reached(X). reached(Y):- cycle(X,Y), min_node(X). :- node(X), not reached(X). :- cycle(X,Y), cycle(Z,X), min_node(X), Z<Y. #minimize[cycle(X,Y):edge(X,Y,C)=C]. #hide. #show cycle/2. Générer les cycles Tester l’accessibilité et filtrer sinon Traiter les symétries Optimiser
Un coup d’œil sur la façon dont ça marche • On utilise des techniques issues de la résolution de contraintes et de la résolution SAT. • La plupart des solveurs SAT utilisent des variantes de l'algorithme de Davis–Putnam–Logemann–Loveland (DPLL)DPLL consiste à appliquer la propagation unitaire sur les clauses, à éliminer les clauses pures et à choisir récursivement et avec backtrack la valeur de vérité d’une proposition. • Un littéral est pur s’il apparaît toujours avec le même signe. Les clauses pures sont celles contenant des littéraux purs. • L’inférence en ASP est un algorithme plus évolué qui consiste principalement à faire de la propagation unitaire sur des « nogoods » appris en cours de résolution de conflits et à faire du backjumping à la place du backtrack classique
La boucle de résolution avec DPLL • affectation=vrai; • Tant que affectation • Propagation des conséquences déterministe du jeu de clauses; • Si pas de conflit (clause vide détectée) • Alors si toutes les variables sont assignées • alors Sortir la solution; affectation=faux • sinon Choisir une variable et lui affecter une valeur de vérité • Sinon si le conflit implique les 2 alternatives possibles du 1er choix • alors Pas de solution; affectation=faux • sinon Backtrack : Défaire toutes les affectations faites depuis le dernier choix et essayer l’autre valeur de vérité pour ce choix
La boucle de résolution clasp dirigée par les conflits (CDCL) • affectation=vrai; • Tant que affectation • Propagation des conséquences déterministe du jeu de clauses; • Si pas de conflit (clause vide détectée) • Alors si toutes les variables sont assignées • alors Sortir la solution; affectation=faux • sinon Choisir une variable et lui affecter une valeur de vérité • Sinon si le conflit implique les 2 alternatives possibles du 1er choix • alors Pas de solution; affectation=faux • sinon • Analyser la source du conflit et ajouter une contrainte de conflit • Défaire toutes les affectations de variable jusqu’à contrainte unitaire
La suite potassco : utiliser ASP en pratique • Plusieurs solveurs existent en fait, il faut essayer... • Utilisation « tout en un » : clingo (gringo+clasp) • Solveur incrémental : iclingo (#base+ paramètre incrémentant d’un pas de résolution à l’autre #cumulative k +) • Solveur de contraintes sur entiers : clingcon • Il existe un petit manuel http://sourceforge.net/projects/potassco/files/potassco_guide/2010-10-04/ainsi que pas mal de slides de cours plus avancés sur le site potasscohttp://potassco.sourceforge.net/teaching.html • Il existe également en support une mailing-list, un forum de discussion et un wiki et même un groupe google+ !http://sourceforge.net/p/potassco/wiki/Home/ • https://plus.google.com/102537396696345299260/
Merci à Torsten Schaub et Martin Gebser dont je me suis beaucoup inspiré pour cette présentation. Answer Set Solving in Practice Martin Gebser, Roland Kaminski, Benjamin Kaufmann, and Torsten SchaubSynthesis Lectures on Artificial Intelligence and Machine Learning, Dec. 2012, Vol. 6, No. 3 , Pages 1-238 (doi: 10.2200/S00457ED1V01Y201211AIM019)
Paradigme de la programmation logique • Langage : logique du premier ordre, clauses de Horn • Une seule structure de données : le terme • Algorithme = Logique + Contrôle [Kowalski] • Réécriture des requêtes par résolution SLD avec les clauses, en effectuant les points de choix dans un ordre fixé « haut-bas gauche-droite ». • Solution = instanciation des variables de la requête. • Enumération des solutions par retour arrière (backtracking) sur les points de choix.
Connaissance nécessaire du solveur en Prolog : exemple des dominos • domino(X,Y):- member(X,[0,1,2,3,4,5,6]), member(Y,[0,1,2,3,4,5,6]). :- domino(A,B).Yes. A=1, B=1; … • domino_chain ([X,Y]) :- domino(X,Y). domino_chain ([X,Y|L]):- domino(X,Y), domino_chain([Y|L]). versus • domino_chain([X,Y|L]):- domino_chain([Y|L]), domino(X,Y).domino_chain([X,Y]):- domino(X,Y). Enumération de l’ensemble des solutions ou boucle infinie de résolutions sans solution !
Propagation unitaire sur nogood • La propagation unitaire est un mécanisme de simplification de clauses utilisant les clauses réduites à 1 seul littéral. • Etant donné un ensembles de clauses comprenant une clause unitaire réduite au littéral p, on peut enlever de l’ensemble toutes les autres clauses qui contiennent p et enlever le littéral opposé ~p des clauses restantes. • {p, p q, not p r , not r s} se réduit ainsi à {p, r , not r s} qui se réduit lui-même en {p, r, s}. • Un nogood est un assignement de valeurs de vérité à un ensemble d’atomes qui suffit à provoquer la violation d’une contrainte du programme.