• Aucun résultat trouvé

5.3 Une approche par apprentissage pour l’instanciation

5.3.2 Concevoir les features

La caractérisation, par l’usage de vecteur de features, du problème de l’instanciation vers l’algorithme d’apprentissage nécessite un travail préliminaire de modélisation. De précédents travaux [69] ont eu pour objet l’étude des différents types de features, dans le contexte de la preuve automatique, qui ont notamment été utilisées en combinaison avec des approches d’ap-prentissage basées sur des arbres de décision [94]. Bien qu’efficaces, ces approches ne peuvent pas être directement utilisées pour les solveurs SMT, car elles sont principalement développées pour des architectures de solveurs basées sur des systèmes de saturations, tels que les calculs de tableaux ou encore de superposition. L’architecture des solveurs SMT étant assez éloignée de

5.3. Une approche par apprentissage pour l’instanciation

ces solveurs, il est nécessaire de repenser la modélisation du problème, tout en s’inspirant des précédentes études. Et pour cause, les features développées dans ce travail sont plus particuliè-rement inspirées de celles utilisées dans ENIGMA [67] et RLCoP [68]. Cette section présente l’encodage des termes, des formules, et des instances satisfaisables du problème original dans un espace vectoriel des features, à traiter par le classifieur.

Un solveur SMT manipule des termes de la logique du premier ordre, qui de manière in-terne sont représentés sous forme de graphes acycliques orientés, aussi appelés DAG (directed acyclic graphs). Cette représentation à l’avantage d’optimiser la représentation en mémoire des problèmes. Via cette représentation, certains termes peuvent partager le même espace mémoire, notamment lorsque certains sous-termes sont dupliqués : c’est en quelque sorte une représentation compressée des arbres de syntaxe abstraite. Le problème d’instanciation se compose naturelle-ment de termes de la logique du première ordre. Ainsi, pour nourrir l’algorithme d’apprentissage des informations provenant du solveur SMT il est nécessaire de déterminer une représentation permettant d’exprimer les termes dans un formalisme adapté à l’algorithme. Malheureusement cette étape n’est pas sans obstacle. Le choix de la méthode d’apprentissage, comme évoqué pré-cédemment, est conditionné par plusieurs contraintes provenant du solveur SMT, et même si l’approche par arbre de décision semble parfaitement répondre aux exigences énoncées plus haut, il y a une difficulté non négligeable qui est la représentation des termes au renommage près sous forme vectorielle. La difficulté peut en effet être contournée lorsque l’encodage permet l’usage de vecteurs réels, comme par exemple avec des systèmes de réseaux de neurones. Dans notre cas les termes doivent pouvoir être représentés de façon plus ou moins uniformes sous forme de vecteurs d’entiers. La contrainte s’exerce donc principalement au niveau des symboles des termes manipulés. Par conséquent, notre représentation ne permet pas à l’algorithme d’apprentissage de déterminer l’équivalence de deux termes au renommage prés. C’est assez dommage car cela prive l’algorithme d’informations utiles, mais c’est une limitation qui est intrinsèquement dépendante de la méthode d’apprentissage choisie.

Malgré cette contrainte importante au niveau des symboles il est possible d’utiliser des mé-thodes d’apprentissage via des modélisations basées sur l’encodage syntaxique des termes, lorsque les benchmarks de problèmes utilisent un domaine de symboles cohérents. C’est-à-dire que la fa-mille de problèmes utilise un domaine de symboles commun, et qu’il n’y a pas (ou très peu de fois) plusieurs définitions du même symbole dans une famille de problèmes. Ce qui est a priori le cas des bibliothèques de preuves, des assistants de preuve comme Isabelle, ou encore Mizar, une fois traduites dans la syntaxe de la SMT-LIB, ou TPTP. Ce sont d’ailleurs les approches utilisées dans le prototype ENIGMA.

L’idée de notre encodage est d’extraire de chaque terme un ensemble de séquences de sym-boles. Ces séquences de symboles sont obtenues au moyen du parcours en profondeur de chaque terme (on retient les symboles de tous les nœuds visités). Par la suite il est possible de trier ces séquences par longueur. Et c’est en pratique avec des séquences de longueurs un, deux et trois que nous obtenons les meilleurs résultats lors de nos évaluations. Techniquement la combinaison de ces séquences, de trois longueurs différentes, représentent le meilleur compromis en termes

Chapitre 5. Améliorer l’instanciation via des méthodes d’apprentissage

de représentation mémoire, de recouvrement des termes, et de modélisation pour l’algorithme d’apprentissage. C’est un résultat qui d’ailleurs corrobore les travaux de Jakubův et Urban [67], qui utilisent uniquement des séquences de longueur trois.

Les symboles de variables et de Skolem sont souvent sujet à de multiples renommages, et sans notion de portée, ces éléments sont peu informatifs sur la structure des termes. Pour ces raisons, l’encodage obfusque les variables par l’usage d’un symbole particulier ~. De la même façon, les constantes de Skolem sont remplacées par le symbole .

