Implémentation d'un algorithme d'unification pour les termes

3.1 Article de Hubert Comon (On unification of terms with integer exponents) . . . 7 ..... `a l'article d'Hubert Comon) [1]. ...... beep (1175 ,1000) ; beep (1868 ,250) ;.
884KB taille 7 téléchargements 30 vues
20 Juin 2008

Impl´ ementation d’un algorithme d’unification pour les termes sch´ ematis´ es ` a exposants entiers Rapport de projet de sp´ecialit´e Mathieu Guillame-Bert et Gabriel Synnaeve

1

Table des mati` eres 1 Introduction

3

2 Conception et Architecture 2.1 Technologies . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2.2 Architecture du code . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2.3 Parsing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

5 5 5 6

3 Unification des termes avec exposants entiers 3.1 Article de Hubert Comon (On unification of terms with integer exponents) . . . 3.2 Validation du fonctionnement . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

7 7 7

4 R´ esolution des contraintes num´ eriques 9 4.1 Pr´esentation du probl`eme . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9 4.2 D´eveloppement de notre propre algorithme de r´esolution . . . . . . . . . . . . . . 9 4.3 Automates pour l’arithm´etique de Presburger . . . . . . . . . . . . . . . . . . . . 11 5 Conclusions

14

6 Annexes 6.1 Manuel Utilisateur - man . . . . . . . . . . . 6.2 Diagramme de classes . . . . . . . . . . . . . 6.3 Exemple de sortie g´en´er´ee avec l’option -latex 6.4 Code source . . . . . . . . . . . . . . . . . . . 6.5 Fichiers d’entˆete . . . . . . . . . . . . . . . . 6.5.1 automata.h . . . . . . . . . . . . . . . 6.5.2 config.h . . . . . . . . . . . . . . . . . 6.5.3 display.h . . . . . . . . . . . . . . . . . 6.5.4 exception.h . . . . . . . . . . . . . . . 6.5.5 main.h . . . . . . . . . . . . . . . . . . 6.5.6 synnaeve.guillame.bert.h . . . . . . . . 6.5.7 unification.h . . . . . . . . . . . . . . 6.6 Fichiers de code . . . . . . . . . . . . . . . . . 6.6.1 automata.h . . . . . . . . . . . . . . . 6.6.2 config.h . . . . . . . . . . . . . . . . . 6.6.3 display.h . . . . . . . . . . . . . . . . . 6.6.4 exception.h . . . . . . . . . . . . . . . 6.6.5 main.h . . . . . . . . . . . . . . . . . . 6.6.6 parser.h . . . . . . . . . . . . . . . . . 6.6.7 parser.ll . . . . . . . . . . . . . . . . . 6.6.8 parser.yy . . . . . . . . . . . . . . . . 6.6.9 synnaeve.guillame.bert.h . . . . . . . . 6.6.10 unification.h . . . . . . . . . . . . . . 6.7 En chiffres . . . . . . . . . . . . . . . . . . . .

2

. . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . .

15 15 17 18 19 19 19 20 20 20 21 21 22 23 23 26 28 30 31 31 46 48 50 56 78

1

Introduction

L’unification est l’un des concept centraux de la logique des pr´edicats (logique du premier ordre). Elle consiste ` a trouver, pour deux termes t1 et t2 , la substitution σ (unificateur le plus g´en´eral) tel que σ(t1 ) = σ(t2 ). De mani`ere un peu plus intuitive, la r´esolution d’´equation est une forme d’unification. Il est ` a noter que, contrairement `a la plupart des ´equations que l’on a l’habitude d’utiliser, l’unification consid`ere les variables et les fonctions qu’elle traite ind´ependament de leurs natures (on ne consid`ere donc pas d’´eventuelles propri´et´es sur ces objets). Dans ce sens, l’unification ne pourra pas assimiler 1 ` a division(2, 2). L’unification “de base” ne traite que les variables, les fonctions d’arit´e fixe et les constantes (fonctions d’arit´e nulle). Sur cette grammaire, l’unification est d´ecidable : il est m´ecaniquement possible de calculer en temps fini s’il existe ou non un unificateur, et, dans le premier cas, de le calculer. Le but de notre stage a ´et´e d’impl´ementer une extension de cette grammaire par l’ajout et le support d’une syntaxe avec “exposants” (cette notion sera pr´ecis´e plus loin), ceci, bien sˆ ur, en gardant la d´ecidabilit´e. Cette forme d’extension de l’unification a d´ej`a ´et´e ´etudi´ee, mais n’a jamais ´et´e impl´ement´ee. Du moins, il n’y a pas de travaux d’impl´ementation connus ni de Nicolas Peltier, ni de nous-mˆeme. Pour cela, nous avons utilis´e les travail r´ealis´e par Hubert Comon en 1993 [1] sous le nom “On unification of terms with integer exponents” dans lequels il d´efini et analyse cette extension grammaticale, les i-terms. De mani`ere pratique, notre travail a ´et´e de reprendre son article, d’impl´ementer ce qu’il y a d´ecrit et de proposer une interface pour l’utilisateur (les r´esultats de l’unification n’´etant pas toujours utilisables directement - utilisation des automates de Presburger pour la r´esolution de contraintes sur les variables num´eriques). Le besoin de cette impl´ementation est venu du domaine de la preuve automatique. Voici quelques exemples simples d’unification et d’unification avec termes `a exposants entiers. Note : les variables sont en majuscules et les constantes en minuscules. f (X, a) = f (b, Y ) L’unification est possible avec X = b et Y = a. f (X, a) = g(b, Y ) L’unification est impossible car rien ne nous dit que f = g. f (X, Z) = g(f (Y ), h(X)) L’unification est possible avec X = f (Y ), Z = h(X) et Y libre. L’ajout des termes avec exposants entiers augmente la puissance du langage mais rend plus complexe la recherche de solution d’unification. Notation ` a exposant La notation suivante sera employ´ee pour d´esigner certaines formes : – u[v]p repr´esentera une s´equence u ayant une sous-s´equence v `a la position p.

3

– u[]N .v repr´esente le “d´epliage” de N fois u sur v. Exemple 1 La forme f (a, g(h(b))) pourra ˆetre assimil´ee `a u[v]p avec u = f (a, g(), v = h(b) et p = {2, 1}. Exemple 2 Si N = 1, u[]N .v revient ` a remplacer  par v dans u. Pour un N > 1 , u[]N .v = u[]N −1 .(u[]1 .v) f (, a)2 .X = f (f (, a), a)1 .X = f (f (f (, a), a), a)0 .X = f (f (f (X, a), a), a) Note : Les N ne sont pas forcement d´efinis ie. ce sont des variables num´eriques libres (pour l’algorithme : dans N∗ ). Les contraintes qui apparaˆıtront au cours de l’unification permettront de d´efinir, dans le cas o` u il en existe, les valeurs possibles qu’elles peuvent prendre. f ()N 1 .Y = f ()N 2 .Y L’unification est possible avec N 1 = N 2 et Y libre. f ()N .a = f (f ())M .a L’unification est possible avec N = 2.M . f (g(f ())N .g(a)) = f (g(f (g())))M .a L’unification est possible avec N = M = 1 ou avec N = 2.H + 1 et M = H + 1, ou H est une variable libre (dans N∗ ) .

4

2

Conception et Architecture

Avant-propos : Il peut ˆetre tr`es int´eressant pour le futur d´eveloppeur de se documenter via la documentation HTML Doxygen du projet qui contient nos commentaires sur les attributs et m´ethodes des classes et qui donne des diagrammes de classe clickables.

2.1

Technologies

Pour l’impl´ementation de l’algorithme, nous avons choisi d’utiliser le langage C++ pour : sa vitesse, le support de la programmation orient´ee objet, la disponibilit´e d’une biblioth`eque d’analyse lexicale et syntaxique (flex/bison) simple `a utiliser et, surtout, pour l’exp´erience que nous en avions d´ej` a. L’application produite se pr´esente donc sous la forme d’un unique ex´ecutable, fonctionnant en mode console, supportant une syntaxe d’option `a la unix et n’utilisant aucune fonctionnalit´e non portable. Notre programme a ´et´e test´e sous GNU/Linux (noyau 2.6), Mac OS X (10.5), et Windows (XP, Vista). L’injection et la r´ecup´eration de donn´ees se font par l’entr´ee et la sortie standards, dans un format textuel facilement exploitable (utilisation facile par des codes externes). L’ensemble des options disponibles sont d´ecrites dans la page du man et par l’appel du binaire avec l’option -help (-h). Un autre mode de sortie a ´egalement ´et´e mis en place : avec l’option -latex (-l), le programme donne les r´esultats avec la syntaxe latex (utilisation simplifi´ee pour les publications). Un exemple complet est donn´e en fin de rapport.

2.2

Architecture du code

De mani`ere pratique, le code est divis´e comme suit : – Gestion des options – Affichage – Erreurs – Parseur – Unificateur – Analyseur d’arithm´etique de Presburger (Automate) L’architecture modulaire est bas´ee sur le concept d’objet. Ceux-ci sont imbriqu´es de fa¸con `a garantir le fonctionnement du programme. Un d´eveloppeur ext´erieur au projet pourra donc reprendre notre librairie et interfacer les modules `a sa convenance. Par exemple, il pourra ne pas acqu´erir les donn´ees ` a partir du parser mais directement construire les ´equations grˆace aux fonctions pr´evues ` a cet effet. On trouve un diagramme de classes du projet en annexe. Pour illustrer ce propos, voici le contenu du fichier “main.cpp”, on pourra utiliser la documentation pour plus d’information sur l’utilisation des fonctions. /* *

* Main f i l e o f t h e u n i f i c a t o r * @author Mathieu G u i l l a m e−B e r t and G a b r i e l Synnaeve */

# i n c l u d e # i n c l u d e # i n c l u d e # include " config .h" # include " exception .h" # include " display .h" # include " parser .h" # include " unification .h"

5

int

main ( int { try

argc ,

char

* argv [ ] )

{ C o n f i g u r a t i o n * config = g l o b c o n f i g = new C o n f i g u r a t i o n ( argc , argv ) ; Display : : Head ( config ) ; Parser * parser = new Parser ( config ) ; Unification * unification = new Unification ( config , parser ) ; u n i f i c a t i o n −>r u n ( ) ; Display : : displayResult ( unification ) ; Display : : Foot ( config ) ; } c a t c h ( e x c e p t i o n& e ) { c e r r 0 et b ≥ 0 : un arc de M vers N portant les valeurs [a; b] avec N ← [1; +∞] et M ← [1; +∞] – Si a = 0 : si b ≥ 0 ⇒ N = b, sinon ´echec. – P = N + M , 3 arcs cond un peu sp´eciaux : on cr´ee un noeud ◦ et on fait : – un arc de N vers ◦ portant [1; 0] – un arc de N vers ◦ portant [1; 0] – un arc de ◦ vers P portant [1; 0] Nota : cel`a peut ˆetre vu comme un “arc `a 3 extr´emit´es”. Quand on a des valeurs non enti`eres dans [min ; max] on prend min = E(min)+1 et max = E(max). It´eration : Chercher puis traiter les cycles 1. On recherche les cycles et dans le cas d’un cycle 2. On ´ecrit l’´equation qu’il faut respecter pour que le cycle soit r´ealisable 3. On la r´esoud, 2 cas : – si elle a des solutions : on les consid`ere (mise `a jour des [min ; max] des sommets du cycle), on ´elimine le cycle en le r´eduisant aux seuls points qui ont un contact avec le reste du graphe. – si elle n’a pas de solution : ´echec. Propapagation des contraintes On propage les contraintes en regardant pour chaque noeud les contraintes qui lui arrivent par les arcs. On n’a plus de cycles (ils ont ´et´e trait´es ci-dessus), on ajuste donc maintenant les [min ; max] de chaque noeud pour respecter les noeuds qui y arrivent. Par un parcours particulier de l’arbre et un syst`eme de marquage sp´ecifique pour les noeuds “´equation”, on peut ensuite d´eterminer quelles variables choisir pour articuler l’ensemble de solution (et n’en oublier aucune). On en d´eduis ainsi un sous-ensemble de variable avec pour chacune ses contraintes propres qui d´efinirons toutes les autres variables du syst`eme d’´equation. On obtient de plus une id´ee de la dimension de la solution (nombre de variables dans ce sous ensemble). Exemple bloquant :

10

X

U

V Y

qui correspond ` a 

U =X +Y V = a.X + b.Y

sans aucune relation entre X, Y, U, V deux `a deux (symbolis´e par - - - -) Explication : Si il y a une relation entre 2 membres de ce type de cycle mais qu’elle n’est pas encore une fois de ce type l` a, on peut commencer par ´eliminer ce cycle de type“traitable” et cel`a changera la forme de ce cycle. Si on se retrouve avec une forme qui correspond vraiment ` a ce sch´ema (donc sans relations 2 ` a 2) avec une alternance de noeuds normaux et ◦, nous n’avons pas trouv´e de moyen de r´eduire ce cycle. Au mieux on retourne le probl`eme. Nous avons quand mˆeme produit un peu de code pour cet algorithme : ce travail de recherche n’a pas ´et´e totalement inutile car cette transformation du syst`eme d’´equation en graphe peut servir `a chercher le meilleur affichage (dans le sens param´etrage) possible pour les solutions, quand elles existent.

4.3

Automates pour l’arithm´ etique de Presburger

Nous avons donc arr´et´e nos recherche sur cet algorithme et nous avons d´ecid´e (en vu des contraintes pr´esent´ees en introduction de cette partie) d’impl´ementer notre propre r´esolution de contraintes dans l’arithm´etique de Presburger via ce qui existait algorithmiquement : les automates pour la r´esolution de contraintes lin´eaires. Nous nous sommes document´es ([5], [6], [7]) sur le sujet et nous sommes principalement bas´e sur un article de Pierre Wolper et Bernard Boigelot [8] d´ecrivant la construction de tels automates. Nous avons des disjonctions de solutions qui sont des conjonctions d’´equations, nous les traitons donc s´epar´ement (une peut ˆetre r´ealisable et pas une autre). Chaque ´equation num´erique est mise sous la forme d’un automate qui permet tr`es facilement de dire si cette ´equation est r´ealisable. Ensuite, on parcourt tous les automate “en parall`ele” pour tester si les ´etats finaux sont accessibles avec un ensemble de transitions commun. Si c’est le cas, la solution est r´ealisable. Sinon, on l’´elimine de l’ensemble des solutions. Si cet ensemble se trouve vide `a la fin de la r´esolution des contraintes, l’unification ´echoue. Nous ne d´etaillerons pas ici les d´etails de la construction des automates, ce travail est tr`es bien effectu´e dans On the Construction of Automata from Linear Arithmetic Constraints [8] et document´e dans Doxygen. L’introduction au fonctionnement de notre impl´ementation de ces automates se fera par un exemple. Soit la solution (simplissime) :  N =2 M =1 11

Elle entraine la construction de ces automates : 0?

si

0

0?

1?

1

2

0?

Automate correspondant `a N = 2

0?

si

0?

0

1?

1

Automate correspondant `a M = 1 Les points d’interrogation remplacent un bit dont ne se soucie pas de la valeur. En effet, la construction des tableaux de bits de transition de taille ´egale au nombre de variables num´eriques permet une fusion (parcours en parall`ele) beaucop plus facile. Ici, leur parcours en parall`ele (en utilisant les mˆeme transitions) permet d’arriver aux ´etats finaux. Cette solution est donc r´ealisable.

En rajoutant la contrainte N = M +2, on obtient ce syst`eme-solution et un nouvel automate.   N =2 M =1  N =M +2

12

00

si

0

00

01

10

1

00, 11

2

01

Automate correspondant `a M = 1 Le parcours en parall`ele de ces 3 automates ne permet pas d’arriver `a un ´etat final pour tous `a un moment commun. Il n’y a donc pas de solution `a ce syst`eme-solution. Si c’est le seul r´esultat d’une unification, elle ´echoue.

13

5

Conclusions

