Ndiff un approccio naturale al confronto di documenti XML

101
Universit ` a degli Studi di Bologna Facolt` a di Scienze Matematiche Fisiche e Naturali Corso di Laurea Specialistica in Informatica Ndiff un approccio naturale al confronto di documenti XML Tesi di Laurea di: Relatore: Chiar.mo Prof. MICHELE SCHIRINZI FABIO VITALI Correlatore: Dott. ANGELO DI IORIO Parole chiave: Diff, Change-Tracking, Ricerca dei cambiamenti, XML 21 Marzo 2007 III Sessione Anno Accademico 2005–2006

Transcript of Ndiff un approccio naturale al confronto di documenti XML

Universita degli Studi di BolognaFacolta di Scienze Matematiche Fisiche e Naturali

Corso di Laurea Specialistica in

Informatica

Ndiffun approccio naturale

al confronto di documenti XML

Tesi di Laurea di: Relatore: Chiar.mo Prof.

MICHELE SCHIRINZI FABIO VITALI

Correlatore: Dott.

ANGELO DI IORIO

Parole chiave: Diff, Change-Tracking, Ricerca dei cambiamenti, XML

21 Marzo 2007

III SessioneAnno Accademico 2005–2006

Indice

Introduzione 1

1 Algoritmi di diff tra documenti XML 71.1 Introduzione . . . . . . . . . . . . . . . . . . . . . . . . . . . . 71.2 Analogie tra Diff e LCS . . . . . . . . . . . . . . . . . . . . . . 91.3 Algoritmi esistenti . . . . . . . . . . . . . . . . . . . . . . . . 14

1.3.1 XyDiff . . . . . . . . . . . . . . . . . . . . . . . . . . . 141.3.2 DeltaXML . . . . . . . . . . . . . . . . . . . . . . . . . 151.3.3 MMDiff e XMDiff . . . . . . . . . . . . . . . . . . . . . 151.3.4 XMLdiff . . . . . . . . . . . . . . . . . . . . . . . . . . 161.3.5 GNUdiff . . . . . . . . . . . . . . . . . . . . . . . . . . 16

1.4 Conclusioni . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18

2 Approccio naturale al diff 192.1 Percezione del confronto . . . . . . . . . . . . . . . . . . . . . 192.2 Diff e soluzioni possibili . . . . . . . . . . . . . . . . . . . . . 202.3 Metrica della naturalezza . . . . . . . . . . . . . . . . . . . . . 242.4 Confronto dei risultati . . . . . . . . . . . . . . . . . . . . . . 25

3 Ndiff 273.1 Intuizione . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 273.2 L’algoritmo . . . . . . . . . . . . . . . . . . . . . . . . . . . . 313.3 Parsing dei documenti XML . . . . . . . . . . . . . . . . . . . 34

3.3.1 Visita top-down . . . . . . . . . . . . . . . . . . . . . . 353.3.2 Visita bottom-up . . . . . . . . . . . . . . . . . . . . . 37

3.4 Partizionamento . . . . . . . . . . . . . . . . . . . . . . . . . . 393.5 Ricerca aggiornamenti . . . . . . . . . . . . . . . . . . . . . . 483.6 Ricerca spostamenti . . . . . . . . . . . . . . . . . . . . . . . . 503.7 Ricerca spostamenti-aggiornamenti . . . . . . . . . . . . . . . 513.8 Propagazione bottom-up . . . . . . . . . . . . . . . . . . . . . 523.9 Rappresentazione del risultato . . . . . . . . . . . . . . . . . . 55

i

INDICE

4 Napply:Motore di ricostruzione 594.1 Sintassi del delta . . . . . . . . . . . . . . . . . . . . . . . . . 594.2 Applicazione del delta . . . . . . . . . . . . . . . . . . . . . . 64

4.2.1 Inserimento di un nodo . . . . . . . . . . . . . . . . . . 654.2.2 Inserimento di un albero . . . . . . . . . . . . . . . . . 684.2.3 Cancellazione di un nodo . . . . . . . . . . . . . . . . . 694.2.4 Cancellazione di un albero . . . . . . . . . . . . . . . . 694.2.5 Aggiornamento di un nodo . . . . . . . . . . . . . . . . 70

4.3 Trasformazione da Vn a Vn+1 . . . . . . . . . . . . . . . . . . . 70

5 Nmerge:Motore di markup dei cambiamenti 735.1 Markup delle differenze . . . . . . . . . . . . . . . . . . . . . . 735.2 Inserimento del markup relativo alle differenze . . . . . . . . . 76

5.2.1 Inserimento di un nodo . . . . . . . . . . . . . . . . . . 775.2.2 Inserimento di un albero . . . . . . . . . . . . . . . . . 795.2.3 Cancellazione di un nodo . . . . . . . . . . . . . . . . . 805.2.4 Cancellazione di un albero . . . . . . . . . . . . . . . . 815.2.5 Aggiornamento di un nodo . . . . . . . . . . . . . . . . 81

6 Un’applicazione di Ndiff: LIBRA 856.1 Contesto . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 856.2 LIBRA . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 89

7 Conclusioni 917.1 Espansione future . . . . . . . . . . . . . . . . . . . . . . . . . 91

Bibliografia e riferimenti 93

ii

Elenco delle figure

1.1 Esempio di matrice per il calcolo della LCS tra due sequenze . 12

1.2 Tabella riassuntiva degli algoritmi esaminati . . . . . . . . . . 18

2.1 Ambiguita nel confronto . . . . . . . . . . . . . . . . . . . . . 21

2.2 Valutazione di parti aggiornate . . . . . . . . . . . . . . . . . 22

2.3 Valutazione di parti spostate . . . . . . . . . . . . . . . . . . . 23

2.4 Confronto tra Ndiff e altri algoritmi . . . . . . . . . . . . . . . 26

2.5 Confronto tra Ndiff e altri algoritmi sulla media della dimen-sione dei delta rilevati . . . . . . . . . . . . . . . . . . . . . . 26

3.1 Modo di procedere di Ndiff . . . . . . . . . . . . . . . . . . . . 28

3.2 Relazione di associazione tra i nodi dei documenti confrontati 30

3.3 Schema del calcolo del diff tra due documenti . . . . . . . . . 33

3.4 Vettore dei puntatori calcolato con una previsita sinistra suun semplice documento . . . . . . . . . . . . . . . . . . . . . . 36

3.5 Esempio di calcolo dei valori HashTree . . . . . . . . . . . . . 38

3.6 Esempio di calcolo della LCCS. . . . . . . . . . . . . . . . . . 41

3.7 Schema di chiamata della funzione findLCCS . . . . . . . . . . 43

3.8 Schema di calcolo della MSC in modo ingenuo . . . . . . . . . 44

3.9 Schema di calcolo della MSC in modo efficiente . . . . . . . . 46

3.10 Grafico delle aree di ricerca degli aggiornamenti. . . . . . . . . 49

3.11 Grafico tridimensionale della funzione che calcola la somiglian-za di nodi di testo. . . . . . . . . . . . . . . . . . . . . . . . . 50

3.12 Grafico delle aree di ricerca degli spostamenti . . . . . . . . . 51

3.13 Diagramma di decisione durante la propagazione del matchingBottom-up. . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53

3.14 Schema di propagazione del matching bottom-up . . . . . . . 54

3.15 Interpretazione di < sugli alberi relativi ai documenti XMLconfrontati. . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55

4.1 Schema di applicazione del delta. . . . . . . . . . . . . . . . . 59

iii

4.2 Un’esecuzione di operazione insert di un nodo. . . . . . . . . . 664.3 Processo di adozione dei nodi . . . . . . . . . . . . . . . . . . 674.4 Esecuzione dell’operazione di inserimento di un albero. . . . . 684.5 Un’esecuzione di operazione delete di un nodo. . . . . . . . . . 694.6 Esecuzione di operazione di cancellazione di un albero. . . . . 704.7 Trasformazione del documento Vn in Vn+1 attraverso l’appli-

cazione del delta. . . . . . . . . . . . . . . . . . . . . . . . . . 71

5.1 Applicazione delle informazioni di markup alla versione Vn perottenere Vn→n+1 . . . . . . . . . . . . . . . . . . . . . . . . . . 76

5.2 Un’esecuzione di operazione insert di un nodo. I nuovi figlidel nodo inserito vengono marcati come downgraded . . . . . . 78

5.3 Un’esecuzione di operazione insert di un albero. . . . . . . . . 795.4 Un’esecuzione di operazione delete di un nodo. . . . . . . . . . 805.5 Un’esecuzione di operazione delete di un albero. . . . . . . . . 815.6 Aggiornamento di un nodo di testo. . . . . . . . . . . . . . . . 82

6.1 Esempio di testo a fronte. . . . . . . . . . . . . . . . . . . . . 886.2 Funzionamento di LIBRA . . . . . . . . . . . . . . . . . . . . 89

Introduzione

Il presente lavoro illustra un algoritmo per rilevare ed esprimere i cambia-

menti tra diverse versioni di uno stesso documento XML. Questi algoritmi

vengono chiamati di diff e trovano applicazione in tutti quei sistemi che

hanno la necessita di mantenere e tracciare lo sviluppo di un documento.

Infatti l’importanza di tracciare e mantenere la storia di un documento e

fondamentale nel momento in cui vogliamo capire come si e arrivati alla sua

versione definitiva. In [Vitali et al,95] e [Vitali,99] si mettono in evidenza

alcuni importanti vantaggi di questi sistemi:

• Revisione storica: L’evoluzione nel tempo e una caratteristica intrin-

seca di alcuni sistemi, per cui e strettamente necessario tenere traccia

delle versioni, basti pensare al diritto, in cui e necessario applicare le

leggi in base al loro contenuto nel momento in cui e avvenuto l’evento

(nonostante possono essere state modificate, soprattutto vista la len-

tezza delle procedure legali) o ai prodotti software di cui si pubblicano

diverse release, mentre si lavora a nuove versioni del software stesso.

In alcuni ambienti come l’ingegneria del software, d’altra parte, e ne-

cessaria un’analisi del processo produttivo per controllare la qualita e

la crescita del prodotto, per cui il versionamento diventa ulteriormente

necessario.

• Sicurezza e produzione esplorativa: La possibilita di ‘congelare’

e recuperare gli stadi intermedi del proprio lavoro, se da un lato per-

mette di sentirsi piu sicuri, dall’altro favorisce anche l’esplorazione e

1

INTRODUZIONE

gli esperimenti, data la possibilita di tornare indietro sui propri passi e

ripetere le prove in una direzione diversa.

• Collaborazione distribuita: se piu autori collaborano alla produ-

zione di un documento in un ambiente che supporta la gestione delle

versioni (per cui ogni autore crea una nuova versione dopo ogni sessio-

ne di editing), e possibile in qualunque momento evidenziare l’apporto

dato da ognuno e le differenze tra i diversi contributi. Inoltre un mec-

canismo di merging, ossia fusione tra le diverse versioni, permette di

convergere ad un unico risultato finale, che e appunto lo scopo ultimo

della produzione collaborativa.

• Collaborazione parallela e asincrona: se supportati da un sistema

di versionamento, tutti gli autori possono modificare un documento

indipendentemente e nello stesso momento, creando diverse varianti

che convergeranno nello stato finale. Poiche ogni sessione di editing

crea una versione indipendente, non c’e nessun rischio di sovrascrittura

e cancellazione del contributo di altri autori e non e necessario nessun

meccanismo di locking alle risorse.

• Pluralismo: chiunque puo creare la propria versione personale del do-

cumento, aggiungendo suggerimenti, modifiche, pareri contrari o nuovi

collegamenti, poiche la fase di editing non coinvolge la risorsa originale

ma ne crea una nuova e ben identificata.

• Forme emergenti di collaborazione[Maioli et al,94]: poiche ogni

utente puo creare la propria versione personale di un documento, egli

puo, in una seconda fase, far visionare la propria variante agli autori

ufficiali, che valuteranno la possibilita di accorpare tale versione alla

storia ufficiale del documento.

• Efficienza e scalabilita: Sono automaticamente risolti problemi di ef-

ficienza e di scalabilita nella produzione distribuita in termini di numero

2

INTRODUZIONE

e distribuzione degli autori, dei documenti e dei server interessati. In-

fatti non risultano piu necessarie strategie di locking, accesso controlla-

to alle risorse, replicazione di oggetti, sincronizzazione o serializzazione

delle operazioni.

Un sistema di questo tipo puo essere realizzato salvando interamente il docu-

mento in diversi istanti di tempo nell’arco del suo sviluppo: una versione sara

stabilita dall’attimo in cui l’utente decide di salvare il documento. Questo

modo di creare versionamento e molto semplice ma presenta notevoli svan-

taggi. Pensiamo alla stesura di un documento molto grande in cui le varie

versioni si discostano per poche frasi. Procedendo in questo modo abbiamo

un notevole spreco di memoria. Intuitivamente sarebbe molto meglio salva-

re solo i cambiamenti avvenuti tra versioni successive che ragionevolmente

avranno una dimensione minore della versione intera. Adottando quest’ul-

timo procedimento, abbiamo un documento iniziale(la prima stesura) e una

lista di documenti delta che descrivono i cambiamenti tra la versione n e la

versione n+1. I documenti delta conterranno solo i cambiamenti tra le ver-

sioni e forniranno un metodo semplice per esaminare e confrontare le varie

versioni.

Una buona gestione del versionamento dipende dal modo con cui andiamo a

rilevare le differenze tra versioni successive. Possiamo usare due approcci:

• Realizzare editor capaci di memorizzare le operazioni che l’utente com-

pie nel momento in cui scrive il documento;

• Realizzare algoritmi capaci di confrontare due versioni successive e

trovare i cambiamenti tra queste.

Procedendo nel secondo modo, andiamo a ‘supporre’ quali possano essere

state le operazioni compiute dall’utente nel passare da una versione alla suc-

cessiva. Intuitivamente la soluzione ad un problema di questo tipo non e

unica, infatti possiamo avere un’insieme di documenti delta, tutti corretti,

che sono possibili interpretazioni dei cambiamenti avvenuti. Diventa quindi

3

INTRODUZIONE

necessario definire delle metriche su cui valutare e quantificare la bonta del

risultato. La metrica piu usata si basa sul dare un peso alle diverse ope-

razioni rilevate e promuovere l’algoritmo che ottiene il risultato con il peso

minimo. Il nostro approccio invece considerera il risultato dal punto di vi-

sta della naturalezza, definibile come la capacita dell’algoritmo di rilevare le

modifiche seguendo una concezione di confronto propria della natura umana.

Vedremo che spesso il delta minimo(con peso minore) coincidera con quello

piu ‘naturale’.

Per completare la contestualizzazione del nostro lavoro definiamo la for-

ma in cui sono scritti i documenti da confrontare. L’algoritmo realizzato si

occupa di trovare le differenze tra documenti strutturati ed in particolare

documenti XML (eXtensible Markup Language).

XML e un linguaggio di markup descrittivo che permette di definire la strut-

tura che descrive un contesto informativo all’interno del contesto stesso, pre-

cisando l’articolazione di un documento attraverso l’uso di marcatori inseriti

al suo interno. XML viene utilizzato spesso nella rappresentazione di do-

cumenti testuali, anche di carattere letterario o genericamente umanistico,

diffondendosi quindi in un settore nel quale la rappresentazione digitale delle

informazioni costituisce in larga misura un elemento di novita. In secondo

luogo, la versatilita di XML nel generare definizioni di diverse tipologie di

documento, produce la convinzione diffusa che tale linguaggio possa costitui-

re una sorta di strumento ‘neutro’ con il quale rappresentare la conoscenza

contenuta nelle diverse fonti informative. Esso risulta essere abbastanza ge-

nerale da poter essere utilizzato nei piu disparati contesti: dalla definizione

della struttura di documenti allo scambio di informazioni tra sistemi diversi,

dalla rappresentazione di immagini alla definizione di formati di dati. Questo

aspetto ha contribuito a rendere il ricorso agli strumenti informatici sempre

piu omogeneo anche in contesti molto diversi tra loro.

4

INTRODUZIONE

Ndiff e un algoritmo capace di confrontare ed esprimere le differenze tra

due documenti XML, cercando di derivare un ‘delta naturale’. Dalla dif-

fusione di XML e dall’importanza dei sistemi di versionamento si evince il

