• Aucun résultat trouvé

V.2 Comparaison des arbres de types

V.2.1 Génération des empreintes de type

Les étapes nécessaires à la génération de l’empreinte d’un type d’élément sont :

1. la mise sous forme canonique des graphes de types. Cette opération consiste à redéfinir un type sous une forme qui ne fait pas usage d’iden-tificateurs déjà utilisés, de manière à ce que chaque type soit identifié de manière unique par son identificateur ;

2. les arbres canoniques sont ensuite ordonnés car l’algorithme de compa-raison travaille sur des arbres ordonnées (cf. section V.2.2) ;

3. enfin, la linéarisation des arbres ordonnés permet de produire des chaînes de caractères représentant leur structure. Durant cette étape, on fait abstraction des noms des types d’éléments, seuls sont conservés : • les constructeurs ;

• l’ordre entre les nœuds frères ; • les types des feuilles.

V.2.1.1 Mise sous forme canonique

Le type d’élément tel qu’il est défini dans la DTD est d’abord mis sous forme canonique. La mise sous forme canonique d’un type se fonde sur la représenta-tion sous forme de graphe de type et produit un arbre de types canonique.

Les opérations nécessaires à la mise sous forme canonique d’un graphe de types sont :

• L’élimination des types identité.

• La définition d’arbres finis : le graphe de types est transformé en graphe connexes sans cycles. Pour cela, les règles récursives sont traitées sé-parément (voir section V.4.4). Le graphe de types est exploré et chaque branche est répliquée si elle a déjà été parcourue précédemment. • La représentation systématique des éléments optionnels de la DTD. Ces

derniers seront éventuellement ignorés par la relation de massif. Par contre, les éléments exclus ne sont pas représentés dans la branche d’arbre concernée par l’exclusion.

Les nœuds non terminaux des arbres canoniques sont étiquetés par les constructeurs choix, liste et agrégat. Les feuilles de ces arbres sont étiquetées par les types de base.

V.2.1.2 Ordre pour les arbres de types

L’algorithme de recherche de massifs nécessite la définition d’un ordre sur les arbres de types sans quoi le problème de la détermination de l’existence d’une relation de massif entre deux types est indécidable [Kilpeläinen 92].

Plusieurs ordres peuvent être proposés pour prendre en compte : • les constructeurs des fils de la racine du sous−arbre de types, • la profondeur du sous−arbre de type,

• le nombre de types compris dans le sous−arbre. La relation d’ordre sur les constructeurs est notée <c.

Le choix de la relation d’ordre associée à l’arbre de types est déterminant pour la pertinence des relations de massif trouvées par l’algorithme de compa-raison d’empreintes (voir section V.6). Pour présenter l’algorithme, nous choi-sissons la relation d’ordre suivante sur les types canoniques d’une structure générique S :

1. si t ∈ BS (type de base) et t’∈ CS (type construit) alors t < t’. 2. si t et t’ ∈ CS avec t = c (t1,..., tm) et t’ = c’(t’1,...,t’n ) alors t < t’ si et seulement si : c <c c’ ou c = c’, m < n et ∀ i ∈ [1,.., m], ti = t’i. ou

c = c’, ∃i ∈ [1,.., min (m, n)] tel que ∀j ∈ [1,.., i−1], tj = t’j et ti < t’i. Cette définition implique le choix d’un ordre sur les types de base et sur les constructeurs. Pour les types de base, nous choisissons arbitrairement : T (texte) < G (graphique) < S (symbole) < P (image)

l’ordre des feuilles n’ayant pas de conséquence pour la comparaison (c.f. fi-gure 38). Les constructeurs sont ordonnés selon deux critères :

• le critère principal est l’arité des types qu’ils sont susceptibles d’en-gendrer : les types de constructeur liste ont une cardinalité égale à un, les types de constructeur choix et agrégat ont une arité supérieure à un. liste <c choix, agrégat.

• un critère secondaire est l’arité des instances des éléments des types concernés : les éléments dont le constructeur de type est le choix ont un unique fils, tandis que les éléments dont le constructeur de type est agrégat ont plusieurs fils.

choix <c agrégat.

Cet ordre a pour but de comparer prioritairement les sous−arbres comprenant le plus petit nombre de nœuds, ceci pour trouver les relations de massifs les plus « compactes » possible.

V.2.1.3 Linéarisation des arbres de types canoniques

Une empreinte de type est ensuite construite à partir de l’arbre de types produit par la canonisation (voir section IV.2.3). Une empreinte d’un type est une chaîne de caractères contenant des parenthèses pour représenter les constructeurs de type (différentes sortes de parenthèses sont utilisées pour représenter les différents constructeurs) et des lettres pour représenter les types de base. Le parenthésage des empreintes reflète la structure générique du