L’impl´ementation de cette unification et des automates de r´esolution `a donc ´et´e r´ealis´ee, test´ee et valid´ee. Le r´esultat de notre travail se pr´esente finalement sous la forme d’un ex´ecutable et de son man, de ce rapport, du code source document´e et laiss´e disponible pour son ´evolution ou son utilisation en tant que librairie. Le fait d’avoir pu faire un peu de travail de recherche nous `a permis de ne pas nous enfermer uniquement dans l’impl´ementation et le suivi de travaux externes ; ce qui `a grandi notre int´erˆet pour ce sujet. L’ensemble du projet a donc ´et´e tr`es agr´eable `a mener, de par sa nature mais aussi grˆace au cadre de travail. Nous avons donc tir´e de ce projet une exp´erience tr`es enrichissante. PS : Nous continuerons ` a maintenir le code fonctionnel.

14

R´ ef´ erences [1] H. Comon, On Unification of Terms with Integer Exponents, Mathematical System Theory 28, 67 (1995). [2] L. Berman, The complexity of logical theories, j-THEOR-COMP-SCI 11, 71 (1980). [3] http ://coq.inria.fr, The coq proof assistant. [4] http ://stud4.tuwien.ac.at/ e0225855/presprover/presprover.html, Presprover - prove formulas of presburger arithmetic. [5] D. Cooper, Theorem proving in arithmetic without multiplication, in Machine Intelligence 7, edited by B. Meltzer and D. Michie, chap. 5, pp. 91–99, Edinburgh University Press, 1972. [6] P. Wolper and B. Boigelot, An automata-theoretic approach to presburger arithmetic constraints (extended abstract), in Static Analysis Symposium, Lecture Notes in Computer Science, pp. 21–32, Springer-Verlag, 1995. [7] F. Klaedtke, ACM Trans. Comput. Logic 9, 1 (2008). [8] P. Wolper and B. Boigelot, On the construction of automata from linear arithmetic constraints, in TACAS ’00 : Proceedings of the 6th International Conference on Tools and Algorithms for Construction and Analysis of Systems, pp. 1–19, London, UK, 2000, Springer-Verlag.

6 6.1

Annexes Manuel Utilisateur - man

15

UNIFICATOR(1)

2008

UNIFICATOR(1)

NAME unificator - unificator with Integer Exponents Terms

SYNOPSIS unificator [OPTIONS] [FILE]

DESCRIPTION A unificator which deal with integer exponents terms. If [FILE] is not given, the standard input is used to get data.

OPTIONS -help, -h Print a usage help message. -step, -s Pause on every step of the unification. -nopbv Do not apply Presburger automata verification. -beep, -b Emit a beep on every step of the unification and at the end -anniversary Emit a special beep on every step of the unification and at the end. -info, -i Print unification applied rules. -latex, -l Print the steps and the final result in latex syntax. -output, -o FILE Redirect standard output in a file.

BUGS Reporting Bugs Email bug reports to .

SEE ALSO unificator -help

June

17

1

6.2

Diagramme de classes

6.3

Exemple de sortie g´ en´ er´ ee avec l’option -latex

Initial set of equation (a = X ∨ b = f (X))

(a = X ∨ b = f (X)) R1 : s = x → x = s (X = a ∨ b = f (X)) R1 : f(x)=g(y) → ⊥ X=a End of computation Number of steps : 3 Computation time : 0 seconde(s) X=a

Unification Succeeds Number of main solution : 1 solution 1 X=a

6.4

Code source

6.5

Fichiers d’entˆ ete

6.5.1

automata.h

/*

* File : automata . h * Author : s n i p p y * * C r e a t e d on June 1 2 , 2 0 0 8 , 1 0 : 3 7 AM */

# ifndef # define

AUTOMATA H AUTOMATA H

# i n c l u d e # i n c l u d e class

Transition ;

class

Automata ;

class Groupe { public : l i s t a u t o s ; }; class State { public : Automata * automata ; bool si ; l i s t s t e p ; int value ; State ( int v , bool s , Automata *a ) ; void addTransition ( Transition * t ) ; ˜ State () ; v o i d d i s p l a y ( o s t r e a m &o ) ; }; class Transition { public : i n t * b i t s ; // 0 ou 1 ou −1 ( pour S t a t e * s t ; // o r i g i n a l s t a t e T r a n s i t i o n ( State * next , int * b ) ; void display ( int bits_size ) ; ˜ Transition () ; };

’? ’)

class StatePara { public : l i s t a c t i v e s ; }; class ExploPara { public : l i s t s t a t e P a r a ; }; class Automata { public : State * si ; int cvalue ; int nvars ; v e c t o r a ; int eqSize ; b o o l i s I n t e r s e c t ( A u t o m a t a * au , i n t s i z e ) ; A u t o m a t a ( C o n d i t i o n * n , s t d : : m a p * n u m v a r s ) ; Automata ( Condition * n) ; ˜ Automata () ; v o i d d i s p l a y ( o s t r e a m &o ) ; }; # endif

/*

AUTOMATA H

*/

19

6.5.2

config.h

# i f n d e f CONFIG H # d e f i n e CONFIG H # i n c l u d e # i n c l u d e using

namespace

std ;

class Configuration { public : enum

Write_Mode { NORMAL , LATEX , XML , HTML };

Write_Mode writeMode ; istream * inputdatas ; bool pauseEveryStep ; bool printRule ; bool NcanbeZero ; bool fileInput ; bool presBurgerVerif ; bool disjonction ; int beep ; static void printOptionInfo () ; static void printConsol () ; C o n f i g u r a t i o n ( int argc , char * argv [ ] ) ; ˜ Configuration () ; }; extern extern

ostream * mycout ; Configuration * globconfig ;

# endif

6.5.3

display.h

# i f n d e f DISPLAY H # d e f i n e DISPLAY H # include

" unification .h"

namespace { void void void void void void void void };

displayResult ( Unification * unification ) ; displayTime ( long atime ) ; Head ( Configuration * config ) ; Foot ( Configuration * config ) ; t e x E n d l ( s t d : : o s t r e a m& s ) ; t e x H s p a c e ( s t d : : o s t r e a m& s ) ; t e x D i ( s t d : : o s t r e a m& s ) ; beep ( int frec , int time ) ;

Display

s t d : : o s t r e a m& o p e r a t o r &p a t h ) ;

string text ; public : const char * what () const throw () ; OptionException ( string t ) ; ˜ OptionException () throw () ; }; class SytaxException : public exception { string text ; public : const char * what () const throw () ; SytaxException ( string t ) ; ˜ SytaxException () throw () ; }; # endif

6.5.5

main.h

6.5.6

synnaeve.guillame.bert.h

# i f n d e f SOLVER H # d e f i n e SOLVER H # i n c l u d e # i n c l u d e # include " unification .h" # i n c l u d e using namespace std ; namespace Solver { class Vertex ; class Edge ; class VariableSolution { public : bool seeoutside ; Node * definition ; }; class Edge { public : Vertex Vertex int a ; int b ; };

* n1 ; * n2 ;

class Vertex { public : l i s t i n ; l i s t o u t ; int variable ; int count ; int min ; int max ; b o o l s e t B o u n d s ( int min , int bool setBoundMin ( int min ) ; bool setBoundMax ( int max ) ; Edge bool };

max ) ;

* father ; visited ;

class Contribution { public : Vertex *v ; float a ; }; class SolverSolution {

:

public

Solution

21

public : Unification * unification ; VariableSolution * variableSolution ; unsigned int ndvar ; bool success ; v o i d d i s p l a y ( o s t r e a m &o ) ; bool check () ; }; class Graph { public : SolverSolution * solus ; Unification * unification ; bool success ; l i s t v e r t e x s ; l i s t e d g e s ; Graph ( Node * node , U n i f i c a t i o n * u n i f i c a t i o n ) ; bool explo ( Node * n ) ; SolverSolution * run () ; ˜ Graph () ; b o o l s e e k C y c l e ( l i s t &v e r , l i s t &e d ) ; void resetVisited () ; void print () ; Vertex * a d d V e r t e x ( int id ) ; E d g e * a d d E d g e ( V e r t e x * v1 , V e r t e x };

* v2 , i n t a , i n t b ) ;

}; # endif

6.5.7

unification.h

# i f n d e f UNIFICATION H # d e f i n e UNIFICATION H # include " parser .h" # include " config .h" # i n c l u d e class

Unification ;

class Solution { public : virtual void virtual bool };

d i s p l a y ( o s t r e a m &o ) = 0 ; check () = 0;

class VariableSolution { public : VariableSolution () ; bool seeoutside ; Node * definition ; l i s t d e f i n i t i o n c ; }; class SimpleSolution : public Solution { public : Unification * unification ; bool fail ; unsigned int ndvar ; unsigned int ndnumvar ; VariableSolution * variableSolution ; VariableSolution * numericalvariableSolution ; S i m p l e S o l u t i o n ( unsigned int ndvar , unsigned int ˜ SimpleSolution () ; v o i d d i s p l a y ( o s t r e a m &o ) ; bool check () ; };

ndnumvar , Unification

class Unification { public : Configuration * configuration ; Parser * parser ; bool result ; l i s t s o l u t i o n s ;

22

* unification ) ;

Unification ( Configuration * configuration , Parser * parser ) ; void run () ; N o d e * A p p l y R 0 ( N o d e * s t a r t=N U L L ) ; bool tryApplyR1 () ; bool tryApplyR2 () ; bool tryApplyR3 () ; bool tryApplyR4 () ; bool tryApplyR5 () ; Node * SetDisjunctiveSystem ( Node * start = NULL ) ; bool checkDefinition () ; v o i d d e b u g D i s p l a y ( o s t r e a m &s ) ; bool e x p l o D e f i n i t i o n ( Node *n , S i m p l e S o l u t i o n * s o l u t i o n ) ; bool verifValidPresburger ( Node *n ) ; ˜ Unification () ; static static static

int gcd ( unsigned int a , unsigned b o o l p r e f i x ( c o n s t l i s t &l 1 , c o n s t l i s t s i−>s t e p . f r o n t ( )−>b i t s ; i n t * m a s k 2 = a u−>s i−>s t e p . f r o n t ( )−>b i t s ; int i ; f o r ( i =0; ii d ] ] ) ) ) / 2 ; } e l s e i f ( t y p e i d ( * n )==t y p e i d ( C o n d N p l u s N ) ) { g 0 = ( d o u b l e ) ( t m p s t −>v a l u e − ( a [ 0 ] * b i t s [ ( * n u m v a r s ) [ n−>n 1−>i d ] ] + a [ 1 ] * b i t s [ ( * n u m v a r s ) [ ( ( C o n d N p l u s N * ) n )−>n 2−>i d ] ] + a [ 2 ] * b i t s [ ( * n u m v a r s ) [ ( ( C o n d N p l u s N * ) n )−>n 3−>i d ] ] ) ) / 2 ; } e l s e { // CondN g 0 = ( d o u b l e ) ( t m p s t −>v a l u e − ( a [ 0 ] * b i t s [ ( * n u m v a r s ) [ n−>n 1−>i d ] ] + a [ 1 ] * b i t s [ ( * n u m v a r s ) [ ( ( C o n d N * ) n )−>n 2−>i d ] ] ) ) / 2 ; } # i f d e f DEBUG // / ( * mycout ) # i n c l u d e # i n c l u d e # i n c l u d e ostream * mycout ; Configuration * globconfig ; /* * * P r i n t o p t i o n s h e lp message */ void

Configuration : : printOptionInfo () { ( * m y c o u t ) r h o t e r m ) rhoterm = true ; n d H o l e += ( * i t )−>n d H o l e ; i t ++; } }

void

Or : : c h e c k S o u n d n e s s A n d C a l c u l () { N o d e : : n d t e r m s ++; l i s t : : i t e r a t o r i t = b r a n c h s . b e g i n ( ) ; rhoterm = false ; ndHole = 0; w h i l e ( i t != b r a n c h s . e n d ( ) ) { ( * i t )−> c h e c k S o u n d n e s s A n d C a l c u l ( ) ; i f ( ( * i t )−>r h o t e r m ) rhoterm = true ; n d H o l e += ( * i t )−>n d H o l e ; i t ++; } }

void

Function : : checkSoundnessAndCalcul () { N o d e : : n d t e r m s ++; rhoterm = false ; ndHole = 0; i f ( p a r s e r −>f o n c t i o n t a b [ i d ] . a r i t y ==−1) p a r s e r −>f o n c t i o n t a b [ i d ] . a r i t y = ( i n t ) a r g u m e n t s . s i z e ( ) ; else i f ( a r g u m e n t s . s i z e ( ) ! = ( u n s i g n e d i n t ) p a r s e r −>f o n c t i o n t a b [ i d ] . a r i t y ) t h r o w S y t a x E x c e p t i o n ( " f o n c t i o n \ " " + p a r s e r −>f o n c t i o n t a b [ i d ] . n a m e + " \ " arities ") ; v e c t o r : : i t e r a t o r i t = a r g u m e n t s . b e g i n ( ) ; int numArg = 0; w h i l e ( i t != a r g u m e n t s . e n d ( ) ) {

38

with

several

( * i t )−> c h e c k S o u n d n e s s A n d C a l c u l ( ) ; i f ( ( * i t )−>r h o t e r m ) rhoterm = true ; n d H o l e += ( * i t )−>n d H o l e ; i f ( ( * i t )−>n d H o l e >0) { t h i s −>h o l e P o s i t i o n = ( * i t )−>h o l e P o s i t i o n ; t h i s −>h o l e P o s i t i o n −>p u s h _ f r o n t ( n u m A r g ) ; } i t ++; n u m A r g ++; } } void

Variable : : checkSoundnessAndCalcul () { N o d e : : n d t e r m s ++; rhoterm = false ; ndHole = 0; }

void

Equal : : checkSoundnessAndCalcul () { N o d e : : n d t e r m s ++; rhoterm = false ; ndHole = 0; n 1−>c h e c k S o u n d n e s s A n d C a l c u l ( ) ; n 2−>c h e c k S o u n d n e s s A n d C a l c u l ( ) ; i f ( n 1−>r h o t e r m ) rhoterm = true ; n d H o l e += n 1−>n d H o l e ; i f ( n 2−>r h o t e r m ) rhoterm = true ; n d H o l e += n 2−>n d H o l e ; }

void

Expo : : checkSoundnessAndCalcul () { N o d e : : n d t e r m s ++; rhoterm = true ; ndHole = 0; n 1−>c h e c k S o u n d n e s s A n d C a l c u l ( ) ; n 2−>c h e c k S o u n d n e s s A n d C a l c u l ( ) ; t h i s −>h o l e P o s i t i o n = n 1−>h o l e P o s i t i o n ; i f ( n 1−>n d H o l e ==0) { t h i s −>p r i n t ( c e r r ) ; throw SytaxException ( " Hole not found " ) ; } i f ( n 1−>n d H o l e >1) { t h i s −>p r i n t ( c e r r ) ; throw SytaxException ( " Too much hole " ) ; } i f ( n 1−>r h o t e r m ) // i f ( n2−>r h o t e r m ) { t h i s −>p r i n t ( c e r r ) ; t h r o w S y t a x E x c e p t i o n ( " Do not t o l e r a t e rho - t e r m s } i f ( n 1−>h o l e P o s i t i o n −>e m p t y ( ) ) { t h i s −>p r i n t ( c e r r ) ; throw S y t a x E x c e p t i o n ( " Do not }

tolerate

single

in

hole

iterated

in

} NodeIterator : : NodeIterator ( Node { t h i s −>m o d e = m o d e ; t h i s −>n = n ; t h i s −>d i r e c t = d i r e c t ; StackElement e (n , direct ) ; stack . push_back ( e ) ; allowUnderEqual = false ; } void

* n , N o d e ** d i r e c t , M o d e m o d e )

NodeIterator : : setUnderEqual ( bool u ) { allowUnderEqual = u ; }

const

l i s t &N o d e I t e r a t o r : : g e t P o s i t i o n ( )

39

part " ) ;

iterated

part " ) ;

{ return }

last . position ;

Node * NodeIterator : : next () { if ( stack . empty () ) return NULL ; StackElement e ; i f ( m o d e==N o d e I t e r a t o r : : B R E A D T H _ F I R S T ) { e = stack . front () ; stack . pop_front () ; } else { e = stack . back () ; stack . pop_back () ; } last = e ; i f ( t y p e i d ( * e . n )==t y p e i d ( A n d ) ) { l i s t : : i t e r a t o r i t = ( ( A n d * ) ( e . n ) )−>b r a n c h s . b e g i n ( ) ; w h i l e ( i t ! = ( ( A n d * ) ( e . n ) )−>b r a n c h s . e n d ( ) ) { s t a c k . p u s h _ b a c k ( S t a c k E l e m e n t ( * i t ,& * i t ) ) ; i t ++; } } e l s e i f ( t y p e i d ( * e . n )==t y p e i d ( O r ) ) { l i s t : : i t e r a t o r i t = ( ( O r * ) ( e . n ) )−>b r a n c h s . b e g i n ( ) ; w h i l e ( i t ! = ( ( O r * ) ( e . n ) )−>b r a n c h s . e n d ( ) ) { s t a c k . p u s h _ b a c k ( S t a c k E l e m e n t ( * i t ,& * i t ) ) ; i t ++; } } e l s e i f ( t y p e i d ( * e . n )==t y p e i d ( F u n c t i o n ) ) { v e c t o r : : i t e r a t o r i t = ( ( F u n c t i o n * ) ( e . n ) )−>a r g u m e n t s . b e g i n ( ) ; int num = 0; w h i l e ( i t ! = ( ( F u n c t i o n * ) ( e . n ) )−>a r g u m e n t s . e n d ( ) ) { s t a c k . p u s h _ b a c k ( S t a c k E l e m e n t ( * i t ,& * i t , e . p o s i t i o n , n u m ) ) ; n u m ++; i t ++; } } e l s e i f ( t y p e i d ( * e . n )==t y p e i d ( E q u a l ) ) { if ( a l l o w U n d e r E q u a l ) { s t a c k . p u s h _ b a c k ( S t a c k E l e m e n t ( ( ( E q u a l * ) ( e . n ) )−>n 1 , & ( ( E q u a l * ) ( e . n ) )−>n 1 ) ) ; s t a c k . p u s h _ b a c k ( S t a c k E l e m e n t ( ( ( E q u a l * ) ( e . n ) )−>n 2 , & ( ( E q u a l * ) ( e . n ) )−>n 2 ) ) ; } } return e . n ; } StackElement : : StackElement ( Node { t h i s −>n = n ; t h i s −>d i r e c t = d i r e c t ; }

* n , N o d e ** d i r e c t )

StackElement : : StackElement ( Node { t h i s −>n = n ; t h i s −>d i r e c t = d i r e c t ; position = parentpos ; p o s i t i o n . p u s h _ b a c k ( me ) ; }

* n , N o d e ** d i r e c t , l i s t &p a r e n t p o s , i n t m e )

StackElement : : StackElement () { } /* *

* r e p l a c e l e c u r r e n t e l e m e n t by n ( you can ’ t u s e n e x t anymore ) */ void NodeIterator : : replaceBy ( Node *n ) { if ( last . direct ) (* last . d i r e c t ) = n ;

40

else assert ( false ) ;

// Can ’ t c h a n g e node

} /* *

* come back t o t h e i n i t i a l p o s s i t i o n */

void

NodeIterator : : reset () { stack . clear () ; StackElement e (n , direct ) ; stack . push_back ( e ) ; }

/* *

* the search f o r a v a r i a b l e */ bool Node : : containVar ( int idvar ) { return false ; }

bool

Variable : : containVar ( int { r e t u r n i d==i d v a r ; }

bool

Function : : containVar ( int idvar ) { v e c t o r : : i t e r a t o r i t = a r g u m e n t s . b e g i n ( ) ; w h i l e ( i t != a r g u m e n t s . e n d ( ) ) { i f ( ( * i t )−>c o n t a i n V a r ( i d v a r ) ) return true ; i t ++; } return false ; }

bool

And : : containVar ( int idvar ) { l i s t : : i t e r a t o r i t = b r a n c h s . b e g i n ( ) ; w h i l e ( i t != b r a n c h s . e n d ( ) ) { i f ( ( * i t )−>c o n t a i n V a r ( i d v a r ) ) return true ; i t ++; } return false ; }

bool

Or : : c o n t a i n V a r ( int idvar ) { l i s t : : i t e r a t o r i t = b r a n c h s . b e g i n ( ) ; w h i l e ( i t != b r a n c h s . e n d ( ) ) { i f ( ( * i t )−>c o n t a i n V a r ( i d v a r ) ) return true ; i t ++; } return false ; }

bool

Equal : : containVar ( int idvar ) { r e t u r n n 1−>c o n t a i n V a r ( i d v a r ) | | }

bool

idvar )

Expo : : containVar ( int idvar ) { r e t u r n n 1−>c o n t a i n V a r ( i d v a r ) }

||

n 2−>c o n t a i n V a r ( i d v a r ) ;

n 2−>c o n t a i n V a r ( i d v a r ) ;

/* *

* r e p a l c e a v a r i a b l e by a g e n e r i c node */ void Node : : replace ( int idvar , Node *n ) { }

void

Function : : replace ( int idvar , Node *n ) { v e c t o r : : i t e r a t o r i t = a r g u m e n t s . b e g i n ( ) ; w h i l e ( i t != a r g u m e n t s . e n d ( ) ) { i f ( ( t y p e i d ( * * i t )==t y p e i d ( V a r i a b l e ) ) &&((( V a r i a b l e * i t = n−>d u p l i c a t e ( ) ; ( * i t )−>r e p l a c e ( i d v a r , n ) ;

41

* ) ( * i t ) )−>i d==i d v a r ) )

i t ++; } } void

void

void

Or : : r e p l a c e ( int idvar , Node *n ) { l i s t : : i t e r a t o r i t = b r a n c h s . b e g i n ( ) ; w h i l e ( i t != b r a n c h s . e n d ( ) ) { i f ( ( t y p e i d ( * * i t )==t y p e i d ( V a r i a b l e ) ) &&((( V a r i a b l e * i t = n−>d u p l i c a t e ( ) ; ( * i t )−>r e p l a c e ( i d v a r , n ) ; i t ++; } }

* ) ( * i t ) )−>i d==i d v a r ) )

And : : replace ( int idvar , Node *n ) { l i s t : : i t e r a t o r i t = b r a n c h s . b e g i n ( ) ; w h i l e ( i t != b r a n c h s . e n d ( ) ) { i f ( ( t y p e i d ( * * i t )==t y p e i d ( V a r i a b l e ) ) &&((( V a r i a b l e * i t = n−>d u p l i c a t e ( ) ; ( * i t )−>r e p l a c e ( i d v a r , n ) ; i t ++; } }

* ) ( * i t ) )−>i d==i d v a r ) )

Equal : : replace ( int idvar , Node *n ) { i f ( ( t y p e i d ( * n 1 )==t y p e i d ( V a r i a b l e ) ) &&((( V a r i a b l e n 1 = n−>d u p l i c a t e ( ) ; i f ( ( t y p e i d ( * n 2 )==t y p e i d ( V a r i a b l e ) ) &&((( V a r i a b l e n 2 = n−>d u p l i c a t e ( ) ;

* ) n 1 )−>i d==i d v a r ) ) * ) n 2 )−>i d==i d v a r ) )

n 1−>r e p l a c e ( i d v a r , n ) ; n 2−>r e p l a c e ( i d v a r , n ) ; } void

Expo : : replace ( int idvar , Node *n ) { i f ( ( t y p e i d ( * n 1 )==t y p e i d ( V a r i a b l e ) ) &&((( V a r i a b l e n 1 = n−>d u p l i c a t e ( ) ; i f ( ( t y p e i d ( * n 2 )==t y p e i d ( V a r i a b l e ) ) &&((( V a r i a b l e n 2 = n−>d u p l i c a t e ( ) ;

* ) n 1 )−>i d==i d v a r ) ) * ) n 2 )−>i d==i d v a r ) )

n 1−>r e p l a c e ( i d v a r , n ) ; n 2−>r e p l a c e ( i d v a r , n ) ; } Node * Hole : : duplicate () { return new Hole () ; } Node * Clash : : duplicate () { return new Clash () ; } Node * Trivial : : duplicate () { return new Trivial () ; } NumericalVar * NumericalVar : : duplicate () { r e t u r n new N u m e r i c a l V a r (* this ) ; } Condition * CondANplusB : : duplicate () { r e t u r n n e w C o n d A N p l u s B ( n 1−>d u p l i c a t e ( ) , a , n 2−>d u p l i c a t e ( ) , b ) ; } Condition * CondA : : duplicate () { r e t u r n n e w C o n d A ( n 1−>d u p l i c a t e ( ) , a ) ; } Condition * CondNplusN : : duplicate () { r e t u r n n e w C o n d N p l u s N ( n 1−>d u p l i c a t e ( ) , n 2−>d u p l i c a t e ( ) , n 3−>d u p l i c a t e ( ) ) ; } Condition * CondN : : duplicate ()

42

{ return }

new

C o n d N ( n 1−>d u p l i c a t e ( ) , n 2−>d u p l i c a t e ( ) ) ;

Node * Variable : : duplicate () { r e t u r n new V a r i a b l e (* this ) ; } Node * Function : : duplicate () { F u n c t i o n * d m e= n e w F u n c t i o n ( i d , p a r s e r ) ; v e c t o r : : i t e r a t o r i t = a r g u m e n t s . b e g i n ( ) ; w h i l e ( i t != a r g u m e n t s . e n d ( ) ) { d m e −>a d d A r g u m e n t ( ( * i t )−>d u p l i c a t e ( ) ) ; i t ++; } return dme ; } Node * Or : : d u p l i c a t e () { O r * d m e= n e w O r ( ) ; l i s t : : i t e r a t o r i t = b r a n c h s . b e g i n ( ) ; w h i l e ( i t != b r a n c h s . e n d ( ) ) { d m e −>a d d B r a n c h ( ( * i t )−>d u p l i c a t e ( ) ) ; i t ++; } return dme ; } Node * And : : duplicate () { A n d * d m e= n e w A n d ( ) ; l i s t : : i t e r a t o r i t = b r a n c h s . b e g i n ( ) ; w h i l e ( i t != b r a n c h s . e n d ( ) ) { d m e −>a d d B r a n c h ( ( * i t )−>d u p l i c a t e ( ) ) ; i t ++; } return dme ; } Node * Equal : : duplicate () { r e t u r n n e w E q u a l ( n 1−>d u p l i c a t e ( ) , n 2−>d u p l i c a t e ( ) ) ; } Node * Expo : : duplicate () { if ( free ) r e t u r n n e w E x p o ( n 1−>d u p l i c a t e ( ) , v a r −>d u p l i c a t e ( ) , n 2−>d u p l i c a t e ( ) ) ; else r e t u r n n e w E x p o ( n 1−>d u p l i c a t e ( ) , e x p N u m , n 2−>d u p l i c a t e ( ) ) ; } /* * * u n f o l d two t i m e t h e exp term */ Node * Expo : : buildTwo ( Node * sub ) { return }

buildOne ( buildOne ( sub ) ) ;

/* * * u n f o l d one t i m e t h e exp term */ Node * Expo : : buildOne ( Node * sub )

{ i f ( t y p e i d ( * n 1 )==t y p e i d ( H o l e ) ) r e t u r n ( ( s u b ) ? s u b : ( n 2−>d u p l i c a t e ( ) ) ) ; Node

* r e t = n 1−>d u p l i c a t e ( ) ;

Node * fonction = ret ; N o d e ** h o l e ; l i s t : : i t e r a t o r i t = h o l e P o s i t i o n −>b e g i n ( ) ; w h i l e ( i t != h o l e P o s i t i o n −>e n d ( ) ) { a s s e r t ( t y p e i d ( * f o n c t i o n )==t y p e i d ( F u n c t i o n ) ) ; // T h i s node i s n o t a f u n c t i o n h o l e = &(( F u n c t i o n * ) f o n c t i o n )−>a r g u m e n t s [ * i t ] ; f o n c t i o n = ( ( F u n c t i o n * ) f o n c t i o n )−>a r g u m e n t s [ * i t ] ; i t ++; } a s s e r t ( t y p e i d ( * * h o l e )==t y p e i d ( H o l e ) ) ; // T h i s node i s n o t a h o l e

43

delete

fonction ;

return }

ret ;

* h o l e = ( ( s u b ) ? s u b : ( n 2−>d u p l i c a t e ( ) ) ) ;

/* * * d u p l i c a t e t h e t r e e and r e p l a c e t h e node a t h e p o s i t i o n path by sub */ N o d e * N o d e : : b u i l d O n e A n d R e p l a c e ( l i s t &p a t h , N o d e * s u b ) { assert ( path . empty () ) ; return sub ; }

N o d e * F u n c t i o n : : b u i l d O n e A n d R e p l a c e ( l i s t &p a t h , N o d e

* sub )

unsigned int top = path . back () ; path . pop_back () ; F u n c t i o n * r e t = n e w F u n c t i o n ( id , p a r s e r ) ; v e c t o r : : i t e r a t o r i t = a r g u m e n t s . b e g i n ( ) ; unsigned int num = 0; w h i l e ( i t != a r g u m e n t s . e n d ( ) ) { i f ( n u m==t o p ) { if ( path . empty () ) r e t −>a d d A r g u m e n t ( s u b ) ; else r e t −>a d d A r g u m e n t ( ( ( F u n c t i o n * ) ( * i t ) )−>b u i l d O n e A n d R e p l a c e ( p a t h , s u b ) ) ; } else r e t −>a d d A r g u m e n t ( ( * i t )−>d u p l i c a t e ( ) ) ; i t ++; n u m ++; } return ret ; } /* * * s e a r c h f o r t h e node a t t h e p o s i t i o n path */ N o d e * N o d e : : f i n d ( l i s t &p a t h ) { assert ( path . empty () ) ; return this ; }

Node

* F u n c t i o n : : f i n d ( l i s t &p a t h ) { a s s e r t ( t y p e i d ( * t h i s )==t y p e i d ( F u n c t i o n ) ) ; if ( path . empty () ) return this ; unsigned int top = path . back () ; path . pop_back () ; a s s e r t ( t o p
f i n d ( p a t h ) ; } }

/* * * equality of structure */ bool

bool

bool

Node : : isEqual ( Node *n ) { r e t u r n ( t y p e i d ( * t h i s )==t y p e i d ( * n ) ) ; }

NumericalVar : : isEqual ( Node *n ) { i f ( t y p e i d ( * t h i s ) != t y p e i d ( * n ) ) return false ; r e t u r n ( t h i s −>i d ==(( N u m e r i c a l V a r } Variable : : isEqual ( Node

* ) n )−>i d ) ;

*n )

44

{ i f ( t y p e i d ( * t h i s ) != t y p e i d ( * n ) ) return false ; r e t u r n ( t h i s −>i d ==(( V a r i a b l e * ) n )−>i d ) ; } bool

Function : : isEqual ( Node *n ) { i f ( t y p e i d ( * t h i s ) != t y p e i d ( * n ) ) return false ; i f ( t h i s −>i d ! = ( ( F u n c t i o n return false ;

* ) n )−>i d )

v e c t o r : : i t e r a t o r i t = a r g u m e n t s . b e g i n ( ) ; v e c t o r : : i t e r a t o r i t 2 = ( ( F u n c t i o n * ) n )−>a r g u m e n t s . b e g i n ( ) ; w h i l e ( i t != a r g u m e n t s . e n d ( ) ) { i f ( ! ( * i t )−>i s E q u a l ( * i t 2 ) ) return false ; i t 2 ++; i t ++; } return } bool

true ;

Or : : i s E q u a l ( Node *n ) { i f ( t y p e i d ( * t h i s ) != t y p e i d ( * n ) ) return false ; l i s t : : i t e r a t o r i t = b r a n c h s . b e g i n ( ) ; l i s t : : i t e r a t o r i t 2 = ( ( O r * ) n )−>b r a n c h s . b e g i n ( ) ; w h i l e ( i t != b r a n c h s . e n d ( ) ) { i f ( ! ( * i t )−>i s E q u a l ( * i t 2 ) ) return false ; i t 2 ++; i t ++; } return true ; }

bool

And : : isEqual ( Node *n ) { i f ( t y p e i d ( * t h i s ) != t y p e i d ( * n ) ) return false ; l i s t : : i t e r a t o r i t = b r a n c h s . b e g i n ( ) ; l i s t : : i t e r a t o r i t 2 = ( ( A n d * ) n )−>b r a n c h s . b e g i n ( ) ; w h i l e ( i t != b r a n c h s . e n d ( ) ) { i f ( ! ( * i t )−>i s E q u a l ( * i t 2 ) ) return false ; i t 2 ++; i t ++; } l i s t : : i t e r a t o r i t 3 = c o n d i t i o n s . b e g i n ( ) ; l i s t : : i t e r a t o r i t 4 = ( ( A n d * ) n )−>c o n d i t i o n s . b e g i n ( ) ; w h i l e ( i t 3 != c o n d i t i o n s . e n d ( ) ) { i f ( ! ( * i t 3 )−>i s E q u a l ( * i t 4 ) ) return false ; i t 3 ++; i t 4 ++; } return }

bool

bool

true ;

Equal : : isEqual ( Node *n ) { i f ( t y p e i d ( * t h i s ) != t y p e i d ( * n ) ) return false ; i f ( ! t h i s −>n 1−>i s E q u a l ( ( ( E q u a l * ) n )−>n 1 ) ) return false ; i f ( ! t h i s −>n 2−>i s E q u a l ( ( ( E q u a l * ) n )−>n 2 ) ) return false ; return true ; } Expo : : isEqual ( Node *n ) { i f ( t y p e i d ( * t h i s ) != t y p e i d ( * n ) ) return false ; i f ( ! t h i s −>n 1−>i s E q u a l ( ( ( E x p o * ) n )−>n 1 ) )

45

return false ; i f ( ! t h i s −>n 2−>i s E q u a l ( ( ( E x p o * ) n )−>n 2 ) ) return false ; i f ( t h i s −>f r e e ==(( E x p o * ) n )−>f r e e ) if ( free ) r e t u r n t h i s −>v a r −>i d == ( ( E x p o * ) n )−>v a r −>i d ; else r e t u r n t h i s −>e x p N u m == ( ( E x p o * ) n )−>e x p N u m ; return } bool

false ;

CondA : : isEqual ( Condition *n ) { i f ( t y p e i d ( * t h i s ) != t y p e i d ( * n ) ) return false ; return false ; }

bool

CondANplusB : : isEqual ( Condition { i f ( t y p e i d ( * t h i s ) != t y p e i d ( * n ) ) return false ; return false ; }

bool

CondNplusN : : isEqual ( Condition { i f ( t y p e i d ( * t h i s ) != t y p e i d ( * n ) ) return false ; return false ; }

bool

*n )

*n )

CondN : : isEqual ( Condition *n ) { i f ( t y p e i d ( * t h i s ) != t y p e i d ( * n ) ) return false ; return false ; }

N o d e * E x p o : : b u i l d ( int num , N o d e { Node * ret = sub ; int i ; f o r ( i =0; ia d d B r a n c h ( $ 1 ) ;

48

* result = $$ ;} else { $$ = NULL ; *

|

Input Ligne { if ( $1 ) $$ = $1 ; ( $2 ) ; }

else { $$ = new

And () ;

* r e s u l t = $ $ ; } i f ( $ 2 ) ( ( A n d * ) $ $ )−>a d d B r a n c h

; Ligne : EOL | RUN EOL { | HELP EOL { | SET OPTION | T EOL { ;

{ $$ = NULL ; } $$ = NULL ; return 0;} Configuration : : printConsol () ;

EOL { $$ = NULL ; } $$ = $1 ;}

$$ = NULL ; }

OPTION : | | | ;

STEP INFO ZERO BEEP

{ { { {

e x t P a r s e r −>c o n f i g −>p a u s e E v e r y S t e p = t r u e ; } e x t P a r s e r −>c o n f i g −>p r i n t R u l e = t r u e ; } / * e x t P a r s e r −>c o n f i g −>NcanbeZero = t r u e ; * / } e x t P a r s e r −>c o n f i g −>b e e p = 1 ; }

T: Tf | T a n d A N D T f { $ $ = $ 1 ; ( ( A n d * ) $ $ )−>a d d B r a n c h ( $ 3 ) ; } | T o r O R T f { $ $ = $ 1 ; ( ( O r * ) $ $ )−>a d d B r a n c h ( $ 3 ) ; } / * | Tf EQUAL Tf { $$ = new Equal ( $ 1 , $ 3 ) ; } * / ; Tand : T f { $ $ = n e w A n d ( ) ; ( ( A n d * ) $ $ )−>a d d B r a n c h ( $ 1 ) ; } | C o n d { $ $ = n e w A n d ( ) ; ( ( A n d * ) $ $ )−>a d d C o n d i t i o n ( $ 1 ) ; } | T a n d A N D C o n d { $ $ = $ 1 ; ( ( A n d * ) $ $ )−>a d d C o n d i t i o n ( $ 3 ) ; } | T a n d A N D T f { $ $ = $ 1 ; ( ( A n d * ) $ $ )−>a d d B r a n c h ( $ 3 ) ; } ; Tor :

Tf :

T f { $ $ = n e w O r ( ) ; ( ( O r * ) $ $ )−>a d d B r a n c h ( $ 1 ) ; } | T o r O R T f { $ $ = $ 1 ; ( ( O r * ) $ $ )−>a d d B r a n c h ( $ 3 ) ; } ; L E F T _ P A R T R I G H T _ P A R { $$ = $2 ;} | Teq { $$ = $1 ;} ;

Teq : Tp Tp :

EQUAL

Tp { $$ = new

E q u a l ( $1 ,

$3 ) ; }

HOLE { $$ = new Hole () ;} | F U N C L E F T _ P A R A R I G H T _ P A R { $ $ = $ 3 ; ( ( F u n c t i o n * ) $ $ )−>s e t N a m e ( $ 1−>c _ s t r ( ) , $1 ;} | M I N { $ $ = n e w F u n c t i o n ( $ 1−>c _ s t r ( ) , e x t P a r s e r ) ; d e l e t e $ 1 ; } | M A J { $ $ = n e w V a r i a b l e ( $ 1−>c _ s t r ( ) , e x t P a r s e r ) ; d e l e t e $ 1 ; } | T p P O W E R L E F T _ B R A N u m V R I G H T _ B R A D O T T p f { $ $ = n e w E x p o ( $1 , $4 , $ 7 ) ; } | T p P O W E R L E F T _ B R A I N T R I G H T _ B R A D O T T p f { $ $ = n e w E x p o ( $1 , $4 , $ 7 ) ; } ;

/ * e x p e r i e n c e p o u r r i e de Gaby pour d e s a m b i g u i f i e r l a grammaire * / Tpf : L E F T _ P A R Tp R I G H T _ P A R { $$ = $2 ; } | F U N C L E F T _ P A R A R I G H T _ P A R { $ $ = $ 3 ; ( ( F u n c t i o n * ) $ $ )−>s e t N a m e ( $ 1−>c _ s t r ( ) , $1 ;} | M I N { $ $ = n e w F u n c t i o n ( $ 1−>c _ s t r ( ) , e x t P a r s e r ) ; d e l e t e $ 1 ; } | M A J { $ $ = n e w V a r i a b l e ( $ 1−>c _ s t r ( ) , e x t P a r s e r ) ; d e l e t e $ 1 ; } ; FUNC : MAJ { $$ = $1 ; } | MIN { $$ = $1 ; } ; A:

T p { $ $ = n e w F u n c t i o n ( ) ; ( ( F u n c t i o n * ) $ $ )−>a d d A r g u m e n t ( $ 1 ) ; } | A C O M M A T p { $ $ = $ 1 ; ( ( F u n c t i o n * ) $ $ )−>a d d A r g u m e n t ( $ 3 ) ; } ;

Cond : N u m V E Q U A L 2 I N T T I M E S N u m V P L U S I N T { $ $ = n e w C o n d A N p l u s B ( $1 , $3 , $5 , $ 7 ) ; } | N u m V E Q U A L 2 I N T T I M E S N u m V { $ $ = n e w C o n d A N p l u s B ( $1 , $3 , $5 , 0) ; } | N u m V E Q U A L 2 N u m V P L U S N u m V { $ $ = n e w C o n d N p l u s N ( $1 , $3 , $ 5 ) ; } | N u m V E Q U A L 2 N u m V { $ $ = n e w C o n d N ( $1 , $ 3 ) ; } ; NumV : M A J { $ $ = n e w N u m e r i c a l V a r ( $ 1−>c _ s t r ( ) , e x t P a r s e r , f a l s e ) ; d e l e t e $ 1 ; } | M I N { $ $ = n e w N u m e r i c a l V a r ( $ 1−>c _ s t r ( ) , e x t P a r s e r , f a l s e ) ; d e l e t e $ 1 ; } ; %%

49

extParser ) ;

delete

extParser ) ;

delete

Parser * extParser ; N o d e ** r e s u l t ; yyFlexLexer * lexer ; int numLine ; void

void

int

set_result ( Node { result = r ; }

** r )

set_extParser ( Parser * extP ) { extParser = extP ; } yyerror ( char *s ) { printf ( "\ nErreur : %s ( line : %i)\n" ,s , numLine ) ; return 1; }

yylex ( void ) { r e t u r n l e x e r −>y y l e x ( ) ; }

int

6.6.9

synnaeve.guillame.bert.h

# include # include # include # include # include # include

" synnaeve . guillame . bert .h" " unification .h" < a s s e r t . h>

namespace { bool

bool

bool

Solver

Vertex : : setBounds ( int { bool ch = false ; i f ( m i n >t h i s −>m i n ) { t h i s −>m i n = m i n ; i f ( m a x m a x ) { t h i s −>m a x = m a x ; return ch ; }

min , int

max )

ch = true ; } ch = true ; }

Vertex : : setBoundMin ( int min ) { i f ( m i n >t h i s −>m i n ) { t h i s −>m i n = m i n ; r e t u r n return false ; } Vertex : : setBoundMax ( int max ) { i f ( m a x m a x ) { t h i s −>m a x = m a x ; r e t u r n return false ; }

true ; }

true ; }

Graph : : Graph ( Node * node , U n i f i c a t i o n * u n i f i c a t i o n ) { t h i s −>u n i f i c a t i o n = u n i f i c a t i o n ; solus = new SolverSolution () ; s o l u s −>u n i f i c a t i o n = u n i f i c a t i o n ;

// ====== DEBUG ========= Vertex * v0 = a d d V e r t e x (0) ; Vertex * v1 = a d d V e r t e x (1) ; Vertex * v2 = a d d V e r t e x (2) ; Vertex * v3 = a d d V e r t e x (3) ; Vertex * v4 = a d d V e r t e x (4) ; Vertex * v5 = a d d V e r t e x (5) ; V e r t e x * v 6 = a d d V e r t e x ( −1) ; V e r t e x * v 7 = a d d V e r t e x ( −2) ; a d d E d g e ( v0 , v1 , 2 , 0 ) ; a d d E d g e ( v1 , v7 , 1 , 0 ) ;

50

a d d E d g e ( v2 , v7 , 1 , 0 ) ; a d d E d g e ( v3 , v7 , −1 ,0) ; a d d E d g e ( v0 , v6 , 1 , 0 ) ; a d d E d g e ( v5 , v6 , 1 , 0 ) ; a d d E d g e ( v4 , v6 , −1 ,0) ; a d d E d g e ( v4 , v3 , 1 , 2 ) ; success = true ; s o l u s −>n d v a r = 0 ; return ; s o l u s −>n d v a r = u n i f i c a t i o n −>p a r s e r −>v a r i a b l e t a b . s i z e ( ) ; s o l u s −>v a r i a b l e S o l u t i o n = n e w V a r i a b l e S o l u t i o n [ s o l u s −>n d v a r ] ; success = explo ( node ) ; } Vertex * Graph : : a d d V e r t e x ( int id ) { i f ( i d >=0) { l i s t : : i t e r a t o r i t = v e r t e x s . b e g i n ( ) ; w h i l e ( i t != v e r t e x s . e n d ( ) ) { i f ( ( * i t )−>v a r i a b l e==i d ) return * it ; i t ++; } } Vertex *v = new Vertex () ; v−>c o u n t = 0 ; v−>v a r i a b l e = i d ; v−>m i n = ( u n i f i c a t i o n −>c o n f i g u r a t i o n −>N c a n b e Z e r o ) ? 0 : 1 ; v−>m a x = I N T _ M A X ; v−>f a t h e r = N U L L ; v−>v i s i t e d = f a l s e ; t h i s −>v e r t e x s . p u s h _ b a c k ( v ) ; return v ; } E d g e * G r a p h : : a d d E d g e ( V e r t e x * v1 , V e r t e x { Edge *e = new Edge () ; e−>a = a ; e−>b = b ; e−>n 1 = v 1 ; e−>n 2 = v 2 ; v 1−>o u t . p u s h _ b a c k ( e ) ; v 2−>i n . p u s h _ b a c k ( e ) ; t h i s −>e d g e s . p u s h _ b a c k ( e ) ; return e ; } bool

* v2 , i n t a , i n t b )

Graph : : explo ( Node * n ) { bool val = true ; i n t f i r s t = ( u n i f i c a t i o n −>c o n f i g u r a t i o n −>N c a n b e Z e r o ) ? 0 : 1 ; i f ( t y p e i d ( * n )==t y p e i d ( C l a s h ) ) val = false ; e l s e i f ( t y p e i d ( * n )==t y p e i d ( T r i v i a l ) ) val = true ; e l s e i f ( t y p e i d ( * n )==t y p e i d ( E q u a l ) ) { E q u a l * e = ( E q u a l *) n ; val = true ; i f ( t y p e i d ( * e−>n 1 )==t y p e i d ( V a r i a b l e ) ) s o l u s −>v a r i a b l e S o l u t i o n [ ( ( V a r i a b l e else return false ;

* ) ( e−>n 1 ) )−>i d ] . d e f i n i t i o n = e−>n 2 ;

i f ( ! e x p l o ( e−>n 2 ) ) val = false ; }

else

i f ( t y p e i d ( * n )==t y p e i d ( A n d ) ) { And * a = ( And *) n ; val = true ; l i s t : : i t e r a t o r i t = a−>b r a n c h s . b e g i n ( ) ; w h i l e ( i t != a−>b r a n c h s . e n d ( ) ) { if ( ! e x p l o (* it ) ) { val = false ; break ; }

51

i t ++; } l i s t : : i t e r a t o r i t 2 = a−>c o n d i t i o n s . b e g i n ( ) ; w h i l e ( i t 2 != a−>c o n d i t i o n s . e n d ( ) ) { V e r t e x * v = a d d V e r t e x ( ( * i t 2 )−>n 1−>i d ) ; i f ( t y p e i d ( * * i t 2 )==t y p e i d ( C o n d A N p l u s B ) ) { E d g e * e = a d d E d g e ( a d d V e r t e x ( ( ( C o n d A N p l u s B * ) ( * i t 2 ) )−>n 2−>i d ) , v , ( ( C o n d A N p l u s B a , ( ( C o n d A N p l u s B * ) ( * i t 2 ) )−>b ) ; i f ( ( e−>a b n 1−>s e t B o u n d M a x ( −( e−>b−f i r s t ) / e−>a ) ; e−>n 2−>s e t B o u n d M a x ( e−>b + e−>a * f i r s t ) ; } else i f ( ( e−>a b n 1−>s e t B o u n d s ( 0 , 0 ) ; e−>n 2−>s e t B o u n d s ( 0 , 0 ) ; } else return false ; } e l s e i f ( t y p e i d ( * * i t 2 )==t y p e i d ( C o n d N p l u s N ) ) { V e r t e x * o n o d e = a d d V e r t e x ( −1) ; a d d E d g e ( v , onode , −1 ,0) ; a d d E d g e ( a d d V e r t e x ( ( ( C o n d N p l u s N * ) ( * i t 2 ) )−>n 2−>i d ) , o n o d e , 1 , 0 ) ; a d d E d g e ( a d d V e r t e x ( ( ( C o n d N p l u s N * ) ( * i t 2 ) )−>n 3−>i d ) , o n o d e , 1 , 0 ) ; } e l s e i f ( t y p e i d ( * * i t 2 )==t y p e i d ( C o n d N ) ) a d d E d g e ( a d d V e r t e x ( ( ( C o n d A N p l u s B * ) ( * i t 2 ) )−>n 2−>i d ) , v , 1 , 0 ) ; e l s e i f ( t y p e i d ( * * i t 2 )==t y p e i d ( C o n d A ) ) v−>s e t B o u n d s ( ( ( C o n d A * ) ( * i t 2 ) )−>a , ( ( C o n d A * ) ( * i t 2 ) )−>a ) ; i t 2 ++; }

* ) ( * i t 2 ) )−>

}

i f ( t y p e i d ( * n )==t y p e i d ( F u n c t i o n ) ) { F u n c t i o n * f = ( F u n c t i o n *) n ; v e c t o r : : i t e r a t o r i t = f−>a r g u m e n t s . b e g i n ( ) ; val = true ; w h i l e ( i t != f−>a r g u m e n t s . e n d ( ) ) { if ( ! e x p l o (* it ) ) { val = false ; break ; } i t ++; } } e l s e i f ( t y p e i d ( * n )==t y p e i d ( O r ) ) { a s s e r t ( f a l s e ) ; // C e c i n ’ e s t p a s une f o r m e d i s j o n c t i v e ( l e s Ors on d ´ ej` a ´ et´ e } e l s e i f ( t y p e i d ( * n )==t y p e i d ( E x p o ) ) { Expo * e = ( Expo *) n ; v a l = e x p l o ( e−>n 1 ) ; i f ( ! e x p l o ( e−>n 2 ) ) val = false ; i f ( e−>f r e e ) a d d V e r t e x ( e−>v a r −>i d ) ; // s o l u t i o n −>n u m e r i c a l v a r i a b l e S o l u t i o n [ e−>var−>i d ] . s e e o u t s i d e = t r u e ; } e l s e i f ( t y p e i d ( * n )==t y p e i d ( V a r i a b l e ) ) { V a r i a b l e * v = ( V a r i a b l e *) n ; s o l u s −>v a r i a b l e S o l u t i o n [ v−>i d ] . s e e o u t s i d e = t r u e ; val = true ; } return val ; } else

SolverSolution * Graph : : run () { if ( ! s u c c e s s ) { s o l u s −>s u c c e s s = f a l s e ; return solus ; } c o u t n 1 ) ? 1 . f : − 1 . f ;

i f ( w a y ==1) { a *= ( * i t 2 )−>a ; b *= ( * i t 2 )−>a ; b += ( * i t 2 )−>b ; } else { a /= ( * i t 2 )−>a ; b /= ( * i t 2 )−>a ; b −= ( * i t 2 )−>b / ( * i t 2 )−>a ; } it3 = contribution . begin () ;

53

w h i l e ( i t 3 != c o n t r i b u t i o n . e n d ( ) ) { i f ( w a y ==1) ( * i t 3 ) . a *= ( * i t 2 )−>a ; else ( * i t 3 ) . a /= ( * i t 2 )−>a ; i t 3 ++; } i t 2 ++; } a −−; if ( c o n t r i b u t i o n . empty () ) { if ( b !=0) { s o l u s −>s u c c e s s = f a l s e ; return solus ; } if ( a !=1) { s o l u s −>s u c c e s s = f a l s e ; return solus ; } else { i f ( ! u n i f i c a t i o n −>c o n f i g u r a t i o n −>N c a n b e Z e r o ) { s o l u s −>s u c c e s s = f a l s e ; return solus ; } else { v e r t e x s . f r o n t ( )−>s e t B o u n d s ( 0 , 0 ) ; // removeEdge ( e d g e s . f r o n t ( ) ) ; } } } else { // V e r t e x * o = a d d V e r t e x ( −1) ; // TODO } contribution . clear () ; vertexs . clear () ; edges . clear () ; } c o u t n 1 ) ; i f ( ( * i t 2 )−>n 1−>v i s i t e d ) { e = * it2 ; v 2 = ( * i t 2 )−>n 1 ; goto buildpath ; } ( * i t 2 )−>n 1−>f a t h e r = * i t 2 ; ( * i t 2 )−>n 1−>v i s i t e d = t r u e ; } i t 2 ++; } i t 2 = v−>o u t . b e g i n ( ) ; w h i l e ( i t 2 != v−>o u t . e n d ( ) ) { i f ( * i t 2 != v−>f a t h e r ) { t o v i s i t . p u s h _ b a c k ( ( * i t 2 )−>n 2 ) ; i f ( ( * i t 2 )−>n 2−>v i s i t e d ) { e = * it2 ; v 2 = ( * i t 2 )−>n 2 ; goto buildpath ; } ( * i t 2 )−>n 2−>f a t h e r = * i t 2 ; ( * i t 2 )−>n 2−>v i s i t e d = t r u e ; } i t 2 ++; } } return false ; buildpath : ; ed . p u s h _ b a c k ( e ) ; resetVisited () ; Vertex * cur = v2 ; while ( cur ) { c u r −>v i s i t e d = t r u e ; i f ( c u r −>f a t h e r ) c u r = ( c u r==c u r −>f a t h e r −>n 1 ) ? c u r −>f a t h e r −>n 2 : c u r −>f a t h e r −>n 1 ; else cur = NULL ; } cur = v ; w h i l e ( ! c u r −>v i s i t e d ) c u r = ( c u r==c u r −>f a t h e r −>n 1 ) ? c u r −>f a t h e r −>n 2 : c u r −>f a t h e r −>n 1 ; w h i l e ( v 2 != c u r ) { ver . p u s h _ f r o n t ( v2 ) ; e d . p u s h _ f r o n t ( v 2−>f a t h e r ) ; v 2 = ( v 2==v 2−>f a t h e r −>n 1 ) ? v 2−>f a t h e r −>n 2 : v 2−>f a t h e r −>n 1 ; } w h i l e ( v != c u r ) { ver . push_back ( v ) ; e d . p u s h _ b a c k ( v−>f a t h e r ) ; v = ( v==v−>f a t h e r −>n 1 ) ? v−>f a t h e r −>n 2 : v−>f a t h e r −>n 1 ; } ver . push_front ( cur ) ; ver . push_back ( cur ) ; return true ; } void

Graph : : resetVisited ()

55

{ l i s t : : i t e r a t o r i t = v e r t e x s . b e g i n ( ) ; w h i l e ( i t != v e r t e x s . e n d ( ) ) ( * ( i t++))−>v i s i t e d = f a l s e ; } void

Graph : : print () { c o u t b r a n c h s . b e g i n ( ) ; w h i l e ( i t 3 ! = ( ( O r * ) ( * i t 2 ) )−>b r a n c h s . e n d ( ) ) { And * newAnd = new And () ; b o o l l a s t = ( ( * i t 3 ) ==(( O r * ) ( * i t 2 ) )−>b r a n c h s . b a c k ( ) ) ; n e w A n d −>a d d B r a n c h ( * i t 3 ) ; // p a r c o u r d e s c o n d i t i o n s e t a j o u t l i s t : : i t e r a t o r i t 5 = ( ( A n d * ) c u r )−>c o n d i t i o n s . b e g i n ( ) ; w h i l e ( i t 5 ! = ( ( A n d * ) c u r )−>c o n d i t i o n s . e n d ( ) ) { n e w A n d −>a d d C o n d i t i o n ( ( * i t 5 )−>d u p l i c a t e ( ) ) ; // i f ( l a s t ) // d e l e t e (* i t 5 ) ; i t 5 ++; } // p a r c o u r du And e t a j o u t ( s a u f i t 2 ) l i s t : : i t e r a t o r i t 4 = ( ( A n d * ) c u r )−>b r a n c h s . b e g i n ( ) ; w h i l e ( i t 4 ! = ( ( A n d * ) c u r )−>b r a n c h s . e n d ( ) ) { i f ( i t 4 != i t 2 ) n e w A n d −>a d d B r a n c h ( ( * i t 4 )−>d u p l i c a t e ( ) ) ; // i f ( l a s t ) // d e l e t e (* i t 4 ) ; i t 4 ++; } n e w O r −>a d d B r a n c h ( n e w A n d ) ; if ( last ) break ; i t 3 ++; } it . r e p l a c e B y ( newOr ) ; action = true ; nothingtodo = false ; goto endthisloop ; } i t 2 ++; }

} } endthisloop : ; ret = ApplyR0 ( ret ) ; } while (! nothingtodo ) ; return ret ; } /* * * A p p l i c a t i o n o f r u l e s R0 ( s i m p l i f i c a t i o n ) */ Node * Unification : : ApplyR0 ( Node * start ) { if ( ! start ) s t a r t = p a r s e r −>r e s u l t ;

57

Node bool do

* ret = start ; nothingtodo ; { nothingtodo = true ; N o d e I t e r a t o r i t ( r e t ,& r e t , N o d e I t e r a t o r : : D E P T H _ F I R S T ) ; it . s e t U n d e r E q u a l ( true ) ; Node * cur ; w h i l e ( ( c u r=i t . n e x t ( ) ) ) { i f ( t y p e i d ( * c u r )==t y p e i d ( A n d ) ) { i f ( ( ( ( A n d * ) c u r )−>b r a n c h s . s i z e ( ) ==1)&&((( A n d * ) c u r )−>c o n d i t i o n s . e m p t y ( ) ) ) { i t . r e p l a c e B y ( ( ( A n d * ) c u r )−>b r a n c h s . f r o n t ( ) ) ; delete cur ; nothingtodo = false ; goto endthisloop ; } l i s t : : i t e r a t o r i t 2 = ( ( A n d * ) c u r )−>b r a n c h s . b e g i n ( ) ; w h i l e ( i t 2 ! = ( ( A n d * ) c u r )−>b r a n c h s . e n d ( ) ) { i f ( t y p e i d ( * ( * i t 2 ) )==t y p e i d ( A n d ) ) { And * s u b A n d = ( And *) (* it2 ) ; ( ( A n d * ) c u r )−>b r a n c h s . e r a s e ( i t 2 ) ; l i s t : : i t e r a t o r i t 3 = s u b A n d −>b r a n c h s . b e g i n ( ) ; w h i l e ( i t 3 != s u b A n d −>b r a n c h s . e n d ( ) ) { ( ( A n d * ) c u r )−>b r a n c h s . p u s h _ b a c k ( * i t 3 ) ; i t 3 ++; } l i s t : : i t e r a t o r i t 4 = s u b A n d −>c o n d i t i o n s . b e g i n ( ) ; w h i l e ( i t 4 != s u b A n d −>c o n d i t i o n s . e n d ( ) ) { ( ( A n d * ) c u r )−>c o n d i t i o n s . p u s h _ b a c k ( * i t 4 ) ; i t 4 ++; } nothingtodo = false ; goto endthisloop ; } i f ( t y p e i d ( * ( * i t 2 ) )==t y p e i d ( C l a s h ) ) { it . r e p l a c e B y ( new Clash () ) ; nothingtodo = false ; goto endthisloop ; } i f ( t y p e i d ( * ( * i t 2 ) )==t y p e i d ( T r i v i a l ) ) { ( ( A n d * ) c u r )−>b r a n c h s . e r a s e ( i t 2 ) ; nothingtodo = false ; goto endthisloop ; } i t 2 ++; } } i f ( t y p e i d ( * c u r )==t y p e i d ( E x p o ) ) i f ( ! ( ( E x p o * ) c u r )−>f r e e ) { i f ( ( ( E x p o * ) c u r )−>e x p N u m ==0) { // TODO −> d e l e t e ( ( Expo * ) c u r )−>n1 i t . r e p l a c e B y ( ( ( E x p o * ) c u r )−>n 2 ) ; nothingtodo = false ; goto endthisloop ; } else { N o d e * n = ( ( E x p o * ) c u r )−>b u i l d ( ( ( E x p o * ) c u r )−>e x p N u m , N U L L ) ; // TODO −> d e l e t e ( ( Expo * ) c u r ) it . r e p l a c e B y ( n ) ; nothingtodo = false ; goto endthisloop ; } } i f ( t y p e i d ( * c u r )==t y p e i d ( O r ) ) { i f ( ( ( O r * ) c u r )−>b r a n c h s . s i z e ( ) ==1) { i t . r e p l a c e B y ( ( ( O r * ) c u r )−>b r a n c h s . f r o n t ( ) ) ; delete cur ;

58

nothingtodo = false ; goto endthisloop ; } l i s t : : i t e r a t o r i t 2 = ( ( O r * ) c u r )−>b r a n c h s . b e g i n ( ) ; w h i l e ( i t 2 ! = ( ( O r * ) c u r )−>b r a n c h s . e n d ( ) ) { i f ( t y p e i d ( * ( * i t 2 ) )==t y p e i d ( O r ) ) { Or * s u b O r = ( Or *) (* it2 ) ; ( ( O r * ) c u r )−>b r a n c h s . e r a s e ( i t 2 ) ; l i s t : : i t e r a t o r i t 3 = s u b O r −>b r a n c h s . b e g i n ( ) ; w h i l e ( i t 3 != s u b O r −>b r a n c h s . e n d ( ) ) { ( ( O r * ) c u r )−>b r a n c h s . p u s h _ b a c k ( * i t 3 ) ; i t 3 ++; } nothingtodo = false ; goto endthisloop ; } i f ( t y p e i d ( * ( * i t 2 ) )==t y p e i d ( T r i v i a l ) ) { it . r e p l a c e B y ( new Clash () ) ; nothingtodo = false ; goto endthisloop ; } i f ( t y p e i d ( * ( * i t 2 ) )==t y p e i d ( C l a s h ) ) { ( ( A n d * ) c u r )−>b r a n c h s . e r a s e ( i t 2 ) ; nothingtodo = false ; goto endthisloop ; } i t 2 ++; } } } endthisloop : ; } while (! nothingtodo ) ; return ret ; } /* * * A p p l i c a t i o n o f r u l e s R1 ( b a s i c u n i f i c a t i o n r u l e s ) */ bool

Unification : : tryApplyR1 () { N o d e I t e r a t o r i t ( p a r s e r −>r e s u l t ,& p a r s e r −>r e s u l t , N o d e I t e r a t o r : : D E P T H _ F I R S T ) ; Node * cur ; // x=x (TODO : pour s=s ) −> w h i l e ( ( c u r=i t . n e x t ( ) ) ) i f ( t y p e i d ( * c u r )==t y p e i d ( E q u a l ) ) { E q u a l * e = ( E q u a l *) cur ; / * i f ( ( t y p e i d ( * e−>n1 )==t y p e i d ( V a r i a b l e ) )&& ( t y p e i d ( * e−>n2 )==t y p e i d ( V a r i a b l e ) )&& ( ( ( V a r i a b l e * ) ( e−>n1 ) )−>i d == ( ( V a r i a b l e * ) ( e−>n2 ) )−>i d ) ) */ i f ( e−>n 1−>i s E q u a l ( e−>n 2 ) ) { i f ( c o n f i g u r a t i o n −>p r i n t R u l e ) { D i s p l a y : : t e x H s p a c e (* m y c o u t ) ; ( * m y c o u t ) n 1 ) != t y p e i d ( V a r i a b l e ) )&& ( t y p e i d ( * e−>n 2 )==t y p e i d ( V a r i a b l e ) ) ) { i f ( c o n f i g u r a t i o n −>p r i n t R u l e ) { D i s p l a y : : t e x H s p a c e (* m y c o u t ) ; ( * m y c o u t ) n 2 ; e−>n 2 = s w a p ; return true ; } } // f ( x )=f ( y ) −> x=y it . reset () ; w h i l e ( ( c u r=i t . n e x t ( ) ) ) i f ( t y p e i d ( * c u r )==t y p e i d ( E q u a l ) ) { E q u a l * e = ( E q u a l *) cur ; i f ( ( t y p e i d ( * e−>n 1 )==t y p e i d ( F u n c t i o n ) )&& ( t y p e i d ( * e−>n 2 )==t y p e i d ( F u n c t i o n ) )&& ( ( ( F u n c t i o n * ) ( e−>n 1 ) )−>i d == ( ( F u n c t i o n {

* ) ( e−>n 2 ) )−>i d ) )