numero di applicazioni che potrebbero usare algoritmi di questo tipo. Ndiff

non e il nostro primo lavoro in questo campo, in particolare Ndiff e il ri-

sultato derivato dalla nostra precedente esperienza nella realizzazione di un

algoritmo di diff [Schirinzi,04] all’interno del motore di versionamento nel

progetto IsaWiki[ISA]. Abbiamo migliorato il nostro precedente lavoro ren-

dendo modulare l’esecuzione dell’algoritmo, definendo il concetto di ‘fase’ e

rendendo queste indipendenti una dall’altra. Per ogni fase abbiamo esplici-

tato dei parametri che permettono di selezionare un particolare tipo di delta

dallo spazio delle soluzioni possibili, dove i parametri sono associabili a con-

cezioni intuitive di confronto, sulle quali basiamo il concetto di ‘naturalezza

del risultato’. Inoltre abbiamo inserito una nuova fase che permette l’indi-

viduazione di altri tipi di modifiche, migliorando la propagazione bottom-up

del matching(cap.3.8). La rappresentazione del delta e stata completamente

ristrutturata eliminando informazioni di markup superflue e ottimizzando l’e-

spressione dei cambiamenti a livello di aggiornamento di nodi testuali e nodi

elemento. Di conseguenza abbiamo modificato sia il motore di ricostruzione

dei documenti, chiamandolo Napply, che il motore di ‘applicazione con mar-

kup’, chiamandolo Nmerge. A livello implementativo, abbiamo aggiornato il

vecchio codice PHP adattandolo alla versione 5 di PHP(con supporto per le

nuove specifiche DOM) ed inserendo le classi relative alle nuove funzionalita

sviluppate.

La motivazione che ha portato a riprendere e migliorare il nostro lavoro e

stata la richiesta da parte del servizio informatico del Senato della Repubbli-

ca, di un algoritmo di diff capace di interpretare al meglio le differenze tra

documenti XML rappresentanti dei DDL(Disegni di Legge), dove, reputato

interessante il nostro primo lavoro, hanno chiesto informazioni e degli esempi

di applicazione dell’algoritmo. Abbiamo realizzato a tale scopo un’interfaccia

grafica per Ndiff, soprannominata LIBRA(cap.6) che permette di testare e

5

INTRODUZIONE

visualizzare i risultati sui DDL.

Di seguito, dopo l’analisi della letteratura scientifica sul diff di documenti

XML contenuta nel primo capitolo, seguira nel capitolo successivo una de-

scrizione dell’approccio utilizzato da Ndiff. Nel terzo capitolo descriveremo

formalmente l’algoritmo; nel quarto e nel quinto capitolo troviamo rispetti-

vamente i due modi in cui si puo utilizzare il delta prodotto da Ndiff, cioe

la riapplicazione alla versione n per ottenere la versione n+1 e la creazione

di un documento strutturato uguale al documento Vn, in cui sono riportate

le modifiche effettuate tra le due versioni. Infine nel sesto capitolo vedremo

l’applicazione di Ndiff al caso reale dei Disegni di Legge del Senato.

6

Capitolo 1

Algoritmi di diff tra documentiXML

In questo capitolo forniamo dei criteri di valutazione sugli algoritmi di diff

e presentiamo un’importante analogia tra il problema del diff e il proble-

ma della LCS. Di seguito elenchiamo una rassegna di lavori che sono stati

realizzati in questo campo. Confronteremo gli algoritmi basandoci sulla loro

descrizione formale ed in particolare considereremo il tempo di calcolo, la

memoria necessaria e la qualita del risultato di ogni soluzione.

1.1 Introduzione

Presentiamo prima di tutto le due principali aree che un algoritmo di diff

deve affrontare: la ricerca dei cambiamenti e la loro rappresentazione. Inoltre

definiamo alcuni criteri di valutazione della bonta di un algoritmo in queste

aree.

• Ricerca dei cambiamenti: Questo problema presenta in ingresso

due documenti e deve restituire un documento delta che rappresenti i

cambiamenti fra i due documenti in input. Gli aspetti importanti in

questa fase sono i seguenti:

– Correttezza: Un algoritmo di diff e considerato corretto se resti-

tuisce un delta sufficiente a trasformare la vecchia versione di un

7

ALGORITMI DI DIFF TRA DOCUMENTI XML

documento XML nella nuova versione. In altre parole, un diff e

corretto se permette la ricostruzione del documento senza perdita

di dati. Deve quindi individuare tutte le modifiche avvenute tra

le due versioni.

– Minimizzazione: In alcune applicazioni, l’obbiettivo principale

del diff e ottenere un delta con dimensione minima. La minimiz-

zazione del delta e un obbiettivo importante se pensiamo a sistemi

in cui bisogna memorizzare notevoli quantita di documenti.

– Semantica: Un algoritmo di diff e considerato semanticamente

corretto se il delta ottenuto si riferisce effettivamente a quello che

e successo fra i due documenti XML in input.

– Velocita e complessita: Un altro fattore di valutazione di un

algoritmo diff e il tempo di esecuzione e la memoria occupata nel

calcolo del risultato. Per esempio alcuni algoritmi esprimono un

delta in tempo e spazio quadratico.

– Ricerca degli spostamenti: La capacita di trovare gli sposta-

menti di parti del documento e un ulteriore parametro di valuta-

zione per un algoritmo di diff.

• Rappresentazione dei cambiamenti: L’importanza della rappre-

sentazione del risultato di un algoritmo di Diff dipende dalle applica-

zioni in cui verra usato:

– Nei sistemi di versionamento[Shu yao et al,01], la rappresen-

tazione del delta deve permettere un buon risparmio di memoria

e un’efficiente ricostruzione delle versioni del documento.

– Nei sistemi di visualizzazione dei cambiamenti, la rappre-

sentazione del delta deve essere chiara e facilmente analizzabile.

8

1.2 Analogie tra Diff e LCS

Ci sono due possibili interpretazioni per la ricerca e l’espressione del delta:

il modello Kuo-Chung Tai’s[Kuo-Chung,79] e quello di Selkow’s[Selkow,77].

In [Kuo-Chung,79] la cancellazione di un nodo implica che i figli di questo

vengono adottati dal padre. Per esempio:

<capitolo><sezione>

<paragrafo>Cancellami

</paragrafo></sezione>

</capitolo>

Se cancelliamo il nodo <sezione> abbiamo

<capitolo><paragrafo>

Cancellami</paragrafo>

</capitolo>

mentre in [Selkow,77] ogni nodo e un’entita rappresentante l’intero sotto-

albero radicato in esso, quindi la cancellazione di un nodo in questo mo-

dello porta alla rimozione di tutto il sotto-albero radicato. Nell’esempio

precedente:

<capitolo> </capitolo>

Nel diff fra documenti XML di solito si preferisce trattare il secondo ap-

proccio, in quanto piu vicino alla logica di definizione di XML. Questo puo

non essere una buona soluzione se trattiamo per esempio documenti XML

con content model misto, in particolare documenti che si riferiscono a testi

letterali, dove ha piu senso usare il primo approccio.

1.2 Analogie tra Diff e LCS

In questa sezione presentiamo un’importante analogia tra il problema del diff

e il problema di trovare la LCS(Longest Common Subsequence) tra due se-

quenze. Il problema di trovare le differenze fra due documenti e riconducibile

a trovare il numero minimo di operazioni per trasformare una stringa x in una

9

ALGORITMI DI DIFF TRA DOCUMENTI XML

stringa y [A. Apostolico et al,97][V.I.Levenshtein,66][R. A. Wagner et al,74].

Inserimenti e cancellazioni corrispondono a inserire e cancellare un simbolo

in una stringa. Per avere il minimo delta per trasformare la stringa x nella

stringa y dobbiamo trovare la ‘Longest Common Subsequence’ fra x e y.

Definiamo sottosequenza di una certa sequenza la sequenza originale con l’e-

sclusione di alcuni elementi(eventualmente nessuno). Formalmente, data una

sequenza X=<x1,x2,x3,...,xm>, una sequenza Z=<z1,z2,z3,...,zk> viene detta

sottosequenza di X se esiste una sequenza, strettamente crescente, <i1,i2,

..., ik> di indici di X tale che per tutti gli indici j=1,2,...,k, vale xij=zj.

Per esempio, Z=<B,C,D,B> e una sottosequenza di X = <A,B,C,B,D,A,B>,

dove la corrispondente sequenza di indici risulta <2,3,5,7>.

Date due sequenze X e Y, diciamo che una sequenza Z e una sottosequenza

comune di X e Y se Z e una sottosequenza di entrambe le sequenze X e Y.

Per esempio, se X=<A,B,C,B,D,A,B> e Y=<B,D,C,A,B,A> la sequenza

<B,C,A> e una sottosequenza comune di X e Y. La sequenza <B,C,A> non

e la piu lunga sottosequenza comune di X e Y, dato che e lunga 3 e la se-

quenza <B,C,B,A>, che e comune a X e Y, ha lunghezza 4. La sequenza

<B,C,B,A> e una LCS di X e Y, come pure la sequenza <B,D,A,B>: non

esiste alcuna sottosequenza comune di lunghezza maggiore o uguale a 5.

Nel problema della piu lunga sottosequenza comune sono date due

sequenze X=<x1,x2,x3,...,xm> e Y=<y1,y2,y3,...,yn> e si vuole determinare

la sottosequenza comune di X e Y di lunghezza massima.

Un metodo di soluzione ingenuo per il problema della LCS consiste nell’enu-

merare tutte le sottosequenze di X e nel controllare che ogni sottosequenza

sia anche sottosequenza di Y. Durante ogni fase del procedimento risoluti-

vo bisogna mantenere l’informazione sulla piu lunga sottosequenza trovata

fino a quel punto. Dato che ogni sottosequenza di X corrisponde a un sot-

toinsieme <1,2,...,m> di indici di X, la soluzione ingenua richiede un tempo

esponenziale, rendendola impraticabile per sequenze lunghe. Illustreremo di

seguito un algoritmo per risolvere il problema in un tempo quadratico.

Per illustrare la soluzione facciamo riferimento alla seguente procedura:

10

1.2 Analogie tra Diff e LCS

1: procedure lengthLCS(var X,Y )

2: begin

3: m := lenght(X)

4: n := lenght(Y)

5: for i := 1 to m do

6: c[i,0] := 0

7: for j := 1 to n do

8: c[0,j] := 0

9: for i := 1 to m do

10: for j := 1 to n do

11: if Xi == Yj then

12: begin

13: c[i,j] := c[i-1,j-1]+1

14: b[i,j] := ↖15: end

16: else

17: if c[i− 1, j] ≥ c[i, j − 1] then

18: begin

19: c[i,j] := c[i-1,j]

20: b[i,j] := ↑21: end

22: else

23: begin

24: c[i,j] := c[i,j-1]

25: b[i,j] := ←26: end

27: return b,c

28: end

11

ALGORITMI DI DIFF TRA DOCUMENTI XML

Figura 1.1: Esempio di matrice per il calcolo della LCS tra due sequenze

La procedura lenghtLCS ha come parametri di ingresso le due sequenze

X=<x1,x2,x3,...,xm> e Y=<y1,y2,y3,...,yn>, i valori c[i,j] sono memorizza-

ti in una tabella c[0..m,0..n] e gli elementi della tabella sono calcolati se-

guendo l’ordine delle righe. La procedura utilizza anche una seconda tabella

b[1..m,1..n] per semplificare la costruzione di una soluzione ottima. L’idea in-

tuitiva e che il generico elemento b[i,j] ‘punta’ alla posizione della tabella che

corrisponde alla scelta della soluzione ottima del sottoproblema nel calcolo

di c[i,j]. La procedura restituisce le due tabelle b e c; il valore dell’elemento

c[m,n] e la lunghezza di una LCS di X e Y. Per chiarire il funzionamento

dell’algoritmo consideriamo il seguente esempio:

Supponiamo di voler calcolare la sequenza massima fra le due sequenze

X=<A,B,C,B,D,A,B> e Y=<B,D,C,A,B,A>. Dopo la chiamata della pro-

cedura lenghtLCS abbiamo le due tabelle b e c rappresentate insieme in

fig.1.1 dove in grigio si vede la scelta del percorso che determina una LCS

per le sequenze trattate. La tabella b restituita dalla procedura lenghtLCS

12

1.2 Analogie tra Diff e LCS

puo essere utilizzata per costruire direttamente una LCS per le sequenze

X=<A,B,C,B,D,A,B> e Y=<B,D,C,A,B,A>. L’idea e piuttosto semplice.

Consideriamo l’elemento b[m,n] e poi percorriamo la tabella nel senso indica-

to dai puntatori. Quando il valore dell’elemento b[i,j] e uguale a↖, significa

che xi = yj appartiene alla LCS. Utilizzando questa strategia gli elementi

della LCS vengono scanditi in ordine inverso. La seguente procedura ricor-

siva stampa una LCS di X e Y nel giusto ordine. La chiamata iniziale della

procedura e PrintLCS(b,X,lenght[X],lenght[Y]).

1: procedure printLCS(var b, X, i, j)

2: begin

3: if (i 6= 0)and(j 6= 0) then

4: begin

