From b98eee6525c152f619b353df7cf3f075101126a1 Mon Sep 17 00:00:00 2001 From: Thomas Pietrzak Date: Sun, 23 Sep 2018 16:14:02 +0200 Subject: [PATCH 1/1] init --- Exemple | Bin 0 -> 71692 bytes IExp.cpp | 249 +++++++++++++++++++++++++++++++++++++ IExp.h | 56 +++++++++ Makefile | 15 +++ PopExp.cpp | 51 ++++++++ PopExp.h | 28 +++++ doc.zip | Bin 0 -> 77115 bytes expression/Constante.cpp | 51 ++++++++ expression/Constante.h | 64 ++++++++++ expression/Et.cpp | 50 ++++++++ expression/Et.h | 56 +++++++++ expression/Expression.cpp | 88 +++++++++++++ expression/Expression.h | 93 ++++++++++++++ expression/Fonction.cpp | 66 ++++++++++ expression/Fonction.h | 81 ++++++++++++ expression/Makefile | 32 +++++ expression/Non.cpp | 52 ++++++++ expression/Non.h | 62 +++++++++ expression/Ou.cpp | 51 ++++++++ expression/Ou.h | 53 ++++++++ expression/TableVerite.cpp | 113 +++++++++++++++++ expression/TableVerite.h | 104 ++++++++++++++++ expression/VarExpr.cpp | 87 +++++++++++++ expression/VarExpr.h | 75 +++++++++++ expression/Variable.cpp | 63 ++++++++++ expression/Variable.h | 77 ++++++++++++ framework/Algogen.cpp | 78 ++++++++++++ framework/Algogen.h | 42 +++++++ framework/Individu.cpp | 13 ++ framework/Individu.h | 33 +++++ framework/Makefile | 14 +++ framework/Population.cpp | 233 ++++++++++++++++++++++++++++++++++ framework/Population.h | 65 ++++++++++ main.cpp | 79 ++++++++++++ 34 files changed, 2274 insertions(+) create mode 100644 Exemple create mode 100644 IExp.cpp create mode 100644 IExp.h create mode 100644 Makefile create mode 100644 PopExp.cpp create mode 100644 PopExp.h create mode 100644 doc.zip create mode 100644 expression/Constante.cpp create mode 100644 expression/Constante.h create mode 100644 expression/Et.cpp create mode 100644 expression/Et.h create mode 100644 expression/Expression.cpp create mode 100644 expression/Expression.h create mode 100644 expression/Fonction.cpp create mode 100644 expression/Fonction.h create mode 100644 expression/Makefile create mode 100644 expression/Non.cpp create mode 100644 expression/Non.h create mode 100644 expression/Ou.cpp create mode 100644 expression/Ou.h create mode 100644 expression/TableVerite.cpp create mode 100644 expression/TableVerite.h create mode 100644 expression/VarExpr.cpp create mode 100644 expression/VarExpr.h create mode 100644 expression/Variable.cpp create mode 100644 expression/Variable.h create mode 100644 framework/Algogen.cpp create mode 100644 framework/Algogen.h create mode 100644 framework/Individu.cpp create mode 100644 framework/Individu.h create mode 100644 framework/Makefile create mode 100644 framework/Population.cpp create mode 100644 framework/Population.h create mode 100644 main.cpp diff --git a/Exemple b/Exemple new file mode 100644 index 0000000000000000000000000000000000000000..8d9285d7cc17e3ad7f719e1bf93d725ee53289ec GIT binary patch literal 71692 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 +#include + +int IExp::nbindividus = 0; + +Variable **IExp::vars=NULL; + +IExp::IExp() +:but(NULL),genome(NULL) +{ + nbindividus++; + if (nbindividus == 1) + vars = NULL; +} + +IExp::IExp(const IExp &ie) +:genome(ie.genome->Copie()),but(ie.but) +{ + nbindividus++; + + if ((nbindividus == 1) || (vars == NULL)) + { + int i; + + vars = new Variable *[but->Nbvars()]; + for (i=0 ; iNbvars() ; i++) + vars[i] = new Variable(*ie.vars[i]); + } +} + +IExp::IExp(const TableVerite *tab) +:genome(NULL),but(tab) +{ + nbindividus++; + + if ((nbindividus == 1) || (vars == NULL)) + { + int i; + + vars = new Variable *[but->Nbvars()]; + for (i=0 ; iNbvars() ; i++) + vars[i] = new Variable(tab->Var(i)); + } + + //création d'un indidividu "viable" + //càd même nb de variables que le but + + Expression *e, *e1, *e2; + int i; + for (i=0 ; i< but->Nbvars() ; i++) + { + if (genome == NULL) + { + switch(random() % 4) + { + case 0: + genome = new VarExpr(vars[i]); + break; + case 1: + genome = new Non(e=new VarExpr(vars[i])); + delete e; + break; + case 2: + if (random()%2 == 0) + genome = new Ou(e1=new VarExpr(vars[i]), e2=new Constante(true)); + else + genome = new Ou(e1=new VarExpr(vars[i]), e2=new Constante(false)); + delete e1; + delete e2; + break; + case 3: + if (random()%2 == 0) + genome = new Et(e1=new VarExpr(vars[i]), e2=new Constante(true)); + else + genome = new Et(e1=new VarExpr(vars[i]), e2=new Constante(false)); + delete e1; + delete e2; + break; + } + } + else + { + switch(random() % 2) + { + case 0: + if (random()%2 == 0) + genome = new Ou(e=new VarExpr(vars[i]), genome); + else + genome = new Ou(genome, e=new VarExpr(vars[i])); + delete e; + break; + case 1: + if (random()%2 == 0) + genome = new Et(e=new VarExpr(vars[i]), genome); + else + genome = new Et(genome, e=new VarExpr(vars[i])); + delete e; + break; + } + + } + } +} + +IExp::IExp(const Expression *e, const TableVerite *tab) +:genome(e->Copie()),but(tab) +{ + nbindividus++; + + if ((nbindividus == 1) || (vars == NULL)) + { + int i; + + vars = new Variable *[but->Nbvars()]; + for (i=0 ; iNbvars() ; i++) + vars[i] = new Variable(tab->Var(i)); + } +} + +IExp::~IExp() +{ + nbindividus--; + if (nbindividus ==0) + { + int i; + if (vars != NULL) + { + for (i=0 ; iNbvars() ; i++) + if (vars[i] != NULL) + delete vars[i]; + delete []vars; + } + } + if (genome != NULL) + delete genome; +} + +void * IExp::PtCoupure()const +{ + if (genome->Fils() == NULL) + return (void *)genome; + else + return (void *)genome->Fils(); +} + +Individu *IExp::Croiser(const Individu *acroiser) const +{ + void *ptcoupa, *ptcoupb; + Expression *e; + Individu *resultat; + ptcoupa = PtCoupure(); + + ptcoupb = acroiser->PtCoupure(); + + switch(random()%2) + { + case 0: + if ((random()%2)==0) + resultat=new IExp(e=new Et((Expression *)ptcoupa,(Expression *)ptcoupb),but); + else + resultat=new IExp(e=new Et((Expression *)ptcoupb,(Expression *)ptcoupa),but); + delete e; + return resultat; + case 1: + if ((random()%2)==0) + resultat=new IExp(e=new Ou((Expression *)ptcoupa,(Expression *)ptcoupb),but); + else + resultat=new IExp(e=new Ou((Expression *)ptcoupb,(Expression *)ptcoupa),but); + delete e; + return resultat; + } +} + +Individu *IExp::Copie() const +{ + return new IExp(*this); +} + +void IExp::Muter() +{ + Expression *e; + switch(random() % 5) + { + case 0: + genome = new Non(genome); + break; + case 1: + if ((random()%2)==0) + genome = new Et(genome,e = new VarExpr(vars[random()%but->Nbvars()])); + else + genome = new Et(e = new VarExpr(vars[random()%but->Nbvars()]),genome); + delete e; + break; + case 2: + if ((random()%2)==0) + genome = new Ou(genome,e = new VarExpr(vars[random()%but->Nbvars()])); + else + genome = new Ou(e = new VarExpr(vars[random()%but->Nbvars()]),genome); + delete e; + break; + case 3: + if ((random()%2)==0) + if ((random()%2)==0) + genome = new Et(genome, e = new Constante(true)); + else + genome = new Et(e = new Constante(true),genome); + else + if ((random()%2)==0) + genome = new Et(genome,e = new Constante(false)); + else + genome = new Et(genome,e = new Constante(true)); + delete e; + break; + case 4: + if ((random()%2)==0) + if ((random()%2)==0) + genome = new Ou(genome,e = new Constante(true)); + else + genome = new Ou(e = new Constante(true),genome); + else + if ((random()%2)==0) + genome = new Ou(genome,e = new Constante(false)); + else + genome = new Ou(e = new Constante(false),genome); + delete e; + break; + } +} + +int IExp::Evaluation() const +{ + int i, score = 0; + TableVerite tab = genome->TabVerite(); + + int nbvals = (int)pow(2.,(double)but->Nbvars()); + + for (i=0 ; iIemeValeur(i) == tab.IemeValeur(i)) + score++; + + return score; +} + +void IExp::Afficher() const +{ + genome->Afficher(); +} diff --git a/IExp.h b/IExp.h new file mode 100644 index 0000000..7eeb48a --- /dev/null +++ b/IExp.h @@ -0,0 +1,56 @@ +#ifndef _IEXP_ +#define _IEXP_ + +#include "framework/Individu.h" +#include "expression/Expression.h" +#include "expression/VarExpr.h" +#include "expression/Variable.h" +#include "expression/Ou.h" +#include "expression/Et.h" +#include "expression/Non.h" +#include "expression/Constante.h" +#include "expression/TableVerite.h" + +class IExp : public Individu +{ + public : + IExp(); + IExp(const IExp &); + IExp(const TableVerite *); + IExp(const Expression *, const TableVerite *); + ~IExp(); + + //Fonctions utiles pour la population + + //retourne un point de coupure sur l'individu + void * PtCoupure()const; + + //croisement de deux individus : points de coupure etc... + Individu *Croiser(const Individu *) const; + + //copie d'un individu. + Individu *Copie() const; + + //modification d'une partie de l'individu + void Muter(); + + //évalue le score de l'individu. + int Evaluation() const; + + //affiche le genome de l'individu + void Afficher() const; + + private: + //génome de l'individu + Expression *genome; + //génome à atteindre + const TableVerite *but; + + //tableau des variables : static car c'est + //les mêmes variables pour tous les individus + static Variable **vars; + + static int nbindividus; +}; + +#endif diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..4947ed6 --- /dev/null +++ b/Makefile @@ -0,0 +1,15 @@ +CCPP = g++ +OBJS = main.o expression/TableVerite.o expression/Variable.o expression/Expression.o expression/VarExpr.o expression/Fonction.o expression/Constante.o expression/Ou.o expression/Et.o expression/Non.o PopExp.o IExp.o framework/Algogen.o framework/Population.o framework/Individu.o +CPPFLAGS = -D _NUNUX_ + +Exemple : $(OBJS) + $(CCPP) $(CPPFLAGS) -o Exemple $(OBJS) + +main.o : expression/TableVerite.o expression/Variable.o expression/Expression.o expression/Fonction.o expression/VarExpr.o expression/Constante.o expression/Ou.o expression/Et.h expression/Non.o + $(CCPP) $(CPPFLAGS) -c main.cpp + +PopExp.o : PopExp.h IExp.h expression/TableVerite.h framework/Population.h + $(CCPP) $(CPPFLAGS) -c PopExp.cpp + +IExp.o : IExp.h expression/Expression.h expression/Non.h expression/Ou.h expression/Et.h expression/Constante.h expression/VarExpr.h expression/Variable.h framework/Individu.h + $(CCPP) $(CPPFLAGS) -c IExp.cpp diff --git a/PopExp.cpp b/PopExp.cpp new file mode 100644 index 0000000..547aa79 --- /dev/null +++ b/PopExp.cpp @@ -0,0 +1,51 @@ +#include "PopExp.h" +#include +#include +using namespace std; + +PopExp::PopExp() +:but(NULL) +{ +} + +PopExp::PopExp(const PopExp &pop) +:Population(pop), but(pop.but) +{ +} + +PopExp::PopExp(const int &tp, const TableVerite *tbbut) +:Population(tp), but(tbbut) +{ +} + +PopExp::~PopExp() +{ +} + +//Création d'une population d'expressions booléennes totalement aléatoire +void PopExp::CreerPopulationAleatoire() +{ + int i; + for (i=0 ; iTaillepop() ; i++) + this->SetInd(i, new IExp(but)); +} + +//évalue si le but est atteint +bool PopExp::EvaluerCondition() const +{ + int i; + int scorebut = (int)pow(2., double(but->Nbvars())); + for (i=0 ; iTaillepop() ; i++) + if (this->Score(i) == scorebut) + { + cout << "element " << i << " : score : " << this-> Score(i) << " scorebut : " << scorebut << endl; + return true; + } + + return false; +} + +Population *PopExp::Copie() const +{ + return new PopExp(*this); +} diff --git a/PopExp.h b/PopExp.h new file mode 100644 index 0000000..aded505 --- /dev/null +++ b/PopExp.h @@ -0,0 +1,28 @@ +#ifndef _POPEXP_ +#define _POPEXP_ + +#include "IExp.h" +#include "expression/TableVerite.h" +#include "framework/Population.h" + +class PopExp : public Population +{ + public : + PopExp(); + PopExp(const PopExp &); + PopExp(const int &tp, const TableVerite*but); + ~PopExp(); + + //Création d'une population d'expressions booléennes totalement aléatoire + void CreerPopulationAleatoire(); + + //évalue si le but est atteint + bool EvaluerCondition() const; + + //copie d'une population. Pour un constructeur virtuel + Population * Copie() const; + + private : + const TableVerite *but; +}; +#endif diff --git a/doc.zip b/doc.zip new file mode 100644 index 0000000000000000000000000000000000000000..a9236175b4157dd0fb99d7387db7df7a92cf658a GIT binary patch literal 77115 zcmcG#QYNoa)|vdY|6+o`?Hz$H*8Nk(n%iH(VoHI0># zmA;X^1Ffl}mE~gccFa5*!tnOH3XHITFRfHV(Qti+;9fhGw<$WMoTI?WuMNZWm#Mk{ zZoPH%FYPxSU9wYJEwoJ@YI(Uua_5U%lOd+3-`y^E&K%$LoIxq~_e`l>-{%*LD5?m- zJ~1VFu8h2=JY1O3y4J1r{(;Jx!Mmr}$#8q|lxagGcU)0a#Bd~XxH~1np3*CdR02Z1 zo?1i!l@=tCwnBM1u9-<2s)d58xH!M0vq9rp#QceiP5O`oqR}WT(ZH;5obkZwP|kSC zVQG<*&llVISSBisbY)2==G60P5W@i5g5DoL0DiMv$f9%TbS!n@`=VnvF<_Ur`6WzY z2=)i)J)rpaz>eZDVmNIITEI6IhB{nQ!V1aRhy9K>dFbHooE7BR z?I4&}=WQmRU4(#yb!eZ<^B`g{e*ER*>B*U^Jsry#-hphOAWP^M&l+!^X-aJrktNeP zV9nV+cOcJ7Q1)qi+(rrlSM~RaJ)r$&Yv;LUuK79@ij$U5Q;0XW!RaYf!%)&I?vX^X zgXHeMiC*dM9iB_Bj1Xi{4+0yE2g?_UGearK5}A_k||b%Ez#uV4We< zUe5^_Iu(D)pKIa1FK%ms-irf_;7^CCKkuk)aGxz}9+X3FxLj2J1}O`3D3J)|MfZf} z7aE9IQPCQ$SqP&yxkULdU*SpNhewm{7ubP-7tCUqZ(^ike$vTD&#$g4>$;<^p7W3; z#Pr?l?di8B)vlrJKAYPkM3e(q)KevCRQLm?IIiw%z|rd^jX0bNJ_%&tNHO~N291?QI@$b%m@lA)kP9SaW9vowfM2l8%2MEHxF%TIoeaD(0PwjY@1%(f$y*JY^qCkUiohfxM2Mw28BNR zJ9Z(^;voi^$3b`bZQagE0?6krvIQ}b(giIRKp3l_@$e*?!@A69nV~M}oI%}Vm*g+Z zJm>tJxFnbeQO{D#Hh8(YUw1-Si;dF_>}dt7!-S!h{r4157S8ww(p-Hd_q;Ao+I;!87G}- z2T(n#4TJgQ7I{kB1qr2EGz+nd8=>QCA~X^6I0xHIioNLcH<-qWJA}xE%uNcz7`?cC zW|~r zp(MZ)L=%d#$b3byfuu6*%guk;9+SKy#r-~13U}xpyWChrWUIX%v@65yDY{Bs#d?x>RZJzTn)qWW-x6L80S?zC z%X9cx$r&qr5o))c{_Nk%ddLRgago}|dYPgs+pO1U8P8cq#b>bvz1MvCWpzBX{dDzO zN#VZKw4t^waO_s+Gt)G~;AF7z+iP^RxAq!!lR-U1n;hE1ZadHL^3o;u6yiQbgf5+v z@X~8fG;<*?zv)V%$CBM6Q2b(QXF>zwUh6M*g$q;O!d9|um9p{tjwJ~x{wn3XNw9bo z}KYo*GiMZ+8L{|q2((ntag2mpW^4gdhe|FJLqGlniTG!(Ge(Y&8) zW*p6tQv0m21O$4n%BgFaI#7*Ed#;ui78Vjsao5+Bbn=xQRzp6P+%~?@Jsiz+)}sND zAzu6jWqBR@HCO#yMrQek8pyOWSOQ8^#yE$k1i4ba> zxk6PZ)?iSMhMO`=Nb3KQG%--5N(coVLlgE%NUN@eh*Ou9EdS=&KPbK&oq0?a-L9-X=kC!Xf#{uIEHQhmpZlb1efZn3`pD-UL4R8pe|$PM7w;&Bu01 zPTgDPOqg#S_#KZyitSTRn&qR#&mW$2 zQ($UUzZ0V;$P&jzCy9^ocX|8ltaT6YLG{HLwJ;M!VTIZD`L){is|q`O>>~4U4@mgsRenqh(a?e#_nJ ze2&=eybjH~jjI_#KYVdXk`Wcq2s5tZu^SV+BghdN-Qfk~<1?07-DPN7-u4^>Zn+!b`^S#|(d( zh!_wEr~(#ukfwZDnnd0!8#V+&!{j)!$ln5u7)*&(aSFGu_2&-dOS)lBdX-&FJPK!w zB$hYK6_gYuDqls&zhG5@MCB7h6n?dRF9&L7gRY{L$eA`O9Ai*^eXMq?P<`Y8B(WMh z(W(Z#na~8^orr&S%lG~AvJGzvP(9_)Bqg)Vdl;Ja_uuCsw)B?6s5)l&K@P?c-hMCw z4zwHI&j6(WT&C%zQ}qH}$)lqbLuIMMT6&7V0znZ@@Oe8yhI6v|`ufeWbxRgRyId7v z&err>Q;!3FdWD;?iZyh(?zyHPG}t#${Jle;rr@Lm3^;M-AkL(&ZbHjs!!2{>9_tt_ zb6hR-n1`4OEXEq)Nm}ZqXlcvS{N&&jvfUxF)yo=x_ElMiv+Mlg48UQMnl$#8;4l{7M!-4dOg!H5Va?;P;#mpi zgnXhT@x#$n)YUJZ9MIyHGl=NKSab*(y7uf4Ek@Jj*svIBJrS^YkoBT+zSH(hlej7Q zkYmJj*1fyqyEP=plPPSm?p8!Rl+?-rX5RcCqE-BtI?Fs^FVDypkO?0z?vi;JMCCwpjJM3kNgcoiEQ zYfeIB!4{yPF_u{ls}?$7$BG-Gcq$+V8mkyar+05XFo-?0iYEP+m1##)*V=YQ--_LsYf1*B@sQ;`063!glGwnsnO&aSc4qg~+My0PVrNpfVJI2J0D!A3j0n3J3!PDXHsQphRk1gtkB~kKy}Yu5Ien>XQR*vD^_P~ zKZA7P&V_Ai;an8O-%I2aN@lO+ZmL-q(HjLsZoPC5No<-$D194dFg9MuQopMy^I`7u z<4n7c3}HT_*B**QC$!d_JO(_`J7U-=W6BWnIsn6n?9_=5u3ykEV)0kjSGU&TMwX6_ zSdC?HZjjTyuu%d65_BfO+4`|<-p-D*uXVJwo6Dio$}V0DT!^r(em#rQ7VKtCQlGj7 zLa~(IZn$)4PhcYNz!DYc-J2j-#`BzPxi~jVg*&ORtar13R#XnUpKOrGIP5Z8e&GFg zCNlm*$P>PaUR59f0BS#J2-;63@-H~nVKb$1uyL|CF#2aY(xkd>z0Zo^HLWti*rVT4 zN;4ks8D<1nmSEg6GH8n9_}-{Xyr!>`--wd5LcaDrsgsDlT8B+0mstrIP|U@}mC63c z{@^cXJBHL34qkuB=qg2IjW_!z7tlg&C2wY&5w2A91fF#RC~~wKKjvm8us*9H)lAbW5JpsiLV8Y<6-oH zpbsK=l~5BpC?d{e6{{mc4Y>;AA14Me4~Nsk?QnO{-T`v4auo*}{2GdY+C%P|_Y%h^ z48r^q&LNswC#lPy4|SS|mJc*K$3;bt++StKNuiYK${iRVBu*ibIQ#Tkm1JQ+ zYh<`Bq9r^E_Yt~9eOrPvEpHYD#CuF^IvNA(9cR$o7#rh|9aKop813)HkrY^b^LX=c zuy;^lLou%_6J^26QqAZIrPe1e+)Tj965Esq%|e=rqwU4skaY!af=W8JiLe9~zTSN2^P36X1;oC2vVZ#rb^6-;|l3{P2wA#D^-N?9D;H{9D* z+eb|(p>`@l6=iC4%Al@@?b#hSXf;HHa>7GRu`E>O4y7{NsP&@J@{5{x-DG_HJTQ3C z(l&QEHK|$S=37RJ^}V%;|D=D|53CWk+8})@qnCG2ByB>!tyb#;;@U19p7JV5=B?ds zEB1YVe<{hd`D_tb>bm5^q_p9IhV(3wpFeSQ=Lc!Dt3-9e#L`v(GK+@%qU~}Ga88D>V6oNjgvqC(B^+-NR|YOJu}&zLq7#jWbI38_e1Gjo#k(T8yVG?ipXzk^2FFk*G3 z+JJ+mXuNcLC1cJyN1AeGo4MZ@6wO!V^CtvaUXeT!%`rf3uz0vFzt19`Dj}}+y-Gb( z#AU=fM(wo=+jY5zCs-6{CbGGCZ)Ii9i1glO1{QU?Ra?1n7i4G4$<%xo{L!l@uqdZp z49r19jg9{+$>r4m_!#B-c6oe7nz=Qyr@L=I=Q6o+W!=W8VU-me3)j#oo<3CO<+`z7 z=qjzyDQ+9J-<_NZf@?}VjW8clV%6f@kILb3N4=cdY}JD^@94|}8n{6^Z=S(Cf-2P| zv~r1_bvv!&O!;>A_7d~Dn{Jj}N&5sDapH)Hy)B=VYBNenGXshfO-M__zr0zUuVhIELMs9GceJKcY5mFX7>A92N{~wtDlAN&_W?&MNzn$h5com-6EeE!otH;= zk?9a!7OVH=%RDQ*Oq^7|EM;tIkO(GPH>8G{W_X|G4Po9`xsxYg!|wGMSw@IL$&44C z;}T$t)Bz-eRjxMCS)l1gu;c*;vx=a1?H<8k`<{lvwwC43>QnOc_;Ca+^-M8gi5_UR ztjKTX}Lm0)Y{?ClfiL7k+p5*;$4TJH;*8AjE!N9Q}PD(*y1Gfb>unr z(x}6T<Nfq8L;d!^Y)C3}l2Pgp69#|8lcf;gcugJS#EKHkO1D1(MhW zn(@Wn+rBVrZY7bqvgsxQ@DjgnFU8C)V0VD_CDi5rG^cC?axKfEH729ic8lJQq2)T z9tr$i`%sxKh9yHi!W5}0PPwEnx9%@T=!pVcVFd_HF-+|;RLu;mkG5OMXr2^q?3c92 z+<}L@&s30~r}U^63o1zx&nHvvNt$g~{3_dZ*#5d-q}nTBZ{05T>#ZkAiD$sjD=S6>VX71NENdJ_E)gpm}ky#LVZ%v#5|2s z$OvY9c%ao6;yi7u^5yJOJu!6W##d@Nli>#)4l`~`Ok5s; zy^KDsqtb)jguU47p8(n8^t}=*iB0!P8!Gi7#7Ts;LJ5$wZ}`?3h#7VAEq;f zv`_EK?n`p<>}wZp_`6M^B0a z(SkN@*`bGV0uYn#LE1WmGA(O6z*D+Ydcz-Dm<2BPgAju=Kr_ZlFG1}jD?_4-2^GLh zb~iv$5n=*PEVo%>-IGotZUi*15z%!An|yMg&nbEe&jIu>*+}W_v0uBisbudlajIk= zDXDdUE!YI}4M%vB`Mjw>2=yF)DAS(QjW&K)V6G_2x2B$}xhs$Kh=?Dx*GsC;4bbP# zV~2_{2J+fOGBPyr)}oL~BV{`033yy0QI)}*oMuGaPGyzcnTD!OMQ&1|q;o{~^$z+* z_tLaunPWX_TG%I*Si;|D2?)XpOdRvwik76ZUGk49V~BD+rrrCiJ5Y1fWnW{P!mC5> zGx2mvWUxGvJ*D-uA^WuOJ{mCdx#kgkUl!OP9xauB?$-2JHH%Zu9?{o!MugC*SIMtVMQN z+|P|Q7+G+mT7g}SG>}97knT|bZJD-McIa<%o8s;_m{<9dkaX8mmsD(jk;fFf3a$#* zUqyO(_E5X^!>VttE?>kIPG#`(R~&)jJeIm5O zOG)W0Zr$F)?p2MOua%8On>~mHfmxd{2#W*z?Gvu#6)lbsFi>heg1m11X@C6F(6wU^ zKNPu_2#xM#|28|+Jo1PmmUeV9U#_QDclY0U6_K8ZcqqClvOV+ZP+TcwjS`{-TfYj# z2%Mn{Sn|&1%!3Y}I<9S~Uc5pp9}S^1#LDoDmJY9mcw6t~6XWG&Cqb>e3@3 zdpuog7kK+9NzKC7JTw&54^!4~RfWELhbnu)%+a&V*sUSt#(U3fE*aH(im$XpQ7#xU zE5lLa5uB05S?}}y11+F_%r}64ns3B}4ICAK0094JNdM2B*Vfu3OjcS1777dM=O(O} zsG$7MS^TGkg8X<30QFnCpFbxISxH5q@9*!Q?)P_3PL6KuPw$_tr>DoG@B83q2)g8(QW7Nkd;~W30%W~K#0$$R3btR!H4Gg z8;jtK$F#TA|9tmk7>;OGD}u{%OoheRAkF__k5fpgCuN6E3U`an0$VrRWPxT z7?3r$5+pEz7^4W)W87zySHyhVr{pG=pi<57z=B3O`dasi=0rPPbY#6IrybCgBfoxZ zwP3MsU0_{hCl{fQy$6)xht^ao#GToPY3JR?$(0$;cs5AfUDUJ4 zGhND-=c28dPworHXYzmxdN+E@kHeS-1}yGEqYpAgaZ83pI#!M)%bx#wW46HX<|LyTJvjAd3(t_0jy8i!7jsNgf!SqwXPkug< zF)9E6_RmxQ^i}_zRQ;#3s=8~v&WiALUD8_57YCALw0gTn67M@Xx&*6cp{pIDhXJO} zp|L?OPGUy(HGf>SonJ`2UUrc;wnGdDgH7tj<-L9DDw6$uvA3!FFnoiw73tmPziYFt z^T`ab*Lro`<#(PM)mqi3p;F7NA)PV@q37L?*lzaa zsSlCtDR=V~!L&QppS1n2kggY zUCbcp22>A^Z*=C7gX71@)f6eWYK>-%Ngnm1i@uzs6hkEyqU?&y4E~Z!+)K*kVV|ba z8+6m)A{#S|8e>M4(CBJ}|GSP|Wcj9VOVm>X}#W6ScmXWJ^(c9a1eHF|*#i&h~gGcS? zpG`QCwq|T4q*Ov69hYllRy>V@=Xh zTz8bmwqUN;&4uia%+}@H3%9l9 zo^p*Ffk&fm=wPYEz+t*`U(Ks>#Z-skkflWp%RKTvPhQTPH1gzyo7E?rJF)8A1#SNV z5B|Zr`*4Uf-?MWV<{Mw_c)_;yxY58nqFz*PHqXv-R6s5k8sgBBa*D6sEPoo-K1qJ6 zzx>U3EBEgd$cJUOHXhe?QJ+svh-d#ni)QglphNi+n9V%E|G7Yvh;q()|4`R9B>=!r?ZtmB5JHas z?l{gcxLX}P-@o_C$?8)%-tP8q!0UE>d}OGt-v6+0 zyY3{?d~F;P2AQ%P`+O~N6&H0wkY zf^i!w3OdgyzC(^2NvA_h>d=+R$3$;UHXgohE8{MonMn$Vpgfc)lQNxUnX_7gdnQ3o zjr)xqzXlm`@={Ilz+G21JzTq{q|J#mEqj2O?;3GZLQytmIF7^IaJV%2UGejS@#4sg zz^hV_%sP+s-c|Y!&YvOqiB39_X#xFbV(KDU_ahDYbLpmcNkOg<%{K+(^f1fh2}~6B zAub}8P!=!x)FMVcb|Wt^u6$L!t@yN3aAGcDqOz;%E_r<`=s&MHWldd4+el^S7zYH) zfCRHD9Qa|Fn7Kam?%p?hH#^iS+jXGjyLnKq-e<#1Zck^=Bv-8=!*d)>`9;j!3y}S%Av{z(F8kh zcHyO2hhJ+h0exnOX(;Hp<>Q?Msm9j3F~igw>3sGO+JdBA&{lDF9UjvzCR|a_6CeI= zov~ma6Su%-X_@t+YFT6%sfY;9n>=kaw@?_@oMT>_wv2S=^9B;fZW%GQ`Lx8Z(kIZ!Y$y? zPPD@Kf)tLP-hB+HbYoywpf=`3+W;rE!TC7BKj-oIt4wj|HA*aC15ndHzl9opQDz8a zc;iYW)i6QfANeW4M}k}8wKE=_#;e$1=fj>>M_0V4Fw`+$fmP;Q_PF<&Hl;XSPvz@& zd8+w312Esqu6r%`KeDXZOq)+Gim$6J&NX72YzBw(u0Y@+x$X8|1%O|l_GYwQM(nu2 zWI5NK3`A9nZGzX1*0iioulG!>)A;ff*9Vwqt*I;;J#Wx>EO6QyHv@gkP#D%VY1q6; zl^~E5YHNc_$P!%l5{FIz;ygnlfMB7xnrPm=xCnU-4LAuK&ph(i&X^vi7ARZQma7Br zB_nF=kI+~yVD_gCsD99@LeU_rWwe*}aKe3OxWy+P~&0)C1?jAV~_=EBx1UK3{* zMrZ|X30Y3)x4>?9Ko99rVQg>Tn|glNCcLoOHF}OMSFfNk;32u5({j)%rGm9K8}L}V zxqAh>*lcRyIrY^SKhND(1kgBCLGWrpl|lXbENM6SI4Ibwp7MdMGtZvv+J^EE?krp^ zTlnqRC>kgH`ctTL%F86{r$nZpGpwd~rrU?T)1&91u()ov>9!Rv93XIQMZV=700q6z zC3xKxzI7?GpZu_S{fPE^@X_edpTtvJ=Yw{c`@FZ=>KI$n)QKOXX6y!-LZ6`4d+65C zNkJmfI>$(RgLXV}O+(7#+tKDevb!jNLx1!?}yXxv{_eY`$#i^{r=h&>HRgKL-E)OP| zk#a2MO`Zl-5dOeQ_K%B|iKBKe2ssH}Tv(~Qifj{UoC+unN~=z86*K7kqiUZHIyyY>lGBgf~Z zR8u{wcQ%jo=Ia=k*_}n|-^?7o9191iy@O*~WKF>p74&2{?=*xz&(c|a~UrHDPF#LZ+O2#bFLjP-SK+bWPCxeVBD z)e49^Cdmr)A{sjoKRT;E5q*8~%lM^YP#yh8NpVdErxvYHJgGc_$}~*RI@Rj~Q>mg< zu_3d>JW$%fX{sV)uXDbL#_S&b+F06)k7 z{x<)EuB>eSL04Bgc1C`Lkd))~=S>pCfEoK$*!4?2opAm1FpZAQt#XOtbJ8D0e_OuL zNl0EvqC-lv_FL&KQ|VkhuU>FsxV}dZ*SBtB`0=#iecJqc|3Oy^!2h7Dtn71bIJ$8^ z^hq=r64Y?BWXLhCmha#|*#Aja*Cm!{vD*KjE12W|rYk6ILC7R1ryj+lPWQ#nrQ1sB zN#^03aEd5|0)LeGIKjh?L%#lF$q(qT0Xx3E3u7Ms*~mmf{5WvIQ+AOgd~={RYRxJW zG7PzvK#sA!HZyKJoEJL+GysUKES(`ZT@A$C(s?J;P~JK zT3iE-a4!&KXfDw|b{I=dJP*AOr86H_gzH;F5=kmI#Dp1JvY-4JJF^@t`&{{+*p0vI zVsI{$h}JV&76oq9qk4*kl{~TxB!^}I;WL%GpfL8$_|=Ge*jjOj4)jGp^}8mJX2Q|@ z!?z`+nnbeC$bsxi(-@1We>sF-x+B;X5*0b|Go$mtZP!j$pr0xI2>rsX4P2KjS6&!x z>c&yV_(w9gsbnFi@%qY6!>voC?mIouTJ&#VV#>|#7Y-r!P)3WGwKTgo&Pj7@-=5rL zqEL}D+>AYhiQx!THq{tMm684iAMwh&RW^05-CDmHH4_u&sw3$N{?F;jaSr|;rbOGK2v?d zM$V1=jEFh9s!les1xSEBBh(?*GX4ZQK(i?EzP8*bt!2AL0gyMNW*Kyv^V)fe^H-xr z72Lt9VjrLJcW!juZ&wYJZcC?%auKtvoQ|uAU|%fKaIrP)ar2?a?Nv%1GWO4U^1 z!Fv11{|Qvlrl2!_euT0Xq5pF+aJ98Ja&R!SvHmZx!dbUpZ@<;jsS8OvBE~!ySdCW_ z*^`XkcQ}1vvpy@FKXqh8fRwOwgNER6#=EO>qyEm1fF8^^5v|8LCU>(X^zYfK?O4(B z#rVFtTf80Qos!vEj@Xvj{g{*~`HLGcd*%Gy?Xz*&-RWAUjpOKU+bfFDu>lLb=hQ)F z61<2t-FB_E&rTA}@JMY^NH@AL&RFkjWm3dt}QPNoDtnoE@E-f*6X7?b#gdh+jpLU z3CrP(gWXg5n?c`uf7Vr+;jUFSF4 zdxSNs3w@%?#9jFOlQfL$&7QpFU{XFFM-Yu*Cuw68!XvO|Y(#iSQZz2OV!H>N^x$c& zF^Goa-&g}R)|5F~P;gO;7+5txVIce?kR{QuHhkzze6{tl=4FXr^LTKvcw zumVUc0$PmZ!{fIu==oVp3ncUIS=z<+#fU_%SZqO>M7B?o=dEjNfDG(Vj|DDp<^|`w znmHa~)Bx;dmM4xJKpqx2VPdej=G=X5cSskvEBn(9+NCMCaRsiw(_8lG^;j3FQER6` zSB9BDW|MSLgGb(i;!LAYd@@TW4h5L7T9LAtSg0YK!IoRG^iMLf!{12ngp zW`6ew0rxoivc;T1)(&*;!|uVC1BzzHU;*Tyiny*+v+s`!T;x6Z-Rqu&!rvvHPRx2D zA^OgSjwO$7vNA?fkS}AE^QO>v9G(XZKWjb%=<7P2c>LoWKAILAaMzX{3k}$9=oaVf zg|6I*wc0J{N7FV}eCb7y5-U5xka|7*?b~}_x`u)j99?j*5)8JI00Y|vXC_7Q~U88(hRaOHDa zXr*p&rXdfjrtgqW-&W3cN+QPQj^_#4R)PdkAT%y-Xlf=Q-&|f#IfQ+!d=V8K+@L_XVPN^h_p~^c#$+Yoztx_HG2E z$25Zz92s>25fdXV`61piKvTV2quW-qol4@tkn2gMw1rJ#4<74Tf@pV+$<}NU8X6vB z$qjNnxM2L0;g0b+?xh%&1TEE>AXE{J<5?(KGTki#)K2J$K%j^rzn zA-Dz{jx>Z2X~x9uL>){euK7?F>q9XN)5KvCBbo;r^o(R@=qK4d;@8M*I%%1OeM!*W3yp4n4Z zWs`XocTG5IlveqKep9PX(TX;ifhqal7Um8}{RzySyknD!VfE{4Ws&980(=CLYfGsQ zTiWAK6OQvOUp%;vpX|?-S0AI4UR0Z^r8L(tqCNC55{6AmUDwusQwYo6Vf}?hY2&T( z>Y@C4xRR1m+^sRgtrlCpMB`%;;llE+HtG2Wdvt$`-H;R0(QQ0J!}wA%h4EeVJkjm` zhkVJb0v16}m-boGzG{0Mm}Zo6PQXS-3=5c!_s}6xj%H-dhCZ$GS4YE>d?jlSo#b%Jb@$o#XuN{E-)xjkGaXnUYYvvyg>9 zzU>?%MMPIoghLmEfTC#M?W8 z3e^%u<4aZt5{IwI_T*g_znm*zR*8lvv_m;tbvbSDm+IrWL%Yb(lhzxJMLm&|2A7m` z;mi*pKWhK>ZpT8LWMnHE7qg=~^ppC+%%ii+J$GGl_fr*fIjpvo^I8t`4#pPb4Uw9S zDRsQ?>`8F=fHB|jnXYrTK{e&!uVp_m|J7{x>M8{sSw(@9v>g3g)Ss3j*$Wy-Z97hp zseKm=bJMme(z;by`1b~J0p~_f2`;mhVrjn#=k?-19JgxUi%Upzgit}B+)&7ko=q4T z)WGv@4;VIEZLd0w`8{#x7 zh+RW6$Xp9xJx6PMQ%dhAInSj8SF5M4Xy0RMHboA|c9SS-EQ6$q(uxp=h2N*6xfn15 zB2+h?#njis;L@Yt%hKn58wj-rCetWUA1oX#j4qYcoOAs-#Hh5?R7#-?=p}_YK-vpc zC{82-Abea!)r>uGucN^p2bJ+*Ui>{?O&2MqQ{z zn=L=@lv!-DM-0&bHEkP*6y(na=zZ&UV0V|H?=h*-_~T3WAmFL1OK|r;jY7 zJ*>BR`vwA-KVvL1+e*bhp70n=r0v_e0vy1a7c7F$%jg>Yg!(@4Q(zteE`DZ%LHZ5) zJpq_{G^_h7u&`CL!kd?|E`@9`tPLk|5YUb6#ik=|FUq+EOi=w2LE3zT%h@X zsRZf#@dflSLbt`sqQ7I0!RD2`vegd1L@>r#;Re7Y)qS((LP#mj40r=k!iD>7{d0v) zBt7{If`&7t>u8J;;~2+A7_fYiP91chBR#T(F@}3F`ZIb57haqWYKR*9O@n76jco3OHZzcBE=uSi!^z$0~HhBqNP&iv{k z(&dCPDGDMJ<%Gw`3x+T@y=s)78M1d0lNrZEF^vi%8Rh?d|0TMc>GPlij-%*t`RaU{ zzl4!;|Ck90V5(R^-9+#&8XQNK9Xo2W@f0RqG?9&_BEn06uVySYA{s{6`Adm0B?PmG7QX1ECb?0&%jVmEgUKgn)cK|g*_0n zq&OrD(DlQ}#z|4c)|x zFlGtk7+aFuP+26Sv{9lRWkI9@=C<8Z%jU*0*M836+`ld|wE`G(&T9xuR?oTaz)}7_ zq0UTwoU4oxQyZR6h(p^~WXzv5p<~+xAfnysqs9EhSMZ6xp1I`)`EW{z!^ftJF|dT= zTX9%hiMZ`!H<0{fpT5c*{jOlsx2$p%i)_LCqa#*t&9ro6fCGMr@n;xTa7b3-Z$yER z-H_U`L>=Zit#JLR`%JtXJ|4{?qk5#0oc_b#7zH1=7)X=}4X4RhRfT2NB`45=Z?8am z9G8V5ucPR+q+9cUy<8eECECGo$K)%XrYA!XrG!VpPdxlz^qxCF9xs-kNCSlZ`C<9z zsehX4{~c}rq5EvASlP_eBYbV?*kM3g&CfAY1=W$n0%u`gWS?({u`PHh9yL1Tn%BF@B4HTN)9L&MFL3;8}2R>DY5&8D+7 zmVYgh(D-)YjnKa5QfOp`&rc|SHqiV2r>ruso3Gjq zsjiYsOH$5B!2rWF5s}H6VD=z1*{>*U{WTLf=nZzUZ~~3F{m|{kuq@df5_Q>j#+QF) z^Azm4_kM(gWUTZw_zz_p10p9HWxv7_QYpArN$?;Mk5Fl&Y*}gRz|1kjhFnasxpmz&0XBUThhUNuj941G#~D9};6TSll*_ zywG?vTd5121zA})y%|`~qZo)HVshPq1pzmktpo261+lJ}EJ7TO-+x3QK2vTNz(<;L1UE zB942em`=21ZpM~hY8BPhwF#4)8)JX;G_O*k!_B!5e~e>+QF~JtwjnM$#0=6Qb4=2f zy}CHmkms^X(#bS5XP(dLi{p-Ni@Wjz8f140xfAWDvs8AlI;(y>(*2^b8uQWGeb8y4 za%vcCn8@SXq*6F1A5^^bLz~~YN}yM;rPyy~D1N>>PxC)^1O@B zG{ZQ(V_Jg=DNu1jzf?bLZY#3!)aHJhff z76c(u4y8_bAc;%l_=EeH>p;kuA;LcsfP?#PIuoO%zXr$ifK6d&j?%%^*yZyHisaJ$ zKP>93lZuiYNC1E+p8umfN!Z5P!13RD3bvNQy6D~JUw!2T(D=S&5`&!{<;7pN9jp3~ zNklGAPEJW!5&MB{Yb`Y&}T7L@VQpJ>DGJJ=}$Paen@O zcsYKBe0$wnR&e~SXl9#6(v@tP+{|dk~aIOQeGj3hT-&&Qa(gb1y~Y>TRV^gR0)3(SSf)c1lFZD ztiE3>$;L_;P&&B)?}Y*(sl<(`ahW z7P6ZX+B)d;(m0K=D_z7;7di?-3IXY90}2B~E9Jc`@~__pa(vq+{}*lV6eVe! zb!(?>RI*Z)wyjFrwrx8rZQHhO+qP}nf4<#czh8Hcz0dZ4aE~~MlNb>ro_o!;=DOwz z{w_W#^D+t2Rf-+VuSgP{5!Bo$i(OYlCu~fKx+2!zMh_(JAM+7@;PVSS<>0wU>=mG}}L)a=7V+=_)7MoNqG7Y(|~Ph#EK#@;3( z{~5wd!Uo-UyCH&BjiTMZm3Q5peB?tlOok2R7VvRw!{t%a7aS|th%OyNWyGMaRy5_# zS%w{bw-x<%C)3OZ&R`r9a42uEqjN#Y*f`Uno4h3l=T}4uzAVO5(KGQg&KEe$|EfIY zT2&;Y0fEP#cV?g`o;C+kkt?4!%fZS4R;>X^7#g>%QS%-H1ES7!m%qDVcy~wM@TO9S z&ga~>I*MVuI2cPoqH_Ui_iDu%gXd0oV1fmJXj6zn3U2O7&RrCG9+i|t+w$y*u!@{=gY(dLFcCpwvbdlbkw7Jy!qMu_z{ zbz~1i9_?>qTq$X^mA0pab4?f>@BQ={(O!LrNxn>}IaGZWnIXq(m1ELmfF!W$SYvoU zJXE5<=s43>^c>I+lDs%`*--!jsn`p!Eq`ro#F;@g-`5f$d-$k&D`00E=}Uf`Pm^dUkQc-KJ7Jw__7|-i+EU%bl5X^42l~ zWF@vfQYhqQgJgQQM43cXPdj-h=7810;;6<@Lhi&ApcZ_u{g|b-21r}FzGi)MvRRum z%DGf>0Rfjgf^iPsLn5Fve;T0k2Z0vSQD`Z=vgyRhpA^rv3P1L9i*q zkQRg^iwsi^w(-6aO#QnHZ|}@cZJf(7K0dSR)gmiX)TqSKh%#zh^&JtAUg5q%aHXW0 zuT0D&!o@(Cl0RsA#*1oib#c5dvFPU(y75hZs1c%yGMIwPr*$dPtu~VR_6T`uH71Vl zQ`~g|J)9BApaq|5li^O2;lxuEQ|oMs$J37((x#V9ClK7AQ5* zAxa^kns+9v7qt*HJ)hQ9v%tv~*OBSz$c37*$z!!Aui7&<2<_45J6h%uA6Oq1Ec_W) zn;gZ7Q(+L7yb?E4R7|p`a}^Yf8~QOdITcLF(o*7*YUuosA*6hF!g0%#r4`#XH2-jl zIQ7n}U;Vm>?3n4oP=7&4KxrN+TY!_e3K@119;_Ceu2KUb05t6=D@2hBXCTV*qk&nG z-Uon9i}cGsT&iSwu!WRC7JlR%8E*x2w=JUL`!f}-!~U$5iNavUG(3!e!<6I#Ov9yZ7mi=s+r0e_qVjXAwBPjVtTyNbL%GdltiS58B0J`Wl>Id+A3@)gGcYv3;T-m z0Dj+Fne$Iq(3Kqc1^ihlZszDV-LS?GGp2-5R9#G^=?&W&uBUx`#m2EV!>EgIhqrOZ zrgt}2-RfvA+;3dBIST*QW+u^N)|eg76ON;%9vW-Uo>#p{4oOmIR?kUR{RijoJY-hwD zM;cx(p9ue$#Ao}p?tRk2ix?n0)o$)6t6H0*l2nn&;$>4v5S=h4KC8SjpG|T#Qn%g(Ut*|`;2uC+0~szClF{$ zi;WEA5jRBOYW?s(eM|JPKX>LUMar z(mtCUVWJvVeJDS46RdOy^waQ9;EXUeVi_(x_^eQ!`TQ@<7$E*oJ^YSypvHDsE5}dx z{~VA3KLsFcep}B^zR%xCjlave?@q-T%(eZ|LF}%cj?VVOy$$5|s{?Q?hf1=Kfsxd^ z5grlZHuCQ4*Oxcm-PafJ-4TfdKyCMPw-4|_&?gTdJ%+gNyDtWI=7xyAj!x;5gDp%+ z^4+79#U=$X;37CrV&)YY%d+u@-f3H@w(zGU{BsriUgA*(BUj7y5n8(1dS-=`l~xSx zh3R~kwKNXVQ2K_Yr^&RL#~91DsMR#(CSD7v0fq3OH5d zq&bWN1M9#p^WC4oY60>&y)1vSbS@zg-v+BHDPm5ow&&%n+q?iBQE8T===}FPwbG%= ziHILD?^t%ydy)RKnyD_gh0~v5Z3E4TTNX23)~{*|oF`*$iajTDvE%nn59vm3?eqCV zmK{57=dV$R2{%;{`^!H{7EipWcDW#z=>p%N7=tF`s)A7@7L1TP_HZEB5<> z@2X9PN7nCMlXa~`HYw3-5;P$S75!usy6Lak!>{{MPg9aftT?X~TD62i4MQfSJtfhG zYGF7T>Thj3m!-u+zCLJ4`PNF>m6GVkk3eHTq!Pp_b=Q){nRv62e+iPFAcLpY;U zTwdp!OTm^0$goK-D-tIY^HCWWRy;4WHC1$D6j#HY-ls}UMCY=vyTFQcZJvi>JexyB z9b64Z9$%AfUNnt3Y_+$-LLP5RSZPZ`TAUB>!TlaD35_48Xgq2dJgLbl@=y;04IZ*5 zlSA!gU)8K%TJ*+G`WYPE4kOzqr$@DuWI2%k1!zhSzNc^dZY9)y?_FU2tCjGtKf`}E z5>)=zK=S9?KqCG>29mhOe;7z$z6~Vt|7IX@{zUurZ6I+9Z4Ibv_S5alAKtrL$C5_l zY;jq_{bX+TXX(qT)VUseQs%k$VXb^KZ@Owl>kE7BxoZUH7Y)!$MfJ5?>hKWHRf;}I z7ycc{7~zY}6d-Xn+w+9X3@h4&fEnNvSce2j_&`dCY29GXl1YN`Z6Fy|*lG7zd0V`x zkoY!`9Df@~qH}$*?^JT3)?a^9Y)iburu55-%IKdE3!2dRoV6Uee zqa{~Z!7@?LreJ&*APNi!bcqhon;CtJ2$T-kJS^M?W#m!}>V*2Sn5zcM3$-q4=6R?>pkz%- z=`0B=?vqelRY}S3rR;>pi><{6gHo6RipJ=HbR{8&&>G4~lYaG~cTX;cX;5`VPyNimfvii%WZK!d>*~f^+cwOh zql5dT9X6eEF%ud`)2_75y#q?uZ&TV<@4V@Tf}$uzl4nqWzU6+2V(mWmK8 zA5yw;_SgvDzMtomnbNW3n`aOoB*>&@t(r;^Bza@H%*?Q(7}i>5RG@#y{ACd~ZV#+4 z_OkCCLpz=jCE5PdrE|H~uc@SKFODl!XUpV+s$PAhJoE~9w>oA{0-;M!qk`k(w{Z^a z^XA4}6#U)pHH*xmRBic$lVgl9?`8|yi?WTfGY{-~SJVA5HbmBhhJIOhtHd%@h4*8_ z{dUPlytMV+Sz!0&$YD*ayA?BxsYgUx(q@zsd7TZn&mxbI$~n64x(wr1VKHln!w8!EP`T zraO9{Qu5n51)Y)$!)3BjtzevUW@Co{# z_g~WtqABoqJ45`t{r(q|?H}Dk(eL)*Kdm7e+SY5VNZwCH$%?j?YW;}^{i3JKK$o$b zR%j>8#|L(-*l^I_w7|;~ZL(3(%bYAnT;(mjpnQX|#0++)RP;*RTVWKobc{*sVGOzR zPn*x1^V6-QtL>sPcr=@rsV>cS9^gEy)Gu~chKai}`;Xn~8Gj0?UVq3R0sSl!&RytE z6=xycO>HMfCuR zyrx9@Go+ED-uA3OQ_cu|ya>9GFU09#Jhcje9f2%@FeK!FoC6rlf^rU>PAo|$b^xP8eh!Ml zCxd-6;)inz}8s6%}$;Ym>}F zL}xo6=KxUr%Ljq!frgu!56p0&dWr8{EX;HT*MS6~$TN#=86$DR6kUjgRfLoiE0Ak4 zF!N807lN#Xx%>P?wcTeSE+iu8BPUi0OghRZsHqvW>|n=J>*|*Typ!{vNd%-v@6|GO zrzEi8Xj(*0M-WN2RLaEe{&phI0wGGJtJXro>;ydTObwkf%IaUP%0_TBq6k@Dz@RE= zg@2S30in}0MfbW2kFlVf<;Z1GHu1PSeHPWy3LE^uO<>RPtC7L-u6ElPLc znI&(IN4m;Sawbo>fN;5MyYqruu8k~f)|&AUjAb#4(hqaZ(^Lfkp*h~&^OZSTB2c4B z`MDsKP#3)n0;m=T=kKl2qE=s*l&%pgFI@VOMw5E)JH`=&<=ryzd#3@FsX6-v$@B61 z5upo8_@Al{gYbjx`1##y}7R%hS=QVoM*WJ>$gMHC7lHYOuo;B%+&K;U&@n5t@}v zw+$G~ziulV7l9q-uw|GOT9FVlC}5K+Qs?~nlqD>MiPtAER%EB4Tf;5+2TGOMYf&#M zA>f8_xIPDuKZE1MVgE|QxfU&>s#&-4+U=VV@;Q(^s)|mfPi~HX#}KCwp$QyqmQh_AtOz-#4Q`hHU4zr%o5&$Y*U*apA{@AMAh7Tt9_(>z=W0D3+@w!sI{3v| zub8MUXiiU+2l9VqGNYMx-_0h#Uie5wEKq?5(frW_axl!VN z1Dr;*>f^S3DD;GKGcopz0`EK;qd_~MJ=*lFEN4U!+p=rw(LJN~hPcY?)c75x!pb4{ zxZj5!>Z<)~ZPFc$^r7O_UEZ0vI`izoyLru^PGcEoR(_i z7Cv$bMVu`yiF&=`{v89y=V{41w`Lmv z!rof*iqJDt1Wza9j2U4ZJX$nfgo%wNp|7=7}1nqs&5y1 z>KD`9j7is0iB_T7^Win{a&!sAY;6kg$%x4tN2SZ|xeTSXrYt`ZRr4 zb%G?N^t}y+nv^Y-^@ibKK>SU;(4{y_j*IFVy#@wt#xj}vKhu|LwQNeyS3;pAJZeVvGrTrm|Sd0F}qLam+Kt}7;s5dC0vbi^W$%3d1)zZ zXGuX3Pp_R;JA8oCQA7uXSpbggPE9t!tZ0z_r;B$lL`GllY~eQy?{a1pr6SL1Hk03F zE1bM6K~@*B!dkd9mY zT6+6ii|By%nht7l<8qR36k}$-!bDFUk3M#$FM_0+@?pM$YI!11 zk)q|9pnoqtV1A$PdF#KGOaF&f0nqFZUhM8(7{aHUsze|;BtUNb%I}qQaQd$=9$Ig& zUJyL!aCmH18PDS{WW2Zsu=BdM3p!`g<(2BpMh3CA`b8twUvhP0>b0?#(lq(Vc>^6?Mr zpysc-^nHir3y!?8o43Z^v#6F7jCg_x*s%+S-q~dp3ysM^Y*Cf+Bs;6I#`P#SZvmu; z(p{c9t5(JASKEYEfawdE%t|lnvvj1?{}P#q3Kmcn-y#zk;h*TRzbnrF5SR-|-;-*Q zZ?g80JWQB>B-D^CUv_H|ax>S*S&5hJfoJN+gbQce*K^NI+suB|4PAR`J6pg_5Ra6!5U(%oyFD#bU*3o;!*%_dUr6Ds z%~(P{0Zi0ZY(4T(BZ6uAFGEv}?1JxUHP~~>t}!GAnW^lmPAzE+?_xcY-c4_y*N$$Y zyyZ0Uda;hT_cK9oyX06!_kBE8Soim|dO#sBq|YcD8JhabPh*b~UqX}ekhCp@4umn( zAH5C1#7;oGyES6%;~k`l(L$yuluG05H$wMVfyOCOyh5L>K1{Av7Zz6#o{c3N0hV`vp2${wms zu6u4BgKb`IMC1jv^91Hp6?;h~xe9?|Z3!6|&O2?o`h#3?o0EJ*3|T}J6nWNHxLSeC zOVk0m_xsPe{?_eIER4P3z?jg!zQx8aMg2)-@*8(xD50n_8#@(Eyq`5fs`EySEKB7Y zU^ur0hfXIzNb2klBj5`7vp4Z{tD84aUzGHD9#h zjw=(5jI~ZW9i;Lw^3QMK=IXLHQP7oFCWHKC-sx{G-cdwDZ~gD%bmjw+SSP6%QiOZP z>5A3Dbw<~jE_c59L&gdU^WN$c=F5)zn{G?Efgi34Ghm8o$ep*Gxq`0E9PuAm@yOaf z+_@AY5bl-O7jS3WU}fela%LKZy*S)H8xGkOAXp=-j}{r#X+J8dyC_DFF%KGY8y%6p zpl%&~&*SbT4V6hYE0Zd6+D2DmN=L=E{O&HryhKBhCLBo zy9mB;5x*Kjuv@OKemyy!b8Gr%#@^peV)rX=xozcb2(EN66<>OL7E~R88;)lw%ajR| z6oO=p0Z)5muJIp5lNBSFQlNtNzKQjkKZOM%2!i+Z^kl<-Xjuaklrn}lyrNO{%{*&X zP;|Ih9AwH5f$O?>d2MQvDHj~=6b7I7wra`Ny0Y85=Va67$dEb$BhW>p zf}{sHPI`;pTCF;-ItIckVIe1Bv&)O)LLLHxIM+ja189TRxt>^wDoXP1a)I8`?&Jvy z%ldNoyhKTFJo~h~ns=O{o;nX&%AnSO>Lrq=JRo%1X!5pwU&NCWJ%=X{AkTPiV%<-W$|-;qAXZ!iG{)lVBPuTjDtaat}p)jnU88&}_XDY|~1;fv#UEre=UFjP-`W3Z5^ z!`x^y7$t@uO3yT1gxL=aT#jh*)M%K2vLJs!aG?^25_EP=aFOt3yLYkxJ?L%19C^EA zsnt->ihD!Xj*f|PgT!!Z4!mEvKEF(|89ic9$&22GK0801mzj9^d_M(V7=W!w7%_5c z##IrEQHnq-pzob^C)~1!NedHLH6cu}jR|2eaFd8qV!Gq+p?pT=g0+`ENlwYJ3#^8N zxImhii!#49>3t}12Pk=sRFwf18t`>+1e4S3XG6GE6w^mJGnIgj$!jc=8x#zw5hbet#YItj{ z`aQfXVz~3@nFq8ayI@^se206s3lb=_%rx%Y9iHLICZiTX%TfTg$~H)@$Tai7z7*Z* zDlfdi;wybMqFE!TELYdGzjp!k=MU_GTug1AXiW2SYoP>B2O5D%6{28eu<*e)>~Er+-EN#n}jC*0Xq$c_R;Pc+cN*!Rqf$C-4k zQqJ%UZMa2M(CLfG?oWYx=()@dZwaW2XLQZE?{sfr4Gp3eM4AA+C^abqLn z_g_w)7$3HoG~cBNaG<=U0qtwxM%qp7B4)GFo~INj~|(uet}exDk*g`+3q zQ#Jz&k&R3g1us^X?(F^A#dMHs)y)Jgr`<<`s%dpk29xjxlN0G_c3jfS&t1B|rgc|B zr;nNV_U3-|4i;@_olQW3zUSSWf2rcAT6CmHldz$YbDOV<|IE&pK^*PeKF4O_%ZBoB z`T@wWG9lRFj09`A+S2bog7vZarzQkp8iAYya~I9xR0Nf$UA(q=dYTN6P^0%Yx{UpI zJzYMvnN>ytbLNN8d`kH4B!6Y>6Y99=CrE1s=te2z>1@H=AVO#ICx9Od3K*epk9>D8qxDDtbOn^z4oneTX(ZNR#_{B3jWz4C=TjUArGcdc1guQkxN?sKDsD#5xn*D|QE(gRFZD&L_3k?C{Blf6? z-&rD^bAV@iPLmUadz+Fy>3ZW=drv}JGp)xQCIVS((Owqa417GgR>pKs+^`sd{f4~| zp4O#xC83sZo!ZZ+~-*a5B*SUoITg)o@zwk%A}q+JCppGk6bVVqFt($YN4 z3Dw_W#el{kp+|`Z4!>0KdCHVjwft^d=sh8}4lMT& z;7IHMSHY+gL4`$ur4Zk&l)p+*4=OZUDgD4Yw3D(~Evf)zN(6%m`2r6rN2$;vLL!|u z7&;^?|1{ylp}V_9{-AQIz_s0tj2${et^5L|A#r?aB_5uBg_X7EqK5&sveMDI-3`nm zc|ad0nnA8tN{MED95ZfXMdrz|e+K?^@w{%|``oqQ^OSe6yD7HplEeCPzJ;m;01fgj zF$J%hS3*BthkhmQUbz-?wM<)EIjc}ktkay*=~CI#+}hOXsb_MzJe+-kuia29P>6D< z{h~>HW--5NYi&WYEn;*~P!_>`O+L}K9qycQZ+UZOzU!TB(MYR0=U%0bYZbkUmQG)N zP}YsILbv|h?j(rpyLAR|mvvk?P+i+x49OH*>5&^iX>T(z-4Dn5$qP^G()!v`ZZBp6 z^k3S@NY1_-_gfpOe{0LX2XO!TGXGN_DO>)PJoN44r9+485j9Pv3NU1;aahv4$ps~! z;qXVmT{l?$NAS?fhS$#1thY}_e%m=tu%H@YDY@bxMpTxuk;PQLbEKB^(UsBAwZ-Qx zh>`b~se zJj}O@`to^@OoDfg5iqw>qv$(q1G>AqT2N=v^d}PaT|BNxL_Nf!a>LU3zx;uIDyUFV zwlZFF!^jamc+0417?sl=ouQuUUSb1>k?Th;LTQGGzzox@SD~T2&o}$E(hjVOJLf`V zTHOy?W&ijQ$*vy_^AtFuA52gc>ppDq5%xy|@`(OX_7rGJ6+Rm^&oOp=Ra=XS8aps65#aN^p2Z_vA4N*=5{%@80MCy;Ev{Gg%lh&Aw zg8R$2tcU`b2q0vv%JU*Yg7HsRug@n;+Qe-_c*FqX$uMhS}pQ_I~&Z4fn1J>QhbL_oOLLC?a~qH6}& zeDzS#HEYI?FvTy`9%mMx_H7}*=nrZ$*K>tC(f-DHbx$rVgcQGcl+EvG9h3YfV)Ur< zC%@_Kpn>X+Kc`XMS^{`YMVvl-#q6+e-I$w4-AH%s>ztE$;C6gjkL5ImBMa_~5rbQz zUWUmLDZc`gYa}=vL$-*K4!p&xP7RR|PWA$uH{7^6wrT0Ywezl-K?4k3tjvoAp$}>*~=XKl`+Ss(?NAsVO<|6DO8Sq=u zWRd<`*GB4J>(6Sc)>teEUQ1QUv?fU4iAofzkrd+4^-ihzHb{MrawvkbGU94uPE|H7 z+^^AFsY@SdKV#d}ekM|^*&(BQP4}2nPr~rv_zAyVJwY_Fk_2j8uNt^7Ut}=dkD7=;>pM!!vaaAumm^fB9JC9zZ7Yt!;NSm zQQ(vv-UyCDJ~uKFhGtO+!>>O8lQUEX5{RdAaCBUyRTh@`L$y3nhxEXkCiWom?0g$) za9JBm=pY2&SwLd5U?9aOX$Cp1UQ~s6Z*4^A9T9ISw>1!DhFkZGIkshnpg6>qK@)M9 z(ymK`p;dXsh|bmZwj0^0oY+@m6 z@;H{=Z>6k?zOCz=KTOJ@|!Vn}rkNEgwJs{FLHN#<&Z$p2o{Kk1{`D_3#~ zVF0+`gWpo+U_ija$nRd))bXNcZeQey(UWvkvaiZ4TwAFrR$pQ2)F^SCQ?142n1Gs! z7$tP9ZZ8E+-t!`046;FOi2{T2GoYPb2Fn8{kjzk`f3G&aV4j62Lwx!es&Au4+fFXv z_9XJA+OLJzU3M)k7b7rz$n_qU5Sx(WzHnxqMBX* zL#SVXSUHiH6C=yWWs+;%Gxg<6_eWog>lw4_OJd!#zwauK7f_Af@7C0*Y6aU` zwvsp4p`GT$kB~77+Rkk8ctk<9>-mqc>iCmfvaHeA-#l`kb6Yo<%G^^SoYWKOiau>} z(Tu3Y8+u&2CF8Y6t(@?0N^^Bh?&zt#=YxIDwsLnG7cH7)WBr?$G~ngI;6}SzH=w9M znKpjFEUDM+SY=9Cn_pVO0@8(eDC&zx+VBkq^WjIaU8|jdj#*b(xej&5Aob27B`yTd zNB_q5Dfvc9Ezl<%Gg3DHMvov zx&(mUx`>H{p9A3@EUzLLEhv1@23T$s0q#fm>sPGnByZC}#~pbCQ&tmICVq@Fytk(G zfC*rNl?6w(eEBt`nPw$vF~C%jGn6u+BJ+8m9Z`-O624U(X^e_maD1GPp7m; zo2~8K_r4g4R|Qu|;Mj+S5MDf}atDm>dF|}4hrs%pBtC&EY*XmsOo9FiKfHSGcLd>9 z1R2F-@Na|TjghQ#87Un=Zp^p4FW)nB8fHW5xNv>J0yo#5+g`w6%+5Id&pV)24vumY z?|)i6otAap4wgPLyL8Uf2HzkJ3Udyk`ty4y?t!DMTHWqbZKf_QoD_?yBMtU~0MBSZPwQB4*&qz>JyNL@FR_RR)WYTIaVPv%c~A3)u6 z54xHt;r)0P>Y6{}m|R&=Epy{f8m?jZNU!*=@k?8ipTrIiq*eJx&xDX52l=E zHZ+=G0heas-8JI?#+Dp`hf2Ted3`R;gEr1P?rHOP=)dmD|3y1du6J+xe%JDUoxc%` zf8CY;$F0r(2jE@w|7AP*(tfj@Ty|V9VA-v+(QZTDaC<)D0YQcIjry0NK!%n+qN5w! zO>*1b?wU2flSeK&`EwjR3j_#4(Qsc29CX?RRmg8eM7T3{5~HG#!84CQGe_a)^6h%d zcb5eLC4O0&r^YRe;6OvS)6x*lCn;}N zSXZ_eWMWEyuQ?tuk1xe3G%|b;2r!K%lP{#Mm|sFG_REM}%Kl&as{a;r9qA)=gx4-2=%Qxrg z8>#!xY1H>`^`A=N->iB*1dwL`Vm-xGV9_uA8|x|mFV+)L*Z)}c8k<=C>Y5?2gGn}T zT7sN8Pkqsna9jPfUzM-DuKSqoykk3QBf-8K)lYdvlXXZ(F~`55~0v)At` z-3UuTOGaE!@{H>bJrME*NE*L-kb?EGq??W+oV1X|f>Jfep)xr| zof(Kfi24=)C{Kqqk|>FskVaVYNjSHAIoZwRAn6`9q!W{kSe6Zhq==fNzQ!lx+*l9N zs{m;X=)u4OYM3uQgiiONdeFmO-B-a$dA5njxG`GAhTH( z7~942wRj17UTf=w_#*VA4-^UZ}XSI zVWR{kQrt?vSUKuw?#)$@gXL=PRbYysvz820ikp1Oapv<>-{cv$SaHv2Z{ z*^7IqN7am`{hE4Hd{l~84@f9C_|QdTF1JW!Rnhu}ItZ z!sDcrO*t~Rt{J;>tyIBWMBJ5#$y$HNoLqQkzKhrJpc8lpm~a?Gf#{nf>t7)Xugw9j zhmVbu!yI4#y8JS{w^)J}KiNS3j8#dOLaA6XT4^^gW)(D4`u}VZ@sRiJVts&eI z(IHjzCAZ+a2qYqg_3VNqW53re`pE`XI;p;$P^lt&QnQzHx`LX~SNzEGpHc_A80((; zTk14@=a&5a_?G^kxy@e$UFN@(&N6{K$)!pz+?cIl2t!2%@d<0qkmKx$13N~rzd(IE zkncZ~j`C+1HGo_^=|}=qffSclw4{c+uJg^#vA4a0oy+Ii3ABsj=OMb()`!dcD}u;I zt=9#%+TzShjOnr^c<~ZsLXiV3{Q!dfj`(n zIR-i9S=vM4fAqzG304y7=evQ2@(6V8y5ovFyS6?$H{}?KlDO-nRE5x*pe3#6o97!xq5RNS`GCrgS;J zPJSh&ZP2B_CcXir#JaR4F1BeuOYf)1JfSz4b+Fdrr@Rmo{(yIghekJMY~n3|55Ed;Vt z2tpi1K>Xxiio662jJ)))U15n zx_$9m6$X}gg;-;b{jygBY(G2m`Lj?DO?~@3cnT}W`fRnt^iGdsNAXN-LS(H{c=Y4~ zc1t36vLncN*)-R@^pknh;XE(#7|PXYX~U^)J7rzD;lO>PxFFFA@$#0LsVxI_kJ=5< zMKM4h36v??c}qV1nG^C(mR%aTrrP*6E~9AU_i~c$CGtgnj>zR8r=&%g zkkbKFBaZ6GhSxLIs5L!M363rEeSGS7s26NT$^j$dR zOs;i2IIeVPHgHfksxt<|Gw*pyq1ZE9`#&xj`oq=mRG>NvTjV~r*Ji*{xFgy+O9s%P ze$mREu_CuD5*uCSzR6kDokeM)F!9Gt*$(8Z!D!GQT{O1ow!!8NYtLC}j-#>?cR1G> zib0jOO{`RWzp=p;RcU&`6@W(PyIn*kKs3L!&7 zA5n3shZ4}V2UL*f5)%goAzFecb4AljfJoe(Uz!#lv5sts=<{c_7GFz=v~h_;)P4XJ z9Qc;Hg`xw{lqqd179(4D)d1|2EM5c1s0}PT9r&vRzDb7BCZt5ZA+-l);;?ImGBC7O zra-%2?(z%-ICxoS9{2)qENC*^mHA*{ERdAH(P-%4{Vq8f(;0ekjiNe}Hub`Ay^Wa+ zohIu?HYUIUCyLXR5}v2eeOaBF4b$wRQN#Sjs%jGcE*91faSRF0y4(FW6PF8JljF@> zXpTH&;!l{8XcXgAB<0V+pnjRZ98VFxyy#gurFWIC3>|1Y1Xghasm5%RCyO< zBGHW5SFf+p5$w&^ZDu!3Tf)l>Sn}W4=-Qz4AQPyC!`8W=kh1P<<24S7wg{XTr{~Pn zJa!P7;e{sUQHzVA@kdYw^_n3sjoq$kB4GVzgdv z+cVE6h~!(+*pj&ViWG^0m^@B2bq zDLq$c8pH9g-up==+MWs)r+?&;$BtCB%_ew-Md&p$=nI!f6-Zm)0uet+u0*{~Z`p%C zBnA-MKtayG)kZ`@VtR)do*BTaPTut;7F{y>5uFXL!ZtO}BU3(0*F@U-pF=d;g0ckV z)H%mBSYUj#V7oy+4HfizBSV*I$l-m4R5gOTcj^#6 zVg~dx7JG|ViECmWKy>uD8Ugig|>0r`=|2Q>53yamNIqY}{vE0@==0 zU{8D3KP$f=i?7yR%(?HAv}X~#2DQteE0n6%P8?UKt(ZBCr0vObc~Tr!c1}XTv=7b* zAADv+PfbWL;rLtd&H&HJ6O@J=zo)QYseAe23!i z{j7vZy53iGx9CfC5@u8;6hC!jyVB~-zy8sg|6f`3s_MAy`Ynn6I)4*yzwg!mzf=+Y z|Ei*Y5N};q>MmeMt*SLmq&L4H^4`g_qXP_68|DVKl}U*QrKU2Iaaw;qF;D zHD4bqIqnozRtslb(UIf6MO~1XLijL++OfM+q8lGsv2`fdW=+NSN5vh35`@R!EHXVbst}_ z4Hgr74FO*C69_?av;*a$oA_B*Rz?b%P|r7ER9uogPM)MJ>l9_?8(2F9t!A&tuOO#s zy^7VA`ZZ6Sb7uN~7ek4(bg_Shi&XzR_g32RzqHUlQ$@0hnoGY^MH&oO9{x@hvHb5; zk+{E7MTA8gk=F$0dsH>hna6**zF$87{N~=S2zIf&>)SwD2X$%mY&Tt1d7b*q*=%fa za4mJ9YsLSpN~J<4CuU;djFV`-Jm4VVyhV-+otBOs$jQppjYf}Sx$cXf0xC)p^_yi3 zyu<$a9V@bp-cDDU;etaXVaf=&q`EhecG(0wb;`I70aMk?3_)imLidww{(Bh|`^9(6 z8()?cE}gY4MOudWSH({mQXt{97TydzOmG;gZ}Khpw8B5gw`>iWOqkbueAM$mc7@x2 z<%-m8+-vdY{pKg|4G;aK4F;KGx8b(I*o%+{B*m08k3fc72EkX>5aKij@=OZ2=8JUj zg3C(Fv{8@{9BG%kNu&v7rjevMRGGtF?9U&EVL(?-UHlBIWt?J+D@@F!BYCnsLAMVR zU6`Xyh%p?I6SsbPy&P=_A%Jq#^@ieL&R};#x8=3ur9~KkFpqt9@h1J~0)`wwlEOch zrl9>W1=Q0jmeH^_QE9=B4cImMU3m?QrMe3EEYxFyWJnk10KGShp>jMvq-!`!N#?Ol=tH=h$Kc>Fp_&NR zcptpI%b{XKs@dYQKcj41N5I1qd%s+~UpzTIyS05pJPQp6oEo-W$JA?5JJB7$3BXL! zeg{SR(csXl;$=|HZ*=zP3gaTUzyMKd=&I~TdZt{E7o;;tZG1UpV&2N^VH-WBL+!tj zZ?WP3BHxDiCNU5fYAX-R!wr(_!Ex>`*{ZXp6PFtnOyM%?@{bjUb_m}8P_u@aEfi4=xO{fWG zRcFL!1llGR+PS*wON=L#W#*HVS$}-2j-glSJd!rUXbx-K8@c-~LNhncEgZcD*N zY-ja38)lApQ-x4qTK6cFQJjez7uz3K0vd zz%7;2l%<7<;s*RrO$36G4zmBPiApH|0KQG9|7?@USlj%)<@6ooxW@eBTNkk!8tvul zhvZrml~CFmnHO2IUoOTqubenIu_Hi+nDmJA$~6AvXB#@`TK0n`ip`Zjc)h9XW9(LE}m9`cp;I$>n!<)y3-W3M94V_~mJ{+ggNHblA6}1A*pC$QDN_ z3E{kf_GS0JNf=A_M1n|^!xK_Mh#;EsaI)r0RWvD@Dv~<%fdWV&Gu z4jwK^ujRbp@%FlR-I8Y{ic5bzGJV`7_xlsa8KmqW1u6-|ZacBG>0h^x77UUhok82t zsx@tZu-^jgds`AWW-fIXEO+up;4-lU^N+mduPaK}s+tGUE_m$(Q8KY_JDWT|OnZ;X zwkOyJH{7=+Du!`#Hl5Ipgxx;ya4q})qwSrdBYU`R z@7Pwyw(X8>+qP}nHaoU$+qRu_oDNU^kDvED@5Q9USw5HwEsOpwkOQI=&dh_3{F1w;e>+~sW2jZ0tRjInqu-A)W&-Gp`u-(s+hU)IE`n{I8hZh_G$pSGN5rt9D2gZhTKvp7Eol(=gdE29_8R84dv|S# z`K9=ZTLgctc4j=@&n1Vwa21}XRC#~T%R$0u9I)Mwr0MRPo)NvlskO9NDRsQvxVeX; zX_Hd?4oB^J_(Er=!w>4=IjUm8?QQ{d1H1v7PjT%}$d3Rb3?wmzB!3aY5_`Rxal@nn z4E}Nfm#B5E2b)82n#%Bsh`}St0B#88hwU2yGWWU;hZT8i^*m(9l2#{|qDI_2{3`>d z0AZ5fUoYLj^p>LCf0(R`v~el#E@_GdKPAj~9_9iFwwy~y6@f}{bt1_GVrVTPSeOSu zl1YfKom$iFVK_(sw~bNWvNkWLZPdo4hYT+?C zGJcoxz@WIcp9@6QN@4w%dW~hs!qD=i2EU8K6D~Sul3*+o4ul z-Sh6S>*es47Mo>wXxNJ$B4TN_*N7kbPmn=ym@sAKHbdsd58XYibn~DFc&rN{Em?BesvPaJpIp_jFil$8;Sr+ zVxgsuWimn&fKme0@P*=j%3$EgI~!3$A&0+A!za+`mGAp_B?9l92ORB)gk9a zGwW5Fpdz*~IKfJm7Dt4cjx%DKOm3R^joX4Coxg&EoJh_42LU*#K-dm_LJ79@%2%pd4_{GEw+#y7zC%*cF+k=UIUh?gog8u0sTHM2dI$A)K;BXw&y89L3o{RviE zNS5BEvf15QbiCu~MwMB;Sj>ELv!+|L-d{f-KKq>7rWts9_o?jSZp?0l)D6S5Q>oI0 z7e)|FhpQTl>uM-e+udSf?z2l;`&R>wH(&C$Em z+Exf@^W2!y8V;ae@&F~fXDVB{KgCfwYlA z#lGUDfrBoN@g(HTQjpNwx^&#c1wLwHwz5sOIM0`0I><#iQvk;=9TkElW<8SN9lMXY zn58Lve}$CV*%?CftFV$MC64 zh4AT0lti;HurWUZSnqg4pyf)TyczV=-9T2{I9_BVX}zttSnU{RXtx03tofd3yA z!T(*+iGIII?r(s}HfiU--tzyNP6}}K4@H;AkMynRgvW+iaNf=Hp+Bf4 z*@teIwGt&xyLAa>u!??yG!pPAMx59K6Ta;3Iw=5P6F^c3Ma85s(s<|yearoSR) z>}2Pe=Wy}kbadonwdeN;nq{&ySN&ub>P;XzD}hU|6d#e;pAbSIunZer#)qOhB+4g| z1O5jSWZ@qT@9TAKE{i?t10sXxy`yZO^?@<#uf3Zpo{_0;Hu>8d; zL9WC|SW@eP9jJwGbgFBe`z4W+@G{|Z^G+us5urN|B27=`sJDthareSK5;}4(Toc0! zBhmvayZdqa4im!b>*~S@unZNT>luj8j*GKG_q2h7j!|8SpO2c#Z+Ax|=~9qY%oy%) zsE#BZ&weN*49%Oo&u9W%1%cWm(g1|<%bCg~Xa(gZT-1CzS~wzjsVXq=ldWoYgP0#F zkx3ttKoD9nD+YF*yj1s6NTIX`pUn-iK}vUqv~<0!2?l07O+7=rk%N!{zs0U02XD6+ zjAgNI+NAoid@11O#KPuS&JK8_i2-6`%jE@5gNBXRIc}~M9IotedH6C>4nwB_jBm-z zla(6d4pKlrNJ6-eL@=F&1%NA5>D&3y^;{UCKi z^Rpf$S!nCF0`RpqglX^GwN?b&MEA5{g(4jiHWe_}8a!&POf0f|dW`e^!*)L|*6l8A zJxTx?|3mx=#GI6OQ}0qw9sl4vFoh-gjh?lNa(TcE<>IK?7HXPJ_&=Kv8C)$wgCjZt z0EigqvI;a!;cFL>F<-UBgk;s=m0uaYS04&t62!V!uLJsH6x^P*;mS}G;bqhG{yTKR z`3V!eS&81FA3XRCkcV$@ZT!sD4N04}4=qR>=K7e78&ZY*n{w_W35k-l6XiFEyQ)=6 zAQ>^vNSRI^J^T^Fpi5HJw>CWv%i6e4Y7XV~P+p)oL4uP$wT z$Z{A%TvTRuMF@{c=YlOyElk-`?}@TLyxclmceRC3DYutjL*jcneED6Ii7ulh*WoZP zByKiSj#9S7S_H;S&3+h|bF%qzvQ6cC!iS;)S~Gd2qQ3`S&yS8%p5Qt#(QBw>wI9BQ z7rZeULxEHO2}4?VYieqFyHg8(%R$>p1?mc3Anoz{nQCtJxaUe{I_Qlnf4Xl>j5IEt zr#wnW&(dk*!s&*0p%)_lQ83wCdsv~Y^}cL*SBWK;ec7S z%nLuQQFTAz=y*`OCXx!&5F{~<0jF8@!`HDhds@cBytNpzD}VUZ`FJ>70A35q zW*s`Ax$()-lKwCc6TqN*o)TP;+)|W#dW(hk_T%|9TrJV*(~ zk~j83QnCY?%sft$YG#T_$DF~jsLCmLY#Y6@SG3yW(R<;fmwM*@Z^KYjw|pS8wWe?2 zNhVfujK~&~N_x7Oun%~XmMI}6dPKI|F#UAu;(@=gAm}sI39EXA01*OR@|T#mxB{RS z98GB)#8M!sSYQ5Rgj-8e=!0 z#br$zrmE5?N+=cKxc`B-dU#S+A_g;iD+XpBl}sQi;ywa(8NLt-n-2_RN*0ts*}OHK zVCp*J`(!ju3lvw+Vz&7^A8cSxB9y}S_95(C!!K+XRiPE45l=~jzCfiySO1~(T@-4X zRar^3Uqip2!ZnL7=3ej56h}O>$0OjN-O8n2?OetET9C{)J;&0ybvc4q3R9?=Lh z9)u{LJz9OJ->lwl$H%=eX+>-`?RFht6&T0fE3a*xq=1J5+z{lE$S|+lMMq8DqbeeA zRw;9|?Rxc)qJ-o`+!#tmF%$9YrIVmj_sfqXsIjU|%HBq9xQ4^K zl*MaeIO3Z1Dz4Z)gh05}c7H~Bmclet7LDR+*ff(v=Tv4yMb>DQ^B3b4p){tBgJ?t0 zHt;taWtkg0O!C!D)T7fi`5i|YbM|^CD_7B5)&v98hy`Gj8d(66u?f+;qGqAZf&9FN zmQai1R*#ubAv-1b-AfWByvVWB>+NZ#@T%T3pYrSW>dzT_!O|M!#)UcycU~Q7>=FULh($mU;fxGI4xVBkxVI^_D|V$hvDNtP|JvH!3l-{e&@a-9x`Er#+WNs zwFfe!UD@_c>Y@$}5x;A>REn|V)5nAs7e+oDt^{HR-nI^oIoFU2bR68Q-KuerceU`X z$R3}1EY7_shBUZ}{0Qlr08TsnFwnVkXa9D?j@lZ>)TcdJ3b!yu6n5D9daWq#YZDu6BP@2pMW#cafW2}N#ppj1;e*`M}*8{>i zpYMTio&pY^>mVdS%b`U?^*Z3_1#N2ywDq8l-;gH}l~|F?muit=V2xN%rSBw6)=03D zjOzX_{Vh=fN#VB5{;CL-pakM1F(nZ*`N_^Wl#$=LO+#wc|FO-%UqjD$;i@UDPM5}6whE29& zdDYpl1V4*-LnP&@?JucSzRqNr?BO=cefy3wDob`$UUESW+=tfPS5U#l&D!d9XGR;b9bm1U2Zo_#f9-`rH;f_u;zLeBKoiJ}BfJxms`k?XEh9%hG(B#lhgqF z40r-mi3t17racutR?*KL6nt7+lXxrQ?+V~79gjQ|a-g$X>Xx~Pikhutf$4)alPd?M z!LlhyBB4QZa%K{`6+qXAH&m2+LrvuME<$bFjY$-c7F%NTE2L(5TKgfFGDk$L5V-pV z-r*}v2(Oqh+ES*tH8xG!o$CrysaMs+wX3N?rQ=Rwz*Ekwhms|W94@Fog!$9u!CG+G zidpmxQ$*5tJ#aq6Jhv!bibDo#m$>3^JE2p`k=rk_rAZBrt+?9kjAwK)vjWnQU9T*Gx z9NHe6LphtKiL*4)?ZjdGW1ie+Lpvy2L0C#8Bd%< z2kIQrFe7jMh}#LPIn{q(crg^WKse4@5l+ry%% z5wXLYUTa9Viy*?tIdBZ1+SvXgXh(YEZdr}RSQGF|F(L%%H4tCZOGuaP&K)+|b)RM( zpIzaJG4$JD5-aM1mV~Jdk{dk)a7`@TZFI?}+9e*TBnT;Q%oU3tAx)lhciPRFG~yg7 z7u|g6CjO5nFg7a_YWabKuitP0am<>~8^hG-V=RcwE{n z(}b>pB|>wcg~jXp;X1_D@_=d#J)TL*fbN4KuOD(+*K^jh9P(>FgAK&<8P7@4`Mr(G&Io+R3kjg zlblF_4qFs(NLb3~FL%-)(AM>5$MylBVKLuJ&UnYj=PE1P)>djCcG6}OV2OrAg)d!v z0QbuYSqZ6wsQKS*8B46Tm-cU4#_jt={0k@Y?{o2A*38jAMvMPu%@j~rOhg>8NdINc zG-Avzsr`icn>Ew?FKfp3gHA#s;)-)B1Mo@D@S7uxa`VF7$#z~qc5?GJumkqvx68{l z6j;x@o%0&_U)D^=2R=Jq&I)|Yw>5+LPiy8DSrYF5W6h-ObDDVnWzB^AWz9U2n*_C> zxb-zKp9~WY^`9?~iQhO=J#dQ04IWCU35?G6qm&Q@vO=AMgU6$s(~ZK$7^a+Utbr(V zHKq9TV=zfFg|mthgB`NkJl#WQnaK&_oLL=<$ZF8IF{wH-g$7`;*Cg|=@>qn{AKNJ~qy#Pik6kxPNKlao9r{6;oWA3ju*GdDrYeQsq6-7bBb9V&^8|^hquqczB%!%Rp97qVuD*T3LD&mHG=0VB3 zPu&aR(WLChIKE!$nroOgD#e|{Ais2x!}d4PD>?iLWeUix`T=UhI&{1m&k$zvXV)`4 ztC1eIr_1;$g5<}FRthxw3_RPY(Sn&So7r5eR#rI4@z3X)+KB|oWMwT%Qhby?CLWq; zp#f{xssgRjjv$I^VU=|{*Yz~SC{ihHhSeOp6HX%Yc_oJa9Mp zU8dF1T>Hfw*gt#q_e7O08Q*aweMD068tU7BweOx`(NN25SvyIFU-pQDz6X)u$r-%D zm+5^WVZ+D%r12-4nR!In#N|}I#M8&<{j1^<4J<@ zaoVZhyR z0gq3U>CJFj4~!559?xpqeOrI$V+ zhq9owDL1*C$v5Xvj;=Y}W%_U1CEJTKU*|gn)K2I>_6U^p4Xlh+j2+CKjQ^1ZI`!?l zAa!3*a7tN!QX-LX$Y5(4EJbB+rI$(VkGnNAl~9BQkzB^%1N+tg4CTJqba_PE01%5$ z5)*AU8j<(<4bNXN_u}_Cy9L1EX7}*<`*3H(cDE!^cc=fB*VpUqo`BtY@d zIkASrrUqb;h;~N7{51SKXA6_Mz}}~p~Cex zO(7xW_4oUTcoN0{nU! zys;~51@>^WI)L|uw-cyG5Pf5pDndh@l;SU0n7e8L3&&k%&)XKnE~6hJ!wo*qJB5Y4 z&q-Q;@wS~$v8VLPcr4%i6oU3)79prcwAvU|W;BqDZ6U&pMwkGN;~y%e3xI#^t}Wz| zYsZZ;K$K&+43Hh5C*bdWVed$Qyq!vJCIC^`dvLj;W1#Ej$iq7v;FoGn#?6IH0DxReg9pWuMUlD+jzFG?DXI#AH+2=MQ?Nf=B4`f_?%O3eQ~Axj za0tm5s?^&WAWAF&_hRmrP6;c(uDmQNcAtkw7DX$#*ine^h;ws~B(fr~ zA2#i;cJ1Rku+>t?9&uo&$al%UJ;PjpXMZIwT!mOyq9;)eJPqG18}D|Jx7LPeCU+rC zaNmEs9bHVU*^{#g14YLg4fHDh+e#7Pl5<ms`3XFKbEWjpCTljVdSNKLL$kx&_T>b*F(8Pp( zC#iU`)==Z`ZX5H5@v!Ea{?Ie#d7$iRzDzCiV40uZO)3f#9f}6H)s^UCFoCF%LQ0oQ zCri((*npuEapuB1U@phL1IB7`1VCn>17!087Pv*crf`L(&*`3hYPhsCW2v=ds{=-% z2H>o3Dsa$^NlMl3KpWZH1d$U^hLF=K0$?MouNHC3M7LH*c8huy&U6tZsVYNn3uGiz z=?DWCDgi2ZkxKdUi$56BzhpRc==X>HI0GXqKYhsPLi%iW02?;>dSn1S+MVJnI@Xgl z$^gpZBHtPMDmf{m{{wg5s%k<1OdmN7hQp7efEWhMAEh8*2NC1tw57H39WvQMWLOF4 zbMVk$jmiREtETPQW@tkJ`muFEBk^OEQVlG!F1rXHKh1H4P)Yi#iG>Qza}~aEz+x}0 zr$8>+yFKEQz}c*Ivc?=Jh3AehbYuKzQ4ZO3;&+|UaJrY7ps}lf%os#DBm77RM|ok9 zRt0%1xv=Q$finFRjMaydPtTG+)|BR~H7=*s@<;_sR<1s$$_|;cx)sMP*vWY$eRg|v zp!qg{Kj*$c+WrXp8%{WtndcEUypg24E6Zz9kI%Fb8Ulbr_TT1}4d_*ts;dc)CnlKd zR(*iBID>L{%z7+6F^%cuqzX#x7M2}F3yh+^-akNn+?LC#Z<|liQGX<%su>jeo1&4t@1Tgx=MkBe})nh zJ=gUi66Q?=>TRb>)YIK4_pDbKz*5nu9p!7P(Q3S9*hK}3Oe7hGlT)n(lu|Q=n!py+ zBqWK8JJ~ebiqll66c`wB6PLHyiJ3)!kdnhkJv?xq)W9uPGuR+_u-JJ=Au4ud$WO^f z#vLIFHm9w}{h>hDPnFK(@P52LyP#TFF}{BDU=C5+UQok{Mit+dyyh=g8$F!#V0p1D zr@2j{*KY~BJC!Z)?dOwwNCOc?UV4{Hmu!*t|5Hn+n1}kAdX;NdoS&RlxHE{I+rxGK z;+430YpmJBcBA5cVo-+$so7{+bZ=uOiqwdCXPK@6sA`*Mt=vgw2T=nbINa> z+A>cmfic`+g_S8`imAWmhlcAw0b4s?U$cAE~mT6F7Y+0r6j!MJn zo!hh44p8IcI;q=>0)L zg=O<6p@Dhe;_7<)vU%fjoQ!!=S~Cwh!eoPG$w8%*1nYzaQrqOX}ONSWlq^n8nC0UfE5$7vd7-;MeX84{QweimC?!U zvi;e#OpSs%XHy4l>?P|h#PrUUG+o+(MeXX&n{@5>eZxiYI6R{Kt;G<@Yg!-q(y19ItzLFg80lZz>r;ksru1~Hm zc{^9vs|#Esgu{Mpd7&dWQ;=Qz7eKEISZ~#yE-uSsydj8@b(){F!j`=S3}Smfb|%DL zRsoU9-NO^RKo5kdAq37*6swKbnpZCRgDkE>JGesP8fJ`Ov^G$w>whi}qNx* z{P^2^0tx^S00h9K&I~P2f3P^hw+Qq4&Vj-CXK(yJ3bOxFVN3spIx-;{Ae(16e?uKp z@&xIb^N@_gVr3kxVPdk^uABc617l>l7Kx4|R#h%i=jij!ebRAAyUqE^j_r%n71DC> zOh*6uetzf%K@2fK_o0uD8y%Yg?zx2<#gZ7JSxt7bZgpGZaV$m+u+%uoORMtd=)-;O~&k(qhWojyV;C z-ppXFQ&1(T0eN6BdDoV|g=CVZ7e=jb(T{>KkrJ3{9lMEZ06peiEFo|jCA2?R2ru*M<;wnpE&FDQ(-hk6Ca<6P#qvtHVbRTkp3- z=JjQBex}-#)4DAuQ(-kftD0PVKV~UCJ_b8}H0P_c8-_k9T77M51pdy+JY!ZAI1A#= zczBPUU2RwMBu^Bz%AHL`zA<0S8B4UzWg2epo%w=0Pbno4TGe{sCE6l;K$qlp2IRFg zTlwWL2_37hj&m0sS0{QJ`jEwf*o~1BySbsDeEp%Hye*-k)srFih}cTMrDID&m!iO` zCBCQ`U%#i3gZK(rC3(el|7xB{97jo#QFhO=a^JbMVA9sHw+;4vNoTv?ESs>!3Km~f z6ST_?fSC;Y$^H15`PQ~U@-Q+r@S;oWy3#IHe!-n`Qk}&pmwHxhf$BvG&v$RG51$RC z$VgzOnbC%KSS_IMAf)%|ucBx|b2V*Q5K z#k9fG!^wshqhZ~;PmCf}PfqM_-ScP20aH+S8p!liai3!VBN@bt;(+uct@h6-XQY6* z;96&Uco}H5c{H^+uehc(x3hOYXfhFL!SR^**UVH*07W`X>3z;`wp;@^8@?dF7AFA? zSZ&V6sgq%Py*=OF6DP*{&eMgdq!1ca2xxX#k(4+#KvbThd7$u9rb-I{nI_o2gVBz@ zW!EXv_qY%WSprh*X;}Kx#`dad2IfrmLE(Oi5xl`!rh1`UD{bxOxwzf16Mt@+);#`c zez32B@EsKSe(enVgo8)a-V?JwvqDWC^oo=LHl&7j15x%F8j;`2mPDDrQ$-fmt_t3T(vgKDz{fG1#>O`TXp9LrV_MC^2-kOt_7H@uHD}+qI+sk#42d!rNvlW?32dM{5F0l;Uc`_UkB|5= z{nbT}a|K8TuToaJYafCPlYzhLdsez;AL0~Zg90^%tU4cbVRux7oFK+*^9~VAL~f-~ zy;{`+YYjRfCj9X;2!sj!(mSTCxLvYRLu+BSPcfHp*pEr+e0!QF1XBr2*9ye6W~ zSG>lyrPRUfdD4-0nkj?&CP`9{0Qo*ba~5{S8q8xspdNb;9;P#zwD1N;$z3UOQz zido-F#6xUu(u1rVt{URc(%-zK)T#i&w}!?T5crTULV6lt@<2VE9j$6hgJZ`Twa&uv zs42u$VG*x#fqe=9iU6q%YKUn|5&RO)@w26i>BZd}D$Z)p)B?x)I?x_!1k;MzDAq*M z%CE!jXHk_x)iHR3^o5b1^fR^~a%Hb*)&mCujB50L>!N)D&hl(l7{`DjDs3jlIY!Cz%~I@5QP4N|%1OAr$D8$IAmx#N){s6N*T z=@V+Fp(()1BK(@O9{5FTbg5cKTPP%(GVVGe;>UWDe?boWz)F9FjTc6FGNZvBkW7Fm z;grsbRr~uC@ytv-mHRkWhOCREOMYl${cbOKT8_2D8iTI5zN~tMuRZtZ+$gf=vL|f9 zpPaI&doB_A&>1-|p&QR77EJZXSIG17w&&8Z2bj`aDpD3 z_xjVePuBc`*0fU7q*5#{r6E7~nvz1)uvXickA5OfL0O#`1))<-;wq0-u(qprjXcBY zdG2t#KzxdJ#i#2da9OkA)^&m{j6r$D^C_4qSz#SE^*|>Z*!$Cj`}Ce?%8Rc-cl)Z! zWpl1~MMbYc=`~(dwY;j3Q*^Y&Ik%FiG+Ine|5@Bau(_r{He^rNaoAWOz}HlCD0W-f z#hEtG-`IoJ*Z_5B{=g?=h`)UEBxNh^yt#_Ah~lQPkyRs1XXVe%`SBCmet1O`?|Fj# zLPlM)#3I-G%K^f9r(Ks=_BXXWgzBKn5rYRLGg2_M1A!-Jhixqxxv&Eu1 zAD<|-=;cBZqpJK)p&jz+w!JHZo^gV=E4U*y4XyRH6;@k@LZny;uLm+C@01J?89WoQ zP6zBqV-5=I92@k}4MbNXRin3#L%p_+gH~p0Dbo8`G2upTh=97l8|S`w@ckqB!-c@x zTbR9A331-IrfUBitGb%Yn#`6`s4BR{7kZ%p?0F0GU{XeZUerAfk`3!DB>`Drqqi5w zHf{IA#lEBq(fODNy0be>`Q~-u5b}nzTDyFUwx3(<2c)n2?9tpmq>L=rR(tM779nronR}GL zJl$jcIE7_y0B@E%l!Jt{cznBhQ#UhtUs2}|*e_1+Qzx*G?Yxyhn~p7}6XsOz*Jz2@ z9PQ8Y8S=8eRLl^Yz#9 zul1yVRw)1X)|bS$Ciwd_vQ)!o&-au6=V|2of406P|C&Y)85?#^zzW*V>ylIbZhVn+ zD)CJ?IgR({jmFW9;bBi!j7%>0w2X`IT zxh_~_VtV!{+`lnfWSlINDtdO7Www|3$}bv%an%o;qGU7z6)@Hd;~WA#wi5&F8g8nV zfE|GgtS*Dav)jzqibZ!S!lf$bDI9j!marxg zDQdS_2WRIG>ZTR#Ao|~%UpPWhTYs?$WWOi8G5)E${&6b)hvxeGBI!*@D44}J;5F0NssvwDeckKDxMifO+b z9$wkKzn!A!#QJgt&b{SM`(OawdwmJ|p1zSCB%16Bw}2Z?B_paNMM&=OdJpW&q-_Wc z>&I|M4gk@FZmy3HM5d>STB%V+j(Z#k2gA${N2Co=U3BywFrTdFMF&xI4Gi>2(%Ge{ zsDG%G1I!dsP{@l&`?CK^z(THr&S&g2pz&Wn zZMRb6-v3r!(8&=Ik}%%51B%IM=jh!iInaw*C4UNn-DpypXfhTr&{JPm;#(Dpj?fy= z%$0i@smtf>jM@6rAt-l#MuppDJ(xf+C37Zg6~gfLbo(lm{V+3cQkgQB4>Z@m*4w%SIFzKhOrS*8$YDnX z3Q`edl$KOK54)1`xE|P_P3UITuN}~>eHjU_pkAhSdER6)poaXpfo(z)uWY7afKIL*#?X^d7-Wl%o>*IBuvWh&fh?CITqq-q`!mw%T5@XTE4CiFO}6kt@5yHsPMt zf68_D3(1Qg&@d;9Xe+PvD8p8HrHe)T+UDeSjdDOQd+%H&+c(tcd1Z_>bn{ViyO?Zq zAhG+|4e`bo?>FZky6Oj>qTg`}#XGMwtv=2t>c>dI?e_&DLJ?)0Ks3c|KS`I1cNK=M zGlez0*%W_Mc?SZ5^v&h@F5V3IeCxULEOYd;JKIJKI8ob+oJkfP>k6Ulqxc(L9UYgN zj&23nj}2HgGL#{dC>hmg{i0%+)~c>c~{_qJ>tPy(!4fZF<|E=d@&DGh*zn3`!{u58|{S`I;t6lXEJb|tw zCL4n9i6VKb`KJ@mh<~^>3|r#5`Fu>Gn?g%AkMW?m-#XV>0rKj#Ade;PK+CB_`@xNW zT^~yyH#>j(g2i*m*3$L)qMOs*-phMU!^-K^pAJQ*r#IP>9&DnL({^8#SncP-_d%Xj zs^q!0L2msB$QZ#D?~mr4ykyq&xH9O%p${gLHMSg#4 z793%^=3>GmW_aEdhEY?U4WLG1~9$v7&rpOk2GnSgks zfDv^S0JG+vL>b6BIa&!zIGQ$k8B=Ehspx z!G2H8nlVi!YQ+e|f@`QVQjYw&?+`TWKw=)d=Y?AbZkVShf>PW^F@6QGJoz({=uPtL z$FR)X3o_tOBZA6%^;Jn`L`Hg?A_egoEwe!ne$f0+L$$(Ma9eK3r8zM;OcO>UWG~KB zG~~HNKCGkLTqnI&OEHae45kphCmV(WdFb9u0aOY=E1-2T-c*-#tnpJHNihNA zhA1G+5C+okT=;bf1MIYvW^_Iof1ZvfJdVo%;T5_&6VN2>0nOW;HF3F3%V281u{=6c z{2xD%Mj%2f2Qm|!+o2w<1;bZcB27d4Ce9L5tGZC%dfMaJ z*PA(vKf4cuiuJQk-m4K;3kZ>k6FRabyjJN>f9?(RyIQRPP9UFzOff=>9VgwF*Nz&2 zHrk*e5U61M=m;up4@bD-_)KMKO+@At(o^}}#R6@!VoS5Xg8kJMrqEZ#xhe9l%Fm~7 zI)&WbY_iu>UoHHQy3Q`J`-is3x6S12Eg-&0tmo#XW}TC^uwsJObvidV`e=TZ#4-cY zdNE*B(Q4Ii*A=bnLt6NzH&3*0`>54WdnvvehS)A>%9BYBw{ipg2n5^G|7rGC7{)vr zsh)$k*`NJc1;RIsK#=imk;M(irhMaW+z^0bZh`>!M$pXbcavOU^}?7 zDwjvxX&lQ`oM{$?pDsWM6Mkp$D1|vr96`C=cC|SXRy}AD;tVRHKU;oWv&OVXVfxXE zm8wfm$T>4cmG)~_%BWaoD1B5K2S2O0_V)rE{;yQ<&jntwVsJ!ztK91*l3e?YqYE<= z!J|?JXXx@`!T5~U)Ey7`w%m~t}%NGy0Va%=#IX{nbb57_PIk% z6;hP|;0AS?mSAy;DaXRWdxaNaczNo)tpg`BB$7t4 zu>5LIF6|y7?U~#^87~H=>=(?~ng{B?FPBXe*V3ncrcFut?>-$D0Hfosy_lGC2EQw; zTo%@>yPzz{7c^t4Aq-0|@$@2rpJy)SuTtPpvaX1N7D34JtH%s_!hk8?#ZPO>Z7E_g6TaBO(St$OY10kqmo^ zbFWyRrt;YJeiRW%AMwCJamTmS4~yiThnz-RrD+XE~XY7#jJ?|YjECH zOgis@RTY7rivF2x8ib(e+x5A)Nk25#12={>sG!-B}LZA2phEstP39w3@(wm@4>z6Fj_J2L72fcluD!6{+sH9vTv+=pdjr z8o}wQ)HJIt4g4NUp+y|&Jix~;*N;u~xx5sLii_hcjIiiyN1mZ7q+Qx%vs6B?pYIre zU5NnFRx#-EIIA*r1YM_l2mkMXezy2A=jU%s``CA`-M_-||M}1V-_`kF@G$ysc-XVz zCbzjk81qzneF-sABQkJw6%y#6BwHIR*vPb%tM<-s_p_E>nfae{eQ|u_N-X0X-S;=N zCx^LqhIZR{-Wa$8W2YY!FudJ7-W%Zie?CuacAmit`JMG!w*2G&k#+eTJ0rFU#gur@ zJ{ebRpH`S3hoR`^#$cF=cqXYYhi==Gkj>zC<>~-RnWTa%yjJPnrv2%mt<{$Z2 z)MYNCHG;xooFR`&sbEk0EEEUw4!$CLxEN&(nj*@TkR=e5yHKOL-6BQ-f!<~Rqle9R z95B^loz#!z_21lX4JeXLK>?KLN`3fdH;sWme{*w@)Qy&2LIwvZRuMV$2}P*>0wa%Z zo(LHf<2f97A&sLvE(FRw>eXZC(7r4u>LuWl39( zw>eK8?TpKSx-Vr%Hko*qjDmEO`d+OuA+*=7kC@l}uFJL8rPk1(_GOhAIFBJLZMwQP zM}hz?fU|(;Oj`$EVmlPC{?O1LQk6RBH3`5rGfGwpW5_Ug)2%;B`&pHxsju$`4Z9D~ z_|1}|%OZ~zMT{Q*I`AQei?*&4Ww4s}M(W9sqOVJ~L!Y^%t)qx3I;<7G-#>NOc=CSz zL2y&-d~m4>{%BkKEMc{Q!t%tLv>R=775^f296bVaIUtMnWUu#YJ;IX?DGoak0 zd9V-mbKt?{ggKGtbhF<#V9EC^WslwR)8%qg`&eD@Z4dXT-NcOa&$NaES<`OYXy(}F z2hBaS8=>uxHj?kxOqX?R(F?gSva}+V0&`NviUi+u@je1drpfVW!bO$??h4Qf>s4sF zpX(Fe13m$3z0yNfW{RiKlOjx)gch_il?A-lPcI(Znulg3#joZE z>tO2K0F|+5V!FX3fTLrNL3K2GLJmnqn;wW^g`&~|xW;2@7IhR5oYC1i(Jq@yN;#_A z*&2m9LFMm4xhaIMhj@Qk_TOKZiSHib)BX-Y$+wo}|K6wjYrj^|*2d9E-^R&Um)(rU z(bn0)@bBevm&$)g**UmcWA*05RV4qvNm)aD+>j4Sv+(BD`R{mGm#6~Ioz5XKiHI&% z`y=Z#fIvd;=i38Uvh5+dY8$eKosyN`E>9D%QobL1$0d+?E(q^v(gC{`F3O*C|A(w^ z;LfyNmQE(t#I|kQwylY6+s4GUZ6_1kwrv|NN*;LW@16>QNC5)4??CHS$JiVY`2%xgrZ1VOpI4JPgW1Y%?A{?MJQehyg0 z?DA=8fo3aREofRzf+61(gQRI<73y@dZ%evFQFt9}hXHo5Rhhzg186Ud3NgC>VJ$99 zx`5%A$Hl*T&bGi_2Fo&zdkP4dw_OGtP&0QHcr8MV@#eFDD^Mpp^3P{VhtyaYm>_=T+Wlc9(e%NmuyvulG2 z8+@PQ*IZocpX|1!?8aUmqFf-YSuK=HS zu(T8)>*~lSGjVd)0=K=?6jEn6$h=SZ^l{Oz4gzjjd2o-dDV2k3vIQ%}9oC0hhj6$9 zbSjQA3XwUm{I<@vXU z?RN&Sa|W|>7Iz9EMafS4LC1Ci)!NnkRJi!|ruS$2;q?;uQ!qIPB)_;8_g-=}z-EIr z+$waeC;-ZYj>?Pnoemmv;2777fQ2UOq6RE`ESZ5ec&Ho}8C`S!faIrEV-%2PSS{@w z(OAafc01LYqiqusp`2xEdM!1tyD;03vg82ydL_uarO#s;Oy3M1hOqW=tAP4)*Uut} zPkw0;(mBm7pH_F3M&YJpERY`O_KSJ!ETysSnicZ_%SPbJSuaGjP~soG6MNz5>i!TK zwN!g7$cHNAWe6VhHtNQ=M9}TAibFi;LS61Eo!Q9UxC1naq|O>j+WA*{c4z;%Xu;`= zn+g7ng^=G&_-`DYp^dAXiIFvpfrG<_l5|Wu9bD&;YNXPGnBg&`@_vKW&vu1{%CZuL zn4dU24TD94?L<+Je_X~@eFYYjZJ1G0-0n7?-NrLvQEOc5aFX512twu6nK)fnJUc$@ zTYR3SUW6#m7E+2+qqa*5bIvawMXP|bw(Y&X!o}ah>P(Q)Ec&df!Zgf++L0L&q;Dix z7Jq!j$(t$Kwg#w4S`oN92twKEsmrNXhcbLb8f!lf?+wi#lM;7yu|XV*m$-hFI^}MY zOeB)h*E7~j}w1z7B~W((z)eCgVCo{DO*tKVmNgooJh4|fv7uki(R9EQWD zHI9?zQO^B5_Un<-mz{NFUNm9%D~$Qs_n-G*82LuGMHO`>VetD&RlnAUZnKffO!NYhIt0d|}V*F*E&HT8ZBka7{wb7jC4Sg?_Nf1+ zL}_LvPD;}N|64>uWS2h^^$in46Ld$$TzGWSJ++KYDw{w)NJgczbWgeEWgGo!!3I%7 zSAs4_zB=Gs@qvhYZ5BFRVn<-+2fqRXA)<`@sU zDRr`-dM-cb!vtgnLThOKXWuOX=B5yqh?twe9$z8^LSGo`W|={I%X``C?y|8*9)!)Y zFbGKAP+l>SH5P>uC6-U8)vtNkw84V}cbP3gqp+;Wfe3bw=nE+yd}Hk_;INkQ@f2x$ zkMGR+iUuEVtZ)TZsDi?*U=>LtCi?=?9?I3%>@d*6tfNm27WBCw*hDk^-m*`zl7`>f z+~WYsJVhPz31_v?=_XcR`)%=*gt%C+lSq$aK$C)8`|@cKtuCP;Pgm`S*|i4ic6_A% zNHQa==S&qJ$Gk|ITV8h;n~PiZ^FPj>q` z5k!NX4z|WJS`t)V6AEe54Tw#hu(7Uuc)!=PjXuB)yJaGhjYwOh`7sxRLBE;D`Hju9U6!{Dt^sA$6lIRUa&RO%(+FP~}A7JrR zPbYlb<{d6pJ;{@g{TK7(ll6m`_1rG`Eog$q`u-@JUqv+xA5p2v@lUU_ z@VO6hCX*TQTrv@y|ZSUnVj%2bVJ!SQmSDS;B?E@T9%_-TD z-u$~C^T>%LQWL}7u|KV*oa{Y2Bt$g088V;P)?J7X(i?bGqY9MdfsMzRP$z;D(V^L;mqR zc=O+_Hp*Y+qWO?=@7epwpR*gNI7+F@ricudd#+`EMfMZ7yhjaVn z^GSZQA!1PCCc*(%1;n@p^K2p zuDzs&y3v-PVlL5}1kv7>c3hKi)RUnwVx9mD9G98Q-Ehb4#bB1Pz;XFbqI+=s%gise zZFq2?7c0?NNFOsz?2!@Y3J>)CO}cH0l->kq}5GR=<)za~GFPf+nN#JGHO ztb`m4EU=yjq69i7C73KqoEAQ3?H03}r#6cyIL}KI1>ah3tpc<>>Y!P9_}aJU$%NVl3E= z#|2nyM55uar(yR~={riNru|v{D?z&8YPEMVZ{8TJDVN;94xi$*z?=jk}$DQpTEjHZv)=;KY zam$Si!Rh(ic${B3n2aTrK*X%TfQX7)@1-jjjX!E%sIa_Wb^@|tow5!Dt}+D+#Kas~ zzTBqXA9i2JI3?!a{L-R-6o@3UXHEt521RI7);c@c%QueY7T>E_lj(pF4ti`;4pYS;VF7zqF)j> zb`kD2C@V^8dQ{NVPG`z$4JGJd-AG35IzAhhYx{bN`~14dl4I1@nM1p)wff4fAz5>e zt=0G2H~ljV;5z_82P}LG1=;-!0uRwcA*S6@l{-2T?=C0EO(qotCmu;Kq!Ifoe^|)h znlGX1>)^UZu8syj5@{UPbgOypeJL6Z=~T3< z!o|{baTm!r!W4jsZbQkuwo4d>ebF#<;js7V5v*bPGJ|Ehr?#P8~4N zpSiQ=Z#In?-%lrE<}D}2rc6PAn<{pbrUbm6XAppYlTif^IU>{xX$~=mmK9M*L2@1I zF({{yY8V2!%iL~f5geOG;U&k+pC_=NW-dipKw0Dn5@!>xC7+AAQxQ3TiZd9lE>nlz zt3uQyW}a}eH1)(InJ%u#-zC{19*Y}7zP2z;DZYehAhuf*i{>)1Cs+bWVGdQVJ