i f ( c o n f i g u r a t i o n −>p r i n t R u l e ) { D i s p l a y : : t e x H s p a c e (* m y c o u t ) ; ( * m y c o u t ) n 2 ) )−>a r g u m e n t s . b e g i n ( ) ; w h i l e ( i t 1 ! = ( ( F u n c t i o n * ) ( e−>n 1 ) )−>a r g u m e n t s . e n d ( ) ) { a d d −>a d d B r a n c h ( n e w E q u a l ( * i t 1 , * i t 2 ) ) ; i t 1 ++; i t 2 ++; } it . r e p l a c e B y ( add ) ; return true ; } }

// f ( x )=g ( y ) −> it . reset () ; w h i l e ( ( c u r=i t . n e x t ( ) ) ) i f ( t y p e i d ( * c u r )==t y p e i d ( E q u a l ) ) { E q u a l * e = ( E q u a l *) cur ; i f ( ( t y p e i d ( * e−>n 1 )==t y p e i d ( F u n c t i o n ) )&& ( t y p e i d ( * e−>n 2 )==t y p e i d ( F u n c t i o n ) )&& ( ( ( F u n c t i o n * ) ( e−>n 1 ) )−>i d != ( ( F u n c t i o n * ) ( e−>n 2 ) )−>i d ) ) { i f ( c o n f i g u r a t i o n −>p r i n t R u l e ) { D i s p l a y : : t e x H s p a c e (* m y c o u t ) ; ( * m y c o u t ) x=s ˆP{x−>s }