5: if (b[i, j] ==↖ then

6: begin

7: printLCS(b,X,i-1,j-1)

8: print Xi

9: end

10: else

11: if b[i, j] ==↑ then

12: printLCS(b,X,i-1,j)

13: elseprintLCS(b,X,i,j-1)

14: end

15: end

Per l’esempio, la procedura stampera la sequenza <B,C,B,A>. E importante

notare che la funzione lenghtLCS impiega un tempo O(m×n), e una dimen-

sione di memoria dell’ordine di 2×m×n per memorizzare le tabelle ‘b’ e ‘c’.

Quindi anche se la funzione printLCS esegue in O(m+n), questa soluzione

ha una complessita totale di O(m×n).

Ci sono varie migliorie per risolvere il problema della LCS, in [Hirschberg,75]

viene proposta una soluzione per portare lo spazio usato dall’algoritmo a

13

ALGORITMI DI DIFF TRA DOCUMENTI XML

lineare. Nel 1986 E.W.Myyers descrive un algoritmo[Eugene W. Myers.,86]

capace di calcolare una LCS in O(n×D), dove D e il numero di differenze fra

le stringhe in input, usato nel famoso GNU diff[GNU diff] programma per la

comparazione di file.

1.3 Algoritmi esistenti

In questa sezione riportiamo le informazioni relative ad un gruppo di lavori

che rappresentano le soluzioni migliori in questo campo. In particolare for-

niscono un set abbastanza ampio di tipologie di approcci che possono essere

usati per affrontare il problema. Gli altri lavori si basano principalmente sulle

stesse idee. Nella definizione delle complessita dei vari algoritmi ci riferiremo

con N alla somma del numero di nodi dei due documenti da confrontare e

con D al numero di differenze tra i documenti.

1.3.1 XyDiff

XyDiff[G.Cobena et al] e un algoritmo che ha come punto di forza la velocita

di calcolo. Questo e stato implementato come supporto nella gestione del-

la memorizzazione di diverse versioni dei documenti all’interno del progetto

XyLemme[XyLemme], dove era richiesto di memorizzare giornalmente una

quantita enorme di documenti. Diventava quindi fondamentale la velocita di

calcolo.

L’idea dell’algoritmo e di ‘segnare’ ogni nodo dei documenti XML da con-

frontare, con un valore hash rappresentante tutto il sotto-albero radicato. Di

seguito i nodi vengono inseriti in una coda con priorita che e data dal pe-

so dell’albero radicato. Il peso di un albero viene calcolato in tempo lineare

attraverso una funzione ω(x) e risulta proporzionale al testo contenuto. L’in-

serimento dei nodi nella coda con priorita, permette di ridurre il numero di

confronti successivi tra i due documenti. Quando due nodi vengono uguaglia-

ti, si cerca di eguagliare iterativamente i loro genitori. L’algoritmo supporta

le operazioni di inserimento, cancellazione, aggiornamento e spostamento ed

14

1.3 Algoritmi esistenti

e in grado di eseguire comparazioni di documenti con dimensioni fino a 10

Mb. Inoltre prevede la possibilita di attivare alcune opzioni, come il non

considerare gli ‘spazi bianchi’. Il primo rilascio dell’algoritmo e stato fatto

in C++, successivamente e stato fatto un porting dell’algoritmo in java con

il nome jXyDiff. XyDiff esegue in tempo O(n×log(n)) e spazio O(n).

1.3.2 DeltaXML

DeltaXML[DeltaXML] e un tool commerciale creato da deltaXML.com, ca-

pace di confrontare, unire e sincronizzare diverse versioni di un documento

XML. I documenti in input devono essere ben formati e devono avere lo stesso

elemento radice, mentre la conoscenza del DTD relativa al documento non e

richiesta. Il delta trovato e descritto solo in termini di inserimenti, cancella-

zioni e aggiornamenti. Gli spostamenti non sono rilevati, perche porterebbero

l’algoritmo ad avere una complessita maggiore. Nel caso in cui un nodo e

spostato tra le due versioni, DeltaXML assume che il nodo sia stato cancella-

to dalla vecchia posizione e inserito in quella nuova. DeltaXML non produce

un documento delta contenente solo le differenze tra i documenti confrontati,

ma un documento XML con una struttura[Robin La Fontaine,2001] simile al

documento originale, in modo tale da poter essere comprensibile e utilizzabile

per una consultazione visiva o come input per ulteriori processi. DeltaXML

usa un algoritmo di matching tra alberi che come affermano gli autori esegue

in tempo e spazio lineari.

1.3.3 MMDiff e XMDiff

Sudarshan S. Chawathe[Chawathe,99] ha presentato un algoritmo capace di

calcolare il delta minimo tra due documenti XML. Intuitivamente l’algorit-

mo costruisce una matrice come quella descritta in fig.1.1, variando pero le

condizioni di inserimento delle frecce ↖, in seguito trova una LCS sfruttan-

do la matrice. MMDiff esegue in tempo O(n2) con spazio O(n2), in XMDiff

15

ALGORITMI DI DIFF TRA DOCUMENTI XML

viene ridotto lo spazio usato a O(n). Entrambi gli algoritmi non rilevano

operazioni di spostamento.

1.3.4 XMLdiff

XMLdiff[XMLDiff] e stato sviluppato da Logilab; attualmente viene incluso

nella distribuzione Debian GNU/Linux come principale tool per il confron-

to di documenti XML. Questo tool utilizza un formato interno(Xupdate)

per rappresentare i cambiamenti tra le varie versioni. Un esempio di delta

prodotto e il seguente:

[rename, /root[1]/sub[1]/node[2]/b[1], node][move−after,/root[1]/sub[1]/node[2]/node[1],/root[1]/sub[1]/node[1]][insert−after, /root[1]/sub2[1]/node[1], <node/> ][rename,/root[1]/sub2[1]/node[3], b][move−first,/root[1]/sub2[1]/b[1], /root[1]/sub2[1]/node[2]][remove, /root[1]/sub[1]/node[3]]

Il principale svantaggio di questo tool risiede nella codifica del delta in quan-

to e in una forma difficile da comprendere. XMLdiff offre due modalita per

il confronto. La prima(Fast match) realizzata per documenti molto grandi,

basata su concetti espressi in [Chawathe,96]: l’algoritmo opera attraverso la

ricerca di una LCS con l’algoritmo di Myers([Eugene W. Myers.,86]) e quindi

il tempo di computazione diventa O(ND). La seconda modalita si basa su

concetti espressi in [Kaizhong et al,89] e [Kaizhong,90], dove vengono cercate

le operazioni di inserimento e cancellazione in base al modello di Kuo-Chung

Tai’s[Kuo-Chung,79] illustrato precedentemente. Piu precisamente, viene mi-

gliorato l’algoritmo di Zhang Shasha aggiungendo un’operazione denominata

swap, che realizza uno scambio tra un nodo ed i suoi vicini[Barnard et al,95].

Questa seconda modalita calcola in tempo quadratico.

1.3.5 GNUdiff

GNUdiff[GNU diff] e il famoso tool diff presente nei sistemi linux. GNUdiff

effettua un confronto fra due file o tra elenchi di file, riportando le differenze

riscontrate. Il confronto tra i file e basato sulle linee, quindi GNUdiff non

16

1.3 Algoritmi esistenti

sfrutta i vantaggi forniti da una rappresentazione strutturata dei documenti.

I parametri di GNUdiff permettono all’utente di scegliere di ignorare gli spazi

bianchi, le linee vuote, il case-sensitive e una moltitudine di altre opzioni.

Nel formato del delta di default, ciascun gruppo di modifiche e preceduto da

un linea di informazioni riportante i numeri di linea di inizio e fine del gruppo

per ciascuno dei due files (vecchio e nuovo) e dal tipo di modifica necessaria

per riallinearli (c = change, a=append, d=delete). Di seguito ciascuna riga di

output e preceduta dal simbolo < se la linea deve essere eliminata dal vecchio

file, e dal simbolo > se la linea deve essere aggiunta al nuovo file. Il tool e

basato sull’algoritmo D-Band[Eugene W. Myers.,86]. Questo algoritmo non

e capace di rilevare gli spostamenti. Per effettuare confronti di file XML con

questo approccio, e necessario formattare i documenti XML in modo che le

linee assumano significato. Un esempio di confronto tra il documento:

<?xml version="1.0"?><a>

<b><c/>

</b><b>

<c/></b>

</a>

e il documento:

<?xml version="1.0"?><a>

<b><c/><c/>

</b></a>

dove l’interpretazione del delta prodotto diviene:

<?xml version="1.0"?><a>

<b><c/>

− </b>− <b>

<c/>

17

ALGORITMI DI DIFF TRA DOCUMENTI XML

Figura 1.2: Tabella riassuntiva degli algoritmi esaminati

</b></a>

Da questo esempio si puo vedere come GNUdiff non prenda in considerazione

la struttura associata al documento.

1.4 Conclusioni

Riportiamo in fig.1.2 una tabella riassuntiva delle caratteristiche dei diversi

lavori che si occupano dell’argomento. Dall’analisi di questi lavori, emerge

l’idea di segnare i sotto-alberi dei documenti da confrontare attraverso valori

hash che ne faciliteranno il confronto. Molti algoritmi usano come soluzione

ridurre il problema a quello della LCS attraverso una serializzazione degli

alberi relativi ai documenti XML da trattare. In questo lavoro noi abbia-

mo implementato un algoritmo basandoci principalmente sulle stesse idee,

ma dando una rilevanza maggiore a cio che noi definiamo naturalezza del

risultato, definibile come la capacita dell’algoritmo di rilevare le modifiche

seguendo una concezione di confronto propria della natura umana.

18

Capitolo 2

Approccio naturale al diff

In questo capitolo cercheremo di affrontare e formalizzare la percezione uma-

na di confronto per ricavare un procedimento che sara alla base di Ndiff.

2.1 Percezione del confronto

Vogliamo ora formalizzare la percezione umana di confronto nel momento in

cui ci troviamo davanti al problema di cercare le differenze tra due documenti

simili.

Dovendo effettuare il confronto manualmente, cercheremo prima di tutto le

parti invariate tra i due documenti e le useremo come base per le osserva-

zioni successive. Valuteremo una parte del documento come aggiornata, se

e simile nei due documenti e si trova nella stessa posizione, dove per stessa

posizione intendiamo l’essere tra due parti ritenute uguali(fig.2.2). Invece

valuteremo una parte come spostata se uguale ma in posizione diversa nei

due documenti(fig.2.3). Comunque potrebbe non essere sempre possibile fa-

re una distinzione netta fra i vari tipi di modifica. Supponiamo di dare due

documenti da confrontare a persone diverse e di chiedergli di evidenziarne

le differenze. Probabilmente le differenze trovate dalle due persone saranno

simili, a patto che non vi siano casi ambigui. Infatti nel momento in cui ab-

biamo delle differenze che possono essere valutate in modo diverso, subentra

la scelta soggettiva della persona, che la portera a scegliere la tipologia di

19

APPROCCIO NATURALE AL DIFF

differenza che giudica piu opportuna. Un esempio di ambiguita si vede in

fig.2.1 dove una parte del documento A puo essere considerata come sposta-

ta o aggiornata dalle relative parti del documento B. Schematizzando queste

osservazioni vengono fuori tre nozioni:

• localita: Due parti di due documenti hanno la stessa localita se si

trovano tra parti riconosciute uguali.

• somiglianza: Due parti si assomigliano se il testo e simile.

• distanza: la distanza tra una parte A del documento A e una parte

B del documento B e definibile come il numero di parti trovate uguali

che intercorrono tra la parte A e la parte B. Se due elementi hanno la

stessa localita allora la loro distanza e 0.

Attraverso questi tre concetti possiamo definire un procedimento naturale

del confronto. In ogni caso non e possibile eliminare quel tipo di ambiguita

illustrata precedentemente, ma si puo scegliere la soluzione desiderata attra-

verso dei valori che esprimono valutazioni sui tre concetti esposti.

Ndiff si basa sul procedimento descritto precedentemente, cercando di inter-

pretare al meglio le differenze tra i due documenti. Le ambiguita vengono

risolte attraverso parametri passati all’algoritmo.

2.2 Diff e soluzioni possibili

Di solito la soluzione al problema del diff non e unica. Esistono infatti un

insieme di delta tutti corretti che rappresentano possibili interpretazioni delle

differenze avvenute. Inoltre le ambiguita sulle tipologie di modifica porta-

no questo insieme ad essere piu o meno vasto. Molti lavori scelgono una

di queste soluzioni in base ai risultati che vogliono ottenere, per esempio la

minimalita del delta. Il nostro scopo e scegliere tra queste soluzioni, quella

che si avvicina di piu alla nostra intuizione di confronto, tenendo conto che

confrontiamo documenti testuali. Nel momento in cui si presentano delle

20

2.2 Diff e soluzioni possibili

Figura 2.1: Ambiguita nel confronto

21

APPROCCIO NATURALE AL DIFF

Figura 2.2: Valutazione di parti aggiornate

22

2.2 Diff e soluzioni possibili

Figura 2.3: Valutazione di parti spostate

23

APPROCCIO NATURALE AL DIFF

ambiguita, vogliamo poter scegliere la soluzione voluta attraverso dei para-

metri che esprimano delle concezioni vicine al nostro modo di pensare. Il

procedimento descritto precedentemente e gia un modo per scegliere un sot-

toinsieme delle soluzioni possibili. Di seguito mostriamo quali possono essere

possibili parametri che ci portano a scremare ulteriormente questo sottoin-

sieme fino ad arrivare alla soluzione voluta. Una possibile parametrizzazione

e la seguente:

• Per valutare gli aggiornamenti fissiamo una soglia che stabilisce il va-

lore di somiglianza oltre il quale una parte viene considerata come

aggiornata.

• Per valutare gli spostamenti fissiamo una distanza oltre la quale una

parte non viene piu valutata come spostata.

• Per valutare parti spostate e aggiornate fissiamo una coppia di valori

sulla somiglianza e sulla distanza che ci serviranno come criterio di

scelta.

Questi parametri si avvicinano all’intuizione umana di confronto e permet-

tono di scegliere una particolare soluzione tra quelle possibili. Questo ci

permette in caso di ambiguita di scegliere la soluzione che si avvicina di piu

a quella voluta, a quella che noi ci aspettiamo dal diff cioe alla soluzione che

ci sembra piu naturale.

2.3 Metrica della naturalezza

Definire una metrica della naturalezza in base alle nozioni esposte prima,

diventa abbastanza complesso a causa dell’ambiguita di fondo che puo esserci

tra un tipo di riconoscimento e un altro. Noi abbiamo definito ‘naturalezza

del risultato’ la capacita dell’algoritmo di trovare le modifiche che troverebbe

un lettore umano, e la giustifichiamo attraverso il procedimento seguito nel

calcolo del delta. Per valutare i risultati in quest’ottica abbiamo eseguito una

24

2.4 Confronto dei risultati

serie di test su vari documenti, confrontando i risultati ottenuti con quelli che

ci aspettavamo. Nella maggior parte dei casi le differenze rilevate ricalcavano

le nostre attese, in altri casi, dove si presentavano delle ambiguita, siamo

riusciti a scegliere la soluzione voluta attraverso la variazione dei parametri

descritti precedentemente.

2.4 Confronto dei risultati

Abbiamo confrontato sul piano della naturalezza diversi algoritmi. I risultati

migliori si sono ottenuti con Ndiff, anche se ci rendiamo conto che questa

valutazione puo apparire soggettiva. Comunque il fatto stesso che Ndiff ci

permetta di esprimere dei parametri vicini alla nostra concezione di confron-

to, che altri lavori non fanno, evidenzia la qualita dell’algoritmo in termini

di naturalezza. Per fornire un approccio piu sperimentale abbiamo valutato

i diversi algoritmi sul piano della dimensione del delta trovato. L’insieme dei

documenti utilizzati per il test e composto da documenti che ci sono stati

inviati dal Senato che rappresentano DDL(quindi casi reali) e da documenti

scaricati casualmente da internet dove sono state apportate modifiche di va-

rio tipo. Nei grafici in fig.2.4 e fig.2.5 sono riportati i risultati dei test, dove

l’asse delle y rappresenta la dimensione del delta trovato. Ndiff e nettamente

migliore di XYdiff in termini di dimensione del risultato, e sembra essere

bilanciato anche rispetto agli altri algoritmi testati. Questo ci fa supporre

che esista una relazione tra naturalezza del risultato e dimensione del delta

rilevato.

25

APPROCCIO NATURALE AL DIFF

Figura 2.4: Confronto tra Ndiff e altri algoritmi

Figura 2.5: Confronto tra Ndiff e altri algoritmi sulla media della dimensionedei delta rilevati

26

Capitolo 3

Ndiff

In questo capitolo descriveremo l’algoritmo Ndiff. Prima di tutto diamo

l’intuizione su cui si basa e di seguito scendiamo in un aspetto piu tecnico

descrivendo le varie fasi che lo compongono. Dal modo di procedere e dai

parametri esplicitati nelle varie fasi dell’algoritmo vedremo come venga fuo-

ri un aspetto ‘naturale’ del risultato, fornendo un delta che si avvicina alla

nostra interpretazione di confronto. L’unica condizione necessaria per l’ap-

plicazione di Ndiff stabilisce che i documenti da confrontare devono avere lo

stesso nodo radice. Non esistono altri vincoli, ne sul DTD dei documenti ne

su attributi ID definiti nel documento. Infatti la comparazione effettuata da

Ndiff si basa sulla struttura dei documenti XML senza appoggiarsi ad altre

informazioni.

3.1 Intuizione

L’intuizione su cui si basa Ndiff e procedere nella rilevazione delle modifi-

che attraverso i concetti di naturalezza descritti nel capitolo precedente. La

tipologia di associazioni vista tra le ‘parti’ dei documenti XML puo essere in-

terpretata come associazione tra nodi e sotto-alberi dei relativi alberi DOM.

Le nozioni di localita, somiglianza e distanza rimangono invariate e valgono

allo stesso modo se consideriamo invece delle ‘parti’, i relativi sotto-alberi

che le compongono. La fig.3.1 mostra un esempio di confronto effettuato da

27

NDIFF

Figura 3.1: Modo di procedere di Ndiff

28

3.1 Intuizione

Ndiff. L’idea di base e trovare i sottoinsiemi piu ‘grandi’ di nodi comuni tra

i due alberi e considerarli ‘non modificati’, per poi identificare come ‘aggior-

nati’ i nodi (o insiemi di nodi) che differiscono di poco e si trovano circa

nella stessa posizione (principi di somiglianza e localita), ed infine identifi-

care come ‘mossi’ i nodi uguali ma in posizioni molto diverse nel documento

(principio di distanza). Il nostro scopo e mettere in relazione i nodi dei due

documenti seguendo il procedimento ‘naturale’ di confronto. La relazione

di associazione si basera sulla posizione di ogni nodo data da una previsi-

ta sinistra dell’albero DOM. Di seguito ci riferiremo alla versione ‘originale’

con Vn e a quella modificata con Vn+1. Un esempio di associazione di nodi

tra due alberi e dato in fig.3.2, dove si vedono gli alberi confrontati e una

rappresentazione grafica dell’associazione. Nel grafico l’asse X rappresenta la

numerazione dei nodi del documento Vn e l’asse Y la numerazione dei nodi

del documento Vn+1 e i punti sul grafico rappresentano l’associazione tra i

nodi dei documenti. Come si intuisce dal grafico, un sotto-albero di Vn messo

in corrispondenza con un sotto-albero di Vn+1 e rappresentato da un’associa-

zione di punti continua derivata dal modo di numerare i nodi.

Come visto nel capito 1.2, il problema di trovare le differenze tra due do-

cumenti e analogo a trovarne le parti comuni, tutto cio che non e uguale tra

Vn e Vn+1 deve essere stato necessariamente aggiornato, inserito o cancellato.

Una rappresentazione del problema in termini matematici e la seguente:

Supponiamo di avere una funzione biiettiva b = Φ(a) che associa i no-

di del documento Vn ai nodi del documento Vn+1 secondo una LCS tra i

due documenti. Definiamo NVn l’insieme dei nodi di Vn e rispettivamente

NVn+1 l’insieme dei nodi di Vn+1. Ora prendiamo l’intervallo definito come

C = NVn − dominio(Φ) e I = NVn+1 − codominio(Φ) abbiamo che gli insiemi

C e I sono rispettivamente i nodi cancellati e inseriti nel passare da Vn a

Vn+1. Quindi avendo Vn e gli insiemi C ed I vale Vn+1=Vn-C+I, e simmetri-

camente Vn=Vn+1+C-I. Se consideriamo la fig.3.2, vediamo che gli insiemi C

e I corrispondono rispettivamente ai punti dell’asse X e dell’asse Y che non

fanno parte della relazione di associazione.

29

NDIFF

Figura 3.2: Relazione di associazione tra i nodi dei documenti confrontati

30

3.2 L’algoritmo

Una prima approssimazione delle differenze tra due versioni, o due docu-

menti, puo essere ottenuta calcolando i nodi inseriti(l’insieme I ) e cancel-

lati(l’insieme C ), ossia le parti non comuni tra i documenti. Possiamo di

seguito raffinare il risultato, andando ad esaminare ulteriormente gli insiemi

I e C per individuare nodi che possono essere considerati aggiornati o mossi

in base ai concetti espressi nel capitolo precedente.

Per raffinare il delta, prendiamo spunto da come un essere umano interprete-

rebbe un aggiornamento o uno spostamento o una combinazione di questi. E’

normale intuizione considerare una parte come ‘spostata’ se appare in punti

diversi del documento rispetto alla parte maggiore del documento stesso; per

esempio, se prendiamo un documento composto da 10 paragrafi e spostiamo

il primo paragrafo dall’inizio alla fine del documento, difficilmente qualcuno

ci dira che i paragrafi mossi sono stati gli altri 9 rispetto al primo. Questa

considerazione ci fornira un metodo per stabilire cosa e stato mosso fra due

documenti, basandoci sulla parte comune piu grande di entrambi.

Prendiamo ora due versioni di un documento che differiscono per l’aggior-

namento di una ‘parte’. Un lettore nel confrontare le due versioni potrebbe

pensare che queste ‘parti’ sono aggiornate, in quanto sono nella stessa posi-

zione e molto simili. Algoritmicamente se definiamo come ‘stessa posizione’

l’essere tra due parti uguali fra le due versioni, e definiamo una funzione che

misuri il grado di somiglianza tra due parti abbiamo un modo per rilevare

gli aggiornamenti.

Per rilevare invece combinazioni di spostamenti ed aggiornamenti possiamo

usare la combinazione dei due procedimenti visti prima. Questo e il mo-

do di procedere di Ndiff, cercando di esprimere l’interpretazione naturale di

confronto tra i due documenti.

3.2 L’algoritmo

L’algoritmo e una concatenazione di passi che lo rendono estremamente mo-

dulare. Partendo dai due documenti Vn e Vn+1 in input, costruiamo due

31

NDIFF

strutture dati particolari(Vtree) che forniscono metodi di accesso in tempo

costante ai nodi del documento ed altre informazioni aggiuntive. A que-

sto punto avviamo un processo incrementale che cerca di mettere in re-

lazione i nodi dei due documenti. I punti che compongono la relazione

< sono le triple (ia, ib, t), dove ia e l’indice del nodo nell’albero del do-

cumento Vn, ib e l’indice del nodo nell’albero del documento Vn+1 e t ∈{E, M, U}(E=uguale,M=mosso,U=aggiornato) rappresenta il tipo di asso-

ciazione tra i due nodi. Quindi < mette in relazione i nodi di Vn con i nodi di

Vn+1, e t rappresenta il tipo di associazione. Ovviamente < deve soddisfare

l’ipotesi ∀i, |{n|(i, j, t) ∈ <}| ≤ 1. Cioe un nodo di Vn puo essere associato

al piu a un nodo di Vn+1 ed un solo tipo di associazione t. Un esempio di

relazione e illustrato in fig. 3.2.

Il procedimento descritto puo essere visto come una concatenazione di varie

fasi, ognuna delle quali prende in input i due ‘Vtree’ e la relazione < di as-

sociazione dei nodi e da in output < arricchita da nuovi punti(fig. 3.3). Le

fasi dell’algoritmo sono:

1. Parsing dei documenti XML: In questa fase creiamo sui documenti

XML delle strutture dati particolarmente adatte ad essere confrontate;

chiameremo queste strutture Vtree.

2. Partizionamento: In questa fase andiamo a creare la prima appros-

simazione della relazione di associazione dei nodi. In particolare inse-

riremo in < i nodi che risulteranno uguali tra i due documenti.

3. Ricerca aggiornamenti: Andiamo a rilevare i nodi che possono es-

sere considerati come aggiornati, basandoci sui concetti di ‘localita’ e

‘somiglianza’.

4. Ricerca spostamenti: Andiamo a cercare i nodi uguali che non ap-

partengono ad <. I nodi trovati uguali saranno necessariamente degli

spostamenti, altrimenti sarabbero stati inseriti in < dalla fase di ‘par-

32

3.2 L’algoritmo

Figura 3.3: Schema del calcolo del diff tra due documenti

33

NDIFF

tizionamento’. Nel valutare un nodo come spostato faremo riferimento

al concetto di ‘distanza’.

5. Ricerca di spostamenti-aggiornamenti: Andiamo a cercare i nodi

che sono in parti diverse fra i documenti e risultano simili. In que-

sta fase faremo riferimento ai concetti di ‘somiglianza’ e ‘distanza’. Le

associazioni prodotte non sono uguali all’insieme delle associazioni ri-

levate dalle due fasi precedenti, in quanto ogni nodo dovra soddisfare

contemporaneamente le due condizioni precedenti.

6. Propagazione bottom-up: Andiamo a propagare il match ai nodi di

livello superiore, partendo dai nodi riconosciuti uguali o aggiornati.

7. Rappresentazione del risultato: In quest’ultimo passo andremo ad

esaminare < per costruire il documento delta che esprime i cambiamenti

trovati.

Notiamo che l’ordine delle fasi e rilevante in quanto cambiera la relazione <sulla quale operera la fase successiva. Inoltre possiamo aggiungere o togliere

delle fasi in modo da rilevare o no alcuni tipi di modifica sui documenti. I con-

cetti che useremo per discriminare aggiornamenti o spostamenti saranno dei

parametri che l’algoritmo prende in input e che permetteranno di selezionare

una particolare soluzione dall’insieme dei delta possibili.

3.3 Parsing dei documenti XML

Il parsing dei documenti XML avviene attraverso un parser di tipo DOM (Do-

cument Object Model). La creazione dell’albero DOM verra seguita da una

fase di post-parsing in cui verranno aggiunte informazioni che faciliteranno

la comparazione dei documenti. La struttura dati ottenuta e stata chiamata

Vtree e verra usata nelle varie fasi di confronto. I Vtree ci permetteranno

di identificare i nodi di un documento attraverso dei numeri corrispondenti

34

3.3 Parsing dei documenti XML

agli indici di un vettore e di confrontare rapidamente i documenti. Per ogni

nodo dell’albero vengono inserite informazioni relative a:

• Un valore hash che rappresenta l’intero sottoalbero radicato nel nodo,

HashTree.

• Un valore hash che rappresenta il nodo piu eventuali attributi, Hash-

Node.

• La posizione del nodo padre in una previsita sinistra dell’albero DOM

del documento XML, PosFather.

• Il numero dei nodi totali presenti nel sottoalbero, NumChild.

Inoltre verra fornito un metodo di accesso in tempo costante ai nodi dell’al-

bero, sfruttando un array di puntatori il cui indice corrisponde all’ordine di

una previsita sinistra dell’albero DOM. Quindi il primo elemento del vettore

sara un puntatore alla radice, l’ultimo un puntatore alla foglia piu a destra

dell’albero(fig.3.4). Facciamo vedere che partendo dall’albero DOM, riuscia-

mo a calcolare queste informazioni aggiuntive in tempo lineare sul numero di

nodi. In pratica si tratta di eseguire due visite sull’albero DOM, valorizzan-

do degli attributi di tipo ‘ereditato’ o ‘sintetizzato’. Ricordiamo che il valore

di attributi sintetizzati e determinabile dagli attributi dei nodi figlio, men-

tre gli attributi ereditati sono valorizzati utilizzando informazioni relative ad

attributi del nodo padre.

3.3.1 Visita top-down

La visita top-down ci permette di aggiungere per ogni nodo le informazioni

relative a:

• Creazione vettore dei puntatori: Inseriamo nel vettore i puntatori

relativi ad ogni nodo dell’albero. L’indice del vettore ci permettera di

accedere al nodo in tempo costante.

35

NDIFF

Figura 3.4: Vettore dei puntatori calcolato con una previsita sinistra su unsemplice documento

36

3.3 Parsing dei documenti XML

• Posizione del padre: Per ogni nodo memorizziamo l’indice sul vettore

dei puntatori del nodo padre(PosFather).

Propieta 3.1 (proprieta della numerazione dei nodi). Se definiamo y=p(x)

la funzione di numerazione dei nodi, dove x e il nodo e y la posizione che gli

viene associata. Valgono:

• Posizione del padre: p(father) < p(child), l’indice associato a un

nodo padre e minore dell’indice associato ai suoi figli. Cioe nella

numerazione il nodo padre viene prima dei suoi figli.

• Posizione dei nodi figlio: La posizione dei nodi appartenenti al sot-

toalbero del nodo X vanno da p(X)+1 a p(X)+nc dove nc rappresenta

la cardinalita(numeri di nodi) del sottoalbero radicato in X.

3.3.2 Visita bottom-up

La visita bottom-up verra eseguita sfruttando il vettore dei puntatori creato

precedentemente. Faremo una scansione del vettore partendo dall’ultimo

elemento fino al secondo. Durante la visita bottom-up andiamo a calcolare

le informazioni relative a:

• HashTree: Questo valore rappresenta l’intero sottoalbero radicato nel

nodo. Se due nodi hanno lo stesso valore HashTree hanno necessaria-

mente lo stesso sotto-albero. Il calcolo avviene aggiungendo il valo-

re HashTree del nodo visitato a quello del padre, ricalcolando l’hash

della nuova stringa ottenuta. HashTreefather = Υ(HashTreefather +

HashTreechild), dove Υ e la funzione che viene usata per calcolare il

valore hash. Un esempio di calcolo e dato in fig.3.5 dove i passi della

procedura sono disegnati da sinistra a destra, dall’alto in basso. Alla

fine del calcolo il nodo 19 contiene un valore hash che rappresenta il

contenuto dell’intero sotto-albero.

• HashNode: Questo valore viene calcolato utilizzando il nome del nodo

e il nome dei suoi eventuali attributi con rispettivi valori. Questo valore

37

NDIFF

Figura 3.5: Esempio di calcolo dei valori HashTree

puo essere calcolato anche durante la visita top-down in quanto dipende

solo da informazioni contenute nel nodo stesso, da cui segue che per i

nodi foglia il valore HashNode e uguale a HashTree.

• NumChild: Rappresenta il numero totale di nodi del sottoalbero ra-

dicato nel nodo. Il calcolo avviene facendo sommare un ‘+1’ al nodo

padre del nodo visitato. Il procedimento e simile al calcolo di HashTree.

Propieta 3.2 (proprieta del valore HashTree). Se il valore di HashTree del

nodo puntato da V [i] e uguale a quello puntato da V [j] allora V [i + k] =

V [j + k] con k=1..N, dove N e il numero di nodi radicati nel sottoalbero

associato al nodo puntato da V [i] o V [j].

38

3.4 Partizionamento

3.4 Partizionamento

La prima fase si occupa di trovare le parti maggiori di documento comuni

rimaste invariate tra le due versioni. In questo momento non abbiamo nes-

suna informazione relativa ad associazione di nodi(< e vuota). Questa fase

puo essere eseguita trovando una LCS tra i valori HashTree dei nodi nei due

documenti, considerando come ordine gli indici del vettore di puntatori. Du-

rante il calcolo della LCS possiamo sfruttare le proprieta 3.1 e 3.2 per evitare

confronti inutili.

La LCS trovata sara la prima approssimazione del risultato, in particolare

verranno aggiunti nella relazione < le coppie di nodi che risultano uguali tra

i due documenti. Per trovare una LCS tra le due sequenze definite preceden-

temente possiamo usare due approcci. Quello classico, piu veloce che esegue

in tempo O(N*D), definito da Myers[Eugene W. Myers.,86], che e un’otti-

mizzazione in termini di tempo e spazio dell’algoritmo illustrato nel capitolo

1.2. Noi useremo un nuovo approccio che esegue in tempo maggiore ma trova

un risultato che puo essere considerato piu ‘naturale’.

Definiamo MSC la massima sottosequenza continua comune tra due sequen-

ze. Per esempio la MSC tra:

S1=<OREVEINVEOD> e S2=<OTRETVEINVTEOTD>

SMSC=< V EINV >

Infatti SMSC e la sottosequenza comune continua piu lunga tra S1 e S2 consi-

derando tutte le sottosequenze possibili. Ora definiamo LCCS(Longest Com-

mon Continuous Subsequence), come l’insieme delle MSC piu lunghe tra S1

e S2, che non si intersecano. Spesso la LCCS e una soluzione particolare

della LCS dove sono state prese le MSC maggiori. Per chiarire il perche della

nostra scelta facciamo un semplice esempio; consideriamo le sequenze:

S1=< FORZALECCE >

S2=< FIOIRIZIAILIEICICIEIFORZALECC >

la LCS assocerebbe la prima ‘F’ di S1, con la prima F di S2, la prima O di S1

con la prima di S2, e cosı via fino ad associare l’intera stringa ‘FORZALEC-

39

NDIFF

CE’ che e propio la LCS. Quindi intuitivamente, se consideriamo la soluzione

della LCS come un diff avremo: ‘FIOIRIZIAILIEICICIEIFORZALECC’ do-

ve sono stati sottolineati i caratteri che risulterebbero inseriti. Una soluzione

ottima, ma non intuitiva, se pensiamo per esempio che le lettere possano esse-

re parole di una frase. Vediamo ora la LCCS, che in questo caso coincide con

l’unica MSC presente tra S1 e S2, che e quindi SLCCS=< FORZALECC >,

se pensiamo anche in questo caso il risultato come un’associazione tra i carat-

teri, avremo un diff del tipo ‘FIOIRIZIAILIEICICIEIFORZALECC’, molto

piu intuitivo.

Descriviamo di seguito un algoritmo capace di trovare una LCCS fra una

sequenza S1 e una sequenza S2. La qualita della soluzione converge con la

‘somiglianza’ delle sequenze in input.

L’idea dell’algoritmo e di considerare che una LCCS per due sequenze X e Y,

sia composta appunto dalla concatenazione di MSC calcolate su parti diverse

delle sequenze originali, senza intersezione e prese nel giusto ordine.

Per illustrare l’algoritmo supponiamo di voler calcolare la LCCS tra

X=<A,B,F,H,F,G,T,R,K,W,E,S,D> e

Y=<A,B,U,H,U,G,T,R,K,M,E,S,D>. Prendiamo la MSC fra X e Y che e

uguale a Z=<G,T,R,K> e supponiamo che Z faccia parte della LCCS, a

questo punto dividiamo le sequenze X e Y attraverso Z, abbiamo che da

X otteniamo le due sequenze Xs=<A,B,F,H,F> e Xd=<W,E,S,D> mentre

da Y abbiamo Ys=<A,B,U,H,U> e Yd=<M,E,S,D>. Nei passi successivi

riapplichiamo lo stesso procedimento su X=Xs e Y=Ys, successivamente su

X=Xd,Y=Yd. Un esempio di calcolo della LCCS per le stringhe X e Y e dato

in fig.3.6, dove le linee tratteggiate rappresentano il calcolo delle MSC per

le rispettive sequenze X e Y, mentre nel rettangolo tratteggiato in basso si

puo vedere che la LCCS per X e Y e ottenuta come concatenazione ordinata

delle MSC calcolate ad ogni passo. Da notare che l’ordine di divisione delle

sequenze e importante in quanto rispettera alla fine l’ordine di concatena-

zione per ottenere la LCCS. Una possibile implementazione dell’algoritmo

descritto e la seguente:

40

3.4 Partizionamento

Figura 3.6: Esempio di calcolo della LCCS.

41

NDIFF

1: procedure findLCCS(var A, B, Ia, Ib)

2: begin

3: Ea, Eb ← MAX-SUB(A, B, Ia, Ib)

4: LCCS ← LCCS + Ea

5: if (Ia.first ≤ Ea.first− 1)and(Ib.first ≤ Eb.first− 1) then

6: begin

7: I la ← [Ia.first,Ea.first− 1]

8: I lb ← [Ib.first,Eb.first− 1]

9: findLCCS(I la,I

lb)

10: end

11: if (Ea.last + 1 ≤ Ia.last)and(Eb.last + 1 ≤ Ib.last) then

12: begin

13: Ira ← [Ea.last + 1,Ia.last]

14: Irb ← [Eb.last + 1,Ib.last]

15: findLCCS(Ira ,I

rb )

16: end

17: end

Dove con la notazione [i,j] si intende la sotto-sequenza di S dall’elemento i

all’elemento j. Per esempio nella sequenza <A,B,G,F,T,Y,S,F>, la notazio-

ne [2,4] corrisponde alla sotto-sequenza <B,G,F> e [5,5] alla sotto-sequenza

<T>.

Prendiamo I=[i,j] e indichiamo con I.first l’estremo sinistro dell’intervallo I e

con I.last l’estremo destro; per esempio se I=[3,7], allora I.first=3 e I.last=7.

Un esempio dello schema di chiamata della funzione e dato in fig.3.7, dove le

linee continue delimitano gli intervalli di chiamata della funzione sulla sequen-

za A e sulla sequenza B, mentre le linee trattegiate delimitano gli intervalli di

ritorno, cioe gli intervalli trovati uguali fra le sequenze. Quindi nella prima

chiamata esaminiamo tutti e due gli intervalli di A e di B, nella seconda la

parte sinistra rimasta ‘fuori’ da A e B e nella terza la parte destra. Dallo

schema di computazione si nota che una chiamata ricorsiva viene provocata

42

3.4 Partizionamento

Figura 3.7: Schema di chiamata della funzione findLCCS

dal fatto che gli intervalli di input non sono uguali, ma neanche completa-

mente diversi. Piu precisamente per ogni differenza fra le due sequenze ci

sara una nuova chiamata, intendendo come differenza non un elemento ma

una parte di sequenza.

Questo modo di procedere fara un numero di chiamate proporzionale alle

differenze fra le due sequenze, e quindi particolarmente adatto a trattare

sequenze simili.

Un altro limite alla complessita di questa funzione e dettato dal modo con cui

viene calcolata la funzione MAX-SUB, che si occupa di trovare la sequenza

continua piu lunga fra due sequenze. Un modo ingenuo per implementarla

potrebbe essere quello di scandire tutte e due le sequenze e una volta trova-

ti degli elementi uguali, contare gli elementi successivi uguali, mantenendo

sempre l’intervallo e la dimensione della MSC migliore.

Questo modo di procedere richiede N*M*l confronti, dove N e M sono la

lunghezza delle sequenze trattate, e l la media degli li(fig.3.8 ). Con que-

sta soluzione abbiamo una complessita totale di O(N*M*l*D) dove D sono

il numero di ‘differenze fra le sequenze esaminate’. E’ quindi necessario mi-

gliorare il modo di trovare una MSC e lo si puo fare basandosi sulle seguenti

43

NDIFF

Figura 3.8: Schema di calcolo della MSC in modo ingenuo

44

3.4 Partizionamento

considerazioni:

• Confrontare solo le sequenze che iniziano allo stesso modo:

(con lo stesso prefisso), cioe attraverso una funzione possiamo suddivi-

dere gli elementi delle sequenze in classi e confrontare elementi solo se

appartenenti alla stessa classe.

• Sfruttiamo informazioni relative alla struttura dell’albero: Le

sequenze trattate sono serializzazioni di alberi XML attraverso la proce-

dura descritta precedentemente, quindi se S1[i]=S2[j] allora S1[i+k]=S2[j+k]

con k=1..N, dove N e il numero di nodi radicati nel sottoalbero associato

all’i-esima posizione della sequenza S1(proprieta 3.2).

Con queste considerazioni possiamo scrivere una procedura che riesce a tro-

vare una MSC in tempo medio lineare sugli elementi della sequenza. Dalla

fig.3.9 si vede che la complessita del calcolo della MSC diventa O((N) ∗ C ∗N/l), dove N e il numero di elementi di una sequenza(pref. la piu corta),

l e la media degli ‘li’ e C rappresenta la cardinalita media delle classi in

cui vengono catalogati gli elementi. Considerando una buona suddivisione la

cardinalita media C puo essere considerata come una costante, inoltre se le

sequenze sono simili allora l si avvicinera al valore di N e di conseguenza il

rapporto N/l tende a 1. Osserviamo che nel caso ottimo, in cui le sequenze

sono uguali, il tempo di confronto diventa O(1). Lo pseudo-codice relati-

vo all’algoritmo descritto per trovare la MSC, sfruttando le ottimizzazioni

diventa:

1: procedure MAX-SUB(var A, B, Ia, Ib)

2: var max:=0;

3: begin

4: for i := Ia.first to Ia.last do

5: begin

6: idc ← getIdClass(i,DOCa)

7: Cb ← getClass(idc, DOCb)

45

NDIFF

Figura 3.9: Schema di calcolo della MSC in modo efficiente

46

3.4 Partizionamento

8: for j := 0 to |Cb| do

9: begin

10: explorer ← 0

11: while A[i + explorer] == B[j + explorer] do

12: begin

13: explorer := explorer + (numero di nodi nel sottoalbero i)

14: if explorer > max then

15: begin

16: max := explorer

17: Ea ¡- [i,i+explorer]

18: Eb ¡- [j,j+explorer]

19: end

20: i := i+1

21: end

22: end

23: end

24: return Ea, Eb

25: end

MAX-SUB ha un tempo medio di esecuzione lineare se la suddivisione degli

elementi fra le classi di appartenenza e buona. Piu precisamente minore sara

il numero medio di elementi per classe maggiore sara la velocita dell’algorit-

mo, in quanto il secondo ciclo for(riga 8) avra meno casi da esaminare. La

riga 13 ci permette di sfruttare la proprieta 3.2.

I punti di forza nel trovare una LCCS con questo approccio sono:

• Numero delle differenze: findLCCS e parametrico rispetto al nu-

mero di differenze.

• Sequenze uguali: Esegue in tempo costante O(1) se le sequenze da

confrontare sono uguali.

• Cardinalita del vocabolario della sequenza: Se gli elementi di

47

NDIFF

una sequenza sono tutti diversi, o abbastanza(come possono essere le

parole di un testo) findLCCS esegue in tempo medio lineare.

Concludiamo dicendo che l’output della fase di ‘Partizionamento’ sara ap-

punto un insieme di terne del tipo (ia, ib, E), che verranno inserite in <.

Questo risultato e appunto il ‘mapping’ dei nodi uguali tra le due versioni

del documento e sara l’input, insieme ai documenti da confrontare, delle fasi

successive.

3.5 Ricerca aggiornamenti

In questo fase andiamo a cercare fra le due versioni, i nodi che possono essere

considerati come aggiornamenti. Per fare questo ci baseremo su due concetti:

• Localita: Consideriamo parti di documento che si trovano tra due

parti considerate uguali nelle due versioni.

• Somiglianza: Definiamo una funzione che ci calcolera l’indice di so-

miglianza di due nodi. Restituira un valore percentuale pari a 100 se i

nodi sono uguali, 0 se sono completamente diversi.

Il concetto di ‘localita’ puo essere spiegato semplicemente considerando che

probabilmente, una parte aggiornata si trova tra due parti di documento

uguali. Per chiarezza consideriamo la fig. 3.10 che rappresenta un possibile

output di < dopo la fase di partizionamento. Andremo a confrontare i no-

di che appartengono ai quadrati illustrati in figura, se questi saranno simili

per un valore maggiore di una certa soglia, verranno considerati aggiornati e

verranno inclusi nella relazione < come triple del tipo(ia,ib,U).

La somiglianza dei nodi viene data dalla funzione:

f(T1, T2) = 50 ∗ (MAX( length(TC)length(T1)

, length(TC)length(T2)

) + MIN( length(TC)length(T1)

, length(TC)length(T2)

))

dove length(x) restituisce la lunghezza della stringa x, e TC e la LCCS(o

48

3.5 Ricerca aggiornamenti

Figura 3.10: Grafico delle aree di ricerca degli aggiornamenti.

49

NDIFF

Figura 3.11: Grafico tridimensionale della funzione che calcola la somiglianzadi nodi di testo.

LCS) tra T1 e T2. La funzione f(T1, T2) assume valori tra 0 e 100 in quanto

i rapporti length(TC)length(T1)

e length(TC)length(T2)

assumono valori in [0,1] perche sicuramente

length(TC) < length(T1) e length(TC) < length(T2). In fig.3.11 vediamo un

esempio dell’andamento di f con length(TC) fissato a 50 e 0 < length(T1) <

100,0 < length(T2) < 100. La funzione si comporta bene, in quanto all’avvi-

cinarsi di length(T1) e length(T2) a length(TC) il valore f(T1, T2) cresce, in

particolare se length(T1) = length(T2) = length(TC)⇒ f(T1, T2) = 100.

3.6 Ricerca spostamenti

In questa fase andiamo a confrontare i nodi del documento non appartenenti

ad <, che quindi non hanno ancora trovato nessuna corrispondenza. Il con-

fronto avviene in modo incrociato, cioe tra parti di documento con ‘localita’

diversa; non confrontiamo parti con la stessa ‘localita’, in quanto se fossero

presenti nodi uguali, avrebbero fatto parte della LCCS(o LCS) trovata nella

fase di ‘partizionamento’. Un esempio delle aree di ricerca degli spostamenti

e dato dai quadrati evidenziati in fig.3.12, dove i punti cerchiati sull’asse X

e Y sono i nodi che non hanno ancora trovato nessuna corrispondenza. Nel

confronto utilizziamo il concetto di distanza per ridurre l’eventuale spazio di

50

3.7 Ricerca spostamenti-aggiornamenti

Figura 3.12: Grafico delle aree di ricerca degli spostamenti

ricerca degli spostamenti. Fissando una valore per la distanza, discriminiamo

il limite dopo il quale un nodo non viene piu considerato spostato. Pensiamo

ad esempio a un paragrafo che appare nella versione Vn nel primo capitolo,

e nella versione Vn+1 nell’ultimo capitolo, potremmo non volerlo considerare

come uno spostamento.

3.7 Ricerca spostamenti-aggiornamenti

Per rilevare i nodi spostati e aggiornati ci basiamo sulle nozioni di distanza

e somiglianza. In particolare fissiamo una coppia di valori (s, d), dove s rap-

presenta la soglia oltre la quale un nodo viene considerato aggiornato e d lo

spazio di ricerca degli spostamenti. Due nodi N1 e N2 verranno considerati

spostati/aggiornati se la loro distanza e minore di d e f(N1, N2) ≥ s, dove

f e la funzione descritta in 3.5. Nonostante questa fase sia un incrocio delle

51

NDIFF

due fasi precedenti, i risultati prodotti sono diversi. Comunque, procedendo

in questo modo corriamo il rischio di associare della parti in modo scorret-

to, occorre quindi un accurato ‘dosaggio’ dei valori d e s, in quanto gia la

condizione di spostato/aggiornato risulta troppo generica.

3.8 Propagazione bottom-up

Fino ad ora abbiamo confrontato i nodi in base al valore HashTree, quin-

di effettivamente non abbiamo confrontato nodi ma sotto-alberi dell’albero

DOM. In fondo, in base alla nostra numerazione dei nodi, un sotto-albero e

un insieme di punti continui in Vn messo in corrispondenza con un insieme

di punti di Vn+1. Quindi il mapping tra i punti contenuti in < puo essere piu

correttamente visto come un mapping di sotto-alberi. Ora partendo dalle ra-

dici di questa foresta di sotto-alberi risaliamo in modo ricorsivo i nodi, fino ad

arrivare alla radice del documento, per cercare singoli nodi rimasti uguali. E’

infatti possibile che due nodi abbiamo HashTree diversi, pur non essendo stati

modificati. Questo perche il valore HashTree di ogni nodo dipende dall’in-

tero sotto-albero radicato(le modifiche al sotto-albero sono quindi propagate

verso l’alto). L’algoritmo riconosce questi casi e considera uguali anche due

nodi con HashTree inizialmente diversi. Questo ci permettera di raffinare

il risultato del delta, eliminando le operazioni di inserimento/cancellazione

di singoli nodi posti ai livelli inferiori dell’albero. La fig.3.13 rappresenta

lo schema decisionale per il riconoscimento di questi nodi. Ragionando per

induzione sul percorso fino alla radice, possiamo avere 3 casi:

• Il nome del nodo Ni ∈ Vn e diverso dal nome del nodo Nj ∈ Vn+1

• Il nome del nodo Ni ∈ Vn e uguale al nome del nodo Nj ∈ Vn+1, ma gli

attributi sono diversi.

• Il nome del nodo Ni ∈ Vn e uguale al nome del nodo Nj ∈ Vn+1, ma

FNi6= FNj

, dove FNi={l’insieme dei sotto-alberi riconosciuti uguali

52

3.8 Propagazione bottom-up

Figura 3.13: Diagramma di decisione durante la propagazione del matchingBottom-up.

o simili tra i discendenti di Ni} e FNj={l’insieme dei sotto-alberi ri-

conosciuti uguali o simili tra i discendenti di Nj }. Per esempio se

consideriamo il nodo ‘D’ in fig.3.14, abbiamo che nel documento n,

FD={E,F}, mentre nel documento n+1 FD={E,F,G}. I nodi contenu-

ti negli insiemi Fx devono necessariamente appartenere alla relazione

<.

Nel primo caso, in cui il nome del nodo e diverso, arrestiamo il procedimento

ricorsivo in quanto i nodi non possono essere considerati uguali. Nel secondo

caso possiamo eguagliare i due nodi a patto di considerare Nj come aggior-

namento di Ni e quindi inserire un ‘minidelta’ sugli attributi dei nodi che

descrive le differenze rilevate e le operazioni necessarie per renderli uguali.

53

NDIFF

Figura 3.14: Schema di propagazione del matching bottom-up

Per chiarire il terzo punto facciamo riferimento alla fig. 3.14, dove sono rap-

presentate le associazioni definite in <. Vogliamo vedere se il nodo ‘D’ puo

essere considerato uguale tra i due documenti. Non basta che il nodo abbia lo

stesso nome e gli stessi attributi, deve valere anche che sia lo stesso ‘contesto’

per i sotto-alberi rilevati uguali o simili(appartenenti a <) al di sotto di lui.

Questo perche, se compariamo i due nodi senza che valga questa condizione,

non riusciremo a trovare i cambiamenti di contesto dei suoi sotto-alberi. In

questo caso particolare possiamo eguagliare ‘D’ solo se consideriamo il nodo

o il sottoalbero radicato in ‘G’ come uno spostamento. Infatti il ‘contesto’

del nodo ‘G’ e cambiato. Prima era figlio del nodo ‘B’, ma ora si ritrova a un

livello piu basso, figlio di ‘D’, e quindi e corretta la supposizione che questo

sia stato spostato. Da questo modo di procedere segue che la radice dei do-

cumenti verra sempre riconosciuta, in quanto e stato supposto che questa sia

uguale tra i due documenti e per costruzione tutti i sotto-alberi presenti in

< sono suoi discendenti. Il risultato di questa fase sara un raffinamento del

delta, evitando cosı di cancellare e reinserire singoli nodi a livello intermedio

dell’albero.

54

3.9 Rappresentazione del risultato

Figura 3.15: Interpretazione di < sugli alberi relativi ai documenti XMLconfrontati.

3.9 Rappresentazione del risultato

In quest’ultima fase andiamo a trasformare le informazioni raccolte nelle fasi

precedenti e contenute in < nell’equivalente documento XML che rappresenta

i cambiamenti fra i documenti confrontati. In fig.3.15 vediamo un’esempio

di interpretazione delle informazioni contenute in <: in alto e illustrato il

documento originale, in basso il documento modificato e le frecce rappresen-

tano le associazioni tra i nodi e i sotto-alberi dei due documenti. Il formato

del delta di Ndiff segue il modello [Kuo-Chung,79] descritto nel capitolo 1.1.

Attualmente il delta viene espresso attraverso 6 tipi di operazione:

• insertTree: Si riferisce all’operazione di inserimento di un sotto-albero.

55

NDIFF

• insertNode: Indica l’operazione di inserimento di un singolo nodo.

• deleteTree: Indica la cancellazione di un intero sotto-albero.

• deleteNode: Si riferisce alla cancellazione di un singolo nodo.

• updateElement: Indica l’operazione di aggiornamento di un nodo ele-

mento. L’aggiornamento viene specificato attraverso delle sub-operazioni

che esprimono l’inserimento, la modifica o cancellazione di attributi del

nodo.

• updateText: Indica l’aggiornamento di un nodo a contenuto testua-

le. L’aggiornamento viene specificato attraverso un insieme di sub-

operazioni che esprimono l’inserimento e la cancellazione di sotto-stringhe

del nodo.

L’operazione di spostamento non e definita esplicitamente, ma viene rap-

presentata da una coppia di operazioni insertTree e deleteTree legate da un

attributo il cui valore ne specifichera il legame.

Per ottenere il delta esaminiamo per ogni nodo di Vn le relative informazioni

contenute in <. I casi possibili sono:

• Il nodo appartiene a < ed e associato come ‘uguale’. In questo caso

non occorre inserire operazioni nel delta in quanto il nodo e presente

sia in Vn che in Vn+1 e soddisfa tutte le condizioni dettate dalle fasi

precedenti.

• Il nodo appartiene a < ed e associato come ‘aggiornato’. In questo

caso dobbiamo calcolare un ‘minidelta’ che renda uguali i due nodi

associati. Se i nodi sono a contenuto testuale calcoleremo un ‘minidelta’

sulle rispettive stringhe, mentre se sono nodi elemento troveremo un

‘minidelta’ sugli attributi.

• Il nodo appartiene a < ed e associato come ‘spostato’. In questo ca-

so generiamo due operazioni, una di insertTree e una deleteTree, che

contengono l’attributo move il cui valore le lega insieme.

56

3.9 Rappresentazione del risultato

• Il nodo non appartiene a <. Non e stata trovata nessuna associazione

per il nodo quindi sara considerato come cancellato.

• Per esplicitare gli inserimenti dobbiamo considerare i nodi di Vn+1 che

non appartengono a <. Questi nodi saranno considerati come inseriti.

Per ognuna delle operazioni precedenti e necessario salvare delle informazioni

che permettano di applicare correttamente l’operazione n alla versione Vn su

cui sono gia state applicate le n-1 operazioni precedenti. Dunque l’ordine

delle operazioni all’interno del delta e rilevante. Infatti l’operazione n, si

riferisce allo stato del documento ottenuto dopo le prime n-1 operazioni.

Il delta ottenuto e composto da tre blocchi di operazioni dove nel primo sono

inserite tutte le operazioni di cancellazione, nel secondo di inserimento e nel-

l’ultimo di aggiornamento. Per capire il motivo di questa scelta indichiamo

con ia l’indice di un nodo del documento Vn e con ib l’indice di un nodo del

documento Vn+1. L’applicazione partira dal documento Vn, quindi gli indici

degli elementi da cancellare saranno gli ia, cioe i nodi di Vn che non hanno

trovato nessuna associazione in <(l’asse delle X del grafico in fig.3.2). L’in-

dice di inserimento dei nuovi nodi sara invece ib, cioe la posizione dei nodi in

Vn+1 perche sara propio quella la posizione che dovranno occupare. L’ordine

delle operazioni di inserimento e molto importante in quanto l’inserimento di

un nodo potrebbe far riferimento ad un nodo padre non ancora presente nel

documento. Per prevenire il problema ordiniamo le operazioni di inserimen-

to secondo ib: questo ci garantisce che un’operazione sul nodo n, trovera gli

n-1 nodi dell’albero gia correttamente inseriti, da cui per la proprieta 3.1 nel

momento in cui inseriamo un nodo, siamo sicuri di aver gia eventualmente

inserito il padre ed i fratelli precedenti.

Le operazioni di aggiornamento faranno riferimento alla posizione ib, in quan-

to quella sara la posizione in cui si trovera il nodo dopo l’applicazione dei

primi due blocchi del delta. Volendo possiamo spostare l’ultimo blocco del

delta in prima posizione e per mantenere la correttezza ci bastera far riferi-

mento ai nodi da aggiornare attraverso le posizioni ia.

57

NDIFF

Per ogni tipo di operazione salveremo dei valori che indicano il punto e il

modo in cui applicarla nell’albero. La trattazione e le specifiche di questi

valori sono affrontate nel capitolo successivo in cui vedremo l’applicazione

del delta.

58

Capitolo 4

Napply:Motore di ricostruzione

Napply e un tool scritto in PHP che partendo dalla versione Vn e dal ∆,

ricostruisce la versione Vn+1. Lo schema di funzionamento del motore di ri-

costruzione e rappresentato in fig.4.1. In questo capitolo descriviamo il pro-

cedimento utilizzato nella ricostruzione. Nell’esposizione successiva indiche-

remo con ‘posizione di un nodo’ l’indice del vettore dei puntatori all’interno

del Vtree(cap.3.3) associato al documento Vn.

4.1 Sintassi del delta

Per comprendere la sintassi del delta partiamo da un esempio di confronto

di due documenti semplici che raccolgono tutte le tipologie di cambiamenti

Figura 4.1: Schema di applicazione del delta.

59

NAPPLY:MOTORE DI RICOSTRUZIONE

trattate.

I documenti che andiamo a confrontare sono la seguente versione Vn:

<?xml version="1.0"?><libro>

<capitolo data="19 feb 2007"><titolo> Ndiff un approccio natuale al diff di documenti XML </titolo>

<sezione><para> Primo approccio a livello naturalesul diff di documenti </para>

</sezione><para> Ndiff risulta modulare, quindi estremamente estendibile. </para>

</capitolo><capitolo info="da completare" data="22 feb 2007">

<titolo> Secondo capitolo, descrizione formale dell algoritmo </titolo><para> Il nostro approccio e estremamente modularein quanto permette di inserire o rimuovere moduli</para>

</capitolo><capitolo>

<titolo> Ricostruzione del documento Originale </titolo><sezione> In questo capitolo parliamo della riapplicazionedel delta al documento originale</sezione>

</capitolo><capitolo>

<titolo> Markup del documento originale</titolo><sezione> Un secondo modo di utilizzare il delta e per marcareil documento orginale in modo da evidenziare le modifiche</sezione>

</capitolo><capitolo>

<titolo> Conclusioni </titolo><sezione> La qualita nel delta di Ndiff risulta miglioredegli altri approcci.</sezione>

</capitolo></libro>

60

4.1 Sintassi del delta

e la versione Vn+1:

<?xml version="1.0"?><libro>

<capitolo data="25 feb 2007"><titolo> Ndiff un approccio natuale al diff di documenti XML </titolo><para> Primo approccio a livello naturale sul diff di documenti </para><para> Ndiff risulta modulare, quindi estremamente estendibile. </para>

</capitolo><capitolo informazioni="completato">

<titolo> Secondo capitolo, descrizione formale dell algoritmo </titolo><sezione>

<para> Il nostro approccio e estremamente modularein quanto permette di inserire o rimuovere moduli</para>

</sezione></capitolo><capitolo>

<titolo> Markup del documento originale</titolo><sezione> Un secondo modo di utilizzare il delta e per marcareil documento orginale in modo da evidenziare le modifiche</sezione>

</capitolo><capitolo>

<titolo> Ricostruzione del documento Originale </titolo><sezione> In questo capitolo parliamo della riapplicazionedel delta al documento originale</sezione>

</capitolo><capitolo>

<titolo> Conclusioni </titolo><sezione> La qualita nel delta di Ndiff risulta molto miglioredegli altri approcci.</sezione>

</capitolo></libro>

61

NAPPLY:MOTORE DI RICOSTRUZIONE

il delta generato da Ndiff su questi due documenti e:

<?xml version="1.0"?><Ndelta>

<DeleteNode vp="4"><sezione/>

</DeleteNode><DeleteTree vp="19:4" move="19:14">

<capitolo><titolo> Markup del documento originale</titolo>

<sezione> Un secondo modo di utilizzare il delta e per marcareil documento orginale in modo da evidenziare le modifiche</sezione>

</capitolo></DeleteTree><InsertNode vp="11:8:1:1">

<sezione/></InsertNode><InsertTree vp="14:0:2:4" move="19:14">

<capitolo><titolo> Markup del documento originale</titolo>

<sezione> Un secondo modo di utilizzare il delta e per marcareil documento orginale in modo da evidenziare le modifiche</sezione>

</capitolo></InsertTree><UpdateElement vp="1">

<updAttr name="data" value="25 feb 2007"/></UpdateElement><UpdateElement vp="8">

<delAttr name="info"/><delAttr name="data"/><insAttr name="informazioni" value="completato"/>

</UpdateElement><UpdateText vp="28">

<Ins tp="39:6">molto </Ins></UpdateText>

</Ndelta>

Come detto nel capitolo precedente, e come si puo vedere dall’esempio,

il delta e espresso in tre blocchi principali, vediamo la composizione e le

operazioni di ognuno dei tre blocchi:

1. Operazioni di cancellazione: Le operazioni di cancellazione sono di

due tipi:

• <DeleteTree vp=‘19:4’ move=‘19:14’>/*albero da cancella-

62

4.1 Sintassi del delta

re*/</DeleteTree>: Questa operazione indica la cancellazione

di un sotto-albero del documento, l’attributo vp specifica in ordine

la posizione della radice e il numero di nodi dell’albero da cancel-

lare. L’attributo opzionale move indica che questa operazione e

un’operazione di spostamento e quindi dovra esserci nel secondo

blocco un’operazione insertTree con lo stesso valore dell’attributo

move. Il contenuto del nodo e l’albero da cancellare, che non viene

utilizzato per l’applicazione ma solo per una maggiore chiarezza

all’interno del delta.

• <DeleteNode vp=‘4’> /*nodo da cancellare*/ </DeleteNode>:

In questo caso l’attributo vp specifica la posizione del nodo da

cancellare. Non sono necessarie altre informazioni per rimuovere

un nodo. Il contenuto del tag e il nodo da cancellare che viene

riportato solo per chiarezza del delta.

2. Operazioni di inserimento: Anche le operazioni di inserimento sono

di due tipi:

• <InsertTree vp=‘14:0:2:4’ move=‘19:14’> /* albero da inse-

rire */ </InsertTree>: L’attributo vp specifica rispettivamente

la posizione del nodo da inserire, la posizione del padre del no-

do, la posizione del nodo come figlio e il numero di nodi totali

dell’albero da inserire. Il contenuto del tag e l’albero da inserire.

• <InsertNode vp=‘11:8:1:1’> /* nodo da inserire */ </InsertNode>:

L’attributo vp specifica la posizione del nodo da inserire, la posi-

zione del padre del nodo, la posizione del nodo come figlio, il nu-

mero di figli che il nodo deve adottare dal contesto. Il contenuto

del tag e il nodo da inserire con rispettivi attributi.

3. Operazioni di aggiornamento: Queste operazioni si distinguono in

base al tipo di nodo che devono aggiornare:

63

NAPPLY:MOTORE DI RICOSTRUZIONE

• <UpdateElement vp=‘1’> /*minidelta*/ </UpdateElement>:

Qui vp specifica solo la posizione del nodo da aggiornare. Il mi-

nidelta interno specifica le sub-operazioni di aggiornamento da

compiere sul nodo elemento. Ci sono tre tipi di sub-operazioni:

– <updAttr name=‘data’ value=‘25 feb 2007’/>: che

indica l’aggiornamento dell’attributo name al valore value.

– <delAttr name=‘info’/>: che indica la cancellazione del-

l’attributo name.

– <insAttr name=‘info’ value=‘ok’/>: che indica l’inseri-

mento dell’attributo name con il valore value.

• <UpdateText vp=‘28’> /*minidelta*/ </UpdateText>: do-

ve vp specifica il nodo a contenuto testuale che deve essere aggior-

nato. L’aggiornamento avviene attraverso un minidelta contenuto

all’interno del nodo e comprende due tipi di operazione:

– <Ins tp=‘39:6’> /*testo da inserire */ </Ins>: qui tp

specifica l’offset iniziale da dove cominciare a inserire nel testo

e la lunghezza del testo da inserire. La stringa da inserire e

contenuta nel tag.

– <Del tp=‘39:6’> /*testo da cancellare */ </Del>: in que-

sto caso tp specifica l’offset iniziale da dove cominciare a can-

cellare il testo e la lunghezza del testo da cancellare. L’infor-

mazione relativa al testo da cancellare non viene usata, ed e

inserita solo per chiarezza del delta.

In tutte le operazioni l’attributo vp determina univocamente il punto dell’al-

bero DOM in cui applicare l’operazione.

4.2 Applicazione del delta

Prima di vedere lo schema di applicazione delle operazioni del delta, ricor-

diamo la sostanziale differenza fra inserimento/cancellazione di un nodo ed

64

4.2 Applicazione del delta

inserimento/cancellazione di un sotto-albero. La cancellazione di un nodo

implica che i suoi sotto-alberi rimangono nel documento e vengono ‘adottati’

dal nodo padre del nodo cancellato. L’inserimento di un nodo invece compor-

ta ‘l’adozione’ di sotto-alberi gia appartenenti al documento, ma figli di altri

nodi. Per ‘adozione’ intendiamo dunque lo spostamento di sotto-alberi, gia

presenti nell’albero, come causa della cancellazione/inserimento di un singolo

nodo. Per cancellazione/rimozione di un sotto-albero intendiamo quella clas-

sica. Forniamo di seguito lo schema di applicazione dei vari tipi di operazione

espressi nel delta.

4.2.1 Inserimento di un nodo

Le informazioni a nostra disposizione per l’inserimento sono:

• p:Posizione del nodo da inserire

• pf :Posizione del nodo padre

• pc:Posizione come figlio del nodo da inserire.

• nc:Numero di figli che il nodo deve adottare dal contesto

• node: Nodo da inserire

Consideriamo la fig.4.2, dove viene inserito il nodo ‘1’. L’operazione delta

relativa a questo esempio e:

<InsertNode vp="2:1:1:2"><1/>

</InsertNode>

I passi dell’applicazione sono i seguenti:

1. Inserimento del nodo node come figlio del nodo pf nella posizione come

figlio pc.

2. Adozione di nc nodi dal contesto.

65

NAPPLY:MOTORE DI RICOSTRUZIONE

Figura 4.2: Un’esecuzione di operazione insert di un nodo.

66

4.2 Applicazione del delta

Figura 4.3: Processo di adozione dei nodi

Il primo passo inserisce il nodo node nella giusta posizione dell’albero. Il

secondo passo inserisce come figli di node, i nodi rimasti uguali tra le due

versioni, che node aveva in Vn+1. I nodi rimasti uguali tra le due versioni

appartengono al documento e la loro posizione sara consecutiva a quella di

node. Dobbiamo quindi spostare un numero nc di nodi, rendendoli figli di

node. Prendiamo questi nodi dai fratelli successivi di node ed eventual-

mente dai fratelli successivi del padre di node e cosı ricorsivamente fino ad

arrivare al primo nodo rimasto uguale tra Vn e Vn+1, che avra necessariamente

per costruzione tutti i figli necessari. Nel peggiore dei casi questo nodo sara

la radice del documento. Per distinguere il nodo rimasto invariato tra le due

versioni bastera segnare i nodi inseriti: se un nodo non e segnato allora era

presente anche in Vn. La fig.4.3 mostra un esempio del processo di adozione,

dove abbiamo inserito il nodo ‘1’ e vogliamo adottare 4 figli dal contesto. I

figli che verranno adottati sono evidenziati in figura attraverso dei quadrati.

67

NAPPLY:MOTORE DI RICOSTRUZIONE

Figura 4.4: Esecuzione dell’operazione di inserimento di un albero.

4.2.2 Inserimento di un albero

Le informazioni a nostra disposizione per l’inserimento di un albero sono:

• p:Posizione della radice dell’albero da inserire

• pf :Posizione del nodo padre

• pc:Posizione come figlio

• ns:Numero di nodi presenti nel sotto-albero da inserire

• tree: Albero da inserire

L’inserimento di un albero e un’operazione semplice in quanto non dobbiamo

preoccuparci di correggere la struttura dell’albero dopo l’inserimento. Basta

infatti inserire l’intero albero tree come figlio pc del nodo padre pf. L’in-

formazione ns viene usata solo per un’applicazione efficiente dell’operazione.

Un’esempio di inserimento di un albero e dato in fig. 4.4 dove il delta relativo

e:

<InsertTree vp="7:0:2:2"><1>

<2/><3/>

</1></InsertTree>

68

4.2 Applicazione del delta

Figura 4.5: Un’esecuzione di operazione delete di un nodo.

4.2.3 Cancellazione di un nodo

Nella cancellazione di un nodo abbiamo a disposizione solo l’informazione p

relativa alla posizione del nodo da cancellare. L’operazione di cancellazione

di un singolo nodo e molto semplice in quanto dobbiamo solo cancellare il

nodo in posizione p e far adottare i suoi figli dal padre. In fig. 4.5 e illustrato

l’esempio di cancellazione di un nodo dove il delta corrispondente e:

<DeleteNode vp="1"><B/>

</DeleteNode>

La figura mostra come i sotto-alberi radicati in ‘D’ e ‘G’, dopo la rimozine di

‘B’ diventano figli della radice ‘A’. La cancellazione di un nodo non portera

mai l’albero in una configurazione inconsistente, in quanto ci sara sempre la

radice che adottera i figli dei nodi cancellati.

4.2.4 Cancellazione di un albero

Per la cancellazione di un’albero abbiamo a disposizione l’informazione re-

lativa alla posizione p della radice dell’albero da rimuovere. La rimozione

consiste nel cancellare l’intero sotto-albero radicato nel nodo in posizione p.

Un esempio di cancellazione e dato in fig.4.6 dove il delta dell’operazione

relativa e:

69

NAPPLY:MOTORE DI RICOSTRUZIONE

Figura 4.6: Esecuzione di operazione di cancellazione di un albero.

<DeleteTree vp="7:3"><C>

<I><L/><M/>

</I></C>

</DeleteTree>

4.2.5 Aggiornamento di un nodo

L’aggiornamento di un nodo si distingue in base al tipo del nodo da aggior-

nare. E’ previsto l’aggiornamento di:

• Nodi elemento: L’aggiornamento di un nodo elemento e definito

in termini di inserimento, cancellazione e modifica del valore degli

attributi del nodo stesso. La sintassi relativa e stata illustrata in 4.1.

• Nodi a contenuto testuale: L’aggiornamento di un nodo di testo

consiste nell’inserire o rimuovere sotto-stringhe del suo contenuto.

4.3 Trasformazione da Vn a Vn+1

Vogliamo mostrare come il documento originale varia durante l’applicazione

del delta. L’ordine di applicazione del delta implica che l’albero verra pri-

70

4.3 Trasformazione da Vn a Vn+1

Figura 4.7: Trasformazione del documento Vn in Vn+1 attraversol’applicazione del delta.

71

NAPPLY:MOTORE DI RICOSTRUZIONE

ma ‘sfrondato’ e poi arricchito dalle operazioni di inserimento. I primi due

blocchi del delta trasformeranno la struttura del documento Vn in quella del

documento Vn+1, le operazioni di aggiornamento non influiranno sulla strut-

tura ma solo sul contenuto o sugli attributi dei singoli nodi. Un esempio

della trasformazione dell’albero dopo l’applicazione dei vari blocchi e dato

in fig.4.7. Dopo le cancellazioni, l’albero si trova in uno stato dove sono

presenti solo i nodi comuni a entrambe le versioni, inoltre ogni nodo inter-

medio soddisfa la condizione descritta nella fase di propagazione del match

bottom-up(cap.3.8). Su quest’albero andiamo ad applicare le operazioni di

inserimento. Ricordiamo che tali operazioni sono ordinate sulla posizione del

nodo sulla quale operano. Questo garantisce che l’operazione di inserimento

Oi sul nodo n trovera lo stato degli n-1 nodi precedenti corretto, in quanto le

Oi−1 operazioni precedenti saranno gia state applicate. Dopo l’applicazione

dei primi due blocchi avremo che la struttura del documento Vn sara divenuta

uguale a Vn+1. A questo punto applichiamo il terzo blocco che si occupera

di modificare i singoli nodi dell’albero, ma non ne cambiera la struttura.

72

Capitolo 5

Nmerge:Motore di markup deicambiamenti

Nmerge e un tool scritto in PHP che partendo dalla versione Vn e dal ∆,

costruisce un documento Vn→n+1 uguale a Vn con l’aggiunta di informazioni

relative ai cambiamenti espressi nel ∆. In questo capitolo descriveremo il

procedimento utilizzato per costruire il documento Vn→n+1. Facciamo notare

che avendo Vn→n+1 e sempre possibile ricondursi alla versione Vn+1 sfrut-

tando appunto le informazioni di markup dei cambiamenti presenti. Questo

vuol dire che il risultato ottenuto da Napply, puo essere ottenuto attraverso

Nmerge piu un ulteriore passo(un foglio di stile XSLT), ma comporterebbe

un costo computazionale maggiore. Nella discussione seguente indicheremo

con ‘posizione di un nodo’ l’indice del vettore dei puntatori all’interno del

Vtree(cap.3.3) associato al documento Vn.

5.1 Markup delle differenze

Per illustrare gli elementi ed attributi usati per esprimere le differenze fac-

ciamo riferimento all’esempio del capitolo precedente. La riapplicazione

all’esempio produce:

<?xml version="1.0"?><libro xmlns:diff="http://www.Ndiff.org" diff:stato="modificato">

<capitolo data="25 feb 2007"><titolo> Ndiff un approccio natuale al diff di documenti XML </titolo>

73

NMERGE:MOTORE DI MARKUP DEI CAMBIAMENTI

<para diff:stato="upgrade"> Primo approccio a livellonaturale sul diff di documenti </para><para> Ndiff risulta modulare, quindi estremamente estendibile. </para>

</capitolo><capitolo informazioni="completato">

<titolo> Secondo capitolo, descrizione formale dell algoritmo </titolo><sezione>

<para diff:stato="downgrade"> Il nostro approccio eestremamente modulare in quanto permette di inserireo rimuovere moduli </para>

</sezione></capitolo><diff:mossoDa id="19:14">

<capitolo><titolo> Markup del documento originale</titolo><sezione> Un secondo modo di utilizzare il delta e per marcareil documento orginale in modo da evidenziare le modifiche</sezione>

</capitolo></diff:mossoDa><capitolo>

<titolo> Ricostruzione del documento Originale </titolo><sezione> In questo capitolo parliamo della riapplicazionedel delta al documento originale</sezione>

</capitolo><diff:mossoIn id="19:14">

<capitolo><titolo> Markup del documento originale</titolo><sezione> Un secondo modo di utilizzare il delta e per marcareil documento orginale in modo da evidenziare le modifiche</sezione>

</capitolo></diff:mossoIn><capitolo diff:stato="modificato">

<titolo> Conclusioni </titolo><sezione diff:stato="modificato">

La qualita nel delta di Ndiff risulta<diff:inserito>molto </diff:inserito>miglioredegli altri approcci.

</sezione></capitolo>

</libro>

Il markup relativo ai cambiamenti fa parte del namespace http://www.Ndiff.org

per non creare ambiguita con i dati gia presenti nel documento. Vediamo per

ogni operazione del delta le relative informazioni inserite:

74

5.1 Markup delle differenze

• Inserimento di un albero: L’intero albero viene inserito nel tag

<diff:inserito>...</diff:inserito>, e viene collocato nella giusta posi-

zione.

• Inserimento di un nodo: Ai nodi che diventeranno i figli del nodo

inserito verra aggiunto l’attributo diff:stato=‘downgrade’.

• Cancellazione di un albero: L’intero albero cancellato viene inserito

nel tag <diff:cancellato>...</diff:cancellato> e viene lasciato nella sua

posizione.

• Cancellazione di un nodo: Ai nodi figli del nodo che verra cancellato

verra aggiunto l’attributo diff:stato=‘upgrade’.

• Spostamento di un albero: Lo spostamento di un sotto-albero del

documento corrisponde a due operazione del delta, deleteTree e insert-

Tree legate insieme dal valore di un attributo. La posizione iniziale del-

l’albero mosso viene segnata con in tag <diff:mossoIn id=‘19:14’>...</diff:mossoIn>,

la nuova posizione dell’albero nel documento viene segnata con il tag

<diff:mossoDa id=‘19:14’>...</diff:mossoDa>.

• Aggiornamento di nodo elemento: L’aggiornamento di nodi ele-

mento prevede l’inserimento, l’aggiornamento o la cancellazione degli

attributi del nodo. Per ora non e stato previsto nessun tipo di markup

per queste operazioni.

• Aggiornamento di nodo a contenuto testuale: Vengono segna-

te le stringhe inserite e cancellate nel nodo rispettivamente con i tag

<diff:inserito>...</diff:inserito> e <diff:cancellato>...</diff:cancellato>.

Ognuna delle operazioni precedenti, aggiunge sul percorso cha va dal nodo a

cui si riferisce fino alla radice del documento, l’attributo diff:stato=modifica-

to. Questo per indicare che e avvenuto un cambiamento nel suo sotto-albero.

Segue che se i documenti non sono identici(il delta non e vuoto) la radice del

documento Vn→n+1 avra sempre l’attributo diff:stato=‘modificato’.

75

NMERGE:MOTORE DI MARKUP DEI CAMBIAMENTI

Figura 5.1: Applicazione delle informazioni di markup alla versione Vn perottenere Vn→n+1

5.2 Inserimento del markup relativo alle dif-

ferenze

Il problema principale nell’inserire il markup dei cambiamenti relativo alle

operazioni descritte nel delta riguarda la non corrispondenza tra il documen-

to che si aspetta l’operazione n e il documento effettivo su cui deve essere

applicata.

Infatti l’operazione n verra applicata su un documento che contiene il mar-

kup dei cambiamenti inserito dalle n-1 operazioni precedenti e che quindi

76

5.2 Inserimento del markup relativo alle differenze

avranno modificato la struttura del documento in un modo diverso da quello

che si aspetta l’operazione. Per chiarezza in fig.5.1 mostriamo l’evoluzione

del documento durante il progressivo inserimento delle informazioni di cam-

biamento contenute nel delta. I problemi maggiori sono dati dalle operazioni

che modificano la struttura dell’albero. In particolare, oltre ai nodi elemento

inseriti a causa del markup(ins,del,ecc..), rimangono nell’albero le parti di

documento che dovrebbero essere rimosse(cancellazione di sotto-alberi) che

ne cambiano profondamente la struttura. Ricordiamo che le operazione de-

scritte nel delta identificano i nodi su cui operare attraverso la loro posizione,

data da una previsita sinistra dell’albero DOM ed equivalente all’indice del

vettore dei puntatori creato all’interno del relativo Vtree.

Per poter individuare correttamente i nodi a cui le operazioni si riferiscono,

dobbiamo trasformare i valori contenuti nel delta tenendo conto delle possi-

bili operazioni di markup presenti nell’albero al momento dell’applicazione

dell’operazione. L’idea e di mantenere la struttura di accesso ai nodi(il vetto-

re dei puntatori), simile al caso dell’applicazione semplice vista nel capitolo

precedente. Nelle sezioni successive vediamo il procedimento per inserire il

markup relativo ai diversi tipi di operazione esprimibili nel delta.

5.2.1 Inserimento di un nodo

L’applicazione dell’operazione di inserimento di un nodo, rimane identica al

caso semplice(cap.4.2.1). Il markup relativo all’inserimento consiste nell’ag-

giunta dell’attributo diff:stato=‘downgrade’ a tutti i suoi figli, in quanto que-

sti scenderanno di un livello nella struttura dell’albero. In fig.5.2 vediamo un

esempio dell’applicazione dell’operazione di inserimento, dove viene inserito il

nodo ‘1’ e ai nodi ‘D’ e ‘G’ viene aggiunto l’attributo diff:stato=‘downgrade’.

Notiamo che questa operazione lascia la struttura dell’albero uguale al caso

semplice in quanto le informazioni di markup vengono aggiunte come attri-

buti.

Tuttavia, nell’effettuare l’inserimento dobbiamo ricalcolare i valori p,pf,pc

77

NMERGE:MOTORE DI MARKUP DEI CAMBIAMENTI

Figura 5.2: Un’esecuzione di operazione insert di un nodo. I nuovi figli delnodo inserito vengono marcati come downgraded

e nc che dovranno considerare le possibili operazioni di markup dei cam-

biamenti aggiunte da operazioni precedenti. Le funzioni di trasformazione

sono:

• p′ = p, la posizione in cui inserire il nodo e uguale, in quanto dipende

dal vettore dei puntatori che e mantenuto uguale al caso di applicazione

semplice.

• pf ′ = pf , la posizione del nodo padre e corretta perche fa riferimento

al vettore dei puntatori.

• pc′ = pc + c, la posizione come figlio viene incrementata di un valore

c, pari al numero di nodi di markup relativi alle cancellazioni di nodi

presenti come figli di pf la cui posizione e minore di pc.

• nc′ = nc + d, il numero di figli da adottare viene aumentato di una

costante d rappresentante i nodi segnati come cancellati il cui indice

appartiene all’intervallo [pc + 1, pc + nc].

78

5.2 Inserimento del markup relativo alle differenze

Figura 5.3: Un’esecuzione di operazione insert di un albero.

Le costanti c e d vengono motivate dalla condizione di non considerare i nodi

segnati come cancellati nell’albero. Notiamo che se le costanti sono nulle, ci

riconduciamo all’applicazione semplice.

5.2.2 Inserimento di un albero

Il markup relativo all’inserimento di un sotto-albero, consiste nell’introdurre

il nodo diff:inserito tra il sotto-albero e il contesto. I nodi del sotto-albero

inserito verranno considerati nella numerazione, eccetto il nodo diff:inserito.

Un esempio e dato in fig.5.3, dove nel vettore dei puntatori non viene con-

siderato il nodo di markup ins. Le funzione di trasformazione degli indici

sono:

• p′ = p, la posizione in cui inserire l’albero rimane uguale come nel caso

di inserimento di un nodo.

• pf ′ = pf , la posizione del nodo padre e corretta perche fa riferimento

al vettore dei puntatori.

79

NMERGE:MOTORE DI MARKUP DEI CAMBIAMENTI

Figura 5.4: Un’esecuzione di operazione delete di un nodo.

• pc′ = pc + c, la posizione come figlio viene incrementata di un valore c

uguale ai nodi di markup relativi ai nodi cancellati presenti come figli

di pf , la cui posizione e minore di pc.

5.2.3 Cancellazione di un nodo

La cancellazione di un nodo avviene allo stesso modo del caso semplice(cap.4.2.3).

Il markup relativo all’operazione consiste nell’aggiungere a tutti i figli del no-

do rimosso l’attributo diff:stato=upgrade. Questo indica che i figli del nodo

sono saliti di livello nell’albero. La fig.5.4 mostra un esempio di cancellazione

di un nodo, dove viene cancellato il nodo ‘B’. Di conseguenza i sotto-alberi

radicati in ‘D’ e ‘G’ salgono di un livello e gli viene aggiunto l’attributo

diff:stato=upgrade. Questa operazione lascia la struttura dell’albero ugua-

le al caso semplice in quanto le informazioni di markup vengono aggiunte

come attributi. La funzione di trasformazione per l’unico valore necessario

alla cancellazione e p′ = p, cioe la posizione del nodo da cancellare rimane

identica al caso semplice in quanto si fa riferimento al vettore dei puntatori.

80

5.2 Inserimento del markup relativo alle differenze

Figura 5.5: Un’esecuzione di operazione delete di un albero.

5.2.4 Cancellazione di un albero

Il markup relativo alla cancellazione di un sotto-albero viene effettuato in-

serendo il nodo diff:cancellato tra il sotto-albero da cancellare e il contesto.

Il sotto-albero da cancellare rimane nell’albero del documento, ma i suoi

nodi non verranno indicizzati dal vettore dei puntatori. Questo ci permet-

tera di far coincidere le posizioni dei nodi al caso dell’applicazione semplice.

L’esempio in fig.5.5 mostra come i nodi dell’albero cancellato non vengano

piu considerati dal vettore dei puntatori. La funzione di trasformazione per

l’unico valore necessario alla cancellazione dell’albero e p′ = p, cioe la posi-

zione della radice dell’albero da cancellare rimane identica al caso semplice

in quanto si fa riferimento al vettore dei puntatori.

5.2.5 Aggiornamento di un nodo

Il markup relativo all’aggiornamento di un nodo e l’operazione piu complessa.

Distinguiamo i casi tra aggiornamento di nodo elemento e aggiornamento di

nodo a contenuto testuale.

• Aggiornamento di nodo elemento: L’aggiornamento di un nodo

81

NMERGE:MOTORE DI MARKUP DEI CAMBIAMENTI

Figura 5.6: Aggiornamento di un nodo di testo.

elemento comporta l’inserimento, l’aggiornamento del valore o la can-

cellazione di un attributo del nodo. Attualmente queste operazioni non

vengono evidenziate.

• Aggiornamento di un nodo a contenuto testuale: Questa e una

delle operazioni piu complesse in quanto la struttura dell’albero cambia

in modo radicale(fig. 5.6). In particolare il vecchio nodo di testo si tra-

sforma in un sotto-albero a causa delle informazioni di markup inserite.

L’aggiornamento consistera nel dividere il nodo di testo in tanti nodi

di testo piu piccoli, determinati dalle operazioni da applicare. I nuovi

nodi di testo ottenuti potranno avere come padre, o un nodo di markup

di cambiamento che identifica se la stringa contenuta e stata inserita

o cancellata, o il padre dell’ex-nodo di testo(parti di testo invariate).

Durante l’aggiornamento e importante fare attenzione al modo di cal-

colare l’offset da cui partire per inserire o cancellare le sotto-strighe, in

particolare calcoleremo l’offset in base ai nodi di testo che sono segnati

82

5.2 Inserimento del markup relativo alle differenze

come inseriti e a quelli che rappresentano parti invariate. Nel vettore

dei puntatori viene lasciata una posizione che indica l’ex-posizione del

puntatore al nodo di testo.

La funzione di trasformazione per l’unico valore necessario all’aggiornamento

del nodo e p′ = p, cioe la posizione del nodo da aggiornare rimane identica

al caso semplice in quanto si fa riferimento al vettore dei puntatori.

83

NMERGE:MOTORE DI MARKUP DEI CAMBIAMENTI

84

Capitolo 6

Un’applicazione di Ndiff:LIBRA

Vediamo in questo capitolo l’utilizzo di Ndiff in un’applicazione reale. L’ap-

plicazione realizzata e un’interfaccia grafica che usa Ndiff come core per

effettuare il calcolo delle differenze tra due DDL(Disegno di Legge). L’appli-

cazione realizzata, soprannominata LIBRA, e schematizzata in fig.6.2.

6.1 Contesto

LIBRA si occupa di rilevare le differenze tra versioni diverse di un DDL.

Per capirne l’applicazione schematizziamo il procedimento formale che porta

all’approvazione di una legge.

Il procedimento legislativo statale per le leggi ordinarie e disciplinato nella

parte II della Costituzione al titolo I, sez II dagli artt. 71-74 della Costi-

tuzione e dai regolamenti parlamentari.Questo procedimento consta di tre

fasi:

• Fase dell’iniziativa: La fase dell’iniziativa consiste nell’esercizio da

parte di determinati soggetti del potere di sottoporre progetti di legge

al Parlamento. La Costituzione riconosce tale potere:

– al Governo

– ai membri del Parlamento

85

UN’APPLICAZIONE DI NDIFF: LIBRA

– al corpo elettorale (che puo essere esercitata attraverso la presen-

tazione alle Camere da una proposta sottoscritta da almeno 50.000

elettori)

– ai Consigli Regionali

– al Consiglio Nazionale dell’Economia e Lavoro

• Fase della discussione e della votazione:

La seconda fase del procedimento legislativo comincia con l’assegnazio-

ne da parte del presidente della camera cui e pervenuto il progetto di

legge alla commissione parlamentare competente ‘rationae materiae’.

La commissione parlamentare opera diversamente a seconda della ‘se-

de’ in cui viene autorizzata a operare. La commissione parlamentare

incaricata di esaminare il progetto di legge puo operare in:

– Sede referente: si tratta della sede in cui le commissioni opera-

no seguendo il cosiddetto ‘procedimento legislativo ordinario’, in

esso si prevede una discussione sul testo nel suo complesso seguita

da una discussione del testo articolo per articolo.Alla discussione

segue un voto sul progetto di legge.La commissione ha in tale sede

il compito di preparare i documenti( testo del progetto di legge e

relazioni) su cui lavorera poi piu accuratamente prima una e poi

l’altra camera del parlamento.

– Sede legislativa:la commissione che opera in sede legislativa (si

tratta di un procedimento speciale) si occupa della discussione,

della votazione e della approvazione del progetto di legge estromet-

tendo completamente il parlamento dai lavori. E sempre ammessa

durante i lavori della commissione la domanda di ‘rimessione in

assemblea’ del progetto di legge.

– Sede redigente:e la seconda procedura speciale prevista dai re-

golamenti di camera e senato; la commissione ha gli stessi compiti

86

6.1 Contesto

che aveva quando operava in sede referente con l’agiunta che la sua

votazione sui singoli articoli del progetto di legge assume caratte-

re di definitivita, ed il testo che viene presentato alla camera sara

votato nella sua interezza (senza quindi procedere alla votazione

articolo per articolo)

Il procedimento legislativo ordinario continua con l’assegnazione del

progetto di legge al presidente di una delle camere del parlamento il

quale permette la discussione, la votazione articolo per articolo ed infine

la votazione finale sull’intero progetto di legge. Qualora la maggioranza

dei presenti in aula abbiano votato favorevolmente il disegno di legge si

intende approvato e passa all’altra camera, la quale se vota favorevol-

mente al progetto senza apportarvi modifiche fa si che sia completata

la fase deliberativa.

• Fase della promulgazione e della pubblicazione

La terza ed ultima fase e quella che attiene alla produzione degli effetti

normativi della legge e riguarda la promulgazione e la pubblicazione.

La promulgazione deve avvenire entro 30 giorni dall’approvazione parla-

mentare o in un termine minore se entrambi la Camere, a maggioranza

assoluta, ne dichiarino l’urgenza (Art.73 della Costituzione) e spetta

al Presidente della Repubblica. Subito dopo la promulgazione ,e co-

munque entro 30 giorni dalla stessa, la legge deve essere pubblicata.

Quest’ultima fase vede l’intervento del Ministro della Giustizia, depo-

sitari del sigillo dello Stato. Una volta posto il sigillo alla legge, essa

viene pubblicata sulla Gazzetta ufficiale.

LIBRA e il tramite che fornisce il supporto dei cambiamenti nel passaggio dei

DDL da una camera all’altra, mettendo in evidenza le modifiche apportate da

ogni camera. Le differenze tra due DDL vengono riportate su un documento

TAF(Testo a Fronte), formato da due colonne, in cui a sinistra viene messo

il testo originale e a destra il testo modificato(fig.6.1).

87

UN’APPLICAZIONE DI NDIFF: LIBRA

Figura 6.1: Esempio di testo a fronte.

88

6.2 LIBRA

Figura 6.2: Funzionamento di LIBRA

6.2 LIBRA

LIBRA e un’interfaccia scritta in PHP che prende in input due versioni di

un disegno di legge e restituisce un documento TAF(Testo a Fronte), dove

attraverso una visualizzazione a due colonne, vengono riportate le differenze

riscontrate. Lo schema di esecuzione e riportato in fig.6.2 in cui partendo

dalle versioni Vn e Vn+1 viene applicato l’algoritmo Ndiff producendo il docu-

mento ∆. A questo punto il documento Vn e il ∆ vengono passati al motore

Nmerge per produrre il documento Vn→n+1 rappresentante in XML il docu-

mento Vn dove sono state aggiunte le informazioni di cambiamento(cap.5).

Per produrre il formato testo a fronte voluto, processiamo attraverso un foglio

di stile il documento Vn→n+1 ottenendo un file HTML che mette in evidenza

le differenze. Notiamo che la creazione del documento finale e indipendente

dall’algoritmo Ndiff e dall’applicativo Nmerge, infatti dipende sono dal foglio

di stile con il quale processiamo il documento Vn→n+1. Questo ci permette

di cambiare la visualizzazioni dei risultati modificando solo il foglio di stile.

89

UN’APPLICAZIONE DI NDIFF: LIBRA

90

Capitolo 7

Conclusioni

L’algoritmo Ndiff ha come punti di forza la modularita del procedimento,

che ci permette di aggiungere o togliere delle fasi e la parametrizzazione di

queste attraverso dei valori che esprimono la concezione umana di confron-

to. Questo modo di procedere, ci permette di scegliere un tipo di soluzione

delta variando i parametri delle fasi dell’algoritmo e attivando, escludendo

o cambiando l’ordine di queste. Inoltre Ndiff fornisce un delta molto detta-

gliato, andando a specificare sia l’inserimento/cancellazione di singoli nodi

che eventuali modifiche all’interno di nodi testuali. Grazie alla sua parame-

trizzazione, Ndiff diviene adattabile ad una molteplicita di contesti fornendo

una forte base sulla quale poter costruire sistemi di versionamento per diversi

tipi di applicazione. A livello implementativo abbiamo realizzato i tre tool

riportati in questa tesi, Ndiff, Napply ed Nmerge, oltre l’applicazione LIBRA

che come detto si basa sui tool precedenti. In LIBRA, le fasi usate da Ndiff

sono quelle descritte in questa tesi, nulla toglie pero una futura espansione

dell’algoritmo aggiungendo nuove fasi per poter individuare una maggiore

varieta di operazioni rilevanti nel contesto dei DDL.

7.1 Espansione future

Possibili espansioni dell’algoritmo saranno la realizzazione di una molteplicita

di moduli, capaci di individuare nuovi tipi di operazione. Questo e possibile

91

CONCLUSIONI

grazie all’indipendenza logica dei vari moduli, in quanto ogni modulo prende

in input una relazione sui nodi(eventualmente vuota) e i due Vtree rappre-

sentanti i documenti da confrontare e produce in output delle nuove relazioni

tra i nodi delle due versioni. La modularita permettera di inserire o togliere

dei moduli adattando il tool alle tipologie di modifica che vogliamo rilevare.

Un esempio di modulo che puo venir creato e il caso della rilevazione del par-

tizionamento di un nodo. Infatti si potrebbe voler identificare l’operazione

di strutturazione di un nodo testo, cioe il caso in cui un nodo di testo del

documento Vn diviene un albero strutturato nella versione Vn+1 attraverso

l’aggiunta di tag. Inoltre e doveroso un porting in java di Ndiff, Napply e

Nmerge, attualmente implementati in PHP, per dotare i tool di una maggiore

portabilita.

92

Bibliografia

[Vitali et al,95] Vitali F., Durand D., ‘Using Versioning to Provide Collabo-

ration on the WWW’,

The World Wide Web Journal, 1(1), 1995, 37-50.

[Vitali,99] Vitali F., ‘Versioning Hypermedia’,

ACM Computing Surveys, 31(4), 1999, article n. 24, pp. 7.

[Schirinzi,04] Schirinzi M., ‘Gestione dei cambiamenti per documenti digitali

sul web’.

Tesi , Universita degli studi di Bologna, Facolta di Scienze Matematiche

Fisiche e Naturali, Dipartimento di Informatica , 2004.

[Chawathe,99] Sudarshan S.Chawathe, ‘Comparing Hierarchical Data in Ex-

ternal Memory’,

Proceedings of the 25th International Conference on Very Large Data

Bases, Sept. 1999.

[Robin La Fontaine,2001] Robin La Fontaine, ‘A Delta Format for XML:

Identifying changes in XML and representing the changes in XML’,

XML Europe, 2001.

[Kuo-Chung,79] K.C. Tai, ‘The tree-to-tree correction problem’,

In Journal of the ACM, 26(3), pages 422-433, july 1979.

[Selkow,77] S. M. Selkow, ‘The tree-to-tree editing problem’,

Information Processing Letters, 6, pages 184-186,1977.

93

BIBLIOGRAFIA

[Hirschberg,75] D. S. Hirschberg, ’A linear space algorithm for computing

longest common sub-sequences’,

Communications of the ACM, 18 (1975), pp. 341-343.

[Conklin,87] Conklin E.J., ‘Hypertext: An Introduction and Survey’,

IEEE Computer, 20, 1987, 17-41.

[Maioli et al,94] Maioli C., Sola S., Vitali F., ‘The Support for Emergence

of Collaboration in a Hypertext Document System’

in: ACM CSCW’94 Workshop on Collaborative Hypermedia Systems,

Chapel Hill (NC), GMD Studien n. 239, ACM, 1994

[Chawathe,97] S. Chawathe, H. Garcia-Molina, ‘Meaningful Change Detec-

tion in Structured Data’,

Proceedings of the ACM SIGMOD International Conference on

Management of Data, June 1996

[Chawathe,96] S. Chawathe, A. Rajaraman, H. Garcia-Molina and J. Wi-

dom, ‘Change Detection in Hierarchically Structured Information’,

SIGMOD,vol.25,no.2,pp.493-504, 1996

[Kaizhong,90] Kaizhong Zhang and Dennis Shasha, ‘Fast algorithms for the

unit cost editing distance between trees’,

Journal of Algorithms, 11(6), pp. 581-621, 1990.

[Kaizhong et al,89] Kaizhong Zhang and Dennis Shasha, ‘Simple Fast Algo-

rithms for the Editing Distance Between Trees and Related Problems’,

SIAM Journal of Computing, 18(6), pp.1245-1262, 1989.

[XMLDiff] Logilab XMLDiff.

Project Website: http://www.logilab.org/projects/xmldiff/ .

[Shu yao et al,01] Shu-Yao Chien, Vassilis J. Tsotras, and Carlo Zaniolo,

‘Version management of XML documents’,

Lecture Notes in Computer Science, 2001.

94

BIBLIOGRAFIA

[Barnard et al,95] David T. Barnard, Gwen Clarke, and Nicolas Duncan,

‘Tree to tree Correction for Document Trees’,

Technical report 95-372,Department of Computing and Information

Science, Queen’s University, Kingston, 1995.

[Eugene W. Myers.,86] Eugene W. Myers., ‘An O(ND) difference algorithm

and its variations’,

In Algorithmica, 1986.

[Berk,96] Berk, E., ‘HtmlDiff: A Differencing Tool for HTML Documents’,

Student Project, Princeton University,1996

[A. Apostolico et al,97] A. Apostolico and Z. Galil, ‘Pattern Matching Algo-

rithms’,

Oxford University Press, 1997.

[V.I.Levenshtein,66] V. I. Levenshtein , ‘Binary codes capable of correcting

deletions, insertions,and reversals’,

Cybernetics and Control Theory 10, pages 707-710, 1966.

[R. A. Wagner et al,74] R. A. Wagner and M. J. Fischer, ‘The string-to-

string correction problem’,

Jour. ACM 21, pages 168-173, 1974

[GNU diff] GNU diff, FSF. GNU diff, www.gnu.org/software/diffutils/diffutils.html

[XyLemme] XyLemme, Xyleme Project, http://www-rocq.inria.fr/verso/

[G.Cobena et al] G. Cobena, S. Abiteboul, and A. Marian, XyDiff, ‘tools for

detecting changes in XML documents’

[DeltaXML] DeltaXML, ‘Change control for XML in XML.’,

http ://www.deltaxml.com/

[ISA] Vitali F., Creating sophisticated Web sites using well-know interfaces’

MCI Internation Conference 2003’, Creta(Greece), june 2003

95