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 2f 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 2f 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; ib 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