l i s t : : i t e r a t o r i t 1 = a n d d −>b r a n c h s . b e g i n ( ) ; w h i l e ( i t 1 != a n d d −>b r a n c h s . e n d ( ) ) { l i s t : : i t e r a t o r i t 2 = a n d d −>b r a n c h s . b e g i n ( ) ; w h i l e ( i t 2 != a n d d −>b r a n c h s . e n d ( ) ) { if ( ( * i t 1 ) !=(* i t 2 ) ) { i f ( ( t y p e i d ( * * i t 1 )==t y p e i d ( E q u a l ) )&& ( t y p e i d ( * ( ( E q u a l * ) ( * i t 1 ) )−>n 1 )==t y p e i d ( V a r i a b l e ) ) ) { V a r i a b l e * x = ( V a r i a b l e * ) ( ( E q u a l * ) ( * i t 1 ) )−>n 1 ; N o d e * s = ( ( E q u a l * ) ( * i t 1 ) )−>n 2 ; Node *p = * it2 ; i f ( ( ! s−>c o n t a i n V a r ( x−>i d ) )&& ( p−>c o n t a i n V a r ( x−>i d ) )&& ( ( t y p e i d ( * s ) != t y p e i d ( V a r i a b l e ) ) | | ( p−>c o n t a i n V a r ( ( ( V a r i a b l e * ) ( s ) )−>i d ) ) )) { i f ( c o n f i g u r a t i o n −>p r i n t R u l e ) { D i s p l a y : : t e x H s p a c e (* m y c o u t ) ; ( * m y c o u t ) i d , s ) ; return true ; } } } i t 2 ++; } i t 1 ++; } } // x=s e t x E s −> it . reset () ; w h i l e ( ( c u r=i t . n e x t ( ) ) ) i f ( t y p e i d ( * c u r )==t y p e i d ( E q u a l ) ) { E q u a l * e = ( E q u a l *) cur ; i f ( ( t y p e i d ( * e−>n 1 )==t y p e i d ( V a r i a b l e ) )&& ( e−>n 2−>c o n t a i n V a r ( ( ( V a r i a b l e * ) ( e−>n 1 ) )−>i d ) ) ) { i f ( c o n f i g u r a t i o n −>p r i n t R u l e ) { D i s p l a y : : t e x H s p a c e (* m y c o u t ) ; ( * m y c o u t ) r e s u l t , N o d e I t e r a t o r : : D E P T H _ F I R S T ) ; Node * cur ; // s = t [@] ˆ N p . u −> . . . w h i l e ( ( c u r=i t . n e x t ( ) ) ) i f ( t y p e i d ( * c u r )==t y p e i d ( E q u a l ) ) { E q u a l * e = ( E q u a l *) cur ; Node *s ; Node * other ; int way = 0; i f ( ( t y p e i d ( * ( o t h e r=e−>n 2 ) )==t y p e i d ( E x p o ) )&&( t y p e i d ( * e−>n 1 ) != t y p e i d ( V a r i a b l e ) ) ) s=e−>n 1 ; e l s e i f ( ( t y p e i d ( * ( o t h e r=e−>n 1 ) )==t y p e i d ( E x p o ) )&&( t y p e i d ( * e−>n 2 ) != t y p e i d ( V a r i a b l e ) ) ) { s=e−>n 2 ; way = 1; } else continue ; rerun : ; Node * curSearchExpo = s ; l i s t : : i t e r a t o r i t 2 = o t h e r −>h o l e P o s i t i o n −>b e g i n ( ) ; bool fail = false ;