Chacune de ces séquences représentent donc une feature, et le nombre d’occurrences d’une séquence représente la valeur associée à la feature. Une séquence apparaissant plus qu’une autre sera donc considérée comme plus importante ou au contraire comme moins importante par l’al-gorithme en fonction des différentes observations auxquelles elle sera soumise. Par conséquent, le classifieur utilisera le nombre d’occurrences de chaque feature, plus quelques features supplémen-taires, pour classer une instance comme utile ou non. Par exemple, l’encodage du terme f(a, b) se traduit par l’ensemble de features{f, a, b, (f, a), (f, b)}, et par exemple, la valeur de l’élément (f, a) est 1. Les exemples ci-dessous présentent, concrètement, l’encodage pour des termes de la logique du premier ordre.

@ t x sk c @ t ~ c

Figure 5.1 – Représentation arborescente du littéral (xt sk) @ c

Exemple 5.3.1. La figure 5.1 montre la représentation arborescente du terme (xt sk) @ c où x est une variable et sk est un symbole de Skolem. L’arbre de gauche est le terme original et celui de droite est l’arbre traité, après avoir remplacé les variables et symboles de Skolem par leurs symboles respectifs.

Le tableau suivant présente les features extraites de ce terme avec leurs valeurs. La ligne k donne la longueur de chaque séquence de symbole. La valeur est le nombre de fois que la séquence de symboles apparaît dans toutes les séquences de longueur au maximum 3.

k 1 valeur 2 valeur 3 valeur

@ 1 (@,t) 1 (@,t, ~) 1 features t 1 (@, c) 1 (@,t, ) 1 1 (t, ~) 1 ~ 1 (t, ) 1 c 1 •

5.3. Une approche par apprentissage pour l’instanciation g f x f y g f ~ f ~ Figure 5.2 – Représentation arborescente du littéral g (f x) (f y)

Exemple 5.3.2. La figure 5.2 et le tableau suivant montrent un autre exemple de représentation arborescente et de valeurs de features.

k 1 valeur 2 valeur 3 valeur

f 2 (g, f) 2 (g, f, ~) 2

features g 1 (f, ~) 2

~ 2

• Pour transformer chaque séquence de symboles, features, en une valeur entière, nous utilisons la fonction de hachage djb2 (voir la figure 5.3), naïve mais suffisante, qui permet d’associer à chaque symbole un entier naturel.

1 I n t 6 4 hash (char * str )

2 {

3 I n t 6 4 hash = 5 3 8 1 ;

4 w h i l e (* str )

5 hash = (( hash << 5) + hash ) + *( str ++) ;

6 r e t u r n hash ;

7 }

Figure 5.3 – Fonction de hachage.

La dimension des vecteurs de features est fixe, en pratique l’expérience a montrer, que des vecteurs de dimension 2310705, soit 2 MB, est un bon compromis. Cette taille permet de stocker suffisamment de features pour les problèmes rencontrés dans nos expérimentations, ce paramètre peut-être réévaluer pour des problèmes différents. La transformation des séquences de symboles en features est calculée par la formule récursive suivante :

un+1 = (unmod 2310705)∗ kn+1+ s.

où unest une séquence de longueur n, avec n compris entre 0 et 2, k est un nombre grand premier, et s la valeur de hachage du symbole n de la séquence. Concrètement, lorsqu’une séquence est de longueur 1, de type (f0), la feature calculée correspond à la valeur de hachage du symbole modulo la dimension. Pour une séquence de longueur 2, de type (f0, f1) on calcule la feature comme suit :

Chapitre 5. Améliorer l’instanciation via des méthodes d’apprentissage

u1 = (hash(f0)mod2310705)∗k + hash(f1)). Et le calcul d’une séquence de symboles de longueur 3, de type (f0, f1, f2), est : ((u1mod 2310705)∗ k2+ hash(f2)). Une fois le calcul terminé chaque feature est ramenée dans l’espace de dimension des vecteurs, par l’application de l’opérateur modulo.

En pratique, l’espace de features est segmenté de sorte que les features provenant, par exemple de E, des instances, ou des paramètres génériques (taille, profondeurs des termes) soient distin-guées entre elles. Pour cela on utilise un simple décalage lors du calcul des features. Par exemple si la séquence u1 est extraite de l’ensemble d’égalités E, nous ajoutons un décalage fixe, d1, mul-tiplié par un certain intervalle : u1+ d1∗ 262139 (ce paramètre a été déterminer par l’expérience pour les problèmes SMT, il peut être réévalué pour d’autres benchmarks). Si au contraire la séquence provient d’une instance, alors la valeur de décalage sera différente. Cette astuce permet donc de partitionner chaque vecteur de façon à ce que l’algorithme puisse identifier la prove-nance des informations. Dans la section suivante nous étudions plus en détail la modélisation du problème de l’instanciation dans SMT.