l 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 literal 0 HcmV?d00001 diff --git a/expression/Constante.cpp b/expression/Constante.cpp new file mode 100644 index 0000000..0fca9f3 --- /dev/null +++ b/expression/Constante.cpp @@ -0,0 +1,51 @@ +#include "Constante.h" + +#include +#include +#include +using namespace std; + +//CETTE PARTIE NE SERT QUE DANS LE CAS D'UNE COMPILATION AVEC +//C++ BUILDER. DONC AVEC GCC ON RAJOUTE -D _NUNUX_ A LA COMPIL ! +#ifndef _NUNUX_ + +#include +#pragma hdrstop + +#endif + +Constante::Constante(): +val(true) +{ + +} + +Constante::Constante(const Constante &c): +val(c.val) +{ +} + +Constante::Constante(const bool &v): +val(v) +{ + nbvars = 0; +} + +Constante::~Constante() +{ +} + +void Constante::Afficher () const +{ + cout << val; +} + +bool Constante::Evaluer() const +{ + return val; +} + +Expression *Constante::Copie() const +{ + return new Constante(val); +} diff --git a/expression/Constante.h b/expression/Constante.h new file mode 100644 index 0000000..a3ffc60 --- /dev/null +++ b/expression/Constante.h @@ -0,0 +1,64 @@ +#ifndef _CONST_ +#define _CONST_ + +#include "Fonction.h" + +//! Classe Constante. +/*! + C'est une fonction d'arité 0. Elle contient juste une valeur booleenne : true ou false. +*/ + +class Constante : public Fonction +{ + public : + //! Constructeur par defaut. + /*! + Constructeur par défaut pour les constantes. + */ + Constante(); + //! Constructeur par copie. + /*! + Constructeur par copie pour les constantes. + */ + Constante(const Constante &); + //! Constructeur standard. + /*! + Constructeur à partir d'un booléen pour les constantes. + \param v : Valeur de la constante. + */ + Constante(const bool &v); + //! Destructeur. + /*! + Destructeur pour les constantes. + */ + ~Constante(); + + //! Fonction membre d'affichage d'une constante. + /*! + Affiche une constante (un booléen). + */ + void Afficher () const; + + //! Fonction membre d'évaluation d'une constante. + /*! + \return Valeur de la constante. + */ + bool Evaluer() const; + + //! Fonction membre retournant une expression. + /*! + \sa Constante(const bool &). + \return Une nouvelle constante initialisée à la même valeur que celle implicite. + */ + Expression *Copie() const; + + private : + + //! Donnée privée. + /*! + Valeur de la constante. + */ + const bool val; +}; + +#endif diff --git a/expression/Et.cpp b/expression/Et.cpp new file mode 100644 index 0000000..5e68a0f --- /dev/null +++ b/expression/Et.cpp @@ -0,0 +1,50 @@ +#include "Et.h" + +#include +#include +#include +using namespace std; + +//CETTE PARTIE NE SERT QUE DANS LE CAS D'UNE COMPILATION AVEC +//C++ BUILDER. DONC AVEC GCC ON RAJOUTE -D _NUNUX_ A LA COMPIL ! +#ifndef _NUNUX_ + +#include +#pragma hdrstop + +#endif + +Et::Et(const Expression *e1, const Expression *e2): +Fonction(e1,e2) +{ + nbvars = (e1->NbVars() + e2->NbVars()); +} + +Et::Et(const Et &e): +Fonction(e.expr[0],e.expr[1]) +{ + nbvars = e.NbVars(); +} + +Et::~Et() +{ +} + +void Et::Afficher () const +{ + cout << "("; + expr[0]->Afficher(); + cout << "&"; + expr[1]->Afficher(); + cout << ")"; +} + +bool Et::Evaluer() const +{ + return (expr[0]->Evaluer() && expr[1]->Evaluer()); +} + +Expression *Et::Copie() const +{ + return new Et(expr[0], expr[1]); +} diff --git a/expression/Et.h b/expression/Et.h new file mode 100644 index 0000000..0441ebd --- /dev/null +++ b/expression/Et.h @@ -0,0 +1,56 @@ +#ifndef _ET_ +#define _ET_ + +#include "Fonction.h" +#include "TableVerite.h" + +//! Classe Et. +/*! + Opérateur logique binaire "et", classe dérivée de Fonction. +*/ +class Et : public Fonction +{ + public : + //! Constructeur standard. + /*! + Constructeur à partir de 2 expressions. + \param e1 : Première expression. + \param e2 : Seconde expression. + \sa Copie(), NbVars() + */ + Et(const Expression *e1, const Expression *e2); + //! Constructeur par copie. + /*! + Constructeur par copie pour l'opérateur "et". + \sa NbVars() + */ + Et(const Et &); + //! Destructeur. + /*! + Destructeur pour l'opérateur "et". + */ + ~Et(); + + //! Fonction membre d'affichage. + /*! + Affiche les 2 expressions séparées par le symbole "&". + */ + void Afficher () const; + + //! Fonction membre d'évaluation. + /*! + \return Resultat de l'expression. + */ + bool Evaluer() const; + + //! Fonction membre retournant une expression. + /*! + \sa Et(const Expression *, const Expression *). + \return Une copie de l'expression. + */ + Expression *Copie() const; + + private : +}; + +#endif diff --git a/expression/Expression.cpp b/expression/Expression.cpp new file mode 100644 index 0000000..00aabf5 --- /dev/null +++ b/expression/Expression.cpp @@ -0,0 +1,88 @@ +#include "Expression.h" + +#include +#include +using namespace std; + +//CETTE PARTIE NE SERT QUE DANS LE CAS D'UNE COMPILATION AVEC +//C++ BUILDER. DONC AVEC GCC ON RAJOUTE -D _NUNUX_ A LA COMPIL ! +#ifndef _NUNUX_ + +#include +#pragma hdrstop + +#endif + +Expression::Expression() +{ +} + +Expression::~Expression() +{ +} + +int Expression::NbVars() const +{ + return nbvars; +} + +TableVerite Expression::TabVerite() const +{ + Variable **vars; + Variable **nvars; + int nbv; + Expression *e = this->Copie(); + + int i,j,jpuiss,nbpuiss; + + //on initialise le nombre de variables à 0. Ce sera incrémenté lors de la recherche des variables. + nbv = 0; + + //allocation des tableaux de pointeurs vers les variables + //ces tableaux contiendront au plus nbvars pointeurs vers des Variable + //le premier sert à mémoriser les adresses des variables de l'expression d'origine + //le deuxième sert à contenir les adresses des nouvelles variables + vars = new Variable *[NbVars()]; + nvars = new Variable *[NbVars()]; + + //recherche des variables + e->Chercher_variables(vars, nvars, nbv, this->NbVars()); + + //calcul de 2^nbvars + nbpuiss = (int)pow(2.,(double)nbv); + //création de la table de vérité + TableVerite tab =TableVerite(nbv); + tab.SetVars(vars); + + //recherche des valeurs de vérité pour toutes les combinaisons de valeurs (true/false) + //pour toutes les variables + + //pour i de 0 à 2^nbvars + for (i=0 ; iAffecter(true); + else + nvars[nbv-j-1]->Affecter(false); + jpuiss *= 2; + } + tab.SetVal(i,e->Evaluer()); + } + + //libération des nouvelles variables + for (i=0 ; i + using namespace std; + +//CETTE PARTIE NE SERT QUE DANS LE CAS D'UNE COMPILATION AVEC +//C++ BUILDER. DONC AVEC GCC ON RAJOUTE -D _NUNUX_ A LA COMPIL ! +#ifndef _NUNUX_ + +#include +#pragma hdrstop + +#endif + +Fonction::Fonction(): +arite(0) +{ +} + +Fonction::Fonction(const Expression *e): +arite(1),expr(new Expression *[1]) +{ + expr[0] = e->Copie(); +} + +Fonction::Fonction(const Expression *e1, const Expression *e2): +arite(2),expr(new Expression *[2]) +{ + expr[0] = e1->Copie(); + expr[1] = e2->Copie(); +} + +Fonction::~Fonction() +{ + int i; + for (i=0 ; i0) + delete [] expr; +} + +void Fonction::ChangerExpr(const int &i, const Expression *e) +{ + if ((i>=0) && (iNbVars(); + delete expr[i]; + expr[i] = e->Copie(); + nbvars += e->NbVars(); + } +} + +void Fonction::Chercher_variables(Variable **vars, Variable **nvars, int &nbv, const int &nbvars) +{ + int i; + for (i=0 ; iChercher_variables(vars, nvars, nbv, nbvars); +} + +Expression *Fonction::Fils() const +{ + if (arite == 0) + return NULL; + return expr[random()%arite]; +} + diff --git a/expression/Fonction.h b/expression/Fonction.h new file mode 100644 index 0000000..18fd8d8 --- /dev/null +++ b/expression/Fonction.h @@ -0,0 +1,81 @@ +#ifndef _FCT_ +#define _FCT_ + +#include "Expression.h" +#include + +//! Classe fonction. +/*! + Cette classe est une classe dérivée de Expression. + C'est grâce à cette classe qu'on va pouvoir construire des fonction d'arité 0 (Constantes par exemple), + des fonctions d'arité 1 (Non par exemple) et des fonction d'arité 2 (Et par exemple) ... +*/ +class Fonction : public Expression +{ + public : + //! Constructeur par défaut. + /*! + Constructeur par défaut pour les fonctions. + */ + Fonction(); + + //! Constructeur standard. + /*! + Constructeur à partir d'une expression. + */ + Fonction(const Expression *e); + + //! Constructeur standard. + /*! + Constructeur à partir de deux expressions. + */ + Fonction(const Expression *e1, const Expression *e2); + + //! Destructeur. + /*! + Destructeur pour les fonctions. Il va s'occuper de détruire récursivement les expressions en données membres + qui sont des copies des fonctions d'origine et qu'il faut donc détruire. + */ + ~Fonction(); + + //! Fonction membre à 1 argument. + /*! + Accesseur permettant de modifier une expression de la Fonction. + \param i : indice de l'expression à modifier. + \param e : nouvelle expression + */ + void ChangerExpr(const int &i, const Expression *e); + + //! Fonction membre à 4 arguments. + /*! + \param vars : tableau des variables de l'expression + \param nvars : tableau des nouvelles variables associées à l'expression copiée + \param nbv : nombre de variables de l'expression (chacune est comptée une seule fois) + \param nbvars : Le nombre de variables différentes de l'expression + */ + void Chercher_variables(Variable **vars, Variable **nvars, int &nbv, const int &nbvars); + + //! Fonction membre qui retourne un fils au hasard ou NULL. + /*! + \return Un fils au hasard. + */ + Expression * Fils() const; + + + + protected : + //! Donnée protegée. + /*! + Arité de la fonction. + */ + int arite; + //! Donnée protegée. + /*! + Tableau d'Expressions. + */ + Expression **expr; + + private : +}; + +#endif diff --git a/expression/Makefile b/expression/Makefile new file mode 100644 index 0000000..95bf7a1 --- /dev/null +++ b/expression/Makefile @@ -0,0 +1,32 @@ +CCPP = g++ +OBJS = TableVerite.o Variable.o Expression.o VarExpr.o Fonction.o Constante.o Ou.o Et.o Non.o +CPPFLAGS = -D _NUNUX_ + +Exemple : $(OBJS) + +Constante.o : Constante.h Fonction.o + $(CCPP) $(CPPFLAGS) -c Constante.cpp + +Non.o : Non.h Fonction.o + $(CC) $(CPPFLAGS) -c Non.cpp + +Et.o : Et.h Fonction.o + $(CCPP) $(CPPFLAGS) -c Et.cpp + +Ou.o : Ou.h Fonction.o + $(CCPP) $(CPPFLAGS) -c Ou.cpp + +VarExpr.o : VarExpr.h Variable.o + $(CCPP) $(CPPFLAGS) -c VarExpr.cpp + +Fonction.o : Fonction.h Variable.o Expression.o + $(CCPP) $(CPPFLAGS) -c Fonction.cpp + +Expression.o : Expression.h TableVerite.o + $(CCPP) $(CPPFLAGS) -c Expression.cpp + +Variable.o : Variable.h + $(CCPP) $(CPPFLAGS) -c Variable.cpp + +TableVerite.o : TableVerite.h + $(CCPP) $(CPPFLAGS) -c TableVerite.cpp diff --git a/expression/Non.cpp b/expression/Non.cpp new file mode 100644 index 0000000..69cf9e3 --- /dev/null +++ b/expression/Non.cpp @@ -0,0 +1,52 @@ +#include "Non.h" + +#include +#include +#include +using namespace std; + +//CETTE PARTIE NE SERT QUE DANS LE CAS D'UNE COMPILATION AVEC +//C++ BUILDER. DONC AVEC GCC ON RAJOUTE -D _NUNUX_ A LA COMPIL ! +#ifndef _NUNUX_ + +#include +#pragma hdrstop + +#endif + +Non::Non(const Expression *e): +Fonction(e) +{ + nbvars = e->NbVars(); +} + +Non::Non(const Non &n): +Fonction(n.expr[0]) +{ + nbvars = n.NbVars(); +} + +Non::~Non() +{ +} + +void Non::Afficher () const +{ + cout << "!"; + expr[0]->Afficher(); +} + +bool Non::Evaluer() const +{ + return (! expr[0]->Evaluer()); +} + +Expression *Non::Copie() const +{ + return new Non(expr[0]); +} + +void Non::Chercher_variables(Variable **vars, Variable **nvars, int &nbv, const int &nbvars) +{ + expr[0]->Chercher_variables(vars, nvars, nbv, nbvars); +} diff --git a/expression/Non.h b/expression/Non.h new file mode 100644 index 0000000..f444d3c --- /dev/null +++ b/expression/Non.h @@ -0,0 +1,62 @@ +#ifndef _NON_ +#define _NON_ + +#include "Fonction.h" + +//! Classe Non. +/*! + Opérateur logique unaire "non", classe dérivée de Fonction. +*/ +class Non : public Fonction +{ + public : + //! Constructeur standard. + /*! + Constructeur à partir d'une expression. + \sa Copie(), NbVars() + */ + Non(const Expression *); + //! Constructeur par copie. + /*! + Constructeur par copie pour l'opérateur "non". + \sa NbVars() + */ + Non(const Non &); + //! Destructeur. + /*! + Destructeur pour l'opérateur "non". + */ + ~Non(); + + //! Fonction membre d'affichage. + /*! + Affiche l'expression précédée du symbole "!". + */ + void Afficher () const; + + //! Fonction membre d'évaluation. + /*! + \return Resultat de l'expression. + */ + bool Evaluer() const; + + //! Fonction membre à 4 arguments. + /*! + \param vars : tableau des variables de l'expression + \param nvars : tableau des nouvelles variables associées à l'expression copiée + \param nbv : nombre de variables de l'expression (chacune est comptée une seule fois) + \param nbvars : Le nombre de variables différentes de l'expression + */ + void Chercher_variables(Variable **vars, Variable **nvars, int &nbv, const int &nbvars); + + //! Fonction membre retournant une expression. + /*! + \sa Non(const Expression *). + \return Une copie de l'expression. + */ + Expression *Copie() const; + + private : +}; + +#endif diff --git a/expression/Ou.cpp b/expression/Ou.cpp new file mode 100644 index 0000000..0c6798a --- /dev/null +++ b/expression/Ou.cpp @@ -0,0 +1,51 @@ +#include "Ou.h" + +#include +#include +#include +using namespace std; + +//CETTE PARTIE NE SERT QUE DANS LE CAS D'UNE COMPILATION AVEC +//C++ BUILDER. DONC AVEC GCC ON RAJOUTE -D _NUNUX_ A LA COMPIL ! +#ifndef _NUNUX_ + +#include +#pragma hdrstop + +#endif + +Ou::Ou(const Expression *e1, const Expression *e2): +Fonction(e1,e2) +{ + nbvars = (e1->NbVars() + e2->NbVars()); +} + +Ou::Ou(const Ou &o): +Fonction(o.expr[0],o.expr[1]) +{ + nbvars = o.NbVars(); +} + +Ou::~Ou() +{ +} + +void Ou::Afficher () const +{ + cout << "("; + expr[0]->Afficher(); + cout << "V"; + expr[1]->Afficher(); + cout << ")"; +} + +bool Ou::Evaluer() const +{ + return (expr[0]->Evaluer() || expr[1]->Evaluer()); +} + + +Expression *Ou::Copie() const +{ + return new Ou(expr[0], expr[1]); +} diff --git a/expression/Ou.h b/expression/Ou.h new file mode 100644 index 0000000..e26b4e8 --- /dev/null +++ b/expression/Ou.h @@ -0,0 +1,53 @@ +#ifndef _OU_ +#define _OU_ + +#include "Fonction.h" + +//! Classe Ou. +/*! + Opérateur logique binaire "ou", classe dérivée de Fonction. +*/ +class Ou : public Fonction +{ + public : + //! Constructeur satndard. + /*! + Constructeur à partir de 2 expressions. + \sa Copie(), NbVars() + */ + Ou(const Expression *, const Expression *); + //! Constructeur par copie. + /*! + Constructeur par copie pour l'opérateur "ou". + \sa NbVars() + */ + Ou(const Ou &); + //! Destructeur. + /*! + Destructeur pour l'opérateur "ou". + */ + ~Ou(); + + //! Fonction membre d'affichage. + /*! + Affiche les 2 expressions séparée par le symbole "V". + */ + void Afficher () const; + + //! Fonction membre d'évaluation. + /*! + \return Resultat de l'expression. + */ + bool Evaluer() const; + + //! Fonction membre retournant une expression. + /*! + \sa Ou(const Expression *, const Expression *). + \return Une copie de l'expression. + */ + Expression *Copie() const; + + private : +}; + +#endif diff --git a/expression/TableVerite.cpp b/expression/TableVerite.cpp new file mode 100644 index 0000000..6085907 --- /dev/null +++ b/expression/TableVerite.cpp @@ -0,0 +1,113 @@ +#include "TableVerite.h" + +#include +#include +#include +#include +using namespace std; + +//CETTE PARTIE NE SERT QUE DANS LE CAS D'UNE COMPILATION AVEC +//C++ BUILDER. DONC AVEC GCC ON RAJOUTE -D _NUNUX_ A LA COMPIL ! +#ifndef _NUNUX_ + +#include +#pragma hdrstop + +#endif + +TableVerite::TableVerite(): +nbvars(0) +{ +} + +TableVerite::TableVerite(const int &nbv): +nbvars(nbv) +{ + int nbvals = (int)pow(2.,(double)nbv); + //allocation du tableau qui contiendra les valeurs de la table de vérité + vals = new bool[nbvals]; + + vars = new char *[nbvars]; +} + +TableVerite::TableVerite(const TableVerite &tab): +nbvars(tab.nbvars) +{ + int i, nbvals = (int)pow(2.,(double)nbvars); + //allocation du tableau qui contiendra les valeurs de la table de vérité + vals = new bool[nbvals]; + + vars = new char *[nbvars]; + + for (i=0 ; iNom()); +} + +//Affichage +void TableVerite::Afficher() const +{ + int i, j, nbpuiss = (int)pow(2.,(double)nbvars); + + for (i=0 ; i +#include +#include +using namespace std; + +//CETTE PARTIE NE SERT QUE DANS LE CAS D'UNE COMPILATION AVEC +//C++ BUILDER. DONC AVEC GCC ON RAJOUTE -D _NUNUX_ A LA COMPIL ! +#ifndef _NUNUX_ + +#include +#pragma hdrstop + +#endif + +VarExpr::VarExpr(Variable *v): +var(v) +{ + nbvars=1; +} + +VarExpr::VarExpr(const VarExpr &v): +var(v.var) +{ + nbvars=v.nbvars; +} + +VarExpr::~VarExpr() +{ +} + +void VarExpr::Afficher () const +{ + var->Afficher(); +} + +bool VarExpr::Evaluer() const +{ + return var->Valeur(); +} + +Expression *VarExpr::Copie() const +{ + return new VarExpr(var); +} + +void VarExpr::Chercher_variables(Variable **vars, Variable **nvars, int &nbv, const int &nbvars) +{ + + //création d'une nouvelle variable pour pouvoir + //essayer toutes les valeurs de vérités + Variable *temp = new Variable(strdup(var->Nom())); + + //ajout de la variable dans la liste des variables de la table de verite + int i=nbvars; + //recherche de la variable dans la liste des variables de la table de vérité + while (i>0) + { + //si la variable est déjà dans la liste il n'y a rien à faire + if (vars[nbvars-i] == var) + break; + i--; + } + + if (i==0) + { + //la Variable n'est pas dans la liste donc il faut l'ajouter. + vars[nbv]=var; + nvars[nbv]=temp; + nbv++; + + //remplacement de la Variable de la formule par la nouvelle + var = temp; + } + else + { + //la Variable est déjà dans la liste à l'emplacement nbvars-i + //on remplace juste la Variable de la formule par celle de nvars + var = nvars[nbvars-i]; + } +} + +Expression *VarExpr::Fils() const +{ + return NULL; +} diff --git a/expression/VarExpr.h b/expression/VarExpr.h new file mode 100644 index 0000000..2c37266 --- /dev/null +++ b/expression/VarExpr.h @@ -0,0 +1,75 @@ +#ifndef _VE_ +#define _VE_ + +#include "Variable.h" +#include "Expression.h" + +//! Classe VarExpr. +/*! + Expression de variables, classe dérivée de Fonction. +*/ +class VarExpr : public Expression +{ + public : + //! Constructeur standard. + /*! + Constructeur à partir d'une variable. + \param v : Variable a mettre dans l'expression. + */ + VarExpr(Variable *v); + //! Constructeur par copie. + /*! + Constructeur par copie pour les expression de variables. + */ + VarExpr(const VarExpr &); + //! Destructeur. + /*! + Destructeur pour les expression de variables. + */ + ~VarExpr(); + + //! Fonction membre d'affichage. + /*! + Affiche l'expression de variables. + */ + void Afficher () const; + + //! Fonction membre d'évaluation. + /*! + \sa Valeur() + \return Resultat de l'expression. + */ + bool Evaluer() const; + + //! Fonction membre à 4 arguments. + /*! + \param vars : tableau des variables de l'expression + \param nvars : tableau des nouvelles variables associées à l'expression copiée + \param nbv : nombre de variables de l'expression (chacune est comptée une seule fois) + \param nbvars : Le nombre de variables différentes de l'expression + */ + void Chercher_variables(Variable **vars, Variable **nvars, int &nbv, const int &nbvars); + + //! Fonction membre retournant une expression. + /*! + \sa Variable (const char *). + \return Une copie de l'expression. + */ + Expression *Copie() const; + + //! Fonction membre qui retourne un fils au hasard ou NULL. + /*! + \return Un fils au hasard. + */ + Expression * Fils() const; + + + private : + //! Donnée privée. + /*! + Une variable. + */ + Variable *var; +}; + +#endif diff --git a/expression/Variable.cpp b/expression/Variable.cpp new file mode 100644 index 0000000..56c8d09 --- /dev/null +++ b/expression/Variable.cpp @@ -0,0 +1,63 @@ +#include "Variable.h" + +#include +#include +#include +using namespace std; + +//CETTE PARTIE NE SERT QUE DANS LE CAS D'UNE COMPILATION AVEC +//C++ BUILDER. DONC AVEC GCC ON RAJOUTE -D _NUNUX_ A LA COMPIL ! +#ifndef _NUNUX_ + +#include +#pragma hdrstop + +#endif + +//Constructeurs / Destructeurs +Variable::Variable(): +N("Defaut"),val(true) +{ +} + +Variable::Variable(const Variable &v): +N(strdup(v.N)),val(v.val) +{ +} + +Variable::Variable(const char *nm): +N(strdup(nm)),val(true) +{ +} + +Variable::Variable(const char *nm, const bool &v): +N(strdup(nm)),val(v) +{ +} + +Variable::~Variable() +{ + delete N; +} + +//Accesseurs +char *Variable::Nom() const +{ + return N; +} + +bool Variable::Valeur() const +{ + return val; +} + +//Affichage +void Variable::Afficher() const +{ + cout << N;//"(" << N << ":" << val << ")"; +} + +void Variable::Affecter(const bool &v) +{ + val = v; +} diff --git a/expression/Variable.h b/expression/Variable.h new file mode 100644 index 0000000..c3b16bf --- /dev/null +++ b/expression/Variable.h @@ -0,0 +1,77 @@ +#ifndef _VAR_ + +#define _VAR_ + +//! Classe Variable. +/*! + Gestion des variables. +*/ +class Variable +{ + public : + //! Constructeur par défaut. + /*! + Constructeur par défaut pour une variable. + */ + Variable(); + //! Constructeur par copie. + /*! + Constructeur par copie pour une variable. + */ + Variable(const Variable &); + //! Constructeur standard. + /*! + Constructeur à partir d'une chaine de caractères. La variable est initialisée à true + \param nm : nom de la variable. + */ + Variable(const char *nm); + //! Constructeur standard. + /*! + Constructeur à partir d'une chaine de caractères et d'un booléen. + \param nm : nom de la variable + \param v : valeur de la variable + */ + Variable(const char *nm, const bool &v); + //! Destructeur. + /*! + Destructeur pour les variables. + */ + ~Variable(); + + //! Accesseur. + /*! + \return Le nom de la variable. + */ + char *Nom() const; + //! Accesseur. + /*! + \return La valeur de la variable. + */ + bool Valeur() const; + + //! Fonction membre d'affichage. + /*! + Affiche la variable. + */ + void Afficher() const; + //! Fonction membre d'affectation. + /*! + Modifie la valeur de la variable. + \param v : valeur à mettre dans la variable. + */ + void Affecter(const bool &v); + + private : + //! Donnée privée. + /*! + Le nom d'une variable. + */ + char *N; + //! Donnée privée. + /*! + La valeur d'une variable. + */ + bool val; +}; + +#endif diff --git a/framework/Algogen.cpp b/framework/Algogen.cpp new file mode 100644 index 0000000..5353fa3 --- /dev/null +++ b/framework/Algogen.cpp @@ -0,0 +1,78 @@ +#include "Algogen.h" +#include +#include +using namespace std; + +Algogen::Algogen() +:generation(1),generationmax(GENERATIONMAX),taillepop(TAILLEPOP),tauxmutation(TAUXMUT),pop(NULL) +{ +} + +Algogen::Algogen(const Algogen &a) +:generation(a.generation),generationmax(a.generationmax),taillepop(a.taillepop),tauxmutation(a.tauxmutation),pop(a.pop->Copie()) +{ +} + +Algogen::Algogen(Population *p, const double &tm, const int &gm) +:generation(1),generationmax(gm),taillepop(p->Taillepop()),tauxmutation(tm),pop(p) +{ + pop->CreerPopulationAleatoire(); + pop->Evaluation(); +} + +Algogen::~Algogen() +{ + delete pop; +} + +int Algogen::Generation() const +{ + return generation; +} + +double Algogen::GetTauxMutation() const +{ + return tauxmutation; +} + +void Algogen::SetTauxMutation(const double &tm) +{ + tauxmutation = tm; +} + +int Algogen::GetTaillePopulation() const +{ + return taillepop; +} + +void Algogen::SetTaillePopulation(const int &tp) +{ + taillepop = tp;; +} + + +void Algogen::Executer() +{ + Population *p1; + bool cont = true; + + while(cont && (generation < generationmax)) + { + p1 = pop->ReproductionParCroisement(); + p1->Mutation(tauxmutation); + p1->Evaluation(); + pop->Selection(p1); + delete p1; + generation++; + cont = !(pop->EvaluerCondition()); + } + if (!cont) + cout << "Objectif atteint" << endl; + else + cout << "Generation max atteinte" << endl; +} + +void Algogen::AfficherMeilleur() const +{ + pop->Ind(pop->Meilleur())->Afficher(); +} diff --git a/framework/Algogen.h b/framework/Algogen.h new file mode 100644 index 0000000..3a4c00a --- /dev/null +++ b/framework/Algogen.h @@ -0,0 +1,42 @@ +#ifndef _ALGOG_ +#define _ALGOG_ + +#define TAUXMUT 0.1 +#define GENERATIONMAX 100 +#include "Population.h" + +class Algogen +{ + public : + Algogen(); + Algogen(const Algogen &); + Algogen(Population *p, const double &tm, const int &gm); + ~Algogen(); + + //accesseurs + int Generation() const; + double GetTauxMutation() const; + void SetTauxMutation(const double &); + int GetTaillePopulation() const; + void SetTaillePopulation(const int &); + + //l'utilisateur peut vouloir ajouter des choses à faire + virtual void Executer(); + + //affichage du meilleur élément + void AfficherMeilleur() const; + + private : + //génération courante + int generation; + //generationmaximale + int generationmax; + //taille de la population + int taillepop; + //taux de mutation (en %) + double tauxmutation; + //population de la génération courante + Population *pop; +}; + +#endif diff --git a/framework/Individu.cpp b/framework/Individu.cpp new file mode 100644 index 0000000..f93ca6e --- /dev/null +++ b/framework/Individu.cpp @@ -0,0 +1,13 @@ +#include "Individu.h" + +Individu::Individu() +{ +} + +Individu::Individu(const Individu &i) +{ +} + +Individu::~Individu() +{ +} diff --git a/framework/Individu.h b/framework/Individu.h new file mode 100644 index 0000000..f7b2e50 --- /dev/null +++ b/framework/Individu.h @@ -0,0 +1,33 @@ +#ifndef _IND_ +#define _IND_ + +class Individu +{ + public : + Individu(); + Individu(const Individu &); + virtual ~Individu(); + + //Fonctions utiles pour la population + + //retourne un point de coupure sur l'individu. + virtual void * PtCoupure()const=0; + + //croisement de deux individus : points de coupure etc... + virtual Individu *Croiser(const Individu *) const=0; + + //copie d'un individu. + virtual Individu *Copie() const=0; + + //modification d'une partie de l'individu + virtual void Muter()=0; + + //évalue le score de l'individu. + virtual int Evaluation() const=0; + + //affiche l'individu + virtual void Afficher() const=0; + + private : +}; +#endif diff --git a/framework/Makefile b/framework/Makefile new file mode 100644 index 0000000..3e002ac --- /dev/null +++ b/framework/Makefile @@ -0,0 +1,14 @@ +CCPP = g++ +OBJS = Algogen.o Population.o +CPPFLAGS = -D _NUNUX_ + +framework : Algogen.o Population.o Individu.o + +Algogen.o : Algogen.h Population.h + $(CCPP) $(CPPFLAGS) -c Algogen.cpp + +Population.o : Population.h Individu.h + $(CCPP) $(CPPFLAGS) -c Population.cpp + +Individu.o : Individu.h + $(CCPP) $(CPPFLAGS) -c Individu.cpp diff --git a/framework/Population.cpp b/framework/Population.cpp new file mode 100644 index 0000000..45ee8a3 --- /dev/null +++ b/framework/Population.cpp @@ -0,0 +1,233 @@ +#include "Population.h" + +#include +#include +using namespace std; + +Population::Population() +:taillepop(TAILLEPOP),individus(new Individu *[taillepop]),score(new int[taillepop]) +{ + int i; + for (i=0 ; iCopie(); + score[i] = p.score[i]; + } +} + + +Population::Population(const int &tp) +:taillepop(tp),individus(new Individu *[taillepop]),score(new int[taillepop]) +{ + int i; + for (i=0 ; iCopie(); + + //réinitialisation de la nouvelle population + for (i=0 ; itaillepop ; i++) + { + if (newpop->individus[i] != NULL) + delete newpop->individus[i]; + newpop->individus[i] = NULL; + newpop->score[i] = -1; + } + + //création des individus + for (i=0 ; itaillepop ; i++) + { + j = random() % taillepop; + pere = individus[j]; + j = random() % taillepop; + mere = individus[j]; + newpop->individus[i] = pere->Croiser(mere); + } + + return newpop; +} + +void Population::Mutation(const double & tauxmutation) +{ + int nbamuter = (int) (tauxmutation * (double)taillepop); + int i,j; + Individu *amuter; + + for (i=0 ; iMuter(); + } +} + +void Population::Evaluation() +{ + int i; + for (i=0 ; iEvaluation(); +} + +void Population::Selection(const Population *pop2) +{ + int selectionnes = 0; + int i, i1 = taillepop - 1, i2 = pop2->taillepop - 1; + + //on copie la population présente afin de garantir de construire un population + //du même type. + Population *newpop = this->Copie(); + + //réinitialisation de la population + for (i=0 ; itaillepop-1); + Trier(pop2, 0, pop2->taillepop-1); + while (selectionnes < taillepop) + { + //on cherche l'élément qui a le plus gros score parmi les deux populations + if ((i2<0) || ((i1>=0)&&(newpop->score[i1] > pop2->score[i2]))) + { + individus[selectionnes] = newpop->individus[i1]->Copie(); + score[selectionnes] = newpop->score[i1]; + i1--; + } + else + { + individus[selectionnes] = pop2->individus[i2]->Copie(); + score[selectionnes] = pop2->score[i2]; + i2--; + } + selectionnes++; + } + delete newpop; +} + +void Trier(const Population*pop, const int &inf, const int &sup) +{ + int milieu; + if (sup > inf) + { + // s'il y a au moins 2 éléments + milieu = Partition(pop, inf,sup); + + // trier la partie de gauche + Trier(pop, inf,milieu); + + // trier la partie de droite + Trier(pop, milieu+1, sup); + } +} + +int Partition(const Population *pop, const int &inf, const int &sup) +{ + int pivot, tempo; + Individu *tempind; + int i,j; + + pivot = pop->score[(sup+inf)/2]; + i = inf -1; + j = sup+1; + + // tant que les index ne croisent pas + while (iscore[i]score[j]>pivot); + + // Permuter les éléments qui ne sont pas + // à leur place + if ( i < j ) + { + tempo = pop->score[i]; + pop->score[i]= pop->score[j]; + pop->score[j]= tempo; + tempind = pop->individus[i]; + pop->individus[i]= pop->individus[j]; + pop->individus[j]= tempind; + } + } + return j; +} + +int Population::Meilleur() const +{ + int i, max, scoremax=-1; + + for (i=0;i scoremax) + { + max = i; + scoremax=score[i]; + } + + return max; +} + +int Population::Taillepop() const +{ + return taillepop; +} + +int Population::Score(const int &i) const +{ + return score[i]; +} + +Individu * Population::Ind(const int &i) const +{ + return individus[i]; +} + +void Population::SetInd(const int &i, Individu *ind) +{ + individus[i]=ind; +} diff --git a/framework/Population.h b/framework/Population.h new file mode 100644 index 0000000..b0beb69 --- /dev/null +++ b/framework/Population.h @@ -0,0 +1,65 @@ +#ifndef _POP_ +#define _POP_ +#define TAILLEPOP 10 + +#include "Individu.h" + +class Population +{ + public : + Population(); + Population(const Population &); + Population(const int &tp); + virtual ~Population(); + + //on ne connait pas le type des individus donc on met en virtuel pur + virtual void CreerPopulationAleatoire()=0; + + //fonction virtuel car l'utilisateur du framework peut décider d'utiliser + //une stratégie de reproduction. Par exemple différencier les pères des mères + //ou faire se reproduire seulement les meilleurs, etc... + virtual Population *ReproductionParCroisement(); + + //fonction virtuelle car l'utilisateur peut vouloir appliquer une stratégie + //de mutation de population différente. Par exemple muter les plus mauvais + //ou éviter la possibiliter de muter plusieurs fois le même individu + virtual void Mutation(const double &); + + void Evaluation(); + + //cette fonction est virtuelle car l'utilisateur peut vouloir définir une + //stratégie de sélection plus précise. Il peut décider de favoriser soit + //l'ancienne soit la nouvelle génération. Dans la fonction implémentée ici + //c'est la nouvelle qui est privilégiée. + virtual void Selection(const Population *); + + //on ne sait pas quel est le but à atteindre donc cette fonction est virtuelle + //pure. + virtual bool EvaluerCondition() const=0; + + //retourne l'indice du meilleur individu + int Meilleur() const; + + //copie d'une population. Pour un constructeur virtuel + virtual Population * Copie() const=0; + + //accesseurs + int Taillepop() const; + + int Score(const int &) const; + + Individu * Ind(const int &) const; + void SetInd(const int &, Individu *); + + private : + int taillepop; + Individu **individus; + int *score; + + //implémentation du Quicksort pour les population. Ceci est utile pour la + //fonction de Sélection par défaut implémentée dans ce fichier. + friend void Trier(const Population *pop, const int &inf, const int &sup); + friend int Partition(const Population *pop, const int &inf, const int &sup); +}; + +#endif diff --git a/main.cpp b/main.cpp new file mode 100644 index 0000000..5b83ee6 --- /dev/null +++ b/main.cpp @@ -0,0 +1,79 @@ +#include "IExp.h" +#include "PopExp.h" +#include "framework/Individu.h" +#include "framework/Population.h" +#include "framework/Algogen.h" +#include "expression/Expression.h" +#include "expression/Variable.h" +#include "expression/Fonction.h" +#include "expression/VarExpr.h" +#include "expression/Constante.h" +#include "expression/Ou.h" +#include "expression/Et.h" +#include "expression/Non.h" + +#include +#include +using namespace std; + +//CETTE PARTIE NE SERT QUE DANS LE CAS D'UNE COMPILATION AVEC +//C++ BUILDER. DONC AVEC GCC ON RAJOUTE -D _NUNUX_ A LA COMPIL ! +#ifndef _NUNUX_ + + #include + + #pragma hdrstop + USEUNIT("\expression\Et.cpp"); + USEUNIT("\expression\Ou.cpp"); + USEUNIT("\expression\Non.cpp"); + USEUNIT("\expression\Constante.cpp"); + USEUNIT("\expression\Fonction.cpp"); + USEUNIT("\expression\VarExpr.cpp"); + USEUNIT("\expression\Expression.cpp"); + USEUNIT("\expression\Variable.cpp"); +#endif + +int main() +{ + Variable *a = new Variable("a"); + Variable *b = new Variable("b"); + Variable *c= new Variable("c"); + + Expression *va = new VarExpr(a); + Expression *vb = new VarExpr(b); + Expression *vc = new VarExpr(c); + + Expression *p = new Et(va,vb); + Expression *t = new Constante(true); + Expression *q = new Et(t,vb); + Expression *r = new Non(q); + Expression *s = new Ou(vc,r); + + Expression *expr = new Ou(p,s); + + expr->Afficher(); + cout << endl; + + TableVerite tab = expr->TabVerite(); + + tab.Afficher(); + + Population *pop = new PopExp(10,&tab); + Algogen *algo=new Algogen(pop, 0.1, 100); + + algo->Executer(); + cout << endl << "meilleur : "; + + algo->AfficherMeilleur(); + + cout << " score : " << pop->Score(pop->Meilleur()) << " génération : " << algo->Generation() << endl; + + cout << endl << "Population : " << endl; + for (int i=0 ; iTaillepop() ; i++) + { + pop->Ind(i)->Afficher(); + cout << " score : " << pop->Score(i) << endl; + } + + return 1; +} -- 2.30.2