bool

i f ( t y p e i d ( * s )==t y p e i d ( E x p o ) ) fail = true ; else w h i l e ( i t 2 != o t h e r −>h o l e P o s i t i o n −>e n d ( ) ) { i f ( t y p e i d ( * c u r S e a r c h E x p o ) != t y p e i d ( F u n c t i o n ) ) break ; i f ( ( ( F u n c t i o n * ) c u r S e a r c h E x p o )−>a r g u m e n t s . s i z e ( ) a r g u m e n t s [ * i t 2 ] ; i f ( t y p e i d ( * c u r S e a r c h E x p o )==t y p e i d ( E x p o ) ) { fail = true ; break ; } i t 2 ++; } if ( fail ) { i f ( w a y ==0) i f ( ( t y p e i d ( * ( o t h e r=e−>n 1 ) )==t y p e i d ( E x p o ) )&&( t y p e i d ( * e−>n 2 ) != t y p e i d ( V a r i a b l e ) ) ) { s=e−>n 2 ; way = 1; goto rerun ; } continue ; } i f ( c o n f i g u r a t i o n −>p r i n t R u l e ) { D i s p l a y : : t e x H s p a c e (* m y c o u t ) ; ( * m y c o u t ) f r e e )

62

a d d 2 −>a d d C o n d i t i o n ( n e w

C o n d A ( e x p o t e r m −>v a r −>d u p l i c a t e ( ) , n u m ) ) ;

i f ( c o n f i g u r a t i o n −>N c a n b e Z e r o ) a d d 2 −>a d d B r a n c h ( n e w E q u a l ( s−>d u p l i c a t e ( ) , e x p o t e r m −>n 1−>d u p l i c a t e ( ) ) ) ; else a d d 2 −>a d d B r a n c h ( n e w E q u a l ( s−>d u p l i c a t e ( ) , e x p o t e r m −>b u i l d O n e ( ) ) ) ; } i f ( ( e x p o t e r m −>f r e e ) | | ( e x p o t e r m −>e x p N u m >1) ) { add3 = new And () ; E x p o * n e w E x p o = ( E x p o * ) e x p o t e r m −>d u p l i c a t e ( ) ; i f ( n e w E x p o −>f r e e ) { N u m e r i c a l V a r * v a r = n e w N u m e r i c a l V a r ( p a r s e r −>g e n N u m e r i c a l V a l N a m e ( ) . c _ s t r ( ) , p a r s e r ) ; a d d 3 −>a d d C o n d i t i o n ( n e w C o n d A N p l u s B ( e x p o t e r m −>v a r −>d u p l i c a t e ( ) , 1 , v a r , 1 ) ) ; d e l e t e n e w E x p o −>v a r ; n e w E x p o −>v a r = v a r −>d u p l i c a t e ( ) ; } else n e w E x p o −>e x p N u m −−; a d d 3 −>a d d B r a n c h ( n e w }

E q u a l ( s−>d u p l i c a t e ( ) , e x p o t e r m −>b u i l d O n e ( n e w E x p o ) ) ) ;