[

( {

T G S P

R a, b, c... @

type. La figure 39 représente la DTD définissant le type exercice, l’arbre de type canonique correspondant et l’empreinte du type.

Dans les empreintes (figure 38), le constructeur choix est représenté par des crochets, le constructeur liste par des parenthèses, le constructeur agrégat par des accolades. Les types de base sont identifiés par les lettres T pour le type texte, G pour le type graphique, S pour le type symbole mathématique, P pour le type image et R pour le type référence. Les autres types de base sont repré-sentés par des lettres minuscules pour les types définis comme vides et par le caractère @ pour les pseudo−types de base récurrence.

Constructeur Liste Choix Agrégat Caractère

Type de base texte graphique symbole image Caractère

Type de base référence autres récurrence Caractère

Figure 38 : Correspondance entre types et caractères des empreintes Un alphabet des constructeurs et des types de base est ainsi établi : S = {’{’, ’[’, ’(’, ’T’, ’G’, ’S’, ’P’,’a’,...,’z’}, L’ensemble S des inverses est {’}’, ’]’, ’)’, ’T’, ’G’, ’S’, ’P’,’a’,..., ’z’}. Les applications associant un nœud de l’arbre de types au caractère représentant son constructeur dans S sont notées e pour les types construits et b pour les types base.

Dans les empreintes, nous confondons les caractères représentant les types de base et leur inverses. En effet, les types de base étant des feuilles des arbres de types, l’opération de réduction effectuée par les transitions M1 et M1’ de l’automate présenté dans la section V.2.2 est unifiée pour être réalisée par la transition Mt.

DTD :

<!ELEMENT exercice (titre, énoncé, solution) > <!ELEMENT énoncé (p | question)+ > <!ELEMENT solution (pa)+ > <!ELEMENT titre (#PCDATA) > <!ELEMENT p (#PCDATA) > <!ELEMENT question (#PCDATA) > <!ELEMENT pa (#PCDATA | réponse) > <!ELEMENT réponse (#PCDATA) > <!ATTRLIST question ident ID #REQUIRED > <!ATTRLIST réponse ident ID #REQUIRED > <!ATTRLIST exercice niveau CDATA "1" >

Arbre de types : {exercice} titre T (énoncé) [énoncé#1] p T question T (solution) [pa] T réponse T Empreinte : {T([TT])([TT])}

Figure 39 : DTD, arbre de types et empreinte du type exercice

La définition donnée des empreintes de types est proche de celle des mots de Dyck. La différence réside dans la représentation des nœuds terminaux par un caractère unique.

Définition

L’empreinte générique d’une forêt d’arbres de types est un mot défini par les règles suivantes :

1. w = b(x) si x ∈ BS

2. w = e(x) w’ e(x) w’’ si x ∈ CS et w’ et w’’ sont les empreintes respec-tives des enfants et des successeurs de x.

Comme pour les mots de Dyck, une bijection φ est définie entre les arbres canoniques et les empreintes. Remarquons que :

• À tout arbre canonique A du système de types des documents structurés, on associe un mot unique Φ(A) ∈ D(S) définie par : Φ(A) = Φ0(r(A))

où r(A) est la racine de l’arbre A et Φ0 l’application de A dans D(S), elle−même définie récursivement par :

Φ0(x) = e(x)

y∈Fils(x)Φ0(y) e(x) (si x est une feuille : Φ0(x) = b(x)).

• L’application Φ est une bijection de A°, l’ensemble des arbres cano-niques de types sur l’ensemble D(S).

• À tout nœud x d’un arbre canonique A on peut associer un unique couple d’entiers (i, j) indices respectifs dans Φ(A) de e(x) et e(x) (pour les nœuds terminaux, on associe le couple (i, i) où i est l’indice de b(x)). Ces indices sont ceux permettant la construction de Φ−1. On notera i = ϕA(x) et j = ϕA(x) (et lorsqu’il n’y a pas ambiguïté i = ϕ(x) et j = ϕ(x). Ces deux applications sont injectives.

• L’application α = ϕ o ϕ−1 qui pour un nœud x associe l’indice de e(x) à celui de e(x) dans Φ(A) est bijective. α associe le caractère « paren-thèse ouvrante » associé à un nœud avec le caractère « parenparen-thèse fer-mante » associé au même nœud.

Un tableau de références vers les nœuds de l’arbre canonique de types est construit simultanément à l’empreinte. Ce tableau est utilisé lors de la généra-tion des éléments transformés pour lier un indice de l’empreinte au type cano-nique qu’il représente. Il implémente Φ0−1 (voir section V.3).

V.2.2 Comparaison des empreintes