i f ( ( a d d 2 ) &&(! a d d 3 ) ) it . r e p l a c e B y ( add2 ) ; e l s e i f ( ( a d d 3 ) &&(! a d d 2 ) ) it . r e p l a c e B y ( add3 ) ; else { Or * add = new Or () ; a d d −>a d d B r a n c h ( a d d 2 ) ; a d d −>a d d B r a n c h ( a d d 3 ) ; it . r e p l a c e B y ( add ) ; } return true ; } return } int

false ;

Unification : : gcd ( unsigned int a , unsigned { r e t u r n ( b != 0 ? g c d ( b , a % b ) : a ) ; }

int b )

/* * * i s l1 a prefix of l2 ? */ bool

Unification : : prefix ( const { i f ( l 1 . s i z e ( )>l 2 . s i z e ( ) ) return false ; l i s t &l 1 , c o n s t

l i s t &l 2 )

itp = l1 . begin () ; itq2 = l2 . begin () ;

w h i l e ( i t p != l 1 . e n d ( ) ) { if ( ( * i t p ) !=(* i t q 2 ) ) return false ; i t q 2 ++; i t p ++; } return true ; } /* * * m e r g i n g o f l 1 and l 2 */ l i s t U n i f i c a t i o n : : a p p e n d ( c o n s t l i s t &l 1 , c o n s t

l i s t &l 2 )

*/ bool

Unification : : tryApplyR3 () { N o d e I t e r a t o r i t ( p a r s e r −>r e s u l t ,& p a r s e r −>r e s u l t , N o d e I t e r a t o r : : D E P T H _ F I R S T ) ; Node * cur ; // s = t [@] ˆ N p . u −> . . . w h i l e ( ( c u r=i t . n e x t ( ) ) ) i f ( t y p e i d ( * c u r )==t y p e i d ( E q u a l ) ) { int way = 0; w h i l e ( w a y n 2 ) )==t y p e i d ( E x p o ) ) &&(( u=e−>n 1 )−>r h o t e r m ) ) ; e l s e i f ( ( t y p e i d ( * ( v=e−>n 1 ) )==t y p e i d ( E x p o ) ) &&(( u=e−>n 2 )−>r h o t e r m ) ) ; else continue ; N o d e I t e r a t o r it2 ( u , NULL , N o d e I t e r a t o r : : D E P T H _ F I R S T ) ; Node * cur2 ; w h i l e ( ( c u r 2=i t 2 . n e x t ( ) ) ) i f ( t y p e i d ( * c u r 2 )==t y p e i d ( E x p o ) ) { c o n s t l i s t p = i t 2 . g e t P o s i t i o n ( ) ; a s s e r t ( ( ( E x p o * ) c u r 2 )−>h o l e P o s i t i o n ) ; c o n s t l i s t &q 1 = * ( ( E x p o * ) c u r 2 )−>h o l e P o s i t i o n ; c o n s t l i s t &q 2 = * v−>h o l e P o s i t i o n ; i f ( ( q 1 . s i z e ( ) != q 2 . s i z e ( ) )&&( p r e f i x ( p , q 2 ) ) ) { int i ; int d = gcd (( u n s i g n e d int ) q1 . size () ,( u n s i g n e d int alpha1 = ( u n s i g n e d int ) q1 . size () / d ; int alpha2 = ( u n s i g n e d int ) q2 . size () / d ; // i n t m = a l p h a 1 * a l p h a 2 * d ;

int ) q2 . size () ) ;

i f ( c o n f i g u r a t i o n −>p r i n t R u l e ) { D i s p l a y : : t e x H s p a c e (* m y c o u t ) ; ( * m y c o u t ) d u p l i c a t e ( ) , v−>d u p l i c a t e ( ) ) ) ; a d d O r −>a d d B r a n c h ( a d d A n d ) ; } } f o r ( r 2=f i r s t ; r 2
f r e e ) { And * addAnd = new And () ; a d d A n d −>a d d C o n d i t i o n ( n e w

C o n d A ( ( ( E x p o * ) v )−>v a r −>d u p l i c a t e ( ) , r 2 ) ) ;

N o d e * n e w T e r m = v−>d u p l i c a t e ( ) ; i f ( ( ( E x p o * ) n e w T e r m )−>f r e e ) { d e l e t e ( ( E x p o * ) n e w T e r m )−>v a r ; ( ( E x p o * ) n e w T e r m )−>f r e e = f a l s e ; } ( ( E x p o * ) n e w T e r m )−>e x p N u m = r 2 ; a d d A n d −>a d d B r a n c h ( n e w E q u a l ( u−>d u p l i c a t e ( ) , n e w T e r m ) ) ; a d d O r −>a d d B r a n c h ( a d d A n d ) ; } e l s e i f ( ( ( E x p o * ) v )−>e x p N u m==r 2 ) { And * addAnd = new And () ; a d d A n d −>a d d B r a n c h ( n e w E q u a l ( u−>d u p l i c a t e ( ) , v−>d u p l i c a t e ( ) ) ) ; a d d O r −>a d d B r a n c h ( a d d A n d ) ; } } f o r ( r 2 =0; r 2
f r e e ; NumericalVar NumericalVar int int

* m1 ; * m2 ;

m1p ; m2p ;

if ( f1 ) { m 1 = n e w N u m e r i c a l V a r ( p a r s e r −>g e n N u m e r i c a l V a l N a m e ( ) . c _ s t r ( ) , p a r s e r ) ; a d d A n d −>a d d C o n d i t i o n ( n e w C o n d A N p l u s B ( ( ( E x p o * ) c u r 2 )−>v a r −>d u p l i c a t e ( ) , a l p h a 2 , m1 , r 1 ) ) ; } else { m 1 p = ( ( ( E x p o * ) c u r 2 )−>e x p N u m − r 1 ) ; i f ( ( m 1 p%a l p h a 2 ) != 0 ) { delete addAnd ; continue ; } m 1 p /= a l p h a 2 ; i f ( m 1 p g e n N u m e r i c a l V a l N a m e ( ) . c _ s t r ( ) , p a r s e r ) ; a d d A n d −>a d d C o n d i t i o n ( n e w C o n d A N p l u s B ( ( ( E x p o * ) v )−>v a r −>d u p l i c a t e ( ) , a l p h a 1 , m2 , r 2 ) ) ;

65

} else { m 2 p = ( ( ( E x p o * ) v )−>e x p N u m − r 2 ) / a l p h a 1 ; i f ( ( m 2 p%a l p h a 1 ) != 0 ) { if ( f1 ) delete m1 ; delete addAnd ; continue ; } m 2 p /= a l p h a 1 ; i f ( m 2 p n 2−>d u p l i c a t e ( ) ; f o r ( i =0; ib u i l d O n e ( t 1 ) ; N o d e * t 2 = ( ( E x p o * ) v )−>n 2−>d u p l i c a t e ( ) ; f o r ( i =0; ib u i l d O n e ( t 2 ) ; N o d e * h 1 = ( ( E x p o * ) c u r 2 )−>n 1−>d u p l i c a t e ( ) ; f o r ( i =0; i
b u i l d O n e ( h 1 ) ; N o d e * h 2 = ( ( E x p o * ) v )−>n 1−>d u p l i c a t e ( ) ; f o r ( i =0; ib u i l d O n e ( h 2 ) ; l i s t tmp = p ;

Node *k ; if ( f1 ) k = (( Function else k = (( Function

* ) u )−>b u i l d O n e A n d R e p l a c e ( t m p , n e w E x p o ( h 1 , m 1 , t 1 ) ) ; * ) u )−>b u i l d O n e A n d R e p l a c e ( t m p , n e w E x p o ( h 1 , m 1 p , t 1 ) ) ;

if ( f2 ) a d d A n d −>a d d B r a n c h ( n e w else a d d A n d −>a d d B r a n c h ( n e w

Equal (k , new

E x p o ( h2 , m2 , t 2 ) ) ) ;

Equal (k , new

E x p o ( h2 , m2p , t 2 ) ) ) ;

a d d O r −>a d d B r a n c h ( a d d A n d ) ; } it . r e p l a c e B y ( addOr ) ; return true ; } } } return }

} false ;

/* * * A p p l i c a t i o n o f r u l e s R4 ( U n f o l d 3 ) */ bool

Unification : : tryApplyR4 () { N o d e I t e r a t o r i t ( p a r s e r −>r e s u l t ,& p a r s e r −>r e s u l t , N o d e I t e r a t o r : : D E P T H _ F I R S T ) ; Node * cur ; w h i l e ( ( c u r=i t . n e x t ( ) ) ) i f ( t y p e i d ( * c u r )==t y p e i d ( E q u a l ) ) { int way = 0; w h i l e ( w a y n 2 ) )==t y p e i d ( E x p o ) ) &&(( u=e−>n 1 )−>r h o t e r m ) ) ; e l s e i f ( ( t y p e i d ( * ( v=e−>n 1 ) )==t y p e i d ( E x p o ) ) &&(( u=e−>n 2 )−>r h o t e r m ) ) ; else continue ; N o d e I t e r a t o r it2 ( u , NULL , N o d e I t e r a t o r : : D E P T H _ F I R S T ) ; Node * cur2 ; w h i l e ( ( c u r 2=i t 2 . n e x t ( ) ) )

66

i f ( t y p e i d ( * c u r 2 )==t y p e i d ( E x p o ) ) { c o n s t l i s t p = i t 2 . g e t P o s i t i o n ( ) ; c o n s t l i s t &q 1 = * ( ( E x p o * ) c u r 2 )−>h o l e P o s i t i o n ; c o n s t l i s t &q 2 = * v−>h o l e P o s i t i o n ; i f ( ( p r e f i x ( p , q 2 ) ) &&((! p r e f i x ( q 2 , a p p e n d ( p , q 1 ) ) ) | | ( ! p r e f i x ( a p p e n d ( p , q 1 ) , a p p e n d ( q 2 , q 2 ))))) { i f ( c o n f i g u r a t i o n −>p r i n t R u l e ) { D i s p l a y : : t e x H s p a c e (* m y c o u t ) ; ( * m y c o u t ) a d d B r a n c h ( a d d A n d ) ; } } i f ( ( ( E x p o * ) c u r 2 )−>f r e e ) { And * addAnd = new And () ; a d d A n d −>a d d C o n d i t i o n ( n e w

C o n d A ( ( ( E x p o * ) c u r 2 )−>v a r −>d u p l i c a t e ( ) , 1 ) ) ;

a s s e r t ( t y p e i d ( * u )==t y p e i d ( F u n c t i o n ) ) ; l i s t t m p = p ; a d d A n d −>a d d B r a n c h ( n e w E q u a l ( ( ( F u n c t i o n * ) u )−>b u i l d O n e A n d R e p l a c e ( t m p , ( ( E x p o * ) c u r 2 )−>b u i l d O n e ( ) ) , ( ( E x p o * ) v )−>d u p l i c a t e ( ) ) ) ; a d d O r −>a d d B r a n c h ( a d d A n d ) ; } else { i f ( ( ( E x p o * ) c u r 2 )−>e x p N u m ==1) { And * addAnd = new And () ; l i s t t m p = p ; a d d A n d −>a d d B r a n c h ( n e w E q u a l ( ( ( F u n c t i o n * ) u )−>b u i l d O n e A n d R e p l a c e ( t m p , ( ( E x p o * ) c u r 2 )−>b u i l d O n e ( ) ) , ( ( E x p o * ) v )−>d u p l i c a t e ( ) ) ) ; a d d O r −>a d d B r a n c h ( a d d A n d ) ; } } i f ( ( ( E x p o * ) v )−>f r e e ) { And * addAnd = new And () ; a d d A n d −>a d d C o n d i t i o n ( n e w

C o n d A ( ( ( E x p o * ) v )−>v a r −>d u p l i c a t e ( ) , 2 ) ) ;

67

a d d A n d −>a d d B r a n c h ( n e w E q u a l ( ( ( E x p o * ) v )−>b u i l d T w o ( ) , ( ( E x p o * ) u )−>d u p l i c a t e ( ) )); a d d O r −>a d d B r a n c h ( a d d A n d ) ; } else { i f ( ( ( E x p o * ) v )−>e x p N u m ==2) { And * addAnd = new And () ; a d d A n d −>a d d B r a n c h ( n e w E q u a l ( ( ( E x p o * ) v )−>b u i l d O n e ( ) , ( ( E x p o * ) u )−> duplicate () ) ) ; a d d O r −>a d d B r a n c h ( a d d A n d ) ; } } bool bool And

f 1 = ( ( E x p o * ) c u r 2 )−>f r e e ; f 2 = ( ( E x p o * ) v )−>f r e e ;

* addAnd = new And () ;

N u m e r i c a l V a r * m1 = NULL ; int m1i ; if ( f1 ) { m 1 = n e w N u m e r i c a l V a r ( p a r s e r −>g e n N u m e r i c a l V a l N a m e ( ) . c _ s t r ( ) , p a r s e r ) ; a d d A n d −>a d d C o n d i t i o n ( n e w C o n d A N p l u s B ( ( ( E x p o * ) c u r 2 )−>v a r −>d u p l i c a t e ( ) , 1 , m 1 ,1) ) ; } else { m 1 i = ( ( E x p o * ) c u r 2 )−>e x p N u m −1; i f ( m 1 i g e n N u m e r i c a l V a l N a m e ( ) . c _ s t r ( ) , p a r s e r ) ; a d d A n d −>a d d C o n d i t i o n ( n e w C o n d A N p l u s B ( ( ( E x p o * ) v )−>v a r −>d u p l i c a t e ( ) , 1 , m 2 , 2 ) ) ; } else { m 2 i = ( ( E x p o * ) v )−>e x p N u m −2; i f ( m 2 i c o n d i t i o n s . f r o n t ( ) ; assert ( m1 ) ; delete m1 ; } delete addAnd ; continue ; } } E x p o * h 1 = ( E x p o * ) v−>d u p l i c a t e ( ) ; if ( f2 ) { d e l e t e h 1−>v a r ; h 1−>v a r = m 2 ; } else h 1−>e x p N u m = m 2 i ; E x p o * h 2 = ( E x p o * ) c u r 2 −>d u p l i c a t e ( ) ; if ( f1 ) { d e l e t e h 2−>v a r ; h 2−>v a r = m 1 ; } else h 2−>e x p N u m = m 1 i ; l i s t t m p = p ; a d d A n d −>a d d B r a n c h ( n e w E q u a l ( ( ( F u n c t i o n * ) u )−>b u i l d O n e A n d R e p l a c e ( t m p , ( ( E x p o * ) c u r 2 )−>b u i l d O n e ( h 2 ) ) , ( ( E x p o * ) v )−>b u i l d T w o ( h 1 ) ) ) ; a d d O r −>a d d B r a n c h ( a d d A n d ) ; i f ( a d d O r −>b r a n c h s . e m p t y ( ) ) {

68

delete addOr ; continue ; } it . r e p l a c e B y ( addOr ) ; return true ; } }

return }

} } false ;

/* * * A p p l i c a t i o n o f r u l e s R5 ( Decompose 2 ) */ bool

Unification : : tryApplyR5 () { N o d e I t e r a t o r i t ( p a r s e r −>r e s u l t ,& p a r s e r −>r e s u l t , N o d e I t e r a t o r : : D E P T H _ F I R S T ) ; Node * cur ; w h i l e ( ( c u r=i t . n e x t ( ) ) ) i f ( t y p e i d ( * c u r )==t y p e i d ( E q u a l ) ) { E q u a l * e = ( E q u a l *) cur ; Node *u ; Node *v ; int way = 0; i f ( ( t y p e i d ( * ( v=e−>n 2 ) )==t y p e i d ( E x p o ) ) &&(( u=e−>n 1 )−>r h o t e r m ) ) ; e l s e i f ( ( t y p e i d ( * ( v=e−>n 1 ) )==t y p e i d ( E x p o ) ) &&(( u=e−>n 2 )−>r h o t e r m ) ) way = 1; else continue ;

rerun : ; N o d e I t e r a t o r it2 ( u , NULL , N o d e I t e r a t o r : : D E P T H _ F I R S T ) ; Node * cur2 ; w h i l e ( ( c u r 2=i t 2 . n e x t ( ) ) ) i f ( t y p e i d ( * c u r 2 )==t y p e i d ( E x p o ) ) { c o n s t l i s t p = i t 2 . g e t P o s i t i o n ( ) ; c o n s t l i s t &q 1 = * ( ( E x p o * ) c u r 2 )−>h o l e P o s i t i o n ; // c o n s t l i s t &q2 = * v−>h o l e P o s i t i o n ; i f ( c o n f i g u r a t i o n −>p r i n t R u l e ) { D i s p l a y : : t e x H s p a c e (* m y c o u t ) ; ( * m y c o u t ) d u p l i c a t e ( ) ) , ( ( E x p o * ) v )−>n 1−>b u i l d O n e A n d R e p l a c e ( t m p 2=p , a d d A −>d u p l i c a t e ( ) ) )); a d d A n d −>a d d B r a n c h ( n e w E q u a l ( ( ( E x p o * ) c u r 2 )−>n 1−>b u i l d O n e A n d R e p l a c e ( t m p 1=q p r i m , a d d A −>d u p l i c a t e ( ) ) , w 2−>b u i l d O n e A n d R e p l a c e ( t m p 2=q p r i m , a d d A −>d u p l i c a t e ( ) ) )); Or

* addOr = new Or () ;

bool

buildit = true ;

And * addAnd2 = new And () ; i f ( ( ! ( ( E x p o * ) c u r 2 )−>f r e e ) & & ( ! ( ( E x p o * ) v )−>f r e e ) ) { i f ( ( ( E x p o * ) c u r 2 )−>e x p N u m ==(( E x p o * ) v )−>e x p N u m ) ; else b u i l d i t= f a l s e ; } else { i f ( ( ( ( E x p o * ) c u r 2 )−>f r e e ) &&((( E x p o * ) v )−>f r e e ) ) a d d A n d 2 −>a d d C o n d i t i o n ( n e w C o n d N ( ( ( E x p o * ) c u r 2 )−>v a r −>d u p l i c a t e ( ) , ( ( E x p o * ) v )−> v a r −>d u p l i c a t e ( ) ) ) ; e l s e i f ( ! ( ( E x p o * ) c u r 2 )−>f r e e ) a d d A n d 2 −>a d d C o n d i t i o n ( n e w C o n d A ( ( ( E x p o * ) v )−>v a r −>d u p l i c a t e ( ) , ( ( E x p o * ) c u r 2 )−> expNum ) ) ; else a d d A n d 2 −>a d d C o n d i t i o n ( n e w C o n d A ( ( ( E x p o * ) c u r 2 )−>v a r −>d u p l i c a t e ( ) , ( ( E x p o * ) v )−> expNum ) ) ; } if ( b u i l d i t ) { a d d A n d 2 −>a d d B r a n c h ( n e w E q u a l ( u−>b u i l d O n e A n d R e p l a c e ( t m p 1=p , ( ( E x p o * ) c u r 2 )−>n 2−> d u p l i c a t e ( ) ) , ( ( E x p o * ) v )−>n 2−>d u p l i c a t e ( ) ) ) ; a d d O r −>a d d B r a n c h ( a d d A n d 2 ) ; } else delete addAnd2 ; int

f i r s t = ( t h i s −>c o n f i g u r a t i o n −>N c a n b e Z e r o ) ? 0 : 1 ;

addAnd2 = new And () ; int m1i ; N u m e r i c a l V a r * m1 = NULL ; i f ( ( ! ( ( E x p o * ) c u r 2 )−>f r e e ) & & ( ! ( ( E x p o * ) v )−>f r e e ) ) { m 1 i = ( ( E x p o * ) c u r 2 )−>e x p N u m − ( ( E x p o * ) v )−>e x p N u m ; i f ( m 1 i>=f i r s t ) ; else b u i l d i t= f a l s e ; } else { m 1 = n e w N u m e r i c a l V a r ( p a r s e r −>g e n N u m e r i c a l V a l N a m e ( ) . c _ s t r ( ) , p a r s e r ) ; i f ( ( ( ( E x p o * ) c u r 2 )−>f r e e ) &&((( E x p o * ) v )−>f r e e ) ) a d d A n d 2 −>a d d C o n d i t i o n ( n e w C o n d N p l u s N ( ( ( E x p o * ) c u r 2 )−>v a r −>d u p l i c a t e ( ) , ( ( E x p o * ) v )−>v a r −>d u p l i c a t e ( ) , m 1−>d u p l i c a t e ( ) ) ) ; e l s e i f ( ! ( ( E x p o * ) c u r 2 )−>f r e e ) a d d A n d 2 −>a d d C o n d i t i o n ( n e w C o n d A N p l u s B ( ( ( E x p o * ) v )−>v a r −>d u p l i c a t e ( ) , −1 , m 1−> d u p l i c a t e ( ) , ( ( E x p o * ) c u r 2 )−>e x p N u m ) ) ; else a d d A n d 2 −>a d d C o n d i t i o n ( n e w C o n d A N p l u s B ( ( ( E x p o * ) c u r 2 )−>v a r −>d u p l i c a t e ( ) , 1 , m 1−> d u p l i c a t e ( ) , ( ( E x p o * ) v )−>e x p N u m ) ) ; } if ( b u i l d i t ) { N o d e * h 1 = u−>d u p l i c a t e ( ) ; E x p o * c o u p = ( E x p o * ) h 1−>f i n d ( t m p 1=p ) ; a s s e r t ( t y p e i d ( * c o u p )==t y p e i d ( E x p o ) ) ; c o u p −>f r e e = ( m 1 != N U L L ) ; if ( m1 ) c o u p −>v a r = m 1 ; else c o u p −>e x p N u m = m 1 i ;

70

a d d A n d 2 −>a d d B r a n c h ( n e w E q u a l ( h 1 , ( ( E x p o * ) v )−>n 2 ) ) ; a d d O r −>a d d B r a n c h ( a d d A n d 2 ) ; } else delete

addAnd2 ;

addAnd2 = new And () ; m1 = NULL ; i f ( ( ! ( ( E x p o * ) c u r 2 )−>f r e e ) & & ( ! ( ( E x p o * ) v )−>f r e e ) ) { m 1 i = ( ( E x p o * ) v )−>e x p N u m − ( ( E x p o * ) c u r 2 )−>e x p N u m ; i f ( m 1 i>=f i r s t ) ; else b u i l d i t= f a l s e ; } else { m 1 = n e w N u m e r i c a l V a r ( p a r s e r −>g e n N u m e r i c a l V a l N a m e ( ) . c _ s t r ( ) , p a r s e r ) ; i f ( ( ( ( E x p o * ) v )−>f r e e ) &&((( E x p o * ) c u r 2 )−>f r e e ) ) a d d A n d 2 −>a d d C o n d i t i o n ( n e w C o n d N p l u s N ( ( ( E x p o * ) v )−>v a r −>d u p l i c a t e ( ) , ( ( E x p o * ) c u r 2 )−>v a r −>d u p l i c a t e ( ) , m 1−>d u p l i c a t e ( ) ) ) ; e l s e i f ( ! ( ( E x p o * ) c u r 2 )−>f r e e ) a d d A n d 2 −>a d d C o n d i t i o n ( n e w C o n d A N p l u s B ( ( ( E x p o * ) c u r 2 )−>v a r −>d u p l i c a t e ( ) , −1 , m 1−> d u p l i c a t e ( ) , ( ( E x p o * ) v )−>e x p N u m ) ) ; else a d d A n d 2 −>a d d C o n d i t i o n ( n e w C o n d A N p l u s B ( ( ( E x p o * ) v )−>v a r −>d u p l i c a t e ( ) , 1 , m 1−> d u p l i c a t e ( ) , ( ( E x p o * ) c u r 2 )−>e x p N u m ) ) ; } if ( b u i l d i t ) { E x p o * h 1 = ( E x p o * ) v−>d u p l i c a t e ( ) ; h 1−>f r e e = ( m 1 != N U L L ) ; if ( m1 ) h 1−>v a r = m 1 ; else h 1−>e x p N u m = m 1 i ; a d d A n d 2 −>a d d B r a n c h ( n e w E q u a l ( w 1−>b u i l d O n e A n d R e p l a c e ( t m p 1=p , ( ( E x p o * ) c u r 2 )−>n 2−> d u p l i c a t e () ) , h1 ) ) ; a d d O r −>a d d B r a n c h ( a d d A n d 2 ) ; } else delete

addAnd2 ;

i f ( a d d O r −>b r a n c h s . e m p t y ( ) ) delete addOr ; else a d d A n d −>a d d B r a n c h ( a d d O r ) ; // i t . r e p l a c e B y ( S e t D i s j u n c t i v e S y s t e m ( ( Node * ) addAnd ) ) ; it . r e p l a c e B y ( ( Node *) a d d A n d ) ; return true ; } i f ( w a y ==0) i f ( ( t y p e i d ( * ( v=e−>n 1 ) )==t y p e i d ( E x p o ) ) &&(( u=e−>n 2 )−>r h o t e r m ) ) { way = 1; goto rerun ; } } return }

false ;

/* * * E x p l o r e and c h e c k d e f i n i t i o n ( i s t h e c u r r e n t s y s t e m w e l l d e f i n e v a r i a b l e s ) */ bool U n i f i c a t i o n : : e x p l o D e f i n i t i o n ( Node *n , S i m p l e S o l u t i o n * s o l u t i o n ) { bool

val = true ;

i f ( t y p e i d ( * n )==t y p e i d ( C l a s h ) ) val = false ; e l s e i f ( t y p e i d ( * n )==t y p e i d ( T r i v i a l ) ) val = true ; e l s e i f ( t y p e i d ( * n )==t y p e i d ( E q u a l ) ) { E q u a l * e = ( E q u a l *) n ; val = true ; i f ( t y p e i d ( * e−>n 1 )==t y p e i d ( V a r i a b l e ) ) s o l u t i o n −>v a r i a b l e S o l u t i o n [ ( ( V a r i a b l e else

* ) ( e−>n 1 ) )−>i d ] . d e f i n i t i o n = e−>n 2 ;

71

return false ; i f ( ! e x p l o D e f i n i t i o n ( e−>n 2 , s o l u t i o n ) ) val = false ; } e l s e i f ( t y p e i d ( * n )==t y p e i d ( A n d ) ) { And * a = ( And *) n ; val = true ; l i s t : : i t e r a t o r i t = a−>b r a n c h s . b e g i n ( ) ; w h i l e ( i t != a−>b r a n c h s . e n d ( ) ) { i f ( ! e x p l o D e f i n i t i o n (* it , s o l u t i o n ) ) { val = false ; break ; } i t ++; } l i s t : : i t e r a t o r i t 2 = a−>c o n d i t i o n s . b e g i n ( ) ; w h i l e ( i t 2 != a−>c o n d i t i o n s . e n d ( ) ) { /* // m u l t i d e f i n i t i o n i f ( s o l u t i o n −>n u m e r i c a l v a r i a b l e S o l u t i o n [ ( * i t 2 )−>n1−>i d ] . d e f i n i t i o n c ) { val = f a l s e ; break ; } else */ s o l u t i o n −>n u m e r i c a l v a r i a b l e S o l u t i o n [ ( * i t 2 )−>n 1−>i d ] . d e f i n i t i o n c . p u s h _ b a c k ( * i t 2 ) ; i f ( t y p e i d ( * * i t 2 )==t y p e i d ( C o n d A N p l u s B ) ) s o l u t i o n −>n u m e r i c a l v a r i a b l e S o l u t i o n [ ( ( C o n d A N p l u s B * ) ( * i t 2 ) )−>n 2−>i d ] . s e e o u t s i d e = t r u e ; e l s e i f ( t y p e i d ( * * i t 2 )==t y p e i d ( C o n d N p l u s N ) ) { s o l u t i o n −>n u m e r i c a l v a r i a b l e S o l u t i o n [ ( ( C o n d N p l u s N * ) ( * i t 2 ) )−>n 2−>i d ] . s e e o u t s i d e = t r u e ; s o l u t i o n −>n u m e r i c a l v a r i a b l e S o l u t i o n [ ( ( C o n d N p l u s N * ) ( * i t 2 ) )−>n 3−>i d ] . s e e o u t s i d e = t r u e ; } e l s e i f ( t y p e i d ( * * i t 2 )==t y p e i d ( C o n d N ) ) s o l u t i o n −>n u m e r i c a l v a r i a b l e S o l u t i o n [ ( ( C o n d N * ) ( * i t 2 ) )−>n 2−>i d ] . s e e o u t s i d e = t r u e ; i t 2 ++; } } i f ( t y p e i d ( * n )==t y p e i d ( F u n c t i o n ) ) { F u n c t i o n * f = ( F u n c t i o n *) n ; v e c t o r : : i t e r a t o r i t = f−>a r g u m e n t s . b e g i n ( ) ; val = true ; w h i l e ( i t != f−>a r g u m e n t s . e n d ( ) ) { i f ( ! e x p l o D e f i n i t i o n (* it , s o l u t i o n ) ) { val = false ; break ; } i t ++; } } e l s e i f ( t y p e i d ( * n )==t y p e i d ( O r ) ) { a s s e r t ( f a l s e ) ; // C e c i n ’ e s t p a s une f o r m e d i s j o n c t i v e ( l e s Ors o n t d¨ı ¿ ½ j¨ı ¿ ½ ) } e l s e i f ( t y p e i d ( * n )==t y p e i d ( E x p o ) ) { Expo * e = ( Expo *) n ; v a l = e x p l o D e f i n i t i o n ( e−>n 1 , s o l u t i o n ) ; i f ( ! e x p l o D e f i n i t i o n ( e−>n 2 , s o l u t i o n ) ) val = false ; i f ( e−>f r e e ) s o l u t i o n −>n u m e r i c a l v a r i a b l e S o l u t i o n [ e−>v a r −>i d ] . s e e o u t s i d e = t r u e ; } e l s e i f ( t y p e i d ( * n )==t y p e i d ( V a r i a b l e ) ) { V a r i a b l e * v = ( V a r i a b l e *) n ; s o l u t i o n −>v a r i a b l e S o l u t i o n [ v−>i d ] . s e e o u t s i d e = t r u e ; val = true ; } return val ; } else

/* *

* *

A function that v e r i f i e s i f a given s o l u t i o n i s a r e a l i e . can be s a t i s f i e d . We t h e n l i s t t h e s o l u t i o n s .

72

solution ,

¨ı ¿ ½ t¨ı ¿ ½

t r a i t¨ı ¿ ½ s

* I f not , THIS i s n o t a s o l u t i o n but t h e r e may be a n o t h e r one t h a t i s v a l i d . */ bool Unification : : verifValidPresburger ( Node * n )

{ # i f d e f DEBUG ( * m y c o u t ) c o n d i t i o n s . e n d ( ) ) { C o n d i t i o n * tmpc = * it ; i f ( n u m v a r s . f i n d ( t m p c −>n 1−>i d ) == n u m v a r s . e n d ( ) ) n u m v a r s [ t m p c −>n 1−>i d ] = n u m v a r s . s i z e ( ) ; i f ( t y p e i d ( * t m p c ) == t y p e i d ( C o n d N ) ) { i f ( n u m v a r s . f i n d ( ( ( C o n d N * ) t m p c )−>n 2−>i d ) == n u m v a r s . e n d ( ) ) n u m v a r s [ ( ( C o n d N * ) t m p c )−>n 2−>i d ] = n u m v a r s . s i z e ( ) ; } e l s e i f ( t y p e i d ( * t m p c ) == t y p e i d ( C o n d A N p l u s B ) ) { i f ( n u m v a r s . f i n d ( ( ( C o n d A N p l u s B * ) t m p c )−>n 2−>i d ) == n u m v a r s . e n d ( ) ) n u m v a r s [ ( ( C o n d A N p l u s B * ) t m p c )−>n 2−>i d ] = n u m v a r s . s i z e ( ) ; } e l s e i f ( t y p e i d ( * t m p c ) == t y p e i d ( C o n d N p l u s N ) ) { i f ( n u m v a r s . f i n d ( ( ( C o n d N p l u s N * ) t m p c )−>n 2−>i d ) == n u m v a r s . e n d ( ) ) n u m v a r s [ ( ( C o n d N p l u s N * ) t m p c )−>n 2−>i d ] = n u m v a r s . s i z e ( ) ; i f ( n u m v a r s . f i n d ( ( ( C o n d N p l u s N * ) t m p c )−>n 3−>i d ) == n u m v a r s . e n d ( ) ) n u m v a r s [ ( ( C o n d N p l u s N * ) t m p c )−>n 3−>i d ] = n u m v a r s . s i z e ( ) ; } // o n l y CondN l e f t and i t i s a l r e a d y t a k e n i n t o a c c o u n t i t ++; } / * v e c t o r numvars ; // t r i c k t o c o u n t w i t h o u t d u p l i c a t e s // OU UN TABLEAU l i s t : : i t e r a t o r i t = ( ( And * ) n )−>c o n d i t i o n s . b e g i n ( ) ; w h i l e ( i t != ( ( And * ) n )−>c o n d i t i o n s . end ( ) ) { C o n d i t i o n * tmpc = * i t ; i f ( numvars [ tmpc−>n1−>i d ] == numvars . end ( ) ) numvars [ tmpc−>n1−>i d ] = numvars . s i z e ( ) ; i f ( t y p e i d ( * tmpc ) == t y p e i d ( CondN ) ) { i f ( numvars . f i n d ( ( ( CondN * ) tmpc )−>n2−>i d ) == numvars . end ( ) ) numvars [ ( ( CondN * ) tmpc )−>n2−>i d ] = numvars . s i z e ( ) ; } e l s e i f ( t y p e i d ( * tmpc ) == t y p e i d ( CondANplusB ) ) { i f ( numvars . f i n d ( ( ( CondANplusB * ) tmpc )−>n2−>i d ) == numvars . end ( ) ) numvars [ ( ( CondANplusB * ) tmpc )−>n2−>i d ] = numvars . s i z e ( ) ; } e l s e i f ( t y p e i d ( * tmpc ) == t y p e i d ( CondNplusN ) ) { i f ( numvars . f i n d ( ( ( CondNplusN * ) tmpc )−>n2−>i d ) == numvars . end ( ) ) numvars [ ( ( CondNplusN * ) tmpc )−>n2−>i d ] = numvars . s i z e ( ) ; i f ( numvars . f i n d ( ( ( CondNplusN * ) tmpc )−>n3−>i d ) == numvars . end ( ) ) numvars [ ( ( CondNplusN * ) tmpc )−>n3−>i d ] = numvars . s i z e ( ) ; } // o n l y CondN l e f t and i t i s a l r e a d y t a k e n i n t o a c c o u n t i t ++; } */ # i f d e f DEBUG ( * m y c o u t ) d i s p l a y ( * m y c o u t ) ; # endif automL . push_back ( tmp ) ; i t ++; } // now merge t h e a u t o m a t a s w i t h t h e h e l p // b u i l d s

of

the

automates groupes

l i s t g r o u p e s ; l i s t
: : i t e r a t o r i t 7 = a u t o m L . b e g i n ( ) ; w h i l e ( i t 7 != a u t o m L . e n d ( ) ) { Groupe tmp ; tmp . a u t o s . p u s h _ b a c k (* it7 ) ; groupes . push_back ( tmp ) ; i t 7 ++; } l i s t : : i t e r a t o r i t g 1 , i t g 2 ; l i s t : : i t e r a t o r i t a 1 , i t a 2 ; bool do

todo ;

73

b i t s map ; )

{ todo = false ; itg1 = groupes . begin () ; w h i l e ( i t g 1 != g r o u p e s . e n d ( ) ) { itg2 = itg1 ; i f ( i t g 2 != g r o u p e s . e n d ( ) ) i t g 2 ++; w h i l e ( i t g 2 != g r o u p e s . e n d ( ) ) { i t a 1 = i t g 1 −>a u t o s . b e g i n ( ) ; w h i l e ( i t a 1 != i t g 1 −>a u t o s . e n d ( ) ) { i t a 2 = i t g 2 −>a u t o s . b e g i n ( ) ; w h i l e ( i t a 2 != i t g 2 −>a u t o s . e n d ( ) ) { i f ( ( * i t a 1 )−>i s I n t e r s e c t ( * i t a 2 , n u m v a r s . s i z e ( ) ) ) { todo = true ; (* itg1 ) . a u t o s . p u s h _ b a c k (* ita2 ) ; (* itg2 ) . a u t o s . e r a s e ( ita2 ) ; if ((* itg2 ) . autos . empty () ) groupes . erase ( itg2 ) ; goto groupeend ; } i t a 2 ++; } i t a 1 ++; } i t g 2 ++; } i t g 1 ++; } groupeend : ; } while ( todo ) ; # i f d e f DEBUG ( * m y c o u t ) s i ) ; i t 2 ++; } exploPara . statePara . push_back ( para ) ; // While empty while (! exploPara . statePara . empty () ) { para = exploPara . statePara . front () ; exploPara . statePara . pop_front () ; bool allfinal = true ; l i s t : : i t e r a t o r i t 3 = p a r a . a c t i v e s . b e g i n ( ) ; w h i l e ( i t 3 != p a r a . a c t i v e s . e n d ( ) ) { i f ( ( * i t 3 )−>v a l u e != ( * i t 3 )−>a u t o m a t a −>c v a l u e ) { allfinal = false ; break ; } i t 3 ++; } if ( a l l f i n a l ) { isgooda = true ; goto gooda ; } State * first = para . actives . front () ; if ( para . a c t i v e s . empty () ) continue ; i f ( f i r s t −>s t e p . e m p t y ( ) ) continue ;

74

l i s t : : i t e r a t o r i t 4 = f i r s t −>s t e p . b e g i n ( ) ; w h i l e ( i t 4 != f i r s t −>s t e p . e n d ( ) ) { StatePara newPara ; n e w P a r a . a c t i v e s . p u s h _ b a c k ( ( * i t 4 )−>s t ) ; bool good2 = true ; it3 = para . actives . begin () ; i t 3 ++; w h i l e ( i t 3 != p a r a . a c t i v e s . e n d ( ) ) { bool good = false ; l i s t : : i t e r a t o r i t 5 = ( * i t 3 )−>s t e p . b e g i n ( ) ; w h i l e ( i t 5 ! = ( * i t 3 )−>s t e p . e n d ( ) ) { // c h e r c h e r * i t 5 ”=” * i t 4 // i f ( ! memcmp ( ( * i t 5 )−>b i t s , ( * i t 4 )−>b i t s , s i z e o f ( i n t ) * numvars . s i z e ( ) ) ) unsigned int i ; bool err = false ; f o r ( i =0; ib i t s [ i ]==−1) | | ( ( * i t 4 )−>b i t s [ i ]==−1) | | ( ( * i t 4 )−>b i t s [ i ]==( * i t 5 ) −>b i t s [ i ] ) ) ; else err = true ; if ( ! err ) { n e w P a r a . a c t i v e s . p u s h _ b a c k ( ( * i t 5 )−>s t ) ; good = true ; break ; } i t 5 ++; } if ( ! good ) { good2 = false ; break ; } i t 3 ++; } if ( ! good2 ) break ; exploPara . statePara . push_back ( newPara ) ; i t 4 ++; } } gooda : ; if ( ! i s g o o d a ) return false ; i t g 1 ++; } return true ; } // t r i v i a l c a s e : no N u m e r i c a l Value C o n d i t i o n return true ; } /* * * c h e c k a l l s o l u t i o n s ( and d e l e t e t h e bad o n e s ) . */ bool

Unification : : checkDefinition () { i f ( t y p e i d ( * p a r s e r −>r e s u l t )==t y p e i d ( O r ) ) // many d i f f e r e n t s o l u t i o n s t h a t we s p l i t { l i s t : : i t e r a t o r i t = ( ( O r * ) ( p a r s e r −>r e s u l t ) )−>b r a n c h s . b e g i n ( ) ; w h i l e ( i t ! = ( ( O r * ) ( p a r s e r −>r e s u l t ) )−>b r a n c h s . e n d ( ) ) { S i m p l e S o l u t i o n * s o l = n e w S i m p l e S o l u t i o n ( ( u n s i g n e d i n t ) p a r s e r −>v a r i a b l e t a b . s i z e ( ) , ( u n s i g n e d i n t ) p a r s e r −>n u m e r i c a l v a r i a b l e t a b . s i z e ( ) , t h i s ) ; solutions . push_back ( sol ) ; s o l −>f a i l = ! e x p l o D e f i n i t i o n ( * i t , s o l ) ; i f ( c o n f i g u r a t i o n −>p r e s B u r g e r V e r i f ) i f ( ! s o l −>f a i l ) s o l −>f a i l = ! v e r i f V a l i d P r e s b u r g e r ( * i t ) ; /* S o l v e r : : Graph * g r = new S o l v e r : : Graph ( * i t , t h i s ) ; s o l u t i o n s . p u s h b a c k ( gr−>run ( ) ) ; */ i t ++; }

75

} e l s e // o n l y one s o l u t i o n s o t h e r e i s no need t o s p l i t { S i m p l e S o l u t i o n * s o l = n e w S i m p l e S o l u t i o n ( ( u n s i g n e d i n t ) p a r s e r −>v a r i a b l e t a b . s i z e ( ) , ( u n s i g n e d i n t ) p a r s e r −>n u m e r i c a l v a r i a b l e t a b . s i z e ( ) , t h i s ) ; solutions . push_back ( sol ) ; s o l −>f a i l = ! e x p l o D e f i n i t i o n ( p a r s e r −>r e s u l t , s o l ) ; i f ( c o n f i g u r a t i o n −>p r e s B u r g e r V e r i f ) i f ( ! s o l −>f a i l ) s o l −>f a i l = ! v e r i f V a l i d P r e s b u r g e r ( p a r s e r −>r e s u l t ) ; /* S o l v e r : : Graph * g r = new S o l v e r : : Graph ( p a r s e r −>r e s u l t , t h i s ) ; s o l u t i o n s . p u s h b a c k ( gr−>run ( ) ) ; */ } l i s t : : i t e r a t o r i t = s o l u t i o n s . b e g i n ( ) ; w h i l e ( i t != s o l u t i o n s . e n d ( ) ) { i f ( ( * i t )−>c h e c k ( ) ) i t ++; else it = s o l u t i o n s . erase ( it ) ; } return ! solutions . empty () ; } /* * * display a solution */ void

S i m p l e S o l u t i o n : : d i s p l a y ( o s t r e a m &o ) { unsigned int i ; f o r ( i =0; ip a r s e r −>n u m e r i c a l v a r i a b l e t a b [ i ] . automatic ) ) { o