ELF>uB@2@8@&%@@@@@ppYH=<PPYPdd@$$o/usr/lib/amd64/ld.so.1;$s8$`tx$pt$t$t$u$ u %@u4%P%%  &`X&&&&'<'t'''@((@`((()P))P) * $* 8* L*0 l*` **0*0+(`+)+++,+p.,0`, 4,07,7,9-<@-Cx-`G-O-P.TP.V.X.P[.a4/0ht/p/z/p~00t0Љ00,1l11п1(2`22`23@3p3334@@4p 4 4 4P5X5 5 5 5`,5,64`6<6D6PR(7U`7Y7Pg7j8nP8 r8w8z8{,9`9P9`9:8:X:`: :;D;x;;;< <D<t<< <`)(=`-X=0=3=z >D>Ѕ>`>>$?P????0?@@P<@Pd@P@P@P@PA0AhA0AA@BPBBBB0$CLCxCC0CD8DlDD0D E4EdE!E&E`+E0$F5TFP;FpDFMFS GPYTG^GcG0iGn$H tXHyH~H0H(I\I0IpII`,J\J@J@JJ(K\KK K`K,L`LL&L2L2(M@CTMCMOM _M_NPo@NopNtNzNO 4OdO@OOOP`@PlPPPP@PP4QplQpQQP RLRRRR0ShS`!S)SP*T*8T,dT2T4TP7U:XU<U0?U BVE0VH`VpLV@PV`S(W XhW]WdWp X0@X`XXX@X@$Y@`YY YZ8Z`lZ@Z`Z[[,[@[``[0[[ [\8\0p\@\\\]$]T]0]p]]]^H^\^Pp^^P^^^@^^P^_`0_D_@ d_ x_ _` _ _ `p <`P P` `` ` ` 4a ta a a@! b$ @b0( |b@+ b- b1 c5 Lc@8 c< cB dPH @dM |d Q dS dZ ,ea dei ep fpt vPE vL $wPR XwS w@S wS wS wT xU AE IJ G i G 0 T> AE IJ G i G 0D `0 AE IJ G i G 0x \ AE IJ G i G 0 8! AE IJ G i G 0 4 AE IJ G i G ,{ AC I H ,DuAE As F ` H H (t`AC G H ,uAE As F ` H H 04 AE IH I i G (mAC G J ,04uAE As F ` H H (`AC G D ,!uAE As F ` H H ,X!AE ED A e K ,& AE ED A e K ,+:AE ED A e K 0L1AE IH I i G ,5AC IH K (;M AC G I (FE AC G  I (QE AC G I (4\! AC G I (`gF AC G I (s6 AC G I ,~zRx @~ 0<~AC A_ D (TAC Gy D 4<AC G} H u K Z F 4AC Ew H B F  J 4AC Ew H } K  J 0(Ć$AC G J t L 0\AC I G P H <<|AC I. E J F  F 8|AC G K } K [ E 4 @ AC I3 H $ D 4D:AC I M F J 4|AC I F  E 4hAC I' D  L 4 AC If E  K 4$mAC I L F J zRx  fAG A\  @4sAG Ai (dAG DH: B <$~AC I A m K d E 8diAC GZ K  G  H 8 AC GZ K  G  H 8H,AC GZ K  J  H 8yAC GZ K  C  H ,eC l Dp A 8dAC Gc B C E  I ,,AC E D i G ,\AC E H i O H`AC Il G  J  H  G  8AC I G  G q G <PQC C A v BA G c BA J <T0AC I G C M 7 I 8lAC I G u K  H 0~AC I E C M 00  AC If E  F 085AC Ij I  H l&HAL h 'HAL h zRx @'*80\()AC GZ K Q G  H 8lP*AC GZ K Q G  H 8,AC GZ K S E  H 8-9AC GZ K ` H  H 0 /AC G^ G  I 0TH4AC G^ G  I 08AC Ih K  L 0p>AC Gb C  N 0D AC G B H H 4$OAC Ie F  I zRx h]0t]D]X]l]ufC K ]Aa  8^AC BJ E ^ J S (L`AC BHI B ,0aAC P4 E DgAC K 4dgW AH FFA J  K sAC K  sAJ C Dt 4@u AC DEEH L  H ,~[AC Az A ,PAC BHEED K ,t_ AC DEEG B = Ћ'AC BGU $܋EAC AU F ` 4AC BGD- J N J (HAC BF* J t02\ؑuDuj :8:df(LjAC  E H\(fpbZH F HԠ`xK Z C(sK V D` A G M Z H0NC Ay E s E  P HzM K Fh,0|!AC DHE K  D 0AC A K W I   E 8AC I\ G | L  F < AC CY H  C  D K M <`dAC I\ G  E  N 8OG ES J  F b N $(AC E J ,lAC E+ L f J 440{NG Eh F n J f J 8lxfAC GB C  E  I 0AC G D  I 0~M | I0 @ p ,AC E K  4@dAC C H l L  F @x$AC Gn G V J 2 F } K <xAC I G  F Z N 4AC I E  K 44 AC DO A t L 8l FAC I K  A ? A 4 tOC Ev K m K & J , dAC FED G D AC I E  G k E  N 4X AC FJ F  A L $ AC I E  D  D * N n B L  AC P D ) G  E  E \ L 40 t OC EJ G u K n J 8h , |AC Ge H  K  I 0 p AC I H C E <  AC Id G z N  G @  AC Gb C  K  I  A 4\ X# sAC Iw D  H D * AC BNG E v J I G  I < 1 3 AC BN  E  A  E < : /AC I F  K  E <\ > AC FJt H r N [ E < I AC I# H  L d D D P a AC Ie F  E { M  A 0$Y OC E J m C ,Xl] OC EE D  J ,` OC EE D  J 0d ,AC I C  O 4k AC DO H t D 4$`w u AC Ib A  L 4\ . AC HH F Q O 8 AC I` C 4 D a G 8 }AC I` C 4 D a G 8 H qAC I` C P H a G 8H AC Im F  N  G 4@ GAC I E  L 8X QF BQA BBBBA L i AJ K <i AC I# H k M C E 0Xlr nAC Il G _ I <v m AC I K  N J E 4؁ AC HH E Q O < V AC If E  N  K 4D 3AC Ic H U K <| < AC If E / I 1 E 4 AC DOc F  L 4 AC FMt E i G 0, AC I= F b F 4` AC HKx A  G 4 Q AC Ie F  F 4 qAC I$ G  L 4\ AC If E M K 4@ AC HK3 F e K 4x JAC HHd H  O 4 :AC HHd H  O <# AC I+ H  I o I 4(, AC I A  J 4`dA AC HHb J { E 0 K  AF Ie K  J 0V AC G^ G  I <` AC Ie F 1 G  A <@v AC I` C  O  I <D} AC I D  I U K 4 AF P_ J  L <l AC IP K  K T L 48L  AF Pg B l L 4p4 AC I J  E 4̯ AC I J  E 4T AC I J  E <ܼ AC I` C  I ~ J 4X AC DO! E  G < AC I C y G  K D AC HH] G  G " N  E D| R-AC I K % K G I  E 0`, AC Ix K T L <? AC If E   K 9 E @T 0LT AC If E  K <[  AC I~ E s M I G 4\e AC Im F  K <0n AC I G  N  F 4 =AC IX K  G 4  AC Im F  K 4D AC Ij I  L 4|X 'AC I E { E  E 0P 0 AF M N  J 0L 8AC I^ E a O 0X 8AC I^ E a O 0Pd AC G G _ I ( AC BIDq L t ?KE Am $ AC AO D t  ,  AC BN J (< AC DJ A @hL YAC GZ K a G  H n J ,h AC DEED M $ RAJ y L A zRx ,( AI IS J  F ,L AG BEGK H <|H AC I= F T D  N < AC I= F T D  N 4( f AC I D  N 44` AC Ih K  I zRx 0, AC Gd A O I 4P|2 AC Ie F Y O 4> A AC Ie F  O 0,J  AC I F R F 4V ] AC I F R F zRx  Xa AC A^ E (@$b AC I~ E V (lb AC I~ E V ,c ((c AC G I (c AC G I d <AC Er ,$d ;AC I B I G ,Te >AF FM E m *0 o %AC FD\ F \ L 0r AC BDF H _ I m  r [AC Az A 4$s 9AC BEEEIn D  (\t rAC BDq E m ,u ,u AC I8 K } 2~ 2 _L K Jp _K K K 4 AC A D 4X mAC C K w I  E  , AC C D  H , AC C E  H ,` :AC C F  H 84p AC I\ G  F  F 8pĐ AC I\ G  G  N 4H MAC C_ J | D  E 4` }AC C E B F  E 4 FAC C_ J  B [ E 8T AC M^ A  E  J 0T AC I B ~ J 8 YAC I` C  E b N ,4 AC C  F ^ J 00 qAC G G  B 8d@ AC El K \ D a O 8 AC El K \ D  O 8( AC Gc B k E  C @ AC G E k E   C  F 8\H AC G  I k E  D D AC IQ B ^ J  K  G 4t 'AC HK F r N Ll @AC Il G S E  H M K i G Dh\ AC I B ^ J  F  E @ DAC BL E  H s M j F L AC Il G  F  H y O q G <D AC I G } C   G < [AC Iw D  J  K < AC Iw D / I ] K 0 AC I M x H 08 l AC I A F J 0l AC I H F J 8 D AC IW D  N # E 8 {AC G F } K  I , AC I- F 8H AC G^ G  I k E < AC I E C M  D 0 3AC I A F J 4 ,AC BQ A G I 00 6AC I H R F 0d AC I M z F , $AC MD K 4 *AC FJ D  F 0 1'AC If E  K 44 7AC DLZ B  G 4l 8@AC I` C R N 4 DAC I` C B N 4 GAC I` C b N 4KAC I` C B N ,LHOjAC I^ E D|cOC EI H y O  I T L  LgNC E C  J d L u K n J b E 4jAC I A ] K 0Lz AC I F F J 4Ą9AC Iy J % K 0̓AC I` C  O ,HAJ BEGG F 0AC I D F J ,PAC E F e K ,AC BD~ H h H 4LAC I` C Q O 0AC I F M K <HKAC I` C 9 G  F 4\XgAC I` C  O <xAC I B M K  A 8wAC G^ G , D _ I 8)AC G F G I t D ,LAC E F G I <|y AC DL H " N  E 4AC BN J K E 8AC G G K E @ H D0TAC I^ E O I U C k E <x/AC I, G  A  F 0 AC I E M K <AC I E M K  E 0,xAC I G M K D`$AC I} F  A  F - C 4|AC I A  F 4:AC I H  O <xAC I H M K  G <XAC I A  B z F ,AC E F K M 8 !AC GN G M K  B 0%AC I K M K 48l*5AC Ic H 0 H 0pt=AC G K E K 0P?6AC I C O I 8\A)AC Gv G X H  M 8PC9AC Gv G X H  M 8PTE9AC Gv G X H  M DXG!AC I J  A  F o E D@M9AC I G  A  B  E <8S7AC Im F R N  G D\8ZAC I8 K  A   F  E Dp`BAC I M  A  F / E <xg AC I F r N 9 G 4,XojAC I G Q O <dsAC I G M K o I 4@x;AC IE F  K 0H~$AC G D E K 0DAC GI D \ L 4DЃfAC I I * F 0|cAC G I I G DDtAC I. E  A " N I G <|DAC I< G O I  G <84AC I  C O I ! G DxPAC Ie F  B B N  G < AC HH A O I * N <d/AC FJ G b N W I (@TAC BH H Z 4lAC I D  L 4/AC I C } K 4*AC DOC F \ L 0PAC IQ B  H H\1,pAV CS C Q G 4dAC DEIH F  J 4AC E_ H w I  J <!uAC I C k E  D 4P))AC PC I   E 4LSP AC I H  F <d_0 AC I E l D j N 4Ti_AC I K " N <8|qAC I  I O I  G 4x A  E Hl.IE BIGHB F ( H ,01(LW HD1)MW dX1' xt1LAH En A $1AC CC F ((2AC Gq D $2AC Eu B $4AC E D $@<6wAC E C $h7_AC C F 89FC Ag G 8JAC Ec E (9AC G| I 9W9$\C (4:AC GO F (`:AC Gd A ,p;=AC FJd H $@AC q K  A ,@AC DLO E 4xFAC BEHv G  A ,L0N#AC HD A $|0UAC q K  A ,UAC HH F ,XAF FEH F (ZAI Iw F ,0[AC M  C ,` ]AF P B ,pAG DEF) H ,rAM I0 I ,sAC M+ D , vkAC M{ D ,Py7AF P A |C }C ~6nC ,8~6AC k A  M A O ,HAC  C Q O A E ,4 AC P; A $d؃AC q K  A $@AC q K  A ,tAC Mk D 0QAO G H P A ( $AF P A ,D Q AF P G 4t (AC DL D } A ( #AC DJ F  ěW 4 H AC FM A  E (, -AF d M  I (X $!AC BJ D  (-AE f ( 8AC U G K C , ܣAF I K AC h D ,$ 8AC M H T h ZRC , HAC GH E N A , ث4AC HH A  ldC  <HAC j A , l7AC HH A P |jbC l бU, lAC FJA K , \AC DLa K , ܸsAC DL K  ,W , W H thW d  W ( ܽ~KC G F zRx 4AC Gt A q G ] K 4TuAC FDY I i G P $HAH I^ H 4AC Gt A q G ] K 4uAC DEDY F l D P ,$eAC BEH[ B d D 0T dQC DDb B ZBBA 0\AC IY J x H M AC AU  LAC Ee E ( <P(d2AC BDT B M $AC AZ (2AC BDT B M (2AC BDT B M ,AC FDb H ` 48dAC BFFHDw K f J 4pdAC BFFHDw K f J ,pAC BEEDY C { <<AC FHDC G L D g I ,AC DFEK_ C ,HAC DFEK_ C 4x<AC DHEHc H x E 4AC DEHH_ D R E <AC DIDc H T L q O ^ 4(AC BEFJg N n B `tEaC A_ ,.AC DFEGi E AL F (0AC BDT B K 0AC BEEEH_ D G ,DAC DKDN K (tUAC BFh D \ 'AC A\ ,AC DLz B ,AC BIDu H ,4P{AH BEIED| B dzRx ,AC DD K o A LL0[AN Cm A G I U K W I W I w I X H ,@&AC FED H 4@AC GW F Q G ] 0AC FI D  E (8$AC BHy I $d~AC BJm zRx $AN CS K                                        !#')*+,-/0123467;<=?@ABCDEFIJKLMOPQRSUVWXY[^_`bcdefijknprstvwxz|~   !"$%&'()+-.234578;=?@ABCEGHJKLNOPQUXZ[\^_`abdhiklnoqstuvxy|~   "#$%&()+,.02359:<=>?@ABDEFHKNOQRVWYZ[\^`abdeghijklopquxy|}     !"#%&(*+-/034679=>@ADFJKLOPRSWXYZ[\^`cfhijmnorstvwxy{~"$%&(.589:>GHNTZ\]aghlmoquy{}   #*,/0169:<>DFIMRSTVWY]cefgjmprwz{}   !'*-/14678;CGIJLMPSTUX]_cfmnrstvwz{~ $'),.1258:;<?BCEGHIMNQTUV]_abdegklpquz|}r1pW %,3?MXPvBZvBmvBvBB7@B`BnВB`BS B&РB ;BUB< aоBIp BB3B`BB Bu 0C_  C#|CprC0 2C`16CM9CMV`;CVq>C}EC@IC`QCPC6C CКCC@CY%CEpCgSC]DiDpD D+P D`DPD%0DD"D "D"D ,@.D%=p.DK6D^>DqFD ~0TDcWD`[D 0iDclDtDyD}DDD +D=pDV@DkDЫD D D@+E@/E"{EEEb@E!E3pE`;ЋEG`ETEucpErE  E0E0E0E0E0E0EGE:EJ!EJ6`EC ENEcзE p`Ew`EEEE\ EE  F FFF#Ff2'FFB@-F6T2FFd7FVw0=F PFFl OFpUF0[Ft`FeF:kFjpFrvF{F: ЀF2 FB! `FS/ FJ= F:K PFY `Fh @F/v pF  F  Fr F) F F F> F> @F0 pG  G!  G  p(G{ 3 3GuA p4GY  EGuj EG { QGm aGu aG 0qGu qG vG  |G: G G ЌGM &  GE ; pGE P G! e GF z @G6  G G `G  G 0G PG PG$ G% 0G|7 GG G U G:c Gr G `H @#Hm  +Hf 0,Hs ,H p.H~ 3Hi `6H 09H ;Hy, `>H< AHG DHV FHb IH`| PNH  RH @UH ZHl p_H~ eH rH5  H* H) H H* H9;`HQHdHvH@H  H`HHHHH HH&HW 1HF H H RH _H[mHH_ aH=PH'HEHH`H2 H0Hu)Hu:0HjGH:^H:p HHf0HjH@HfIb III@I2 IGP IV`Ig@IvIII(&If -I/I`3I6I$ :Ix3>ICDIU0JIF`OItnSIUI\IpcI kI`rIPvI|zII#I5pIsII3 ]I/qI I Ia II@I@I,pI @Iu I. II}"Jq0JL JG[JkJJ Jm `J@JV K3K<  !K +K,>KC0FKZ@ZKQ rcKq uKyK KJK:PK KK `K K `K0K>K KKY Ll@L `L0$L*L1L 8L VLp]LPuLR-8LI@LfL|LL LLL=MM  .M' 5M0 -?M8>0GM8OpNMep\Mx_MhM  tM Mf PMMM`M M M+M;M<F@M;aM> M*wM% M_M[@M9MrMMM2:M2 NN N!`Nm2NN N ^ Nx N:NN@NMN}NF`N0N  "NY%N$p(Nq3+NJ/N\P3Nn7N:N>NBN'FN@KNONDUN ZN"^N[6dNIiNYqNiwNy0}NЀN{PNpNN0N3pNPN6 NN* N8N'PNcNNNNNjPN N! N;O MO9f O'O@<sB\<@Som<kBv<kB<@8p<W<@nS<@nT2<<V<hB<o<hB<WL =jB=.W =*=`S<=lBE=uSJ=WY=Ueb=?S^t== mW=Tp=iW7=e=uB=2V=@i=pB>W2 >W{!>`i:>`*SbI>pBj>pJWu>0sB|>@W>POV>hB>jB>o>@mB>pB>>>PW> qB>\Y?`Hp ?BP$?-W5?XYD U\DST"D![r*DU6DRCDocUDVM`DUzDoDUQDW~DWdDUDPSDD ^VDiBD0jBDPSD0qBDjCZEpXEXSv'E/ES:EW'MES\EprBAhBeE0TM:;@jBnEpBEWEoEM EHEuBEuWE+XEPiB-@PlBEoBFAq FiBFiB FS-)FW 5FW@FR)RFmB[FYMkFԬrFpSF0tB>=lBF̬FgBFثF CFYFSFtBFe*FP%WJF G0PVG>OGTM?(GЍS93GiBDGP0CI\G@picGWuGqBG[rGtBG`G@rBGGGGlBG`S1GЫGSG`SHpRH`YVHNq1HsBNHhXHScHUqHnB|H`giHIHHWHPWlHSqAmBH#VF HSHйWdH[rIpBIPTI`SaI@D6$I`ti8I@pB?IqBYIlBgIppBISIW.InW6I@`WISI`VIWI JnBJpW"JtW8J@Um"BJpWJTbJpW qJbWJV=JмJS*r7 J[MRJ{DJdJ`jBJWuJVC'K VLKW-K@V8KfEKSq!PkBOK`U[K*CrKKVSK IlKp(SK@ VKKBPoBKКUKKS5K0 L tiLiBL S+LIV8L 0VvCL$tiOLqfLHuuL C LiL`pBLUML LLSLHHLELULpkBL`pg M VMd`-M S9MoB@MgBJMS9WMWliMPWxM0WMMA MV3M SMPsBMoBE0UMWLMrBMrBM0"WwM MsBMpV"N`q] $N`iB)Nȫ1N U'ENhBMN`kB=V2SNU\NsBiNpBNpWN`&WWNR]N'WNlBN`ZCNpBO`OsB"OT,OܬDOCWOOKVeOJn{OtBO`UO:SOaS;gBOUODO oBOWOS.OUPRvP謕PW)PVa3PU;PpWFPptBYPSDmP #I{PnBPmBPRP>qP&OP+XP`CjPtiPPuBPUQ@W7QgZA 'QДS1QS?QVF sB44SNQ@%T2WQoB_QW0nQSOwQSQwBQ@SQe 7Q RQpSAQ CQkBQsBQ`+j Qd QPWRRI*R6RTDRBSORXR pAiRFWzR`WR`P1R*IR`rBR쬕R@WRpU3R2qRvWtSpS쫕+Sp@SnT%MS#W__SoS`HHSUSUSWSCmS(tiS@qSmBS@+jTS TPUE)TnB0TWDTSQROTػnT@&ZA~TPRdT&W$TTWTpBTWTtBTTWT@kBT`9CUjBU`B,UkB0URCKUVw[UsB|UxUWUPrBUS7QlBURFU UMUphBU UU@SUjBVbS2V6SlVC#j2D81V@W2qZPUR>iBZxWQZ`nBZti[@P[лW$"[%W.[6[MSt=[R8K[ CY[Vf[SVm[puBu[`pD[[r[rB[`qB[rB[@uB[@ASn[軕\`U[.46V \@U\\OqvL4U .\DD\`W Q\f\`mBo\НU|\PV\ ,X\\pC\C\`We\W\Ь\p]PqB]tB ]@Xo3]mB<]kBB]]SxP]piBZ]@W4m] jBu]]`8p]PWS]@j\D]0BK]S_]PU,] W]paSK]諕]^WU^`I%^U -^PY6^,X@^pV#N^hBW^S\b^,Xk^*C,x^C^i^rB^0XS^jB| oS!D[r^0oB^V^iZ5RS^kB^?j^0_ mB_Q_R_`Y@&_U?2_ ?@ABCDEFGHIJKLMNO%PQRSIUVWXYZ[\O3!^_`abdefghijklmnopqrstuvwxy z{|}~      VP| !"#$%&'()*+,-./0s123456789:;<=>?@ABCD<EFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuz}c wxyz{|U{:.cM     n@ !"#$%&'()*+,-./01234568:;<=>?@ABCDEFGHIJKLMNktaS79P'RSTUVoH';NXW5HA j1?iZ[^j %ZJ^_`abcdefhghk\2Owi@j02k?r4+l sLbsFR@B1dm,-FuO}]!jpqrstuvwxyzeo{<a"Du aFv|}SfLEb~ud\Bw2 A/XIW,Z7_4GP Gxq]f<L(-i>`?8S.U:;L-uyw#/=p|l$ZN,+Kg_"4>R+Q}ZTE!0m2B:y l /D1yH[UM[=qJh# d>ivRzgYV Yz]9Xp\piXe 7`h&oWkM\C/vdb{~e$Kx@T13%G;O_&r5'r3StQkT=]H C8K Jo65b{PqV?9PI~0n):"wtX6,El) YhYZ`Yػ軕<໕00|UмpPY#(Y8YXYpYQxY3Y:YYfYYYvY:YYxȀYЀY9؀YYYYYYYkYHY Y)(Y0YI8Y@Y6HYWPYXY+`Y'hY@pYxY}Y Y]YsYYYY~YY$YȁYЁY؁YGYYYYYYYY Y(YH0Y8Y@Y:HYPYXYz`YhYpYUxY}YYYYY$YYYYȂY!ЂY؂YYCYYYYYYY8 Y}(Y;0Y8Y@YFHYPYXY`YhYpYTxYNYbYY YYYYYY)ȃY ЃY؃YYYaYYY#YIYsY YT(Yv0Y/8Y@YHYPYgXY`YhYVpYxYY,Y"YYYYpYYYȄYЄY؄YYYY>YEYYYY2 Y (Y0Y 8YQ@Y8HY"PYXY`YhYpY>xYYYYYFYiY0YYYȅYЅY؅YYYqY0Y7Y9Y/Y3YS Yp(Y0Y 8Y+@YHYPY=XY`YhYpYxYGY~YYMYYSYYYeYkȆY^ІYR؆YYYYYYYnYY Y(Y60Y:8Yi@Y5HY45%%h%h%h%h%h%h%h%hp%h`%h P%zh @%rh 0%jh %bh %Zh%Rh%Jh%Bh%:h%2h%*h%"h%h%hp% h`%hP%h@%h0%h %h%h%h%h %h!%h"%h#%h$%h%%h&%h'p%h(`%h)P%zh*@%rh+0%jh, %bh-%Zh.%Rh/%Jh0%Bh1%:h2%2h3%*h4%"h5%h6%h7p% h8`%h9P%h:@%h;0%h< %h=%h>%h?%h@%hA%hB%hC%hD%hE%hF%hGp%hH`%hIP%zhJ@%rhK0%jhL %bhM%ZhN%RhO%JhP%BhQ%:hR%2hS%*hT%"hU%hV%hWp% hX`%hYP%hZ@%h[0%h\ %h]%h^%h_%h`%ha%hb%hc%hd%he%hf%hgp%hh`%hiP%zhj@%rhk0%jhl %bhm%Zhn%Rho%Jhp%Bhq%:hr%2hs%*ht%"hu%hv%hwp% hx`%hyP%hz@%h{0%h| %h}%h~%h%h%h%h%h%h%h%h%hp%h`%hP%zh@%rh0%jh %bh%Zh%Rh%Jh%Bh%:h%2h%*h%"h%h%hp% h`%hP%h@%h0%h %h%h%h%h%h%h%h%h%h%h%hp%h`%hP%zh@%rh0%jh %bh%Zh%Rh%Jh%Bh%:h%2h%*h%"h%h%hp% h`%hP%h@%h0%h %h%h%h%h%h%h%h%h%h%h%hp%h`%hP%zh@%rh0%jh %bh%Zh%Rh%Jh%Bh%:h%2h%*h%"h%h%hp% h`%hP%h@%h0%h %h%h%hjjHHH}HuÐUHLeLmIH]H H=q AtHH=M Ha IcH=& IDHH? L tDLwu\jHDLrÐH=1/H*/H9tH Ht H=/H5/H)HH?HHHtH HtfD= /uUH~/]Dff.@뎐=Z6SwBUHAWAVAUIATA1SHH03X@pXHmXL-`/H94SH*4SD%;4SnA`WX?kXHHapXHDH1QH<p3HH AADhEƅfMDžpDžCfDA-u AA-u3Ahu,Au%DžIM95N{f4{*E1ƅgE1Dp@IM9tgID#A-u {-u{tNs`XHdXHlTIADžpM9uff.DgL%Q&MwL@pifInfl)pf.LcHM>lXLuHCD0I~IHHsLHCD5L1\X11ƅfopHE)EoH}HULcHEIIL$I)L)H9r7K&HEHL9HHEHHvLH}H\X1wLe03XLLeA$HUHHDHH 0d"H}L9t?LHA-L#MEuuH`X HXHtHH )HPHtH1HHA1tfuH5.&0W11{ILLDHDžL.nXLӃHIHLH;A)uE<A 2HL.SHLLLL9rỦ0?WM͉@ ?WPu΍fDJu͉ ʈUΉ UP HHI+H([A\A]A^A_]@Et}̍ AIcH|5D)t1AB9ru͉ ʈAuU PzfDH(1[A\A]A^A_]ÿ@HULEIHtA@f1ÐUHAWAVIAUATISH(HG0HML0Mu ff.MMA9 uMH L{A<$HtYA|$H=]SHEH}XH}HMHLe+uHEI HH H([A\A]A^A_]DAD$tuRIT$AD$At$H|@At$I|$ HEIhHH H([A\A]A^A_]@It$I|$\fUHAVAUATSHH HHDLhLopPt6DPt?1"'H [A\A]A^]f.D`,DLh AUuLuLe;LDLDHfH [A\A]A^]@tD`,H{HD@(HLCPH׋J89R()HHL HЀtFff.ff.ff.I$HHLukH‹BIHH NjBDI8D9rˋI(D)H DLHA4nX[ \XA\A]A^]+R$HHLHfDI9s t'Dt IVAUKfDD`DLhAU,HHLXL_pPt)Pt01"f.p,LX AuIs1ҋNIHD;FrHEI$HLAуIHILIAoMILHA;FseHG`HDH@ OLOHO LWPEY8D9rEI(D)HLHI‰ЃHHHoAH@IBA;FrÐ@tp,LOH@(HLWPIыJ89R()HHL AHЀt?}ff.ff.ff.I$HHLuCH‹BAHHI BDY8D9rʋI(D)fR$HHLvfDID9s DtEt(I AzmX \XLkApLXAfUHAVAUATSHH0HHLOLKpG< <AMfA}tAE<GH@MLCpA<<FMfA9tDA9t>"1H0[A\A]A^]f.Dg,DLo s@A@H@MLSpA<<,A"uAdX \XLH0H[A\A]A^]@AGtDg,LCHDLSPHIG(J89R()HHLDMHAt=ff.ff.E[$LHLDAH‹BIHMBEk8D9rE[(D)"AZX \XDL DA@tAxLKHLSPHIA@J89R()HHLDAtcff.ff.ff.ff.ff.E[$LHLDAH‹BHHMBEs8D9rE[(D)R$HHLsfDR$HHL;fDArMRAAmX \XLI9s DAD8LEfDI9s DA8LEAxMHDABtArH{HLCPHHABJ89R$HHLDHAt NER$LHLDAu0H‹BHHLNjBEZ8D9rER(D)I9s DAIVARHMLHm}H{0HLu3L1LDLDH]@R()HHL@D`DLh@xLHCfDApLPAMH@ff.UHAVAUATISH@HHLPLWpP<t7Pt>A$"1H@[A\A]A^]f.p,LP AuIL$HHIt$PHABz89R$HHHDj<E$<uHRLrMwLH]t<@fA>SA9FHLI<<E$AAMQ<<E$fA:u QSA9Bt LLVLUHHqf:S9BH@[A\A]A^]fDAFtEnIt$HDI|$PHHAFJ89AR$HHHDHAtEsff.ff.ff.E@$LHHDAu0H‹BIHLƋBEH8D9rE@(D)IA9$s A$DA5E$8LEDAAtAI,I|$HMD$PHHAA(r89/R$HHLD HAtKyfff.ff.ff.ff.EI$LHLDAu0H‹BHHL NjBEQ8D9rEI(D)IA9$s A$DAMA$8LEwDAAtAII|$HMD$PHHAAr89R$HHLDHAtKyfff.ff.ff.ff.EI$LHLDAu0H‹BHHL NjBEQ8D9rEI(D)IA9$s A$DAA$8LEVEnE$MvAA,A$MQ IAAA$MIR()HHL@R()HHL@R()HHH@@tp,MD$H@(HML$PIЋJ89R()HHL HЀtBff.ff.ff.I$HHLwH‹BHHI BDQ8D9rNjI(D)R()HHHDj<}DHHu~MDAID;LK`HsHH{PMAAAQ HHƋH899@()HHHDhIƀ7D@HH֋J89R$HHHDA/fff.E@$LHHDAu0H‹BIHLƋBEP8D9rE@(D)I9s DAD8A{LpAnR()HHH3@I9s DA!DIDeLuH?HHHXALDH[A\A]A^A_]GFAUfDpLhAUfDhDLpAR()HHH@DH|E1@$HHLpI€uLPIzfAnHuHIHfAn@HEHEfbfE=D;|HKHLKPL[0I80KDLAAPHHp89J@()HHLpI€H@HHыz89R$HHLD2AMJff.ff.ff.ff.ER$LHLD0Au0H‹BHHLBEr8D9rER(D)I9s D0Atf8LEIz~ID;|R()HHL@MHйAPLPHйcD`DLpAeHHAgXNXAHп'HйzAgXNXHH fUHAWAVAUAATISHHHHHpA$HxOI|$pPt)A$Pt/A$"1efp,A$Hx uMD$HM\$PHIGJ89?R$HHIDSI<AE$<uL{IOHu EHp@;)R;!RWLDx!=HpHMLVN$}HhL!DxHSEMOM4fA9(H@ELO<uE~,E$IF HxHhyA>HLA~H=YRHXH`NH`HXHHhQHp8)@HRHH`HHx8xH=RHPHXгHXHPHH`uHxN:HLL8HHuH<{<E$f;R9CHuHI<<gE$EIFHxAF<dAFtE~,It$HDI|$PHHAF(J89R$HHHDHAt5XfDff.E@$LHHDA$H‹BIHLƋBEH8D9rE@(D)HpxHpf.@tp,MD$H@(HMT$PIЋJ89R()HHLDHAtbbff.ff.ff.ff.ff.$HHLDAH‹BHHI@HvHx )HNH H`fO&HEHLHph81fIA9$s A$D0A4E$8LEfIVAFAvH|f.DxE$H@Hx@DxE$LpDhE$HXpHP@vH|@HVFNHDH`DR()HHLl@pA$Hxt R9H1HCfCIT$hHJ@BWDPE$Lx@UHAWAVAUATSHHHHHDLWLSpG<<t>DWDMрt>"E1HHD[A\A]A^A_]fDw,LO Au‹GH@M4LspA<O<DAtAFAFE1;Ru E1A~AfA>u ;NRHHDDLH[A\A]A^A_]DDGtw,LCHLKPHIG(J89R()HHLDAt]Ifff.ff.ff.ff.ff.E[$LHLDAH‹BHHMBEk8D9rE[(D)A4nX \XLHHH[A\A]A^A_]"RfR$HHL1fD<DDDHHfADŽLHuI<y<qDAf=vRA9F|LHuH<rDGtwLCHLSPHIGJ896R()HHLDHAt;Cfff.ff.$HHLDA H‹BHHIMt$R F;eR# MN;PRWDžPE1WHMHDhHxN}HpMt$HxDhfA>H`DLDV^<PDEID$HxAD$<<uE|$,DID$ HxHp茠A<$HFEd$L%jRHhLcHhHHpLjH`8D`L%RLHHx8,xH=RHXHhHhHXHLuHxW@8pLHuI<<(DfA>RA9FHuLI<{EAD$tE|$HsHDLKPHHAD$J89R$HHL:H@tG@ff.ff.ff.$HHL8@VH‹BIHH<ƋBDG8D9rƋ(D)fDDFt~,LCHLKPHIF(J89R()HHLDAtM ff.ff.ff.E[$LHLDAH‹BHHMBEc8D9rE[(D)A4nX \XLHĘH[A\A]A^A_]GR$HHL9fDD~DHv{fI9s 8@D8LEqAD$BIt$Md$AD$tE|$,HsHDH{PHHAD$(J89R$HHHD HAtHvHxfH@HNLfp@E|$DMd$fEnDMv@At$I fR()HHHY@R()HHL@R()HHH&@NLf HvHx Da()IIMFtD~LCHDLSPHIFJ89R$HHLDHAt(Off.v$HHLDAu)H‹BIHI4BD^8D9rɋv(D)ĐH9s DADjHIT$AD$At$LdnAEF"9ALX \XDfDDVDxDH@HxDDxDL`n@HxMHLefA>Hx DHxMA@<DDABMZ<u<uAB,MZ fA;u RA9Ct LHLHuI<#<kDfA}wRA9EgLLI<NDABtARH{HLKPHH ABq89GI$HHLDHAt/^ff.AC$LHLDA4HADQHHLAC8A9rA)AC(f.DHH AD$y89=I()HHLD HAtSff.ff.ff.ff.EI$LHLDAHAIHL ‹AEQ8D9rEI(D)DhDLp3@xLHA8f.HVFNLdp@HP@vH|@R()HHL@FW<t$M@I$HHLMRDžPAFHWf.HxHHxHxHf8u RE19HUDHDHm!A8DI9s DA8LEABtAR,H{HLKPHH AB(q89LI$HHLDHAtHvf.ff.ff.ff.ER$LHLDAu0HAHHLNjAEZ8D9rER(D)I9s DA8LEAEtEuHsHDH{PHHAEJ89;R$HHHD HAtO}fDff.ff.ff.ff.E@$LHHDAu0H‹BIHLƋBEH8D9rE@(D)I9s DAD8LEfDI9s DAD8LEfDARMR7DEuDMm@R()HHH@I()HHL@I()HHLDžPE1WKDMHhPLXDpDLhPLPgDxDHp0DhDL`PEH`DLEHHHNXHAgX;AnAc(UHD RHAVAUATSL_HHMS$M$ABLCP1AR9AHHLHIƀi|IFHts1f8t"hffx ыPHTRHf8uD9Ht܄t>[A\A]A^]DI9s D(A)8 HA;z1IHM91AB)HHLHIƀ$ʋ@HIӋr89R$HHLD*HAt1fDAmX \XDLDH9s DADHI9s DAD8LEfDL 0@HHNXHAgXx0AEgDMQ@A}gX \XDHfHHNXf~HAgX0Af.DhDHxLGkD`DLx@LHDfA9A<xGHw!Hw ~G(HtqAgXLXDLfff.UHAWAVAUATSHHHHDLFLGpF<<DVEMƀFH@MIH M<mAFMF G,IVAFLD-fDn,DLv AO1"H[A\A]A^A_]EFtDn,H{HDLKPHHNjF(J89R()HHLDMHAt]|fff.ff.ff.ff.ff.ER$LHLDA$H‹BIHLNjBEZ8D9rER(D)<EFLRLeX1LLLfA>AIH t2< AFMF t,IVAFLDfD<tEFLRH9kX1H蚁HNHI3HD1LHJIH@H @HHH~IHjHLufIHL9tsAo$IT$HPAT$tA4$@@@t@t@ t @ uDIT$HIHL9ufHC0Hp0HC0LHP0qufHC0LHP0quHC0LLHP0lH{0Hp0裛fIf 2fAGtEgHsHDH{PHHAGJ89R()HHHDHAtafDff.ff.ff.ff.ff.E@$LHHDA$H‹BIHLƋBEH8D9rE@(D)AV<ARA9FSJAFM^fA~H@MA~SfA:A<<4AB )A~Av,H5CRH{0LL褰LHILAMfDR$HHLCfDEFeX1LLL}LfDEFoX1HH}H&fR$HHHfDAbX \XDLHH[A\A]A^A_]n(fDAmX \XDLDI9s DADII9s DAD8LEfDL 0%@HHNXHAgX'nEgDM@A}gX \XDLfAiDhDLpAJMF MF}fDD`DLxQ@fA:|A<]kAFIv!pIv dAF(HtVAgXLXDL4ff.UHAWAVAUATSHH(HHDLhLopPfDP&(HC00LhfA}IH AEME ff.LeX1LzHC0LHp0>HC0LLHP0afA}AEIH H<xAEME tME9kXL1\zWD`,DLh AU">E1fDHC0Hp0舕HAĄHH1HLHHHsMjLkpAB<<6ARAM|ABH@M\L[pA<?<A u >AHHLAH(D[A\A]A^A_]@@tD`,H{HD@(HLCPH׋J89R()HHL HЀtR<Dff.ff.ff.ff.I$HHLH‹BIHH NjBDI8D9rNjI(D)#EELR/AE5aRA9uS<KAEMMfA}H@M<7A}<fA?A<<AG A}Au,H5dRH{0L̩LHIAM5DL 0$@EEeX1LL9wO@R$HHLHfDEEoX1LwHC0LLHP0*^H{0Hp0RDAABtEJ,LCHDL[PHIAB(J89PR$HHLD2AtKfDff.ff.ff.Ev$LHLD0AtH‹BIHM4BE~8D9rEv(D)IUAELDfDA}gX \XDLH(H[A\A]A^A_] fDAbX \XDLDAmX \XDLDI9s DI<EELRHHNXHAgX A"A}gXDLH߹ \XAfAUdfDI9s D0A(DID`DLhAUEJ,DMZ AAgXNXLH(AACtASLKHLSPHI ACDA8D9I(D)HHLD)AHAtXff.ff.ff.ff.ff.E[$LHLD(AupHAAHHMAEk8D9rE[(D)fDR()HHL@ME'I$HHL.fDID9s DD(AIfDASM[A ffA?A<AIUAELD DHDLXALCHHHKPIfDAbX \XDLfAmX \XDLf.I9s DtEIkDHC0Hp0AgXHHHNXHA+A%" A}gX \XLH AD`DLHAAq,MQ AfR$HHL,fDMAI9s D0ACIDACtAsLKHLSPHIACz89R$HHLD*HAtKE[$LHLD(Au0H‹BHHMBEk8D9rE[(D)I9s D(A`FIHp0gfA}AE<f.AsM[AR()HHLA;AAIq!Iq AA(HtpLPAH{HKHSPLNjAEH8D9AH$HHHH H4AK~89srv$HHHoLo@BHC0HP0YH{0AHp0׃=ApLXAMHv()HHHAH(D)HHHTAgXLXDLff.UHAWAVAUATSHH(HHDLHLOpP^DPHC00HhfA9HH AAMA 4ff.L9kX1LgHC0Hp0uHC0HLHP0+N+HNHq1H߀!"H!"HHLHDMiLkpAA<<uDAQDMAAH@I|H{p<<DDIGH@L LKpA<><DEƉHLLxLALLwg1DHHIIH@H @HHHeIHHLuUGff.ff.ff.ff.ff.IHI9Ao$IT$HPAT$tA4$@@@t@t @ t@ uIT$H@D`,DLH A"A}gX \XDLH(H[A\A]A^A_]MD@tD`,H{HD@(HLCPH׋J89R()HHL HЀtJLff.ff.ff.I$HHLH‹BIHH NjBDI8D9rNjI(D)2EALff.ff.ff.I$HHHuCH‹BIHI BDI8D9rˋI(D)R$HHHxfDI9s tD8LE@D`DLh@LHDUMZHAUATSL_pAB<th<tTDDLABH@M$LgpA$<<D>[A\A]]fDAR,Ir DABtAR,H_HHwPHH AB(DI8D9I(D)HHHD!AAt_:ff.ff.ff.ff.ff.Ed$$LHHD AHAAHHL$ËAEl$8D9rEd$(D)AD$tED$L_HDLWPHI AD$DI8D9I(D)HHLAHȀt9fff.ff.[$HHLHAAIHIËADc8D9rƋ[(D)fD[LA\A]]f.ED$DMd$f.I$HHL@fDI$HHHGfDID9s DtED8LEfHD9s DD At+8HEJD@DL`a@PHpfDLHUHAWAAVMAUIATISHHHh upXLUHt \XLSufXLSLXLDƅHsmallintH9w LA}M H8E D`L%RLTHLףoXHIH1 SLƅzSHE1fDAHx,THuHH8 DxL=~ReXLR[XLR HhA}ƅƅAML  E}L=RLLSLHLLLLfA} AuH5ȕRHh1 8E}Ah \XLQH4nXQH_XQa HIH5RHгH{0L$I诳LLRI0LH聰5RIHxAGJf%f fAGJAoEAG`IEIGpAEAU } g AuIx5RIH{0AHf%f fA<I莱H8 HpIGfIXL3PKAXLPHIIHM5WRHELPILH5$RI0AG2H{0Hf%f fAG2SIH訰H8 HpI`d@"@LHƃ"sHI{HLcL8O1HH([A\A]A^A_]LXLNH^XNAE<t<AE HIH5RHݰH{0L1I輰LL OI0LH莭5RIH腰AGJf%f fAGJA} EeL%RLNI`LH6AuA}tAt$ HҽIH5RAL$HίH{0L"AL$AT$I譯E LA`LMI0LHpHHDžHDžHDžHDžxM4?5ARML0AFf%f fAFAoEA$IEID$AEa AE< < HAuLs5ɐRLML豮AD$H{0Hf%f fAD$}HL<H8 HpHLDAEHߍpIHAE5#RLHH{0EeAXa}IDEuIG0EKvI|0LHHH9oHJHHJ8uHuŃfHH?XL KS:JXLJ>,L@8ItILLI݉IHHA܃I?HHDH@I<违,LB@LHuLLLA>LHHkLtHHNXHAgX1@tt5$fbBBAMtЀu IEHtvA}AEfff.UHH IA(AoAHEIA8LM)EE@UHSHHLHMYL_pAA<<t.AQt51"H]fAq,MY AuHAsHtHHPHSXHH@@HH]fAAtAq,LCHLSPHIAA(J89R()HHL HЀt-Dff.I$HHLucH‹BHHI BDY8D9rˋI(D)HH]AdXɹ \XLCR$HHLifDI9s t/tIwf.AdpLXAGf.LHUHSIYH_pAA<tm<t9AQt uLFtzM$HH[A\A]A^A_]3@t/@tA@t@t @ HSH&D@ DI$HLNXA$HAgX[IA\A]A^A_]@ CfgH#/ f.*CFgHo#/ f..C&gHW#/@ -\ff.HHHp@H@HƋ"t(BLJ"H@HHHfDUHSHHLHMYL_pAA<<t.AQt51"H]fAq,MY AuAsH}uHHHAgXH]NXIAAtAq,LCHLSPHIAA(J89R()HHL HЀt=f.ff.ff.I$HHLucH‹BHHI BDY8D9rˋI(D)HH]AdXɹ \XLR$HHLYfDI9s t/tIwf.AdpLXAGf.UHAWAVAUATSHH"LHMaLcpAA<t<tAQtAD$LAH5)qR11IAD$IDpH@M|LmH^ /H}IGD1H@fAw1AMt5pRL-H /HIFDHfANH@It蛸LHH[A\A]A^A_]H8HHPHSXH€f1"uAbX \XLHH[A\A]A^A_]AAtAq,H{HLCPHHAA(J89R$HHLDHAt8fff.ff.ER$LHLDAuXH‹BHHLNjBEZ8D9rER(D)HHAgXNXII9s DAt]t@IAq,Ma A$R()HHL@A$UfDpL`A$8 CaH/f. CfaH/mf.UHAWAVAUATISHHHE$LGMD$pG<<E$DMNjGDH@Ifff.ff.E[$LHLDAH‹BHHLNjBEk8D9rE[(D)DAADH@I HKp<Y<uQAH@L,LkpAE<< DAUtAEDALHǃ"踈IHAE5:?RIDhH@Mfff.ff.EI$LHLDAH‹BIHL NjBEQ8D9rEI(D)"!H1[A\A]A^A_]f.I9s DAt%8LE?HH@HLhfDEeDMm,@AEtEeHsHDH{PHHAEJ89R()HHHDA.@ff.E@$LHHDAH‹BIHLƋBEP8D9rE@(D)AtQHsHDAHH{PHDP8E9@(E)LHHDAAtH/fDff.ff.ff.ER$LHHDADP@ALONEZ8D9rER(D)@R$HHLrfD2C&/H.AbX \XDL@$LHH&R$HHHl2C.Hg.)f.I9s DAD8LEfDD9s DDAPfI9s DAtlDtTI MHоEeDMmAUD`DLh[AUD`DLhAUHйHйIfDUHAWAVAUATSHH(HHLNLOpF<;<AM̋"5:RLu1ɺLWH.HHEED$DHߺfUALǂIH@AD$AFIFE|$EttDHTRI4fDHIH9tSAo$IT$HPAT$"8uPuăDhHIfPH9uff.AG58RH@EgM,LVH.HIEfAEDH@I<4VAGHH@I4HC0LHH([A\A]A^A_]DDn,"DLf ZHH1uH|HCp"DPHRH DHKp<<uQAH@L$LcpA$<<LDǃ"57RLu1ɺLjUH{.H(HEED$LDHfuA葀IH AD$AFIFE|$EtnDHTRI4 HIH9tSAo$IT$HPAT$ 8uPuăDhHIfPH9uff.AG56RH@EgM,LxTH.HLIEDfAMH@I<TAGHH@I4~HHHHAgXNXIH([A\A]A^A_]fA $tt t IT$HAFtDn,LSHDLCPHI‹F(J89R()HHLDMHAt-fE[$LHLDAH‹BIHM‹BEc8D9rE[(D)1R$HHLkfDA $tt t fIT$HI9s DAD8LEfDFH@ML[pA<<DH(LH[A\A]A^A_]-}D :f.9f "fDhDL`@ACtA{LCHLKPHIACr89 R()HHLDHAt*)fDER$LHLDAH‹BHHMBEZ8D9rER(D)AD$tEl$LCHDH{PHIAD$J89R()HHH HЀtEff.ff.ff.I$HHHH‹BIHI BDI8D9rNjI(D)AtQH{HDAHHsPHDH8E9@(E)LHHDAAtH7fDff.ff.ff.E@$LHHDAD@@ALONEP8D9rE@(D)@`C$Ho.fR$HHL@$LHH@R$HHHqf.I9s DA8LEI9s D8LE+D9s DDAPf.`QC$Ho.f.A{M[.DEl$DMd$`C#H9.*C#H.xLXDhDL`SUHAUATISHHH腁tyHHPHCXДu֨tLH$HH6Hǃ"VHǃtH[A\A]]@LH͎!"DxIx,H=p.RYcXtZDLH,`1HHHƋ\hHHC001"[fY?X@HC001"Hǃ&D@I|$!OI|$ BAD$(H|3HHHHAgX[NXA\IA]]AHC0Hp0@" pXk ""-t{ƃ"DLHA@E,$ "u(AA|$DjXH=,R'EHC0ƃ"Hp0eA<$A|$H=,RDjX\@_fX> pXuAD$I|$ tI|$u AD$H|DjXdur@pX'6@)(W  "AD$I|$ 1I|$$AD$H|@)E,$DUHATSLHHMYL_pAA<<tpAQtw"@Lƃ"H IHYHHLL+H[A\]fAq,MY Au",[1A\]DAAtAq,LCHLSPHIAA(J89rxR()HHL HЀt1jff.ff.I$HHLu;H‹BHHI BDY8D9rˋI(D)R$HHL눐I9s tfIfD[1A\]@HHHAgX[NXA\I]aHA}gX[ \XA\L]D@A"pLXAf.UHAWAVAUATISHLHMiLopAA<*<zAQtAEEu_)RA9Eu ALEyRHLLSHEC\/Aw;<HA$LLsSHRAA9ID$pA$PHRLMT$pA<uABtAJI|$HMD$PHHABr89R$HHLD HAt&lfEI$LHLDAuHH‹BHHL NjBEQ8D9rEI(D)AY,Mi AUyIA9$s A$DA}A$8LEfAJA$MRR()HHL@1A$"H[A\A]A^A_]AAtAY,It$HI|$PHHAA(J89R()HHHDHAt`Dff.ff.ff.ff.ff.E@$LHHDADH‹BHHLƋBEP8D9rE@(D)I$HA$IAgXNXHL[A\A]A^A_]餍@HA$LPL@R$HHHAUI}`fA}t Ѓ<VwH5k%RI|$0HtI$hM$HAE0MU0< <=A$AU0MՀtAEEu5IA9$s A$DAaA$DIfEI\$hA$;CDs=HUϹHLHCDu%ExAbX \XLaA$HھLA=nIHf`C5$RIƍXH@M|LBH;.H6IGA$fAGH@I|,BAFLH@ItlL}I$HFtfAMM$HAUuXA$LhAU\CfI$hH蠸AE,A$I} f?t Ѓ<oAEtAM,MD$HMT$PHIAE(r89R$HHLDHAt2Xff.ff.$HHLDAu(H‹BHHI f:)RA9F*;s{H=R.DLIhH(HDž,LDIHɋtFmXHωDL虽LD݃,ƅLLHD@ff.fA>A>AFHL@I<<AA$ LH0I<0<AfA>yRA9FiyDGtW,MEHM]PHI G(q89II()HHLD!A>f.ff.ff.[$HHLD AHAHHIADc8D9rŋ[(D)EGtDMEHDMMPHI Gq89I()HHLD!AJf.ff.ff.ff.E[$LHLD AjHAIHMAEc8D9rE[(D)뿋I$HHLA;DAC9hAmX \XHHL[A\A]A^A_]eI$HHLAFtEVI}HDMEPHH AFq89^I()HHLD A$DEI$LHLDAHAIHL NjAEa8D9rEI(D)뿋QA9FA>vA"ASYX \XDLDA|$H }QAD$kXHHHH袹 HGdX艹u&fA|$t A|$ZQA9D$,zHbXNufA|$o 'QA9D$,GHnhXufA|$QA9D$,HgXu"fA|$tA|$uXQA9D$,HcX豸u2fA|$A|$uAD$,9}Q9QQHjXju A|$HeXIfA|$OA|$CHZnXu9fA|$AD$1<A<$=AD$HQHHiXɷfA|$AD$<AD$xIt$(I|$ aHHA|$[A|$,H=QQpDAD$tAt$MEHMMPHIAD$z89R$HHLDA ;ff.ff.I$HHLDA%H‹BHHI BDQ8D9rŋI(D)DAFtA^IuHI}PHHAFJ89~R$HHHDA1 Efff.ff.ff.E@$LHHDAu0H‹BHHLƋBEH8D9rE@(D)IA9s ADA A8LEd@IA9s ADAAIwHA9s AD AA8HEAD$AMd$A$(A^AMvR()HHLR()HHH{IA9s AD A E8LEDEL_ACpX&pXHHELL;q {H=QL=LHI$ A!"DMߐfA?A?AGHPLH<<AAf=g;bfl5rQ9s]LI߉A?AGLHuoH<a<AEDHLHH³I$HHHóHH9{H;LHuI<<EfA?uQA9G+I$hAf= `QA9GA?L I$LHp,I<<AfA?QA9GDGtwMUHM]PHI‹GJ89R$HHL@ff.ff.ff.$HHLH‹BHHI<‹BDG8D9rNj(D)AGtEwIuHDI}PHHAGJ89[R$HHHDA]Dff.ff.ff.E@$LHHDAuhH‹BIHLƋBEH8D9rE@(D)HA9s AA8HEfDIA9s ADAE8LEJ@wAHDEwEM@R()HHLHй;R()HHHDAHйIfDpAHx.DDpELx@5&Q9s;UAlXDHL \XYf.ACtDsI}HDMEPHHNjCr89R$HHLD AEI$LHLDAH‹BIHL NjBEQ8D9rEI(D)HпiHоdDxELXHо{CH{ H{}CH|pCH{ H{{CH|nLHȾIHȾDPELpIGHHEIH9A HYHEHH8LH}Dz>XHHEHELhA< 0HHEL8IHtvII3HMLhfDLH@Hh8AuA KDžTWfA w$LsHh{  f{ HDž)pu ^${*HEH9EL`L3fAn HuHUfnHH03XLpfbf֍H)HLHDžHDH`HτHAL0r_HsHH`L.fo@T{ HEƅ)UULhDžXE1ƅ_ƅ^A< HH]I{ ?{HEH9E L`LS2A HufnHUfnHfbLpHDžH)HLHfօ03XHDH`Hτ2AHL3/r_Hst?H H`L,=@LP=LhA? uHH`L/.TH}HH9t{Cfo@HETƅ)e9tH{H`.HH(H0HDH`PHDH.AHĨD[A\A]A^A_]ÐAXtL8<AD uD9sD93]E1H{H`L,LmL;mu!IEHEAELmL;mA}[ufH}H<-Hr110 BHt<.uBHu|s$1LpqL @H}HUHEII)L)Hw>IGHHEIH9H.HEHHLH}DO8HHEHELhfDL`L.fAnHuHUfnHH03XLpfbf֍H)HLHDžHDx03X1 LpXLHp@._ X HxH(HxHpH@H HP0迎<f.ƅ^LhAH`L![@##MfDLp5QL3fDL8AGHWSHHEHHIWHHHxH(tHxƅp\HxH(JHxHx贜HxHx褜Hx蘜ƅp  HxH(HxHxXHxVƅpf.HHEHHIWHHHxH(HxHx.Hx1frZH`ƅpƅ;HhD{L zDcL%QLHLDLLLpAptuCf H`1H1AHh葐H2H`A$;XIXHދEA H`HHAgXNX\EAHxH(HHxHpHx^HxHx螚$!H[HH H`VXHA^XDA]H`AgXNXf~HHDA3CpHSLc{L`L)AHufnHUfnHfbLpHDžH)HLHfօ03XHDnLSLc p<G<<<< P< BHxH(0HxHpH@H HP0HxHxHxƅpH`L6P,H`Lp56QLZHKCSLdH`A^XIXHދBAs ]HxH(KHxHxTHx2ƅp#HxH(HxH(HxHpHxHxH(HxHx谗HxHx蠗Hx蔗ƅpHxH(sHxHxHxZ1frI RX;X1Va,f.UHAWAVAUATSHH(HHDLWLSpG<<tFDDMfA}tQA}tJ"1H([A\A]A^A_]f.w,Lo fA}uff.GH@M4LspA<<]DA"uA4nX \XDLJf.DGtw,LCHLKPHIG(DZ8D9J(D)HHLDMHAt\cff.ff.ff.ff.ff.E[$LHLDA HAHHMAEk8D9rE[(D)HEHE1fE1A}cHhEHE<A}INAMH ;QHHUEMLLtAFtEfHsHDH{PHHAFJ89R()HHHDHAtI@@ff.ff.ff.E@$LHHDAH‹BIHLƋBEH8D9rE@(D)J$HHLfDAmX \XLH(H[A\A]A^A_]J>f.AEAEIM IMAEHLDR$HHHfDI9s DAtm8LEbI9s DAteDtGIEfDMvApLhfDAmD`DLpANUHAWAVAUATSHHHHDLOLKpG<<tCDDMfA?tOA?tI"L1HĨ[A\A]A^A_]w,L fA?uff.GH@IfAx4QA9@,ƅ&QA9@,ƅ DxEL`IHbsHHǃ uHHǃ1LHbXrLzHgXLrLAxsAdXDLLVX:JHMLXDLHAXX A@,;Qƅ<SA@,HHH<Ax,HLHHHqrHLH<?Ax,H=@QLH5rHLHL8LHAx_Ax,H=Q <AAx,H=ƴQLHqHLH*IH ZnXLHHpHLcHA@Ix!HIx HqA@(HDH\AHuJIH A@tRIp(Ix AxAx,H=سQ MHAp Ix!Ap Ix!Ap Ix!"A@Ix!Ix A@(H|A@Ix!Ix  A@(H|IH A@(Ap,H|rA@Ix!@Ix 4A@(H|&IH A@(Ap,H|uIH A@(Ap,H|A@HDzQHUHAWAVAUATSHHG0Lh0MƇ"HIt}HLLI|$0I*[ ML-?XHhHH L1oLnƃ"H[A\A]A^A_]fDLH~0LZ L+KXLHhHH 1hoƃ"HLZLI|$0IeZ ML?XHhHH 6UHAVIAUATSFWIHE10@<< AHfnE;eDCK<iX< w HWDW1m<{u<ushX1H5QXm<us1@WAAAAAm;4SsCHQSX1l @CHsmX1lFfDC4nXcXHEA"[>VX1A\A]@A^]@|l@GX1llsZX1JlfUHAWAVAUIATSHHW0Hc0HiL4Hhf "L MLA$A|$hAD$|HQ8$t~I\$HurH[ HtbH{hu1LamE11LADžxHL_A"tLLpXkH[ HuMd$MHfA "H[A\A]A^A_]L llAT$jID$q.ID$p AT$xHDfUHAWAVIAUIATSH(IPHwH@H@(A "A "L MYILEHEE1DMljfff.t$t2;r|uBi9tRHRHt%u9r|uBi9t3@t.HRHuA "DA "H([A\A]A^A_]HZHHU@}ƉuMfDH[ HH{huH}Ⱥ1lkADžxEfH$E11LLRoXjL{xMA? tD pX14iE11LLLAG H@Mt.>t)1"[A\A]A^]ÐA@,Mh LcpAxDQxW9FDDHHCHMDHЋH1"?H[A\A]A^]fw,LO fA9uȐff.GH@M,LkpAE<l<DA9#AyH=QLuL$K HhLeHALDHH~H[A\A]A^]ÐDGtw,LCHLKPHIG(J89R()HHLDAtUDff.ff.ff.ff.E[$LHLDA\H‹BHHMBEk8D9rE[(D)AAIy IyAAH|DAEtEeHsHDH{PHHAEJ89R()HHHDHAtYfff.ff.ff.ff.E@$LHHDAH‹BIHLƋBEP8D9rE@(D)R$HHLafDR$HHHBfDI9s DA8LEI9s DAD8LE9fDEeDMm@HHAmX[ \XA\LA]A^],@HHHAgXNXH[A\A]A^]ÐpLHCfDD`DLh@MHDH8t Q9Ht UHAVLpAUAATISHL6Pt\[DPAvH5QI|$0芌HHPHRHH[A\A]A^]fD@tH,I|$Hʋ@(HMD$PH׋r89R()HHLD HAt`Dff.ff.ff.ff.ff.EI$LHLDAH‹BHHL NjBEQ8D9rEI(D)AFIv IvAFHtDP,Lp AfR$HHL fDIA9$s A$DAtQA$t2IJf[DLLAgXA\LXA]A^]APA$LpAUHAWAVIAUATSHHHHDLVLWpF<<DVDLH}tG}FH@ML jE~L=QMLLULLUMHLMLELL{}t }fA}>I$hE}譵HID9 AGHt@H7KIHHDx H@DHTRH4+ff.ff.HIH9tsAoEIUHPAUtAMtt t ufff.IUHHIH9uf.D1LL%PIfxLhnID$0Hp0=eII$hˋpHP?HID$0Hp0eIL@襱HHLH([A\A]A^A_]Dh,DLp AE1A$"WH([A\A]A^A_]@tDh,I|$HD@(HMD$PH׋J89R()HHL HЀtLff.ff.ff.ff.I$HHLusH‹BIHH NjBDI8D9rˋI(D)R$HHLjfDA$AbX \XLH(L[A\A]A^A_] @IA9$s A$E$I@AbX \XDif RfA$AgXNXI$H>NQA9EMuADHGEgfDDhE$LpA AF#IVM~fDQA9EAEHD@I|? HA$AbXHL \X}Y5^Q9p,Lh0zAFf &A$A^XLL繡IX#AVM~ A$AWAXA$1LLA$IXLHA^XIvAFAVL|lID$0Hp0aA$AgXLI$HNXvR&fD1fUHAWAVAUATISHHHLV LWpF<<D DVLHtXYFH@I IL$p<l<D HE$t AH@HI\$p<<q A$f;t<HDLmH9HfD5Q11HPZH8.HHXE$HPfRHDLFY<"I$LADŽ$"<<{H=QHP[0 I$hHPHfoPfofsffH~HI$PLxxfHIE$HDLoXfAQA9G,AG4HD@IL9 E$fDDn,DH~ tfD FtDn,I|$HDMD$PHHNjF(J89R()HHLDAWff.ff.ff.ff.ff.E[$LHLDAH‹BIHLNjBA[89rE[()DGA$"O1H[A\A]A^A_]fD AtDqI|$HDMD$PHHNjAr89R()HHLDAGff.ff.ff.ER$LHLDA4H‹BIHLNjBEZ8D9rER(D)H@A$"HALX \XDBR$HHL!fDR$HHLfDALX \XDHHL[A\A]A^A_]fDCA$H[ fDCH{ iH{]CH|P5Q9HfH1DLI$PHPL0Hx0, HP@HPLH肞LHLE$ 2I$PLxxD CvH3.f.HA9$s A$DAE$ZHfHA9$s A$DAE$Hf.0p  H8H(H8HpH@H HP0/H8Hx/>H8#>fDCt C It$HI|$PHHƋCJ89CR$HHHDAjLDff.ff.ff.ff.E@$LHHDAuXH‹B HLƋBEP8D9rE@(D)@DqE$HAHfHA9$s A$DA A$8HEAZX \XA$" H)3R()HHH@H><AWAXDhE$HxHH8H(f H8H(pH8HxVH8;OD<t`LL爍 v H8H(H8Hxx;H8Hxh;H8\;L爍  f.DpE$H@HLHйX A$HXH8H(^H8HxH8:=HHоH8H(H8H LxHx' H L3Hй4UHSHH!" h!"H]ff.UHAWIAVAUATSHHHHDLpLwpPYDPtAF A^9~}QLA~A>A^H|QH9Hƹ]pXH߉t:A>A^H|QH9HƹoXH詉!fA~IvA~^AFH@L$A<$AdX \XDLHHL[A\A]A^A_]XDh,DLp A1A"pHH[A\A]A^A_]Ð@tDh,IHD@(HMGPH׋J89R()HHL HЀtNDff.ff.ff.ff.I$HHLu[H‹BIHH NjBDI8D9rˋI(D)R$HHLhfDAmX \XDDIA9s AEwIAVMVMԀuAF,AMf A$aAt$H5ezQI0LUhLUAgXLXHAFH@M4A~@EAAH}sIh}DuL uH5yQHHu6HuHE1LEDLHm}IW0MLE1E1Hc0HiH<HH[A\A]A^A_]fDAbX \XDL,f.AFS+IVAFAvH\dDDHuLA9XIXFHH[A\A]A^A_]EEHMUHtAFH@L$A<$jA~Av,H5xQI0fMd$A>DeEvL5rxQLr5HƹoXL}t!EE/DAAD$EAD@DhELpAAvI^ !fUHu DAFtAN,IHMGPHHAF(r89qR()HHLD MHAtLff.ff.ff.EI$LHLDATH‹BHHL NjBEa8D9rEI(D)AD$It$ It$AD$Ht|fAFIvI^#fDAFIvMv'fDAFIv!Iv AF(HtDAAX \XDL f.R$HHLAvI^ IvI^BHUHu,AvI IA9s ADAtLAtI;A$1IVAFAvH\IVAFAvLtPAL`A$@ff.UHAWIAVAUATSHHHHDLpLwpPYDPtAF A^9nuQ<A~A>A^HtQH1Hƹ]pXHρt:A>A^HtQH1HƹoXH虁fA~IvA~NAFH@L$A<$AdX \XDLHHL[A\A]A^A_]HDh,DLp A1A"xHH[A\A]A^A_]Ð@tDh,IHD@(HMGPH׋J89R()HHL HЀt>ff.ff.ff.I$HHLu[H‹BIHH NjBDI8D9rˋI(D)R$HHLxfDAmX \XDDIA9s AEIAVMVMԀuAF,AMf A$aAt$H5erQI0LU`LUAgXLXHAFH@M4A~PEAAH}sIh}DuL uH5qQHHu.HuHE1LEDLHe}Mg0MLAE1Ic$0HiII<$I4$ /HH[A\A]A^A_]@AbX \XDL$fAFSIVAFAvH\dDDHuLA9XIX6HH[A\A]A^A_]EEHMUHtAFH@L$A<$jA~Av,H5pQI0^Md$A>DeEvL5bpQLb-HƹoXLm}t!EEDAAD$EAD@DhELpAAvI^ !fUHuDAFtAN,IHMGPHHAF(r89aR()HHLD MHAt<fff.ff.EI$LHLDATH‹BHHL NjBEa8D9rEI(D)AD$It$ It$AD$Ht|fAFIvI^3fDAFIvMv7fDAFIv!Iv AF(HtDAAX \XDLf.R$HHLAvI^ IvI^RHUHu,AvI IA9s ADAtLAtI;A$1IVAFAvH\IVAFAvLt(PAL`A$@ff.UHAWIAVAUATSHHHHDLpLwpPYDPtAF A^9nmQ<A~A>A^HlQH)Hƹ]pXHyt:A>A^HlQH)HƹoXHyfA~IvA~NAFH@L$A<$AdX \XDLHHL[A\A]A^A_]HDh,DLp A1A"xHH[A\A]A^A_]Ð@tDh,IHD@(HMGPH׋J89R()HHL HЀt>ff.ff.ff.I$HHLu[H‹BIHH NjBDI8D9rˋI(D)R$HHLxfDAmX \XDDIA9s AEIAVMVMԀuAF,AMf A$aAt$H5ejQI0LUXLUAgXLXHAFH@M4A~PEAAH}sIh}DuL uH5iQHHu&HuHE1LEDLH]}Mg0MLE1AIc$0HiII<$莻I4$ 'HH[A\A]A^A_]@AbX \XDL$fAFSIVAFAvH\dDDHuLA9XIX6HH[A\A]A^A_]EEHMUHtAFH@L$A<$jA~Av,H5hQI0VMd$A>DeEvL5bhQLb%HƹoXLmut!EEDAAD$EAD@DhELpAAvI^ !fUHuDAFtAN,IHMGPHHAF(r89aR()HHLD MHAt<fff.ff.EI$LHLDATH‹BHHL NjBEa8D9rEI(D)AD$It$ It$AD$Ht|fAFIvI^3fDAFIvMv7fDAFIv!Iv AF(HtDAAX \XDLf.R$HHLAvI^ IvI^RHUHu,AvI IA9s ADAtLAtI;A$1IVAFAvH\IVAFAvLt(PAL`A$@ff.UHAWAVAUATSHHXHHDLhLopPeDfA}MmA<<HhƅA>ANL E~L=dQLL!LHE1LLL XtAFf 9fA}HCpDPHRLANL E~L=OQLL LHE1LLL)CtAFf YfA}HCpDPHRLIA<<E$ADArVXAXtt8uABt,AbX \XHLL[A\A]A^A_] f>DLPAEt A$"tHD[A\A]A^A_]ID$0M$PLh0MtOHI~0AƄ$"HVI$h+KXLHHH 1AƄ$"IFLHx(1҃IvxL聋O@;Q9FHHTHHDL͠AD:Q9FYLVPDABtAzMD$HML$PHIABJ89R$HHLDAT8ff.ff.ER$LHLDAuXH‹BHHMBEZ8D9rER(D)f>9Q9FHDIA9$s A$DA}A$t^IQfDAzA$MRA2R()HHL@L萘DAxA$LPAHй6UHAWAVAUATSHH(HHDLHLOpPaDPLMȀtAAHuDH٘AńLufA>A<<DHh1LrIHHHHC0Hp0Lu#"uEHHǃ"-DLH:uMwPIH_H{0Hp0B0D`,DLH A"E1H(D[A\A]A^A_]fD@tD`,H{HD@(HLCPH׋J89R()HHL HЀt:ff.ff.I$HHLH‹BIHH NjBDI8D9rNjI(D)R$HHLxfDAFMv:DID$ IGM;g I|$xVLL{IHID$Ht IT$ HP ID$ Ht IT$HPM;gu뙐I9s DI4fH(DHAbX[ \XA\LA]A^A_]ɛfDAFtANH{HLCPHHAFr89R$HHLD HAt=kf.ff.ff.EI$LHLDAu0H‹BHHL NjBEQ8D9rEI(D)I9s DA38LEt4QA9FBI9HhANEA>L EfL%L3QMLIMHE1LELL&}A^XLH߹IX;AAbD`DLHACR()HHLh@ID$IG Uf.AFtSt]IVMfCPLpAIHI8I0fAG0AVMf IvAFAVLdUHATSHH HHDLHLOpP~DPLMtyAAurHuDH#tlHC0Hp0? HuDH߹ H{0EHp0( EH [A\]D`,DLH Au"H 1[A\]@tD`,H{HD@(HLCPH׋J89R()HHL HЀtI$HHLukH‹BIHH NjBDI8D9rˋI(D)H DHAbX[ \XA\L]鯗R$HHLpfDI9s t'Dt IVALD`DLHA-UHAWIAVAUAATSHH1HHh%HILHXHtHCHHx(0H[ HuMt$PIǰI$HL貈HHt"f.L(L萈HHuI|$8I|$0f1A$AD$0AD$I$Et A$H[A\A]A^A_]HC ID$I;\$ tUH{xoPHwLHHkHCHtHS HP HC HtHSHPI;\$tI;\$ uHCID$ AHHL[A^XA\IXA]A^A_]uDUHAWAVAUATSHHHHDLFLGpF<w<DVEMǀtAG FH@M4LspA<Z<RDAf=f.QA9FA?-QA9Gu AGHD@MAFueIvI~AGtEoHsHDH{PHHAGJ89R$HHHD HAt/]ff.E@$LHHDAu0H‹BIHLƋBEH8D9rE@(D)I9s DADvIƅ`K@AVMvAAF,Mf DEoDMA,AjX?XDLMEfL%<QLt A>|AE0M}0<<DA}YA}H=QH}H}HƹoX'AdX \XIG0LDA?u2IGAG HABDXVX@ff.DLDD`,DLh AUR1"AHH[A\A]A^A_]f@tD`,H{HD@(HLCPH׋J89R()HHL HЀtRDff.ff.ff.ff.I$HHLWH‹BIHH NjBDI8D9rNjI(D)AAX \XDLHHH[A\A]A^A_]aR$HHL8fDAE,Mu D5@8p eH=EA>{AvH5QEHHuHuMHH{0E1LE }H{0 AoHp0)EIFfeHEIGE HULH߹SH{0EHp0 EI9s DaIfAbX \XDLf.AEcIUAEAuLtDDAEtAM,H{HLCPHHAE(r89YR$HHLD HAtM{@ff.ff.ff.ff.EI$LHLDAu0H‹BHHL NjBEQ8D9rEI(D)I9s DA8LEAUfDAEtqIuI}fAuI} fDAE2tAMDH{HLCPHHAE@r891R()HHLD HAtONf.ff.ff.ff.EI$LHLDAH‹BHHL NjBEQ8D9rEI(D)AmX \XDL;fD`DLhAUrAuMu fAEt_YIuMufAEDM}8)DR()HHL@R$HHLfDAuMu {f.IuMu-I9s DA8LEHp0, IXDLA^XH{-fDAFt3t{IVIvAjX?XPLpAVIv _IUAEAuH|*PLxIUAEAuLtqIvAFAVHt f.UHAWAVAAUIATISHHhf "L HHMAAhsAG|H9Q8$I_Huf.H[ HtuH{huEH1E11LADŽ$xHLA$"LpXH[ HuMM0fA$ "H[A\A]A^A_]LpXH1E11LADŽ$xHLHH{0H1hXLHHA$")L AWjIGqIGpyAWxHDkff.UHATSLeHHLHúLHXH[A\]ÐUHAWIHAVAUATSHXEAWEkE(KDmI HIH@ LhI_ D]MHuL4HMLEHULmMI <w$ŠW@I$HIL9uLmHUIDHX[A\A]A^A_]fDI$fDI$PfDI$pfDI$fDI${I$мkI$[JLHEH)HUHذIF0H`0HuRtkLEHMLHUHuft]EH}H@HI$I$I$0I$0Hu0W511HHLXL_pPtbt%Pt,1"WfDp,LX AuACUI{H]@tp,LOH@(HLWPIыJ89R()HHL AHЀt?}ff.ff.ff.I$HHLuCH‹BAHHI BDY8D9rʋI(D)fR$HHLvfDID9s Dt]t@IAgXLXLtAdX \XLtAtpLXAWf.UHAUATSLHDIXH_pA@<<t0DDIfA:tfu  Q9Ft2"u[ASYXA\ \XA]D]s Q9FHh[LA\A]]@DA@tAp,LWHL_PHIA@(J89IR()HHLD"AtKNDff.ff.ff.Ed$$LHLD A+H‹BHHM$‹BEl$8D9rEd$(D)FtDNLWHDL_PHI‹FJ89R()HHLHЀtBff.ff.ff.v$HHLH‹BIHI4‹B^89rɋv()fR$HHLfD>F?R$HHLHfDI9s D A8LE4H9s twD8HEn@FmDNDHvF@[A\AmXA] \XL]qDpLPfDDHDHp@IHfff.UHAUATSLHDIXH_pA@<<t0DDIfA:ttfu  Q9Ft2"u[ASYXA\ \XA]D]o Q9FHh[LA\A]]鼛@DA@tAp,LWHL_PHIA@(J899R()HHLD"At;>ff.ff.Ed$$LHLD A+H‹BHHM$‹BEl$8D9rEd$(D)FtDNLWHDL_PHI‹FJ89R()HHLHЀtBff.ff.ff.v$HHLH‹BIHI4‹B^89rɋv()fR$HHLfD>,F"OR$HHLHfDI9s D A8LEDH9s twD8HE~@F}DNDHvV@[A\AmXA] \XL]]mDpLPfDDHDHp@IHfff.UHAWIAVAUATSHHHEL_M_pG<<tsEDMfA<$ttA<$AD$tzGH@II_p<<`EA"W1w,ALg fA<$uOQA9D$tA<$A"uAlX \XLHĈL[A\A]A^A_]kDDGtw,MGHI_PHIG(J89R()HHHD*MHAt8ff.Ed$$LHHD(AH‹BHHM$BEl$8D9rEd$(D)R$HHHqfDDsEH[A4nX \XDHf.IA9s AD(AA8LE@CtDsIwHDIPHHƋCJ89}R$HHHDHAt9gfDff.ff.E@$LHHDAu0H‹BIHLƋBEX8D9rE@(D)HA9s ADAEeHODHpL8DhL-mQIG0LHhHDžhH`0LHE1Lf8HVQ9BuoHpHHXoHhHXHDD <v$HWHAIID$HHAf8HtHI)LLHLHLHLDHEL(KHĈ[A\A]A^A_]fDHAIfAD$jDHAIAD$SfDHAIAD$;fDpAL`ODR()HHH|@fIZAAD$L0Wk1<@PLh  Lh@MlD>X1HXHXDpEHXE1}fUHAWAVAUATSHH8HHDLWLSpG<<t>DDMfA9tBA9t<"/1H8[A\A]A^A_]fDw,LO fA9u@GH@IuPA9F"AaX \XLyfAA@tEXLSHDLcPHIA@J89R$HHLD*At/ @ff.Em$LHLD(Au0H‹BIHM,‹BEu8D9rEm(D)I9s D(A D8LEUfDApLHAf.ACtASLcHLkPHI ACDA8D9I(D)HHLD9AMHAtUfff.ff.ff.ff.Ev$LHLD8Au`HAAHHM4ċAE~8D9rEv(D)fDR()HHLA@I$HHL>fDID9s DD8A 8LEtDASMs\DMHDACH@MLLP}DLAL0MX@<DA TLHp=I<?<DfA?PA9GL@\LL I<vDACtAsLKHLSPHI ACy89I$HHLD1HAt:aff.ff.R$HHLD0Au)HAHHIADB8D9rɋR(D)ĐI9s D0AIAGtEgH{HDLKPHH AGq89I$HHLDHAtNufDff.ff.ff.ff.R$HHLDAu)HAIHHNjADB8D9rɋR(D)ĐI9s DAD8LEfDEsL5PiXLТTmXL転Q iXL覢t]QfXL蕢6HcLD@L7EgDMLACM[A HcLD@LI()HHLqI()HHLqDLL0A?5EoL-PiXLA͡TmXLA 財 iXLA藡fQfXLA|KJfXLAa0CfXLAFkXLA+giXLA fXLAfXLAڠfXLA迠 lXLA褠twoXLA荠t`hXLAvtIfnXLA_t2?mXLAHt>mXLA1Lk0HcH@CHHHHgZH8LgZEgIIGfhZEtHhZDHuHIH0H@LHHDHjZHǀXjZEPLphMHIAGtAL[HLcPHI AGDA8D9eI$HHLD)AHAtKsfff.ff.ff.ff.Em$LHLD(Au*HAAHHM,ËAE}8D9rEm(D)ID9s DD(A8LEMA HcLD @L D`DLx$HLXA AMABIr H@CIrH@0ABHDH@I(D)HHLAGMo MoAGMlL0A@AgXLXxLx9JfXLJuHcLD@LCfXLuHcLD@LkXLuHcLD@LgiXLɜ_fXL贜u1HcLD@LZL=X1E1VfXLruHcLD@LfXLGuHcLD@L lXLuHcLD@L+fXLuHcLD@LfXLƛuHcLD@LliXL蛛uHcLD@LATiXLpuHcLD@LoXLEuHcLD@LhXLuHcLD@LfnXLuHcLD@L?mXLĚuHcLD@Lj>mXL虚UHcLD@L;UHATSIĸDL˜LH谚H[A\]雜ff.UHAWIAVAUATSHfA8pH(EE1MH HD<PA9GAI@OHPLHHtsD`H1PDbiXH@IHHLNOA<$-A|$H@z@@@Mz,HHHǾiXH0EtdTmXLט tL@H0x z,HHHǾTmXH0蚘5 ff.LHpB-yIH <J<BDIfA?SDmXL¸tmXL qD@tpLSHLKPHI ‹By89I$HHLDHAtFR$HHLDAu)HAHHI‹ADB8D9rɋR(D)ĐH9s DA1 H€@9X61AGtEwHsHDH{PHHAGJ89R$HHHD HAt7e@ff.ff.E@$LHHDAu0H‹BIHLƋBEH8D9rE@(D)I9s DAAD8LEfD@HR EwDM@I()HHL%@R()HHH@BHz!Hz B(H|  iXLs@H0Vz,HHHǾ iXH02EQfXL@H0"z,HHHǾQfXH0ՑIFJfXL蹑*@H0Bz,HHHǾJfXH0xMCfXL\@H0z,HHHǾCfXH0QkXLp@H0z,HHHǾkXH0辐]/+fXL袐@H0z,HHHǾ+fXH0aUiXLE@H0rz,HHHǾiXH0eugiXL Y@H0z,HHHǾgiXH0觏5fXL苏@H0fz,HHHǾfXH0J9fXL.@H0z,HHHǾfXH0=^fXLюB@H0'z,HHHǾfXH0萎A lXLtH0@z,HHHǾ lXH03afXL@H0z,HHHǾfXH0֍9GTiXL躍+@H0z,HHHǾTiXH0yioXL]H0@z,HHHǾoXH0mhXLH0j@z,HHHǾhXH0迌q0fnXL裌H0 @z,HHHǾfnXH0bu?mXLFH0@z,HHHǾ?mXH0 y}>mXLH0@Mz,HHHǾ>mXH0趋}'tmXL蚋 @H0z,HHHHǾtmX]¸E!@BHz!Hz yB(H|lPHP rDpDLx@LL ]rLYH|IH|L)H)Dу1AJK9rL(L EXfHcI-L(A@L PM$ Hi -L ]rL ]rA@@>DAD ]rWtftHBHz!Hz B(H|BHz!Hz B(H|DD ]rttHcf~-L PHi O~-L ]rH ]rA@BHz!Hz B(H|BHz!Hz B(H|BHz!#Hz B(H| BHz!WHz KB(H|>BHz!9Hz -B(H| BHz!Hz B(H|BHz!'Hz B(H|BHz!Hz B(H|BHz!Hz B(H|~BHz!Hz B(H|BHz!Hz B(H|rBHz!Hz B(H|BHz!tHz hB(H|[BHz!Hz B(H|BHz!hHz \B(H|OBHz!Hz B(H|BHz!\Hz PB(H|CBHz!Hz B(H|ff.UHAWMAVIHAUATESHH HH8誈H(HE1fA?tdD<(<EA0@LHpIA<<EfA?ufPA9GuZA@HPLIMr<zLHp[f8Iu7PE1A9GtfA]H}iXLc%H KH Et$ID@HHHLgZ EAIcH8D5@vKIHHgZH(gZHgZHǀgZfhZtHhZHu袄KH]H8LIHDHjZHXjZHHHH0oH[A\A]A^A_]AGtEgMNHDMFPHI4AG~89v$HHLDHAt>eff.ff.ff.@$HHLDAu)HƋFVIHIH89rˋ@()@IA9s ADAE8LE@HPAXiXL0HH@HAMHHLHpBD-LcHIfDA@tAxM^HMVPHI4A@DN8D9v$HHLAHt)R@ff.R$HHLu+HƋFAHHIËFJ89r̋R()DIE9s E9A0@IfDHPAXiXL0HH@H跁AMH= ;-L0TmXH舁Ƹ 9 LHpBD-uLcHIME1f.A@AM@A0SEgEMn@v(D)HHLqv()HHL@{9A@0< Ax,H@HǾiXL蜀ƸETmXH耀Ƹ 0L Ax,H@HǾTmXL>Ƹ5 iXH"Ƹ0L Ax,H@HǾ iXLƸEXQfXHƸ<0L Ax,H@HǾQfXLƸIJfXHfƸ0L Ax,H@HǾJfXL$ƸMCfXHƸ0L Ax,H@HǾCfXL~ƸQ>kXH~Ƹ"0L Ax,H@HǾkXLh~Ƹ]+fXHL~Ƹ0L Ax,H@HǾ+fXL ~ƸUiXH}Ƹf0LW Ax,H@HǾiXL}Ƹe$giXH}L 0 Ax,H@HǾgiXLU}Ƹ5fXH9}Ƹ0LAx,H@HǾfXL|Ƹ9ofXH|LY0!Ax,H@HǾfXL|Ƹ=fXH|Ƹ0L Ax,H@HǾfXLB|ƸA lXH&|LD 0 Ax,H@HǾ lXL{ƸacfXH{LƸ@0 Ax,H@HǾfXL{ƸYTiXHq{L/ 0A Ax,H@HǾTiXL6{ƸioXH{LƸ0 Ax,H@HǾoXLzƸmPhXHzLd 0, Ax,H@HǾhXLzƸqfnXHezL 0 Ax,H@HǾfnXL*zƸu?mXHzLL 0 Ax,H@HǾ?mXLyƸyK>mXHyLƸ(0 Ax,H@HǾ>mXLuyƸ}tmXHYyƸ0LM Ax,H@HHǾtmXyƸE!fH}TmXH0xH0TH} iXxH0H}QfXxH0dH}JfXxH0WH}CfXwxH0H}kXZxH0H}+fX=xH0H}iX xH0H}giXxH0lH}fXwH0H}fXwH0H}fXwH0H} lXwH0bH}fXrwH0 H}TiXUwH0H}oX8wH0H}hXwH0H}fnXvH0lH}?mXvH0?H}>mXvH0H}tmXvH0H}kXvH0A!LHpBD-E1`LcHI iXH3vƸQfXHvƸJfXHuƸsCfXHuƸWkXHuƸ;+fXHuƸiXHuƸgiXHouƸ fXHSuƸfXH7uƸfXHuƸ lXHtƸwfXHtƸ[TiXHtƸ?oXHtƸ#hXHtƸfnXHstƸ?mXHWtƸ>mXH;tƸtmXHtƸA@Ix!JIx >A@(H|0DA0pAL@A0D`ELx@AbfD5A 1GA@Ix! Ix A@(H|IA^MANA@Ix!Ix A@(H|H8IcſD5D1A HgZH(IGIOfhZEo-QAA@Ix!Ix A@(H|]AA@Ix!Ix A@(H|UAOeA?A@Ix!'Ix A@(H| }AA@Ix!JIx >A@(H|0A@Ix!2Ix &A@(H| A@Ix!Ix A@(H|A@Ix!Ix A@(H|aA>AA.=A9AA@Ix!Ix A@(H|0A@Ix!]Ix QA@(H|CA@Ix!Ix A@(H|A@Ix!EIx 9A@(H|+A@Ix!Ix A@(H|A@Ix!Ix A@(H|A@Ix!'Ix A@(H| yAuAqAmAiAsYAcA@Ix!zIx nA@(H|`A@Ix!Ix A@(H|PA@Ix!eIx YA@(H|KA@Ix!Ix A@(H|A@Ix!PIx DA@(H|6ff.UHAWAVAUATSHHHDH^H_pF<<t9DVEI܀t<"1He[A\A]A^A_]DDV,DLf A$uċFH@LLGpA< <DDDLf;;|"uAmX \XHfAdX \XDLHe[A\A]A^A_] @EFtDV,LGHDLOPHIF(J89R()HHLD*IHAtBff.ff.ff.Ed$$LHLD(Au_H‹BIHM$BEl$8D9rEd$(D)@R$HHLkfDApIXDI9s D(AyDWIA@H@M LOpA<\<DDLf>uP9FAaX \X"U@DA@tApLOHH_PHIA@J89R$HHHD*At0Dff.Em$LHHD(Au0H‹BHHM,BEu8D9rEm(D)H9s D(A8HE0A$fDDPDL`A$DAAtAQHwHLoPHH AADA8D9I(D)HHLD1AAtZ>ff.ff.ff.ff.ff.Ev$LHLD0Au`HAAHHL4ƋAE~8D9rEv(D)fDR()HHH@@I$HHL?fDHD9s DD0A8HE~DAQIqfDAAH@M LOpA<<DfA9t\A9"AmX \XDLpHX0PHpLHAD$A9WAAH!P;KH PHM\$AILhPHLLZYVAAtEYLoHDLwPHILAADA8D9XI$HHLD9AHAtU~ff.ff.ff.ff.ff.EI$LHLD8Au+HAAIHMLAEy8D9rEI(D)ID9s DD8AD8LEIt$pfHDž2H22fHp2L3HL2Ip)p2)2mNL2IrH2HH5L2MNI$HE$L2HrIt$pB<<{ E$DI2Mr$AL2L?ML2Mff.A}uXA5P3PI]fA8*_A@Ix pI<$AGAL$H@LM$A<,<M$AL$[DA\]D@tH,LKHʋ@(HLCPIыr89R()HHLDAtHff.ff.ff.ER$LHLDAH‹BHHMBEZ8D9rER(D)I|$H6HcI)\$ [AA\]DA@ fA8AACtAKLKHH{PHIACr89R()HHHDHAt:ff.ff.ER$LHHDAH‹BHHMBEZ8D9rER(D)AxH=}PE@R$HHL>fDR$HHH1fDIxA@H|~fDI9s DA8LEI9s DAt]t@IP,L@ Af.AKM[DAPL@A|fHLXfDIHPfff.H~UHIHAUATSf8tluw@tyPL@NHRIPtjA N<Z<;HL[A\A]N]DF}P9XttuE1[A\LA]]H,L@ 덐1D@tH,LgHʋ@(HL_PIDR8D9R$HHLD*AHAt8fDff.ff.E@$LHLD(Au0H‹BAHHMċBEh8D9rE@(D)fDID9s DD(AO8LEA N<CtKL_HLWPHIËCDJ8D9R$HHLD"AHAtHoff.ff.ff.ff.[$HHLD Au)H‹BAHHIËBDc8D9rȋ[(D)HD9s DD Ats8HEKH[fDR(D)HHL"R(D)HHLHL@RfDHHXYff.UHAWIDAVAUATASDH(A?Hu AG IGHxgHcGLc{5HIIGLHxcdK|-I5IHL5ILI9ELAA5DPAӅ9HFD@I9t2HH~u EutAPD9AHI9uFL(5I|L9HIuHff.HHJH9uHL)_HDA?uAG tLs4Lk4H([A\A]A^A_]DH1#F.AH1 fDHDIWLDɾLLNlfLH171Pff.UfHAWAVAUATSHf9L|HHhDHXDLLH@DHXE<:HDžHDžPHP H`HHX2IH+Hƅ HUHE1H eu HXHE]Džd A DžHDž`HH8HDžH LDžH4HXƅH(ƅHDž @LfDMI)HH`HH(AEL@HHLHPHWHXIMcL)`LAA~ IwFHHDHDHH1DHH)LN$(M)DLDIDHIHXA MHI)HL@MtfA8A8}HLA$HteHpHfHMH )EHpHEx ~Hff.HhLHh8HhH( LHhL  HHiIF0HIIfLLLbZI}IH1I}1I}1fHL@LLLAEA* A`<AAЃ o AE1DžHHL9IcI)AtAN AnR A+x w DEE‰DžH(H H@4HXHHHPHPH`HcHLdH)ȃ`@H8HfD>rPA9@AEIHHH@HPHH`HA@<<HIʉAPfA:ABIz tIzu ABH|LH@HLAAH@LHIAED9AHwEҸ D`AEE1퉅dELLIHHw:MO|?LM)LLLHIOLN$L)ËdLHA蒷HID9`uHLLIfA;t A;.H"@D"A;.EtHDp HL޹LBLHHH(.HH@HHDL9rJHHHHHHHHXHHH"LN$(M)LLHI)LL3LL4IHE"IHXƅH AHyHuQH\HHHP/HXH@HPHVXA]XHHXHHHH|H>DVXHhHALX[HLLIHXHHHHHXHUHAXAmXHHe[A\A]A^A_]H 5XHe1[A\A]A^A_]HHhH Hc0HiHG0IM]IސLLLEI}IHu.QpI}P_I}ODCMM)uAbHYHHX@HDHHPHX@HPWxoD`L%]PLmXLHjt|Hh8'D`L%k]PLkHƹwjXLvjt@Hh8'D`L%/]PL/HƹfXL:jHh@<LhA~A>EfL%\PLmXLHiAFMn<B$<)HDLeHHLwHLLDHUE<%<D%<%<$< *< HEH(HEHpH@H HP0P HEHxsH}jDL2HA HHPHX@HPHL AJXLXHH|=HH HH"@D"AkAqƀ"A;EA<D<TAo)EICHEHE1fDǀ"A<.%< }A9AMLcL9q M)ED @DѺnXAgtnXLLWHIA<q<Ao)EICHEH1fǀ"A<e$<)!}A9AMLcL9 M)ED DѺnXAe8nX.A<<jAo)EICHEH1fǀ" A<#<BE<K<HEH11HDH9HHHHZHDDL9HLA ,HH)кLp1EDEEHLH$H""@EtDpHHH L^HpLHHHx'HHho "HDž!f=DHHLLEIs<9 DDHLHHA qLHu}eI< < DADf=1XPA9GLH LdH<`DGtwLCHLSPHIGJ89L R$HHLDHAtA' ff.ff.$HHLDA H‹BHHIHHI)MHDHHHHfLN$ M)uLI謧HIoA<n <Ao)EICHEHE1fDǀ"uA<<@}A9AMLcL9EM)ED e DѺ nXLf"dXL)ELmI0HE>LMnIhLEL LHCHH3 HhHXAS!dXLBH@HHHH)HL|$Hx0MIIB>LƍJnHhLIW0oH@BJ(ACH@It0HIH9nAoICHBAKH:uBuăfBBA< <Ao)EICHEH1fǀ"?A<<E<<JHEH11HDH/HH HH HDDL9VHLA ,HH)Lp1EDE1E3Eu AB"A< <\Ao)EICHEH1fǀ"%A<<E<f<0HEH11HDH.HH HIy KDHHtCDL9HA,I)EEEE11Eu AB"A<\<vAo)EICHEH1fǀ" A<<RE<J<HEH11HDH-HH HI] KDHHtCDL9"HA,I)AEEE11H9s DAa8HEAGtEgHsHDH{PHHAGJ89R$HHHDHAtX@ff.ff.ff.ff.ff.E@$LHHDAu)H‹BIHLƋBEH8D9rE@(D)I9s DAxD8LEwHEgDMHh8xLh@<< HD;LeHHL3g:HCHAgXNXHH蟱`R()HHHgR()HHLLAgA]XVXLHƉG HKP9Hf@W5KPLAg{HHHuA_X \XHVHHuAdX \X走vHhD HhHLA DALcHMi"@Lh0IHƀ"HL*A"AƇ"I}'I}wpHxlHh@t @,DHDHwHHHPHHhJ8@(9~R$HHHDHAt\Dff.ff.ff.ff.ff.E@$LHHDAu)H‹BIHLƋBEP8D9rE@(D)DDIH9s DA^HD8LEHAvgXAX覮gA<<m<t<t < t< ICHHD \XHhHAU^X?oXAgtpXLH pXAetܺpXպoXD`DLxAC gL LDLLaAoILDHE)E>AC L LDLL'aAoILDHE)EOAC "L LDLL`AoILDHE)EaAC ] L LDDLLh`AoILDHED)E>bUA]XHHƹVXDAC / HLDL_HLDoH)EHEAC 0 HLDL_HLDoH)EHEAC;{EPpAJCEkHDPLHDIDLHLLDDLA; ASHCPHUHMD)DEHL fAH葛IwFLO|?H߉H)LHHHHML$I)LI՘HIAEuLDE AC L LDLL]AoILDHE)E%AC  HLDLR]HLDoH)EHEWCPA9C D HE1LH DDL1LDu VAHhHA,Li AC L LDDLL`\AoILDHED)EkA;FEtDpH" ƀ"HLLL:f BP9JL L޹LL!I(LH+H|IǍ@MHDL9rHi0 Hp0H#%HGpx H{0Auff.ff.ff.I$HHLukH‹BIHH NjBDI8D9rˋI(D)H0DLHA4nX[ \XA\A]A^]aR$HHLPfDI9s tgDtII0貹HS0HH0HHH{0"fDAUfDD`DLhAUUHAWAVAUATSHH(HHDLWLSpG<<t6DWDMՀt7"1H([A\A]A^A_]fw,Lo AUuɋGH@MLCpA<<VDADMƀ"uAdX \XLAdX \XLH(H[A\A]A^A_]*`f.DGtw,LCHLKPHIG(J89R()HHLDMHAt[@ff.ff.ff.ff.ff.E[$LHLDAuhH‹BHHMBEk8D9rE[(D)R$HHLQfDAxMpAfI9s DAxIDA@tAxLKHLSPHIA@J89aR$HHLDMHAtJxff.ff.ff.ff.E[$LHLDAu0H‹BHHMBEs8D9rE[(D)I9s DA[AI[A@H@MAF HYMFIuLmLH,HI~HLDLDH??f.AGtEgLCHDLKPHIAGJ89R$HHLDHAtO}fDff.ff.ff.ff.ER$LHLDAu0H‹BIHMBEZ8D9rER(D)I9s DAtRDt;IAxLpAR()HHLAD`DLxAUHAWAVAUATSHHHLHMPLWpA@<<t6AHMԀt9"1HH[A\A]A^A_]Ap,M` A $uA@H@MLCpA<<$AMƀl"uAdX \XLAdX \XLHHH[A\A]A^A_]:Zf.A@tAp,LKHL[PHI A@(y89r~I()HHLD)MHAt.fff.Ed$$LHLD(AugHAHHM$AEl$8D9rEd$(D)@I$HHLfDApMpAfI9s D(AI"A@tApLKHLSPHI A@y89rI$HHLDMHAtKyfff.ff.ff.ff.E[$LHLDAu0HAHHMAEk8D9rE[(D)I9s DAkIA@H@I;Ly1"8 {dLeHL%?18 EHuLLLON1؉8 GHuHELLHpHhHx>1藉8 1臉8 H 譎aƃH$H1F8 tCHLHx;Kt( H1fH18 H`AgXNXHn2UAfH*EXhfTf.\ƃAHHxLG1y8 HL融QHL脍7LHuA課HEE1UƃHfD ƃHÆH18 HLHx;;CJHufU1HSHH荇" uFHh t H]1DHHHA^XH]LX0HH] ff.U1HAUATSHH8 "AAAuOHh tH8D[A\A]]ËHHH8HA^X[LXA\A]]60fDHHLhLkpPNP"YAoE)EIEHEǃ1fAE<V<>}EH}Ȩ H~WHƃHcH HEHHH(EGp,Lh AU6HuVXHAFX/AE<<HEHHHuHEHxH}MZ@tp,LKH@(HLCPIыz89R$HHLDHAtCqDff.ff.ff.ER$LHLDAu0H‹BHHMBEZ8D9rER(D)I9s DApIAE tDHLoH"HE)EfAEA_X \XLHm-AEIEHH@H=EH=EA_X \XLH-AEfHu \XHAdX,AER()HHL2@HHuHE;EgHEƃHEp@EAUcfDAvgXAX"fpLhAU.HEHx>H}蓁ff.U1HAUATSHH8Y"AAAuOHh tH8D[A\A]]ËHHH8HA^X[LXA\A]]+fDHHLhLkpPnP2iAoE)EIEHEǃ1fAE<f<N}UH} H~v1@uff.HH@tHƃ HEHHHEIDp,Lh AUHuVXHAFXC*AE<|<nHEHaHHUHEHxH}}:@tp,LKH@(HLCPIыz89R$HHLDHAt3aff.ff.ER$LHLDAu0H‹BHHMBEZ8D9rER(D)I9s DApIAE tDHLoH"HE)EfAEA_X \XLH(AEIEHH@H=EH=E~A_X \XLHU(AE fHu \XHAdX#(AER()HHLB@HHuHEs;@wHEƃHE@U AUSfDAvgXAX"fpLhAUHEHx\9H}|ff.U1HAUATSHH8}"AAAuOHh tH8D[A\A]]ËHHH8HA^X[LXA\A]]&fDHHLhLkpPnP2iAoE)EIEHEǃ1fAE<f<N}MH} Hxvt@ff.HGHH!uHƃ HEHHHEIDp,Lh AUHuVXHABDX%AE<|<nHEHaHHUHEHxH}z:@tp,LKH@(HLCPIыz89R$HHLDHAt3aff.ff.ER$LHLDAu0H‹BHHMBEZ8D9rER(D)I9s DApIAE tDHL oH"HE)EfAEA_X \XLH#AEIEHH@H=EH=E~A_X \XLH#AE fHu \XHAdXc#AER()HHLB@HHuHE;<wHEƃHE@M AUSfDAvgXAX"fpLhAUHEHx4H}xff.U1HAWAVAUATSHHhx"AAAu[HhD EtHhD[A\A]A^A_]fDHHHhHA^X[LXA\A]A^A_]!fLHDMHLKpA@<<DDMA@H@M@AFA_X \XLH}EoDMO@AFIFHH@H=ExH=ElA_XLH߹ \XAAG DLH跶Ho1ǃfHE")E&fDR()HHL@R()HHL@HuAdX \XHSAAGA_XDLH߹ \X$8E HEHHHEh@HEH_HHSHEHx肩H}9W8@AG9IGH,H@H=EH=EA_XLH߹ \X`AHuƃHoVH1W8 t,HHHx ;@fHuNXHAgXA;AvgXLH߹AXA2@pLpVfDDhDLxg@Hx[Hu:JXHATXBAf.AvgXLH߹AXA|@ED-<.H <HEHuHx(e3D9HD9DEHuD-E t^HH< D9HuH D9,d@HEHxCH}T}<HUHݥD9HEHxH}yTxE HEHpHEHx(/D9HEHHp(HEHx/D9HEH HpHEHx(f/D9PE D9pHEH HpD9NfDE HB D9u(U1HAUATSHHHiT"AAAuOHh tHHD[A\A]]ËHHHHHA^X[LXA\A]]fDHHLhLkpP-P2iAoE)EIEHEǃ1҃fAE<f<VEƒ<ƃHRH1=S8 HEHp(HHx<1S8 d Hf1HE<h<HEHHHHEHx H}Qn@p,Lh AUAE @HLدoH"HE)ED@tp,LKH@(HLCPIыz89gR$HHLDHAt#QfDER$LHLDAu0H‹BHHMBEZ8D9rER(D)I9s DA`IE 8HEH+HHEl@AEA_X \XLHAEIEHH@H=EH=EvA_XLH߹ \X`AR()HHL@HuNXHAgXAHu \XHA%aXAgH} foEHEH:fDAUSfDAvgXLH߹AXA@pLhAUHEHx\ H}Nff.U1HAUATSHH(O"AAAuOHh tH(D[A\A]]ËHHH(HA^X[LXA\A]]fDHHLhLkpP-P2AoE)EIEHEǃ1҃fAE<v<Eƒ< ƃHKMH1mN8 HEHpHHxl1EN8  Hf1HE<<HEHHHHEHx:H}Ln@p,Lh AUAE HLoH"HE)ED@tp,LKH@(HLCPIыz89R$HHLDHAtS~ff.ff.ff.ff.ER$LHLDAu0H‹BHHMBEZ8D9rER(D)I9s DA@IHEfoEHE HEHHHME%DAEDA_X \XLHhAE_IEHRH@H=EBH=E6A_XLH߹ \XPAR()HHLR@Hu \XHA%aX AOHuNXHAgXA'AUCfDAvgXLH߹AXA@pLhAUHEHx|H}Ipff.U1HAUATSHH(J"AAAuOHh tH(D[A\A]]ËHHH(HA^X[LXA\A]]fDHHLhLkpPP9AoE)EIEHEǃ1fuWAE<"<*E<~Hu<<<u E A_X \XHAE<|<HEHHHHEHx螚H}UHp,Lh AUf@tp,LKH@(HLCPIыz89R$HHLDHAt3aff.ff.ER$LHLDAu0H‹BHHMBEZ8D9rER(D)I9s DAI%AE ttHL茥oH"HE)EfE hHEH[HHEX@AEA_X \XLH=|AEIEHH@H=EH=EA_XLH߹ \XAEfH,H*\fTYf.!ƃqR()HHL@AoX \XH]A=DAUfDAvgXLH߹AX$A@pLhAUVArVXAXHADH:JXHAOXAHEHxH}"Efff.U1HAUATSHH(E"AAAuOHh tH(D[A\A]]ËHHH(HA^X[LXA\A]]fDHHLhLkpPP)AoE)EIEHEǃ1fuWAE<<E<nHu< <u E A_X \XHKAE<l<HEHHHHEHxΕH}Cp,Lh AUf@tp,LKH@(HLCPIыz89R$HHLDHAt#QfDER$LHLDAu0H‹BHHMBEZ8D9rER(D)I9s DAhI5AE ttHL̠oH"HE)E"fE xHEHkHHhEh@AEA_X \XLH}|AEIEHH@H=EH=EA_XLH߹ \X AH,EfƃH*DR()HHL*@AoX \XHAmDAUfDAvgXLH߹AXA4@pLhAUArVXAXHMAHEHx8H}@f.U1HAUATSHH(yA"AAAuOHh tH(D[A\A]]ËHHH(HA^X[LXA\A]]fDHHLhLkpPNP9AoE)EIEHEǃ1҃fuWAE<<*E<Hu<,<u E A_X \XHAE<|<HEHHHHEHx^H}?p,Lh AUfAE PHL(oH"HE)ED@tp,LKH@(HLCPIыz89wR$HHLDHAt3aff.ff.ER$LHLDAu0H‹BHHMBEZ8D9rER(D)I9s DAIE hHEH[HHEX@AEA_X \XLHAEIEHH@H=EH=EA_XLH߹ \XAR()HHL@E?H,H?ƃl@AUfDAoX \XHA=DAvgXLH߹AXA@pLhAUfArVXAXHADELL蜇1=8 ƃH;H1<8 tiHLHx;?tN1<8 tB Hf1H>BHEHx H};!HuNXHAgXAf.U1HAUATSHH()<"AAAuOHh tH(D[A\A]]ËHHH(HA^X[LXA\A]]VfDHHLhLkpPNP)AoE)EIEHEǃ1҃fuWAE<<E<Hu<<u E A_X \XHAE<l<HEHHHHEHxH}9p,Lh AUfAE @HLؗoH"HE)ED@tp,LKH@(HLCPIыz89gR$HHLDHAt#QfDER$LHLDAu0H‹BHHMBEZ8D9rER(D)I9s DAIE xHEHkHHEh@AEA_X \XLHAEIEHH@H=EH=EA_XLH߹ \X`AR()HHL@E:H,Hx:ƃ|@AUfDAoX \XHAMDAvgXLH߹AXA$@pLhAUvArVXAXH}ADELL\178 ƃH{6H178 tiHLHx;tN1v78 tB Hf1HO9RHEHxH}D61HuNXHAgXAf.U1HAUATSHH(6"AAAuOHh tH(D[A\A]]ËHHH(HA^X[LXA\A]]fDHHLhLkpPNP)AoE)EIEHEǃ1҃fuWAE< <E<Hu<,<u E A_X \XHKAE<l<HEHHHHEHxΆH}4p,Lh AUfAE @HL蘒oH"HE)ED@tp,LKH@(HLCPIыz89gR$HHLDHAt#QfDER$LHLDAu0H‹BHHMBEZ8D9rER(D)I9s DA IE xHEHkHH#Eh@AEA_X \XLH}AEIEHH@H=EH=EA_XLH߹ \X AR()HHL@XE65H,H05ƃt@AUfDAoX \XHAEDAvgXLH߹AXlA@pLhAUnfArVXAXH-ADELL }1u28 ƃH+1H1M28 tiHLHxU;tN1&28 tB Hf1H3BHEHx}H}0!HuNXHAgXRAf.U1HAUATSHH(1"AAAuOHh tH(D[A\A]]ËHHH(HA^X[LXA\A]]fDHHLhLkpPNPYAoE)EIEHEǃ1҃fuQAE<"<JE<Hu<<<A_X \XHAE<<HEHHHHEHx脁H};/fDp,Lh AUfAE pHLHoH"HE)ED@tp,LKH@(HLCPIыz89R$HHLDHAtS~ff.ff.ff.ff.ER$LHLDAu0H‹BHHMBEZ8D9rER(D)I9s DAq(IE HHEH;HHE2@AEA_X \XLHAEIEHH@H=EH=EA_XLH߹ \XAR()HHLb@AoX \XHeA_DH,EȿH/u}ƃ3AUfDAvgXLH߹AXA@pLhAUVArVXAXHADELLw1-8 ƃH+H1,8 tiHLHx;OtN1,8 tB Hf1H.,HEHxH}+HuNXHAgXAf.U1HAWAVAUATSHHH5,"AAAu[Hh tHHD[A\A]A^A_]HHHHHA^X[LXA\A]A^A_]RfLHDMHLKpA@<=<-DDMA@H@M<Hu<A_X \XHAE<r<HEHHHHEHxXH}KfDp,Lh AUf@tp,LKH@(HLCPIыz89R$HHLDHAt#QfDER$LHLDAu0H‹BHHMBEZ8D9rER(D)I9s DAiI-AE ttHLcoH"HE)EfE jHEH]HHEb@AEA_X \XLH=|AEIEHH@H=EH=EA_XLH߹ \XAE HEHuHxNEkf.#ƃw f.zHu:JXHA-^XkAUR()HHL@ArVXAXH5ADfH*Ei@AUcfDLmLuLI}MEI}(LEME^EfAvgXLH߹AX褭A@ENfpLhAUHEHx\H}2ff.U1HAVAUATSHH@"AAAuUHh tH@D[A\A]A^]@HHH@HA^X[LXA\A]A^]鼬@HHLhLkpP&PQAoE)EIEHEǃ1fugAE<<BE<<~<VHu<$A_X \XHAff.E<<HEHHHHEHxfSH}p,Lh AUf@tp,LKH@(HLCPIыz897R$HHLDHAt3aff.ff.ER$LHLDAu0H‹BHHMBEZ8D9rER(D)I9s DAqI AE ttHLL^oH"HE)EfE JHEH=HH EP@AEA_X \XLH|AEIEHH@H=EH=EA_XLH߹ \X蠩AE HEHuHxeIE;f(fT ƃf. Вw f.\Hu:JXHA-^XA7R()HHL@fH*Ey@ArVXAXHͨADEFAU#fDLmLuLI}|HEI}(LEfHE^E7fAvgXLH߹AXDA\@pLhAUHEHxH} fDU1HAVAUATSHH@W"AAAuUHh tH@D[A\A]A^]@HHH@HA^X[LXA\A]A^]|@HHLhLkpP&PQAoE)EIEHEǃ1fugAE< <BE<<<~Hu<$A_X \XH豦Aff.E<<HEHHHHEHx&NH}p,Lh AUf@tp,LKH@(HLCPIыz897R$HHLDHAt3aff.ff.ER$LHLDAu0H‹BHHMBEZ8D9rER(D)I9s DAI AE ttHL YoH"HE)EfE JHEH=HH<EP@AEA_X \XLH轤|AEIEHH@H=EH=EA_XLH߹ \X`AE HEHuHx%DE f(fT ύƃf. }f.XH:JXHA-^XأA0R()HHL@fH*Ey@ArVXAXH荣AH:JXHAOXeADE.fAUfDLmLuLI} CEI}(LEBE^EfAvgXLH߹AXԢA,@pLhAUnHEHx褴H}fDU1HAVAUATSHH@"AAAuUHh tH@D[A\A]A^]@HHH@HA^X[LXA\A]A^] @HHLhLkpPPaAoE)EIEHEǃ1fuYAE<<RE<<<Hu< A_X \XHAAE<<HEHHHHEHxHH}{fDp,Lh AUf@tp,LKH@(HLCPIыz89GR$HHLDHAtS~ff.ff.ff.ff.ER$LHLDAu0H‹BHHMBEZ8D9rER(D)I9s DAIAE ttHLSoH"HE)EfE :HEH-HH4E2@AEA_X \XLH=|AEIEHH@H=EH=EzA_XLH߹ \XAE HEHuHx>Ef.#ƃw~f.JH:JXHA-^XhA"R()HHL@ArVXAXH5ADfH*E iH:JXHAOXA@AU fDLmLuLI}=EI}(LE=E^Ef.AvgXLH߹AXtA.@ENfpLhAUfHEHx,H}ff.U1HAVAUATSHH@g"AAAuUHh tH@D[A\A]A^]@HHH@HA^X[LXA\A]A^]錜@HHLhLkpPPaAoE)EIEHEǃ1fuYAE< <RE<<<Hu<A_X \XHAE<<HEHHHHEHxDCH}fDp,Lh AUf@tp,LKH@(HLCPIыz89WR$HHLDHAtS~ff.ff.ff.ff.ER$LHLDAu0H‹BHHMBEZ8D9rER(D)I9s DAIAE ttHL NoH"HE)EfE :HEH-HHDE2@AEA_X \XLH轙|AEIEHH@H=EH=EzA_XLH߹ \X`AE HEHuHx%9E+f(fT ςƃf. ~f.:H:JXHA-^XؘAR()HHL@ArVXAXH襘ADfH*EYH:JXHAOXdA@AUfDLmLuLI}$8EI}(LE8E^Ef.AvgXLH߹AXA@EfpLhAUVHEHx蜩H}ff.U1HAVAUATSHH@"AAAuUHh tH@D[A\A]A^]@HHH@HA^X[LXA\A]A^]@HHLhLkpP&PQAoE)EIEHEǃ1fugAE<<BE<<~<VHu<$A_X \XH1Aff.E<<HEHHHHEHx=H}]p,Lh AUf@tp,LKH@(HLCPIыz897R$HHLDHAt3aff.ff.ER$LHLDAu0H‹BHHMBEZ8D9rER(D)I9s DAqI AE ttHLHoH"HE)EfE JHEH=HH EP@AEA_X \XLH=|AEIEHH@H=EH=EA_XLH߹ \XAE HEHuHx3Ef(fT O}ƃf. }w f.\Hu:JXHA-^X_A7R()HHL@fH*E9y@ArVXAXH ADEFAU#fDLmLuLI}2EI}(LE2E^EfAvgXLH߹AX脒A\@pLhAUHEHxTH} fDU1HAVAUATSHH@"AAAuUHh tH@D[A\A]A^]@HHH@HA^X[LXA\A]A^]鼑@HHLhLkpPPQAoE)EIEHEǃ1fuYAE<<BE<<^<Hu<A_X \XHAE<<HEHHHHEHxt8H}+fDp,Lh AUf@tp,LKH@(HLCPIыz897R$HHLDHAtCqDff.ff.ff.ER$LHLDAu0H‹BHHMBEZ8D9rER(D)I9s DAiI AE ttHLLCoH"HE)EfE JHEH=HHEB@AEA_X \XLH|AEIEHH@H=EH=EA_XLH߹ \X蠎AE HEHuHxe.Ef.wƃw f.ZHu:JXHA-^X+A5R()HHL@ArVXAXHADfH*Ei@AUCfDLmLuLI}-EI}(LE-E^EfAvgXLH߹AXdAn@EnfpLhAUHEHxH}ff.U1HAVAUATSHH@W"AAAuUHh tH@D[A\A]A^]@HHH@HA^X[LXA\A]A^]|@HHLhLkpPPQAoE)EIEHEǃ1fuYAE<<BE<<n<Hu< A_X \XH豋AE<<HEHHHHEHx43H}fDp,Lh AUf@tp,LKH@(HLCPIыz89GR$HHLDHAtCqDff.ff.ff.ER$LHLDAu0H‹BHHMBEZ8D9rER(D)I9s DAyI AE ttHL >oH"HE)EfE JHEH=HHEB@AEA_X \XLH轉|AEIEHH@H=EH=EA_XLH߹ \X`AE HEHuHx%)E[f(fT rƃf. rw f.NHu:JXHA-^X߈A)R()HHL@ArVXAXH襈ADfH*EY@AU3fDLmLuLI}L(EI}(LE6(E^EgfAvgXLH߹AXA^@E.fpLhAUHEHx̙H}Cff.U1HAVAUATSHH@"AAAuUHh tH@D[A\A]A^]@HHH@HA^X[LXA\A]A^],@HHLhLkpP&PAAoE)EIEHEǃ1fugAE<<2E<<n<FHu<A_X \XHaAff.E<t<HEHHHHEHx-H}p,Lh AUf@tp,LKH@(HLCPIыz89'R$HHLDHAt#QfDER$LHLDAu0H‹BHHMBEZ8D9rER(D)I9s DAqIAE ttHL8oH"HE)E fE ZHEHMHH5E`@AEA_X \XLH}|AEIEHH@H=EH=EA_XLH߹ \X AE HEHuHx#E+f(fT mf. Om)f.ƃhHu:JXHA-^X蛃ACR()HHL@fH*EyfArVXAXHMADEFfDAU3fDLmLuLI}"EI}(LE"E^EAvgXLH߹AXĂAl@pLhAUH:JXHAOX耂A(HEHxkH}fff.U1HAVAUATSHH@"AAAuUHh tH@D[A\A]A^]@HHH@HA^X[LXA\A]A^]́@HHLhLkpP&PaAoE)EIEHEǃ1fugAE<<RE<<<fHu<4A_X \XHAff.E<<HEHHHHEHxv(H}-p,Lh AUf@tp,LKH@(HLCPIыz89GR$HHLDHAtCqDff.ff.ff.ER$LHLDAu0H‹BHHMBEZ8D9rER(D)I9s DAqIAE ttHLL3oH"HE)EfE :HEH-HH E@@AEA_X \XLH~|AEIEHH@H=EH=EzA_XLH߹ \X~AE HEHuHxeEf(fT hƃf. gw f.LHu:JXHA-^X~A'R()HHL@fH*E9y@ArVXAXH}ADEFAUfDLmLuLI}|EI}(LEfE^EfAvgXLH߹AXD}AL@pLhAUHEHxH}fDU1HAVAUATSHH@W"AAAuUHh tH@D[A\A]A^]@HHH@HA^X[LXA\A]A^]||@HHLhLkpP&PQAoE)EIEHEǃ1fugAE<<BE<<~<VHu<$A_X \XH{Aff.E<<HEHHHHEHx&#H}p,Lh AUf@tp,LKH@(HLCPIыz897R$HHLDHAt3aff.ff.ER$LHLDAu0H‹BHHMBEZ8D9rER(D)I9s DAqI AE ttHL .oH"HE)EfE JHEH=HH EP@AEA_X \XLHy|AEIEHH@H=EH=EA_XLH߹ \X`yAE HEHuHx%Ef(fT bƃf. bw f.\Hu:JXHA-^XxA7R()HHL@fH*E y@ArVXAXHxADEFAU#fDLmLuLI}<EI}(LE&E^EfAvgXLH߹AXxA\@pLhAUHEHxԉH}K fDU1HAVAUATSHH@"AAAuUHh tH@D[A\A]A^]@HHH@HA^X[LXA\A]A^]HpAXHArVXdAE<i<1EfEp<x<(HxHHH HxHx HxȹAp,Mp UDDA@tAp,L[HLSPHIA@(z89R$HHLD:MHAt"PDEv$LHLD8Au0H‹BHHM4ËBE~8D9rEv(D)I9s D8A8LEAF xHLoH"HE)pfAGtEoLKHDLCPHIAGz89R$HHLDHAtO}fDff.ff.ff.ff.ER$LHLDAu0H‹BIHMBEZ8D9rER(D)I9s DAD8LEifDr HxHHHpSAF4A_X \XLHaxEoDM@AF8IFH+H@H=EH=EA_XLH߹ \XHaAAG DLHHo1ǃfHE")E6fDR()HHL@R()HHL@E u<f<Hp \XHA_Xz`AfAG$A_XDLH߹ \XL` E HEHHHEk@HEHbHHVHEHxH}a;@AGIGHH@H=EH=EA_XLH߹ \X_Ar KE HE .x8H rHpHxLLHx;$xQ1苵8 ƃHAH1c8 HLHxgi;w148  1fHHfAvgXLH߹AXd^A@pLpnfDDhDLx@5fMH*x@苷f(fT Gf. _Gƃf.Hp:JXHA-^X]AAvgXLH߹AX]A@Mx]HxHxMoHxfH*ME HE u8H 8LmHxLLhHELLHp赳;uLnnHuAgXNXH\AHuHH?HxLLHx ;ruNHEHxanH}رHxHH}pHuHLL|;u1y8 HL螷1O8 ƃHH1'8 HLHx+f;tt18 tsfǃ H1HDcm1̱8 tCƃH膰H1許8 tHLHxe; tIHp;H:JXHAOXZA%Hu \XHAVXZAHHHHHuUHuHt5kffH*H*ƃH,HHǃƃH} Hp \XHAoX%ZAhHuLHEƃHEf.U1HAWAVAUATSHHhE"AAAu[Hh tHhD[A\A]A^A_]HHHhHA^X[LXA\A]A^A_]bYfLHDMHLKpA@<<%DDMA@H@M@E<T<ta<Hu \XHA_XSAE0AG)A_XDLH߹ \XSE uEfHEf.z u HfH*f(fT =f. <4f.ƃHf.E HEHHHEm@HEHdHHXHEHxH}Q=@AGaIGHTH@H=EDH=E8A_X \XLHuRAEfEE <JE HHEHx裭HEu H.fHuH*HEHxxxE|fT;f.T;ƃEfDAvgXLH߹AXQA@pLpVfDDhDLxg@<<PHEHuff/EfH*M赪f(fT :f. :f.ƃcHuA-^X:JXHPA*DAvgXAX2fEff.nhf/M]HuHEHxsbH}E\E ZHUHEHuHxfH*HEHx%bH}蜥HAOX@ff.U1HAUATSHH(I"AAAuOHh tH(D[A\A]]ËHHH(HA^X[LXA\A]]vOfDHHLhLkpP>PAoE)EIEHEǃ1fuIAE<<:E<<Hu \XHAdXNAE<<HEHHHHEHx<H}fDp,Lh AUAE @HLoH"HE)ED@tp,LKH@(HLCPIыz89R$HHLDHAtS~ff.ff.ff.ff.ER$LHLDAu0H‹BHHMBEZ8D9rER(D)I9s DAy0IAEA_X \XLHLE (HEHHH$E @AEIEHH@H=EH=EA_XLH߹ \X`LAE pHEƃHH~@R()HHL:@HuAXHArVXKA5AUfDAvgXLH߹AXKA@pLhAU^HEHx]H}ff.U1HAWAVAUATSHHHš"AAAu[HhD EtHHD[A\A]A^A_]fDHHHHHA^X[LXA\A]A^A_]JfLHDMHLKpA@<=<uDDMA@H@M1$|8  1fHHE%f.AvgXAXjHxHxZ7HxzAE HuLmLL0HxHEHx7H}zHxH#UƃH_HpNXHAgX$ARHELLHpHxHx1{8 tOƃHyH1z8 t+HLHx.;@=t1z8 HpNXHAgX$AEfU1HAWAVAUATSHHhez"AAAu[HhD EtHhD[A\A]A^A_]fDHHHhHA^X[LXA\A]A^A_]#fLHDMHLKpA@<<DDMA@H@M<Ao1)EIFfHEǃA<<p}HpAdX \XHAE< <p1EfEr -HxHHHDp~Ap,Mh uDAEIEHH@H=EH=EA_X \XLHApPHxHqHHeHxDoHx&HxIDo5DDA@tAp,LkHL[PHITA@(z89R$HHLD2AtKfDff.ff.ff.Ev$LHLD0AdH‹BHHMtBE~8D9rEv(D)f.AE hHLDo1oH"DoHE)pAFtEfLSHDLCPHIAFz89R$HHLDHAt/]ff.E[$LHLDAu0H‹BIHM‹BEs8D9rE[(D)I9s DAD8LEfDI9s D0A8LEAEA_X \XLHDofEfDMv_@AF DLHDoxHo1ǃfDoHE")ER()HHL9@R()HHL6@AFA_XDLH߹ \XDoPHpAXHArVXAEH@HEHGHpH;HEDoHxLH}FpDo E HEHHHE@AFgIFHZH@H=EJH=E>A_X \XLHAE]fEr us<<Hu@AvgXAXf.D`DLp@pLhfD<uE DoLeHuLL1LLHxHx(1LJ1LAJDoD1#LDo1>EDo8 `ƃHDoCH1EDo8 )HLDoHx;VDo1DoDDo8  1fHHEAvgXAX f.MHHxDoHxHxBCDoE umHuHHxHHHt H2H1HHHƃHEDoHx_H}BpDoHxLeDoLLHE1LLLhL&1LH1LAHDoD1LDo1;CDo8 taƃHDoAH1CDo8 t.HLDoHx;[DoHpNXHAgX=AHEL1LLhHxLHx%1LG1LAGDoD1 1DoHBDo8 t|ƃHDo@H1BDo8 tIHLDoHx;hDot1DoADo8 HpNXHAgX/AEHp:JXHATXAE{LLLDoLLLnDoLLLSDofDUHAWAVAUATSHHHHDLGLCpG<<DDMŋGH@M4LspA<<DAE<K<AoE)0IEH@E1ɸǃfD"AE<<A<<AoE1)PIFfDH`ǃA<c<0P<d<d[H0AdX \XHP1ƅPfR0Hĸ[A\A]A^A_]w,Lo \fDDGtw,LSHLKPHI‹G(J89dR()HHLDMHAt'E[$LHLDAH‹BHHM‹BEk8D9rE[(D)2 "H8HHH0AE XHL舛oH)0H@fDAFtEfLCHDH{PHIAFJ89cR()HHHD HAtQff.ff.ff.ff.EI$LHHDADH‹BIHM BEQ8D9rEI(D)H8HHH/H8HxVH8 </fDAEZA_X \XLHUoH)0H@8EfDMv@R$HHLfDR$HHHfD<H0AXHArVXP@I9s DAD8LEVfDI9s DAQ8LEAEvIEHiH@H=EYH=EMA_XLH߹ \XAF DLH蟘Ho1ǃfH`")PPmR fHXHVHHP5HXH.HH"/HXHx΋HX9/fDAF:A_XDLH߹ \XAFJIFH=H@H=E-H=E!A_XLH߹ \XpPP@2 teHPAvgXLH߹AXpLhfDD`DLp@uR .H8LpLmLLeL.LLHXLLHp/LLLHX1LHpvR  HXLpLmLLeLL~LvH8LLHx0/H8LLHxZ1LLL1C88 ƃH6H188 HLHx;y178  H1fHLSLKLC/HXHx(HX6/AvgXLH߹AXP/H8HxH8F6/H0NXHAgXzHXH4H8HHHHtIH:I1HHHƃH)HHHLmLeLLLHXLHpH8Hx3-H8LLHx]1LLHXHp1>68  ƃH4H168 HLHx;t158  H1fHH0:JXHATX1PDU1HSHH}5" uFHh t H]1DHHHA^XH]LXHH] ff.UHAVAUATSHHHHDLGLCpG<<DDMŋGH@M4LspA<<DAE<M<AoE)`IEHpǃE1fD"AE<<A<<AoE1)EIFfDHEǃA< <D`A6A}H` \XHAdX2U D`1EfUAb  HhHHHD`f.w,Lo ZfDDGtw,LSHLKPHI‹G(J89dR()HHLDMHAt'E[$LHLDAH‹BHHM‹BEk8D9rE[(D)D`AAHĐ[A\A]A^]AE XHL舏oH)`HpfDAFtEfLCHDH{PHIAFJ89cR()HHHD HAtQff.ff.ff.ff.EI$LHHDAH‹BIHM BEQ8D9rEI(D)HhHHH_HhHxVHh 0_fDAEXA_X \XLHUoH)`Hp6EfDMv@R$HHLfDR$HHHE 6 HuHD`DAAAA*@H`AXHArVXII9s DA8LEI9s DAyD8LEfDAE7IEH*H@H=EH=EA_XLH߹ \XD`AF DLH_Ho1ǃfHE")EUE HUHHHUDHUHHD`H_HEHxH}S-D`_AFA_XDLH߹ \XAFIFHH@H=EH=EA_XLH߹ \X8E<<|Hu \XHAdXf.AvgXLH߹AXD`pLhZfDD`DLpj_HEHxH}+D`_P@AvgXLH߹AXD E u`HuH=H`:JXHATX_HhHxHh^+_HEHx51tUD`AtQAiAtSAH` \XHA_XZ#b uLeLLxHhL{HEHxLL`1i+8 L|1Q+8 H w0ƃH)H1+8 tCHLHxz;rt( H1fH1*8 H`NXHAgX8h^EfTf.GƃdLeLLrwHuLzHhHhHuHxsE^EfT)f.1ƃfHuNXHAgX9ƃHc(H1)8 HLHx;mb uGLhHHMHLHI?LIHHHhL1LHxT1(8 1(8 ƃH'H1(8 HLHx; 1~(8 fǃ H1HfhH*^fTvf.>H:JXHAOXafH*h_HELLHpHhHx~1'8 1'8 H ,,ƃHU&H1w'8 HLHx;w;_H?H9LeLLI1"'8 QHuL1LLR1&8 +Ly1&8 ƃH%H1&8 HLHx;1&8 fǃ HL(ƃH)%H1K&8 zHLHxO;3VD`AtQAt YHEHuHxooh^EfTf.ڸb HhLeL1%8 HEL1LLHp1l%8 L1T%8 ƃH $H1,%8 [HLHx0;7HEL1LHpHhHx{1$8 HL)LH?)HuL OHEƃfǃHff.U1HSHHM$" uFHh t H]1DHHHA^XH]LXHH]ff.U1HAWAVAUATSHHH#"AAAu[Hh tHHD[A\A]A^A_]HHHHHA^X[LXA\A]A^A_]fLHDMHLKpA@<<DDMA@H@Mf. f.ƃ AAu MtIEHuI}rL E<<HEHHHHEHxrH}m Ap,Mp %DDA@tAp,L[HLSPHIA@(z899R$HHLD:MHAtBp@ff.ff.ff.Ev$LHLD8Au0H‹BHHM4ËBE~8D9rEv(D)I9s D8A8LE/AF pHL}oH"HE)E=DAGtEoLKHDLCPHIAGz89R$HHLDHAtO}fDff.ff.ff.ff.ER$LHLDAu0H‹BIHMBEZ8D9rER(D)I9s DAiD8LEfDE \HEHOHHE@@AFA_X \XLH=EoDM@AFIFHH@H=EH=EA_XLH߹ \XAA DLHx{"1DǃfDL sR()HHL@R()HHL@A <$<Hu \XHDMA_XDMAfAA_XDLH߹ \XA vMmIEH`I}LJf.<t ALHuAXHDMArVXADMADAGEIGH8H@H=E(H=EDMA_X \XLHDMAifE AA ZMffH*EI*AvgXLH߹AXdA,@pLpfDDhDLx@AAfInff.z{HEHuDMMHxdMEDM^f(fT wf. 79H:JXHAOXAYfDMAvgXAXfD<:HuI}DM7d]DM~ f(fTf.w/ff.z/E^fTf.yH:JXHAOXA#HEHxH}3A8fInff.ztfH*EHu:JXHATXgA/DMA urHEHuHx4cEDMf(fT ߬f. hMtfI*^MmfI*@HEL}LHxbEDM~ nfTf.*I}LDMbUDM~ 3fTf. ff.z^fHuI}DMH*Eb]DM~ īf(fTf. ff.zt HuATX:JXHAHu:JXHDMA-^XDMA/HUHAVAUATSHHĀHHDLGLCpG<|<\DDMŋGH@M4LspA<< DAE<0<AoE)`IEHpǃE1fD"AE<<A<<AoE1)EIFfDHEǃA< <`E7<6<:t<H`AXHArVXAE@w,Lo fDDGtw,LSHLKPHI‹G(J89R()HHLDMHAtOf.ff.ff.ff.E[$LHLDAH‹BHHM‹BEk8D9rE[(D)`A*YHD[A\A]A^]fAE HLroH)`HpfDAFtEfLCHDH{PHIAFJ89sR()HHHD HAtQff.ff.ff.ff.EI$LHHDAH‹BIHM BEQ8D9rEI(D)b HhHHH`HhHHHHhHx$eHhjAEMA_X \XLH-oH)`Hp+EfDMv@R$HHHfDR$HHL1fDE q 9H` \XHA_XyAE&DI9s DA8LEI9s DAqD8LEfDAEDIEH7H@H=E'H=EA_X \XfDAF DLH_oHoE1ǃfDHE")EEA<tc<uOHEHtFH`Ht1EfEHEHxbH}zf.`E tHEHtHHEwf.AFA_XDLH߹ \X茺AFIFH H@H=EH=EA_X \Xff.LH%AEfb <<<LeLLx]HhL`HEHxLLf18 jLYa18 H (ƃHH18 tLHLHx_;#t1 1fHH18 fH`AgXNXHAbAvgXAXLH贸`ADD`DLp@pLh?fD<A<HhHuHx6XEYEfTܡf.1ƃEfD<hAHEHuHxWEYhfT[f.#H:JXHAOX}AE*<ALeLLZHuL^HhyfH*hYEfTǠf.lƃAE Lh1HLHmHHHHDHAƃHuHhLE HxL1 8  1 8 ƃH H1 8 HLHx;1 8 A H1fDHHEHxH}S `AvgXAXzHhHxHh ƃH H1 8 aHLHx޿;8=HhLeL1 8 HELLLHp1i 8 L1Q 8 ƃH H1) 8 HLHx-;1 8 y|LeLL1 8 ]HuLLL1 8 GHu5HELLHpHhHx`1o 8 1_ 8 H _ƃHH1 8 tCHLHxY;t( H1fH1 8 H`AgXNXHFAEfH*EYhfTȜf.mƃAHHxL1Q 8 HLvOHL\5LHuA3HE1ƃfHE'ƃHH18 HLHxü;HuU1HSHHm" uFHh t H]1DHHHA^XH]LX髱HH]ff.UHAVAUATSHHĀHHDLGLCpG<|<\DDMŋGH@M4LspA<<DAE<8<AoE)`IEHpǃ1f"AE<<A<<AoE1)EIFfDHEǃA< <`U<J<I<P<t H`AXHArVX UAw,Lo fDDGtw,LSHLKPHI‹G(J89R()HHLDMHAt_&@ff.ff.ff.ff.ff.E[$LHLDAH‹BHHM‹BEk8D9rE[(D)`A<+<[HD[A\A]A^]AE HLboH)`HpfDAFtEfLCHDH{PHIAFJ89{R()HHHD HAtYfff.ff.ff.ff.EI$LHHDAH‹BIHM BEQ8D9rEI(D)b HhHHH`HhHHHHhHx$UHhhAE=A_X \XLH-oH)`HpEfDMv@R$HHHfDR$HHL!fDU < <B<pH` \XHA_X{AU(I9s DA8LEI9s DAqD8LEfDAE2IEH%H@H=EH=E A_X \XfDAF DLH__HoE1ǃfDHE")EUAtbuMHEHtDH`HtD1EfUHEHxRH}zf.`U tHEHtHHUwfAFA_XDLH߹ \X茪AFIFHH@H=EH=EA_X \Xff.LH%UAfb  LeLLuMHhLPHEHxLL.U18 LVQ18 H %ƃHH18 tIHLHxO; t. H1fH18 fDH`AgXNXHA`AvgXAXLH质A`DD`DLpo@pLh/fDAHhHuHx4HE\EfTڑf.1ƃUfhf.A<HEHuHxGh\EfTTf.zH:JXHAOXvUA#YLeLLJHuLMHhtfH*h\EfTf.kƃAE LEHhMHHI?H?L)ILE1IILHGHAƃjHuHhLE HxL18  18 ƃHqH18 HLHx藰;1d8 A H1fDH{HEHx迷H}6`f.AvgXAXZHhHxzHh~ƃHH18 AHLHx辯;HhLeL蚰1s8 HELLLHpP1I8 Lȶ118 ƃHH1 8 HLHx ;gq18 v\LeHLݯ18 =HuLLLw18 GHuHELLHpHhHxfO1O8 1?8 H eeƃHH18 tCHLHxI;`t( H1fH18 H`AgXNXH&UAfhH*M\fTf.lPƃAHHxL41-8 HLRHHL8.LHuA^#HEE1UƃHfDƃHwH18 HLHx蝬;Hufff.U1HSHH=" uFHh t H]1DHHHA^XH]LX{HH]ff.U1HAUATSHH("AAAuOHh tH(D[A\A]]ËHHH(HA^X[LXA\A]]fDHHLhLkpPNPIAoE)EIEHEǃ1fAE<^<^Eƃ<tg<<Mfƃf/f/SHHp,Lh AU>fE NHEHx9HHE<<HEHHHuHEHxFGH}Z@tp,LKH@(HLCPIыz89R$HHLDHAt3aff.ff.ER$LHLDAu0H‹BHHMBEZ8D9rER(D)I9s DAhIAE tDHLLRoH"HE)EfAEA_X \XLH-E HEHHHeEH@AEIEHH@H=EzH=EnA_XLH߹ \X訝AR()HHLR@H}HMH H7Hu \XHA_X8ApAU{fDHEHxPHHEDAvgXLH߹AXA@pLhAUHǃHǃHEHx蓮H} gDU1HAUATSHH("AAAuOHh tH(D[A\A]]ËHHH(HA^X[LXA\A]]fDHHLhLkpP.P)AoE)EIEHEǃ1fAE<<>E<<<u7EfTfDp,Lh AUVHu \XHA_XAĐE<<HEHHHHEHxBH}=z@tp,LKH@(HLCPIыz89gR$HHLDHAt3aff.ff.ER$LHLDAu0H‹BHHMBEZ8D9rER(D)I9s DAA@IAE tDHLMoH"HE)EfAEA_X \XLHmE  HEHHHEH@AEIEHH@H=EH=EA_XLH߹ \XAE uHUHHHHHHELLHx艬18 ƃHH18 HLHx;H18  1fHH%DR()HHL@ƃH7H1Y8 t$HLHxa;DHuNXHAgX裗AAUfDHELLHxa@18 tH DƃH{H18 dHLHxa=;E Hf1H1V8 AvgXLH߹AX贖A@pLhAUHEHx脨H}8fDU1HAUATSHH("AAAuOHh tH(D[A\A]]ËHHH(HA^X[LXA\A]]fDHHLhLkpPPAoE)EIEHEǃ1fu_AE<<2E<x<<Hu<.A_X \XH#AE<<HEHHHHEHx<H}]p,Lh AUf@tp,LKH@(HLCPIыz89gR$HHLDHAt3aff.ff.ER$LHLDAu0H‹BHHMBEZ8D9rER(D)I9s DA`IAE tDHLGoH"HE)EfAEA_X \XLHmE 0HEH#HHE(@AEIEHH@H=EH=EA_XLH߹ \XAE uHEHHHELLHxI18 ƃHH18 HLHx;H18  1fHHDR()HHL@ArVXAXHADƃHH198 t$HLHxA;DHuNXHAgX胑A[AUfDHELLHx:18 tH DƃH[H1}8 dHLHxA7;۩E Hf1H168 EfWczhfDAvgXLH߹AXtAL@pLhAUHEHxDH}fDU1HAWAVAUATSHH8"AAAu[Hh tH8D[A\A]A^A_]HHH8HA^X[LXA\A]A^A_]颏fHHLhLkpPVDpE}AAIIEAoEMMHE)Eǃ1fu9AE<<.HEDufD}LMfoEHAAMIHIyLMt6H}+fDp,Lh EufA xHL9BoHDDHEL")E@tp,LKH@(HLCPIыz89R$HHLDHAt+Yff.ER$LHLDAu0H‹BHHMBEZ8D9rER(D)I9s DA9D0EIfDA TMKIH?IyLMH}$fDAA_X \XLHxAEIEHH@H=EH=ELMA_X \XLH腌LMAfR()HHLj@EufDLMAvgXAX롐pLhEufUHAWAVAUATSHH8HHDH~H{pF<B<"DEIFH@LA<<Ao1)EIFfHEǃA<r< `<S<E< <g<H` \XHA_XnAE<G<HEHH`H1EfU<b HhHHH`fw,Lo *fDDGtw,LSHLKPHI‹G(J89|R()HHLDMHAt76ff.E[$LHLDAH‹BHHM‹BEk8D9rE[(D)`A<<#HĐD[A\A]A^]AE HHLH oH)`HpcfDAFtEfLCHDH{PHIAFJ89;R()HHHD HAtQHff.ff.ff.ff.EI$LHHDAH‹BIHM BEQ8D9rEI(D)HhHHHHhHxHhAE2A_X \XLH%koH)`HpEfDMv@R$HHHfDR$HHLfD<qUTRLeLmLI|$l EI|$(LXR X^Ef(fT Sf. Shf/A fDHEHxH}芿f.`@I9s DAY8LEkI9s DA D8LE\fDAEIEHH@H=EH=EA_X \XfDAF DLHHo1ǃfAHE")EOE<E HEHHH>EDAFA_XDLH߹ \XthXAFIFHH@H=EH=EA_XLH߹ \XhAUb fH*hf/EAfAvgXAXLHgA`DD`DLpR@pLhfDt~HhLeLHpqH}rHELHp=LAE YHEHhHxAE VHEHpHhHxAAHhHuHxEf(fT 8Pf. PMf/ALHEHx[xH}һ`fhf/EAPHEHhHxA@AvgXLH߹AXeA@E HhHuHx=AAHhHxwHhE t{HEHuHxgEf(fT Of. NHuAOX:JXH;eAHEHpHhHx;AAfhH*Ef/AHEH]HHpjoH}\pHhHHxHAAh HMH9hAH`/HhHuHxAA?ff.UHAVAUATSHHHHDLGLCpG<<DDMŋGH@M4LspA<<!DǃtAE<s<AoE)`IEHpǃ1f"AE<<.A<r<Ao1)EIFfHEǃA<Z<`<C<E< <O<}H` \XHA_XbAE<7<HEHH`H1EfU< b HhHHH`fw,Lo *fDDGtw,LSHLKPHI‹G(J89lR()HHLDMHAt'&E[$LHLDAH‹BHHM‹BEk8D9rE[(D)`A<<#HĐD[A\A]A^]AE HHLoH)`HpsfDAFtEfLCHDH{PHIAFJ89;R()HHHD HAtQHff.ff.ff.ff.EI$LHHDAH‹BIHM BEQ8D9rEI(D)HhHHHHhHxHh萵AEBA_X \XLH_oH)`Hp EfDMv@R$HHHfDR$HHLfD<U ObLeLmLI|$,EI|$(LXX^Ef(fT Hf. Hhf/AfDHEHxH}Jf.`$@I9s DAY8LE{I9s DA D8LElfDAEIEHH@H=EH=EA_X \XfDAF DLHHo1ǃfAHE")E_E<E HEHHH9EDAFA_XDLH߹ \X4]XAFIFHH@H=EH=EA_XLH߹ \X\AUb fH*hf/EAfAvgXAXLHd\A`DD`DLpb@pLh"fDt|#HhLeLHpfH}}gHELHpLAE JHEHhHxZAE GHEHpHhHx荵AHhHuHxNEf(fT Df. DMf/AaHEHx mH}藰`{hf/EAeHEHhHx\AAvgXLH߹AXZA@E HhHuHxAHhHxjlHhޯE txHEHuHx2Ef(fT Cf. C(HuAOX:JXHZA2HEHpHhHx AfhH*Ef/A,HEH]HHp8dH}*eHhHHx H߅A9HMH9hAH`5HhHuHxAc@ff.UHAVAUATSHHHHDLGLCpG<<DDMŋGH@M4LspA<<1DǃtAE<<AoE)`IEHpǃ1f" AE<<>A<<Ao1)EIFfHEǃA<z< `<S<E<! <o<H` \XHA_XWAE<G<HEHH`H1EfU<b HhHHH`fw,Lo *fDDGtw,LSHLKPHI‹G(J89|R()HHLDMHAt76ff.E[$LHLDAH‹BHHM‹BEk8D9rE[(D)`A<<#HĐD[A\A]A^]AE HHL oH)`HpcfDAFtEfLCHDH{PHIAFJ89;R()HHHD HAtQHff.ff.ff.ff.EI$LHHDAH‹BIHM BEQ8D9rEI(D)HhHHHHhHxHhPAE2A_X \XLHToH)`HpEfDMv@R$HHHfDR$HHLfD<qUTRLeLmLI|$EI|$(LXX^Ef(fT y=f. A=f.hADEHEHxSH} f.`@I9s DAY8LEkI9s DA D8LE\fDAEIEHH@H=EH=EA_X \XfDAF DLHgHo1ǃfAHE")EOE<E HEHHH>EDAFA_XDLH߹ \XQXAFIFHH@H=EH=EA_XLH߹ \XQAUb fH*hf.EADEAvgXAXLH$QA`DD`DLpR@pLhfDt|HhLeLHpK[H}=\HELHpLSAE _HEHhHxAE \HEHpHhHxMAHhHuHxEf(fT 9f. 9f.EADELHEHxaH}R`fhf.EADEGHEHhHxAAvgXLH߹AXdOA@E HhHuHxAHhHxaHh莤E txHEHuHxEf(fT 8f. Y8HuAOX:JXHNAHEHpHhHxAfH*Ef.hADEHEH]HHpXH}YHhHHxRH߅AHMH9hAH`0HhHuHx蕩A>f.UHAVAUATSHHHHDLGLCpG<<DDMŋGH@M4LspA<<!DǃtAE<s<AoE)`IEHpǃ1f"AE<<.A<r<Ao1)EIFfHEǃA<j<`<C<E< <_<}H` \XHA_XOLAE<7<HEHH`H1EfU< b HhHHH`fw,Lo *fDDGtw,LSHLKPHI‹G(J89lR()HHLDMHAt'&E[$LHLDAH‹BHHM‹BEk8D9rE[(D)`A<<#HĐD[A\A]A^]AE HHLoH)`HpsfDAFtEfLCHDH{PHIAFJ89;R()HHHD HAtQHff.ff.ff.ff.EI$LHHDAH‹BIHM BEQ8D9rEI(D)HhHHHHhHx\HhAEBA_X \XLHeIoH)`Hp EfDMv@R$HHHfDR$HHLfD<UTbLeLmLI|$EI|$(LXX^Ef(fT 92f. 2f.hADEHEHxH}ʝf.`$@I9s DAY8LE{I9s DA D8LElfDAEIEHH@H=EH=EA_X \XfDAF DLH'Ho1ǃfAHE")E_E<E HEHHH>EDAFA_XDLH߹ \XFXAFIFHH@H=EH=EA_XLH߹ \XXFAUb fH*hf.EADEAvgXAXLHEA`DD`DLpb@pLh"fDt|#HhLeLHp PH}PHELHp}LAE _HEHhHxڠAE \HEHpHhHx AHhHuHxEf(fT }.f. E.f.EADE\HEHxVH}`vhf.EADEWHEHhHxAAvgXLH߹AX$DA@E HhHuHxuAHhHxUHhNE txHEHuHxEf(fT Q-f. -HuAOX:JXHvCA"HEHpHhHxvAfH*Ef.hADEHEH]HHpMH}NHhHHxH߅AHMH9hAH`0HhHuHxUANf.A_X \XB[ff.UHSHHHHLPLWpPtVt9LHm1҅xHHiHC0H]P,LP f@tp,LKH@(HLCPIыJ89R()HHL HЀt@~fff.ff.ff.I$HHLuCH‹BHHI BDQ8D9rˋI(D)R$HHLvfDI9s t8LEDPLPfDUHAVAUATSHH HHDLhLopPtotRD "t/LuLe LDLDHfM "H [A\A]A^]D`,DLh @tD`,LCHD@(HH{PIЋJ89R()HHH HЀtNDff.ff.ff.ff.I$HHHuCH‹BIHI BDI8D9rˋI(D)R$HHHhfDI9s tD8LE@D`DLh@UHAVAUATSHHHDLoLkpG<<t\DD "t_"Ls0DuqMiLH K&`H1[A\A]A^]3  "O,Lo uHA}RXHD[IXA\A]A^]&>fDMiK&`u[A\A]A^]DDGtO,LSHLCPHI‹G(r89R()HHLDHAt>ff.ff.E[$LHLDAuHH‹BHHM‹BEc8D9rE[(D)R$HHLqfDI9s DAt8LEQHLh<ff.UHAUATSHHHHDLhLopPtPDLHVhxXLHGhHHiHC0HH[A\A]]kD`,DLh HLgyAfX \X"H1[A\A]]D@tD`,H{HD@(HLCPH׋J89R()HHL HЀtNDff.ff.ff.ff.I$HHLukH‹BIHH NjBDI8D9rˋI(D)A}RXLXHDLH[A\A]]-;DR$HHL@fDI9s tD8LEC@D`DLh+ff.UHAUATSHHHHDLhLopPtPDLH6fxXLH'fHHiHC0 HH[A\A]]KD`,DLh HLeyAfX"H1[A\A]]f.@tD`,H{HD@(HLCPH׋J89R()HHL HЀt.fDff.I$HHLukH‹BIHH NjBDI8D9rˋI(D)A!_XHDLH߹ \X[A\A]]-9DR$HHL`fDI9s tD8LEc@D`DLhKff.UHAVAUATSHHHLnLopF<<t}A "A}RXDMiLs0I`HH11H@ DLHIdž`HD[A\A]A^]DDf, "A}RXDLn }LXH[A\A]A^]7AFtDf,LKHDLCPHIF(J89R()HHLDHAtLff.ff.ff.ff.ER$LHLDAuHH‹BIHMBEZ8D9rER(D)R$HHLcfDI9s DAt%D8LE>fAWdXDD`DLhff.UHAWAVAUATSHHHHDLhLopPDLHaHCpDPHRLa@E1"uAfX \XHDLH[A\A]A^A_]C5@tD`,H{HD@(HLCPH׋J89R()HHL HЀt>ff.ff.ff.I$HHLuCH‹BIHH NjBDI8D9rˋI(D)R$HHLxfDI9s KD8LEAGtEwHsHDH{PHHAGJ89R$HHHDHAt?mff.ff.ff.E@$LHHDAu0H‹BIHLƋBEH8D9rE@(D)I9s DAtuD8LEYf.A}RXLXEwDM+@R()HHH@D`DLh@DpDLx@UHAWAVAUATSHHHHDLpLwpPYDLHN^HCpDPHRL"H 1[A\A]A^]f.@tD`,H{HD@(HLCPH׋J89riR()HHL HЀt"DI$HHLukH‹BIHH NjBDI8D9rˋI(D)R$HHL뗐AfXDEeDMmAUI9s sD8LEA!_XDAEtEeH{HDLKPHHAEr89;R$HHLDHAtO}fDff.ff.ff.ff.ER$LHLDAu0H‹BIHLNjBEZ8D9rER(D)I9s DADIjHiɈLuI<gLH LDLDHq H [A\A]A^]@D`DLh@R()HHL@AUD`DLhAUfff.UHAWAVAUATSHHHHDLxLpPDLHULHULs0LcIiňA ;HCpDPHRH HKp<6<.DDIfA9fA<W"j1lD`,DLx HLUK"uAfX \XDLHH[A\A]A^A_])@tD`,H{HD@(HLCPH׋J89raR()HHL HЀtkI$HHLuSH‹BIHH NjBDI8D9rˋI(D)R$HHL럐qLIfDI9s [D8LE"AH@L{HH HMiHHDž(H(HK<.jaHPLHL(AL-u ANIF1I t2+:wdHHuLtQHHuօ 1LL{L0HL L4fLLL0*zLLH LHI9tLyDHLDL2gH[A\A]A^A_]D`DLx@EgDM@R()HHLe@MiHPIImXHH1{xH(HDž(K<.LL_M>1=@R()HHH@I9L1x A`hX \XLAqIy DAdX \XDL1LL0L zL LafD0%b  \H8H(JH8HpH@H HP0hH8HxwH8wfD"ASX \XDLpLH2D`DLxAgXNXHHnH8H(y\IQAAAqH| SH8H(AH8Hx83H8v IHWH8H(H8HxH8nvH8H(H8HxGvH8Hx7vH8+vH8H(H8HpHx谧Lff.UHAWAVAUATSHHHHDLpLwpP6DLHKLHKL{0LcIiÈEAAHCpPHRL$LcpA$<<}A$fA<$MB<aAdX \XLHĘH[A\A]A^A_]XD`,DLp HLJ"aE1HĘD[A\A]A^A_]f@tD`,H{HD@(HLCPH׋J89R()HHL HЀt>ff.ff.ff.I$HHLucH‹BIHH NjBDI8D9rˋI(D)R$HHLxfDAt$Md$A$tfDI9s D8LEA!_X \XDLYf.AfX \XDL9f.AD$tAt$H{HLCPHHAD$J89R$HHLDHAtKEI$LHLDAu0H‹BHHL NjBEQ8D9rEI(D)I9s DAhI&tzEL$L ~MLHLMtrLHHLLH; LHHHMiK<7bED`DLp&@AD$It$Md$fDIL$LP1mXLLHpLrLHHafR()HHLh@"A`hX \XL5fDAt$I AgXNXHHA$pL`A$IT$AD$At$LdfDUHAWAVAUATSHHHHDLhLopPMDLHFUHLFH{0HcHi THCpPHRL<ЋL{p$A<p<-$fA?OA<<HiɈAH<7bHHDž8I H[H8LbiL!cHHff.BH0 vHH(yoH(H@H H8H-uOHG1tD+:7LHuH HHHuąR1 pH`H$ Lu5VMLh HPLHfo@HEHpEfo`HEE)Ef%f fE f.D`,DLh HLFD"1Hĸ[A\A]A^A_]D@tD`,H{HD@(HLCPH׋J89R()HHL HЀtZLfff.ff.ff.ff.ff.I$HHLH‹BIHH NjBDI8D9rNjI(D)R$HHLXAfX \XDLHĸH[A\A]A^A_]LAGM$H(lH(HH`Hk fD1HϺ QnH@H J1&nH` DI9s D8LEH LIaLLHD$DA!_X \XDLAG"$ACYX \XLAGt AG$$LCHLKPHIAGr89R$HHLDHAtGqfff.ff.ff.ER$LHLDAu,H‹B$HMBEZ8D9rER(D)I9s DAt\$8LEfA?MA9GD`DLhR()HHLpLx$PHHNXHAgX)UHAWAVAUATSHHHHDLADLGpA<<AH@IAEt AEllHsHH{PHHAEJ89BR$HHHDA'?f.ff.ff.E@$LHHDAH‹BIHLƋBEP8D9rE@(D)I9s DAD'IYI9s DA8ALEMDlI9s DAlIqNMA9EA}"E1E~DMvAAbX \XLHĨH[A\A]A^A_] AEMmlAUfEFtDNH{HDLCPHHNjFJ89R$HHLDAER$LHLDAuXH‹BIHLNjBEZ8D9rER(D)AvI~ f.AT$It$ H`9s DA]D8HD`H`At$Mt$ R()HHH@R()HHLH@R()HHH@" H`AZX \XD1AEtEeHsHDH{PHHAEJ89R$HHHDALDff.ff.ff.ff.E@$LHHDAuPH‹BIHLƋBEP8D9rE@(D)DNDHFH`hDI9s DAD8LEvfDAR()HHLg@AEqRA1pLHAvf.IVAFAvH|Nf.AU|fDIL$AD$AT$HtwIT$AD$At$LtASYX \XDLf.R()HHH@DxDLpAJPL`Adf.HLhlAUAEK'IHйDHDH@H`Hй3HоfH`DPLxAUQAD$TpL`hA$LPH81ҾUGDLL`Hh/,HhHXL`HiшHHHp EALDAQXH߹VX@ADxDL`SAnIXNX1Ҿ@UGH`Lh+LhH`I@A$hLDAWH߹AXAdAQXLH߹AXA@LDAIXH߹IXxADhAWLH߹AXDPALeHLhLB LDHDHhfM HHNXHAgXAff.UHAWAVAUATSHHHHDLpLwpP6DLH;LH(L{0HHHHiEAAuHCpDPHRH HKp<<XDDIfA9A<y"u_A`hX \XLHĨH[A\A]A^A_]D`,DLp HLV"E1HĨD[A\A]A^A_]f@tD`,H{HD@(HLCPH׋J89riR()HHL HЀt"{I$HHLu[H‹BIHH NjBDI8D9rˋI(D)R$HHLfDqLIfDI9s D8LEAH@LLSpA<<DfA:t/A<v$"A`hX \XDLAA<fA9i<1AABIqIyvA!_X \XDLfAfX \XDLf.DAtqLCHLKPHIAz89R$HHLDAtSff.ff.ff.ff.ER$LHLDAu0H‹BHHMBEZ8D9rER(D)I9s DA8LEABtEbH{HDLCPHHABJ89CR$HHLDHAtO}fDff.ff.ff.ff.ER$LHLDAu0H‹BIHLNjBEZ8D9rER(D)I9s DAD8LEPfD<AyH=EML8H@:@H@L8HL@ L@IM2A<<fA:s<*AB)ArMb fff.LL@葏 L@HHLiHLK<7*4fD`DLp@EbDMR>@R()HHL@IImX1HPL@E>HP?L@If.R()HHL@AgXNXHHAqIy \IrMbAdX \XL<ERL]ML@LMS>L@H@IJmX1LPL@LJ=L?L@H\ABWkXLPLL@=L>L@HLLHZ=HH \XDAdXpLHD`DLPTIQAAAqH|+IHIRABArLdsUfHSHHuH)E@HMHS㥛 Hiu@BHǃHH?HH)HHH]f.UfHSHHuH)E^@HuHS㥛 HiM@BƃHH?H4ׂCHH)HHHHH]fff.UfHAUATLeSLHHH)E?HuHS㥛 HiM@BHH?HHH)HHH)fH* H^^^HfH*YLp`Lh蝜 E1LLA _LWh`^^;"ugHǃHĈ[A\A]]ÐHЃfHH H*X fHHfHH H*X@ pX:{f.UHAWAVAUATSHHHHDLhLopPtQDPfA}tZ41AmJX \X"eHĘ[A\A]A^A_]D`,DLh fA}AUuA}H=|MHv;A}EuL5|ML9Hƹ YXL蒉 HS0A}Lc0u!AE I}AOX?XMiIAA%=hI?HX);2 HXƸD"tEI?T:HXTu&I?:HXTtfIiΈTHXHр I?HHc:HXTtRHHhuA@ Ј@Lu5+|MLc SIiƈDŽh tuMiB2߃tL}L`LLLHcN DLDLHf@tD`,H{HD@(HLCPH׋J89R$HHL HЀtDfff.ff.ff.I$HHLH‹BIHH NjBDI8D9rNjI(D)HS0Lc0R()HHLT@AUfDAQAXVXHĘDLH[A\A]A^A_]fDI9s DI AEI} oI}cAEH|UDLeLL1 IXLHߋABXAEIUAEAuLt!DLeLLі IXLHߋA9X~AU@fDD`DLhAU!AuMu IuMuI?=7HĘH߾[A\A]A^A_]T I?7fUHAVAUATSHH HHDLhLopPt6DPt?1"wH [A\A]A^]f.D`,DLh AUuLufL)E8HuHiM@BLHS㥛 HH?H4ׂCHH)HHHHK LDLDHH [A\A]A^]fD@tD`,H{HD@(HLCPH׋J89R()HHL HЀtNDff.ff.ff.ff.I$HHLukH‹BIHH NjBDI8D9rˋI(D)H DLHA4nX[ \XA\A]A^]+R$HHL@fDI9s t'Dt IAUfDD`DLhAUUHAVAUATSHH HHDLhLopPt6DPt?1"H [A\A]A^]f.D`,DLh AUuLufL)E5HuHS㥛 HiM@BHH?HH)HYHHfH*HifH*\ [L^^蓒 LDLDH+H [A\A]A^]fD@tD`,H{HD@(HLCPH׋J89R()HHL HЀt:ff.ff.I$HHLH‹BIHH NjBDI8D9rNjI(D)H DLHA4nX[ \XA\A]A^]R$HHLPfDHȃfHH H*HHXHHƒfHH H*XI9s t'Dt IAUfDD`DLhAU|UHAVAUATSHH HHDLhLopPt6DPt?1"H [A\A]A^]f.D`,DLh AUuLufL)E2HufLHS㥛 HiM@B fHH?H4ׂCHH)HHHH?H*HH)H*f(YY\^^X讏 LDLDHFH [A\A]A^]f@tD`,H{HD@(HLCPH׋J89R()HHL HЀtNDff.ff.ff.ff.I$HHLukH‹BIHH NjBDI8D9rˋI(D)H DLHA4nX[ \XA\A]A^]R$HHL@fDI9s t'Dt IAUfDD`DLhAUUHAVAUATSHH HHDLhLopPt6DPt?1"H [A\A]A^]f.D`,DLh AUuLufL)E.0HufLHS㥛 HiM@B fHH?H4ׂCHH)HH+0HHH?H*HH)H*f(YY\^^X LDLDH菸H [A\A]A^]f@tD`,H{HD@(HLCPH׋J89R()HHL HЀtI$HHLukH‹BIHH NjBDI8D9rˋI(D)H DLHA4nX[ \XA\A]A^]+R$HHLpfDI9s t'Dt IAUfDD`DLhAUHHLXL_pPPB<AYC,UHH f)E)Et?Hc‰fHiMbH&)ifnifnfbfffb)EHu11-p,LX AB<L1"-@AC }ASH@@tp,LOH@(HLWPIыJ89R()HHL AHЀtOfDff.ff.ff.ff.I$HHLuCH‹BAHHI BDY8D9rʋI(D)fR$HHLffDID9s Dt]t@I AvgX \XLkɉAIXVXLRfApLXAf.AIXVXL ff.UHAVAUATSHHHHLPLWpPt7Pt>1AdX \X"H[A\A]A^]Ðp,LP AuAB MjI`NH[A\A]A^]@@tp,LCH@(HLKPIЋJ89R()HHL HЀtHf.ff.ff.ff.I$HHLukH‹BHHI BDQ8D9rˋI(D)AQAXVXHHL[A\A]A^]l@R$HHLFfDI9s I]f.LufIS㥛 L)E)HuHiM@BHH?IHH)HHHHIHIffL)E;)HuHiM@BHH?IHH)HHHHIHL9iMtH_ftfDAzpLPA]f.UHAUATSHHHHDLhLopPtxDPAEfA}f=ughMA9Eu[DLH輲 HHDLUQ HMD`,DLh AEAUfBEmL-fML#HLs HH'H#H[A\A]]1"uHDLHAXX[ \XA\A]]f@tD`,H{HD@(HLCPH׋J89R()HHL HЀtBff.ff.ff.I$HHLH‹BIHH NjBDI8D9rNjI(D)f=uAE9gMcAEt1IuMm@R$HHL8fDAuI f.I9s t'Dt IAUfDD`DLhAUzIUAEAuLl f.UHAUATSHHHHDLhLopP-txDPAEfA}f=ugeMA9Eu[DLH̯ HHDLeN HMD`,DLh AEAUfREmL-dML!HLp HH$HA EH[A\A]]1"uHDLHAXX[ \XA\A]]f.@tD`,H{HD@(HLCPH׋J89R()HHL HЀtBff.ff.ff.I$HHLH‹BIHH NjBDI8D9rNjI(D)f=uAE9dMSAEt1IuMm@R$HHL8fDAuI |f.I9s t'Dt IAUfDD`DLhAUjIUAEAuLlf.UHAWAVAUATSHHHHHDLhLopPtDDPtTtO1AYOX \X"HH[A\A]A^A_]fDD`,DLh AUuHK0Lc0$MiIAA%=I?HM1 : HMƸD"t0I?uHMuuI?HMuIiֈuHMHʀ I?HUHMHcutPHUhuB@ Ȉ@LuH1fIiƈDŽh ULLuL@~ LDLDH踩HH[A\A]A^A_]f@tD`,H{HD@(HLCPH׋J89R$HHL HЀtDfff.ff.ff.I$HHLH‹BIHH NjBDI8D9rNjI(D)AE =I}AOX?XHHDLH[A\A]A^A_] R()HHL,@MiB1I9s Dt}IDLeLL| LH߹IXABXuHH[A\A]A^A_]fDLeLLa| IXLHߋA9X5{AUMfDD`DLhAU.AQAXVXI?mI?HHH߾[A\A]A^A_]: UHAWAVAUATSHH"vfHu)E(HMHS㥛 Hiu@BHǃHHHH?L`HLcpH)HHP-PtAD$LAH踦 5]M11IAD$IDxH@MtL.{ HUMH~IFD5 ]MfAVH@M|Et$Lz HTMHIGfAGDH@I|rz AD$HH@It< HD LHH[A\A]A^A_]fD@tp,LCH@(HLKPIЋJ89R()HHL HЀtDfff.ff.ff.I$HHLH‹BHHI BDQ8D9rNjI(D)"t'1H[A\A]A^A_]fD1AbX \XLHH[A\A]A^A_]fR$HHLfDI9s tNIfDp,L` A$ofAgXNXHH[A$tA<t <uzA~tsFH@M<A>rEvL5TMLHLa ILLA>IcLmLr LDLDH7H([A\A]A^A_]AGtEgHsHDH{PHHAGJ89R()HHHDHAtAff.ff.E@$LHHDAH‹BIHLƋBEH8D9rE@(D)R$HHL3fDR$HHHZfDA4nX \XDLfAF#)IVAFAvLtyDI9s DAD8LEfDI9s DADIEgDMASMA9FDLHݝ HLDHv< IfDDhDLp@AAvI fIvMvYDD`DLxAUHAWAVAUATSHHHHDLNLOpF<<DEMfA>tA<t<A~FH@MA>[EvL5PML HLe] IfA?A?dEL=YPMLY HL.] HH޺LKH L H[A\A]A^A_]EFtDn,H{HDLCPHHNjF(J89JR()HHLDMHAt=tff.ff.ER$LHLDA<H‹BIHLNjBEZ8D9rER(D)AGtEgHsHDH{PHHAGJ89R()HHHDHAtI@ff.ff.ff.E@$LHHDAH‹BIHLƋBEH8D9rE@(D)R$HHLfDAXX \XDLRf.R$HHH2fDI9s DAiD8LEfDI9s DAiD8LEfDOMA9FDLH% H,DLH7 IfDNMA9G DLHݘ H;HDLv7 HfDAFt_IVAFAvLtEgDM@AGt/ucIWAGAwL|DAvI EfAwI lfDhDLp@IvMvIwM5D`DLx+@UHAWAVAUATSHH8HHDLFLGpF<<DEMfA>tA<t <uzA~tsFH@MA>2EnL-oJMLoHLDW HH}xH}IM|L;A>Hu AFwLuLLe DHLDLГE,UHZ{  HEH(HEHpH@H HP0 HEHx,H}#fDAGtEgHsHDH{PHHAGJ89R()HHHDHAtY0fff.ff.ff.ff.E@$LHHDAH‹BIHLƋBEH8D9rE@(D)R$HHLcfDR$HHHBfDA4nX \XDLfAF#)IVAFAvLlDI9s DAD8LEfDI9s DADIEgDMAHMA9FDLHݒ HHDLv1 HfDDhDLp@AJAvMn IvMn 8HEH()HEHxH}D`DLxALuLL1c HEH(HEH(HEHxLUH}HEH(zHEHxHEHxH}RHEH(CHEHpHxW4ifUHAWAVAUATSHHHHDLOLKpG<<t;DODM΀t;"1HĨ[A\A]A^A_]@W,Lw AuŋGH@IHPH;ff.UHAWAVAUATSHHHHDLOLKpG<<tCDlMDOtE"1Hĸ[A\A]A^A_]G,Lw lAuGH@I"1H0[A\A]A^]fw,LO fA9uȐff.GH@I~F tHFIuxEAEx<3<D>DF :HFIEA<<D>F HFIEA<P</D>F HFIEA<<D>F zHFIEA<x<WD>DF :HFH}LmELH# LDLDHOGDAUfDpLhAUfEfDMvAR$HHHZfDA4nX \XDL fI9s DAt=Dt&IvAdXDLH߹ \XksAOD`DLpA7DAEtAM,H{HLCPHHAE(r89R$HHLDHAt=df.ff.ff.EI$LHLDAu)H‹BHHL NjBEQ8D9rEI(D)I9s DATIR()HHL?DAE2tAMDLCHH{PHIAE@r89R$HHHDHAt@gfff.ff.ff.EI$LHHDAu)H‹BHHM BEQ8D9rEI(D)I9s DAuDIAEDMM8AAAdX \XDHai.PLHAR()HHHDAEJtAM\H{HLCPHHAEXr89R$HHLDHAt/Vff.EI$LHLDAu)H‹BHHL NjBEQ8D9rEI(D)I9s DAtxI"AAE\MMPAPLHADHHR()HHLAEtIuhAPLHADHqH5AIDHEHAIAIDHHAI+DHHAIDHHUHAWAVAUATSHHxLHDMHLOpA@<<t=DDLf?tB?t=" 1Hx[A\A]A^A_]DAp,Ix f?u@A@H@I4Hsp<<DEId"uA4nX \XDLHxH[A\A]A^A_]e@DA@tAp,H{HLSPHHA@(J899R()HHLDAt2ff.E[$LHLDA4H‹BHHLNjBEc8D9rE[(D)EFtDfLCHDLKPHIFJ89R()HHLDIHAtEff.ff.ff.ER$LHLDAH‹BIHMBEZ8D9rER(D)R$HHLfDAmX \XHQR$HHL;fDH9s DA8HEgI9s DADOIǀff.FH@L4LspA<u<uDAAF  LA9N< ?GHLHHpHxHxfEI~)E)EAVuAF,I~ %G HGIv0EAF0<<DAV0F HFIvHEAFH<<D>F HFIv`EAF`<<D>F HFIvxEAFx<<D>XF NHFIEA<<D>F HFIEA<<wD>F HFIEA<,< D>F HFIEA<<D>XF NHFHhAE1HxEH@LHH"HpHMHHIHAuLDDfDL~AC"AbX \XDLCDpHxfDAFtEnHsHDLCPHHAFJ89R()HHLDHAt-fff.EI$LHLDAuXH‹BIHL ƋBEQ8D9rEI(D)ARR$HHLrfDI9s DAtiDtRIEnDMvA~D`DLxALHAJDhDLpA2HAdXHD \X^HAdX \XD^GSHOHpEGHDHpGHxDAFtAN,LCHLSPHIAF(r89R$HHLDHAtFlfff.ff.ff.$HHLDAu(H‹BHHI1"tDA4nX \XX@tP,xuUH8]ff.U1HHHVVVVVVhVlVdV`VVVVVVDWL@蠭fUHAWAAVAUATSHHx"HxHpDlFHC `HELeLufDH`L聟 HExhP|H9L:$tfup|LLm HELpiR LDHDHx8tDlLHHp8[Hx[A\A]A^A_]@HjHPqfHPpYHxHT LDH`x趠 xHx[A\A]A^A_]fHhHX m HH`.B HHHxHAgX[NXA\A]A^A_](UUHAUA03XATLeSHHG0HX0 HfDLH՝ thHE؋HP!trҾWXA03XIDx tAhXHxHAmXVAPEXHILEϿ@1YH^Lm uH聟 He[A\A]]ÐҹWXA03XID̀x tAhXHHPX1Q@1I赪XZ.ff.UHAWAVAUATSHHP +HgIHPA LHhH` 蹛 H`fH`Hx荜 HxDh EtՃxP$@XDžxfxL@ff.L(LHPLI݉M)Hh HxLL)HhH:HX̨HX11҉z oXHHHX1ȧHXHULEHH: L<A kX5jXLHEȺGXW1LELE{nXnXWMAroXAA LD111aLLcH)LH)IIH9r4N$ HLMI$HU荟HULMHHL<A AroXLLM{nXnXWIE1VLM{nXAroXVjXWMAA @LD111诞LLcH)LH)IHH9r4N$HLEI$HU۞HULEHHL<A @roX{nXLHEȺVjXW1LE襞LEMAmXAA wLXcXW111LLcH)LIHH)H9r4N$HLEI$HU$HULEHH5L<A mXwH XcXLW1LELELMLAH)H)H,w+H,HHULb+褝HUHHL<LeXdbX1W臝MG+AG+LMI)L)H%w#HI%Mg$IHHpN8LǹkXkX1WLE,LELIx$A@$II)L)H(w#HI(Mg'HHJ<8cXkX1H}WМH}LL'G'LH)H)H.w+H.HHULb-苜HUHHL<LJX1@WnI-AG-LII)L)H+w#HI+Mg*0HHJ<81cXH}@WH}IE0A5jXG*0L*yAkX|_XW111lLLcH)LH)IHH9r4N$HLEI$HU蘛HULEHHL<IE05jX0ykXL|_XW1LEaLEIE0cXWMA5jXA0kXLD111跚LLcH)LH)IHH9r4N$HLEI$HUHULEHHL<IE0kXLLEcXW05jXHE1誚LELMLAH)H)H+w+H+HHULb*fHUHHL<LcX>eX1WIMG*AG*LMI)L)H)w#HI)Mg( HHUN8Lǹ5jXveX1WLELELIx(A@(II)L)H)w#HI)Mg(謙HHJ<8jX1H}@W蒙H}_X1D @W1G(L(1LLcH)LIHH)H9r4N$HLEI$HU&HULEHHvL< L_X1@WLELELMMAI)L)HAw#HIAMg@HHN8LǹXX}8X1WLE裘LEIE0kX5jXA5jXA@@0Mx@D0HEF@XLEHhWV111ܗLY^LcH)IBI)L9r0JHLUHU HULUHHkL<IE0hWLLUAkXA5jX005jXMEȃF@XLD1轗LUCI H 0 11I@IHHDT L, HeH[A\A]A^A_]vfDA cDAnXajXLE f.nXajXHE!?X;X15@㺨ܺպκǺ빺벺뫺뤺띺떺돺눺끺wmcfUH]U4pX1HATSLh@I$H YA$ t`1Hu&ID$@HH A$ v8@,聗ID@HHH A;$ r@pX4[A\]f.HI@tpMPHMHPHI ҋPy89I$HHL t-Dff.I$HHLu+H‹BHHI ‹BDY8D9rˋI(D)IA9s At=A8LELI()HHL tIH@PALHLfDUHAWAVIAUIATISHhD>xD|A{^HL4nXHuXA<$ArVXAXu }gXHiAVXAX|HhLL[A\A]A^A_]>}gXH{uA<$tyiXHctOhXHRt~A$ArVXAXtbXH߈w&wt%fDbXHA$tVuAD$tIAbX \X&@bXHÒtċ|LL~ AYXVXHh[A\A]A^A_]FH^ H^sFH\fbXHCWhXH.g_XHA$PwtA|$ul<A|$H=L"H>A<$NA\$HzLHzHƹ YXH fff.A_XDwjXHs~eXH^u:fA<$uAD$;7L; LA~eXLf.mXHKfA<$dA<$AmXS fAD$I|$ VI|$|E1HMLL u }|LLѶ gMfA<$>A<$u AD$|1LLp HA<$uAAD$I|$AD$At$H|.pX TI| \XLA_X:4f.`hXH賏uWfA<$A$A`hX<AD$It$I\$dXHKA<$AdXODLA9D$w|ArVXLLAX9[At$I\$ *|E1HMLLI &}AlX| \XLL9oXH艎uSA<$AoXIT$AD$H|sAt$I|$ EIT$AD$At$H\{vgXH%u%A$<vAvgX(It$BDXHu>A$Pw<<3ffA/D$"ABDXVXyiXH蠍bXH苍u(A$<-<u AD$AbXlXHRA?XH3J~lXH{A<$u A|$A~lX|LL7 DAyiXAX!AD$ tID$ P8H I|$|E1HMLL }AlXAXLLH7A}AEI]<r<VxA|HME1LLEL}w 8fA<$GLA9D$6LL H<<|AEDHL^LHu I<t]<tF|AA|^A|$LA9D$#AD$AMd$봋|LLI랋AAHIG|HLH.AE,AI] xHLlH@UHSHH<t]<t)<<tu< HGH(H]G tHGH(uHGHx2GH{詊@Gt¨uHGH(uH{耊HGH(uHGHx`HCHxSH{JlfHGH([HGHxdH{1fC:HGHpHx读HCHxd< HGH(HGHpH@H HP0z DUHAWIHAVEAUAATISHHLEщLLt uhEbX^XMHEȺE5XH1ȈHL4EL)HMHLH}`X[1A\A]A^A_]鎈fDLP11L E^XHIĸbXWHEM1GLHL4蹈EwALpXLH)LH)1L*pXLcMLLH)H)1HIAtUALLqpXH)AH)1輇*pXLcMLLH)H)1虇LcME9uHغpXLL)H1rHM4UHAWAVMAUEATIHSHHhEHHEHfHnfl)чLHމt AĄQLIظbX^XHE5XHEL1贆HLHEMAFfoHHEƅ)UEQX111JH}HULcHEIIL$I)L)H9r>KKJ#HHEHH9HkHEHHLH}LoX1UH]H]DLHHLLH)кpXH)1HHHcILLH)к*pXH)1wHIAHxADLLpMLDELLLqpXL)AH)1L*pXHILLL)H)1~HID9uMDHxLpHHLLH)кpXH)1~HLHDH`11H߉ ^XHIǸbXHWHEM1M~HLHHH~He~HEHHIT$HT~HH4~HEHLHH%~H?H~HEHHIWH}H>H}HEHHtsIWH}HH}HEHtXLHH}HJ?X;X1}~HPܺSպ8κ:Ǻ><t)<t<t Pv< uHGHG uÐGttUHATIHSH{}HL[HA\] fUHSHHO t H]DHHHAgXH]NXK'ff.UHAVIAUATISBHӍpq HHIŋC5LLHl HŸLHLIEI}fAEAv SIE0HRH45ff.ff.ff.HHH9tNoHSHPSt tkt~tt HSHHHH9uAELLVXA$A\Xf%f fAE[A\A]A^]%D_V@ GD[LAgXNXA$I$HA\A]A^]%DE薲 H_L 6ff.UHAUIATSHHFp HIIċC5LLH HLH=ID$I}0F@XfAD$ϫ I|$# SID$0twHRH4fff.HHH9tSoHSHPSt tstt HSHHHH9uAD$AVXLA\Xf%f fAD$HL[A\A]]5$DWN@ ?f.AAgXNXIHDEְ HL :ff.HHHLXL_pPt't LËP,LX L@tx,LVH@(HLNPIҋJ89rsR()HHL AHЀt+dfDff.I$HHLu;H‹BAHHI ‹BDY8D9rʋI(D)fR$HHL덐ID9s Dt8LEL@PLXff.HHHLXL_pPt?t@<f.P,H@ <f.@tx,LVH@(HLNPIҋJ89R()HHL AHЀtOfDff.ff.ff.ff.I$HHLuCH‹BAHHI ‹BDY8D9rʋI(D)fR$HHLffDID9s DtAPH@ff.HHHLXL_pPt?t@<f.P,H@ <f.@tx,LVH@(HLNPIҋJ89R()HHL AHЀt?}ff.ff.ff.I$HHLuCH‹BAHHI ‹BDY8D9rʋI(D)fR$HHLvfDID9s DtAPH@ff.HHHLXL_pPt?t@<P,H@ <@tx,LVH@(HLNPIҋJ89R()HHL AHЀt?}ff.ff.ff.I$HHLuCH‹BAHHI ‹BDY8D9rʋI(D)fR$HHLvfDID9s DtAPH@ff.HGpHPHRLL_pA<t,<tLfDACM[LfDACtA{LVHLNPHIACJ89R()HHL AHЀtLff.ff.ff.ff.I$HHLuCH‹BAHHI ‹BDY8D9rʋI(D)fR$HHLifDID9s Dt8LEL@PLXfDHHLXL_pPt2tL DH,LX L @tH,LWHʋ@(HLOPIҋr89rkR()HHL2AH@t#[v$HHL0@u:H‹BAHHI4‹BD^8D9rɋv(D)ĐR$HHL땐ID9s D0@t8LEL- DHLXfDHHLXL_pPt2tL鍖 DH,LX Lq @tH,LWHʋ@(HLOPIҋr89rkR()HHL2AH@t#[v$HHL0@u:H‹BAHHI4‹BD^8D9rɋv(D)ĐR$HHL땐ID9s D0@t8LEL靕 DHLXfDHHHLXL_pPtGt*P1vDA{P,LX AD@tx,LNH@(HLVPIыJ89R()HHL AHЀtGfff.ff.ff.I$HHLuCH‹BAHHI BDY8D9rʋI(D)fR$HHLnfDID9s Dt-tIAPLXAf.HHHLXL_pPtGt*P1t AC@P,LX AD@tx,LNH@(HLVPIыJ89rsR()HHL AHЀt+dfDff.I$HHLu;H‹BAHHI BDY8D9rʋI(D)fR$HHL덐ID9s Dt%tIAPLXAf.UHHHHLXL_pPt:tHME1L. @p,LX f@tp,LWH@(HLOPIҋJ89R()HHL AHЀt?}ff.ff.ff.I$HHLuCH‹BAHHI ‹BDY8D9rʋI(D)fR$HHLvfDID9s Dt8LEpLXfDHHHLXL_pPtWt:Pt1tfDACfP,LX AD@tx,LNH@(HLVPIыJ89R()HHL AHЀt7xff.ff.I$HHLuCH‹BAHHI BDY8D9rʋI(D)fR$HHL~fDID9s Dt-tIAPLXAf.HHHLXL_pPtOt"PB<v)P,LX AB<wA{@tx,LNH@(HLVPIыJ89rkR()HHL AHЀt#\fI$HHLu;H‹BAHHI BDY8D9rʋI(D)fR$HHL땐ID9s Dt%tIAPLXAf.HHLXL_pPtRtACt$f.H,LX ACuULHY ]@@tH,LOHʋ@(HLWPIыr89r{R()HHL2AH@t3kfff.ff.v$HHL0@u:H‹BAHHI4BD^8D9rɋv(D)ĐR$HHL념ID9s D0@t8LEfHLXff.HHHLXL_pPtOt*Pt11tAC@P,LX AuA{Ð@tx,LNH@(HLVPIыJ89R()HHL AHЀt?}ff.ff.ff.I$HHLuCH‹BAHHI BDY8D9rʋI(D)fR$HHLvfDID9s Dt-tIAPLXAf.HHLXL_pPtbt=PtDUE1LHHHM萗 1uEfp,LX Au@@tp,LWH@(HLOPIҋJ89R()HHL AHЀtOfDff.ff.ff.ff.I$HHLuCH‹BAHHI ‹BDY8D9rʋI(D)fR$HHLffDID9s Dt-tIApLXAwf.HHLXL_pPtbt5PtA{t7UHhLHD1 ]Dp,LX Atf1"@tp,LOH@(HLWPIыJ89R()HHL AHЀt?ff.ff.ff.I$HHLu[H‹BAHHI BDY8D9rʋI(D)fAbX \XL;R$HHL^fDID9s Dt%tIApLXAwf.HHLXL_pPtbt%Pt,"A1fDp,LX AuAC /ICf""1Ð@tp,LOH@(HLWPIыJ89R()HHL AHЀt?}ff.ff.ff.I$HHLuCH‹BAHHI BDY8D9rʋI(D)fR$HHLvfDID9s Dt]t@IAdX \XL+AQAXVXLAtpLXAWf.UHAUATISH(HHLhLopPt)Pt1H([A\A]]f.X,Lh AUuϾL H I\$PID$HH AEq89I()HHHË5LH}ۺ foEHEHCH([A\A]]@tX,MD$Hڋ@(HI|$PIЋJ89}R()HHH HЀt6ff.ff.I$HHHu[H‹BHHI BDI8D9rˋI(D)R$HHHfDI$HHHfDIA9$s A$t+A$t IM@AU?fDXA$LhAU @ff.UHSHHHHLPLWpPt]fA:tA<t <uTAztMH HHH7H HhH]HCo P,LP 뚐H]1@tp,LKH@(HLCPIыJ89R()HHL HЀt@~fff.ff.ff.I$HHLuCH‹BHHI BDQ8D9rˋI(D)R$HHLvfDI9s t/8LEDHH]AgXNXPLPgff.UHAWAVAUATSHHHHDLhLopPt4DPt="oH1[A\A]A^A_]fDD`,DLh AUuDEtLAG`H IHt5LH5 DLDLHH[A\A]A^A_] @tD`,H{HD@(HLCPH׋J89R()HHL HЀtZ fff.ff.ff.ff.ff.I$HHLH‹BIHH NjBDI8D9rNjI(D)HDLHA4nX[ \XA\A]A^A_]R$HHL0fDLH} LH AWHHRMOfu 7yL9Ft^ASYX \X"[1A\]VHvf=uxL9Ft>uFtff.Hx HHHHJ Hh[HA\]WL N, FtVLCHLKPHI Fy89I()HHLDAAfff.ff.ff.v$HHLDAuHAHHI4ADV8D9rŋv(D)DFtN,H{HDV(HLCPHDX8E9@(E)LHLDAAtHfDff.ff.ff.E[$LHLDADX@ALONEc8D9rE[(D)@AgXNXH[A\]F@$LHLBfDI$HHLnfDD9s DDAHf.H9s DAt8HEPHpfDHȿff.UHAVAUATSHH HHDLhLopPtFDfA}tNAE<B<"]H 1[A\A]A^]fDD`,DLh fA}u"A}AuH5-tLH{0b HH [A\A]A^]f@tD`,H{HD@(HLCPH׋J89UR()HHL HЀtBff.ff.ff.I$HHLwH‹BIHH NjBDI8D9rNjI(D)"HC(HLpLs(MH$ t^IH H{0a LuLb LDLDH躼 H [A\A]A^]D"uH uzAgXNXHHH H[A\A]A^]fDR$HHLfDAEIu 2Iu&AEHtDH{0H0HC(HH DAZX \XDLhfI9s tD8LE5@D`DLhff.UHAWAVAUATSHH8HHDLGLCpG<"<tfDMŋGH@M4LspA<<DAt9t4"H81[A\A]A^A_]fDG,Lo 땐A}uE}L=pLL-HL A}AAUHpLHUtE1AE9|H} =~DLmL LDLDHL H8[A\A]A^A_]DDGtO,LKHLSPHIG(r89R()HHLDMHAtWff.ff.ff.ff.E[$LHLDAH‹BHHMBEk8D9rE[(D)AFtEfHsHDH{PHHAFJ89R()HHHDHAtIx@ff.ff.ff.E@$LHHDA4H‹BIHLƋBEH8D9rE@(D)EfDMvArAMIU IUAMHT AEtG!IuM}fR$HHHfDR$HHLfDAuM} CfH8DLHAYOX[ \XA\A]A^A_]9fI9s DAtu8LEWI9s DAt-DtIQAAD`DLpA"PLhIUAEAuL|YUHAWAVAUATSHH(HHDLGLCpG<<DDMƋGH@M,LkpAE<><DAU1AYOX \X"H([A\A]A^A_]@w,Lw |fDDGtw,LKHLSPHIG(J89R()HHLDMHAtW>ff.ff.ff.ff.E[$LHLDAH‹BHHMBEk8D9rE[(D)AEtEeH{HDLCPHHAEJ89R()HHLDHAtI@ff.ff.ff.ER$LHLDAdH‹BIHLNjBEZ8D9rER(D)A'$fA>A&AFAFI f.I41HfDff.AIʉ Љ1I9uɉ 1Љ4LLb "DEeDMmAUBAE !AQAXVXH(DLH[A\A]A^A_]fDR$HHLRfDR$HHLifDAF fA>HLHJ HI]&HI4L1ff.H‰ Љ1H9u 1Љ4LLC L%DLDLH賲 HfDI9s DA8LEI9s DAtUDt7IENL LhLLMI%@AUtfDD`DLhAUUpLp fDIN1/oXLL $L$HtLI4L1H‰ Љ1H9u\@tIFMv1HINAVAFLt1Jff.UHAWAVIAUATSHLHMPLWpA@<<tcMA@H@M,MnpAE<S< AAMt2A"<1H[A\A]A^A_]Ap,MX A;u:ACt1<u-#gLA9Cu!fA{tA{uA{0u AC2 AAX \XLHL[A\A]A^A_]gA@tAp,M^HI^PHI A@(y89JI$HHHD!At%EI$LHHD AHAHHM ËAEa8D9rEI(D)AEtAUMFHI^PHI AEy89I()HHHD!HAtJDff.ff.ff.EI$LHHD AHAHHM AEQ8D9rEI(D)AUAMmAMI()HHH@I$HHH1fDA4nX \XL%DIA9s AD AtcAtEIfDIA9s AD AtKA8LEAMfDPALhAMpALXAC,IhHIC8 HHLO HLcMLHL(5fdLH踁 I~03bX Q L薁 Ml$(LLH@Hg~ 5 dLHX[ I~0iXP Hp5 At$pH} At$tH}ـ 5cLH} HL菤 Md$ M!LLv HAHt$ALL LfDMHAgXNXLIHAIHNXLAgXfDUHAUATSHHHLXL_pPQhACEEAfA;5ACIs @HG0LeHX0 HfLH HELMtLHx!03XtWXx 03XthXHW1@VEXIiHEA[A]Hx!A03XtAWXx 03XthXHpHAmXAPW@HILEξEX1 AYLAZH 5Hj He[A\A]]f.p,LX fDx!03XtWXx A03XtAhXHH@1QPX1Ix_AXW<O5`LA9C?fA{t A{,A{0!AC2 A{}As,H5H_LMk8H0HMLEDER }HuHlLMtBHt;x!03XtWX{ 03XthXHV@EXP1IY^H03XHHDE {!HtWX{ 03XthXLKmX@MLDHHP1VIо:XQD&H 3AAX \XLkHe[A\A]]@tp,LWH@(HLOPIҋJ89R()HHL AHЀt#fI$HHLH‹BAHHI ‹BDY8D9rƋI(D)fDJAsH5|]LOR$HHLnfDIs$ACHtfDID9s Dt58LEAmX \XL+He[A\A]]ËpLXlACIs!}Is qAC(Htc1{!HtWX{ A03XtAhXHP@X@Q11I1XZf.LHDUHAUATSIYH_pAA<<thDAQDIڀt udABu]AAH@L$LgpA$<<xD[LA\LA]]ރfDAq,MQ A@"#[1A\A]]f.DAAtAq,LWHL_PHIAA(J89R()HHLD"At?.ff.ff.Ed$$LHLD AuGH‹BHHM$‹BEl$8D9rEd$(D)@R$HHLtfDI9s D Ay@Ij[A\AbXA] \XL]DAD$tED$LOHDL_PHIAD$J89R$HHLHЀtKtDff.ff.ff.ff.[$HHLu+H‹BIHIBDc8D9rˋ[(D)I9s D8LEED$DMd$yf.A)R()HHL @pLPAfIHHDD@DL` ff.UHAWAVAUAATISHH89DqL5XLLIIHEH6LHUL"7L}LuLrLLHt H} HLDDL EuHH8[A\A]A^A_]fDALqADyMtPUt~  C uHEH(wHEHpH@H HP0 HEHx3H}*=DDyLq f  HEH(HEHxl H}fDHEH(LyPHEH(HEHxeH}{fDHEH(yHEHxTHEHxGH}>QfHEH(9HEHpHxDHHNXHAgXkUHAWAVAUATSHH8HHDH~H{pF<b<tvDEIFH@Lq EAFDUAFHDU@ DUHIAFH@I"HSHKLHHD@<w& D|EHC0H80AFDHA fҿfnHfpHHff.ff.ff.fnH(fn`5@ff.ff.EI$LHHDAH‹BIHL ƋBEQ8D9rEI(D)DE_ DEDLHH HH[A\A]A^A_]EgDM@R$HHH-fDR$HHL#fD5CLHHE._ HUDjI9s DAD8LEefDI9s DAD8LEZfDf fHHDLHA{DX[ \XA\A]A^A_])fHHHAgXNXHH[A\A]A^A_]ÐDhDLp@D`DLxAlXDLH߹ \X諧fDE1(E11HA*UHAWAVAUATSHLHMZL_pAB<<tfMABH@M$LgpA$<<&fA<$t8A<$t1"t1He[A\A]A^A_]Ar,MJ ƅƅA<$A\$Hs?LAAARfA9AAIq DHG0HA03XHX0 IHL toHHP!ҾWXA03XIDx tAhXHxHAmXVAPEXHILEϿ@1sYL^HV uL Heظ[A\A]A^A_]fDABtAr,LOHH_PHI AB(DA8D9I(D)HHHD!AAt0ff.Ed$$LHHD ASHAAHHM$AEl$8D9rEd$(D)AD$tAT$LWHL_PHI AD$DA8D9I(D)HHLAHȀt:ff.ff.[$HHLgHAAHHI‹ADc8D9rƋ[(D)fD<=LA9AfAyt AyAy0AA2 AyEa,L%fDAmX \XL蓢He[A\A]A^A_]@HeLAmX \X[A\A]A^A_]_ҹWXA03XID̀x tAhXHHPX1Q@1IXZfDID9s Dte8LEID9s DD AtK8LEv!AqH5d:L'PL`nfDpLH+fDIqAAHtfDMHXAAMa!AR()HHL4@pLPAfIHDDHDHXfUHAVAUATSHH LHDMPLWpA@<+<t?DDMfA}tBA}t;"H 1[A\A]A^]Ap,Mh fA}ufA@H@M4LspA<<<DfA>tA<7A}A}H=4LIHƹgXLA VHhH{0LmHH i" LQ LDLDH~ H [A\A]A^]f.DA@tAp,H{HLKPHHA@(J89iR()HHLDMHAt\ff.ff.ff.ff.ff.E[$LHLDADH‹BHHLNjBEk8D9rE[(D)AFtEfHsHDLCPHHAFJ89R()HHLD HAtI@ff.ff.ff.EI$LHLDAH‹BIHL ƋBEQ8D9rEI(D)R$HHLfDAmX \XLH H[A\A]A^]錙@R$HHL*fDI9s DA8LEI9s DAD8LEfDAEtgIUAEAuLl fEfDMv@"MAZX \XDLDAuI fpLhfDIuMmD`DLp?@UHAWAVAUATSHHHHHDLNLOpF<<t~DVEM΀t u{AFutFH@MDDMfA9tBA9t<"HX1[A\A]A^A_]fDw,LO fA9u@GH@M4LspA<<DA"uA4nX \XDLHXH[A\A]A^A_]yfDGtw,LCHLKPHIG(J89<R()HHLDAw/Dff.E[$LHLDAdH‹BHHMBEk8D9rE[(D)A9AqH5{)LH{0 IHHFS HM L}Mtrfff.A5)LLG EAu|H}f%f fE]F AuiH}/G LHk MmMuHl HHQHXALDH[A\A]A^A_]rr fAFtEfHsHDH{PHHAFJ89R()HHHDANff.ff.ff.ff.E@$LHHDAH‹BIHLƋBEP8D9rE@(D)R$HHLfDR$HHHJfDAAIq IqAAHtDMmM+fDI9s DAt}8LE:I9s DAtuDtWI}EfDMvA^AmX \XLlpLHfDA%D`DLpAMHйHHAgXNXHйAgXNXHH@ff.UHAVAUATSHHHHDLWLSpG<<t8DDMfA9tDA9t>"1He[A\A]A^]fw,LO fA9uȐff.GH@M,LkpAE<<<DEEA9cAqH5@%LH{0 IHrAEAU fA}UAmXAEIu IIu=AEHt/DGtw,LCHLKPHIG(J89R()HHLDAtMff.ff.ff.E[$LHLDAdH‹BHHMBEk8D9rE[(D)<$LA9EfA}t A}A}0AE2 A}Au,H5#LMe8HMLELDD^ }HP!03XҺWXHEEx 03XthXHpHAmXQWٿ@HILEξEX1Y^gfDAAXDLH߹ \X7He[A\A]A^]f.AAIq IqAAHt}DAEtEeHsHDH{PHHAEJ89R$HHHDHAt3@ff.E@$LHHDAH‹BIHLƋBEP8D9rE@(D)R$HHLifDHeHAmX[ \XA\LA]A^] @R()HHH>@AuH5!LHC0LeA03XHX0 H@ff.LH% twHEL9uHP!ҾWXA03XIDx tAhXHxHAmXVAPEXHILEϿ@1AYLAZH uH2 He[A\A]A^]I9s DA8LEҹWXA03XID̀x tAhXHH@1QPX1I-_AXDI9s DAtED8LEfEeDMm@pLH+fDD`DLh@MHAEIu!Iu AE(Htx A03XtAhXHHPX1Q@1IBXZKff.UHAWAVAUATSHH8HHDLhLopPtIDPfA}tR%"1H8[A\A]A^A_]D`,DLh fA}AUuA}H=Lk Hv;A}"EuL5LLHƹ YXL+ HCpDPHRLAFEn5uL11AEEDH@L4L1 HH LHIFAE5LEEfAVH@L4L1 H LHWIFAfAFDuKvH< 1 AELH@H4[ Ll IHMhH([A\A]A^A_]IhLa HCA^AMvApALhgDAAIHNXLAgXyjfXALpAYAEI} I}AEH| C H La*C H LAAgXLXff.UHAWIAVAUATSH(HHELOMOpG<<EDM΋GH@I<)EEHGH@HI_p<S<<Ef=fLDEuHM^d HMȋuDErALLEZ uI(L9 H8DuLILuA;H]DeMf.LmMl$`AEIt$HI|$PHHAE J89R$HHHDpHÀE$uHXKAMH<@HMHI5NLHǃ- HLHfAn$IGfAnE fAGHIGIG0fbIG fAG(St]HRH4HHH9tCoHSHPS8uPuɃHDpHfPH9uLLP L-EEHEA;$MH]DeL\ ALQ DHLEH(H[A\A]A^A_]W w,ALw  t8tKtt t $ff.HSH f@ DR()HHHDpHÀD@HH֋J89R$HHHD HAt9gfDff.ff.E@$LHHDAu0H‹BIHLƋBEH8D9rE@(D)HA9$s A$DAtME$8HE$D`I HWLTf.R()HHHDpE$HXDGtw,MGHMWPHIG(J89R()HHLDMHAtF(ff.ff.ff.E[$LHLDAH‹BHHMBA[89rE[() L9CCA"H(1[A\A]A^A_]CtDcMOHDMWPHICz89R()HHLDHAtLff.ff.ff.E[$LHLDAH‹BIHMBA[89rE[()EGtDGIOHDMWPHHGDJ8D9R(D)HHLDAAtL0ff.ff.ff.E[$LHLDAWH‹BAIHLBA[89rE[()MAAgXNXIHH(L[A\A]A^A_]pDGEHOCf C9 LfDDcEH[R$HHLR$HHLR$HHLAHA9s ADAE8HE@IA9s ADAtmA8LEHE9s EDAtPE8HE L9CADX \XDHpALpKD@EHHfD`EHX{HHcfff.UHAWAVAUATSHH8HHDLFLGpF<"<DEMAftA>tf=uLA9FusFH@M<Hh AwjX \XDLH8H[A\A]A^A_]mfDEFtDf,H{HDLKPHHNjF(J89bR()HHLDMHAtUDff.ff.ff.ff.ER$LHLDAtH‹BIHLNjBEZ8D9rER(D)AGtEoHsHDH{PHHAGJ89R()HHHDHAtI0@ff.ff.ff.E@$LHHDAH‹BIHLƋBEH8D9rE@(D)R$HHLfDDLH 1DLHJP HLeHDR$HHHfDAYOX \XDLfI9s DAD8LEfDI9s DA!DIEoDMA<EvL5LLHLLeP HL " LDLDHM H8[A\A]A^A_]@A~H=LH}H}.pXH |AiDD`DLp@AAFt/tDIvMvf5gLA9v;SHs HuMhf= f.&LA9F!HuLD I<<EA $D A|$ AD$I\$<<A|$H=kLH}jH}HƹgXt f;<CHS tHS@ff.I}0HHUp IHLHu8 I<2<rEfA>IhH@ HuLe HfDDf,EH^ @=LA9~GA>A"h1HX[A\A]A^A_]<SH&LfIE8HUII}0H_ IHAIHNXLAgXgwDDAD$tAT$I}HMEPHH AD$q89fI$HHLDHAt2`f.ff.EI$LHLDAu0HAHHL NjAEQ8D9rEI(D)IA9s ADAAEI.DAD$tAT$,I}HMUPHH AD$(q89I$HHLDHAtEsff.ff.ff.E@$LHLDAu0HAHHLNjAEX8D9rE@(D)HA9s ADAA8HEA<$_AD$IT$AD$At$H|LAFtE~I}HDMEPHHAFr89R$HHLD HAtWff.ff.ff.ff.ff.EI$LHLDAu0H‹BIHL NjBEQ8D9rEI(D)IA9s ADAE8LE@AT$AMd$A $DAD$,AI\$ f.E~EMv@At$I|$ I()HHL@I()HHLh@EFtDf,MEHDMMPHIF(J89:R()HHLDHHAt-fER$LHLDAH‹BIHMBEZ8D9rER(D)AFtE~IuHDI}PHHAFJ89{R()HHHDHAtI@ff.ff.ff.E@$LHHDAH‹BIHLƋBEH8D9rE@(D)R()HHL@=7X@1/HU[fDE~EMv@AF;DHLE Hf;u@K9CAwjX \XDHASYX \XDLHXL[A\A]A^A_]`fIt$I|$NR$HHHfDR$HHLfDCHTcHsHuTSH\H]CfDAFDHLB HEA DIA9s ADAE8LE@HA9s ADAE8HE@A $fDALLA_gXVX_HX[A\A]A^A_]@PAL`A $PAHXDDDxELpI@DxELp@D`EHX_L$ff.UHAWAVAUATSHHHHHDLFLGpF<<DEMfA>tA<FH@I HKp<}<MDEHMAH@LLSpA<<<DfA>A.<6HuELDH; 5Kt 5KI5KLmL& LDLDH~@ HH[A\A]A^A_]Df,DLv @EFtDf,H{HDLKPHHNjF(J89:R()HHLDMHAt-fER$LHLDA\H‹BIHLNjBEZ8D9rER(D)<A~H=KLUH}踲H}LUHƹPpXLU LUA>A~H=qKLUH}lH}LUHƹIpXLUn LUDA>A~H=%KLUH} H}LUHƹMpXLU" LUAiXVXHHDLH[A\A]A^A_][1AZX \X"tHH[A\A]A^A_]ABtEjHsHDH{PHHABJ89R()HHHDHAtQff.ff.ff.ff.E@$LHHDAH‹BIHLƋBEP8D9rE@(D)EAtDyH{HDLCPHHNjAr89R()HHLDAtKfDff.ff.ff.ER$LHLDA H‹BIHLNjBEZ8D9rER(D)R$HHLfDR$HHLSfDR$HHHrfDAF{IvI~MfDI9s DAD8LEfDI9s DAD8LE)fDHU9s DAD8HDEHEDyDHAHEEjDMR@AFtIVAFAvH|AvI~ fD`DLp@DxDH@HE!DhDLP7@AvI~ f.IvI~vAFtt=IvI~HMHAvI~ IVAFAvH|uIVAFAvH|UHAWAVAUATSHHLHMXL_pA@<<t;MfA9tAA9t;"1He[A\A]A^A_]DAp,MH fA9uA@H@I HKp<=<eAI̋AH@H4Hsp<W<f>t >ƅƅ>DvL5KA9~AqH5KH{0 IH AD$A$fA<$AmXAD$It$ fff.HC0LA03XHX0蓟 HLH赠 tyHL9uHP!zҾWXA03XIDx tAhXHxHAmXVAPEXHILEϿ@1Z_LAXH< uH Heظ[A\A]A^A_]@A@tAp,LKHLSPHIA@(J89ZR()HHLD"At\ff.ff.ff.ff.ff.Ed$$LHLD AH‹BHHM$BEl$8D9rEd$(D)Ft~LCHLSPHIFJ89R()HHLDHAtDlff.ff.ff.v$HHLDA-H‹BHHI4BD^8D9rŋv(D)DAAtDiLCHDLSPHIAr89ZR$HHLDIHAtGfff.ff.ff.E[$LHLDAH‹BIHMBEc8D9rE[(D)"AmX \XHeH[A\A]A^A_]SR$HHLfD<MKA9D$nfA|$t A|$YA|$0MAD$2 AA|$hA\$,HYKMd$8LHHLDEY IHInXLWoL@nXL;wAG!WX03XHEEA 03XthXMOmXC?X@MLDHIAVPI1QDRH (@AmX \XLmR$HHLfDR()HHL@AAXDLH߹ \XOQHe[A\A]A^A_]I9s D Aa8LEgH9s DAy8HEI9s DAYD8LEmfDҹWXA03XID̀x tAhXHHPX1Q@1IY^fDAAIq |IqpAAHtbDFLv 8Lv,FMt~HvfDDiDLa@pLHfDAt$H5[K.It$!AD$HtfxHpUfDDhDL`@MHAD$I\$!I\$ AD$(H\uA A03XtAhXIAV1ɾHXP@1IgXZEHٺHXLL豣EHٺXL蔣l@ff.LHDUHAUATSIXH_pA@<<t0DAPDIڀt0"|1DAp,MP AuA@H@HH_p<<6DAdX \X"uDHAdX \XL[A\A]]MDDA@tAp,LWHL_PHIA@(J89R()HHLD"AtOnfff.ff.ff.ff.Ed$$LHLD AugH‹BHHM$‹BEl$8D9rEd$(D)@R$HHLdfDDKDH[fI9s D A1IA:>C |IRH9SI[A\A]]fCtDKLGHDL_PHICJ89R$HHLD"HAt G@[$HHLD Au)H‹BIHIBDc8D9rɋ[(D)ĐH9s D ADH{A pLPAf.R()HHL$@AB AQAXVXLHH1IRIH8DAQAXVXDHDHXLHDUHAUATSIXH_pA@<<t0DAPDIڀt0"|1[A\A]]Ap,MP AuA@H@HH_p<<DSAdX \X"uDHAdX \XL[A\A]]IDDA@tAp,LWHL_PHIA@(J89rmR()HHLD"At#BfEd$$LHLD AugH‹BHHM$‹BEl$8D9rEd$(D)@R$HHLfDDKDH[fI9s D A1IJA:VC |IBH9CHIB%CtDKLGHDL_PHICJ89R$HHLD"HAt G@[$HHLD Au)H‹BIHIBDc8D9rɋ[(D)ĐH9s D ADHA9pLPAf.R()HHL @AB AQAXVXL`IH8DAQAXVX!DHDHXLHDUHAUATSIXH_pA@<<t0DAPDIڀt0"|1[A\A]]Ap,MP AuA@H@HH_p<<DSAdX \X"uDHAdX \XL[A\A]]EDDA@tAp,LWHL_PHIA@(J89rmR()HHLD"At#fEd$$LHLD AugH‹BHHM$‹BEl$8D9rEd$(D)@R$HHLfDDKDH[fI9s D AqPIJA:~C IBH9C#DCtDKLGHDL_PHICJ89 R$HHLD"HAtXDff.ff.ff.ff.ff.[$HHLD Au)H‹BIHIBDc8D9rɋ[(D)ĐH9s D ADHkApLPAf.R()HHL@AB wAQAXVXL8HIBlIHDAQAXVXDHDHXUHAWAVAUATSHHLHMPLWpA@<<APMԀtAD$u|A@H@M,LkpAE</<gAUr"u>AYOX \XL@Ap,M` A$n"1H[A\A]A^A_]fA@tAp,LKHL[PHIA@(J89R()HHLD*MHAtN$ff.ff.ff.Ed$$LHLD(AH‹BHHM$BEl$8D9rEd$(D)AbX \XLHH[A\A]A^A_]@f.R$HHL+fD_LAHg# 5%KIAD$IDhH@MKHIGE̾fAOE|$H@I< AD$IuH@I< AD$11H@5|KM,L HKHGIED5KfAUH@M1"H([A\A]A^A_]Df,DH~ f?uff.FH@MfA?qoXLbvgXL bXLkXLlXLz?XLtBDXL.AP<<~lXLl@fDbXLCNA<<u AG3AbXD`hXLfA?A<A`hX<fDH9s DA D8HEfDI9s DAiDI5GLw ;Lw/GMt"EoDMAAmX \XDHf.AbXDoXL}uGA?AoXf.D`DHx@A]vgXLk}AAvgX<NGE1HMDLH贰 AlXDLH߹ \X(fDDhDLxALH DLHW u+kXL|DLH0 AkXAGIwIAP~~lXL^|A?u AA~lX:E1HMDLH襯 }AwI AWSIWAGAwH|~AG t'IG ?8H LABDXVXDI.ffA/GAdX \XDKA9G&ff.UHAWAVAUATISHhHHE$H~I|$pF<<E$EH}FH@H4It$p<<E$EHf={fFH@L4Mt$pA<<E$AkA$"EEHh[A\A]A^A_]DDN,E$HF HE&EFtDN,MD$HDMT$PHIF(J89R()HHLDAtafDff.ff.ff.ff.ff.E[$LHLDAH‹BIHMBA[89rE[()DNK9CCA$"ADX \XDHHhL[A\A]A^A_]#f.EFtDnI|$HDMD$PHHNjFJ89R()HHLDHHAt[ff.ff.ff.ff.ff.ER$LHLDAH‹BIHLNjBEZ8D9rER(D)AFtE~It$HDI|$PHHAFJ89R()HHHDHAtGfff.ff.ff.E@$LHHDAH‹BIHLƋBEP8D9rE@(D)DnE$H^cCfC9KdLDx DxExLxIDE@ff.fA>A>zAFoHuL I<<A$AHuLDL A>uAFuL LHuW I<Y<iA$fA>YKA9FIYR$HHL=fDR$HHLfDR$HHHfDAABtEBIt$HDI|$PHHABJ89VR$HHHDHAt"PDEI$LHHDAu0H‹BIHL ƋBEQ8D9rEI(D)IA9$s A$DAE$8LE_AFtA^It$HI|$PHHAFJ89R$HHHDHAtN|Dff.ff.ff.ff.E@$LHHDAu0H‹BHHLƋBEH8D9rE@(D)IA9$s A$DAA$8LEEBE$MRIA^A$MvHA9$s A$DAE$8HEfHUA9$s A$DAlE$8HDEHE"R()HHH@R()HHH_@IA9$s A$DAE$JI>fK9C@E~E$MvA A4nX \XDLbfD@E$LPXA$Lpt@A$ALLxf;uK9CEHDLL @DhE$HXDHE$H@HEA$LxA$ ADLHL "f.AA$AgXNXI$HGDxE$LpAH}HfUHAWAVAUATSHHHHDLWLSpG<<t6DWDMԀt7"KH1[A\A]A^A_]fw,Lg A$uɋGH@M,LkpAE<<DAUtKAE@A<$u AD$ DLAH߾ Em5KIƺAEEDH@MArVXHLXM1LXEHDXADHELPfA$bAD$HuL H<l<DDH8LHu軧 I<<uDAA$f=k qKA9L$ZoDA:if_:KA9EOZABHELp5KLXL LHHXHu HHHXHuΦ HHsfDAD$tEt$HsHDH{PHHAD$J89R$HHHD HAtTff.ff.ff.ff.E@$LHHDAu0H‹BIHLƋBEH8D9rE@(D)I9s DAD8LEfDA}AEHhH, fDDFtNLKHLSPHIFz89|R$HHLDHAtFv$HHLDAu)H‹BHHI4BDF8D9rɋv(D)ĐH9s DA8HEI9s DAD8LEOfDI9s DAD8LEfDNHv\fDEt$DMd$|f.KA9EA:]A]XVXDR()HHL}@R()HHH1@HHNXHAgXh]A:ƅnE1HnDLHLX LXKn>@AlXDLH߹ \XfHHp$fDDpDL`F@DpDLPj@DxDLh}@DLPDXDHfUcKA9D$DLchAϋAA$< <EA|$A`hXLH߹ \XDLPDXDHd֔KA9EXAUIuFDHLXlLXH5DA}fff.ArVXAXDLJAlXAXDLHA6@FHvHLPX_IH{XLP H@IHHH}LIă%>>4JIԹRXE1A$AXLL޴LH)HL>HHHHLH)H9r7L4HHI&>HHHLIă@=_IIԹpXE1A$Ac8XLL9LH)HL$>HHHHLH)H9r7L4HHI=HHH2LIă[<HIԹkXE1A$A<;XLL蔳LH)HL=HHHHLH)H9r7L4HHIIԹ&hXE1A$A5XLLثLH)HL5HHHHLH)H9r7L4HHI 5HHHLIă9=IԹ&hXE1A$Am3XLL3LH)HL5HHHHLH)H9r7L4HHI{4HHHLIă5;Ґ<IԹbXE1A$A3XLL莪LH)HLy4HHHHLH)H9r7L4HHI3HHHٞLIăP:<IԹBhXE1A$A5XLLLH)HL3HHHHLH)H9r7L4HHI13HHHLIăk9ُ:;IԹIhXE1A$A6XLLDLH)HL/3HHHHLH)H9r7L4HHI2HHHLIă8e:IԹ9fXE1A$AXLL蟨LH)HL2HHHHLH)H9r7L4HHI1HHH;LIă7t9IԹ`XE1A$AXLLLH)HL1HHHHLH)H9r7L4HHIB1HHH{LIă6;8IԹQXE1A$AXLLULH)HL@1HHHHLH)H9r7L4HHI0HHHBLIă5{7IԹQXE1A$AXLL谦LH)HL0HHHHLH)H9r7L4HHI/HHHLIă4 7IHA$LLLADAN-DkXE1HLLLLH-HHHHI)L)H9rBIHHHH--HHH:LHUtAEHkHHAAH5OLIHLHoA`YLMv'tAEA$&IAOIAfXA$EO!LH訢LLH)H,HHHHLH)H9r7L4HHI+HHHLIăQtAEA$%MA AAOIAnXLEO!HMLI)ڡL+LHHHLL)H9r1N4"HHI/+HHHN $tAEAIAIGAW!ƅEGIHt18t,LMLjRHAYAZLLML*I)LHHHLL)H9r1M4HHIU*HHHN UtAEAO$IGIƅAW!EGAIHtA8ttAEAbIAIGAW!ƅEGIHt18t,LMLjRHLAYAZLML" I)LHHHLL)H9r1M4HHI|HHHkN \stAEA~OIGIƅAW!EGAIHtA8tEtAEA$A<MAOIAfXA$EO!LHdLLH)HHHHHLH)H9r7L4HHIHHHVLIătAEA$x;MA AAOIAnXLEO!HMLI)cLLHHHLL)H9r1N4"HHIEtAEA$A,MAOIAfXA$EO!LHLLH)HLHHHHLH)H9r7L4HHI=HHH<LIătAEA$+MA AAOIAnXLEO!HMLI)'LLLHLL)HJH9r1M4HHI|HHH;N )tAEAE/IAIGAW!ƅEGIHt18t,LMLjRH5MAYAZLLMLHI)LHHHLL)H9r1M4HHIHHH:N R1tAEAb*IGIƅAW!EGAIHtA8tEtAEA$A'MAOIAfXA$EO!LHGLH)HLHHHHLH)H9r7L4HHIMHHHT6LIătAEA$l&MA AAOIAnXLEO!HMLI)7FL/LHLL)HJH9r1M4HHIHHHx5N $tAEAh)IAIGAW!ƅEGIHt/8t*LLMjRHEGLY^LMLZI)LHHHLL)H9r1M4HHIHHH4N T3tAEA$IGIƅAW!EGAIHt@8t;IHt/8t*LMLjRH\FLXZLMLqI)LHHHLL)H9r1M4HHIHHH3N btAEA#M$A$IIǠHmHLH HH0 I:$tAOEO!AbXLHCLLH)HHIHPLH)H9r7N4HLILHH3LIAIEI|$LLHI$DH)ITH)DITHIEI|$LHI$ILILLH)H)HBf.IEIzLHIILILLH)H)H@IEIzLHIILILLH)H)HG@IEIzLHIILILLH)H)HN@AEA$DATATfDAEA$ALALWAEAALALAEAALALAEAALALLH5HA`pgLM{@A>EtAEA$AP!MAOIAfXA$EO!LH@LH)HLHHHHLH)H9r7L4HHI=HHH/LIătAEA$ MA AAOIAnXLEO!HMLI)'@LLHLL)HJH9r1M4HHI|HHH.N tAEAk#IAIGAW!ƅEGIHt18t,LMLjRH5ALA[A\LMLHI)LHHHLL)H9r1M4HHIHHH-N RItAEA@IGIƅAW!EGAIHtB8t=IHt18t,LMLjRHJ@AYAZLLML]I)LHHHLL)H9r1M4HHIHHH,N FtAEABM$A$IIǠHiHLH HH0謲 I:$tAOEO!AbXLH=LLH)HqHIHPLH)H9r7N4HLILHHi,LIAIEI|$LLHI$DH)ITH)DITHIEI|$LHI$ILILLH)H)H:fIEIzLHIILILLH)H)H@IEIzLHIILILLH)H)HK@IEIzLHIILILLH)H)HN@AEA$DATATfDAEA$ALALWAEAALALAEAALALAEAALALLH5HA}gLMx@AVEtAEA$AMAOIAfXA$EO!LH:LH)HLHHHHLH)H9r7L4HHI-HHH&)LIătAEA$MA AAOIAnXLEO!HMLI):LLHLL)HJH9r1M4HHIlHHHJ(N htAEAnIAIGAW!ƅEGIHt08t+LMLjRH%;L_AXLML9I)LHHHLL)H9r1M4HHIHHHV'N SJtAEA\IGIƅAW!EGAIHt@8t;IHt/8t*LLMjRH;:LY^LMLPI)LHHHLL)H9r1M4HHIHHHR&N  tAEAM$A$IIǠHlHLH HH0蟬 I:$tAOEO!AbXLHy7LLH)HdHIHPLH)H9r7N4HLILHH%LIAIEI|$LLHI$DH)ITH)DITHfIEI|$LHI$ILILLH)H)HBf.IEIzLHIILILLH)H)H@IEIzLHIILILLH)H)HH@IEIzLHIILILLH)H)HN@AEAALALAEA$DATATfDAEA$ALAL?AEAALALAEAALALLH5HpA@gLMy@A>EtAEA$AMAOIAfXA$EO!LH4LLH)HHHHHLH)H9r7L4HHIHHH"LIătAEA$MA AAOIAnXLEO!HMLI)4LLHLL)HJH9r1M4HHI\HHH!N tAEAqIAIGAW!ƅEGIHt/8t*LMLjRH5LXZLML*I)LHHHLL)H9r1M4HHI脼HHH N TtAEAcIGIƅAW!EGAIHtB8t=IHt18t,LMLjRH,4LA[A\LML?I)LHHHLL)H9r1M4HHI虻HHHN `tAEAM$A$IIǠHHLH HH0莦 I:$tAOEO!AbXLHh1LLH)HSHIHPLH)H9r7N4HLI谺LHH=LIAIEI|$LLHI$DH)ITH)DITHIEI|$LHI$ILILLH)H)HBf.IEIzLHIILILLH)H)H@IEIzLHIILILLH)H)HI@IEIzLHIILILLH)H)HN@AEA$DATATfDAEAALALAEA$ALAL?AEAALALALfAL DALfALqDALfALoDDATfATV@ALfALDAEAALALBLH5DH`AhLMz@A6EtAEA$AMAOIAfXA$EO!LHU.LH)HL@HHHHLH)H9r7L4HHI蝷HHHLIătAEA$MA AAOIAnXLEO!HMLI)-LLHLL)HJH9r1M4HHIܶHHHN  tAEAIAIGAW!ƅEGIHt18t,LMLjRH.AYAZLLML訶I)LHHHLL)H9r1M4HHIHHHN )tAEAhIGIƅAW!EGAIHtA8tEtAEA$A{ MAOIAfXA$EO!LH'LLH)HбHHHHLH)H9r7L4HHI-HHHLIătAEA$ MA AAOIAnXLEO!HMLI)'LLHLL)HJH9r1M4HHIlHHHN tAEA IAIGAW!ƅEGIHt/8t*LLMjRH%(LY^LML:I)LHHHLL)H9r1M4HHI蔯HHHN T3tAEA IGIƅAW!EGAIHt@8t;IHt/8t*LMLjRH<'LXZLMLQI)LHHHLL)H9r1M4HHI諮HHHN btAEA7M$A$IIǠHHLH HH0蠙 I:$tAOEO!AbXLHz$LLH)HeHIHPLH)H9r7N4HLI­LHH\LIAIEI|$LLHI$DH)ITH)DITHIEI|$LHI$ILILLH)H)HBf.IEIzLHIILILLH)H)H@IEIzLHIILILLH)H)HG@IEIzLHIILILLH)H)HN@AEA$DATATfDAEA$ALALWAEAALALAEAALALALfAL%DDATfATV@ALfALtDALfALqDAEAALALJLL HIĸ03XHEL11A$I@I$h L HeH[A\A]A^A_]GDATfAT~@ALfALDALfALDALfALDAEAALALZALfALDALfAL DALfALDDATfAT@AEAALALALfALALfALALfALDATfAT-AEAALALALfAL#DATfATALfALALfALAEAALAL@DATfATALfAL?ALfALALfALAEAALAL[ALfALALfALgALfALDATfATAEAALALfHI|$LHI$ILILLH)H)HȜHI|$LHI$ILILLH)H)H՛HI|$LHI$ILILLH)H)HALfALDATfAT.ALfALALfAL;ALfAL+ALfALDATfATNALfALALfALALfALDATfATqALfALALfAL{ALfALeA\ALfAL7ALfALAEHALLyAEHALLxALfAL鷓ALfAL-ALfAL4ALfALALfALALfALALfALALfALALfALALfALALfAL|ALfALALfALFHALfL|xHALfLvA$ALAL!`A$ALALa_A$ALAL`A$ALALaA$ALAL]A$ALALP^A$ALAL\A$ALAL+\A$ALALbA$ALALaA$ALALaA$ALALuZA$ALALZA$ALALYA$ALALXALLXA$ALALRbA$ALALoA$ALALpA$ALALyqA$ALALpA$ALALToA$ALALrrA$ALALqA$ALALrA$ALALiA$ALALeA$ALALQfA$ALALdA$ALAL,dA$ALALjA$ALAL kA$ALALiA$ALALhA$ALALaA$ALAL`A$ALAL%bA$ALALbA$ALALkA$ALALjA$ALAL lA$ALAL!fA$ALALaeA$ALALfA$ALALA$ALAL"A$ALALOA$ALAL|ALfALiALfALƓALfALALfALX?X;X1?X;X1?X;X1ݟ?X;X1Ÿ͠?X;X1觟負?X;X1茟藠?X;X1q|?X;X1Va?X;X1;F?X;X1 +?X;X1?X;X1?X;X1Ϟڟ?X;X1贞迟?X;X1虞褟?X;X1~艟?X;X1cn?X;X1HS?X;X1-8?X;X1?X;X1 ?X;X1ܝ?X;X1̞?X;X1覝豞?X;X1苝薞?X;X1p{?X;X1U` ?X;X1:E ?X;X1*?X;X1?X;X1?X;X1Μٝ?X;X1賜辝?X;X1蘜裝?X;X1}舝?X;X1bm?X;X1GR?X;X1,7?X;X1y?X;X1x?X;X1ۛw?X;X1˜v?X;X1襛谜u?X;X1芛蕜o?X;X1ozn?X;X1T_m?X;X19Dl?X;X1)k?X;X1e?X;X1d?X;X1͚؛c?X;X1貚轛b?X;X1藚袛a?X;X1|臛[?X;X1alZ?X;X1FQY?X;X1+6X?X;X1W?X;X1Q?X;X1ڙP?X;X1这ʚO?X;X1褙诚N?X;X1艙蔚M?X;X1nyG?X;X1S^F?X;X18CE?X;X1(D?X;X1 C?X;X1=?X;X1̘י<?X;X1豘輙;?X;X1薘衙:?X;X1{膙9?X;X1`k3?X;X1EP2?X;X1*51?X;X10?X;X1/?X;X1ٗ)?X;X1辗ɘ(?X;X1裗讘'?X;X1舗蓘&?X;X1mx%?X;X1R]?X;X17B?X;X1'?X;X1?X;X1ߖ?X;X1Ėϗ?X;X1詖贗?X;X1莖虗?X;X1s~?X;X1Xc?X;X1=H?X;X1"-?X;X1?X;X1?X;X1ѕܖ?X;X1趕?X;X1蛕視?X;X1耕苖?X;X1ep?X;X1JU?X;X1/:?X;X1?X;X1?X;X1ޔ?X;X1ÔΕ?X;X1訔賕?X;X1荔蘕?X;X1r}?X;X1Wb?X;X1tƒb<t*<+FHJH{0H9 HtHhAF0I~0<1<D<<GHhOIL Q@Dn,DLv AHhA>L AL-JMLLULUMHLMLELLr }}ff.1HH[A\A]A^A_]"uAbX \XDLHHH[A\A]A^A_]9EFtDn,H{HDLKPHHNjF(J89r~R()HHLDMHAt1fff.ER$LHLDAH‹BIHLNjBEZ8D9rER(D)R$HHLfDH{0bXLm访 LLDLDH\ u8H{0fXz LLDLDH( HH[A\A]A^A_]@I9s DAQDI^AGtEgHsHDH{PHHAGJ89R$HHHDHAt'Uf.E@$LHHDAu0H‹BIHLƋBEH8D9rE@(D)I9s DAD8LEfDHhL!AIH5Lm@0H{0h^X輽 LLDLDHj BH{0scX脽 LLDLDH2 DEgDM@"cAZX \XDLDAFt_uiIvAFAVLlDAFR()HHH@DhDLpAAVMn IVMnH{06eX臼 LLDLDH5 ACXDLH߹VXt5qH{06eX1 LLDLDH ADHHH{0nfXٻ L/LDLDH _AH{0+_X蔻 LLDLDHB ADD`DLxH{0bXLm2 LLDLDH A H{0fX LCLDLDH sAHAbXDH߹ \X3HhOIwL SDHHmDH3gXT LLDLDH H{0ARDt'I EfDMvAAD`DLpALEELMKHHNXHAgX'.fUHAWAVAUATSHH(HHDH~H{pF<"<2DEIFH@H4Hsp<K<DEItABFH@L LKpA<'<DAf=RAf"dEHLULUHLDHLULUHIrHLU  LUHtAbXDLH߹ \X,(Df,DLv @"1H([A\A]A^A_]f.EFtD~H{HDLCPHHNjFJ89R()HHLD IHAt-fEI$LHLDA|H‹BIHL NjBEQ8D9rEI(D)EFtDf,LCHDLKPHIF(J89R()HHLDIHAtE<ff.ff.ff.ER$LHLDAH‹BIHMBEZ8D9rER(D)D~DLVAMAbX \XDLH(H[A\A]A^A_]*fR$HHL#fDR$HHLcfDJA9AEII9s DAqDII9s DAID8LE1fDAA;JAj"+ff.LMH HHDL|EHMHDǁǁLMHGH߾LM?LMHH55J1ɺLM1L怋!"H!"LMHAT$HHRM$A)uLLMJ~HLMHHAD;JEqV@AAKf"ADX \XDLnDAAtEiHsHDH{PHHAAJ89R$HHHDHAtGufff.ff.ff.E@$LHHDAu0H‹BIHLƋBEH8D9rE@(D)I9s DAD8LEfDEiDMI@AR()HHH@L|AgXHHNX DxDLPA-D`DLpHØ(|HDŽӘHDŽDŽHHNXHAgXS&fD"zEE1HMDLHLULM詮 LU}LMAlXDLH߹ \X%XLX{HDŽӘHDŽDŽDLMEDHH(HL[A\A]A^A_] oJA9A*@LUHØzLUHDŽØ<DŽDŽEFDLHA IHAEAN5JDhH@MLLEHJLEHI@DfApAvH@IDžHRI<IHI9AoIVHPAVu%8uPuǃD`fPf.Att t ufDIVHDAAUDhDLHLB.5J11D`H@M,LHcJHIEDHfAMH@I4i Hq LHF 8A\XDLH߹NX"qHHAgXNX Cٯ HJS Iï LEHJUHAWAVAUATISHHHHA$LOML$pG<<xA$WM̀tyAEnGH@M4Mt$pA<<2A$fA>tA<,EEA>E~L=JLwHƹbXLA>E~L=uJLuwHƹfXLA>E~L=;JL;wHƹ6eXLFA>.E~L=JLwHƹeXL thADXVXLL!A5w,A$Lo AUA$"IE1HHD[A\A]A^A_]@I$hA}AML qE}L=NJMLLUGvLUMHLLMLEL説 D}Et}utA}A}H=JH}uH}HƹdXt;A}EmL-øJLuHƹoXL I|$0bXLm蓦 LLLE$LA I|$0fXZ LLLE$L I|$06eX! LwLLE$L ^I|$0eX L>LLE$L %fGtw,MD$HMT$PHIG(J89R()HHLDMHAtZff.ff.ff.ff.ff.E[$LHLDAupH‹BHHMBEk8D9rE[(D)R$HHLRfDAF{IvM~,fDIA9$s A$DAA$I+f.AbX \XLHHL[A\A]A^A_]Zf.AFtA^It$HI|$PHHAFJ89R$HHHDHAtN|Dff.ff.ff.ff.E@$LHHDAu0H‹BHHLƋBEH8D9rE@(D)IA9$s A$DAA$8LE7AF IVAFAvL|IDAEIuAEAUL|DA^A$MvA$"AZX \XLD@AUGfDR()HHHw@pA$LhAUAvM~ ~f.AUM} fAvM~ fIvM~GIUM}AFIvM~AEIuMmfAFtKIvM~JfAEt9IuI}nfXA$LpbAvM~ AuI} IVAFAvL|IUAEAuH|IVAFAvL|IUAEAuLlfDUHAWAVAUATSHHXHHDLNLOpF<<t>DEMfA<$tAA<$t:"}1HX[A\A]A^A_]@D~,DLf fA<$uFH@M LKpA<]<DDLf>t*>t%"uAmX \X f.AAH@I HKp<E<DEHMAH@LLSpA<<<DEfA<$A<$El$L-'JA} >K~H= JDMLU L: LUDMHDMLUI9HEHHELL)HHEKL]LUDMHMHuDHDDMLUL]Y UL]LUDMf|f(*fDEFtD~,H{HDLSPHHNjF(J89RR()HHLDMHAtEff.ff.ff.E[$LHLDAdH‹BIHLNjBEc8D9rE[(D)DAAtAyHsHLSPHHAAJ89R$HHLDAtLff.ff.ff.E[$LHLDAdH‹BHHLƋBEk8D9rE[(D)R$HHLfDAmX \XDLHXH[A\A]A^A_]fR()HHL @DqDHAHEI9s DA9D8LEfDVJA9D$DMLUDEDEHuDHH LUDMDLUDMLULUEHHXHL[A\A]A^A_]v fDH9s DAA8HEAyIquDEAtDqLKHDLSPHIAz89"R$HHLDAtEff.ff.ff.E[$LHLDA$H‹BIHMBEk8D9rE[(D)EABtEJH{HDL[PHHABJ89PR$HHLD*HAtDrfDff.ff.ff.ER$LHLD(Au0H‹BIHLNjBEj8D9rER(D)I9s D(AD8LETfDHU9s DAD8HDEHEAD$jAD$&IT$AD$LlfEJDMR@DxDL`@fVM{HLULDMIH;AguLLUIDMHE8A<$A|$H=JgLUDMHLH}LDML)LUH)LUDMDDLHHM EH}EER()HHL@R()HHL@A|$Ml$ fFH~ H~FH|I|$Ml$mH}DMLUL]DMLUL]5JH}DMLUDMLUxHpNfDHE5RJHEHHEnDMLUL]NHuELDHDMLU DLULUHEDpDH@HE#DHDLPH8A<$yHHEfHnH(ƅfl))M@A$f=A<$AD$LHP諪H<<DDHwHa0ƅAH}HUHEII)L)H9r>H(K7HEHH9HEYHEHH}LH}LHYLuLHpLuAĪI<<&DA$f= ~JA9L$fDGtOLCHLKPHIGr89R$HHLDA" f$HHLDA H‹BHHIDDMfA}tAA}t:"]1He[A\A]A^A_]@w,Lo fA}uGH@M4LspA<<DfA>bA<V<YA}E}L=JLSHƹFeXL+A}E}L=͕JLRHƹkXLآ`A}E}L=JLRHƹdXL蝢]A}E}L=WJLWRHƹzkXLbu A>A}!E}L=JLRHƹcXL!ZA}AE}L=۔JLQHƹgXLu A> A}0E}L=JLQHƹ^eXL襡u A>t A}E}L=YJLYQHƹXfXLdu A>> A}E}L=JLQHƹNiXL#u A>& A}EmL-דJLPHƹlXLA>LmLޱfDGtw,LCHLSPHIG(J894R()HHLDMHAt?fDff.ff.E[$LHLDA,H‹BHHMBEk8D9rE[(D)AF"#ACYX \XDLzf.AFtEfHsHDH{PHHAFJ89YR()HHHDHAtQff.ff.ff.ff.E@$LHHDAdH‹BIHLƋBEH8D9rE@(D)JA9FA>fH+HfH* LmL^^蟯DLDLH7 He[A\A]A^A_]A>LmfLV@R$HHLfDA>+XNHC0L0MM MI\$Ml$qHu:@AT$|HJHtff.ff.[$HHLH‹BHHIBDc8D9rNj[(D)R$HHHfDAmX \XLHĈL[A\A]A^A_]R$HHL)fDD{EH[@IA9s AD A?A8LEv@IA9s AA8LEfDwALgDCtD{IvHDI~PHHƋCJ89R$HHHDHAtIoff.ff.ff.ff.E@$LHHDAu(H‹BIHLƋBAX89rE@()ŐHA9s ADAWE8HE@AUI} Fx@HH@H=xHIu mIu`AEHtRAD$I|$ yI|$lAD$H|]AT$AnIt$Hu AD$H|`HPDX?Hp`HH9DXHPAAD$HtDHHMHHpHx>HxHpHHEHHxHE>HEHHHEA}HxXAuHJ 1A03XhA"AZXDHL \Xm@pALh7DR()HHH4@It$ `HHXv>Hp`HH9s0HXd@I}AEH|DHH9hI|$ I|$AD$H|ED$It$ AIt$+pAL`DAUCH=LxLHHE~JA9BH88ƅO@EoH88DAHHH<<EAf==}J9{DFt~MWHM_PHI‹FJ89R$HHL [AI$HHLH‹BAHHI ‹Bq89rȋI()ĐMAAdX \XLDCtDkIwHDIPHHƋCJ89MR$HHHD AE@$LHHDAupH‹BIHLƋBEH8D9rE@(D)HE9s E)AHHA9s ADA/E8HE@FAHv/f.DkEH[@H88|R()HHL@R()HHH@H8A9s ADA_E H8DuPAHp_f.ABtErIuHDI}PHHABJ89R$HHHDA  E@$LHHDAH‹BIHLƋBEH8D9rE@(D)AB;JzJAuFH8;;zJƅOcfDfff.A" ADX \XDLa@DhEHX@IA9s ADA@E8LE@ErEMR@ABMƅOf2yJA9BA\XX A"Aƅ"HIC4LHHœLf3HDLEH0 fH߈8莨8LfH8HAfHйR()HHH&DxEH@H8H88twƅOE1LHODLL( f L(u\OuSAlXDLL \XOf.>wJA9BP A:uArVXAXAD0ED(MLD$f$uZH88H8ArVXDLAXD0ED(MLD$ftVAlXDLL \XhH8HйABd)DpELPC9&vJuHfHnH(fl)H88A:0HEMDfoƅL0D$)Mff.fA<$A<$AD$HPL譁H<<AHVHEAօH}HUII)L)Hw>H(IWIHUH9H]0HEHHBLH}D~ LHpHHEHEI<<$AfA<$tJA9D$fFt~MMHMUPHIFDB8D9R$HHLDAA>f.ff.ff.I$HHLDAH‹BAHHI Bq89rƋI()AD$tA\$I}HMEPHHAD$r89qR$HHLD AAfDff.ff.ff.I$HHLDAuaH‹BHHH NjBDI8D9rɋI(D)ĐHE9s EDAA8HE@IA9s ADAA8LE@~AHv?DA\$AMd$fH-HEHHH(IW-HSR(D)HHLR()HHLxAHpXAL`NH}HUAHEL0HD$H)H)HwEH(HCHH94HHE,L0HHEHHH}1L0 HHEHEI]@HƓHE03XHHHD11H HYHH}A"L0<w.Hu%4uH8uHxH(H9tL85,L8foHHEAKXƅ)]bLVHAYHоH(H9tHH8+AH8foLAOX?XHEƅ)U5HйQHǃH(H9t8L+8oJ9CHfHnH(fl)XNHL0HE*HEHHH(HS*L0HH(H9t*oDLfoEH8HE)HHHƅH)ue MN!?X;X15*@+'fUHAWAVAUATSHHHHDLhLopP>tQDPtZAEcIUAEAuLtBD`,DLh AUuA}EuL5lJL)Hƹ]pXLyTA}EuL5NlJLN)HLoXASyAAXHDLH߹ \X[A\A]A^A_]11AU^X"tH[A\A]A^A_]D@tD`,H{HD@(HLCPH׋J89R()HHL HЀtJDff.ff.ff.I$HHLH‹BIHH NjBDI8D9rNjI(D)E1AEI}<<tpDAE0M}0<<Df?w?AmXA?AdXR$HHLfDAE,I} AuMu fAE+}IuMufDI9s DI DAEtAM,LCHLKPHIAE(r89R$HHLDHAt&HMLHL1LPXƅƅ)H{0LEƅ@V H1HDLwH@I9s DA8LEAU`fDAEDM}8tDD`DLhAU)G LgHGDoMdR()HHL@R()HHL@H{0fLHDž)ƅT Hh1HDH¸H}H{0E1DLLLƅY NDAuMu f.IuMuDoLg PLxPHxIUAEAuLt}Lo@ff.UHAWAVAUATISHHHE$H~I|$pF<E<tQHXEE$VB< HtCA$"1HĨ[A\A]A^A_]Dv,E$HF HX@FH@L ML$pA<|<lE$Af=.Af_vHX8 ƅoA9EbD@DMD0Mff.AEf=AUAE HpLqI<<A$AAf AFI~ tI~uAFH|; A>HA~H=cJHP HPH9QLHqI<:<rA$AEf= dJA9MfDEFtDv,MD$HDML$PHIF(J89rlR()HHLDAxER$LHLDAH‹BIHMBEZ8D9rER(D)R$HHLfDAoRX \XHXDHĨL[A\A]A^A_]f~cJA9AHX8ƅo@AFtA~ML$HMT$PHIAFJ89`R$HHLDAbLfff.ff.ff.ff.v$HHLDAH‹BHHI4BDF8D9rŋv(D)DfHX8fƅHfAEtA]It$HI|$PHHAEJ89R$HHHD AE@$LHHDAuxH‹BHHLƋBEH8D9rE@(D)IA9$s A$DAA$IUf.IA9$s A$DAA$8LEfA~A$MvAA]A$Mm{LA_X \XLAFIF f.R()HHLDAHйfDR()HHHD A\HйfDƅHA~H=_JYfHXA9$s A$DAE$HXof.AF&fDAxA$LpAXA$Lh @AAtEiIt$HDI|$PHHAAJ89R$HHHDAn Vff.ff.ff.ff.ff.E@$LHHDAH‹BIHLƋBEH8D9rE@(D)AA;^JA uFHX;;^JƅotfDfff.A$"ADX \XDLIA9$s A$DA E$8LEAF7AAmƅof]JA9AA\XHPIFIHEH9kHHEHH;LH}D謮 HHHHEHEgH<<E$f;YJ9CA9ArVXAXYJ9C HfHnHPfl)0,fDAqHXArVXDLAX2DAFI~ I~AFH|DDAFtANI|$HMD$PHHAFr897R$HHLDAi4f.ff.EI$LHLDAH‹BHHL NjBEQ8D9rEI(D)CtDkIt$HDI|$PHHƋCJ89R$HHHDADff.ff.ff.E@$LHHDAuxH‹BIHLƋBEH8D9rE@(D)IA9$s A$DA A$If.HA9$s A$DAE$8HE)fAFA$MvAVDkE$H[HHEHHHPIVH}R()HHL@R()HHHVAPA$LpADhE$HXNH}HUHEDHHL@H)H)HwLHPHCLHHHEH96H7LHHHEHHH}1LHK HHEHEI\$@HxHE03XHHHD11H HHH}A$"LHAm<w.Hu%4uH8uHxHPH9tLXlLXfo0HHEAKXƅ)MLKXMLDHXHйRAA DhE$LHbA$L \XLA_XHHоHйA$AGXLLDVEM€t@t;"1HX[A\A]A^A_]DDf,DLV AuFH@I4Hsp<F<HuEDAYOX \X"uHuDEFtDf,H{HDLKPHHNjF(J89"R()HHLDMHAtM\ff.ff.ff.ER$LHLDAH‹BIHLNjBEZ8D9rER(D)FH@H HKp<<NDEHMAH@LL[pA<5<DHE8H}f?<<HEHEH8.HufHULMLEHL]LUD}HE)E> LUL]HHD}EDLHLUHM虘 EHMLUf=f<<HuH}LUlHuHMDDH* DR$HHLfDAYOX \XDLHXH[A\A]A^A_]AEAtDyLCHDLKPHIAr89R()HHL2@tBef.ff.ff.v$HHL0@>H‹BIHI4BD^8D9rƋv(D)fD<uHE@Lu1L]LLUpkHuLDDH L]HuELDHƖ I9s DA9DIbEFtDvH{HDLCPHHNjFJ89R$HHLD At!EI$LHLDAu0H‹BIHL NjBEY8D9rEI(D)HU9s DA DHEDDvDHFHEDAZR()HHL@HH@A _= @8x ABDXVXfDACtEkHsHDH{PHHACJ89R()HHHDHAtI@ff.ff.ff.E@$LHHDADH‹BIHLƋBEH8D9rE@(D)D`DLPA+EkDM[@DyDHAHER$HHLkfDR$HHH fDH@KJ9AkyQHA tHAuQHD8[ux]uxFff.HH}LUgHuHMDDHb LUfI9s DAD8LEfDHU9s 0@D8HDEHEiHE'@@ HHDD}HMDpDH@HEIJ9A$H}@zLUHMHuHsDhDLXDxDH@HEHMH @ff.UHAWAVAUATSHHHHDLFLGpF<<D4L8DVB<FH@M$LcpA$<v<fDA$f=@A$f8H88 ƅOA$<SfA<$ EM<YfAf=AW AGz LHkTH<<}DDtH88LHTI<<EDAf=^ GJA9ONaF,4HF H8B<eH8x]"1H[A\A]A^A_]fDD4Ft F,44H{HLKPHHNjF(J896R()HHLDAa )f.ER$LHLDA|H‹BIHLNjBEb8D9rER(D)AD$;FJOA$5 H89@ ;VFJƅO,A$<H8< QH DJ< PH8DpL5DJLLHHHH((aDDLHH(f D GH(8u8)fAD$tEl$HsHDH{PHHAD$J89R$HHHDA -ff.E@$LHHDAH‹BIHLƋBEH8D9rE@(D)R$HHLfDAYX \X4H8HH[A\A]A^A_] vDJA9L$ H88>ƅOfR()HHH@H88ƅOE1HODLH2 aOTAlXDLH߹ \X˩vfDAD$f#f."AADX \XDLDDGtwLCHLKPHIGJ89R$HHLDA8@ff.ff.$HHLDAH‹BHHIfDwH{EwDM @R()HHL@R()HHH@D4H89s DA4H8I9s DA D8LEfDpHxDpDLx@El$DMd$fAdXH \XHHH8HйHйFAD$Ш H8<HHEfHnH(ƅfl))Mfff.A$f=A<$5AD$)LHPKH<<DDHwHƅAH}HUHEII)L)H9r>H(K7HEHH9mHUHEHHLH}LHLuLHpLuAKI<<DA$f= >JA9L$fHH@4H88yTH8y<-A҃ H8Lq LqAMtfu)A<$H8DfAlXDLH߹ \X蝣H<Am =JA9L$ƅOA$<2A9L$L5Z=JLrYDLHߋ4H8Å A<$ArVXAX[AG9ff.ff.ff.I$HHLusH‹BIHH NjBDI8D9rˋI(D)HĸDLHA4nX[ \XA\A]A^A_]&fDR$HHLHfDI9s toDtQI3fI0HHH0f1iHH!I0RAUfDD`DLhAU H8H(H8Hx= H8@H8H(uH8H(^H8HxA H8S=H8H(+H8Hx,H8HxH8 H8H(H8HpH@H HP0 &fUHAWAVAUATISHHHE$LOML$pG<E<E$ELf=f2J9CGH@MMD$pA< <E$LD4L8f8H<A$"uZ4A`hX \XH8jfDo,E$H_ f=A)2J9CKA$"t1H[A\A]A^A_]DAOYX \XDHHL[A\A]A^A_]ƗfDEGtDo,MD$HDMT$PHI G(q89I()HHLDLHAt6ff.ff.R$HHLDAuaHAIHIADZ8D9rɋR(D)ĐI$HHL}A@4A$I@H8P@HA9$s A$DAE$8HEA@H@M4Mt$pA<<E$HfA>fHnfl) tA<fo D0LHEƅ)Mf.f=tz<CHPH&<H<8<E$Dv9f>t3A`hX \XL蘕/J9CwA$"L L}LEA$"ILLL@L)HHHuHHHxHH)H9rVL@HHHEHI9kLKHEHHiLHLIL}HLLLHELHEHHp;H<<E$f;;D0L<-LmMqLHHLHxHH}HH9tHDLLfo E$HEƅ)Uov H߈H$^HDFtVMD$HML$PHI Fy89*I$HHLDHAtDv$HHLDAu)HAHHI4ADV8D9rɋv(D)ĐHA9$s A$DAA$HfC9,Jt;,C"f4H8LA$"= L}LEA$"ILLL@L)HH-HuHHHxHH)H9rVL@HHHEHI9FLvHEHHLHLIL}HLL2LHELHEGCtDkIt$HDI|$PHHƋCJ89[R$HHHDHAt7e@ff.ff.E@$LHHDAu0H‹BIHLƋBEH8D9rE@(D)HA9$s A$DAE$8HEbVA$HvfCDkE$H[HHEHHHHHHHPHsfDI()HHL@R()HHH@NPA$Hp7fDhE$HXlHHEHHiHHHHHPHfDD4A@t A@44ML$HMT$PHI A@y89I$HHLDAtGff.ff.ff.v$HHLDAu)HAHHI4AD^8D9rɋv(D)Đ4H8A9$s A$DA4A$8HD8H8AFtE~MD$HDML$PHI AFy89(I()HHLDHAt<5ff.ff.R$HHLDAHAIHIAr89rNjR()DhE$HXA`hXAXL訍E~E$MvA$"vAZXDLL \XfZD0LD0LI()HHLI$HHLA1@XDHLAXIA9$s A$DAtBE$8LEQ1A03XxA$H@4H8 DxE$LpL8H?X;X1UHAWAVAUATISHXHHE$LOML$pG<8<tDE$DMfA>tOA>tIA$"1HX[A\A]A^A_]w,A$Lw fA>uf.GH@IHEID$p<<yE$HEf8tE<vA> A^H$JH]A>H HH q HH@H|HM[HEHHHMLyHt3ff.H}{ H߉vy HHIsA>NA~H={#J~HLuH]HL?LHuHDE$Lm EU;  EHEH(6HEHpH@H HP0O HEHxrH}i@DGtw,MD$HMT$PHIG(J89jR()HHLDMHAt]fff.ff.ff.ff.ff.E[$LHLDALH‹BHHMBA[89rE[()DHE@tDhIt$HDI|$PHHHEJ8@9R$HHHDHAtCfff.ff.E@$LHHDAH‹BIHLƋBEH8D9rE@(D)R$HHLfDAmX \XLHXL[A\A]A^A_] f.R()HHH&@IA9$s A$DAeA$8LEHUA9$s A$DAE$8HDEHEAFNAVfAFI^AFH\H]A>AvHEDhE$H@HErA$"HuAZX \XDf.AFttfDAVfDAvVfDI^ H]A>tA~H=7J*f.pA$LpF@XPHEH(A2@H]A>uIvIVYHEH( HEHxhHEHx[H}R HEH(HEHx詗 H} DhE$H@HEHEH(HEHx#- H}mHEH(^HEHpHxe 1A$I$HNXLAgX fDUHAWAVAUATISHXHHE$LOML$pG<8<tDE$DMfA>tOA>tIA$"1HX[A\A]A^A_]w,A$Lw fA>uf.GH@IHEID$p<y<iE$HEf8tE<fA>A^HJH]A>HpHHi HH@H|HM HEHHHMLyHt3ff.H}t PH߉&r HHIsA>>A~H=+J.HLuH]HL8LHuHDE$Le EUt+  EHEH(6HEHpH@H HP0 HEHx"H}@DGtw,MD$HMT$PHIG(J89ZR()HHLDMHAtMff.ff.ff.E[$LHLDALH‹BHHMBA[89rE[()DHE@tDhIt$HDI|$PHHHEJ8@9R$HHHDHAtCfff.ff.E@$LHHDAH‹BIHLƋBEH8D9rE@(D)R$HHLfDAmX \XLHXL[A\A]A^A_]ʀf.R()HHH&@IA9$s A$DAeA$8LEHUA9$s A$DAE$8HDEHEAFNAVfAFI^AFH\H]A>AvHEDhE$H@HEA$"HuAZX \XDf.AFttfDAVfDAvffDI^ H]A>tA~H=J:f.pA$LpV@h`HEH(QB@H]A>uIvIViHEH(HEHx(HEHxH} HEH(HEHxi H}DhE$H@HEHEH(HEHx% H}}HEH(nHEHpHx%AA$I$HNXLAgX}.fDUHAWAVAUATSHHHHHLGLCpG<#<AMŋGH@MLCpA<<lALA}oAoE)EIEEHE1EfEA}LuAHDL_ t\HCpDPHRLt<tMfkMGEEdDH߈MLE0_ LEMAH߈MLE-VHHEE[LEHIApLEu>uLEHMIfH@D@pA<<AvH5'JH{0M# MAEAt$f@Ѝ H@ID@H@@HHfHA9s1HULHn9M5DI$HHH-fDI$HHLsfDEgDM@AGtAWLKHLCPHI AGy89I()HHLDHAtBff.ff.ER$LHLDAlHAHHMAEZ8D9rER(D)I9s DAyD8LEfDH9s DAYD8HEfDAGtEgHsHDH{PHHAGJ89+R$HHHDHAtWff.ff.ff.ff.ff.E@$LHHDAu0H‹BIHLƋBEH8D9rE@(D)I9s DA4D8LEfD~A`hX \XD\fDDpDLh@D`DHp@R()HHH@AdX \XLHHH[A\A]A^A_]u@I$HHLiHHEHDLH[A\A]A^A_],X @I9s DAtr8LEAWMDLHD`DLxbAjX?XL4ABDXVXL!PLxEAgXNXHHAFAE}IxMHu HuMsDULHHu$W AFIv  IvAFHtAmX \XDe"UHAWAVAUATSHHHHHDLWLSpG<<DDMfA}tAE<EGH@M4LspA<b< DfA>tKA<tC<t8"1HH[A\A]A^A_]Ëw,Lo yfDA~tAE<L fA}<A>Em)E~L= JLHƹjXLA> E~L= JLHƹ X]XLA>f E~L=k JLkHƹjXLvA> E~L=1 JL1Hƹ :dXL<A>c E~L= JLHƹ:gXL A> E~L= JLHƹDSXL A>' E~L= JLHƹ XXL A>Z E~L=I JLIHƹ HSXLTL A>v E~L= JLHƹ?dXLA> E~L= JLHƹ [XLR A> E~L= JLHƹiXLu A~d A> E~L=Z JLZHƹhXLeu A~R A> E~L= JLHƹiXL$u A~# A>: E~L=JLHƹhXLu A~S A> A^HJHHH߹dXÅ A> A^H[JH[HH߹ RXfÅ A> A^HJHHƹ dXH* A> A^HJHHƹjXHD A> A^HJHHƹGXH A> A^HqJHqHƹiXH|A A> A^H7JH7HƹgXHBY A>5 A^HJHHƹEbXH A> A^HJHHƹlXHI A>% A^HJHHH߹#pXÅ A>u EvL5MJLMHƹkXLXÅA) A ~1H!LÃ@DGtw,LKHLCPHIG(J89|R()HHLDMHAt/^ff.E[$LHLDA4H‹BHHMBEk8D9rE[(D)"ALX \XLHHH[A\A]A^A_]UlDAFtEfH{HDLCPHHAFJ89R()HHLD HAtQff.ff.ff.ff.EI$LHLDAlH‹BIHL NjBEQ8D9rEI(D)R$HHLfDR$HHLJfD<oAEI} @ff.P HA}fA}H=JZ A>AAFtIVAFAvL|fDAFIvM~fDAbX \XDLf.I9s DA8LEjI9s DAD8LEsfDD}fDAE mfA}A}H=JEfDMv@D{"D{pLhfDAvM~ ^f.D`DLp@AFtZtIvM~f.I}AEH|fDAvM~ IvM~AvM~ ?AFIvM~DAEI} I}AEH|zDAQAXVXAFtb IvM~DDDIVAFAvL|3AvM~ AF(IvM~DBIVAFAvL|AvM~ {AFnIvM~AE1ۃ DbXQHIVAFAvL|AvM~ HAFIvM~A0A IVAFAvL|AvM~ ,AFIvM~~IVAFAvL|AvM~ DDYAAA A/  AFt[iIvM~IVAFAvL|VAvM~ AF<IvM~AvM~ A@A"xA#>1LaAFbIvM~IVAFAvL|AFIvM~D[IVAFAvL|AvM~ EAvM~ xAFt3IvI^AFt#IvM~AvI^ AvM~ IVAFAvL|AFM~<<$DDD蒿LmLeLR LLH!D1LkAFtQt7IvI^A+AAFtKt1IvI^sIVAFAvH\AvI^ IVAFAvH\9AvI^ +AAEAFtftLIvI^DĶ[A AKAFtKt1IvI^NIVAFAvH\rAvI^ dIVAFAvH\AvI^ IVAFAvH\AF,M~ A[A"H1LAFtotUIvMvIVAFAvH\AvI^ IVAFAvH\AvI^ IVAFAvLt)AvI DUHAWAVAUATISHhHHE$L_M\$pG<8<tDE$DMfA9tOA9tIA$"t1Hh[A\A]A^A_]fw,A$LO fA9uf.GH@IMA~H= IMIHMHEH]LHLLMH)I)= LMtdA9AyH=I®HUHMH)H9t HL3L4A$HHtHuALDM; A$I$HAgXNXLXXA$HuDLHA: 1CH{ H{CH|ACI{ TI{HACH|:AAII HMIIHMAAHDHEHE@tDxIt$HDI|$PHHHEJ8@9R$HHHDHAtI@ff.ff.ff.E@$LHHDAH‹BIHLƋBEP8D9rE@(D)뿋pA$LHR()HHHR()HHHCAFMFyHUA9$s A$DAE$8HDEHEzHEDxE$H@HE]pA$LXMHpA$HXIHKAAt;tJIADxE$H@HEHHEFAAEFAAUIHAWAVAUATSHH8LHUDMXL_pA@<<t?DAPDLހt>"1H8[A\A]A^A_]f.Ax,Ip uA@H@M4LspA<<FDfA>TA>b"uAmX \XDLfDAdX \XH8H[A\A]A^A_]TDDA@tAx,HsHLcPHHA@(J89R()HHLD2AtNfff.ff.ff.ff.Ev$LHLD0Au`H‹BHHL4ƋBE~8D9rEv(D)R$HHLdfDEnDMv@H9s D0AI HAFtEnH{HDLCPHHAFJ89CR$HHLDHAtMfE[$LHLDAu0H‹BIHLNjBEc8D9rE[(D)I9s DA"D8LEfDfA:t A:A>Df]E~L=.ILUL*LUHƹoXLLU-LUA>1E~L=ILLUHƹoXLLULU;A>E~L=IL螧LUHƹRoXLLULU@A>E~L=XILXLUHƹoXLLU[LUA>E~L=ILLUHƹoXLLULUMA>E~L=IL̦LUHƹOoXLLULUYA>E~L=IL膦LUHƹ+nXLLULUE1E1AQfA:UA:KAmX \XULDAAAEtLA:KAzH=ILUH}ץH}LUHƹpXLULU}A:EzL=ILUL茥LUHƹ.pXLLULUSA:9EzL=FILULBLUHƹpXLLUELU A:'EzL=ILULLUHƹqpXLLULUA:E<ArH5IHh1HULUALU/D tOAFwẼ,A:ArH5UIHhDDLULUAvEqff.ALXIXxHpDfAFIvM~fR()HHL@ABtjIrMzf.AAAkfM̍Q D AvM~ ArMz ABIrMzfDLHDABIrMzAFIvM~ABIrIzABIr IrABHtDhDLpArMz AAA AXLX ArMz AvM~ ArIz IVAFAvL|AFDIvM~ABIr CIr7ABHt)IRABArL|E1AA^IRABArL| UALXLH߹IX]KUAUXLH߹NX?KIRABArL|AvM~ OIVAFAvL|IRABArH|AFt)IvM~KE1AAAvM~ )IVAFAvL|AFt(tbIvM~?AAA5AvM~ IVAFAvL|AFt'toIvM~0IVAFAvL|AvM~ AFt'tGIvM~8A/DXVXDL&AvM~ IVAFAvL|IVAFAvL|UHAVAUATSHH@HHDLWLSpG<<t8DWDMрt8"1H@[A\A]A^]fDw,LO AuȋGH@MLCpA<_<7DDMfA:oA:e"uAmX \XLf.AdX \XLH@H[A\A]A^]|H@DGtw,LCHLKPHIG(J89R()HHLDA3fff.ff.E[$LHLDAu`H‹BHHMBEk8D9rE[(D)R$HHLyfDAxMPDI9s DA IA@H@M4LspA<<DAftKA>tEf=t'"AeVX \XDLl@IA9Fu͐ff.A<$<IAH=|!"LmAn<DDLHLLHuI<<DA'Aff=u =IA9NtA>AFLLKI<UDAAtAIH{HLCPHHAAr89R$HHLDAc;fDff.ff.EI$LHLDA H‹BHHL NjBEQ8D9rEI(D)AFtEfHsHDH{PHHAFJ89sR$HHHDAHff.ff.ff.E@$LHHDAH‹BIHLƋBEH8D9rE@(D)AN9 IM;fDI9s DA8LEI9s DADIAIMIGDEfDMvAlR()HHL@R()HHH@DA@tAxLSHL[PHIA@J891R$HHLD*AqJff.ff.ff.ff.Em$LHLD(Au0H‹BHHM,‹BEu8D9rEm(D)I9s D(As8LEA@A#pLHAf.AFtEfH{HDLCPHHAFJ89 R()HHLDAANff.ff.ff.ff.ER$LHLDAH‹BIHLNjBEZ8D9rER(D)HLHfDD`DLpAIyfff.AFXVXR()HHL@R$HHLfDffHnf/%I9s DAD8LEfDAA MIA sY 8H QIAEfDMv7@MHйHоHй xLPJAmXDLH߹AX @fDLH>D`DLpMHйHйUHAWAVAUATSHHLHMXL_pA@<<t;MfA:tAA:t;"&1He[A\A]A^A_]DAp,MP fA:uA@H@I<F H8xH=IIHƹfXL>H88 xH=II讓HƹfXLa H88xH=oIIoHƹfXLzBDž LHpI< <3DAf=fA? AG HPLRI<L<dDAUE\ A}Q IED0H8AE<<:A}H=oIH(kH(Hƹ '`Xr*A}'A}H=,IH0(H0HƹlX/H8f8=+I9x1ҹHHD HsH81HھHnfDA@tAp,LKHLSPHI A@(y89jI()HHLD!A Vf.ff.ff.ff.ff.Ed$$LHLD AHAHHM$AEl$8D9rEd$(D)$Gt G$$LCHLKPHI Gq89I()HHLD!Ac 3ff.Ed$$LHLD AHAIHM$AEl$8D9rEd$(D)I$HHLfDAmX \XLHeH[A\A]A^A_]:fI$HHL6fDAWM&DIA9GEAEtEeHsHDH{PHHAEJ89R$HHHD A5ff.ff.E@$LHHDAH‹BIHLƋBEH8D9rE@(D)AEt AE,00H{HL[PHHAE(J89R$HHL >ff.ff.ff.I$HHL/H‹BIHH NjBDA8D9rNjI(D)AGtEwHsHDH{PHHAGJ89R$HHHDAHff.ff.ff.E@$LHHDAH‹BIHLƋBEH8D9rE@(D)I9s DADIbD0H89s 08HD8H8A}EAE:IuI}DDI9s DAaD8LEZfDEeDMmAUAE,0IE H8VI9s D AI8LEEwDM@H{0fXL軼 LDLHߋ0H8b Dž CAuI} fR()HHH@5IA9wA?"ASYX \XL6fDAEScIuI}fDR()HHLG@R()HHH@H8F-HHP@vLdfDD$I9s D A$8LEf."$AZX \XL2f.AGtAWLCHLKPHI AGy89I$HHLD!A@ff.ff.ff.v$HHLD AHAHHI4ADf8D9rŋv(D)DDLHAZgXVXo3He[A\A]A^A_]Dž AUYfDGL_$:I9s D A8LE@AuI} f.IUAEAuH|)f.HvL` D`DLhAUxH@0H8_AGDpDLx@H@tHHvL`:DHvL` %I()HHL@pLPnfDIUAEAuH|lf.HйD HƅLLEDžLA:2EbL%IL8L L8IL(LA臌HMMHHLL1PHMnHAYAZH8L(H0Hff.AMLHߺmX1I襅HHI)HI9uH0MHL0L0L8L0L'LLHDLHߋ$H0 L88HоHйHvL`AGZF DžLA:bEbL%WIL8LPL8IL(LAHMLHHLM1PHM贊H_AXH8L(H0LI@ff.AMHLmX1IHIH)HL9u;@H@tRH|HvL` pLX$MHȿ0PLxHvL` HP@vLdlIHȾHȿ DžLA:EbL%IL8L跃L8IL0LjHLMHHLM1PHAMHH8IY^H(Hff.ALLmX1IVHII)L9uL0H(HP@vLdAB%MjMb A<8EbL%IL8L蜂L8HLLL0LLAMIHH(H8HÐALHߺmX1IfHHI)M9uL0H(EjMb AB_MjMb <uERLIL8LM贁L8HLLLL0LMwL8H(ILff.ALHߺmX1IvHHI)M9uHL0H(L8D0VXHA'`XDL+EjMb ABt+1MjMb IRABEjLdEjMb IRABEjLd8AB#IrMbABIrMb<EbL%IL8LL8HLLL0LLAMHH(H8Hfff.ALHߺmX1I~HHI)M9ukIRABEjLdABtotUIrMbVIRABArLdArMb ArMb IRABArLdrIRABArLdArMb UHAWAVAUATSHH8HHDLWLSpG<<t6DWDMрt6"1H8[A\A]A^A_]fw,LO AuʋGH@It>>t9"1H([A\A]A^A_]Dg,DLo A@H@ML[pA<<$AAMހtAFACH@IHCpWAUb>FHIHEH}bXU:vUTAUFH}_XUuUuvA}I} tI}u AEH|k HvEA}u A}H=gIH}fvH}Hƹ YXpxH}~eXrufA}AE;DIt ;IH}mX8ut;H}`hX&uu)fA}t!AE<MA`hX<H}dXtcA}H}oXtcH}vgXt|H}bXtH}kXtH}lXrtH}?X\ttH}BDXFt+AEP<<H}~lXtfD"AbX \XDLsDAGtDg,LKHDLSPHIG(r89R()HHLDA-5ff.ff.E[$LHLDAH‹BIHMBEk8D9rE[(D)AA@tExHsHDLSPHHA@z89PR()HHLDACff.ff.ff.EI$LHLDAdH‹BIHL ƋBEY8D9rEI(D)ExDIp@AACtESLsHDLKPHIACz89R()HHL:@D}A%$HHL8@H‹BAIHI<ƋBD8D9rŋ(D)DR$HHLfDR$HHLfDAmX \XDH(H[A\A]A^A_]4@R$HHL-fD@tHH{Hʋ@HLCPHDR8D9R(D)HHLDAtZfff.ff.ff.ff.ff.EI$LHLDADH@LO N EQ8D9rEI(D)DI9s DAD8LEfDH9s DAD8HEfDD}ID9s D8@$DIf.ESDMsAH}_XUooUB<wLA}uEA}H=Il@H}_X*oA}tff.MA_XH(DLH߹ \X[A\A]A^A_]v1fD9s DANHF@FHN HMYHNHMIFHDHE8DxDHp@@D`DLh@H}mXBnfA}5A}MAmXH}dX nMAdXfDA3R$HHLfDMAbXf.MA~eXfDPDLpAH}oXrmA}MAoXJMHоLHпH}bX"mAE<<u AEhMAbXMHAH}vgXluAE<MAvgXDLH! AkX \XDL)E1HMDLH fMAlXDL \XH.3AEIuI}A}}H}~lXlA}u A}A~lXME1HMDLHK }NAuI} AUAE t:IE S/ 8H dABDXVXIUAEAuH|I}3AdX \XDٯIA9E+;ffA/E@UIHAWAVAUATSHHHEL_MYpG<7<tCEDLf;tP;tKA"1HĨ[A\A]A^A_]fw,AH_ f;uff.GH@It*A>t$A"yAmX \XL)GH@HEDIfA<$uA<$jA"AmX \XLDGtw,MAHIYPHIG(J89dR()HHHD"AtV Dff.ff.ff.ff.Ed$$LHHD AkH‹BHHM$BEl$8D9rEd$(D)DGtwMAHMYPHIGJ89R$HHLD"IHAtBff.ff.Ed$$LHLD ASH‹BHHM$BEl$8D9rEd$(D)R$HHHfDAmX \XHHĨL[A\A]A^A_]R()HHL@wALgDHA9s AD AA8HE@GH@HHXIAp<<gHXE}A"bHXA4nX \XD DIA9s AD A'A8LE{@wALwdDDGtwMAHMYPHIGJ894R$HHLD*IHAtN{@ff.ff.ff.ff.Ed$$LHLD(Au/H‹BHHM$BEl$8D9rEd$(D)@IA9s AD(AA8LE@;g[HEILHD7fDLIA>A$HIE~J :H<#AD$HLxDHHpeDLxIHpLxDeDLxHHHEfHnƅfl)@)EMIHGLAHhMHxDTL8DL9hrSHxHL`LHEHI9L{dL`HHEHN<L}LxHpLL3dHELHEHL}LuI)HMLeHHHcMM)M)ą4IwMM`HL`LeII9 LcL`HHEHIN<L}IHAHEHPHU@L}LuMSLDTML8L9FL)03XMLLDHHDHLDLH}HH9t!LD cLDEHDLfo@HXHEƅ)M H߈fDHX@tDPIqHDIyPHHHXJ8@9R()HHHDHAtMff.ff.ff.E@$LHHDAtH‹BIHLƋBEX8D9rE@(D)pAHXDR()HHL@R$HHH6AT$fI|$HpcAD$LhxHDHDHp~aDxLhIƃI|$@H`HEHXL`HHIP`L`H>fHx`HEH3LHHi`L`Hf.HXA9s ADAt&EHXHXDPEH@HXpALpTDLHDANtvI~Hg<AD$H=IMvH HpH;CtT]LkH[pAL`I~ H<tpAD$HIHpEvDkH `HX5IHLHD贿LDAD$¨I|$HpuAt$H|7Hp EvHID$ LxDHp^DLxIA|$#AVH|H<bAD$H=IEvH HpHSCDkH\HA|$I|$ HpuXEvHL`hxD&^DxhL`If5t MvƒEv?X;X1]^UHAWAVAUATSHHHHDH~H{pF<2<DEIFH@LLCpA<<zDDLf>t<YA@H@M4LspA<e<}D|IA9GuzAGI<q<DEHH AG0MO0<<DEL"@Df,DL~ @ELHDLH[A\A]A^A_]. fDEFtDf,LCHDLKPHIF(J89R()HHLDIHAtEff.ff.ff.ER$LHLDAH‹BIHMBEZ8D9rER(D)DA@tAPHsHLKPHH A@y89I()HHLDAtJnDff.ff.ff.ER$LHLDAHAHHLƋAEZ8D9rER(D)"SH1[A\A]A^A_]f.AFtEnLCHDLKPHI AFy89I()HHLDHAtafDff.ff.ff.ff.ff.ER$LHLDA<HAIHMAEZ8D9rER(D)APIpDI$HHLTfDR$HHL{fDI$HHL fDHHAZX \X[A\A]A^A_]EG,DI e@I9s DAD8LEfDH9s DA8HEI9s DAQD8LEfDEnDMvv@EAGtEG,LSHDL[PHI AG(L]DI8D9I$HHLDAHAHuL]Mff.ff.ff.ff.v$HHL0@u*HAAIHI4‹A~89rˋv()@AHuHD9s DDAD8HEDD`DLx@PHpfDI(D)HHEHHAG2tEgDHsHDH{PHHAG@J89R()HHHDHAt=ff.ff.E@$LHHDAu`H‹BIHLƋBEH8D9rE@(D)DhDLp>@R$HHHZfDI9s DAtTD8LEVf.EgDDMO88@LHD@DHxD`DLHDUIHAWAVAUATSHxLHDMXL_pA@<N<tBDDLf?tO<vEA"_1Hx[A\A]A^A_]ÐAp,Ix f?uff.A@H@I IIp<<%EEIfA?t9A<v.A"yA`hX \XDLf.AH@HIYp<<Ef;t<HHfHnLDpflLx)w DLHxIw foLHEƅI)ESLxDpHH@H=+HLpDxHU SHEIHLHE~SDxLpHLLLpDxRLLSHELHELuLEMM)Lh$SHuDxHxLpHL)H9rzLhLHHI9LHEfRDxLpHHEH N49LLpDxLuRLpDxHLLLpDxQLhRHELHERLLQHuHUL03XH)HHD跰H}HDxLpH9tQLpDxEHLDfoLHEƅ)M |  ?HH(-HHpH@H HP0A HHxPHPDA@tAp,IyHIYPHHA@(J89AR()HHHD"AtKDff.ff.ff.Ed$$LHHD A#H‹BHHL$NjBEl$8D9rEd$(D)EAtDaMYHDIYPHIËADB8D9R(D)HHHD*AIHAt9f.ff.Em$LHHD(AH‹BAIHM,ËBEu8D9rEm(D)f.L@CtDSMYHDMAPHIËCJ89R()HHLD*HAt2B@ff.[$HHLD(AH‹BIHIËBDk8D9rŋ[(D)DA`hX \XHHxL[A\A]A^A_]R$HHHfDR$HHHnfDR$HHL fDHA9s AD A/A8HE@IE9s ED(AE8LE$@HA9s AD(AE8HEU@DaELy@A"[AZX \XDH@DSEH[@HLpDxHELHEHIWHHLDxLpHXpAHxDD`ELx@HH(f sHH(aHHx H*L@HH(.HHxLHHxKHKfDPEHX@LHHH(HHx۝ HKHH(HHpHx}o?X;X1iKtLfff.UHAWAVAUATSHHHHDLQELWpyDADEH@ML[pA;MẺyuA(yADLSpA<M< DDL׋AH@I HKp<<Df?<f9<Ẻ1HMHPASHHǃHǃX^H L_L[pG<<uw,GH@M$LcpA$<<AL$q,Hy fDHHeH[A\A]A^A_]m DDAtq,LsHLkPHIƋA(z89R()HHLD:ALHAtEff.ff.ff.$HHLD8AuH‹BAHHI<ƋBD8D9rċ(D)@ACACEAmDI,dDAtDALsHDLkPHIƋADb8D9R(D)HHLD:AHAtVff.ff.ff.ff.I$HHLD8AH‹BAIHI ƋBDy8D9rċI(D)@DADHI@R$HHLCfDR$HHL9fDHD9s DD8AtC8HEHD9s DD8At+D8HEpHxNfDD@DHH]@Gtw,LSHDG(HLKPID`8E9@$LHLD AAt0]f.ff.Ed$$LHLD Au/D`@ALO$O$El$8D9rEd$(D)DD9s DD A'pfAD$tA|$LSHLKPHI4AD$DF8D9&v$HHLDAHAtXff.ff.ff.ff.ff.E[$LHLDAu0HƋFAHHM‹FEc8D9rE[(D)fDID9s DDAty8LEHA|$Md$3@HeHAgXH߹NX[A\A]A^A_]@(E)LHLv(D)HHLxL`UHAWAVAUATSHHHHDLQELWpyyDADEH@ML[pA;=ẺyuA(yADLSpA<M< DDL׋AH@I HKp<<Df?<f9<Ẻ1HMHPASϹHHǃHǃX^HL_L[pG< <uw,GH@M$LcpA$<<AL$q,Hy fDHHeH[A\A]A^A_] DDAtq,LsHLkPHIƋA(z89R()HHLD:ALHAt5ff.$HHLD8AuH‹BAHHI<ƋBD8D9rċ(D)@ACACEA}DI,tDAtDALsHDLkPHIƋADb8D9R(D)HHLD:AHAtVff.ff.ff.ff.I$HHLD8AH‹BAIHI ƋBDy8D9rċI(D)@DADHI-@R$HHLCfDR$HHLIfDHD9s DD8AtC8HEHD9s DD8At+D8HEpHx^fDD@DHHm@Gtw,LSHDG(HLKPID`8E9@$LHLD AAt0]f.ff.Ed$$LHLD Au/D`@ALO$O$El$8D9rEd$(D)DD9s DD A7p/fAD$tA|$LSHLKPHI4AD$DF8D9&v$HHLDAHAtXff.ff.ff.ff.ff.E[$LHLDAu0HƋFAHHM‹FEc8D9rE[(D)fDID9s DDAty8LEXA|$Md$C@HeHAgXH߹NX[A\A]A^A_]\@(E)LHLv(D)HHLxL`UHAWAVAUATSHHHHDLQELWpyyDADEH@ML[pA;=ẺyuA(yADLSpA<M< DDL׋AH@I HKp<<Df?<f9<ẺHMHPAS HHǃHǃX^H L_L[pG<<uw,GH@M$LcpA$<<AL!@q,Hy fDHHeH[A\A]A^A_] DDAtq,LsHLkPHIƋA(z89R()HHLD:ALHAt5ff.$HHLD8AuH‹BAHHI<ƋBD8D9rċ(D)@ACACEA}DI,tDAtDALsHDLkPHIƋADb8D9R(D)HHLD:AHAtVff.ff.ff.ff.I$HHLD8AH‹BAIHI ƋBDy8D9rċI(D)@DADHI-@R$HHLCfDR$HHLIfDHD9s DD8AtC8HEHD9s DD8At+D8HEpHx^fDD@DHHm@Gtw,LSHDG(HLKPID`8E9@$LHLD AAt0]f.ff.Ed$$LHLD Au/D`@ALO$O$El$8D9rEd$(D)DD9s DD A:p2fAD$tA|$LSHLKPHI4AD$DF8D9&v$HHLDAHAtXff.ff.ff.ff.ff.E[$LHLDAu0HƋFAHHM‹FEc8D9rE[(D)fDID9s DDAty8LE[A|$Md$F@HeHAgXH߹NX[A\A]A^A_]@(E)LHLv(D)HHLxL`UHAWAVAUATSHH8HHDLWLSpG<<t6DODMՀt7"1H8[A\A]A^A_]fW,Lo AMuɋGH@MLCpA<<FDADMƀ"uAdX \XLAdX \XLH8H[A\A]A^A_]\@DGtW,LCHLKPHI G(q89I()HHLDMHAtSff.ff.ff.ff.E[$LHLDAuhHAHHMAEk8D9rE[(D)I$HHLYfDApMpAfI9s DAxIDA@tApLKHLSPHI A@y89aI$HHLDMHAtJxff.ff.ff.ff.E[$LHLDAu0HAHHMAEs8D9rE[(D)I9s DAIIkA@H@M"IEI9FtHpH߉U UH8ALDLH[A\A]A^A_]u DAGtEgLCHDLKPHI AGy89I$HHLDHAtO}fDff.ff.ff.ff.ER$LHLDAu0HAIHMAEZ8D9rER(D)I9s DA#DIA!AE vAQAXVXL6pLpAAF LAQAXVXAG "u+IMIFH9NIWH9H9 Ѓ6HpLmLHpHp)IFH9pt H thDLDLH舽 I()HHL9AD`DLxAAQAXVXDL&HHNXHAgXxrAgXNXHHfDUHAWAVIAUATSHHHDLFELGpF<<tDLDf=vf FH@M MNpA<l<EAf=fA9K;ƅ%A9)DMME@AU~AELHhH<r <B EDt;~LHI< < EAEf=c5rIA9uSgfDF,H^ f=~rI9CCA"1A"uA{DX \XDLDFt F,I~HM^PHHNjF(J89fR()HHLD*LHAt@O ff.ff.[$HHLD(A H‹BIHHNjBDk8D9rŋ[(D)DAAtEQIvHDI~PHHAAJ89R()HHHDHAtI @ff.ff.ff.E@$LHHDA H‹BIHLƋBEH8D9rE@(D)AQ;pIeA96;;kpIƅ%OA9LDLژLDHLI݋Dff.AEf=A}AEHpL{I<^ <N AfA:A <ABIz tIzuABH|f. HЃ vH HLLLAL|I< < AfA} A}3AE(HpL{H< < Af>C=FH~ tH~uFH|ff. HAtЃ vHAtvH~AtLLQLL6LLK{I< < AAEf=5nIA9uf.Cf|mI9CmmIA9AA9^; ƅ%A9< fR$HHLfDR$HHH:fDADX \XHHL[A\A]A^A_];ƅ%E1DLLH%DLm[ LD- AfnA9Ff=elIA9AUf=H5lI9s9DDMb;CfA<$4A<$AD$vH0H]xH<^<EDHHPyH<<bEH0HwH<&< EDHpLwH<w<ALNL&LDL P0pWFѿ L&LHHHHmELHH芳 LDL P0pWF\ L&LLHLLLEH f%fzHHPswH< < ELHGwI<F<?Af=iI9C; ƅ%EHLHT WDGtwMNHMVPHIGJ89R$HHLDHAt'Nff.$HHLDAu)H‹BHHI 9L爅 ALLrA9FAA9EYIA9AcmXH?XLYIA9D$AIHAgXNXLؾ{LL~IAHDLk~HAHDL@~HADHL~EHqDHL}EHHLzL(L}HHLuAcmX?XLL追bAD=fD:FAHv5HpAH@HD{EH[HpAH@H>D{EH[LDLALHDHALDLw zAD$AMd$DDM`1A03XEftDA>t>A$" 1HX[A\A]A^A_]fDDn,DLv fA>ufFH@MA~H=MIH} H}Hƹ (SXZ A> A~H=[MIH}Z H}HƹF@XdZ A> A~H=MIH} H}HƹLX(Z A>NA~H=LIH} H}HƹcXY A> A~H=LIH} H}Hƹ |_XYX A> A~H=kLIH}j H}HƹcXtY A> A~H=/LIH}. H}Hƹ cX8Y% A> A~H=KIH}H}HƹJXX] A> A~H=KIH}H}HƹkXX A> A~H={KIH}zH}Hƹ VXX A># A~H=?KIH}>H}HƹdbXHX A>Y A~H=KIH}H}Hƹ nX X A> A~H=JIH}H}HƹVjXWA> A~H=JIH}H}HƹGXW A> A~H=OJIH}NH}Hƹ>eXXW A> A~H=JIH}H}Hƹ}8XW> A> A~H=IIH}H}HƹveXV3 A> A~H=IIH}H}Hƹ jXV; A>i A~H=_IIH}^H}Hƹ 3YXhV1A> A~H=#IIH}"H}Hƹ 'YX,VA>mA~H=HIH}H}Hƹ _XU$A> A~H=HIH}H}Hƹ}cXU A>l A~H=oHIH}nH}Hƹ UXxU A>A~H=3HIH}2H}Hƹ WXA~H=GIH}H}HƹmXU Hc;GIH GILmPLUL4H4I LL聈U;tGI}3H_GILUJ40IنLL莉U9AGIL苊A$HH ALL fAFtDn,ML$HDI|$PHIF(J89R()HHHDMHAtKrfDff.ff.ff.ER$LHHDA,H‹BIHMBEZ8D9rER(D)I$h YLmE$LLL HX[A\A]A^A_]fDAF#SIvI~OfDAGtA_It$HI|$PHHAGJ89R$HHHDHAtJiDff.ff.ff.E@$LHHDA$H‹BHHLƋBEH8D9rE@(D)R$HHH%fDAmX \XHXDLL[A\A]A^A_] fAvI~ 3fR()HHH@AFbIvI~fDI|$0mXq2 LmLa1fDIA9$s A$DAE$8LEIA9$s A$DA-A$8LE5fAF[IVAFAvH|bDA_A$MAF IVAFAvH|VDI$hLm 59DI@I|$0@_XLmLu)1 LaID$0L0baLLI|$0,gX0 LtaID$05CIL0D5CI`LL؄I|$0(SX0 L%aID$05CIL0D5yCI_LL艄E$L艅LLHE $AvI~ fDhE$LpID$0Lm5 CIL0D5CIC_fDAvI~ I$hLm @5BIL_pDIVAFAvH|fAvI~ fIvI~IvI~?AFtIvI~ @ID$055BI05BBIDAFIvI~GfDI|$0ajX[XA$Lx@AFIvI~3Lm5AIL]RI|$0wjXp. L]4AvI~ AFIvI~FIVAFAvH|@AvI~ AFIvI~IL [AFtqSIvI~AvI~ IVAFAvH|BAFIvI~IVAFAvH|FAvI~ AFtXIvI~ I|$0cXAFttIvI~IVAFAvH|AvI~ AvI~ oI|$0XX1AFt9IvI~AvI~ IVAFAvH|AvI~ IVAFAvH|LmLpZAFIvI~AFt=t#IvI~IVAFAvH|FIVAFAvH|lAvI~ ^1HMLE^XH=UUUHUMLhIH I|$0cXe) LXuI}YuI}0YuI}HwY5eMuL YAFIvI~Lm5LX`AF7IvI~IVAFAvH|A>A~H=8:IH}7H}HƹmXAGA>A~H=9IH}H}HƹcXGDA>A^H9IHHƹJBXHFAXXVXAvI~ AvI~ dIVAFAvH|^A$I$HAgXNXLv4IVAFAvH|LAFt{taIvI^TAFt=t#IvI~IVAFAvH|IVAFAvH|AvI~ IVAFAvH\AvI^ I$hI|$0 tutdt/mXm& LmAFt3tIvI~T,]X>& IVAFAvH|2AvI~ $kcX& 럾DjX& H7ILmE1LH0WwLLxH7ILJ47wLLyID957IWAFIvI~XIVAFAvH| AvI~ H5I|$0LmO% AFtUt;IvI~E$THXL[ELHA\A]A^A_]Ѐ IVAFAvH|AvI~ IVAFAvH|#AvI~ IVAFAvH|rAvI~ d@UHAWAVAUATSHHXHHDH~H{pF<<tvDEIFH@L$LcpA$<U<DfA>AtKAmX \X<AFIvI~8D~,DLv <tA~H=5IH}H}Hƹ _XBu A<$DLH  A>A~H=X5IH}WH}Hƹ (SXaB!A<$nEl$L-5ILHƹmXL%BmHh  H0 o ؖo !HX[A\A]A^A_]f.EFtD~,LKHDLCPHIF(J89RR$HHLDIHAtO6f.ff.ff.ff.ER$LHLDAH‹BIHMBEZ8D9rER(D)AD$tEl$H{HDHsPHHAD$J89R()HHHDHAtF5ff.ff.ff.E@$LHHDAH‹BIHLNjBEH8D9rE@(D)A>.A~H=2IH}H}HƹF@X@A$<<DA$f=A<$4fu3IA9D$)HXLH[A\A]A^A_]6tfDEl$DMd$EnL-0ILHƹGXL=VA<$El$L-/ILHƹkXL<ZA<$El$L-/ILHƹroXL<A<$'El$L-_/IL_Hƹ5jXLj<tEnL-.ILHƹLXL;A<$ El$L-G.ILGHƹkXLR; A<$IEl$L- .IL HƹroXL; A<$El$L--ILHƹ5jXL:tA<AF9IvI~fkXq79A>A~H=,*IH}+H}HƹroX57A>eA~H=)IH}H}Hƹ5jX6t:A>(EvL5)ILHƹ{nXL6HC00LHu7I<<~DfA<$AT$*I9HuL6I<DLHPIHC00p<rA~H=(IH}H}HxLHOIA?XAGIwIQfDDLHODI AGIwILfDAGSIwIgfDAWMDAG,Mw 3DEl$DMd$sf.AwI }fA>IFAF HHS00AwI xf.fA>Ai<AFoIvI~ff.kXA4A>A~H=&IH}H}HƹroX4A>'A~H=&IH}H}Hƹ5jX3t:A> EvL5&ILHƹ{nXL3HC00AwI f.AvI~ fAF3bIvI~fDHC00h<A~H=%IH}H}H ҥ 8H "LHugIWAGAwH|Uf.IWAGAwH|xf.A>EnL-S%ILSHƹ VXL^26A<$El$L-%ILHƹkXL"2A<$> El$L-$ILHƹroXL1yA<$y El$L-$ILHƹ5jXL1bA<$El$L-c$ILcHƹ{nXLn1&A<$El$L-'$IL'HƹDjXL21Hhǀ '@AvI~ fIWAGAwH| El$DMd$IVAFAvH|>AFbIvI~AvMn ^At$Ml$ Hh ~IVAFAvH|BIT$AD$At$LlHXLLH[A\A]A^A_]bA>EnL-"ILHƹVjXL/bA<$/El$L-"ILHƹkXL/A<$El$L-k"ILkHƹroXLv/A<$El$L-/"IL/Hƹ5jXL:/tEnL-G ILGHƹ |_XLR-yA<$El$L- IL HƹkXL-A<$u El$L-ILHƹroXL,A<$ El$L-ILHƹ5jXL,tEnL-ILHƹ nXL*A<$m El$L-XILXHƹkXLc*uA<$ El$L-ILHƹroXL'*9A<$ El$L-ILHƹ5jXL)tEnL-ILHƹcXL'HA<$El$L-ZILZHƹmXLe'Hh1҉ \AvI At$Ml$ IT$AD$At$LlIVAFAvH|$IVAFAvLlAD$WIt$Ml$9At$Ml$ IT$AD$At$LldAD$It$Ml$KIT$AD$At$Ll2AD$bIt$Ml$yAt$Ml$ -AD$ttIt$Ml$PAFtFIvMn5Hh At$Ml$ AvMn QAvMn At$Ml$ IVAFAvLtAt$Ml$ At$Ml$ 9At$Ml$ A>EfL%ILHƹveXL%A>EfL%ILHƹ jXL$cA>?EfL%ILHƹ 3YXL$)A> EfL%fILfHƹ 'YXLq$A>\ EfL%,IL,Hƹ}cXL7$A> EfL%ILHƹ UXL#{A> EfL%ILHƹ WXL#AA> EfL%~IL~HƹdbXL#A> EfL%DILDHƹkXLO#A>t EfL% IL HƹcXL#A> EfL%ILHƹJXL"YA> EfL%ILHƹ cXL"A>, EfL%\IL\HƹcXLg"A> EfL%"IL"Hƹ}8XL-"A>x EfL%ILHƹ>eXL!qA>EfL%ILHƹwnXL!7A>EfL%tILtHƹJBXL!AXXVXIVAFAvLlIT$AD$At$LlLIT$AD$At$LlAD$* It$Ml$AF?!IvMn%AD$It$Ml$gAD$It$Ml$AD$ It$Ml$}A<$9El$L-*IL*HƹDjXL5 Hhǀ *IT$AD$At$Ll:IT$AD$At$LlAD$t8{It$Ml$AD$t'sIt$Ml$,At$Ml$ At$Ml$ AFt+IvMf4IVAFAvLlAvMf AD$tnIt$Ml$IT$AD$At$LlSAD$It$Ml$IT$AD$At$Ll At$Ml$ AD$It$Ml$PAFIvMfAFIvMfYAD$L+It$Ml$AD$FIt$Ml$At$Ml$ IT$AD$At$LlUIT$AD$At$LlIVAFAvLlAvMn IT$AD$At$LlAt$Ml$ A<$El$L-8IL8HƹkcXLCbHhǀ 8AD$It$Ml$IT$AD$At$LlrAt$Ml$ bAt$Ml$ IT$AD$At$LlbAt$Ml$ RAvMf IT$AD$At$LlAt$Ml$ {IT$AD$At$Ll:IVAFAvLdAIT$AD$At$LlAt$Ml$ IT$AD$At$Ll~At$Ml$ nAD$tEt(It$Ml$IT$AD$At$LllIT$AD$At$LlAt$Ml$ IVAFAvLd@IT$AD$At$LlIT$AD$At$LlIT$AD$At$LlIT$AD$At$LlAt$Ml$ IVAFAvLd*AvMf A<$tdEl$L- ILHƹ ,]XLeHhǀ AD$tNt1It$Ml$AD$It$Ml$IT$AD$At$LlAt$Ml$ AFtIt/IvMfxAF$IvMfIVAFAvLd@AvMf 2AFtIt/IvMfHAF|^IvMfIVAFAvLdAvMf AFtIt/IvMfAFIvMftIVAFAvLdAvMf AFtIt/IvMfAFzIvMfDIVAFAvLdhAvMf ZAFtIt/IvMfAFIvMf(IVAFAvLdLAvMf >AFtIt/IvMfTAF IvMfIVAFAvLdAvMf AFtIt/IvMfAFP2IvMfIVAFAvLdAvMf IT$AD$At$LlAt$Ml$ IVAFAvLdAvMf IVAFAvLdAvMf wIVAFAvLdAvMf IVAFAvLd AvMf IVAFAvLduAvMf gIVAFAvLdAvMf IVAFAvLdEAvMf 7ff.UHAWAVAUATSHHHLH"DM}LpAEuW<</DAUEM "E1HHD[A\A]A^A_]f.<<DDMfA>tt6"uAmX \XLHHH[A\A]A^A_]woAEH@I@ff.ff.EI$LHLDALH‹BHHL NjBEQ8D9rEI(D)EAEtEu,HsHDH{PHHAE(J89R$HHHDMHAtEff.ff.ff.E@$LHHDALH‹BIHLƋBEH8D9rE@(D)DGtwLCHLKPHIGJ89$R$HHLDIHAtI@ff.ff.ff.ER$LHLDA\H‹BHHMBEZ8D9rER(D)GH@H4Hsp<<Df>>"AmX \XD@I9s DADgI*I9s DA)8LEDAEH@I4Hsp<<DD/"A4nX \X A?EoL-CILHu[ A>HuI.A~H=IHuHA?AH=IHuHUHUHuHECD%EHHxLPDD@H@M4A>HELmN"1HHLD]LU)O LUD]ALDLHH ELELLLHM)N AĄt@AЋULLH|H E}<AmX \XDLNDDf,DLv AB<A~"1HĈ[A\A]A^A_]@EFtDf,H{HDLKPHHNjF(J89R()HHLDMHAtUDff.ff.ff.ff.ER$LHLDAtH‹BIHLNjBEZ8D9rER(D)AyYAYX" \XDLf.EAtDyH{HDLCPHHNjAr89R()HHLDIHAtMff.ff.ff.EI$LHLDAH‹BIHL NjBEQ8D9rEI(D)R$HHL[fDAYX \XDLHĈH[A\A]A^A_]FYfDR$HHLfDEjDMRAA9 fA>8ff.fA9t A9u LHEfInƅfl)EA>)f E~L=hHLpLLxZLxLpLHH@H=HLpLxHU舭HEHHLxHEA>Lp E~L=HLpLLxHhLxLpHhHLHLpLxA>L}LxLp A~H=aHdLxLpLHEL}HMLEMI)M)A9T AqH5HLXHL`HhLpHxL`HxHH@LpHhL9LXLLpLxHUL9 HH'LxLpHHEH_N<1L}A9V AqH5THLhHLpHx?HxLpLhHLLpLx葫LxLuLpA9o AyH=HLxޫLxLHEL}MX LLx豫LxHLLLxL H}LxL9t )LxDLDLfoHHEƅ)M8 LfDI9s DA)DII9s DAqDIAzAE)AZA~H=NHhpLxL7LLxphHAAyH=HhpLxLLLxphIĀAzH=HhpLxL蒩LLxphHƀANH WHAEqL5BHEjL-.HJ#H9HHL+I|LLf"AYX \XDLDDyDLIAABtEjHsHDH{PHHABJ89R$HHHDHAtMfE@$LHHDAu0H‹BIHLƋBEP8D9rE@(D)I9s DA9DIAD`DLpAbR()HHH&@AAAEiL=hHxLMLXxLHƀ.HxABLIL!LHxILx1I9I)HLK<Lp1ɅHxLp1HLLc5 JALDLHa3 BL(AF@I^2f.DxDLHA AQH HEfhLpILxLH֥hHLxLpIŀ`ABLxLL4L营LLxI1M9LpLxLLLLh[1ɅLHpLHLM)L3 LxALDLH1 L爅ufDhDLPAABMj aMjUABMlGAAMq "MqAAMtAFIN INAFHLAB`IrAA0Ma&EyEfAADIqH HAzLhHpHLxH`茣fEHLxHpLhICAMi`2AAMlAB1MzABM|AFIFHHHHLM~H0AALIQHrHL9IqH}AF>IF0AAzIA1A03XHHNXAgXHqLAmXEa`ArA^AApHIACAvAfA@1MnH HAzLpLxHH`h蕡fEHLxLpI@`Mfh*AFMdABMrABMtMi EzIABZEBMz Aq!HĈH[A\A]A^A_]H6HEHIVLH*LxLpHAF4AAAQHrHL9HIq 8LAVM~ AB|EBMr Mf ErIEnGAFtZIFABDEBfAMivEaA^Ar6MBMzAAAqAFHHHH3LIvHAFL|AFABEBfMfEBA)Mi AAAQHrHL9IIHAAHttJMBMr5AAAF?EnEBMzlEB@_Mf 5EBMrAu AF IVLDLLL9L!LLHLDLDLH$ YLy ?AFff/v|<#H~3AdXVXOHHIFLHHx HLA<<[AFff.G@tD`,H{HD@(HLCPH׋J89R()HHL HЀt.fDff.I$HHLukH‹BIHH NjBDI8D9rˋI(D)AuMu fR$HHLxfDAu,MM ;DI9s DQI$fHSHHHEfHnHHf~MH@ 1LL LcfHLHDž)讵 ;M LHLLF HLDDL , 2 dHH(RHHpH@H HP0Iz HHxiH]EFtDf,H{HDLKPHHNjF(J89R()HHLDMHAtMtff.ff.ff.ER$LHLDA,H‹BIHLNjBEZ8D9rER(D)R$HHLcfDAYOX \XDLHHH[A\A]A^A_]2fD<u AF IN'oX1LLLL脇LLLLHLDHLDL wLjAAcIqMifDI9s DADIAAtEiHsHDH{PHHAAJ89SR$HHHDHAtGufff.ff.ff.E@$LHHDAu0H‹BIHLƋBEH8D9rE@(D)I9s DADImAmXAXDLfEiDMIA&"AZX \XDL~DAmR()HHH@Hƅ_HH6HHHxLL}: f CD`DLpAAqMi fIFLHx׶ HcIH ȄLHII~DH¾LLH蟳 LLLHL豄L THH(BHHx@ Ho!f.AuDhDLHAVHH(IQAAAqLlcHH(HHx H̃~HH(lHHx襃HHx蕃H艃;HH()HHpHxHHHAgXNX-AgXNXHHDUHAWAVAUATSHHxHHLGLCpG<S<toALxGH@IDHpbXwHxDH5 &HxAYXVXDAR$HHHfDHpmXwHxf88HpBDXvhMAdXJHx)Hp~lXvgHx8 xHx H9H7A~lX \XDHMArVXDHƹAXxLpA\f.HxE1DHHMg u }HxDH 8HxHf8qHx8u@uuLx1DHL HuYA?aHxAgHyAqH|.pX ff. fDIHоLxHо[HpdXtuEHx>jMAdX \XDRMHAMA~eX$HpoXtuHx8)MAoXAHy bHyVAH|I $H9HH@*sHqHyLHpvgXsHxg<MAvgX \XDUHxDH zMAyiXAXHxArVXDH߹AXZXMAmXDHƹ \XHMABDXVXAlXHx \XDHHMDHA_X \X~5qHy *AAGM_<]<BDfA;t A;LxE1DHHMLpL =fA>Lp:DpLxMA}h}gXL,r_XLr~eXLru$fA}AE;ضHt ;HdXLqA}oXLqvgXLqKAUBDXLhxqhuGmXLNqfA}t A}yiXL&qNbXLqu AE<<AELHuI<<pfA?pHA9GwHuLI<<NpA<$xEt$L5H4nXL9p}gXL$pu A}_XLpAEPwlA}ue<A}H=Ht HA}A}H=lHHhhpHhHƹ YXoxxA_XLH߹ \X[YfDLxE1DHHMLĢ }AlXAXDLH HxxMAbXqHy HxE1DHHMO }HxMDHAlX \X-1HQAqH|Hq6AvgX \XDHHxABDXVXDBDXL8nAUB<xAvgXLH߹ \XoXLmA}:xAoXLH߹ \X`hXLmvfA}jAE<ZxA`hXLH߹ \Xa_A}txAbXLH߹ \X53AEI} VI}JAEH|A< H8? < LHI<r<DAEf=K=HA9};OD~,DHF H8B<-H8x%"1H[A\A]A^A_]f.EFtD~,H{HDLKPHHNjF(J89*R()HHLDA*]ff.ff.ff.ff.ff.E[$LHLDATH‹BIHLNjBEc8D9rE[(D)AA;JHKA7H8?;HƅO)H8f?H<ZwH H<1hfA9Q <hA)<H8#H2AAtEQHsHDH{PHHAAJ89#R$HHHDA\PDff.ff.ff.ff.E@$LHHDALH‹BIHLƋBEH8D9rE@(D)R$HHLfDAYX \XH8DHH[A\A]A^A_]f~HA9AH88ArVXAXf.R()HHH@AA_f "ADX \XDLRH88 ƅOE1DLHHOD(L0@ L0D(OAlXDLH߹ \Xt3<xA~H=H A>HA~H=HH0dH0H9EA_XLH߹ \XDAFtAvLKHLSPHIAFz899R$HHLDA;5ff.ff.I$HHLDAH‹BHHI BDA8D9rŋI(D)DAEtEeHsHDH{PHHAEJ89R$HHHD ADff.ff.ff.E@$LHHDAuhH‹BIHLƋBEH8D9rE@(D)I9s DA8LENI9s DAqD8LEfDAvMvDEeDMm@AFI~ I~vAFH| A>HmAFtw/IFqfDR()HHLDAHпfDR()HHHD ACHйfDAFfDH89s DADSH8pLpfDD`DLhL@I9s DA D8LEzfDAFB<$fA9AH8H HpEQDMI AA - MALL1HLd H8ALDHfƅO fDH8OOA H8 HPH Lh>fDDxDH@H8DMD L(AHfHnH fl)fTH8A<,<H8D(L0D`L%KHLK_L0D(IHD0L8H{ML8D0LtNL8D0Lh LLIHwM)LHMMuL8D0HD0L8L8HD0HALDH< [DL(MD AfDAlXDLH߹ \X]A_X \XLH@AL,1A}LD0L8]L8D0HLLD0LL88DLHߋ0H8Y pL爅88VH fA95qHA9qWHA9AL5LHLdLDHDH8 AA9 H@IfoHEEƅD M)Ufff.Af=kA?AGHPLάI<<DAEcL%!HHELmL+mHH0L)H(L H(HH9rvHEHuLH)H(H H9G HuH0HH)H}HLHHHE)[HEHHKH(HHML H}LHZL HELHpHE蒬I<<DAf=5MHA9w0HA9D$HfHnH fl)4H8A LaLADiMddA9hHA9D$fACMc 6Mc*ACMdDAGtEwHsHDH{PHHAGJ89;R$HHHDAl0fDff.E@$LHHDAH‹BIHLƋBEH8D9rE@(D)DACtAKH{HLCPHHACr89}R$HHLD"ABfDff.ff.ff.EI$LHLD Au)H‹BHHL NjBEQ8D9rEI(D)I9s D AIjI9s DAD8LEACM[A!EwDM H0HHEH)LHHHEWHEHHH(H HHPtWHcR()HHL|R()HHHAADPDLHHHAgXNXHoL8Hй~wH UHZAADHLDH EAKAH8VLn .DD0L8\0EHH8H Hй:PLXA\DpDLxMED fHA9ALeMLIVHLLLĴH}H H9tUDLDHfoH8HEƅ)] L8m8WgnDiLa hEAHоHйP~HH@LlLi 1A03XpH ;H@?X;X1TVUHAWAVAUATSHH8HHDLFLGpF<'<tCDVEMƀtMtH"1H8[A\A]A^A_]DDf,DLv AuFH@MDUL]DxHpHHhHpHEAOHEH`HhxH=HHpLxDU=DULxHEHpHhH`Hc}HhLxHDUHMHpo>Hh}HHAD BH;HMHH)H)HuHHHUH)HuHAHDULxHpt;HpH=DULxHtHDULxA?AH=HLpDxH}fDAZX \XMqpAE<<AAMA׀{A"A4nX \XDL|IA9s ADAA8LE@HE9s ED8AE8HE@?t\Af.D_EH@A"AZX \XDH@?LωULMXLMUf8H|8sA"cAAmX \XHTpALPDDXEHxE},EMu Ad@MHAAEtE},IyHDMAPHH AE(q89I$HHLDHAt)Pff.ER$LHLDAu)HAIHLNjAEZ8D9rER(D)IA9s ADAEI|LωULM襹LMUf8Rp@L`p@Md4HxLMUr,ULMHHEHA$IH]A uO@ff.ff.ff.ff.<+IADAEA$I|$I<%uHھnX1LMEI1ELMA AELωULM艸LM8HEAUUA"UA4nX \XHAEH}LM+A>LMHu AF}HuHLMMLMH}LM\+LMHDLEL` E>H߈EE*I()HHL^HH CnHLMHωUI9+ULM;KH nHLMHωUI+ULMHH|vLMUHuY*HuUHHELMIƅ~lFMlJALM0A~LMA_@!A|$@@@tE&IM9tE'IA uA+IAH}LMM*;LMHu C HuH]LMH賈LMH}LM)LMUHHuELŶ E`A"AAmX \XHADxELpALAԾnX1*)ILMCt:L{uaCsM|_L` @>HuHԈLMsL{ 0HuH]H讈LMH@HsAgXNXLUHAWAVAUATSHHXHHDL_L[pG<j<DWDM߃AGH@IHEHCp<<dHEDB<A?XEgL%%kHLeA?L<(HL, HH@H|HMg'HEIHHMLiHt/f.H} ,L HIIsA$A?AH=jH'HL}LeLLL'HuHLDD% EU  u{HEH(upHEHpH@H HP0f HEHx&H}&9fDw,L Aff."t1HX[A\A]A^A_]@AaX \XLHXH[A\A]A^A_]f.DGtw,LCHLSPHIG(J89R()HHLD"MHAt@fDff.ff.Ed$$LHLD A+H‹BHHM$BEl$8D9rEd$(D)R$HHLifDHE@tDpHsHDH{PHHHEJ8@9R()HHHDHAtcff.ff.ff.ff.ff.E@$LHHDAH‹BIHLƋBEX8D9rE@(D)I9s D AtetHIHEx"HuAYX \XDfDA~pLxAafHEDpDH@HEAGtaMgMAGMdLeA?uTAwAGtK)IWfDR$HHH@Mg LeA?AH=QfH8AWHEH(MfDHU9s DADt6HEfAGtIwAwHEZ HEH(HEHx H}3"LeA? AWHEH(HEHx9t H}!HEH(HEHx!HEHx!H}!oHEH(`HEHpHxDSHHHAgXNX#UHAWAVAUATSHHXHHDL_L[pG<j<DWDM߃AGH@IHEHCp<<dHEDB<A?XEgL%cHLeA?L< HL HH@H|HM' HEIHHMLiHt/f.H}跻 p%LF HIIsA$A?AH=IcHL HL}LeLL~LHuHLDD EU  u{HEH(upHEHpH@H HP0& HEHxIH}@9fDw,L Aff."t1HX[A\A]A^A_]@AaX \XLHXH[A\A]A^A_]Jf.DGtw,LCHLSPHIG(J89R()HHLD"MHAt@fDff.ff.Ed$$LHLD A+H‹BHHM$BEl$8D9rEd$(D)R$HHLifDHE@tDpHsHDH{PHHHEJ8@9R()HHHDHAtcff.ff.ff.ff.ff.E@$LHHDAH‹BIHLƋBEX8D9rE@(D)I9s D AtetHIHEx"HuAYX \XDfDA~pLxAafHEDpDH@HEAGtaMgMAGMdLeA?uTAwAGtK)IWfDR$HHH@Mg LeA?AH=_H8AWHEH(MfDHU9s DADt6HEfAGtIwAwHEZ HEH(HEHx| H}LeA? AWHEH(HEHxl H}HEH(HEHxHEHxH}yoHEH(`HEHpHxLHHHAgXNX#UHAVAUATSHH HHDLWLSpG<<DDWDMՃGA}<GH@M4LspA<1<DAA}EML \HLMHLLm輩 LHzHLDDLI EU] . \ uoHEH(udHEHpH@H HP0 HEHxH}-fw,Lo AUf"t1H [A\A]A^]fDAaX \XLH H[A\A]A^]@DGtw,LCHLKPHIG(J89R()HHLDMHAt7ff.E[$LHLDAH‹BHHMBEk8D9rE[(D)R$HHLyfDAFtEfHsHDH{PHHAFJ89sR()HHHDHAt1fff.E@$LHHDAlH‹BIHLƋBEP8D9rE@(D)I9s DAt}t`IAF t)A(LX \X"DLfDI~ABDXVXAUcfDpLhAUFfEfDMvAjAEt)IuMmzfR$HHHAuI X3+HEH(@I9s DAtDtIAD`DLpA HEH(HEHx H} IUAEAuLlHEH(jHEHxg H}OHEH(@HEHxHEHxH}HEH( HEHpHxFUHAULp0ATISHLH./H0td,H;0tH0Hǃ0I$H0LHPH0H0ID$H 0ID$H[A\A]].1 HH!H0|IU1HSHHֺlCXHLGHHM!I0HH]ÐUHSHH(Ht51HMHUؾoXLEHEHEHE?tf1H]HE~EHH#UH0H fHnȸflH]HH׋16fff.UHAWIAVAUATSHIIL47:fD_€~!ʍKӀttIA]IM9tA$I uAE+IM9uAEHL[A\A]A^A_]fLӾnXIf.Iff.UHAVAUIATSHHIA Jfff.ff.ff.ff.<+HADAD$t6H{I<%uHUܾnX1HEdEAD$uA$HL[A\A]A^]Iff.UHAVAUATSHH HHDLhLopPt6DPt?1"7H [A\A]A^]f.D`,DLh AUuLuL5rH=OALDLH{ H [A\A]A^]fD@tD`,H{HD@(HLCPH׋J89R()HHL HЀtFff.ff.ff.I$HHLukH‹BIHH NjBDI8D9rˋI(D)H DLHA4nX[ \XA\A]A^]R$HHLHfDI9s tWDt9IFHHHAgXNX膹H [A\A]A^]fAU fDD`DLhAUUHAWAVEAUIATISHHD}H}HLMH}L~AujEbX^XMHEȺE5XHL1 HM<ELHMHLL)}`XH)1H[A\A]A^A_] LX11L DE^XLIŸbXWHHEM1Q LHM< EuLH޺pXLL)H)1 H޺*pXLcMLLL)H)1 HIAtULHLqpXL)MH)1 H޺*pXLcMLLL)H)1 MLcMD9uLH޺pXLL)H)1 HM|UIAHD]DUHt88t3EtIHt"8tEEDUD]]DŽ]ÐUHIHAUATSHHr_BIHDNH?RE@A9|2] 1҅IH[A\A]]fHHt DNO IJ4DIO IJ Ƀu<t\<l<C<;Dϓ r1؅ɉ¸IH[A\A]]DFtVL_HLgPHM ËFEQ8D9%EI$IIME)ALAtN}fDff.ff.ff.ff.v$HHLD(Au1IAAAHHI4AADn8D9rƋv(D)fDLD9s DD(A}8HEDAtDAL_HDLgPHM ËAEQ8D9EI$IIME)ALAtL{@ff.ff.ff.ff.I$HHLD(Au1IAAAIHI AADi8D9rƋI(D)fDLD9s DD(AD8HEB@DADHI*@VHvfDEI(D)IIMf.EI(D)IIMPHp:D@DHH@UfHAWIAVAAUATELHSHHHL LPDHDHDžHHDž`)Ph; RHHH<@H8HH(HIf;LHDž0MIff.;CHpHXH<<EDAOIwAM/Eg>t=Et`A~lXL \X+H H(1K~tH0EtFHJH8-uxuHHuXH<<EIf;KH9C ;L8H(\MMLm 0L菖ÅMtuH(Hp>|LH8tBH(AL8Lh LMII6>LIIM9uLH(HDHH[A\A]A^A_]DFt~MUHMMPHI‹FDB8D9R$HHLDAHAt$K@$HHLDAu)H‹BJAHHI‹p89rʋ@()HE9s EDAwA8HE~@CtDsI}HDMEPHHNjCr89R$HHLD HAtXDff.ff.ff.ff.ff.@$HHLDAu)H‹BJIHHDH8D9rɋ@(D)ĐHA9s ADAE8HE%@~AHvgDDsEH[@R(D)HHL&R()HHL@xAHpDDpEHXPW,  HXH(HXHpH@H HP0+HXHxKHX?ƅP~zPfnDcLfAnLmHEDHLfbfA~HEfE L( WHXH(EHXHx- HXƅPD~AVfnÍCHMfAn8HH}LfbfA~HEfE\ HM8H>LYL8IH(ALpIvL[tIv>tLVIIM9ui~tAVfnÍCHMfAn8HH}LfbfA~HEfE蔎 HM8H뇨HXH(fD~ PfnLmDcfAnLLDHHEfbfA~HEfE LHXH(RHXHxR HX1fR(HXH(HXHpHx*2HXH(HXHxSHXHxCHX7ƅPH(1UHAWAVAUATSHH(HHDLFLGpF<r<DEMAf=A>f!DHA9F FH@MEKfA?'Afqf=y A>DLHAlX \XTH([A\A]A^A_]DDf,DLv Af=)CHA9FA>"1H([A\A]A^A_]EFtDf,H{HDLKPHHNjF(J89R()HHLDMHAt%4ER$LHLDAH‹BIHLNjBEZ8D9rER(D)AF* ASYX \XDLH(H[A\A]A^A_] fR$HHLCfDEoDMAf=AHA9GAAG"ADX \XDL^DAFdUI9s DAD8LEfDAGtEoHsHDH{PHHAGJ89#R$HHHDHAt'Uf.E@$LHHDAu0H‹BIHLƋBEH8D9rE@(D)I9s DAD8LEmfDAF;R@HfA?;:@HtA>AFAf=:Af^HEH-A>A?HLME1DLE#HEHLHDM`LcpA@<<YDDMAf=A:$f7?HA9BA@H@ML[pA<x<hDAf=A ZfAHDLH\ AGf>HA9GfD~>HA9Gn>HA9GHMLEDLH, }AlXDLH߹ \Xf>HA9FDDZDLHHE耆 R()HHH@D`DLpg@HUHH9=HA9GDA@tAP,LSHL[PHI A@(q89MI$HHLD)At< fff.ff.Em$LHLD(AHAHHM,‹AEu8D9rEm(D)f8HA9F FH@Mfd;HEHEfA>EkfA?GAff= A>DLHAlX \X贝H([A\A]A^A_]DDf,DLv Af=7HA9FA>"1H([A\A]A^A_]EFtDf,H{HDLKPHHNjF(J89R()HHLDMHAtETff.ff.ff.ER$LHLDAH‹BIHLNjBEZ8D9rER(D)AF ASYX \XDLH(H[A\A]A^A_]IfR$HHL#fDEoDMAf=6HA9GAAG"wADX \XDL^DAFD5I9s DAD8LEfDAGtEoHsHDH{PHHAGJ89#R$HHHDHAt'Uf.E@$LHHDAu0H‹BIHLƋBEH8D9rE@(D)I9s DAD8LEMfDAF;4HfA?;z4HtA>AFAf=:Af^HEH-A>A?HLME11DLEfHEH|LHDM`LcpA@<<\DDMAf=A:'fz3HA9BA@H@ML[pA<{<kDAf= A ]fAHDLH{ f.AGf2HA9GfD2HA9G2HA9GHMLEDLH! }AlXDLH߹ \XWfN2HA9FDNDLHHEz R()HHH@D`DLpG@HUHH9q1HA9GDA@tAP,LSHL[PHI A@(q89MI$HHLD)At< fff.ff.Em$LHLD(AHAHHM,‹AEu8D9rEm(D)1HA9GAAGpAF}DhDLxc0HA9B0A:uABff."ASYX \XLH]AFBLHI/AG.LHAGfAG90HDDHMLELHj Eu.AlXDLH߹AX觕HufI9s D(A8LEABAP,MP I()HHL./HA9CA AC"ADXDLH߹ \Xڔ{ACtEKLCHDLSPHI ACq89%I$HHLD!HAtT{ff.ff.ff.ff.ff.E[$LHLD Au)HAIHMAEc8D9rE[(D)I9s D AD8LEEKDM[ACfAC9-H-HA9ClpI()HHLPLPMHDHDLXAFDUHAWAVAUATSHHxHHDLFLGpF<Z<DEMAf=A>f,HA9FFH@MƅfA?fA>HEHtHUHt H9RHLMA1DLEhHEH&LHDM`LcpA@<<qDDMAf=A:_f|+HA9BA@H@ML[pA<<mDAf=0A _f8AHDLHs MDf,DLv Af=*HA9FA>"1Hx[A\A]A^A_]EFtDf,H{HDLKPHHNjF(J89R()HHLDMHAt]fff.ff.ff.ff.ff.ER$LHLDAtH‹BIHLNjBEZ8D9rER(D)AF ASYX \XDLHxH[A\A]A^A_]鉏fR$HHL fDEoDMAf=Q)HA9GAAG"_ADX \XDL^DAF,5(HA9BbA:uABQ@ff."ASYX \XLH荎I9s DAD8LEifDAGtEoHsHDH{PHHAGJ89R$HHHDHAtGufff.ff.ff.E@$LHHDAu0H‹BIHLƋBEH8D9rE@(D)I9s DAD8LEfDV'HA9FDHLHLE ff.AlXDLH߹AX0fAGzfAG9&H[fD&HA9G<@&HA9G\HDLHLE u dfA?&X&HA9GHuLv2I<<DDHuLLhd3LhA<<du!AytAAH$H8-u xA~lX \XLH詋@%HA9FoDADLHHEn R()HHHF@D`DLpW4DA@tAP,LSHL[PHI A@(q89I$HHLD)At(zEm$LHLD(Au0HAHHM,‹AEu8D9rEm(D)I9s D(A8LEDhDLxAP,MP ABI()HHL $HA9CA AC"ADXDLH߹ \X跉ACtEKLCHDLSPHI ACq89I$HHLD!HAt1Xfff.E[$LHLD Au)HAIHMAEc8D9rE[(D)I9s D AD8LEEKDM[ACfAC9"H"HA9CjnI()HHLPLPDAAtAQLCHH{PHI AAq89I$HHHDHAtZ~ff.ff.ff.ff.ff.EI$LHHDAu)HAHHM AEQ8D9rEI(D)I9s DA8LEHMHDHDLXAQMII()HHHAlXDLH߹ \XHAlXDLH߹ \X*PLHf.UHAWAVAUATSHHLHDMHLOpA@<<tBDAHDL΀tA"1H[A\A]A^A_]f.AP,Ip uA@H@MLCpA<<VDELL(f88"tAmX \XDHAdX \XHH[A\A]A^A_]锅@DA@tAP,HsHLSPHH A@(y89I()HHLDA, Hff.ff.ff.ff.E[$LHLDAuhHAHHLƋAEc8D9rE[(D)I$HHLdfDEpDI@H(DH9s DA`HA@H@M LKpA<\<DEMA$f=A<$fHA9D$AAH@M LKpA<I <DAf=A  f HFƅ3HDž8HDž@>H v H(8 xH=H@r <h ^ ƅƅ fA<$ fA92 fA<$w H8HtH@Ht H9tfLHHH4LPHDžHLHD4HDž`)P RP LHKu ~H(LHu(I<<EHfA<$NtHA9D$=OVHA9D$UA<$uAD$Bff."ASYX \XDLPDEA@tEpLKHDLSPHI A@y89I$HHLDAy 1ff.ff.E[$LHLDAu0HAIHMAEc8D9rE[(D)H(9s DA D8HD(H(PHpkEAAtEyLSHDL[PHI AAy89I()HHL9@ AQff.ff.ff.ff.$HHL8@HAAIHI<‹ADg8D9rŋ(D)DI()HHL9@I$HHLEEiDMI f.AD$tE|$IuHDI}PHHAD$J890R$HHHD A=ff.ff.E@$LHHDAH‹BIHLƋBEH8D9rE@(D)DFtNMMHMUPHIFz89dR$HHLDA Dfff.ff.ff.v$HHLDAu)H‹BHHI4BDF8D9rɋv(D)ĐHA9s ADAA8HEB@IA9s ADAE8LEe@NAHvDE|$EMd$3fID9s D8@UD8LE^DR()HHL@R()HHH@AD$R2EyDMa@LHȿ{LH\MLL(L`Aą[ MtaH Hp'>HVUIt2HALx I7>HIIcVM9uHfWHIMHHDL_L[pG<h<x DWDMـAdX" \XLHztHA9A/A AA"=ADX \XDLAAtEiLCHDLSPHI AAy89I$HHLDA EDff.ff.ff.EI$LHLDAHAIHM AEY8D9rEI(D)oXL HLt H@>ƅƅ FI9s DA&D8LEmDxEL`HAHp+DpDH@H(HH?F t  8G hABDXVXHxTAAfHA9AfDH@H~ 'H~FH|ZHA9D$8DH3LHL8L( L(3N AlXDLH߹AXwHA9A8<HA9ALH3DHL@L(* L(u 3$ fA9w|HA9AgLHuL(L(I< <M DELHuL(D2AL(<<LDu9A~t2A~dpXH=HD(D(LA~lXDLH߹ \Xv:fDI()HHL1zHA9D$xDL(,H(DHHEX DxDL`ƅƅ ~lPfAnL}HfnEl$LHHEEfbfA~HEfE_X LHп]Hй~ fnAWfAnHAD$H}HMHfbfA~Љ(HEfEW HMD(HL(HȿPh; P sHXH(aHXHpH@H HP0HXHxHXƅP>H/NIHALxIwL8tIw>2H/OIIM9uGH@I"A1H0[A\A]A^]Ëw,LO fA9uȐff.GH@M,LkpAE<<DAU"uA4nX \XDLDGtw,LCHLKPHIG(J89lR()HHLDAt%E[$LHLDAH‹BHHMBEk8D9rE[(D)A9NAyH=;HHu/ IHfHHE)EHEvHEHfInƺE@HDHHMDLJ E=U I HEH(HEHpH@H HP0ԭHEHxH}fAEtEeHsHDH{PHHAEJ89R()HHHDHAta@fDff.ff.ff.ff.ff.E@$LHHDAH‹BIHLƋBEP8D9rE@(D)R$HHLfDAmX \XLH0H[A\A]A^]Lf@R$HHHfDAAIy IyAAH|DI9s DAtm8LEI9s DADtCIKEeDMmAU/pLHfDAUHEH(fD`DLhAUMH NHEH(?HEHxv H}X$HEH(HEHxw H}.HEH(HEHx HEHxH}HEH(HEHpHxHHHAgXNX-dwfDUHAWAVAUATSHHXLHDMHLOpA@<<t=DDLf?tB?t="P1HX[A\A]A^A_]DAp,Ix f?u@A@H@MLCpA<,<DDMfA}t'A}t "uAmX \XLfA@H@I4Hsp<<DEIfA;tA<FH@LELULcELu1LLHLUDM4LUDMQR()HHL@EbDMRd@"SAZX \XDLDR$HHL HEH(H}LUjELUDI9s D0AD8LEfDAEtzIU4fDAEtdrMEM9f5^GLLU~LUDpLhfDLHAUEEM9FDHDLx HEH(HELUHx_ H}>ELUD`DLPHEH(rf zHEH(kHEHxL_ H}âPHEH(-HELUHx H}蕢1LUfEAUEEM91HEH(HELUHxKHEHxHEH(HEHxb H}HEH(HELUHpHxHEH(nHEHxϡHEHx¡H}蹡FHEH(7HEHpHxD@ff.UHAWAVAUATSHHXLHDMHLOpA@<<DAPDLπGA@H@MLCpA<<DDMfA}OA}D"1HX[A\A]A^A_]DAp,Ix hff."uAfX \XHHXH[A\A]A^A_]JDA@tAp,H{HLSPHHA@(J89R()HHLDAtRfff.ff.ff.ff.E[$LHLDAH‹BHHLNjBEk8D9rE[(D)R$HHLdfDDA@tApLKHLSPHIA@J891R()HHLDMHAt,SE[$LHLDA,H‹BHHMBEk8D9rE[(D)H9s DAiPHaA@H@I4Hsp<<DEIfA;tA<FH@LDA@tAp,H{HLSPHHA@(J89r}R()HHLDAt6bff.E[$LHLDAH‹BHHLNjBEk8D9rE[(D)R$HHLfDDA@tApLKHLSPHIA@J89R()HHLDMHAt,3E[$LHLDA H‹BHHMBEk8D9rE[(D)H9s DAI(HA@H@I4Hsp<<DEIfA;tA<FH@LDLHDAGtEgLCHDHsPHIAGJ89R$HHHD2HAt/]ff.ER$LHHD0Au0H‹BIHMBEr8D9rER(D)I9s D0AD8LEvfDDNDL^AEIu IusAEHteM4k L o HEH(HEUHpH@H HP0}HEHxٌH}ЌEUUR()HHL:"AZX \XDLEAEtOMEM965GH}7R()HHHpLhiEEM9DHDLXHEH(H}UEUj ZHEH(KHEUHx)H H}蠋EU%D`DLx_HEH( HEH(HEHxG H}+HEH(HEUHxG H}1UfEEEM9oHEH(`HEUHx辊HEHxHEH(4HEUHpHx>HEH(HEHx H}dHEH(HEHxCHEHx6H}-HEH({HEHpHx踻pUHSHHHu>HHt+s.u@.t)@/t@\uSHHuH]@s@/t@\t.HHHQHH9u%fH /t%\t HJH9uHSH_HJHSG@ff.UHAUATSHH_0Lc0IiԈH@tdLlHfInflL9t)E芈foEMiJDŽ#B#AEH[A\A]]@@H[A\A]]fUHAUATSHH_0Lc0IiԈH@tdLlHfInflL9t)EڇfoEMiJDŽ#B#AEH[A\A]]@@H[A\A]]f ff.UHAVAUATSH_0D0AMcIIiňH<H@Ht HMiEMiII@LlI(I ߆H{H1HǃHH)HIF0ǀ0[A\A]A^]KlfDUHAVAUATSH_0D0AMcIIiňH<H@Ht HMiEMiII@LkI(I H{H1HǃHH)HIF0ǀ0[A\A]A^][lfDUHSHHG0H0HtHȒH[HuH]@UHAUATSHLg0Ic$0LiMAhIPHtHHt 8LiMI}jA@u'Ahu LpS! HiӈAhLiMI}tSHiۈAtaH[A\A]]ÐH AhXHiӈA@u눐I}藆uH1[A\A]]fDI}臆DUHcHAWAVAUIATSH8 HHiH_0HƅHHDž@AAă@s;HiLMH@uHI[DLwHH襃11H߉WLH范 LIH)DX1蟂HHI1LxvuLHxLiIAx HiH6 NvLւ DLH)ƺpX1H81͈HH@HiHBD kBƅX ƅDAM(LL11L謷LI MDH)ƺ@XL1LHIgLI9؃LA蝁 EDH)ƺpXL1谀LAkXHIm DLLH)ƺX1MyLHI< DLLH)ƺX1M DLLHIA;hXLE LDH)MX1LAHIIPHtD A LD蘀LXLDH)D1HLHI1HHEHTLLDLH)1@XA5jX_HIA~Hi@kXLDL MLH)DpX1AylXHIHiuAnXoXLEL MLH)D麠X1~ANbXHIHitADjX<t<AlXiXLDLA L6LLDLH)ƺX1G~HIHiHutA5jXkXLLEL~LDXLH)L1}LHI~LLDH)AjX(X1}HIHiJlXH }LA_~ DXXH)EtxXL1k}LHM<-~ DLH)AiXX1=}LcMfL} DLH)ƺX1}HHh11I@HHL:HH8 [A\A]A^A_]@HiHDžD tLiIAIPAhL褩AAhI>~I>~EhfDL| DLH)ƺX1{fL| DLH)ƺ X1{fLh| DLH)ƺHX1~{kI>a~Hi7fHI@tpMPHMHPHI ҋPy89I$HHL tM@ff.ff.ff.ff.I$HHLu+H‹BHHI ‹BDY8D9rˋI(D)IA9s At=A8LELI()HHL tIH@PALHLfDUHAVAUATISf>Hz<A<?~5DvL5GLzZpXLHCLs<<mE$C0Hs0<<5E$fA>t A>f><F',HFH^HHII$hLH@ {LHyH؄tfD\WPHuI$hHwHCy[A\A]A^]DDHL[AXXA\ \XA]A^]#<^H>GH>yHHII$hLH@ LHxH؄U\tPH@\u/PHu'fCtuRHSCsH\usH hDLuHHDLDLZI HsH[*D/PH<vH5&GHH#xfDCDA$Hs8@C,A$Ls FH^ HNVFH\ff.UHATISH_0Hc0HiHu0H3 xH;yt>H;y[A\]@[IXA?XHHLA\]t!@1w8w[LAjXA$I$HIA\]>!ff.UHSHH<t]<t)<<tu< HGH(H]G tHGH(uHGHx2 H{Iv@Gt¨uHGH(uH{ vHGH(uHGHxvHCHxuH{ulfHGH([HGHx H{u1fC:HGHpHxOHCHxud< HGH(HGHpH@H HP0'fDUHAWIAVMAUIATIaXSHӺHLMtuYAIAEA?:HtoLMXL1yAƄ$;/ƃH[A\A]A^A_]oXLNtu:IAHAEPA?:uL꾁]XL1yf.cXLsPHEI=LcLtHLHHP[A\A]A^A_]|UHATISHG0Hc0Hi҈HH;xvtH;;v[A\]Ð1t8t[LAjXA$I$HIA\]ff.HHRH46ff.ff.ff.HHH9tJoHPHWPtt3t>t t u6HPHHHH9utu@ tʀ tfUHAWAVAUATSHHx>HpZxZc~H=GƅПƅƅ_ƅ[ƅZEHHПLXHhZL_MH[PHZM1ALyHrB<=uƅAGIOHH{0MpXʠHZRZLf%f fZoHxnIHHL4]LloLHZHLoHHCoHxnHHIHH\LoLHZHLnZHZHt'ƅпAGIOLƅZfLHпN[X1LH[ƅLZDžпLZ-sH{0lXƅXLLCH7p%=HĈ[A\A]]f."sHĈ1[A\A]]@tD`,HsHD@(HH{PH֋J89 R()HHHDHAtcBff.ff.ff.ff.ff.E@$LHHDAH‹BIHLƋBEH8D9rE@(D)/JHHh6f=uzGA9EAEt1IuMm@R$HHHfDAuI fAXXHĈDLH߹ \X[A\A]]Zf.I9s DAt-DtIAUfDD`DLhAUIUAEAuLlGAmXTff.UHAVAUATSHHĀHHDLhLopPktvDPAEftgA}f=ueSyGA9EuYDLHnHDLHbIKfD`,DLh AEAUfuEuL5wGL4HLzIALt!ff.\_PHu1H`HH`L:CL:L3H[A\A]A^]Ð1AXX"uHDLH߹ \X[A\A]A^] @tD`,HsHD@(HH{PH֋J89-R()HHHDHAtc2ff.ff.ff.ff.ff.E@$LHHDAH‹BIHLƋBEH8D9rE@(D)/PHL2DLHA mXLXH[A\A]A^]ff=uwGA9EAEt1IuMu@R$HHHfDAuMu fI9s DAt-DtIAUfDD`DLhAUIUAEAuLtWAmXff.UHAVAUATSHHĀHHDLhLopPtvDPAEftw.A}#f=ueuGA9EuYDLH辿H<DLHW^IKfD`,DLh AEAUfuEuL5sGL0HLʀIALt1fDff.ff.\_PHu1H`HH`L6CL7L0H[A\A]A^]@1AXX"uHDLH߹ \X[A\A]A^]P@tD`,HsHD@(HH{PH֋J89R()HHHDHAtS"ff.ff.ff.ff.E@$LHHDAH‹BIHLƋBEH8D9rE@(D)/PHL.DLHA mXLXOH[A\A]A^]ff=u@sGA9EAEt1IuMu@R$HHHfDAuMu fI9s DAt]Dt?I#.DLHA mXIXH[A\A]A^]DAUfDD`DLhAUIUAEAuLtAmXff.UHAVAUATSHH HHDLhLopP[DPfA}AEI} [Hv;A}:EuL5WpGLW-Hƹ YXLb}HC0Hc0HiֈH݈IUhH [A\A]A^]D`,DLh fA}AUA}H=oG1"uH DLHAVX[ \XA\A]A^]@tD`,H{HD@(HLCPH׋J89R()HHL HЀtNDff.ff.ff.ff.I$HHLucH‹BIHH NjBDI8D9rˋI(D)R$HHLhfDI}AEH|fDI9s DtuIDAEtoIUAEAuLtfLeL4LH߹IXABXH [A\A]A^]AUfDAuMu Vf.D`DLhAUIuMuLeL褋IXLHߋA9Xx^UHAWAVAUATSHH8HHDLhLopP DP)4HS0Lc0MiIAA%=9Ahu:IPHtHHt ?IiHUHUHU"MiuHUII>>+HUHcutAhMiLuB:hLHLDLDHH8[A\A]A^A_]ÐD`,DLh AUIEHH=1"uH8DLHAwOX[ \XA\A]A^A_]D@tD`,H{HD@(HLCPH׋J89R$HHL HЀt,ff.I$HHLH‹BIHH NjBDI8D9rNjI(D)MiuHUII>)HUuYI>)HUuBI>)H8H߾[A\A]A^A_]vGfDR()HHL@I9s toDtQI4fLeLLQLH߹IXAFX%H8[A\A]A^A_]fDAUfDD`DLhAUHUWHUAh.DI>Lu(H`LeLL衇IXLHߋA9XuPUHAWAVAUATISHHHDLpLwpP}DPAfA~wf=ukiGA9Fu_DLLHuDLLRHQfDDh,DLp AAf{lA^HChGHC%HHuHH؄t ff.\PHu1HPHL{CuLff.AGIt3tH~Hhf.HiMM4I> =A /AhE"t$I>uI>HiuL I>HubtHuhLiuHcuCDŽ7hLuLh}LDLDHHH[A\A]A^A_]ÐD`,DLh AUgIEHH=\1"uHHDLHAwOX[ \XA\A]A^A_]DI>HiEAhELGE"@tD`,H{HD@(HLCPH׋J89R()HHL HЀtBff.ff.ff.I$HHLH‹BIHH NjBDI8D9rNjI(D)R$HHLpfD@ Ј@LuH@I9s tgDtIILeHuL@{LH߹IXAFXHH[A\A]A^A_]DAUAfDD`DLhAU"HuLeLzIXLHߋA9X_I>HHH߾[A\A]A^A_]L9I>d@ff.UHAVIAUATSH@HHDL`LgpPDA$fA$ uA|$H]A"UH@1[A\A]A^]@\GA9D$tA<$AD$tHLhI<<EDLLPtLHuiI<<EA$f=lA<$yH@[A\A]A^]Dh,DL` A$fH@DLL[A\A]A^]鸜DAAtAII~HMFPHHAAr89R$HHLDHAtM{@ff.ff.ff.ff.EI$LHLDAu0H‹BHHL NjBEQ8D9rEI(D)IA9s ADAA8LEW@AD$tEl$IvHDI~PHHAD$J89R$HHHDHAtLzff.ff.ff.ff.E@$LHHDAu0H‹BIHLƋBEH8D9rE@(D)IA9s ADA7E8LE@AIAMI?@El$EMd$_fR()HHL@R()HHH@@tDh,IvHD@(HI~PH֋J89R()HHHDHAt3@ff.E@$LHHDAH‹BIHLƋBEH8D9rE@(D)HALH8DDhEL`Y@R$HHHPH@DLL[AXXA\ \XA]A^]aIA9s ADAtE8LEDhEL`ff.UHAWAVAUATSHHHHHDLhLopP)tDDPtTtO1AYOX \X"HH[A\A]A^A_]fDD`,DLh AUuL{0E0TIcHiЈHEM4A4A%=Ahu*IPHtHHt9fHiUM4I>etA HiEAhuLpS肮"tI>u\uHiMuL I>HM0HcutHHMhu:@ @LuH-LiuMALJh )XLuLrLDLDHdHH[A\A]A^A_]D@tD`,H{HD@(HLCPH׋J89R()HHL HЀt2$fDff.I$HHLH‹BIHH NjBDI8D9rNjI(D)AE I}AOX?XHHDLH[A\A]A^A_]˺R$HHL@fDAhI>@AI>XuI>UHHH߾[A\A]A^A_]0f.I9s DtuIDDLeHL qLH߹IXABXݹHH[A\A]A^A_]fDIPAH @AUfDD`DLhAUHuLeLppIXLHߋA9XDAQAXVXAHAhI>ff.UHAWAVAUATSHHxHHDLhLopP`DPB<jA}_&A}H=CQG&Hv;A}EuL5"QGL"Hƹ YXL-^L{0A}Mc07A}H=PG_HIiƈAA}AUHPGH`HHh H`HhH9HxHxLe蜨MiL+LS MLLH7I>JHx[A\A]A^A_]fDD`,DLh AUB<1"Hx[A\A]A^A_]f@tD`,H{HD@(HLCPH׋J89R()HHL HЀtR4Dff.ff.ff.ff.I$HHLH‹BIHH NjBDI8D9rNjI(D)AEkAEIU H9vHxDLHA_X[ \XA\A]A^A_]fR$HHLfDAEI} I}AEH|DAE IuMuGfDI9s tWDt9IAEI} I}AEH|DAUfDD`DLhAUbLeLLlIXLHߋA?Xմt*I;MIUfAuMu SAEH9lIUAEHTIUAEAuLtfff.UHAWAVAUATSHHHHDLhLopPtIDPfA}tR1" HĈ[A\A]A^A_]D`,DLh fA}AUuCA}H=pLGSHv;A}EuL5OLGLO Hƹ YXLZY2HS0Lc0MiIAA%=AhuEIPHtHHt ?$IipSHXHHX"t4MiTHXII> HXT{MiTHXII>L HXTtAhMiL`B:hL}LڠLLHchDLDLH贔"@tD`,H{HD@(HLCPH׋J89R()HHL HЀtJff.ff.ff.I$HHLH‹BIHH NjBDI8D9rNjI(D)R$HHLhfDAU!fDI>HXThI>HĈH߾[A\A]A^A_]&DHXLHXAhI9s DI[AEI} I}AEH|DLeLLAgIXLHߋABX#AEIUAEAuLtiDHĈDLHAmJX[ \XA\A]A^A_]鶯fDAUfDD`DLhAUqAI>Lu\5VIGLe-fLeLLQfIXLHߋA9X%3AuMu IuMuDUHAWAVAUATSHHHHDLhLopP^tIDPfA}tR1"HĘ[A\A]A^A_]D`,DLh fA}AUuA}H=GGHv;A}EuL5FGLHƹ YXLSRLs0Ic0HiЈHXM<AGA%=Ahu%IPHtHHt 94@HiXM<I?ytA HiXAhuLpS"tI?TTHiXTL񀉂 I?HHTtHHhLiXMAdžh JL}L`L7LLHcbDLDLH@@tD`,H{HD@(HLCPH׋J89ryR()HHL HЀt.(fff.I$HHLH‹BIHH NjBDI8D9rNjI(D)R$HHLfDAUfDAhWI?$@I?XTUI?RHĘH߾[A\A]A^A_]!@@ @Lu5DGL2atDI9s DI AEI} gI}[AEH|MDLeHLaIXLHߋABXeIPAH @AEIUAEAuLtDHĘDLHAmJX[ \XA\A]A^A_]ީfDAUfDD`DLhAUHXLeL`IXLHߋA9Xy@AuMu FfHTAhIuMuI?#ff.UHAWAVAUATSHH(HHDLFLGpF<<DEMfA?tA<t<AFH@M4LspA<<DfA>A<<t{AXX \X"uLDLH(H[A\A]A^A_]8Df,DL~ J@"1H([A\A]A^A_]A~zfA?QA?AH=@GHHHYMHfA>VA>A~H=I@GHEHHMHHt\?PHuHt2ff.ff.\PHuH^oX HHHNHUoXHHH!6HHHiHH9HHHHuHxHHmXfD/PH/PHEFtDf,H{HDLKPHHNjF(J89ZR()HHLDMHAtMff.ff.ff.ER$LHLDA<H‹BIHLNjBEZ8D9rER(D)AFtEnHsHDH{PHHAFJ89R()HHHDHAtI@ff.ff.ff.E@$LHHDAH‹BIHLƋBEH8D9rE@(D)R$HHLfDAXX \XDLf.R$HHH2fDI9s DAD8LEfDI9s DA1D8LEfD=GA9GDLH襇HDLH>&HfF=GA9FDLH]HDLH%Hf.AGNIWAGAwH|DEnDMv&@HH/UXDLA mXHwifAFt7IVAFAvH|fAwI fAvI~ fHHLXDLA mXfD`DLx @H H@A mXIXY/UXDLA mXH蒡IwIIvI~DhDLpAmX \XDLHAmX \Xf.UHAWAVAUATSHHHHDLFLGpF<<DEMfA>tA<t <uwA~tpFH@MA>A~H=7GH(H(HDIALt#ff.\PHu1HPL(HHPLL(LL0fLH*EtULDLDH AGtEgHsHDH{PHHAGJ89R()HHHDHAtaXfDff.ff.ff.ff.ff.E@$LHHDAH‹BIHLƋBEH8D9rE@(D)R$HHLfDR$HHH:fDA4nX \XDLfAFkqIVAFAvH|D/PH I9s DAD8LEfDI9s DADIEgDMAf6GA9FDLH}HDLHIfDLLXDLA mXHfDhDLp @AEAvI~ IvI~DD`DLxAAmXLDUHAWAVAUATSHHHHDLFLGpF<<DEMfA>tA<t <uA~txFH@MlA>A~H=3GH( H(H?IALt#ff.\PHu1HPL(HHPLL(LL06HxLPLDLDH/|f./PH]mEFtDn,H{HDLKPHHNjF(J89jR()HHLDMHAt]fff.ff.ff.ff.ff.ER$LHLDA4H‹BIHLNjBEZ8D9rER(D)AGtEgHsHDH{PHHAGJ89R()HHHDHAtI@ff.ff.ff.E@$LHHDAH‹BIHLƋBEH8D9rE@(D)R$HHLfDR$HHHRfDAYOX \XDLfI9s DA!D8LEfDI9s DADI%EgDMA0GA9FDLH {HDLHIfDL LXDLA mXH臖fAFtuTIVAFAvH|,DAvI~ f.DhDLp@A5IvI~fD`DLxAAmX\fff.UHAUATSHLHDIXH_pA@<<t4DAPDIڀt4"H1[A\A]]Ap,MP AuA@H@HH_p<v<DS"uAdX \XDHAdX \XLH[A\A]]fDA@tAp,LWHL_PHIA@(J89rmR()HHLD"At#fEd$$LHLD AugH‹BHHM$‹BEl$8D9rEd$(D)@R$HHLfDDKDH[fI9s D AI(I>CtDKHwHDLGPHHƋCJ89R$HHLDHAtQwff.ff.ff.ff.E[$LHLDAu(H‹BIHLƋBA[89rE[()ŐH9s DADtvHsAzH[A\A]]@ApLPAfR()HHL@IH`1DHDHXff.UHAVAUATSLHHMPLWpA@<<t|AMfA}tAE<t <usA}tlA@H@M4LspA<@<fA>tkA>te"[1A\A]A^]DE`,DMh |@"uAXX \XDLH[A\A]A^]NfDfA}+A}EmL-)GLHL6IA$Lt$ff.\t{PHuUoXLIHA>4EvL5y)GLyHLLLL[A\A]A^]/PHmyAA@tE`,H{HDLKPHHA@(J89XR()HHLDMHAtKzfDff.ff.ff.E[$LHLDA4H‹BIHLNjBEk8D9rE[(D)AFtAvH{HLCPHHAFJ89R()HHLD HAtJDff.ff.ff.EI$LHLDAH‹BHHL NjBEQ8D9rEI(D)R$HHLfDR$HHLQfDAmX \XL%I9s DA!D8LENfDI9s DA8LE](GA9EDLH-rH DLHIfDAvMvDAEtGuwIUAEAuLlsDAFt/u\INAFAVLtDAuI 8fAVI fD`DLh,IuMmIVMvlfpLpDfDAgXNXHH}AmX \XDLgDUHAWAVAUATSHH8HHDLhLopP!DLs0HEHEIc0HiII>LuH}LHuLuLmHEHt/ID  uLuHmfff.LL}LLH&AH}=HLDDLEnEH8[A\A]A^A_]DD`,DLh @@tD`,LCHD@(HH{PIЋJ89R()HHH HЀt* fI$HHHH‹BIHI BDI8D9rNjI(D)I>~Uto 7HEH(HEHpHxHEHx;@R$HHHfDHEH(H}}I9s D8LEgHELuHPHUHID+1@ HEH(HEHx|H}fDD`DLh HEH(HEHpH@H HP0mHEH(kHEHx0 H}kPHEH(AHEHxJHEHx=H}4@ff.UHAVAUATSHH HHDLWLSpG<<t8DWDMрt8"H 1[A\A]A^]fDw,LO AuȋGIqH@M,LkpAE<<BDAU"uAYOX \XDLAdX \XLH H[A\A]A^]錇@DGtw,LCHLKPHIG(J89R()HHLDAtIqff.ff.ff.E[$LHLDAuhH‹BHHMBEk8D9rE[(D)R$HHLifDEeDMmAUI9s DAqPILuH6Lq=LDLDHhH [A\A]A^]@AEtEeH{HDLCPHHAEJ89 R$HHLD HAtWff.ff.ff.ff.ff.EI$LHLDAu0H‹BIHL NjBEQ8D9rEI(D)I9s DAtzDtbI1ApLHAf.R()HHL@MH0AUD`DLhAUf.UHAWAVAUATSHHXHHDLFLGpF<<DEMfA9tA<t <uzAytsFH@M,LkpAE<<DAU*"1HX[A\A]A^A_]@D~,DLN w@"uAXX \XDLHXH[A\A]A^A_]鈃EFtD~,H{HDLKPHHNjF(J89R()HHLDAtC?fff.ff.ER$LHLDAH‹BIHLNjBEZ8D9rER(D)fA9A9rEqL5oGLMLkLMHLLM8(LMHHt\WJHupXLMH}iH}IHEMLMLuoBLs=t 11LHHEHEDHuERfDA uL}Hcfff.LuLL7LH\HUH}Hu1SL}LN1҉tHcLJK<DA uL}1DAEtEeHsHDH{PHHAEJ89R()HHHDHAtI@ff.ff.ff.E@$LHHDALH‹BIHLƋBEP8D9rE@(D)R$HHL3fDR$HHHRfDA4nX \XDLfAA IQAAAqLtD/JHI9s DA)D8LEyfD3H}H[HHALDHbHX[A\A]A^A_]I9s DA9DI4EeDMmAUGA9A<LDHLM!cLMAmX \XH%LHDLMLMH*DxDLHOHHAgXNXHt~I|LDwAUKfDAqMq fAJXLX|IqMqD`DLhAUMHDUHAWAVAUATSHHHHDLFLGpF<<DEMfA>tA<t <uwA~tpFH@MA>AFHGHH(H(Hy!HHt!ff.\JHu^oXH H H(H()H(oB8mHDž =tH(11HDž 1HPHH(HPHxH H)HxHH HHH(HǾHHH9H H(VXDLAYXHhz1AGtEoHsHDH{PHHAGJ89R()HHHDHAtaXfDff.ff.ff.ff.ff.E@$LHHDAH‹BIHLƋBEP8D9rE@(D)R$HHLfDR$HHH:fDA4nX \XDLTfAFIVAFAvH|GD/JHM]I9s DAD8LE,fDI9s DAD'I5EoDMAfGA9FTDLH}\AmX \XH5HDL HMD`DLpj@HxH HL0H( HHH L -DLDLH5Z3H ((8f.A AvI~ tfAJXLX<5.GLR-pIvI~BDhDLxAL爅(U(VH(AgXHHHNXv{fff.UHAWIAVAUATSHHHDLFLGpF<<DELf;t<t <uy{tsFH@M,MopAE<<EAU:A"1H[A\A]A^A_]Dv,DH^ z@A"uAXX \XDHHL[A\A]A^A_]u@EFtDv,IHDMWPHHNjF(J89R()HHLDLHAtMff.ff.ff.E[$LHLDADH‹BIHLNjBA[89rE[()Df;;CHr GHH(kH(H<H1HPHHHPHt0Dff.ff.\WPHuHH HoH;HpHu CH(L0H(LH(LLqMH eHuFcH(\H(LH'LLoNH #H"Hp;HuCtH( H(LH(AEtEeIwHDIPHHAEJ89R()HHHDHAtaXfDff.ff.ff.ff.ff.E@$LHHDAH‹BIHLƋBEP8D9rE@(D)R$HHLfDR$HHH:fDA4nX \XDLUfCHSCsH|G/PHHA9s ADA/E8HE*@IA9s ADA?EI2DH HL(MDLLEHS EeEMmAU G9C DHLTHDHLHHLXDHA_XLkptfDDpEHX@AU3fDsH{ HsH{fDD`ELhAUH(L0H(LH3%AmX UHAWAVAUATSHH(HHDLWLSpG<<DWDMрEAAGH@M,LkpAE<M<DAU"1H([A\A]A^A_]w,LO Avff."uAfX \XLH(H[A\A]A^A_]nDGtw,LCHLKPHIG(J89rpR()HHLDAt)DE[$LHLDAH‹BHHMBEk8D9rE[(D)R$HHLfDAEtEeHsHDH{PHHAEJ89sR()HHHDHAt1fff.ER$LHHDATH‹BIHLƋBEZ8D9rER(D)I9s DAt|I@A9H{0AqH5G.\IHHL}LLH'"L?LDLDHGOfA&pLHA f.EeDMmAU.R$HHHfDA4nX \XDLkfI9s DAtbDtJIIq AAIqAAHtfDMHhAUzD`DLhAUaf.UHAWAVAUATSHHHHDLFLGpF<w<DEMfA>tA<t<A~FH@M LKpA<<}DfA9A<<t{"uWAXX \XDLHĘH[A\A]A^A_]jDf,DLv J@";1HĘ[A\A]A^A_]DAyzfA>A>E~L=GLHLLHHLLHLHIfA9A9EIL GLM薿HLkIALt.ff.ff.\t{PHuAULt\t{PHu1HPHHPLgLL L蟾L藾f/PHmy/PHmyEFtDf,H{HDLKPHHNjF(J89ZR()HHLDMHAtMff.ff.ff.ER$LHLDA<H‹BIHLNjBEZ8D9rER(D)AAtEiHsHDH{PHHAAJ89R()HHHDHAtI@ff.ff.ff.E@$LHHDAH‹BIHLƋBEH8D9rE@(D)R$HHLfDAXX \XDLif.R$HHH2fDI9s DAD8LEfDI9s DAD8LEfDGA9F?DLHLHJLHHDLHLH)LHI8f.&GA9A*LιDHLH6JLHH0DLHILHL@H߹LXDA mXLe7AFtgIVAFAvL|nfEiDMIv@AAt/u\IQAAAqLlrDAvM~ fAqMi OfD`DLpIvM~IqMifDhDLHAmX \XDLL.LH \XDAmX@UHAWAVAUATSHhf>E#IIH]AU<@EAEALHuU I<<EfA?FA9GHL1 I<uEAAtEaI~HDIvPHHAAJ89R$HHHDHAt#QfDEI$LHHDAu0H‹BIHL NjBEQ8D9rEI(D)IA9s ADAEEIfAyAyH=FLxH}誸H} +\XH{LxAAMQ<e<@EAQfA:";ABWIrMbf.AGtEoI~HDIvPHHAGJ89#R$HHHDHAtO}fDff.ff.ff.ff.E@$LHHDAu0H‹BIHLNjBEH8D9rE@(D)IA9s ADAE8LEfA?AEHh[A\A]A^A_]f.EoEM@EaEMIAR()HHH@R()HHH*@A}DhELx@D`ELHAFArMb kXL^E"ERLFLMHAAtEa,IvHDI~PHHAA(J89R$HHHD HAt>eff.ff.ff.EI$LHHDAu)H‹BIHL ƋBEQ8D9rEI(D)IA9s ADAtKEt4IAA,AMQ AR()HHH+APALPAIRABArLdzf.UHAWAVAUIATSHXHHDLFLGpF<<t~DEMfA?tA<t <uvAtoFH@II]p<-<EA"1HX[A\A]A^A_]Dv,DL~ {@A"uAXX \XDLEFtDv,I}HDM]PHHNjF(J89RR()HHLMHЀtfNLF9F?LDUfA?DUEA?_EgL%FDULϱDUHLDUDUHHt ff.\PHupXDUH}ɲH}IMDUL濐oBDU_MDU=LDUHEHEHHE}DUL}HEHEHErfHuH}1LDUʰLuDUeL1DUt5HcLZOA8@ q@ uALuHcL}LDULLL5DUifR$HHLfDA4nX \XDHHXL[A\A]A^A_]AZR$HHH fD.F9F>uFf.ASYX \XA"DLDU褯LLHc&LL4DUHuH}1LDUaLuDUuLDULL5ADUHHAHDL;fDIA9s AE8LEefD/PH%5HA9s ADAEtIHVfDSEH[6fDpELx@ 11LDUALu1FDPEHXfFA9GDLL-<DUAmX \XHLDLDUDUHAGtGtQIwMgAIHAgXNXL|W-AJXLX\AwMg aIWAGAwLdKMDLA8ffUHAWAVAUATSHH8HHDLFLGpF<<t;DVEMŀt>"1H8[A\A]A^A_]@Df,DLn AUu‹FH@M4LspA<<LDAfAf=x"jA^BX \XDLA4nX \XDLH8H[A\A]A^A_]UfDEFtDf,H{HDLSPHHNjF(J89r~R()HHLDMHAt-fff.E[$LHLDAu`H‹BIHLNjBEk8D9rE[(D)R$HHLfDE~DMv@I9s DADIFA9FxH蟱 oXHH1蔩Ht'ff.\PHuHHHH AAfWf=LDDLHH6H2D/PHEUAFtE~HsHDH{PHHAFJ89R$HHHDHAt/]ff.E@$LHHDAu0H‹BIHLƋBEP8D9rE@(D)I9s DAD8LEafDAFHFHH}HHNHH/HtD AtlXDLH߹LX^RfAUdfD軧"fDD`DLhAU5f=u FA9FtFAFt|IvI~=R()HHHV@FA9FDLH5Hupu}AmXDLH߹ \X~QAvI~ H/0DxDLpIVAFAvH|HDLHH/rfUHAWAVIAUATSHhHHELOMNpG<<t6EWDLˀt6A"1Hh[A\A]A^A_]Ðw,AH_ uʋGH@M,MnpAE<<fEAEf=xA}]fu-FA9ERA"oASYX \XDLfDAdX \XHHhL[A\A]A^A_]OfDGtw,MFHMVPHIG(J89R()HHLDAO@ff.ff.ff.ff.E[$LHLDAH‹BHHMBA[89rE[()DR$HHLafDE}EMm@AE1H[HuE9 HA9s ADAGA-HDAEtE}IvHDI~PHHAEJ89R$HHHDA$fE@$LHHDAuxH‹BIHLƋBEH8D9rE@(D)AEF9A}AEDžt1҃tfIA9s ADAE8LE@pAHXuf.R()HHHDžtD<EA$DA|$A|$H=FHx脢cXHxHAD$<fA|$<0LHuI<<vEfA}AEDfDAHq(HH~H(!}H(HHILA AHIEl$DMd$A2Hq@HH~H(|IHXHH(HI8 y H@(Hf|IHH(LA!%R()HHLR()HHHy8H@(H|IHH(H9hHrAmXDH߹ \X&y,H(H{(HHIDHQ A(LDUIDAbXH߹ \XL&DhDL`yDH(HzIHfH(HQ8A@HLHrAdXDH߹ \X.%SHazHHH3IVLRzHoH2zHHHIWL#zHHzHHHIWLyHHyHHHt{IWLyHHqDAmXH߹ \XW$|Dž$LAlXDH߹ \X*$ONFX;X1yzHHNXHAgX#봺 뭺fDLHDUHAUATSIXH_pA@<<t8DDIfA;t9A;t?"[1A\A]]AP,MX fA;uNjHFA9CuA@H@H4Hwp<c<{Df>t<xA;[AA\LA]D]f.DA@tAP,LOHL_PHI A@(q89I()HHLD!AtOffff.ff.ff.ff.Ed$$LHLD AuGHAHHM$AEl$8D9rEd$(D)@I$HHLdfDI9s D A8LE<FtDVH_HDLgPHH ËFDA8D9+I$HHLD AHAt5\ff.ff.v$HHLDAu)HAAIHH4ËADN8D9rȋv(D)HD9s DDAD8HE@>[A\E1A]L]l@A?YX \XL[A\A]] DVDHvx@" AZX \XDI(D)HHLPLXfDDPDHp@IH [IA\ArVXA]AXL]7LHUHAUATSIXH_pA@<<}AIfA;tA<CA@H@L LOpA<<AfA99"[1A\A]]fEP,DMX {@AA@tEP,LOHDL_PHIA@(J89R()HHLD"At*DEd$$LHLD AH‹BIHM$BEl$8D9rEd$(D)A;Q[A\AA]LL] D"[AZXA\ \XA]DL]/.FA9AA;[AA\LA]DL]fDAAtAqLGHH_PHIAAJ89R()HHHD"HAt*fDEI$LHHD AH‹BHHM BEa8D9rEI(D)R$HHLMfDR$HHHqfDI9s D AD8LE5fDI9s D At}t`ICAqMIA,f[A\A?YXA] \XL]uDDPDLX@ApLHAfIH[ArVXA\AXA]DL]3ff.UHAWAVAUATSHH(HHDLFLGpF<<DEMfA:tA<t <uwAztpFH@ML[pA<%<DA"L1H([A\A]A^A_]Df,DLV z@"uAXX \XDLfEFtDf,H{HDLSPHHNjF(J89R()HHLDAt3/ @ff.E[$LHLDAH‹BIHLNjBEk8D9rE[(D)ACtEKHsHDH{PHHACJ89SR$HHHDHAtKfDff.ff.ff.E@$LHHDAH‹BIHLƋBEX8D9rE@(D)HLDL;DLIDLf=A?f)FA9GfA:A:;ABH±FLHDILnLDLHLLDLULDLHt+Hff.\PHuE1ƅEƅHDLDDLfff.fA?A?AGHL I<<JDA< <u}A~uvAFMf<<=A~H=JFHFmHHƹkXM5fA<$A$4<dfDAQXVXLHDR$HHLKfDA4nX \XDLH(H[A\A]A^A_]fDR()HHH@FA9GA?uAGt@ff."/ASYX \XDLvDI9s DA9D8LEfDA>A~H=ӮFIkHƹnXL޻u*fA<$A$9<1ƅf.LHѼI<<cDA?zDAXLH߹AXq*@/PHVFA9G;AFIvI~:fDDLHBDIAFMvDEKDM[AAF,Mf kDEoDM@AvI~ f<0AD$HĬFHHiHHƹ;hXĹfA<$A$uA<tEEd$L%wFLwiHƹkXL肹Nƅ<:AD$IT$AD$At$Ldf.AFWIVAFAvLtDƅD@D`DLPJ@AAD$It$I|$AvI f<A|$H=TFIThHƹkXL_t{fA<$A$<Ed$L%FLhHƹ5jXLƅ RfIVAFAvH|f.ƅAt$I|$ IvMvIt$Md$AGkDHDLXA.At$I MHDfFA9BALֹDHLDLhLDHLWLHDLDLדLDLH=ABIrMjAD$It$Mt$<AD$It$Md$DHLDDLE^oXLLDHgHIeeMLDLE11HPLHLDLgHP(ltA<t<A~FH@MA>EvL5ףFL`HL謰IA?/EwL5FL`HƹJlXL跰wA?EwL5rFLr`HƹhXL}UA?EwL58FL8`HƹnhXLCA?EwL5FL_Hƹ&eXL A?EwL5ĢFL_HLlXϯL<O_AlXVX@DLgDEFtDn,H{HDLCPHHNjF(J89"R()HHLDMHAt-fER$LHLDAdH‹BIHLNjBEZ8D9rER(D)AGtEgHsHDH{PHHAGJ89R()HHHDHAtI @ff.ff.ff.E@$LHHDAH‹BIHLƋBEH8D9rE@(D)AULt\PHu1HPHHPL;dA?EgL%FL]HƹJlXL豭YA?oEgL%lFLl]Hƹ;jXLwA?EgL%2FL2]Hƹ&eXL=A?EgL%FL\HƹlXLA?+EgL%FL\HƹhXLɬt:A?!EL=FL\HƹnhXL蓬KL\f/PH=MR$HHLfDR$HHHjfDAGt?IwMg?fAGIwMwOfDAwMg f.I9s DAD8LEfDI9s DA D8LEfDLZLFbLZffD&FA9FDLH=HDLHևIfDEgDM@AGtWIWAGAwLtfAFt7IVAFAvLtefAwMw yfAvI >fAGt9aIwMgfDhDLpAwMw _AwMg WIwMw IvMvAGSIwMgAGUIwMwgfAGtgIwMgfD`DLxAGta3IwMwAGt}+IwMgAwMg IWAGAwLdAwMw IWAGAwLt/IWAGAwLdAwMg AGt]IwMIWAGAwLdAwMg }AmX \XDLAwMw AwI AGtWIwMw'IWAGAwLtIWAGAwLdIWAGAwLdAwMw IWAGAwLtIWAGAwL|IWAGAwLtfDUHAWAVAUATSHHHHLFLGpF<<tNLALf8tO8tJ"1HĈ[A\A]A^A_]fD~,DHF f8Hu@FH@M$LcpA$<<, fA<$tA$<HPDIf=A}fRFA9EH#]HVHpHQ Hf8H89 xH=FHxUHxH脥HxHt\u/PHuHpƅ`Hh@fA}A}AEHL螥I<<DALHEI<<DfA}xFA9EhyfDFA9EA}%"ASYX \XDLfDFtD~,H{HDLSPHHNjF(J89fR()HHLDAt_D @ff.ff.ff.ff.ff.EI$LHLDAH‹BIHL NjBEY8D9rEI(D)AD$t AD$HsHH{PHHAD$J89R()HHHDHAt=ff.ff.E@$LHHDALH‹BIHLƋBEP8D9rE@(D)R$HHLfDHAmX \XDHĈH[A\A]A^A_]fDR$HHH.fDAEY:AEtEuHsHDH{PHHAEJ89R$HHHDHAtO}fDff.ff.ff.ff.E@$LHHDAu0H‹BIHLƋBEH8D9rE@(D)I9s DAID8LEfDAxQAxH=BFLPHX7QgXHXH>LPA8AxH=FLPHXPHXLPHƹ XXLXLXfAxA@<A@CIIp(Ix VHhff.DA@tAHH{HLKPHHA@r89R$HHLDHAtM{@ff.ff.ff.ff.E@$LHLDAu0H‹BHHLNjBEP8D9rE@(D)I9s DAaISEuDMm@A@M@A$R()HHL@R()HHH@H9s DAD8HDHDI9s DA8LE f.`tHx8$0Hx11LULc-HhHpH9tHMHxMHpMLMLLHH8u @fL~MLLHDL@Ar"AZX \XLfAD$Md$DDpDLh@PL@AfDxDH@HD=F9xDHH.HHDHyHxH@tp#HwHAELAxQAx,H=BFHX>LkXHXHE`wH _Hh1:SLczLxLA fFA9F Hs0L@Hp0HHHh$YHHL@HhH0H(fff.ff.H9 IHAtAEIiЈHH:uDAuH0DtD@LHLhXAALhLHfD@ f=C ҁFA9G3 DLHL@LHDhDhLHHL@ DLHL@LHDhBjL@LHH8DhDH8t'ff.\PHuIcHC0HiΈH@HHHH@" H8L(L0Dhf=HHHi@HDhL0L(H( A9 AyH= FL D(L0Hh fA>A>AFHpLI<l<DA$< <3A|$'AD$Ml$<c<uAD$,Ml$ AE<AuH5}FHHh:HhHH{0& A<$A|$H=|FHh9HhHƹoX؉`A<$=A|$H=|FHh9HhHƹkX蔉<fA}AEi<NAE5 1 IuMe;hXLDfA}AE<EmL-{FL8HƹkXL (|FA9FA>uAF"PASYX \XLf.DhDLxB@/PHeuv|FA9FjzLDHIfAE;,IUIufDLH轻IfAD$"&It$I|$DLHzDIA}A}H=jzFIj7HƹOXLu<HC0003A<$lA|$H=zFI7Hƹ ]XLfA}AEz<AEu IuMeDjXL̆#fA}AE7<7A}H=xyFIx6HƹNbXL胆XfA}AE<EmL-/yFL/6HƹiXL: D@ DAD$Md$^E~DMv@AUIu f.HоvAt$I|$ AEs5IuMe?fDAD$X"It$I|$AFpH0ONXDLAnIXA}A}H=wFI4Hƹ rSXLHC000AH=wFL8L@DHHh4HhDHL@L8HL@LHDh2fA?DhH8LHL@)AG9[xF@AuMe At$I|$ o<A}H=vFI3HIMAEAUHtAD$%It$Md$IT$AD$At$H|AEIuMeAXXVXDLƅ(2AQXVXLHQOAAIqIyA}BEmL-uFL2HL豂HH1HHi@H@AG|ZIwIAt$I iAuMe <A}H=NuFIN2HIUAEAuLdIT$AD$At$H|AEIuMe<AEcIuMmHi@HHJlXD(LDLHDL0L Dh L爁 0DhLPL0.E۸^oXpXH8HELh`8LhMiHHH8LhII$0I<$LhLeLLLHfMD`HXlAqIy ƅ p1Ҿ@UML H(L0DhH(L L0DhH@AwI AuMe ƅ AuMe AXAXLHAIXLH߹IXAEIuMmIT$AD$At$LddIUAEAuLd<OAEIuMeAuI 7DAXLH߹AX;9hXLLPL0Dh$.LPDhUoXpXH8EHE6L0AgXNXHHIQAAAqH|<dAE|IuMmAuMe {IWAGAwH|IUAEAuLdIUAEAuLd1.8 %Hi@HHH JlX-t1X.8AXXDLH߹LXAuI AuMe IUAEAuLlrAuI %IUAEAuLd}IUAEAuLdAmX \XDLIUAEAuLl dAlXLH߹VX IUAEAuLlAIXDLH߹IX@UHAUATSHHHHL`LgpPtYPfA<$tau'AD$tIL$HcHi҈HS0H:tycH1[A\A]]DP,L` fA<$A$u]El$L-nFL+HH{0LjtAD$fH[A\A]]f.@tp,LCH@(HLKPIЋJ89R()HHL HЀtPff.ff.ff.ff.I$HHLuCH‹BHHI BDQ8D9rˋI(D)R$HHLffDI9s totRI;f.AD$t&ubIL$AD$AT$LlfAT$Ml$ zA$fDPL`A$fIT$Ml$;UHATISf>t=<ti<FHFHHiHG0H8t~[A\]<t,vHlFHH)HI|$0H[A\]3Ftu$HNFVH\VH^ fDHVH^fDxfDUHAWAVAUATSHH(HHDLWLSpG<<t6DWDMрt6"C1H([A\A]A^A_]fw,LO AuʋGMiH@M4LspA<S<DLHq LH^IMLC0HHEIUE1HiM<H01E1fIUDsLI9sYI?1HUȾ+oXm/"IEIUEILI?. uI?DsL.IUI9rEIMDeI9pAdX \XLH(H[A\A]A^A_]f.DGtw,LCHLKPHIG(J89rpR()HHLDAt%DE[$LHLDAu`H‹BHHMBEk8D9rE[(D)R$HHLfDEfDMv @I9s DA)I{"AfX \XDLDAFtEfH{HDLCPHHAFJ89R$HHL HЀt6_fDff.ff.I$HHLu+H‹BIHH NjBDI8D9rˋI(D)I9s tjD8LE@ArpLHAUf.R()HHL@MHxD`DLp}D}AGIH9rB@UHAWAVAUATSHHHHDLxLpPDLHHLxLC0DAHCpPHRHEf1E1I~uDOIFIVoXI}ILD{¸LM;~tIu,@AdX \XLHH[A\A]A^A_]fDGtw,LCHLSPHIG(J89|R()HHLDAt5-fDff.E[$LHLDAH‹BHHMBEk8D9rE[(D)R$HHLEeDMm7fIu EDeM;&H[A\A]A^A_]DI9s DA+I["`AfX \XDLAEtEeH{HDLCPHHAEJ89R$HHL HЀtKqDff.ff.ff.ff.I$HHLu(H‹BIHH NjBDI8D9rˋI(D)I9s tQD8LEAIpLPA3R()HHL!MHD`DLhjDUHAWAVAUATSHHHHDLWLSpG<Z<t6DWDMрt6"1H[A\A]A^A_]fw,LO AuʋGMiH@M4LspA<c<DLHLHI}L{0toHE1Lu1HiIff.I?1L+oX. CI]IEEI?[ :A\$II;]r f.AdX \XLHH[A\A]A^A_]f.DGtw,LCHLKPHIG(J89R()HHLDAtEiff.ff.ff.E[$LHLDAH‹BHHMBEk8D9rE[(D)R$HHLqfDEfDMv@@I?A\$II;]nfI9s DAQ0Is"pAfX \XDLmDAFtEfHsHDH{PHHAFJ89R$HHHDHAtGufff.ff.ff.E@$LHHDAu0H‹BIHLƋBEH8D9rE@(D)I9s DAtpD8LEf.ABpLHA%f.R()HHH@MHPD`DLpMfUHAWAVAUATSHHHHDLhLopPDLH LHLK0DHcHCpPHRLI9s D8LE?AFtEfHsHDH{PHHAFJ89SR$HHHDHAt/]ff.E@$LHHDAu0H‹BIHLƋBEH8D9rE@(D)I9s DAD8LEfDI}WfLEuEHH[A\A]A^A_]fEfDMv[@"t I}tmLm5/FL LLDLDHcxHH[A\A]A^A_]@R()HHH@D`DLh@I}WtI}ZH- uD`DLpff.UHAWAVAUATSHHHHDLhLopPDLHLHL{0DLcHCpMiPHRMH4Hsp<E<Df=fF9^.FDHHuxHuHf>'.F9FMiKfDHvfDH5HH HLH|HD`DHp~UHAWAVAUATSHHHHHDLhLopPDLHnHCpDPHRL$LcpA$<<oDA$R"1HH[A\A]A^A_]@D`,DLh HLx"uAfX \XDLHHH[A\A]A^A_]fD@tD`,H{HD@(HLCPH׋J89rqR()HHL HЀt*fff.I$HHLu[H‹BIHH NjBDI8D9rˋI(D)R$HHLfDA4nX \XDLfI9s 3D8LE7AD$tEt$HsHDH{PHHAD$J89R$HHHDHAt+R@ff.@$LHHDAu)H‹BDBIHHDP8E9rȋ@(E)I9s DADgIĀHxIf=A?Pf.&FA9GLH߉U耸ULH߉ELk0HEHE (HA@OH3HcEHuHuHuHiHuIEIUHu1H} L}L1҉t0HcLRK<DA A _fff.HMLHQAHMHHf뀋%FA9GA?uAG@ff."NASYX \XLLXHMLHHc@HMHHgfIUHu1H}L}uLHKgHHALDHmfDEt$DMd$A$DR()HHH!@D`DLh@A$CL}Hc@AGDpDL`A$L}u,1THHAgXNXH4I|LDff.UHAWAVAUATSHH8HHDLpLwpPDLH~HCpDPHRL,LkpAE<<DAUr"-1H8[A\A]A^A_]@D`,DLp HLx"uAfX \XDLH8H[A\A]A^A_]fD@tD`,H{HD@(HLCPH׋J89}R()HHL HЀt6ff.ff.I$HHLu[H‹BIHH NjBDI8D9rˋI(D)R$HHLfDA4nX \XDLfI9s [D8LE'AEtEeHsHDH{PHHAEJ89R$HHHDHAt/]ff.E@$LHHDAu0H‹BIHLƋBEH8D9rE@(D)I9s DADIŀff.LH赲HLs0HEAHEIHIcHAHiI9A uL}HcDHMLH;HMHHaIH}Hu10L}LtEfH}HuLL}L_LHE}Hu0ID uL}LHID eLuLL>8H}ULDLDH]eELExaEz@tD`,H{HD@(HLCPH׋J89R()HHL HЀtVfff.ff.ff.ff.ff.I$HHLukH‹BIHH NjBDI8D9rˋI(D)R$HHL`fDASYX \XDLfI><I9s D8LEAAtEyHsHDH{PHHAAJ89+R$HHHDHAtMfE@$LHHDAu0H‹BIHLƋBEH8D9rE@(D)I9s DA9D8LEAf=9FA9AA9?AA4EAtDiH{HDLCPHHNjAr89R$HHLD IHAt[@ff.ff.ff.ff.ff.EI$LHLDAu0H‹BIHL NjBEQ8D9rEI(D)I9s DAD8LEfDDiDLa@EyDMI@R()HHL@R()HHH@D`DLp@S"I>I>I>Hag@L}LIHDxDLH@DhDL`@UHAWAVAUATSHHHHHDLhLopPPDLH让XHCpDPHRL4LspA<`<XDLHfHELcHEMiLk0I}H}HuLL}LLHEHID uL}LHID uL}LHLmLLO2H}fLDLDHn_EDHH[A\A]A^A_]DD`,DLh HLV"HH1[A\A]A^A_]@tD`,H{HD@(HLCPH׋J89ryR()HHL HЀt2f.ff.I$HHLukH‹BIHH NjBDI8D9rˋI(D)R$HHLfDHHDLHAfX[ \XA\A]A^A_]{I9s D8LEgAFtEfHsHDH{PHHAFJ89CR$HHHDHAtMfE@$LHHDAu0H‹BIHLƋBEH8D9rE@(D)I9s DAD8LEfDI}fLEEYEHH[A\A]A^A_]fEfDMv@"I}I}I}H5fR()HHH@D`DLh@D`DLpff.UHAWAVAUATSHHHHDLhLopP@DLHHLHDAHC0HEHCpPHRL4LspA<z<rDAFMn<z<uAF,Mn A<,<|AFoAvI~ fDoXAE<RfA}< AE4AuMu f dSXL.&HC0D05@D`,DLh HLƣ"1H[A\A]A^A_]@tD`,H{HD@(HLCPH׋J89R()HHL HЀt"I$HHLH‹BIHH NjBDI8D9rNjI(D)AKXVXDLHH[A\A]A^A_]!wR$HHLhfDAfX \XDLDIVAFAvH|2fI9s kD8LEGA~MA~H=RFH}QH}HDDAFtAN,H{HLCPHHAF(r89R$HHLDHAt-[Dff.EI$LHLDAu0H‹BHHL NjBEQ8D9rEI(D)I9s DA8LEAFtE~HsHDH{PHHAFJ89R$HHHDHAtO}fDff.ff.ff.ff.E@$LHHDAu0H‹BIHLƋBEH8D9rE@(D)I9s DAD8LEfDE~DMv@R()HHL0@R()HHH@D`DLhIvI~IuMufA}EuL5 FLHƹOXLuhHC0D0fPLhfDDxDLp<$EuL5I FLIH!A}MEuL5# FL#Hƹ rSXL.L{0uGE0AQXAXLAE-IuMuA}EuL5 FLHLL3t0A}HS0AuH5l FHHiH@޸A}EMH@ FLH=HHIcHi҈HHEH@1AuMu @IUAEAuLtAEtIuMuAuMu AEtrIUMuIUAEAuLtAEtLtlIuI]5AMIu IuAMHtAUMu AuI] IUAEAuLtIUAEAuH\IMAEAULtF@UHAWAVAUATSHH8HHDL`LgpPDLH~LHkLK0DLcHCpPHRL,LkpAE< <DAUDuIEHH=M"1H8[A\A]A^A_]Dh,DL` HLΛP"uAfX \XDL@tDh,H{HD@(HLCPH׋J89rqR()HHL HЀt&DI$HHLH‹BIHH NjBDI8D9rNjI(D)R$HHLfDA`mX \XLH8H[A\A]A^A_] of.IiLjJlXII LMLMAAIUAhkfI9s +D8LEDAEtAuH{HLCPHHAEJ89R$HHLDHAt-[Dff.ER$LHLDAu0H‹BHHLNjBEZ8D9rER(D)I9s DAt}t`I2AuMmAUR()HHL(@DhDL`{@AUfDpLhAUAVXIXDLeLL$IXLHߋAFXlfDUHAWAVAUATSHH8HHDL`LgpPDLH>LH+LK0DLcHCpPHRL,LkpAE<<DAUD"1H8[A\A]A^A_]Dh,DL` HL螗`"uAfX \XDLH8H[A\A]A^A_]kfD@tDh,H{HD@(HLCPH׋J89R()HHL HЀt"I$HHLH‹BIHH NjBDI8D9rNjI(D)AE I}IiLjJlXII LMLM'A/AIEAhH8[A\A]A^A_]fDR$HHLfDAdX \XLI9s #D8LEDAEtAuH{HLCPHHAEJ89R$HHLDHAtKER$LHLDAu0H‹BHHLNjBEZ8D9rER(D)I9s DAttI.@AuMmAUR()HHL8@DhDL`{@AQAXVXL/AUfDAOX?XLpLhAUfAVXIXDDLeLLIXLHߋABX]hJUHAWAVAUATSHH8HHDL`LgpPiDLH输LH諓DLcHC0HEHCpPHRL4LspA<j<bDAfA>tpAFI~ tjI~ubAFH|WDh,DL` HLX"91H8[A\A]A^A_]ÀtA~H=ELH A>'A~H=EH}üH}Hƹ YX "uAVX \XDLfD@tDh,H{HD@(HLCPH׋J89eR()HHL HЀt2fDff.I$HHLH‹BIHH NjBDI8D9rNjI(D)MiHEJlXII AAhu8IPHt,HHt :tHVAhIi݈HEHH;zt uhuH;dMiHULꀢIFhH8[A\A]A^A_]ÐR$HHLfDAfX \XDLH8H[A\A]A^A_]dAF#IvI~fDLeLLIXLHߋABXdII9s KD8LEGAFtE~HsHDH{PHHAFJ89R$HHHDHAtO}fDff.ff.ff.ff.E@$LHHDAu0H‹BIHLƋBEH8D9rE@(D)I9s DADt{IE~DMvAR()HHH@DhDL`@AVXIXf.A0AvI~ fDxDLpAIVAFAvH|fUHAUATSHHHHDLhLopP-DLHLHLS0HcHCpPHRL$LcpA$<<HiLH߁" ƃ"AǃxǃpI42C"Hƃ"-H[A\A]]DD`,DLh HL.,1"uHDLHAfX[ \XA\A]]8a@tD`,H{HD@(HLCPH׋J89ryR()HHL HЀt2sfff.ff.I$HHLuCH‹BIHH NjBDI8D9rˋI(D)R$HHLfDI9s 3D8LEAD$tAL$LCHLKPHIAD$z89R$HHLDHAt=kf.ff.ff.E[$LHLDAu0H‹BHHMBEc8D9rE[(D)I9s DAt]8LEgAL$Md$OR()HHL(@D`DLh@HL` ff.UHAVAUATSHH HHDL`LgpP"DLH`*HHDLpLspPDP8GAo)EIFHEǃ1f"uzA<<Y}HL贉Ls01H}Lc~,MiMf.I4$ H辴H9]MiK<.舵H [A\A]A^]fDDh,DL` HL61"uH DLHAfX[ \XA\A]A^]>]fD@tDh,H{HD@(HLCPH׋J89}R()HHL HЀt6ff.ff.I$HHLukH‹BIHH NjBDI8D9rˋI(D)R$HHLfDHuDHAdX \X^\H [A\A]A^]ÐI9s D8LEuAF DLHoH)EHE@tDh,HsHD@(HH{PH֋J89eR$HHHDHAt)Wff.E@$LHHDAu0H‹BIHLƋBEH8D9rE@(D)I9s DA9DIAFDLH_oH)EHEDh,DLp AWAFIFHH@H=EH=EsA_XLH߹ \X`ZR()HHH@DhDL`@AAvgXLH߹AXYTDhDLpAwUHAWAVAUATSHHHHDLhLopPDLH>LH+Lc0HCpPHRL,LkpAE<<gAU[AdX \X"1H[A\A]A^A_]f.D`,DLh HL薄X"uAfX \XDHLH[A\A]A^A_]XfD@tD`,H{HD@(HLCPH׋J89MR()HHL HЀtZ|fff.ff.ff.ff.ff.I$HHL'H‹BIHH NjBDI8D9rNjI(D)AE LcMiMI>訯1IchtA 0IiI3@ADŽ$hI>4 tgI;]tqIc$hA$ uLpSIHcf.R$HHLfDAQAXVX?fDA$I} ufDI9s 3D8LEAEtAuLCHLKPHIAEJ89R$HHLDHAt NER$LHLDAu0H‹BHHMBEZ8D9rER(D)I9s DAttI@AuMmAUR()HHL5@A$f.D`DLh@AU2fDI>XIch@pLhAUUHAWAVAUATSHHHHHDLGLCpG<<:DMƋGH@MH}HƹjXH A? AH=EH}H}HƹSgX & A?{ AH=EH}ƥH}Hƹ ]X A? AH=EH}芥H}Hƹ SX} A?Q AH=OEH}NH}HƹoaXXu A> A? AH= EH} H}Hƺ\X 1\A>RHcEHMHiHP fDDGtO,LSHLKPHI‹G(r89R()HHLDMHAt'E[$LHLDAH‹BHHM‹BEk8D9rE[(D)AGtEgH{HDHsPHHAGJ89R()HHHD HAtI@@ff.ff.ff.E@$LHHDAH‹BIHLNjBEH8D9rE@(D)AG;#IwIfDDLH'DIAG3;IwIfDEgDMV@Eg,DMo t@HcEHMHiL(LLu蕢LHLLDLDH?/ELEZ+EHH[A\A]A^A_]HcEHMHiH41HLuLvkAwI fR$HHLqfDR$HHHfDAwI fI9s DA8LEI9s DAt}D8LEf.AGtGIWAGAwH|fIWAGAwH|f.AwI fD`DLx^@PLpfDIWAGAwH|f.AGt7#IwIfAGt4'IwIfAwI SfIwIAwI rAGPIwIHcEHM5jXHix-LuUHcEHMHi>kX@AG)IwIfDHcEHML}HiH@蘑Iud1LrtVL覒HHE:HuLHLDLDH+EtLE(E@LE-EV@HcEHMHiL #AGte IwI[HcEHMHi5jXAwI IWAGAwH|WAwI IWAGAwH|oAGIwI=HcEHMHi j.IWAGAwH|QAwI AGIwIIWAGAwH|GAwI AGIwI"HcEHMHi;hXIIWAGAwH|HcEHuHHi@ul-_AGIwIAwI !"AwI XkXIWAGAwH|AGIwIAG IwIAwI HcEH]JlXHiH @hAGIwIIWAGAwH|'HcEH]JlXHiH ݚAGIwIvLuiXAwI IWAGAwH|AwI AwI IWAGAwH|AG IwIcLHp+HcEHMNbXH{0HitDjX<tiX<tlXLuLLujXAwI dAGt7IwIAGIwIAwI RAGIwILHopLcuHMIiֈL<Au A$MiHEH{0B0ylXIWAGAwH|IWAGAwH|IWAGAwH|HcEHMHiH<1qHcwIWAGAwH|AwI IWAGAwH|lAwI ^IWAGAwH|IWAGAwH|AwI IWAGAwH|IPHtHHt9ugIiֈHEL<AhLAhEI?6u:I?:u.EAhbnXuH13AhI?IiƈHMH{0H3toX#ff.UHAVAUATSHHHDLhLopPtjDLHXmxrLHImLs0JlXAHHiI wWE0[A\A]A^]f.D`,DLh HLly1"uAfX \XDLH[A\A]A^]@fD@tD`,H{HD@(HLCPH׋J89ryR()HHL HЀt2sfff.ff.I$HHLuCH‹BIHH NjBDI8D9rˋI(D)R$HHLfDI9s t/D8LEi@AaRXIXfD`DLh9ff.UHAWAVAUATSHHHHDLhLopPDLH>kLH+kLs0JlXAHHiM LVt@@tD`,H{HD@(HLCPH׋J89}R()HHL HЀt6wfDff.ff.I$HHLuCH‹BIHH NjBDI8D9rˋI(D)R$HHLfDI9s tD8LEC@D`DLh+@AVXIXf.UHAVAUATSHH HHDLhLopPtNDPtWLHh#LHhHS090H [A\A]A^]fDD`,DLh AUuHC0LuL0LDLDHfM\H [A\A]A^]@tD`,LCHD@(HH{PIЋJ89R()HHH HЀt&fI$HHHusH‹BIHI BDI8D9rˋI(D)H LHAfX[VXA\A]A^];R$HHH`fDI9s t/DtINfAU;fDD`DLhAUUHAVAUATSHH HHDLhLopPtNDPtWLHf3LHfHS090H [A\A]A^]fDD`,DLh AUuHC0LuL0LDLDHfM,H [A\A]A^]@tD`,LCHD@(HH{PIЋJ89R()HHH HЀt6ff.ff.I$HHHusH‹BIHI BDI8D9rˋI(D)H LHAfX[VXA\A]A^]9R$HHHPfDI9s t/DtI>fAU+fDD`DLhAU UHAVAUATSHH HHDLhLopPtNDPtWLHd3LHxdHS090H [A\A]A^]fDD`,DLh AUuHC0LuL0yLDLDHfMH [A\A]A^]@tD`,LCHD@(HH{PIЋJ89R()HHH HЀt6ff.ff.I$HHHusH‹BIHI BDI8D9rˋI(D)H LHAfX[VXA\A]A^]h7R$HHHPfDI9s t/DtI>fAU+fDD`DLhAU UHAWAVAUATSHHHHHDLhLopP9DLHNbLH;bLc0LcHCpPHRL ЋLKpA</<7A AրitIiψJlXULMLH HMHMLMU/J%=dhu[HPHt6HHt*?t%HMLM%HMLMƉhu@IiLMLͷLM"t)MiLMuMI}uLMMiLMuMI}HcuLMtAh$MiLMCn}IiՈHXJlXHH HP~HP%=hu>HPHtHHt ?,IiHXpSH"t.MiHXPII<$言PMiHXPII<$zPtA$hMiHXL`B(hLmLLLHcDLDLH 8Dh,DL` HLS"1HĈ[A\A]A^A_]D@tDh,H{HD@(HLCPH׋J895R()HHL HЀt2DfDff.I$HHLH‹BIHH NjBDI8D9rNjI(D)A~H=E HA>kA~H=ؿEHP|HPHƹ YX?A-f."AmJX \XDLHĈH[A\A]A^A_]&fR$HHLfDAfX \XDLDI9s {D8LE AFtE~HsHDH{PHHAFJ89R$HHHDHAt/]ff.E@$LHHDAu0H‹BIHLƋBEH8D9rE@(D)I9s DADIE~DMvAoAFI~ I~AFH|DR()HHH@AVXIXLDhDL`@AFLIvI~fDLeLLIXLHߋABX]$QAI<$|P_I<$|HĈH߾[A\A]A^A_]ҙfAvI~ HPfHPƉhf.DxDLpAA$I<$Le{5|EL&LeLLIXLHߋA9XT#HIVAFAvH|?fUHAWAVAUATSHHHHHDL`LgpPYDLHNLHNLcHC0HEHCpPHRL,ЋLkpAE<:<BAMAրs~IiψHEJlXUHH HM\wHMU=X%=hu0HPHt$HHtthff.IiψHEL$I<$yQwtA$ IiLjHuhEu LE"tI<$HyIi׈HEH€ I<$HUytHUhMiHEHcuLeBDŽ8hL!LDLDHHH[A\A]A^A_]f.Dh,DL` HLL"1HH[A\A]A^A_]@tDh,H{HD@(HLCPH׋J89R()HHL HЀt"I$HHLH‹BIHH NjBDI8D9rNjI(D)IEHH="6AwOX \XDL-@R$HHLXfDAfX \XDLHHH[A\A]A^A_]I9s [D8LEwAAEtEuH{HDLCPHH AEq89I$HHLDHAt\Dff.ff.ff.ff.ff.EI$LHLDAu0HAIHL NjAEQ8D9rEI(D)I9s DA!DtsIEuDMmAMI()HHL@DhDL`@AVXIXLFDAMZfDLeLLIXLHߋAFXA$hEI<$uLeLLIXLHߋA9XTDpDLhAM@ @tELeHI<$toI<$tHHH߾[A\A]A^A_]鋒I<$tUHAWAVAUATSHHHHHDLhLopPDLHHLH HLc0LcHCpPHRL ЋLKpA<<A Aր0"u^AYOX \XDLHHH[A\A]A^A_]D`,DLh HLfGH"1HH[A\A]A^A_]@tD`,H{HD@(HLCPH׋J89mR$HHL HЀtDfff.ff.ff.I$HHLGH‹BIHH NjBDI8D9rNjI(D)?IiψJlXULMLH HMoHMLMU%=huIHPHt=HHt1:t,HHMLM( HMLMhf.IiψLMM, I}qoLMtA kIiLjAhuLpSLM LM"tI}LMMhqMLMIi׈LMML  I}HU4qMLMtHUhMiMADŽ$h LMHcLeL%HuLDDHHH[A\A]A^A_]DR()HHL@AfX \XDLf.I9s {D8LEAAAtEqH{HDLCPHH AAq89 I$HHLDHAt-DIiՈHXJlXHH HP{iHP4%=hu/HPHt#HHt9ff.IiՈHXL$I<$kniIiňHXhuLpS"tI<$PfkPxIiňPHXH I<$HH)kPtHHhjMiHXLǀh vLmL`LLLHceDLDLH}4Dh,DL` HL~>"1HĘ[A\A]A^A_]D@tDh,H{HD@(HLCPH׋J89UR()HHL HЀtRDff.ff.ff.ff.I$HHLGH‹BIHH NjBDI8D9rNjI(D)OA~H=|E_HA>A~H=XEHPTgHPHƹ YX[Af."AmJX \XDLHĘH[A\A]A^A_]fR$HHLfDAfX \XDLDA$ A$hI<$hI9s D8LEjAFtE~HsHDH{PHHAFJ89R$HHHDHAt?mff.ff.ff.E@$LHHDAu0H‹BIHLƋBEH8D9rE@(D)I9s DAyDIE~DMvAAFI~ I~AFH|DR()HHH@AVXIXLDhDL`@AFt~IvI~XfLeLLIXLHߋABXHPHs gDAAvI~ HHPGHPh5DDxDLpAgI<$ePqI<$eHĘH߾[A\A]A^A_]颃f@ Ȉ@t]Le5ELLeLLIXLHߋA9Xf IVAFAvH|I<$2eUHAWAVAUATSHHXHHDL`LgpPDLH8HL8L[0DLcHCpPHRHkb I9s 3D8LEWDGtwLKHLSPHIGJ89R$HHLD2HAtOvff.ff.ff.ff.$HHLD0Au)H‹BHHI4LH+4LC0DAHCpPHRL LKpA<~<fDAEWAdX \X" 1Hh[A\A]A^A_]fDDh,DL` HL3X"uAfX \XDLHhH[A\A]A^A_]fD@tDh,H{HD@(HLCPH׋J89MR()HHL HЀtZ\fff.ff.ff.ff.ff.I$HHLH‹BIHH NjBDI8D9rNjI(D)AA IcƾJlXLxHiЈHpM4I [LxASIqH6H]HH"\LHH蔆I>^Hh[A\A]A^A_]R$HHLfDAQAXVXDL>fI9s ;D8LE7EAAtEiHsHDH{PHHAAJ89R$HHHDHAtY1Dh,DL` HLv-+"1HĈ[A\A]A^A_]D"uA_X \XDLf@tDh,H{HD@(HLCPH׋J89rqR()HHL HЀt&DI$HHLH‹BIHH NjBDI8D9rNjI(D)R$HHLfDAfX \XDLHĈH[A\A]A^A_]fDAGI hI\AGH|NDI9s D8LEAGtEwHsHDH{PHHAGJ89R$HHHDHAtMfE@$LHHDAu0H‹BIHLƋBEH8D9rE@(D)I9s DADIEwDMAR()HHH6@DhDL`n@AGI MIAAGH|3DAAGIwIfDDpDLxAOAGt~HXI;GMg.DAaRXIXLLeLL8IXLHߋA?X hAwI +AGMg H9X_IWAGAwH|AGH9X8IWAGLd~DUHAVAUATSHHHDLhLopPtrDLH)xzLH )JlXLcMiLs0I :RRI>*UaI>T[A\A]A^]D`,DLh HL(y1AfX \X"uDLH[A\A]A^]fD@tD`,H{HD@(HLCPH׋J89rqR()HHL HЀt*cDff.I$HHLu;H‹BIHH NjBDI8D9rˋI(D)R$HHL돐I9s tWD8LEq@AaRXIXf.1R8"RAjXIDD`DLhff.UHAVAUATSHHHDLhLopPODLH&LH&H{0DHCpPHRL,LkpAE<<DHcHiH@DAAA}YAE NIuH?11WtKAoaX5D`,DLh HL&"E1AfX \X"t[DA\A]A^]AFXIXDLH[A\A]A^]@tD`,H{HD@(HLCPH׋J89uR()HHL HЀt.fDff.I$HHLu[H‹BIHH NjBDI8D9rˋI(D)R$HHLfDALXVXI9s #D8LEAEtEeLCHDLKPHIAEJ89R$HHLDHAt/]ff.ER$LHLDAu0H‹BIHMBEZ8D9rER(D)I9s DAteD8LEEf.EeDMm'@R()HHL.@D`DLh@D`DLh@UHAWAVAUATSHHHHDLhLopP(DLH#0LH #Ls0JlXLcIiĈM L8LtKI>fK[A\A]A^]D`,DLh HLb1AfX \X"uDLH[A\A]A^]"f@tD`,H{HD@(HLCPH׋J89riR()HHL HЀt"cI$HHLuCH‹BIHH NjBDI8D9rˋI(D)R$HHLfDI9s tOD8LEM@A?XIXfAaRXIXf.D`DLh@1aH8jHAjXIfff.UHAWAVAUATSHH8HHDL`LgpPIDLH>LH+LK0HCpPHRL<ЋL{pEA<M<eEAHc־JlXHiˆHUM4I FHUBA"@DLLAHnk"I>HHF@I>HH8[A\A]A^A_]@Dh,DL` HL6"1H8[A\A]A^A_]@tDh,H{HD@(HLCPH׋J89R()HHL HЀtRDff.ff.ff.ff.I$HHLH‹BIHH NjBDI8D9rNjI(D)R$HHL`fDI>xG1fAfX \XDH8LH[A\A]A^A_])fI9s {D8LEgDmAGtEoH{HDLCPHHAGJ89R$HHLDHAt+Yff.ER$LHLDAu0H‹BIHLNjBEZ8D9rER(D)I9s DAD8LEfDLeHLLH߹IXA?XH8[A\A]A^A_]fDEoDM@UAaRXIXcDR()HHL@DhDL`@DhDLx3ff.UHAWAVAUATSHH8HHDL`LgpPqDLHLHLK0HCpPHRL<ЋL{pEA<<%EAHc־JlXHiˆHUM4I AHUA"@DLLƃ"AHf"ƃ"I>1DAI>CH8[A\A]A^A_]fDDh,DL` HL1"uAfX \XDH8LH[A\A]A^A_]@@tDh,H{HD@(HLCPH׋J89rqR()HHL HЀt*kDff.I$HHLuCH‹BIHH NjBDI8D9rˋI(D)R$HHLfDI9s D8LEDmAGtEoH{HDLCPHHAGJ89?R$HHLDHAt;iff.ff.ER$LHLDAu0H‹BIHLNjBEZ8D9rER(D)I9s DAD8LE-fDLeHLѠLH߹IXA?XH8[A\A]A^A_]fDEoDM@UAaRXIXDI>hA1R()HHL@DhDL`@DhDLxcff.UHAWAVAUATSHH8HHDL`LgpPQDLHnLH[LK0HCpPHRL<ЋL{pEA<<EAHc־JlXHiˆHUM4I F=HUAI6ADLH^I>?=I>?H8[A\A]A^A_]fDh,DL` HLv1"uAfX \XDH8LH[A\A]A^A_]|@@tDh,H{HD@(HLCPH׋J89}R()HHL HЀt6wfDff.ff.I$HHLuCH‹BIHH NjBDI8D9rˋI(D)R$HHLfDI9s D8LEDmAGtEoH{HDLCPHHAGJ89?R$HHLDHAt;iff.ff.ER$LHLDAu0H‹BIHLNjBEZ8D9rER(D)I9s DAD8LE=fDLeHL葜LH߹IXA?XeH8[A\A]A^A_]fDEoDM@UAaRXIXDI>(=%R()HHL@DhDL`+@DhDLxsff.UHAWAVAUATSHH8HHDLFLGpF< <t>DVEMƀt@t;"H81[A\A]A^A_]DDf,DLv AuFH@MfDhE$HXRA}E1LMAI(ULMHHH;}`-jA$AgXNXI$HIiH}LMHTLMI0TG},NXDLAnIXDDhE$LxAHо3Hйf},LXDLADXDUHAWAVAUIATSH8HHELGMEpG<J<ELËGH@M$MepA$<<EHLA|$~A$<tM<t<iAD$];t0H8L[A\A]A^A_]rfG,AH_ eDA"3LAIHHLHHnE1LFA|E5nEH]H/IhHEEIHt4HXHt@HI(H[ #Huf1AGIA$<Z<AD$It$ tIt$u AD$Ht(X@+H|AKXVXDLH8L[A\A]A^A_])f;=AAfXCtHiCIE0LXHH8tVXHDGtO,MMHMUPHIG(r89R()HHLDLHAt_@ff.ff.ff.ff.ff.E[$LHLDAtH‹BHHMBA[89rE[()DAD$tEt$IuHDI}PHHAD$J89R()HHHDHAtF-ff.ff.ff.E@$LHHDAH‹BIHLƋBEH8D9rE@(D)Et$EMd$EfR$HHHUfDR$HHLafDIPLHXx}1HLfH+EH8[A\A]A^A_]HA9s ADA6A8HEt@IA9s ADAE8LEgAIHAgXNX5jEH]HTIhHEEIHt9HXHtfHI(H[ @Huf1AGI1$f.ff.8HcHiIE0H8t@uuɨuʼnLۡ빋PAHX>DpEL`UAt$H5hEUHATLp0SHL@H0Hff.ff.H9tSHHt%Hi҈HH:uuH0LÉt&@[A\]H0L@[A\]fff.UHAWAVAUATSHHHHDLxLpPtiDfA?tA<t <ugAt`Hغ8HXT$"1H[A\A]A^A_]Dh,DLx "uAXX \XDL@tDh,LCHD@(HH{PIЋJ89uR()HHH HЀtRDff.ff.ff.ff.I$HHHH‹BIHI BDI8D9rNjI(D)H萹DIf=A>ofgEA9FHlocalhostDžlPHfƅADždADžhf f=0$gEA9G DLH;H DLHOH0fff.DžPDž(Dž8HDž@RXHDžHXXff.fA>tA>AFHpLrI<f<DA8LHNsI<`<HDfA>ufEA9FqR$HHHfDA4nX \XHHH[A\A]A^A_]eEA9FA>uAF"ASYX \XDLI9s tD8LE @DhDLxAGJIwI@ff.pfA?H0AG9dEDLHbDIAxXAxH=RcELH G ZELH 3H LHƹaXL ,gL fAxA@<A@hIH(IP HtA@KIpIxBAp Ix!<A@,HfYEHHUIPA@ApH|ApIx IP A@(Ap,H|?A8AxH= YELH H LHƹgXL eL fAxA@<A@Ip(Ix  jXeDžld[A@IpIx$A8fAxH=)XELH H LHƹ[lXL eL AxI@ lApIx sIPA@ApH|<A@,HWEH@~IP A@(Ap,H|Ap Ix!IP A@(AH,HTIPA@ApH|IP A@(Ap,H|AH IP!P<+AP,HVEHH H HAp Ix!D<Ax,H=VEH H HIP A@(Ap,H|A@IpIxIPA@ApH|:ApIx ,A8AxH=1VELH &H LHƹiXL cL AxA@ PA@t>t$IpIxA@tltRIpIxIPA@ApH|ApIx tIPA@ApH||ApIx nIPA@ApH|2ApIx $fUHAWAVAUATSHHHHDLhLopPtaDfA}tAE<t <u]A}tVHƧD8I"n1H[A\A]A^A_]fD`,DLh "uAXX \XDL2f@tD`,LCHD@(HH{PIЋJ89R()HHH HЀtBff.ff.ff.I$HHHH‹BIHI BDI8D9rNjI(D)H萦8H08tp"A4nX \XH2fR$HHH(fDA4nX \XDHHH[A\A]A^A_]>fDH8H($lHܥIËAD$2HPL^I<<<A8LHp_I<t|<t<fA<$tMREA9D$cuI9s tD8LE@D`DLhtuLHp\I<t7<<fA<$yOEA9D$hz@AXXDLH߹VX7^IP A@(Ap,H|(<A@,HCEHA8AxH=CELHHLHƹgXLPLfAxA@<3A@tTIp(Ix  jX|PDDžLA@t:t IpIxIP A@(Ap,H|IPA@ApH|ApIx Ap Ix!o<NAx,H=BEHHHAA8AxH=BELHHLHƹ[lXL}OLut$IpIxA@tltRIpIxIPA@ApH|ApIx IPA@ApH|qApIx cIPA@ApH|2ApIx $UHAWAVIAUATSH褒IAfA:t-A:t'A"Q1HĘ[A\A]A^A_]DLL葓LIAAEf=tGA}lfu AEA9EtRA"uASYX \XL^AEA9EtA}uAEtff.LLLIAAf=A? f@EA9GfA:A<aABOIrIZAmX \XLHĘL[A\A]A^A_]on@EA9GtA?J A"[ASYX \XLfDAE<GAZH>ELHLHHLKLHfA:Ht2ff.ff.\'PHu1HLHHHHL%!LHI<$HLf.H݈HHI|Hu≅LfA}LLDLf<hEDf><FmuHFH~fff.HJLHHݐaKI<<EHfA}C>EA9EH<LL%JH<'DL|}AHf>$<$vH5ku9;& DcL%0ELHƹMnXL= A}EeL%0ELHƹfXL=u9; DcL%m0ELmHƹlXLx=| A}=EeL%20EL2HƹfXL==uI; DcL%/ELHƹ`lXL=u;ff.A}EeL%/ELHƹfXL<=; DcL%y/ELyHƹfXL<<<AHL!HHiIF0H8LH@A_AMH@ABAMR@AEPIuI}fDAE>IuMefDAEVIuMefDDA=XLLVXof.AEIuMefD>/EA9BmLֹLLKyLH-LLLLHLL@AEIuMefDA}NEeL%:-EL:HƹfXLE:u9;DcL%-ELHƹMnXL:A}EeL%,ELHƹfXL9u9;DcL%,ELHƹlXL9A}*EeL%Z,ELZHƹfXLe9uA; DcL%%,EL%Hƹ`lXL09u ;FA}EEL+ELMHƹfXL8u; DcL%+ELHƹfXL8<<T<AHLNHHiIF0H8yHAXXVXf.AuI} WfAE IuMefDAuMe Wf.AuMe SfAmXVXL͑AuMe fAECMIuMeOfDf+EA9Bxfo`ƅHDž)fAzAzHIcAHՐ%DAuMe fIUAEAuH|f.AE@)IuMefDCR4HsLc]C&:AuMe fAuMe fCAE IuMe_fDAEn IuMefDCU HsLc5C: HsLcDL7P XXNFXLX{IUAEAuH|IUAEAuLdDž{AuMe sLc [IUAEAuLdAEW6 IuMe114C1 HsLcIF0H0n\tA>uWHLhhLh8HPXty"wA4nX \XH>f."NAmX \XL`AXX \XLHH[A\A]A^A_]#|HLhgLhIŋHAEf=A}YfEA9EH{0Lh臫Lh,sA<Afg <_ACx\IsM{fLLh!LhHDžIHfA; Ht(ff.\PHuLc0LhL Hc,LhH0HiɈLHH( H@ A>u A~H=ZEL@HhOHhL@HLh H Hi0HLhH H LLhLhLƅ(DHƅ*Dž@HDž8ƅ)ƅƅ+L@A$<OL8<u,AD$@ID$H8@ff.LH I<[<DA}1 fA}A}YAENHpLWI<<)DDhA< AWMguAG,Mg A<fAH=sEHHoHHHƹlXvA?AH=1EHH-HHHƹdbX4lA$<fA<$<DhAQXLH߹VXDwfDEA9EA}uAEff."HASYX \XL^f.EA9EDULDHQINjhcfDAGIwIfDhLHPIAMDLHPDI/PHA?fAH=EHHHHHƹoXVA$< fA<$<RAD$ G IT$It$fff.H{0觉A<$#E|$L=ELHƹ dSXLHC0,0]DAGMhEuDMmP@AwI fAGIwIfD@LHOH8@A?AH= EHHHHHƹkXVA$<F fA<$D <AD$] KIt$I|$D;hXƅ+ DAEAwI fAG#xIwIfDIWAGAwH|ffEA9CHDž`L޹HLhXLhH@`LHLhLhIHvA?AH=S EHHOHHHƹnXVA$< fA<$Q<"AD$xIt$M|$kXLƅ(ƅ*pA<$E|$L= ELHƹOXLHC0,0A{ Af_E{L=< ELhL5LhHfD`AXXVXLAwI }f<ufA<$A$q<AD$2 It$Md$kXLƅ+*f.AG)eIwIqfDIWAGAwH|f<At$H5 EHHH HHHfDAF5IvI~fDAD$It$M|$1HLHH Hi0HLhLH(Lh%=t* (ƅ*H )LhHi0L<2A+ AHDŽ2h AHHH8M JlXALLh>ApX^oXHEDLhHLi0H II>H%=Li0H JlXIM LHAz* E1ɀ(LP AH8Ht 8H0L%DLHߋXHPfRMQAC9EcA?6AH=;EHH7HHHƹ maX>A$<fA<$ < AD$c It$M|$kXLHƅ_A<$ E|$L=ELHƹ rSXLHC0,0<Ed$L%BELBHAwI OAT$It$ AvI~ At$M|$ "`AnIXNXLfA<$A$ <ƅ*pAgXNXHHIWAGAwH|AG>?IwI&1Ҿ@UMH@Lh H@LhH@DhAXLH߹AXDBl*AD$It$M|$JDAXLH߹AXkAsM{ M JlXLLhApX^oXI(HELhHA?;AH=KEHHGHHHƹ ]XN;A$<fA<$( <AD$6  It$M|$DjXLƅ)oA<$Ed$L%ELHLuH 1HHi0H@qhXL蟿E1ALPzAwI At$M|$ fA<$A$<AD$  It$M|$NbXLhfA<$A$ < Ed$L%EL褿HƹiXL)DȈ)#fA<$A$z< AD$ < It$Md$5jXLH AGIwIIWAGAwH|IL$AD$AT$HtIT$AD$At$L|IVAFAvH|ZAD$AIt$M|$AQXLH߹AXhohXLLh~Lh=ApXUoXhXLLhDLhXApXUoXWISACAsL|<Ed$L%EL謽Hƹ5jXL  (At$I E1LP<A|$H=MEHHIHHHAt$I|$ 1Lh輽Lh8 I JlXLh4Lht1肽Lh8`AXXLH߹LXfE{L=DLhL藼fXLH LhAAwI /1ɺ1~At$M|$ IWAGAwH|AGIwIIT$AD$At$L|JAD$It$Md$&I>L`LLPA1LHDDh[1DLxL`DhLHvHDžf)MsHLHHLD@LHH8G?nhXLLhLh&pXAtoXDLh,LhH5nhXLLhɹLh4&pXAtoXH LhHi0H(萻LhH<E|$L=DLH"AD$eWIt$Md$?<Ed$L%DL̹H<E|$L=DL訹HIT$AD$At$LdAt$M|$ AwI ,ƅ) `AmX \XL8IT$AD$At$H|At$I IWAGAwH|DhAIXLH߹IXDcIT$AD$At$L|;IHhAU(HLPL[QL胸LLHHhJlXII 虷E1ɅA{pSLFTI>A+AHi0H JlXLPHH "A넾11LP赼H JlXHi0H E1sL5DLAt$I fIT$AD$At$Ld\AlXLH߹VX_At$M|$ kIT$AD$At$L|hIT$AD$At$L|9I>Hu@D9Su:CHD@H<tK<Af=tf;u[A\]fD;St;t[1A\]fDCtKMAHIyPHICr89R$HHHD"HAt*Qff.[$HHHD Au)H‹BHHIBDc8D9rɋ[(D)ĐHA9s AD AtSA8HED9[KAH[DR()HHH2@HAHXfff.UHAWAVLcAUMiATISHH_0IIPIEIDžPH=@H=eH=YID$0MD90=D90GD90QIiƈ1Ҿ[XH@PhIiƈ1ҾXXH@-Iiƈ1Ҿ \XH@ JIiƈH@@u@u]fff.MiIAMiLH@蠖Hǃ@IEH H(Hǃ 誰H0Hǃ(蓰Hǃ0H[A\A]A^A_]DA QL/I@ILJ@IEI I(ILJ I0ILJ(AILJ0H1貰8軰A$LI$HHIAjX[A\A]A^A_] ZDǀ0D90ǀ0D90ǀ0M|$0XXy1I HxM|$0[XQ1I@HPsM|$0 \X)1IPH(I}臔fLIH5DHIILL0>fAn$fnIG8HfbIG0AGAGfAO@ADŽ$")fDA$" ADŽ$"LCA$LL轵uADŽ$"I}藇A$I$HNXLAgXXI$HNXf~LAgXWffDUHAUATSHHHHDLhLopP}t8DLHfx@LHWHH߉[A\A]]D`,DLh HL&y" H1[A\A]]@tD`,H{HD@(HLCPH׋J89R()HHL HЀt>ff.ff.ff.I$HHLuCH‹BIHH NjBDI8D9rˋI(D)R$HHLxfDI9s t?D8LE@HDLHAfX[ \XA\A]]%VDD`DLh[ff.UHAWAVAUATSHHXHHDLhLopPDLHnHCpDPHRL,LkpAE<<DAEf=AA}fu NDA9M$1"HX[A\A]A^A_]f &DA9MtAU*AEHuL/I<1<ADADAuAH=tDItjXLH?AtA,H=9DH}8H}HƹkXBLHu^I<X<DAEf=DD`,DLh HL@1"AfX \XDHXLH[A\A]A^A_]SDAGtAwH{HLCPHHAGJ891R$HHLD A.@ff.EI$LHLDA,H‹BHHL NjBEQ8D9rEI(D)AGsIW AG(Aw,H||DAEtEuHsHDH{PHHAEJ89sR$HHHDAPTfff.ff.ff.ff.ff.E@$LHHDAuhH‹BIHLƋBEH8D9rE@(D)I9s DA HII9s DAD8LE}fDAwMAEuDMmK@Aw I!f.R()HHL@R()HHH@@tD`,H{HD@(HLCPH׋J89R()HHL 5I$HHLucH‹BIHH NjBDI8D9rˋI(D)AIw(I R$HHLxfDI9s KD8LEo &DA9MA}AEDAEtEuHsHDH{PHHAEJ89[R$HHHDA,fDff.E@$LHHDAu`H‹BIHLƋBEH8D9rE@(D)HLAWXVX*OHX[A\A]A^A_]I9s DA@D8LEvfDpLxAf.DpDLh@EuDMm$@AEi*ASYX \XDDR()HHH@Hй>Hйffu(DA9Eu H&AlXDLH߹ \XMD`DLh#uAWXDLH߹AXMDpDLh5HоCHйvff.UHAWAVAUATSHH(HPH LeHLDH H HPH H LDžDžHPDžHDžHHDžHDžLMAA$f=*A$;AD$ H0LI<:<H(EDAU3A}H I]HPHAE<ID<A}H=DH裡HHƹGX; LHPI<<H(DA$f= mDA9L$A$ML5f )DA9F H HPHMHt36H HPH$ H$LHU H(11LQHHI‹@<,\H HPDHLJ,E> I1 HDLH(fA<$A<$AD$HpL-I<e < AA<<Z E~L=qDLqHƹ ^XL|u A~ A>` E~L=0DL0Hƹ _YXL;u A~LHuPI< <= fA<$DA9D$A}A]HDH蝞Hƹ ^XHu A}7A}A]H[DH[Hƹ _YXHfuA}H(AXXDLVXA=HHD[A\A]A^A_]EAEtE}H(DHH{HHsPHAEJ89 R$HHHHЀtU}ff.ff.ff.ff.ff.E@$LHHu*H‹BIHLNjBEH8D9rE@(D)ŐIH(9s |H(DIŀAXXAXHH(FA@AD$tEt$H(DHHsHH{PHAD$J89R$HHHD HAtEsff.ff.ff.E@$LHHDAu0H‹BIHLƋBEH8D9rE@(D)IH(9s DARH(D8LE(E}H(DMmAUdA}A}H=RDHNHHƹpoXU ;[HDHkXHHH ЈXEt$H(DMd$CR()HHH@R()HHH(@H(HDNHH(A}AEhIUAEAuH|fA}A}H=DHHHƹ [XA}A}H=DH軙HHƹ (SX;CHDHI|mXLH;CHDDHIAHƹwjXLLHAE,H(I] AUfDAuI} fAEIUAEAuH|ADDxH(DLhAUTDpH(DL`D;[H%DH%kXH߹H0Hˆ ЈnAuI} fIuI}*[HDH讗kXHHH ЈDAE>NIuI}RfDH(Hh H HPH HH(Hho HHHQ8ؖHJJဃ ʈJHPA}A}H=DH蕖HHƹ ^Xf=fm;HAlX \XgMLAuI} IuI}AE IuI}UAEIUAEAuH|A}>A}H=DH蓕HHƹRNX{f=fc;HDH(HDDHAuI} TIUAEAuH|LƇHMt(L荔urH HPLHLJf112H HPt HH9ȖtHtЀ8.uˀxuŀHLH HPHHPH(L^XDMLDAA}FA}H=DHՓHHƹ r\Xf=.f;HDH(HD(DHD9CH(HH( "@H HPAuI} rIuI}?D9CHAD9CPgAEJ~IuI}HA^XIHY |E1HDžDžLL(DEHHIM0L<H80|*D5DH@L$LAD$5ZD)ȹAD$LeLHoDH HEAFLfUH@foEHHUHPIE0H80Bt8MAVAFfoEHRH@AHHHMHJIU0HfAnH80fBnD:HMHEfbfEfoEHUHPA|HH9EDIDD`5kDH@I|AEH(DEeIH\ HDLH(EbLыHDHHH(HH | H(HH@0H80HA HL 1҃8u)H x HH9t8tHH9uɅ H(4HEIH` |E1HDžDžDML(HIU0HH80HHكy IHt y5D5DH@Mt[fu SDA9FtP"E1HeD[A\A]A^A_]Dn,DHF HgDAFtFH@H4Hsp<O<DEIFH@HHHCp<<!D1H@fA;HAz<LE1LDLHDL٪AlX \XLDLt\HD1LjLDHL LHHY^q,A4nXAXDLH!AzEFtDn,LCHDLKPHIF(J89R()HHLDAt3@ff.E[$LHLDAH‹BIHMBEc8D9rE[(D)DA9FA>AFfDEFtDfH{HDLCPHHNjFJ89R()HHLD IHAtUDff.ff.ff.ff.EI$LHLDAH‹BIHL NjBEY8D9rEI(D)DfDLv@R$HHLCfDR$HHLSfDD~DL^@I9s DAD8LEfDH9s DAmD8HDHASYX \XDLHeH[A\A]A^A_]<ACHD8[Dx]:x0L 5DLLDHDH?A^H@tDPH{HDLCPHHHJ8@9_R$HHL HЀtBoff.ff.ff.I$HHLu+H‹BIHH NjBDI8D9rˋI(D)H9s D8HDHEFtD~LCHDLKPHIFJ89RR$HHL IHЀtJs@ff.ff.ff.ff.I$HHLu+H‹BIHI BDY8D9rˋI(D)I9s D8LEA_X \XDLsf.HDPDH@HfDASu.IC TICGASHD9fDACM{ HHhLDHHhHo HLJؖ-HDLLA?HEDMLH@DHHjHLDALXEZA;uACuLpL=R()HHL@R()HHL@DhDH@H'DD`DLp=@A_X \XM{ACM|ACHkfDLHRLDIHhLDHHhHo HLJؖwHMDLLAffDHHXDxDLX@DPDH@HLLD'AHDILH!8A;u ACEHLL DHnHLHaDLLLDLDA;uACuLD3nDDLDHH0#JLK=ICH5dDL LLDsLD=LHIHA^XHHLH<LE1DHLDHɞHDLHD1HjLDH^HH_jA4nXAXDHf.AAAtEi,HsHDLSPHH AA(y89I()HHLDAt1mfff.E[$LHLDAHAIHLƋAEc8D9rE[(D)DA9D$oA<$"AD$SAAD$tEt$LCHDL[PHI AD$y89I()HHLD9HAtTff.ff.ff.ff.Ed$$LHLD8AHAIHM$AE|$8D9rEd$(D)AGtDWL[HDLcPHI ËGDA8D9I(D)HHLD1AAt?Dff.ff.Ev$LHLD0A<HAAIHM4ËAE~8D9rEv(D)f.DWDHGHDEt$DMd$f.I$HHL.fDI$HHL@fDI$HHLMfDNuwHF 8[Dx]xL 5aDLDLHߋHHe[A\A]A^A_]QDLAHFHHxH7gHLHDIMHvff.HLDfHHhADAHHhHHo HǂؖHDLA}1LHDfDHA|.t .fALHEMDHLHjH_HH:HL:fXZ@I9s D8A9D8LEfDH9s DAD8HEfDHD9s DD0AD8HDHDASYX \XDLHeH[A\A]A^A_]f<FHvDD8[ A_X \XDfDDPDH@HMDDhDHp@DpDL`I@AlX \XDH"bDA_X \XDHBDHFIVHD<FLHxDHHcLHIHDH DH]HhIHHhHHo HǂؖHMDLHDLvcsLHxDHHFHHxHbHLHDItHVFHtAgXNXLUHAWAVAUATSHHHHLFLGpF<<AMFH@I<AA$f=A<$tWfu DA9D$tLE1"HeD[A\A]A^A_]f.D~,DLN 8@AD$tL@1fA9LHAm<AADH XAAL(HxH0!aL(H HDIIQAALLUAFtD~,LKHDLSPHI F(y89I()HHLDAtcff.ff.ff.ff.ff.E[$LHLDAHAIHMAEc8D9rE[(D)ΤDA9D$gA<$AD$KAAD$tEl$LCHDL[PHI AD$y89I()HHLD1HAtTff.ff.ff.ff.Ed$$LHLD0AHAIHM$AEt$8D9rEd$(D)AGtDWL[HDLcPHI ËGDA8D9I(D)HHLD)AAt?;Dff.ff.Em$LHLD(A|HAAIHM,ËAEu8D9rEm(D)f.El$DMd$%f.DWDHGH8D<EIL uDDLωH L(Z^HxH0]L(H HDI2H0LLD(]H0D(ALD0]D0A|.t .fA HLEMAWH8DH^HALG]XZ4I$HHL.fDI$HHL@fDI$HHLfD1LDHL0D(L0HDLH,D(IDI9s D0AD8LE1fDI9s DAD8LEfDH8D9s DD(AD8HD8H8DASYX \XDLHeH[A\A]A^A_]IfDxDLH@DhDL`O@DPDH@H8DAAL(HxH0[L(H HDII QIAL(HxH0ZL(H HDItEMI DAmX \XDLfMHHDH8HpAgXNXUHAWAVAUATSHH8HHDL`LgpPADLH~0LHk0LK0HCpPHRL<ЋL{pEA<<EAHc־JlXLi҈HUO,I VYHUA\wHDLjDMILH艶ZYHe[A\A]A^A_]Dh,DL` HL/1"uAfX \XDHeLH[A\A]A^A_]@@tDh,H{HD@(HLCPH׋J89raR()HHL HЀt[I$HHLuCH‹BIHH NjBDI8D9rˋI(D)R$HHLfDI9s D8LEDuAGtEwH{HDLCPHHAGJ89/R$HHLDHAt;iff.ff.ER$LHLDAu0H‹BIHLNjBEZ8D9rER(D)I9s DAD8LEmfDLeHLѸLH߹IXABXHe[A\A]A^A_]fDEwDM@UAVXIXDR()HHL@DhDL`k@DpDLxff.UHAWAVAUATSHH(HHDLpLwpPtdDEHs0Hc0HiЈL<AHDLjELHIZYHe[A\A]A^A_]D`,DLp E@tD`,LCHD@(HH{PIЋJ89R()HHH HЀtWf.ff.ff.ff.ff.I$HHHH‹BIHI BDI8D9rNjI(D)LeHL艶LH߹IXABX]He[A\A]A^A_]fDR$HHHfDI9s tD8LE:@D`DLp"ff.UHAWAVAUATSHHHHHDLhLopPPDLHN*XLH;*DHC0HEHCpPHRH4Hsp<<DEHFH@L$LcpA$<<DEA$f=A<$fDA9D$HcHEJlXHULiшDMHMLH HERLUHMDMHUAHDEMjHLZYHe[A\A]A^A_]ÐD`,DLh HL("11He[A\A]A^A_]ËDA9D$+A<$L"uASYX \XDLD@tD`,H{HD@(HLCPH׋J89R()HHL HЀtRDff.ff.ff.ff.I$HHLH‹BIHH NjBDI8D9rNjI(D)R$HHL`fDAfX \XDLHeH[A\A]A^A_]fLeHLIXLHߋABXqI9s D8LEEAD$tEt$LCHDLSPHI AD$q89=I$HHLDHAtYfff.ff.ff.ff.ff.E[$LHLDAu0HAIHMAEc8D9rE[(D)I9s DAD8LEMfDEFtD~HSHDLSPHH ‹FDA8D9I$HHLDAAtNfff.ff.ff.ff.E[$LHLDAu0HAAIHL‹AEc8D9rE[(D)fDHD9s DDAD8HE@D~DHV@Et$DMd$fAD$@ I(D)HHLI()HHL@D`DLh+@AVXIXDDAD$DpDL`s@DxDHP-HHfUHAUATSHH(LHDMPLWpA@<<tyDDLA@H@I4Hsp<<YDf=U>t@fu ȑD9Ft51"He[A\A]]DAH,IP FtHC0Hc0LiLjLHIHHjԩZYHe[A\A]]DA@tAH,HSHL[PHH4A@(~89v()HHLD&AtCff.ff.Ed$$LHLD AHƋFHHL$‹FEl$8D9rEd$(D)D9F>FfFtDNLSHDL[PHI<‹FDG8D9(D)HHLD'AHAtJf.ff.ff.ff.v$HHLD AuqHNjGAIHI4‹GDf8D9rȋv(D)DNDHv@$HHLSfDv$HHLLfDHD9s DD AD8HE2@H9s D A8HEHeHASYXD[ \XA\A]]LeHL豫LH߹IXABXHe[A\A]]f.DHDHpz@HHP:fDLH(DUHAWAVIAUATASHHxLE<<~FIL~<B<|A>A~H=DH}IH}Hƹ @_X芙u&A<<ufIGHx]pkA>vA~H=#DH}"IH}Hƹ!bX,A<(<(ATXDLH߹VX1Hx[A\A]A^A_]fDF,L~ | AFIVAFAvH|DLHINj|LDxLufDATXDLH߹AXWKfA>fA~H=DH}HH}Hƹ ^X LA>A~H=NJDH}GH}HƹuoXЗ A<<EoL-DLGkXLH茗t:A? EoL-KDLKGHƹ5jXLV>A?5EL=DLGHƺkXL" Ј"DAvI~ Qf.AF;IvI~fDA<<EoL-qDLqFkXLH|t:A?/EoL-;DL;FHƹ5jXLF.A?EL=DLFHƺkXL " Ј"DEoL-DLEkXLHt:A?EoL-DLEHƹ5jXL芕rA?(EL=EDLEEHƺkXLP" Ј"AvI~ fIvI~zMLDxLuLpfATXDLH߹AXfAF#IvI~fDA>A~H=kDH}jDH}HƹpoXt$A<p<HEoL-%DL%DkXLH0t:A?EoL-DLCHƹ5jXLA?EL=DLCHƺkXL"҃ Ј";fAvI~ wfIVAFAvH|?f.AF1IvI~ofDA>A~H= DH} CH}Hƹ,gXPA<<EoL-ŅDLBkXLHВt:A?EoL-DLBHƹ5jXL蚒A?HEL=UDLUBHƹkXL`"fAGt}YIwMAvI~ EIVAFAvH|AFnYIvI~iAG}IwMo.AwI ZA>A~H=DH}~AH}Hƹ (SX舑A<<\EoL-9DL9AkXLHDt:A?9 EoL-DLAHƹ5jXLA?jEL=ɃDL@HƺkXLԐ!" Ј!"NAGIwMuAvI~ AFIvI~@IVAFAvH|nAwMo AGIwMoAwI AGIwMA>A~H=DH}?H}Hƹ`X蹏A<<EoL-jDLj?kXLHut:A? EoL-4DL4?Hƹ5jXL?'A?EL=DL>HƺkXL " Ј "IWAGAwL|nAvI~ AFIvI~ IVAFAvH|AwMo $AGWIwMoIWAGAwLlAwI AGIwMBIWAGAwL|A>A~H=DH}=H}Hƹ \XʍeA<<EoL-{DL{=kXLH膍t:A?VEoL-EDLE=Hƹ5jXLP8A?EL= DL =HƺkXL" Ј"AvI~ RIVAFAvH|AwMo ]AFIvI~AwI IWAGAwLl'AGWIwMoQA>A~H= DH}A~H=%}DH}$:H}HƹRNX.A<*Af)<f~DA9GD|LuIDxMLpEA$f=A$AD$tHuLEH<:Dd<{ {H=6|DHh29MpXHhH9;u?CDdHs<<uE<f>t<LHu8I@tDhDAD$INPHkHIVHr89vR$HHHA"9PPA$<*<+EIWAGAwL|AvI~ nDCtKʋCIvPHkHIVHz89DR$HHHA"9P;P<-<AE<RATXDHLAX{DA9\$IVAFAvH|AwMo AFIvI~!IWAGAwL|AwI OAG(IwMIWAGAwLlAGIwMoR()HHHHމLzHIVAFAvH|dAvI~ VAGt+IwMHIWAGAwLlAwI $El$EMd$oR()HHHAGIwMoAwI AG yDA9O<AGAFIvI~[C,AHs DL:HlIWAGAwL|vLDxLu9AGtltvIwMoCAH[7IVAFAvH|-AvI~ IWAGAwLlAwMo AwMo uIWAGAwLl_MLDLuLHDxQ|AGtKt1IwMoIWAGAwLlAwMo IWAGAwLlwAwMo iMLLuDxLpfxDA9@MtM}HEH{|nIVAFAvH|AGt't IwMIWAGAwL|AwI IWAGAwL|TIWAGAwL|-DLLEIqUHAWAVIAUATSHHHELGMFpG<<GEELPGH@It=<<u ~7AmX \XHDLH[A\A]A^A_]<DnL-?DLHLLIHhLH@ AgIDŽt(ff.ff.\tcPHuHhL`L1ҹLHhHLH[A\A]A^A_]D/PHuAFIVAFAvLlDDnL->DLZpXLHKAFM~<<rDAF0Mn0<<DfA?mA?DfA}t A}1AGIw tIwu AGHtH{0qA}IEmL-=DLHLJHHhHHUH@ heH}IlAULt%Dff.\PHuLL1ҹLLHL 'LAXXLX<AvMn `IvMnSAF,M~ f/PHM]fA}t A}A?AwH5yfMVA$LNXI$HHAgX[A\A]A^A_]馕1UHAWAVAUATISH(ff.I$FE$!"AA//DtLX,M$1HS㥛 HHHHUMf.A "t ?IA"Ht&u"HuH95ILJf.AAIHLE"MMt.DkLs+[EfoZH}H)EI$A$!"H([A\A]A^A_]fDIGHtIOHHMwMt.IOINMwM9$t8LMJM9$tLE%NM$MwfM UHAWAVAUATSHH(HHD]LhILkpxDDAD$<t<AD$HUHLDHVHHHEl$~DECHVHHH|AD$VAE)A9AHCpPHRH4Hsp>uFtVD1"tUH([A\A]A^A_]fD@Dx,DAgXNXH(H[A\A]A^A_]AbX \XDLDLchEAT$L1AD$HhߞID$IHfAd$DLE11HZtHH"HHPHtHBHH([A\A]A^A_]fDHH HhA<$AL$L tJEl$L-)DMLMHE1LELL4}ID$.fAL$"AD$t tIT$Ml$ 1El$AT$Iff."tUHSHH"tG"HLJ@HHS㥛 HHHHH|1t H]fDHHHAgXH]NXHHLXL_pPtRt%Pt,1"fDp,LX AuICHXÐ@tp,LOH@(HLWPIыJ89R()HHL AHЀt?ff.ff.ff.I$HHLu[H‹BAHHI BDY8D9rʋI(D)fR$HHLvfDAdX \XL风ID9s Dt%tIApLXAf.HHLXL_pPtrt%Pt,1"/fDp,LX AuHISHu H@HtH9Xu"Ð@tp,LOH@(HLWPIыJ89r{R()HHL AHЀt3lff.ff.I$HHLu;H‹BAHHI BDY8D9rʋI(D)fR$HHL념ID9s Dt=t IAdX \XL黌ApLXAfUHAVAUATSHHHDLhLopPD@ff.&DHH4IHL4AF9uǃǃDLDLHrnup1LH!pHxHHHAgX[NXA\A]A^]鐋D`,DLh %DAHx".1[A\A]A^]D@tD`,LCHD@(HH{PIЋJ89R()HHH HЀtNDff.ff.ff.ff.I$HHHuCH‹BIHI BDI8D9rˋI(D)R$HHHhfDI9s tD8LE @D`DLh@"uÐUHATASH"HLJ@LHHS㥛 HHHEAOHcHHv1t[A\]fHHHAgX[NXA\]錉ff."uÐUHATASH"HLJ@HHS㥛 HHHHHut@HHPHCXHEu 1[A\]@@1[A\]fHHHAgX[NXA\]鼈ff.UHATISHS㥛 HHHHDHI$@[A\]Ð[ff.UHAVAULATILSSA|$pYI|$OI|$ID$L1A$Mt$XsH{|@HTLyHHuMt$@DsH{L@H$LyHHuI|$8Htw"@I|$8ID$8ID$L[A\A]A^]fDUHp0HAWAVIAUIATE1SHHH "HHEIAHAtgtHHHt1Lu+L0MtLL9uLLLuH}HD[A\A]A^A_]H}A@UHATISf>tE<tq<FHFHO0HH@HH "t|[A\]D<t,vHDHHHI|$0H[A\]Ftu$HNFVH\VH^ fDHVH^fDzff.UfHHH})EHfff.UHSHH<t]<t)<<tu< HGH(H]G tHGH(uHGHxH{@Gt¨uHGH(uH{`HGH(uHGHx@HCHx3H{*lfHGH([HGHxD,H{1fC:HGHpHx HCHxd< HGH(HGHpH@H HP0gDUHSHH/Ht.HNjH3011H]ú@@)@t@t@ t@ ufIVHHIH9uf.H[HuL4IO7 "L }HuK7@ "uqLH[HA "u H([A\A]A^A_]@A$AgXNXI$HH(L[A\A]A^A_]gfA ;XVXDLD f.K7X "p)fDK5 "HK5x "H#ff.UHAVAUIATSHw H_I]A!" AIu0HtAI}IE0AMeI$ "H1fH11@tH4vH4A "0u;AuL0I(f.H0I9uuH{CCHI9uAu [1A\A]A^]I}MMuXIEI}迬IELDsH{5HLLoHHuMu@fDsH{5HLoHHuI}8Htw5I}8jIE81AL![1A\A]A^]H@H4@HzIE8HHHH IH4Hff.ff.ff.ff.ff.HHH9oHHHJHt8@t)@t7@t@t @ t@ uHHHtuE1 tf.HHLXL_pPPB<UHHICfHnt fH*YrfH}H,Hc‰HiMbH&)ifn)i@Bfnfbfffb)Ezp,LX AB<d1"@@tp,LOH@(HLWPIыJ89rkR()HHL AHЀt#\fI$HHLu;H‹BAHHI BDY8D9rʋI(D)fR$HHL땐ID9s Dt=t IuAvgX \XLyATpLXA7fUHAVAUATSHH HHDLhLopP3t6DPt?"H 1[A\A]A^]f.D`,DLh AUu "1;ff.ff.ff.HtHs0<@tLOJ4 "0u9p "uLuHL/LDLDHfMF[H [A\A]A^]fH DLHA4nX[ \XA\A]A^]kx@tD`,HsHD@(HH{PH֋J89ryR()HHHDHAt+qff.E@$LHHDAuHH‹BIHLƋBEH8D9rE@(D)R$HHHfI9s DAt DtIAUD`DLhAUff.UHAWAVAUATSHHHHDLhLopPDPLHqaHS0HH@HH "@LH=xCHH@L4HC0N4M "A " I "Ʊ1Idž "AH[A\A]A^A_]fD`,DLh AUGAoXAX1LH+vfD@tD`,H{HD@(HLCPH׋J89R()HHL HЀt"I$HHLH‹BIHH NjBDI8D9rNjI(D)AoXLX1LHpuAiX \X"HDLH[A\A]A^A_]4u@R$HHL8fDI9s t?Dt!IfAJGXIXAUfDD`DLhAUUHAVAUATISHHLhLopPPPL6HLL7IH1HL GAELp^9HHI|$0EugXDH߉M+AUHCHRIt?fDff.ff.ff.ff.IHL9tsAoEIUHPAUtAMtt t ufff.IUHIHL9uf.k "1AEff.ff.ff.ff.HIt$0t݉H<H

<<uUFtOHNHw0HcH@HHH " "<u%x!ID$0tH[A\A]]fANXLXHHL1[A\A]]ifD<tDDnL-ADLAHI|$0LtHH@HH "tDCtu$HKCSLlSLk fDHSLkfDUHAWAVAUIATSH(HHDL`LgpP1tDDLLrÄuDAiX \XA"H([A\A]A^A_]fDx,DL` LLxHMu0HEH@HHA "`I "IHUHHEO>X "=AwI LsLYIHuHEH@HM$I$ "DIDŽ$ "HEA "H} D@tDx,I}HD@(HMEPH׋J89R()HHL HЀtVfff.ff.ff.ff.ff.I$HHLusH‹BIHH NjBDI8D9rˋI(D)A8GXIXH(DLL[A\A]A^A_]ffR$HHL0fDIA9s AtE8LEf.DxEL`ff.UHAWAVAUAATASHHhHHUDLxLpPP_DLHg"HK0cEHMIK@DmHLxH4HEH1 "HuH}H<1H}H}HELh "MHEH]LX "MELLIFpEPHRHff.ff.ff.I$HHLuCH‹BIHH NjBDI8D9rˋI(D)R$HHLxfDI9s {D8LEUHDLHAiX[ \XA\A]A^A_]XfAGtEgHsHDH{PHHAGJ89R$HHHDHAtO}fDff.ff.ff.ff.E@$LHHDAu0H‹BIHLƋBEH8D9rE@(D)I9s DAteD8LEf.EgDM@R()HHH@D`DLh@D`DLxA@UAoXAXHAUATISHH<tvf><<uUFtOHNHw0HcH@HHH " "<u%x!ID$0tH[A\A]]fAoXLXHHL1[A\A]]UfD<tDDnL-CL豫HI|$0LtHH@HH "tDCtu$HKCSLlSLk fDHSLkfDUHAVAUATSHHHDLhLopPt:DLHxAƄu9"[DA\A]A^]D`,DLh LH]LcExLc0,1I$ "&Dff.H tH IH A "0u;CuKDmHL,K, "苲SK, " "D[A\A]A^]@tD`,H{HD@(HLCPH׋J89}R()HHL HЀt6wfDff.ff.I$HHLuCH‹BIHH NjBDI8D9rˋI(D)R$HHLfDI9s t8D8LE@DLHAiX[ \XA\A]A^]'SD`DLhIcHiI ",% UHAVAUATSHHHDLhLopPt:DLHAƄu9"E1[DA\A]A^]DD`,DLh LHxLcLc0KDmHIĸ " uH[0菰1H "*fff.Hn1@tH4vH4 "0u;AuKDmQHIă " "&@tD`,H{HD@(HLCPH׋J89ryR()HHL HЀt2sfff.ff.I$HHLuCH‹BIHH NjBDI8D9rˋI(D)R$HHLfDI9s t?D8LE@DLHAiX[ \XA\A]A^]PD`DLhUHAWAVAUATSHHHHDLhLopPtDDLHADŽuCAiX \X"HD[A\A]A^A_]ÐD`,DLh LH]ExLs0-Hc}1I "$ff.H1@tH4vH4A "0u;AuHHIƋA9 " "u ǂ "HHIƸ "腭@tD`,H{HD@(HLCPH׋J89R()HHL HЀt.fDff.I$HHLukH‹BIHH NjBDI8D9rˋI(D)A13XIXHDLH[A\A]A^A_]lN@R$HHL`fDI9s tD8LED`DLh{ff.UAKXAXHAUATISHH<tvf><<uUFtOHNHw0HcH@HHH " "<u%x!ID$0tH[A\A]]fAKXLXHHL1[A\A]]NMfD<tDDnL-CLHI|$0LtHH@HH "tDCtu$HKCSLlSLk fDHSLkfDUHAVAUATSHHHDLhLopPtBDLHxAƄuAAgfX \X"T[DA\A]A^]DD`,DLh LHxAlX HHS0H@HH "0H "Ƃ"H ""H "" "dp "蒪TD@tD`,H{HD@(HLCPH׋J89R()HHL HЀt&fI$HHLukH‹BIHH NjBDI8D9rˋI(D)A&GXIXDLH[A\A]A^]JR$HHLhfDI9s tD8LE!@D`DLh ff.UHAVAUATSHHHDLhLopPt:DLH8AƄu9"E1[DA\A]A^]DD`,DLh HCpPHRL LKpA<{<Ah"uHAdX[ \XA\LA]A^]I@tD`,H{HD@(HLCPH׋J89R()HHL HЀtFff.ff.ff.I$HHLuCH‹BIHH NjBDI8D9rˋI(D)R$HHLpfDI9s D8LEEAgfX \XDLH[A\A]A^]_HAAtAqH{HLCPHHAAJ89<R$HHLDHAtXff.ff.ff.ff.ff.EI$LHLDAu0H‹BHHL NjBEQ8D9rEI(D)I9s DAILHHHS0H@HH "0A:XIXfDAqMIA0R()HHL@D`DLh@ApLHAf.UHAVAUATSHHHDLhLopPt:DLHHAƄu9"dE1[DA\A]A^]DD`,DLh HCpPHRL LKpA<;<SA"uHAdX[ \XA\LA]A^]E@tD`,H{HD@(HLCPH׋J89raR()HHL HЀtSI$HHLu;H‹BIHH NjBDI8D9rˋI(D)R$HHL럐I9s D8LE}AgfX \XDLH[A\A]A^]DAAtAqH{HLCPHHAAJ89 R$HHLDHAt(Vff.EI$LHLDAu0H‹BHHL NjBEQ8D9rEI(D)I9s DAILHEHHS0H@HH "0mA DXIXfDAqMIAR()HHL@D`DLh@AfpLHAIf.UHAVAUATSHHHDLhLopPtBDLHAƄuAAgfX \X"$[DA\A]A^]DD`,DLh LHxAlXHHS0H@HH "0H "[DA\A]A^]@tD`,H{HD@(HLCPH׋J89R()HHL HЀtI$HHLukH‹BIHH NjBDI8D9rˋI(D)AGXIXDLH[A\A]A^]oAR$HHLpfDI9s tD8LEQ@D`DLh9ff.UHAWAVAUATSHH(HHDLpLwpPtDDLHAńuC"nE1H(D[A\A]A^A_]fD`,DLp HCpPHRL<ЋL{pA<3<+A"tAbX \XLH(H[A\A]A^A_]?fD@tD`,H{HD@(HLCPH׋J89ER()HHL HЀt*<fI$HHLH‹BIHH NjBDI8D9rNjI(D)AGLH߉U诸ƅLcLS0UKIHMA "0AALHLML]LUrff.ff.ff.I$HHLuCH‹BIHH NjBDI8D9rˋI(D)R$HHLxfDI9s {D8LEUHDLHAgfX[ \XA\A]A^A_]Y:fAGtEgHsHDH{PHHAGJ89R$HHHDHAtO}fDff.ff.ff.ff.E@$LHHDAu0H‹BIHLƋBEH8D9rE@(D)I9s DAteD8LEf.EgDM@R()HHH@D`DLh@D`DLxA@UHAWAVAUIATSH(HHL`LgpPztELLAƄu=A"E1H(D[A\A]A^A_]f.X,L` 벐IEpEPHRLA<$3 fECA9D$4H{0LhLh LcHK0fA9K[HH`H " A9 H`K[HL4I "# K[DhE1HLPH@DLL8fDfA<$A<$K AD$? HpL=I<<gDhDA AFMn<<uAF,Mn ATA~H=YCHXUrHXHƹoX\ AU fA} AEIUIu@H{0ǔ A}EuL5CLqHLH@1HH`H "\A}AuH5wCH{0LurLDLHߋLHPAƄu LHuI<<hA$L8H`DhK[HH "1A0 XAXDLHA{EFtD~,H{HDLKPHHNjF(J89R()HHLDAtcff.ff.ff.ff.ff.ER$LHLDAH‹BIHLNjBEZ8D9rER(D)A4nX \XDLHĨH[A\A]A^A_]fDR$HHL#fDEl$DMd$f.I9s DADIfCA9D$,>f.DhAFtE~HsHDH{PHHAFJ89R$HHHD HAt8fDff.ff.E@$LHHDAu0H‹BIHLƋBEH8D9rE@(D)I9s DAYDIzAFIvI~fDDAFtAN,H{HLKPHHAF(r89R$HHLDHAtKE@$LHLDAu0H‹BHHLNjBEP8D9rE@(D)I9s DAy8ALEAuH5CHHXlHXHfDAEIu XIuLAEHt>DAEIuMufDAD$t AD$hhHsHH{PHHAD$J89R$HHHDHAt3hff.ff.E@$LHHDAu0H‹BIHLƋBEP8D9rE@(D)DhI9s DA*hkIƯCA9D$A<$ "'ASYX \XDLE~DMvAAD$Md$hA$AvI~ fAUIu fAuMu %fR()HHH@R()HHL@R()HHHR@AD$tEl$HsHDH{PHHAD$J89R$HHHDHAtDrfDff.ff.ff.E@$LHHDAu0H‹BIHLƋBEP8D9rE@(D)I9s DAD8LEfDAEAD$ADxDLHAIVAFAvH|f.A$fDIMAEAUHtf.IUAEAuLt-f.DxDLpA#PLhA5f.R()HHH1@HL`hA$`AD$f.HA9EqL5*CLXLLhhLhLXHLLXLhշLhH`1HK[HH "RHC0LXLhH`ZMH0L8LPH`DLK[H " A9u ETAHAAIqMqDhDL`41Ҿ@UQLXLhKLhLXI "A]IXNXL8H`K[HH "1A0 XAXLHAEL8H`K[HH "1AQXVXLDHwAL8H`K[HH "AQXAXLH3AL8H`K[HH "1AIXIXtL8H`K[HH "DdAqMq 1Ҿ@UQLXLh4JLXH`HLhK[HH "L8H`K[HH "IQAAAqLtLeLLhLLX1LDHDHXfMLh_IiH`H "D0cUHAWAVAUATSHHHHHDLFLGpF<<t;DVEMÀt="1HH[A\A]A^A_]@Df,DL^ AuËFH@I fJCA9F|A? AH=CLHaHLHƉL蕱HH&1HPHHHPgLp H{0L݇Lx LcH{0K@HHH L<I "F K@LHDHHLffA>|A> AF HL0I<b<DAEk AGMW<*<uAG,MW AAH=PCLHE`HLHƹoXL> LAK fA:m ABIIJABARHtCA9FA>uAF@ff."CASYX \XDLDCA9FtEAGtEgHsHDH{PHHAGJ89R$HHHDHAtfAFtEnH{HDLCPHH AFq893I()HHLD HAtafDff.ff.ff.ff.ff.EI$LHLDA4HAIHL NjAEQ8D9rEI(D)ARIr f.ArMz fR()HHHI@R()HHL(@I()HHLM@R()HHH.@I$HHLIwIIRIrIrMz%1Ҿ@UQLHLq<LHI "LsI9s DAD8LE fDAFA"EnDMv@AAGIwI6HVLXLHߋA mXAgD`DLxA PLPA'PLxDhDLpAAwI DhDLp LHLLLLK@HHHLDI "L _L@ _HQLL0I "Ip "H^HL߶LDHDHf2K8IOAGAwH|HE1H "AQXVXDLH]A0 XDLH߹AX?H1H "AIXIXDLH A]IXDLH߹NXyHH "AQXAXLHCHEH "@ff.UHAWAVAUIATSH(HHL`LgpPZtELLADŽu=A"gE1H(D[A\A]A^A_]f.X,L` 벐IEpEPHRHI]p<+<ELL%wEȅ~{XIE0HE<%<eEEH];{H=CH}SH}HƹoX%;{H=CH}RH}HƹlXHcEH@L4HEIJ0 "D1HHE-HGLI}0lXHgHH]ƺIU0N2 "HULZ]HULH[HHh "ZHELpLFH]HuDELHCLvf.@tX,I}Hڋ@(HMEPH׋J89r{R()HHL HЀt4ff.ff.I$HHLukH‹BHHH NjBDQ8D9rˋI(D)R$HHLfDANXVXDHH(L[A\A]A^A_]IA9s AYA8LEfDA}gX \XA"DAiX \XL|CtDsIuHDI}PHHƋCJ89R$HHHDHAt!O@E@$LHHDAu0H‹BIHLƋBEX8D9rE@(D)HA9s ADAEHDDsEH[R()HHH4@XAL`FDCHsH{ECtDcIuHDI}PHHƋCJ89~R()HHHDAt[{ff.ff.ff.ff.ff.E@$LHHDA4H‹BIHLƋBEH8D9rE@(D)Hc]HuH[HH "k@1HHNAH~AHISCL膽I}0oXH~H߉聯HCLHEMLH{HRHuHDELyCH}NrsH{ hR$HHHf.HBdHUA9s ADAE8HDEHEfDCtOHsH{ DcEHCHEDpEHX sH{ HSCsH|tD`EH@HE9HSCsH|H]HUHAWAVAUIATSH(HHL`LgpPtELL脟AƄu=A"'E1H(D[A\A]A^A_]f.X,L` 벐IEpEPHRHI]p<<ELL%oEx{IE0HE<<yEID}̀;{H= CH}KH}HƹoX)i;{H=CIJHƹfXLHcEHuH@HL4A "LI}0fXH{H߉I}0gXf{H{Ic "H{0聫fK2A "H{HlEUHLH(L[A\A]A^A_]fD@tX,I}Hڋ@(HMEPH׋J89r{R()HHL HЀt4ff.ff.I$HHLukH‹BHHH NjBDQ8D9rˋI(D)R$HHLfDAJOXVXDHH(L[A\A]A^A_]QIA9s AYA8LEfDA}gX \XA"DAiX \XL|CtD{IuHDI}PHHƋCJ89R$HHHDHAt!O@E@$LHHDAu0H‹BIHLƋBEX8D9rE@(D)HA9s ADAGEHTDD{EH[8R()HHH4@XAL`DCHsH{WD}CtCE̋EIuHI}PHHƋCJ89R()HHHDIHAtRfff.ff.ff.ff.E@$LHHDAH‹BEHLƋBE`8D9rE@(D)HcEHuH@HH "81HH9H߄9HI;LƵI}0oXH5wH߉HCLHEFLH{H蒤UHLELCH}jf.L3I}0fXHvH߉.I}0gXvH{եDsH{ KR$HHH):XIA9s ADAuA8LEfoCtO~HsLsCALcEf.DxEHXsLs HSCsH|`pAL`u'HSCsLtkff.UHAWAVAUATSHHHHDLFLGpF<<DVEMÀtACFH@I4Hsp<<; DdIDA4nX \X"n ƅXXH[A\A]A^A_]fDDf,DL^ AR"uAbX \XDLHH[A\A]A^A_]=DEFtDf,H{HDLKPHHNjF(J89R()HHLDMHAt1wfff.ER$LHLDAuHH‹BIHLNjBEZ8D9rER(D)R$HHL{fDI9s DA DIDdFt FddH{HLCPHHNjFJ89R$HHLD IHAtTfEI$LHLDAu0H‹BIHL NjBEq8D9rEI(D)DdI9s DA2 d ItFH@LHhYf9iHhFt HVHvdCA9GA?uAG@ff."ASYX \XDLGDA<$A|$H=ICHPE>HPHƹeXL$Hh'tG`HhH0LHu#I<<DA1HHH> "A0 XAXDLHXfDCA9GtEAD$tEt$HsHDH{PHHAD$J895R$HHHDHAt9gfDff.ff.E@$LHHDAu0H‹BIHLƋBEH8D9rE@(D)I9s DADIAD$:BIT$AD$At$H|fDAD$tAt$,LSHL[PHIAD$(J89FR$HHL HЀtIvff.ff.ff.ff.I$HHLu+H‹BHHI ‹BDA8D9rˋI(D)Hh9s 8HDhA$HhDAGtEoHsHDH{PHHAGJ89R$HHHDHAtGufff.ff.ff.E@$LHHDAu0H‹BIHLƋBEH8D9rE@(D)I9s DADImA]IXNX@dLfA<$A|$H=|CHP9HPHƹmbX Hh A|$ 5}C9w#DFLVdA@Et$DMd$A$DEoDMAnA)At$I|$ R()HHL3@R()HHH@AD$@It$I|$pR()HHL@qH5u{CHHXn8HXHH{0;[' Hh8xH=0{CI08HLH81HHHH "#Hh8pH5zCH{0LuhL4DLHߋdH@XHHHX@ "XfDD`DLXArH@Hq bHqVAHtI@H@AHqLa@R()HHH@AGtEoHsHDH{PHHAGJ89R$HHHDHAtcff.ff.ff.ff.ff.E@$LHHDAH‹BIHLƋBEH8D9rE@(D)At$I|$ It$I|$VHv qLa R()HHH I9s DAdD8LEfDAA$fDAAD$It$I|$XEoDM.@AGQ2HLPdAE@DpDL`A$,PH@A$HhJDhDLxAAt$I|$ IT$AD$At$H|&HNFVHtHQAqLd L@XLD LhuMH(LmLPL:LHfMDdHhLPEHLh蘠LhHDLHjIH1HH衰HHHhH(H@HL4A "I "HHHHL "L$I "AD$p腢IHXAD$5vCLH~H/oCHIFIFfAvAt$HRI IHI9Ao$IT$HPAT$tA<$@@ @t@t @ t@ uIT$HDhDLx;AH{0lXH@M4c11L蚓H3nCHIFHH1fAFH(H@HL4LI "聦I0 "HHHNXHAgXX1Ҿ@UQLXLhLhLXI "IT$AD$At$H|Q1HHH> "A0 XAXLH!XvH{0FlXH@M$a11L_HmCHOID$H(HHfAL$H@H0HL$M$ "HGH`H0HIH1HHPHA$ "AFp號IHlAF5sCLH蓑H4lCHID$ANID$fAT$HRI4IHI9AoIVHPAVtA>@@@t@t @ t@ uIVH E1MHHH> "AIXIXDLH%XzHHH "AQXAXHߋHhX:HHH> "H]H7#HHHLPQH0p "H7ƅXXE1MHHH> "AQXVXEMHHH "AQXVX*!w iEME1M뤾@H6H(HHH@H "HHHX@ "@HdHiC CpdHiCf CZdHkiC;@HDdHMiCUHAWAVIAUATSHHHHDLhLopPt "H}/@tP,MFHы@(H MNPI ȋy89I$HHLDHAt[~Dff.ff.ff.ff.ff.v$HHLDAu(HAHHI4ADV8D9rɋv(D)IA9s ADAA8LEIFpEPHRL MNpA<<ELU5jC11LLM~H7bCLMLUHELDLHELfEqSHA9s ADA}E8HEI()HHLaDGtwMNHMVPHIGJ89R$HHLDHAtCifDff.ff.ff.$HHLDAu(H‹BHHIxHLs0H@HI "GA}t.LH>xHL[0H@HI "HHDLAA<$%LCpA<]<DQEMŀ%AH@MLSpA<` <DA D"ELp= LK0HIHIH " "F Hpt1=t:LC0HRHIH " "tA tH軰: HpLuLzHLDDLfMSH+H [A\A]A^]fDA,Li fDH 1[A\A]A^]ÐDAD$tAt$LSHL[PHIAD$z89R()HHLD2HAt-;Ed$$LHLD0AH‹BHHM$‹BEt$8D9rEd$(D)DAtq,LSHL[PHI‹A(z89DR()HHLD"MHAt@Dff.ff.Ed$$LHLD AH‹BHHM$‹BEl$8D9rEd$(D)A<$A}HHDLALCpA<P<DQEMŀ"A4nX \XDLH H[A\A]A^]l@AD$Md$R$HHLfDR$HHLfDDa,DLi AU`Da,DLi AUI9s D0A8LEI9s D Aa8LEEAtDa,H{HDLSPHHNjA(r89zR$HHLDMHAt+Yff.E[$LHLDAu0H‹BIHLNjBEk8D9rE[(D)I9s DADRIEAtDa,H{HDLSPHHNjA(r89R$HHLDMHAtCqDff.ff.ff.E[$LHLDAu0H‹BIHLNjBEk8D9rE[(D)I9s DADHIAH@MLSpA<M<DA"A4nX \XDLfDPLh,fDPL`?fDH H[A\A]A^]@H H[A\A]A^]L@R()HHL@R()HHLOEJDMRA*EJDMRA@Hǃp&f."p=Hs0HIHHH " "FHpt1=t:HK0HRHHH " "tAtHqHpLuLsHLDDLfM Hq@,Hǃp`f.fDABtEJHsHDH{PHHABJ89"R$HHHDHAtMfE@$LHHDAu0H‹BIHLƋBEP8D9rE@(D)I9s DADIABtEJHsHDH{PHHABJ89^R$HHHDHAtGufff.ff.ff.E@$LHHDAu0H‹BIHLƋBEP8D9rE@(D)I9s DADIAUyAUHǃxD`DLhAUfD`DLhAU("gA}gX \XDLQR()HHHR()HHHAgXNXHH AADHDLPADHDLPAUHAWAVAUATSHHHHDLpLwpP tDDLHBbAńuC"E1HD[A\A]A^A_]fD`,DLp HCpDPHRLL+oH} HuI~HlLDLDH*AFAV*S IF H(UIF HpHxR>IF Hx I~ AF$f@tD`,H{HD@(HLCPH׋J895R()HHL HЀtB,ff.ff.ff.I$HHLH‹BIHH NjBDI8D9rNjI(D)HxHHxKvHL4A "CHV{H{0fXI<LQmH{0gX<I}kDLDLHH[A\A]A^A_]BfR$HHLfDI9s kD8LE[AiX \XDLHH[A\A]A^A_])fAGtEgHsHDH{PHHAGJ89R$HHHDHAtMfE@$LHHDAu0H‹BIHLƋBEH8D9rE@(D)I9s DAD8LEfDEgDM@AgXNXHHR()HHH@D`DLp@H߾yH{0fXI:LkH{0gX`:I}jIc "I}0{jfAM2A "I}HejD`DLxVNIF H(?I~ AF, $IF H(IF HxI~ ]AFIF H(IF HxwZI~ .1fAVIF H(IF HxIF HxW IF H(~IF HpH@H HP0UHAVAUATSHH HHDLALGpA<<<\DMŋAH@M$LcpA$<^<^DA}LH)+!HHS0H@HH "A}tcLH*xHLs0H@HI " GA}t.LH*xHL[0H@HI " HHDLAA<$%LCpA<]<DQEMŀ%AH@MLSpA<` <DA D"ELp= LK0HIHIH " "F Hpt1=t:LC0HRHIH " "tA tH軜: HpLuLfHLDDLfMSH+H [A\A]A^]fDA,Li fDH 1[A\A]A^]ÐDAD$tAt$LSHL[PHIAD$z89R()HHLD2HAt-;Ed$$LHLD0AH‹BHHM$‹BEt$8D9rEd$(D)DAtq,LSHL[PHI‹A(z89DR()HHLD"MHAt@Dff.ff.Ed$$LHLD AH‹BHHM$‹BEl$8D9rEd$(D)A<$A}HHDLALCpA<P<DQEMŀ"A4nX \XDLH H[A\A]A^]l@AD$Md$R$HHLfDR$HHLfDDa,DLi AU`Da,DLi AUI9s D0A8LEI9s D Aa8LEEAtDa,H{HDLSPHHNjA(r89zR$HHLDMHAt+Yff.E[$LHLDAu0H‹BIHLNjBEk8D9rE[(D)I9s DADRIEAtDa,H{HDLSPHHNjA(r89R$HHLDMHAtCqDff.ff.ff.E[$LHLDAu0H‹BIHLNjBEk8D9rE[(D)I9s DADHIAH@MLSpA<M<DA"A4nX \XDLfDPLh,fDPL`?fDH H[A\A]A^]@H H[A\A]A^]L@R()HHL@R()HHLOEJDMRA*EJDMRA@Hǃp&f."p=Hs0HIHHH " "F Hpt1=t:HK0HRHHH " "tA tHqHpLuL_HLDDLfM H!@,Hǃp`f.fDABtEJHsHDH{PHHABJ89"R$HHHDHAtMfE@$LHHDAu0H‹BIHLƋBEP8D9rE@(D)I9s DADIABtEJHsHDH{PHHABJ89^R$HHHDHAtGufff.ff.ff.E@$LHHDAu0H‹BIHLƋBEP8D9rE@(D)I9s DADIAUyAUHǃxD`DLhAUfD`DLhAU("gA}gX \XDLQR()HHHR()HHHAgXNXHH AADHDLPADHDLPAUHAWAVAUATSHHHHDLpLwpP!tDDLHVAńuC"E1HD[A\A]A^A_]fD`,DLp HCpDPHRLD`DLhAUR()HHHAfDHDLPADADHDLPADUHATSLeHLHVLYLH^H[A\]Dff.UHg]ff.ff.UHAUATISH tpHcH[HM,I "t=lX1HH[HIH " "H[A\A]]@1Ҿ@UQI "멺 ;#C;4$CH ;#C ;#Cu ~_FH;L,@ILL+M,$H8[A\A]A^A_]@~lE}HAGAEI4$L35W#CIFLHAHCHIFH;DfAv5#CHGH@H}LHL`L35#C11IFLH4AHCHIF5)#CfANL3IFLH@HCH*CjHCfDP0CNHC^fF<t<HI4$L;55"CIGLHIo@HpCHIGH;A1fEGHGH?H}LHL=L5!CI@LLEHHE@HCLEHI@1fAxH;LEHGH?H3LL)IHIl?H}LHLLEH3H}L)HI??L#5"C11ID$LHb?HSCHkID$fA|$H8[A\A]A^A_]HF H~!~sHx0]CeAEH0I4$L;Aƃ5 CAEIGLH>HCHgIGH;DfAG5'!CHGH=H;1HGHB>H}LHLL5CI@LLEHJ>HkCLEHI@H;ADfEX5 CHGH_=L5 CI@LLEH=HCLEHOI@H;ADfEP5B CHGH<H}LHLH;5+CHGIHHEv=HCHIFH;A1fENHGH=H3I0HL)HH<H}LHL#H3H}HL)HH<L#5yC11ID$LH<HCHs CKHC]~HAEHI4$L;Aƃ5-CAEIGLHf<H'CHIGH;DfAG5CHGH;H;1HGH;H}LHLL5CI@LLEH;HCLEH2I@H;DfA@5ACHGH:H}LHLL5*CI@LLEHIr;H#CLEHI@H;1fA@HGLEH:H3I0HL)HH:H}LHLLEH3LHL)HH:L#5kC11ID$LH:HpCHe C=HVCOVHF Ht ~ HF H~L~V~NAEHEAED~DvI4$L+5CIELH:HCHhU5rCIEH;fAEHGH9L+5pCANIELH9HECH IEI4$AfEuL3FLLuH@L,LHL+AM,$AFDiADAFAt/I4$FH;L<@IL L;I4$LI4$AsL}HEHL)LHH1AGHEL`(L荎IGHHl HEf`HuH;FL$@ILL#5CID$LH8HCHID$H;AfEl$UHGH5CH8[A\A]A^A_]7~.AEHEAEI4$L;5CIGLH7HCHIGH;AU5`CfE_HGH7H;1HGHv7L35C1ɺL7HCHIFHAfEVPHxfffPH;I4$FL,@IL,L+I4$LFI4$H;L,@ILL+53CHM,$L#LLL)HHºAFID$H6HCH=ID$H;AU5CCfEL$HGH5L#5,C11ID$LH6HuCHID$H3AHfED$I0L)HH 6L#5C11ID$LH-6HCH C HC~ ;C;C~EuHAFAEI4$L+5aCIELH5HCH IEH;DfAE5CHGH4H;1HGH5I4$H;FL<@ILL;5C1M<$L#1ID$LH5H:CH2 ID$5 CfAD$L#ID$LH4HCH ID$H;ADfE|$51CHGH3L#5 C11ID$LH4HCHm ID$H3AHfEt$I}0L)HH3L#5C11ID$LH!4H*CH C HCE}HAGAEI4$L5{CI@LLEH3HACLEH I@H;ADfEX5CHGH2L5 CI@LLEHI$HU3HCLEHX I@I4$AfEPH;FH@HHUHUHLH}HLL#5 CID$LH2HTCH ID$H;DfAL$HGHP~EuHAFAEI4$L+5CIELHi2HB CHD IEH;DfAu5CHGH1L+5CIELHI$H2H CHIEI4$fAMH;FL,@ILL+5zCM,$L+IELHI$H1Hu CH[IEI4$fAUH;FL,@ILTH;LH;I4$FL,@IL4L+5CM,$L#ID$LH*1H CHID$H;DfAD$HGHHxpcCwAEH0I4$L;Aƃ5yCAEIGLH0H CH IGH;DfAG5CHGH/H;1HGH+0H}LHLiL5C11I@LLEH90H CLEHY I@5*CfA@LI@LLEH/H2 CLEHI@H;DfA@5KCHGH/H}LHLH;54CHGIHHE/H CHsIFH;1fAFHGH/H3I0HL)HH.H}LHL-H3H}HL)HH.L#5C11ID$LH.H CH} CUH CgfP0C6H Cf. CHg CV~JAEHAƃAEI4$L;5CIGLH8.H CHIGH;fAW5CDHGHR-H;1HGH-L5CI@LLEHI$H-H CLEHI@I4$fA@H;FH@HHUlHUHLH}HLL#5C11ID$LHV-HCHID$5JCfAD$L#ID$LH-HLCHID$H;DfAD$5oCHGH+,H3I0HL)HHz,L#5AC11ID$LH,HCH; CHC%`9CHnCHEM$ 8DxpH5 CHHuHuHE1DLELHM}HHAA`ƒyfQ(9qH51 C1HULHMUA fEf% fA`ZC'H0CP0CH"CHxpcCxfE}HAGAEI4$L5 CI@LLEH&+HCLEHI@H;ADfEH5 CHGH;*L5 CI@LLEHI$H*H,CLEHI@I4$fAxH;FH@HHUfHUHLH}HL}L#5 C11ID$LHP*HCHID$fAt$L#51 CID$LH *HfCH2*CHLC CmHCIWLEHC*C=H>C**C'LEHLCRC H>CILEHC*IHC'`ZCHC*IHC*IHC*CHnC`ZCoLEH\CP0CULEHJC C;H C_fA`ZCLEHCP0CLEHCM*CHCF CHC`ZCLEHnCdRCH`C CH C}*CsHC C]HCRCGHC C1HC*CH|C`IHnCRCH`CeH@tt9HEHP Hq 1CHE@Ht2qQHIH+Cw*ClLEHC CRLEHCRC8HCI"HC *C LEHC.CLEHCRCHqCHEHp V@ff.H>t fUHFHAUIHATH)ISHHiUUUUH~Hi` HHMHUHHLHELeHE؀8 u4HuoH@HHFH;HuH)sHH[A\A]]ù` XK RX=AXHI@tpMPHMHPHI ҋPy89I$HHL tM@ff.ff.ff.ff.I$HHLu+H‹BHHI ‹BDY8D9rˋI(D)IA9s At=A8LELI()HHL tIH@PALHLfDUHAWAVAUATISH8; U-DHAAV;DH @HGhHHtwoHSHP;8tq;uWDkEtMAf;DuHA$!" <UDHL8H1H8[A\A]A^A_]fDPuA$!"wũfPpefDA$"8M@UDHLIDŽ$(DEDEHsEFCH@HA&EIH@ID$hHA$D)PA$",fH"<SufMT$HML$PHI ‹Cy89Dq$AMIME$"EFD]E9ftSHHI ҋy89Q()HHL tUff.ff.ff.ff.I$HHLoH‹BHHI ‹BDY8D9rNjI(D)D,D}AAHMI9LBKtmI|$hHHDID$hD}MA$E$A$H IHfDVC9C6EEIDuH]fff.AEIuA$!"X<DLSHAEHD@MlA}fA}LDuH]DLL H}t=D-C*@D9ku*I$(uCHD@HÀ;f;tD5Wb\XMX1ڽ1IDŽ$(ZC+sA9$sfDDq(AA)MIM3Q$HHL`fD<A}ff}Mt$HAM(HMID$PEH8D9EP$AMIIA$"EZ}D9}f}tA},HHftA}IHftA}IHIHtIHH[A\A]A^A_]L)HLI9rA"1fDUHSHHHGhHtǃH]H<@HUHChHuf.UHAVAUATSHD$2D;sHGhDHRH[A\A]A^]G,EAM9MBKtmH{hHHtHChMt$DM)IMM9rÀ"1fD""D""UHAWAVAUAATISHHD~AD;H@HGhDH4HCH@H HEff.ff.ff.ff.ff.HHH9t5oHS8HPuPuփDhHHfPH9uHH[A\A]A^A_]@G4DAI9LBI|$hK4vHUHpHUHt/ID$hMtpL]f.ELL]AD$AlL]D1^fHRL,v$L{HHHM,HA$I$iD8MD4HULk'HEȃ2AA$|uE$ADŽ$|DsA$SMtK}tEID$hE$ID$hH{HE1ɃHEE$ID$hHL9S;uCt It$HSfCCIL$PHHHDN8D9v(L{D)HHHMLy1LLHtYHCI|$hJUI$LUnDE$LAFA$1MA$LNXI$HHeAgX[A\A]A^A_]-ff.UHAUA1ATI1SH1HgH1ɺLE1E1HI$E$ADŽ$|jZI$YtWgCIDŽ$t,H@H;uCtfCHH9uA$He[A\A]]gDIDŽ$He[A\A]]ÐUHAWAVIAUEATMSH<a<!A"LA"DA"A"IHIEHLMELLLPAXZAGLE1u|f.AHA9se;uHKHtCHIFHH4ЋCIVP~89spv$HHHHHS1LHCsAHAGA9rEtIHeL[A\A]A^A_]VHvfDv()HHHE1FtVMFHMNPHI Fy89I()HHLDHAt,fv$HHLDAHAHHI4ADV8D9rŋv(D)D111dINHHEILMLALHHL@ BEfLtY\fff.ff.ff.ff.ff.PD`AA)HTRHf8u9HtI}hADž[LA\A]A^]1 "fCEL9IBH4[I}hHwHtoIEhH|AAEHRHADž[A\A]A^]fAH<@HvIEhH-3L)HLI9iA"E1UHAVAUATISDhD;H@HGhDHHںBL@P1@A$fPHHIt$hHH@Hu5Bf8XHt%(PX)HTRHf8u9pt[HA\A]A^]@C\EL9IBH4[I|$hH|uHt/ID$hHtjXLidtA<$.tLnH(L[A\A]A^A_]A|$tE1ߺMQX;X1deoUHoX1Hcnntn]HB@RUHbn]|nfHGHHHFHt H0HGH7ÐHGHwH7HGHFHHtHpHGHwfDHGH7Hwff.fHnFHVH9wt HG@HGHWfDHHtHPHHtHHoHGff.HGHtHHWHtHBHoDH@ff.HHFH97tHBH9wtHHoÐHH9wuHoHWfff.fHGUHATISHIbHL`HHPHtHHCH[A\]fHCHCH[A\]@ff.UHATISHaHSL`H@HHtHBHCHC[A\]HCHHC[A\]UHSHHHt?HPHXHHtHHoHaHH]fHGfD1ff.UHSHHGHt>HHXHWHtHBHoHIaHH]H1㐐UHAWAAVIAULmATISH(Hh HuMTHLHUtMHUȋB tJqwEuMtA $B H߉E+VEH([A\A]A^A_]fHVI` Hu8THLHZUtHUȋB tJqwEtHUIh HuS}Ht+LH UtKHUȋB tJq=LHTHUȋB tJqHFUI` HuvSHLHTt'HEȋP tPJwMtA$@ HTHu1LLDHTI` HuSHLH)TtHEȃx tPJwHT1g@ff.UHAWIAVIAULmATASH(Hh RHLHSt4HUȋB tD9buH߉E(TEH([A\A]A^A_]fDHTI` L9RHLH[StHUȋB tD9bu@HS1@]ff.GV8r<8r Gv9t&H=GBHH]@f.1DfUHAWAVAUIATISHLp HUMt1L @HHt LsLL]uK(W0.]HHtPL8H}^LHC^1HC\K(LsHC HCIp HL[A\A]A^A_]úUX;X1 ]+^ff.U("HAVAULATI1SHLH0"^H L HHMux@ff.MmMt`AuI]HtH{hu4HE11LLfL ]H[ HtH{htH[ HuMmMuH0"[A\A]A^]UHAWAAVIAUATLeSH8H` HuMOHAGAGAŃELHPtzHUȋBHD8u܃:Eu΋r tNjEt)EDzH߉B QA"H8[A\A]A^A_]HBHPH8[A\A]A^A_]ÐHPIh HuNHLHPt6HUȋBHA8u܃8Eu΋J XfDHhPZHHIp HEHtSIDMmMt@MeHuLZuEL#HLA"I` C D{E0ZIHtXHELeIELy[LIEm[Ae(IEIIEMp 녺UX;X1Z%[ff.<eUHAWAVIAUATISHtCH<tT<<<,fNf<@1Hĸ[A\A]A^A_]@G u2YHwI|$H)DuHvHAD$ HĸH[A\A]A^A_]_'1DXfDG;HvAD$ HHĸ[A\HA]A^A_]vfD1DO+bff>AD$9BL0@;CfA<$ A<$AD$LH莨HpLI|LLH8HHP7LHuH( IfgB9CXffA<$,ID7frftfA<$EuAD$It$ tIt$uAD$HtfH{ tH{uCH|Hĸ[A\A]A^A_]@VC4\AT$N8&8>KAT$9`HBH4H<HĸHH[A\A]A^A_]ZfD B9OA $fAD$H~F u^H9{}cVBA9D$f.OFf/=1f/ fDHsH[@HvHHĸ[A\HA]HA^A_]f.LLHRDKAt$9H5PB<OH=?B,fFffA<$=OBA9|$G93BsLeHL H} H{LHL牅,蠦,ۘB9G&f~9=BBA9D$AT$It$ tIt$u AT$Ht<t){H=BAt$H5BCH{ H{AT$It$ tIt$fAT$HtWW;ؗBpf;V* f.fHIDMtE;tvA<$toLLHlCH@HAD$H@M$AuG1LH4CHkHAD$HkIAuL 9L8CHkHAD$HkI돐HhUHAWAVAUATSHLgMI@ff.M$fA$MA$I\$ A$Hu!1LtRH[ HH{hufHű B9u1HLufIG(H 0t fA$tgMd$ M1H[A\A]A^A_]fA$A$f.~BA9$M$VBA9$uA$HD@Iƀ: oIt$xL职]ff.UHAWAVAAUIATISHHHHtHID$@HHI It$0;uH{0H"fA$I$Fti<FAHD@L,ƀ~uLEq7H{8HtEt LL#H[A\A]A^A_]fEuSLH[A\A]A^A_]%7DHޓBA9$KI$>LH[A\A]A^A_]:f{:H{8HfE]LLDHH==L1@S3HC0H{iv3L1@S3HC8HuUX;XNOfLcMuKfI|$hu.H{0LL9H{8HtAELHD@It9Md$ MfA$M$uBA9$uM$DE1E1UX;XN$O@UHAWIAVAAULmATISH(H LEHX0AHLHBtIHEL9uD9puMtAHUHt@!HBHEH([A\A]A^A_]MtAHEHtHBH(1[A\A]A^A_]f.UHATSHp Ht)IHHtH{L|Luc([A\]@ff.UHATISHp Ht(f.C(tH{L.LtHHuL[A\]f.Lc[LA\]@UHATISHp Ht(f.C(tH{LKtHHuL[A\]f.HC[HLELA\]fff.UHAUATSHHp Ht%IIՐC(tH{L^KtHHuH[A\A]]LkH[A\A]]ÐUHATSHH0HFoHE1>)EEfEEt\HX HuLe(?HEHLHB@tfHEHtuH@HEH0[A\]VHF tHFuVHDH H3|EoH`@H01[A\]DUHAWAVLuAUIATSH8L H}M@I|$@HtLJID$(CXH {LI|$(LEIHt=HXHt4H@HèPA8T$iu@A9D$|H[ HuI$HA$Md$MHHEHp Hu"fDHHtH{LAWЃ}tЃfAGBA9Gt!H8[A\A]A^A_]fEAWEt.}IGHRIT0 HH9t_8u먉H@I AEH@IDH9rAGH]fAOHtA9{|uA@8{iufAG}A?FA;fAO0AGIWIwfDRf hAO; ҉BXA?H BHMHu1HUHA E1tIff.J|H9t*"t!Hu1HULEut LEIA9rEAGfAWIw f1LHcAWIGEDmDIwAGAWHtE̍PwAW f fAGAGIIG HEIH}AGHDHEDUHAWAVIAUIATISH(HtAt$;5wB}A$<pM AL$<HBMHDMHLMLEHL~z}u}t x DHHWI HMtAI@ Ao$Lk(I HC@ID$ChHCxChCl0u{iHsh HڈIX D.H(H[A\A]A^A_]fAD$t^trIT$I\$I0 I@t0A<$AL$tYAT$H߅Bp X1CfD1@AT$I\$ AD$It$H\AD$IT$ tIT$uAD$HT돺pUX;X10B;Cff."x.H Ht'V H@Ht9P4uN8H!u1Ðff."HxEFANH }BHA6eXLjH+L艤11HHfH@@HHHˡ^_HHxHfoA>HEƅ)MANH /}BhDX111W9H}HUHcHEIHKI)L)H9A>0AVH|B1hDX9HH]1H]HXHHH!xizCLpAILh<@L}HMMHI)HML)H<s H5S|BHHL9HHHH@H9r{HHH9k9HLHHE8HEHHN<1L}{2s H5{BHH8HHL/8{LuDc L%{BL8ILuAHA@iA9#HEH}HUII)L)Hw>Mt$HLuI$H9G7HEHHJ!HE,HEHIHPHU@C<\C bL}HEMHI)HEL)HUf.SAHsHuCH|HxDs7HDHHxH9HH9HH{CH|CnLcbCMdUH߉6HHH9uH6HHDDCAtHsACHtfKoX1115H}HULcHEIIL$I)L)H9r>K4HHEHH9H5HEHHLH}SoX15LeLeA$i@HP5HEHLHHA5HfH5LHHE5HEH2IVHH4HDHtH{uCH|DLpLhHEH}HUHH)H)HwANH wBHHLjw%L_11HHfH@@HHH衛XZHe[A\A]A^A_]H3HEHHIVH3HJ#HHEHH9nHy3HEHHLA>H}AFIV IVAFHTDHGjHOq/HOp#GxHLHGjHwqHwpGxHtAFIN INAFHLAFIN SINGAFHL9AFIN INAFHLH2HEHtjHSHH 2HH1HEHHtBIT$H1H}UX;X123 ܺպ@ff.UAIɺHHATSLHLHjj$H趛11fH@@HHLHXZHe[A\]@UfHAWAVAAUIATISHXH )EHEEfbE:HEDufoEHE1})EEfEEtvI$X HuL}$HEHLH%HEHtuH!&H]HyKHX[A\A]A^A_]@EHutHuuEHtI$ aEYDLL6SX}HX[A\A]A^A_]H%Hu1LHHZA$" UUX;X1/0DUfHAWAVAAUIATISHXH )EHEE`E:HEDufoEHE1})EEfEEtvI$X HuL}"HEHLH$HEHtuH$H]H@tKHX[A\A]A^A_]@EHutHuuEHtI$ _EYDLL+_X@HX[A\A]A^A_]H#Hu1LHHZA$" U(UX;X1:.E/DUfHAWAVAAUIATISHXH )EHEE&_E:HEDufoEHE1})EEfEEtvI$X HuL}Y!HEHLHs"HEHtuH"H]HtKHX[A\A]A^A_]@EHutHuuEHtI$ O^EYDLL6eX=HX[A\A]A^A_]HH"Hu1LzHHZA$" U9UX;X1,-DUHAWAVAUATISHHh*>DnL-oBI$ fLHDž)Dsƅ`]XLLDLHIH A tBHe[A\A]A^A_]FLn nLnbFMlUH("1Lxf-11HHI$ LHqGUDXLHLI1*LL!+HELjLLL=L%11fH@@IHLLnLxXZIzHHtwԍLxIzH*LxA CLxH @IL$L4*LxJ #IBHEu!ff.HHH9mHSoHPSt3@t.@t8@t@t @ t@ uHSHDtu@ tf1LLIHA$" LUX;X1)*ff.UF~HD@HLt*N,H lBHE111hdX軎@FHN!tHN űF(HLfUHAVAUATISH@F~HD@L4Dn,L-5lB1LHHfA>LmtafDHH kBL@@H@I:tzBHkBHE1H1PLáLHuzIXZfA>ujlBA9Fu^LLy8uPHH tHHuPHLurHB @tHBuRHDhHe[A\A]A^]fDFLn!Ln F(MlI$p M$@ Ht!C(tH{L't/HHuLL꾠 X1{(1A$" `LsDUHSHH>t7vH5}jBH yXC1HCfCH]FtFHs tHsuCHtfUHAWAVAUIATISMH8B/kBu99vjBlMAE<KLLIH$fA?AG9,jBR}tA@A"tAEA9sAE|$AGfAnfnH@fbH4ŐfM.'HH[ DHLHRL<L%EJ;fHǂƂ I HEHH0HLsHC`I@ HC(H8H[A\A]A^A_]fDA|$fA|$AD$<mAD$M|$!t"M|$ uAD$(M|@ff.I LVIHdAD$0<t< AD$2fA|$0u#iBA9D$DAD$It$0LH@H-fA<$"A$MDfA?AGL9hBMHULLEIHA?EGAOH /gBIH X1$@ff.1ifA|$fA<$9]gBAfAAG<AGMw!tMw uAG(MtfI LTHiHEAD$LIL$HM|$HLHMH@HHU+HUHM5fBLMtLÄHeBLUH=IFI fAFIH LUSI~?fA<$LUA$M<<pAG4fA?EMfDLL9fB9fBL~HLMAuIwL@AL$,M|$9b9eB ;fB_AG,IwRA"JH}#eBA9D$A?AWAwH5dBLAWA<AwH5VdB6eXLaA@AGIO IOAGHLDAGIw uIwiAGHt[DA|$0A#A"!<GE|$,L=cBgA"t%<AwH5kcBbXLvAWA?AwH5DcBfXLOA"A?AWAwH5cB3gXLAkDA<$ED$+AL$H bBIH 0 X11ۿy @<AG,HbBIDcBA9D$AD$M|$AGIw IwAGHtAGIw IwAGHt7cBA9D$A$M<:AG9*cBEMAGIw XIwLAGHt>A<$ED$wAL$H aBLP X181AGIw IIw=AGHt/.EGAOH &aBIH 0 X11ۿoA?EGAOH `BL X112ILUTLUHY`BAD$IL$ IL$AD$HL aBA9O]EGIO .IO"AGHLAD$<vfA|$.9AD$IL$ IL$uAD$HLfAGIO IOAGHLUX;X1A|$A|$t,H _BIH X11A)AD$IL$!tIL$ uAD$(HLUfHATASHHPH )EHEEMDefoEEHE)EHE1}EfEEtXHX HuLeLHEHLHftbHEHtuHHEHP[A\]EHutHuuEHtH `LExHHP1[A\]fff.UHAWIAVAAUAATISH设A t31ېI|I9t"tDDLA H9rH[A\A]A^A_]Ðff.UHAWIAVIAUDATDISH*E̅uTA 1ۅt:fDI|I9t""tDLLu3A H9rMtA$EH[A\A]A^A_]DEUHAWIAVAAUATISH8Hh HuMc HHEA}HEHuHhHUȋB trNvMBAB H߉EEA$ '1ufDnHuL sHMȋA tQrvMALAA EHEA$ H9MtM9tA"tIh HuE IŋE^HuLZ *HMȋA tQrwMgLE EH8[A\A]A^A_]H A$ ff.MtAH81[A\A]A^A_]HEHuH qHUȋB tJwMXH߉E EH8[A\A]A^A_]@L I` Hu0 IHuLQ NHMȋA tQrZDL I` Hu IHuL IHMȋA tQr He I$` Hu HHuH HHUȋB tJIHuL HMȋA HuH` 1HUȋB H I$` Hu HHuH HUȋB tJL Ih Hu IHuL HMȋA tQrL8 Ih Huh IHuL HMȋA tQrH I$h Hu HHuH= HUȋB tJH I$h HuHHuH HUȋB tJLU I` HuIHuL [HEȋH tPvMtPA@ LE EL I` HuIHuL@  HMȋA TH I$` HuHHuH\HUȋB Ln I` HuIHuLtxHEȋP tPH' I$` HuVHHuHw\HEȃx tPvMPA@ LA$ LIh HuIHuLHMȋA HvI$` HuHHuHHEȃx tPKы@ H#I$h HuRHHuHstPHUȋB LI` HuIHuL7HEȃx HI$` HuHHuHHEȃx @ff.UHAWIAVAUAATISHAƅuKA 1ۅt>fff.I|I9t"tDL育u&A H9rHD[A\A]A^A_]DAUHAWAVAUATSHHUV,f;FUBH}E1;UBIu~AAVI^E1E1E0fHMH}AHEELsAVAHA9s@;usTB9CuHMH}HEE1LAA/AVHA9rH[A\A]A^A_]UHATSL Mtqfff.A$uMI\$A$Ht(ff.I|$(HsxLH[ HuI|$0uL覽Md$Mu[A\]FeUHAUIATE1SHH^DiX< w H XD激 X1<<<tC AHE;eDCK<uC4nXcXHE@s1(5X +;uSsCujH;RBSX1wfCkHsmX1<Lff.shX1H5QB#fGX1H[A\A]]f.UHAWAVDAUATSHHuHUMHUuDHAƄ$H6L11fInHEA$IHH fl1 Xƅ)EH}HULcHEHIwH)H)H9rEJ9HHEHL9HHHHEHHH}I$ XHH 1L}03XLL}AHuHHDE111 tI$0H}L9tRI$"1$L X1A$ +HHEHHt=HLHQHH UX;X1tff.UHAWAVIHAUIATSHHxIEHHIT$LH9;~H1HIIHt;L;H3LLhL H[A\A]A^A_]@LH] 1H.pl}IHuLH1붐mX6IHZHLIHItzHHt?LH IuH+HCLUX;X1xff.UHAWAVIAUIATSHHHDAjHII@ H_AI@PXHLMII11LbMI11LIF‹^DBtRAHAH+3ILHHuVXL.DBAHBAHAIuI@tIH HHu>LcMtfH{(It$xH_Md$ MuH{0uHFH[HuIIAID0AIAA"t AIAL0AD Ј0EHeHI@ Et@3ILHjeHI@ LLHHH[A\A]A^A_]Ip HHI @M$$MtwI\$LHuI@ XHDžoILHdHI@ F0HH\HLHHHLHBHHÀb(HBHBIp I@ AƇH11 XDAIHHH fHn1HEflƅ)EH}HULcHEDHIt$H)H)H9rTJ!HHH9HHHEDHHHEHCHH}I XDHH 1nLe03XLLeA$HuHHDE111rDtI0H}HH9tDDI"IH|L X1A ZHHDHExHEHHtIHHHQeHDHUX;X1ff.UHAWAVAUATIHpXSHHEHHI$ LuLmLh0Hǀh0I$ 1,LHLHE HuHyHHrI$ Lh0H[A\A]A^A_]H1[A\A]A^A_]UHAWIAVAUIkXATLSHAI HL 0I HLLuserMcAH$H1Ҿ[XHIiƈH@HI HH@HuHH8I@ LbIHI 11LH@0HAI@MIݴuAIAHI ILH@0H_I H@0H:MiLHHDLH0IaI>IHL[A\A]A^A_]ÐLHHxI)IHuIT$HHA>~[L{HLH1LIHHLMp Mu!@M6MtI~L\uAf(1HHHHc%=@LLL诘pXHIHHMP HƿoB诒=t 11HLHLHLDHILiAF(tI~LuM6Mu AA=f.LHxH\IHHLHRA.plLLLIVLNfI ILH@0H\M~@I LH@0Hǀ\DmXNIHHHH HLHtIHLHHsH4LL@4HL1LIH?1LIH)HL1L.plIH1LIHHLL1L.pro@hIH1LRIHHL1LH.prologH IHq1L IH[HL1Lf.p@IH-1LIHHL{1Lf.P@HILME1JLLẵ UX;X1ff.UHAWAVAUATSHHH"Hp "HLP @HL1IHLPLI}HuIE H9E~HHM}Lp Mt'@AF(tI~L}M6MuLL QXI1MmLLDupMLLHL1LLLH)HH"HH"HĘ[A\A]A^A_]HHL|@I~HID>UHAWAVIAUATISHHHHF< Dn,L-4B<u ~ƅH Lq"HtH0BILHLA/I|UHHI9tef:u_B; 1BtT:uBLj tLjuBMl뛐A}iH@ztYfH LHt\H9 1t*HH ff.H9BSHH9u HD7f.eXLCcXL.6iXLiXLgXLhXL/jXLjXLJmXLtioXL_A@piM>MhLLat[IAF2Mn9Mn8AF@MlLp X1Ly1IFHzHIHIvLfHnHfl)H11foMkYX/ƅHDžAD1)SHHLLcIIJLI)M)L9rKHKHHH9HHUHHHJ<9HI/kYX13HHHHHtEHL$HIHH9tfoHDž)03X봺UX;X1HiHHtHIWHZH 뭺ƅUHAVAUHUATISH5AńtBLuMt9I Ht-ft/HKhHLLEH[HuHD[A\A]A^]@H[HuHD[A\A]A^]@ff.UHAWAVHhIAUATSHHLhAMCLpHD@Hf;t4cHHu8f8Hd+B9CULH7f8uP;*Bt;*BuPHTRH P4u@txuP,;*BS;*Bmyco@0HuLHX)EHP@HUH@PEHHHXHuLA,HLE蘪P !*B9Ho@HuL)EHP(HUH@8EhHHt0HHhLL1@@PE1HĈD[A\A]A^A_]PYPx,9=~)Bu f9t(9t#=k)B9x,+f9t 9o@0HuLHX)EHP@HUH@PE藙HXHuHHPALHLELUHAUIATIpXSLHHt+HLH݇HH[A\A]]DL⾘ X1H1[A\A]]@ff.UHAVAUIATSH]HHh IfH}GHLuLIh I` I H}HLluLI` M MM fff.IX It$hI\$Ht)DHC H{xID$~HHI\$HufI|$8AD$(I|$0I|$HHtwlFI|$HBLLGL/M M_I HtHGI I HuI8 HtIX I0 kJIp HuADHMt*LH{L#HtH{HuHMuI LH0vHL[A\A]A^]RfUHAWAVIAUATSH"HzHL IHp HEHIfDM?MMgHLmuM@ L}@M?MMgHL=uMH 11` SHA I A0A"ADž A0A `H߾ufX XIh A M(t>@HHH3HCHIh H2HB<H;u11` SL1p SI` LIX JI0 H[CXLLJIHI@HL MtgA$uMI\$A$Ht(ff.I|$(HsxLH[ HuI|$0uLƍMd$MuLGIH I0 A" zMqaNXL_OXLMaNXLۯOXLɯ]XL路aNXLEOXL3]XL!Ix I0L6{HL[A\A]A^A_]@0IHHEHIHIGAg(IGIIGMp L}0^HHtxHEHHUHHUHHBHUIĀb(HBHBIp LE1*A UX;X1JU/ 㺆UHATIHSL [A\]ÐU@ƾ1)HAUATISHxtdHrLEkLpfpnLt Hx[A\A]]É@ff.fU1 1HAVAULpIATLASHpH@ƾ)fW1TtoLHrfprLZnL[t Eu UHp[A\A]A^]É/@ff.fUҸf)ЉoXHAVAAULmATLeSHHpEE1HLEEЉE1HMLLHuyH]HthLm@S s{BAăt=LAESHs D*u5D=H[(HuH]HhHpA[DA\A]A^]fH}H|EwRJ<;HPL}DuynD}ċUA)DNfDndHD H@ DXE1H¿1ƃH@^fDHUHATSHHH@ul>ugF;bBtt;BHutPHHuIHLP若A$"Lu ff.1H[A\]D1D~uUHAUIATSHHFIHt 8.IH;AAuA DcHA tAt@{HuD#EtAJu A(t/fDH[A\A]]ÀxmAJt^AH teFXI1AƅHDEuAH t@XIA H@ ~پXH1IA H@ }پ(XH1fUYUX;X1HUUX;X1HfqUHAWIAVAUATSH8HUHH}H=D2LbHULeMDH}kHUHtBAsH}t(HaH)D4M/H8D[A\A]A^A_]@HM uEɐAFD vDAxHUH}ȾxAHELh\M/HEE1fAxtAU@AuA0t&ff.IA$IL0tMhCE1<@ff.ff.0IHF4C<vMhR@߀UuxHEx 8AUHUH}ȾzLmAHEHuA}\tHEIAzfDA\eA"[A'QA GA =HUH}ȾofD\~f.HUHAVAUIATSHHHOW H)H)IHIHLGp9PHRH4)t8HHH)H@HHHH|HIHOfH[HHHu BHCCH+ BHtnHCEfCIKd@HD[A\A]A^]ÐDtRAAFH4@HHHt5IHODp @`CH B|DUHAWAVAAUAATSHHhLAaDKIAIIAE1fAyHEDAAjESLuE1M9VAIA9rAA@LeM̐A?u\AO|hX1H}1AOHuHߺ\DAG=AW~AG>AD$AIA9rDKMLeAAE1DmL}LME{fDEuuA?u]AO|hX1H}AO1HuHUAG=eAW~AG>HE@AIA9sM9uLMDEaD0AQeLEHBHRLxD=BDeHEILHED}?ODgEfOA9ufOHEIA$_uAD$;H}fMEE1E1MfN4;LLqu }LAM|B<;uH}M1H}E1E1fMuN<3LL!u }[LAMtB<3uˋuH}MGNfOHH9}LxDeEtIE1MϨ@}HGO P9oH@WfH HDH@HHh[A\A]A^A_]fDf`\fORfH tAE;wdg@DL$A$>*AE;w?I+H}MBnzuH}MtGNB^fփ>WN fOL}E1M9AIA9rAEADDIAč@H4@HMHHHD` @PV@fOfDA$~HiB<_H0qBA9G,u AHD H@ tA$~EHBHX1MHLMA>uOANAvH}H5B-H}D=AFAV~AF>AD$AIA9rDKMIHAAcE1HDmLuDLMEIcEucA>uMANAv1LH5BUAF=AVA~AFA>HE@I9sM9uLMLHHD H@ rDhXH1XƃHHh[A\A]A^A_]fBA9A,AA4HUHD@L$1A<$ LD1LMLMAADKǃ0LD8UHAWAVAUIATSHHHf;,<CLs1EfUE:LYIH%D%BEf}DeL%[BI1ҹLH;CH{ t H{X;ICL9 oH}Jt# )EHCHESL)XCL)DCD)Ef}H] B9K<SHsf>>tTDfCHD@H~LH}HEͼL}BD%f}DeLFLf LfFMdF93BhL@HH[A\A]A^A_]ÐSLt L4XnefSMtCH|W;ImC‰҃ftUuQHCSH@H)I9tKofAnfp)EHCfoHE~CfffECDCI9HHEBEL}D9%BL8L@A9EqL;cto)EHCHEHCLHEHCL)HELEUHuHHECr@UAHAWAVAUATSHhHqA9I^DE1AE1AL@:uVDRfEtKDXA991DfJIq9s%ff.HRHTzv9rE4DƺHyD9'fL4@IN<7AG]A?SAOfEDE989u/EWAAGfA f fA4fA`fDAAw AMOAoLMEA)EADAE9_UAAAfA9MLL)IxHi9L4RIJ7rf ׃fRDDJHRDEJHDUI)MIKtK<LM!LMMDUDEKtHEDEfoEHFDAGFIFHfAJ2xu9A9Xu.PHTRHЋPtHRHЀ8ufHHH9uHhD[A\A]A^A_]AEtWA9AEu EEDREEDAf IA>fD9ryfD9AfAWHTRI4HI+HHiҫ9҃tfu8AuCfA;O sH@߃^fDUHATIH~SHzHtHLHw[A\]9fUHATISHHH9HHFѵuL9r1I9[A\]fD[A\]DÐ?usGtkUHAUATSHHu_GLl 1CfCC?u GШ twLIIHv>aACHH[A\A]]@HGLouGMlfDH{ HLfBD# Dcf.LuHHHCfff.UHAUATSHH?GtIH H;ICI9oI|$ Jt+ A$HCID$SL)躭CL)AD CD)AD$HL[A\A]]CHHD@H[A\A]]fH{dCH|WC‰҃t~fF>HCSH@H)I9t2oA$HCID$CDAD$CD)AD$LDHI$AAD$)f.L;ktoA$HCID$HCLID$HCL)ID$ff.UHAWAVIAUATSH~pu ~0It,AH &AƆHHĈ[A\A]A^A_]@DfHAfAt~HtfAuA9F\uAqDH5mALhHHx_HxHëHxLhHI HHLx觫ADAELxfxyA}fA}LLhIYH聫LhDžxDž`DždIA H@ f^پ8XH10A}xA}LLhIYHLhDžxDž`DždLhD\Rf.;CHuHQf8HHuHD#fAuC9AufA}yA}uLLhIYHLhDžxDž`Džd*@A}f2A}'LLhIYHǩLhDžxDž`DždDD`L%AL̩II0IHLLH&CD=1LEIHU{͎dwEHhILxH tBpt*IxLH 0HhH tL跨7fAH tFL螨-fPtLxL`DxL` fIE H@ v[DᾰXH1?DLhD\fAC9ALpH:AHHh3LpII}Lp艧IHHhLH{C,1HUEIL{#`LpEAI ILLpx`Lp0Et,IAI L拕xH 0,d@LHĈ[A\A]A^A_]LhD\fAuIA9CNCHCLkHh@HPDx@LdAH 'LefdEAH 6IA H@ LYپXH1AH IA H@ YپXH1ӦoXLLx:LxoXLLx"+nXLLxCLLhIYHPLhDžxDž`DždLhD\G;C%HuHf8t8'HHu{HD#fAuRA9CuD`L%ALIIPIHLLHFCD=1LEIHU{EHhILxH ?tCpt*IxLH 0HhH tLAH t>LƣPttZLxL` DDxL` fIE H@ VDᾰXH1oDHPDx@LdIA H@ YVپXH1#HC DkHh LLhIYHLhDžxDž`DždHSCDkHDHhAH IA H@ UپXH1r]LLhIYHJLhDžxDž`DždAH IA H@ (UپXH1sx1f?tfD .A9OuGHD@Hǀ8 tf8u1ҋ5A9pHDfD1DIIHItIHtDfDff.ff.LHH)H)LHtLuHL)1fUHAVAUATSHHfHGIIHHHvYHz蘠IHt7HxLL葠CD%MeIEfKLkCDc[A\A]A^]H OBD# Dc[A\A]A^]HfHGHAG[A\A]A^]fff.UHAVAUATSHHu=HfHGH{AG[A\A]A^]f.fHGIIHHHzeIHtHxLL^CD%MeIEfKLkCDc[A\A]A^]fHGHwHËAsiff.HUfHATISHH GHGHG謞BD# Dc[A\]fff.HfWH195Aw fGHHGHGDHHGHHwfDHHGHHwfDHHGHHwfDfHGwOWÐfHGH HHHGH1HwHÐH HGH1HwHÐH HGH1HwHÐHtYHvH4fff.HH9t7Ptt.t9t t u1HPHHH9utu@ tπ tf.UHvHATL$SHff.HL9ttCttn #HCH(uHCHpHxHCHxIH{HHCH(uHCHpHx"HCHxeH{HXCL9uI<$FI$AD$AD$H[A\A]]ÐH@HCH(1  HCH(HCHxTVH{˙HCH(HCHx褙HCHx藙H{莙fDHCH(HCHxH{[1fC wHCH(hHCHpH@H HP0@UHSHHfHnHflHHH9t)E՘foEHfIƃ0HǃЖƃHHǃ@Ho ؖH]fHUHAVAUATISI$fHnflHHH9t)EfoEIDŽ$ЖI$AƄ$A$M$MAEI]HD@Mtff.HL9t_Ct PHCH(uHCHpHxfDI}?IEI$AEAEHL[A\A]A^]fDH@HCH(1H{ؖ HCH( HCHx,SH{裖HCH(HCHxH{s1fCHCH(HCHxIfUHAWAVIAUATSHHDHI9II虔H;.Iuh{.ub{/u\LIUL}K|/I9u aHI9tW?/uI9tMHIT$HIHL[A\A]A^A_]H߾/ÕLHufL벺UX;X1EPJ>UHAWAVAUIATSHH"f>FH)AHЀ8:uWx-uQxuK{uE{u?Dc,LIf{uo;5Aug{0CDH4X1誓AƅHHe[A\A]A^A_]9AtIgAJI]XfchOXLC詒alXL蔒u{~fDlXLL{0ou {dXLT,{DAgXL5u { `XLu { gXLw{mC0<f{0<C2Lc9tLc8uC@MdI"{f{HLcHrL@x{R{0HoC)HC(HHC8; KHʀ:/uz/uzu HIHEH\f.LH`f8IAA9D$LL8HuHtHHA@HЀ8/ 0/ux/u xoNAH  AƅH3D{I"RXL{f{0C0 <E C2Hs9tHs8uC@HtIH@ I11HH螖HHE o\XLLsot{bXL^tjWlXLMtYOXL<{PC0<{1IHeL[A\A]A^A_]e@CS0tC2IL<He[A\A]A^A_]S{0{1}C4H@M$A$f=fYYAA9D$HE1ƅ8L0H("1薐11LHIHIH諲I蹏IH{0F{DH=A脏A~I$C1L0AD$A$A<(t#ufff.<(t CHu<(LH-LAD8;I4$M$IDAD$ IAD$#I\$HX0xA|$ AT$I4$LI[f{0C0<E C2Hs9tHs8uC@HtIH@ I1ɺHH蘓HIH@ HP @H݌E OOXLTtvCXLCue{u_f{0t {0ILic@{0sDH5AHeؿE`X1[A\A]A^A_]j^XL͋u { XXL貋u {A<$ouA|$puA|$u {f{0A<G <fDILH8BL8/8/ux/uxuADXL0dbXL^XLފdAA9GuIL8LL^A"AHAGH@MH8HA0IW0tSL5AxAfI4A9/IG9xiAO2tσIG88/HfDDrAE fzt Az0oBHJ8)HB(H:0BHA8/ux/uxu A0+_XLH(H(u.Ar,H5AL80LrY6SXLH(虈H(A$ r,H5.AL80LW<Aw,L.C0< f{0<NC2Lc9tLc8uC@MdIL.HAHIA?AGHA8,AH I0KHeL⾰X[A\1A]A^A_]AO@HD8/.rHB @;HB.rHD0!CD;Au4 DAWDHAAOPII`IZAG;AukAudAt] 6AA9O,uQA0uAG2IW9tIW8uAG@HTAH oHE AƅHqA?gA\;APAAW,HAIIAO8He[A\A]A^A_]釨E <8sDH5AE3gXLH(NYlXL96eXL˅IH:H(Htu Hxz r,H54AL80LWKHS 'HSKHT  E <EsDH5ARC2Hs9Hs8C@HtAAw,H5AIH8BHr!Hr B(Ht^XL茄6eXLwtz6SXLf{=C2Hs9KHs8?C@Ht2AWIG HIG;AWHD-{6SXL+_XL̓bA9CD:dA?'AGH`L8IuH -A@HȀ8/u5xu/A~t=LH^IfA?u9AA9Gu뢀8/uӀx/ùxtfAV0fA~t 0A~0Iv88/8ux/uxu F8AoF6eXLH()IF(H8菂H(dbXLH(l3gXLWYlXLB6SXL-H( 0Av,HI8QI"AH{AH xIA H@ P5پXH1CI1H=HI_E1MAH H%@  D<rDcDL%A~A Hھ:X藂spppHLAH {IA H@ S4پHXH1F<gDcDL%=AsIL衲HsILyHIH9t q HDIAH I0KL4X1jILHYIH9t q HDf{HHHL`(HLHHf8HZbA9CtJBHr!Hr B(HtIoXLLH@ 1~LHID.@DŽ@@tCHu$;ff.ff.L9tPH@ƀ.@u.IoXLLH@ 1X~L HID@ǀ.@@tAHu"9Dff.ff.L9tPH@ƀ.@u.{0{1ZAA9D$E1ƅ8L02@LHf8IJAA9D$9H`L8IuxtfxnxBA~uA~*mXH=A4}uAFIv(Mv LH0OAGIw!Iw AG(Ht{H{0DcDL5mA(SXML|[\mXLH|ajXHu|wjXH`|I  o Aؖ{HsS\HͿAIIKhHe[A\A]A^A_]H AxnXHH({u3A~AF,H(H<kX{ƅ8fA~;H A~ƅ8-AI  {I  \AFJI~QI~PAFXH|AFbIViIVhyAFpHTkIN AF(Av,Ltƅ8rUX;X1tu VXLsTL5AI8LDAFMF!MF AF(MDvAH AIA H@ 'H(IztxJ,H AH8HH VSD0 X1tXZAH I0KL⾈X1vtBHJ!tHJ zB(HLmIǀ xAH VIA H@ .&A~IAN,H -AIHH WSD8I IE H@ %;HtNSHҵAEX1sAFIv!Iv AF(HtCHS tHSuCHTInAFIN!&IN AF(HL UHAWAVAUATISHHLJ>Mc uH=AFH8:9G/ EtAHD[A\A]A^A_]LHUDHEufA<$Lh<uPA<uSAHq tHquAHtHHMaHMȃAADyHHLp,fHfAAAD 򈐌$Pp Ptǃ$fx-x~F,L4A>iuuA~funA~ug~IcA AE McCƄ/ CƄ/![fD^AA9D$IL$}D%mXLSou7A|$u/C/!uC/ YCƄ/  mXL ou?A|$C/!uC/ tCƄ/ CƄ/!fD{oXLnzA|$nAE lH Hǃ \XƃHG@H kHǃAXƃH@ A9HTRHА: J5A9; Af: ղA9JHD H@ V!DXH14nƃHg@+`   HAH(HAHMHpH@H HP0]^HMHAHx|mHMHyomHMrfDHD H@ v DXH1TmdHv0HsHƋ  Hc@ !VHAH(HyHMlHM@ HAH(HAHMHx)HMHylHMHAH(wHAHMHx蚾HMHyMlHMPIt$0H臟HHc @ !uHAH( HAHMHxkHMHAHx^9r,q ^ HAH(HAHMHpHxJ fHtHuf.@ff.UHATSHt`<<t<HDH[A\]fD1CHDH[A\]fDCH@IĀ{u@ff.CfuC;At);At!;At;At;Au)fLcLDHtHa1H[A\]fDUHAUATASHHHGO P9s9H@fWHHDH@D`HH[A\A]]fDlIAAEH4@HiHHtHDh @PWUHAVAUATISHH?H}M$LmA$HHujA$JI$I$LiHI$A$HI$H} u A$ LH}!ljxiuH}<%uI$HA$I ?/@* u A$ HWHU؀I$HA$JI$HLhHI$A$HI$H}؀?tbA$I tU ` HH[A\A]A^]H* -A@/HA$IA$H}؃<vI$1O@A$ Ycf.I$H1@ff.HHH}t&< uA$ ztHzH}fD< tA$JxYI$HL6gHt@I$A$HI$H}9fD HA$IH}kIDŽ$03X03XH[HA\A]A^]A$H tAƄ$H1H[HA\A]A^]I$A$ H@ vپ(XH1@gHGfff.ff. tHEHHu A$ Hf.UHAWIAVAUATSH(L1HuHMA>@IE1HE0@DAIȖIIЖII)L)HwFHMID$I$IЖH9HdIHHLIȖA6MfHIȖIȖA~@_Lf.IH8_tIL8I@DD)Dj0@MEAD$0 II03XH}HHD1躖IIfHnflH9t)EdfoEHEAƇILJЖAL H([A\A]A^A_]@u0@JMF@ME1 uE0 A!AH HEL0AƇHH([A\A]A^A_]hEuAFMhI0@_fDHbIHHtqHuIT$bHMAD$eAhI[IA H@ پXXH1cj UX;X1bcD?\HtH8\ux tUHAWAVAUATSHxHuUHIH8LHEfInfl)p1A$HfopfA$LIDŽ$ЖAƄ$AƄ$ADŽ$ADŽ$@A$HEHHF ; A$K A$JE@tA$JE<-!A$JA$J"<>%H!@HHCHE A$JA$@"H]8H5ADžA  E9$@ZA A\I$ȖI$I$ЖII)L)HwCIFII$ЖI9H`I$HHLI$ȖD,HI$ȖI$ȖHE8-A$@A$JfI$HUxA$HAlA fDH]I$HHIVL]H IFHEE>}1H]IDŽ$fA$.D}Iƒ0 00ALuLHEHE80tHM LLHEA$Ht .HuLЇ;"HEHHEHEI$LLuAƄ$AF<.t E\tILuLLuAHEHxH}AD4\uA(gHE}t I$jI$ȖH)I$HHpI$ЖII)L)H9rNJ2I$ЖHI9{HH9[I$HHJ<1HUI$ȖH)HZHEH)I$ȖI$ȖH}I$HULI$H}(_wDI$A$ H@ پXH1[$fA~'A~@hgh'\I$11Ҿ03X?HEP'Nx'DHPHUP\HPHUDpA-AVHPA HUx'u;LpLuP.@0 vH]ht ~A$H t{IDŽ$vgXH]AƄ$H.HHEPA$gA$JWE1.LuADŽ$@A$JI$A$ H@  پ(XH1YNHNу߀E4@0 -AƄ$1yYH}HuFZ,t 1hOYh8" EtfW! A$[HELHEHERI$H[(u {{ IA}]u A}pXLMW{pXL8WfI$ȖH9t$A}tH)H1A|>HH9uI$11L<I$A$JH qpXVfA$H IDŽ$~9XHEAƄ$HI$A$H CIDŽ$9XHEAƄ$HI$cAFI Ѓ0 L PՁ+ < =A~AVA;HPLPb)oxmHHMLLHE%HuLY;O HELHHEHEI$<AƄ$HEHEA$H 2I$A$ H@ پXH1uVI$A$ H@ tپXH1>VI$'tH}A$HyAƄ$EEHEHcHEI$ I$HHuLzA0uljhEahuI$A$ H@ پ XH1tUA$H IDŽ$KXH]AƄ$H HSI$H HI$HxL EtI$@P fA$ M$ЖI$A$JI$Ȗf%H)fA$JLH)Hw@LsHM$ЖI9HPSI$HH M$ЖI$ȖIw;IDŽ$ЖI9SI$HH I$Ȗ$|G|f7I$ȖHPI$Ȗ@Hlj!X_L}L4H}H}I$}Z)I 'xA$IHH?RI$HHJ<1I$ȖXHI$ȖI$ȖH=]}SH ]R H}Ã% A$y - H=F]'SH R H^ _ LÅ I$ȖI$I$ЖII)L)H INII$ЖI9HPI$H IVLHPHfDL}PfHPI$HH, LI$ȖHI$ȖI$ȖH}ÉK]_tt{L I$ȖI$I$ЖII)L)HwIFII$ЖI9WHOI$HH IVLOHCI$03XHHDA$A$xUttA$Ku A$JH}I$HUL褃Qx'A$ sI$11Ҿ03X5U_tI$03XI$HHD114nA$K_A$JQ{A03XHHMLLHEHuLBz;8H|NI$H HI$HxLEtI$P fA$ HHMLLHE|HuLy;WHMI$HnM UX;X%N0OA$H IDŽ$9XHEAƄ$HI${I$A$ H@ پ(XH1NDI$Жw3IDŽ$ЖI9EJMI$HHI$ЖI$Ȗw;IDŽ$ЖI9uMI$HHI$Ȗ[]fI$ȖHPI$Ȗ@A$H%A$HHEI$HuLI$Hc UX;XLM>LI$HH$A$GA$H I$A$ H@ _پXH1)MHPHUPI$A$ H@ I$AؾXXH1LHCH/LHEHHt 8I$ȖI$I$ЖII)L)HwGINII$ЖI96HH!KI$HHJ<1I$Ȗ:HI$ȖI$ȖI$HI$110A$J A$JHEI$HlJI$HHRHSL\JH0A$H IDŽ$OXH]AƄ$H.{iI~HuH}LHHE8\HH9AƄ$HEtHI$HE'HII$H2IVLHIHtoII$HHKA${- UX;X1IJA$H IDŽ$vgXAƄ$H03XI,HI$HHA$[]I$I$ȖI$ЖH)H)Hw8HSHI$ЖI9HHI$HHkI$ЖI$Ȗw;IDŽ$ЖI9A$ DI$HHA$ HCI$HHtHSLCHsI$DLwI$H7 UX;XCD  I$Lw'03X fUHAWAVIAUATASHUHD@~@(EtEƅ}EEƅDžxEpDUDLDAAHEAHt @ 8@E@EKMMMp A}.A}I,B<Ѓ<]@XDhL`|NDhXM|_s uAJ`A4u I8t2 :IdžXAƆHAdž<Idž4IpP'@ff.1LvuAHEIX9X.A,1LzAHIAI@tAJ/I1/AH,AI@tAJ`aAIAKt IdžAHAHEE$EA A$AIAIAM[ { AJ  {7A},ID%2AGW Hx9PH@f1HDAW1LH@@D`fDAIA8AdžD{AH EA(EHĈ[A\A]A^A_]fE$EuA A$AIAIAJutMMt A}|w U }t EMAItLMA]uAyt)uAyt }u'Ayu AH pNX Mt;A)u Ay]u Ay}uAyoAJƒAJtI8((AE M1M1A}!A}I<;HRHAdž@1AJJƅIE1EMHύpEMtAM)uAM!ƅ}AIGw H9jH@fOLdA$ID$AD$AA$AMfAT$f% fAD$EA$<AE<< AJ;EtIHt 8.ht"A$A4A<A8BAD$AKoI03XIHHD$mAD$B#@1AHAIAIVAJ OAM(u A} [WA}LID%AGO Px9 H@fWHDALH@@D`fDAHA<EHAdžD[f%AfAH_AH AHAAH%D AHxIHHRH|@)ȉGAEEs@~ <= IHUDMMHfA@w  }}]EVJAH QFXf.A@q }WAJa AH uIA H@ mIAؾXH03XHHD1#:jfDLU-HUEpg AIy };(P ff.}AE}I8({ 1Ҁ}zfAJ MUAM@AJ1ҋEHMHIEM ƅE1@(A}A41LAIAdžD(.AHt+xIHHRHTBI@)BAHEEƅJ}E DA$AI1AJ~D}:}  f.IID$EEE@DdvUAAD$H4@H36HHIUD` @HTfD~}}  ,u A} AIEA A$AIAIhAJ ~u} @}td~tQXM AM,abAILg:}"MAM,_A}TItG9jbI:, @u = lXIAƆH7@EJfAI@ OI03XLEIȖIH)HHDE11k}IHt8[ux]uxlf.A$IMȖAJI)IAKMI03XI}HHDHuq3IH!HuHxLe3CD/MoIfAL$M|$AD$El$A}3 L ;OXfA}tAJ ((A}fMw AM|,I11LDhvDht =jA@} MM A9,u AyAJAH)MfA}~ IA H@ bIAؾXH03XHHD13VH03XI|$ LHD1CD, El$JfDIH8]xw@AI,u A}|u A}gxIEEHH @B)DAHJDlRAAEH4@H0HHIDh @E~}0I8(E~8AJ*AH &IA H@ IH03XHHDj@u*AIu&AIJf.LH  IH-h+q~_b}AƆEAdž@ AAD$62IHtd8|u_xuY sIA H@ 6IHHAؾX1/*fID-6sAGO P9iH@fWHHDH@DhHDlIAAEH4@H7.HHIDh @PDAD$AtfAD$AJ*AD$fAD$DA}It@9MEDLruEI8,~:EE=(AH  jXA}Eƅƅ}E1*DEf.EP1f.A}{03XfDx1fAT$AJyAJdAH \Xf.;~(HHzMMAM-+A}}>EA6fDAHtAK5IAJE}GHxD1A1ƅ}E}AJZDI]@tt"IHt8|uxu AH]AJD=A}qpXLXL`Dhr*DhL`X>AH s6XIpt9H {AH UIdžXAƆHAdž<Adž4A8AJ tfLFou $7RXbf.EA1҈]|@H$A@ hLXfDA03XDg*fIA H@ IH03XHHDKD|IAAGH4@H(HHIDx @P\D>O PD%gmA9&H@WfHDH@@D`f8AH%AHEDAH  mXIA H@ ~پXH1H)AJAHAA}DIA H@ IAؾXH03XHHD1(kIpt9H(AH 4 IdžXAƆHIdž8A4AJ tff.LVluIpt9H[AH P IdžXAƆHIdž4A<AJ tfLku_DlIAAEH4@Ht&HH IDh @P IA H@ IH03XHHDAؾXX15'E @AH vIA H@ پXH1&ADIA H@ پHXH1&+AH pRXIE H@ DXH1d%IA H@ UپXH1&XAH x\XJAH rIA H@ IHH~03XtDILHp IBBA4A8A<|IA H@ iIAؾPXH03XHHD1%fIA H@ IAؾXH03XHHD1$GH~hHAH 0IdžbXAƆH1E6IA H@ پXH1d$SAHXDhIAH@! y MgA9A, aNXLH HxIfyHA@;fA ;fA L%IH"MLAGpLIEoaNXHS MfA HSHCf CIDkAwHAHtvH<f.HHH9tRoHHHJHt0@&@3@t@t @ t@ uHHHIAwFQfLHH@HHHP@H@FHH@HH@HIP}A$"CHD@L A<<ADŽ$LLADŽ$p=HHTH!.Pf<M"IHI ]MI!IH@ 11LAIAo ALJ IAؖAHII1H IBHZHD@HXL, HL9Ct _! 2  uHCH(uHCHpH@H HP0:HCHx]H{TmHXH:HX6HXIHBBILILJIA0A0LAHDhIyu[y;HhDa,L%aASXLHh YXLHhHhW AI@AJfyHYLebA9CLHnLHnAH`HHuoHf;`f=t  HCH(HCHxH{fwoHCH(`f.C9aAt(;``uHL AHaI1҉P.IaNXL 0LHHxDHCH(HCHxnH{{fCHCH(HCHxTHCHxGH{>W`A9Y,_HA0VAAtAqI|$HMD$PHHAAJ89R$HHL€:EI$LHL8u)H‹BHHL NjBEQ8D9rEI(D)IA9$sA$8aA$8LEdAqA$MIOIA H@ fڿXH1EIA H@ 6ڿXH1{IA H@ IHHEAؾX1IA H@ ڿXH1HCH(HCHpHx LAH PSRXR()HHLF03X/AH Idž@XAƆHkIA H@ IHH>AؾX1IA H@ پXH103XNYLa LuA(I|SXHhHh[A(MdpA$LHDh=IA H@ IHHtoAؾX1nHhLa! UX;X1LDhCAƆHI03XLDhIH{"ILBHhpHhVSXIHDbJIHIډ1HhAfsDcrIHkHHHII9tBoABHHIJ(xftk9@ tHHHIE1HދHBHHkH؉HHH1HHD`BHkHT01HLH HIP7^A "PCHHkH4<K<E11EADžpL2IHHLfA.HPIHhHhHHH H]HhHmHhHHa@ 1H߀Io 1ǃ Lؖ|H&HH1jLIPIHhLHkL,HL9tVKtC<< tHC H(uHC HxH{ 5CHйHhH8HhE1E1ILDHDHI$E1LM$IA$0A0^|I<<< ubHC H(HC HpHx.FHC HxqH{ hCHC H(< HC H(HC HpH@H HP0HC H(tHC HxHC HxH{ CHHC H(9HC HxeH{ fCH1{LYAƆH1FtVI}HDNHkHIMPHDP8E9@$LHHA8uTPHADFHkHHDP8E9s"@$LHH̋VAHvB@(E)LHHE9sE8t-A8 H@(E)LHH_PAHp03XAJfIA H@ ڿxXH1fAH t[IdžFXAƆHMIA H@ 'پXH1IA H@ IHHٿ0X1eLDhH)yLQAƆHIAƆHLDh I  `@V@LAII[Iy$1AIq203XUHAWAVAUATSHHHHu`IH@uT>uOv;5ZTAtd;5TAtXI~fAFLLzmLIFH(IFLHxIFHx؉@pAHkaHHIDp IFH( IFLHpHx6I(D)HHHcIA H@ .XH1xA$LPF:;UX;X1UX;Xff.HUHHAWAVAUIATSHHXHHH)HHIVf у҃GE_~UHIHވENS5GAIH 999wGAEID$HI HLHCHsDpDE1HEMt?ID$HHt5DCHEt'1Ҁ8u D9WxH<HD9u@CE1+F}CEFD(vCFH@H4IGL9}I{V;CGAI;FAu ~H)HXHi۫H[[A\HA]A^A_]V;FA;FA;oFA;_FA;FAu~LvEAFDHRH@MAID${EHIDULE2DULEH=ANID${EHuGIDULEE2DULEH=AKID$Ht+EIE1XID$Ht(EIA.u ~{LoX111HEƅ)EH}HULcHEHIvH)H)H9rLJ1HHHEHH9HHHHEH HH}LLuLuALuL}M9u!=DIFHEAFLuL}M9tA~uM9t A~.HHEMM)L)HwLHIHII9LLHMGLHHEI" MLuA.HEHPHU03X@A$KHEHHDI$M#I$L=fHnHfl)qA"Mf8L A"I$"A "҃ A "I$VHA"y>I$A"0 Ј0I$A"0I$A"0@ Ј0I$A"0 Ј0A"I$0 Ј0IhA"I$I$H0(0I$H78&I$HA$HH9tAfof11I$LA$IAƄ$A$0IDŽ$ЖAƄ$HIDŽ$A$@I$o M$ A$HA$ؖf% fA$HLA$HI$PA$IuI$"t^A$JI$IHt"MuNL?IDŽ$f.H@ A$ پ(XH1I$AƄ$H0I$IDŽ$H}0HH9tff.1HH[A\A]A^A_]f.IFHEAFLuL}fDI$HѻH9HHH0HH}HHǁ0HǁXǁlIDŽ$H9I?DHLHMH^HEIH`HHHHL@H HEHHHHHQ HHf. HH@ 7پXH1l@M$L5ѤfInfl)@A"Mg8L A"I$"A "҃ A "I$VHA"y>I$A"0 Ј0I$A"0I$A"L0@ Ј0I$A"0 Ј0A"I$0 Ј0IhA"I$BI$0HI$H8I$A$HL9tfof11I$LA$IAƄ$A$0IDŽ$ЖAƄ$HIDŽ$A$@I$o M$ A$HA$ؖf% fA$HA$HI$@A$IuI$",A$J}I$IHt@L1IDŽ$fI$0I$I$vfDI$H}0@HIDŽ$H9tpfD&fD1UX;X1S^ 㐐UHATISH0@u H]HqHHM1ҾHpEȾpXLPA11HHھIH~IT$ HVHH0L[A\]fH]HHqyff.UHAHAUATSHDxH0EE1ff.HI9t9)uLoXHNNND,LILHHRHH*pXHH)03XAEHE1I HL[A\A]]DHNNNME]IHHRHHI)AADx1B)+Dff.ff.HH=u‰ƄB,E03X*pXHELoXDL1A1HNNN#oXHHcI<1HHL[A\A]]f.HHھ#oXI<1kHL[A\A]]úYAA1AE1fff.UHAWAVAUIATSHHA} ""LHKHNHKPEH8D9E`(AE)MIII)IAEH(HC8~;u "DH'oX11H1LLLcHM)IUL)H9K.HHHI9LHHHJfA" DH}oX11H1:LLLcHM)IUL)H9rGK.HHHI9LIHHHLH "u "DHHHLLAEH[A\A]A^A_]DQAE<9<AMH +AoX111&HLLcHIIT$M)L)H9K'HHHI9L-HHHE`$AMII;f.H(uHC8;0NDH߃oX11H1JLLLcHM)IUL)H9SK.HHHI9LUHHH DuDAEA}AMH m*AoX111HLLcHIIT$M)L)H9rGK'HHHI9VLHHHRLHA}AuH5)A8LLA$lH(HHHHIVLHfDDHoX11H1LLLcHM)IUL)H9K.HHHI9xLHHHWtXX;X1fAEoX1D11HLLcHIIUM)L)H9rGK.HHHI9VLHHHQLHDoX1LLAEf.AEIu 2Iu&AEHtD~oX11H 'A1HLLcHIIT$M)L)H9rGK&HHHI9L HHHjLHHC8AU~H5B'ALLA$DHHHHh AEIM IMHL9fIMOHL9Ef.oX1H &A11HLLcHIIT$M)L)H9K&HHHI9LHHH)HHHHIVLyHHYHHHLIWLJHH*HHHuպHHHHHHHHtiIVLHHHHHDHHHHufDUHHAWAVAUIATSHHHHcHIHBR0I ~ BT3WHMuHHH)[A\A]A^A_]HHADHHIHuSR0I ~ BT8WHMt%HHDI AVa뤐Hf.HHHIHtLHH}H}H4AT$0I ~ BT WHFMtI ~.DHNx3AWD~I ~ AVv@0AW0BA7D~I ~AVAfDUHAWAVAUATSHXLwxHuMAH]I„MAfA}uhAE9R$AuTHLy0x0u#HMD@@D9AuEL ff.LHu$1IfA}tHE<tM<E$A$"tHuDLK~1HX[A\A]A^A_]HE@tDxIt$HDI|$PHHHEJ8@9R()HHHDHAtPff.ff.ff.ff.@$LHHDAH‹BDBIHHDH8E9rċ@(E)@fA>"AA9FHuL.It$HMD$PH<2<RA$GLo< <uG,A$Lo G0LO0<<A$0HHHAQDN8D9F$HHL@Hu9VA9L)HIA$"AU[ AMH p A9_y DLDEA$ "oX11H1\M$DEM$HcI$HSM)L)H9rSIDI$HI9 I$HL^DEHI$H" LI$A$ "uA$"DLI$HI$I$ADŽ$"DF(D)HHL@jLHup-IA<Q<A$j@G2tODHG@HLAz89Az$HHLDAHAt,b@ff.EI$LHLDAu8HNjGAHHGHL EY8D9rEI(D)f.IE9$s E$DAA$8@I"AGtDO,DHHƋG(DR8D9@R$HHLDAHAtCqDff.ff.ff.E[$LHLDAu0H‹BAIHLƋBEk8D9rE[(D)fDIE9$s E$DAE$8LEGtOHHƋGDJ8D9;R$HHLDAHAtU|fff.ff.ff.ff.ff.$HHLDAu)H‹BAHHH<ƋBDW8D9rȋ(D)HE9$s E$DAA$8HEfGDA$LO8HHHA9DOA$H@ER()IIK<f.R(D)HHLR(D)HHLA9HA$LHHA9HofDHA$Hx@PA$LhR$HHHA^A$MvsID$8A$11~oX1H A I$M$HcI$IHSM)L)H9rLIDI$I$HI9LI$HHLI$ID$8A$~H5>AI$I$@HUA9$s A$DA(E$8HDEHE>HEDxE$H@HE!fDAFtA^It$HI|$PHHAFJ89R$HHHDHAt.UfDff.E@$LHHDAu)H‹BHHLƋBEH8D9rE@(D)IA9$s A$DA@A$8LEVR()HHHODxE$H@HE-AMH AoX111I$M$HcI$IHSM)L)H9rOII$I$HI9HLI$HHJ<1I$A}tlAuH5AdI$I$HTI$HHWIULDHPXA$LpAEIu tIuuAEHt|AUIM IMAEHLHI$HIVLHHAUt.IMHu AuHt1>_u~A} _IM :mI$HDE8I$Ht'IULH,DEHII tXX;X1NYff.UHAUATLmISHHH$@2f;uBCtIFHHEIH9HuHEHH^LH}DjLHHHEHE"I< <DA$fA}AA9EA}@H]H}H)HHHtH۸03XHHDHHHhH[A\A]A^A_]DH}HUHEEzII)L)HIFHHEIH9>HVHEHHE:@ABtArML$HMD$PHIABz89@R$HHLDHAtTff.ff.ff.ff.ER$LHLDAu0H‹BHHMBEZ8D9rER(D)IA9$s A$DAA$INf.AEtA]I|$HMD$PHHAEr89BR$HHLD HAt=dff.ff.ff.I$HHLDAu)H‹BHHH NjBDI8D9rɋI(D)ĐIA9$s A$DAA$8LE fABA$MRA;ABIz @Iz4ABH|&DA]A$MmR()HHL@R()HHL@HpHEHHt}IVHdH@AXA$Lh@PA$LPALHHEHHuItXX;X11HIFIH9HHEmHEHHLH}HL+=B48~aHHEHEH cHIcHULmD)HMAIM)L)Au A' HwAHID$I$I9LHEHEHH J!HUH׾'`HHEHEH}HUHEII)L)Hw>HIFIH9HHE7HEHH LH}'fDHHEHEHIT$HHH HHEHEHH5IVHHG@HwAHID$I$I9=LHEqHEHHIJ!HUH׾\_HHEHEH}HUHEII)L)Hw>HIGIH9HHEHEHHLH}x_oX11HHEDHE1\H}HULcHEIIwI)L)H9r>K'HHH9HHEtHEHH`LH}DoX1^L}L}AH}HUHEII)L)Hw>IFHHEIH9HHEHHLH}\DH_HHT`HUHMHLEAII))M)% |'=E4AaEXADA AIwBIWHHUIH9v HHHEHHQ J9HUH׾\]11HHEiXHE1LH}HULcHEIIOI)L)H9rBK>HHEHH9HHaHEHHJ<1H}iX1GL}L}AH}HEHUII)L)HwBINHHMIH9HHHEHHJ<1H}\\HHEHEH}HEHUII)L)HwBINHHMIH99HHrHEHHJ<1H}iX1XHEHPHU@]LmMt,LHHI9u"HhH[A\A]A^A_]ÿ03XQHL@HHEHEHIT$HHHHHE|HEHH~IVHlHM@HHHEHHIVH8HPHHEHEHIT$HHHHHEHEHHIWHH@HHEHEHHIT$HH7HHwtXX;X1A'XEUEA A/ zAIwBIWHHUIH9sHHHEHHJ9HUH׾\YHHEHEH}HEHUII)L)HwBIOHHMIH9,HH~HEHHtJ<9H}xXDoX1HHE1HE1ܾH}HUHcHEIHNHI)L)H9rBI7HHEHH9HHHEHHJ<9H}DoX1ӾHHEHEH}HEHUII)L)H INHHMIH9iHHhHEHH~ HHEHtIVHHH xndApA6A\HwAHID$I$I9LHE蝽HEHHJ!HUDH7f.DHH HHDHH讽HHAt AHwAHID$I$I9LHEӼHEHHJ!HUH׾\UHHEHEH}HUHEII)L)Hw>HIGIH9HHE_HEHHMLH}x~UoX11HHEDHE1辻H}HULcHEIIwI)L)H9r>K'HHH9HHEֻHEHHLH}DoX1L}L}AH}HUHEII)L)HIFHHEIH9H^HEHH^@HwAHID$I$I9LHEHEHHJ!HUH׾\,THHEHEH}HUHEII)L)Hw>HIGIH9HHE蝺HEHHwLH}xSoX11HHEDHE1H}HULcHEIIwI)L)H9r>K'HHH9HHEHEHHLH}DoX1L}L}AH}HUHEII)L)HHIFIH9tdHHE蠹HEHHfDHHETHEHHXIT$HCHGHHEHEHHf.HHEHEHIT$HHHHHE輸HEHHIWH謸H'@H舸HEHH@EHHEdHEHHrIWHTH @HHE,HEHHIT$HH]HHEHEHIT$HHH(HwAHID$I$I9LHE輷HEHHnJ!HUH׾\PHHEHEH}HUHEII)L)HIFHHEIH9HDHEHHD!f.HHEHEHtnIT$HHHbHHEöHEHIT$HH貶HH蒶HEHHJi#HaHEHtIWHHUHyA NA/ w< vA\teIwBIWHHUIH9 HHµHEHHJ9HUDHNHHEHEUIwBIWHHUIH9HH]HEHHJ9HUH׾\xNHHEHEH}HEHUII)L)Hw>INHHMIH9t]HHHEHHJ<1H}\$H蠴HEHuIWHH萴HKHpHEHHLHIVH]H뎺H6HEHtIVHH*HHHEHtIVHHH&E ADLHHoHHLu%DHHLIwBIWHHUIH9 HHQHEHH!J9HUH׾\lLHHEHEH}HEHUII)L)HwBIOHHMIH96HHڲHEHHJ<9H}xKDoX1HHE1HE18H}HUHcHEIHNHI)L)H9rBI7HHEHH9HHFHEHH*J<9H}DoX1/HHEHEH}HEHUII)L)HINHHMIH9HHıHEHHH臱HEHIWHHwHHWHEH^IWHHGHH'HEHHH=˼DLxHH螲EHHHLxHIwBIWHHUIH9HH谰HEHH4J9HUH׾\IHHEHEH}HEHUII)L)HwBINHHMIH9HH9HEHHJ<1H}HHH+4_EA"IwBIWHHUIH9HHHEHHpJ9HUH׾\HHHEHEH}HEHUII)L)Hw:IOHHMIH9t2HHMHEHHtJ<9H}DHHEHtIWHHHA'AIwBIWHHUIH9HH蹮HEHHJ9HU\HGHHEHEAF$ŐXHKHEHIVHH;HHHEHtIWHHHZ ~HحHEHtIWHH̭H+EAt AlIwBIWHHUIH9HH腭HEHHKJ9HUH׾\FHHEHEH}HEHUII)L)HwBIOHHMIH9HHHEHHJ<9H}x,FDoX1HHE1HE1lH}HUHcHEIHNHI)L)H9rBI7HHEHH9HHzHEHH6J<9H}DoX1cHHEHEH}HEHUII)L)HPINHHMIH9tPHHHEHHH迫HEHIWHH诫HMH菫HEHHLHrHEH[IWHHbHHBHEHSIWHH2HLH 6H~HHHBIVL~H$fHHLz~HHHIULk~LH@HHL2~HHHIUL#~LHt@Lf(QkXL ~1Lf.e _ HLH}LH<-uƅ-HH0 w7fff.ff.rHH0 vƃ@,.0Hfqf.HHuHLHE1jEN1^_fHHL|HHkIT$LH|LHOHHLb|HHH*IVLS|LHc@HHL|HHHIUL |LH@H{HHLLH{LHpHLHLIDM)L)HwXID$HLHI$I9 Lk{LHHH J!HH"||... H0HHPH@-fD1ALHPL`pLh&D"l f(AHHLH}zHHHLHkzLHPHHL6zHHHlIUL'zLHNHHLyHHHIULyLHHHLyHHHIULyLHvHxyHHIT$LHhyLH<,1.BHH*H%yHHHDHyHHH IVLxHDLHDLژL DLH藍HxHHH\ IUL{xHHLHIM)L)HwXID$HLHI$I9 L,xLHHH J!H@AML'.'(HDIHPH@A}AELLIP%<A_H@HwI$hH耪A?yAOH @oX111vI$M$HcI$HHSL)H)H9rYH I$HHI9I$LvHHI$HK HI$A?AwH5@cvI$I$LH1f8IA}$AEI$M$I$HL)H)HwLHSI$I$HI9LuI$HH HI$A(,'.'fDXI$HPI$@fA}C@A9E&@A9E AOoX111tI$M$HcI$HHSL)H)H9rYH I$HHI9I$LtHHI$Hb HI$AWoX1tI$I$&fDAGAWI_fDI$M$I$HL)H)HwLI$HSHI9uI$L%tI$HHHI$'fI$HPI$@A??EL=8@L8tL11IHM$M$HLLL)LHsHLHI$HSH)H9rYLHI$HI9I$L#sI$IHHIM$LHLrI$LHI$rI$M$I$HL)H)HwLHSI$I$HI9L~rI$HHHI$'fI$HPI$@fHrI$HHSLHqHAGIw WIwKAGHt=AGIO IOuAGHLgAWI_ ,AGiAwMf(KkXLtqI$HL(qI$HHHHHQ qHH5I$HLpI$HHvHHHQpHHHpHHHKIT$LpLHIOAGAWH\H1LHAWLLLA_LHZVHpHHHNIT$LoHHHoI$HwHLHoHVI$HLHoI$H8HHHkoHbI$HLhHPL8HHHOXLHHuHPgHPHHA<s&U4" 'HMoX111SgHHLcHIIT$I)L)H9rGK,HHH9#HH^gHHHsWLHHugLHLA$ " Ј "A?sAGfDUDEBHHHII)L)HwMHIT$I$H9-,HHHfHHH?aJ'HDME%pXMgL`AHfHHPH@HH#"H H"EEDEA$<<jEM㉃A"ptx}>9}u A;HHEL}DM"DE1LL]AHDUP"XZEDME]" MHLHIM)L)HMt$HLI$L9(LdHHH|_J!HDEEGpXfHHPH@""t ǃ"He[A\A]A^A_]f.A?EAHhHULJEEPE"  DpAGMG<<'EA7@A"@@A9GMA8IHHAPLLELfu1oX1H1bHLLcHLEI)IT$L)H9rKK,LHL9UHHbLEHHHTLHA0IHLAPtHHxbLLA$ǃ" fD1Ʉ;DžX@FAG;!".DžXFwLn FMlFHhHH AE" l+ƅH0AGMgpH@IHx.HEEPA<$Q>AD$Hߤ@H@=HE@H@H8h"DžX,<HhLmH AE{|(A}}q(A}f(EA $=ƅHE1E11fA<$<At$E1Dž @uEA @@!H^- CƅHg-"t E=$p$uN9u$HLHIM)L)HwJHIWII9UHHL_HHHULH f9HHPH@HLHIM)L)HwJHIWII9UHHLE_HHHqULH...HHPH@"fA<$u H=E1Es6LHh,LPݑAĄ+PduAE,IA}IA}".>tXt EMKLgcH@"!uGDE…@ !EPAP "tBX$6EHLHIM)L)HwLHIT$I$I9THHLt]HHHfTLH f1HHPH@ǃ"Xu5HLHHhIM)HVL)H9rKJ&HHI9;HHL\HHHLJu }t1EHLHHhIM)HVL)H9rKJ&HHI9:HHLUHHH-PJ$ƅX1EAG1;6@&9.@AąA!A Lxx9UƅxEA>p}W9"HLHIM)L)HwLMt$HLI$I9IHLRHHH{ILH f9HHPH@HLHIM)L)HIT$HHI$I9:HLQHHHtXX;X1QRMAGtAO,H{HLKPHHAG(r89R()HHLDA44E@$LHLDAH‹BHHLNjBEP8D9rE@(D)HHLXPHHHIKHpHXHHPePH" pXDUM"vMmLff.HHNL9XuD9PuE A<$nXuAD$*pXHEȺoX111rOHLHcHIHQM)L)H9rcJHHI9~ HLLhHppOHpLhHHH?LHA<$nXuAD$*pXHEHpNHpHHE-ǃ"DMEHLHIM)L)HfHLHIM)L)HwVHIPII9AHLLp[NLpHHHHJHA,AfDHHPH@AD$H@M$DUAD$tET$HsHDH{PHHAD$J89lR$HHHDAnTff.ff.ff.ff.ff.@$LHHDAu)H‹BDBIHHDH8E9rȋ@(E)I9s DAD8LE+fDHLHIM)L)HwVHLpIPII9HLLLpHHH(=JH...HHPH@ǃ"EHLHIM)L)HwVHIPII9wHLLpKLpHHH<JHA,AfDHHPH@ǃ"AD$H@M$D" AKAs1DhHhH5ˎ@Lp1LpDh=A{HLH"HL)H)HpHwmHHVHI9HHLD`LhJLhD`HHH)@HpHH(HDME1fHAHHHPHD@HH#"H L}LH"HEL]DUPðHLH"IY^M)L)HwVHIPII9HLLpILpHHHR<JHA)fDHHPH@"ET$DM\$fR()HHHDAMHйHHL`LhHpHHHrCHpHhHHL`HHLHIM)L)HHIPII9PHLLpwHLpHHH}HHL`LhHp HHH:HpHhHGL`HLHC8AT$11~oX1H 6@iGHLHcHIHQM)L)H9rcJHHI9HLLhHpgGHpLhHHH8LHHC8AT$Hp~H5@FHpHHDPDLXHHLhFHHa7LpHhHIPFLpHHHL`LhHpUFHHH7HpHhHHLLcHIIT$M)L)H9rKK,HHHI9)HL!>HHH<2J<)HAG<1$<#Aw,H5K@1I9s DAg8A7LExX"@E1HLHHhIM)HVL)H9rKJ&HHHI9HL$=HHH1JOjA[uA}]u A}A}!u A}qD,ELrA(>D=A_HuH 11r(D=)Db=)H D,LMME`)H}H}IQE)ljuDu҃_tMH MLDžXA)HLHIM)L)HwLHIT$I$I9'HHL7HHH&LHA fDHHPH@ǃ"ƅHƅ0H`hHEHEHEEEHLHIM)L)HwLMt$HLI$I9!HLC6HHH+LH(HHuE1f9HHpHPHU@HH#"H$H"HEPEDHbHLH"IAXAYM)L)HwLMt$HLI$I9*HLd5HHH*LH)f1HHPH@H`HLeHEPE?HLHIM)L)HwJHIWII9 HHL4HHH\)LHA(HLE1fD9HHpHPHP@HH#"H$H"HEPEDHɚHLH"IZ^M)L)HwLIT$HHI$I9(HL3HHH(LHA)fD!HHPH@ǃ"AG<<EPHx<<!EHxHEE1D ʈHD9EOw@A9D$ H?uA}-u A}EAE+u.A}u'AVf уf@@@Mx9}E:uAE-uAED ALm7""tH`g}uyEutA> p DMAA9=H`LuHEEEHHEUL"pE1HPP"Y^)HLHIM)L)HwLIT$HHI$I9!HLO1HHH!LH fHHPH@ǃ"A>p}DOA9E)HLHIM)L)HIT$HHI$I9+HL0HHHqDA"/H`}LuHEEE HLHIM)L)HwLM|$HLI$I9HL/HHH(LHA(HLE1fDHHpHPHU@HH#"H$H"HEPEDHHLH"IA[A^M)L)HMt$HLI$I9HL.HHHYfDH"E1HEpHLPEDH2"_fA<$AX` "A!~ANHhHUAvH5q@‹EEXAHHLPDXL`Hh-HHx#HhHPH-L`DXH#E"DE1H߃HpHu ЋU"HEPEDH"AYAZEǃ"PL@A7}HhhLM`}HLHIM)L)HwLM|$HLI$I9HL,HHHLHA fD HHPH@HLHIM)L)HwLM|$HLI$I9HL8,HHH[LHA'AfDHHPH@qHLHIM)L)HwLMt$HLI$I9HL+HHH LHA fDHHPH@ǃ"AGtAG,EEH{HHsPHHAG(J89 R$HHHDAE@$LHHDAu)H‹BIHLNjBEP8D9rE@(D)DMI9s DA}8LEzH^*HHIT$LHN*HEIFAF t/5@8p A A<wH?A A}\CA}+8A}-HLHHL)H)H}HwNHHWHI9HHL)HHHHEHH fHHPH@ǃ"A>AvH5l@Hh1ҹDEDEA~EAP <M<sEAvH5 EfLƾo1ErA<$[pXL,$A TH`LuHEEEEDHoƅHƅ0rLmA}ALXI'H}H}H衿A)މG$ELLXDžXAt$H5$g@HhHUDD A $DD HuFH~ H8H~H8FHDH8VAD$I|$ H@It$H@AD$HDH@~AL$HhHUAt$H59f@, A $AEA9A"HHL込(xHLHHL)H)HHwQHHVHI9HHL1"HHHHHHA fDHHPH@ǃ"A $HHLH!HHHHIT$H!HDžPHE@ H@ =@8x ALLXDžXAG,Mw E'x EA<$AD$Hmd@ILc&oL\&XLD"$qpXL_ SpXLJ .pXL5 pXL AAE1pHLHIM)L)HwLHIT$I$I9nHHLHHHLH'EfHHPH@AmH0E>"Hx@t@EEH{HHsPHHHxJ8@9R$HHHDA-E@$LHHDAHЋPUHL׋PEH8D9rE@(D)뿋EPAGt AG,PPH{HHsPHHAG(J893 R$HHHDAt6cff.ff.E@$LHHDAu,HЋPPHL׋PEH8D9rE@(D)IH9s DAuP8LEHEH9s DAhuHHE$HHLHHPuHHHPHHH_HHW҃UANHh1AvH5`@xHR()HHH<AFIv Iv AFHtHоMg p.ELXAWAGEH{HHHsPHAG(J89R$HHHDAE@$LHHDAu)HЋPUHL׋PEH8D9rE@(D)IH9s DAb}EINHhI1ҋvH5_@uAAA9"0A9!ʈhAf=HA9E1E1HHHLxHHHxIT$HH_AE:uAE-uAEA A}:A}-A}HLHIM)L)HwLHIT$I$I9HHLrHHHYLH HHPH@"HHHa IT$LHHAGIw!2Iw &AG(HtAG*pXHLHIM)L)HwLMt$HLI$I9HL]HHHLHA fD9HHPH@BAE|uAEA LAD$M|$ M|$AD$M|AG(pMd9R()HHHKEHHLxHU_HH$HUHxHLHrHLHIM)L)HwJIVHHII9 HLHHH LHA fDHHPH@ǃ"駼AG,Mg PAIFAF 4 5@8p EHQHHHHIT$L>HlDžPHEff/@AIHHHLLHHDHHL@HHHH| HHH@HHgHHHP LLHwHAGIw!Iw AG(Ht*pXAGHHHIT$LHHHxAHq KHq?AHt2Hx@HHH?IAGIO!RIO FAG(HL8*pXAG(*pXAGA~E;HHLEHUHHP HUHuH HHHH* IULHHAGIO!KIO ?AG(HL1;*A}HtHH LLHfH>H}GHw ?Hw3GHt&AE|uAEDžPAHHLHHhHHHhHHHHHHLHHHfHHHHAE[uA}]uA}{uA}}uA}Ŵ"AA鬴AD$It$ bIt$UAD$HtFHLHIM)L)HwLIT$HHI$I9HLHHHLHA fD HHPH@ǃ"H;HHHIT$L+HHxGHO aHOUGHLHHx*pX@2HHHHHLLHfHHH.LLHHpLpuhR()HHHHxpuH@HE鯯R()HHHAFIv IvAFHt釿HHHtLLHHSHHHtLLHHq{ HHLH3HHtHHH!H 鲾HHLXHpHHtHpHXHHafWA|$]/A|$U0k&HHUdHHtHULHYH%ֽ̽z½Lu LH'LHw"LHapXLLpXLw7>pXLb"/pXLM pXL8pXL#mMH MLTHhLuL I߃ITHA6PXHthILuI9uLL \釼HHLE HHtIULH LEHE1sDžXLL 頬%"HHU\ HHtHULHQ Hػλ*ĻH HHtIULH HHxH}y3oHHLHHP HHtHPHHH HxL`P HйffA/FE|HH?غHHP HHtHPLH H%険H HHtLLH Hre [QfDHHL HHHtHPHHHPi Hyܹҹȹ龹HHP HHtHPLH H9|fHHP HHtHPLH HH HHH2&4fHH HHH8޸ԸHHU HHtHULH H"雸HHLHP HHtHPHH HJHHLPz HHtHPIWHk HAHE٧x}H@HE齧RԷLY.pXLpXLA 鄷HHL@HHHHtHHH@HHHAA!鮩LXHPHHtLLHFHJHExfH@@Lh?.pXLL@H@GpXHEA9LHu HE@I|.pXqLHu HE@I|pXGHHE@MlqHE.pXLh L pXLEA9.pXLtpXL PAƅhA@.pXITHH@|H@Pvƅh髫H@tJt2HEPL`A隮xLp}A遮HNFVLdHEPL` Ǵ@HHHtLLHHF鏴HHLhHHtHhIT$HH_pGHHHtLLHH@S fDHHHHHٳvϳųfUHAWAVAUATSHf>MlLmDMDE$H}IUHEHxI@pA9GfDI@Epu9}DEDuMgEtAG<t <J DMlLHHTL9`uD9pu"({lHS811~oX1H gG@HLLcHHIVL)H)H9rUIHH`HI9 HLH`HHHHHHC8~H5F@.LLAHǃ(A<$fDEd$L%F@LLH術HuD!"AApfA<$LmLeDuHHEMD"ALHPEDHKi"Hǃ(XZA<$\E1AGDeHD@MEA<c <% EMĉAMCLff.HH$L9`uD9puHLLEIHIM)L)HwTHIT$I$I9/HHLLELEHHH~LHA|fDHHPH@"(e DlEU M KLDHLEDpD+!LE UDLH fM9u EA9fA<$EE~Hh t pA$<QfA<$ 5JE@A9t$ HHHII)L)HwEHxIWIHH9HHHHJ9HA,EfDHEHPH@ǃ"fA<$uMDuD@A9GHe[A\A]A^A_]fDuMh@HHHII)L)HwEHxIFIHH9eHHHJ1H...HHPH@Hǃ(H@X+HHHII)L)HwGHxMt$I$LH9THHHKJ!HA[fDHHPH@ǃ"fDAD$!"HLHIM)L)HwJM}HLII9 HLHHHLHA,LHfDHHPH@WHLHIM)L)HwLMt$HLI$I91HLVHHHLHA]fDHHPH@ǃ"2f." 5E,HDLM1jLELH|A_ZH}LHD8*HI HpX1L11 HLLcHIIVM)L)H9rKK>HHI9HHL)HHHJ<9HL⾜pX1 LLAL}u }MHLHIM)L)HwLHM|$I$I9WLHL|HHHLHA]fDHHPH@ǃ"HHUHHHUHxHHfEA<$AL$At$H54>@HhHULmLeDuA<$A|$=HLHHL)H)HwYHHQHI9] HLHH`6H`HHHHH(HMHfHHAHPHD@HH#"H LH"HEPEDHG`HHHǃ(H"I^_I)L)HwHHIVIH9;HHEHHHJ7HA)fD0HHPH@kfDuA@tEpH{HDL[PHHA@J89R$HHL MHЀtW}ff.ff.ff.ff.ff.I$HHLu+H‹BIHH NjBDQ8D9rˋI(D)I9s D8LEAGtEw,HsHDH{PHHAG(J89R$HHHDHAtMfE@$LHHDAu0H‹BIHLƋBEH8D9rE@(D)I9s DAD8LEEpDM`Ew,DMg R()HHL8R()HHH HHLXHHHJH`HXHQH`HHoHHHxIVH\HHHHHHEHHA(HLHfDMAHHPHD@Eǃ"AVDHoRHLHA_IZM)L)HwLHM|$I$I9[LHLyHHHLHA)fDHHPH@LHLEHHoHuLHHHC8Ev(oX11B~1H C.@vHLLcHIIT$M)L)H9rKK,HHHI9HL~HHHJ<)HHC8B~H5-@LLA$LHLEHHrHuLHHHHHIT$LHH.AD$At$Md$HHLxHUgHHHUHxHTHHHLpHxHHHxHpH HHHHHtIT$LHutXX;X1IT$AD$At$LdAt$I 뻺!A<$'HhLLHHLHIM)L)HwKIVHHII9HL HHHJ<1HLoX1HHPH@-kX1L11OHLLcHIIVM)L)H9rKK>HHI9<HHLXHHH J<9HL-kX*vC9/HHHtLLHH/@HHHtIULHH:(#u}kaWHHHtLLHH@HHHtLLHH@HHHtIVLHH`HHLEUHHtHuIWHIH gHHLEHHtHuIWHH&HHHtIVLHHHLHIM)L)HwKIVHHII9HLHHHJ<1HL⾜pX1mHHPH@XXNHHLEHHtHuIWHH HHHtIVLHHKfUE1E1HHAVAUATLSfInHflH8H#" "H=UH"HEƇ"HLJƇHEHu)EPIXZ"HHHII)L)Hw@IEIHI9HHHHLH {HHHLHƃ""L)H_IMtGLHuHE1[DA\A]]DHH(0IA7H@0HtEKDE1L 1ɈKH@0IH@0H@0A0@tHH(03DHǃ@0H[A\A]]fD7H@0XHǀHfDHUHAVAUATISH>IHHH(0A5H@0HtrIELL怋0H@0H@00@tHH(0E3EHǃ@0H[A\A]A^]H1[A\A]A^]Ð1fff.Ht+UHSHHjtH]HȤH]11fff.HtUH]1DHt "1fff.HtUHb]1DUH 01AH(]HUH 01ҹH]HÐUHSHH&pXHHHh0H]@H 0@UHSHHHH]fUHAWIAVMAULmATASHHX0膽H HED9`t>LH蛾uMtAMtAH H1[A\A]A^A_]@MtAMt@!AH۾HEH[A\A]A^A_]UHAWMAVMAULmATASHHH0ּH HED9`t>LHuMtAMtAH]H1[A\A]A^A_]@MtAMt@!AH+HEH[A\A]A^A_]H=Hgt>`g+fff.ff.HH8t H9xuDH= t6d#ff.ff.HH8t H9xuDH=@!t6e#ff.ff.HH8t H9xuDH=wt1f#ff.ff.HH8tH9xuH=Et6`Y(fDff.ff.HH8tH9xuH=t6`Y(fDff.ff.HH8tH9xuH=t6Y(fDff.ff.HH8tH9xuH=et@&Z HH8tH9xuH=!wt Z HH8tH9xuH=]t}g HH8tH9xuH=t`pg HH8tH9xuH=uRth HH8tH9xuH=t $i HH8tH9xuH=t@g HH8tH9xuøeH9xrHH8ugZH9xUHH8ueH9x8HH8u1UH5(HATSHHtEA`Y@HH0L聰I4$>$HX0LIĠ^I4$HuH5HtDAYHH0L1I4$>$HX0LIĠI4$HuH5>uHtDA ZHH0LI4$>$THX0LIĠ辯I4$HuH5HtDA@&ZHH0L葯I4$>$$HX0LIĠnI4$HuH5HtDAdHH0LAI4$>$HX0LIĠI4$HuH5HtDAgZHH0LI4$>$HX0LIĠήI4$HuH5HtDAdHH0L衮I4$>$HX0LIĠ~I4$HuH5aHtDA`gHH0LQI4$>$dHX0LIĠ.I4$HuH5HtDAeHH0LI4$>$4HX0LIĠޭI4$HuH5HtDAeHH0L豭I4$>$HX0LIĠ莭I4$HuH5rHtDAfHH0LaI4$>$HX0LIĠ>I4$HuH5HtDA`YHH0LI4$>$HX0LIĠI4$HuH5QHtDAeHH0LI4$>$tHX0LIĠ螬I4$HuH5HtDA`pgHH0LqI4$>$DHX0LIĠNI4$HuH5HtDA}gHH0L!I4$>$HX0LIĠI4$HuH5NHtDA@gHH0LѫI4$>$HX0LIĠ讫I4$HuH5LHt@AhHH0L聫I4$>$txHX0LIĠbI4$HuH5{HtDA $iHH0L1I4$>$tHHX0LIĠI4$Hu[A\]@I$IĠHXfDI$IĠHu[A\]I$IĠHNI$IĠHH~I$IĠHxI$IĠHI$IĠHI$IĠH>I$IĠH8nI$IĠHhI$IĠHI$IĠHI$IĠH.I$IĠH(^I$IĠHXI$IĠHI$IĠHI$IĠHHt fD@ff.U0HAWAVAUATSHH}HTƀ0IƸ@uH==@)1ҾPU0UI1Ҿ@UIP00Uס"H}L9tHMl$IMObXL肸t"dXLqt}oXL`uID$HxHuHHIt$HHeH11foL\XHE1ƅ)EܷH}HULcHEHIuH)H)H9J)HHEHL9HзHEHHHLHQ轷HHmfDL E1HHL[A\A]A^A_]I 0H"H@ f@LH=辸1Ҿ@U0UH?H?[@H?*H=?LPjX{PjX@@M?H=?LhX褝$hXb@@?H=O?L5jXb5jX @@?dH= ?LkX kX@B@?"H=?LBpXޜABpX@@?H=?LqpX蜜qpXZ@@?H=G?LSpXZSpX@|@?\H=?LHpX8HpX@:@/?H=?LGpX֛GpX@@?H=?LoX蔛oXR@@?H=??LapXR3apX@t@?TH=?LtpXtpX@2@_?H=?LdpXΚdpX@@?H=y?L03X茚.03XJ@@3?H=7?L*pXJ*pX@l@?LH=?LoXxoX@*@/? H=?LodXƙ!odX@@?H=q?L[mX脙[mXB@@?H=/?L}jXBs}jX@d@?DH=?LgXgX@"@?H=?L6_X辘6_X|@@?H=i?LPcX|nPcX:@@S?~H='?L4hX:4hX@\@?H=?LokX' okX@@%?H=?LcQX踏 cQXv@@?H=c?LTXvy TX4@@?xH=!?L NX4" NX@V@3?6H=?L[X [X@@?H=?LoX谎t oXn@@?H=[?LZpXn ZpX,@@Q?pH=?L,pX, ,pX@N@?.H=?LlXlX@ @?H=?LJmX訍xJmXf@@s?H=S?Lf[Xf!f[X$@@-?hH=?LxoX$xoX@F@?&H=?LHXsHX@@?H=?L6QX蠌6QX^@@W?H=K?L[X^[X@@?`H= ?L'QXn'QX@>@?H=?LiXڋiX@@}?ܿH=?LikX蘋ikXV@躿@7?蚿H=C?LiXViiX@x@?XH=?LgXgX@6@?H=?L~oXҊ~oX@@m?ԾH=}?LZmX萊dZmXN@貾@'?蒾H=;?L!nXN !nX @p@?PH=?LgX gX@.@?H=?LUpXʉUpX@@E?̽H=u?LnX舉nXF@誽@?芽H=3?L[XFU[X@h@?HH=?LpXpX@&JXo?膡HtHIHH??L譮HH H=?hs7XH?@讼@虼@脼K@o@Z@EF@0@@A@@ܻ@ǻ<@費@蝻@舻7@s@^@I2@4@@ U@@@˺@趺i@衺@茺@w|@b%@M@8w@# @@r@K@Ϲ@躹@襹F@萹@{@fA@Q@<@'<@@@7@Ӹ@辸@詸2@蔸;@@j@U6@@@+@1@@@׷,@·@護~@蘷'@胷@ny@Y"@D@/t@@@o@۶@ƶ@豶j@蜶@臶@re@]@H@3`@ @ 4}UX;X1HUHAWAVAUATISHXxHAA<|AD$;-?V;?J;?>;i?2;a?&;q?;a?Eu"E1AEHX11fHnHHEflƅLHHh)LLH )MPPPPPP1H}HUH0LcHEHIuH)H)H9rLJ)HHHEHH9H'HHHEHHH}HhHXLHH PPPPPD1ĘLmoX1LmN<@X11AEH0L(H}HULcHEHIuH)H)H9rLJ)HHHEHH9H9HHHEH]HH}LoX1LmLDLmHAEpƃ"!"ǃp LmLEHIMLM)HuHxHL)H9rPLLHHEHI9LhHEHHN,9LLm踗HLL*L袗HELHE?!"HEH}HUƃ"II)L)Hw>M|$HL}I$H9ЖHEHHLJ!HE 03XfHEHPHU@HS0HEHuHc0HHEHiɈH)H_H}HH9tz"foHEp"ƅ)UD‰""uEHe[A\A]A^A_]fDFzHFHmHxb@foIHH)誖HxHEHIWHHhHHHHEHHHHHQ1HHfHHEHHHHHQHHfHȔHEHtkLHH轔HyhXX;X1hXX;X1ԔߕrhXX;X1蹔ĕhXX;X1螔評fHoUHAWAVAUIATSHHHXԉIDžXuH[A\A]A^A_]ÐHHHtH(uH{`tuHC(LsPIŰHx ˮfDL;c H{0t_HHtSfA$M$H{0LL苂H{8Ht"{ivAGLHD@I4gA$LLl/L/IHt\ID$Ht IT$ HP ID$ Ht IT$HPL;cxH{05xfC0ff.UHAVAAUIATSHH@>u FDLLeH7fA}A}AELLI<<DDfA9LHuG?A9A輔LHu@I<B<RDfA}d?A9EjA}Tff.H@[A\A]A^]fDDAAtAILCHH{PHIAAr89R$HHHDHAt5cfff.ff.EI$LHHDAu0H‹BHHM BEQ8D9rEI(D)I9s DA8LEAEtEuHsHDH{PHHAEJ89R$HHHDHAtO}fDff.ff.ff.ff.E@$LHHDAu0H‹BIHLƋBEH8D9rE@(D)I9s DAD8LE7fDAIMIlDEuDMm@R()HHH@R()HHH@7fDHLHfDDpDLh跑RDH@DLHAbX[ \XA\A]A^]8UHAWAVIAUATISHHpDx@4@HII$pMhoAH@I@I$pMvHHXIEMf.A$x<e<A$IAyA9%{2HLLHf.HHL9tCoHHHJH:uJuɃHrHfJL9ufCH@HHAFMlH@M4A&M)MIAiūA@M$pH[A\A]A^A_]DDAt6AtHAtAtA tA M@HHH;f0'@ DCt{ML$HMT$PHICJ89R$AHHL L]2ff.ff.I$HHLH‹BAHHI BDY8D9rƋI(D)fD?A9AfAyAyA9fA9A{<,<AF IFHH5?OLL]&H?L]HIL]H?L]IE9$s E$"A$8LECA$LK@R()AHHL [IH112?A9AA{<?A9FOƺLL]H?L]HIEI|$0fAEIEI0HEI$hL]HH (H}ȉ}A$x{L]PA$LHA$LNXI$HHAgX[A\A]A^A_]3eIL]HM?AUHAVAAUIATISHH|H~0HLJXHpx3 )HLDHHƀ~I|$0t4~t A$t#I|$8HFHD@H4ƀ>pHǃP`|IHE1LuHULHr@sLL]}t9Mu111YmHIn@tEHpDL}Mt)LzHPHIi{ LXH[A\A]A^]DHFHPzt tItLpDxAEMM<<DAUL|ƒ Ј|f?t <| Ј|A}CAEH@I<<\<3DI|҃ Ј|fA8t A<| Ј|A}GH@L A<<DA| Ј|fA9t A<| Ј|J@ID$HP5HHHHAgX[NXA\A]A^]l0@Lp{GLGMK|1DAEtAM,H{HLCPHHAE(r89R$HHLDAt0 Dff.ER$LHLDAu0H‹BHHLNjBEZ8D9rER(D)H9s DAZ-HQAE,I} ;DGtOLCHLKPHIGr89R$HHLDAt=4ff.ff.ER$LHLDAu)H‹BHHMBEZ8D9rER(D)I9s DAIR()HHLOAAtEqH{HDLCPHHAAJ89R$HHL HЀtAgfDff.ff.ff.I$HHLu(H‹BIHH NjBDI8D9rˋI(D)I9s DtI]AAMIMu\|1oR()HHL*$R()HHLPHxApAPL@LHFPLHgIH"ff.UHAWIAVIAUATSHAH L(OAHƅMHDž@L0DfA>A>AFIhD AAD ODNHPLE1E1 8HI<b<zp@W{M<{H=Y?;H{H=>?H8:H8H9H@MtEl$LHpZ8Ixft @HHMWHAVMOPHMAp89eA@$HA"HL9pipA<<HANfA>Md?A9FaA>LfDMML0A<5<u<<fA>H}AtHEH HH@H[A\A]A^A_]DpHftxMWHMOPHM‹CEX8D9 AP$ALHM$El$E"E9E\$<<tAI<H(HDž@8fDOtsH}H}rH@fDCH{ oHsCH|7;H[ff.CCQ@AP(AE)LHM$fDA@(AA)A"LHL9pftAFHHMA@89Ax()HHLDALHAt,f$HHLDAH‹BAHHI<‹BD_8D9rċ(D)@C\Cff.ftsHH4MAp89E@()IIK4DAHAt;fff.ff.R$HHLDAHƋFAHHI‹FJ89rƋR()CAH[!DAV1~DH{FHCdAp$HHL-DA@$HHLaDHE9s EDA?A8HE@HHE9s EDAAHA8HE NIMAFAMvHNMfA?mL H]`fA<$LAD$@Ih u O#LHLHu8IfA<$uV?A9D$uAFpAHXIDH(H}AHEL0HAHxHfA>AF9?Pft @I}HED$IuPHH DI8E9sLA$LHH@A$<tA<A@?A9F A(E)LHHftAD$HH AD$DA8D9Q$HHHDHAtKE@$LHHDAu)H‹BIHLNjBEP8D9rE@(D)DIA9s ADAtJA8LEAD$AMd$Q(D)HHH=HAL`L0L IAff.U1eXHAUATSHHDj`xEE1-f<tl<< AHxE9te pX1x1D,WXxf;u<tsH5?oX1wfCHs tHsu܋CHtfH[A\A]]DShshX1H5?wMfsmX1qw0ff.UHSHHHhHt wGw^H]DvHChǃvHs`HDAA?OvHsXHDAA?JHsHHHDAA?HsPHߺ DAA?H]@ff.UHATASH09s;9s9s,HHCHHD`@P$[A\]f`DHsHHAHA?HDHsP H߃hAA?t 6fHHH߹NX"AgX[A\]f"[A\]ÐUHSHH09s;sH]fDDHsP H߃hAA?t D"H]UHSHH9s9sH]DHs`H߃lAA?Qt D"H]UHATIHSHkA$IL$HH4I$HPHRHHCHDHCI$h C[A\]@UHATIHSH A$I$HHID$HHKHDHCI$h C[A\]@ff.UHAVIAUAATASrHD^HH}A"AAD A"CtYH@H4HHHH9t>oHSHPSu;8uPu̓HD`HfPH9u[HA\A]A^]f t(t3t t u+HSHftu@ tՀ tt@ff.UH#oX1Hhq]Ð""AɅAD‰")fUAHH""jLMADLE"DHMthHL€8tpH5+?HD@DEAtRHp fEtHpAu@HtAtHxU5?H1]f.oHWHOff.UHAWAVAUATSHHHGHL4AF<HA=@09s;?E~(EnIA<<DAEHhL1 HHIGHFHt @|AGHvDLHHuHK0HHCHH0HLHuH@<HPHGHHHCHHLL<茲I<v<DLPMmLmDuMMܐA<IGI;F`.I~hHOH9MLMHKHfA<$LM@H@ @uAfnHHHLPMv LPMH@HC1HH[A\A]A^A_]?9FL~EAGtEgHsHDH{PHHAGJ89`R()HHHDHAt>]@ff.ff.E@$LHHDA$H‹BIHLƋBEH8D9rE@(D)HHAgXNXHHH[A\A]A^A_]f.HXH0HPDdHPH@HHݼIwHAG fDA^XIXDLJf.R$HHHfDDACtAKH{HLCPHHACr89R()HHLD HAtWff.ff.ff.ff.EI$LHLDADH‹BHHL NjBEQ8D9rEI(D)HǃPHXEHǃXuELM I9s DADIOEgDMA0HHPH@@HPH@H@ HPfHhL'HhEA?AOL EoL-8?ML5OMHE1LELL蝅EHǃPA`ACM[VfA9~A<<EfAʒ?A9MHhL1HHA?R$HHLeAG2CIWMoD]AAtEYDHSPHH4AA~89v$HHHDHAt`Dff.ff.ff.ff.ff.E@$LHHDA0HƋFIHLFEH8D9rE@(D)뿋=y?A9yrMIifI9s DA8LED`DLxA_}DuMA$<<D5?Le11LL]PHY?L]HDLDLHEH߸fEGxA^XDLH߹IXZI9s DAjD8LEfPLXAWMo AAMI3v()HHHAD$tEt$LCHDH{PHIACJ89 R$HHH HЀtGmff.ff.ff.ff.I$HHHu(H‹BIHI BDI8D9rˋI(D)I9s tD8LE-IwAGAWLlEt$DM\$pLH C߁L]HT?R()HHHDpDLXUHAWIAVAAUATSHH("U<<Ih1HqIHHCIEHt @|CMmAuEA!" ?MHLL,AIO0HIGHH0HLM@AIPHALiLiAqIGHMPHAEL,MuBD fH}MPMd$ MPMA$uIEI;D$`rIt$hHNH9rI$fA$Iuڌ?A9$x胦M$fHpff.AE$HIGHfAnfpH4fN8IEtvD1Cff.ff.ff.V$HHHHBH9t0DF8IOPD9r֋V(AHE)LHHAH9uEULHLu`L/f.LnMaAC jDfDI@L衲A1H([A\A]A^A_]HXHIPD:t`IPM@HLL>1f.AIHAgXNXH(L[A\A]A^A_]ILJPIX;ILJXyfIIPM@@IPM@H@ IPfHh UA^XIXHKfIh;EKL DkL-?MLEMHE1LELLS|EτA^XEuA9XUIXHLGUA9XIXHHh1IH<;TCt!t*HSLkbILJPSLk EHsCSLl1fDUHAWAVAUATSHH(D"E\LHDAE<i<#Hh1LIHE1IEfEUID$Ht @|AEMd$DLLHٺHK0HHCHH0HLL@A$%HPHA$H]HMHCHHfL,HPHHK@IMH;J`HzhHwH9fHDH HSHfAnfpH4fN8HEt]E1#fV$HHHHBL9t0DN8HKPD9r֋V(AHE)LHHAI9uHPH@PDHHߋxHpNHXfHXHHP5fHPHHH@HʭE1H(D[A\A]A^A_]fDMeMA$gAE s@HPHP HPH|fDHǃPHXA7HPfHǃXHA5?90H$fHHAgXNXH(H[A\A]A^A_]fHXHHP4t'HPL@H$LH莬HǃPHXr6HǃXDI$HPL@AE< [<6Hh WA^XLXDLHPL@H@ HPhHhLA"LSHHPHH4M4HhH@HIHIv"u@u "LPAv4EADσ@}9}@u Ir(HhHHLSHAH II4ʋOH IH H{00t 9 V VDF4F(L" ʈVDH HWH N,HVN0N<N4EIH4H4qHKXH HAHQhIExHHHHǃXeHh1L$IHA}lA}hOXH=?=" AHPbHR(HHHhʋfAIAH@H/LLmDeAWH9>H([A\A]A^A_]fDID$(Mt$PHx OIHEf.I;T$ I|$0tmI$Ht`fHI|$0HUHuX#I|$8HUHt*A|$iv"HuFHD@H4-#HUfH}H-LHHtUHBHtHr Hp HB HtHrHpI;T$0HB ID$I;T$ 'HBID$ fDI|$0t I$Ht9I|$(Hx N=Dw?9HI|$8I|$0fAD$0f.HCsHPLXt+AH(LL[A\A]A^A_]@tp,MOH@(HMWPIыz89r{R()HHL:AH@t4mff.ff.$HHL8@u;H‹BAHHILLAWy MM4Mu߃mẼuI\$HtAIWH;LLAWu,H}t HCHMHH[A\A]A^A_]fDH1[A\A]A^A_]UHAWAVAUATSHH@H|sIoDwhL'IAx^IcHHDHcHMHIWI>LLAWy MM4MuHHLPHHHyIl$f*^c^,ظ9OAGh9CH<1HH@L(HHRHcHPHzHLLBHs*HcHPHLLBHsHcHPHLLHsHcHPHLLBHsHcHPHLLBHsHcHPHLLBHshHcHPHLLBHsAHcHPHLLBHsHcHPHLLBHsHcHPHLLBHs HcHPHLLBHs HcHPHLLBHs ~HcHPHLLBHs t[HcHPHLLBHs t8HcHPHLLBHtHPH~HzHFDIGHHĘ[A\A]A^A_]ÍPI7AWhHcHPG1Ɛff.UHAWAVAUATSHH@H|sIoDwhL'IAx^IcHHDHcHMHIWI>LLAW MM4MuHHLPHHHyIl f*^^,ظ9OAGh9CH<HH@L(HHRHcHPHzHLLBHs*HcHPHLLBHsHcHPHLLHsHcHPHLLBHsHcHPHLLBHsHcHPHLLBHshHcHPHLLBHsAHcHPHLLBHsHcHPHLLBHsHcHPHLLBHs HcHPHLLBHs HcHPHLLBHs ~HcHPHLLBHs t[HcHPHLLBHs t8HcHPHLLBHtHPH~HzHFDIGHHĘ[A\A]A^A_]ÍPI7AWhHcHPG1Ɛff.UHAWAVAUATSHH8HsIDwhL'IExrIcHHHPH@HcHMHIWI>LLAWy MM4MuHHH@L$HHHyI\$Ht$IWH;LLAWuH8H9stf1HĨ[A\A]A^A_]IGHt IWH;EOhAQEHPMc1H@$@HcLGH9\u"H|HJLLAWy MM4MuHHH@L$HHHyI\$HIWH;LLAWIGHt IWHsH;EOhAQE~HPMc1H@'HcLGH9\u"H|HJAHGwAHHHDx8D9rċ@(D)@IA2HXH[A\A]A^A_]AUvLEMIuHuAEEuHDHEID$MMLEL}MH]HLOI$IHI)HuLEH]MA@A}iHEA}MLEH=qG?L]I)mL]LEL9dL9}@L)LLL]HLEcL]LELIBtzH]HLcHLSPI ċBDI8D9I(D)HHLAHȀtP*ff.ff.ff.ff.R$HHLHAAHHIċAZ89rȋR()Đ?MtLEMfGtIIMc@GMfBtrL}HMOHMPMLMBEH8L}D9E@$IIME8ALAutH]L}H}H]fDR$HHIu8IA@AHHHA@z89rɋR()HHLtH]H}ALLEE9s ED8ArLMA8HEsrHEHRZfE@(D)IHEII fDM3A2sDuE1I9t^dAfA}u7]A;]u.AMHLIMlAMJIAfII9u9f8u];XuHHLIHx@tPMfHI^PH I<̋HDO8D9 $HHHD?AHAtW~@ff.ff.ff.ff.ff.@$HHHD9Au)HϋGOAHHIDx8D9rȋ@(D)HE9s ED9AA9HE@AEtAuMfHI^PH IAA>HEqALiQAHAPAH@(D)HHL=zHEHRI$HHLrHz LEL]L]LEH؋5A?ILLE^HUVHHMD9s Dt)H]8HEPVAHF xH]HP'HrcIE EuHE/Mu&AUHuMI)IEL95&A?LL]LEB]LEL]A@L}tAD  I@H(I@L]LEHpH@H HP0LEI@HxLEIxLEL]AAEL9#L9LAEL9 UI@H(FI@L]LEHx냨'I@H(IxL]LEILEL]AI@H(I@L]LEHpHx,I@H(I@LEL]HxLEI@HxI@H(}I@L]LEHxLLEIxLEL]fA@GUHAWAAVAAUATISHHEHuff.f;>?9C{HsDLMSHTRHӀ;usftDsMD$HDKHI|$PMEJ8D9AR$ALE$"HHD9JDJvE$f;EAfD}ELut4 >?ELD9SuCHD@HÀ;f;tHDHL[A\A]A^A_]SD[fAtS,I|$HDC(H L IL$PEQ8E9|Ei$EMIIAEE$"ED9EUDCAAA$>LtEAEhDFu5Ei(DD)III|AR(AE)E$"LHHD9JtAftSIHMAr89AR$HHHDHAt@xfff.ff.ff.R$HHHDAu:HыAIHIADR8D9rȋR(D)HHHDAtHA9$s A$DAE$:HEEEf.fEtDK,LO N EQ8E9EI$MIIEAMAt2aff.ff.v$IIIEAu1MAqEAAHH4H4D^8E9rƋv(E)fDLE9$s E$EAA$A8IEKE1DDC(1DEI(E)MIIf.AR()HHHS,A$Hs &@DsEE$H[WH[A\A]A^A_]APA$Ip6DrE$HZ'KftDkMD$HDDKHI|$PI4DV8E9s0F$LHH@<t'<E$F(E)LHHftCIHI4CDN8D9N(D)HHHD HAtD}fDff.ff.ff.EI$LHHDAu;HAIHM AEQ8D9rEI(D)ËN$HHHrHA9$s A$DAt)E$8HEDkE$H[DhE$HXUHAWAVAUAATISH<tb<uEFt=Fu7f>tiDmDH^;txUHLCH@HAuH[A\A]A^A_]f.FuH[A\A]A^A_] 7?9NuH[A\A]A^A_]fSMftKM\$HMT$PHI4ËC~89srDv$IIMEnA$"A9tqA~<<JA$IA:LLtEn ABu4fDv(AA)MIMf.ftSHHI4DN8D9rV(D)HHL2A@t)ff.v$HHL0@uJH‹BAHHI4ËBDF8D9rɋv(D)ĐC1kfDV$HHL낐IE9$s E$0@t:A$8LEЅfDKA$LS@HA$LPIH@ff.UAHAWAAVAAUIATSHH(HuEEȉUff;U{5?9CF{HsDCDfAtS,IMHЋ{(HL IEPEQ8D9Ea$AMIIE\$E"E9ET${@#@AMLD]!D]E\$CHD@HÀ;%KftDsI}HDSHIuPL EA8D9AA$ALE"HHD;@D@< <+Ef;ED}Det74?H]E!9SuCHD@HÀ;"f;tH(AODHL[A\A]A^A_]MDLzH([A\A]A^A_]fDEa(AE)MII\EfEtDC,LON EA8D9EA$IIIEALAt(Wff.v$HHHDAu1IApAxAHH4H4DV8D9rƋv(D)fDLE9s EDAA?HEE̅fAA(AE)E"LHHD;@ AftCIHL AI89AA$HHHD HAt!g@EI$LHHDAuHH‹BIHL NjBEQ8D9rEI(D)E{(XfHA9s ADAE8HEEEEI(D)IIN S,AHs cDSE1DAA()HHHDsEEH[xWAHwDDDpEHXCKftDsMEHDDKHI}PI4DV8E9s+F$LHH@<t6<tEF(E)LHHDsEH[_ftCIHI4CDN8D9N$HHHD HAtNuDff.ff.ff.ff.EI$LHHDAu)HAIHM AEQ8D9rEI(D)HA9s ADAt(E8HEyN(D)HHH5DpEHXPfD; >>3F'FUHAWAVAUAATISHf>cDADmH^EMfSuftsMUHMMPHI ‹CDA8D9Dq$AME"IMEfE9EF<<AIًMȉLLu3EfCH@HAt?;VMȋUHLtH[A\A]A^A_]D1DH1[A\A]A^A_]Dq(AE)E"MIMEfE97ftSHHI ҋQ89Q$HHL At*fff.I$HHLu;H‹BAHHI ‹BDY8D9rʋI(D)ff.IE9s EA8LEȅfDC1fDI()HHI +sALK=D=,?9~HL[A\A]A^A_]pALHrDIH8D<UHAWIAVIAUATASH8<tH81[A\A]A^A_]fDA~tAFufA>u+?A9Fkf0HELm)ELLpHD`9L衃HH~H_Dw;Cf;u b+?9KDDuHE@<CH@HAt<uSDeftDcMOHDMGPHI4C~89N$HHLDQA"A9y<<EIAtyu EDQMDDHL:u LcHHuH8[A\A]A^A_]f.L#HHufN(AA)LHLE1ftSIHI4ыV89V$HHL2@HM#f.I$HHL0@urH‹BIHI Bq89r̋I()D{C DeIؿ0LEgLELD`HL@谀HMIA9s A0@EtnI5fDDcAELCAf.v()HHI0AxA@8DAEDMLuDe;LAEHD@MlA}fA}(?A9EA}IuuAUftAM,MOHMGPHIeff.ff.ff.v$HHLDAu)H‹BHHI4BD^8D9rɋv(D)ĐHA9s ADApA8HEEqZAA(AE)LHHAE(E1@AftAEHHL AI89AA$HHHD HAt%LEI$LHHDAu)H‹BHHL NjBEQ8D9rEI(D)IA9s ADAA8LEEED`EL@A()HHI8AM,AIu AUE1AA()HHH}LuDef$?AMA<7EFfAtEfIHDENHIwPHDP8E9@$LHH@A<<Ef.fA>vA9VlAFHD@M4A>ueIHA]EAMmbHAHpXALhy@(E)LHHHfEtANIHkHANHD@8D9@$HHH8AtMxfff.ff.ff.ff.EI$LHH9u*HȋHAIH L ϋHEQ8D9rEI(D)IHE9sE8tAE8IEfEMv|@(D)HHH%D`ELpSCA8DUHAWAVAUAպATISHH""LJ|D11"1THHHA$<<u^AD$tTAD$uLfA<$DmDIA<$ULHAD$H@M$AuH}HǃH[A\A]A^A_]AD$uHDL:H뿐 !?A9L$nHDLHAT$MftAL$L[HLSPHI4AD$~89snDv$IIMEn"A9toA~A$<<vMA:LHtEnABudfDv(AA)MIMf.ftAT$HHI4DN8D9V(D)HHL2A@tSfff.ff.ff.ff.v$HHL0@uRH‹BAHHI4ËBDF8D9rɋv(D)ĐAD$19@V$HHLUfDID9s D0@t48LEЅfAL$MT$~HLPMH뜺\XX;X1KVfD""D"Nff.""AкD‰"^r>FFf>IUDMHAWL~AVAUATSH8L}EA@ff.H}<Q=$<GHGEE1f;DeDHMLuDEDMD}fDSuftsML$HHI Cy89{Dq$MD$PIIME~A$"A9A~<j<*A$I؉LLu9E~CH@HA;OUHLttH8[A\A]A^A_]@1DHEf}ftD`MSHDI{PHI HEDA8@D9q$ALHL47A"EFA9HEAv<?<wEH]ȃ=G;uCt C3MtEFH]ȋCH@HHEAH81[A\A]A^A_]fq(D)HHL47A"EFA9OAftH]ȋSIHI ҋq89Q$HHH t/ff.I$HHHu[H‹BIHI ‹BY89r͋I()fDf.Dq(AA)MMD$PIM|fHA9s AE8HEEvDAftSHHI ыQ89I()HHI t+f.I$HHLH‹BHHI BDQ8D9rNjI(D)HEE1@VfQ()HHHh@CE13DHED`EHX|Q$HHL2fDIA9$s A$A$8LEE0zf.=?9~1DLD@LuDEMDMD}sA$LC@=?9{L߹DHDMDEL]L]DEDMD`EHX@pA$L@@H]HIHf""AкD‰">FFUIHAWAVAUATSH8f>$L~DML}EA@ff.H}<Q=$<GHGEE1f; DeDHMLuDEDMD}fDSuftsML$HHI Cy89Dq$MD$PIIME~A$"A9A~<<ZA$I؉LL]u9E~CH@HA;OUHL$t1H8[A\A]A^A_]fHEf}ftD`MSHDI{PHI HEDA8@D9q$ALHL47A"EFA9HEAv<o<EH]ȃ=G;uCt C3MtEFH]ȋCH@HHEAH8[A\A]A^A_]fD1Dq(D)HHL47A"EFA9GAftH]ȋSIHI ҋq89Q$HHH tW ff.ff.ff.ff.ff.I$HHHuKH‹BIHI ‹BY89r͋I()fDDq(AA)MMD$PIM\fHA9s A!E8HEEVDAftSHHI ыQ89I()HHI t;@ff.ff.I$HHLH‹BHHI BDQ8D9rNjI(D)HEE1@.fQ()HHH@@CE1#DHED`EHXLQ$HHL"fDIA9$s A$A$8LEEJf.=?9~1DL@LuDEMDMD}sA$LC@=>?9{L߹DHDMDEL]ZL]DEDMvD`EHX@pA$L@@H]HIHfHtHtqIHD1fff.UfHAUMATISHH8HEUHE)EHtHt%HHULMʚ;LEHEuUMtHEIEf;t*;uMu1H8[A\A]]A$f ?9KufDUt^ HEH(oHEHpHxHEHxH}E?@ 3HEH($HEHx$H}EfHEH(HEH(HEHxH}C1fE HEH(HEHpH@H HP0ѻ@HEH(\HEHxHEHxH}E0UHAWAVIAUATSHHGHLg8PLJ|HX"^I1+E$0ELh1@ff.HD9HD ?A~<_uLtA>AtAAAwHMHL1mXƅEEw$kDtHhHƄE$0HD9cLhLLmL}1}6A$0tS5 ?L+A~L)5 ?H}HC*LLxNA;$0rL1tOƅHAdžIAdžxE$0IFxƅ`ELhH@Au=HD9HhL% ?mXD~MLtA?_tIF00tA?_tHXIvPTA89DA$IIIAzM<<AdžAE1`*A"tA "@@ pXLHL`L`LHHhLHL`~H ?A9EkX@1MLHL`AE1<fA9<AAf E1EIV0@L0ApA!"0 DA!"0DA"A" LA"TA"@AA"A"A@AZEA "A"ƅ`HD !HhHD0D9|`L@LM~xA"AdžAdžxƅ`@6IV0L0 `0H?Ht HH[Hr?]HuHĨ[A\A]A^A_]fDDA()IIIAA ?AAHh~A<_"D0bA@1E1M^HAHL؋x89@$HHHD)HAt1ff.R$HHHD(AHAIHIËADJ8D9rŋR(D)AAtf ҃6E1Iy IyAAH|A@IHH@ LHL`QLHL`CIA9s AD(AEIAA7fA9#AAf E1AyH=?L8LH2]lj`u`L8LH_!A E@(LHAL`ULHL`hX@1L`LHo@oXLHL`L`LH@)<_Aq;5?+H5y?Ih11LHL`SL`LHErA9AAyH='?L8LH[lj`L8`LHAA@ƃ_f ҃@ AE1E1ExEMHA xL0LM~xI~0SXAdžH]AdžxbH߉"5x?H}!HA1AL%NHx0H"A" LIHA"ǎA"% A"A"PHtA"@pXAAE1f ҃'AA@()HHHGHhD0`AA Z?A9IIq IqAAHtuaM~xAdžAdžxAAE1f ҃mA0@ IhAq1H5p?LHL`UL`LH=AAA DxELHA E1f ҃DAAIy IyAAH|AE1fUHAWAVAUATSHH=%?/HtHG8Ht Ku "H[A\A]A^A_]DwB?/CX1@vW3oXAĉ1Aht*AtAgt*As HXfDXF@HCHLHHILt UHATSHHPt:t HP[A\]@HqA u>H{HDHqH{HH @LeHL`lH}оRmH{LHLEb EdfUHAUATHP>tL<|E1<t HPDA\A]]HvHyH9AA tHAf.F t<tvE1<uHAA u=H~HH赼ADHyHvH藼Ao@H~HHHԺALfHvLmHMLH(kH}оlHMLHyHLA(UHAWAVAUIATSHH<trE1<tHD[A\A]A^A_]fYL5>LH۵A}I=AEIL辵L9uLHL軻ADvL%>UK<4}D{UHDft`AHCE1H9CEuL%->MuL'uHf@Hs \SH9tE1FD{NDf_SH9u\IUfMuHs @AEtWAEL9gIUAELtCD{NDfnDAEL9Mu `fD{HNDf.DM9}Mu$DAtrHsEuMfAUfu&Hs Mu fAEfDAHsuKHttMuAEMtHKCHtAUfuMuHs @ff.UHHAWAVIAUATISHHHGHLoPDEHЋVH89@$HHIM}AD$u D9tJHHuU>UHu0fAnfnfbxHHC`L8f@Mt"A$<<tWAo$AEID$IEAD$H[A\A]A^A_]D@()HHI7f.A|$tHMeIEEAE;rAD$u"HfDfAnD$fnUHIEIEfbfAED9KFPA"@A$t6tItB<v ID$HH[A\A]A^A_]fD ff.UAHAWIAVAUATISHH(F!DẼ AfAA D  DLkPH HCHHAOp89@$HHIIuAD$u D;tYHDMHuMĈU<UȋMĄHuDMfAnfnfbxHHC`H0f@Ht"A$<<Ao$AEID$IEAD$[!t tH([A\A]A^A_]tEtۋULHHtHǃ(1D@()HHIf.A|$VHMeIEEAE;TAD$H"H4fAnD$fnUHIEIEfbfAED;AGPf1fULHDMSDMȉ"e@A $t6tItA<v ff.ID$Hf]UfD Eff.UHHADHATSDA3t6AAH[AA\L(#XDH]HA@D@DEA trAfEt1f>us>9^uh[AHA\DH]yfAAv"[AHA\DH]@AuNt1[A\]H(fF1f8uNj>9Xu[EA\H][EA\H]E9rcE9rDFHD9rRA9sAHDH4fDVAAu;fE{[AHA\DH]@EH8fE@1AUHAWIAVIAUIATSH8f>UDEDMtDAFAUuAE<I<1H8[A\A]A^A_]>9Fuf9u;AuD˃]'AUftEE,M_HDMWPHI AE(DI8D9y$ALHI:DKA"DMA9{AE< < Efff.DMHMLHuMtEAD$HtECAFHD@M4AEA>HD@MlA}.A"tA "# fA> z>A9F fA} A9E IFA~uHEIEHEEE1A}DE187A]A9^)EII]fSDEftDCM_HDMWPHI ËCDI8D9Da$AMIMAt$E"uD9EL$<b<jEIڋEUHLLDHwMtEAEMtEAD$AFmH@M4ƋCH@HA>EELE1EȀ;DEIE1qE&AA~H=>肨A]AfA/AU"DAEA9FH8[A\A]A^A_]fDEAVEftAFEȋEMOHIPHI AFDQ8D9DA$AMIN,AuE"uD9SEEA< <SEELAfDa(D)IIMEftSIHI ӋQ89Q$HHL At;ff.ff.I$HHLuKH‹BAIHI ËBq89r̋I()DDA(AE)MIN,fDIE9s E!E8LEЃ}yT@EftAVUHI ыQ89Q$HHH At7@ff.ff.I$HHHuSH‹BAHHI BDQ8D9rʋI(D)fC\DCELS@uHE9s E.uA8HEI()HHI AFEAI~Ef.AUH9AVH5>HAHHuHuHI} fEtI}u AEH|E@7fDI()HHHfIUlAFtGIFfDD@ELP@x}AHxfAFfDIHxLHxE^fAtAv,MOHMWPHIAF(z89J$L$9IMA\$A"]9AL$AF<<AEAVftAFEċEIOHA~IwPHLEH8D9;A@$ALHHXE"]D9CDHA<H<?EAA}E1AUftAEEEHHIV5IOHIwPE1EftAU,IHI ӋQ89Q$HHL AHЀt#HfI$HHLu&H‹BAIHI ËBy89r̋I()HUE9s E*E8HDEHEȃ}J(AA)N$IMaDG(D)LHHXA@(AE)LHHAV ftAEEHHAE(AftAFEHLA@89FAP$HHHDHAt:eff.ff.E@$LHHDAu)H‹BIHLBEX8D9rE@(D)DUIA9s ADA$]A8LEA}A"EA"EfEtAV,HHIыJ89TR$HHL AHЀt2Wfff.ff.I$HHLu&H‹BAHHI By89r̋I()HUE9s EA8HDEHE8DMDELLUH8L[A\A]A^A_]I()HHLAFAA}EMvjAEAMmEAv,EAIF HEAP()HHHR()HHL()HHHzD@EH@HEpAH@HE7XALh]xXALp]E1AF(DEA~E11AFu]fDUHAWEAVAUIATISHHLf.fA<$A<$AD$f;>9CHPLHuHII<<EELE1LLL LHpFHHuI7H<y<EfA<$*>A9D$0A<$LE1EHLLHĘ[A\A]A^A_]@EABtEBI}HDIuPHHABJ89R$HHHD HAt\Dff.ff.ff.ff.ff.EI$LHHDAu0H‹BIHL NjBEQ8D9rEI(D)IA9s ADAwE8LE@@CtD{IuHDI}PHHƋCJ89R$HHHDHAtQff.ff.ff.ff.E@$LHHDAu0H‹BIHLƋBEH8D9rE@(D)HA9s ADAE8HE@EBEMR(@D{EH[@R()HHH@R()HHH@D@ELP@DxEHX4@UEHAWIAVIAUATSHH(D D+AAAA AAE<s@HA~ Cj B@+AO@82@8 fA?+>A9G3EAAD(D (f;CfA? A?AGH0HH(< <iEDHpL H<S<OEE能t!HDH(L*HHP3H<< ELHu I<<E3f>9C( 9{9rSAO9r19H[A\A]A^A_]f .ff.fW uIwAG .H{H[A\HA]A^A_][AG uAAE<6CAO88r3\DCf  fo6KAG8E83fuC9=>c EEgL%>DLޔDHKAGf/j1f/\AO CAw@8@8^3Ef IOMgf.A&DkL->DLHHDHLLDCMoH&DDDAymA}5w,DLHLD (fCH@HAEH@Ml;u(Kft CI~HIvPHLNjCEH8D9aE`$AMIIAT$E"D9EL$<*<IDžDžAA}L!D LE1DHLLiMt AD$M AGfB<ffDAG IwH{H[A\HA]A^A_]郗LeHLPFH}BGH{LHL牅(T(f(I~HIE1DžIvPDžAMD ftEEDHL AEEQ8D9Ey$AMIIAWE" D9uEWAE<<ELAM`oE`(AE)MIIEy(D)IIIiAD$DžDžftKH LAH89AH$HHHD AAUf.ff.ff.ff.ff.EI$LHHDA$HAAHHL NjAEQ8D9rEI(D)f.EUAtEA ELfAEftAMIH L AI89`AI$HHHD AA6fDff.ff.R$HHHDAuiHAAIHHNjADJ8D9rȋR(D)ÉIE9s EDAIA8LEHE9s EDA/E8HE@DžCDžAL[BDD(D Aff.1NfEI()IIJ f.E@()IIJ ^f.AG IGH9CL@EEEIu@CHsLkV@AG@8@8fIwH{H[A\HA]HA^A_]f.AOfDAOMg "fsLk OEEEIu@AAHALX^D@EHp@fu C9>tEZ@fA?1EрAG4fD1sAG@8u@8GAO@8IW AwAOHT2H{< CsH|H[A\A]A^A_]AG@8@8HsH]HHG?H}9@IHHH߉(K(IHALHAHSCsLl6IWAGAOLdIHsHAO>A9G$H(D@tPI~HMFPHH H(q8@9I$HHLD AFQfDff.ff.ff.ff.EI$LHLDAHAHHL NjAEQ8D9rEI(D)EFtDFMNHDMVPHI Fy89I$HHLDAIf.ff.ff.ff.v$HHLDAHAIHI4AD^8D9rŋv(D)EgL%>LIA[H>HHLLHAGtEoIvHDI~PHHAGJ89SR$HHHDAi Aff.ff.ff.E@$LHHDAH‹BIHLƋBEH8D9rE@(D)CtDcIvHDI~PHHƋCJ89R$HHHDA Mfff.ff.ff.ff.E@$LHHDAH‹BIHLƋBEH8D9rE@(D)A9GAD(D DAw'DEHDH(L0CHD@HAG;HD@M<A?jA"tA "f;>9CfA?A;GHC{H(IG6{EfftDS,IvHED[(KH IVPDA8E9ZI$ELHH< H DGA"DA9OKS  E1EDAEHDž`DHDLH(KH tH xHfHxQ=>9{VHA9s ADAE8HEH(A9s ADAA8HD(H(gH{HH[A\HA]A^A_]܇IA9s ADAWE8LEHA9s ADAE8HEnAOAG@88@8AC@H(PAH@H(DFEHvDcEH[EoEMI()HHL@YI()HHLR()HHHnR()HHHxsH{ LAOIW IvHIVPEHDž DžAEfftEG,DE_(H HH DI8E9I$ELHH< HA"9fHOAOcQEH DSfAtDcIvHDKHIVPHD@8D9@$ALHHDXE"DE9D@<M<EA?E1E_fAtEoDHH;fA?A?uAG[1JD ALHދ(L'IvHIVPE1PAH@H(D`EHX^DhELxsD@EHpIOI(DD)HHH< H3I(DD)HHH< H EwMg HsD(D f>9CosH @(AE)LHHMH x=(D)HHHV>A9Gd+DžftDK,MIkHHDI8E9I$EIIIA8At5eff.ff.$HHHр9u+IAHAIH H@$HHHр9t4^fDff.ff.E@$LHHЀ8u)HAIHLƋAEX8D9rE@(D)IHA9sA9ZE9IAfEt{IHkHHx89@$HHHр9t(RDff.E@$LHHЀ8u)HAIHLƋAEP8D9rE@(D)HHA9sA9CE9tHA?uA"EWA"HE_(ftA,HIHkHHy8A9kI$ELHHр9At5_ff.ff.@$IIIA9u)LɋADIAIHHƋx8A9r̋@(A)HLE9sE9kE98H0HйHйzHȾ HȿDS,E1DEH{ H(CDcEA?H[HSCsH\IWAGEwLdEoEM/DI(D)LHH@()HHH@()HHHsDA(DD)IIIJEG,EIG DaEHYEG,EIG DAEHAEPEIxH(DiELyW1D[(KE1Dž1ҋCEAOz%D""AHLJ"ADE1ɉ">ff.UHAVIAUAATASHt0APHIF`ADhD` H[A\A]A^]A"[A\A]A^]@ff.UHHATISHGHH_PHЋFJ89s:R$HHHAD$u<CujAo$ID$HC[A\]fR()HHHAD$tA$twID$HCttnD HCH([HCHpHxHCHx6vH{-v,D q HCH(HCHxl2H{u!HCH(f@HCH(HCHxH{su1fCo fHCH(WHCHpH@H HP0f@HCH( HCHx uHCHxtH{tff.UHHATSHGHHLgPHЋFJ89s:R$HHIAD$uID$HxR0I|$s!ID$H(fDID$H(ID$HxI|$ps1fAD$ ID$H(ID$HpH@H HP0c DID$H(nID$HxsID$HxrI|$rCDUHAUEATI̹SHH"""HLJ"D"A $<S<tofHE1ELH(#XH(t !"yHSHHH€HDH[A\A]]f~AAAAA lfElfA<$H(t !toH1[A\A]]DtL>fDD9A9fAL$F99NH(!HDLHAkX[?XA\A]]AHE1DL\AD$f>$o>9FAHDLHFqF>A9D$ELH!L@AHDLH褽H(E!AL$udfE^E1ELHa@]AD$OuSELH"DfE 두1҄t+ff.ff.H<@HuHHH<7H9HFHHAAA????HfInfEnfAnH ffEpffffpflofDofDofDoHfAfftftfDdfofA`fAhfDofDefDefDofEafAifDofEffEafAifEofEjfEbfDofDffDfEfDofEjfAbfDofEffDfDfAofAjfEbfDoffAfDofDffEbfAjfEfDfAfAfH9fofsffH~H9 Hr@HH9`JHr@HH9EJHr@HH9*JHr@HH9JHr@HH9JHr@HH9JHr@HH9JHr@HH9JHr @HH9J Hr @HH9sqJ Hr @HH9sZJ Hr @HH9sCJ Hr @HH9s,J Hr@HH9sR€@H@11~fff.?HAHE11Hցցցցց EA91f.Hсt]сtqсt:1AfAffDAFfDA&fDE1? EAvE1H1ff.HցtMցtQցtUցtYցt]xfEup1A9HDAAApA`E1S? 듃!A8HAE19sHE11@ff.HցIցYցiցyցEA9tf1ff.Hҁҁҁ tE1H1fHցցցցցE#A9u 9ILÉAfDApfDAPfDA0fDE1҃? EjAfDAAAAE1҃? EAif1fDA HȉHH D9rH}AILLADMAH}TEH}1HHEoXHU1LaXDMHULLEDHuDELMH}EĉƃHEH}LIM$1DHHLL)H)‰QH HHL9uH}I)I}ċDGLȉA97DM11Hfff.ff.ff.AEHL)H)AH HHHD9rHUI 9usH)HA9}HUHuHUHUHHL1fff.ff.D9HHLHFH L9uH}A HȉHEH1f. AIHHHЉCH M9uHpH}TH}AILLADMAH}8EH}1HHESVHU1LEVDMHULLEDHuDELMH}uă)X:*FXIX`\LU1LE1\LUH}11KDL]MEH HHH)HUHHuySHUEHڅt5HEM$^H H)BUąIO1HEALU1L1t15T 10)X*FX7]X[@ff.UHAWAVAAUATISHHH^t D9%MD$E^E1IEu)ff.IAE9HAHtމAxLHHAxH E9sdED]HN|Lr2HD(HL9t5KHʋHL N,LH HyHD(LHL9uD]KDHH Lff.HHHʉH uIAE9.HH[A\A]A^A_]AFƃEAljuH<H}HH}D)}<H=QHHD1H}HLHMN,L]O|2SUHuH#UH}LDEMLHuHEL]LK41HHH ЉAH H9uCHuDLL]PHML]LOHL1@ff.ff.DHHLH‰WH L9uH]AHЉH ODAAUIIHHA@H M9uHuNH}HH[A\A]A^A_]PHuDLL]AOHMEL]L,A벹k)X*FX7]X"Xk)X*FX7]X X1P UHAWAAVAAAUATISH_EL$HE,A.A۹ JtD)EDA9bf.EINt~C:JL1HHff.oDHH9uڃHHIHt!A J9sHAJ9s@ABL1DfPI|$EA\$HDwDt HtA\$H[A\A]A^A_]DE9EDHUăΉMHI9MMȋUHH I|$AL$WAJtDLA9@A 1D)E)DXLOLDff.ff.ff.ff.ff.A0DHDAD PL9uECtfDAEJt@fHLHHtA$MȋUĉ1M 1I1J ff.AHH9uff.t=2XU*X*FX`XHTv=WUp*X*FX8XHTHtHHHG1GøfU HSHKHHt"HCHDCHCHH]1L @UHATSHtlD%IWHu6DH:KHtfHCCDcC1[A\]DDfAuHH{HGG̹P*X*FX]XoS1K 1HCDUHAVAUATSHIHDvHAuSHAH[fAnfAnCBfbfCAD$CIt$NJ1[A\A]A^]D-%VE9DACƅt tDhADHJHHt(HC{0*X*FX39XrR1J 1HCyDUHAUATSHHHukEHE1HغAH[KHu؉DcDk0tU؈1H[A\A]]ÐHHHHƉEH EܸHHD%TAA9DBAADHHHHC<HMHxHHHLHLH) H)ƃ41ƒLL9rHtPD%7TA9DBE1J DU؉TTAs0*X*FX39XP I 1HCUHAUATSHHHEHAHAH[ADkHu؉DcCHMHxHHHLHLH) H)ƃr$1ƒLL9rff.1H[A\A]]uH tuAH@D-RE9ECAADHFHtsHCB fu#sU؈hAU؉TTF0*X*FX39XN1fG 1HCUHAUATSHHHEE1AH@H{D9ks*H9EHHH{CBHU؃sYtE؈Dk1DcH[A\A]]fHHHHƉEH EAH?I]@HMHHt HtHOHH)H)r1L:L99rsf.DHHt  1F AAcM؉TT9fUHATSHHHEAff.H!H{D9cs*H9jDHHH{CBHUsJtEDc1CH[A\]DuH iuAmDHMHHt HtHOHH)H)r1L:L99rDCHHt 71D XfDMTT6Ht3UHSHHHHtH9t\CHCH]fDUHSHHt#HHHt H9tCHH]C *X*FX]XVKfDUHAVAUATSHHHIH9tUDgH~D9fs*Et$ADHH9tEBHHtNH{DsIuBOBDcAEC1[A\A]A^]HBHHt13C H9t8oDHGHOWoFGDHFHNVH;wtH9tfHvHHFH9ufHtHGGGUHff.UHAVAUATSHHHIH9t$DoH~D9nr*It$B(ADkC1[A\A]A^]DEuADHH9tAHHt%H{DsDH@HHt1A qUHAVAUATSHHHDgIH9t'H~D9fr:IuBi@DcAECAtGA*EC1[A\A]A^]Et$ADHH9t;6@HHtDH{Ds@HCtA*ECH?HHt1@ zff.UHAWAVAUIATSHHMIHDg^IF8G5LGHND9rYA9DL OIEI1IIfD9`HI9A4A9sE9e]IuA9\MDLIIHiA9]I}HL9>HH A]EgA^IuINMGD9DEPH1E1Iff.ff.ff.ff.ELL)L)ЉH HHIH9uAD$HH|HLA9sAI1D)L LL)ЉH HHII9uAVHAUHTwft HtAEAFIE1AEAE1H[A\A]A^A_]A9܉I}ICA9MQM̃։UHI9 =M̋UHH{I}IvAUMOA9yEDAYIuDEIHE1DLDMIHvMOA9r/HLI1E1ff.ff.ELLH HI9rCHLDHtD9s(1fLAH HI֍D9rMu.AMAGH;HHtTAE)DYA9]s3DaMADHI9;MHHtI}EeD41< IALE11uUH;HHtAEM̋Uȉ(HE1DHME1LE1 AI1E1H:MHHZAE?A9]IuF)X*FX#XC)X:*FXIXCUHH0Hu3HHuEEHEHEHEf.HHHHƉEH t-EܸH?EHE@uHuEHEBøfUHAWAVIAUATSHHH!H 1_DfIIAF~D9ELCA8}GI~D9AWLM։UHI9h9ULMHHI~IqAVMMD9I1ɅtX11fff.ff.ELHȉH HH9rCHHtLDD9s(1fHAHHэH D9rHE~EUEV1H[A\A]A^A_]@HvMMD9;EuHLIDA%D9sIAI~LMAUDHL9#8ULMH IFE~A]EaIMMAA9ID9A}IvMͅLIAHDA܉D1E1IHDff.ff.ff.ff.E<LL)L)؉H HHIH9uAD$HH|HLA9sAI1D)L LL)؉H HHII9uAUHAVHTwft HtAFDA_A9^s9EgHMADHI9f6HMHHI~EfB AEI1EL1jDA1NIN<IMÅub@9%HI9A<A49sA}urIvE1E!FfDH5HHt;AULMZEUAuIvEHE1T16 HF5ULMHtSA=1QLIME1HDA܉mH4HMHHtA6 EAA}IvMDLE1HAE1IvEu\E1DME1LHE1E1^)X`*FX#X*HHI|$E|$HhB)xEt$AD$DsHh1BG<6+H{HhDHhDDtHDAw,ff.ff.AAt 0Ht쀽xDtHPHXLEHMH`xDtH{D9{s=AGHHHH9(HHHH{SHhB(xD{CA탭LH@H8H@H9LIE/A4AD{Hh1BG4?K*H{HhD8HhDDtHDAw&ff.ff.AAt HtHPHXLEHMH`DtHH`AdA1f.EMILN'HLHhDp)'HHED}ED9mL&HtnUHED}efH&HHHt(H&HHA$1' E1L1' EEH`E1~.H{HtH9t&EHCAH A9|ՋEHĨ[A\A]A^A_]1I' ODCE|$1HhG4DLB(HhHsDI|$DLHhDDtHDAw#+ff.ff.AAt HtHPHXLEHMH`DtCLH`E1s@(X *FXF6X-@(X *FXF6X-fff.UHH0Hu3HHuEEHEHEHEf.HHHHƉEH t-EܸH?EHE@uHuEHEøfUHAWAVAUATISH(HMjHH^DwIAEAAE9DAACֈEAAE΍L9M9Ml$A9\$sTD{LMAHMDDEUHM9L#UDEHHMLMIMl$E|$E1fDHG8?ID$1A\$AD$1H([A\A]A^A_]D/D{LMAHMA9DEDBUDH"UDEHHMLMI1LLMHMDE$HMLMLDEHyIqDI|$I9tI9t"Ml$E|$A\$IDw&ff.ff.t Htu@8ufDIA0 H "UDEHHMLMItA$AEi11# )X*FX#XU*DUHHAWAVAUIATISH8H]EAHdM[DQA`AE9DAACЈEL9pMt$A9\$sTD{HMADUDUDEHM9L!DEUHDUHMIeMt$E|$E11LHMDEDU"HMDELHuHyM)I|$I9tI9t Mt$E|$A\$IDwCfff.t HtD8mUDHHHHƉEH EAI?HA8ID$1A\$AD$1H8[A\A]A^A_]D+D{HMADUA9ljUDBDEDHDEUHDUHMI1 덐uȅ^A5H=DEUHDUHMItA$A@1)X*FX#X'f.UHHHAWAVAUATSHHHH?IHIH9t+DwH{D9srBIuBDsAECDH*ti1H[A\A]A^A_]DE~ADHH9tgHHt%H{D{DH(HHt1C 뒹)X*FX#X&fff.UHAWAVAUATSHHuIHiGHDhABH9L~9^s>DsH}ADHM9LHMHIM|$Et$E1A1LHMDmHMLHyQZI|$I9tI9tVM|$Et$A\$IDwfDt HtA\$1AD$H[A\A]A^A_]fD5(H}D9DCDHHMHI@1 fDHpHMHItA$A1sx)X*FX_X$UHHAWAVAUATSHHHH(H9HGII͈'Fv&/ WID$9rV9; L_AN MI I1IA9 HL9b EA D9sL&fH0HPHDžp)0)@)P)`DžpHH8L@HXL`NH41(fDff.ff. H9 D8HEtH(LHH I9 HHttHHILLLM L9 LLLLtLHAB@@Eb EA)ǃXEt$E1HHHHH@x[fDAyDLLDL(HLDLE9rtIzE9rsiAD$LDLHHI9'LDHLHIzAJBEr HAH{9CsfDaLADDLH4H9 LDHLHIHHxD` fLeEOHHHEHE)E)E)E)EHEHEL]LeL]AvVAWDDLIHLDHDHEDu[LMrIc1DHDLIvELDDLDL)DHHLHDIHHH)LAHBHHLLMHHLAHLHHH AA49H}H 1HHNH9HGEa E11fDff.ff.C4!HHB'IH I9uHHt7HHtHDUDHHDff.t D.HEtUD@E IEt9P9A9 IM,1ff.ff.ff.DE!HIMM)I)DAI LHL9uՍJILD9sGD A)NDff.ff.HLH)QH HHL9uHL1HUD ELLHDII9LDDLHUDDMHDAw'1Dff.ff.AAt D HEtAJIRDMHHTw!@ff.t HtABE HLL HH}D]LE~71LeM։I|$HtL9tID$I ;]|MEąH'DžtxXd&8'ABAzH(Mp~DHE1ff.H{HtH9t pHCAH A9|ҋtgf.ML$A`GuPMtL H(tH(HCCC1HH[A\A]A^A_]ÐL_LAfDMtIEAEAEH(HtHCCC&@8'tC}fwttD˅H(H^HHtQMLt&H(Ή肱AEQ9rFAUIu!AUHHTw t DHEtAE'A]H(t?H(&8'@xH(Ht[LHLtp:@fDMLTtHHH"HHIڅtLPHLHLLtdmDH(Hǯ&@8'C{H(H|t! DDD`LADL4LLDHDH<DHEDe@@ukALE1N,I܉N4/IMA9IM9G CtD9sL@ff.HPE1HD1ff.ff.G!MLB'IH I9uHt LADULDDE0IEtU9HgHE11AG!MLB'IH I9uHt LADULD Dt E(IEtU9?P)XK *FX $XEHu@EIEDEuAEH(jH(&8'@xH/H@u H(@LL(H(LtW[ALE1N,IHN4/IMA9r*IM9t!G CDD9sLHLH9bA1N,IN4/IMDE97HI9*E 6ED5E9snLXfH0HPHDžp)0)@)P)`DžpHH8L@HXL`A11ۃ|DIBDEAB9A9)X:*FXIXt@H@H@~H(H@8bH(@RH@0H(@Hg LDHLH9HHMBH@8DILEH1L @ff.ff.ff.ff.ff.H H H9rkH1HHAHI9uABIIDAwAAt D0HEtEbHLCLHL9tH: LDHLHt A-16 pDžtLDLILL L UEI1L L ǹ`)X *FX#X1P)X *FXiXP)XE *FX.aXIUfHAWAVIAUIATSH]IHHH9H)ELE1HE)ELEH]HEEAąAOAM'M9tdI~A9Ns7DiMADHL9yMHHI~EnIwM?MANAGAFDeċE~3E1H{HtH9t=EHCAH A9|DeHHD[A\A]A^A_]IG)ALLLEA{HHHt AM/1A Bff.UHHH?HAWAVAUATSHHH9„TIHHIIHtoH9t_DH{D9{s4AW։UHH9UHHH{SIuBD{AECDHM|LLDPA9T$rYAT$It$D!AT$HHTw'f.ff.t HtAD$1H[A\A]A^A_]HUHHt 1  빹@)X{*FX`$XW UHAWAVAUATSHxH`HIH{fHEHEI)EHEH!)EEHEHKDoAH}It$B5AD$H`H}DmEEHEHEHxDžxEHE*EAADuD%AVD<lE9ECDHlHHX1HH}DH荰H}H9tHEH9tH]DeDD}HDAw&ff.ff.AAt HtD}EEA#H`HuHpEąu AEH]E1~-fH{HtH9tEHCAH A9|ՋEHx[A\A]A^A_]AU׉lHXHHt/lHEUE1ED}E41J EH|艤()X*FX `X UHAWAVAUATSHxH`HIHfHEHE)EHEHT)EEHEH,HHHHljEH EH?ICHHiEHEH}%tEHuEH`DeHEHxEDžxEHE EAADuD% AVD<lE9ECDHkHHl1H|H}DHmH}H9tHEH9tfH]DeDD}HDAw&ff.ff.AAt HtD}EEA#H`HuHPEąu AEH]E1~-fH{HtH9tEHCAH A9|ՋEHx[A\A]A^A_]HUH}E1EHLHLH1AN N 9rE1ED}EEDD 1 EN?)X*FX `X(HUYDUHHAWAVAUATSHHHPHH`HH~fHEDgHE)EHEH)EEHEAH}HsBCHPH}DeEH{EHEHxDžxEHEںH`HDžHHLH`HHDžh H@D$ȃ\fAAuH`\9HDu AVD<lA9AC߉HlHId1HH}DLH}L9tHEH9tLm]DD}IDAw' fff.ff.AAt Ht샭hD}EEH`HHHH;AEH]E1~.H{HtH9t=EHCAH A9|ՋEHĘ[A\A]A^A_]El$ADHHHt>HEDmHPHuH-EąL\E11 E;p(X*FX#XfHHDGD:FtE@OF9rN9rbLOHIHVHׅt^HH419r,HH9t;A 9sEDED11fUHqHt~HtyOV9r\9rSLGH~HIHׅtBHH419rHH9t#A 9sff.1UH@Ht(tu@HW1uUHf.UHHH HH?:WtHHHHOEwltHHHLD1L 1@9r[HL9ts4A 9sɄDɸfH؉EH t:EO9r9sDH]11뜸ǹ(X*FX]Xf.UHHHH|uH tzuW9r[9rRHOHHHt1HL1f9r,HL9t3 9sɉEfɹ1ɉù`(X*FX]XUHAWAVAUATSHHIHIHIHRIA~A~1H` HHHuHMH`EHhHpHuHEHMHEEM9LM9CLXHLLpEąuUE1~9ff.H{HtH9tUHCAH A9|ՋEHĘ[A\A]A^A_]É׍BLXHHHPH@HPHhXpLHMHHEXEEM9t M99Us9H׉XHqXHMHuHEU0EHXIL$ A~IFfDAD$UH}D<D9s;DHEHHPH9PHHH}UID9s@AGHH4HEPH9PHHH}UB1BDD}HU1LH EąAVIvLELLXHMEąLLHE{HPHHt*EHPHHt(EB1 E1 5H(X*FX$XUHH0Hu3HHuEEHEHEHEf.HHHHƉEH t-EܸH?EHE@uHuEHErøfUHH0Hu3HH}EEHEHEHE,f.HHHHljEH t-EܸH?EHE@}H}EHEøfUHAWAVAUATSHxHxH:IH.IH"MMRI<A|$KA|$fH]HMHzHE)E)E)E)EEH]HEHMHEALhItLfHZtM9HELhUM9MHLLEąUE1~9ff.H{HtH9t-UHCAH A9|ՋEHx[A\A]A^A_]M9tM9uI냐IM tA|$ID$AT$It$MLLxHAEąALL蛭E.LLht+tLhHMHtHEUM1, E (XB*FXJXlff.UHH9HAVAUATSHH GDvIH~D$E9s,DIHH9HHH{DsIE9s*At$IHH9tpSHHH{DsB1@BDDcHLH1[A\A]A^]HHHt&uHHHt!1 [A\A]A^]1 녹(X]*FX$X@ff.UHHAWAVAUATSHHHXHIHFI1L}Lm H`H`HHHLEHhHpL}HELmHEEątKEE1~,H{HtH9tEHCAH A9|ՋEHĈ[A\A]A^A_]LL襪EąuLhtƅxEAhmL1@ff.AH tuff.tHM}E1u&AHA tufff.AtA9HANAԉ։PDLLAL輩}Le*EEEA$HWD E|HXL`u>HX@1f.ID$8HXL"t¸R11 EHߨEąLe}A$DLȋDuA}HhD9psDAV։THH9/THHMLeHhpBLEDtxLLHEEąLe}A$L fPH tDtA $EH}EEEHU@ff.)ˆU&1xLXHLtEąPLk fDH}D9us:AV։THL9t}THHLeH}UBLdEDuEA?!f.H(THHf`HTHH?EzA1E1%11XA4$t5*EEEA$1HVDEoEA$'X*FX#XUHHAWAVAUATSH8HHHHHL IH L  F1!HHHHL@HHuH`LHHLuHLL HHPHpHEHuLHEHEHLL(LHHhLuDžDž H0`EąuiHH`FEąuOHHTƅXƅx1vWH tbEfDEE1~/H{HtH9tEHCAH A9|ՋUH8[A\A]A^A_]fDHWDEAHHHiHCHHHCCC71nHH@0HLuHHH@HHGHC1CCDfDtHhtTuff.WH tufff.t9LNSH`ALLEąHuH`EąHHTHTtlH1H<ȋ HBH9u싕THHTw%fff.Z HtꉅTLAu HtLHHuHLEąAHLHEą$HLHHITtnH1L :HBI9u싕HITw%fff.DHEt艅HTtqH1Lf.:HBI9u싕HHTw%fff.D HEt艅HF8k.HhHftHTtmH1L:HBL9u싕tHHTw%fff.t:Htꉅtu H(tHLHuL4Eą)LLLEąHhH(HHTtzHE1L ff.DDHDBL9u鋕HHTw"1fDff.DHEt艅4HTtqHE1L fDDHDBL9u鋕4HHTw"fDff.<DHEt艅4X:xvLH`L茦EąHLHsEąHLHVEą{HHTnfHHL0Eą5HH`eHH`EĉDžtDEƅxzfDDž4ƅ8DžDEƅ $fDh1DžTƅXDžDEƅDžEE>ƅ2H`LHzEąLHLaEąLHLDEąd@Tt9v9rLHHA`ÅuA+A-1AGAЃ0 LFfDMo*^*XX~H,HHPA9W6AGIEAEA6HE@D@GЃ `@0D9EWEK|LE1HHL؉BH IH9uHCDAGPAWE]H}BHcIAUI t*DPHKtHLډPH IH9uJ|MIAGA6@AWHITwM HtAGHEHtL0A>H([A\A]A^A_]0D9;3IHMA d}T}pD9@HM4EWErAELcI}IøAUI fAvI@fAGiHMHHUM9tiLAUHMHItrMoAWI#AGAEAGIHUHMHIt AAE1 i_ 'X*FX^X 'X*FX%Xfff.1fHtLGHOt'PЋt҃ )@t1҃ )fUHFlfDUHATSHHHHwIHUHMAH!lA|$tH[A\]@HcExHcHH)HڹHfDHȉBfH9uH[A\]ù&X1*FXL9XUHAWAVAUATASHHHEIHBLGIHHH9GAAD$AGAGA}"EDeLLKL5EMHMLmMff.AAN<B|?MgAD9JsQEYHUALUDD]DMHH91DMD]HLUHUHHzDZtmIHE1Dff.DDHDFL9uAtFDDL$ZIw@t A$ItZAA EIHEI9tDHzZHHDMD]HLUHUHt22zLmLceEte1HH[A\A]A^A_]1HU#HU k@XHL9LIHMGA_HcKt%LH)DHȉBfH9u`IcAGHcȾI|LH)fHֈQfH9uMGA_HIHt AAU15 &X<*FX%X|ff.Ht^GHOt?PЋt ҃ )Љ…~Hʃ9‰tUHg@UHHUHtHtGHHMHE1gù&Xi*FXL9XUHAWAVAUATASH(HEIHBHIHHHA9FqMAFAFff.AAJ|LjAE9FsMAHLMDEĉΉMHUHL9eHUDEHMLMHI~ANt`H41HDȋ HBH9utB DDL,A^J/wfDt HtA^AI M9t;A^fHHUDEHMLMHt"AM1H([A\A]A^A_]1I~ @XHI9tRHHt$I~A^dHHHtA1/ 넹&Xo*FX%XyfHt\GHOt7PЋt ҃ )Ѕ~f.tDUHdfD@X-t2t't.t/t0t IXHDøIXøkXøVXøgXø%>Xø&^Xff.UHAWAVAUIATSHHM+IHFH8GDg^I}A9AECE9}s=AWHM։UHI9tUHMHHI}AUHIIVA9HGHH)HH)H*1Hff.ff.oofHH9utYAۉAED)J4L7L 2H΃t*B~B~ ffBtHIIHA ACHH|HTD9D)ލFCA9HGH)H1Hfff.oHH9uHHHЃt SD9sPWD9s@GE}AFAE1H[A\A]A^A_]f.EHHHDA61ff.4 44H9rf.1ff.ff. H D9rQfHHHt%AEUHMIIHE121 AH1Zp&X7 *FX#X4@UHAWAVIAUATSHHMgIH[FH8GADDfI~E9DACA9^s2-蟓 "f{1{UHHHHATSw$Ű.X@E19AD[A\][A\]@[ADA\]f.E1[0 ADA\]E1[0 ADA\]A_yډWgSE1 AUDE1_Dډ"2SE1 A [A\]D@E15[ADA\]ADUHAWAVAUIATISHHD:SXF<uA$A}@t;HIHs<w $0/X@@19Duff.E<$E1HD[A\A]A^A_]K;f@_tDDΝuA~Ѓ v!fDA@_DD芝A~Ѓ U01 001  K;fDL;LsH LLHWA\AEDLDEDEȅIuLHDEȅA$ @HC A $AUMHEHLsMĉÄu*fIA$At:LUu*H}LLIA1A,$M9s؋EE1A$HC AULsMHEHÄufDIA$AtLuM9rA,$M9H}LLIAtE1A}Af.UHAVAUATSHtR?IHIAuT@Ht0LHLAt݄t[DA\A]A^]DA[DA\A]A^]fDHG[AADA\A]A^]fUHAVAUATI(SHH讍A $IńfL111MAQ܀:w$հ/XfDAAHHcA initial_slots=%u, f->actual_slots=%u args_not_sufficiently_instantiated4nXaX?mXdXoX%aXaXzmX4mXlXwrapper: not found struct: %s Error: ffi_prep_cif status=%d Warning: struct ptr->ret_type=%u @DDDDDxDhDXDxDDhDDXDD`DPDDDD DțDЪDDDDЪDDDDDDDDDDDDDE^E@E@E@E@E+EEE^E+EEEEEPE{EEE@E@E@E@E@E@E@E@E@E@E@E@E@E@E@E@E@E@E@E@E@EXE@E@E@EXE@E@E@EXE@E@E@EXE@E@E@EXE@E@E@EXE@E@E@EXE@E@E@EXE@E@E@EXE@E@E@EXE@E@E@EXE@E@E@EXE@E@E@EXE@E@E@EXE@E@E@EXE@E@E@EXE@E@E@EXE@E@E@EqE@E@E@EqE3 E E E3 E E E E3 E E E E E3 E3 E E Eh Eh Eh E_EEEE_EEEE_EEEE_EEEE_EEEE_EEEE_EEEE_EEEE_EEEE_EEEE_EEEE_EEEE_EEEE_EEEE_EEEE_EEEE_EEEExEEEExEExEEE0E0E+EEeExE+EEESE0EEEEE0EZE0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0EPE0E0E0EPE0E0E0EPE0E0E0EPE0E0E0EPE0E0E0EPE0E0E0EPE0E0E0EPE0E0E0EPE0E0E0EPE0E0E0EPE0E0E0EPE0E0E0EPE0E0E0EPE0E0E0EPE0E0E0EPE0E0E0EPE0E0E0EE0E0E0EE2E EHEXE(E EEE8EEHEEXE8E(E E EEEE(!EE#ElEEEEEEElElEEEEE7EEEEE0E_E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0EE0E0E0EE0E0E0EE0E0E0EE0E0E0EE0E0E0EE0E0E0EE0E0E0EE0E0E0EE0E0E0EE0E0E0EE0E0E0EE0E0E0EE0E0E0EE0E0E0EE0E0E0EE0E0E0EE0E0E0EE0E0E0EEE_E_E_EE_E_E_EE_E_E_EE_E_E_EE_E_E_EE_E_E_EE_E_E_EE_E_E_EE_E_E_EE_E_E_EE_E_E_EE_E_E_EE_E_E_EE_E_E_E`E_E_E_EE_E_E_EE_E_E_EE_E_E_EE#E!E EhE!E!E EhE!E!E E EhEhE!Ee"E!E>, %s:%d Error: syntax error, unexpected term %s:%d Error: syntax error, mismatched parens/brackets/braces, %s:%d mismatched_parens_or_brackets_or_bracesError: syntax error, operator expected unfinished input '%s', %s:%d Error: type error, not callable, %s:%d Error: syntax error, needs operator '%s', %s:%d Error: syntax error, quotes needed around operator '%s', %s:%d Error: syntax error, parens needed around operator '%s', %s:%d Error: syntax error, missing arg '%s', %s:%d Error: syntax error, missing element '%s', %s:%d Error: syntax error, parsing list '%s', %s:%d Error: max arity reached, %s:%d Error: syntax error, parsing '%s', %s:%d Error: syntax error, start of rule expected, %s:%d Error: syntax error, var as functor, %s:%d Error: syntax error, incomplete, %s:%d Error: syntax error, incomplete, needs parenthesis, %s:%d Error: syntax error, near "%s", expected atom, %s:%d Error: syntax error, near '%s', expected, %s:%d Error: syntax error, near '%s', operator expected, %s:%d goal_expansion((%s),_TermOut), !.Error: instantiation error, goal_expansion/2, %s:%d Error: syntax error, missing operand or operator, %s:%d :TTTTӿTCT[%u:%s:%lu:f%u:fp%u:cp%u:sp%u:hp%u:tp%u] resource_error(memory). %%query terminated mXmXmXmXmXd@9B.Action: ENTER,. abort - abort current query a abort - abort current query c continue - resume current query e exit - exit top-level t trace - toggle tracing (creeping) g goals - show goals s statistics - show stats h help - display this helpAction: ENTER,. abort - abort current query e exit - exit top-level t trace - toggle tracing (creeping) ; next - display next solution f digit - display 5 solutions # digit - display # solutions a all - display all solutions s statistics - display stats h help - display this help VVVVVVVVVVVVVVVVVVVVVVVIVVVVVVVVVVVVV VV8V8V8V8V8V8V8V8V8V8VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV8VVVVPV8VVVVVVVVVVVVVAVVVVVVa != NULL && b != NULL && c != NULLa != NULL && c != NULL && p2 >= 0a != NULL && b != NULL && q != rs_ucmp(TEMP(1), &r) <= 0 && "The mathematics failed us."a != NULL && p2 >= 0 && q != ra != NULL && b != NULL && c != NULL && m != NULLm != NULL && c != NULL && m != ca != NULL && b != NULL && c != NULL && (x != NULL || y != NULL)a != NULL && m != NULL && c != NULLa != NULL && c != NULL && b > 0z != NULL && str != NULL && limit >= 2radix >= MP_MIN_RADIX && radix <= MP_MAX_RADIXz != NULL && buf != NULL && len > 0mp_int_to_doublemp_int_msbmp_int_lsbmp_int_popcountmp_int_andmp_int_xormp_int_ormp_int_read_unsignedmp_int_to_unsignedmp_int_read_binarymp_int_to_binarymp_int_count_bitsmp_int_read_cstringmp_int_string_lenmp_int_to_stringmp_int_to_uintmp_int_to_intmp_int_rootmp_int_is_pow2mp_int_lcmmp_int_egcdmp_int_gcdmp_int_invmodmp_int_redux_constmp_int_exptmod_knowns_qsubs_embarmp_int_exptmodmp_int_compare_uvaluemp_int_compare_valuemp_int_compare_zeromp_int_compare_unsignedmp_int_comparemp_int_expt_fullmp_int_expt_valuemp_int_exptmp_int_div_pow2s_udiv_knuthmp_int_divs_ksqrmp_int_sqrmp_int_mul_pow2s_kmulmp_int_mulmp_int_subs_usubmp_int_addmp_int_negmp_int_absmp_int_zeromp_int_copymp_int_freemp_int_init_copymp_int_init_sizemp_int_multiply_thresholdmp_int_default_precision?=p0??h4?:F2?R:?TUU?=p0?8PD? ?E3?+cK?h?? ĝa??Yk~P?x,?B!? ͝? xL$?9z4?=SZK?h?h4?:$@C;?uo?<8?)ma0Y??<0??Q,_?DPz(?#kj?rG2?? !??mp_rat_freeWWWWWWWWWWWWWWWWWpWWWWWWWWWWWWWWWRWWWW>WWWWWWWWWWWWWWWWWWIWWWWWWWWWWWWWWWWWWW7WxWWxWxWxWxWxWxWWWWWW8WpWW0WW0W0W0W0W0W0W0W WWWWWWpW@WWWWWWPW`WWWpWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWHWWW0WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWnXjXnX9WXmXmXmXv]Xr]XjXjXjXjXg]Xc]XhXmutex_unlock,not_locked_by_memeta_predicate(retractall(:))meta_predicate(clause(:,?,?))meta_predicate(call_nth(0,?))meta_predicate(bb_b_put(:,?))Warning: struct ptr->type=%u Warning: overwriting '%s'/%u Error: uninstantiated: %s/%d +term,:callable,?stream,+list+source_sink,-string,+optionsmeta_predicate(retract(:,?))meta_predicate(catch(0,?,0))meta_predicate(assertz(:,-))meta_predicate(asserta(:,-))Error: unknown value, %s:%d Error: file not found: '%s' Error: end of file on write , local=%d, temp=%d, anon=%d'$predicate_property'(%s, %s%*c%llu,%ld%*c%ld,%lg,%127s -t, --trace - trace mode -q, --quiet - quiet mode -d, --daemon - daemonize meta_predicate(clause(:,?))meta_predicate(bb_put(:,?))meta_predicate(bb_get(:,?))SSL load certificate failedMP_SIGN(TEMP(0)) == MP_ZPOSError: syntax error, %s:%d :callable,?term,?term,?term$legacy_current_prolog_flagvariable_cannot_be_functormeta_predicate(retract(:))meta_predicate(assertz(:))meta_predicate(asserta(:))meta_predicate(abolish(:))Info: created module '%s' ?integer,?integer,-integer/usr/share/trealla/library+predicate_indicator,-list+predicate_indicator,+atom+integer,-integer,-integer%*c%llu,%u%*c%u,%lg,%127s $legacy_predicate_propertythresh >= sizeof(mp_word)meta_predicate(ignore(0))meta_predicate(if(0,0,0))meta_predicate(((:)|(+)))integer_rounding_functionError: unknown op, %s:%d :callable,?term,:callable+stream,-integer,-integer+source_sink,+source_sink+integer,+integer,-string+callable,?atom,?callablez != NULL && old != NULLz != NULL && buf != NULLwrite_canonical_to_charsunterminated_quoted_atominvalid_quoted_characterinput,past_end_of_streamillegal_character_escapeaccess,private_procedureWarning: register structError: not found: %s:%d +stream,+integer,-string+source_sink,-list,+list+source_sink,-atom,+list+number,+number,-integer+atom,-compound,+options%% %s/%u: %s(%s)%s%s %s $capture_output_to_charswrite_canonical_to_atomset_priority,not_threadno_such_thread_or_queuemodify_static_proceduremeta_predicate(time(0))meta_predicate(task(0))meta_predicate(once(0))meta_predicate(call(0))meta_predicate((0*->0))Error: no memory %s %d Error: can't chdir(%s) :callable,-thread,+list+term,+atom,+list,+atom+string,+string,?string+stream,+atomic,-atomic+stream,+atomic,+atomic+atomic,+atomic,?atomic'%s/%u',%llu,%llu,%llu $capture_output_to_atom$capture_error_to_charspl_thread_set_prioritymeta_predicate(task(%dmeta_predicate(call(%dmeta_predicate((0->0))a != NULL && b != NULL+term,+atom,+term,?any'$op'( (%s), %s, %u). '$op'( '%s', %s, %u). $capture_error_to_atomprocess_create_optionmeta_predicate((\+0))meta_predicate((0;0))message_queue_destroyinvalid ret_type: %s float_fractional_partcrypto_n_random_bytesargument out of range?string,?string,+list:callable,?term,?term:callable,?term,-term+term,:callable,-list+stream,-string,+list+source_sink,-integer+atom,-atom,+compound+atom,+atom,-compound*** struct to ptr %u '$op'('%s', %s, %u). %s:'$z_'((%s),'%s'). %s:'$a_'((%s),'%s'). %s/%u: %s(%s)%s%s %s %% Execution aborted $retract_on_backtracksrc/bif_predicates.crepresentation_error$read_term_from_charsoutput,binary_streammessage_queue_createis_list_or_partial_listincomplete_statementenvironment_variableatomic_list_concat/3answer_write_options?integer,?atom,+atom?atom,+atom,+integer:callable,?term,term+atom,+list,+options%% %s/%u: %s%s%s %s $current_prolog_flagwrite_term_to_charsunknown result codetime_limit_exceededthread_send_messagethread_peek_messagesrc->tag == TAG_ENDsmall_integer_rangeread_term_from_atomread_line_to_stringread_file_to_stringprolog_load_contextprocess_wait_option+atom,+predicate_indicatorlist_or_atom_or_varuninstantiation_errorinput,binary_streamget_unbuffered_codeget_unbuffered_chargenerate_debug_infoatom_or_list_or_varatom_or_list_or_nilSSL_connect failed ?term,?term,-string?term,+list,?string?string,?term,+list:callable,:callable,:callable+string,?term,+list+stream,-term,+list+stream,-list,+list+source_sink,-float+list,+list,-atomic+atom,+symbol,-term%016lx-%04lx-%012lx$register_predicate$det_length_rundown Action or (h)elp: write_term_to_atomuse_foreign_modulethread_get_message$predicate_propertypin_cpu,not_threadoutput,text_streamoperator_specifiernot_less_than_zerometa_predicate(%s)meta_predicate(%s(iso_list_or_nil_or_varfloat_integer_part$legacy_evaluable_propertycreate_prolog_flagcannot_open_streamatomic_list_concatUPPER_HALF(w) != 0SSL_accept failed @callable,-integer:callable,+integer+source_sink,-list+source_sink,-atom+source_sink,+atom+rational,-integer+integer,:callable+integer,-compound+compound,-integer%% %s/%u: %s(%s)%s%s $struct_to_pointer$is_partial_stringworking_directorysrc/imath/imrat.csrc/imath/imath.csrc/bif_threads.csrc/bif_streams.csrc/bif_control.csignal,not_threadreposition,streampl_thread_pin_cpuoperator_priorityoperator_expectednot_less_than_onematrix_dimensionsinput,text_streamimported_from(%s)illegal_characterdetach,not_threaddestroy,not_queuedestroy,not_mutexcurrent_predicatecould_not_connectcharacter_escapescancel,not_threadascii_punctuation@integer,+integer?term,?list,-term?atom,?term,+list-integer,+integer, slot=%u, ctx=%u+thread,:callable+stream,+compound+integer,+integer,-integer+integer,+integer+callable,?string+atom,?term,+list+atom,+list,+list+atom,+atom,?atom%s/%u: %s%s%s %s $unattributed_var$succeed_on_retry$register_cleanup$integer_in_radix$gsl_vector_write$gsl_vector_alloc$gsl_matrix_write$gsl_matrix_alloc#%llu,%ux%u,%.1f too_many_threadstoo_many_streamssize_a >= size_bpositive_integerpermission_erroroutput truncatedopen,source_sinkmutex_unlock_allinvalid argumentinteger_or_floathardware_threadsformat_characterexists_directoryevaluation_errorcrypto_data_hashchoice_constructin_character_or_varcannot_open_filea && b && m && cTPL_LIBRARY_PATH?integer,?string+thread,+integer+string,?integer+string,-string,+stream,-integer+stream,+integer+character,+term%s:'$e_'('%s'). $post_unify_hook$load_properties$list_attributed$gsl_vector_size$gsl_vector_read$gsl_matrix_read#%llu,%ux1,%.1f write_canonicalunexpected_charthread_propertythread_or_alias$stream_propertyset_stream_positionstream_or_aliassmallint_or_varposix_localtimeoperand_missingmodify,operatormissing_elementjoin,not_threadis_partial_listexistence_errordirectory_filescreate,operatorchar_conversioncallable_or_varatom_or_integerargs < MAX_ARGS@variable,-term@variable,+term?string,?string?number,+number:callable,?term?term,+list,+string,-string+stream,-string+number,+number,-number+integer,-codes+float,-integer+chars,-integer*** OOPS %s %d %1023[^/]%4095s$stream_to_file$duplicate_term$cleanup_if_det$capture_output$attributed_varError: write_csv_filevariable_namesterm_expansionstart_expectedresource_errorrandom_integermessage_queue_propertyqueue_or_aliasprocess_createposix_strptimeposix_strftimeportray_clauseparse_csv_lineparse_csv_fileoperator_clashno_such_threadneeds_operatormutex_propertyinteger_or_varinitializationin_byte_or_vargoal_expansionforeign_structfloat_overflowengine_destroyeafbtvrnsd'\"`current_outputcurrent_modulein_character_codebegin_of_file.?list,?integer?list,+integer?term,?atom,?integer+source_sink,--stream,+list--consult-file+number,+number,-float+list,-integer+integer,+integer,-list+integer,-atom+integer,+term+-*<>=@#^~\:$.%% %s/%u: %s%s%s %255[^:]:%255s%255[^,],%s255%% %s changed $skip_max_list$reset_handler$fail_on_retry$capture_error$cancel_future$block_catcher  '\"`thread_signalthread_detachthread_createthread_canceltemplate('%s'string_lengthstring_concatstream_optionsrc/network.csrc/history.csrc/compile.csrc/bif_csv.cserver_failedquotes_neededposix_getppidparens_neededoutput,streamnumber_or_varnot_an_enginenot availablemutex_trylockmutex_destroyhttp_locationgraphic_tokenfullchain.pemexpected_atomensure_loadedengine_createat_end_of_streamdump_attvars_double_quotesdiscontiguoushexadecimal_digitdcg_translatecurrent_inputcurrent_errorcopy_term_natbegin_of_fileatomic_or_varatomic_concat?thread,?term?string,?string,?list?number,?list-thread,?term, slot=%u, %s+thread,-term+thread,+term+term,-string+string,?term+string,-list+stream,+string,+list+stream,-term+stream,-list+stream,+term+stream,+opts'$thread'(%d)'$stream'(%d)%% %s/%u: %s $drop_barrier$call_cleanup!(){}[]|,;`'"zero_divisorwrite_optionversion_datatoo_many_opsthread_yieldsystem_errorsyntax_errorstrip_modulestring_upperstring_lowerstring_codessrc/prolog.csrc/parser.csrc/module.csplit_stringrandom_floatprocess_waitprocess_killposix_spawnpposix_mktimeposix_gmtimeunify_with_occurs_checknumber_codesnumber_charsnot_a_streamno_recov=%d mutex_unlockmutex_createlist_or_atomnot_sufficiently_instantiatedinput,streamin_characterheader_errorgreater_zeroflush_outputerror code 0engine_fetchend_of_file.domain_errorcurrent_ruleclose_optionatom_or_list[%u] tag=%u QUESTIONMARK?queue,?term?mutex,?term.tpl_history-queue,+list-mutex,+list--query-goal+queue,?term+queue,+term'$queue'(%d)'$mutex'(%d)'$alias'(%d)$make_string$jump_if_nil [EVALUABLE]version_gituser_outputtoward_zerothread_selfthread_jointhread_exittemplate(%ssre_compilesrc/terms.csrc/query.csrc/print.c-atom,+source_sinksource_inforename_filerelative_toread_optionset_prolog_flagprivkey.pemposix_ctimeoctal_digitoctal_charsmodule_infomodule_helpmodify,flagmin_integermax_integeriso_list_or_variso_list_or_nilline_countslibrary%c%sexists_fileenvironmentengine_selfengine_postengine_nextend_of_fileempty_list1denominatordelete_fileacyclic_termcannot_readiso_atom_or_varatom_lengthatom_concataccess_fileabort_error:atom,?term,?term?term,+term?list,?atom?atom,?list:atom,?term:atom,+term-list,-blob, ground=%u+integer,+term,?term+term,?list+term,+term,-list+atom,+term,+term+stream,+term,+list+term,+atom+integer,+atom,+list,?list+blob,+atom-thread,+atom,+list'$blob'(%p)%255[^:]:%d$undo_trail$set_if_var$set_future$redo_trail$record_key$mark_start$load_flags$cut_if_det$create_var$clone_term$call_checkwrite_termwhitespacevar_prefixuser_inputuser_erroruse_moduletype_errorterminatorsub_stringstatisticssre_substpsre_matchpsrc/heap.cterm_singletonsset_streamretractallposix_timenumbervarsmutex_lockmax_queuesmap_createline_countlibrary/%serror_incompleteignore_opsflag_valueeof_actionnon_empty_listconcurrentchangeablecarry == 0atom_charsarithmeticalphabeticNOT_WHITESPACEINV_CHAR_CLASS:%u/%4095s--watchdog, (%s))). '$map'(%d)$put_chars$ops_dirty$get_chars$dump_term$directive$code_typez != NULLwall_timeterm_variablesv%u.%u.%uunifiableresult undefinedtimed_outtime_fileterm_hashstructuresre_substsre_matchsize_fileset_errorrow_arityread_termz != NULL && str != NULLmodify,static_proceduremeta_predicatepositionsportrayedpeek_codepeek_charpeek_byteparse_urlnumeratornot_a_mapmultifile$memberchkmax_depthmap_countmap_closeis_streamhex_charshex_bytesglobal_bbis_absolute_file_nameexceptionevaluablemake_directorydate_timecpu_countcopy_termcopy_file?characterchar_codea != NULL && c != NULLbb_deleteattributealgorithmaggregateOptions: INFO: %s @variable+atom,:callable--restore--consult, (%s)). $xlisting$readline$load_ops$countall~/.tplrcvarnamesv2.89.13type: %struncatesub_atomsmallintskiplistsize > 0set_seedsavefile+integer,+integer,-rationalqhat > 0put_codeput_charput_byteput_attsprotocolpositiverepositionpopcountmap_listloadfileiso_listiso_atominternedinstanceinfiniteindirecthttps://hostnameget_timeget_seedunget_codeunget_charunget_byte$register_functionfullstopfragmentfilenameexportedexponenteof_codeend_waithex_encodingdetachedcpu_timeatom_or_compoundcommentscertfile+integer,+callablecall_nthbuiltinsbuilt_inbb_b_putautoload_TermOut+term,?integer01234567+atom,-integer+stream,--stream--daemon$reunify$modules$keysort$elapsed$counter$aborted [%llu] warningvisible--versionverbosevar_refunknownunix://ugraphstreallatimeoutmax_threadstellingstringssqlite3samsortruntimerunningretractreplacerbtreesprofileprocess$portrayordsetsnumlistalphanumericnumbersnodelayno_datanewlinemust_bemaplistmap_setmap_getmap_del$dlisting--librarykeyfileiso_extis_listradix_invalid+term,+integerincludeascii_graphicgetlinegetfilemissing_functorforeignfindallfile_noexecuteepsilondynamicdialectcputimecomparecommentchoicescharsioceilingboundedbooleanrandom_betweenat_exit$assertzassertaabolishUsage: +list,-string--quiet--noopt*** %s 'UTF-8'%s://%s%s:%s:b%s:%d:b$dlopen$bflush true ... .writequshorturlencbb_updateuint64uint32uint16trailsthrow(+threadtabledsystem+stream,+string+integer,+streamstdoutstderrstatusstaticsshortsregexsint64sint32sint16sha512sha384sha256unsetenvserverseeingsearchschemerepeatraylibsrandomquotedpublicprologpragmaphraseset_outputhash_optionoffset+number,+numbernonvar$moduleout of memorymemberunlockedloaderlayoutlambdaignoreheaderhandlegensymfreezeframesformatexpandexitedis_enginedoubleacycliccryptoclient$clausecan_bebracesbinarybb_putbb_getbase64+stream,+atomicassertappendaccept___V%uBRANCH--goal,'%s'), '%s'+queue%s/%u %s is $timer$msort$match$dlsym$alarm [ISO]engine_yield$bwriteusingatom_upperulonguint8ucharu%04Xtypes--tracetpl.cthrowtermsstdinstacksplitslotsslongthread_sleepsint8shiftshellgroundresetquote$queueposixpairsotherorder$first_non_octetn > 1+mutexatom_lowerlog10listsgetlineslindalimit$get_levelset_inputhttpsheapshalt.forcefloorunload_filesfalseexistio_errorerasedummydebugatom_codes$dlclosechdirccharscatchatan2assocasciimax_arityapplyalphaalnumabortUTF-8NOT_DIGITBEGINNOT_ALPHA+atom,?term?atom,?atom+atom,+atom,-term+string,+atom,+atom,-list+atom,-atom--cd=,'%s'%s=%d%s:%s%s/%s%s = %.17g%.16g%.*lg$undo$sort$jump$incrwhenwallawaitvoiduuiduserunixuint$char_typeboolean truetrimtreetoldgctimeload_text+atom,+termcall_taskatanhsqrtsolo$gsl_matrix_sizesintasinhcopysignpl_msg_sendseenreifredopl_msg_recv$breadsetrandreexportpipemake_directory_pathpastpairpopenonce/dev/nullnoneio_modemmapmakedetach,thread,main$listkvidiso_getaddrinfohttphosthmac--helpheaphaltposix_fork--file--autofailerfcelseelifdescdcgsdbidcurlccstracoshcontclpzschar$callin_bytebusy+term,+bool+blobget_atts+atom,+atomraw_argvno argsabnf__G__%u STARREDOPLUSNEXTHOMEFAILEXITCHARCALL.tsv-var%s. , %lld%c%u%02x%%%02X%.*g%.*f%.*e%.*G%.*E$cut$VARyfxxor+varv%uudptauatanswistdsslasinsepremrb+ptrpioposix_getpidoffnotmsbdivmodminmaxlsb--logstrict_isogslgcdexperfgetenvrdivcwdbomargabs$:ENDDOT????- ?%s=:==..%s=%s...-O0-->,%s%s/%s %lx%*c%lx%*c%lx%lu%lo%lg%ld%c $z_$ne$lt$gt$e_ ; yfxfwbtmsirbr+piacos$opjsonnlisendifxfyxfx+float,-floatmutex_or_aliastab=\=\/\+@>@<?->>@>=@=<:-http://-t-q-l-g-e-d, %x_%u#%s%g%f%s:%d%s%c%G%E {}$||{now_or%emeta$a_^[]/\%% %s --> [C@,?*->\==<< ;$LOOP:./%s.--+atom,+term,++**meta_predicate((0,0))'$z_'( '%c'|"%s"!]. PYgBgB0WgBPY[r[rgBgBgBgBgBhBhB&hB6hBFhBVhBfhBvhBhBhBhBhBhBhBhBhBiBiB&iB6iBFiBViBfiBviBiBiBiBiBiBiBiBiBjBjB&jB6jBFjBVjBfjBvjBjBjBjBjBjBjBjBjBkBkB&kB6kBFkBVkBfkBvkBkBkBkBkBkBkBkBkBlBlB&lB6lBFlBVlBflBvlBlBlBlBlBlBlBlBlBmBmB&mB6mBFmBVmBfmBvmBmBmBmBmBmBmBmBmBnBnB&nB6nBFnBVnBfnBvnBnBnBnBnBnBnBnBnBoBoB&oB6oBFoBVoBfoBvoBoBoBoBoBoBoBoBoBpBpB&pB6pBFpBVpBfpBvpBpBpBpBpBpBpBpBpBqBqB&qB6qBFqBVqBfqBvqBqBqBqBqBqBqBqBqBrBrB&rB6rBFrBVrBfrBvrBrBrBrBrBrBrBrBrBsBsB&sB6sBFsBVsBfsBvsBsBsBsBsBsBsBsBsBtBtB&tB6tBFtBVtBftBvtBtBtBtBtBtBtBtBtBuBuB&uB6uBFuBVuBfuBvuBo1boMboco#conboybobb W 0W/c/cAA Ee(sA `,A` ``;B`oZo2Bo0Y8YpRBPB o@ooo``>YvBvBXM`XВBp@XRaXоBMXmX BMX^KXBPXHXBO`X,NX`BO`XZ[XРBZX~[X`BymX[X@B cXbXB~ZXBhXB~ZXIhX`BrZX9fX0CCg>XmiX@ICkX!nX.CdXcQX`QCf[XCNZX NX2C[X`ZCbXTX*CdXiX@CbXHX`;CTXjC6QXP0C cXHX`9CdXHXRCGXhX,CbXNXpCkXNXC:XOXC6[XCNXC@XeXDAXeX0DkXeX"DkXcXyDkX\XtDkX&hXDZXeXlD"TXeXWD"TXJjXDfX&hX"DBXeX}DZXaX D0TXdXpCdXp.DAX`X>DAXdX6DAX]XpDmmX%hXDBZX%hX@.DBXo?XDfXeX"DkX(pX0iDZX7oX0TDZXGoXDmXfXЫDjXhXDXCXgjXDkXbXмD;XCXD;XEXDPXOX@D6[XCXpD6[XgXEfXgXETTXgX{ELTXnX@GmgXoXGmgXIpXGmgXoXpGmgXoX GmgXPpXЌGmgXLpX0EZXKpX0EZXoX0EZXoX0EZXoX0EZXoX EZXxoXG8MXoXEugXdXEugXOlXpEdX$gXpEdXaXpEdXaXE cXRlX EbX%gX`EbXeXEX7XtpXGMXdpX|GMXnXvGMXlXqGMX.eXEoXdoX`EoX!pXЋEoXtpXEMXdpX0qGMXwpXaGMX]pXEGnPXoX EG4HXnX3G4HXnXG4HX^nXG4HXnXpGMXnX@FMX/nXF4HX1pXF4HXoXF4HXOpXF=HXoXF=HX2pX F=HXvpX FnPX,pXpFx:XnX@FvPXkX`FvPXnXPFvPXVnXFvPXhoXFvPXEnX`FvPXUnXFvPXgoXЀFvPXDnX{FvPXlXvFvPXEmXpFvPXkXkFvPXlXeFvPXDmX`FvPXkX0[FvPXnXpUFvPXmXOFvPXjXPFFnPXlX0=FMX`X7FMXziX2FMXneX@-FMX"jX'FMXDX#FMX=XFoX_XF~EXYXF~EX%aXEkXnX FaXnXзE@WnXEnPXiXEvPXNXE cXUXEoXRlXE cXnXE4HXxaXE=HXnXE=HXnX`E=HX\X`HPPXwdX@#HDHdXhX+HGcX,HNX H>XNXH>XUXHEX8LX`HEXUX@HEXXXHPX\X H cXERX H cXnnXH cXlX H cXwnXH cX$iX`HA\X@HA\XKjXOX6I!kXAXPvIjXIUX L9XhX H\X`IkX\X`3IZXYXIkXXXDI7X+_X -IkX^X IkXlXkI7XlX0JIAXlXHYX IHXYXIAXYX&ImXjXHpUXK>TXm\XpcIZXfXHkXSX@L\IbXPhXpI;>X2fX5M;>XiX0GMjXhX?MjXcUXK(MXVUXK(MXr_X8LSXh_XMJXXXLJXkXKKX]XKPXkX uKeXbX@I2EXiXIEXfgXIbX^XIZXQX !KXJMXYXHkXkXITTXeX1L4HX2dXKPXgdXL/=XgdXOIkX-hXK/=X-hX@IfpXKJX`KSX[X/IZXgX*IjX5cXIkX`XzIEXPcXI6Xp]LjX7XJaHXDX`JaHXCXVLPX5_XIGXEX@IfXMKXJ[XH`XH]XHlX@IkXiX IkXokX`rIGXiX :IMXQX@ZKXHXL8XikXIWX #IdX?oX@ICoXI;oXI]kXH3nX[X0ImXWXJeXZpXIY`XnX JZXMpX`IZXoX\IZXgXHmX HkX`hX@HkXvgXHkXbX IkX4nXHkX}gX0HkXyiXIkXbXHkX_XpI4PXB]XLSX\jXcKSX$VX0FKSXVX+KSXnXJZXeXPK.PXMX*LZX_X0$LZXSX`LZX^XUIZX ZXpNMPXZXLHX`X.MX6\XMXWX>KjXYX@HlX@HlXP IdXXXPuLkXmoXK[@XeXJ}>X\GXLAXYXHkXNeXIZXUXIZXckXhM[XhX tM[X>cXM[XckXPM[XPXXMJXW\X0MXi^XMXL\XMX_^XMXlXPXjjX PfXjjXPTX^XQbTX^X0QCXJlXQjXJlXQbTXKX NkXKX*P~TX[X``Q~TX[XRQZX$fX NkX$fX%P~TXhX NkXhX@!P~TXuoX MuoXPfX SX@M SX`PfXLXP KXVXMVXpPfX@aX ZNdX@aX0P KX7aXNdX7aX@ P KXIaXNdXIaXP KXaXdN cXaXOJXaXUN cXaX`OJXbXKN cXbXOJX^X^N cX^XOJX^XFN cX^X`OJX_X>N cX_X0OJXdSXOcXOXOcXrSXOcXjX@OfXOgX0OfX}^X0OfXKXXiX "NkXiXOpTXiXOCX*jXoQ6[X(jXONmXlXMdXNEEXdX NF:XaX0NXEX aXЀN8XXXN8X_XiN8XLXpNEEXYXP3NXXwYX/NXX$ZXOkEXA^XqN0CXs^XwN>X)JX+NXX_X7NXXelXBNXXFXNXX_XO_:X_XNXXpjX%NXX]X0NfX]X}O|fXeAXQsHX?XpPBX?X PXMXCX@IQGX:X?QGX@X5QBXe9X?QBXyAXxOtMXAX N?4XRXPNZZX _X NfZXhXVPXfXCPCPXuhX5PcXoXP.P"[XMXtOJXNX`M:XNeXXkXQ~6XkXQh XkXQ XkXQ XkXQ XWbXwQkXp}QkX {QhXQmXzQ(lXwQkXClXQjXTQXЄQdXr[X QdXgfX@R.[XFXQJXq>qgXAqAq dXOqNq2lXqq[oX`q@qcXqqkX qqcX`q@qkXArArukX`Pr@PrOXrQXTXpᆳ`X /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Written Apr 2021 by Aram Panasenco (panasenco@ucla.edu) Part of Scryer Prolog. [Core Rules](https://tools.ietf.org/html/rfc5234#appendix-B.1) of the Augmented Backus-Naur Form specification (ABNF - RFC 5234). ABNF commonly serves as the definition language for IETF communication protocols, so having these DCGs can be extremely useful for reasoning about most IETF syntaxes. The DCGs are presented in the order they appear in the RFC. While some DCGs below use `char_type/2`, the most common ones are defined manually in order to take advantage of Prolog's first-argument indexing. BSD 3-Clause License Copyright (c) 2021, Aram Panasenco All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ :- module(abnf, [abnf_alpha//1, abnf_bit//1, abnf_char//1, abnf_cr//0, abnf_crlf//0, abnf_ctl//1, abnf_digit//1, abnf_dquote//0, abnf_hexdig//1, abnf_htab//0, abnf_lf//0, abnf_lwsp//0, abnf_octet//1, abnf_sp//0, abnf_vchar//1, abnf_wsp//0 ]). :- use_module(library(charsio)). :- use_module(library(dcgs)). :- use_module(library(dif)). :- use_module(library(lists)). abnf_alpha('a') --> "a". abnf_alpha('b') --> "b". abnf_alpha('c') --> "c". abnf_alpha('d') --> "d". abnf_alpha('e') --> "e". abnf_alpha('f') --> "f". abnf_alpha('g') --> "g". abnf_alpha('h') --> "h". abnf_alpha('i') --> "i". abnf_alpha('j') --> "j". abnf_alpha('k') --> "k". abnf_alpha('l') --> "l". abnf_alpha('m') --> "m". abnf_alpha('n') --> "n". abnf_alpha('o') --> "o". abnf_alpha('p') --> "p". abnf_alpha('q') --> "q". abnf_alpha('r') --> "r". abnf_alpha('s') --> "s". abnf_alpha('t') --> "t". abnf_alpha('u') --> "u". abnf_alpha('v') --> "v". abnf_alpha('w') --> "w". abnf_alpha('x') --> "x". abnf_alpha('y') --> "y". abnf_alpha('z') --> "z". abnf_alpha('A') --> "A". abnf_alpha('B') --> "B". abnf_alpha('C') --> "C". abnf_alpha('D') --> "D". abnf_alpha('E') --> "E". abnf_alpha('F') --> "F". abnf_alpha('G') --> "G". abnf_alpha('H') --> "H". abnf_alpha('I') --> "I". abnf_alpha('J') --> "J". abnf_alpha('K') --> "K". abnf_alpha('L') --> "L". abnf_alpha('M') --> "M". abnf_alpha('N') --> "N". abnf_alpha('O') --> "O". abnf_alpha('P') --> "P". abnf_alpha('Q') --> "Q". abnf_alpha('R') --> "R". abnf_alpha('S') --> "S". abnf_alpha('T') --> "T". abnf_alpha('U') --> "U". abnf_alpha('V') --> "V". abnf_alpha('W') --> "W". abnf_alpha('X') --> "X". abnf_alpha('Y') --> "Y". abnf_alpha('Z') --> "Z". abnf_bit('0') --> "0". abnf_bit('1') --> "1". abnf_char(Char) --> [Char], { dif(Char, '\x0000\'), char_type(Char, ascii) }. %' abnf_cr --> "\r". abnf_crlf --> "\r\n". abnf_ctl(Char) --> [Char], { char_type(Char, ascii), char_type(Char, control) }. abnf_digit('0') --> "0". abnf_digit('1') --> "1". abnf_digit('2') --> "2". abnf_digit('3') --> "3". abnf_digit('4') --> "4". abnf_digit('5') --> "5". abnf_digit('6') --> "6". abnf_digit('7') --> "7". abnf_digit('8') --> "8". abnf_digit('9') --> "9". abnf_dquote --> "\"". abnf_hexdig(Char) --> abnf_digit(Char). abnf_hexdig('A') --> "A". abnf_hexdig('B') --> "B". abnf_hexdig('C') --> "C". abnf_hexdig('D') --> "D". abnf_hexdig('E') --> "E". abnf_hexdig('F') --> "F". abnf_htab --> "\t". abnf_lf --> "\n". abnf_lwsp --> "". abnf_lwsp --> abnf_wsp, abnf_lwsp. abnf_lwsp --> abnf_crlf, abnf_wsp, abnf_lwsp. abnf_octet(Char) --> [Char], char_type(Char, octet). abnf_sp --> " ". abnf_vchar(Char) --> [Char], char_type(Char, ascii_graphic). abnf_wsp --> abnf_sp. abnf_wsp --> abnf_htab. :- module(aggregate, [ aggregate_all/3, aggregate/3 ]). :- meta_predicate aggregate_all(?,0,-), aggregate(?,^,-). /** * aggregate_all(A, G, S): * The predicate aggregates A for the solutions of G and unifies the * result with S. Works like findall/3, without witness grouping. See * documentation for the supported aggregates functions. */ % aggregate_all(+Aggregate, +Goal, -Term) aggregate_all(A, G, S) :- sys_aggr_init(A, T, I), findall(T, G, L), sys_aggr_compute(L, A, I, S). /** * aggregate(A, G, S): * The predicate aggregates A for the solutions of G and unifies the * result with S. Works like bagof/3, with witness grouping. See * documentation for the supported aggregates functions. */ % aggregate(+Aggregate, +Goal, -Term) aggregate(A, G, S) :- sys_aggr_init(A, T, I), bagof(T, G, L), sys_aggr_compute(L, A, I, S). % sys_aggr_compute(+List, +Aggregate, +Term, -Term) sys_aggr_compute([], A, I, S) :- sys_aggr_fini(A, I, S). sys_aggr_compute([T|L], A, I, S) :- sys_aggr_next(A, I, T, J), sys_aggr_compute(L, A, J, S). % sys_aggr_init(+Aggregate, -Term, -Term) sys_aggr_init(A, _, _) :- var(A), throw(error(instantiation_error,_)). sys_aggr_init(count, '', 0) :- !. sys_aggr_init(sum(X), X, 0) :- !. sys_aggr_init(mul(X), X, 1) :- !. sys_aggr_init(min(X), X, sup) :- !. sys_aggr_init(max(X), X, inf) :- !. sys_aggr_init(bag(X), X, []) :- !. sys_aggr_init(set(X), X, []) :- !. sys_aggr_init((F,G), (X,Y), (C,D)) :- !, sys_aggr_init(F, X, C), sys_aggr_init(G, Y, D). sys_aggr_init(A, _, _) :- throw(error(type_error(aggregate,A),_)). % sys_aggr_next(+Aggregate, +Term, +Term, -Term) sys_aggr_next(count, A, '', C) :- C is A+1. sys_aggr_next(sum(_), A, B, C) :- C is A+B. sys_aggr_next(mul(_), A, B, C) :- C is A*B. sys_aggr_next(min(_), A, B, C) :- sys_min(A, B, C). sys_aggr_next(max(_), A, B, C) :- sys_max(A, B, C). sys_aggr_next(bag(_), A, B, [B|A]). sys_aggr_next(set(_), A, B, [B|A]). sys_aggr_next((F,G), (A,B), (X,Y), (C,D)) :- sys_aggr_next(F, A, X, C), sys_aggr_next(G, B, Y, D). % sys_aggr_fini(+Aggregate, +Term, -Term) sys_aggr_fini(count, A, A). sys_aggr_fini(sum(_), A, A). sys_aggr_fini(mul(_), A, A). sys_aggr_fini(min(_), A, A). sys_aggr_fini(max(_), A, A). sys_aggr_fini(bag(_), A, B) :- reverse(A, B). sys_aggr_fini(set(_), A, B) :- reverse(A, H), sort(H, B). sys_aggr_fini((F,G), (X,Y), (C,D)) :- sys_aggr_fini(F, X, C), sys_aggr_fini(G, Y, D). % sys_min(+ExtNumber, +ExtNumber, -ExtNumber) sys_min(sup, X, R) :- !, R = X. sys_min(X, sup, R) :- !, R = X. sys_min(inf, _, R) :- !, R = inf. sys_min(_, inf, R) :- !, R = inf. sys_min(X, Y, R) :- R is min(X, Y). % sys_max(+ExtNumber, +ExtNumber, -ExtNumber) sys_max(inf, X, R) :- !, R = X. sys_max(X, inf, R) :- !, R = X. sys_max(sup, _, R) :- !, R = sup. sys_max(_, sup, R) :- !, R = sup. sys_max(X, Y, R) :- R is max(X, Y). i:- module(arithmetic, [ lsb/2, msb/2, popcount/2, rational_numerator_denominator/3 ]). rational_numerator_denominator(R, N, D) :- N is numerator(R), D is denominator(R). :- help(rational_numerator_denominator(+rational,-integer,-integer), [iso(false)]). lsb(I, N) :- must_be(I, integer, lsb/2, _), N is lsb(I). :- help(lsb(+integer,?integer), [iso(false)]). msb(I, N) :- must_be(I, integer, msb/2, _), N is msb(I). :- help(msb(+integer,?integer), [iso(false)]). popcount(I, N) :- must_be(I, integer, popcount/2, _), N is popcount(I). :- help(popcount(+integer,?integer), [iso(false)]). B/* Author: R.A.O'Keefe, L.Damas, V.S.Costa, Glenn Burgess, Jiri Spitz and Jan Wielemaker E-mail: J.Wielemaker@vu.nl WWW: http://www.swi-prolog.org Copyright (c) 2004-2018, various people and institutions All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ :- module(assoc, [ empty_assoc/1, % -Assoc is_assoc/1, % +Assoc assoc_to_list/2, % +Assoc, -Pairs assoc_to_keys/2, % +Assoc, -List assoc_to_values/2, % +Assoc, -List gen_assoc/3, % ?Key, +Assoc, ?Value get_assoc/3, % +Key, +Assoc, ?Value get_assoc/5, % +Key, +Assoc0, ?Val0, ?Assoc, ?Val list_to_assoc/2, % +List, ?Assoc map_assoc/2, % :Goal, +Assoc map_assoc/3, % :Goal, +Assoc0, ?Assoc max_assoc/3, % +Assoc, ?Key, ?Value min_assoc/3, % +Assoc, ?Key, ?Value ord_list_to_assoc/2, % +List, ?Assoc put_assoc/4, % +Key, +Assoc0, +Value, ?Assoc del_assoc/4, % +Key, +Assoc0, ?Value, ?Assoc del_min_assoc/4, % +Assoc0, ?Key, ?Value, ?Assoc del_max_assoc/4 % +Assoc0, ?Key, ?Value, ?Assoc ]). :- use_module(library(lists)). /** Binary associations Assocs are Key-Value associations implemented as a balanced binary tree (AVL tree). Authors: R.A.O'Keefe, L.Damas, V.S.Costa and Jan Wielemaker */ :- meta_predicate(map_assoc(1, ?)). :- meta_predicate(map_assoc(2, ?, ?)). %% empty_assoc(?Assoc) is semidet. % % Is true if Assoc is the empty association list. empty_assoc(t). %% assoc_to_list(+Assoc, -Pairs) is det. % % Translate Assoc to a list Pairs of Key-Value pairs. The keys % in Pairs are sorted in ascending order. assoc_to_list(Assoc, List) :- assoc_to_list(Assoc, List, []). assoc_to_list(t(Key,Val,_,L,R), List, Rest) :- assoc_to_list(L, List, [Key-Val|More]), assoc_to_list(R, More, Rest). assoc_to_list(t, List, List). %% assoc_to_keys(+Assoc, -Keys) is det. % % True if Keys is the list of keys in Assoc. The keys are sorted % in ascending order. assoc_to_keys(Assoc, List) :- assoc_to_keys(Assoc, List, []). assoc_to_keys(t(Key,_,_,L,R), List, Rest) :- assoc_to_keys(L, List, [Key|More]), assoc_to_keys(R, More, Rest). assoc_to_keys(t, List, List). %% assoc_to_values(+Assoc, -Values) is det. % % True if Values is the list of values in Assoc. Values are % ordered in ascending order of the key to which they were % associated. Values may contain duplicates. assoc_to_values(Assoc, List) :- assoc_to_values(Assoc, List, []). assoc_to_values(t(_,Value,_,L,R), List, Rest) :- assoc_to_values(L, List, [Value|More]), assoc_to_values(R, More, Rest). assoc_to_values(t, List, List). %% is_assoc(+Assoc) is semidet. % % True if Assoc is an association list. This predicate checks % that the structure is valid, elements are in order, and tree % is balanced to the extent guaranteed by AVL trees. I.e., % branches of each subtree differ in depth by at most 1. is_assoc(Assoc) :- is_assoc(Assoc, _Min, _Max, _Depth). is_assoc(t,X,X,0) :- !. is_assoc(t(K,_,-,t,t),K,K,1) :- !, ground(K). is_assoc(t(K,_,>,t,t(RK,_,-,t,t)),K,RK,2) :- % Ensure right side Key is 'greater' than K !, ground((K,RK)), K @< RK. is_assoc(t(K,_,<,t(LK,_,-,t,t),t),LK,K,2) :- % Ensure left side Key is 'less' than K !, ground((LK,K)), LK @< K. is_assoc(t(K,_,B,L,R),Min,Max,Depth) :- is_assoc(L,Min,LMax,LDepth), is_assoc(R,RMin,Max,RDepth), % Ensure Balance matches depth compare(Rel,RDepth,LDepth), balance(Rel,B), % Ensure ordering ground((LMax,K,RMin)), LMax @< K, K @< RMin, Depth is max(LDepth, RDepth)+1. % Private lookup table matching comparison operators to Balance operators used in tree balance(=,-). balance(<,<). balance(>,>). %% gen_assoc(?Key, +Assoc, ?Value) is nondet. % % True if Key-Value is an association in Assoc. Enumerates keys in % ascending order on backtracking. gen_assoc(Key, Assoc, Value) :- ( ground(Key) -> get_assoc(Key, Assoc, Value) ; gen_assoc_(Key, Assoc, Value) ). gen_assoc_(Key, t(_,_,_,L,_), Val) :- gen_assoc_(Key, L, Val). gen_assoc_(Key, t(Key,Val,_,_,_), Val). gen_assoc_(Key, t(_,_,_,_,R), Val) :- gen_assoc_(Key, R, Val). %% get_assoc(+Key, +Assoc, -Value) is semidet. % % True if Key-Value is an association in Assoc. % % Throws error: `type_error(assoc, Assoc)` if Assoc is not an association list. get_assoc(Key, Assoc, Val) :- must_be(assoc, Assoc), get_assoc_(Key, Assoc, Val). /* :- if(current_predicate('$btree_find_node'/5)). get_assoc_(Key, Tree, Val) :- Tree \== t, '$btree_find_node'(Key, Tree, 0x010405, Node, =), arg(2, Node, Val). :- else. */ get_assoc_(Key, t(K,V,_,L,R), Val) :- compare(Rel, Key, K), get_assoc(Rel, Key, V, L, R, Val). get_assoc(=, _, Val, _, _, Val). get_assoc(<, Key, _, Tree, _, Val) :- get_assoc(Key, Tree, Val). get_assoc(>, Key, _, _, Tree, Val) :- get_assoc(Key, Tree, Val). % :- endif. %% get_assoc(+Key, +Assoc0, ?Val0, ?Assoc, ?Val) is semidet. % % True if Key-Val0 is in Assoc0 and Key-Val is in Assoc. get_assoc(Key, t(K,V,B,L,R), Val, t(K,NV,B,NL,NR), NVal) :- compare(Rel, Key, K), get_assoc(Rel, Key, V, L, R, Val, NV, NL, NR, NVal). get_assoc(=, _, Val, L, R, Val, NVal, L, R, NVal). get_assoc(<, Key, V, L, R, Val, V, NL, R, NVal) :- get_assoc(Key, L, Val, NL, NVal). get_assoc(>, Key, V, L, R, Val, V, L, NR, NVal) :- get_assoc(Key, R, Val, NR, NVal). %% list_to_assoc(+Pairs, -Assoc) is det. % % Create an association from a list Pairs of Key-Value pairs. List % must not contain duplicate keys. % % Throws error: `domain_error(unique_key_pairs, List)` if List contains duplicate keys list_to_assoc(List, Assoc) :- ( List = [] -> Assoc = t ; keysort(List, Sorted), ( ord_pairs(Sorted) -> length(Sorted, N), list_to_assoc(N, Sorted, [], _, Assoc) ; throw(error(domain_error(unique_key_pairs, List), list_to_assoc/2)) ) ). list_to_assoc(1, [K-V|More], More, 1, t(K,V,-,t,t)) :- !. list_to_assoc(2, [K1-V1,K2-V2|More], More, 2, t(K2,V2,<,t(K1,V1,-,t,t),t)) :- !. list_to_assoc(N, List, More, Depth, t(K,V,Balance,L,R)) :- N0 is N - 1, RN is N0 div 2, Rem is N0 mod 2, LN is RN + Rem, list_to_assoc(LN, List, [K-V|Upper], LDepth, L), list_to_assoc(RN, Upper, More, RDepth, R), Depth is LDepth + 1, compare(B, RDepth, LDepth), balance(B, Balance). %% ord_list_to_assoc(+Pairs, -Assoc) is det. % % Assoc is created from an ordered list Pairs of Key-Value % pairs. The pairs must occur in strictly ascending order of % their keys. % % Throws error: `domain_error(key_ordered_pairs, List)` if pairs are not ordered. ord_list_to_assoc(Sorted, Assoc) :- ( Sorted = [] -> Assoc = t ; ( ord_pairs(Sorted) -> length(Sorted, N), list_to_assoc(N, Sorted, [], _, Assoc) ; domain_error(key_ordered_pairs, Sorted) ) ). %% ord_pairs(+Pairs) is semidet % % True if Pairs is a list of Key-Val pairs strictly ordered by key. ord_pairs([K-_V|Rest]) :- ord_pairs(Rest, K). ord_pairs([], _K). ord_pairs([K-_V|Rest], K0) :- K0 @< K, ord_pairs(Rest, K). %% map_assoc(:Pred, +Assoc) is semidet. % % True if Pred(Value) is true for all values in Assoc. map_assoc(Pred, T) :- map_assoc_(T, Pred). map_assoc_(t, _). map_assoc_(t(_,Val,_,L,R), Pred) :- map_assoc_(L, Pred), call(Pred, Val), map_assoc_(R, Pred). %% map_assoc(:Pred, +Assoc0, ?Assoc) is semidet. % % Map corresponding values. True if Assoc is Assoc0 with Pred % applied to all corresponding pairs of of values. map_assoc(Pred, T0, T) :- map_assoc_(T0, Pred, T). map_assoc_(t, _, t). map_assoc_(t(Key,Val,B,L0,R0), Pred, t(Key,Ans,B,L1,R1)) :- map_assoc_(L0, Pred, L1), call(Pred, Val, Ans), map_assoc_(R0, Pred, R1). %% max_assoc(+Assoc, -Key, -Value) is semidet. % % True if Key-Value is in Assoc and Key is the largest key. max_assoc(t(K,V,_,_,R), Key, Val) :- max_assoc(R, K, V, Key, Val). max_assoc(t, K, V, K, V). max_assoc(t(K,V,_,_,R), _, _, Key, Val) :- max_assoc(R, K, V, Key, Val). %% min_assoc(+Assoc, -Key, -Value) is semidet. % % True if Key-Value is in assoc and Key is the smallest key. min_assoc(t(K,V,_,L,_), Key, Val) :- min_assoc(L, K, V, Key, Val). min_assoc(t, K, V, K, V). min_assoc(t(K,V,_,L,_), _, _, Key, Val) :- min_assoc(L, K, V, Key, Val). %% put_assoc(+Key, +Assoc0, +Value, -Assoc) is det. % % Assoc is Assoc0, except that Key is associated with % Value. This can be used to insert and change associations. put_assoc(Key, A0, Value, A) :- insert(A0, Key, Value, A, _). insert(t, Key, Val, t(Key,Val,-,t,t), yes). insert(t(Key,Val,B,L,R), K, V, NewTree, WhatHasChanged) :- compare(Rel, K, Key), insert(Rel, t(Key,Val,B,L,R), K, V, NewTree, WhatHasChanged). insert(=, t(Key,_,B,L,R), _, V, t(Key,V,B,L,R), no). insert(<, t(Key,Val,B,L,R), K, V, NewTree, WhatHasChanged) :- insert(L, K, V, NewL, LeftHasChanged), adjust(LeftHasChanged, t(Key,Val,B,NewL,R), left, NewTree, WhatHasChanged). insert(>, t(Key,Val,B,L,R), K, V, NewTree, WhatHasChanged) :- insert(R, K, V, NewR, RightHasChanged), adjust(RightHasChanged, t(Key,Val,B,L,NewR), right, NewTree, WhatHasChanged). adjust(no, Oldree, _, Oldree, no). adjust(yes, t(Key,Val,B0,L,R), LoR, NewTree, WhatHasChanged) :- table(B0, LoR, B1, WhatHasChanged, ToBeRebalanced), rebalance(ToBeRebalanced, t(Key,Val,B0,L,R), B1, NewTree, _, _). % balance where balance whole tree to be % before inserted after increased rebalanced table(- , left , < , yes , no ) :- !. table(- , right , > , yes , no ) :- !. table(< , left , - , no , yes ) :- !. table(< , right , - , no , no ) :- !. table(> , left , - , no , no ) :- !. table(> , right , - , no , yes ) :- !. %% del_min_assoc(+Assoc0, ?Key, ?Val, -Assoc) is semidet. % % True if Key-Value is in Assoc0 and Key is the smallest key. % Assoc is Assoc0 with Key-Value removed. Warning: This will % succeed with _no_ bindings for Key or Val if Assoc0 is empty. del_min_assoc(Tree, Key, Val, NewTree) :- del_min_assoc(Tree, Key, Val, NewTree, _DepthChanged). del_min_assoc(t(Key,Val,_B,t,R), Key, Val, R, yes) :- !. del_min_assoc(t(K,V,B,L,R), Key, Val, NewTree, Changed) :- del_min_assoc(L, Key, Val, NewL, LeftChanged), deladjust(LeftChanged, t(K,V,B,NewL,R), left, NewTree, Changed). %% del_max_assoc(+Assoc0, ?Key, ?Val, -Assoc) is semidet. % % True if Key-Value is in Assoc0 and Key is the greatest key. % Assoc is Assoc0 with Key-Value removed. Warning: This will % succeed with _no_ bindings for Key or Val if Assoc0 is empty. del_max_assoc(Tree, Key, Val, NewTree) :- del_max_assoc(Tree, Key, Val, NewTree, _DepthChanged). del_max_assoc(t(Key,Val,_B,L,t), Key, Val, L, yes) :- !. del_max_assoc(t(K,V,B,L,R), Key, Val, NewTree, Changed) :- del_max_assoc(R, Key, Val, NewR, RightChanged), deladjust(RightChanged, t(K,V,B,L,NewR), right, NewTree, Changed). %% del_assoc(+Key, +Assoc0, ?Value, -Assoc) is semidet. % % True if Key-Value is in Assoc0. Assoc is Assoc0 with % Key-Value removed. del_assoc(Key, A0, Value, A) :- delete(A0, Key, Value, A, _). % delete(+Subtree, +SearchedKey, ?SearchedValue, ?SubtreeOut, ?WhatHasChanged) delete(t(Key,Val,B,L,R), K, V, NewTree, WhatHasChanged) :- compare(Rel, K, Key), delete(Rel, t(Key,Val,B,L,R), K, V, NewTree, WhatHasChanged). % delete(+KeySide, +Subtree, +SearchedKey, ?SearchedValue, ?SubtreeOut, ?WhatHasChanged) % KeySide is an operator {<,=,>} indicating which branch should be searched for the key. % WhatHasChanged {yes,no} indicates whether the NewTree has changed in depth. delete(=, t(Key,Val,_B,t,R), Key, Val, R, yes) :- !. delete(=, t(Key,Val,_B,L,t), Key, Val, L, yes) :- !. delete(=, t(Key,Val,>,L,R), Key, Val, NewTree, WhatHasChanged) :- % Rh tree is deeper, so rotate from R to L del_min_assoc(R, K, V, NewR, RightHasChanged), deladjust(RightHasChanged, t(K,V,>,L,NewR), right, NewTree, WhatHasChanged), !. delete(=, t(Key,Val,B,L,R), Key, Val, NewTree, WhatHasChanged) :- % Rh tree is not deeper, so rotate from L to R del_max_assoc(L, K, V, NewL, LeftHasChanged), deladjust(LeftHasChanged, t(K,V,B,NewL,R), left, NewTree, WhatHasChanged), !. delete(<, t(Key,Val,B,L,R), K, V, NewTree, WhatHasChanged) :- delete(L, K, V, NewL, LeftHasChanged), deladjust(LeftHasChanged, t(Key,Val,B,NewL,R), left, NewTree, WhatHasChanged). delete(>, t(Key,Val,B,L,R), K, V, NewTree, WhatHasChanged) :- delete(R, K, V, NewR, RightHasChanged), deladjust(RightHasChanged, t(Key,Val,B,L,NewR), right, NewTree, WhatHasChanged). deladjust(no, OldTree, _, OldTree, no). deladjust(yes, t(Key,Val,B0,L,R), LoR, NewTree, RealChange) :- deltable(B0, LoR, B1, WhatHasChanged, ToBeRebalanced), rebalance(ToBeRebalanced, t(Key,Val,B0,L,R), B1, NewTree, WhatHasChanged, RealChange). % balance where balance whole tree to be % before deleted after changed rebalanced deltable(- , right , < , no , no ) :- !. deltable(- , left , > , no , no ) :- !. deltable(< , right , - , yes , yes ) :- !. deltable(< , left , - , yes , no ) :- !. deltable(> , right , - , yes , no ) :- !. deltable(> , left , - , yes , yes ) :- !. % It depends on the tree pattern in avl_geq whether it really decreases. % Single and double tree rotations - these are common for insert and delete. /* The patterns (>)-(>), (>)-( <), ( <)-( <) and ( <)-(>) on the LHS always change the tree height and these are the only patterns which can happen after an insertion. That's the reason why we can use a table only to decide the needed changes. The patterns (>)-( -) and ( <)-( -) do not change the tree height. After a deletion any pattern can occur and so we return yes or no as a flag of a height change. */ rebalance(no, t(K,V,_,L,R), B, t(K,V,B,L,R), Changed, Changed). rebalance(yes, OldTree, _, NewTree, _, RealChange) :- avl_geq(OldTree, NewTree, RealChange). avl_geq(t(A,VA,>,Alpha,t(B,VB,>,Beta,Gamma)), t(B,VB,-,t(A,VA,-,Alpha,Beta),Gamma), yes) :- !. avl_geq(t(A,VA,>,Alpha,t(B,VB,-,Beta,Gamma)), t(B,VB,<,t(A,VA,>,Alpha,Beta),Gamma), no) :- !. avl_geq(t(B,VB,<,t(A,VA,<,Alpha,Beta),Gamma), t(A,VA,-,Alpha,t(B,VB,-,Beta,Gamma)), yes) :- !. avl_geq(t(B,VB,<,t(A,VA,-,Alpha,Beta),Gamma), t(A,VA,>,Alpha,t(B,VB,<,Beta,Gamma)), no) :- !. avl_geq(t(A,VA,>,Alpha,t(B,VB,<,t(X,VX,B1,Beta,Gamma),Delta)), t(X,VX,-,t(A,VA,B2,Alpha,Beta),t(B,VB,B3,Gamma,Delta)), yes) :- !, table2(B1, B2, B3). avl_geq(t(B,VB,<,t(A,VA,>,Alpha,t(X,VX,B1,Beta,Gamma)),Delta), t(X,VX,-,t(A,VA,B2,Alpha,Beta),t(B,VB,B3,Gamma,Delta)), yes) :- !, table2(B1, B2, B3). table2(< ,- ,> ). table2(> ,< ,- ). table2(- ,- ,- ). must_be(assoc, X) :- ( X == t -> true ; compound(X), functor(X, t, 5) ), !. must_be(assoc, X) :- throw(error(type_error(assoc, X), _)). :- module(atts, [ op(1199, fx, attribute), get_attr/3, put_attr/3, del_attr/2 ]). % Compatability get_attr(Var, Module, Value) :- var(Var), Access =.. [Module, Value], get_atts(Var, Access). put_attr(Var, Module, Value) :- Access =.. [Module, Value], put_atts(Var, Access). del_attr(Var, Module) :- Access =.. [Module, _], var(Var) -> put_atts(Var, -Access); true. N:- pragma(builtins, [once(true)]). :- use_module(library(error)). :- use_module(library(lists)). expand_term((H --> B), Out) :- dcg_translate((H --> B), Out), !. dcg_translate(TermIn, Term) :- nonvar(TermIn), dcg_rule(TermIn, Term). :- help(writeln(+term), [iso(false),deprecated(true)]). :- help(writeln(+stream,+term), [iso(false),deprecated(true)]). writeln(T) :- write(T), nl. % SWI writeln(S, T) :- write(S, T), nl. % SWI :- help(predicate_property(+callable,+term), [iso(true)]). read_from_chars(Cs, T) :- read_term_from_chars(Cs, T, []). :- help(read_from_chars(+chars,?term), [iso(false)]). predicate_property(P, A) :- nonvar(P), atom(A), !, must_be(P, callable, predicate_property/2, _), '$legacy_predicate_property'(P, A). predicate_property(P, A) :- '$load_properties', ( var(A) -> true ; (Controls = [ built_in,choice_construct, discontiguous,private,static, dynamic,foreign,multifile, meta_predicate(_),imported_from(_),template(_), iso,visible,tabled ], ( memberchk(A, Controls) -> true ; throw(error(domain_error(predicate_property, A), P)) ) ) ), must_be(P, callable, predicate_property/2, _), ( P = (M:P2) -> M:'$predicate_property'(predicate, P2, A) ; '$predicate_property'(predicate, P, A) ). :- help(evaluable_property(+callable,+term), [iso(true)]). evaluable_property(P, A) :- nonvar(P), atom(A), !, must_be(P, callable, evaluable_property/2, _), '$legacy_evaluable_property'(P, A). evaluable_property(P, A) :- '$load_properties', ( var(A) -> true ; (Controls = [iso,built_in,static,dynamic,template(_),template(_,_)], (memberchk(A, Controls) -> true ; ( must_be(A, callable, evaluable_property/2, _), throw(error(domain_error(evaluable_property, A), P)) ) ) ) ), must_be(P, callable, evaluable_property/2, _), ( P = (M:P2) -> M:'$predicate_property'(function, P2, A) ; '$predicate_property'(function, P, A) ). :- help(current_prolog_flag(+callable,+term), [iso(true)]). current_prolog_flag(P, A) :- nonvar(P), !, '$legacy_current_prolog_flag'(P, A). current_prolog_flag(P, A) :- '$load_flags', '$current_prolog_flag'(P, A). :- help(argv(-list), [iso(false)]). :- help(raw_argv(-list), [iso(false)]). argv(L) :- current_prolog_flag(argv, L). raw_argv(L) :- current_prolog_flag(raw_argv, L). '$post_unify_hook' :- '$undo_trail'(Vars, State), process_vars_(Vars, [], Goals), '$redo_trail'(State), xmaplist_(Goals). xmaplist_([]). xmaplist_([E|T]) :- once(E), xmaplist_(T). process_vars_([], Goals, Goals). process_vars_([Var-Val|Vars], SoFar, Goals) :- ( get_atts(Var, Atts) -> process_var_(Atts, Var, Val, SoFar, MoreGoals), process_vars_(Vars, MoreGoals, Goals) ; process_vars_(Vars, SoFar, Goals) ). process_var_([], _, _, Goals, Goals). process_var_([Att|Atts], Var, Val, SoFar, Goals) :- functor(Att, F, A), attribute(M, F, A), M:verify_attributes(Var, Val, NewGoals), append(SoFar, NewGoals, MoreGoals), process_var_(Atts, Var, Val, MoreGoals, Goals). term_attvars_([], VsIn, VsIn). term_attvars_([H|T], VsIn, VsOut) :- ( '$attributed_var'(H) -> term_attvars_(T, [H|VsIn], VsOut) ; term_attvars_(T, VsIn, VsOut) ). term_attributed_variables_(Term, Vs) :- can_be(Vs, list, term_attributed_variables_/2, _), term_variables(Term, Vs0), term_attvars_(Vs0, [], Vs). :- help(call_residue_vars(@goal,-list), [iso(false)]). :- meta_predicate(call_residue_vars(0,?)). call_residue_vars(G, Ls) :- '$mark_start'(Mark), G, '$list_attributed'(Mark, Ls0), sort(Ls0, Ls). duplicate_term_(Term, Copy) :- '$duplicate_term'(Term, Copy). copy_term(Term, Copy, Gs) :- duplicate_term_(Term, Copy), term_attributed_variables_(Copy, Vs), collect_goals_(Vs, [], Gs). collect_goals_(_, [], GsIn, GsIn). collect_goals_(V, [H|T], GsIn, GsOut) :- nonvar(H), H =.. [M, _], catch(M:attribute_goals(V, Goal0, []), _, Goal0 = put_atts(V, +H)), !, (Goal0 = [H2] -> Goal = H2 ; Goal = Goal0), collect_goals_(V, T, [Goal|GsIn], GsOut). /* collect_goals_(V, [H|T], GsIn, GsOut) :- nonvar(H), H =.. [F, _], attribute(M, F, 1), Goal = M:put_atts(V, H), collect_goals_(V, T, [Goal|GsIn], GsOut). */ collect_goals_(V, [_|T], GsIn, GsOut) :- collect_goals_(V, T, GsIn, GsOut). collect_goals_([], GsIn, GsIn). collect_goals_([V|T], GsIn, GsOut) :- get_atts(V, Ls), collect_goals_(V, Ls, GsIn, GsOut2), collect_goals_(T, GsOut2, GsOut). % Debugging... print_goals_(_, []). print_goals_(Any, [Goal|Goals]) :- (Any -> write(',\n ') ; true), write(Goal), (Goals == [] -> true ; write(', ')), print_goals_(false, Goals). dump_attvars_([], []). dump_attvars_(Vars, Gs) :- collect_goals_(Vars, [], Gs). dump_attvars_(Any) :- '$list_attributed'(0, Vs0), sort(Vs0, Vs), dump_attvars_(Vs, Gs0), flatten(Gs0, Gs1), sort(Gs1, Gs), print_goals_(Any, Gs). sort(A, B) :- '$sort'(A, B). :- help(sort(+term,?term), [iso(true)]). msort(A, B) :- '$msort'(A, B). :- help(msort(+term,?term), [iso(true)]). keysort(A, B) :- '$keysort'(A, B). :- help(keysort(+term,?term), [iso(true)]). sort(A, B, C, D) :- '$sort'(A, B, C, D). :- help(sort(+term,+atom,+list,?term), [iso(false)]). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % :- meta_predicate(bagof(-,0,?)). :- help(bagof(+term,:callable,?list), [iso(true)]). /** * bagof(T, X1^…^Xn^G, L): [ISO 8.10.2] * The predicate determines all the solutions to the goal G, * whereby collecting copies of the template T and the * witness. The predicate then repeatedly succeeds for * the witness and the list of associated templates. */ % bagof(+Term, +Goal, -List) bagof(T, G, L) :- (var(L) -> true; must_be(L, list_or_partial_list, bagof/3, _)), acyclic_term(G), sys_globals_kernel_(T^G, W, H), findall(W-[+T], H, J), sys_same_vars_(J, _), keysort(J, K), sys_enum_runs_(K, W, L). :- meta_predicate(setof(-,0,?)). :- help(setof(+term,+callable,?list), [iso(true)]). /** * setof(T, X1^…^Xn^G, L): [ISO 8.10.3] * The predicate determines all the solutions to the goal G, * whereby collecting copies of the template T and the * witness. The predicate then repeatedly succeeds for * the witness and the set of associated templates. */ % setof(+Term, +Goal, -List) setof(T, G, L) :- (var(L) -> true; must_be(L, list_or_partial_list, setof/3, _)), acyclic_term(G), sys_globals_kernel_(T^G, W, H), findall(W-[+T], H, J), sys_same_vars_(J, _), sort(J, K), sys_enum_runs_(K, W, L). % sys_same_vars_(+Pairs, +List) sys_same_vars_([K-_|L], V) :- term_variables(K, V, _), sys_same_vars_(L, V). sys_same_vars_([], _). % sys_enum_runs_(+Pairs, +Term, -List) sys_enum_runs_([K-[+V]|L], W, Q) :- sys_key_run_(L, K, R, H), (K = W, Q = [V|R], (H = [], !; true); sys_enum_runs_(H, W, Q)). % sys_key_run_(+Pairs, +Term, -List, -Pairs) sys_key_run_([K-[+V]|L], J, [V|R], H) :- K == J, !, sys_key_run_(L, J, R, H). sys_key_run_(L, _, [], L). /********************************************************************/ /* Helpers */ /********************************************************************/ % sys_goal_split_(+Goal, -List, -Goal) sys_globals_kernel_(G, W, H) :- sys_goal_split_(G, I, H), term_variables(H, A), term_variables(I, B), sys_var_subtract_(A, B, W). % sys_goal_split_(+Goal, -List, -Goal) sys_goal_split_(G, [], G) :- var(G), !. sys_goal_split_(V^G, [V|L], H) :- !, sys_goal_split_(G, L, H). sys_goal_split_(G, [], G). % sys_var_subtract_(+List, +List, -List) sys_var_subtract_([X|L], R, T) :- member(Y, R), Y == X, !, sys_var_subtract_(L, R, T). sys_var_subtract_([X|L], R, [X|S]) :- sys_var_subtract_(L, R, S). sys_var_subtract_([], _, []). % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Edinburgh... :- help(get0(?integer), [iso(false),deprecated(true)]). :- help(get0(+stream,?integer), [iso(false),deprecated(true)]). :- help(get0(+term), [iso(false),deprecated(true)]). :- help(get0(+stream,+term), [iso(false),deprecated(true)]). :- help(put(+integer), [iso(false),deprecated(true)]). :- help(put(+stream,+integer), [iso(false),deprecated(true)]). :- help(see(+filename), [iso(false),deprecated(true)]). :- help(tell(+filename), [iso(false),deprecated(true)]). :- help(append(+filename), [iso(false),deprecated(true)]). get0(C) :- get_code(C). get0(S, C) :- get_code(S, C). display(T) :- write_canonical(T). display(S, T) :- write_canonical(S, T). put(C) :- put_code(C). put(S,C) :- put_code(S, C). see(F) :- open(F, read, S), set_input(S). tell(F) :- open(F, write, S), set_output(S). append(F) :- open(F, append, S), set_output(S). % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% '$portray_term'(S, T) :- compound(T), !, functor(T, _, Args), T =.. [Functor|_], writeq(S, Functor), write(S, '('), (between(1, Args, I), arg(I, T, Arg), '$portray'(S, Arg), (I < Args -> write(S, ',') ; true), fail ; true), write(S, ')'). '$portray_term'(S, T) :- writeq(S, T). '$portray'(S, T) :- current_output(S0), set_output(S), ((catch(once(portray(T)), _, write(T)), !) ; '$portray_term'(S, T)), set_output(S0). '$portray'(T) :- current_output(S), ((catch(once(portray(T)), _, write(T)), !) ; '$portray_term'(S, T)). :- help(print(+term), [iso(false)]). :- help(print(+stream,+term), [iso(false)]). print(T) :- current_output(S), format(S, "~p", [T]). print(S, T) :- format(S, "~p", [T]). :- help(open(+atom,+atom,--stream), [iso(true)]). open(F, M, S) :- open(F, M, S, []). :- meta_predicate(engine_create(?,0,?)). engine_create(T, G, S) :- engine_create(T, G, S, []). :- help(engine_create(+term,+callable,?stream), [iso(false)]). engine_post(E, T, R) :- engine_post(E, T), engine_next(E, R). current_engine(E) :- stream_property(E, engine(true)). :- help(atomic_list_concat(+list,+atomic), [iso(false)]). atomic_list_concat(L, Atom) :- atomic_list_concat(L, '', Atom). :- help(chars_base64(+atom,?atom,+list), [iso(false)]). chars_base64(Plain, Base64, Opts) :- base64(Plain, Base64, Opts). :- help(chars_urlenc(+atom,?atom,+list), [iso(false)]). chars_urlenc(Plain, Url, Opts) :- urlenc(Plain, Url, Opts). :- help(term_to_atom(+term,?atom), [iso(false)]). term_to_atom(T, S) :- write_term_to_chars(T, [], S). :- help(absolute_filename(+atom,?atom), [iso(false)]). absolute_file_name(R, A) :- absolute_file_name(R, A, []). :- help(client(+atom,-atom,-atom,--stream), [iso(false)]). client(Url, S) :- client(Url, _, _, S, []). :- help(client(+atom,-atom,-atom,--stream), [iso(false)]). client(Url, Host, Path, S) :- client(Url, Host, Path, S, []). :- help(server(+atom,--stream), [iso(false)]). server(Host, S) :- server(Host, S, []). :- help(load_files(+list), [iso(false)]). load_files(Files) :- load_files(Files,[]). :- help(load_files(+list), [iso(false)]). consult(Files) :- load_files(Files,[]). :- help(reconsult(+list), [iso(false),deprecated(true)]). reconsult(Files) :- load_files(Files,[]). :- help(deconsult(+list), [iso(false),deprecated(true)]). deconsult(Files) :- unload_files(Files). :- help('?='(+term,+term), [iso(false)]). ?=(X, Y) :- \+ unifiable(X, Y, [_|_]). :- help(atom_number(+atom,-number), [iso(false)]). atom_number(A, N) :- atom_codes(A,Codes), number_codes(N, Codes). :- help(rational_numerator_denominator(+rational,-integer,-integer), [iso(false)]). rational_numerator_denominator(R, N, D) :- N is numerator(R), D is denominator(R). '$skip_list'(Skip, Xs0, Xs) :- '$skip_max_list'(Skip,_, Xs0, Xs). :- help(term_hash(+term,+list,-integer), [iso(false)]). term_hash(Term, _Opts, Hash) :- term_hash(Term, Hash). read_term_from_chars_(T, Cs, Rest) :- '$read_term_from_chars'(T, [], Cs, Rest). read_term_from_chars_(T, Opts, Cs, Rest) :- '$read_term_from_chars'(T, Opts, Cs, Rest). :- help(read_from_atom(+atom,?term), [iso(false)]). read_from_atom(A, T) :- read_term_from_atom(A, T, []). with_output_to(chars(Cs), Goal) :- setup_call_cleanup( '$capture_output', once(Goal), '$capture_output_to_chars'(Cs) ), !. with_output_to(string(Cs), Goal) :- setup_call_cleanup( '$capture_output', once(Goal), '$capture_output_to_chars'(Cs) ), !. with_output_to(atom(Cs), Goal) :- setup_call_cleanup( '$capture_output', once(Goal), '$capture_output_to_atom'(Cs) ), !. iso_dif(X, Y) :- X \== Y, ( X \= Y -> true ; throw(error(instantiation_error,iso_dif/2)) ). :- help(numbervars(+term,+integer,?integer), [iso(false)]). numbervars(Term, N0, N) :- must_be(N0, integer, numbervars/3, _), can_be(N, integer, numbervars/3, _), term_variables(Term, Vars), numberlist_(Vars, N0, N). numberlist_([], N, N). numberlist_(['$VAR'(N0)|Vars], N0, N) :- N1 is N0+1, numberlist_(Vars, N1, N). :- help(read_line_to_codes(+stream,?list), [iso(false)]). read_line_to_codes(Stream, Codes) :- read_line_to_string(Stream, String), string_codes(String, Codes). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % thread_property(P) :- thread_self(Id), thread_property(Id, P). :- meta_predicate(with_mutex(-,0)). with_mutex(Id, Goal) :- setup_call_cleanup(mutex_lock(Id), once(Goal), mutex_unlock(Id)). :- meta_predicate(thread_create(0,-)). thread_create(Goal, Id) :- thread_create(Goal, Id, []). thread_send_message(Term) :- thread_self(Id), thread_send_message(Id, Term). thread_get_message(Term) :- thread_self(Id), thread_get_message(Id, Term). thread_peek_message(Term) :- thread_self(Id), thread_peek_message(Id, Term). xthread_statistics(K, V) :- thread_self(Id), thread_statistics(Id, K, V). message_queue_create(Id) :- message_queue_create(Id, []). mutex_create(Id) :- mutex_create(Id, []). % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % NOTE: this doesn't display var names properly... :- help(pretty(+predicateindicator), [iso(false)]). pretty(PI) :- nonvar(PI), ( PI = Name/Arity0 -> Arity = Arity0 ; PI = Name//Arity0 -> Arity is Arity0 + 2 ; type_error(predicate_indicator, PI, listing/1) ), functor(Head, Name, Arity), \+ \+ clause(Head, _), % only true if there is at least one clause ( clause(Head, Body), ( Body == true -> portray_clause(Head) ; portray_clause((Head :- Body)) ), false ; true ). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % :- help(current_op(?integer,?atom,?atom), [iso(true)]). current_op(A, B, C) :- var(A), var(B), var(C), !, ( '$ops_dirty' -> (retractall('$op'(_,_,_)),'$load_ops') ; true ), '$op'(C, B, A). current_op(_, _, C) :- nonvar(C), \+ atom(C), !, throw(error(type_error(atom,C), current_op/3)). current_op(_, B, _) :- nonvar(B), \+ atom(B), !, throw(error(domain_error(operator_specifier, B), current_op/3)). current_op(_, B, _) :- nonvar(B), \+ memberchk(B,[xf, yf, fx, fy, xfx, xfy, yfx]), !, throw(error(domain_error(operator_specifier, B), current_op/3)). current_op(A, _, _) :- nonvar(A), \+ integer(A), !, throw(error(domain_error(operator_priority, A), current_op/3)). current_op(A, _, _) :- nonvar(A), \+ (A >= 0), !, throw(error(domain_error(operator_priority, A), current_op/3)). current_op(A, _, _) :- nonvar(A), \+ (A =< 1200), !, throw(error(domain_error(operator_priority, A), current_op/3)). current_op(A, B, C) :- ( '$ops_dirty' -> (retractall('$op'(_,_,_)),'$load_ops') ; true ), '$op'(C, B, A). % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % :- help(sre_match_all_in_file(+pattern,+filename,-list), [iso(false)]). sre_match_all_in_file(Pat, Filename, L) :- setup_call_cleanup( open(Filename, read, S, [mmap(Cs)]), sre_match_all(Pat, Cs, L), close(S) ). :- help(sre_match_all(+pattern,+text,-list), [iso(false)]). sre_match_all(Pat, Text, L) :- sre_compile(Pat, Reg), sre_match_all_(Reg, Text, [], L2), reverse(L2, L). sre_match_all_(_, [], L, L) :- !. sre_match_all_(Reg, TextIn, L0, L) :- sre_matchp(Reg, TextIn, Match, TextOut), ( TextOut \= [] -> sre_match_all_(Reg, TextOut, [Match|L0], L) ; L = L0 ). :- help(sre_match_all_pos_in_file(+pattern,+filename,-list), [iso(false)]). sre_match_all_pos_in_file(Pat, Filename, L) :- setup_call_cleanup( open(Filename, read, S, [mmap(Cs)]), sre_match_all_pos(Pat, Cs, L), close(S) ). :- help(sre_match_all_pos(+pattern,+subst,-list), [iso(false)]). sre_match_all_pos(Pat, Text, L) :- sre_compile(Pat, Reg), sre_match_all_pos_(Reg, Text, 0, [], L2), reverse(L2, L). sre_match_all_pos_(_, [], _, L, L) :- !. sre_match_all_pos_(Reg, TextIn, Offset, L0, L) :- sre_matchp(Reg, TextIn, Match, TextOut), string_length(TextIn, N0), string_length(Match, N1), string_length(TextOut, N2), Pos is N0 - (N1 + N2) + Offset, Pos2 is Pos + 1, ( TextOut \= [] -> sre_match_all_pos_(Reg, TextOut, Pos2, [Pos-N1|L0], L) ; L = L0 ). :- help(sre_subst_all_in_file(+pattern,+filename,+subst,-list), [iso(false)]). sre_subst_all_in_file(Pat, Filename, Subst, L) :- setup_call_cleanup( open(Filename, read, S, [mmap(Cs)]), sre_subst_all(Pat, Cs, Subst, L), close(S) ). :- help(sre_subst_all(+pattern,+text,+subst,-text), [iso(false)]). sre_subst_all(Pat, Text, Subst, L) :- sre_compile(Pat, Reg), sre_subst_all_(Reg, Text, Subst, [], L0), reverse(L0, L1), append(L1, L). sre_subst_all_(_, [], _, L, L) :- !. sre_subst_all_(Reg, TextIn, Subst, L0, L) :- sre_substp(Reg, TextIn, Prefix, TextOut), ( TextOut \= [] -> sre_subst_all_(Reg, TextOut, Subst, [Subst,Prefix|L0], L) ; L = [Prefix|L0] ). % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% /********************************************************/ /* Float Approximation */ /********************************************************/ :- help(rationalize(+number,-rational), [iso(false)]). /** * See also: * Continued Fractions on the Stern-Brocot Tree * https://www.cut-the-knot.org/blue/ContinuedFractions.shtml */ /** * rationalize(X): * If X is a number then the function returns an approximate rational number. */ % rationalize(+Number, -Rational) rationalize(F, C/B) :- F < 0, !, H is -F, rationalize(H, A/B), C is -A. rationalize(F, R) :- rat_start(F, V, W), divmod(V, W, D, U), rat_iter(W/U, D/1, 1/0, F, R). % rat_start(+Number, -Integer, -Integer) rat_start(F, V, W) :- parts(F, M, E), (E < 0 -> V = M, W is 2^(-E); V is M*E^2, W = 1). % rat_iter(+Rational, +Rational, +Rational, +Number, -Rational) rat_iter(_, X, _, Y, X) :- X =:= Y, !. rat_iter(_/0, X, _, _, X) :- !. rat_iter(V/W, M/N, P/Q, Y, X) :- divmod(V, W, D, U), R is D*M+P, S is D*N+Q, rat_iter(W/U, R/S, M/N, Y, X). /********************************************************/ /* IEEE Simulation */ /********************************************************/ % parts(+Number, -Integer, -Integer) parts(F, M, E) :- logb(F, G), E is G-52, U is -E, scalb(F, U, N), M is truncate(N). % scalb(+Number, +Integer, -Number) scalb(M, E, R) :- R is M*2**E. % logb(+NUmber, -Integer) logb(M, E) :- E is floor(log(M)/log(2)). goal_expansion(maplist(G, L1), Goal) :- nonvar(G), !, term_variables(G, Args), gensym:gensym(maplist_, U), Goal =.. [U,Args,L1], G1 =.. [U,Args,[]], user:'$assertz'(G1), % not dynamic G2a =.. [U,Args,[E1|T1]], G2b =.. [U,Args,T1], user:'$assertz'((G2a :- call(G, E1), G2b)), % not dynamic true. goal_expansion(maplist(G, L1), maplist(G, L1)). goal_expansion(maplist(G, L1, L2), Goal) :- nonvar(G), !, term_variables(G, Args), gensym:gensym(maplist_, U), Goal =.. [U,Args,L1,L2], G1 =.. [U,Args,[],[]], user:'$assertz'(G1), % not dynamic G2a =.. [U,Args,[E1|T1],[E2|T2]], G2b =.. [U,Args,T1,T2], user:'$assertz'((G2a :- call(G, E1, E2), G2b)), % not dynamic true. goal_expansion(maplist(G, L1, L2), maplist(G, L1, L2)). goal_expansion(call_det(G, Det), Goal) :- nonvar(G), !, Goal = ('$get_level'(L1), call(G), '$get_level'(L2), (L1 = L2 -> Det = true; Det = false)), true. goal_expansion(call_det(G, V), call_det(G, V)). :- module(charsio, [ char_type/2, get_line_to_chars/3, get_single_char/1, get_n_chars/3 ]). get_single_char(C) :- get_unbuffered_char(C). get_line_to_chars(Stream, Cs0, Cs) :- getline(Stream, Line,[terminator(true)]), partial_string(Line,Cs0,Cs). get_n_chars(Stream, N, Cs) :- '$get_chars'(Stream, N, Cs). fabricate_var_name(VarType, VarName, N) :- char_code('A', AC), LN is N mod 26 + AC, char_code(LC, LN), NN is N // 26, ( NN =:= 0 -> ( VarType == fabricated -> atom_chars(VarName, ['_', LC]) ; VarType == numbervars -> atom_chars(VarName, [LC]) ) ; number_chars(NN, NNChars), ( VarType == fabricated -> atom_chars(VarName, ['_', LC | NNChars]) ; VarType == numbervars -> atom_chars(VarName, [LC | NNChars]) ) ). %% char_type(?Char, ?Type). % % Type is one of the categories that Char fits in. % At least one of the arguments must be ground. % Possible categories are: % % - `alnum` % - `alpha` % - `alphabetic` % - `alphanumeric` % - `ascii` % - `ascii_graphic` % - `ascii_punctuation` % - `binary_digit` % - `control` % - `decimal_digit` % - `exponent` % - `graphic` % - `graphic_token` % - `hexadecimal_digit` % - `layout` % - `lower` % - `meta` % - `numeric` % - `octal_digit` % - `octet` % - `prolog` % - `sign` % - `solo` % - `symbolic_control` % - `symbolic_hexadecimal` % - `upper` % - `lower(Lower)` % - `upper(Upper)` % - `whitespace` % % An example: % % ``` % ?- char_type(a, Type). % Type = alnum % ; Type = alpha % ; Type = alphabetic % ; Type = alphanumeric % ; Type = ascii % ; Type = ascii_graphic % ; Type = hexadecimal_digit % ; Type = lower % ; Type = octet % ; Type = prolog % ; Type = symbolic_control % ; Type = lower("a") % ; Type = upper("A") % ; false. % ``` % % Note that uppercase and lowercase transformations use a string. This is because % some characters do not map 1:1 between lowercase and uppercase. char_type(Char, Type) :- can_be(character, Char), ( \+ ctype(Type) -> domain_error(char_type, Type, char_type/2) ; true ), ( ground(Char) -> ctype(Type), '$char_type'(Char, Type) ; ground(Type) -> ccode(Code), char_code(Char, Code), '$char_type'(Char, Type) ; must_be(character, Char) ). % 0xD800 to 0xDFFF are surrogate code points used by UTF-16. ccode(Code) :- between(0, 0xD7FF, Code). ccode(Code) :- between(0xE000, 0x10FFFF, Code). ctype(alnum). ctype(alpha). ctype(alphabetic). ctype(alphanumeric). ctype(ascii). ctype(ascii_graphic). ctype(ascii_punctuation). ctype(binary_digit). ctype(control). ctype(decimal_digit). ctype(exponent). ctype(graphic). ctype(graphic_token). ctype(hexadecimal_digit). ctype(layout). ctype(lower). ctype(meta). ctype(numeric). ctype(octal_digit). ctype(octet). ctype(prolog). ctype(sign). ctype(solo). ctype(symbolic_control). ctype(symbolic_hexadecimal). ctype(lower(_)). ctype(upper(_)). ctype(upper). ctype(whitespace). ):- module(concurrent, [ future/3, future_all/2, future_any/2, future_cancel/1, future_done/1, await/2 ]). :- use_module(library(apply)). :- dynamic('$concurrent_count'/1). :- dynamic('$future'/1). '$concurrent_count'(0). future(Template, Goal, F) :- retract('$concurrent_count'(N)), N1 is N + 1, assertz('$concurrent_count'(N1)), F = '$future'(N), assertz(F), Task0 = ((Goal -> (retract(F), send([F-Template])) ; (retract(F), fail))), copy_term(Task0, Task), write_term_to_atom(A, Task, [quoted(true)]), call_task(callgoal_, A, F). :- meta_predicate(future(-,0,?)). :- help(future(+term,+callable,?list), [iso(false)]). future_all(Fs, all(Fs)). future_any(Fs, any(Fs)). :- help(future_all(+list,-term), [iso(false)]). :- help(future_any(+list,-term), [iso(false)]). :- help(future_any(+list,-term), [iso(false)]). await(all(Fs), Templates) :- !, findall([F-Template], ( member(F, Fs), wait, recv([F-Template]) ), Msgs), msort(Msgs, Msgs1), strip_prefix_(Msgs1, [], Templates0), Templates = Templates0. await(any(Fs), Template) :- !, await, recv([F-Template0]), member(F, Fs), !, Template = Template0. await(F, Template) :- repeat, wait, recv([F-Template]), !. future_cancel(all(Fs)) :- Fs = [F|Rest], future_cancel(F), future_cancel(Rest). future_cancel(any(Fs)) :- Fs = [F|Rest], future_cancel(F) -> true ; future_cancel(any(Rest)). future_cancel([]). future_cancel('$future'(N)) :- '$cancel_future'(N). future_done(all(Fs)) :- Fs = [F|Rest], future_done(F), future_done(Rest). future_done(any(Fs)) :- Fs = [F|Rest], future_done(F) -> true ; future_done(any(Rest)). future_done([]). future_done(F) :- \+ clause(F, _). :- help(await(+term,?term), [iso(false)]). strip_prefix_([], L0, L) :- reverse(L0, L). strip_prefix_([[_-V]|Rest], Init, L) :- strip_prefix_(Rest, [V|Init], L). % NOTE: going via an atom through callgoal/1 is to get around a bug to % do with passing variables in call_task/1. Maybe it will get fixed one day. callgoal_(A, '$future'(N)) :- read_term_from_atom(A, T, []), '$set_future'(N), T. \D/* CLP(ℤ): Constraint Logic Programming over Integers. Author: Markus Triska E-mail: triska@metalevel.at WWW: https://www.metalevel.at Copyright (C): 2016-2024 Markus Triska This library provides CLP(ℤ): Constraint Logic Programming over Integers ========================================== Highlights: -) DECLARATIVE implementation of integer arithmetic. -) Fully relational, MONOTONIC execution mode. -) Always TERMINATING labeling. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ :- module(clpz, [ op(760, yfx, #<==>), op(750, xfy, #==>), op(750, yfx, #<==), op(740, yfx, #\/), op(730, yfx, #\), op(720, yfx, #/\), op(710, fy, #\), op(700, xfx, #>), op(700, xfx, #<), op(700, xfx, #>=), op(700, xfx, #=<), op(700, xfx, #=), op(700, xfx, #\=), op(700, xfx, in), op(700, xfx, ins), op(450, xfx, ..), % should bind more tightly than \/ op(150, fx, #), (#>)/2, (#<)/2, (#>=)/2, (#=<)/2, (#=)/2, (#\=)/2, (#\)/1, (#<==>)/2, (#==>)/2, (#<==)/2, (#\/)/2, (#\)/2, (#/\)/2, (in)/2, (ins)/2, all_different/1, all_distinct/1, nvalue/2, sum/3, scalar_product/4, tuples_in/2, labeling/2, label/1, indomain/1, lex_chain/1, serialized/2, global_cardinality/2, global_cardinality/3, circuit/1, cumulative/1, cumulative/2, disjoint2/1, element/3, automaton/3, automaton/8, zcompare/3, chain/2, fd_var/1, fd_inf/2, fd_sup/2, fd_size/2, fd_dom/2, % for use in predicates from library(reif) clpz_t/2, (#=)/3, (#<)/3 % called from goal_expansion % clpz_equal/2, % clpz_geq/2 ]). :- use_module(library(assoc)). :- use_module(library(pairs)). :- use_module(library(between)). :- use_module(library(lists)). :- use_module(library(atts)). :- use_module(library(iso_ext)). :- use_module(library(dcgs)). :- use_module(library(terms)). :- use_module(library(error), [domain_error/3, type_error/3, can_be/2]). :- use_module(library(si)). :- use_module(library(freeze)). :- use_module(library(arithmetic)). :- use_module(library(debug)). :- use_module(library(format)). % :- use_module(library(types)). :- attribute clpz/1, clpz_aux/1, clpz_relation/1, edges/1, flow/1, parent/1, free/1, g0_edges/1, used/1, lowlink/1, value/1, visited/1, index/1, in_stack/1, clpz_gcc_vs/1, clpz_gcc_num/1, clpz_gcc_occurred/1, queue/2, disabled/0. :- dynamic(monotonic/0). :- dynamic(clpz_equal_/2). :- dynamic(clpz_geq_/2). :- dynamic(clpz_neq/2). /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Compatibility predicates. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ cyclic_term(T) :- \+ acyclic_term(T). must_be(What, Term) :- must_be(What, unknown(Term)-1, Term). must_be(ground, _, Term) :- !, ( ground(Term) -> true ; instantiation_error(Term) ). must_be(acyclic, Where, Term) :- !, ( acyclic_term(Term) -> true ; domain_error(acyclic_term, Term, Where) ). must_be(list, Where, Term) :- !, ( list_si(Term) -> true ; type_error(list, Term, Where) ). must_be(list(What), Where, Term) :- !, must_be(list, Where, Term), maplist(must_be(What, Where), Term). must_be(Type, _, Term) :- error:must_be(Type, Term). instantiation_error(Term) :- instantiation_error(Term, unknown(Term)-1). instantiation_error(_, Goal-Arg) :- throw(error(instantiation_error, instantiation_error(Goal, Arg))). domain_error(Expectation, Term) :- domain_error(Expectation, Term, unknown(Term)-1). type_error(Expectation, Term) :- type_error(Expectation, Term, unknown(Term)-1). :- meta_predicate(partition(1, ?, ?, ?)). partition(Pred, Ls0, As, Bs) :- include(Pred, Ls0, As), exclude(Pred, Ls0, Bs). partition(Pred, Ls0, Ls, Es, Gs) :- partition_(Ls0, Pred, Ls, Es, Gs). partition_([], _, [], [], []). partition_([X|Xs], Pred, Ls0, Es0, Gs0) :- call(Pred, X, Cmp), ( Cmp = (<) -> Ls0 = [X|Rest], partition_(Xs, Pred, Rest, Es0, Gs0) ; Cmp = (=) -> Es0 = [X|Rest], partition_(Xs, Pred, Ls0, Rest, Gs0) ; Cmp = (>) -> Gs0 = [X|Rest], partition_(Xs, Pred, Ls0, Es0, Rest) ). /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - include/3 and exclude/3 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ :- meta_predicate(include(1, ?, ?)). include(_, [], []). include(Goal, [L|Ls0], Ls) :- ( call(Goal, L) -> Ls = [L|Rest] ; Ls = Rest ), include(Goal, Ls0, Rest). :- meta_predicate(exclude(1, ?, ?)). exclude(_, [], []). exclude(Goal, [L|Ls0], Ls) :- ( call(Goal, L) -> Ls = Rest ; Ls = [L|Rest] ), exclude(Goal, Ls0, Rest). %:- discontiguous clpz:goal_expansion/5. /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Public operators. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ :- op(760, yfx, #<==>). :- op(750, xfy, #==>). :- op(750, yfx, #<==). :- op(740, yfx, #\/). :- op(730, yfx, #\). :- op(720, yfx, #/\). :- op(710, fy, #\). :- op(700, xfx, #>). :- op(700, xfx, #<). :- op(700, xfx, #>=). :- op(700, xfx, #=<). :- op(700, xfx, #=). :- op(700, xfx, #\=). :- op(700, xfx, in). :- op(700, xfx, ins). :- op(450, xfx, ..). % should bind more tightly than \/ :- op(150, fx, #). /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Privately needed operators. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ :- op(700, xfx, cis). :- op(700, xfx, cis_geq). :- op(700, xfx, cis_gt). :- op(700, xfx, cis_leq). :- op(700, xfx, cis_lt). :- op(1200, xfx, ++>). /** Constraint Logic Programming over Integers ## Introduction This library provides CLP(ℤ): Constraint Logic Programming over Integers. CLP(ℤ) is an instance of the general CLP(_X_) scheme, extending logic programming with reasoning over specialised domains. CLP(ℤ) lets us reason about *integers* in a way that honors the relational nature of Prolog. There are two major use cases of CLP(ℤ) constraints: 1. [*declarative integer arithmetic*](#clpz-integer-arith) 2. solving *combinatorial problems* such as planning, scheduling and allocation tasks. The predicates of this library can be classified as: * _arithmetic_ constraints like `(#=)/2`, `(#>)/2` and `(#\=)/2` * the _membership_ constraints `(in)/2` and `(ins)/2` * the _enumeration_ predicates `indomain/1`, `label/1` and `labeling/2` * _combinatorial_ constraints like `all_distinct/1` and `global_cardinality/2` * _reification_ predicates such as `(#<==>)/2` * _reflection_ predicates such as `fd_dom/2` In most cases, [_arithmetic constraints_](#clpz-arith-constraints) are the only predicates you will ever need from this library. When reasoning over integers, simply replace low-level arithmetic predicates like `(is)/2` and `(>)/2` by the corresponding CLP(ℤ) constraints like `(#=)/2` and `(#>)/2` to honor and preserve declarative properties of your programs. For satisfactory performance, arithmetic constraints are implicitly rewritten at compilation time so that low-level fallback predicates are automatically used whenever possible. Almost all Prolog programs also reason about integers. Therefore, it is highly advisable that you make CLP(ℤ) constraints available in all your programs. One way to do this is to put the following directive in your `~/.scryerrc` initialisation file: ``` :- use_module(library(clpz)). ``` All example programs that appear in the CLP(ℤ) documentation assume that you have done this. Important concepts and principles of this library are illustrated by means of usage examples that are available in a public git repository: [*https://github.com/triska/clpz*](https://github.com/triska/clpz) If you are used to the complicated operational considerations that low-level arithmetic primitives necessitate, then moving to CLP(ℤ) constraints may, due to their power and convenience, at first feel to you excessive and almost like cheating. It _isn't_. Constraints are an integral part of all popular Prolog systems, and they are designed to help you eliminate and avoid the use of low-level and less general primitives by providing declarative alternatives that are meant to be used instead. When teaching Prolog, CLP(ℤ) constraints should be introduced _before_ explaining low-level arithmetic predicates and their procedural idiosyncrasies. This is because constraints are easy to explain, understand and use due to their purely relational nature. In contrast, the modedness and directionality of low-level arithmetic primitives are impure limitations that are better deferred to more advanced lectures. More information about CLP(ℤ) constraints and their implementation is contained in: [*metalevel.at/drt.pdf*](https://www.metalevel.at/drt.pdf) The best way to discuss applying, improving and extending CLP(ℤ) constraints is to use the dedicated `clpz` tag on [stackoverflow.com](http://stackoverflow.com). Several of the world's foremost CLP(ℤ) experts regularly participate in these discussions and will help you for free on this platform. {#clpz-arith-constraints} ## Arithmetic constraints In modern Prolog systems, *arithmetic constraints* subsume and supersede low-level predicates over integers. The main advantage of arithmetic constraints is that they are true _relations_ and can be used in all directions. For most programs, arithmetic constraints are the only predicates you will ever need from this library. The most important arithmetic constraint is `(#=)/2`, which subsumes both `(is)/2` and `(=:=)/2` over integers. Use `(#=)/2` to make your programs more general. In total, the arithmetic constraints are: | Expr1 `#=` Expr2 | Expr1 equals Expr2 | | Expr1 `#\=` Expr2 | Expr1 is not equal to Expr2 | | Expr1 `#>=` Expr2 | Expr1 is greater than or equal to Expr2 | | Expr1 `#=<` Expr2 | Expr1 is less than or equal to Expr2 | | Expr1 `#>` Expr2 | Expr1 is greater than Expr2 | | Expr1 `#<` Expr2 | Expr1 is less than Expr2 | `Expr1` and `Expr2` denote *arithmetic expressions*, which are: | _integer_ | Given value | | _variable_ | Unknown integer | | #(_variable_) | Unknown integer | | -Expr | Unary minus | | Expr + Expr | Addition | | Expr * Expr | Multiplication | | Expr - Expr | Subtraction | | Expr ^ Expr | Exponentiation | | min(Expr,Expr) | Minimum of two expressions | | max(Expr,Expr) | Maximum of two expressions | | Expr `mod` Expr | Modulo induced by floored division | | Expr `rem` Expr | Modulo induced by truncated division | | abs(Expr) | Absolute value | | sign(Expr) | Sign (-1, 0, 1) of Expr | | Expr // Expr | Truncated integer division | | Expr div Expr | Floored integer division | where `Expr` again denotes an arithmetic expression. The bitwise operations `(\)/1`, `(/\)/2`, `(\/)/2`, `(>>)/2`, `(<<)/2`, `lsb/1`, `msb/1`, `popcount/1` and `(xor)/2` are also supported. {#clpz-integer-arith} ## Declarative integer arithmetic The [_arithmetic constraints_](#clpz-arith-constraints) `(#=)/2`, `(#>)/2` etc. are meant to be used _instead_ of the primitives `(is)/2`, `(=:=)/2`, `(>)/2` etc. over integers. Almost all Prolog programs also reason about integers. Therefore, it is recommended that you put the following directive in your `~/.scryerrc` initialisation file to make CLP(ℤ) constraints available in all your programs: ``` :- use_module(library(clpz)). ``` Throughout the following, it is assumed that you have done this. The most basic use of CLP(ℤ) constraints is _evaluation_ of arithmetic expressions involving integers. For example: ``` ?- X #= 1+2. X = 3. ``` This could in principle also be achieved with the lower-level predicate `(is)/2`. However, an important advantage of arithmetic constraints is their purely relational nature: Constraints can be used in _all directions_, also if one or more of their arguments are only partially instantiated. For example: ``` ?- 3 #= Y+2. Y = 1. ``` This relational nature makes CLP(ℤ) constraints easy to explain and use, and well suited for beginners and experienced Prolog programmers alike. In contrast, when using low-level integer arithmetic, we get: ``` ?- 3 is Y+2. error(instantiation_error,(is)/2). ?- 3 =:= Y+2. error(instantiation_error,(is)/2). ``` Due to the necessary operational considerations, the use of these low-level arithmetic predicates is considerably harder to understand and should therefore be deferred to more advanced lectures. For supported expressions, CLP(ℤ) constraints are drop-in replacements of these low-level arithmetic predicates, often yielding more general programs. See [`n_factorial/2`](#clpz-factorial) for an example. This library uses `goal_expansion/2` to automatically rewrite constraints at compilation time so that low-level arithmetic predicates are _automatically_ used whenever possible. For example, the predicate: ``` positive_integer(N) :- N #>= 1. ``` is executed as if it were written as: ``` positive_integer(N) :- ( integer(N) -> N >= 1 ; N #>= 1 ). ``` This illustrates why the performance of CLP(ℤ) constraints is almost always completely satisfactory when they are used in modes that can be handled by low-level arithmetic. To disable the automatic rewriting, set the Prolog flag `clpz_goal_expansion` to `false`. If you are used to the complicated operational considerations that low-level arithmetic primitives necessitate, then moving to CLP(ℤ) constraints may, due to their power and convenience, at first feel to you excessive and almost like cheating. It _isn't_. Constraints are an integral part of all popular Prolog systems, and they are designed to help you eliminate and avoid the use of low-level and less general primitives by providing declarative alternatives that are meant to be used instead. {#clpz-factorial} ## Example: Factorial relation We illustrate the benefit of using `(#=)/2` for more generality with a simple example. Consider first a rather conventional definition of `n_factorial/2`, relating each natural number _N_ to its factorial _F_: ``` n_factorial(0, 1). n_factorial(N, F) :- N #> 0, N1 #= N - 1, n_factorial(N1, F1), F #= N * F1. ``` This program uses CLP(ℤ) constraints _instead_ of low-level arithmetic throughout, and everything that _would have worked_ with low-level arithmetic _also_ works with CLP(ℤ) constraints, retaining roughly the same performance. For example: ``` ?- n_factorial(47, F). F = 258623241511168180642964355153611979969197632389120000000000 ; false. ``` Now the point: Due to the increased flexibility and generality of CLP(ℤ) constraints, we are free to _reorder_ the goals as follows: ``` n_factorial(0, 1). n_factorial(N, F) :- N #> 0, N1 #= N - 1, F #= N * F1, n_factorial(N1, F1). ``` In this concrete case, _termination_ properties of the predicate are improved. For example, the following queries now both terminate: ``` ?- n_factorial(N, 1). N = 0 ; N = 1 ; false. ?- n_factorial(N, 3). false. ``` To make the predicate terminate if _any_ argument is instantiated, add the (implied) constraint `F #\= 0` before the recursive call. Otherwise, the query `n_factorial(N, 0)` is the only non-terminating case of this kind. The value of CLP(ℤ) constraints does _not_ lie in completely freeing us from _all_ procedural phenomena. For example, the two programs do not even have the same _termination properties_ in all cases. Instead, the primary benefit of CLP(ℤ) constraints is that they allow you to try different execution orders and apply [*declarative debugging*](https://www.metalevel.at/prolog/debugging) techniques _at all_! Reordering goals (and clauses) can significantly impact the performance of Prolog programs, and you are free to try different variants if you use declarative approaches. Moreover, since all CLP(ℤ) constraints _always terminate_, placing them earlier can at most _improve_, never worsen, the termination properties of your programs. An additional benefit of CLP(ℤ) constraints is that they eliminate the complexity of introducing `(is)/2` and `(=:=)/2` to beginners, since _both_ predicates are subsumed by `(#=)/2` when reasoning over integers. {#clpz-combinatorial} ## Combinatorial constraints In addition to subsuming and replacing low-level arithmetic predicates, CLP(ℤ) constraints are often used to solve combinatorial problems such as planning, scheduling and allocation tasks. Among the most frequently used *combinatorial constraints* are `all_distinct/1`, `global_cardinality/2` and `cumulative/2`. This library also provides several other constraints like `disjoint2/1` and `automaton/8`, which are useful in more specialized applications. {#clpz-domains} ## Domains Each CLP(ℤ) variable has an associated set of admissible integers, which we call the variable's *domain*. Initially, the domain of each CLP(ℤ) variable is the set of _all_ integers. CLP(ℤ) constraints like `(#=)/2`, `(#>)/2` and `(#\=)/2` can at most reduce, and never extend, the domains of their arguments. The constraints `(in)/2` and `(ins)/2` let us explicitly state domains of CLP(ℤ) variables. The process of determining and adjusting domains of variables is called constraint *propagation*, and it is performed automatically by this library. When the domain of a variable contains only one element, then the variable is automatically unified to that element. Domains are taken into account when further constraints are stated, and by enumeration predicates like labeling/2. {#clpz-sudoku} ## Example: Sudoku As another example, consider _Sudoku_: It is a popular puzzle over integers that can be easily solved with CLP(ℤ) constraints. ``` sudoku(Rows) :- length(Rows, 9), maplist(same_length(Rows), Rows), append(Rows, Vs), Vs ins 1..9, maplist(all_distinct, Rows), transpose(Rows, Columns), maplist(all_distinct, Columns), Rows = [As,Bs,Cs,Ds,Es,Fs,Gs,Hs,Is], blocks(As, Bs, Cs), blocks(Ds, Es, Fs), blocks(Gs, Hs, Is). blocks([], [], []). blocks([N1,N2,N3|Ns1], [N4,N5,N6|Ns2], [N7,N8,N9|Ns3]) :- all_distinct([N1,N2,N3,N4,N5,N6,N7,N8,N9]), blocks(Ns1, Ns2, Ns3). problem(1, [[_,_,_,_,_,_,_,_,_], [_,_,_,_,_,3,_,8,5], [_,_,1,_,2,_,_,_,_], [_,_,_,5,_,7,_,_,_], [_,_,4,_,_,_,1,_,_], [_,9,_,_,_,_,_,_,_], [5,_,_,_,_,_,_,7,3], [_,_,2,_,1,_,_,_,_], [_,_,_,_,4,_,_,_,9]]). ``` Sample query: ``` ?- problem(1, Rows), sudoku(Rows), maplist(portray_clause, Rows). [9,8,7,6,5,4,3,2,1]. [2,4,6,1,7,3,9,8,5]. [3,5,1,9,2,8,7,4,6]. [1,2,8,5,3,7,6,9,4]. [6,3,4,8,9,2,1,5,7]. [7,9,5,4,6,1,8,3,2]. [5,1,9,2,8,6,4,7,3]. [4,7,2,3,1,9,5,6,8]. [8,6,3,7,4,5,2,1,9]. Rows = [[9,8,7,6,5,4,3,2,1]|...]. ``` In this concrete case, the constraint solver is strong enough to find the unique solution without any search. {#clpz-residual-goals} ## Residual goals Here is an example session with a few queries and their answers: ``` ?- X #> 3. clpz:(X in 4..sup). ?- X #\= 20. clpz:(X in inf..19\/21..sup). ?- 2*X #= 10. X = 5. ?- X*X #= 144. clpz:(X in-12\/12) ; false. ?- 4*X + 2*Y #= 24, X + Y #= 9, [X,Y] ins 0..sup. X = 3, Y = 6. ?- X #= Y #<==> B, X in 0..3, Y in 4..5. B = 0, clpz:(X in 0..3), clpz:(Y in 4..5). ``` The answers emitted by the toplevel are called _residual programs_, and the goals that comprise each answer are called *residual goals*. In each case above, and as for all pure programs, the residual program is declaratively equivalent to the original query. From the residual goals, it is clear that the constraint solver has deduced additional domain restrictions in many cases. To inspect residual goals, it is best to let the toplevel display them for us. Wrap the call of your predicate into `call_residue_vars/2` to make sure that all constrained variables are displayed. To make the constraints a variable is involved in available as a Prolog term for further reasoning within your program, use `copy_term/3`. For example: ``` ?- X #= Y + Z, X in 0..5, copy_term([X,Y,Z], [X,Y,Z], Gs). Gs = [clpz: (X in 0..5), clpz: (Y+Z#=X)], X in 0..5, Y+Z#=X. ``` This library also provides _reflection_ predicates (like `fd_dom/2`, `fd_size/2` etc.) with which we can inspect a variable's current domain. These predicates can be useful if you want to implement your own labeling strategies. {#clpz-search} ## Core relations and search Using CLP(ℤ) constraints to solve combinatorial tasks typically consists of two phases: 1. First, all relevant constraints are stated. 2. Second, if the domain of each involved variable is _finite_, then _enumeration predicates_ can be used to search for concrete solutions. It is good practice to keep the modeling part, via a dedicated predicate called the *core relation*, separate from the actual search for solutions. This lets us observe termination and determinism properties of the core relation in isolation from the search, and more easily try different search strategies. As an example of a constraint satisfaction problem, consider the cryptoarithmetic puzzle SEND + MORE = MONEY, where different letters denote distinct integers between 0 and 9. It can be modeled in CLP(ℤ) as follows: ``` puzzle([S,E,N,D] + [M,O,R,E] = [M,O,N,E,Y]) :- Vars = [S,E,N,D,M,O,R,Y], Vars ins 0..9, all_different(Vars), S*1000 + E*100 + N*10 + D + M*1000 + O*100 + R*10 + E #= M*10000 + O*1000 + N*100 + E*10 + Y, M #\= 0, S #\= 0. ``` Notice that we are _not_ using `labeling/2` in this predicate, so that we can first execute and observe the modeling part in isolation. Sample query and its result (actual variables replaced for readability): ``` ?- puzzle(As+Bs=Cs). As = [9, A2, A3, A4], Bs = [1, 0, B3, A2], Cs = [1, 0, A3, A2, C5], A2 in 4..7, all_different([9, A2, A3, A4, 1, 0, B3, C5]), 91*A2+A4+10*B3#=90*A3+C5, A3 in 5..8, A4 in 2..8, B3 in 2..8, C5 in 2..8. ``` From this answer, we see that this core relation _terminates_ and is in fact _deterministic_. Moreover, we see from the residual goals that the constraint solver has deduced more stringent bounds for all variables. Such observations are only possible if modeling and search parts are cleanly separated. Labeling can then be used to search for solutions in a separate predicate or goal: ``` ?- puzzle(As+Bs=Cs), label(As). As = [9,5,6,7], Bs = [1,0,8,5], Cs = [1,0,6,5,2] ; false. ``` In this case, it suffices to label a subset of variables to find the puzzle's unique solution, since the constraint solver is strong enough to reduce the domains of remaining variables to singleton sets. In general though, it is necessary to label all variables to obtain ground solutions. {#clpz-n-queens} ## Example: Eight queens puzzle We illustrate the concepts of the preceding sections by means of the so-called _eight queens puzzle_. The task is to place 8 queens on an 8x8 chessboard such that none of the queens is under attack. This means that no two queens share the same row, column or diagonal. To express this puzzle via CLP(ℤ) constraints, we must first pick a suitable representation. Since CLP(ℤ) constraints reason over _integers_, we must find a way to map the positions of queens to integers. Several such mappings are conceivable, and it is not immediately obvious which we should use. On top of that, different constraints can be used to express the desired relations. For such reasons, _modeling_ combinatorial problems via CLP(ℤ) constraints often necessitates some creativity and has been described as more of an art than a science. In our concrete case, we observe that there must be exactly one queen per column. The following representation therefore suggests itself: We are looking for 8 integers, one for each column, where each integer denotes the _row_ of the queen that is placed in the respective column, and which are subject to certain constraints. In fact, let us now generalize the task to the so-called _N queens puzzle_, which is obtained by replacing 8 by _N_ everywhere it occurs in the above description. We implement the above considerations in the *core relation* `n_queens/2`, where the first argument is the number of queens (which is identical to the number of rows and columns of the generalized chessboard), and the second argument is a list of _N_ integers that represents a solution in the form described above. ``` n_queens(N, Qs) :- length(Qs, N), Qs ins 1..N, safe_queens(Qs). safe_queens([]). safe_queens([Q|Qs]) :- safe_queens(Qs, Q, 1), safe_queens(Qs). safe_queens([], _, _). safe_queens([Q|Qs], Q0, D0) :- Q0 #\= Q, abs(Q0 - Q) #\= D0, D1 #= D0 + 1, safe_queens(Qs, Q0, D1). ``` Note that all these predicates can be used in _all directions_: We can use them to _find_ solutions, _test_ solutions and _complete_ partially instantiated solutions. The original task can be readily solved with the following query: ``` ?- n_queens(8, Qs), label(Qs). Qs = [1,5,8,6,3,7,2,4] ; ... . ``` Using suitable labeling strategies, we can easily find solutions with 80 queens and more: ``` ?- n_queens(80, Qs), labeling([ff], Qs). Qs = [1,3,5,44,42,4,50,7,68,57,76,61,6,39,30,40,8,54,36,41|...] ; ... . ?- time((n_queens(90, Qs), labeling([ff], Qs))). % CPU time: 2.382s Qs = [1,3,5,50,42,4,49,7,59,48,46,63,6,55,47,64,8,70,58,67|...] ; ... . ``` Experimenting with different search strategies is easy because we have separated the core relation from the actual search. {#clpz-optimisation} ## Optimisation We can use `labeling/2` to minimize or maximize the value of a CLP(ℤ) expression, and generate solutions in increasing or decreasing order of the value. See the labeling options `min(Expr)` and `max(Expr)`, respectively. Again, to easily try different labeling options in connection with optimisation, we recommend to introduce a dedicated predicate for posting constraints, and to use `labeling/2` in a separate goal. This way, we can observe properties of the core relation in isolation, and try different labeling options without recompiling our code. If necessary, we can use `once/1` to commit to the first optimal solution. However, it is often very valuable to see alternative solutions that are _also_ optimal, so that we can choose among optimal solutions by other criteria. For the sake of [*purity*](https://www.metalevel.at/prolog/purity) and completeness, we recommend to avoid `once/1` and other constructs that lead to impurities in CLP(ℤ) programs. Related to optimisation with CLP(ℤ) constraints are `library(simplex)` and CLP(Q) which reason about _linear_ constraints over rational numbers. {#clpz-reification} ## Reification The constraints `(in)/2`, `(#=)/2`, `(#\=)/2`, `(#<)/2`, `(#>)/2`, `(#=<)/2`, and `(#>=)/2` can be _reified_, which means reflecting their truth values into Boolean values represented by the integers 0 and 1. Let P and Q denote reifiable constraints or Boolean variables, then: | `#\ Q` | True iff Q is false | | `P #\/ Q` | True iff either P or Q | | `P #/\ Q` | True iff both P and Q | | `P #\ Q` | True iff either P or Q, but not both | | `P #<==> Q` | True iff P and Q are equivalent | | `P #==> Q` | True iff P implies Q | | `P #<== Q` | True iff Q implies P | The constraints of this table are reifiable as well. When reasoning over Boolean variables, also consider using CLP(B) constraints as provided by `library(clpb)`. {#clpz-monotonicity} ## Enabling monotonic CLP(ℤ) In the default execution mode, CLP(ℤ) constraints still exhibit some non-relational properties. For example, _adding_ constraints can yield new solutions: ``` ?- X #= 2, X = 1+1. false. ?- X = 1+1, X #= 2, X = 1+1. X = 1+1. ``` This behaviour is highly problematic from a logical point of view, and it may render declarative debugging techniques inapplicable. Assert `clpz:monotonic` to make CLP(ℤ) *monotonic*: This means that _adding_ new constraints _cannot_ yield new solutions. When this flag is `true`, we must wrap variables that occur in arithmetic expressions with the functor `(?)/1` or `(#)/1`. For example: ``` ?- assertz(clpz:monotonic). true. ?- #X #= #Y + #Z. clpz:(#Y+ #Z#= #X). ?- X #= 2, X = 1+1. error(instantiation_error,instantiation_error(unknown(_408),1)). ``` The wrapper can be omitted for variables that are already constrained to integers. {#clpz-custom-constraints} ## Custom constraints We can define custom constraints. The mechanism to do this is not yet finalised, and we welcome suggestions and descriptions of use cases that are important to you. As an example of how it can be done currently, let us define a new custom constraint `oneground(X,Y,Z)`, where Z shall be 1 if at least one of X and Y is instantiated: ``` :- multifile clpz:run_propagator/2. oneground(X, Y, Z) :- clpz:make_propagator(oneground(X, Y, Z), Prop), clpz:init_propagator(X, Prop), clpz:init_propagator(Y, Prop), clpz:trigger_once(Prop). clpz:run_propagator(oneground(X, Y, Z), MState) :- ( integer(X) -> clpz:kill(MState), Z = 1 ; integer(Y) -> clpz:kill(MState), Z = 1 ; true ). ``` First, `clpz:make_propagator/2` is used to transform a user-defined representation of the new constraint to an internal form. With `clpz:init_propagator/2`, this internal form is then attached to X and Y. From now on, the propagator will be invoked whenever the domains of X or Y are changed. Then, `clpz:trigger_once/1` is used to give the propagator its first chance for propagation even though the variables' domains have not yet changed. Finally, `clpz:run_propagator/2` is extended to define the actual propagator. As explained, this predicate is automatically called by the constraint solver. The first argument is the user-defined representation of the constraint as used in `clpz:make_propagator/2`, and the second argument is a mutable state that can be used to prevent further invocations of the propagator when the constraint has become entailed, by using `clpz:kill/1`. An example of using the new constraint: ``` ?- oneground(X, Y, Z), Y = 5. Y = 5, Z = 1, X in inf..sup. ``` @author [Markus Triska](https://www.metalevel.at) */ /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Duo DCGs ======== A Duo DCG is like a DCG, except that it describes *two* lists at the same time. A Duo DCG rule has the form Head ++> Body. The language construct As+Bs is used within Duo DCGs to describe that the elements in As occur in the first list, and the elements in Bs occur in the second list. Duo DCGs are compiled to Prolog code via term expansion. The interface predicates are: *) duophrase(NT, As, Bs) *) duophrase(NT, As0, As, Bs0, Bs) (difference list version). Duo DCGs could be used to efficiently describe scheduled propagators, taking into account the two possible propagator priorities. However, it turns out that passing around a single argument is more efficient than passing around multiple arguments, and therefore regular DCGs are used for propagator scheduling. Still, everything is completely pure: No global data structures are needed to schedule the propagators! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ :- meta_predicate(duophrase(4, ?, ?)). :- meta_predicate(duophrase(4, ?, ?, ?, ?)). duophrase(NT, As, Bs) :- duophrase(NT, As, [], Bs, []). duophrase(NT, As0, As, Bs0, Bs) :- call(NT, As0, As, Bs0, Bs). %:- multifile user:term_expansion/6. term_expansion(Term0, Term) :- nonvar(Term0), Term0 = (Head0 ++> Body0), Term = (Head :- Body), duodcg_head(Head0, Head, As0, As, Bs0, Bs), once(duodcg_body(Body0, Body, As0, As, Bs0, Bs)). duodcg_body([], (As0=As,Bs0=Bs), As0, As, Bs0, Bs). duodcg_body(Xs+Ys, (phrase(seq(Xs), As0, As), phrase(seq(Ys), Bs0, Bs)), As0, As, Bs0, Bs). duodcg_body({Goal}, call(Goal), As, As, Bs, Bs). duodcg_body((A0,B0), (A,B), As0, As, Bs0, Bs) :- duodcg_body(A0, A, As0, As1, Bs0, Bs1), duodcg_body(B0, B, As1, As, Bs1, Bs). duodcg_body((A0->B0;C0), (A->B;C), As0, As, Bs0, Bs) :- duodcg_body(A0, A, As0, As1, Bs0, Bs1), duodcg_body(B0, B, As1, As, Bs1, Bs), duodcg_body(C0, C, As0, As, Bs0, Bs). duodcg_body((A->B), Body, As0, As, Bs0, Bs) :- duodcg_body((A->B;false), Body, As0, As, Bs0, Bs). duodcg_body((A0;B0), (A;B), As0, As, Bs0, Bs) :- duodcg_body(A0, A, As0, As, Bs0, Bs), duodcg_body(B0, B, As0, As, Bs0, Bs). duodcg_body(NT0, NT, As0, As, Bs0, Bs) :- duodcg_head(NT0, NT, As0, As, Bs0, Bs). duodcg_head(Head0, Head, As0, As, Bs0, Bs) :- Head0 =.. [F|Args0], append(Args0, [As0,As,Bs0,Bs], Args), Head =.. [F|Args]. goal_expansion(get_attr(Var, Module, Value), (var(Var),get_atts(Var, Access))) :- Access =.. [Module,Value]. goal_expansion(put_attr(Var, Module, Value), put_atts(Var, Access)) :- Access =.. [Module,Value]. goal_expansion(del_attr(Var, Module), (var(Var) -> put_atts(Var, -Access);true)) :- Access =.. [Module,_]. goal_expansion(A cis B, Expansion) :- phrase(cis_goals(B, A), Goals), list_goal(Goals, Expansion). goal_expansion(A cis_lt B, B cis_gt A). goal_expansion(A cis_leq B, B cis_geq A). goal_expansion(A cis_geq B, cis_leq_numeric(B, N)) :- nonvar(A), A = n(N). goal_expansion(A cis_geq B, cis_geq_numeric(A, N)) :- nonvar(B), B = n(N). goal_expansion(A cis_gt B, cis_lt_numeric(B, N)) :- nonvar(A), A = n(N). goal_expansion(A cis_gt B, cis_gt_numeric(A, N)) :- nonvar(B), B = n(N). /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - A bound is either: n(N): integer N inf: infimum of Z (= negative infinity) sup: supremum of Z (= positive infinity) - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ is_bound(n(N)) :- integer(N). is_bound(inf). is_bound(sup). defaulty_to_bound(D, P) :- ( integer(D) -> P = n(D) ; P = D ). /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Compactified is/2 and predicates for several arithmetic expressions with infinities, tailored for the modes needed by this solver. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ % cis_gt only works for terms of depth 0 on both sides cis_gt(sup, B0) :- B0 \== sup. cis_gt(n(N), B) :- cis_lt_numeric(B, N). cis_lt_numeric(inf, _). cis_lt_numeric(n(B), A) :- B < A. cis_gt_numeric(sup, _). cis_gt_numeric(n(B), A) :- B > A. cis_geq(inf, inf). cis_geq(sup, _). cis_geq(n(N), B) :- cis_leq_numeric(B, N). cis_leq_numeric(inf, _). cis_leq_numeric(n(B), A) :- B =< A. cis_geq_numeric(sup, _). cis_geq_numeric(n(B), A) :- B >= A. cis_min(inf, _, inf). cis_min(sup, B, B). cis_min(n(N), B, Min) :- cis_min_(B, N, Min). cis_min_(inf, _, inf). cis_min_(sup, N, n(N)). cis_min_(n(B), A, n(M)) :- M is min(A,B). cis_max(sup, _, sup). cis_max(inf, B, B). cis_max(n(N), B, Max) :- cis_max_(B, N, Max). cis_max_(inf, N, n(N)). cis_max_(sup, _, sup). cis_max_(n(B), A, n(M)) :- M is max(A,B). cis_plus(inf, _, inf). cis_plus(sup, _, sup). cis_plus(n(A), B, Plus) :- cis_plus_(B, A, Plus). cis_plus_(sup, _, sup). cis_plus_(inf, _, inf). cis_plus_(n(B), A, n(S)) :- S is A + B. cis_minus(inf, _, inf). cis_minus(sup, _, sup). cis_minus(n(A), B, M) :- cis_minus_(B, A, M). cis_minus_(inf, _, sup). cis_minus_(sup, _, inf). cis_minus_(n(B), A, n(M)) :- M is A - B. cis_uminus(inf, sup). cis_uminus(sup, inf). cis_uminus(n(A), n(B)) :- B is -A. cis_abs(inf, sup). cis_abs(sup, sup). cis_abs(n(A), n(B)) :- B is abs(A). cis_times(inf, B, P) :- ( B cis_lt n(0) -> P = sup ; B cis_gt n(0) -> P = inf ; P = n(0) ). cis_times(sup, B, P) :- ( B cis_gt n(0) -> P = sup ; B cis_lt n(0) -> P = inf ; P = n(0) ). cis_times(n(N), B, P) :- cis_times_(B, N, P). cis_times_(inf, A, P) :- cis_times(inf, n(A), P). cis_times_(sup, A, P) :- cis_times(sup, n(A), P). cis_times_(n(B), A, n(P)) :- P is A * B. cis_exp(inf, n(Y), R) :- ( even(Y) -> R = sup ; R = inf ). cis_exp(sup, _, sup). cis_exp(n(N), Y, R) :- cis_exp_(Y, N, R). cis_exp_(n(Y), N, n(R)) :- R is N^Y. cis_exp_(sup, _, sup). cis_exp_(inf, _, inf). cis_goals(V, V) --> { var(V) }, !. cis_goals(n(N), n(N)) --> []. cis_goals(inf, inf) --> []. cis_goals(sup, sup) --> []. cis_goals(sign(A0), R) --> cis_goals(A0, A), [cis_sign(A, R)]. cis_goals(abs(A0), R) --> cis_goals(A0, A), [cis_abs(A, R)]. cis_goals(-A0, R) --> cis_goals(A0, A), [cis_uminus(A, R)]. cis_goals(A0+B0, R) --> cis_goals(A0, A), cis_goals(B0, B), [cis_plus(A, B, R)]. cis_goals(A0-B0, R) --> cis_goals(A0, A), cis_goals(B0, B), [cis_minus(A, B, R)]. cis_goals(min(A0,B0), R) --> cis_goals(A0, A), cis_goals(B0, B), [cis_min(A, B, R)]. cis_goals(max(A0,B0), R) --> cis_goals(A0, A), cis_goals(B0, B), [cis_max(A, B, R)]. cis_goals(A0*B0, R) --> cis_goals(A0, A), cis_goals(B0, B), [cis_times(A, B, R)]. cis_goals(div(A0,B0), R) --> cis_goals(A0, A), cis_goals(B0, B), [cis_div(A, B, R)]. cis_goals(A0//B0, R) --> cis_goals(A0, A), cis_goals(B0, B), [cis_slash(A, B, R)]. cis_goals(A0^B0, R) --> cis_goals(A0, A), cis_goals(B0, B), [cis_exp(A, B, R)]. list_goal([], true). list_goal([G|Gs], Goal) :- foldl(list_goal_, Gs, G, Goal). list_goal_(G, G0, (G0,G)). cis_sign(sup, n(1)). cis_sign(inf, n(-1)). cis_sign(n(N), n(S)) :- S is sign(N). cis_div(sup, Y, Z) :- ( Y cis_geq n(0) -> Z = sup ; Z = inf ). cis_div(inf, Y, Z) :- ( Y cis_geq n(0) -> Z = inf ; Z = sup ). cis_div(n(X), Y, Z) :- cis_div_(Y, X, Z). cis_div_(sup, _, n(0)). cis_div_(inf, _, n(0)). cis_div_(n(Y), X, Z) :- ( Y =:= 0 -> ( X >= 0 -> Z = sup ; Z = inf ) ; Z0 is X // Y, Z = n(Z0) ). cis_slash(sup, _, sup). cis_slash(inf, _, inf). cis_slash(n(N), B, S) :- cis_slash_(B, N, S). cis_slash_(sup, _, n(0)). cis_slash_(inf, _, n(0)). cis_slash_(n(B), A, n(S)) :- S is A // B. /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - A domain is a finite set of disjoint intervals. Internally, domains are represented as trees. Each node is one of: empty: empty domain. split(N, Left, Right) - split on integer N, with Left and Right domains whose elements are all less than and greater than N, respectively. The domain is the union of Left and Right, i.e., N is a hole. from_to(From, To) - interval (From-1, To+1); From and To are bounds Desiderata: rebalance domains; singleton intervals. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Type definition and inspection of domains. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ check_domain(D) :- ( var(D) -> instantiation_error(D) ; is_domain(D) -> true ; domain_error(clpz_domain, D) ). is_domain(empty). is_domain(from_to(From,To)) :- is_bound(From), is_bound(To), From cis_leq To. is_domain(split(S, Left, Right)) :- integer(S), is_domain(Left), is_domain(Right), all_less_than(Left, S), all_greater_than(Right, S). all_less_than(empty, _). all_less_than(from_to(From,To), S) :- From cis_lt n(S), To cis_lt n(S). all_less_than(split(S0,Left,Right), S) :- S0 < S, all_less_than(Left, S), all_less_than(Right, S). all_greater_than(empty, _). all_greater_than(from_to(From,To), S) :- From cis_gt n(S), To cis_gt n(S). all_greater_than(split(S0,Left,Right), S) :- S0 > S, all_greater_than(Left, S), all_greater_than(Right, S). default_domain(from_to(inf,sup)). domain_infimum(from_to(I, _), I). domain_infimum(split(_, Left, _), I) :- domain_infimum(Left, I). domain_supremum(from_to(_, S), S). domain_supremum(split(_, _, Right), S) :- domain_supremum(Right, S). domain_num_elements(empty, n(0)). domain_num_elements(from_to(From,To), Num) :- Num cis To - From + n(1). domain_num_elements(split(_, Left, Right), Num) :- domain_num_elements(Left, NL), domain_num_elements(Right, NR), Num cis NL + NR. domain_direction_element(from_to(n(From), n(To)), Dir, E) :- ( Dir == up -> between(From, To, E) ; between(From, To, E0), E is To - (E0 - From) ). domain_direction_element(split(_, D1, D2), Dir, E) :- ( Dir == up -> ( domain_direction_element(D1, Dir, E) ; domain_direction_element(D2, Dir, E) ) ; ( domain_direction_element(D2, Dir, E) ; domain_direction_element(D1, Dir, E) ) ). /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Test whether domain contains a given integer. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ domain_contains(from_to(From,To), I) :- From cis_leq n(I), n(I) cis_leq To. domain_contains(split(S, Left, Right), I) :- ( I < S -> domain_contains(Left, I) ; I > S -> domain_contains(Right, I) ). /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Test whether a domain contains another domain. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ domain_subdomain(Dom, Sub) :- domain_subdomain(Dom, Dom, Sub). domain_subdomain(from_to(_,_), Dom, Sub) :- domain_subdomain_fromto(Sub, Dom). domain_subdomain(split(_, _, _), Dom, Sub) :- domain_subdomain_split(Sub, Dom, Sub). domain_subdomain_split(empty, _, _). domain_subdomain_split(from_to(From,To), split(S,Left0,Right0), Sub) :- ( To cis_lt n(S) -> domain_subdomain(Left0, Left0, Sub) ; From cis_gt n(S) -> domain_subdomain(Right0, Right0, Sub) ). domain_subdomain_split(split(_,Left,Right), Dom, _) :- domain_subdomain(Dom, Dom, Left), domain_subdomain(Dom, Dom, Right). domain_subdomain_fromto(empty, _). domain_subdomain_fromto(from_to(From,To), from_to(From0,To0)) :- From0 cis_leq From, To0 cis_geq To. domain_subdomain_fromto(split(_,Left,Right), Dom) :- domain_subdomain_fromto(Left, Dom), domain_subdomain_fromto(Right, Dom). /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Remove an integer from a domain. The domain is traversed until an interval is reached from which the element can be removed, or until it is clear that no such interval exists. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ domain_remove(empty, _, empty). domain_remove(from_to(L0, U0), X, D) :- domain_remove_(L0, U0, X, D). domain_remove(split(S, Left0, Right0), X, D) :- ( X =:= S -> D = split(S, Left0, Right0) ; X < S -> domain_remove(Left0, X, Left1), ( Left1 == empty -> D = Right0 ; D = split(S, Left1, Right0) ) ; domain_remove(Right0, X, Right1), ( Right1 == empty -> D = Left0 ; D = split(S, Left0, Right1) ) ). %?- domain_remove(from_to(n(0),n(5)), 3, D). domain_remove_(inf, U0, X, D) :- ( U0 == n(X) -> U1 is X - 1, D = from_to(inf, n(U1)) ; U0 cis_lt n(X) -> D = from_to(inf,U0) ; L1 is X + 1, U1 is X - 1, D = split(X, from_to(inf, n(U1)), from_to(n(L1),U0)) ). domain_remove_(n(N), U0, X, D) :- domain_remove_upper(U0, N, X, D). domain_remove_upper(sup, L0, X, D) :- ( L0 =:= X -> L1 is X + 1, D = from_to(n(L1),sup) ; L0 > X -> D = from_to(n(L0),sup) ; L1 is X + 1, U1 is X - 1, D = split(X, from_to(n(L0),n(U1)), from_to(n(L1),sup)) ). domain_remove_upper(n(U0), L0, X, D) :- ( L0 =:= U0, X =:= L0 -> D = empty ; L0 =:= X -> L1 is X + 1, D = from_to(n(L1), n(U0)) ; U0 =:= X -> U1 is X - 1, D = from_to(n(L0), n(U1)) ; between(L0, U0, X) -> U1 is X - 1, L1 is X + 1, D = split(X, from_to(n(L0), n(U1)), from_to(n(L1), n(U0))) ; D = from_to(n(L0),n(U0)) ). /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Remove all elements greater than / less than a constant. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ domain_remove_greater_than(empty, _, empty). domain_remove_greater_than(from_to(From0,To0), G, D) :- ( From0 cis_gt n(G) -> D = empty ; To cis min(To0,n(G)), D = from_to(From0,To) ). domain_remove_greater_than(split(S,Left0,Right0), G, D) :- ( S =< G -> domain_remove_greater_than(Right0, G, Right), ( Right == empty -> D = Left0 ; D = split(S, Left0, Right) ) ; domain_remove_greater_than(Left0, G, D) ). domain_remove_smaller_than(empty, _, empty). domain_remove_smaller_than(from_to(From0,To0), V, D) :- ( To0 cis_lt n(V) -> D = empty ; From cis max(From0,n(V)), D = from_to(From,To0) ). domain_remove_smaller_than(split(S,Left0,Right0), V, D) :- ( S >= V -> domain_remove_smaller_than(Left0, V, Left), ( Left == empty -> D = Right0 ; D = split(S, Left, Right0) ) ; domain_remove_smaller_than(Right0, V, D) ). /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Remove a whole domain from another domain. (Set difference.) - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ domain_subtract(Dom0, Sub, Dom) :- domain_subtract(Dom0, Dom0, Sub, Dom). domain_subtract(empty, _, _, empty). domain_subtract(from_to(From0,To0), Dom, Sub, D) :- ( Sub == empty -> D = Dom ; Sub = from_to(From,To) -> ( From == To -> From = n(X), domain_remove(Dom, X, D) ; From cis_gt To0 -> D = Dom ; To cis_lt From0 -> D = Dom ; From cis_leq From0 -> ( To cis_geq To0 -> D = empty ; From1 cis To + n(1), D = from_to(From1, To0) ) ; To1 cis From - n(1), ( To cis_lt To0 -> From = n(S), From2 cis To + n(1), D = split(S,from_to(From0,To1),from_to(From2,To0)) ; D = from_to(From0,To1) ) ) ; Sub = split(S, Left, Right) -> ( n(S) cis_gt To0 -> domain_subtract(Dom, Dom, Left, D) ; n(S) cis_lt From0 -> domain_subtract(Dom, Dom, Right, D) ; domain_subtract(Dom, Dom, Left, D1), domain_subtract(D1, D1, Right, D) ) ). domain_subtract(split(S, Left0, Right0), _, Sub, D) :- domain_subtract(Left0, Left0, Sub, Left), domain_subtract(Right0, Right0, Sub, Right), ( Left == empty -> D = Right ; Right == empty -> D = Left ; D = split(S, Left, Right) ). /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Complement of a domain - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ domain_complement(D, C) :- default_domain(Default), domain_subtract(Default, D, C). /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Convert domain to a list of disjoint intervals From-To. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ domain_intervals(D, Is) :- phrase(domain_intervals(D), Is). domain_intervals(split(_, Left, Right)) --> domain_intervals(Left), domain_intervals(Right). domain_intervals(empty) --> []. domain_intervals(from_to(From,To)) --> [From-To]. /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - To compute the intersection of two domains D1 and D2, we choose D1 as the reference domain. For each interval of D1, we compute how far and to which values D2 lets us extend it. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ domains_intersection(D1, D2, Intersection) :- domains_intersection_(D1, D2, Intersection), Intersection \== empty. domains_intersection_(empty, _, empty). domains_intersection_(from_to(L0,U0), D2, Dom) :- narrow(D2, L0, U0, Dom). domains_intersection_(split(S,Left0,Right0), D2, Dom) :- domains_intersection_(Left0, D2, Left1), domains_intersection_(Right0, D2, Right1), ( Left1 == empty -> Dom = Right1 ; Right1 == empty -> Dom = Left1 ; Dom = split(S, Left1, Right1) ). narrow(empty, _, _, empty). narrow(from_to(L0,U0), From0, To0, Dom) :- From1 cis max(From0,L0), To1 cis min(To0,U0), ( From1 cis_gt To1 -> Dom = empty ; Dom = from_to(From1,To1) ). narrow(split(S, Left0, Right0), From0, To0, Dom) :- ( To0 cis_lt n(S) -> narrow(Left0, From0, To0, Dom) ; From0 cis_gt n(S) -> narrow(Right0, From0, To0, Dom) ; narrow(Left0, From0, To0, Left1), narrow(Right0, From0, To0, Right1), ( Left1 == empty -> Dom = Right1 ; Right1 == empty -> Dom = Left1 ; Dom = split(S, Left1, Right1) ) ). /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Union of 2 domains. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ domains_union(D1, D2, Union) :- domain_intervals(D1, Is1), domain_intervals(D2, Is2), append(Is1, Is2, IsU0), merge_intervals(IsU0, IsU1), intervals_to_domain(IsU1, Union). /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Shift the domain by an offset. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ domain_shift(empty, _, empty). domain_shift(from_to(From0,To0), O, from_to(From,To)) :- From cis From0 + n(O), To cis To0 + n(O). domain_shift(split(S0, Left0, Right0), O, split(S, Left, Right)) :- S is S0 + O, domain_shift(Left0, O, Left), domain_shift(Right0, O, Right). /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - The new domain contains all values of the old domain, multiplied by a constant multiplier. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ domain_expand(D0, M, D) :- ( M < 0 -> domain_negate(D0, D1), M1 is abs(M), domain_expand_(D1, M1, D) ; M =:= 1 -> D = D0 ; domain_expand_(D0, M, D) ). domain_expand_(empty, _, empty). domain_expand_(from_to(From0, To0), M, from_to(From,To)) :- From cis From0*n(M), To cis To0*n(M). domain_expand_(split(S0, Left0, Right0), M, split(S, Left, Right)) :- S is M*S0, domain_expand_(Left0, M, Left), domain_expand_(Right0, M, Right). /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - similar to domain_expand/3, tailored for truncated division: an interval [From,To] is extended to [From*M, ((To+1)*M - 1)], i.e., to all values that truncated integer-divided by M yield a value from interval. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ domain_expand_more(D0, M, D) :- %format("expanding ~w by ~w\n", [D0,M]), ( M < 0 -> domain_negate(D0, D1), M1 is abs(M) ; D1 = D0, M1 = M ), domain_expand_more_(D1, M1, D). %format("yield: ~w\n", [D]). domain_expand_more_(empty, _, empty). domain_expand_more_(from_to(From0, To0), M, from_to(From,To)) :- ( From0 cis_leq n(0) -> From cis (From0-n(1))*n(M) + n(1) ; From cis From0*n(M) ), ( To0 cis_lt n(0) -> To cis To0*n(M) ; To cis (To0+n(1))*n(M) - n(1) ). domain_expand_more_(split(S0, Left0, Right0), M, split(S, Left, Right)) :- S is M*S0, domain_expand_more_(Left0, M, Left), domain_expand_more_(Right0, M, Right). /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Scale a domain down by a constant multiplier. Assuming (//)/2. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ domain_contract(D0, M, D) :- %format("contracting ~w by ~w\n", [D0,M]), ( M < 0 -> domain_negate(D0, D1), M1 is abs(M) ; D1 = D0, M1 = M ), domain_contract_(D1, M1, D). domain_contract_(empty, _, empty). domain_contract_(from_to(From0, To0), M, from_to(From,To)) :- ( From0 cis_geq n(0) -> From cis (From0 + n(M) - n(1)) // n(M) ; From cis From0 // n(M) ), ( To0 cis_geq n(0) -> To cis To0 // n(M) ; To cis (To0 - n(M) + n(1)) // n(M) ). domain_contract_(split(_,Left0,Right0), M, D) :- % Scaled down domains do not necessarily retain any holes of % the original domain. domain_contract_(Left0, M, Left), domain_contract_(Right0, M, Right), domains_union(Left, Right, D). /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Similar to domain_contract, tailored for division, i.e., {21,23} contracted by 4 is 5. It contracts "less". - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ domain_contract_less(D0, M, D) :- ( M < 0 -> domain_negate(D0, D1), M1 is abs(M) ; D1 = D0, M1 = M ), domain_contract_less_(D1, M1, D). domain_contract_less_(empty, _, empty). domain_contract_less_(from_to(From0, To0), M, from_to(From,To)) :- From cis From0 // n(M), To cis To0 // n(M). domain_contract_less_(split(_,Left0,Right0), M, D) :- % Scaled down domains do not necessarily retain any holes of % the original domain. domain_contract_less_(Left0, M, Left), domain_contract_less_(Right0, M, Right), domains_union(Left, Right, D). /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Negate the domain. Left and Right sub-domains and bounds switch sides. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ domain_negate(empty, empty). domain_negate(from_to(From0, To0), from_to(From, To)) :- From cis -To0, To cis -From0. domain_negate(split(S0, Left0, Right0), split(S, Left, Right)) :- S is -S0, domain_negate(Left0, Right), domain_negate(Right0, Left). /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Construct a domain from a list of integers. Try to balance it. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ list_to_disjoint_intervals([], []). list_to_disjoint_intervals([N|Ns], Is) :- list_to_disjoint_intervals(Ns, N, N, Is). list_to_disjoint_intervals([], M, N, [n(M)-n(N)]). list_to_disjoint_intervals([B|Bs], M, N, Is) :- ( B =:= N + 1 -> list_to_disjoint_intervals(Bs, M, B, Is) ; Is = [n(M)-n(N)|Rest], list_to_disjoint_intervals(Bs, B, B, Rest) ). list_to_domain(List0, D) :- ( List0 == [] -> D = empty ; sort(List0, List), list_to_disjoint_intervals(List, Is), intervals_to_domain(Is, D) ). intervals_to_domain([], empty) :- !. intervals_to_domain([M-N], from_to(M,N)) :- !. intervals_to_domain(Is, D) :- length(Is, L), FL is L // 2, length(Front, FL), append(Front, Tail, Is), Tail = [n(Start)-_|_], Hole is Start - 1, intervals_to_domain(Front, Left), intervals_to_domain(Tail, Right), D = split(Hole, Left, Right). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% in(?Var, +Domain) % % Var is an element of Domain. Domain is one of: % % * Integer % Singleton set consisting only of _Integer_. % * Lower..Upper % All integers _I_ such that _Lower_ =< _I_ =< _Upper_. % _Lower_ must be an integer or the atom *inf*, which % denotes negative infinity. _Upper_ must be an integer or % the atom *sup*, which denotes positive infinity. % * Domain1 `\/` Domain2 % The union of Domain1 and Domain2. Var in Dom :- clpz_in(Var, Dom). clpz_in(V, D) :- fd_variable(V), drep_to_domain(D, Dom), domain(V, Dom). fd_variable(V) :- can_be(integer, V). %% ins(+Vars, +Domain) % % The variables in the list Vars are elements of Domain. Vs ins D :- fd_must_be_list(Vs), maplist(fd_variable, Vs), drep_to_domain(D, Dom), domains(Vs, Dom). fd_must_be_list(Ls) :- ( fd_var(Ls) -> type_error(list, Ls) ; must_be(list, Ls) ). fd_must_be_list(Ls, Where) :- ( fd_var(Ls) -> type_error(list, Ls, Where) ; must_be(list, Where, Ls) ). %% indomain(?Var) % % Bind Var to all feasible values of its domain on backtracking. The % domain of Var must be finite. indomain(Var) :- label([Var]). order_dom_next(up, Dom, Next) :- domain_infimum(Dom, n(Next)). order_dom_next(down, Dom, Next) :- domain_supremum(Dom, n(Next)). %% label(+Vars) % % Equivalent to labeling([], Vars). label(Vs) :- labeling([], Vs). %% labeling(+Options, +Vars) % % Assign a value to each variable in Vars. Labeling means systematically % trying out values for the finite domain variables Vars until all of % them are ground. The domain of each variable in Vars must be finite. % Options is a list of options that let you exhibit some control over % the search process. Several categories of options exist: % % The variable selection strategy lets you specify which variable of % Vars is labeled next and is one of: % % * leftmost % Label the variables in the order they occur in Vars. This is the % default. % % * ff % _|First fail|_. Label the leftmost variable with smallest domain next, % in order to detect infeasibility early. This is often a good % strategy. % % * ffc % Of the variables with smallest domains, the leftmost one % participating in most constraints is labeled next. % % * min % Label the leftmost variable whose lower bound is the lowest next. % % * max % Label the leftmost variable whose upper bound is the highest next. % % The value order is one of: % % * up % Try the elements of the chosen variable's domain in ascending order. % This is the default. % % * down % Try the domain elements in descending order. % % The branching strategy is one of: % % * step % For each variable X, a choice is made between X = V and X #\= V, % where V is determined by the value ordering options. This is the % default. % % * enum % For each variable X, a choice is made between X = V_1, X = V_2 % etc., for all values V_i of the domain of X. The order is % determined by the value ordering options. % % * bisect % For each variable X, a choice is made between X #=< M and X #> M, % where M is the midpoint of the domain of X. % % At most one option of each category can be specified, and an option % must not occur repeatedly. % % The order of solutions can be influenced with: % % * min(Expr) % * max(Expr) % % This generates solutions in ascending/descending order with respect % to the evaluation of the arithmetic expression Expr. Labeling Vars % must make Expr ground. If several such options are specified, they % are interpreted from left to right, e.g.: % % ``` % ?- [X,Y] ins 10..20, labeling([max(X),min(Y)],[X,Y]). % ``` % % This generates solutions in descending order of X, and for each % binding of X, solutions are generated in ascending order of Y. To % obtain the incomplete behaviour that other systems exhibit with % "maximize(Expr)" and "minimize(Expr)", use once/1, e.g.: % % ``` % once(labeling([max(Expr)], Vars)) % ``` % % Labeling is always complete, always terminates, and yields no % redundant solutions. % labeling(Options, Vars) :- must_be(list, labeling(Options, Vars)-1, Options), fd_must_be_list(Vars, labeling(Options, Vars)-2), maplist(finite_domain(labeling(Options, Vars), 2), Vars), label(Options, Options, default(leftmost), default(up), default(step), [], upto_ground, Vars). finite_domain(Goal, Arg, Var) :- ( fd_get(Var, Dom, _) -> ( domain_infimum(Dom, n(_)), domain_supremum(Dom, n(_)) -> true ; instantiation_error(Dom) ) ; integer(Var) -> true ; must_be(integer, Goal-Arg, Var) ). finite_domain(Var) :- finite_domain(finite_domain(Var), 1, Var). label([O|Os], Options, Selection, Order, Choice, Optim, Consistency, Vars) :- ( var(O)-> instantiation_error(O) ; override(selection, Selection, O, Options, S1) -> label(Os, Options, S1, Order, Choice, Optim, Consistency, Vars) ; override(order, Order, O, Options, O1) -> label(Os, Options, Selection, O1, Choice, Optim, Consistency, Vars) ; override(choice, Choice, O, Options, C1) -> label(Os, Options, Selection, Order, C1, Optim, Consistency, Vars) ; optimisation(O) -> label(Os, Options, Selection, Order, Choice, [O|Optim], Consistency, Vars) ; consistency(O, O1) -> label(Os, Options, Selection, Order, Choice, Optim, O1, Vars) ; domain_error(labeling_option, O) ). label([], _, Selection, Order, Choice, Optim0, Consistency, Vars) :- maplist(arg(1), [Selection,Order,Choice], [S,O,C]), ( Optim0 == [] -> label(Vars, S, O, C, Consistency) ; reverse(Optim0, Optim), exprs_singlevars(Optim, SVs), call_cleanup(optimise(Vars, [S,O,C], SVs), retractall(extremum(_))) ). % Introduce new variables for each min/max expression to avoid % reparsing expressions during optimisation. exprs_singlevars([], []). exprs_singlevars([E|Es], [SV|SVs]) :- E =.. [F,Expr], #Single #= Expr, SV =.. [F,Single], exprs_singlevars(Es, SVs). all_dead(fd_props(Bs,Gs,Os)) :- all_dead_(Bs), all_dead_(Gs), all_dead_(Os). all_dead_([]). all_dead_([propagator(_, S)|Ps]) :- S == dead, all_dead_(Ps). label([], _, _, _, Consistency) :- !, ( Consistency = upto_in(I0,I) -> I0 = I ; true ). label(Vars, Selection, Order, Choice, Consistency) :- ( Vars = [V|Vs], nonvar(V) -> label(Vs, Selection, Order, Choice, Consistency) ; select_var(Selection, Vars, Var, RVars), ( var(Var) -> ( Consistency = upto_in(I0,I), fd_get(Var, _, Ps), all_dead(Ps) -> fd_size(Var, Size), I1 is I0*Size, label(RVars, Selection, Order, Choice, upto_in(I1,I)) ; Consistency = upto_in, fd_get(Var, _, Ps), all_dead(Ps) -> label(RVars, Selection, Order, Choice, Consistency) ; choice_order_variable(Choice, Order, Var, RVars, Vars, Selection, Consistency) ) ; label(RVars, Selection, Order, Choice, Consistency) ) ). choice_order_variable(step, Order, Var, Vars, Vars0, Selection, Consistency) :- fd_get(Var, Dom, _), order_dom_next(Order, Dom, Next), ( Var = Next, label(Vars, Selection, Order, step, Consistency) ; neq_num(Var, Next), label(Vars0, Selection, Order, step, Consistency) ). choice_order_variable(enum, Order, Var, Vars, _, Selection, Consistency) :- fd_get(Var, Dom0, _), domain_direction_element(Dom0, Order, Var), label(Vars, Selection, Order, enum, Consistency). choice_order_variable(bisect, Order, Var, _, Vars0, Selection, Consistency) :- fd_get(Var, Dom, _), domain_infimum(Dom, n(I)), domain_supremum(Dom, n(S)), Mid0 is (I + S) // 2, ( Mid0 =:= S -> Mid is Mid0 - 1 ; Mid = Mid0 ), ( Order == up -> ( Var #=< Mid ; Var #> Mid ) ; Order == down -> ( Var #> Mid ; Var #=< Mid ) ; domain_error(bisect_up_or_down, Order) ), label(Vars0, Selection, Order, bisect, Consistency). override(What, Prev, Value, Options, Result) :- call(What, Value), override_(Prev, Value, Options, Result). override_(default(_), Value, _, user(Value)). override_(user(Prev), Value, Options, _) :- ( Value == Prev -> domain_error(nonrepeating_labeling_options, Options) ; domain_error(consistent_labeling_options, Options) ). selection(ff). selection(ffc). selection(min). selection(max). selection(leftmost). choice(step). choice(enum). choice(bisect). order(up). order(down). consistency(upto_in(I), upto_in(1, I)). consistency(upto_in, upto_in). consistency(upto_ground, upto_ground). optimisation(min(_)). optimisation(max(_)). select_var(leftmost, [Var|Vars], Var, Vars). select_var(min, [V|Vs], Var, RVars) :- find_min(Vs, V, Var), delete_eq([V|Vs], Var, RVars). select_var(max, [V|Vs], Var, RVars) :- find_max(Vs, V, Var), delete_eq([V|Vs], Var, RVars). select_var(ff, [V|Vs], Var, RVars) :- fd_size_(V, n(S)), find_ff(Vs, V, S, Var), delete_eq([V|Vs], Var, RVars). select_var(ffc, [V|Vs], Var, RVars) :- find_ffc(Vs, V, Var), delete_eq([V|Vs], Var, RVars). find_min([], Var, Var). find_min([V|Vs], CM, Min) :- ( min_lt(V, CM) -> find_min(Vs, V, Min) ; find_min(Vs, CM, Min) ). find_max([], Var, Var). find_max([V|Vs], CM, Max) :- ( max_gt(V, CM) -> find_max(Vs, V, Max) ; find_max(Vs, CM, Max) ). find_ff([], Var, _, Var). find_ff([V|Vs], CM, S0, FF) :- ( nonvar(V) -> find_ff(Vs, CM, S0, FF) ; ( fd_size_(V, n(S1)), S1 < S0 -> find_ff(Vs, V, S1, FF) ; find_ff(Vs, CM, S0, FF) ) ). find_ffc([], Var, Var). find_ffc([V|Vs], Prev, FFC) :- ( ffc_lt(V, Prev) -> find_ffc(Vs, V, FFC) ; find_ffc(Vs, Prev, FFC) ). ffc_lt(X, Y) :- ( fd_get(X, XD, XPs) -> domain_num_elements(XD, n(NXD)) ; NXD = 1, XPs = [] ), ( fd_get(Y, YD, YPs) -> domain_num_elements(YD, n(NYD)) ; NYD = 1, YPs = [] ), ( NXD < NYD -> true ; NXD =:= NYD, props_number(XPs, NXPs), props_number(YPs, NYPs), NXPs > NYPs ). min_lt(X,Y) :- bounds(X,LX,_), bounds(Y,LY,_), LX < LY. max_gt(X,Y) :- bounds(X,_,UX), bounds(Y,_,UY), UX > UY. bounds(X, L, U) :- ( fd_get(X, Dom, _) -> domain_infimum(Dom, n(L)), domain_supremum(Dom, n(U)) ; L = X, U = L ). delete_eq([], _, []). delete_eq([X|Xs], Y, List) :- ( nonvar(X) -> delete_eq(Xs, Y, List) ; X == Y -> List = Xs ; List = [X|Tail], delete_eq(Xs, Y, Tail) ). /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - contracting/1 -- subject to change This can remove additional domain elements from the boundaries. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ contracting(Vs) :- must_be(list, contracting(Vs)-1, Vs), maplist(finite_domain(contracting(Vs), 1), Vs), contracting(Vs, false, Vs). contracting([], Repeat, Vars) :- ( Repeat -> contracting(Vars, false, Vars) ; true ). contracting([V|Vs], Repeat, Vars) :- fd_inf(V, Min), ( \+ \+ (V = Min) -> fd_sup(V, Max), ( \+ \+ (V = Max) -> contracting(Vs, Repeat, Vars) ; V #\= Max, contracting(Vs, true, Vars) ) ; V #\= Min, contracting(Vs, true, Vars) ). /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - fds_sespsize(Vs, S). S is an upper bound on the search space size with respect to finite domain variables Vs. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ fds_sespsize(Vs, S) :- must_be(list, Vs), maplist(fd_variable, Vs), fds_sespsize(Vs, n(1), S1), bound_portray(S1, S). fd_size_(V, S) :- ( fd_get(V, D, _) -> domain_num_elements(D, S) ; S = n(1) ). fds_sespsize([], S, S). fds_sespsize([V|Vs], S0, S) :- fd_size_(V, S1), S2 cis S0*S1, fds_sespsize(Vs, S2, S). /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Optimisation uses the clause database to save the computed extremum over backtracking. Failure is used to get rid of copies of attributed variables that are created in intermediate steps. Example: ?- X in 1..3, call_residue_vars(labeling([min(X)], [X]), Vs). %@ X = 1, Vs = [] %@ ; X = 2, Vs = [] %@ ; X = 3, Vs = [] %@ ; false. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ :- dynamic(extremum/1). optimise(Vars, Options, Whats) :- Whats = [What|WhatsRest], asserta(extremum(mark)), ( catch(store_extremum(Vars, Options, What), time_limit_exceeded, false) ; once(extremum(Val0)), retract_until_mark, Val0 = n(Val), arg(1, What, Expr), append(WhatsRest, Options, Options1), ( Expr #= Val, labeling(Options1, Vars) ; Expr #\= Val, optimise(Vars, Options, Whats) ) ). retract_until_mark :- ( retract(extremum(E)), E == mark -> true ; retract_until_mark ). store_extremum(Vars, Options, What) :- catch((labeling(Options, Vars), throw(w(What))), w(What1), true), functor(What, Direction, _), maplist(arg(1), [What,What1], [Expr,Expr1]), optimise(Direction, Options, Vars, Expr1, Expr). optimise(Direction, Options, Vars, Expr0, Expr) :- must_be(ground, Expr0), update_extremum(Expr0), catch((tighten(Direction, Expr, Expr0), labeling(Options, Vars), throw(v(Expr))), v(Expr1), true), optimise(Direction, Options, Vars, Expr1, Expr). update_extremum(Expr) :- ( once(extremum(Prev)), Prev = n(_) -> once(retract(extremum(_))) ; true ), asserta(extremum(n(Expr))). tighten(min, E, V) :- E #< V. tighten(max, E, V) :- E #> V. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% all_different(+Vars) % % Like all_distinct/1, but with weaker propagation. all_different(Ls) :- fd_must_be_list(Ls, all_different(Ls)-1), maplist(fd_variable, Ls), Orig = original_goal(_, all_different(Ls)), new_queue(Q0), phrase((all_different(Ls, [], Orig),do_queue), [Q0], _). all_different([], _, _) --> []. all_different([X|Right], Left, Orig) --> ( { var(X) } -> { make_propagator(pdifferent(Left,Right,X,Orig), Prop) }, init_propagator_([X], Prop), trigger_prop(Prop) ; exclude_fire(Left, Right, X) ), all_different(Right, [X|Left], Orig). %% all_distinct(+Vars). % % True iff Vars are pairwise distinct. For example, all_distinct/1 % can detect that not all variables can assume distinct values given % the following domains: % % ``` % ?- maplist(in, Vs, % [1\/3..4, 1..2\/4, 1..2\/4, 1..3, 1..3, 1..6]), % all_distinct(Vs). % false. % ``` all_distinct(Ls) :- fd_must_be_list(Ls, all_distinct(Ls)-1), maplist(fd_variable, Ls), make_propagator(pdistinct(Ls), Prop), new_queue(Q0), phrase((distinct_attach(Ls, Prop, []),trigger_prop(Prop),do_queue), [Q0], _), variables_same_queue(Ls). %% nvalue(?N, +Vars). % % True if N is the number of distinct values taken by Vars. Vars is a % list of domain variables, and N is a domain variable. Can be % thought of as a relaxed version of all_distinct/1. nvalue(N, Vars) :- fd_must_be_list(Vars), maplist(fd_variable, Vars), length(Vars, Len), N in 0..Len, zero_or_more(Vars, N), propagator_init_trigger(Vars, pnvalue(N, Vars)). zero_or_more([], 0). zero_or_more([_|_], N) :- N #> 0. %% sum(+Vars, +Rel, ?Expr) % % The sum of elements of the list Vars is in relation Rel to Expr. % Rel is one of #=, #\=, #<, #>, #=< or #>=. For example: % % ``` % ?- [A,B,C] ins 0..sup, sum([A,B,C], #=, 100). % A in 0..100, % A+B+C#=100, % B in 0..100, % C in 0..100. % ``` sum(Vs, Op, Value) :- must_be(list, Vs), same_length(Vs, Ones), maplist(=(1), Ones), scalar_product(Ones, Vs, Op, Value). %% scalar_product(+Cs, +Vs, +Rel, ?Expr) % % True iff the scalar product of Cs and Vs is in relation Rel to Expr. % Cs is a list of integers, Vs is a list of variables and integers. % Rel is #=, #\=, #<, #>, #=< or #>=. scalar_product(Cs, Vs, Op, Value) :- must_be(list(integer), Cs), must_be(list, Vs), maplist(fd_variable, Vs), ( Op = (#=), single_value(Value, Right), ground(Vs) -> foldl(coeff_int_linsum, Cs, Vs, 0, Right) ; must_be(ground, Op), ( memberchk(Op, [#=,#\=,#<,#>,#=<,#>=]) -> true ; domain_error(scalar_product_relation, Op) ), must_be(acyclic, Value), foldl(coeff_var_plusterm, Cs, Vs, 0, Left), ( left_right_linsum_const(Left, Value, Cs1, Vs1, Const) -> scalar_product_(Op, Cs1, Vs1, Const) ; sum(Cs, Vs, 0, Op, Value) ) ). single_value(V, V) :- var(V), !, non_monotonic(V). single_value(V, V) :- integer(V). single_value(?(V), V) :- fd_variable(V). coeff_var_plusterm(C, V, T0, T0+(C* #V)). coeff_int_linsum(C, I, S0, S) :- S is S0 + C*I. sum([], _, Sum, Op, Value) :- call(Op, Sum, Value). sum([C|Cs], [X|Xs], Acc, Op, Value) :- #NAcc #= Acc + C* #X, sum(Cs, Xs, NAcc, Op, Value). multiples([], [], _). multiples([C|Cs], [V|Vs], Left) :- ( ( Cs = [N|_] ; Left = [N|_] ) -> ( N =\= 1, gcd(C,N) =:= 1 -> gcd(Cs, N, GCD0), gcd(Left, GCD0, GCD), ( GCD > 1 -> #V #= GCD * #_ ; true ) ; true ) ; true ), multiples(Cs, Vs, [C|Left]). abs(N, A) :- A is abs(N). divide(D, N, R) :- R is N // D. scalar_product_(#=, Cs0, Vs, S0) :- ( Cs0 = [C|Rest] -> gcd(Rest, C, GCD), S0 mod GCD =:= 0, maplist(divide(GCD), [S0|Cs0], [S|Cs]) ; S0 =:= 0, S = S0, Cs = Cs0 ), ( S0 =:= 0 -> maplist(abs, Cs, As), multiples(As, Vs, []) ; true ), propagator_init_trigger(Vs, scalar_product_eq(Cs, Vs, S)). scalar_product_(#\=, Cs, Vs, C) :- propagator_init_trigger(Vs, scalar_product_neq(Cs, Vs, C)). scalar_product_(#=<, Cs, Vs, C) :- propagator_init_trigger(Vs, scalar_product_leq(Cs, Vs, C)). scalar_product_(#<, Cs, Vs, C) :- C1 is C - 1, scalar_product_(#=<, Cs, Vs, C1). scalar_product_(#>, Cs, Vs, C) :- C1 is C + 1, scalar_product_(#>=, Cs, Vs, C1). scalar_product_(#>=, Cs, Vs, C) :- maplist(negative, Cs, Cs1), C1 is -C, scalar_product_(#=<, Cs1, Vs, C1). negative(X0, X) :- X is -X0. coeffs_variables_const([], [], [], [], I, I). coeffs_variables_const([C|Cs], [V|Vs], Cs1, Vs1, I0, I) :- ( var(V) -> Cs1 = [C|CRest], Vs1 = [V|VRest], I1 = I0 ; I1 is I0 + C*V, Cs1 = CRest, Vs1 = VRest ), coeffs_variables_const(Cs, Vs, CRest, VRest, I1, I). sum_finite_domains([], [], Inf, Sup, Inf, Sup) ++> []. sum_finite_domains([C|Cs], [V|Vs], Inf0, Sup0, Inf, Sup) ++> { fd_get(V, _, Inf1, Sup1, _) }, ( Inf1 = n(NInf) -> ( C < 0 -> Sup2 is Sup0 + C*NInf ; Inf2 is Inf0 + C*NInf ) ; ( C < 0 -> Sup2 = Sup0, []+[C*V] ; Inf2 = Inf0, [C*V]+[] ) ), ( Sup1 = n(NSup) -> ( C < 0 -> Inf2 is Inf0 + C*NSup ; Sup2 is Sup0 + C*NSup ) ; ( C < 0 -> Inf2 = Inf0, [C*V]+[] ; Sup2 = Sup0, []+[C*V] ) ), sum_finite_domains(Cs, Vs, Inf2, Sup2, Inf, Sup). remove_dist_upper_lower([], _, _, _) --> []. remove_dist_upper_lower([C|Cs], [V|Vs], D1, D2) --> ( { fd_get(V, VD, VPs) } -> ( C < 0 -> { domain_supremum(VD, n(Sup)), L is Sup + D1//C, domain_remove_smaller_than(VD, L, VD1), domain_infimum(VD1, n(Inf)), G is Inf - D2//C, domain_remove_greater_than(VD1, G, VD2) } ; { domain_infimum(VD, n(Inf)), G is Inf + D1//C, domain_remove_greater_than(VD, G, VD1), domain_supremum(VD1, n(Sup)), L is Sup - D2//C, domain_remove_smaller_than(VD1, L, VD2) } ), fd_put(V, VD2, VPs) ; true ), remove_dist_upper_lower(Cs, Vs, D1, D2). remove_dist_upper_leq([], _, _) --> []. remove_dist_upper_leq([C|Cs], [V|Vs], D1) --> ( { fd_get(V, VD, VPs) } -> ( C < 0 -> { domain_supremum(VD, n(Sup)), L is Sup + D1//C, domain_remove_smaller_than(VD, L, VD1) } ; { domain_infimum(VD, n(Inf)), G is Inf + D1//C, domain_remove_greater_than(VD, G, VD1) } ), fd_put(V, VD1, VPs) ; true ), remove_dist_upper_leq(Cs, Vs, D1). remove_dist_upper([], _) --> []. remove_dist_upper([C*V|CVs], D) --> ( { fd_get(V, VD, VPs) } -> ( C < 0 -> ( { domain_supremum(VD, n(Sup)) } -> { L is Sup + D//C, domain_remove_smaller_than(VD, L, VD1) } ; VD1 = VD ) ; ( { domain_infimum(VD, n(Inf)) } -> { G is Inf + D//C, domain_remove_greater_than(VD, G, VD1) } ; VD1 = VD ) ), fd_put(V, VD1, VPs) ; true ), remove_dist_upper(CVs, D). remove_dist_lower([], _) --> []. remove_dist_lower([C*V|CVs], D) --> ( { fd_get(V, VD, VPs) } -> ( C < 0 -> ( { domain_infimum(VD, n(Inf)) } -> { G is Inf - D//C, domain_remove_greater_than(VD, G, VD1) } ; VD1 = VD ) ; ( { domain_supremum(VD, n(Sup)) } -> { L is Sup - D//C, domain_remove_smaller_than(VD, L, VD1) } ; VD1 = VD ) ), fd_put(V, VD1, VPs) ; true ), remove_dist_lower(CVs, D). remove_upper([], _) --> []. remove_upper([C*X|CXs], Max) --> ( { fd_get(X, XD, XPs) } -> D is Max//C, ( C < 0 -> { domain_remove_smaller_than(XD, D, XD1) } ; { domain_remove_greater_than(XD, D, XD1) } ), fd_put(X, XD1, XPs) ; true ), remove_upper(CXs, Max). remove_lower([], _) --> []. remove_lower([C*X|CXs], Min) --> ( { fd_get(X, XD, XPs) } -> D is -Min//C, ( C < 0 -> { domain_remove_greater_than(XD, D, XD1) } ; { domain_remove_smaller_than(XD, D, XD1) } ), fd_put(X, XD1, XPs) ; true ), remove_lower(CXs, Min). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Parsing a CLP(ℤ) expression has two important side-effects: First, it constrains the variables occurring in the expression to integers. Second, it constrains some of them even more: For example, in X/Y and X mod Y, Y is constrained to be #\= 0. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ constrain_to_integer(Var) :- ( integer(Var) -> true ; fd_get(Var, D, Ps), fd_put(Var, D, Ps) ). power_var_num(P, X, N) :- ( var(P) -> X = P, N = 1 ; P = Left*Right, power_var_num(Left, XL, L), power_var_num(Right, XR, R), XL == XR, X = XL, N is L + R ). /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Given expression E, we obtain the finite domain variable R by interpreting a simple committed-choice language that is a list of conditions and bodies. In conditions, g(Goal) means literally Goal, and m(Match) means that E can be decomposed as stated. The variables are to be understood as the result of parsing the subexpressions recursively. In the body, g(Goal) means again Goal, and p(Propagator) means to attach and trigger once a propagator. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ :- op(800, xfx, =>). parse_clpz(E, R, [g(cyclic_term(E)) => [g(domain_error(clpz_expression, E))], g(var(E)) => [g(non_monotonic(E)), g(constrain_to_integer(E)), g(E = R)], g(integer(E)) => [g(R = E)], ?(E) => [g(must_be_fd_integer(E)), g(R = E)], #E => [g(must_be_fd_integer(E)), g(R = E)], m(A+B) => [p(pplus(A, B, R))], % power_var_num/3 must occur before */2 to be useful g(power_var_num(E, V, N)) => [p(pexp(V, N, R))], m(A*B) => [p(ptimes(A, B, R))], m(A-B) => [p(pplus(R,B,A))], m(-A) => [p(pplus(A,R,0))], m(max(A,B)) => [g(A #=< #R), g(B #=< R), p(pmax(A, B, R))], m(min(A,B)) => [g(A #>= #R), g(B #>= R), p(pmin(A, B, R))], m(A mod B) => [g(B #\= 0), p(pmod(A, B, R))], m(A rem B) => [g(B #\= 0), p(prem(A, B, R))], m(abs(A)) => [g(#R #>= 0), p(pabs(A, R))], m(A/B) => [g(B #\= 0), p(ptimes(R, B, A))], m(A//B) => [g(B #\= 0), p(ptzdiv(A, B, R))], m(A div B) => [g(#R #= (A - (A mod B)) // B)], m(A^B) => [p(pexp(A, B, R))], m(sign(A)) => [g(R in -1..1), p(psign(A, R))], % bitwise operations m(\A) => [p(pfunction(\, A, R))], m(msb(A)) => [p(pfunction(msb, A, R))], m(lsb(A)) => [p(pfunction(lsb, A, R))], m(popcount(A)) => [p(ppopcount(A, R))], m(A< [p(pfunction(<<, A, B, R))], m(A>>B) => [p(pfunction(>>, A, B, R))], m(A/\B) => [p(pfunction(/\, A, B, R))], m(A\/B) => [p(pfunction(\/, A, B, R))], m(xor(A, B)) => [p(pxor(A, B, R))], g(true) => [g(domain_error(clpz_expression, E))] ]). non_monotonic(X) :- ( \+ fd_var(X), monotonic -> instantiation_error(X) ; true ). % Here, we compile the committed choice language to a single % predicate, parse_clpz/2. make_parse_clpz(Clauses) :- parse_clpz_clauses(Clauses0), maplist(goals_goal, Clauses0, Clauses). goals_goal((Head :- Goals), (Head :- Body)) :- list_goal(Goals, Body). parse_clpz_clauses(Clauses) :- parse_clpz(E, R, Matchers), maplist(parse_matcher(E, R), Matchers, Clauses). parse_matcher(E, R, Matcher, Clause) :- Matcher = (Condition0 => Goals0), phrase((parse_condition(Condition0, E, Head), parse_goals(Goals0)), Goals), Clause = (parse_clpz(Head, R) :- Goals). parse_condition(g(Goal), E, E) --> [Goal, !]. parse_condition(?(E), _, ?(E)) --> [!]. parse_condition(#E, _, #E) --> [!]. parse_condition(m(Match), _, Match0) --> [!], { copy_term(Match, Match0), term_variables(Match0, Vs0), term_variables(Match, Vs) }, parse_match_variables(Vs0, Vs). parse_match_variables([], []) --> []. parse_match_variables([V0|Vs0], [V|Vs]) --> [parse_clpz(V0, V)], parse_match_variables(Vs0, Vs). parse_goals([]) --> []. parse_goals([G|Gs]) --> parse_goal(G), parse_goals(Gs). parse_goal(g(Goal)) --> [Goal]. parse_goal(p(Prop0)) --> { term_variables(Prop0, Vs), morphing_propagator(Prop0, Prop, _) }, [make_propagator(Prop, P), new_queue(Q0), phrase(init_propagator_(Vs, P), [Q0], [Q]), variables_same_queue(Vs), trigger_once_(P, Q)]. morphing(pplus). morphing(ptimes). morphing(pexp). morphing(ptzdiv). morphing_propagator(P0, P, Target) :- P0 =.. [F|Args0], ( morphing(F) -> append(Args0, [Last], Args), Target = p(Last) ; Args = Args0, Target = none ), P =.. [F|Args]. morph_into_propagator(MState, Vs, P0, Morph) --> kill(MState), { morphing_propagator(P0, P, _), make_propagator(P, Morph) }, init_propagator_(Vs, Morph), trigger_prop(Morph). /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ?- use_module(library(lists)), use_module(library(format)), clpz:parse_clpz_clauses(Clauses), maplist(portray_clause, Clauses). - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% trigger_once(Prop) :- new_queue(Q), trigger_once_(Prop, Q). trigger_once_(Prop, Q) :- phrase((trigger_prop(Prop),do_queue), [Q], _). neq(A, B) :- propagator_init_trigger(pneq(A, B)). propagator_init_trigger(P) --> { term_variables(P, Vs) }, propagator_init_trigger(Vs, P). propagator_init_trigger(Vs, P) --> [p(Prop)], { make_propagator(P, Prop), new_queue(Q0), phrase(init_propagator_(Vs, Prop), [Q0], [Q]), variables_same_queue(Vs), trigger_once_(Prop, Q) }. variables_same_queue(Vs0) :- include(var, Vs0, Vs), ( Vs == [] -> true ; maplist(variable_queue, Vs, Qs0), sort(Qs0, [Q|Qs]), Q =.. [_|Args], append_queues_(Qs, Args, [append,append,append,ignore]), maplist(clear_queue, Qs), maplist(=(Q), Qs) ). append_queues_([], _, _). append_queues_([Q|Qs], Args0, Is) :- Q =.. [_|Args], maplist(append_queue, Is, Args0, Args), append_queues_(Qs, Args, Is). append_queue(ignore, _, _). append_queue(append, Q0, Q) :- ( get_atts(Q0, queue(Ls0,Ls)) -> ( get_atts(Q, queue(Ms0,Ms)) -> Ls = Ms0, put_atts(Q0, queue(Ls0,Ms)) ; true ) ; ( get_atts(Q, queue(Ms0,Ms)) -> put_atts(Q0, queue(Ms0,Ms)) ; true ) ). clear_queue(queue(Goals,Fast,Slow,Aux)) :- put_atts(Goals, -queue(_,_)), put_atts(Fast, -queue(_,_)), put_atts(Slow, -queue(_,_)), put_atts(Aux, -disabled). variable_queue(Var, Q) :- get_attr(Var, clpz, Attr), Attr = clpz_attr(_Left,_Right,_Spread,_Dom,_Ps,Q). propagator_init_trigger(P) :- phrase(propagator_init_trigger(P), _). propagator_init_trigger(Vs, P) :- phrase(propagator_init_trigger(Vs, P), _). prop_init(Prop, V) :- init_propagator(V, Prop). geq(A, B) :- new_queue(Q), phrase((geq(A, B),do_queue), [Q], _). geq(A, B) --> ( { fd_get(A, AD, APs) } -> { domain_infimum(AD, AI) }, ( { fd_get(B, BD, _) } -> { domain_supremum(BD, BS) }, ( { AI cis_geq BS } -> true ; { propagator_init_trigger(pgeq(A,B)) } ) ; ( { AI cis_geq n(B) } -> true ; { domain_remove_smaller_than(AD, B, AD1) }, fd_put(A, AD1, APs) ) ) ; { fd_get(B, BD, BPs) } -> { domain_remove_greater_than(BD, A, BD1) }, fd_put(B, BD1, BPs) ; A >= B ). /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Naive parsing of inequalities and disequalities can result in a lot of unnecessary work if expressions of non-trivial depth are involved: Auxiliary variables are introduced for sub-expressions, and propagation proceeds on them as if they were involved in a tighter constraint (like equality), whereas eventually only very little of the propagated information is actually used. For example, only extremal values are of interest in inequalities. Introducing auxiliary variables should be avoided when possible, and specialised propagators should be used for common constraints. We again use a simple committed-choice language for matching special cases of constraints. m_c(M,C) means that M matches and C holds. d(X, Y) means decomposition, i.e., it is short for g(parse_clpz(X, Y)). r(X, Y) means to rematch with X and Y. Two things are important: First, although the actual constraint functors (#\=2, #=/2 etc.) are used in the description, they must expand to the respective auxiliary predicates (match_expand/2) because the actual constraints are subject to goal expansion. Second, when specialised constraints (like scalar product) post simpler constraints on their own, these simpler versions must be handled separately and must occur before. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ match_expand(#>=, clpz_geq_). match_expand(#=, clpz_equal_). match_expand(#\=, clpz_neq). symmetric(#=). symmetric(#\=). matches([ m_c(any(X) #>= any(Y), left_right_linsum_const(X, Y, Cs, Vs, Const)) => [g(( Cs = [1], Vs = [A] -> geq(A, Const) ; Cs = [-1], Vs = [A] -> Const1 is -Const, geq(Const1, A) ; Cs = [1,1], Vs = [A,B] -> #A + #B #= #S, geq(S, Const) ; Cs = [1,-1], Vs = [A,B] -> ( Const =:= 0 -> geq(A, B) ; C1 is -Const, propagator_init_trigger(x_leq_y_plus_c(B, A, C1)) ) ; Cs = [-1,1], Vs = [A,B] -> ( Const =:= 0 -> geq(B, A) ; C1 is -Const, propagator_init_trigger(x_leq_y_plus_c(A, B, C1)) ) ; Cs = [-1,-1], Vs = [A,B] -> #A + #B #= #S, Const1 is -Const, geq(Const1, S) ; scalar_product_(#>=, Cs, Vs, Const) ))], m(any(X) - any(Y) #>= integer(C)) => [d(X, X1), d(Y, Y1), g(C1 is -C), p(x_leq_y_plus_c(Y1, X1, C1))], m(integer(X) #>= any(Z) + integer(A)) => [g(C is X - A), r(C, Z)], m(abs(any(X)-any(Y)) #>= any(Z)) => [d(X, X1), d(Y, Y1), d(Z, Z1), g((abs(#A)#= #B,Y1+A#=X1,Z1#== integer(I)) => [d(X, RX), g((I>0 -> I1 is -I, RX in inf..I1 \/ I..sup; true))], m(integer(I) #>= abs(any(X))) => [d(X, RX), g(I>=0), g(I1 is -I), g(RX in I1..I)], m(any(X) #>= any(Y)) => [d(X, RX), d(Y, RY), g(geq(RX, RY))], %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% m(var(X) #= var(Y)) => [g(constrain_to_integer(X)), g(X=Y)], m(var(X) #= var(Y)+var(Z)) => [p(pplus(Y,Z,X))], m(var(X) #= var(Y)-var(Z)) => [p(pplus(X,Z,Y))], m(var(X) #= var(Y)*var(Z)) => [p(ptimes(Y,Z,X))], m(var(X) #= -var(Y)) => [p(pplus(X,Y,0))], m_c(any(X) #= any(Y), left_right_linsum_const(X, Y, Cs, Vs, S)) => [g(scalar_product_(#=, Cs, Vs, S))], m_c(var(X) #= abs(var(Y)) + any(V0), X == Y) => [d(V0,V),p(x_eq_abs_plus_v(X,V))], m_c(var(X) #= abs(var(Y)) - any(V0), X == Y) => [d(-V0,V),p(x_eq_abs_plus_v(X,V))], m(var(X) #= any(Y)) => [d(Y,X)], m(any(X) #= any(Y)) => [d(X, RX), d(Y, RX)], %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% m(var(X) #\= integer(Y)) => [g(neq_num(X, Y))], m(var(X) #\= var(Y)) => [p(pneq(X,Y))], m(var(X) #\= var(Y) + var(Z)) => [p(x_neq_y_plus_z(X, Y, Z))], m(var(X) #\= var(Y) - var(Z)) => [p(x_neq_y_plus_z(Y, X, Z))], m(var(X) #\= var(Y)*var(Z)) => [p(ptimes(Y,Z,P)), g(neq(X,P))], m(integer(X) #\= abs(any(Y)-any(Z))) => [d(Y, Y1), d(Z, Z1), p(absdiff_neq(Y1, Z1, X))], m_c(any(X) #\= any(Y), left_right_linsum_const(X, Y, Cs, Vs, S)) => [g(scalar_product_(#\=, Cs, Vs, S))], m(any(X) #\= any(Y) + any(Z)) => [d(X, X1), d(Y, Y1), d(Z, Z1), p(x_neq_y_plus_z(X1, Y1, Z1))], m(any(X) #\= any(Y) - any(Z)) => [d(X, X1), d(Y, Y1), d(Z, Z1), p(x_neq_y_plus_z(Y1, X1, Z1))], m(any(X) #\= any(Y)) => [d(X, RX), d(Y, RY), g(neq(RX, RY))] ]). /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - We again compile the committed-choice matching language to the intended auxiliary predicates. We now must take care not to unintentionally unify a variable with a complex term. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ make_matches(Clauses) :- matches(Ms), findall(F, (member(M=>_, Ms), arg(1, M, M1), functor(M1, F, _)), Fs0), sort(Fs0, Fs), maplist(prevent_cyclic_argument, Fs, PrevCyclicClauses), phrase(matchers(Ms), Clauses0), maplist(goals_goal, Clauses0, MatcherClauses), append(PrevCyclicClauses, MatcherClauses, Clauses1), sort_by_predicate(Clauses1, Clauses). sort_by_predicate(Clauses, ByPred) :- map_list_to_pairs(predname, Clauses, Keyed), keysort(Keyed, KeyedByPred), pairs_values(KeyedByPred, ByPred). predname((H:-_), Key) :- !, predname(H, Key). predname(M:H, M:Key) :- !, predname(H, Key). predname(H, Name/Arity) :- !, functor(H, Name, Arity). prevent_cyclic_argument(F0, Clause) :- match_expand(F0, F), Head =.. [F,X,Y], Clause = (Head :- ( cyclic_term(X) -> domain_error(clpz_expression, X) ; cyclic_term(Y) -> domain_error(clpz_expression, Y) ; false )). matchers([]) --> []. matchers([Condition => Goals|Ms]) --> matcher(Condition, Goals), matchers(Ms). matcher(m(M), Gs) --> matcher(m_c(M,true), Gs). matcher(m_c(Matcher,Cond), Gs) --> [(Head :- Goals0)], { Matcher =.. [F,A,B], match_expand(F, Expand), Head =.. [Expand,X,Y], phrase((match(A, X), match(B, Y)), Goals0, [Cond,!|Goals1]), phrase(match_goals(Gs, Expand), Goals1) }, ( { symmetric(F), \+ (subsumes_term(A, B), subsumes_term(B, A)) } -> { Head1 =.. [Expand,Y,X] }, [(Head1 :- Goals0)] ; [] ). match(any(A), T) --> [A = T]. match(var(V), T) --> [( nonvar(T), ( T = ?(Var) ; T = #Var ) -> must_be_fd_integer(Var), V = Var ; v_or_i(T), V = T )]. match(integer(I), T) --> [integer(T), I = T]. match(-X, T) --> [nonvar(T), T = -A], match(X, A). match(abs(X), T) --> [nonvar(T), T = abs(A)], match(X, A). match(X+Y, T) --> [nonvar(T), T = A + B], match(X, A), match(Y, B). match(X-Y, T) --> [nonvar(T), T = A - B], match(X, A), match(Y, B). match(X*Y, T) --> [nonvar(T), T = A * B], match(X, A), match(Y, B). match_goals([], _) --> []. match_goals([G|Gs], F) --> match_goal(G, F), match_goals(Gs, F). match_goal(r(X,Y), F) --> { G =.. [F,X,Y] }, [G]. match_goal(d(X,Y), _) --> [parse_clpz(X, Y)]. match_goal(g(Goal), _) --> [Goal]. match_goal(p(Prop0), _) --> { term_variables(Prop0, Vs), morphing_propagator(Prop0, Prop, _) }, [make_propagator(Prop, P), new_queue(Q0), phrase(init_propagator_(Vs, P), [Q0], [Q]), variables_same_queue(Vs), trigger_once_(P, Q)]. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% #>=(?X, ?Y) % % Same as Y #=< X. When reasoning over integers, replace (>=)/2 by (#>=)/2 % to obtain more general relations. X #>= Y :- clpz_geq(X, Y). clpz_geq(X, Y) :- clpz_geq_(X, Y), reinforce(X), reinforce(Y). %% #=<(?X, ?Y) % % The arithmetic expression X is less than or equal to Y. When % reasoning over integers, replace (=<)/2 by (#=<)/2 to obtain more % general relations. X #=< Y :- Y #>= X. %% #=(?X, ?Y) % % The arithmetic expression X equals Y. When reasoning over integers, % replace `(is)/2` by `(#=)/2` to obtain more general relations. X #= Y :- clpz_equal(X, Y). clpz_equal(X, Y) :- clpz_equal_(X, Y), reinforce(X). /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Conditions under which an equality can be compiled to built-in arithmetic. Their order is significant. (/)/2 becomes (//)/2. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ expr_conds(E, E) --> [integer(E)], { var(E), !, \+ monotonic }. expr_conds(E, E) --> { integer(E) }. expr_conds(?(E), E) --> [integer(E)]. expr_conds(#E, E) --> [integer(E)]. expr_conds(-E0, -E) --> expr_conds(E0, E). expr_conds(abs(E0), abs(E)) --> expr_conds(E0, E). expr_conds(A0+B0, A+B) --> expr_conds(A0, A), expr_conds(B0, B). expr_conds(A0*B0, A*B) --> expr_conds(A0, A), expr_conds(B0, B). expr_conds(A0-B0, A-B) --> expr_conds(A0, A), expr_conds(B0, B). expr_conds(A0//B0, A//B) --> expr_conds(A0, A), expr_conds(B0, B), [B =\= 0]. %expr_conds(A0/B0, AB) --> expr_conds(A0//B0, AB). expr_conds(min(A0,B0), min(A,B)) --> expr_conds(A0, A), expr_conds(B0, B). expr_conds(max(A0,B0), max(A,B)) --> expr_conds(A0, A), expr_conds(B0, B). expr_conds(A0 mod B0, A mod B) --> expr_conds(A0, A), expr_conds(B0, B), [B =\= 0]. expr_conds(A0^B0, A^B) --> expr_conds(A0, A), expr_conds(B0, B), [(B >= 0 ; A =:= -1)]. % Bitwise operations, added to make CLP(ℤ) usable in more cases expr_conds(\ A0, \ A) --> expr_conds(A0, A). expr_conds(A0< expr_conds(A0, A), expr_conds(B0, B). expr_conds(A0>>B0, A>>B) --> expr_conds(A0, A), expr_conds(B0, B). expr_conds(A0/\B0, A/\B) --> expr_conds(A0, A), expr_conds(B0, B). expr_conds(A0\/B0, A\/B) --> expr_conds(A0, A), expr_conds(B0, B). expr_conds(xor(A0,B0), xor(A,B)) --> expr_conds(A0, A), expr_conds(B0, B). % expr_conds(lsb(A0), lsb(A)) --> expr_conds(A0, A). % expr_conds(msb(A0), msb(A)) --> expr_conds(A0, A). expr_conds(popcount(A0), Count) --> expr_conds(A0, A), [I is A, arithmetic:popcount(I, Count)]. no_popcount_t(Gs, T) :- ( member(arithmetic:popcount(_, _), Gs) -> T = false ; T = true ). clpz_expandable(_ in _). clpz_expandable(_ #= _). clpz_expandable(_ #>= _). clpz_expandable(_ #=< _). clpz_expandable(_ #> _). clpz_expandable(_ #< _). clpz_expandable(_ #\= _). clpz_expandable(_ #<==> _). clpz_expansion(Var in Dom, In) :- ( ground(Dom), Dom = L..U, integer(L), integer(U) -> expansion_simpler( ( integer(Var) -> between:between(L, U, Var) ; clpz:clpz_in(Var, Dom) ), In) ; In = clpz:clpz_in(Var, Dom) ). clpz_expansion(A #<==> B, Reif) :- nonvar(A), A =.. [F0,X0,Y0], clpz_builtin(F0, F), phrase(expr_conds(X0, X), Cs0, Cs), phrase(expr_conds(Y0, Y), Cs), list_goal(Cs0, Cond), Expr =.. [F,X,Y], expansion_simpler(( Cond, ( var(B) ; integer(B), clpz:between(0, 1, B) ) -> ( Expr -> B = 1 ; B = 0 ) ; clpz:reify(A, RA), clpz:reify(B, RA) ), Reif). clpz_expansion(X0 #= Y0, Equal) :- phrase(expr_conds(X0, X), CsX), phrase(expr_conds(Y0, Y), CsY), list_goal(CsX, CondX), list_goal(CsY, CondY), no_popcount_t(CsY, YT), no_popcount_t(CsX, XT), expansion_simpler( ( CondX -> ( YT, var(Y) -> Y is X ; CondY -> X =:= Y ; T is X, clpz:clpz_equal(T, Y0) ) ; CondY -> ( XT, var(X) -> X is Y ; T is Y, clpz:clpz_equal(X0, T) ) ; clpz:clpz_equal(X0, Y0) ), Equal). clpz_expansion(X0 #>= Y0, Geq) :- phrase(expr_conds(X0, X), CsX), phrase(expr_conds(Y0, Y), CsY), list_goal(CsX, CondX), list_goal(CsY, CondY), expansion_simpler( ( CondX -> ( CondY -> X >= Y ; T is X, clpz:clpz_geq(T, Y0) ) ; CondY -> T is Y, clpz:clpz_geq(X0, T) ; clpz:clpz_geq(X0, Y0) ), Geq). clpz_expansion(X #=< Y, Leq) :- clpz_expansion(Y #>= X, Leq). clpz_expansion(X #> Y, Gt) :- clpz_expansion(X #>= Y+1, Gt). clpz_expansion(X #< Y, Lt) :- clpz_expansion(Y #> X, Lt). clpz_expansion(X0 #\= Y0, Neq) :- phrase(expr_conds(X0, X), CsX), phrase(expr_conds(Y0, Y), CsY), list_goal(CsX, CondX), list_goal(CsY, CondY), expansion_simpler( ( CondX -> ( CondY -> X =\= Y ; T is X, clpz:clpz_neq(T, Y0) ) ; CondY -> T is Y, clpz:clpz_neq(X0, T) ; clpz:clpz_neq(X0, Y0) ), Neq). clpz_builtin(#=, =:=). clpz_builtin(#\=, =\=). clpz_builtin(#>, >). clpz_builtin(#<, <). clpz_builtin(#>=, >=). clpz_builtin(#=<, =<). expansion_simpler((True->Then0;_), Then) :- is_true(True), !, expansion_simpler(Then0, Then). expansion_simpler((False->_;Else0), Else) :- is_false(False), !, expansion_simpler(Else0, Else). expansion_simpler((If->Then0;Else0), (If->Then;Else)) :- !, expansion_simpler(Then0, Then), expansion_simpler(Else0, Else). expansion_simpler((A0,B0), (A,B)) :- !, expansion_simpler(A0, A), expansion_simpler(B0, B). expansion_simpler(Var is Expr0, Goal) :- ground(Expr0), !, phrase(expr_conds(Expr0, Expr), Gs), ( maplist(call, Gs) -> Value is Expr, Goal = (Var = Value) ; Goal = false ). expansion_simpler(Var =:= Expr0, Goal) :- ground(Expr0), !, phrase(expr_conds(Expr0, Expr), Gs), ( maplist(call, Gs) -> Value is Expr, Goal = (Var =:= Value) ; Goal = false ). expansion_simpler(between:between(L,U,V), Goal) :- maplist(integer, [L,U,V]), !, ( between(L,U,V) -> Goal = true ; Goal = false ). expansion_simpler(Goal, Goal). is_true(true). is_true(integer(I)) :- integer(I). % :- if(current_predicate(var_property/2)). % is_true(var(X)) :- var(X), var_property(X, fresh(true)). % is_false(integer(X)) :- var(X), var_property(X, fresh(true)). % :- endif. is_false((A,B)) :- is_false(A) ; is_false(B). is_false(var(X)) :- nonvar(X). :- dynamic(goal_expansion/1). user:goal_expansion(Goal0, Goal) :- \+ goal_expansion(false), clpz_expandable(Goal0), clpz_expansion(Goal0, Goal). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% linsum(X, S, S) --> { var(X), !, non_monotonic(X) }, [vn(X,1)]. linsum(I, S0, S) --> { integer(I), S is S0 + I }. linsum(?(X), S, S) --> { must_be_fd_integer(X) }, [vn(X,1)]. linsum(#X, S, S) --> { must_be_fd_integer(X) }, [vn(X,1)]. linsum(-A, S0, S) --> mulsum(A, -1, S0, S). linsum(N*A, S0, S) --> { integer(N) }, !, mulsum(A, N, S0, S). linsum(A*N, S0, S) --> { integer(N) }, !, mulsum(A, N, S0, S). linsum(A+B, S0, S) --> linsum(A, S0, S1), linsum(B, S1, S). linsum(A-B, S0, S) --> linsum(A, S0, S1), mulsum(B, -1, S1, S). mulsum(A, M, S0, S) --> { phrase(linsum(A, 0, CA), As), S is S0 + M*CA }, lin_mul(As, M). lin_mul([], _) --> []. lin_mul([vn(X,N0)|VNs], M) --> { N is N0*M }, [vn(X,N)], lin_mul(VNs, M). v_or_i(V) :- var(V), !, non_monotonic(V). v_or_i(I) :- integer(I). must_be_fd_integer(X) :- ( var(X) -> constrain_to_integer(X) ; must_be(integer, X) ). samsort(Ls0, Ls) :- maplist(as_key, Ls0, LKs0), keysort(LKs0, LKs), maplist(as_key, Ls, LKs). as_key(E, E-t). left_right_linsum_const(Left, Right, Cs, Vs, Const) :- phrase(linsum(Left, 0, CL), Lefts0, Rights), phrase(linsum(Right, 0, CR), Rights0), maplist(linterm_negate, Rights0, Rights), samsort(Lefts0, Lefts), Lefts = [vn(First,N)|LeftsRest], vns_coeffs_variables(LeftsRest, N, First, Cs0, Vs0), filter_linsum(Cs0, Vs0, Cs, Vs), Const is CR - CL. %format("linear sum: ~w ~w ~w\n", [Cs,Vs,Const]). linterm_negate(vn(V,N0), vn(V,N)) :- N is -N0. vns_coeffs_variables([], N, V, [N], [V]). vns_coeffs_variables([vn(V,N)|VNs], N0, V0, Ns, Vs) :- ( V == V0 -> N1 is N0 + N, vns_coeffs_variables(VNs, N1, V0, Ns, Vs) ; Ns = [N0|NRest], Vs = [V0|VRest], vns_coeffs_variables(VNs, N, V, NRest, VRest) ). filter_linsum([], [], [], []). filter_linsum([C0|Cs0], [V0|Vs0], Cs, Vs) :- ( C0 =:= 0 -> constrain_to_integer(V0), filter_linsum(Cs0, Vs0, Cs, Vs) ; Cs = [C0|Cs1], Vs = [V0|Vs1], filter_linsum(Cs0, Vs0, Cs1, Vs1) ). gcd([], G, G). gcd([N|Ns], G0, G) :- G1 is gcd(N, G0), gcd(Ns, G1, G). even(N) :- N mod 2 =:= 0. odd(N) :- \+ even(N). /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - k-th root of N, if N is a k-th power. TODO: Replace this when the GMP function becomes available. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ integer_kth_root(N, K, R) :- ( even(K) -> N >= 0 ; true ), ( K < 0 -> ( N =:= 1 -> R = 1 ; N =:= -1 -> odd(K), R = -1 ; false ) ; ( N < 0 -> odd(K), integer_kroot(N, 0, N, K, R) ; integer_kroot(0, N, N, K, R) ) ). integer_kroot(L, U, N, K, R) :- ( L =:= U -> N =:= L^K, R = L ; L + 1 =:= U -> ( L^K =:= N -> R = L ; U^K =:= N -> R = U ; false ) ; Mid is (L + U)//2, ( Mid^K > N -> integer_kroot(L, Mid, N, K, R) ; integer_kroot(Mid, U, N, K, R) ) ). integer_log_b(N, B, Log0, Log) :- T is B^Log0, ( T =:= N -> Log = Log0 ; T < N, Log1 is Log0 + 1, integer_log_b(N, B, Log1, Log) ). floor_integer_log_b(N, B, Log0, Log) :- T is B^Log0, ( T > N -> Log is Log0 - 1 ; T =:= N -> Log = Log0 ; T < N, Log1 is Log0 + 1, floor_integer_log_b(N, B, Log1, Log) ). /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Largest R such that R^K =< N. TODO: Replace this when the GMP function becomes available. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ integer_kth_root_leq(N, K, R) :- ( even(K) -> N >= 0 ; true ), ( N < 0 -> odd(K), integer_kroot_leq(N, 0, N, K, R) ; integer_kroot_leq(0, N, N, K, R) ). integer_kroot_leq(L, U, N, K, R) :- ( L =:= U -> R = L ; L + 1 =:= U -> ( U^K =< N -> R = U ; R = L ) ; Mid is (L + U)//2, ( Mid^K > N -> integer_kroot_leq(L, Mid, N, K, R) ; integer_kroot_leq(Mid, U, N, K, R) ) ). %% #\=(?X, ?Y) % % The arithmetic expressions X and Y evaluate to distinct integers. % When reasoning over integers, replace (=\=)/2 by (#\=)/2 to obtain more % general relations. X #\= Y :- clpz_neq(X, Y). % X #\= Y + Z x_neq_y_plus_z(X, Y, Z) :- propagator_init_trigger(x_neq_y_plus_z(X,Y,Z)). % X is distinct from the number N. This is used internally, and does % not reinforce other constraints. neq_num(X, N) :- ( fd_get(X, XD, XPs) -> domain_remove(XD, N, XD1), fd_put(X, XD1, XPs) ; X =\= N ). neq_num(X, N) --> ( { fd_get(X, XD, XPs) } -> { domain_remove(XD, N, XD1) }, fd_put(X, XD1, XPs) ; X =\= N ). %% #>(?X, ?Y) % % Same as Y #< X. X #> Y :- X #>= Y + 1. %% #<(?X, ?Y) % % The arithmetic expression X is less than Y. When reasoning over % integers, replace `(<)/2` by `(#<)/2` to obtain more general relations. % % In addition to its regular use in tasks that require it, this % constraint can also be useful to eliminate uninteresting symmetries % from a problem. For example, all possible matches between pairs % built from four players in total: % % ``` % ?- Vs = [A,B,C,D], Vs ins 1..4, % all_different(Vs), % A #< B, C #< D, A #< C, % findall(pair(A,B)-pair(C,D), label(Vs), Ms). % Ms = [ pair(1, 2)-pair(3, 4), % pair(1, 3)-pair(2, 4), % pair(1, 4)-pair(2, 3)]. % ``` X #< Y :- Y #> X. %% #\(+Q) % % The reifiable constraint Q does _not_ hold. For example, to obtain % the complement of a domain: % % ``` % ?- #\ X in -3..0\/10..80. % X in inf.. -4\/1..9\/81..sup. % ``` #\ Q :- reify(Q, 0). %% #<==>(?P, ?Q) % % P and Q are equivalent. For example: % % ``` % ?- X #= 4 #<==> B, X #\= 4. % B = 0, % X in inf..3\/5..sup. % ``` % The following example uses reified constraints to relate a list of % finite domain variables to the number of occurrences of a given value: % % ``` % vs_n_num(Vs, N, Num) :- % maplist(eq_b(N), Vs, Bs), % sum(Bs, #=, Num). % % eq_b(X, Y, B) :- X #= Y #<==> B. % ``` % % Sample queries and their results: % % ``` % ?- Vs = [X,Y,Z], Vs ins 0..1, vs_n_num(Vs, 4, Num). % Vs = [X, Y, Z], % Num = 0, % X in 0..1, % Y in 0..1, % Z in 0..1. % % ?- vs_n_num([X,Y,Z], 2, 3). % X = 2, % Y = 2, % Z = 2. % ``` L #<==> R :- reify(L, B), reify(R, B). %% #==>(?P, ?Q) % % P implies Q. /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Implication is special in that created auxiliary constraints can be retracted when the implication becomes entailed, for example: %?- X + 1 #= Y #==> Z, Z #= 1. %@ Z = 1, %@ X in inf..sup, %@ Y in inf..sup. We cannot use propagator_init_trigger/1 here because the states of auxiliary propagators are themselves part of the propagator. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ L #==> R :- reify(L, LB, LPs), reify(R, RB, RPs), append(LPs, RPs, Ps), propagator_init_trigger([LB,RB], pimpl(LB,RB,Ps)). %% #<==(?P, ?Q) % % Q implies P. L #<== R :- R #==> L. %% #/\(?P, ?Q) % % P and Q hold. L #/\ R :- reify(L, 1), reify(R, 1). conjunctive_neqs_var_drep(Eqs, Var, Drep) :- conjunctive_neqs_var(Eqs, Var), phrase(conjunctive_neqs_vals(Eqs), Vals), list_to_domain(Vals, Dom), domain_complement(Dom, C), domain_to_drep(C, Drep). conjunctive_neqs_var(V, _) :- var(V), !, false. conjunctive_neqs_var(L #\= R, Var) :- ( var(L), integer(R) -> Var = L ; integer(L), var(R) -> Var = R ; false ). conjunctive_neqs_var(A #/\ B, VA) :- conjunctive_neqs_var(A, VA), conjunctive_neqs_var(B, VB), VA == VB. conjunctive_neqs_vals(L #\= R) --> ( { integer(L) } -> [L] ; [R] ). conjunctive_neqs_vals(A #/\ B) --> conjunctive_neqs_vals(A), conjunctive_neqs_vals(B). %% #\/(?P, ?Q) % % P or Q holds. For example, the sum of natural numbers below 1000 % that are multiples of 3 or 5: % % ``` % ?- findall(N, (N mod 3 #= 0 #\/ N mod 5 #= 0, N in 0..999, % indomain(N)), % Ns), % sum(Ns, #=, Sum). % Ns = [0, 3, 5, 6, 9, 10, 12, 15, 18|...], % Sum = 233168. % ``` L #\/ R :- ( disjunctive_eqs_var_drep(L #\/ R, Var, Drep) -> Var in Drep ; reify(L, X, Ps1), reify(R, Y, Ps2), propagator_init_trigger([X,Y], reified_or(X,Ps1,Y,Ps2,1)) ). disjunctive_eqs_var_drep(Eqs, Var, Drep) :- disjunctive_eqs_var(Eqs, Var), phrase(disjunctive_eqs_vals(Eqs), Vals), list_to_drep(Vals, Drep). disjunctive_eqs_var(V, _) :- var(V), !, false. disjunctive_eqs_var(V in I, V) :- var(V), integer(I). disjunctive_eqs_var(L #= R, Var) :- ( var(L), integer(R) -> Var = L ; integer(L), var(R) -> Var = R ; false ). disjunctive_eqs_var(A #\/ B, VA) :- disjunctive_eqs_var(A, VA), disjunctive_eqs_var(B, VB), VA == VB. disjunctive_eqs_vals(L #= R) --> ( { integer(L) } -> [L] ; [R] ). disjunctive_eqs_vals(_ in I) --> [I]. disjunctive_eqs_vals(A #\/ B) --> disjunctive_eqs_vals(A), disjunctive_eqs_vals(B). %% #\(?P, ?Q) % % Either P holds or Q holds, but not both. L #\ R :- (L #\/ R) #/\ #\ (L #/\ R). /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - A constraint that is being reified need not hold. Therefore, in X/Y, Y can as well be 0, for example. Note that it is OK to constrain the *result* of an expression (which does not appear explicitly in the expression and is not visible to the outside), but not the operands, except for requiring that they be integers. In contrast to parse_clpz/2, the result of an expression can now also be undefined, in which case the constraint cannot hold. Therefore, the committed-choice language is extended by an element d(D) that states D is 1 iff all subexpressions are defined. a(V) means that V is an auxiliary variable that was introduced while parsing a compound expression. a(X,V) means V is auxiliary unless it is (==)/2 X, and a(X,Y,V) means V is auxiliary unless it is (==)/2 X or Y. l(L) means the literal L occurs in the described list, and ls(Ls) means the literals Ls occur in the described list. When a constraint becomes entailed or subexpressions become undefined, created auxiliary constraints are killed, and the "clpz" attribute is removed from auxiliary variables. For (//)/2, (mod)/2 and (rem)/2, we create a skeleton propagator and remember it as an auxiliary constraint. The pskeleton propagator can use the skeleton when the constraint is defined. We cannot use a skeleton propagator for (/)/2, since (/)/2 can fail in cases such as 0 #==> X #= 1/2, where we expect success. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ parse_reified(E, R, D, [g(cyclic_term(E)) => [g(domain_error(clpz_expression, E))], g(var(E)) => [g(non_monotonic(E)), g(constrain_to_integer(E)), g(R = E), g(D=1)], g(integer(E)) => [g(R=E), g(D=1)], ?(E) => [g(must_be_fd_integer(E)), g(R=E), g(D=1)], #E => [g(must_be_fd_integer(E)), g(R=E), g(D=1)], m(A+B) => [d(D), p(pplus(A,B,R)), a(A,B,R)], m(A*B) => [d(D), p(ptimes(A,B,R)), a(A,B,R)], m(A-B) => [d(D), p(pplus(R,B,A)), a(A,B,R)], m(-A) => [d(D), p(pplus(A,R,0)), a(R)], m(max(A,B)) => [d(D), p(pgeq(R, A)), p(pgeq(R, B)), p(pmax(A,B,R)), a(A,B,R)], m(min(A,B)) => [d(D), p(pgeq(A, R)), p(pgeq(B, R)), p(pmin(A,B,R)), a(A,B,R)], m(abs(A)) => [d(D), g(#R#>=0), p(pabs(A, R)), a(A,R)], m(A^B) => [d(D1), p(preified_exp(A,B,D2,R)), p(reified_and(D1,[],D2,[],D)),a(D2),a(A,B,R)], m(A/B) => [d(D1), p(preified_slash(A,B,D2,R)), p(reified_and(D1,[],D2,[],D)),a(D2),a(A,B,R)], m(A div B) => [d(D1), g(phrase(parse_reified_clpz(((A-(A mod B)) // B), R, D2), Ps)), ls(Ps), p(reified_and(D1,[],D2,[],D)),a(D2),a(A,B,R)], m(A//B) => [skeleton(A,B,D,R,ptzdiv)], m(A mod B) => [skeleton(A,B,D,R,pmod)], m(A rem B) => [skeleton(A,B,D,R,prem)], % bitwise operations m(\A) => [function(D,\,A,R)], m(msb(A)) => [g(#A#>0) ,function(D,msb,A,R)], m(lsb(A)) => [g(#A#>0), function(D,lsb,A,R)], m(popcount(A)) => [d(D), p(ppopcount(A, R)), a(A,R)], m(sign(A)) => [d(D), p(psign(A, R)), a(A,R)], m(A< [function(D,<<,A,B,R)], m(A>>B) => [function(D,>>,A,B,R)], m(A/\B) => [function(D,/\,A,B,R)], m(A\/B) => [function(D,\/,A,B,R)], m(xor(A, B)) => [skeleton(A,B,D,R,pxor)], g(true) => [g(domain_error(clpz_expression, E))]] ). % Again, we compile this to a predicate, parse_reified_clpz//3. This % time, it is a DCG that describes the list of auxiliary variables and % propagators for the given expression, in addition to relating it to % its reified (Boolean) finite domain variable and its Boolean % definedness. make_parse_reified(Clauses) :- parse_reified_clauses(Clauses0), maplist(goals_goal_dcg, Clauses0, Clauses). goals_goal_dcg((Head --> Goals), Clause) :- list_goal(Goals, Body), expand_term((Head --> Body), Clause). parse_reified_clauses(Clauses) :- parse_reified(E, R, D, Matchers), maplist(parse_reified(E, R, D), Matchers, Clauses). parse_reified(E, R, D, Matcher, Clause) :- Matcher = (Condition0 => Goals0), phrase((reified_condition(Condition0, E, Head, Ds), reified_goals(Goals0, Ds)), Goals, [a(D)]), Clause = (parse_reified_clpz(Head, R, D) --> Goals). reified_condition(g(Goal), E, E, []) --> [{Goal}, !]. reified_condition(?(E), _, ?(E), []) --> [!]. reified_condition(#E, _, #E, []) --> [!]. reified_condition(m(Match), _, Match0, Ds) --> [!], { copy_term(Match, Match0), term_variables(Match0, Vs0), term_variables(Match, Vs) }, reified_variables(Vs0, Vs, Ds). reified_variables([], [], []) --> []. reified_variables([V0|Vs0], [V|Vs], [D|Ds]) --> [parse_reified_clpz(V0, V, D)], reified_variables(Vs0, Vs, Ds). reified_goals([], _) --> []. reified_goals([G|Gs], Ds) --> reified_goal(G, Ds), reified_goals(Gs, Ds). reified_goal(d(D), Ds) --> ( { Ds = [X] } -> [{D=X}] ; { Ds = [X,Y] } -> { phrase(reified_goal(p(reified_and(X,[],Y,[],D)), _), Gs), list_goal(Gs, Goal) }, [( {X==1, Y==1} -> {D = 1} ; Goal )] ; { domain_error(one_or_two_element_list, Ds) } ). reified_goal(g(Goal), _) --> [{Goal}]. reified_goal(p(Vs, Prop0), _) --> { morphing_propagator(Prop0, Prop, Target) }, [{make_propagator(Prop, P)}], target_propagator(Target), parse_init_dcg(Vs, P), [{variables_same_queue(Vs), trigger_once(P)}], [( { propagator_state(P, S), S == dead } -> [] ; [p(P)])]. reified_goal(p(Prop), Ds) --> { term_variables(Prop, Vs) }, reified_goal(p(Vs,Prop), Ds). reified_goal(function(D,Op,A,B,R), Ds) --> reified_goals([d(D),p(pfunction(Op,A,B,R)),a(A,B,R)], Ds). reified_goal(function(D,Op,A,R), Ds) --> reified_goals([d(D),p(pfunction(Op,A,R)),a(A,R)], Ds). reified_goal(skeleton(A,B,D,R,F), Ds) --> { Prop0 =.. [F,X,Y,Z], morphing_propagator(Prop0, Prop, Target) }, target_propagator(Target), reified_goals([d(D1),l(p(P)),g(make_propagator(Prop, P)), p([A,B,D2,R], pskeleton(A,B,D2,[X,Y,Z]-P,R,F)), p(reified_and(D1,[],D2,[],D)),a(D2),a(A,B,R)], Ds). reified_goal(a(V), _) --> [a(V)]. reified_goal(a(X,V), _) --> [a(X,V)]. reified_goal(a(X,Y,V), _) --> [a(X,Y,V)]. reified_goal(l(L), _) --> [[L]]. reified_goal(ls(Ls), _) --> [Ls]. target_propagator(p(Prop)) --> [[p(Prop)]]. target_propagator(none) --> []. parse_init_dcg([], _) --> []. parse_init_dcg([V|Vs], P) --> [{init_propagator(V, P)}], parse_init_dcg(Vs, P). /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ?- use_module(library(lists)), use_module(library(format)), clpz:parse_reified_clauses(Cs), maplist(portray_clause, Cs). - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ reify(E, B) :- reify(E, B, _). reify(Expr, B, Ps) :- ( acyclic_term(Expr), reifiable(Expr) -> phrase(reify(Expr, B), Ps) ; domain_error(clpz_reifiable_expression, Expr) ). reifiable(E) :- var(E), non_monotonic(E). reifiable(E) :- integer(E), E in 0..1. reifiable(?(E)) :- must_be_fd_integer(E). reifiable(#E) :- must_be_fd_integer(E). reifiable(V in _) :- fd_variable(V). reifiable(Expr) :- Expr =.. [Op,Left,Right], ( memberchk(Op, [#>=,#>,#=<,#<,#=,#\=]) ; memberchk(Op, [#==>,#<==,#<==>,#/\,#\/,#\]), reifiable(Left), reifiable(Right) ). reifiable(#\ E) :- reifiable(E). reifiable(tuples_in(Tuples, Relation)) :- must_be(list(list), Tuples), maplist(maplist(fd_variable), Tuples), must_be(list(list(integer)), Relation). reifiable(finite_domain(V)) :- fd_variable(V). reify(E, B) --> { B in 0..1 }, reify_(E, B). reify_(E, B) --> { var(E), !, E = B }. reify_(E, B) --> { integer(E), E = B }. reify_(?(B), B) --> []. reify_(#B, B) --> []. reify_(V in Drep, B) --> { drep_to_domain(Drep, Dom) }, propagator_init_trigger(reified_in(V,Dom,B)), a(B). reify_(tuples_in(Tuples, Relation), B) --> { maplist(relation_tuple_b_prop(Relation), Tuples, Bs, Ps), maplist(monotonic, Bs, Bs1), fold_statement(conjunction, Bs1, And), #B #<==> And }, propagator_init_trigger([B], tuples_not_in(Tuples, Relation, B)), kill_reified_tuples(Bs, Ps, Bs), seq(Ps), as([B|Bs]). reify_(finite_domain(V), B) --> propagator_init_trigger(reified_fd(V,B)), a(B). reify_(L #>= R, B) --> arithmetic(L, R, B, reified_geq). reify_(L #= R, B) --> arithmetic(L, R, B, reified_eq). reify_(L #\= R, B) --> arithmetic(L, R, B, reified_neq). reify_(L #> R, B) --> reify_(L #>= (R+1), B). reify_(L #=< R, B) --> reify_(R #>= L, B). reify_(L #< R, B) --> reify_(R #>= (L+1), B). reify_(L #==> R, B) --> reify_((#\ L) #\/ R, B). reify_(L #<== R, B) --> reify_(R #==> L, B). reify_(L #<==> R, B) --> reify_((L #==> R) #/\ (R #==> L), B). reify_(L #\ R, B) --> reify_((L #\/ R) #/\ #\ (L #/\ R), B). reify_(L #/\ R, B) --> ( { conjunctive_neqs_var_drep(L #/\ R, V, D) } -> reify_(V in D, B) ; boolean(L, R, B, reified_and) ). reify_(L #\/ R, B) --> ( { disjunctive_eqs_var_drep(L #\/ R, V, D) } -> reify_(V in D, B) ; boolean(L, R, B, reified_or) ). reify_(#\ Q, B) --> reify(Q, QR), propagator_init_trigger(reified_not(QR,B)), a(B). arithmetic(L, R, B, Functor) --> { phrase((parse_reified_clpz(L, LR, LD), parse_reified_clpz(R, RR, RD)), Ps), Prop =.. [Functor,LD,LR,RD,RR,Ps,B] }, seq(Ps), propagator_init_trigger([LD,LR,RD,RR,B], Prop), a(B). boolean(L, R, B, Functor) --> { reify(L, LR, Ps1), reify(R, RR, Ps2), Prop =.. [Functor,LR,Ps1,RR,Ps2,B] }, seq(Ps1), seq(Ps2), propagator_init_trigger([LR,RR,B], Prop), a(LR, RR, B). a(X,Y,B) --> ( nonvar(X) -> a(Y, B) ; nonvar(Y) -> a(X, B) ; [a(X,Y,B)] ). a(X, B) --> ( { var(X) } -> [a(X, B)] ; a(B) ). a(B) --> ( { var(B) } -> [a(B)] ; [] ). as([]) --> []. as([B|Bs]) --> a(B), as(Bs). kill_reified_tuples([], _, _) --> []. kill_reified_tuples([B|Bs], Ps, All) --> propagator_init_trigger([B], kill_reified_tuples(B, Ps, All)), kill_reified_tuples(Bs, Ps, All). relation_tuple_b_prop(Relation, Tuple, B, p(Prop)) :- put_attr(R, clpz_relation, Relation), make_propagator(reified_tuple_in(Tuple, R, B), Prop), new_queue(Q0), phrase((tuple_freeze_(Tuple, Prop), init_propagator_([B], Prop), do_queue), [Q0], _). tuples_in_conjunction(Tuples, Relation, Conj) :- maplist(tuple_in_disjunction(Relation), Tuples, Disjs), fold_statement(conjunction, Disjs, Conj). tuple_in_disjunction(Relation, Tuple, Disj) :- maplist(tuple_in_conjunction(Tuple), Relation, Conjs), fold_statement(disjunction, Conjs, Disj). tuple_in_conjunction(Tuple, Element, Conj) :- maplist(var_eq, Tuple, Element, Eqs), fold_statement(conjunction, Eqs, Conj). fold_statement(Operation, List, Statement) :- ( List = [] -> Statement = 1 ; List = [First|Rest], foldl(Operation, Rest, First, Statement) ). conjunction(E, Conj, Conj #/\ E). disjunction(E, Disj, Disj #\/ E). var_eq(V, N, #V #= N). % Match variables to created skeleton. skeleton(Vs, Vs-Prop) :- ( propagator_state(Prop, State), State == dead -> true ; maplist(prop_init(Prop), Vs), trigger_once(Prop) ). /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - A drep is a user-accessible and visible domain representation. N, N..M, and D1 \/ D2 are dreps, if D1 and D2 are dreps. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ is_drep(N) :- integer(N). is_drep(N..M) :- drep_bound(N), drep_bound(M), N \== sup, M \== inf. is_drep(D1\/D2) :- is_drep(D1), is_drep(D2). is_drep({AI}) :- is_and_integers(AI). is_drep(\D) :- is_drep(D). is_and_integers(I) :- integer(I). is_and_integers((A,B)) :- is_and_integers(A), is_and_integers(B). drep_bound(I) :- integer(I). drep_bound(sup). drep_bound(inf). drep_to_intervals(I) --> { integer(I) }, [n(I)-n(I)]. drep_to_intervals(N..M) --> ( { defaulty_to_bound(N, N1), defaulty_to_bound(M, M1), N1 cis_leq M1} -> [N1-M1] ; [] ). drep_to_intervals(D1 \/ D2) --> drep_to_intervals(D1), drep_to_intervals(D2). drep_to_intervals(\D0) --> { drep_to_domain(D0, D1), domain_complement(D1, D), domain_to_drep(D, Drep) }, drep_to_intervals(Drep). drep_to_intervals({AI}) --> and_integers_(AI). and_integers_(I) --> { integer(I) }, [n(I)-n(I)]. and_integers_((A,B)) --> and_integers_(A), and_integers_(B). drep_to_domain(DR, D) :- must_be(ground, DR), ( is_drep(DR) -> true ; domain_error(clpz_domain, DR) ), phrase(drep_to_intervals(DR), Is0), merge_intervals(Is0, Is1), intervals_to_domain(Is1, D). merge_intervals(Is0, Is) :- keysort(Is0, Is1), merge_overlapping(Is1, Is). merge_overlapping([], []). merge_overlapping([A-B0|ABs0], [A-B|ABs]) :- merge_remaining(ABs0, B0, B, Rest), merge_overlapping(Rest, ABs). merge_remaining([], B, B, []). merge_remaining([N-M|NMs], B0, B, Rest) :- Next cis B0 + n(1), ( N cis_gt Next -> B = B0, Rest = [N-M|NMs] ; B1 cis max(B0,M), merge_remaining(NMs, B1, B, Rest) ). domain(V, Dom) :- ( fd_get(V, Dom0, VPs) -> domains_intersection(Dom, Dom0, Dom1), %format("intersected\n: ~w\n ~w\n==> ~w\n\n", [Dom,Dom0,Dom1]), fd_put(V, Dom1, VPs), reinforce(V) ; domain_contains(Dom, V) ). domains([], _). domains([V|Vs], D) :- domain(V, D), domains(Vs, D). props_number(fd_props(Gs,Bs,Os), N) :- length(Gs, N1), length(Bs, N2), length(Os, N3), N is N1 + N2 + N3. fd_get(X, Dom, Ps) :- ( get_attr(X, clpz, Attr) -> Attr = clpz_attr(_,_,_,Dom,Ps,_) ; var(X) -> default_domain(Dom), Ps = fd_props([],[],[]) ). fd_get(X, Dom, Inf, Sup, Ps) :- fd_get(X, Dom, Ps), domain_infimum(Dom, Inf), domain_supremum(Dom, Sup). /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Constraint propagation always terminates. Currently, this is ensured by allowing the left and right boundaries, as well as the distance between the smallest and largest number occurring in the domain representation to be changed at most once after a constraint is posted, unless the domain is bounded. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ fd_put(X, Dom, Ps) --> put_terminating(X, Dom, Ps). fd_put(X, Dom, Ps) :- new_queue(Q), phrase((put_terminating(X, Dom, Ps), % { portray_clause(done_terminating) }, do_queue), [Q], _). put_terminating(X, Dom, Ps) --> Dom \== empty, ( Dom = from_to(F, F) -> queue_goal(F = n(X)) ; ( { get_attr(X, clpz, Attr) } -> { Attr = clpz_attr(Left,Right,Spread,OldDom, _OldPs,Q), put_attr(X, clpz, clpz_attr(Left,Right,Spread,Dom,Ps,Q)) }, ( { OldDom == Dom } -> [] ; { ( Left == (.) -> Bounded = yes ; domain_infimum(Dom, Inf), domain_supremum(Dom, Sup), ( Inf = n(_), Sup = n(_) -> Bounded = yes ; Bounded = no ) ) }, ( { Bounded == yes } -> { put_attr(X, clpz, clpz_attr(.,.,.,Dom,Ps,Q)) }, trigger_props(Ps, X, OldDom, Dom) ; % infinite domain; consider border and spread changes { domain_infimum(OldDom, OldInf), ( Inf == OldInf -> LeftP = Left ; LeftP = yes ), domain_supremum(OldDom, OldSup), ( Sup == OldSup -> RightP = Right ; RightP = yes ), domain_spread(OldDom, OldSpread), domain_spread(Dom, NewSpread), ( NewSpread == OldSpread -> SpreadP = Spread ; NewSpread cis_lt OldSpread -> SpreadP = no ; SpreadP = yes ), put_attr(X, clpz, clpz_attr(LeftP,RightP,SpreadP,Dom,Ps,Q)) }, ( { RightP == yes, Right = yes } -> [] ; { LeftP == yes, Left = yes } -> [] ; { SpreadP == yes, Spread = yes } -> [] ; trigger_props(Ps, X, OldDom, Dom) ) ) ) ; { var(X) } -> { new_queue(Q), put_attr(X, clpz, clpz_attr(no,no,no,Dom,Ps,Q)) } ; [] ) ). new_queue(queue(_Goals,_Fast,_Slow,_Aux)). queue_goal(Goal) --> insert_queue(Goal, 1). queue_fast(Prop) --> insert_queue(Prop, 2). queue_slow(Prop) --> insert_queue(Prop, 3). insert_queue(Element, Which) --> state(Queue), { arg(Which, Queue, Arg), ( get_atts(Arg, queue(Head0,Tail0)) -> Head = Head0, Tail0 = [Element|Tail] ; Head = [Element|Tail] ), put_atts(Arg, queue(Head,Tail)) }. domain_spread(Dom, Spread) :- domain_smallest_finite(Dom, S), domain_largest_finite(Dom, L), Spread cis L - S. smallest_finite(inf, Y, Y). smallest_finite(n(N), _, n(N)). domain_smallest_finite(from_to(F,T), S) :- smallest_finite(F, T, S). domain_smallest_finite(split(_, L, _), S) :- domain_smallest_finite(L, S). largest_finite(sup, Y, Y). largest_finite(n(N), _, n(N)). domain_largest_finite(from_to(F,T), L) :- largest_finite(T, F, L). domain_largest_finite(split(_, _, R), L) :- domain_largest_finite(R, L). /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - All relevant constraints get a propagation opportunity whenever a new constraint is posted. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ reinforce(X) :- term_variables(X, Vs), maplist(reinforce_, Vs). reinforce_(X) :- ( fd_var(X), fd_get(X, Dom, Ps) -> put_full(X, Dom, Ps) ; true ). put_full(X, Dom, Ps) :- Dom \== empty, ( Dom = from_to(F, F) -> F = n(X) ; ( get_attr(X, clpz, Attr) -> Attr = clpz_attr(_,_,_,OldDom, _OldPs,Q), put_attr(X, clpz, clpz_attr(no,no,no,Dom,Ps,Q)), %format("putting dom: ~w\n", [Dom]), ( OldDom == Dom -> true ; new_queue(Q), % TODO: queue? phrase((trigger_props(Ps, X, OldDom, Dom), do_queue), [Q], _) ) ; var(X) -> %format('\t~w in ~w .. ~w\n',[X,L,U]), new_queue(Q), put_attr(X, clpz, clpz_attr(no,no,no,Dom,Ps,Q)) ; true ) ). /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - A propagator is a term of the form propagator(C, State), where C represents a constraint, and State is a free variable that can be used to destructively change the state of the propagator via attributes. This can be used to avoid redundant invocation of the same propagator, or to disable the propagator. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ make_propagator(C, propagator(C, _)). propagator_state(propagator(_,S), S). trigger_props(fd_props(Gs,Bs,Os), X, D0, D) --> ( { ground(X) } -> trigger_props_(Gs), trigger_props_(Bs) ; Bs \== [] -> { domain_infimum(D0, I0), domain_infimum(D, I) }, ( { I == I0 } -> { domain_supremum(D0, S0), domain_supremum(D, S) }, ( { S == S0 } -> [] ; trigger_props_(Bs) ) ; trigger_props_(Bs) ) ; [] ), trigger_props_(Os). trigger_props(fd_props(Gs,Bs,Os), X) --> trigger_props_(Os), trigger_props_(Bs), ( { ground(X) } -> trigger_props_(Gs) ; [] ). trigger_props(fd_props(Gs,Bs,Os)) --> trigger_props_(Gs), trigger_props_(Bs), trigger_props_(Os). trigger_props_([]) --> []. trigger_props_([P|Ps]) --> trigger_prop(P), trigger_props_(Ps). trigger_prop(P) :- trigger_once(P). trigger_prop(Propagator) --> { propagator_state(Propagator, State) }, ( { State == dead } -> [] ; { get_attr(State, clpz_aux, queued) } -> [] ; { bb_get('$clpz_current_propagator', C), C == State } -> [] ; % passive %{ format("triggering: ~w\n", [Propagator]) }, { put_attr(State, clpz_aux, queued) }, ( { arg(1, Propagator, C), functor(C, F, _), global_constraint(F) } -> queue_slow(Propagator) ; queue_fast(Propagator) ) ). all_propagators(fd_props(Gs,Bs,Os)) --> propagators_(Gs), propagators_(Bs), propagators_(Os). propagators_([]) --> []. propagators_([P|Ps]) --> propagator_(P), propagators_(Ps). propagator_(Propagator) --> { propagator_state(Propagator, State) }, ( { State == dead } -> [] ; { get_attr(State, clpz_aux, queued) } -> [] ; % passive % format("triggering: ~w\n", [Propagator]), [clpz:trigger_prop(Propagator)] ). % DCG variants kill(State) --> { kill(State) }. kill(State, Ps) --> { kill(State, Ps) }. T =.. Ls --> { T =.. Ls }. A = A --> []. A == B --> { A == B }. A \== B --> { A \== B }. integer(I) --> { integer(I) }. nonvar(X) --> { nonvar(X) }. var(V) --> { var(V) }. ground(T) --> { ground(T) }. true --> []. false --> { false }. X >= Y --> { X >= Y }. X =< Y --> { X =< Y }. X =:= Y --> { X =:= Y }. X =\= Y --> { X =\= Y }. X is E --> { X is E }. X > Y --> { X > Y }. X < Y --> { X < Y }. /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Duo DCG variants - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ A = B ++> { A = B }. A < B ++> { A < B }. A is B ++> { A is B }. kill(State) :- del_attr(State, clpz_aux), State = dead. kill(State, Ps) :- kill(State), maplist(kill_entailed, Ps). kill_entailed(p(Prop)) :- propagator_state(Prop, State), kill(State). kill_entailed(a(V)) :- del_attr(V, clpz). kill_entailed(a(X,B)) :- ( X == B -> true ; del_attr(B, clpz) ). kill_entailed(a(X,Y,B)) :- ( X == B -> true ; Y == B -> true ; del_attr(B, clpz) ). no_reactivation(rel_tuple(_,_)). no_reactivation(pdistinct(_)). no_reactivation(pnvalue(_)). no_reactivation(pgcc(_,_,_)). no_reactivation(pgcc_single(_,_)). %no_reactivation(scalar_product(_,_,_,_)). activate_propagator(propagator(P,State)) --> % { portray_clause(running(P)) }, ( State == dead -> [] ; { del_attr(State, clpz_aux) }, ( { no_reactivation(P) } -> { bb_b_put('$clpz_current_propagator', State) }, run_propagator(P, State), { bb_b_put('$clpz_current_propagator', []) } ; run_propagator(P, State) ) ). %do_queue --> print_queue, false. do_queue --> ( queue_enabled -> ( queue_get_goal(Goal) -> { call(Goal) }, do_queue ; queue_get_fast(Fast) -> activate_propagator(Fast), do_queue ; queue_get_slow(Slow) -> activate_propagator(Slow), do_queue ; true ) ; true ). :- meta_predicate(ignore(0)). ignore(Goal) :- ( Goal -> true ; true ). print_queue --> state(queue(Goal,Fast,Slow,_)), { ignore(get_atts(Goal, queue(GHs,_))), ignore(get_atts(Fast, queue(FHs,_))), ignore(get_atts(Slow, queue(SHs,_))), format("Current queue:~n goal: ~q~n fast: ~q~n slow: ~q~n~n", [GHs,FHs,SHs]) }. queue_get_goal(Goal) --> queue_get_arg(1, Goal). queue_get_fast(Fast) --> queue_get_arg(2, Fast). queue_get_slow(Slow) --> queue_get_arg(3, Slow). queue_get_arg(Which, Element) --> state(Queue), { queue_get_arg_(Queue, Which, Element) }. queue_get_arg_(Queue, Which, Element) :- arg(Which, Queue, Arg), get_atts(Arg, queue([Element|Elements],Tail)), ( var(Elements) -> put_atts(Arg, -queue(_,_)) ; put_atts(Arg, queue(Elements,Tail)) ). queue_enabled --> state(queue(_,_,_,Aux)), { \+ get_atts(Aux, disabled) }. disable_queue --> state(queue(_,_,_,Aux)), { put_atts(Aux, disabled) }. enable_queue --> state(queue(_,_,_,Aux)), { put_atts(Aux, -disabled) }. portray_propagator(propagator(P,_), F) :- functor(P, F, _). init_propagator_([], _) --> []. init_propagator_([V|Vs], Prop) --> ( { fd_get(V, Dom, Ps0) } -> { insert_propagator(Prop, Ps0, Ps) }, fd_put(V, Dom, Ps) ; [] ), init_propagator_(Vs, Prop). init_propagator(Var, Prop) :- ( fd_get(Var, Dom, Ps0) -> insert_propagator(Prop, Ps0, Ps), fd_put(Var, Dom, Ps) ; true ). constraint_wake(pneq, ground). constraint_wake(x_neq_y_plus_z, ground). constraint_wake(absdiff_neq, ground). constraint_wake(pdifferent, ground). constraint_wake(pexclude, ground). constraint_wake(scalar_product_neq, ground). constraint_wake(x_eq_abs_plus_v, ground). constraint_wake(x_leq_y_plus_c, bounds). constraint_wake(scalar_product_eq, bounds). constraint_wake(scalar_product_leq, bounds). constraint_wake(pplus, bounds). constraint_wake(pgeq, bounds). constraint_wake(pgcc_single, bounds). constraint_wake(pgcc_check_single, bounds). global_constraint(pdistinct). global_constraint(pnvalue). global_constraint(pgcc). global_constraint(pgcc_single). global_constraint(pcircuit). %global_constraint(rel_tuple). %global_constraint(scalar_product_eq). insert_propagator(Prop, Ps0, Ps) :- Ps0 = fd_props(Gs,Bs,Os), arg(1, Prop, Constraint), functor(Constraint, F, _), ( constraint_wake(F, ground) -> Ps = fd_props([Prop|Gs], Bs, Os) ; constraint_wake(F, bounds) -> Ps = fd_props(Gs, [Prop|Bs], Os) ; Ps = fd_props(Gs, Bs, [Prop|Os]) ). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% lex_chain(+Lists) % % Lists are lexicographically non-decreasing. lex_chain(Lss) :- must_be(list(list), lex_chain(Lss)-1, Lss), maplist(maplist(fd_variable), Lss), ( Lss == [] -> true ; Lss = [First|Rest], make_propagator(presidual(lex_chain(Lss)), Prop), foldl(lex_chain_(Prop), Rest, First, _) ). lex_chain_(Prop, Ls, Prev, Ls) :- maplist(prop_init(Prop), Ls), lex_le(Prev, Ls). lex_le([], []). lex_le([V1|V1s], [V2|V2s]) :- #V1 #=< #V2, ( integer(V1) -> ( integer(V2) -> ( V1 =:= V2 -> lex_le(V1s, V2s) ; true ) ; freeze(V2, lex_le([V1|V1s], [V2|V2s])) ) ; freeze(V1, lex_le([V1|V1s], [V2|V2s])) ). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% tuples_in(+Tuples, +Relation). % % True iff all Tuples are elements of Relation. Each element of the % list Tuples is a list of integers or finite domain variables. % Relation is a list of lists of integers. Arbitrary finite relations, % such as compatibility tables, can be modeled in this way. For % example, if 1 is compatible with 2 and 5, and 4 is compatible with 0 % and 3: % % ``` % ?- tuples_in([[X,Y]], [[1,2],[1,5],[4,0],[4,3]]), X = 4. % X = 4, % Y in 0\/3. % ``` % % As another example, consider a train schedule represented as a list % of quadruples, denoting departure and arrival places and times for % each train. In the following program, Ps is a feasible journey of % length 3 from A to D via trains that are part of the given schedule. % % ``` % trains([[1,2,0,1], % [2,3,4,5], % [2,3,0,1], % [3,4,5,6], % [3,4,2,3], % [3,4,8,9]]). % % threepath(A, D, Ps) :- % Ps = [[A,B,_T0,T1],[B,C,T2,T3],[C,D,T4,_T5]], % T2 #> T1, % T4 #> T3, % trains(Ts), % tuples_in(Ps, Ts). % ``` % % In this example, the unique solution is found without labeling: % % ``` % ?- threepath(1, 4, Ps). % Ps = [[1, 2, 0, 1], [2, 3, 4, 5], [3, 4, 8, 9]]. % ``` tuples_in(Tuples, Relation) :- must_be(list(list), Tuples), maplist(maplist(fd_variable), Tuples), must_be(list(list(integer)), Relation), new_queue(Q0), phrase(tuples_relation(Tuples, Relation), [Q0], [Q]), append(Tuples, Vs), variables_same_queue(Vs), phrase(do_queue, [Q], _). tuples_relation([], _) --> []. tuples_relation([Tuple|Tuples], Relation) --> { relation_unifiable(Relation, Tuple, Us, _, _) }, ( ground(Tuple) -> { memberchk(Tuple, Relation) } ; tuple_domain(Tuple, Us), ( Tuple = [_,_|_] -> tuple_freeze(Tuple, Us) ; [] ) ), tuples_relation(Tuples, Relation). list_first_rest([L|Ls], L, Ls). tuple_domain([], _) --> []. tuple_domain([T|Ts], Relation0) --> { maplist(list_first_rest, Relation0, Firsts, Relation1) }, ( Firsts = [Unique] -> T = Unique ; ( var(T) -> { list_to_domain(Firsts, FDom), fd_get(T, TDom, TPs), domains_intersection(TDom, FDom, TDom1) }, fd_put(T, TDom1, TPs) ; [] ) ), tuple_domain(Ts, Relation1). tuple_freeze(Tuple, Relation) --> ( ground(Tuple) -> { memberchk(Tuple, Relation) } ; { put_attr(R, clpz_relation, Relation), make_propagator(rel_tuple(R, Tuple), Prop) }, tuple_freeze_(Tuple, Prop) ). tuple_freeze_([], _) --> []. tuple_freeze_([T|Ts], Prop) --> ( var(T) -> init_propagator_([T], Prop), trigger_prop(Prop) ; [] ), tuple_freeze_(Ts, Prop). relation_unifiable([], _, [], Changed, Changed). relation_unifiable([R|Rs], Tuple, Us, Changed0, Changed) :- ( all_in_domain(R, Tuple) -> Us = [R|Rest], relation_unifiable(Rs, Tuple, Rest, Changed0, Changed) ; relation_unifiable(Rs, Tuple, Us, true, Changed) ). all_in_domain([], []). all_in_domain([A|As], [T|Ts]) :- ( fd_get(T, Dom, _) -> domain_contains(Dom, A) ; T =:= A ), all_in_domain(As, Ts). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %run_propagator(P, _) --> { portray_clause(run_propagator(P)), false }. % trivial propagator, used only to remember pending constraints run_propagator(presidual(_), _) --> []. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% run_propagator(pdifferent(Left,Right,X,_), MState) --> run_propagator(pexclude(Left,Right,X), MState). run_propagator(pexclude(Left,Right,X), _) --> ( ground(X) -> disable_queue, exclude_fire(Left, Right, X), enable_queue ; true ). run_propagator(pdistinct(Ls), _MState) --> distinct(Ls). run_propagator(pnvalue(N, Vars), _MState) --> { propagate_nvalue(N, Vars) }. run_propagator(check_distinct(Left,Right,X), _) --> { \+ list_contains(Left, X), \+ list_contains(Right, X) }. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% run_propagator(pelement(N, Is, V), MState) --> ( { fd_get(N, NDom, _) } -> ( { fd_get(V, VDom, VPs) } -> { integers_remaining(Is, 1, NDom, empty, VDom1), domains_intersection(VDom, VDom1, VDom2) }, fd_put(V, VDom2, VPs) ; [] ) ; { kill(MState), nth1(N, Is, V) } ). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% run_propagator(pgcc_single(Vs, Pairs), _) --> gcc_global(Vs, Pairs). run_propagator(pgcc_check_single(Pairs), _) --> gcc_check(Pairs). run_propagator(pgcc_check(Pairs), _) --> gcc_check(Pairs). run_propagator(pgcc(Vs, _, Pairs), _) --> gcc_global(Vs, Pairs). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% run_propagator(pcircuit(Vs), _MState) --> distinct(Vs), { propagate_circuit(Vs) }. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% run_propagator(pgeq(A,B), MState) --> ( A == B -> kill(MState) ; nonvar(A) -> ( nonvar(B) -> kill(MState), A >= B ; { fd_get(B, BD, BPs), domain_remove_greater_than(BD, A, BD1) }, kill(MState), fd_put(B, BD1, BPs) ) ; nonvar(B) -> { fd_get(A, AD, APs), domain_remove_smaller_than(AD, B, AD1) }, kill(MState), fd_put(A, AD1, APs) ; { fd_get(A, AD, AL, AU, APs), fd_get(B, _, BL, BU, _), AU cis_geq BL }, ( { AL cis_geq BU } -> kill(MState) ; AU == BL -> kill(MState), A = B ; { NAL cis max(AL,BL), domains_intersection(AD, from_to(NAL,AU), NAD) }, fd_put(A, NAD, APs), ( { fd_get(B, BD2, BL2, BU2, BPs2) } -> { NBU cis min(BU2, AU), domains_intersection(BD2, from_to(BL2,NBU), NBD) }, fd_put(B, NBD, BPs2) ; [] ) ) ). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% run_propagator(rel_tuple(R, Tuple), MState) --> { get_attr(R, clpz_relation, Relation) }, ( { ground(Tuple) } -> kill(MState), { del_attr(R, clpz_relation), memberchk(Tuple, Relation) } ; { relation_unifiable(Relation, Tuple, Us, false, Changed), Us = [_|_] }, ( { Tuple = [First,Second], ( ground(First) ; ground(Second) ) } -> kill(MState) ; [] ), ( { Us = [Single] } -> kill(MState), { del_attr(R, clpz_relation) }, Single = Tuple ; { Changed } -> { put_attr(R, clpz_relation, Us) }, disable_queue, tuple_domain(Tuple, Us), enable_queue ; [] ) ). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% run_propagator(pserialized(S_I, D_I, S_J, D_J, _), MState) --> ( nonvar(S_I), nonvar(S_J) -> kill(MState), ( S_I + D_I =< S_J -> [] ; S_J + D_J =< S_I -> [] ; false ) ; serialize_lower_upper(S_I, D_I, S_J, D_J, MState), serialize_lower_upper(S_J, D_J, S_I, D_I, MState) ). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % X #\= Y run_propagator(pneq(A, B), MState) --> ( nonvar(A) -> ( nonvar(B) -> A =\= B, kill(MState) ; { fd_get(B, BD0, BExp0), domain_remove(BD0, A, BD1), kill(MState) }, fd_put(B, BD1, BExp0) ) ; nonvar(B) -> run_propagator(pneq(B, A), MState) ; A \== B, { fd_get(A, _, AI, AS, _), fd_get(B, _, BI, BS, _) }, ( { AS cis_lt BI } -> kill(MState) ; { AI cis_gt BS } -> kill(MState) ; [] ) ). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Y = abs(X) run_propagator(pabs(X,Y), MState) --> ( nonvar(X) -> kill(MState), Y is abs(X) ; nonvar(Y) -> kill(MState), Y >= 0, YN is -Y, { X in YN \/ Y } ; X == Y -> kill(MState) ; { fd_get(X, XD, XPs), fd_get(Y, YD, _), domain_negate(YD, YDNegative), domains_union(YD, YDNegative, XD1), domains_intersection(XD, XD1, XD2) }, fd_put(X, XD2, XPs), ( { fd_get(Y, YD1, YPs1) } -> { domain_negate(XD2, XD2Neg), domains_union(XD2, XD2Neg, YD2), domain_remove_smaller_than(YD2, 0, YD3), domains_intersection(YD1, YD3, YD4) }, fd_put(Y, YD4, YPs1) ; [] ) ). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % abs(X-Y) #\= C run_propagator(absdiff_neq(X,Y,C), MState) --> ( C < 0 -> kill(MState) ; nonvar(X) -> kill(MState), ( nonvar(Y) -> abs(X - Y) =\= C ; V1 is X - C, neq_num(Y, V1), V2 is C + X, neq_num(Y, V2) ) ; nonvar(Y) -> kill(MState), V1 is C + Y, neq_num(X, V1), V2 is Y - C, neq_num(X, V2) ; [] ). % X #= abs(X) + V run_propagator(x_eq_abs_plus_v(X,V), MState) --> ( nonvar(V) -> ( V =:= 0 -> kill(MState), { X in 0..sup } ; V < 0 -> kill(MState), { X #= V / 2 } ; false % V > 0 ) ; nonvar(X) -> kill(MState), { V #= X - abs(X) } ; true ). % X #\= Y + Z run_propagator(x_neq_y_plus_z(X,Y,Z), MState) --> ( nonvar(X) -> ( nonvar(Y) -> ( nonvar(Z) -> kill(MState), X =\= Y + Z ; kill(MState), XY is X - Y, neq_num(Z, XY) ) ; nonvar(Z) -> kill(MState), XZ is X - Z, neq_num(Y, XZ) ; [] ) ; nonvar(Y) -> ( nonvar(Z) -> kill(MState), YZ is Y + Z, neq_num(X, YZ) ; Y =:= 0 -> kill(MState), { neq(X, Z) } ; [] ) ; Z == 0 -> kill(MState), { neq(X, Y) } ; true ). % X #=< Y + C run_propagator(x_leq_y_plus_c(X,Y,C), MState) --> ( nonvar(X) -> ( nonvar(Y) -> kill(MState), X =< Y + C ; kill(MState), R is X - C, { fd_get(Y, YD, YPs), domain_remove_smaller_than(YD, R, YD1) }, fd_put(Y, YD1, YPs) ) ; nonvar(Y) -> kill(MState), R is Y + C, { fd_get(X, XD, XPs), domain_remove_greater_than(XD, R, XD1) }, fd_put(X, XD1, XPs) ; ( X == Y -> C >= 0, kill(MState) ; { fd_get(Y, YD, _) }, ( { domain_supremum(YD, n(YSup)) } -> YS1 is YSup + C, { fd_get(X, XD, XPs), domain_remove_greater_than(XD, YS1, XD1) }, fd_put(X, XD1, XPs) ; [] ), ( { fd_get(X, XD2, _), domain_infimum(XD2, n(XInf)) } -> XI1 is XInf - C, ( { fd_get(Y, YD1, YPs1) } -> { domain_remove_smaller_than(YD1, XI1, YD2), ( domain_infimum(YD2, n(YInf)), domain_supremum(XD2, n(XSup)), XSup =< YInf + C -> kill(MState) ; true ) }, fd_put(Y, YD2, YPs1) ; [] ) ; [] ) ) ). run_propagator(scalar_product_neq(Cs0,Vs0,P0), MState) --> { coeffs_variables_const(Cs0, Vs0, Cs, Vs, 0, I), P is P0 - I, ( Vs = [] -> kill(MState), P =\= 0 ; Vs = [V], Cs = [C] -> kill(MState), ( C =:= 1 -> neq_num(V, P) ; C*V #\= P ) ; Cs == [1,-1] -> kill(MState), Vs = [A,B], x_neq_y_plus_z(A, B, P) ; Cs == [-1,1] -> kill(MState), Vs = [A,B], x_neq_y_plus_z(B, A, P) ; P =:= 0, Cs = [1,1,-1] -> kill(MState), Vs = [A,B,C], x_neq_y_plus_z(C, A, B) ; P =:= 0, Cs = [1,-1,1] -> kill(MState), Vs = [A,B,C], x_neq_y_plus_z(B, A, C) ; P =:= 0, Cs = [-1,1,1] -> kill(MState), Vs = [A,B,C], x_neq_y_plus_z(A, B, C) ; true ) }. run_propagator(scalar_product_leq(Cs0,Vs0,P0), MState) --> { coeffs_variables_const(Cs0, Vs0, Cs, Vs, 0, I) }, P is P0 - I, ( Vs = [] -> kill(MState), P >= 0 ; { duophrase(sum_finite_domains(Cs, Vs, 0, 0, Inf, Sup), Infs, Sups) }, D1 is P - Inf, disable_queue, ( Infs == [], Sups == [] -> Inf =< P, ( Sup =< P -> kill(MState) ; remove_dist_upper_leq(Cs, Vs, D1) ) ; Infs == [] -> Inf =< P, remove_dist_upper(Sups, D1) ; Infs = [_] -> remove_upper(Infs, D1) ; true ), enable_queue ). run_propagator(scalar_product_eq(Cs0,Vs0,P0), MState) --> { coeffs_variables_const(Cs0, Vs0, Cs, Vs, 0, I) }, P is P0 - I, ( Vs = [] -> kill(MState), P =:= 0 ; Vs = [V], Cs = [C] -> kill(MState), P mod C =:= 0, V is P // C ; Cs == [1,1] -> kill(MState), Vs = [A,B], { A + B #= P } ; Cs == [1,-1] -> kill(MState), Vs = [A,B], { A #= P + B } ; Cs == [-1,1] -> kill(MState), Vs = [A,B], { B #= P + A } ; Cs == [-1,-1] -> kill(MState), Vs = [A,B], P1 is -P, { A + B #= P1 } ; P =:= 0, Cs == [1,1,-1] -> kill(MState), Vs = [A,B,C], { A + B #= C } ; P =:= 0, Cs == [1,-1,1] -> kill(MState), Vs = [A,B,C], { A + C #= B } ; P =:= 0, Cs == [-1,1,1] -> kill(MState), Vs = [A,B,C], { B + C #= A } ; { duophrase(sum_finite_domains(Cs, Vs, 0, 0, Inf, Sup), Infs, Sups) }, % { nl, writeln(Infs-Sups-Inf-Sup) }, D1 is P - Inf, D2 is Sup - P, disable_queue, ( Infs == [], Sups == [] -> { between(Inf, Sup, P) }, remove_dist_upper_lower(Cs, Vs, D1, D2) ; Sups = [] -> P =< Sup, remove_dist_lower(Infs, D2) ; Infs = [] -> Inf =< P, remove_dist_upper(Sups, D1) ; Sups = [_], Infs = [_] -> remove_lower(Sups, D2), remove_upper(Infs, D1) ; Infs = [_] -> remove_upper(Infs, D1) ; Sups = [_] -> remove_lower(Sups, D2) ; true ), enable_queue ). % X + Y = Z run_propagator(pplus(X,Y,Z,Morph), MState) --> ( nonvar(X) -> ( X =:= 0 -> kill(MState), Y = Z ; Y == Z -> kill(MState), X =:= 0 ; nonvar(Y) -> kill(MState), Z is X + Y ; nonvar(Z) -> kill(MState), Y is Z - X ; { fd_get(Z, ZD, ZPs), fd_get(Y, YD, _), domain_shift(YD, X, Shifted_YD), domains_intersection(ZD, Shifted_YD, ZD1) }, fd_put(Z, ZD1, ZPs), ( { fd_get(Y, YD1, YPs) } -> O is -X, { domain_shift(ZD1, O, YD2), domains_intersection(YD1, YD2, YD3) }, fd_put(Y, YD3, YPs) ; [] ) ) ; nonvar(Y) -> run_propagator(pplus(Y,X,Z,Morph), MState) ; nonvar(Z) -> ( X == Y -> kill(MState), { even(Z), X is Z // 2 } ; { fd_get(X, XD, _), fd_get(Y, YD, YPs), domain_negate(XD, XDN), domain_shift(XDN, Z, YD1), domains_intersection(YD, YD1, YD2) }, fd_put(Y, YD2, YPs), ( { fd_get(X, XD1, XPs) } -> { domain_negate(YD2, YD2N), domain_shift(YD2N, Z, XD2), domains_intersection(XD1, XD2, XD3) }, fd_put(X, XD3, XPs) ; [] ) ) ; ( X == Y -> morph_into_propagator(MState, [X,Z], ptimes(2,X,Z), Morph) ; X == Z -> kill(MState), Y = 0 ; Y == Z -> kill(MState), X = 0 ; { fd_get(X, XD, XL, XU, XPs), fd_get(Y, _, YL, YU, _), fd_get(Z, _, ZL, ZU, _), NXL cis max(XL, ZL-YU), NXU cis min(XU, ZU-YL) }, update_bounds(X, XD, XPs, XL, XU, NXL, NXU), ( { fd_get(Y, YD2, YL2, YU2, YPs2) } -> { NYL cis max(YL2, ZL-NXU), NYU cis min(YU2, ZU-NXL) }, update_bounds(Y, YD2, YPs2, YL2, YU2, NYL, NYU) ; NYL = n(Y), NYU = n(Y) ), ( { fd_get(Z, ZD2, ZL2, ZU2, ZPs2) } -> { NZL cis max(ZL2,NXL+NYL), NZU cis min(ZU2,NXU+NYU) }, update_bounds(Z, ZD2, ZPs2, ZL2, ZU2, NZL, NZU) ; [] ) ) ). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% run_propagator(ptimes(X,Y,Z,Morph), MState) --> ( nonvar(X) -> ( nonvar(Y) -> kill(MState), Z is X * Y ; X =:= 0 -> kill(MState), Z = 0 ; X =:= 1 -> kill(MState), Z = Y ; nonvar(Z) -> kill(MState), 0 =:= Z mod X, Y is Z // X ; ( Y == Z -> kill(MState), Y = 0 ; { fd_get(Y, YD, _), fd_get(Z, ZD, ZPs), domain_expand(YD, X, Scaled_YD), domains_intersection(ZD, Scaled_YD, ZD1) }, fd_put(Z, ZD1, ZPs), ( { fd_get(Y, YDom2, YPs2) } -> { domain_contract(ZD1, X, Contract), domains_intersection(YDom2, Contract, NYDom) }, fd_put(Y, NYDom, YPs2) ; kill(MState), Z is X * Y ) ) ) ; nonvar(Y) -> run_propagator(ptimes(Y,X,Z,Morph), MState) ; nonvar(Z) -> ( X == Y -> kill(MState), { integer_kth_root(Z, 2, R), NR is -R, X in NR \/ R } ; { fd_get(X, XD, XL, XU, XPs), fd_get(Y, YD, YL, YU, _), min_max_factor(n(Z), n(Z), YL, YU, XL, XU, NXL, NXU) }, update_bounds(X, XD, XPs, XL, XU, NXL, NXU), ( { fd_get(Y, YD2, YL2, YU2, YPs2) } -> { min_max_factor(n(Z), n(Z), NXL, NXU, YL2, YU2, NYL, NYU) }, update_bounds(Y, YD2, YPs2, YL2, YU2, NYL, NYU) ; ( Y =\= 0 -> 0 =:= Z mod Y, kill(MState), X is Z // Y ; kill(MState), Z = 0 ) ), ( Z =:= 0 -> ( { \+ domain_contains(XD, 0) } -> kill(MState), Y = 0 ; { \+ domain_contains(YD, 0) } -> kill(MState), X = 0 ; [] ) ; neq_num(X, 0), neq_num(Y, 0) ) ) ; ( X == Y -> morph_into_propagator(MState, [X,Z], pexp(X,2,Z), Morph) ; { fd_get(X, XD, XL, XU, XPs), fd_get(Y, _, YL, YU, _), fd_get(Z, ZD, ZL, ZU, _) }, ( { Y == Z, \+ domain_contains(ZD, 0) } -> kill(MState), X = 1 ; { X == Z, \+ domain_contains(ZD, 0) } -> kill(MState), Y = 1 ; { min_max_factor(ZL, ZU, YL, YU, XL, XU, NXL, NXU) }, update_bounds(X, XD, XPs, XL, XU, NXL, NXU), ( { fd_get(Y, YD2, YL2, YU2, YPs2) } -> { min_max_factor(ZL, ZU, NXL, NXU, YL2, YU2, NYL, NYU) }, update_bounds(Y, YD2, YPs2, YL2, YU2, NYL, NYU) ; NYL = n(Y), NYU = n(Y) ), ( { fd_get(Z, ZD2, ZL2, ZU2, ZPs2) } -> { min_product(NXL, NXU, NYL, NYU, NZL), max_product(NXL, NXU, NYL, NYU, NZU) }, ( { NZL cis_leq ZL2, NZU cis_geq ZU2 } -> ZD3 = ZD2 ; { domains_intersection(ZD2, from_to(NZL,NZU), ZD3) }, fd_put(Z, ZD3, ZPs2) ), ( { domain_contains(ZD3, 0) } -> [] ; neq_num(X, 0), neq_num(Y, 0) ) ; [] ) ) ) ). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % X // Y = Z (round towards zero) run_propagator(ptzdiv(X,Y,Z,Morph), MState) --> ( nonvar(X) -> ( nonvar(Y) -> kill(MState), Y =\= 0, Z is X // Y ; { fd_get(Y, YD, YL, YU, YPs) }, ( nonvar(Z) -> ( Z =:= 0 -> NYL is -abs(X) - 1, NYU is abs(X) + 1, { domains_intersection(YD, split(0, from_to(inf,n(NYL)), from_to(n(NYU), sup)), NYD) }, fd_put(Y, NYD, YPs) ; ( sign(X) =:= sign(Z) -> { NYL cis max(n(X) // (n(Z)+sign(n(Z))) + n(1), YL), NYU cis min(n(X) // n(Z), YU) } ; { NYL cis max(n(X) // n(Z), YL), NYU cis min(n(X) // (n(Z)+sign(n(Z))) - n(1), YU) } ), update_bounds(Y, YD, YPs, YL, YU, NYL, NYU) ) ; { fd_get(Z, ZD, ZL, ZU, ZPs), ( X >= 0, ( YL cis_gt n(0) ; YU cis_lt n(0) )-> NZL cis max(n(X)//YU, ZL), NZU cis min(n(X)//YL, ZU) ; X < 0, ( YL cis_gt n(0) ; YU cis_lt n(0) ) -> NZL cis max(n(X)//YL, ZL), NZU cis min(n(X)//YU, ZU) ; % TODO: more stringent bounds, cover Y NZL cis max(-abs(n(X)), ZL), NZU cis min(abs(n(X)), ZU) ) }, update_bounds(Z, ZD, ZPs, ZL, ZU, NZL, NZU), ( { X >= 0, NZL cis_gt n(0), fd_get(Y, YD1, YPs1) } -> { NYL cis n(X) // (NZU + n(1)) + n(1), NYU cis n(X) // NZL, domains_intersection(YD1, from_to(NYL, NYU), NYD1) }, fd_put(Y, NYD1, YPs1) ; true ) ) ) ; nonvar(Y) -> Y =\= 0, ( Y =:= 1 -> kill(MState), X = Z ; Y =:= -1 -> morph_into_propagator(MState, [X,Z], pplus(X,Z,0), Morph) ; { fd_get(X, XD, XL, XU, XPs) }, ( nonvar(Z) -> kill(MState), ( sign(Z) =:= sign(Y) -> { NXL cis max(n(Z)*n(Y), XL), NXU cis min((abs(n(Z))+n(1))*abs(n(Y))-n(1), XU) } ; Z =:= 0 -> { NXL cis max(-abs(n(Y)) + n(1), XL), NXU cis min(abs(n(Y)) - n(1), XU) } ; { NXL cis max((n(Z)+sign(n(Z)))*n(Y)+n(1), XL), NXU cis min(n(Z)*n(Y), XU) } ), update_bounds(X, XD, XPs, XL, XU, NXL, NXU) ; { fd_get(Z, ZD, ZPs), domain_contract_less(XD, Y, Contracted), domains_intersection(ZD, Contracted, NZD) }, fd_put(Z, NZD, ZPs), ( { fd_get(X, XD2, XPs2) } -> { domain_expand_more(NZD, Y, Expanded), domains_intersection(XD2, Expanded, NXD2) }, fd_put(X, NXD2, XPs2) ; true ) ) ) ; nonvar(Z) -> { fd_get(X, XD, XL, XU, XPs), fd_get(Y, _, YL, YU, _), ( YL cis_geq n(0), XL cis_geq n(0) -> NXL cis max(YL*n(Z), XL), NXU cis min(YU*(n(Z)+n(1))-n(1), XU) ; %TODO: cover more cases NXL = XL, NXU = XU ) }, update_bounds(X, XD, XPs, XL, XU, NXL, NXU) ; ( X == Y -> kill(MState), Z = 1 ; { fd_get(X, _, XL, XU, _), fd_get(Y, _, YL, _, _), fd_get(Z, ZD, ZPs), NZU cis max(abs(XL), XU), NZL cis -NZU, domains_intersection(ZD, from_to(NZL,NZU), NZD0), ( XL cis_geq n(0), YL cis_geq n(0) -> domain_remove_smaller_than(NZD0, 0, NZD1) ; % TODO: cover more cases NZD1 = NZD0 ) }, fd_put(Z, NZD1, ZPs) ) ). %% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% % Z = X mod Y run_propagator(pmod(X,Y,Z), MState) --> ( Y == 0 -> false ; Y == Z -> false ; X == Y -> kill(MState), queue_goal(Z = 0) ; true ), ( nonvar(X), nonvar(Y) -> kill(MState), Z is X mod Y ; nonvar(Y), nonvar(Z) -> ( Y > 0 -> Z >= 0, Z < Y ; Z =< 0, Z > Y % Y < 0 ), ( { fd_get(X, _, n(XL), _, _) } -> ( (XL - Z) mod Y =\= 0 -> XMin is Z + Y * ((XL - Z) div Y + 1) ; XMin is XL ), { fd_get(X, XD0, XPs), domain_remove_smaller_than(XD0, XMin, XD2) }, fd_put(X, XD2, XPs) % queue_goal(X #>= XMin) ; true ), ( { fd_get(X, _, _, n(XU), _) } -> XMax is Z + Y * ((XU - Z) div Y), { fd_get(X, XD1, XPs), domain_remove_greater_than(XD1, XMax, XD3) }, fd_put(X, XD3, XPs) % queue_goal(X #=< XMax) ; true ) ; nonvar(Z), nonvar(X) -> ( Z > 0 -> ( X < 0 -> true ; X >= Z, % due to X = Z+Y*_ and Y > Z ( X-Z > 0 -> X-Z > Z ; true ) ) ; Z < 0 -> ( X > 0 -> true ; X =< Z, % due to X = Z+Y*_ and Y < Z ( X-Z < 0 -> X-Z < Z ; true ) ) ; Z =:= 0 % Multiple solutions so do nothing special. ), ( { fd_get(Y, _, _, n(YU), _), YU < X, X =< 0 } -> kill(MState), Z =:= X ; { fd_get(Y, _, n(YL), _, _), YL > X, X >= 0 } -> kill(MState), Z =:= X ; ( Z > 0, X < 0 -> { fd_get(Y, YD, YPs), YMin is Z+1, YMax is Z-X, domain_remove_smaller_than(YD, YMin, YD1), domain_remove_greater_than(YD1, YMax, YD2) }, fd_put(Y, YD2, YPs) % queue_goal((Y #> Z, Y #=< Z-X)) ; Z < 0, X > 0 -> { fd_get(Y, YD, YPs), YMax is Z-1, YMin is Z-X, domain_remove_greater_than(YD, YMax, YD1), domain_remove_smaller_than(YD1, YMin, YD2) }, fd_put(Y, YD2, YPs) % queue_goal((Y #< Z, Y #>= Z-X)) ; Z > 0 -> { fd_get(Y, YD, YPs), YMin is Z + 1, domain_remove_smaller_than(YD, YMin, YD1) }, fd_put(Y, YD1, YPs) % queue_goal(Y #> Z) ; Z < 0 -> { fd_get(Y, YD, YPs), YMax is Z - 1, domain_remove_greater_than(YD, YMax, YD1) }, fd_put(Y, YD1, YPs) % queue_goal(Y #< Z) ; Z =:= 0, ( X =:= 0 -> kill(MState) % trivial ; % only 4 solutions {-abs(X),-1,1,abs(X)} { YL is -abs(X), YU is abs(X), fd_get(Y, YD0, YPs), domain_remove_smaller_than(YD0, YL, YD1), domain_remove_greater_than(YD1, YU, YD) }, fd_put(Y, YD, YPs) ) ) ) ; run_propagator(pmodz(X,Y,Z), MState), run_propagator(pmody(X,Y,Z), MState), true ). run_propagator(pmodz(X,Y,Z), MState) --> ( nonvar(Z) -> true % Nothing to do. ; nonvar(X) -> ( X =:= 0 -> kill(MState), queue_goal(Z = X) ; ( X > 0 -> ( { fd_get(Y, _, n(YL), _, _), YL > X } -> kill(MState), queue_goal(Z = X) ; { fd_get(Z, ZD0, ZPs), domain_remove_greater_than(ZD0, X, ZD2) }, fd_put(Z, ZD2, ZPs) % queue_goal(Z #=< X) ) ; X < 0, ( { fd_get(Y, _, _, n(YU), _), YU < X } -> kill(MState), queue_goal(Z = X) ; { fd_get(Z, ZD0, ZPs), domain_remove_smaller_than(ZD0, X, ZD2) }, fd_put(Z, ZD2, ZPs) % queue_goal(Z #>= X) ) ), ( { fd_get(Y, _, n(YL), n(YU), _), YL > 0 } -> ZMax is YU - 1, { fd_get(Z, ZD1, ZPs), domain_remove_smaller_than(ZD1, 0, ZD3), domain_remove_greater_than(ZD3, ZMax, ZD5) }, fd_put(Z, ZD5, ZPs) % queue_goal(Z in 0..ZMax) ; { fd_get(Y, _, n(YL), n(YU), _), YU < 0 } -> ZMin is YL + 1, { fd_get(Z, ZD1, ZPs), domain_remove_greater_than(ZD1, 0, ZD3), domain_remove_smaller_than(ZD3, ZMin, ZD5) }, fd_put(Z, ZD5, ZPs) % queue_goal(Z in ZMin..0) ; true ) ) ; nonvar(Y) -> ( abs(Y) =:= 1 -> kill(MState), queue_goal(Z = 0) ; Y < 0 -> ( { fd_get(X, _, n(XL), n(XU), _), XU =< 0, Y < XL } -> kill(MState), queue_goal(Z = X) ; ZMin is Y + 1, { fd_get(Z, ZD1, ZPs), domain_remove_greater_than(ZD1, 0, ZD3), domain_remove_smaller_than(ZD3, ZMin, ZD5) }, fd_put(Z, ZD5, ZPs) % queue_goal(Z in ZMin..0) ) ; Y > 0, ( { fd_get(X, _, n(XL), n(XU), _), XL >= 0, Y > XU } -> kill(MState), queue_goal(Z = X) ; ZMax is Y - 1, { fd_get(Z, ZD1, ZPs), domain_remove_smaller_than(ZD1, 0, ZD3), domain_remove_greater_than(ZD3, ZMax, ZD5) }, fd_put(Z, ZD5, ZPs) % queue_goal(Z in 0..ZMax) ) ) ; ( { fd_get(X, _, n(XL), n(XU), _), XL >= 0, fd_get(Y, _, n(YL), _, _), XU < YL } -> kill(MState), queue_goal(Z = X) ; { fd_get(X, _, n(XL), n(XU), _), XU =< 0, fd_get(Y, _, _, n(YU), _), XL > YU } -> kill(MState), queue_goal(Z = X) ; ( { fd_get(X, _, n(XL), n(XU), _), XL >= 0 } -> { fd_get(Z, ZD0, ZPs), domain_remove_greater_than(ZD0, XU, ZD2) }, fd_put(Z, ZD2, ZPs) % queue_goal(Z #=< XU) ; { fd_get(X, _, n(XL), n(XU), _), XU =< 0 } -> { fd_get(Z, ZD0, ZPs), domain_remove_smaller_than(ZD0, XL, ZD2) }, fd_put(Z, ZD2, ZPs) % queue_goal(Z #>= XL) ; true ), ( { fd_get(Y, _, n(YL), n(YU), _), YL > 0 } -> ZMax is YU - 1, { fd_get(Z, ZD1, ZPs), domain_remove_smaller_than(ZD1, 0, ZD3), domain_remove_greater_than(ZD3, ZMax, ZD5) }, fd_put(Z, ZD5, ZPs) % queue_goal(Z in 0..ZMax) ; { fd_get(Y, _, n(YL), n(YU), _), YU < 0 } -> ZMin is YL + 1, { fd_get(Z, ZD1, ZPs), domain_remove_greater_than(ZD1, 0, ZD3), domain_remove_smaller_than(ZD3, ZMin, ZD5) }, fd_put(Z, ZD5, ZPs) % queue_goal(Z in ZMin..0) ; { fd_get(Y, _, n(YL), n(YU), _), YL < 0, YU > 0 } -> ZMin is YL + 1, ZMax is YU - 1, { fd_get(Z, ZD1, ZPs), domain_remove_greater_than(ZD1, ZMax, ZD3), domain_remove_smaller_than(ZD3, ZMin, ZD5) }, fd_put(Z, ZD5, ZPs) % queue_goal(Z in ZMin..ZMax) ; { fd_get(Y, _, _, n(YU), _), YU > 0 } -> { fd_get(Z, ZD1, ZPs), ZMax is YU - 1, domain_remove_greater_than(ZD1, ZMax, ZD3) }, fd_put(Z, ZD3, ZPs) % queue_goal(Z #< YU) ; { fd_get(Y, _, n(YL), _, _), YL < 0 } -> { fd_get(Z, ZD1, ZPs), ZMin is YL + 1, domain_remove_smaller_than(ZD1, ZMin, ZD3) }, fd_put(Z, ZD3, ZPs) % queue_goal(Z #> YL) ; true ) ) ). run_propagator(pmody(_X,Y,Z), _MState) --> ( nonvar(Y) -> true % Nothing to do. % ; nonvar(X) -> true ; nonvar(Z) -> ( Z > 0 -> { fd_get(Y, YD, YPs), YMin is Z + 1, domain_remove_smaller_than(YD, YMin, YD1) }, fd_put(Y, YD1, YPs) % queue_goal(Y #> Z) ; Z < 0 -> { fd_get(Y, YD, YPs), YMax is Z - 1, domain_remove_greater_than(YD, YMax, YD1) }, fd_put(Y, YD1, YPs) % queue_goal(Y #< Z) ; Z =:= 0 % Multiple solutions so do nothing special. ) ; ( { fd_get(Z, _, n(ZL), _, _), ZL > 0 } -> { fd_get(Y, YD, YPs), YMin is ZL + 1, domain_remove_smaller_than(YD, YMin, YD1) }, fd_put(Y, YD1, YPs) % queue_goal(Y #> ZL) ; { fd_get(Z, _, _, n(ZU), _), ZU < 0 } -> { fd_get(Y, YD, YPs), YMax is ZU - 1, domain_remove_greater_than(YD, YMax, YD1) }, fd_put(Y, YD1, YPs) % queue_goal(Y #< ZU) ; true ) ). %% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% % Z = X rem Y run_propagator(prem(X,Y,Z), MState) --> ( nonvar(X) -> ( nonvar(Y) -> kill(MState), Y =\= 0, Z is X rem Y ; U is abs(X), { fd_get(Y, YD, _) }, ( X >=0, { domain_infimum(YD, n(Min)), Min >= 0 } -> L = 0 ; L is -U ), { Z in L..U } ) ; nonvar(Y) -> Y =\= 0, ( abs(Y) =:= 1 -> kill(MState), Z = 0 ; var(Z) -> YP is abs(Y) - 1, YN is -YP, ( Y > 0, { fd_get(X, _, n(XL), n(XU), _) } -> ( abs(XL) < Y, XU < Y -> kill(MState), Z = X, ZL = XL ; XL < 0, abs(XL) < Y -> ZL = XL ; XL >= 0 -> ZL = 0 ; ZL = YN ), ( XU > 0, XU < Y -> ZU = XU ; XU < 0 -> ZU = 0 ; ZU = YP ) ; ZL = YN, ZU = YP ), ( { fd_get(Z, ZD, ZPs) } -> { domains_intersection(ZD, from_to(n(ZL), n(ZU)), ZD1) }, fd_put(Z, ZD1, ZPs) ; ZD1 = from_to(n(Z), n(Z)) ), ( { fd_get(X, XD, _), domain_infimum(XD, n(Min)) } -> Z1 is Min rem Y, ( { domain_contains(ZD1, Z1) } -> true ; neq_num(X, Min) ) ; true ), ( { fd_get(X, XD1, _), domain_supremum(XD1, n(Max)) } -> Z2 is Max rem Y, ( { domain_contains(ZD1, Z2) } -> true ; neq_num(X, Max) ) ; true ) ; { fd_get(X, XD1, XPs1) }, % if possible, propagate at the boundaries ( { domain_infimum(XD1, n(Min)) } -> ( Min rem Y =:= Z -> true ; Y > 0, Min > 0 -> Next is ((Min - Z + Y - 1) div Y)*Y + Z, { domain_remove_smaller_than(XD1, Next, XD2) }, fd_put(X, XD2, XPs1) ; % TODO: bigger steps in other cases as well neq_num(X, Min) ) ; true ), ( { fd_get(X, XD3, XPs3) } -> ( { domain_supremum(XD3, n(Max)) } -> ( Max rem Y =:= Z -> true ; Y > 0, Max > 0 -> Prev is ((Max - Z) div Y)*Y + Z, { domain_remove_greater_than(XD3, Prev, XD4) }, fd_put(X, XD4, XPs3) ; % TODO: bigger steps in other cases as well neq_num(X, Max) ) ; true ) ; true ) ) ; X == Y -> kill(MState), Z = 0 ; { fd_get(Z, ZD, ZPs) } -> { fd_get(Y, _, YInf, YSup, _), fd_get(X, _, XInf, XSup, _), M cis max(abs(YInf),YSup), ( XInf cis_geq n(0) -> Inf0 = n(0) ; Inf0 = XInf ), ( XSup cis_leq n(0) -> Sup0 = n(0) ; Sup0 = XSup ), NInf cis max(max(Inf0, -M + n(1)), min(XInf,-XSup)), NSup cis min(min(Sup0, M - n(1)), max(abs(XInf),XSup)), domains_intersection(ZD, from_to(NInf,NSup), ZD1) }, fd_put(Z, ZD1, ZPs) ; true % TODO: propagate more ). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Z = max(X,Y) run_propagator(pmax(X,Y,Z), MState) --> ( nonvar(X) -> ( nonvar(Y) -> kill(MState), queue_goal(Z is max(X,Y)) ; nonvar(Z) -> ( Z =:= X -> kill(MState), queue_goal(X #>= Y) ; Z > X -> queue_goal(Z = Y) ; false % Z < X ) ; Y == Z -> kill(MState), queue_goal(Y #>= X) ; { fd_get(Y, _, YInf, YSup, _) }, ( { YInf cis_gt n(X) } -> queue_goal(Z = Y) ; { YSup cis_lt n(X) } -> queue_goal(Z = X) ; YSup = n(M) -> { fd_get(Z, ZD, ZPs), domain_remove_greater_than(ZD, M, ZD1) }, fd_put(Z, ZD1, ZPs) ; [] ) ) ; nonvar(Y) -> run_propagator(pmax(Y,X,Z), MState) ; { fd_get(Z, ZD, ZPs) } -> { fd_get(X, _, XInf, XSup, _), fd_get(Y, _, YInf, YSup, _) }, ( { YInf cis_gt XSup } -> kill(MState), queue_goal(Z = Y) ; { YSup cis_lt XInf } -> kill(MState), queue_goal(Z = X) ; { n(M) cis max(XSup, YSup) } -> { domain_remove_greater_than(ZD, M, ZD1) }, fd_put(Z, ZD1, ZPs) ; [] ) ; [] ). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Z = min(X,Y) run_propagator(pmin(X,Y,Z), MState) --> ( nonvar(X) -> ( nonvar(Y) -> kill(MState), Z is min(X,Y) ; nonvar(Z) -> ( Z =:= X -> kill(MState), { X #=< Y } ; Z < X -> Z = Y ; false % Z > X ) ; Y == Z -> kill(MState), queue_goal(Y #=< X) ; { fd_get(Y, _, YInf, YSup, _) }, ( { YSup cis_lt n(X) } -> Z = Y ; { YInf cis_gt n(X) } -> Z = X ; YInf = n(M) -> { fd_get(Z, ZD, ZPs), domain_remove_smaller_than(ZD, M, ZD1) }, fd_put(Z, ZD1, ZPs) ; [] ) ) ; nonvar(Y) -> run_propagator(pmin(Y,X,Z), MState) ; { fd_get(Z, ZD, ZPs) } -> { fd_get(X, _, XInf, XSup, _), fd_get(Y, _, YInf, YSup, _) }, ( { YSup cis_lt XInf } -> kill(MState), Z = Y ; { YInf cis_gt XSup } -> kill(MState), Z = X ; { n(M) cis min(XInf, YInf) } -> { domain_remove_smaller_than(ZD, M, ZD1) }, fd_put(Z, ZD1, ZPs) ; [] ) ; [] ). %% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% % Z = X ^ Y run_propagator(pexp(X,Y,Z,Morph), MState) --> ( X == 1 -> kill(MState), Z = 1 ; X == 0 -> queue_goal((Z in 0..1, Y #>= 0)), morph_into_propagator(MState, [Y,Z], reified_eq(1,Y,1,0,[],Z), Morph) ; Y == 0 -> kill(MState), Z = 1 ; Y == 1 -> kill(MState), Z = X ; Y == Z -> kill(MState), X = Y, queue_goal(X in -1\/1) ; nonvar(X) -> ( nonvar(Y) -> ( Y >= 0 -> true ; X =:= -1 ), kill(MState), Z is X^Y ; nonvar(Z) -> ( Z > 1 -> abs(X) > 1, kill(MState), { integer_log_b(Z, X, 1, Y) } ; true ) ; { fd_get(Y, _, YL, YU, _), fd_get(Z, ZD, ZPs) }, ( { X > 0, YL cis_geq n(0) } -> { NZL cis n(X)^YL, NZU cis n(X)^YU, domains_intersection(ZD, from_to(NZL,NZU), NZD) }, fd_put(Z, NZD, ZPs) ; true ), ( { X > 0, fd_get(Z, _, _, n(ZMax), _), ZMax > 0 } -> { floor_integer_log_b(ZMax, X, 1, YCeil) }, queue_goal(Y in inf..YCeil) ; true ) ) ; nonvar(Z) -> ( nonvar(Y) -> { integer_kth_root(Z, Y, R) }, kill(MState), ( { even(Y) } -> N is -R, { X in N \/ R } ; X = R ) ; { fd_get(X, _, n(NXL), _, _), NXL > 1 } -> ( { Z > 1, between(NXL, Z, Exp), NXL^Exp > Z } -> Exp1 is Exp - 1, { fd_get(Y, YD, YPs), domains_intersection(YD, from_to(n(1),n(Exp1)), YD1) }, fd_put(Y, YD1, YPs), ( { fd_get(X, XD, XPs) } -> { domain_infimum(YD1, n(YL)), integer_kth_root_leq(Z, YL, RU), domains_intersection(XD, from_to(n(NXL),n(RU)), XD1) }, fd_put(X, XD1, XPs) ; true ) ; true ) ; true ) ; nonvar(Y), Y > 0 -> ( { even(Y) } -> { fd_get(Z, ZD0, ZPs0), domain_remove_smaller_than(ZD0, 0, ZDG0) }, fd_put(Z, ZDG0, ZPs0) ; true ), ( { fd_get(X, XD, XL, XU, _), fd_get(Z, ZD, ZL, ZU, ZPs) } -> ( { domain_contains(ZD, 0) } -> XD1 = XD ; { domain_remove(XD, 0, XD1) } ), ( { domain_contains(XD, 0) } -> ZD1 = ZD ; { domain_remove(ZD, 0, ZD1) } ), ( { even(Y) } -> ( { XL cis_geq n(0) } -> { NZL cis XL^n(Y) } ; { XU cis_leq n(0) } -> { NZL cis XU^n(Y) } ; NZL = n(0) ), { NZU cis max(abs(XL),abs(XU))^n(Y), domains_intersection(ZD1, from_to(NZL,NZU), ZD2) } ; ( { finite(XL) } -> { NZL cis XL^n(Y), NZU cis XU^n(Y) }, { domains_intersection(ZD1, from_to(NZL,NZU), ZD2) } ; ZD2 = ZD1 ) ), fd_put(Z, ZD2, ZPs), { ( even(Y), ZU = n(Num) -> integer_kth_root_leq(Num, Y, RU), ( XL cis_geq n(0), ZL = n(Num1), Num1 >= 0 -> integer_kth_root_leq(Num1, Y, RL0), ( RL0^Y < Num1 -> RL is RL0 + 1 ; RL = RL0 ) ; RL is -RU ), RL =< RU, NXD = from_to(n(RL),n(RU)) ; odd(Y), ZL cis_geq n(0), ZU = n(Num) -> integer_kth_root_leq(Num, Y, RU), ZL = n(Num1), integer_kth_root_leq(Num1, Y, RL0), ( RL0^Y < Num1 -> RL is RL0 + 1 ; RL = RL0 ), RL =< RU, NXD = from_to(n(RL),n(RU)) ; NXD = XD1 % TODO: propagate more ) }, ( { fd_get(X, XD2, XPs) } -> { domains_intersection(XD2, XD1, XD3), domains_intersection(XD3, NXD, XD4) }, fd_put(X, XD4, XPs) ; true ) ; true ) ; { fd_get(X, _, XL, _, _), XL cis_gt n(0), fd_get(Y, _, YL, _, _), YL cis_gt n(0), fd_get(Z, ZD, ZPs) } -> { n(NZL) cis XL^YL, domain_remove_smaller_than(ZD, NZL, ZD1) }, fd_put(Z, ZD1, ZPs) ; true ). %% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% % Y = sign(X) run_propagator(psign(X,Y), MState) --> ( nonvar(X) -> kill(MState), queue_goal(Y is sign(X)) ; Y == -1 -> kill(MState), queue_goal(X #< 0) ; Y == 0 -> kill(MState), queue_goal(X = 0) ; Y == 1 -> kill(MState), queue_goal(X #> 0) ; { fd_get(X, _, XL, XU, _) }, ( { XL = n(L), L > 0 } -> kill(MState), queue_goal(Y = 1) ; { XU = n(U), U < 0 } -> kill(MState), queue_goal(Y = -1) ; true ) ). %% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% % Y = popcount(X) run_propagator(ppopcount(X,Y), MState) --> ( nonvar(X) -> kill(MState), queue_goal(popcount(X, Y)) ; true ). %% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% % Z = X xor Y run_propagator(pxor(X,Y,Z), MState) --> ( nonvar(X), nonvar(Y) -> kill(MState), Z is xor(X, Y) ; nonvar(Y), nonvar(Z) -> kill(MState), X is xor(Y, Z) ; nonvar(Z), nonvar(X) -> kill(MState), Y is xor(Z, X) ; X == Y -> kill(MState), queue_goal(Z = 0) ; Y == Z -> kill(MState), queue_goal(X = 0) ; Z == X -> kill(MState), queue_goal(Y = 0) ; X == 0 -> kill(MState), queue_goal(Y = Z) ; Y == 0 -> kill(MState), queue_goal(Z = X) ; Z == 0 -> kill(MState), queue_goal(X = Y) ; true ). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% run_propagator(pzcompare(Order, A, B), MState) --> ( A == B -> kill(MState), Order = (=) ; ( nonvar(A) -> ( nonvar(B) -> kill(MState), ( A > B -> Order = (>) ; Order = (<) ) ; { fd_get(B, _, BL, BU, _) }, ( { BL cis_gt n(A) } -> kill(MState), Order = (<) ; { BU cis_lt n(A) } -> kill(MState), Order = (>) ; [] ) ) ; nonvar(B) -> { fd_get(A, _, AL, AU, _) }, ( { AL cis_gt n(B) } -> kill(MState), Order = (>) ; { AU cis_lt n(B) } -> kill(MState), Order = (<) ; [] ) ; { fd_get(A, _, AL, AU, _), fd_get(B, _, BL, BU, _) }, ( { AL cis_gt BU } -> kill(MState), Order = (>) ; { AU cis_lt BL } -> kill(MState), Order = (<) ; [] ) ) ). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % reified constraints %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% run_propagator(reified_in(V,Dom,B), MState) --> ( integer(V) -> kill(MState), ( { domain_contains(Dom, V) } -> B = 1 ; B = 0 ) ; B == 1 -> kill(MState), { domain(V, Dom) } ; B == 0 -> kill(MState), { domain_complement(Dom, C), domain(V, C) } ; { fd_get(V, VD, _) }, ( { domains_intersection(VD, Dom, I) } -> ( I == VD -> kill(MState), B = 1 ; [] ) ; kill(MState), B = 0 ) ). run_propagator(reified_tuple_in(Tuple, R, B), MState) --> { get_attr(R, clpz_relation, Relation) }, ( B == 1 -> kill(MState), { tuples_in([Tuple], Relation) } ; ( ground(Tuple) -> kill(MState), ( { memberchk(Tuple, Relation) } -> B = 1 ; B = 0 ) ; { relation_unifiable(Relation, Tuple, Us, _, _) }, ( Us = [] -> kill(MState), B = 0 ; [] ) ) ). run_propagator(tuples_not_in(Tuples, Relation, B), MState) --> ( B == 0 -> kill(MState), { tuples_in_conjunction(Tuples, Relation, Conj), #\ Conj } ; [] ). run_propagator(kill_reified_tuples(B, Ps, Bs), _) --> ( B == 0 -> { maplist(kill_entailed, Ps), phrase(as(Bs), As), maplist(kill_entailed, As) } ; [] ). run_propagator(reified_fd(V,B), MState) --> ( { fd_inf(V, I), I \== inf, fd_sup(V, S), S \== sup } -> kill(MState), B = 1 ; { B == 0 } -> ( { fd_inf(V, inf) } -> [] ; { fd_sup(V, sup) } ) ; [] ). % The result of X/Y, X mod Y, and X rem Y is undefined iff Y is 0. run_propagator(pskeleton(X,Y,D,Skel,Z,_), MState) --> ( Y == 0 -> kill(MState), D = 0 ; D == 1 -> kill(MState), neq_num(Y, 0), { skeleton([X,Y,Z], Skel) } ; integer(Y), Y =\= 0 -> kill(MState), D = 1, { skeleton([X,Y,Z], Skel) } ; { fd_get(Y, YD, _), \+ domain_contains(YD, 0) } -> kill(MState), D = 1, { skeleton([X,Y,Z], Skel) } ; [] ). /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Propagators for arithmetic functions that only propagate functionally. These are currently the bitwise operations. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ run_propagator(pfunction(Op,A,B,R), MState) --> ( integer(A), integer(B) -> kill(MState), Expr =.. [Op,A,B], R is Expr ; [] ). run_propagator(pfunction(Op,A,R), MState) --> ( integer(A) -> kill(MState), ( Op == msb -> { msb(A, R) } ; Op == lsb -> { lsb(A, R) } ; Expr =.. [Op,A], R is Expr ) ; [] ). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% run_propagator(reified_geq(DX,X,DY,Y,Ps,B), MState) --> ( DX == 0 -> kill(MState, Ps), B = 0 ; DY == 0 -> kill(MState, Ps), B = 0 ; B == 1 -> kill(MState), DX = 1, DY = 1, { geq(X, Y) } ; DX == 1, DY == 1 -> ( var(B) -> ( nonvar(X) -> ( nonvar(Y) -> kill(MState), ( X >= Y -> B = 1 ; B = 0 ) ; { fd_get(Y, _, YL, YU, _) }, ( { n(X) cis_geq YU } -> kill(MState, Ps), B = 1 ; { n(X) cis_lt YL } -> kill(MState, Ps), B = 0 ; [] ) ) ; nonvar(Y) -> { fd_get(X, _, XL, XU, _) }, ( { XL cis_geq n(Y) } -> kill(MState, Ps), B = 1 ; { XU cis_lt n(Y) } -> kill(MState, Ps), B = 0 ; [] ) ; X == Y -> kill(MState, Ps), B = 1 ; { fd_get(X, _, XL, XU, _), fd_get(Y, _, YL, YU, _) }, ( { XL cis_geq YU } -> kill(MState, Ps), B = 1 ; { XU cis_lt YL } -> kill(MState, Ps), B = 0 ; [] ) ) ; B =:= 0 -> { kill(MState), X #< Y } ; [] ) ; [] ). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% run_propagator(reified_eq(DX,X,DY,Y,Ps,B), MState) --> ( DX == 0 -> kill(MState, Ps), B = 0 ; DY == 0 -> kill(MState, Ps), B = 0 ; B == 1 -> kill(MState), DX = 1, DY = 1, X = Y ; DX == 1, DY == 1 -> ( var(B) -> ( nonvar(X) -> ( nonvar(Y) -> kill(MState), ( X =:= Y -> B = 1 ; B = 0) ; { fd_get(Y, YD, _) }, ( { domain_contains(YD, X) } -> [] ; kill(MState, Ps), B = 0 ) ) ; nonvar(Y) -> run_propagator(reified_eq(DY,Y,DX,X,Ps,B), MState) ; X == Y -> kill(MState), B = 1 ; { fd_get(X, _, XL, XU, _), fd_get(Y, _, YL, YU, _) }, ( { XL cis_gt YU } -> kill(MState, Ps), B = 0 ; { YL cis_gt XU } -> kill(MState, Ps), B = 0 ; [] ) ) ; B =:= 0 -> kill(MState), { X #\= Y } ; [] ) ; [] ). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% run_propagator(reified_neq(DX,X,DY,Y,Ps,B), MState) --> ( DX == 0 -> kill(MState, Ps), B = 0 ; DY == 0 -> kill(MState, Ps), B = 0 ; B == 1 -> { kill(MState), DX = 1, DY = 1, X #\= Y } ; DX == 1, DY == 1 -> ( var(B) -> ( nonvar(X) -> ( nonvar(Y) -> kill(MState), ( X =\= Y -> B = 1 ; B = 0) ; { fd_get(Y, YD, _) }, ( { domain_contains(YD, X) } -> [] ; kill(MState, Ps), B = 1 ) ) ; nonvar(Y) -> run_propagator(reified_neq(DY,Y,DX,X,Ps,B), MState) ; X == Y -> kill(MState), B = 0 ; { fd_get(X, _, XL, XU, _), fd_get(Y, _, YL, YU, _) }, ( { XL cis_gt YU } -> kill(MState, Ps), B = 1 ; { YL cis_gt XU } -> kill(MState, Ps), B = 1 ; [] ) ) ; B =:= 0 -> kill(MState), X = Y ; [] ) ; [] ). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% run_propagator(reified_and(X,Ps1,Y,Ps2,B), MState) --> ( nonvar(X) -> kill(MState), ( X =:= 0 -> { maplist(kill_entailed, Ps2), B = 0 } ; B = Y ) ; nonvar(Y) -> run_propagator(reified_and(Y,Ps2,X,Ps1,B), MState) ; B == 1 -> kill(MState), X = 1, Y = 1 ; [] ). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% run_propagator(reified_or(X,Ps1,Y,Ps2,B), MState) --> ( nonvar(X) -> kill(MState), ( X =:= 1 -> { maplist(kill_entailed, Ps2), B = 1 } ; B = Y ) ; nonvar(Y) -> run_propagator(reified_or(Y,Ps2,X,Ps1,B), MState) ; B == 0 -> kill(MState), X = 0, Y = 0 ; [] ). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% run_propagator(reified_not(X,Y), MState) --> ( X == 0 -> kill(MState), Y = 1 ; X == 1 -> kill(MState), Y = 0 ; Y == 0 -> kill(MState), X = 1 ; Y == 1 -> kill(MState), X = 0 ; [] ). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% run_propagator(pimpl(X, Y, Ps), MState) --> ( nonvar(X) -> kill(MState), ( X =:= 1 -> Y = 1 ; { maplist(kill_entailed, Ps) } ) ; nonvar(Y) -> kill(MState), ( Y =:= 0 -> X = 0 ; { maplist(kill_entailed, Ps) } ) ; [] ). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% run_propagator(preified_slash(X, Y, D, R), MState) --> ( Y == 0 -> kill(MState), D = 0 ; Y == 1 -> kill(MState), D = 1, R = X ; nonvar(X), nonvar(Y) -> kill(MState), ( X mod Y =:= 0 -> D = 1, R is X // Y ; D = 0 ) ; D == 1 -> kill(MState), queue_goal(X/Y #= R) ; [] ). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% run_propagator(preified_exp(X, Y, D, R), MState) --> ( X == 1 -> kill(MState), D = 1, R = 1 ; Y == 0 -> kill(MState), D = 1, R = 1 ; Y == 1 -> kill(MState), D = 1, R = X ; nonvar(X), nonvar(Y) -> kill(MState), ( ( abs(X) =:= 1 ; Y >= 0 ) -> D = 1, R is X^Y ; D = 0 ) ; D == 1 -> kill(MState), queue_goal(X^Y #= R) ; [] ). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% update_bounds(X, XD, XPs, XL, XU, NXL, NXU) --> ( NXL == XL, NXU == XU -> [] ; { domains_intersection(XD, from_to(NXL, NXU), NXD) }, fd_put(X, NXD, XPs) ). min_product(L1, U1, L2, U2, Min) :- Min cis min(min(L1*L2,L1*U2),min(U1*L2,U1*U2)). max_product(L1, U1, L2, U2, Max) :- Max cis max(max(L1*L2,L1*U2),max(U1*L2,U1*U2)). finite(n(_)). in_(L, U, X) :- fd_get(X, XD, XPs), domains_intersection(XD, from_to(L,U), NXD), fd_put(X, NXD, XPs). min_max_factor(L1, U1, L2, U2, L3, U3, Min, Max) :- % use findall/3 to forget auxiliary constraints that are only % needed temporarily for reasoning about domain boundaries findall(Min-Max, min_max_factor_(L1, U1, L2, U2, L3, U3, Min, Max), [Min-Max]). min_max_factor_(L1, U1, L2, U2, L3, U3, Min, Max) :- ( U1 cis_lt n(0), L2 cis_lt n(0), U2 cis_gt n(0), L3 cis_lt n(0), U3 cis_gt n(0) -> maplist(in_(L1,U1), [Z1,Z2]), in_(L2, n(-1), X1), in_(n(1), U3, Y1), ( X1*Y1 #= Z1 -> ( fd_get(Y1, _, Inf1, Sup1, _) -> true ; Inf1 = n(Y1), Sup1 = n(Y1) ) ; Inf1 = inf, Sup1 = n(-1) ), in_(n(1), U2, X2), in_(L3, n(-1), Y2), ( X2*Y2 #= Z2 -> ( fd_get(Y2, _, Inf2, Sup2, _) -> true ; Inf2 = n(Y2), Sup2 = n(Y2) ) ; Inf2 = n(1), Sup2 = sup ), Min cis max(min(Inf1,Inf2), L3), Max cis min(max(Sup1,Sup2), U3) ; L1 cis_gt n(0), L2 cis_lt n(0), U2 cis_gt n(0), L3 cis_lt n(0), U3 cis_gt n(0) -> maplist(in_(L1,U1), [Z1,Z2]), in_(L2, n(-1), X1), in_(L3, n(-1), Y1), ( X1*Y1 #= Z1 -> ( fd_get(Y1, _, Inf1, Sup1, _) -> true ; Inf1 = n(Y1), Sup1 = n(Y1) ) ; Inf1 = n(1), Sup1 = sup ), in_(n(1), U2, X2), in_(n(1), U3, Y2), ( X2*Y2 #= Z2 -> ( fd_get(Y2, _, Inf2, Sup2, _) -> true ; Inf2 = n(Y2), Sup2 = n(Y2) ) ; Inf2 = inf, Sup2 = n(-1) ), Min cis max(min(Inf1,Inf2), L3), Max cis min(max(Sup1,Sup2), U3) ; min_factor(L1, U1, L2, U2, Min0), Min cis max(L3,Min0), max_factor(L1, U1, L2, U2, Max0), Max cis min(U3,Max0) ). min_factor(L1, U1, L2, U2, Min) :- ( L1 cis_geq n(0), L2 cis_gt n(0), finite(U2) -> Min cis div(L1+U2-n(1),U2) ; L1 cis_gt n(0), U2 cis_lt n(0) -> Min cis div(U1,U2) ; L1 cis_gt n(0), L2 cis_geq n(0) -> Min = n(1) ; L1 cis_gt n(0) -> Min cis -U1 ; U1 cis_lt n(0), U2 cis_leq n(0) -> ( finite(L2) -> Min cis div(U1+L2+n(1),L2) ; Min = n(1) ) ; U1 cis_lt n(0), L2 cis_geq n(0) -> Min cis div(L1,L2) ; U1 cis_lt n(0) -> Min = L1 ; L2 cis_leq n(0), U2 cis_geq n(0) -> Min = inf ; Min cis min(min(div(L1,L2),div(L1,U2)),min(div(U1,L2),div(U1,U2))) ). max_factor(L1, U1, L2, U2, Max) :- ( L1 cis_geq n(0), L2 cis_geq n(0) -> Max cis div(U1,L2) ; L1 cis_gt n(0), U2 cis_leq n(0) -> ( finite(L2) -> Max cis div(L1-L2-n(1),L2) ; Max = n(-1) ) ; L1 cis_gt n(0) -> Max = U1 ; U1 cis_lt n(0), U2 cis_lt n(0) -> Max cis div(L1,U2) ; U1 cis_lt n(0), L2 cis_geq n(0) -> ( finite(U2) -> Max cis div(U1-U2+n(1),U2) ; Max = n(-1) ) ; U1 cis_lt n(0) -> Max cis -L1 ; L2 cis_leq n(0), U2 cis_geq n(0) -> Max = sup ; Max cis max(max(div(L1,L2),div(L1,U2)),max(div(U1,L2),div(U1,U2))) ). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - J-C. Régin: "A filtering algorithm for constraints of difference in CSPs", AAAI-94, Seattle, WA, USA, pp 362--367, 1994 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ distinct_attach([], _, _) --> []. distinct_attach([X|Xs], Prop, Right) --> ( var(X) -> init_propagator_([X], Prop), { make_propagator(pexclude(Xs,Right,X), P1) }, init_propagator_([X], P1), trigger_prop(P1) ; exclude_fire(Xs, Right, X) ), distinct_attach(Xs, Prop, [X|Right]). /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - For each integer of the union of domains, an attributed variable is introduced, to benefit from constant-time access. Attributes are: value ... integer corresponding to the node free ... whether this (right) node is still free edges ... [flow_from(F,From)] and [flow_to(F,To)] where F has an attribute "flow" that is either 0 or 1 and an attribute "used" if it is part of a maximum matching parent ... used in breadth-first search g0_edges ... [flow_to(F,To)] as above visited ... true if node was visited in DFS index, in_stack, lowlink ... used in Tarjan's SCC algorithm - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ difference_arcs(Vars, FreeLeft, FreeRight) :- empty_assoc(E), phrase(difference_arcs(Vars, FreeLeft), [E], [NumVar]), assoc_to_list(NumVar, LsNumVar), pairs_values(LsNumVar, FreeRight). domain_to_list(Domain, List) :- phrase(domain_to_list(Domain), List). domain_to_list(split(_, Left, Right)) --> domain_to_list(Left), domain_to_list(Right). domain_to_list(empty) --> []. domain_to_list(from_to(n(F),n(T))) --> { numlist(F, T, Ns) }, seq(Ns). difference_arcs([], []) --> []. difference_arcs([V|Vs], FL0) --> ( { fd_get(V, Dom, _), domain_to_list(Dom, Ns) } -> { FL0 = [V|FL] }, enumerate(Ns, V), difference_arcs(Vs, FL) ; difference_arcs(Vs, FL0) ). writeln(T) :- write(T), nl. :- meta_predicate(must_succeed(0)). must_succeed(G) :- ( G -> true ; throw(failed-G) ). enumerate([], _) --> []. enumerate([N|Ns], V) --> state(NumVar0, NumVar), { ( get_assoc(N, NumVar0, Y) -> NumVar0 = NumVar ; put_assoc(N, NumVar0, Y, NumVar), put_attr(Y, value, N) ), put_attr(F, flow, 0), must_succeed(append_edge(Y, edges, flow_from(F,V))), must_succeed(append_edge(V, edges, flow_to(F,Y))) }, enumerate(Ns, V). append_edge(V, Attr, E) :- ( get_attr_(Attr, V, Es) -> put_attr_(Attr, V, [E|Es]) ; put_attr_(Attr, V, [E]) ). get_attr_(edges, V, Es) :- get_attr(V, edges, Es). get_attr_(g0_edges, V, Es) :- get_attr(V, g0_edges, Es). put_attr_(edges, V, E) :- put_attr(V, edges, E). put_attr_(g0_edges, V, E) :- put_attr(V, g0_edges, E). /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Strategy: Breadth-first search until we find a free right vertex in the value graph, then find an augmenting path in reverse. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ clear_parent(V) :- del_attr(V, parent). maximum_matching([]). maximum_matching([FL|FLs]) :- augmenting_path_to([[FL]], Levels, To), phrase(augmenting_path(FL, To), Path), maplist(maplist(clear_parent), Levels), del_attr(To, free), adjust_alternate_1(Path), maximum_matching(FLs). reachables([]) --> []. reachables([V|Vs]) --> { get_attr(V, edges, Es) }, reachables_(Es, V), reachables(Vs). reachables_([], _) --> []. reachables_([E|Es], V) --> edge_reachable(E, V), reachables_(Es, V). edge_reachable(flow_to(F,To), V) --> ( { get_attr(F, flow, 0), \+ get_attr(To, parent, _) } -> { put_attr(To, parent, V-F) }, [To] ; [] ). edge_reachable(flow_from(F,From), V) --> ( { get_attr(F, flow, 1), \+ get_attr(From, parent, _) } -> { put_attr(From, parent, V-F) }, [From] ; [] ). augmenting_path_to(Levels0, Levels, Right) :- Levels0 = [Vs|_], Levels1 = [Tos|Levels0], phrase(reachables(Vs), Tos), Tos = [_|_], ( member(Right, Tos), get_attr(Right, free, true) -> Levels = Levels1 ; augmenting_path_to(Levels1, Levels, Right) ). augmenting_path(S, V) --> ( { V == S } -> [] ; { get_attr(V, parent, V1-Augment) }, [Augment], augmenting_path(S, V1) ). adjust_alternate_1([A|Arcs]) :- put_attr(A, flow, 1), adjust_alternate_0(Arcs). adjust_alternate_0([]). adjust_alternate_0([A|Arcs]) :- put_attr(A, flow, 0), adjust_alternate_1(Arcs). % Instead of applying Berge's property directly, we can translate the % problem in such a way, that we have to search for the so-called % strongly connected components of the graph. g_g0(V) :- get_attr(V, edges, Es), maplist(g_g0_(V), Es). g_g0_(V, flow_to(F,To)) :- ( get_attr(F, flow, 1) -> append_edge(V, g0_edges, flow_to(F,To)) ; append_edge(To, g0_edges, flow_to(F,V)) ). g0_successors(V, Tos) :- ( get_attr(V, g0_edges, Tos0) -> maplist(arg(2), Tos0, Tos) ; Tos = [] ). put_free(F) :- put_attr(F, free, true). free_node(F) :- get_attr(F, free, true). :- meta_predicate(with_local_attributes(?, 0, ?)). :- dynamic(nat_copy/1). with_local_attributes(Vars, Goal, Result) :- catch((Goal, % Create a copy where all attributes are removed. Only % the result and its relation to Vars matters. We throw % an exception to undo all modifications to attributes % we made during propagation, and unify the variables % in the thrown copy with Vars in order to get the % intended variables in Result. copy_term_nat(Vars-Result, Copy), throw(local_attributes(Copy))), local_attributes(Vars-Result), true). distinct(Vars) --> { with_local_attributes(Vars, ( difference_arcs(Vars, FreeLeft, FreeRight0), length(FreeLeft, LFL), length(FreeRight0, LFR), LFL =< LFR, maplist(put_free, FreeRight0), maximum_matching(FreeLeft), include(free_node, FreeRight0, FreeRight), maplist(g_g0, FreeLeft), scc(FreeLeft, g0_successors), maplist(dfs_used, FreeRight), phrase(distinct_goals(FreeLeft), Gs)), Gs) }, disable_queue, neq_nums(Gs), enable_queue. neq_nums([]) --> []. neq_nums([neq_num(V,N)|VNs]) --> % { portray_clause(neq_num(V, N)) }, neq_num(V, N), neq_nums(VNs). distinct_goals([]) --> []. distinct_goals([V|Vs]) --> { get_attr(V, edges, Es) }, distinct_goals_(Es, V), distinct_goals(Vs). distinct_goals_([], _) --> []. distinct_goals_([flow_to(F,To)|Es], V) --> ( { get_attr(F, flow, 0), \+ get_attr(F, used, true), get_attr(V, lowlink, L1), get_attr(To, lowlink, L2), L1 =\= L2 } -> { get_attr(To, value, N) }, [neq_num(V, N)] ; [] ), distinct_goals_(Es, V). /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Mark used edges. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ dfs_used(V) :- ( get_attr(V, visited, true) -> true ; put_attr(V, visited, true), ( get_attr(V, g0_edges, Es) -> dfs_used_edges(Es) ; true ) ). dfs_used_edges([]). dfs_used_edges([flow_to(F,To)|Es]) :- put_attr(F, used, true), dfs_used(To), dfs_used_edges(Es). /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Tarjan's strongly connected components algorithm. DCGs are used to implicitly pass around the global index, stack and the predicate relating a vertex to its successors. For more information about this technique, see: https://www.metalevel.at/prolog/dcg =================================== A Prolog implementation of this algorithm is also available as a standalone library from: https://www.metalevel.at/scc.pl - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ scc(Vs, Succ) :- phrase(scc(Vs), [s(0,[],Succ)], _). scc([]) --> []. scc([V|Vs]) --> ( vindex_defined(V) -> scc(Vs) ; scc_(V), scc(Vs) ). vindex_defined(V) --> { get_attr(V, index, _) }. vindex_is_index(V) --> state(s(Index,_,_)), { put_attr(V, index, Index) }. vlowlink_is_index(V) --> state(s(Index,_,_)), { put_attr(V, lowlink, Index) }. index_plus_one --> state(s(I,Stack,Succ), s(I1,Stack,Succ)), { I1 is I+1 }. s_push(V) --> state(s(I,Stack,Succ), s(I,[V|Stack],Succ)), { put_attr(V, in_stack, true) }. vlowlink_min_lowlink(V, VP) --> { get_attr(V, lowlink, VL), get_attr(VP, lowlink, VPL), VL1 is min(VL, VPL), put_attr(V, lowlink, VL1) }. successors(V, Tos) --> state(s(_,_,Succ)), { call(Succ, V, Tos) }. scc_(V) --> vindex_is_index(V), vlowlink_is_index(V), index_plus_one, s_push(V), successors(V, Tos), each_edge(Tos, V), ( { get_attr(V, index, VI), get_attr(V, lowlink, VI) } -> pop_stack_to(V, VI) ; [] ). pop_stack_to(V, N) --> state(s(I,[First|Stack],Succ), s(I,Stack,Succ)), { del_attr(First, in_stack) }, ( { First == V } -> [] ; { put_attr(First, lowlink, N) }, pop_stack_to(V, N) ). each_edge([], _) --> []. each_edge([VP|VPs], V) --> ( vindex_defined(VP) -> ( v_in_stack(VP) -> vlowlink_min_lowlink(V, VP) ; [] ) ; scc_(VP), vlowlink_min_lowlink(V, VP) ), each_edge(VPs, V). state(S), [S] --> [S]. state(S0, S), [S] --> [S0]. v_in_stack(V) --> { get_attr(V, in_stack, true) }. node_lowlink(V, L) :- get_attr(V, lowlink, L). /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - nvalue/2: A relaxed version of all_distinct/1. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ maximal_matching([]) --> []. maximal_matching([FL|FLs]) --> ( { augmenting_path_to([[FL]], Levels, To) } -> { phrase(augmenting_path(FL, To), Path), maplist(maplist(clear_parent), Levels), del_attr(To, free), adjust_alternate_1(Path) }, [FL] ; [] ), maximal_matching(FLs). propagate_nvalue(N, Vars0) :- sort(Vars0, Vars), include(integer, Vars, Ints), length(Ints, Distinct), vars_num_infinite(Vars, NumInfinite), N #>= Distinct, with_local_attributes(Vars, ( difference_arcs(Vars, FreeLeft, FreeRight0), maplist(put_free, FreeRight0), phrase(maximal_matching(FreeLeft), MatchedLeft), length(MatchedLeft, MaxFurther) ), MaxFurther), N #=< NumInfinite + Distinct + MaxFurther. vars_num_infinite(Vars, Num) :- foldl(num_infinite, Vars, 0, Num). num_infinite(Var, N0, N) :- ( integer(Var) -> N = N0 ; fd_get(Var, Dom, _), ( domain_infimum(Dom, n(_)), domain_supremum(Dom, n(_)) -> N = N0 ; N #= N0 + 1 ) ). /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Weak arc consistent constraint of difference, currently only available internally. Candidate for all_different/2 option. See Neng-Fa Zhou: "Programming Finite-Domain Constraint Propagators in Action Rules", Theory and Practice of Logic Programming, Vol.6, No.5, pp 483-508, 2006 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ weak_arc_all_distinct(Ls) :- must_be(list, Ls), Orig = original_goal(_, weak_arc_all_distinct(Ls)), all_distinct(Ls, [], Orig). all_distinct([], _, _). all_distinct([X|Right], Left, Orig) :- %\+ list_contains(Right, X), ( var(X) -> make_propagator(weak_distinct(Left,Right,X,Orig), Prop), init_propagator(X, Prop), trigger_prop(Prop) % make_propagator(check_distinct(Left,Right,X), Prop2), % init_propagator(X, Prop2), % trigger_prop(Prop2) ; exclude_fire(Left, Right, X) ), outof_reducer(Left, Right, X), all_distinct(Right, [X|Left], Orig). exclude_fire(Left, Right, E) :- all_neq(Left, E), all_neq(Right, E). exclude_fire(Left, Right, E) --> all_neq(Left, E), all_neq(Right, E). list_contains([X|Xs], Y) :- ( X == Y -> true ; list_contains(Xs, Y) ). kill_if_isolated(Left, Right, X, MState) :- append(Left, Right, Others), fd_get(X, XDom, _), ( all_empty_intersection(Others, XDom) -> kill(MState) ; true ). all_empty_intersection([], _). all_empty_intersection([V|Vs], XDom) :- ( fd_get(V, VDom, _) -> domains_intersection_(VDom, XDom, empty), all_empty_intersection(Vs, XDom) ; all_empty_intersection(Vs, XDom) ). outof_reducer(Left, Right, Var) :- ( fd_get(Var, Dom, _) -> append(Left, Right, Others), domain_num_elements(Dom, N), num_subsets(Others, Dom, 0, Num, NonSubs), ( n(Num) cis_geq N -> false ; n(Num) cis N - n(1) -> reduce_from_others(NonSubs, Dom) ; true ) ; %\+ list_contains(Right, Var), %\+ list_contains(Left, Var) true ). reduce_from_others([], _). reduce_from_others([X|Xs], Dom) :- ( fd_get(X, XDom, XPs) -> domain_subtract(XDom, Dom, NXDom), fd_put(X, NXDom, XPs) ; true ), reduce_from_others(Xs, Dom). num_subsets([], _Dom, Num, Num, []). num_subsets([S|Ss], Dom, Num0, Num, NonSubs) :- ( fd_get(S, SDom, _) -> ( domain_subdomain(Dom, SDom) -> Num1 is Num0 + 1, num_subsets(Ss, Dom, Num1, Num, NonSubs) ; NonSubs = [S|Rest], num_subsets(Ss, Dom, Num0, Num, Rest) ) ; num_subsets(Ss, Dom, Num0, Num, NonSubs) ). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% serialized(+Starts, +Durations) % % Describes a set of non-overlapping tasks. % Starts = [S_1,...,S_n], is a list of variables or integers, % Durations = [D_1,...,D_n] is a list of non-negative integers. % Constrains Starts and Durations to denote a set of % non-overlapping tasks, i.e.: S_i + D_i =< S_j or S_j + D_j =< % S_i for all 1 =< i < j =< n. Example: % % ``` % ?- length(Vs, 3), % Vs ins 0..3, % serialized(Vs, [1,2,3]), % label(Vs). % Vs = [0,1,3] % ; Vs = [2,0,3] % ; false. % ``` % % @see Dorndorf et al. 2000, "Constraint Propagation Techniques for the % Disjunctive Scheduling Problem" serialized(Starts, Durations) :- must_be(list(integer), Durations), pairs_keys_values(SDs, Starts, Durations), Orig = original_goal(_, serialized(Starts, Durations)), serialize(SDs, Orig). serialize([], _). serialize([S-D|SDs], Orig) :- D >= 0, serialize(SDs, S, D, Orig), serialize(SDs, Orig). serialize([], _, _, _). serialize([S-D|Rest], S0, D0, Orig) :- D >= 0, propagator_init_trigger([S0,S], pserialized(S,D,S0,D0,Orig)), serialize(Rest, S0, D0, Orig). % consistency check / propagation % Currently implements 2-b-consistency earliest_start_time(Start, EST) :- ( fd_get(Start, D, _) -> domain_infimum(D, EST) ; EST = n(Start) ). latest_start_time(Start, LST) :- ( fd_get(Start, D, _) -> domain_supremum(D, LST) ; LST = n(Start) ). serialize_lower_upper(S_I, D_I, S_J, D_J, MState) --> ( { var(S_I) } -> serialize_lower_bound(S_I, D_I, S_J, D_J, MState), ( { var(S_I) } -> serialize_upper_bound(S_I, D_I, S_J, D_J, MState) ; [] ) ; [] ). serialize_lower_bound(I, D_I, J, D_J, MState) --> { fd_get(I, DomI, Ps) }, ( { domain_infimum(DomI, n(EST_I)), latest_start_time(J, n(LST_J)), EST_I + D_I > LST_J, earliest_start_time(J, n(EST_J)) } -> ( nonvar(J) -> kill(MState) ; [] ), { EST is EST_J+D_J, domain_remove_smaller_than(DomI, EST, DomI1) }, fd_put(I, DomI1, Ps) ; [] ). serialize_upper_bound(I, D_I, J, D_J, MState) --> { fd_get(I, DomI, Ps) }, ( { domain_supremum(DomI, n(LST_I)), earliest_start_time(J, n(EST_J)), EST_J + D_J > LST_I, latest_start_time(J, n(LST_J)) } -> ( nonvar(J) -> kill(MState) ; [] ), { LST is LST_J-D_I, domain_remove_greater_than(DomI, LST, DomI1) }, fd_put(I, DomI1, Ps) ; [] ). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% element(?N, +Vs, ?V) % % The N-th element of the list of finite domain variables Vs is V. % Analogous to nth1/3. element(N, Is, V) :- must_be(list, Is), length(Is, L), N in 1..L, element_(Is, 1, N, V), propagator_init_trigger([N|Is], pelement(N,Is,V)). element_domain(V, VD) :- ( fd_get(V, VD, _) -> true ; VD = from_to(n(V), n(V)) ). element_([], _, _, _). element_([I|Is], N0, N, V) :- #I #\= #V #==> #N #\= N0, N1 is N0 + 1, element_(Is, N1, N, V). integers_remaining([], _, _, D, D). integers_remaining([V|Vs], N0, Dom, D0, D) :- ( domain_contains(Dom, N0) -> element_domain(V, VD), domains_union(D0, VD, D1) ; D1 = D0 ), N1 is N0 + 1, integers_remaining(Vs, N1, Dom, D1, D). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% global_cardinality(+Vs, +Pairs) % % Global Cardinality constraint. Equivalent to % `global_cardinality(Vs, Pairs, [])`. Example: % % ``` % ?- Vs = [_,_,_], global_cardinality(Vs, [1-2,3-_]), label(Vs). % Vs = [1,1,3] % ; Vs = [1,3,1] % ; Vs = [3,1,1] % ; false. % ``` global_cardinality(Xs, Pairs) :- global_cardinality(Xs, Pairs, []). %% global_cardinality(+Vs, +Pairs, +Options) % % Global Cardinality constraint. Vs is a list of finite domain % variables, Pairs is a list of Key-Num pairs, where Key is an % integer and Num is a finite domain variable. The constraint holds % iff each V in Vs is equal to some key, and for each Key-Num pair % in Pairs, the number of occurrences of Key in Vs is Num. Options % is a list of options. Supported options are: % % `consistency(value)` % A weaker form of consistency is used. % % `cost(Cost, Matrix)` % Matrix is a list of rows, one for each variable, in the order % they occur in Vs. Each of these rows is a list of integers, one % for each key, in the order these keys occur in Pairs. When % variable v\_i is assigned the value of key k\_j, then the % associated cost is Matrix\_{ij}. Cost is the sum of all costs. global_cardinality(Xs, Pairs, Options) :- must_be(list(list), [Xs,Pairs,Options]), maplist(fd_variable, Xs), maplist(gcc_pair, Pairs), pairs_keys_values(Pairs, Keys, Nums), ( sort(Keys, Keys1), same_length(Keys, Keys1) -> true ; domain_error(gcc_unique_key_pairs, Pairs) ), length(Xs, L), Nums ins 0..L, list_to_drep(Keys, Drep), Xs ins Drep, gcc_pairs(Pairs, Xs, Pairs1), % pgcc_check must be installed before triggering other % propagators propagator_init_trigger(Xs, pgcc_check(Pairs1)), propagator_init_trigger(Nums, pgcc_check_single(Pairs1)), ( member(OD, Options), OD == consistency(value) -> true ; propagator_init_trigger(Nums, pgcc_single(Xs, Pairs1)), propagator_init_trigger(Xs, pgcc(Xs, Pairs, Pairs1)) ), ( member(OC, Options), functor(OC, cost, 2) -> OC = cost(Cost, Matrix), must_be(list(list(integer)), Matrix), maplist(keys_costs(Keys), Xs, Matrix, Costs), sum(Costs, #=, Cost) ; true ). keys_costs(Keys, X, Row, C) :- element(N, Keys, X), element(N, Row, C). gcc_pair(Pair) :- ( Pair = Key-Val -> must_be(integer, Key), fd_variable(Val) ; domain_error(gcc_pair, Pair) ). /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - For each Key-Num0 pair, we introduce an auxiliary variable Num and attach the following attributes to it: clpz_gcc_num: equal Num0, the user-visible counter variable clpz_gcc_vs: the remaining variables in the constraint that can be equal Key. clpz_gcc_occurred: stores how often Key already occurred in vs. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ gcc_pairs([], _, []). gcc_pairs([Key-Num0|KNs], Vs, [Key-Num|Rest]) :- put_attr(Num, clpz_gcc_num, Num0), put_attr(Num, clpz_gcc_vs, Vs), put_attr(Num, clpz_gcc_occurred, 0), gcc_pairs(KNs, Vs, Rest). /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - J.-C. Régin: "Generalized Arc Consistency for Global Cardinality Constraint", AAAI-96 Portland, OR, USA, pp 209--215, 1996 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ gcc_global(Vs, KNs) --> % at this point, all elements of clpz_gcc_vs must be % variables, which a previously scheduled and called % gcc_check//1 ensures. Note that gcc_check//1 disables the % queue and accumulates constraints in the queue. Do we need % to insert a call of do_queue//0 here to reach a fixpoint? I % think not, because verify_attributes/3 gives each variable % that is involved in a unification an opportunity to schedule % its propagators, even if the unifications happen % simultaneously (such as [A,B] = [0,1], which can happen in % the propagator of tuples_in/2). Hence: We need this only if % an example shows it, ideally found by a systematic search % that can be used to test the implementation. { with_local_attributes(Vs, (gcc_arcs(KNs, S, Vals), variables_with_num_occurrences(Vs, VNs), maplist(target_to_v(T), VNs), ( get_attr(S, edges, Es) -> put_attr(S, parent, none), % Mark S as seen to avoid going back to S. feasible_flow(Es, S, T), % First construct a feasible flow (if any) maximum_flow(S, T), % only then, maximize it. gcc_consistent(T), scc(Vals, gcc_successors), phrase(gcc_goals(Vals), Gs) ; Gs = [] )), Gs) }, disable_queue, neq_nums(Gs), enable_queue. gcc_consistent(T) :- get_attr(T, edges, Es), maplist(saturated_arc, Es). saturated_arc(arc_from(_,U,_,Flow)) :- get_attr(Flow, flow, U). gcc_goals([]) --> []. gcc_goals([Val|Vals]) --> { get_attr(Val, edges, Es) }, gcc_edges_goals(Es, Val), gcc_goals(Vals). gcc_edges_goals([], _) --> []. gcc_edges_goals([E|Es], Val) --> gcc_edge_goal(E, Val), gcc_edges_goals(Es, Val). gcc_edge_goal(arc_from(_,_,_,_), _) --> []. gcc_edge_goal(arc_to(_,_,V,F), Val) --> ( { get_attr(F, flow, 0), get_attr(V, lowlink, L1), get_attr(Val, lowlink, L2), L1 =\= L2, get_attr(Val, value, Value) } -> [neq_num(V, Value)] ; [] ). /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Like in all_distinct/1, first use breadth-first search, then construct an augmenting path in reverse. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ maximum_flow(S, T) :- ( gcc_augmenting_path([[S]], Levels, T) -> phrase(augmenting_path(S, T), Path), Path = [augment(_,First,_)|Rest], path_minimum(Rest, First, Min), maplist(gcc_augment(Min), Path), maplist(maplist(clear_parent), Levels), maximum_flow(S, T) ; true ). feasible_flow([], _, _). feasible_flow([A|As], S, T) :- make_arc_feasible(A, S, T), feasible_flow(As, S, T). make_arc_feasible(A, S, T) :- A = arc_to(L,_,V,F), get_attr(F, flow, Flow), ( Flow >= L -> true ; Diff is L - Flow, put_attr(V, parent, S-augment(F,Diff,+)), gcc_augmenting_path([[V]], Levels, T), phrase(augmenting_path(S, T), Path), path_minimum(Path, Diff, Min), maplist(gcc_augment(Min), Path), maplist(maplist(clear_parent), Levels), make_arc_feasible(A, S, T) ). gcc_augmenting_path(Levels0, Levels, T) :- Levels0 = [Vs|_], Levels1 = [Tos|Levels0], phrase(gcc_reachables(Vs), Tos), Tos = [_|_], ( member(To, Tos), To == T -> Levels = Levels1 ; gcc_augmenting_path(Levels1, Levels, T) ). gcc_reachables([]) --> []. gcc_reachables([V|Vs]) --> { get_attr(V, edges, Es) }, gcc_reachables_(Es, V), gcc_reachables(Vs). gcc_reachables_([], _) --> []. gcc_reachables_([E|Es], V) --> gcc_reachable(E, V), gcc_reachables_(Es, V). gcc_reachable(arc_from(_,_,V,F), P) --> ( { \+ get_attr(V, parent, _), get_attr(F, flow, Flow), Flow > 0 } -> { put_attr(V, parent, P-augment(F,Flow,-)) }, [V] ; [] ). gcc_reachable(arc_to(_L,U,V,F), P) --> ( { \+ get_attr(V, parent, _), get_attr(F, flow, Flow), Flow < U } -> { Diff is U - Flow, put_attr(V, parent, P-augment(F,Diff,+)) }, [V] ; [] ). path_minimum([], Min, Min). path_minimum([augment(_,A,_)|As], Min0, Min) :- Min1 is min(Min0,A), path_minimum(As, Min1, Min). gcc_augment(Min, augment(F,_,Sign)) :- get_attr(F, flow, Flow0), gcc_flow_(Sign, Flow0, Min, Flow), put_attr(F, flow, Flow). gcc_flow_(+, F0, A, F) :- F is F0 + A. gcc_flow_(-, F0, A, F) :- F is F0 - A. /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Build value network for global cardinality constraint. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ gcc_arcs([], _, []). gcc_arcs([Key-Num0|KNs], S, Vals) :- ( get_attr(Num0, clpz_gcc_vs, Vs) -> get_attr(Num0, clpz_gcc_num, Num), get_attr(Num0, clpz_gcc_occurred, Occ), ( nonvar(Num) -> U is Num - Occ, U = L ; fd_get(Num, _, n(L0), n(U0), _), L is L0 - Occ, U is U0 - Occ ), put_attr(Val, value, Key), Vals = [Val|Rest], put_attr(F, flow, 0), append_edge(S, edges, arc_to(L, U, Val, F)), put_attr(Val, edges, [arc_from(L, U, S, F)]), variables_with_num_occurrences(Vs, VNs), maplist(val_to_v(Val), VNs) ; Vals = Rest ), gcc_arcs(KNs, S, Rest). variables_with_num_occurrences(Vs0, VNs) :- include(var, Vs0, Vs1), samsort(Vs1, Vs), ( Vs == [] -> VNs = [] ; Vs = [V|Rest], variables_with_num_occurrences(Rest, V, 1, VNs) ). variables_with_num_occurrences([], Prev, Count, [Prev-Count]). variables_with_num_occurrences([V|Vs], Prev, Count0, VNs) :- ( V == Prev -> Count1 is Count0 + 1, variables_with_num_occurrences(Vs, Prev, Count1, VNs) ; VNs = [Prev-Count0|Rest], variables_with_num_occurrences(Vs, V, 1, Rest) ). target_to_v(T, V-Count) :- put_attr(F, flow, 0), append_edge(V, edges, arc_to(0, Count, T, F)), append_edge(T, edges, arc_from(0, Count, V, F)). val_to_v(Val, V-Count) :- put_attr(F, flow, 0), append_edge(V, edges, arc_from(0, Count, Val, F)), append_edge(Val, edges, arc_to(0, Count, V, F)). gcc_successors(V, Tos) :- get_attr(V, edges, Tos0), phrase(gcc_successors_(Tos0), Tos). gcc_successors_([]) --> []. gcc_successors_([E|Es]) --> gcc_succ_edge(E), gcc_successors_(Es). gcc_succ_edge(arc_to(_,U,V,F)) --> ( { get_attr(F, flow, Flow), Flow < U } -> [V] ; [] ). gcc_succ_edge(arc_from(_,_,V,F)) --> ( { get_attr(F, flow, Flow), Flow > 0 } -> [V] ; [] ). /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Simple consistency check, run before global propagation. Importantly, it removes all ground values from clpz_gcc_vs. The pgcc_check/1 propagator in itself suffices to ensure consistency. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ gcc_check(Pairs) --> disable_queue, gcc_check_(Pairs), enable_queue. gcc_done(Num) :- del_attr(Num, clpz_gcc_vs), del_attr(Num, clpz_gcc_num), del_attr(Num, clpz_gcc_occurred). gcc_check_([]) --> []. gcc_check_([Key-Num0|KNs]) --> ( { get_attr(Num0, clpz_gcc_vs, Vs) } -> { get_attr(Num0, clpz_gcc_num, Num), get_attr(Num0, clpz_gcc_occurred, Occ0), vs_key_min_others(Vs, Key, 0, Min, Os), put_attr(Num0, clpz_gcc_vs, Os), put_attr(Num0, clpz_gcc_occurred, Occ1), Occ1 is Occ0 + Min }, geq(Num, Occ1), % The queue is disabled for efficiency here in any case. % If it were enabled, make sure to retain the invariant % that gcc_global is never triggered during an % inconsistent state (after gcc_done/1 but before all % relevant constraints are posted). ( Occ1 == Num -> all_neq(Os, Key), { gcc_done(Num0) } ; Os == [] -> { gcc_done(Num0) }, Num = Occ1 ; { length(Os, L), Max is Occ1 + L }, geq(Max, Num), ( { nonvar(Num) } -> Diff is Num - Occ1 ; { fd_get(Num, ND, _), domain_infimum(ND, n(NInf)) }, Diff is NInf - Occ1 ), L >= Diff, ( L =:= Diff -> Num is Occ1 + Diff, { maplist(=(Key), Os), gcc_done(Num0) } ; true ) ) ; true ), gcc_check_(KNs). vs_key_min_others([], _, Min, Min, []). vs_key_min_others([V|Vs], Key, Min0, Min, Others) :- ( fd_get(V, VD, _) -> ( domain_contains(VD, Key) -> Others = [V|Rest], vs_key_min_others(Vs, Key, Min0, Min, Rest) ; vs_key_min_others(Vs, Key, Min0, Min, Others) ) ; ( V =:= Key -> Min1 is Min0 + 1, vs_key_min_others(Vs, Key, Min1, Min, Others) ; vs_key_min_others(Vs, Key, Min0, Min, Others) ) ). all_neq([], _) --> []. all_neq([X|Xs], C) --> neq_num(X, C), all_neq(Xs, C). all_neq([], _). all_neq([X|Xs], C) :- neq_num(X, C), all_neq(Xs, C). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% circuit(+Vs) % % True iff the list Vs of finite domain variables induces a % Hamiltonian circuit. The k-th element of Vs denotes the % successor of node k. Node indexing starts with 1. Examples: % % ``` % ?- length(Vs, _), circuit(Vs), label(Vs). % Vs = [] % ; Vs = [1] % ; Vs = [2,1] % ; Vs = [2,3,1] % ; Vs = [3,1,2] % ; Vs = [2,3,4,1] % ; ... . % ``` circuit(Vs) :- must_be(list, Vs), maplist(fd_variable, Vs), length(Vs, L), Vs ins 1..L, ( L =:= 1 -> true ; neq_index(Vs, 1), make_propagator(pcircuit(Vs), Prop), new_queue(Q0), phrase((distinct_attach(Vs, Prop, []),trigger_prop(Prop),do_queue), [Q0], _) ). neq_index([], _). neq_index([X|Xs], N) :- neq_num(X, N), N1 is N + 1, neq_index(Xs, N1). /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Necessary condition for existence of a Hamiltonian circuit: The graph has a single strongly connected component. If the list is ground, the condition is also sufficient. Ts are used as temporary variables to attach attributes: lowlink, index: used for SCC [arc_to(V)]: possible successors - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ propagate_circuit(Vs) :- with_local_attributes([], (same_length(Vs, Ts), circuit_graph(Vs, Ts, Ts), scc(Ts, circuit_successors), maplist(single_component, Ts)), _). single_component(V) :- get_attr(V, lowlink, 0). circuit_graph([], _, _). circuit_graph([V|Vs], Ts0, [T|Ts]) :- ( nonvar(V) -> Ns = [V] ; fd_get(V, Dom, _), domain_to_list(Dom, Ns) ), phrase(circuit_edges(Ns, Ts0), Es), put_attr(T, edges, Es), circuit_graph(Vs, Ts0, Ts). circuit_edges([], _) --> []. circuit_edges([N|Ns], Ts) --> { nth1(N, Ts, T) }, [arc_to(T)], circuit_edges(Ns, Ts). circuit_successors(V, Tos) :- get_attr(V, edges, Tos0), maplist(arg(1), Tos0, Tos). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% cumulative(+Tasks) % % Equivalent to cumulative(Tasks, [limit(1)]). cumulative(Tasks) :- cumulative(Tasks, [limit(1)]). %% cumulative(+Tasks, +Options) % % Schedule with a limited resource. Tasks is a list of tasks, each of % the form task(S_i, D_i, E_i, C_i, T_i). S_i denotes the start time, % D_i the positive duration, E_i the end time, C_i the non-negative % resource consumption, and T_i the task identifier. Each of these % arguments must be a finite domain variable with bounded domain, or % an integer. The constraint holds iff at each time slot during the % start and end of each task, the total resource consumption of all % tasks running at that time does not exceed the global resource % limit. Options is a list of options. Currently, the only supported % option is: % % * limit(L) % The integer L is the global resource limit. Default is 1. % % For example, given the following predicate that relates three tasks % of durations 2 and 3 to a list containing their starting times: % % ``` % tasks_starts(Tasks, [S1,S2,S3]) :- % Tasks = [task(S1,3,_,1,_), % task(S2,2,_,1,_), % task(S3,2,_,1,_)]. % ``` % % We can use cumulative/2 as follows, and obtain a schedule: % % ``` % ?- tasks_starts(Tasks, Starts), Starts ins 0..10, % cumulative(Tasks, [limit(2)]), label(Starts). % Tasks = [task(0, 3, 3, 1, _G36), task(0, 2, 2, 1, _G45), ...], % Starts = [0, 0, 2] . % ``` cumulative(Tasks, Options) :- must_be(list(list), [Tasks,Options]), ( Options = [] -> L = 1 ; Options = [limit(L)] -> must_be(integer, L) ; domain_error(cumulative_options_empty_or_limit, Options) ), ( Tasks = [] -> true ; fully_elastic_relaxation(Tasks, L), maplist(task_bs, Tasks, Bss), maplist(arg(1), Tasks, Starts), maplist(fd_inf, Starts, MinStarts), maplist(arg(3), Tasks, Ends), maplist(fd_sup, Ends, MaxEnds), MinStarts = [Min|Mins], foldl(min_, Mins, Min, Start), MaxEnds = [Max|Maxs], foldl(max_, Maxs, Max, End), resource_limit(Start, End, Tasks, Bss, L) ). /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Trivial lower and upper bounds, assuming no gaps and not necessarily retaining the rectangular shape of each task. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ fully_elastic_relaxation(Tasks, Limit) :- maplist(task_duration_consumption, Tasks, Ds, Cs), maplist(area, Ds, Cs, As), sum(As, #=, #Area), #MinTime #= (Area + Limit - 1) // Limit, tasks_minstart_maxend(Tasks, MinStart, MaxEnd), MaxEnd #>= MinStart + MinTime. task_duration_consumption(task(_,D,_,C,_), D, C). area(X, Y, Area) :- #Area #= #X * #Y. tasks_minstart_maxend(Tasks, Start, End) :- maplist(task_start_end, Tasks, [Start0|Starts], [End0|Ends]), foldl(min_, Starts, Start0, Start), foldl(max_, Ends, End0, End). max_(E, M0, M) :- #M #= max(E, M0). min_(E, M0, M) :- #M #= min(E, M0). task_start_end(task(Start,_,End,_,_), #Start, #End). /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - All time slots must respect the resource limit. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ resource_limit(T, T, _, _, _) :- !. resource_limit(T0, T, Tasks, Bss, L) :- maplist(contribution_at(T0), Tasks, Bss, Cs), sum(Cs, #=<, L), T1 is T0 + 1, resource_limit(T1, T, Tasks, Bss, L). task_bs(Task, InfStart-Bs) :- Task = task(Start,D,End,_,_Id), #D #> 0, #End #= #Start + #D, maplist(finite_domain, [End,Start,D]), fd_inf(Start, InfStart), fd_sup(End, SupEnd), L is SupEnd - InfStart, length(Bs, L), task_running(Bs, Start, End, InfStart). task_running([], _, _, _). task_running([B|Bs], Start, End, T) :- ((T #>= Start) #/\ (T #< End)) #<==> #B, T1 is T + 1, task_running(Bs, Start, End, T1). contribution_at(T, Task, Offset-Bs, Contribution) :- Task = task(Start,_,End,C,_), #C #>= 0, fd_inf(Start, InfStart), fd_sup(End, SupEnd), ( T < InfStart -> Contribution = 0 ; T >= SupEnd -> Contribution = 0 ; Index is T - Offset, nth0(Index, Bs, B), #Contribution #= B*C ). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% disjoint2(+Rectangles) % % True iff Rectangles are not overlapping. Rectangles is a list of % terms of the form F(X_i, W_i, Y_i, H_i), where F is any functor, % and the arguments are finite domain variables or integers that % denote, respectively, the X coordinate, width, Y coordinate and % height of each rectangle. disjoint2(Rs0) :- must_be(list, Rs0), maplist(=.., Rs0, Rs), non_overlapping(Rs). non_overlapping([]). non_overlapping([R|Rs]) :- maplist(non_overlapping_(R), Rs), non_overlapping(Rs). non_overlapping_(A, B) :- a_not_in_b(A, B), a_not_in_b(B, A). a_not_in_b([_,AX,AW,AY,AH], [_,BX,BW,BY,BH]) :- #AX #=< #BX #/\ #BX #< #AX + #AW #==> #AY + #AH #=< #BY #\/ #BY + #BH #=< #AY, #AY #=< #BY #/\ #BY #< #AY + #AH #==> #AX + #AW #=< #BX #\/ #BX + #BW #=< #AX. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% automaton(+Vs, +Nodes, +Arcs) % % Describes a list of finite domain variables with a finite % automaton. Equivalent to automaton(Vs, _, Vs, Nodes, Arcs, % [], [], _), a common use case of automaton/8. In the following % example, a list of binary finite domain variables is constrained to % contain at least two consecutive ones: % % ``` % two_consecutive_ones(Vs) :- % automaton(Vs, [source(a),sink(c)], % [arc(a,0,a), arc(a,1,b), % arc(b,0,a), arc(b,1,c), % arc(c,0,c), arc(c,1,c)]). % ``` % % Example query: % % ``` % ?- length(Vs, 3), two_consecutive_ones(Vs), label(Vs). % Vs = [0,1,1] % ; Vs = [1,1,0] % ; Vs = [1,1,1] % ; false. % ``` automaton(Sigs, Ns, As) :- automaton(_, _, Sigs, Ns, As, [], [], _). %% automaton(+Sequence, ?Template, +Signature, +Nodes, +Arcs, +Counters, +Initials, ?Finals) % % Describes a list of finite domain variables with a finite % automaton. True iff the finite automaton induced by Nodes and Arcs % (extended with Counters) accepts Signature. Sequence is a list of % terms, all of the same shape. Additional constraints must link % Sequence to Signature, if necessary. Nodes is a list of % source(Node) and sink(Node) terms. Arcs is a list of % arc(Node,Integer,Node) and arc(Node,Integer,Node,Exprs) terms that % denote the automaton's transitions. Each node is represented by an % arbitrary term. Transitions that are not mentioned go to an % implicit failure node. `Exprs` is a list of arithmetic expressions, % of the same length as Counters. In each expression, variables % occurring in Counters symbolically refer to previous counter % values, and variables occurring in Template refer to the current % element of Sequence. When a transition containing arithmetic % expressions is taken, each counter is updated according to the % result of the corresponding expression. When a transition without % arithmetic expressions is taken, all counters remain unchanged. % Counters is a list of variables. Initials is a list of finite % domain variables or integers denoting, in the same order, the % initial value of each counter. These values are related to Finals % according to the arithmetic expressions of the taken transitions. % % The following example is taken from Beldiceanu, Carlsson, Debruyne % and Petit: "Reformulation of Global Constraints Based on % Constraints Checkers", Constraints 10(4), pp 339-362 (2005). It % relates a sequence of integers and finite domain variables to its % number of inflexions, which are switches between strictly ascending % and strictly descending subsequences: % % ``` % sequence_inflexions(Vs, N) :- % variables_signature(Vs, Sigs), % automaton(Sigs, _, Sigs, % [source(s),sink(i),sink(j),sink(s)], % [arc(s,0,s), arc(s,1,j), arc(s,2,i), % arc(i,0,i), arc(i,1,j,[C+1]), arc(i,2,i), % arc(j,0,j), arc(j,1,j), % arc(j,2,i,[C+1])], % [C], [0], [N]). % % variables_signature([], []). % variables_signature([V|Vs], Sigs) :- % variables_signature_(Vs, V, Sigs). % % variables_signature_([], _, []). % variables_signature_([V|Vs], Prev, [S|Sigs]) :- % V #= Prev #<==> S #= 0, % Prev #< V #<==> S #= 1, % Prev #> V #<==> S #= 2, % variables_signature_(Vs, V, Sigs). % ``` % % Example queries: % % ``` % ?- sequence_inflexions([1,2,3,3,2,1,3,0], N). % N = 3. % % ?- length(Ls, 5), Ls ins 0..1, % sequence_inflexions(Ls, 3), label(Ls). % Ls = [0, 1, 0, 1, 0] ; % Ls = [1, 0, 1, 0, 1]. % ``` template_var_path(V, Var, []) :- var(V), !, V == Var. template_var_path(T, Var, [N|Ns]) :- arg(N, T, Arg), template_var_path(Arg, Var, Ns). path_term_variable([], V, V). path_term_variable([P|Ps], T, V) :- arg(P, T, Arg), path_term_variable(Ps, Arg, V). initial_expr(_, []-1). automaton(Seqs, Template, Sigs, Ns, As0, Cs, Is, Fs) :- must_be(list(list), [Sigs,Ns,As0,Cs,Is]), ( var(Seqs) -> ( monotonic -> instantiation_error(Seqs) ; Seqs = Sigs ) ; must_be(list, Seqs) ), maplist(monotonic, Cs, CsM), maplist(arc_normalized(CsM), As0, As), include_args1(sink, Ns, Sinks), include_args1(source, Ns, Sources), maplist(initial_expr, Cs, Exprs0), phrase((arcs_relation(As, Relation), nodes_nums(Sinks, SinkNums0), nodes_nums(Sources, SourceNums0)), [s([]-0, Exprs0)], [s(_,Exprs1)]), maplist(expr0_expr, Exprs1, Exprs), phrase(transitions(Seqs, Template, Sigs, Start, End, Exprs, Cs, Is, Fs), Tuples), list_to_drep(SourceNums0, SourceDrep), Start in SourceDrep, list_to_drep(SinkNums0, SinkDrep), End in SinkDrep, tuples_in(Tuples, Relation). expr0_expr(Es0-_, Es) :- pairs_keys(Es0, Es1), reverse(Es1, Es). transitions([], _, [], S, S, _, _, Cs, Cs) --> []. transitions([Seq|Seqs], Template, [Sig|Sigs], S0, S, Exprs, Counters, Cs0, Cs) --> [[S0,Sig,S1|Is]], { phrase(exprs_next(Exprs, Is, Cs1), [s(Seq,Template,Counters,Cs0)], _) }, transitions(Seqs, Template, Sigs, S1, S, Exprs, Counters, Cs1, Cs). exprs_next([], [], []) --> []. exprs_next([Es|Ess], [I|Is], [C|Cs]) --> exprs_values(Es, Vs), { element(I, Vs, C) }, exprs_next(Ess, Is, Cs). exprs_values([], []) --> []. exprs_values([E0|Es], [V|Vs]) --> { term_variables(E0, EVs0), copy_term(E0, E), term_variables(E, EVs), #V #= E }, match_variables(EVs0, EVs), exprs_values(Es, Vs). match_variables([], _) --> []. match_variables([V0|Vs0], [V|Vs]) --> state(s(Seq,Template,Counters,Cs0)), { ( template_var_path(Template, V0, Ps) -> path_term_variable(Ps, Seq, V) ; template_var_path(Counters, V0, Ps) -> path_term_variable(Ps, Cs0, V) ; domain_error(variable_from_template_or_counters, V0) ) }, match_variables(Vs0, Vs). nodes_nums([], []) --> []. nodes_nums([Node|Nodes], [Num|Nums]) --> node_num(Node, Num), nodes_nums(Nodes, Nums). arcs_relation([], []) --> []. arcs_relation([arc(S0,L,S1,Es)|As], [[From,L,To|Ns]|Rs]) --> node_num(S0, From), node_num(S1, To), state(s(Nodes, Exprs0), s(Nodes, Exprs)), { exprs_nums(Es, Ns, Exprs0, Exprs) }, arcs_relation(As, Rs). exprs_nums([], [], [], []). exprs_nums([E|Es], [N|Ns], [Ex0-C0|Exs0], [Ex-C|Exs]) :- ( member(Exp-N, Ex0), Exp == E -> C = C0, Ex = Ex0 ; N = C0, C is C0 + 1, Ex = [E-C0|Ex0] ), exprs_nums(Es, Ns, Exs0, Exs). node_num(Node, Num) --> state(s(Nodes0-C0, Exprs), s(Nodes-C, Exprs)), { ( member(N-Num, Nodes0), N == Node -> C = C0, Nodes = Nodes0 ; Num = C0, C is C0 + 1, Nodes = [Node-C0|Nodes0] ) }. include_args1(Goal, Ls0, As) :- include(Goal, Ls0, Ls), maplist(arg(1), Ls, As). source(source(_)). sink(sink(_)). monotonic(Var, #Var). arc_normalized(Cs, Arc0, Arc) :- arc_normalized_(Arc0, Cs, Arc). arc_normalized_(arc(S0,L,S,Cs), _, arc(S0,L,S,Cs)). arc_normalized_(arc(S0,L,S), Cs, arc(S0,L,S,Cs)). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% zcompare(?Order, ?A, ?B) % % Analogous to compare/3, with finite domain variables A and B. % % This predicate allows you to make several predicates over integers % deterministic while preserving their generality and completeness. % For example: % % ``` % n_factorial(N, F) :- % zcompare(C, N, 0), % n_factorial_(C, N, F). % % n_factorial_(=, _, 1). % n_factorial_(>, N, F) :- % F #= F0*N, N1 #= N - 1, % n_factorial(N1, F0). % ``` % % This version is deterministic if the first argument is instantiated, % because first argument indexing can distinguish the two different % clauses: % % ``` % ?- n_factorial(30, F). % F = 265252859812191058636308480000000. % ``` % % The predicate can still be used in all directions, including the % most general query: % % ``` % ?- n_factorial(N, F). % N = 0, F = 1 % ; N = 1, F = 1 % ; N = 2, F = 2 % ; ... . % ``` zcompare(Order, A, B) :- ( nonvar(Order) -> zcompare_(Order, A, B) ; integer(A), integer(B) -> compare(Order, A, B) ; freeze(Order, zcompare_(Order, A, B)), fd_variable(A), fd_variable(B), propagator_init_trigger([A,B], pzcompare(Order, A, B)) ). zcompare_(O, A, B) :- ( member(O, "<=>") -> true ; domain_error(order, O, zcompare/3) ), zcompare__(O, A, B). zcompare__(=, A, B) :- #A #= #B. zcompare__(<, A, B) :- #A #< #B. zcompare__(>, A, B) :- #A #> #B. %% chain(+Relation, +Zs) % % Zs form a chain with respect to Relation. Zs is a list of finite % domain variables that are a chain with respect to the partial order % Relation, in the order they appear in the list. Relation must be #=, % #=<, #>=, #< or #>. For example: % % ``` % ?- chain(#>=, [X,Y,Z]). % X#>=Y, % Y#>=Z. % ``` chain(Relation, Zs) :- must_be(list, Zs), maplist(fd_variable, Zs), must_be(ground, Relation), ( chain_relation(Relation) -> true ; domain_error(chain_relation, Relation) ), chain_(Zs, Relation). chain_([], _). chain_([X|Xs], Relation) :- foldl(chain(Relation), Xs, X, _). chain_relation(#=). chain_relation(#<). chain_relation(#=<). chain_relation(#>). chain_relation(#>=). chain(Relation, X, Prev, X) :- call(Relation, #Prev, #X). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Reflection predicates - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ %% fd_var(+Var) % % True iff Var is a CLP(ℤ) variable. fd_var(X) :- get_attr(X, clpz, _). %% fd_inf(+Var, -Inf) % % Inf is the infimum of the current domain of Var. fd_inf(X, Inf) :- ( fd_get(X, XD, _) -> domain_infimum(XD, Inf0), bound_portray(Inf0, Inf) ; must_be(integer, X), Inf = X ). %% fd_sup(+Var, -Sup) % % Sup is the supremum of the current domain of Var. fd_sup(X, Sup) :- ( fd_get(X, XD, _) -> domain_supremum(XD, Sup0), bound_portray(Sup0, Sup) ; must_be(integer, X), Sup = X ). %% fd_size(+Var, -Size) % % Size is the number of elements of the current domain of Var, or the % atom *sup* if the domain is unbounded. fd_size(X, S) :- ( fd_get(X, XD, _) -> domain_num_elements(XD, S0), bound_portray(S0, S) ; must_be(integer, X), S = 1 ). %% fd_dom(+Var, -Dom) % % Dom is the current domain (see `(in)/2`) of Var. This predicate is % useful if you want to reason about domains. It is _not_ needed if % you only want to display remaining domains; instead, separate your % model from the search part and let the toplevel display this % information via residual goals. % % For example, to implement a custom labeling strategy, you may need % to inspect the current domain of a finite domain variable. With the % following code, you can convert a _finite_ domain to a list of % integers: % % ``` % dom_integers(D, Is) :- phrase(dom_integers_(D), Is). % % dom_integers_(I) --> { integer(I) }, [I]. % dom_integers_(L..U) --> { numlist(L, U, Is) }, Is. % dom_integers_(D1\/D2) --> dom_integers_(D1), dom_integers_(D2). % ``` % % Example: % % ``` % ?- X in 1..5, X #\= 4, fd_dom(X, D), dom_integers(D, Is). % D = 1..3\/5, % Is = [1,2,3,5], % X in 1..3\/5. % ``` fd_dom(X, Drep) :- ( fd_get(X, XD, _) -> domain_to_drep(XD, Drep) ; must_be(integer, X), Drep = X..X ). /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Entailment detection. Subject to change. Currently, Goals entail E if posting ({#\ E} U Goals), then labeling all variables, fails. E must be reifiable. Examples: %?- clpz:goals_entail([X#>2], X #> 3). %@ false. %?- clpz:goals_entail([X#>1, X#<3], X #= 2). %@ true. %?- clpz:goals_entail([X#=Y+1], X #= Y+1). %@ ERROR: Arguments are not sufficiently instantiated %@ Exception: (15) throw(error(instantiation_error, _G2680)) ? %?- clpz:goals_entail([[X,Y] ins 0..10, X#=Y+1], X #= Y+1). %@ true. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ goals_entail(Goals, E) :- must_be(list, Goals), \+ ( maplist(call, Goals), #\ E, term_variables(Goals-E, Vs), label(Vs) ). /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Unification hook and constraint projection - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ verify_attributes(Var, Other, Gs) :- % portray_clause(Var = Other), ( get_atts(Var, clpz(CLPZ)) -> CLPZ = clpz_attr(_,_,_,Dom,Ps,Q), ( nonvar(Other) -> ( integer(Other) -> true ; type_error(integer, Other) ), domain_contains(Dom, Other), phrase(trigger_props(Ps), [Q], [_]), Gs = [phrase(do_queue, [Q], _)] ; ( get_atts(Other, clpz(clpz_attr(_,_,_,OD,OPs,_))) -> domains_intersection(OD, Dom, Dom1), append_propagators(Ps, OPs, Ps1), new_queue(Q0), variables_same_queue([Var,Other]), phrase((fd_put(Other,Dom1,Ps1), trigger_props(Ps1)), [Q0], _), Gs = [phrase(do_queue, [Q0], _)] ; put_atts(Other, clpz(CLPZ)), Gs = [] ) ) ; Gs = [] ). append_propagators(fd_props(Gs0,Bs0,Os0), fd_props(Gs1,Bs1,Os1), fd_props(Gs,Bs,Os)) :- maplist(append, [Gs0,Bs0,Os0], [Gs1,Bs1,Os1], [Gs,Bs,Os]). bound_portray(inf, inf). bound_portray(sup, sup). bound_portray(n(N), N). list_to_drep(List, Drep) :- list_to_domain(List, Dom), domain_to_drep(Dom, Drep). domain_to_drep(Dom, Drep) :- domain_intervals(Dom, [A0-B0|Rest]), bound_portray(A0, A), bound_portray(B0, B), ( A == B -> Drep0 = A ; Drep0 = A..B ), intervals_to_drep(Rest, Drep0, Drep). intervals_to_drep([], Drep, Drep). intervals_to_drep([A0-B0|Rest], Drep0, Drep) :- bound_portray(A0, A), bound_portray(B0, B), ( A == B -> D1 = A ; D1 = A..B ), intervals_to_drep(Rest, Drep0 \/ D1, Drep). attribute_goals(X) --> % { get_attr(X, clpz, Attr), format("A: ~w\n", [Attr]) }, { get_attr(X, clpz, clpz_attr(_,_,_,Dom,fd_props(Gs,Bs,Os),_)), append(Gs, Bs, Ps0), append(Ps0, Os, Ps), domain_to_drep(Dom, Drep) }, ( { default_domain(Dom), \+ all_dead_(Ps) } -> [] ; [clpz:(X in Drep)] ), attributes_goals(Ps), { del_attr(X, clpz) }. attributes_goals([]) --> []. attributes_goals([propagator(P, State)|As]) --> ( { ground(State) } -> [] ; { phrase(attribute_goal_(P), Gs) } -> { del_attr(State, clpz_aux), State = processed, ( monotonic -> maplist(unwrap_with(bare_integer), Gs, Gs1) ; maplist(unwrap_with(=), Gs, Gs1) ), maplist(with_clpz, Gs1, Gs2) }, seq(Gs2) ; [P] % possibly user-defined constraint ), attributes_goals(As). with_clpz(G, clpz:G). unwrap_with(_, V, V) :- var(V), !. unwrap_with(Goal, #V0, V) :- !, call(Goal, V0, V). unwrap_with(Goal, Term0, Term) :- Term0 =.. [F|Args0], maplist(unwrap_with(Goal), Args0, Args), Term =.. [F|Args]. bare_integer(V0, V) :- ( integer(V0) -> V = V0 ; V = #V0 ). attribute_goal_(presidual(Goal)) --> [Goal]. attribute_goal_(pgeq(A,B)) --> [#A #>= #B]. attribute_goal_(pplus(X,Y,Z,_)) --> [#X + #Y #= #Z]. attribute_goal_(pneq(A,B)) --> [#A #\= #B]. attribute_goal_(ptimes(X,Y,Z,_)) --> [#X * #Y #= #Z]. attribute_goal_(absdiff_neq(X,Y,C)) --> [abs(#X - #Y) #\= C]. attribute_goal_(x_eq_abs_plus_v(X,V)) --> [#X #= abs(#X) + #V]. attribute_goal_(x_neq_y_plus_z(X,Y,Z)) --> [#X #\= #Y + #Z]. attribute_goal_(x_leq_y_plus_c(X,Y,C)) --> [#X #=< #Y + C]. attribute_goal_(ptzdiv(X,Y,Z,_)) --> [#X // #Y #= #Z]. attribute_goal_(pexp(X,Y,Z,_)) --> [#X ^ #Y #= #Z]. attribute_goal_(psign(X,Y)) --> [#Y #= sign(#X)]. attribute_goal_(pabs(X,Y)) --> [#Y #= abs(#X)]. attribute_goal_(pmod(X,M,K)) --> [#X mod #M #= #K]. attribute_goal_(prem(X,Y,Z)) --> [#X rem #Y #= #Z]. attribute_goal_(pmax(X,Y,Z)) --> [#Z #= max(#X,#Y)]. attribute_goal_(pmin(X,Y,Z)) --> [#Z #= min(#X,#Y)]. attribute_goal_(pxor(X,Y,Z)) --> [#Z #= xor(#X, #Y)]. attribute_goal_(ppopcount(X,Y)) --> [#Y #= popcount(#X)]. attribute_goal_(scalar_product_neq(Cs,Vs,C)) --> [Left #\= Right], { scalar_product_left_right([-1|Cs], [C|Vs], Left, Right) }. attribute_goal_(scalar_product_eq(Cs,Vs,C)) --> [Left #= Right], { scalar_product_left_right([-1|Cs], [C|Vs], Left, Right) }. attribute_goal_(scalar_product_leq(Cs,Vs,C)) --> [Left #=< Right], { scalar_product_left_right([-1|Cs], [C|Vs], Left, Right) }. attribute_goal_(pdifferent(_,_,_,O)) --> original_goal(O). attribute_goal_(weak_distinct(_,_,_,O)) --> original_goal(O). attribute_goal_(pdistinct(Vs)) --> [all_distinct(Vs)]. attribute_goal_(pnvalue(N, Vs)) --> [nvalue(N, Vs)]. attribute_goal_(pexclude(_,_,_)) --> []. attribute_goal_(pelement(N,Is,V)) --> [element(N, Is, V)]. attribute_goal_(pgcc(Vs, Pairs, _)) --> [global_cardinality(Vs, Pairs)]. attribute_goal_(pgcc_single(_,_)) --> []. attribute_goal_(pgcc_check_single(_)) --> []. attribute_goal_(pgcc_check(Pairs)) --> { pairs_values(Pairs, Nums), maplist(gcc_done, Nums) }. attribute_goal_(pcircuit(Vs)) --> [circuit(Vs)]. attribute_goal_(pserialized(_,_,_,_,O)) --> original_goal(O). attribute_goal_(rel_tuple(R, Tuple)) --> { get_attr(R, clpz_relation, Rel) }, [tuples_in([Tuple], Rel)]. attribute_goal_(pzcompare(O,A,B)) --> [zcompare(O,A,B)]. % reified constraints attribute_goal_(reified_in(V, D, B)) --> [V in Drep #<==> #B], { domain_to_drep(D, Drep) }. attribute_goal_(reified_tuple_in(Tuple, R, B)) --> { get_attr(R, clpz_relation, Rel) }, [tuples_in([Tuple], Rel) #<==> #B]. attribute_goal_(kill_reified_tuples(_,_,_)) --> []. attribute_goal_(tuples_not_in(_,_,_)) --> []. attribute_goal_(reified_fd(V,B)) --> [finite_domain(V) #<==> #B]. attribute_goal_(pskeleton(X,Y,D,_,Z,F)) --> { Prop =.. [F,X,Y,Z], phrase(attribute_goal_(Prop), Goals), list_goal(Goals, Goal) }, [#D #= 1 #==> Goal, #Y #\= 0 #==> #D #= 1]. attribute_goal_(reified_neq(DX,X,DY,Y,_,B)) --> conjunction(DX, DY, #X #\= #Y, B). attribute_goal_(reified_eq(DX,X,DY,Y,_,B)) --> conjunction(DX, DY, #X #= #Y, B). attribute_goal_(reified_geq(DX,X,DY,Y,_,B)) --> conjunction(DX, DY, #X #>= #Y, B). attribute_goal_(reified_and(X,_,Y,_,B)) --> [#X #/\ #Y #<==> #B]. attribute_goal_(reified_or(X, _, Y, _, B)) --> [#X #\/ #Y #<==> #B]. attribute_goal_(reified_not(X, Y)) --> [#\ #X #<==> #Y]. attribute_goal_(preified_slash(X, Y, _, R)) --> [#X/ #Y #= R]. attribute_goal_(preified_exp(X, Y, _, R)) --> [#X^ #Y #= R]. attribute_goal_(pimpl(X, Y, _)) --> [#X #==> #Y]. attribute_goal_(pfunction(Op, A, B, R)) --> { Expr =.. [Op,#A,#B] }, [#R #= Expr]. attribute_goal_(pfunction(Op, A, R)) --> { Expr =.. [Op,#A] }, [#R #= Expr]. conjunction(A, B, G, D) --> ( { A == 1, B == 1 } -> [G #<==> #D] ; { A == 1 } -> [(#B #/\ G) #<==> #D] ; { B == 1 } -> [(#A #/\ G) #<==> #D] ; [(#A #/\ #B #/\ G) #<==> #D] ). original_goal(original_goal(State, Goal)) --> ( { var(State) } -> { State = processed }, [Goal] ; [] ). /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Projection of scalar product. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ scalar_product_left_right(Cs, Vs, Left, Right) :- pairs_keys_values(Pairs0, Cs, Vs), partition(ground, Pairs0, Grounds, Pairs), maplist(pair_product, Grounds, Prods), sum_list(Prods, Const), NConst is -Const, partition(compare_coeff0, Pairs, Negatives, _, Positives), maplist(negate_coeff, Negatives, Rights), scalar_plusterm(Rights, Right0), scalar_plusterm(Positives, Left0), ( Const =:= 0 -> Left = Left0, Right = Right0 ; Right0 == 0 -> Left = Left0, Right = NConst ; Left0 == 0 -> Left = Const, Right = Right0 ; ( Const < 0 -> Left = Left0, Right = Right0+NConst ; Left = Left0+Const, Right = Right0 ) ). negate_coeff(A0-B, A-B) :- A is -A0. pair_product(A-B, Prod) :- Prod is A*B. compare_coeff0(Coeff-_, Compare) :- compare(Compare, Coeff, 0). scalar_plusterm([], 0). scalar_plusterm([CV|CVs], T) :- coeff_var_term(CV, T0), foldl(plusterm_, CVs, T0, T). plusterm_(CV, T0, T0+T) :- coeff_var_term(CV, T). coeff_var_term(C-V, T) :- ( C =:= 1 -> T = #V ; T = C * #V ). /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Reified predicates for use with predicates from library(reif). - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ clpz_t(Expr, T) :- Expr #<==> #B, zo_t(B, T). #=(X, Y, T) :- clpz_t(X #= Y, T). #<(X, Y, T) :- clpz_t(X #< Y, T). zo_t(0, false). zo_t(1, true). /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Generated predicates - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ term_expansion(make_parse_clpz, Clauses) :- make_parse_clpz(Clauses). term_expansion(make_parse_reified, Clauses) :- make_parse_reified(Clauses). term_expansion(make_matches, Clauses) :- make_matches(Clauses). make_parse_clpz. make_parse_reified. make_matches. >:- module(curl, [ curl_easy_init/1, curl_easy_setopt/4, curl_easy_perform/2, curl_easy_cleanup/1 ]). :- use_foreign_module('libcurl.so', [ curl_easy_init([], ptr), curl_easy_setopt([ptr,uint,ptr], sint), curl_easy_perform([ptr], sint), curl_easy_cleanup([ptr], void) ]). % Zero return status means everything was ok, non-zero means an error occured. curlopt(xCURLOPT_WRITEDATA, xCURLOPTTYPE_CBPOINT, 10001) :- !. % HACK curlopt(xCURLOPT_URL, xCURLOPTTYPE_STRINGPOINT, 10002) :- !. % HACK curlopt(xCURLOPT_READDATA, xCURLOPTTYPE_CBPOINT, 10009) :- !. % HACK curlopt(xCURLOPT_REFERER, xCURLOPTTYPE_STRINGPOINT, 10016) :- !. % HACK curlopt(xCURLOPT_USERAGENT, xCURLOPTTYPE_STRINGPOINT, 10018) :- !. % HACK curlopt(xCURLOPT_COOKIE, xCURLOPTTYPE_STRINGPOINT, 10022) :- !. % HACK curlopt(xCURLOPT_TIMEOUT, xCURLOPTTYPE_LONG, 13) :- !. % HACK curlopt(xCURLOPT_VERBOSE, xCURLOPTTYPE_LONG, 41) :- !. % HACK curlopt(xCURLOPT_NOBODY, xCURLOPTTYPE_LONG, 44) :- !. % HACK curlopt(xCURLOPT_POST, xCURLOPTTYPE_LONG, 47) :- !. % HACK curlopt(xCURLOPT_PUT, xCURLOPTTYPE_LONG, 54) :- !. % HACK % TODO: fix this... /* This is the FILE * or void * the regular output should be written to. */ curlopt(xCURLOPT_WRITEDATA, xCURLOPTTYPE_CBPOINT, 1). /* The full URL to get/put */ curlopt(xCURLOPT_URL, xCURLOPTTYPE_STRINGPOINT, 2). /* Port number to connect to, if other than default. */ curlopt(xCURLOPT_PORT, xCURLOPTTYPE_LONG, 3). /* Name of proxy to use. */ curlopt(xCURLOPT_PROXY, xCURLOPTTYPE_STRINGPOINT, 4). /* "user:password;options" to use when fetching. */ curlopt(xCURLOPT_USERPWD, xCURLOPTTYPE_STRINGPOINT, 5). /* "user:password" to use with proxy. */ curlopt(xCURLOPT_PROXYUSERPWD, xCURLOPTTYPE_STRINGPOINT, 6). /* Range to get, specified as an ASCII string. */ curlopt(xCURLOPT_RANGE, xCURLOPTTYPE_STRINGPOINT, 7). /* not used */ /* Specified file stream to upload from (use as input): */ curlopt(xCURLOPT_READDATA, xCURLOPTTYPE_CBPOINT, 9). /* Buffer to receive error messages in, must be at least CURL_ERROR_SIZE * bytes big. */ curlopt(xCURLOPT_ERRORBUFFER, xCURLOPTTYPE_OBJECTPOINT, 10). /* Function that will be called to store the output (instead of fwrite). The * parameters will use fwrite() syntax, make sure to follow them. */ curlopt(xCURLOPT_WRITEFUNCTION, xCURLOPTTYPE_FUNCTIONPOINT, 11). /* Function that will be called to read the input (instead of fread). The * parameters will use fread() syntax, make sure to follow them. */ curlopt(xCURLOPT_READFUNCTION, xCURLOPTTYPE_FUNCTIONPOINT, 12). /* Time-out the read operation after this amount of seconds */ curlopt(xCURLOPT_TIMEOUT, xCURLOPTTYPE_LONG, 13). /* If the xCURLOPT_INFILE is used, this can be used to inform libcurl about * how large the file being sent really is. That allows better error * checking and better verifies that the upload was successful. -1 means * unknown size. * * For large file support, there is also a _LARGE version of the key * which takes an off_t type, allowing platforms with larger off_t * sizes to handle larger files. See below for INFILESIZE_LARGE. */ curlopt(xCURLOPT_INFILESIZE, xCURLOPTTYPE_LONG, 14). /* POST static input fields. */ curlopt(xCURLOPT_POSTFIELDS, xCURLOPTTYPE_OBJECTPOINT, 15). /* Set the referrer page (needed by some CGIs) */ curlopt(xCURLOPT_REFERER, xCURLOPTTYPE_STRINGPOINT, 16). /* Set the FTP PORT string (interface name, named or numerical IP address) Use i.e '-' to use default address. */ curlopt(xCURLOPT_FTPPORT, xCURLOPTTYPE_STRINGPOINT, 17). /* Set the User-Agent string (examined by some CGIs) */ curlopt(xCURLOPT_USERAGENT, xCURLOPTTYPE_STRINGPOINT, 18). /* If the download receives less than "low speed limit" bytes/second * during "low speed time" seconds, the operations is aborted. * You could i.e if you have a pretty high speed connection, abort if * it is less than 2000 bytes/sec during 20 seconds. */ /* Set the "low speed limit" */ curlopt(xCURLOPT_LOW_SPEED_LIMIT, xCURLOPTTYPE_LONG, 19). /* Set the "low speed time" */ curlopt(xCURLOPT_LOW_SPEED_TIME, xCURLOPTTYPE_LONG, 20). /* Set the continuation offset. * * Note there is also a _LARGE version of this key which uses * off_t types, allowing for large file offsets on platforms which * use larger-than-32-bit off_t's. Look below for RESUME_FROM_LARGE. */ curlopt(xCURLOPT_RESUME_FROM, xCURLOPTTYPE_LONG, 21). /* Set cookie in request: */ curlopt(xCURLOPT_COOKIE, xCURLOPTTYPE_STRINGPOINT, 22). /* This points to a linked list of headers, struct curl_slist kind. This list is also used for RTSP (in spite of its name) */ curlopt(xCURLOPT_HTTPHEADER, xCURLOPTTYPE_SLISTPOINT, 23). /* This points to a linked list of post entries, struct curl_httppost */ curlopt(xCURLOPT_HTTPPOST, xCURLOPTTYPE_OBJECTPOINT, 24). /* name of the file keeping your private SSL-certificate */ curlopt(xCURLOPT_SSLCERT, xCURLOPTTYPE_STRINGPOINT, 25). /* password for the SSL or SSH private key */ curlopt(xCURLOPT_KEYPASSWD, xCURLOPTTYPE_STRINGPOINT, 26). /* send TYPE parameter? */ curlopt(xCURLOPT_CRLF, xCURLOPTTYPE_LONG, 27). /* send linked-list of QUOTE commands */ curlopt(xCURLOPT_QUOTE, xCURLOPTTYPE_SLISTPOINT, 28). /* send FILE * or void * to store headers to, if you use a callback it is simply passed to the callback unmodified */ curlopt(xCURLOPT_HEADERDATA, xCURLOPTTYPE_CBPOINT, 29). /* point to a file to read the initial cookies from, also enables "cookie awareness" */ curlopt(xCURLOPT_COOKIEFILE, xCURLOPTTYPE_STRINGPOINT, 31). /* What version to specifically try to use. See CURL_SSLVERSION defines below. */ curlopt(xCURLOPT_SSLVERSION, xCURLOPTTYPE_VALUES, 32). /* What kind of HTTP time condition to use, see defines */ curlopt(xCURLOPT_TIMECONDITION, xCURLOPTTYPE_VALUES, 33). /* Time to use with the above condition. Specified in number of seconds since 1 Jan 1970 */ curlopt(xCURLOPT_TIMEVALUE, xCURLOPTTYPE_LONG, 34). /* 35 = OBSOLETE */ /* Custom request, for customizing the get command like HTTP: DELETE, TRACE and others FTP: to use a different list command */ curlopt(xCURLOPT_CUSTOMREQUEST, xCURLOPTTYPE_STRINGPOINT, 36). /* FILE handle to use instead of stderr */ curlopt(xCURLOPT_STDERR, xCURLOPTTYPE_OBJECTPOINT, 37). /* 38 is not used */ /* send linked-list of post-transfer QUOTE commands */ curlopt(xCURLOPT_POSTQUOTE, xCURLOPTTYPE_SLISTPOINT, 39). /* OBSOLETE, do not use! */ curlopt(xCURLOPT_OBSOLETE40, xCURLOPTTYPE_OBJECTPOINT, 40). /* talk a lot */ curlopt(xCURLOPT_VERBOSE, xCURLOPTTYPE_LONG, 41). /* throw the header out too */ curlopt(xCURLOPT_HEADER, xCURLOPTTYPE_LONG, 42). /* shut off the progress meter */ curlopt(xCURLOPT_NOPROGRESS, xCURLOPTTYPE_LONG, 43). /* use HEAD to get http document */ curlopt(xCURLOPT_NOBODY, xCURLOPTTYPE_LONG, 44). /* no output on http error codes >= 400 */ curlopt(xCURLOPT_FAILONERROR, xCURLOPTTYPE_LONG, 45). /* this is an upload */ curlopt(xCURLOPT_UPLOAD, xCURLOPTTYPE_LONG, 46). /* HTTP POST method */ curlopt(xCURLOPT_POST, xCURLOPTTYPE_LONG, 47). /* bare names when listing directories */ curlopt(xCURLOPT_DIRLISTONLY, xCURLOPTTYPE_LONG, 48). /* Append instead of overwrite on upload! */ curlopt(xCURLOPT_APPEND, xCURLOPTTYPE_LONG, 50). /* Specify whether to read the user+password from the .netrc or the URL. * This must be one of the CURL_NETRC_* enums below. */ curlopt(xCURLOPT_NETRC, xCURLOPTTYPE_VALUES, 51). /* use Location: Luke! */ curlopt(xCURLOPT_FOLLOWLOCATION, xCURLOPTTYPE_LONG, 52). /* transfer data in text/ASCII format */ curlopt(xCURLOPT_TRANSFERTEXT, xCURLOPTTYPE_LONG, 53). /* HTTP PUT */ curlopt(xCURLOPT_PUT, xCURLOPTTYPE_LONG, 54). /* 55 = OBSOLETE */ /* DEPRECATED * Function that will be called instead of the internal progress display * function. This function should be defined as the curl_progress_callback * prototype defines. */ curlopt(xCURLOPT_PROGRESSFUNCTION, xCURLOPTTYPE_FUNCTIONPOINT, 56). /* Data passed to the xCURLOPT_PROGRESSFUNCTION and xCURLOPT_XFERINFOFUNCTION callbacks */ curlopt(xCURLOPT_XFERINFODATA, xCURLOPTTYPE_CBPOINT, 57). curlopt(xCURLOPT_PROGRESSDATA, xCURLOPTTYPE_CBPOINT, 57). /* We want the referrer field set automatically when following locations */ curlopt(xCURLOPT_AUTOREFERER, xCURLOPTTYPE_LONG, 58). /* Port of the proxy, can be set in the proxy string as well with: "[host]:[port]" */ curlopt(xCURLOPT_PROXYPORT, xCURLOPTTYPE_LONG, 59). /* size of the POST input data, if strlen() is not good to use */ curlopt(xCURLOPT_POSTFIELDSIZE, xCURLOPTTYPE_LONG, 60). /* tunnel non-http operations through a HTTP proxy */ curlopt(xCURLOPT_HTTPPROXYTUNNEL, xCURLOPTTYPE_LONG, 61). /* Set the interface string to use as outgoing network interface */ curlopt(xCURLOPT_INTERFACE, xCURLOPTTYPE_STRINGPOINT, 62). /* Set the krb4/5 security level, this also enables krb4/5 awareness. This * is a string, 'clear', 'safe', 'confidential' or 'private'. If the string * is set but doesn't match one of these, 'private' will be used. */ curlopt(xCURLOPT_KRBLEVEL, xCURLOPTTYPE_STRINGPOINT, 63). /* Set if we should verify the peer in ssl handshake, set 1 to verify. */ curlopt(xCURLOPT_SSL_VERIFYPEER, xCURLOPTTYPE_LONG, 64). /* The CApath or CAfile used to validate the peer certificate this option is used only if SSL_VERIFYPEER is true */ curlopt(xCURLOPT_CAINFO, xCURLOPTTYPE_STRINGPOINT, 65). /* 66 = OBSOLETE */ /* 67 = OBSOLETE */ /* Maximum number of http redirects to follow */ curlopt(xCURLOPT_MAXREDIRS, xCURLOPTTYPE_LONG, 68). /* Pass a long set to 1 to get the date of the requested document (if possible)! Pass a zero to shut it off. */ curlopt(xCURLOPT_FILETIME, xCURLOPTTYPE_LONG, 69). /* This points to a linked list of telnet options */ curlopt(xCURLOPT_TELNETOPTIONS, xCURLOPTTYPE_SLISTPOINT, 70). /* Max amount of cached alive connections */ curlopt(xCURLOPT_MAXCONNECTS, xCURLOPTTYPE_LONG, 71). /* OBSOLETE, do not use! */ curlopt(xCURLOPT_OBSOLETE72, xCURLOPTTYPE_LONG, 72). /* 73 = OBSOLETE */ /* Set to explicitly use a new connection for the upcoming transfer. Do not use this unless you're absolutely sure of this, as it makes the operation slower and is less friendly for the network. */ curlopt(xCURLOPT_FRESH_CONNECT, xCURLOPTTYPE_LONG, 74). /* Set to explicitly forbid the upcoming transfer's connection to be re-used when done. Do not use this unless you're absolutely sure of this, as it makes the operation slower and is less friendly for the network. */ curlopt(xCURLOPT_FORBID_REUSE, xCURLOPTTYPE_LONG, 75). /* Set to a file name that contains random data for libcurl to use to seed the random engine when doing SSL connects. */ curlopt(xCURLOPT_RANDOM_FILE, xCURLOPTTYPE_STRINGPOINT, 76). /* Set to the Entropy Gathering Daemon socket pathname */ curlopt(xCURLOPT_EGDSOCKET, xCURLOPTTYPE_STRINGPOINT, 77). /* Time-out connect operations after this amount of seconds, if connects are OK within this time, then fine... This only aborts the connect phase. */ curlopt(xCURLOPT_CONNECTTIMEOUT, xCURLOPTTYPE_LONG, 78). /* Function that will be called to store headers (instead of fwrite). The * parameters will use fwrite() syntax, make sure to follow them. */ curlopt(xCURLOPT_HEADERFUNCTION, xCURLOPTTYPE_FUNCTIONPOINT, 79). /* Set this to force the HTTP request to get back to GET. Only really usable if POST, PUT or a custom request have been used first. */ curlopt(xCURLOPT_HTTPGET, xCURLOPTTYPE_LONG, 80). /* Set if we should verify the Common name from the peer certificate in ssl * handshake, set 1 to check existence, 2 to ensure that it matches the * provided hostname. */ curlopt(xCURLOPT_SSL_VERIFYHOST, xCURLOPTTYPE_LONG, 81). /* Specify which file name to write all known cookies in after completed operation. Set file name to "-" (dash) to make it go to stdout. */ curlopt(xCURLOPT_COOKIEJAR, xCURLOPTTYPE_STRINGPOINT, 82). /* Specify which SSL ciphers to use */ curlopt(xCURLOPT_SSL_CIPHER_LIST, xCURLOPTTYPE_STRINGPOINT, 83). /* Specify which HTTP version to use! This must be set to one of the CURL_HTTP_VERSION* enums set below. */ curlopt(xCURLOPT_HTTP_VERSION, xCURLOPTTYPE_VALUES, 84). /* Specifically switch on or off the FTP engine's use of the EPSV command. By default, that one will always be attempted before the more traditional PASV command. */ curlopt(xCURLOPT_FTP_USE_EPSV, xCURLOPTTYPE_LONG, 85). /* type of the file keeping your SSL-certificate ("DER", "PEM", "ENG") */ curlopt(xCURLOPT_SSLCERTTYPE, xCURLOPTTYPE_STRINGPOINT, 86). /* name of the file keeping your private SSL-key */ curlopt(xCURLOPT_SSLKEY, xCURLOPTTYPE_STRINGPOINT, 87). /* type of the file keeping your private SSL-key ("DER", "PEM", "ENG") */ curlopt(xCURLOPT_SSLKEYTYPE, xCURLOPTTYPE_STRINGPOINT, 88). /* crypto engine for the SSL-sub system */ curlopt(xCURLOPT_SSLENGINE, xCURLOPTTYPE_STRINGPOINT, 89). /* set the crypto engine for the SSL-sub system as default the param has no meaning... */ curlopt(xCURLOPT_SSLENGINE_DEFAULT, xCURLOPTTYPE_LONG, 90). /* Non-zero value means to use the global dns cache */ /* DEPRECATED, do not use! */ curlopt(xCURLOPT_DNS_USE_GLOBAL_CACHE, xCURLOPTTYPE_LONG, 91). /* DNS cache timeout */ curlopt(xCURLOPT_DNS_CACHE_TIMEOUT, xCURLOPTTYPE_LONG, 92). /* send linked-list of pre-transfer QUOTE commands */ curlopt(xCURLOPT_PREQUOTE, xCURLOPTTYPE_SLISTPOINT, 93). /* set the debug function */ curlopt(xCURLOPT_DEBUGFUNCTION, xCURLOPTTYPE_FUNCTIONPOINT, 94). /* set the data for the debug function */ curlopt(xCURLOPT_DEBUGDATA, xCURLOPTTYPE_CBPOINT, 95). /* mark this as start of a cookie session */ curlopt(xCURLOPT_COOKIESESSION, xCURLOPTTYPE_LONG, 96). /* The CApath directory used to validate the peer certificate this option is used only if SSL_VERIFYPEER is true */ curlopt(xCURLOPT_CAPATH, xCURLOPTTYPE_STRINGPOINT, 97). /* Instruct libcurl to use a smaller receive buffer */ curlopt(xCURLOPT_BUFFERSIZE, xCURLOPTTYPE_LONG, 98). /* Instruct libcurl to not use any signal/alarm handlers, even when using timeouts. This option is useful for multi-threaded applications. See libcurl-the-guide for more background information. */ curlopt(xCURLOPT_NOSIGNAL, xCURLOPTTYPE_LONG, 99). /* Provide a CURLShare for mutexing non-ts data */ curlopt(xCURLOPT_SHARE, xCURLOPTTYPE_OBJECTPOINT, 100). /* indicates type of proxy. accepted values are CURLPROXY_HTTP (default). CURLPROXY_HTTPS, CURLPROXY_SOCKS4, CURLPROXY_SOCKS4A and CURLPROXY_SOCKS5. */ curlopt(xCURLOPT_PROXYTYPE, xCURLOPTTYPE_VALUES, 101). /* Set the Accept-Encoding string. Use this to tell a server you would like the response to be compressed. Before 7.21.6, this was known as xCURLOPT_ENCODING */ curlopt(xCURLOPT_ACCEPT_ENCODING, xCURLOPTTYPE_STRINGPOINT, 102). /* Set pointer to private data */ curlopt(xCURLOPT_PRIVATE, xCURLOPTTYPE_OBJECTPOINT, 103). /* Set aliases for HTTP 200 in the HTTP Response header */ curlopt(xCURLOPT_HTTP200ALIASES, xCURLOPTTYPE_SLISTPOINT, 104). /* Continue to send authentication (user+password) when following locations, even when hostname changed. This can potentially send off the name and password to whatever host the server decides. */ curlopt(xCURLOPT_UNRESTRICTED_AUTH, xCURLOPTTYPE_LONG, 105). /* Specifically switch on or off the FTP engine's use of the EPRT command ( it also disables the LPRT attempt). By default, those ones will always be attempted before the good old traditional PORT command. */ curlopt(xCURLOPT_FTP_USE_EPRT, xCURLOPTTYPE_LONG, 106). /* Set this to a bitmask value to enable the particular authentications methods you like. Use this in combination with xCURLOPT_USERPWD. Note that setting multiple bits may cause extra network round-trips. */ curlopt(xCURLOPT_HTTPAUTH, xCURLOPTTYPE_VALUES, 107). /* Set the ssl context callback function, currently only for OpenSSL or WolfSSL ssl_ctx, or mbedTLS mbedtls_ssl_config in the second argument. The function must match the curl_ssl_ctx_callback prototype. */ curlopt(xCURLOPT_SSL_CTX_FUNCTION, xCURLOPTTYPE_FUNCTIONPOINT, 108). /* Set the userdata for the ssl context callback function's third argument */ curlopt(xCURLOPT_SSL_CTX_DATA, xCURLOPTTYPE_CBPOINT, 109). /* FTP Option that causes missing dirs to be created on the remote server. In 7.19.4 we introduced the convenience enums for this option using the CURLFTP_CREATE_DIR prefix. */ curlopt(xCURLOPT_FTP_CREATE_MISSING_DIRS, xCURLOPTTYPE_LONG, 110). /* Set this to a bitmask value to enable the particular authentications methods you like. Use this in combination with xCURLOPT_PROXYUSERPWD. Note that setting multiple bits may cause extra network round-trips. */ curlopt(xCURLOPT_PROXYAUTH, xCURLOPTTYPE_VALUES, 111). /* Option that changes the timeout, in seconds, associated with getting a response. This is different from transfer timeout time and essentially places a demand on the server to acknowledge commands in a timely manner. For FTP, SMTP, IMAP and POP3. */ curlopt(xCURLOPT_SERVER_RESPONSE_TIMEOUT, xCURLOPTTYPE_LONG, 112). /* Set this option to one of the CURL_IPRESOLVE_* defines (see below) to tell libcurl to use those IP versions only. This only has effect on systems with support for more than one, i.e IPv4 _and_ IPv6. */ curlopt(xCURLOPT_IPRESOLVE, xCURLOPTTYPE_VALUES, 113). /* Set this option to limit the size of a file that will be downloaded from an HTTP or FTP server. Note there is also _LARGE version which adds large file support for platforms which have larger off_t sizes. See MAXFILESIZE_LARGE below. */ curlopt(xCURLOPT_MAXFILESIZE, xCURLOPTTYPE_LONG, 114). /* See the comment for INFILESIZE above, but in short, specifies * the size of the file being uploaded. -1 means unknown. */ curlopt(xCURLOPT_INFILESIZE_LARGE, xCURLOPTTYPE_OFF_T, 115). /* Sets the continuation offset. There is also a CURLOPTTYPE_LONG version * of this; look above for RESUME_FROM. */ curlopt(xCURLOPT_RESUME_FROM_LARGE, xCURLOPTTYPE_OFF_T, 116). /* Sets the maximum size of data that will be downloaded from * an HTTP or FTP server. See MAXFILESIZE above for the LONG version. */ curlopt(xCURLOPT_MAXFILESIZE_LARGE, xCURLOPTTYPE_OFF_T, 117). /* Set this option to the file name of your .netrc file you want libcurl to parse (using the xCURLOPT_NETRC option). If not set, libcurl will do a poor attempt to find the user's home directory and check for a .netrc file in there. */ curlopt(xCURLOPT_NETRC_FILE, xCURLOPTTYPE_STRINGPOINT, 118). /* Enable SSL/TLS for FTP, pick one of: CURLUSESSL_TRY - try using SSL, proceed anyway otherwise CURLUSESSL_CONTROL - SSL for the control connection or fail CURLUSESSL_ALL - SSL for all communication or fail */ curlopt(xCURLOPT_USE_SSL, xCURLOPTTYPE_VALUES, 119). /* The _LARGE version of the standard POSTFIELDSIZE option */ curlopt(xCURLOPT_POSTFIELDSIZE_LARGE, xCURLOPTTYPE_OFF_T, 120). /* Enable/disable the TCP Nagle algorithm */ curlopt(xCURLOPT_TCP_NODELAY, xCURLOPTTYPE_LONG, 121). /* 122 OBSOLETE, used in 7.12.3. Gone in 7.13.0 */ /* 123 OBSOLETE. Gone in 7.16.0 */ /* 124 OBSOLETE, used in 7.12.3. Gone in 7.13.0 */ /* 125 OBSOLETE, used in 7.12.3. Gone in 7.13.0 */ /* 126 OBSOLETE, used in 7.12.3. Gone in 7.13.0 */ /* 127 OBSOLETE. Gone in 7.16.0 */ /* 128 OBSOLETE. Gone in 7.16.0 */ /* When FTP over SSL/TLS is selected (with xCURLOPT_USE_SSL). this option can be used to change libcurl's default action which is to first try "AUTH SSL" and then "AUTH TLS" in this order, and proceed when a OK response has been received. Available parameters are: CURLFTPAUTH_DEFAULT - let libcurl decide CURLFTPAUTH_SSL - try "AUTH SSL" first, then TLS CURLFTPAUTH_TLS - try "AUTH TLS" first, then SSL */ curlopt(xCURLOPT_FTPSSLAUTH, xCURLOPTTYPE_VALUES, 129). curlopt(xCURLOPT_IOCTLFUNCTION, xCURLOPTTYPE_FUNCTIONPOINT, 130). curlopt(xCURLOPT_IOCTLDATA, xCURLOPTTYPE_CBPOINT, 131). /* 132 OBSOLETE. Gone in 7.16.0 */ /* 133 OBSOLETE. Gone in 7.16.0 */ /* null-terminated string for pass on to the FTP server when asked for "account" info */ curlopt(xCURLOPT_FTP_ACCOUNT, xCURLOPTTYPE_STRINGPOINT, 134). /* feed cookie into cookie engine */ curlopt(xCURLOPT_COOKIELIST, xCURLOPTTYPE_STRINGPOINT, 135). /* ignore Content-Length */ curlopt(xCURLOPT_IGNORE_CONTENT_LENGTH, xCURLOPTTYPE_LONG, 136). /* Set to non-zero to skip the IP address received in a 227 PASV FTP server response. Typically used for FTP-SSL purposes but is not restricted to that. libcurl will then instead use the same IP address it used for the control connection. */ curlopt(xCURLOPT_FTP_SKIP_PASV_IP, xCURLOPTTYPE_LONG, 137). /* Select "file method" to use when doing FTP, see the curl_ftpmethod above. */ curlopt(xCURLOPT_FTP_FILEMETHOD, xCURLOPTTYPE_VALUES, 138). /* Local port number to bind the socket to */ curlopt(xCURLOPT_LOCALPORT, xCURLOPTTYPE_LONG, 139). /* Number of ports to try, including the first one set with LOCALPORT. Thus, setting it to 1 will make no additional attempts but the first. */ curlopt(xCURLOPT_LOCALPORTRANGE, xCURLOPTTYPE_LONG, 140). /* no transfer, set up connection and let application use the socket by extracting it with CURLINFO_LASTSOCKET */ curlopt(xCURLOPT_CONNECT_ONLY, xCURLOPTTYPE_LONG, 141). /* Function that will be called to convert from the network encoding (instead of using the iconv calls in libcurl) */ curlopt(xCURLOPT_CONV_FROM_NETWORK_FUNCTION, xCURLOPTTYPE_FUNCTIONPOINT, 142). /* Function that will be called to convert to the network encoding (instead of using the iconv calls in libcurl) */ curlopt(xCURLOPT_CONV_TO_NETWORK_FUNCTION, xCURLOPTTYPE_FUNCTIONPOINT, 143). /* Function that will be called to convert from UTF8 (instead of using the iconv calls in libcurl) Note that this is used only for SSL certificate processing */ curlopt(xCURLOPT_CONV_FROM_UTF8_FUNCTION, xCURLOPTTYPE_FUNCTIONPOINT, 144). /* if the connection proceeds too quickly then need to slow it down */ /* limit-rate: maximum number of bytes per second to send or receive */ curlopt(xCURLOPT_MAX_SEND_SPEED_LARGE, xCURLOPTTYPE_OFF_T, 145). curlopt(xCURLOPT_MAX_RECV_SPEED_LARGE, xCURLOPTTYPE_OFF_T, 146). /* Pointer to command string to send if USER/PASS fails. */ curlopt(xCURLOPT_FTP_ALTERNATIVE_TO_USER, xCURLOPTTYPE_STRINGPOINT, 147). /* callback function for setting socket options */ curlopt(xCURLOPT_SOCKOPTFUNCTION, xCURLOPTTYPE_FUNCTIONPOINT, 148). curlopt(xCURLOPT_SOCKOPTDATA, xCURLOPTTYPE_CBPOINT, 149). /* set to 0 to disable session ID re-use for this transfer, default is enabled (== 1) */ curlopt(xCURLOPT_SSL_SESSIONID_CACHE, xCURLOPTTYPE_LONG, 150). /* allowed SSH authentication methods */ curlopt(xCURLOPT_SSH_AUTH_TYPES, xCURLOPTTYPE_VALUES, 151). /* Used by scp/sftp to do public/private key authentication */ curlopt(xCURLOPT_SSH_PUBLIC_KEYFILE, xCURLOPTTYPE_STRINGPOINT, 152). curlopt(xCURLOPT_SSH_PRIVATE_KEYFILE, xCURLOPTTYPE_STRINGPOINT, 153). /* Send CCC (Clear Command Channel) after authentication */ curlopt(xCURLOPT_FTP_SSL_CCC, xCURLOPTTYPE_LONG, 154). /* Same as TIMEOUT and CONNECTTIMEOUT, but with ms resolution */ curlopt(xCURLOPT_TIMEOUT_MS, xCURLOPTTYPE_LONG, 155). curlopt(xCURLOPT_CONNECTTIMEOUT_MS, xCURLOPTTYPE_LONG, 156). /* set to zero to disable the libcurl's decoding and thus pass the raw body data to the application even when it is encoded/compressed */ curlopt(xCURLOPT_HTTP_TRANSFER_DECODING, xCURLOPTTYPE_LONG, 157). curlopt(xCURLOPT_HTTP_CONTENT_DECODING, xCURLOPTTYPE_LONG, 158). /* Permission used when creating new files and directories on the remote server for protocols that support it, SFTP/SCP/FILE */ curlopt(xCURLOPT_NEW_FILE_PERMS, xCURLOPTTYPE_LONG, 159). curlopt(xCURLOPT_NEW_DIRECTORY_PERMS, xCURLOPTTYPE_LONG, 160). /* Set the behavior of POST when redirecting. Values must be set to one of CURL_REDIR* defines below. This used to be called xCURLOPT_POST301 */ curlopt(xCURLOPT_POSTREDIR, xCURLOPTTYPE_VALUES, 161). /* used by scp/sftp to verify the host's public key */ curlopt(xCURLOPT_SSH_HOST_PUBLIC_KEY_MD5, xCURLOPTTYPE_STRINGPOINT, 162). /* Callback function for opening socket (instead of socket(2)). Optionally, callback is able change the address or refuse to connect returning CURL_SOCKET_BAD. The callback should have type curl_opensocket_callback */ curlopt(xCURLOPT_OPENSOCKETFUNCTION, xCURLOPTTYPE_FUNCTIONPOINT, 163). curlopt(xCURLOPT_OPENSOCKETDATA, xCURLOPTTYPE_CBPOINT, 164). /* POST volatile input fields. */ curlopt(xCURLOPT_COPYPOSTFIELDS, xCURLOPTTYPE_OBJECTPOINT, 165). /* set transfer mode (;type=) when doing FTP via an HTTP proxy */ curlopt(xCURLOPT_PROXY_TRANSFER_MODE, xCURLOPTTYPE_LONG, 166). /* Callback function for seeking in the input stream */ curlopt(xCURLOPT_SEEKFUNCTION, xCURLOPTTYPE_FUNCTIONPOINT, 167). curlopt(xCURLOPT_SEEKDATA, xCURLOPTTYPE_CBPOINT, 168). /* CRL file */ curlopt(xCURLOPT_CRLFILE, xCURLOPTTYPE_STRINGPOINT, 169). /* Issuer certificate */ curlopt(xCURLOPT_ISSUERCERT, xCURLOPTTYPE_STRINGPOINT, 170). /* (IPv6) Address scope */ curlopt(xCURLOPT_ADDRESS_SCOPE, xCURLOPTTYPE_LONG, 171). /* Collect certificate chain info and allow it to get retrievable with CURLINFO_CERTINFO after the transfer is complete. */ curlopt(xCURLOPT_CERTINFO, xCURLOPTTYPE_LONG, 172). /* "name" and "pwd" to use when fetching. */ curlopt(xCURLOPT_USERNAME, xCURLOPTTYPE_STRINGPOINT, 173). curlopt(xCURLOPT_PASSWORD, xCURLOPTTYPE_STRINGPOINT, 174). /* "name" and "pwd" to use with Proxy when fetching. */ curlopt(xCURLOPT_PROXYUSERNAME, xCURLOPTTYPE_STRINGPOINT, 175). curlopt(xCURLOPT_PROXYPASSWORD, xCURLOPTTYPE_STRINGPOINT, 176). /* Comma separated list of hostnames defining no-proxy zones. These should match both hostnames directly, and hostnames within a domain. For example, local.com will match local.com and www.local.com, but NOT notlocal.com or www.notlocal.com. For compatibility with other implementations of this, .local.com will be considered to be the same as local.com. A single * is the only valid wildcard, and effectively disables the use of proxy. */ curlopt(xCURLOPT_NOPROXY, xCURLOPTTYPE_STRINGPOINT, 177). /* block size for TFTP transfers */ curlopt(xCURLOPT_TFTP_BLKSIZE, xCURLOPTTYPE_LONG, 178). /* Socks Service */ /* DEPRECATED, do not use! */ curlopt(xCURLOPT_SOCKS5_GSSAPI_SERVICE, xCURLOPTTYPE_STRINGPOINT, 179). /* Socks Service */ curlopt(xCURLOPT_SOCKS5_GSSAPI_NEC, xCURLOPTTYPE_LONG, 180). /* set the bitmask for the protocols that are allowed to be used for the transfer, which thus helps the app which takes URLs from users or other external inputs and want to restrict what protocol(s) to deal with. Defaults to CURLPROTO_ALL. */ curlopt(xCURLOPT_PROTOCOLS, xCURLOPTTYPE_LONG, 181). /* set the bitmask for the protocols that libcurl is allowed to follow to, as a subset of the xCURLOPT_PROTOCOLS ones. That means the protocol needs to be set in both bitmasks to be allowed to get redirected to. */ curlopt(xCURLOPT_REDIR_PROTOCOLS, xCURLOPTTYPE_LONG, 182). /* set the SSH knownhost file name to use */ curlopt(xCURLOPT_SSH_KNOWNHOSTS, xCURLOPTTYPE_STRINGPOINT, 183). /* set the SSH host key callback, must point to a curl_sshkeycallback function */ curlopt(xCURLOPT_SSH_KEYFUNCTION, xCURLOPTTYPE_FUNCTIONPOINT, 184). /* set the SSH host key callback custom pointer */ curlopt(xCURLOPT_SSH_KEYDATA, xCURLOPTTYPE_CBPOINT, 185). /* set the SMTP mail originator */ curlopt(xCURLOPT_MAIL_FROM, xCURLOPTTYPE_STRINGPOINT, 186). /* set the list of SMTP mail receiver(s) */ curlopt(xCURLOPT_MAIL_RCPT, xCURLOPTTYPE_SLISTPOINT, 187). /* FTP: send PRET before PASV */ curlopt(xCURLOPT_FTP_USE_PRET, xCURLOPTTYPE_LONG, 188). /* RTSP request method (OPTIONS, SETUP, PLAY, etc...) */ curlopt(xCURLOPT_RTSP_REQUEST, xCURLOPTTYPE_VALUES, 189). /* The RTSP session identifier */ curlopt(xCURLOPT_RTSP_SESSION_ID, xCURLOPTTYPE_STRINGPOINT, 190). /* The RTSP stream URI */ curlopt(xCURLOPT_RTSP_STREAM_URI, xCURLOPTTYPE_STRINGPOINT, 191). /* The Transport: header to use in RTSP requests */ curlopt(xCURLOPT_RTSP_TRANSPORT, xCURLOPTTYPE_STRINGPOINT, 192). /* Manually initialize the client RTSP CSeq for this handle */ curlopt(xCURLOPT_RTSP_CLIENT_CSEQ, xCURLOPTTYPE_LONG, 193). /* Manually initialize the server RTSP CSeq for this handle */ curlopt(xCURLOPT_RTSP_SERVER_CSEQ, xCURLOPTTYPE_LONG, 194). /* The stream to pass to INTERLEAVEFUNCTION. */ curlopt(xCURLOPT_INTERLEAVEDATA, xCURLOPTTYPE_CBPOINT, 195). /* Let the application define a custom write method for RTP data */ curlopt(xCURLOPT_INTERLEAVEFUNCTION, xCURLOPTTYPE_FUNCTIONPOINT, 196). /* Turn on wildcard matching */ curlopt(xCURLOPT_WILDCARDMATCH, xCURLOPTTYPE_LONG, 197). /* Directory matching callback called before downloading of an individual file (chunk) started */ curlopt(xCURLOPT_CHUNK_BGN_FUNCTION, xCURLOPTTYPE_FUNCTIONPOINT, 198). /* Directory matching callback called after the file (chunk) was downloaded, or skipped */ curlopt(xCURLOPT_CHUNK_END_FUNCTION, xCURLOPTTYPE_FUNCTIONPOINT, 199). /* Change match (fnmatch-like) callback for wildcard matching */ curlopt(xCURLOPT_FNMATCH_FUNCTION, xCURLOPTTYPE_FUNCTIONPOINT, 200). /* Let the application define custom chunk data pointer */ curlopt(xCURLOPT_CHUNK_DATA, xCURLOPTTYPE_CBPOINT, 201). /* FNMATCH_FUNCTION user pointer */ curlopt(xCURLOPT_FNMATCH_DATA, xCURLOPTTYPE_CBPOINT, 202). /* send linked-list of name:port:address sets */ curlopt(xCURLOPT_RESOLVE, xCURLOPTTYPE_SLISTPOINT, 203). /* Set a username for authenticated TLS */ curlopt(xCURLOPT_TLSAUTH_USERNAME, xCURLOPTTYPE_STRINGPOINT, 204). /* Set a password for authenticated TLS */ curlopt(xCURLOPT_TLSAUTH_PASSWORD, xCURLOPTTYPE_STRINGPOINT, 205). /* Set authentication type for authenticated TLS */ curlopt(xCURLOPT_TLSAUTH_TYPE, xCURLOPTTYPE_STRINGPOINT, 206). /* Set to 1 to enable the "TE:" header in HTTP requests to ask for compressed transfer-encoded responses. Set to 0 to disable the use of TE: in outgoing requests. The current default is 0, but it might change in a future libcurl release. libcurl will ask for the compressed methods it knows of, and if that isn't any, it will not ask for transfer-encoding at all even if this option is set to 1. */ curlopt(xCURLOPT_TRANSFER_ENCODING, xCURLOPTTYPE_LONG, 207). /* Callback function for closing socket (instead of close(2)). The callback should have type curl_closesocket_callback */ curlopt(xCURLOPT_CLOSESOCKETFUNCTION, xCURLOPTTYPE_FUNCTIONPOINT, 208). curlopt(xCURLOPT_CLOSESOCKETDATA, xCURLOPTTYPE_CBPOINT, 209). /* allow GSSAPI credential delegation */ curlopt(xCURLOPT_GSSAPI_DELEGATION, xCURLOPTTYPE_VALUES, 210). /* Set the name servers to use for DNS resolution */ curlopt(xCURLOPT_DNS_SERVERS, xCURLOPTTYPE_STRINGPOINT, 211). /* Time-out accept operations (currently for FTP only) after this amount of milliseconds. */ curlopt(xCURLOPT_ACCEPTTIMEOUT_MS, xCURLOPTTYPE_LONG, 212). /* Set TCP keepalive */ curlopt(xCURLOPT_TCP_KEEPALIVE, xCURLOPTTYPE_LONG, 213). /* non-universal keepalive knobs (Linux, AIX, HP-UX, more) */ curlopt(xCURLOPT_TCP_KEEPIDLE, xCURLOPTTYPE_LONG, 214). curlopt(xCURLOPT_TCP_KEEPINTVL, xCURLOPTTYPE_LONG, 215). /* Enable/disable specific SSL features with a bitmask, see CURLSSLOPT_* */ curlopt(xCURLOPT_SSL_OPTIONS, xCURLOPTTYPE_VALUES, 216). /* Set the SMTP auth originator */ curlopt(xCURLOPT_MAIL_AUTH, xCURLOPTTYPE_STRINGPOINT, 217). /* Enable/disable SASL initial response */ curlopt(xCURLOPT_SASL_IR, xCURLOPTTYPE_LONG, 218). /* Function that will be called instead of the internal progress display * function. This function should be defined as the curl_xferinfo_callback * prototype defines. (Deprecates xCURLOPT_PROGRESSFUNCTION) */ curlopt(xCURLOPT_XFERINFOFUNCTION, xCURLOPTTYPE_FUNCTIONPOINT, 219). /* The XOAUTH2 bearer token */ curlopt(xCURLOPT_XOAUTH2_BEARER, xCURLOPTTYPE_STRINGPOINT, 220). /* Set the interface string to use as outgoing network * interface for DNS requests. * Only supported by the c-ares DNS backend */ curlopt(xCURLOPT_DNS_INTERFACE, xCURLOPTTYPE_STRINGPOINT, 221). /* Set the local IPv4 address to use for outgoing DNS requests. * Only supported by the c-ares DNS backend */ curlopt(xCURLOPT_DNS_LOCAL_IP4, xCURLOPTTYPE_STRINGPOINT, 222). /* Set the local IPv6 address to use for outgoing DNS requests. * Only supported by the c-ares DNS backend */ curlopt(xCURLOPT_DNS_LOCAL_IP6, xCURLOPTTYPE_STRINGPOINT, 223). /* Set authentication options directly */ curlopt(xCURLOPT_LOGIN_OPTIONS, xCURLOPTTYPE_STRINGPOINT, 224). /* Enable/disable TLS NPN extension (http2 over ssl might fail without) */ curlopt(xCURLOPT_SSL_ENABLE_NPN, xCURLOPTTYPE_LONG, 225). /* Enable/disable TLS ALPN extension (http2 over ssl might fail without) */ curlopt(xCURLOPT_SSL_ENABLE_ALPN, xCURLOPTTYPE_LONG, 226). /* Time to wait for a response to a HTTP request containing an * Expect: 100-continue header before sending the data anyway. */ curlopt(xCURLOPT_EXPECT_100_TIMEOUT_MS, xCURLOPTTYPE_LONG, 227). /* This points to a linked list of headers used for proxy requests only, struct curl_slist kind */ curlopt(xCURLOPT_PROXYHEADER, xCURLOPTTYPE_SLISTPOINT, 228). /* Pass in a bitmask of "header options" */ curlopt(xCURLOPT_HEADEROPT, xCURLOPTTYPE_VALUES, 229). /* The public key in DER form used to validate the peer public key this option is used only if SSL_VERIFYPEER is true */ curlopt(xCURLOPT_PINNEDPUBLICKEY, xCURLOPTTYPE_STRINGPOINT, 230). /* Path to Unix domain socket */ curlopt(xCURLOPT_UNIX_SOCKET_PATH, xCURLOPTTYPE_STRINGPOINT, 231). /* Set if we should verify the certificate status. */ curlopt(xCURLOPT_SSL_VERIFYSTATUS, xCURLOPTTYPE_LONG, 232). /* Set if we should enable TLS false start. */ curlopt(xCURLOPT_SSL_FALSESTART, xCURLOPTTYPE_LONG, 233). /* Do not squash dot-dot sequences */ curlopt(xCURLOPT_PATH_AS_IS, xCURLOPTTYPE_LONG, 234). /* Proxy Service Name */ curlopt(xCURLOPT_PROXY_SERVICE_NAME, xCURLOPTTYPE_STRINGPOINT, 235). /* Service Name */ curlopt(xCURLOPT_SERVICE_NAME, xCURLOPTTYPE_STRINGPOINT, 236). /* Wait/don't wait for pipe/mutex to clarify */ curlopt(xCURLOPT_PIPEWAIT, xCURLOPTTYPE_LONG, 237). /* Set the protocol used when curl is given a URL without a protocol */ curlopt(xCURLOPT_DEFAULT_PROTOCOL, xCURLOPTTYPE_STRINGPOINT, 238). /* Set stream weight, 1 - 256 (default is 16) */ curlopt(xCURLOPT_STREAM_WEIGHT, xCURLOPTTYPE_LONG, 239). /* Set stream dependency on another CURL handle */ curlopt(xCURLOPT_STREAM_DEPENDS, xCURLOPTTYPE_OBJECTPOINT, 240). /* Set E-xclusive stream dependency on another CURL handle */ curlopt(xCURLOPT_STREAM_DEPENDS_E, xCURLOPTTYPE_OBJECTPOINT, 241). /* Do not send any tftp option requests to the server */ curlopt(xCURLOPT_TFTP_NO_OPTIONS, xCURLOPTTYPE_LONG, 242). /* Linked-list of host:port:connect-to-host:connect-to-port, overrides the URL's host:port (only for the network layer) */ curlopt(xCURLOPT_CONNECT_TO, xCURLOPTTYPE_SLISTPOINT, 243). /* Set TCP Fast Open */ curlopt(xCURLOPT_TCP_FASTOPEN, xCURLOPTTYPE_LONG, 244). /* Continue to send data if the server responds early with an * HTTP status code >= 300 */ curlopt(xCURLOPT_KEEP_SENDING_ON_ERROR, xCURLOPTTYPE_LONG, 245). /* The CApath or CAfile used to validate the proxy certificate this option is used only if PROXY_SSL_VERIFYPEER is true */ curlopt(xCURLOPT_PROXY_CAINFO, xCURLOPTTYPE_STRINGPOINT, 246). /* The CApath directory used to validate the proxy certificate this option is used only if PROXY_SSL_VERIFYPEER is true */ curlopt(xCURLOPT_PROXY_CAPATH, xCURLOPTTYPE_STRINGPOINT, 247). /* Set if we should verify the proxy in ssl handshake, set 1 to verify. */ curlopt(xCURLOPT_PROXY_SSL_VERIFYPEER, xCURLOPTTYPE_LONG, 248). /* Set if we should verify the Common name from the proxy certificate in ssl * handshake, set 1 to check existence, 2 to ensure that it matches * the provided hostname. */ curlopt(xCURLOPT_PROXY_SSL_VERIFYHOST, xCURLOPTTYPE_LONG, 249). /* What version to specifically try to use for proxy. See CURL_SSLVERSION defines below. */ curlopt(xCURLOPT_PROXY_SSLVERSION, xCURLOPTTYPE_VALUES, 250). /* Set a username for authenticated TLS for proxy */ curlopt(xCURLOPT_PROXY_TLSAUTH_USERNAME, xCURLOPTTYPE_STRINGPOINT, 251). /* Set a password for authenticated TLS for proxy */ curlopt(xCURLOPT_PROXY_TLSAUTH_PASSWORD, xCURLOPTTYPE_STRINGPOINT, 252). /* Set authentication type for authenticated TLS for proxy */ curlopt(xCURLOPT_PROXY_TLSAUTH_TYPE, xCURLOPTTYPE_STRINGPOINT, 253). /* name of the file keeping your private SSL-certificate for proxy */ curlopt(xCURLOPT_PROXY_SSLCERT, xCURLOPTTYPE_STRINGPOINT, 254). /* type of the file keeping your SSL-certificate ("DER", "PEM", "ENG") for proxy */ curlopt(xCURLOPT_PROXY_SSLCERTTYPE, xCURLOPTTYPE_STRINGPOINT, 255). /* name of the file keeping your private SSL-key for proxy */ curlopt(xCURLOPT_PROXY_SSLKEY, xCURLOPTTYPE_STRINGPOINT, 256). /* type of the file keeping your private SSL-key ("DER", "PEM", "ENG") for proxy */ curlopt(xCURLOPT_PROXY_SSLKEYTYPE, xCURLOPTTYPE_STRINGPOINT, 257). /* password for the SSL private key for proxy */ curlopt(xCURLOPT_PROXY_KEYPASSWD, xCURLOPTTYPE_STRINGPOINT, 258). /* Specify which SSL ciphers to use for proxy */ curlopt(xCURLOPT_PROXY_SSL_CIPHER_LIST, xCURLOPTTYPE_STRINGPOINT, 259). /* CRL file for proxy */ curlopt(xCURLOPT_PROXY_CRLFILE, xCURLOPTTYPE_STRINGPOINT, 260). /* Enable/disable specific SSL features with a bitmask for proxy, see CURLSSLOPT_* */ curlopt(xCURLOPT_PROXY_SSL_OPTIONS, xCURLOPTTYPE_LONG, 261). /* Name of pre proxy to use. */ curlopt(xCURLOPT_PRE_PROXY, xCURLOPTTYPE_STRINGPOINT, 262). /* The public key in DER form used to validate the proxy public key this option is used only if PROXY_SSL_VERIFYPEER is true */ curlopt(xCURLOPT_PROXY_PINNEDPUBLICKEY, xCURLOPTTYPE_STRINGPOINT, 263). /* Path to an abstract Unix domain socket */ curlopt(xCURLOPT_ABSTRACT_UNIX_SOCKET, xCURLOPTTYPE_STRINGPOINT, 264). /* Suppress proxy CONNECT response headers from user callbacks */ curlopt(xCURLOPT_SUPPRESS_CONNECT_HEADERS, xCURLOPTTYPE_LONG, 265). /* The request target, instead of extracted from the URL */ curlopt(xCURLOPT_REQUEST_TARGET, xCURLOPTTYPE_STRINGPOINT, 266). /* bitmask of allowed auth methods for connections to SOCKS5 proxies */ curlopt(xCURLOPT_SOCKS5_AUTH, xCURLOPTTYPE_LONG, 267). /* Enable/disable SSH compression */ curlopt(xCURLOPT_SSH_COMPRESSION, xCURLOPTTYPE_LONG, 268). /* Post MIME data. */ curlopt(xCURLOPT_MIMEPOST, xCURLOPTTYPE_OBJECTPOINT, 269). /* Time to use with the xCURLOPT_TIMECONDITION. Specified in number of seconds since 1 Jan 1970. */ curlopt(xCURLOPT_TIMEVALUE_LARGE, xCURLOPTTYPE_OFF_T, 270). /* Head start in milliseconds to give happy eyeballs. */ curlopt(xCURLOPT_HAPPY_EYEBALLS_TIMEOUT_MS, xCURLOPTTYPE_LONG, 271). /* Function that will be called before a resolver request is made */ curlopt(xCURLOPT_RESOLVER_START_FUNCTION, xCURLOPTTYPE_FUNCTIONPOINT, 272). /* User data to pass to the resolver start callback. */ curlopt(xCURLOPT_RESOLVER_START_DATA, xCURLOPTTYPE_CBPOINT, 273). /* send HAProxy PROXY protocol header? */ curlopt(xCURLOPT_HAPROXYPROTOCOL, xCURLOPTTYPE_LONG, 274). /* shuffle addresses before use when DNS returns multiple */ curlopt(xCURLOPT_DNS_SHUFFLE_ADDRESSES, xCURLOPTTYPE_LONG, 275). /* Specify which TLS 1.3 ciphers suites to use */ curlopt(xCURLOPT_TLS13_CIPHERS, xCURLOPTTYPE_STRINGPOINT, 276). curlopt(xCURLOPT_PROXY_TLS13_CIPHERS, xCURLOPTTYPE_STRINGPOINT, 277). /* Disallow specifying username/login in URL. */ curlopt(xCURLOPT_DISALLOW_USERNAME_IN_URL, xCURLOPTTYPE_LONG, 278). /* DNS-over-HTTPS URL */ curlopt(xCURLOPT_DOH_URL, xCURLOPTTYPE_STRINGPOINT, 279). /* Preferred buffer size to use for uploads */ curlopt(xCURLOPT_UPLOAD_BUFFERSIZE, xCURLOPTTYPE_LONG, 280). /* Time in ms between connection upkeep calls for long-lived connections. */ curlopt(xCURLOPT_UPKEEP_INTERVAL_MS, xCURLOPTTYPE_LONG, 281). /* Specify URL using CURL URL API. */ curlopt(xCURLOPT_CURLU, xCURLOPTTYPE_OBJECTPOINT, 282). /* add trailing data just after no more data is available */ curlopt(xCURLOPT_TRAILERFUNCTION, xCURLOPTTYPE_FUNCTIONPOINT, 283). /* pointer to be passed to HTTP_TRAILER_FUNCTION */ curlopt(xCURLOPT_TRAILERDATA, xCURLOPTTYPE_CBPOINT, 284). /* set this to 1L to allow HTTP/0.9 responses or 0L to disallow */ curlopt(xCURLOPT_HTTP09_ALLOWED, xCURLOPTTYPE_LONG, 285). /* alt-svc control bitmask */ curlopt(xCURLOPT_ALTSVC_CTRL, xCURLOPTTYPE_LONG, 286). /* alt-svc cache file name to possibly read from/write to */ curlopt(xCURLOPT_ALTSVC, xCURLOPTTYPE_STRINGPOINT, 287). /* maximum age (idle time) of a connection to consider it for reuse * (in seconds) */ curlopt(xCURLOPT_MAXAGE_CONN, xCURLOPTTYPE_LONG, 288). /* SASL authorization identity */ curlopt(xCURLOPT_SASL_AUTHZID, xCURLOPTTYPE_STRINGPOINT, 289). /* allow RCPT TO command to fail for some recipients */ curlopt(xCURLOPT_MAIL_RCPT_ALLLOWFAILS, xCURLOPTTYPE_LONG, 290). /* the private SSL-certificate as a "blob" */ curlopt(xCURLOPT_SSLCERT_BLOB, xCURLOPTTYPE_BLOB, 291). curlopt(xCURLOPT_SSLKEY_BLOB, xCURLOPTTYPE_BLOB, 292). curlopt(xCURLOPT_PROXY_SSLCERT_BLOB, xCURLOPTTYPE_BLOB, 293). curlopt(xCURLOPT_PROXY_SSLKEY_BLOB, xCURLOPTTYPE_BLOB, 294). curlopt(xCURLOPT_ISSUERCERT_BLOB, xCURLOPTTYPE_BLOB, 295). /* Issuer certificate for proxy */ curlopt(xCURLOPT_PROXY_ISSUERCERT, xCURLOPTTYPE_STRINGPOINT, 296). curlopt(xCURLOPT_PROXY_ISSUERCERT_BLOB, xCURLOPTTYPE_BLOB, 297). /* the EC curves requested by the TLS client (RFC 8422, 5.1); * OpenSSL support via 'set_groups'/'set_curves': * https://www.openssl.org/docs/manmaster/man3/SSL_CTX_set1_groups.html */ curlopt(xCURLOPT_SSL_EC_CURVES, xCURLOPTTYPE_STRINGPOINT, 298). /* HSTS bitmask */ curlopt(xCURLOPT_HSTS_CTRL, xCURLOPTTYPE_LONG, 299). /* HSTS file name */ curlopt(xCURLOPT_HSTS, xCURLOPTTYPE_STRINGPOINT, 300). /* HSTS read callback */ curlopt(xCURLOPT_HSTSREADFUNCTION, xCURLOPTTYPE_FUNCTIONPOINT, 301). curlopt(xCURLOPT_HSTSREADDATA, xCURLOPTTYPE_CBPOINT, 302). /* HSTS write callback */ curlopt(xCURLOPT_HSTSWRITEFUNCTION, xCURLOPTTYPE_FUNCTIONPOINT, 303). curlopt(xCURLOPT_HSTSWRITEDATA, xCURLOPTTYPE_CBPOINT, 304). /* Parameters for V4 signature */ curlopt(xCURLOPT_AWS_SIGV4, xCURLOPTTYPE_STRINGPOINT, 305). /* Same as xCURLOPT_SSL_VERIFYPEER but for DoH (DNS-over-HTTPS) servers. */ curlopt(xCURLOPT_DOH_SSL_VERIFYPEER, xCURLOPTTYPE_LONG, 306). /* Same as xCURLOPT_SSL_VERIFYHOST but for DoH (DNS-over-HTTPS) servers. */ curlopt(xCURLOPT_DOH_SSL_VERIFYHOST, xCURLOPTTYPE_LONG, 307). /* Same as xCURLOPT_SSL_VERIFYSTATUS but for DoH (DNS-over-HTTPS) servers. */ curlopt(xCURLOPT_DOH_SSL_VERIFYSTATUS, xCURLOPTTYPE_LONG, 308). /* The CA certificates as "blob" used to validate the peer certificate this option is used only if SSL_VERIFYPEER is true */ curlopt(xCURLOPT_CAINFO_BLOB, xCURLOPTTYPE_BLOB, 309). /* The CA certificates as "blob" used to validate the proxy certificate this option is used only if PROXY_SSL_VERIFYPEER is true */ curlopt(xCURLOPT_PROXY_CAINFO_BLOB, xCURLOPTTYPE_BLOB, 310). /* used by scp/sftp to verify the host's public key */ curlopt(xCURLOPT_SSH_HOST_PUBLIC_KEY_SHA256, xCURLOPTTYPE_STRINGPOINT, 311). /* Function that will be called immediately before the initial request is made on a connection (after any protocol negotiation step). */ curlopt(xCURLOPT_PREREQFUNCTION, xCURLOPTTYPE_FUNCTIONPOINT, 312). /* Data passed to the xCURLOPT_PREREQFUNCTION callback */ curlopt(xCURLOPT_PREREQDATA, xCURLOPTTYPE_CBPOINT, 313). /* maximum age (since creation) of a connection to consider it for reuse * (in seconds) */ curlopt(xCURLOPT_MAXLIFETIME_CONN, xCURLOPTTYPE_LONG, 314). /* Set MIME option flags. */ curlopt(xCURLOPT_MIME_OPTIONS, xCURLOPTTYPE_LONG, 315). /* set the SSH host key callback, must point to a curl_sshkeycallback function */ curlopt(xCURLOPT_SSH_HOSTKEYFUNCTION, xCURLOPTTYPE_FUNCTIONPOINT, 316). /* set the SSH host key callback custom pointer */ curlopt(xCURLOPT_SSH_HOSTKEYDATA, xCURLOPTTYPE_CBPOINT, 317). /* specify which protocols that are allowed to be used for the transfer, which thus helps the app which takes URLs from users or other external inputs and want to restrict what protocol(s) to deal with. Defaults to all built-in protocols. */ curlopt(xCURLOPT_PROTOCOLS_STR, xCURLOPTTYPE_STRINGPOINT, 318). /* specify which protocols that libcurl is allowed to follow directs to */ curlopt(xCURLOPT_REDIR_PROTOCOLS_STR, xCURLOPTTYPE_STRINGPOINT, 319). @!/** Support for Definite Clause Grammars. A Prolog definite clause grammar (DCG) describes a sequence. Operationally, DCGs can be used to parse, generate, complete and check sequences manifested as lists. Check [The Power of Prolog chapter on DCGs](https://www.metalevel.at/prolog/dcg) to learn more about them. */ :- module(dcgs, [op(1105, xfy, '|'), phrase/2, phrase/3, phrase//2, phrase//3, seq//1, seqq//1, ... //0, (-->)/2 ]). :- use_module(library(error)). :- use_module(library(iso_ext)). :- use_module(library(lists), [append/3, member/2]). :- use_module(library(loader), [strip_module/3]). :- meta_predicate(phrase(2, ?)). :- meta_predicate(phrase(2, ?, ?)). :- meta_predicate(phrase(3, ?, ?, ?)). :- meta_predicate(phrase(4, ?, ?, ?, ?)). :- meta_predicate(','(2, 2, ?, ?)). :- meta_predicate(;(2, 2, ?, ?)). %% phrase(+Body, ?Ls). % % True iff Body describes the list Ls. Body must be a DCG body. % It is equivalent to `phrase(Body, Ls, [])`. % % Examples: % % ``` % as --> []. % as --> [a], as. % % ?- phrase(as, Ls). % Ls = [] % ; Ls = "a" % ; Ls = "aa" % ; Ls = "aaa" % ; ... . % % ?- phrase(as, "aaa"). % true. % ``` phrase(GRBody, S0) :- phrase(GRBody, S0, []). %% phrase(+Body, ?Ls, ?Ls0). % % True iff Body describes part of the list Ls and the rest of Ls is Ls0. % % Example: % % ``` % ?- phrase(seq(X), "aaa", Y). % X = [], Y = "aaa" % ; X = "a", Y = "aa" % ; X = "aa", Y = "a" % ; X = "aaa", Y = []. % ``` phrase(GRBody, S0, S) :- strip_module(GRBody, M, GRBody1), ( var(GRBody) -> instantiation_error(phrase/3) ; nonvar(GRBody1), dcg_constr(GRBody1), dcg_body(GRBody1, S0, S, GRBody2) -> call(M:GRBody2) ; call(M:GRBody1, S0, S) ). phrase(GRBody, Arg, S0, S) :- strip_module(GRBody, M, GRBody1), ( var(GRBody) -> instantiation_error(phrase/4) ; nonvar(GRBody1), GRBody1 =.. GRBodys1, append(GRBodys1, [Arg], GRBodys2), GRBody2 =.. GRBodys2, dcg_constr(GRBody2), dcg_body(GRBody2, S0, S, GRBody3) -> call(M:GRBody3) ; call(M:GRBody1, Arg, S0, S) ). phrase(GRBody, Arg1, Arg2, S0, S) :- strip_module(GRBody, M, GRBody1), ( var(GRBody) -> instantiation_error(phrase/5) ; nonvar(GRBody1), GRBody1 =.. GRBodys1, append(GRBodys1, [Arg1,Arg2], GRBodys2), GRBody2 =.. GRBodys2, dcg_constr(GRBody2), dcg_body(GRBody2, S0, S, GRBody3) -> call(M:GRBody3) ; call(M:GRBody1, Arg1, Arg2, S0, S) ). % The same version of the below two dcg_rule clauses, but with module scoping. dcg_rule(( M:NonTerminal, Terminals --> GRBody ), ( M:Head :- Body )) :- dcg_non_terminal(NonTerminal, S0, S, Head), dcg_body(GRBody, S0, S1, Goal1), dcg_terminals(Terminals, S, S1, Goal2), Body = ( Goal1, Goal2 ). dcg_rule(( M:NonTerminal --> GRBody ), ( M:Head :- Body )) :- NonTerminal \= ( _, _ ), dcg_non_terminal(NonTerminal, S0, S, Head), dcg_body(GRBody, S0, S, Body). % This program uses append/3 as defined in the Prolog prologue. % Expands a DCG rule into a Prolog rule, when no error condition applies. dcg_rule(( NonTerminal, Terminals --> GRBody ), ( Head :- Body )) :- dcg_non_terminal(NonTerminal, S0, S, Head), dcg_body(GRBody, S0, S1, Goal1), dcg_terminals(Terminals, S, S1, Goal2), Body = ( Goal1, Goal2 ). dcg_rule(( NonTerminal --> GRBody ), ( Head :- Body )) :- NonTerminal \= ( _, _ ), dcg_non_terminal(NonTerminal, S0, S, Head), dcg_body(GRBody, S0, S, Body). dcg_non_terminal(NonTerminal, S0, S, Goal) :- NonTerminal =.. NonTerminalUniv, append(NonTerminalUniv, [S0, S], GoalUniv), ( callable(NonTerminal) -> Goal =.. GoalUniv ; Goal = NonTerminal % let call/N throw an error instead of throwing one here. ). dcg_terminals(Terminals, S0, S, S0 = List) :- append(Terminals, S, List). dcg_body(Var, S0, S, Body) :- var(Var), Body = phrase(Var, S0, S). dcg_body(GRBody, S0, S, Body) :- nonvar(GRBody), dcg_constr(GRBody), dcg_cbody(GRBody, S0, S, Body). dcg_body(NonTerminal, S0, S, Goal1) :- nonvar(NonTerminal), \+ dcg_constr(NonTerminal), loader:strip_module(NonTerminal, M, NonTerminal0), dcg_non_terminal(NonTerminal0, S0, S, Goal0), ( functor(NonTerminal, (:), 2) -> Goal1 = M:Goal0 ; Goal1 = Goal0 ). % The following constructs in a grammar rule body % are defined in the corresponding subclauses. dcg_constr([]). % 7.14.1 dcg_constr([_|_]). % 7.14.2 - terminal sequence dcg_constr(( _, _ )). % 7.14.3 - concatenation dcg_constr(( _ ; _ )). % 7.14.4 - alternative dcg_constr(( _'|'_ )). % 7.14.6 - alternative dcg_constr({_}). % 7.14.7 dcg_constr(call(_)). % 7.14.8 dcg_constr(phrase(_)). % 7.14.9 dcg_constr(phrase(_,_)). % extension of 7.14.9 dcg_constr(phrase(_,_,_)). % extension of 7.14.9 dcg_constr(!). % 7.14.10 dcg_constr(\+ G_0) :- % 7.14.11 - not (existence implementation def.) throw(error(representation_error(dcg_body), [culprit- (\+ G_0)])). dcg_constr((If->Then)) :- % 7.14.12 - if-then (existence implementation def.) throw(error(representation_error(dcg_body), [culprit- (If->Then)])). % The principal functor of the first argument indicates % the construct to be expanded. dcg_cbody([], S0, S, S0 = S). dcg_cbody([T|Ts], S0, S, Goal) :- must_be(list, [T|Ts]), dcg_terminals([T|Ts], S0, S, Goal). dcg_cbody(( GRFirst, GRSecond ), S0, S, ( First, Second )) :- dcg_body(GRFirst, S0, S1, First), dcg_body(GRSecond, S1, S, Second). dcg_cbody(( GREither ; GROr ), S0, S, ( Either ; Or )) :- \+ subsumes_term(( _ -> _ ), GREither), dcg_body(GREither, S0, S, Either), dcg_body(GROr, S0, S, Or). dcg_cbody(( GRCond ; GRElse ), S0, S, ( Cond ; Else )) :- subsumes_term(( _GRIf -> _GRThen ), GRCond), dcg_cbody(GRCond, S0, S, Cond), dcg_body(GRElse, S0, S, Else). dcg_cbody(( GREither '|' GROr ), S0, S, ( Either ; Or )) :- dcg_body(GREither, S0, S, Either), dcg_body(GROr, S0, S, Or). dcg_cbody({Goal}, S0, S, ( Goal, S0 = S )). dcg_cbody(call(Cont), S0, S, call(Cont, S0, S)). dcg_cbody(phrase(Body), S0, S, phrase(Body, S0, S)). dcg_cbody(phrase(Body, Arg), S0, S, phrase(Body, Arg, S0, S)). dcg_cbody(phrase(Body, Arg1, Arg2), S0, S, phrase(Body, Arg1, Arg2, S0, S)). dcg_cbody(!, S0, S, ( !, S0 = S )). % dcg_cbody(\+ GRBody, S0, S, ( \+ phrase(GRBody,S0,_), S0 = S )). dcg_cbody(( GRIf -> GRThen ), S0, S, ( If -> Then )) :- dcg_body(GRIf, S0, S1, If), dcg_body(GRThen, S1, S, Then). % When DCG expansion throws an exception – remove offending term and rethrow. user:term_expansion(throw_dcg_expansion_error(E), _) :- throw(E). user:term_expansion(Term0, Term) :- nonvar(Term0), catch(dcg_rule(Term0, Term), E, Term = throw_dcg_expansion_error(E)). %% seq(Seq)// % % Describes a sequence seq(Xs, Cs0,Cs) :- var(Xs), Cs0 == [], !, Xs = [], Cs0 = Cs. seq([]) --> []. seq([E|Es]) --> [E], seq(Es). %% seqq(SeqOfSeqs)// % % Describes a sequence of sequences seqq([]) --> []. seqq([Es|Ess]) --> seq(Es), seqq(Ess). %% ...// % % Describes an arbitrary number of elements ...(Cs0,Cs) :- Cs0 == [], !, Cs0 = Cs. ... --> [] | [_], ... . % defer instantiation errors until runtime. instantiations may be made % then. error_goal(error(instantiation_error, _Context), _). error_goal(error(E, must_be/2), error(E, must_be/2)). error_goal(error(E, (=..)/2), error(E, (=..)/2)). error_goal(error(representation_error(dcg_body), Context), error(representation_error(dcg_body), Context)). error_goal(E, _) :- throw(E). user:goal_expansion(phrase(GRBody, S, S0), GRBody2) :- loader:strip_module(GRBody, M, GRBody0), nonvar(GRBody0), catch(dcgs:dcg_body(GRBody0, S, S0, GRBody1), E, dcgs:error_goal(E, GRBody1) ), ( E = error(instantiation_error, _), GRBody0 = [T|Ts] -> GRBody2 = (error:must_be(list, [T|Ts]), lists:append([T|Ts], S0, S)) ; GRBody = (_:_) -> GRBody2 = M:GRBody1 ; GRBody2 = GRBody1 ). user:goal_expansion(phrase(GRBody, S), phrase(GRBody, S, [])). % (-->)/2 behaves as if it didn't exist. We export (and define) it % only so that clauses for (-->)/2 cannot be asserted when % library(dcgs) is loaded. (_-->_) :- throw(error(existence_error(procedure,(-->)/2),(-->)/2)). /** Declarative debugging. This library provides three predicates with associated operators. The operators can be placed in front of goals to debug Prolog programs. Of these predicates, the most frequently used is `(*)/1`, with associated prefix operator `*` (star). Placing `*` in front of a goal means to _generalize away_ the goal. `* Goal` acts as if `Goal` did not appear at all in the source code. It is declaratively equivalent to _commenting out_ the goal, and easier to write, because `*` can also be placed in front of the last goal in a clause without any additional changes. Source: [https://stackoverflow.com/a/30791637](https://stackoverflow.com/a/30791637) */ :- module(debug, [ op(900, fx, $), op(900, fx, $-), op(950, fy, *), (*)/1, ($)/1, ($-)/1 ]). :- use_module(library(format), [portray_clause/1]). :- meta_predicate(*(0)). :- meta_predicate($(0)). :- meta_predicate($-(0)). %% $-(Goal) % % Portray exceptions thrown by Goal. $-(G_0) :- catch(G_0, Ex, ( portray_clause(exception:Ex:G_0), throw(Ex) ) ). %% $(Goal) % % Provide a _trace_ for calls of Goal. $(G_0) :- portray_clause(call:G_0), $-G_0, portray_clause(exit:G_0). %% *(Goal) % % Generalize away Goal. *(_). ; /** Provides predicate `dif/2`. `dif/2` is a constraint that is true only if both of its arguments are different terms. */ :- module(dif, [dif/2]). :- use_module(library(atts)). :- use_module(library(dcgs)). :- use_module(library(lists), [append/3, maplist/3]). :- attribute dif/1. put_dif_att(Var, X, Y) :- ( get_atts(Var, +dif(Z)) -> sort([X \== Y | Z], NewZ), put_atts(Var, +dif(NewZ)) ; put_atts(Var, +dif([X \== Y])) ). dif_set_variables([], _, _). dif_set_variables([Var|Vars], X, Y) :- put_dif_att(Var, X, Y), dif_set_variables(Vars, X, Y). remove_goal([], _, []). remove_goal([G0|G0s], Goal0, Goals) :- ( G0 == Goal0 -> remove_goal(G0s, Goal0, Goals) ; Goals = [G0|Goals1], remove_goal(G0s, Goal0, Goals1) ). vars_remove_goal([], _). vars_remove_goal([Var|Vars], Goal0) :- ( get_atts(Var, +dif(Goals0)) -> remove_goal(Goals0, Goal0, Goals), ( Goals = [] -> put_atts(Var, -dif(_)) ; put_atts(Var, +dif(Goals)) ) ; true ), vars_remove_goal(Vars, Goal0). reinforce_goal(Goal0, Goal) :- Goal = ( term_variables(Goal0, Vars), dif:vars_remove_goal(Vars, Goal0), Goal0 = (L \== R), dif:dif(L, R) ). append_goals([], _). append_goals([Var|Vars], Goals) :- ( get_atts(Var, +dif(VarGoals)) -> append(Goals, VarGoals, NewGoals0), sort(NewGoals0, NewGoals) ; NewGoals = Goals ), put_atts(Var, +dif(NewGoals)), append_goals(Vars, Goals). verify_attributes(Var, Value, Goals) :- ( get_atts(Var, +dif(Goals0)) -> term_variables(Value, ValueVars), append_goals(ValueVars, Goals0), maplist(reinforce_goal, Goals0, Goals) ; Goals = [] ). %% dif(?X, ?Y). % % True iff X and Y are different terms. Unlike `\=/2`, `dif/2` is more declarative because if X and Y can % unify but they're not yet equal, the decision is delayed, and prevents X and Y to become equal later. % Examples: % % ``` % ?- dif(a, a). % false. % ?- dif(a, b). % true. % ?- dif(X, b). % dif:dif(X,b). % ?- dif(X, b), X = b. % false. % ``` dif(X, Y) :- X \== Y, ( X \= Y -> true ; term_variables(dif(X,Y), Vars), dif_set_variables(Vars, X, Y) ). gather_dif_goals(_, []) --> []. gather_dif_goals(V, [(X \== Y) | Goals]) --> ( { term_variables(X-Y, [V0 | _]), V == V0 } -> [dif:dif(X, Y)] ; [] ), gather_dif_goals(V, Goals). attribute_goals(X) --> { get_atts(X, +dif(Goals)) }, gather_dif_goals(X, Goals), { put_atts(X, -dif(_)) }. /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Written 2018-2025 by Markus Triska (triska@metalevel.at) I place this code in the public domain. Use it in any way you want. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ :- module(error, [must_be/2, can_be/2, instantiation_error/0, domain_error/2, type_error/2, representation_error/1, resource_error/1, instantiation_error/1, domain_error/3, type_error/3, call_with_error_context/2 ]). :- meta_predicate(check_(1, ?, ?)). %% must_be(Type, Term) % % This predicate is intended for type-checks of built-in predicates. % % It asserts that Term is: % % 1) instantiated *and* % 2) instantiated to an instance of the given Type. % % It corresponds to usage mode +Term. % % Currently, the following types are supported: % % - atom % - boolean % - character % - chars % - in_character % - integer % - list % - octet_character % - octet_chars % - pair % - term must_be(Type, Term) :- must_be_(type, Type), must_be_(Type, Term). must_be_(Type, _) :- var(Type), instantiation_error(must_be/2). must_be_(var, Term) :- ( var(Term) -> true ; throw(error(uninstantiation_error(Term), must_be/2)) ). must_be_(integer, Term) :- check_(integer, integer, Term). must_be_(not_less_than_zero, N) :- must_be(integer, N), ( N >= 0 -> true ; domain_error(not_less_than_zero, N, must_be/2) ). must_be_(atom, Term) :- check_(atom, atom, Term). must_be_(character, T) :- check_(error:character, character, T). must_be_(in_character, T) :- check_(error:in_character, in_character, T). must_be_(chars, Ls) :- can_be(chars, Ls), % prioritize type errors over instantiation errors must_be(list, Ls), ( '$is_partial_string'(Ls) -> % The expected case (success) uses a very fast test. % We cannot use partial_string/1 from library(iso_ext), % because that library itself imports library(error). true ; all_characters(Ls) ). must_be_(octet_character, C) :- must_be(character, C), ( octet_character(C) -> true ; domain_error(octet_character, C, must_be/2) ). must_be_(octet_chars, Cs) :- must_be(chars, Cs), ( '$first_non_octet'(Cs, C) -> domain_error(octet_character, C, must_be/2) ; true ). must_be_(list, Term) :- check_(error:ilist, list, Term). must_be_(type, Term) :- check_(error:type, type, Term). must_be_(boolean, Term) :- check_(error:boolean, boolean, Term). must_be_(pair, Term) :- check_(error:pair, pair, Term). must_be_(term, Term) :- ( acyclic_term(Term) -> ( ground(Term) -> true ; instantiation_error(must_be/2) ) ; type_error(term, Term, must_be/2) ). % We cannot use maplist(must_be(character), Cs), because library(lists) % uses library(error), so importing it would create a cyclic dependency. all_characters([]). all_characters([C|Cs]) :- must_be(character, C), all_characters(Cs). check_(Pred, Type, Term) :- ( var(Term) -> instantiation_error(must_be/2) ; call(Pred, Term) -> true ; type_error(Type, Term, must_be/2) ). pair(_-_). boolean(B) :- ( B == true ; B == false ). character(C) :- atom(C), atom_length(C, 1). octet_character(C) :- char_code(C, Code), 0 =< Code, Code =< 0xff. in_character(C) :- ( character(C) ; C == end_of_file ). ilist(Ls) :- '$skip_max_list'(_, _, Ls, Rs), ( var(Rs) -> instantiation_error(must_be/2) ; Rs == [] ). type(type). type(integer). type(atom). type(character). type(in_character). type(octet_character). type(octet_chars). type(chars). type(list). type(var). type(boolean). type(term). type(not_less_than_zero). type(pair). %% can_be(Type, Term) % % This predicate is intended for type-checks of built-in predicates. % % It asserts that there is a substitution which, if applied to Term, % makes it an instance of Type. % % It corresponds to usage mode ?Term. % % It supports the same types as must_be/2. can_be(Type, Term) :- must_be(type, Type), ( var(Term) -> true ; can_(Type, Term) -> true ; type_error(Type, Term, can_be/2) ). can_(integer, Term) :- integer(Term). can_(not_less_than_zero, N) :- ( integer(N) -> ( N >= 0 -> true ; domain_error(not_less_than_zero, N, can_be/2) ) ; type_error(integer, N, can_be/2) ). can_(atom, Term) :- atom(Term). can_(character, T) :- character(T). can_(in_character, T) :- in_character(T). can_(chars, Ls) :- ( '$is_partial_string'(Ls) -> true ; can_be(list, Ls), can_be_chars(Ls) ). can_(octet_character, C) :- ( octet_character(C) -> true ; domain_error(octet_character, C, can_be/2) ). can_(octet_chars, Cs) :- can_be(chars, Cs), ( '$skip_max_list'(_, _, Cs, []), % temporarily turn Cs into a list '$first_non_octet'(Cs, C) -> domain_error(octet_character, C, can_be/2) ; true ). can_(list, Term) :- list_or_partial_list(Term). can_(boolean, Term) :- boolean(Term). can_(pair, Term) :- pair(Term). can_(term, Term) :- ( acyclic_term(Term) -> true ; type_error(term, Term, can_be/2) ). can_be_chars(Var) :- var(Var), !. can_be_chars([]). can_be_chars([X|Xs]) :- can_be(character, X), can_be_chars(Xs). list_or_partial_list(Ls) :- '$skip_max_list'(_, _, Ls, Rs), ( var(Rs) -> true ; Rs == [] ). /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Shorthands for throwing ISO errors. The variants without context promote the use of call_with_error_context/2. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ instantiation_error :- throw(error(instantiation_error, [])). domain_error(Type, Term) :- throw(error(domain_error(Type, Term), [])). type_error(Type, Term) :- throw(error(type_error(Type, Term), [])). representation_error(Flag) :- throw(error(representation_error(Flag), [])). resource_error(Resource) :- throw(error(resource_error(Resource), [])). /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - The variants *with* context would not have been needed if call_with_error_context/2 had been found earlier. In the future, we may be able to remove them. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ instantiation_error(Context) :- throw(error(instantiation_error, Context)). domain_error(Type, Term, Context) :- throw(error(domain_error(Type, Term), Context)). type_error(Type, Term, Context) :- throw(error(type_error(Type, Term), Context)). /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - call_with_error_context/2 See https://github.com/mthom/scryer-prolog/discussions/2839 . - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ %% call_with_error_context(+Goal, +Pair) % % Call _Goal_ with error context _Pair_. % % Examples of error contexts: `predicate-PI`, `file-Filename` etc. :- meta_predicate(call_with_error_context(0,+)). call_with_error_context(G_0, Pair) :- must_be(pair, Pair), catch(G_0, error(E,Pairs), throw(error(E,[Pair|Pairs]))). c/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Written 2020-2025 by Markus Triska (triska@metalevel.at) Part of Scryer Prolog. I place this code in the public domain. Use it in any way you want. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ /** This library provides the nonterminal `format_//2` to describe formatted strings. `format/[2,3]` are provided for _impure_ output. The entire library only works if the Prolog flag `double_quotes` is set to `chars`, the default value in Scryer Prolog. This should also stay that way, to encourage a sensible environment. */ :- module(format, [format_//2, format/2, format/3, portray_clause_//1, portray_clause/1, portray_clause/2, listing/1 ]). :- use_module(library(dcgs)). :- use_module(library(lists)). :- use_module(library(error)). :- use_module(library(charsio)). :- use_module(library(between)). :- use_module(library(pio)). %% format_(+FormatString, +Arguments)// % % Usage: % % ``` % phrase(format_(FormatString, Arguments), Ls) % ``` % % `format_//2` describes a list of characters Ls that are formatted % according to FormatString. FormatString is a string (i.e., a list of % characters) that specifies the layout of Ls. The characters in % FormatString are used literally, except for the following tokens % with special meaning: % % | `~q` | use the next argument here, formatted as by `writeq/1` | % | `~a` | use the next argument here, which must be an atom | % | `~s` | use the next argument here, which must be a string | % | `~d` | use the next argument here, which must be an integer | % | `~f` | use the next argument here, a floating point number | % | `~Nf` | where N is an integer: format the float argument | % | | using N digits after the decimal point | % | `~Nd` | like ~d, placing the last N digits after a decimal point; | % | | if N is 0 or omitted, no decimal point is used. | % | `~ND` | like ~Nd, separating digits to the left of the decimal point | % | | in groups of three, using the character "," (comma) | % | `~NU` | like ~ND, using "_" (underscore) to separate groups of digits | % | `~NL` | format an integer so that at most N digits appear on a line. | % | | If N is 0 or omitted, it defaults to 72. | % | `~Nr` | where N is an integer between 2 and 36: format the | % | | next argument, which must be an integer, in radix N. | % | | The characters "a" to "z" are used for radices 10 to 36. | % | | If N is omitted, it defaults to 8 (octal). | % | `~NR` | like ~Nr, except that "A" to "Z" are used for radices > 9 | % | `~|` | place a tab stop at this position | % | `~N|` | where N is an integer: place a tab stop at text column N | % | `~N+` | where N is an integer: place a tab stop N characters | % | | after the previous tab stop (or start of line) | % | `~t` | distribute spaces evenly between the two closest tab stops | % | ``~`Ct`` | like ~t, use character C instead of spaces to fill the space | % | `~n` | newline | % | `~Nn` | N newlines | % | `~i` | ignore the next argument | % | `~~` | the literal ~ | % | `~w` | format like `write/1` would; consider using `~q`, `~d`, etc. | % % Instead of `~N`, you can write `~*` to use the next argument from % Arguments as the numeric argument. % % Example: % % ``` % ?- phrase(format_("~s~n~`.t~w!~12|", ["hello",there]), Cs). % Cs = "hello\n......there!". % ``` format_(Fs, Args) --> { format_args_cells(Fs, Args, Cells) }, format_cells(Cells). format_args_cells(Fs, Args, Cells) :- must_be(chars, Fs), must_be(list, Args), unique_variable_names(fabricated, Args, VNs), phrase(cells(Fs,Args,0,[],VNs), Cells). unique_variable_names(Type, Term, VNs) :- term_variables(Term, Vs), foldl(var_name(Type), Vs, VNs, 0, _). var_name(Type, V, Name=V, Num0, Num) :- charsio:fabricate_var_name(Type, Name, Num0), Num is Num0 + 1. user:goal_expansion(format_(Fs,Args,Cs0,Cs), format:format_cells(Cells, Cs0, Cs)) :- catch(format_args_cells(Fs,Args,Cells), E, % no partial evaluation for uses of format_//2 that % cannot be compiled statically, for example those where % the argument list is a variable, or where ~*n occurs % in the format string, or a domain error occurs ( ( E = error(instantiation_error,_) ; E = error(domain_error(_,_), _) ) -> false ; throw(E) )). /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Partial evaluation of goals involving conditions that can be checked at compilation time. This is especially useful for the common case of conditions that test a numeric argument against 0. It is currently used for the goals of ~d. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ goal_pe(G0, G) :- var(G0), !, G = G0. goal_pe((A0,B0), (A,B)) :- !, goal_pe(A0, A), goal_pe(B0, B). goal_pe((Body0 ; Else0), Body) :- nonvar(Body0), Body0 = ( If -> Then0 ), !, ( ground(If) -> ( If -> goal_pe(Then0, Body) ; goal_pe(Else0, Body) ) ; goal_pe(Then0, Then), goal_pe(Else0, Else), Body = ( If -> Then ; Else ) ). goal_pe(Goal, Goal). /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - format_cells//1 is an interpreter for cells, describing a string. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ format_cells([]) --> []. format_cells([Cell|Cells]) --> format_cell(Cell), format_cells(Cells). format_cell(newline) --> "\n". format_cell(cell(From,To,Es)) --> % distribute the space between the glue elements { phrase(elements_gluevars(Es, 0, Length), Vs), ( Vs = [] -> true ; Space is To - From - Length, ( Space =< 0 -> maplist(=(0), Vs) ; length(Vs, NumGlue), Distr is Space // NumGlue, Delta is Space - Distr*NumGlue, ( Delta =:= 0 -> maplist(=(Distr), Vs) ; BigGlue is Distr + Delta, reverse(Vs, [BigGlue|Rest]), maplist(=(Distr), Rest) ) ) ) }, format_elements(Es). format_elements([]) --> []. format_elements([E|Es]) --> format_element(E), format_elements(Es). format_element(chars(Cs)) --> seq(Cs). format_element(glue(Fill,Num)) --> { length(Ls, Num), maplist(=(Fill), Ls) }, seq(Ls). format_element(goal(_)) --> []. elements_gluevars([], N, N) --> []. elements_gluevars([E|Es], N0, N) --> element_gluevar(E, N0, N1), elements_gluevars(Es, N1, N). element_gluevar(chars(Cs), N0, N) --> { must_be(chars, Cs), length(Cs, L), N is N0 + L }. element_gluevar(glue(_,V), N, N) --> [V]. element_gluevar(goal(G), N, N) --> { G }. /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Our key datastructure is a list of cells and newlines. A cell has the shape cell(From,To,Elements), where From and To denote the positions of surrounding tab stops. Elements is a list of elements that occur in a cell, namely terms of the form chars(Cs), glue(Char, Var) and goal(G). "glue" elements (TeX terminology) are evenly stretched to fill the remaining whitespace in the cell. For each glue element, the character Char is used for filling, and Var is a free variable that is used when the available space is distributed. Goals are dynamically executed to obtain characters. In this way, format strings can be parsed and compiled statically when possible. newline is used if ~n occurs in a format string. It is used because a newline character does not consume whitespace in the sense of format strings. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ cells([], Args, Tab, Es, _) --> !, ( { Args == [] } -> cell(Tab, Tab, Es) ; { domain_error(empty_list, Args, format_//2) } ). cells([~,~|Fs], Args, Tab, Es, VNs) --> !, cells(Fs, Args, Tab, [chars("~")|Es], VNs). cells([~,w|Fs], [Arg|Args], Tab, Es, VNs) --> !, { G = write_term_to_chars(Arg, [numbervars(true),variable_names(VNs)], Chars) }, cells(Fs, Args, Tab, [chars(Chars),goal(G)|Es], VNs). cells([~,q|Fs], [Arg|Args], Tab, Es, VNs) --> !, { G = write_term_to_chars(Arg, [quoted(true),numbervars(true),variable_names(VNs)], Chars) }, cells(Fs, Args, Tab, [chars(Chars),goal(G)|Es], VNs). cells([~,a|Fs], [Arg|Args], Tab, Es, VNs) --> !, { G = atom_chars(Arg, Chars) }, cells(Fs, Args, Tab, [chars(Chars),goal(G)|Es], VNs). cells([~|Fs0], Args0, Tab, Es, VNs) --> { numeric_argument(Fs0, Num, [d|Fs], Args0, [Arg0|Args]) }, !, { G0 = ( Arg is Arg0, % evaluate compound expression must_be(integer, Arg), number_chars(Arg, Cs0), ( Num =:= 0 -> Cs = Cs0 ; length(Cs0, L), ( L =< Num -> Delta is Num - L, length(Zs, Delta), maplist(=('0'), Zs), phrase(("0.",seq(Zs),seq(Cs0)), Cs) ; BeforeComma is L - Num, length(Bs, BeforeComma), append(Bs, Ds, Cs0), phrase((seq(Bs),".",seq(Ds)), Cs) ) )), goal_pe(G0, G) }, cells(Fs, Args, Tab, [chars(Cs),goal(G)|Es], VNs). cells([~|Fs0], Args0, Tab, Es, VNs) --> { numeric_argument(Fs0, Num, ['D'|Fs], Args0, [Arg|Args]) }, !, { G = separate_digits_fractional(Arg, ',', Num, Cs) }, cells(Fs, Args, Tab, [chars(Cs),goal(G)|Es], VNs). cells([~|Fs0], Args0, Tab, Es, VNs) --> { numeric_argument(Fs0, Num, ['U'|Fs], Args0, [Arg|Args]) }, !, { G = separate_digits_fractional(Arg, '_', Num, Cs) }, cells(Fs, Args, Tab, [chars(Cs),goal(G)|Es], VNs). cells([~|Fs0], Args0, Tab, Es, VNs) --> { numeric_argument(Fs0, Num0, ['L'|Fs], Args0, [Arg|Args]) }, !, { G = (( Num0 =:= 0 -> Num = 72 ; Num = Num0 ), phrase(format_("~d", [Arg]), Cs0), phrase(split_lines_width(Cs0, Num), Cs) ) }, cells(Fs, Args, Tab, [chars(Cs),goal(G)|Es], VNs). cells([~,i|Fs], [_|Args], Tab, Es, VNs) --> !, cells(Fs, Args, Tab, Es, VNs). cells([~,n|Fs], Args, Tab, Es, VNs) --> !, cell(Tab, Tab, Es), n_newlines(1), cells(Fs, Args, 0, [], VNs). cells([~|Fs0], Args0, Tab, Es, VNs) --> { numeric_argument(Fs0, Num, [n|Fs], Args0, Args) }, !, cell(Tab, Tab, Es), n_newlines(Num), cells(Fs, Args, 0, [], VNs). cells([~,s|Fs], [Arg|Args], Tab, Es, VNs) --> !, cells(Fs, Args, Tab, [chars(Arg)|Es], VNs). cells([~,f|Fs], Args, Tab, Es, VNs) --> !, cells([~,'6',f|Fs], Args, Tab, Es, VNs). cells([~|Fs0], Args0, Tab, Es, VNs) --> { numeric_argument(Fs0, Num, [f|Fs], Args0, [Arg|Args]) }, !, { G = phrase(float_with_n_decimal_digits(Arg, Num), Chars) }, cells(Fs, Args, Tab, [chars(Chars),goal(G)|Es], VNs). cells([~,r|Fs], Args, Tab, Es, VNs) --> !, cells([~,'8',r|Fs], Args, Tab, Es, VNs). cells([~|Fs0], Args0, Tab, Es, VNs) --> { numeric_argument(Fs0, Num, [r|Fs], Args0, [Arg|Args]) }, !, { G = integer_to_radix(Arg, Num, lowercase, Cs) }, cells(Fs, Args, Tab, [chars(Cs),goal(G)|Es], VNs). cells([~,'R'|Fs], Args, Tab, Es, VNs) --> !, cells([~,'8','R'|Fs], Args, Tab, Es, VNs). cells([~|Fs0], Args0, Tab, Es, VNs) --> { numeric_argument(Fs0, Num, ['R'|Fs], Args0, [Arg|Args]) }, !, { G = integer_to_radix(Arg, Num, uppercase, Cs) }, cells(Fs, Args, Tab, [chars(Cs),goal(G)|Es], VNs). cells([~,'`',Char,t|Fs], Args, Tab, Es, VNs) --> !, cells(Fs, Args, Tab, [glue(Char,_)|Es], VNs). cells([~,t|Fs], Args, Tab, Es, VNs) --> !, cells(Fs, Args, Tab, [glue(' ',_)|Es], VNs). cells([~,'|'|Fs], Args, Tab0, Es, VNs) --> !, ( { ground(Tab0), Es = [chars(Cs)], ground(Cs) } -> { length(Cs, Width), Tab is Tab0 + Width }, cell(Tab0, Tab, Es) ; { G = (phrase(elements_gluevars(Es, 0, Width), _), Tab is Tab0 + Width) }, cell(Tab0, Tab, [goal(G)|Es]) ), cells(Fs, Args, Tab, [], VNs). cells([~|Fs0], Args0, Tab, Es, VNs) --> { numeric_argument(Fs0, Num, ['|'|Fs], Args0, Args) }, !, cell(Tab, Num, Es), cells(Fs, Args, Num, [], VNs). cells([~|Fs0], Args0, Tab0, Es, VNs) --> { numeric_argument(Fs0, Num, [+|Fs], Args0, Args) }, !, ( { ground(Tab0+Num) } -> { Tab is Tab0 + Num }, cell(Tab0, Tab, Es) ; { G = (Tab is Tab0 + Num) }, cell(Tab0, Tab, [goal(G)|Es]) ), cells(Fs, Args, Tab, [], VNs). cells([~|Cs], Args, _, _, _) --> ( { Args == [] } -> { domain_error(non_empty_list, [], format_//2) } ; { domain_error(format_string, [~|Cs], format_//2) } ). cells(Fs0, Args, Tab, Es, VNs) --> { phrase(upto_what(Fs1, ~), Fs0, Fs), Fs1 = [_|_] }, cells(Fs, Args, Tab, [chars(Fs1)|Es], VNs). float_with_n_decimal_digits(F, N) --> { Fr is abs(float_fractional_part(F)), FrR0 is round(Fr*10^N), I0 is truncate(F), ( FrR0 >= 10^N -> I is I0+truncate(sign(F)), FrR = FrR0 ; I = I0, FrR is FrR0+10^N ) }, ( { I=0, F<0, FrR>10^N } -> "-0" ; { number_chars(I, Is) }, seq(Is) ), ".", ( { FrR = 1 } -> "0" ; { number_chars(FrR, ['1'|FrRs]) }, seq(FrRs) ). n_newlines(N0) --> { N0 > 0, N is N0 - 1 }, [newline], n_newlines(N). n_newlines(0) --> []. /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ?- phrase(format:upto_what(Cs, ~), "abc~test", Rest). Cs = "abc", Rest = "~test". ?- phrase(format:upto_what(Cs, ~), "abc", Rest). Cs = "abc", Rest = []. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ separate_digits_fractional(Arg, Sep, Num, Cs) :- number_chars(Num, NCs), phrase(("~",seq(NCs),"d"), FStr), phrase(format_(FStr, [Arg]), Cs0), phrase(upto_what(Bs0, .), Cs0, Ds), reverse(Bs0, Bs1), phrase(groups_of_three(Bs1,Sep), Bs2), reverse(Bs2, Bs), append(Bs, Ds, Cs). upto_what([], W), [W] --> [W], !. upto_what([C|Cs], W) --> [C], !, upto_what(Cs, W). upto_what([], _) --> []. groups_of_three([A,B,C,D|Rs], Sep) --> !, [A,B,C,Sep], groups_of_three([D|Rs], Sep). groups_of_three(Ls, _) --> seq(Ls). split_lines_width(Cs, Num) --> ( { length(Prefix, Num), append(Prefix, [R|Rs], Cs) } -> seq(Prefix), "_\n", split_lines_width([R|Rs], Num) ; seq(Cs) ). cell(From, To, Es0) --> ( { Es0 == [] } -> [] ; { reverse(Es0, Es) }, [cell(From,To,Es)] ). %?- format:numeric_argument("2f", Num, [f|Fs], Args0, Args). %?- format:numeric_argument("100b", Num, Rs, Args0, Args). numeric_argument(Ds, Num, Rest, Args0, Args) :- ( Ds = [*|Rest] -> Args0 = [Num|Args] ; phrase(numeric_argument_(Ds, Rest), Ns), foldl(plus_times10, Ns, 0, Num), Args0 = Args ). numeric_argument_([D|Ds], Rest) --> ( { member(D, "0123456789") } -> { number_chars(N, [D]) }, [N], numeric_argument_(Ds, Rest) ; { Rest = [D|Ds] } ). plus_times10(D, N0, N) :- N is D + N0*10. radix_error(lowercase, R) --> format_("~~~dr", [R]). radix_error(uppercase, R) --> format_("~~~dR", [R]). integer_to_radix(I0, R, Which, Cs) :- I is I0, % evaluate compound expression must_be(integer, I), must_be(integer, R), ( \+ between(2, 36, R) -> phrase(radix_error(Which,R), Es), domain_error(format_string, Es, format_//2) ; true ), digits(Which, Ds), ( I < 0 -> Pos is abs(I), phrase(integer_to_radix_(Pos, R, Ds), Cs0, "-") ; I =:= 0 -> Cs0 = "0" ; phrase(integer_to_radix_(I, R, Ds), Cs0) ), reverse(Cs0, Cs). integer_to_radix_(0, _, _) --> !. integer_to_radix_(I0, R, Ds) --> { M is I0 mod R, nth0(M, Ds, D), I is I0 // R }, [D], integer_to_radix_(I, R, Ds). digits(lowercase, "0123456789abcdefghijklmnopqrstuvwxyz"). digits(uppercase, "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"). /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Impure I/O, implemented as a small wrapper over format_//2. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ %% format(+Fs, +Args) % % The predicate `format/2` is like `format_//2`, except that it % outputs the text on the terminal instead of describing it % declaratively as a list of characters. % % If at all possible, `format_//2` should be used, to stress pure % parts that enable easy testing etc. If necessary, you can emit the % described list of characters `Ls` with `maplist(put_char, Ls)` or, % much faster, with `format("~s", [Ls])`. Ideally, however, you use % `phrase_to_file/[2,3]` or `phrase_to_stream/2` from `library(pio)` % to write the described list directly to a file or stream, % respectively: `phrase_to_stream(format_(..., [...]), S)`. The % advantage of this is that an ideal implementation writes the % characters as they become known, without manifesting the list. format(_, _) :- not_used. user:goal_expansion(format(Fs, Args), ( current_output(Stream), format(Stream, Fs, Args))). %% format(Stream, FormatString, Arguments) % % Output the described string to the given Stream. If Stream is a % binary stream, then the code of each emitted character must be in % 0..255. format(_, _, _) :- not_used. user:goal_expansion(format(Stream, Fs, Args), ( pio:phrase_to_stream(format:format_(Fs, Args), Stream), flush_output(Stream))). /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ?- phrase(format:cells("hello", [], 0, [], []), Cs). ?- phrase(format:cells("hello~10|", [], 0, [], []), Cs). ?- phrase(format:cells("~ta~t~10|", [], 0, [], []), Cs). ?- phrase(format_("~`at~50|", []), Ls). ?- phrase(format:cells("~`at~50|", [], 0, [], []), Cs), phrase(format:format_cells(Cs), Ls). ?- phrase(format:cells("~ta~t~tb~tc~21|", [], 0, [], []), Cs). Cs = [cell(0,21,[glue(' ',_A),chars("a"),glue(' ',_B),glue(' ',_C),chars("b"),glue(' ',_D),chars("c")])]. ?- phrase(format:cells("~ta~t~4|", [], 0, [], []), Cs). Cs = [cell(0,4,[glue(' ',_A),chars("a"),glue(' ',_B)])]. ?- phrase(format:format_cell(cell(0,1,[glue(a,_94)])), Ls). ?- phrase(format:format_cell(cell(0,50,[chars("hello")])), Ls). ?- phrase(format_("~`at~50|~n", []), Ls). ?- phrase(format_("hello~n~tthere~6|", []), Ls). ?- format("~ta~t~4|", []). a true. ?- format("~ta~tb~tc~10|", []). a b c true. ?- format("~tabc~3|", []). ?- format("~ta~t~4|", []). ?- format("~ta~t~tb~tc~20|", []). a b c true. ?- format("~2f~n", [3]). 3.00 true. ?- format("~20f", [0.1]). 0.10000000000000000000 true. ?- X is atan(2), format("~7f~n", [X]). 1.1071487 X = 1.1071487177940906. ?- format("~`at~50|~n", []). aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa true ?- format("~t~N", []). ?- format("~q", [.]). '.' true. ?- format("~12r", [300]). 210 true. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - We also provide rudimentary versions of portray_clause/1 and listing/1. In the eventual library organization, portray_clause/1 and related predicates may be placed in their own dedicated library. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ %% portray_clause(+Term) % % `portray_clause/1` is useful for printing solutions in such a way % that they can be read back with `read/1`. portray_clause(Term) :- current_output(Out), portray_clause(Out, Term). portray_clause(Stream, Term) :- phrase_to_stream(portray_clause_(Term), Stream), flush_output(Stream). portray_clause_(Term) --> { unique_variable_names(numbervars, Term, VNs) }, portray_(Term, VNs), ".\n". literal(Lit, VNs) --> { write_term_to_chars(Lit, [quoted(true),variable_names(VNs),double_quotes(true)], Ls) }, ( { nonvar(Lit), \+ number(Lit), functor(Lit, F, A), current_op(Pri, _, F), ( A =:= 0 ; Pri >= 1000 ) } -> "(", seq(Ls), ")" ; seq(Ls) ). literal_(Lit, VNs) --> { phrase(literal(Lit, VNs), Ls) }, seq(Ls), ( { phrase((...,[Last]), Ls), char_type(Last, graphic_token) } -> " " ; "" ). portray_(Var, VNs) --> { var(Var) }, !, literal(Var, VNs). portray_((Head :- Body), VNs) --> !, literal(Head, VNs), " :-\n", body_(Body, 0, 3, VNs). portray_((Head --> Body), VNs) --> !, literal(Head, VNs), " -->\n", body_(Body, 0, 3, VNs). portray_(Any, VNs) --> literal_(Any, VNs). body_(Var, C, I, VNs) --> { var(Var) }, !, indent_to(C, I), literal(Var, VNs). body_((A,B), C, I, VNs) --> !, body_(A, C, I, VNs), ",\n", body_(B, 0, I, VNs). body_(Body, C, I, VNs) --> { body_if_then_else(Body, If, Then, Else) }, !, indent_to(C, I), "( ", { C1 is I + 3 }, body_(If, C1, C1, VNs), " ->\n", body_(Then, 0, C1, VNs), "\n", else_branch(Else, I, VNs). body_((A;B), C, I, VNs) --> !, indent_to(C, I), "( ", { C1 is I + 3 }, body_(A, C1, C1, VNs), "\n", else_branch(B, I, VNs). body_(Goal, C, I, VNs) --> indent_to(C, I), literal_(Goal, VNs). % True iff Body has the shape ( If -> Then ; Else ). body_if_then_else(Body, If, Then, Else) :- nonvar(Body), Body = (A ; Else), nonvar(A), A = (If -> Then). else_branch(Else, I, VNs) --> indent_to(0, I), "; ", { C is I + 3 }, ( { body_if_then_else(Else, If, Then, NextElse) } -> body_(If, C, C, VNs), " ->\n", body_(Then, 0, C, VNs), "\n", else_branch(NextElse, I, VNs) ; { nonvar(Else), Else = ( A ; B ) } -> body_(A, C, C, VNs), "\n", else_branch(B, I, VNs) ; body_(Else, C, C, VNs), "\n", indent_to(0, I), ")" ). indent_to(CurrentColumn, Indent) --> format_("~t~*|", [Indent-CurrentColumn]). /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ?- portray_clause(a). a. ?- portray_clause((a :- b)). a :- b. ?- portray_clause((a :- b, c, d)). a :- b, c, d. true. ?- portray_clause([a,b,c,d]). "abcd". ?- portray_clause(X). ?- portray_clause((f(X) :- X)). ?- portray_clause((h :- ( a -> b; c))). ?- portray_clause((h :- ( (a -> x ; y) -> b; c))). ?- portray_clause((h(X) :- ( (a(X) ; y(A,B)) -> b; c))). ?- portray_clause((h :- (a,d;b,c) ; (b,e;d))). ?- portray_clause((a :- b ; c ; d)). ?- portray_clause((h :- L = '.')). ?- portray_clause(-->(a, (b, {t}, d))). ?- portray_clause((A :- B)). - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ listing(PI) :- nonvar(PI), ( PI = Name/Arity0 -> Arity = Arity0 ; PI = Name//Arity0 -> Arity is Arity0 + 2 ; type_error(predicate_indicator, PI, listing/1) ), functor(Head, Name, Arity), \+ \+ clause(Head, _), % only true if there is at least one clause ( clause(Head, Body), ( Body == true -> portray_clause(Head) ; portray_clause((Head :- Body)) ), false ; true ). :- module(freeze, [freeze/2, frozen/2]). /** Provides the constraint `freeze/2`. */ :- use_module(library(atts)). :- use_module(library(dcgs)). :- meta_predicate(freeze(-, 0)). :- attribute(frozen/1). verify_attributes(Var, Other, Goals) :- get_atts(Var, frozen(Fa)), !, % are we involved? ( var(Other) -> % must be attributed then ( get_atts(Other, frozen(Fb)) % has a pending goal? -> put_atts(Other, frozen((Fb,Fa))) % rescue conjunction ; put_atts(Other, frozen(Fa)) % rescue the pending goal ), Goals = [] ; Goals = [Fa] ). verify_attributes(_, _, []). %% freeze(Var, Goal) % % Schedules Goal to be executed when Var is instantiated. This can % be useful to observe the exact moment a variable becomes bound to a % more concrete term, for example when creating animations of search % processes. Higher-level constructs such as `phrase_from_file/2` can % also be implemented with `freeze/2`, by scheduling a goal that % reads additional data from a file as soon as it is needed. freeze(X, Goal) :- put_atts(Fresh, frozen(Goal)), Fresh = X. attribute_goals(Var) --> { get_atts(Var, frozen(Goals)), put_atts(Var, -frozen(_)) }, [freeze:freeze(Var, Goals)]. %% frozen(Var, Goal) :- use_module(library(lists)). :- help(freeze(-var,+goal), [iso(false)]). :- help(frozen(@term,-goal), [iso(false)]). frozen(Term, Goal) :- term_attributed_variables_(Term, Vs), collect_atts_(Vs, [], AttsList), collect_goals_(Vs, [], Gs), reapply_atts_(Vs, AttsList), ( Gs = [] -> Goal = true ; flatten(Gs, Gs2), list_to_conjunction(Gs2, Fresh), Fresh = Goal ). collect_atts_([], AttsList, AttsList). collect_atts_([X|Tail], AttsList0, AttsList) :- get_atts(X, Atts), collect_atts_(Tail, [Atts|AttsList0], AttsList). reapply_atts_([], _). reapply_atts_([X|Tail], [Atts|Tail2]) :- put_atts(X, Atts), reapply_atts_(Tail, Tail2). :- module(gensym, [gensym/2, reset_gensym/1]). :- use_module(library(error)). :- use_module(library(si)). gensym_key(Base, BaseKey) :- atom_concat('gensym_', Base, BaseKey). gensym(Base, Unique) :- must_be(var, Unique), atom_si(Base), gensym_key(Base, BaseKey), ( bb_get(BaseKey, UniqueID0) -> N is UniqueID0 + 1 ; N is 1 ), atomic_concat(Base, N, Unique), bb_put(BaseKey, N). reset_gensym(Base) :- atom_si(Base), gensym_key(Base, BaseKey), bb_put(BaseKey, 0). ':- module(gsl, [ gsl_set_error_handler_off/1, gsl_vector_alloc/2, gsl_vector_calloc/2, gsl_vector_free/1, gsl_vector_ptr/3, gsl_vector_const_ptr/3, gsl_vector_memcpy/3, gsl_vector_swap/3, gsl_vector_set/3, gsl_vector_get/3, gsl_vector_set_all/2, gsl_vector_set_zero/1, gsl_vector_set_basis/3, gsl_vector_fwrite/3, gsl_vector_fread/3, gsl_vector_add/3, gsl_vector_sub/3, gsl_vector_mul/3, gsl_vector_div/3, gsl_vector_scale/3, gsl_vector_add_constant/3, gsl_vector_sum/2, gsl_vector_subvector/4, gsl_matrix_alloc/3, gsl_matrix_calloc/3, gsl_matrix_free/1, gsl_matrix_ptr/4, gsl_matrix_const_ptr/4, gsl_matrix_memcpy/3, gsl_matrix_swap/3, gsl_matrix_set/4, gsl_matrix_get/4, gsl_matrix_set_all/2, gsl_matrix_set_zero/1, gsl_matrix_set_identity/1, gsl_matrix_minmax/3, gsl_matrix_max/2, gsl_matrix_min/2, gsl_matrix_transpose_memcpy/3, gsl_matrix_transpose/2, gsl_matrix_fwrite/3, gsl_matrix_fread/3, gsl_matrix_get_row/4, gsl_matrix_get_col/4, gsl_matrix_set_row/4, gsl_matrix_set_col/4, gsl_matrix_swap_rows/4, gsl_matrix_swap_columns/4, gsl_matrix_swap_rowcol/4, gsl_matrix_add/3, gsl_matrix_sub/3, gsl_matrix_mul_elements/3, gsl_matrix_div_elements/3, gsl_matrix_scale/3, gsl_matrix_scale_columns/3, gsl_matrix_scale_rows/3, gsl_matrix_add_constant/3, gsl_matrix_submatrix/6, gsl_matrix_row/3, gsl_matrix_column/3, gsl_matrix_subrow/5, gsl_matrix_subcolumn/5, gsl_matrix_diagonal/2, gsl_matrix_subdiagonal/3, gsl_matrix_superdiagonal/3, gsl_permutation_calloc/2, gsl_permutation_alloc/2, gsl_permutation_init/1, gsl_permutation_free/1, gsl_eigen_symmv_calloc/2, gsl_eigen_symmv_alloc/2, gsl_eigen_symmv/4, gsl_eigen_symmv_free/1, gsl_eigen_symmv_sort/3, gsl_linalg_LU_decomp/4, gsl_linalg_LU_solve/5, gsl_linalg_LU_det/3, vec_from_list/2, vec_to_list/2, vec_read/3, vec_write/2, vec_random/2, mat_from_list/2, mat_to_list/2, mat_read/4, mat_write/2, mat_lup_det/2, mat_random/3, mat_eigen/3 ]). % GNU Scientific Library (GSL) % % UBUNTU: sudo apt install libgsl-dev % % REF: https://www.gnu.org/software/gsl/doc/html/index.html % % Contributions to add new definitions are most welcome! :- use_module(library(lists)). :- foreign_struct(gsl_vector_view, [ulong,ulong,ptr,ptr,sint]). :- foreign_struct(gsl_matrix_view, [ulong,ulong,ulong,ptr,ptr,sint]). :- use_foreign_module('libgslcblas.so', []). :- use_foreign_module('libgsl.so', [ gsl_set_error_handler_off([], ptr), gsl_vector_alloc([ulong], ptr), gsl_vector_calloc([ulong], ptr), gsl_vector_free([ptr], void), gsl_vector_memcpy([ptr,ptr], sint), gsl_vector_swap([ptr,ptr], sint), gsl_vector_ptr([ptr,ulong], ptr), gsl_vector_const_ptr([ptr,ulong], ptr), gsl_vector_set([ptr,ulong,double], void), gsl_vector_get([ptr,ulong], double), gsl_vector_set_all([ptr,double], void), gsl_vector_set_zero([ptr], void), gsl_vector_set_basis([ptr,ulong], sint), gsl_vector_fwrite([ptr,ptr], sint), gsl_vector_fread([ptr,ptr], sint), gsl_vector_add([ptr,ptr], sint), gsl_vector_sub([ptr,ptr], sint), gsl_vector_mul([ptr,ptr], sint), gsl_vector_div([ptr,ptr], sint), gsl_vector_scale([ptr,double], sint), gsl_vector_add_constant([ptr,double], sint), gsl_vector_sum([ptr], double), gsl_vector_subvector([ptr,ulong,ulong], gsl_vector_view), gsl_matrix_alloc([ulong,ulong], ptr), gsl_matrix_calloc([ulong,ulong], ptr), gsl_matrix_free([ptr], void), gsl_matrix_memcpy([ptr,ptr], sint), gsl_matrix_swap([ptr,ptr], sint), gsl_matrix_ptr([ptr,ulong,ulong], ptr), gsl_matrix_const_ptr([ptr,ulong,ulong], ptr), gsl_matrix_set([ptr,ulong,ulong,double], void), gsl_matrix_get([ptr,ulong,ulong], double), gsl_matrix_set_all([ptr,double], void), gsl_matrix_set_zero([ptr], void), gsl_matrix_set_identity([ptr], void), gsl_matrix_minmax([ptr,-double,-double], void), gsl_matrix_max([ptr], double), gsl_matrix_min([ptr], double), gsl_matrix_transpose_memcpy([ptr,ptr], sint), gsl_matrix_transpose([ptr], sint), gsl_matrix_fwrite([ptr,ptr], sint), gsl_matrix_fread([ptr,ptr], sint), gsl_matrix_get_row([ptr,ptr,ulong], sint), gsl_matrix_get_col([ptr,ptr,ulong], sint), gsl_matrix_set_row([ptr,ulong,ptr], sint), gsl_matrix_set_col([ptr,ulong,ptr], sint), gsl_matrix_swap_rows([ptr,ulong,ulong], sint), gsl_matrix_swap_cols([ptr,ulong,ulong], sint), gsl_matrix_swap_rowcol([ptr,ulong,ulong], sint), gsl_matrix_swap_add([ptr,ptr], sint), gsl_matrix_swap_sub([ptr,ptr], sint), gsl_matrix_swap_mul_elements([ptr,ptr], sint), gsl_matrix_swap_div_elements([ptr,ptr], sint), gsl_matrix_scale([ptr,double], sint), gsl_matrix_scale_columns([ptr,ptr], sint), gsl_matrix_scale_rows([ptr,ptr], sint), gsl_matrix_add_constant([ptr,double], sint), gsl_matrix_submatrix([ptr,ulong,ulong,ulong,ulong], gsl_matrix_view), gsl_matrix_row([ptr,ulong], gsl_vector_view), gsl_matrix_column([ptr,ulong], gsl_vector_view), gsl_matrix_subrow([ptr,ulong,ulong,ulong], gsl_vector_view), gsl_matrix_subcolumn([ptr,ulong,ulong,ulong], gsl_vector_view), gsl_matrix_diagonal([ptr], gsl_vector_view), gsl_matrix_subdiagonal([ptr,ulong], gsl_vector_view), gsl_matrix_superdiagonal([ptr,ulong], gsl_vector_view), gsl_permutation_calloc([ulong], ptr), gsl_permutation_alloc([ulong], ptr), gsl_permutation_init([ptr], void), gsl_permutation_free([ptr], void), gsl_eigen_symmv_calloc([ulong], ptr), gsl_eigen_symmv_alloc([ulong], ptr), gsl_eigen_symmv([ptr,ptr,ptr,ptr], void), gsl_eigen_symmv_free([ptr], void), gsl_eigen_symmv_sort([ptr,ptr,sint], void), gsl_linalg_LU_decomp([ptr,ptr,-sint], sint), gsl_linalg_LU_solve([ptr,ptr,ptr,ptr], sint), gsl_linalg_LU_det([ptr,sint], double) ]). gslConst(gslGSL_EIGEN_SORT_VAL_ASC, 0). gslConst(gslGSL_EIGEN_SORT_VAL_DESC, 1). gslConst(gslGSL_EIGEN_SORT_ABS_ASC, 2). gslConst(gslGSL_EIGEN_SORT_ABS_DESC, 3). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Create vector of random values vec_random(V, Cols) :- gsl_vector_alloc(Cols, V), ( cfor(0, Cols-1, J), random(Val), gsl_vector_set(V, J, Val), fail; true ). % Create matrix of random values mat_random(M, Rows, Cols) :- gsl_matrix_alloc(Rows, Cols, M), ( cfor(0, Rows-1, I), ( cfor(0, Cols-1, J), random(Val), gsl_matrix_set(M, I, J, Val), fail; true ), fail; true ). check_error_(Goal, Check, Action) :- Goal, (Check; (Action, Goal =.. [Pred|_], throw(domain_error(Pred, Check)))), !. % Calculate LU(P) determinant of square matrix mat_lup_det(M0, Det0) :- '$gsl_matrix_size'(M0, Rows, Cols), (Rows =:= Cols -> true; throw(error(domain_error(matrix_not_square, (Rows * Cols)), mat_lup_det/2))), Size is Rows, (Size > 0 -> true; throw(error(domain_error(matrix_empty, Size), mat_lup_det/2))), gsl_matrix_alloc(Size, Size, M), gsl_matrix_memcpy(M, M0, _), gsl_permutation_alloc(Size, P), check_error_( gsl_linalg_LU_decomp(M, P, Signum, Status1), Status1 =:= 0, (gsl_permutation_free(P), gsl_matrix_free(M)) ), gsl_vector_alloc(Size, B), ( cfor(0, Size-1, I), V is float(I+1), gsl_vector_set(B, I, V), fail; true ), gsl_vector_alloc(Size, X), check_error_( gsl_linalg_LU_solve(M, P, B, X, Status2), Status2 =< 1, (gsl_vector_free(X), gsl_vector_free(B), gsl_permutation_free(P)) ), gsl_vector_free(X), gsl_vector_free(B), gsl_permutation_free(P), gsl_linalg_LU_det(M, Signum, Det), gsl_matrix_free(M), Det0 is Det. % checks for NAN % Calculate the eigenvalues/eigenvectors of a square matrix... mat_eigen(M, Vals, Vecs) :- '$gsl_matrix_size'(M, Rows, Cols), (Rows =:= Cols -> true; throw(error(domain_error(matrix_not_square, (Rows * Cols)), mat_eigen/3))), Size is Rows, gsl_vector_calloc(Size, Eval), gsl_matrix_calloc(Size, Size, Evec), gsl_eigen_symmv_alloc(Size, W), gsl_eigen_symmv(M, Eval, Evec, W), gsl_eigen_symmv_free(W), gslConst(gslGSL_EIGEN_SORT_ABS_ASC,Val), gsl_eigen_symmv_sort(Eval, Evec, Val), Size1 is Size - 1, findall( Eval_i, (between(0, Size1, I), gsl_vector_get(Eval, I, Eval_i) ), Vals ), findall( L, (between(0, Size1, I), gsl_matrix_column(Evec, I, Evec_i), '$struct_to_pointer'(Evec_i, V), vec_to_list(V, L) ), Vecs ), gsl_vector_free(Eval), gsl_matrix_free(Evec). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Eg. vec_from_list(V, [1,2,3]) vec_from_list(V, L) :- length(L, Size), Size > 0, gsl_vector_alloc(Size, V), vec_from_list_(V, 0, L). vec_from_list_(_, _, []) :- !. vec_from_list_(V, I, [H|T]) :- H2 is float(H), gsl_vector_set(V, I, H2), I2 is I + 1, vec_from_list_(V, I2, T). vec_to_list(V, L) :- '$gsl_vector_size'(V, Size), vec_to_list_(V, Size, [], L). vec_to_list_(_, 0, L, L) :- !. vec_to_list_(V, Col, L0, L) :- NewCol is Col - 1, gsl_vector_get(V, NewCol, Val), vec_to_list_(V, NewCol, [Val|L0], L). vec_write(V, S) :- '$gsl_vector_write'(V, S). vec_read(V, S, Size1) :- '$gsl_vector_alloc'(S, Size1), gsl_vector_alloc(Size1, V), '$gsl_vector_read'(V, S). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Eg. mat_from_list(M, [[1,2,3],[4,5,6],[7,8,9]]) mat_from_list(M, L) :- length(L, Rows), Rows > 0, L = [H|_], length(H, Cols), Cols > 0, gsl_matrix_calloc(Rows, Cols, M), new_row_(M, 0, L). new_row_(_, _, []) :- !. new_row_(M, Row, [H|T]) :- new_col_(M, Row, 0, H), Row2 is Row + 1, new_row_(M, Row2, T). new_col_(_, _, _, []). new_col_(M, Row, Col, [H|T]) :- H2 is float(H), gsl_matrix_set(M, Row, Col, H2), Col2 is Col + 1, new_col_(M, Row, Col2, T). mat_to_list(M, L) :- '$gsl_matrix_size'(M, Size1, Size2), mat_to_list_row_(M, Size1, Size2, [], L). mat_to_list_row_(_, 0, _, L, L) :- !. mat_to_list_row_(M, Row, Size2, L0, L) :- NewRow is Row - 1, mat_to_list_col_(M, NewRow, Size2, [], NewL), mat_to_list_row_(M, NewRow, Size2, [NewL|L0], L). mat_to_list_col_(_, _, 0, L, L) :- !. mat_to_list_col_(M, Row, Col, L0, L) :- NewCol is Col - 1, gsl_matrix_get(M, Row, NewCol, Val), mat_to_list_col_(M, Row, NewCol, [Val|L0], L). mat_write(M, S) :- '$gsl_matrix_write'(M, S). mat_read(M, S, Size1, Size2) :- '$gsl_matrix_alloc'(S, Size1, Size2), gsl_matrix_alloc(Size1, Size2, M), '$gsl_matrix_read'(M, S). U /* Part of SWI-Prolog Author: Lars Buitinck E-mail: larsmans@gmail.com WWW: http://www.swi-prolog.org Copyright (c) 2006-2015, Lars Buitinck All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ :- module(heaps, [ add_to_heap/4, % +Heap0, +Priority, ?Key, -Heap delete_from_heap/4, % +Heap0, -Priority, +Key, -Heap empty_heap/1, % +Heap get_from_heap/4, % ?Heap0, ?Priority, ?Key, -Heap heap_size/2, % +Heap, -Size:int heap_to_list/2, % +Heap, -List:list is_heap/1, % +Term list_to_heap/2, % +List:list, -Heap merge_heaps/3, % +Heap0, +Heap1, -Heap min_of_heap/3, % +Heap, ?Priority, ?Key min_of_heap/5, % +Heap, ?Priority1, ?Key1, % ?Priority2, ?Key2 singleton_heap/3 % ?Heap, ?Priority, ?Key ]). /** heaps/priority queues * * Heaps are data structures that return the entries inserted into them in an * ordered fashion, based on a priority. This makes them the data structure of * choice for implementing priority queues, a central element of algorithms * such as best-first/A* search and Kruskal's minimum-spanning-tree algorithm. * * This module implements min-heaps, meaning that items are retrieved in * ascending order of key/priority. It was designed to be compatible with * the SICStus Prolog library module of the same name. merge_heaps/3 and * singleton_heap/3 are SWI-specific extension. The portray_heap/1 predicate * is not implemented. * * Although the data items can be arbitrary Prolog data, keys/priorities must * be ordered by @= N == 0 ; N > 0, Q = t(_,MinP,Sub), are_pairing_heaps(Sub, MinP) ). % True iff 1st arg is a pairing heap with min key @=< 2nd arg, % where min key of nil is logically @> any term. is_pairing_heap(V, _) :- var(V), !, fail. is_pairing_heap(nil, _). is_pairing_heap(t(_,P,Sub), MinP) :- MinP @=< P, are_pairing_heaps(Sub, P). % True iff 1st arg is a list of pairing heaps, each with min key @=< 2nd arg. are_pairing_heaps(V, _) :- var(V), !, fail. are_pairing_heaps([], _). are_pairing_heaps([Q|Qs], MinP) :- is_pairing_heap(Q, MinP), are_pairing_heaps(Qs, MinP). %! list_to_heap(+List:list, -Heap) is det. % % If List is a list of Priority-Element terms, constructs a heap % out of List. Complexity: linear. list_to_heap(Xs,Q) :- empty_heap(Empty), list_to_heap(Xs,Empty,Q). list_to_heap([],Q,Q). list_to_heap([P-X|Xs],Q0,Q) :- add_to_heap(Q0,P,X,Q1), list_to_heap(Xs,Q1,Q). %! min_of_heap(+Heap, ?Priority, ?Key) is semidet. % % Unifies Key with the minimum-priority element of Heap and % Priority with its priority value. Complexity: constant. min_of_heap(heap(t(X,P,_),_), P, X). %! min_of_heap(+Heap, ?Priority1, ?Key1, ?Priority2, ?Key2) is semidet. % % Gets the two minimum-priority elements from Heap. Complexity: logarithmic % (amortized). % % Do not use this predicate; it exists for compatibility with earlier % implementations of this library and the SICStus counterpart. It performs % a linear amount of work in the worst case that a following get_from_heap % has to re-do. min_of_heap(Q,Px,X,Py,Y) :- get_from_heap(Q,Px,X,Q0), min_of_heap(Q0,Py,Y). %! merge_heaps(+Heap0, +Heap1, -Heap) is det. % % Merge the two heaps Heap0 and Heap1 in Heap. Complexity: constant. merge_heaps(heap(L,K),heap(R,M),heap(Q,N)) :- meld(L,R,Q), N is K+M. % Merge two pairing heaps according to the pairing heap definition. meld(nil,Q,Q) :- !. meld(Q,nil,Q) :- !. meld(L,R,Q) :- L = t(X,Px,SubL), R = t(Y,Py,SubR), ( Px @< Py -> Q = t(X,Px,[R|SubL]) ; Q = t(Y,Py,[L|SubR]) ). % "Pair up" (recursively meld) a list of pairing heaps. pairing([], nil). pairing([Q], Q) :- !. pairing([Q0,Q1|Qs], Q) :- meld(Q0, Q1, Q2), pairing(Qs, Q3), meld(Q2, Q3, Q). :- module(http, [ http_open/3, http_get/3, http_post/4, http_patch/4, http_put/4, http_delete/3, http_server/2, http_request/5 ]). :- use_module(library(lists)). read_response(S, Code) :- getline(S, Line), split(Line, ' ' ,_Ver, Rest), split(Rest, ' ', Code2, _), number_chars(Code, Code2). read_header(S, Pair) :- getline(S, Line), split(Line,':', K, V), (K \= [] -> true ; (!, fail)), string_lower(K, K2), Pair=K2:V. read_header(S, Pair) :- \+ at_end_of_stream(S), read_header(S, Pair). read_chunks(S, Tmp, Data) :- getline(S, Line), hex_chars(Len, Line), Len > 0, !, '$bread'(S, Len, Tmp2), getline(S, _), ( Tmp = "" -> Tmp3 = Tmp2 ; string_concat(Tmp, Tmp2, Tmp3) ), read_chunks(S, Tmp3, Data). read_chunks(_, Data, Data). read_body(S, Hdrs, Data) :- member("content-length":V, Hdrs), number_chars(Len, V), '$bread'(S, Len, Data). % Open with options... http_open([], _, _) :- !, fail. http_open(UrlList, S, Opts) :- is_list(UrlList), is_list(Opts), union(UrlList, Opts, OptList), memberchk(host(Host), UrlList), memberchk(path(Path), UrlList), (memberchk(method(Method), OptList) -> true ; Method = get), (memberchk(version(Major-Minor), OptList) -> true ; (Major = 1, Minor = 1)), client(Host, _Host, _Path, S, OptList), string_upper(Method, UMethod), format(S, '~s /~s HTTP/~d.~d\r~nHost: ~s\r~nConnection: keep-alive\r~n\r~n', [UMethod,Path,Major,Minor,Host]), read_response(S, Code), findall(Hdr, read_header(S, Hdr), Hdrs), ignore(member("location":Location, Hdrs)), ignore(memberchk(status_code(Code), OptList)), ignore(memberchk(headers(Hdrs), OptList)), ignore(memberchk(final_url(Location), OptList)). % Client request processing... process(Url, S, Opts) :- is_list(Opts), OptList=Opts, (memberchk(post(PostData), OptList) -> Method2 = post ; Method2 = get), (memberchk(method(Method), OptList) -> true ; Method = Method2), (memberchk(version(Major-Minor), OptList) -> true ; (Major = 1, Minor = 1)), client(Url, Host, Path, S, OptList), string_upper(Method, UMethod), ( memberchk(header("content-type", Ct), OptList) -> format(atom(Ctype), "Content-Type: ~w\r~n",[Ct]) ; Ctype = '' ), ( nonvar(PostData) -> (length(PostData, DataLen), format(atom(Clen), "Content-Length: ~d\r~n", [DataLen])) ; Clen = '' ), format(S, "~s /~s HTTP/~d.~d\r~nHost: ~s\r~nConnection: close\r~n~a~a\r~n", [UMethod,Path,Major,Minor,Host,Ctype,Clen]), (nonvar(DataLen) -> '$bwrite'(S, PostData) ; true), read_response(S, Code), findall(Hdr, read_header(S, Hdr), Hdrs), ignore(memberchk(status_code2(Code), OptList)), ignore(memberchk(headers2(Hdrs), OptList)). % Client requests... http_get(Url, Data, Opts) :- Opts2=[headers2(Hdrs)|Opts], Opts3=[status_code2(Code)|Opts2], process(Url, S, Opts3), ( member("transfer-encoding":TE, Hdrs) -> true ; Te = ''), ( TE == "chunked" -> read_chunks(S, "", Body) ; read_body(S, Hdrs, Body) ), close(S), ( memberchk(Code, [301,302]) -> ( (member("location":Loc, Hdrs) -> true ; Loc = ''), http_get(Loc, Data, Opts) ) ; (Data=Body, ignore(memberchk(final_url(Url), Opts)), ignore(memberchk(status_code(Code), Opts)), ignore(memberchk(headers(Hdrs), Opts))) ). http_post(Url, Data, Reply, Opts) :- http_get(Url, Reply, [post(Data)|Opts]). http_patch(Url, Data, Reply, Opts) :- http_post(Url, Data, Reply, [method(patch)|Opts]). http_put(Url, Data, Reply, Opts) :- http_post(Url, Data, Reply, [method(put)|Opts]). http_delete(Url, Data, Opts) :- http_get(Url, Data, [method(delete)|Opts]). % Handle a server request... http_request(S, Method, Path, Ver, Hdrs) :- getline(S, Line), split(Line, ' ', Method2, Rest), split(Rest, ' ', Path, Rest2), split(Rest2, '/', _, Ver), string_upper(Method2, Method), findall(Hdr, read_header(S, Hdr), Hdrs). % Create a server... http_server(Goal, Opts) :- (memberchk(port(Port), Opts) -> true ; Port = 0), ( integer(Port) -> format(atom(Host), ':~d', Port) ; format(atom(Host), '~w', Port) ), server(Host, S, []), accept(S, S2), fork, call(Goal, S2). :- help(subsumes_term(+term,+term), [iso(true)]). subsumes_term(G, S) :- \+ \+ ( term_variables(S, V1), G = S, term_variables(V1, V2), V2 == V1 ). :- meta_predicate(countall(0,?)). :- help(countall(:callable,?integer), [iso(true)]). countall(_, N) :- can_be(N, integer, countall/2, _), integer(N), (N >= 0 -> true; throw(error(domain_error(not_less_than_zero, N), countall/2))), fail. countall(G, N) :- '$countall'(call(G), N0), N = N0. :- meta_predicate(call_cleanup(0,0)). :- help(call_cleanup(:callable,:callable), [iso(false)]). call_cleanup(G, C) :- (var(C) -> throw(error(instantiation_error, call_cleanup/3)); true), '$register_cleanup'(ignore(C)), '$call_cleanup'( call(G), Err, (catch(ignore(C), _, true), throw(Err)) ). :- meta_predicate(setup_call_cleanup(0,0,0)). :- help(setup_call_cleanup(:callable,:callable,:callable), [iso(false)]). setup_call_cleanup(S, G, C) :- once(S), (var(C) -> throw(error(instantiation_error, setup_call_cleanup/3)); true), '$register_cleanup'(ignore(C)), '$call_cleanup'( call(G), Err, (catch(ignore(C), _, true), throw(Err)) ). :- meta_predicate(forall(0,0)). :- help(forall(:callable,:callable), [iso(false)]). forall(Cond, Action) :- \+ (Cond, \+ Action). :- help(succ(?integer,+integer), [iso(false)]). :- help(succ(+integer,-integer), [iso(false)]). succ(I, S) :- can_be(not_less_than_zero, I), can_be(not_less_than_zero, S), ( integer(S) -> S > 0, I is S-1 ; integer(I) -> S is I+1 ; instantiation_error(succ/2) ). :- help(cfor(+evaluable,+evaluable,-var), [iso(false),desc('C-style for loop')]). cfor(I0,J0,K) :- I is I0, J is J0, between(I, J, K). :- help(variant(+term,+term), [iso(false)]). variant(X,Y) :- \+ \+ ( copy_term(X,XC), subsumes_term(XC,Y), subsumes_term(Y,XC) ). :- meta_predicate(call_det(0,?)). :- help(call_det(:callable,?boolean), [iso(false)]). call_det(G, Det) :- '$get_level'(L1), call(G), '$get_level'(L2), (L1 = L2 -> Det = true; Det = false). :- meta_predicate(findall(?,0,-,?)). :- help(findall(+term,:callable,-list,+list), [iso(false)]). findall(T, G, B, Tail) :- can_be(B, list, findall/4, _), can_be(Tail, list, findall/4, _), findall(T, G, B0), append(B0, Tail, B), !. :- meta_predicate(call_with_time_limit(+,0)). :- help(call_with_time_limit(+millisecs,:callable), [iso(false)]). call_with_time_limit(Time, Goal) :- Time0 is truncate(Time * 1000), '$alarm'(Time0), ( catch(once(Goal), E, ('$alarm'(0), throw(E))) -> '$alarm'(0) ; ('$alarm'(0), fail) ). :- meta_predicate(time_out(0,+,-)). :- help(time_out(:callable,+integer,?atom), [iso(false)]). time_out(Goal, Time, Result) :- '$alarm'(Time), ( catch(once(Goal), E, ('$alarm'(0), throw(E))) -> ('$alarm'(0), Result = success) ; ('$alarm'(0), fail) ). :- help(not(:callable), [iso(false),deprecated(true)]). :- meta_predicate(not(0)). not(X) :- X, !, fail. not(_). :- help(term_variables(+term,-list,?tail), [iso(false)]). term_variables(P1, P2, P3) :- term_variables(P1, P4), append(P4, P3, P2). P+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Written Apr 2021 by Aram Panasenco (panasenco@ucla.edu) Part of Scryer Prolog. `json_chars//1` can be used with [`phrase_from_file/2`](src/lib/pio.pl) or [`phrase/2`](src/lib/dcgs.pl) to parse and generate [JSON](https://www.json.org/json-en.html). BSD 3-Clause License Copyright (c) 2021, Aram Panasenco All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ :- module(json, [ json_chars//1 ]). :- use_module(library(dcgs)). :- use_module(library(dif)). :- use_module(library(lists)). /* The DCGs are written to match the McKeeman form presented on the right side of https://www.json.org/json-en.html as closely as possible. Note that the names in the McKeeman form conflict with the pictures on the site. */ json_chars(Internal) --> json_element(Internal). /* Because it's impossible to distinguish between an empty array [] and an empty string "", we distinguish between different types of values based on their principal functor. The principal functors match the types defined in the JSON Schema spec here: https://json-schema.org/draft/2020-12/json-schema-validation.html#rfc.section.6.1.1 EXCEPT we don't yet support the integer type. There are plans for more JSON Schema support in the near future. */ json_value(pairs(Pairs)) --> json_object(Pairs). json_value(list(List)) --> json_array(List). json_value(string(Chars)) --> json_string(Chars). json_value(number(Number)) --> json_number(Number). json_value(boolean(Bool)) --> json_boolean(Bool). json_value(null) --> "null". /* We pull json_boolean out into its own predicate in order to take advantage of first argument indexing and not leave choice points. For more details, watch this video on decomposing arguments: https://youtu.be/FZLofckPu4A?t=1648 */ json_boolean(true) --> "true". json_boolean(false) --> "false". json_object([]) --> "{", json_ws, "}". json_object([Pair|Pairs]) --> "{", json_members(Pairs, Pair), "}". /* `json_members//2` below is implemented with a lagged argument to take advantage of first argument indexing. This is a pure performance-driven decision that doesn't affect the logic. The predicate could equivalently be implementes as `json_members//1` below: ``` json_members([Key-Value, Pair2 | Pairs]) --> json_member(Key, Value), ",", json_members([Pair2 | Pairs]). ``` That's a logically equivalent and equally clean representation to the lagged argument. However, it leaves choice points, while using the lagged argument doesn't. For more info, watch: https://youtu.be/FZLofckPu4A?t=1737 */ json_members([], Key-Value) --> json_member(Key, Value). json_members([NextPair|Pairs], Key-Value) --> json_member(Key, Value), ",", json_members(Pairs, NextPair). json_member(string(Key), Value) --> json_ws, json_string(Key), json_ws, ":", json_element(Value). json_array([]) --> "[", json_ws, "]". json_array([Value|Values]) --> "[", json_elements(Values, Value), "]". /* Also using a lagged argument with `json_elements//2` to take advantage of first-argument indexing */ json_elements([], Value) --> json_element(Value). json_elements([NextValue|Values], Value) --> json_element(Value), ",", json_elements(Values, NextValue). json_element(Value) --> json_ws, json_value(Value), json_ws. json_string(Chars) --> "\"", json_characters(Chars), "\"". json_characters("") --> "". json_characters([Char|Chars]) --> json_character(Char), json_characters(Chars). /* Note on variable instantiation checks (`var/1` and `nonvar/1`) used below and in Prolog in general. Instantiation checks should never be used to change the logic of your program. Instead, they are one of many tools to adjust the 'control' or 'search strategy' used by Prolog to execute the logic of your program. For a general overview of the idea, read Bob Kowalski's "Algorithm = Logic + Control": https://www.doc.ic.ac.uk/~rak/papers/algorithm%20=%20logic%20+%20control.pdf For an introduction to search strategies in Prolog, read: https://www.metalevel.at/prolog/sorting#searching It's tempting to use instantiation checks to be more strict while generating and more relaxed while parsing. In fact, the early version of this library aimed to return exactly one result when generating. However, doing that is **wrong** and leads to difficult-to-catch bugs. Instead, adjust the search strategy to return the most ideal and strictest answer FIRST and then return less ideal answers on backtracking. As an example, consider a string containing just the forward slash. The JSON standard recommends the forward slash be escaped with a backslash, but allows it to not be escaped. Attempting to force stricter behavior with instantiation checks can lead to this confusing mess: ``` phrase(json:json_characters("/"), External). External = "\\/". ?- phrase(json:json_characters(Internal), "/"). Internal = "/" ; false. ?- phrase(json:json_characters("/"), "/"). false. ``` To avoid such bugs, never use instantiation checks to reduce the number of right answers, but rather to adjust the *path* used to traverse those answers. */ escape_char('"', '"'). escape_char('\\', '\\'). escape_char('/', '/'). escape_char('\b', 'b'). escape_char('\f', 'f'). escape_char('\n', 'n'). escape_char('\r', 'r'). escape_char('\t', 't'). json_character(EscapeChar) --> { escape_char(EscapeChar, PrintChar) }, "\\", [PrintChar]. json_character(PrintChar) --> [PrintChar], { dif(PrintChar, '\\'), dif(PrintChar, '"'), char_code(PrintChar, PrintCharCode), PrintCharCode >= 32 }. json_character(EscapeChar) --> "\\u", json_hex(H1), json_hex(H2), json_hex(H3), json_hex(H4), { ( nonvar(H1) -> EscapeCharCode is H1 * 16^3 + H2 * 16^2 + H3 * 16 + H4, char_code(EscapeChar, EscapeCharCode) ; char_code(EscapeChar, EscapeCharCode), H1 is (EscapeCharCode // 16^3) mod 16, H2 is (EscapeCharCode // 16^2) mod 16, H3 is (EscapeCharCode // 16^1) mod 16, H4 is (EscapeCharCode // 16^0) mod 16 ) }. json_hex(Digit) --> json_digit(Digit). json_hex(10) --> "a". json_hex(11) --> "b". json_hex(12) --> "c". json_hex(13) --> "d". json_hex(14) --> "e". json_hex(15) --> "f". json_hex(10) --> "A". json_hex(11) --> "B". json_hex(12) --> "C". json_hex(13) --> "D". json_hex(14) --> "E". json_hex(15) --> "F". /* I can't think of any alternatives to using `number_chars/2` when generating, though this leads to under-reporting of correct solutions. At least matching solutions unify when both are instantiated... ``` ?- phrase(json:json_number(N), "123E2"). N = 12300 ; false. ?- phrase(json:json_number(12300), Cs). Cs = "12300". ?- phrase(json:json_number(12300), "123E2"). true ; false. ``` */ parsing, [C] --> [C], { nonvar(C) }. json_number(Number) --> ( parsing -> json_sign_noplus(Sign), json_integer(Integer), json_fraction(Fraction), json_exponent(Exponent), { ( Exponent >= 0 -> Base = 10 ; Base = 10.0 ), Number is Sign * (Integer + Fraction) * Base ^ Exponent } ; { number_chars(Number, NumberChars) }, NumberChars ). json_integer(Digit) --> json_digit(Digit). json_integer(TotalValue) --> json_onenine(FirstDigit), json_digits(RemainingValue, Power), { TotalValue is FirstDigit * 10 ^ (Power + 1) + RemainingValue }. json_digits(Digit, 0) --> json_digit(Digit). json_digits(Value, Power) --> json_digit(FirstDigit), json_digits(RemainingValue, NextPower), { Power is NextPower + 1, Value is FirstDigit * 10^Power + RemainingValue }. json_digit(0) --> "0". json_digit(Digit) --> json_onenine(Digit). json_onenine(1) --> "1". json_onenine(2) --> "2". json_onenine(3) --> "3". json_onenine(4) --> "4". json_onenine(5) --> "5". json_onenine(6) --> "6". json_onenine(7) --> "7". json_onenine(8) --> "8". json_onenine(9) --> "9". json_fraction(0) --> "". json_fraction(Fraction) --> ".", json_digits(Value, Power), { Fraction is Value / 10.0 ^ (Power + 1) }. json_exponent(0) --> "". json_exponent(Exponent) --> json_exponent_signifier, json_sign(Sign), json_digits(Value, _), { Exponent is Sign * Value }. json_exponent_signifier --> "E". json_exponent_signifier --> "e". json_sign_noplus(1) --> "". json_sign_noplus(-1) --> "-". json_sign(Sign) --> json_sign_noplus(Sign). json_sign(1) --> "+". /* Make `json_ws/0` greedy when parsing, lazy when generating */ json_ws_empty --> "". json_ws_nonempty --> " ". json_ws_nonempty --> "\n". json_ws_nonempty --> "\r". json_ws_nonempty --> "\t". json_ws_greedy --> json_ws_nonempty, json_ws_greedy. json_ws_greedy --> json_ws_empty. json_ws_lazy --> json_ws_empty. json_ws_lazy --> json_ws_nonempty, json_ws_lazy. json_ws --> ( parsing -> json_ws_greedy ; json_ws_lazy ). /* Author: Ulrich Neumerkel E-mail: ulrich@complang.tuwien.ac.at Copyright (C): 2009 Ulrich Neumerkel. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY Ulrich Neumerkel ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL Ulrich Neumerkel OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. The views and conclusions contained in the software and documentation are those of the authors and should not be interpreted as representing official policies, either expressed or implied, of Ulrich Neumerkel. */ :- module(lambda, [ (^)/3, (^)/4, (^)/5, (^)/6, (^)/7, (^)/8, (^)/9, (^)/10, (\)/1, (\)/2, (\)/3, (\)/4, (\)/5, (\)/6, (\)/7, (\)/8, (+\)/2, (+\)/3, (+\)/4, (+\)/5, (+\)/6, (+\)/7, (+\)/8, (+\)/9, op(201,xfx,+\)]). :- use_module(library(iso_ext)). /** Lambda expressions This library provides lambda expressions to simplify higher order programming based on call/N. Lambda expressions are represented by ordinary Prolog terms. There are two kinds of lambda expressions: ``` Free+\X1^X2^ ..^XN^Goal \X1^X2^ ..^XN^Goal ``` The second is a shorthand for `t+\X1^X2^..^XN^Goal`. Xi are the parameters. Goal is a goal or continuation. Syntax note: Operators within Goal require parentheses due to the low precedence of the ^ operator. Free contains variables that are valid outside the scope of the lambda expression. They are thus free variables within. All other variables of Goal are considered local variables. They must not appear outside the lambda expression. This restriction is currently not checked. Violations may lead to unexpected bindings. In the following example the parentheses around X>3 are necessary. ``` ?- use_module(library(lambda)). ?- use_module(library(lists)). ?- maplist(\X^(X>3),[4,5,9]). true. ``` In the following X is a variable that is shared by both instances of the lambda expression. The second query illustrates the cooperation of continuations and lambdas. The lambda expression is in this case a continuation expecting a further argument. ``` ?- use_module(library(dif)). true. ?- Xs = [A,B], maplist(X+\Y^dif(X,Y), Xs). Xs = [A,B], dif:dif(X,A), dif:dif(X,B). ?- Xs = [A,B], maplist(X+\dif(X), Xs). Xs = [A,B], dif:dif(X,A), dif:dif(X,B). ``` The following queries are all equivalent. To see this, use the fact `f(x,y)`. ``` ?- call(f,A1,A2). ?- call(\X^f(X),A1,A2). ?- call(\X^Y^f(X,Y), A1,A2). ?- call(\X^(X+\Y^f(X,Y)), A1,A2). ?- call(call(f, A1),A2). ?- call(f(A1),A2). ?- f(A1,A2). A1 = x, A2 = y. ``` Further discussions [http://www.complang.tuwien.ac.at/ulrich/Prolog-inedit/ISO-Hiord](http://www.complang.tuwien.ac.at/ulrich/Prolog-inedit/ISO-Hiord) @tbd Static expansion similar to apply_macros. @author Ulrich Neumerkel */ :- meta_predicate(^(?,0,?)). :- meta_predicate(^(?,1,?,?)). :- meta_predicate(^(?,2,?,?,?)). :- meta_predicate(^(?,3,?,?,?,?)). :- meta_predicate(^(?,4,?,?,?,?,?)). :- meta_predicate(^(?,5,?,?,?,?,?,?)). :- meta_predicate(^(?,6,?,?,?,?,?,?,?)). :- meta_predicate(^(?,7,?,?,?,?,?,?,?,?)). :- meta_predicate(\(0)). :- meta_predicate(\(1,?)). :- meta_predicate(\(2,?,?)). :- meta_predicate(\(3,?,?,?)). :- meta_predicate(\(4,?,?,?,?)). :- meta_predicate(\(5,?,?,?,?,?)). :- meta_predicate(\(6,?,?,?,?,?,?)). :- meta_predicate(\(7,?,?,?,?,?,?,?)). :- meta_predicate(+\(?,0)). :- meta_predicate(+\(?,1,?)). :- meta_predicate(+\(?,2,?,?)). :- meta_predicate(+\(?,3,?,?,?)). :- meta_predicate(+\(?,4,?,?,?,?)). :- meta_predicate(+\(?,5,?,?,?,?,?)). :- meta_predicate(+\(?,6,?,?,?,?,?,?)). :- meta_predicate(+\(?,7,?,?,?,?,?,?,?)). :- meta_predicate(no_hat_call(0)). ^(V1,C_0,V1) :- no_hat_call(C_0). ^(V1,C_1,V1,V2) :- call(C_1,V2). ^(V1,C_2,V1,V2,V3) :- call(C_2,V2,V3). ^(V1,C_3,V1,V2,V3,V4) :- call(C_3,V2,V3,V4). ^(V1,C_4,V1,V2,V3,V4,V5) :- call(C_4,V2,V3,V4,V5). ^(V1,C_5,V1,V2,V3,V4,V5,V6) :- call(C_5,V2,V3,V4,V5,V6). ^(V1,C_6,V1,V2,V3,V4,V5,V6,V7) :- call(C_6,V2,V3,V4,V5,V6,V7). ^(V1,C_7,V1,V2,V3,V4,V5,V6,V7,V8) :- call(C_7,V2,V3,V4,V5,V6,V7,V8). \(FC_0) :- copy_term_nat(FC_0,C_0), no_hat_call(C_0). \(FC_1,V1) :- copy_term_nat(FC_1,C_1), call(C_1,V1). \(FC_2,V1,V2) :- copy_term_nat(FC_2,C_2), call(C_2,V1,V2). \(FC_3,V1,V2,V3) :- copy_term_nat(FC_3,C_3), call(C_3,V1,V2,V3). \(FC_4,V1,V2,V3,V4) :- copy_term_nat(FC_4,C_4), call(C_4,V1,V2,V3,V4). \(FC_5,V1,V2,V3,V4,V5) :- copy_term_nat(FC_5,C_5), call(C_5,V1,V2,V3,V4,V5). \(FC_6,V1,V2,V3,V4,V5,V6) :- copy_term_nat(FC_6,C_6), call(C_6,V1,V2,V3,V4,V5,V6). \(FC_7,V1,V2,V3,V4,V5,V6,V7) :- copy_term_nat(FC_7,C_7), call(C_7,V1,V2,V3,V4,V5,V6,V7). +\(GV,FC_0) :- copy_term_nat(GV+FC_0,GV+C_0), no_hat_call(C_0). +\(GV,FC_1,V1) :- copy_term_nat(GV+FC_1,GV+C_1), call(C_1,V1). +\(GV,FC_2,V1,V2) :- copy_term_nat(GV+FC_2,GV+C_2), call(C_2,V1,V2). +\(GV,FC_3,V1,V2,V3) :- copy_term_nat(GV+FC_3,GV+C_3), call(C_3,V1,V2,V3). +\(GV,FC_4,V1,V2,V3,V4) :- copy_term_nat(GV+FC_4,GV+C_4), call(C_4,V1,V2,V3,V4). +\(GV,FC_5,V1,V2,V3,V4,V5) :- copy_term_nat(GV+FC_5,GV+C_5), call(C_5,V1,V2,V3,V4,V5). +\(GV,FC_6,V1,V2,V3,V4,V5,V6) :- copy_term_nat(GV+FC_6,GV+C_6), call(C_6,V1,V2,V3,V4,V5,V6). +\(GV,FC_7,V1,V2,V3,V4,V5,V6,V7) :- copy_term_nat(GV+FC_7,GV+C_7), call(C_7,V1,V2,V3,V4,V5,V6,V7). %% no_hat_call(:Goal_0) % % Like call, but issues an error for a goal (^)/2. Such goals are % likely the result of an insufficient number of arguments. no_hat_call(MGoal_0) :- strip_module(MGoal_0, _, Goal_0), ( nonvar(Goal_0), Goal_0 = (_^_) -> throw( error( existence_error(lambda_parameter,MGoal_0), _)) ; call(MGoal_0) ). % I would like to replace this by: % V1^Goal :- throw(error(existence_error(lambda_parameter,V1^Goal),_)). :- module(linda, [ linda_eval/1, linda_eval/2, out/1, inp/1, rdp/1, in/1, rd/1, bagof_inp/3, bagof_rdp/3 ]). :- dynamic(linda/1). linda_call_(H, G) :- G, H = G, out(H). linda_eval(Goal) :- copy_term(Goal, Goal2), call_task(linda_call_(_, Goal2)). linda_eval(Head, Goal) :- copy_term(Goal, Goal2), call_task(linda_call_(Head, Goal2)). out(Tuple) :- assertz('$linda'(Tuple)), yield. inp(Tuple) :- retract('$linda'(Tuple)). rdp(Tuple) :- '$linda'(Tuple). in(Tuple) :- once(retract('$linda'(Tuple))). in(Tuple) :- yield, in(Tuple). rd(Tuple) :- '$linda'(Tuple). rd(Tuple) :- yield, rd(Tuple). turn_(Free^Generator, Functor, Goal) :- !, turn_(Generator, Functor, Goal2), Goal = Free^Goal2. turn_(Generator, Functor, Goal) :- Goal =.. [Functor,Generator]. bagof_inp(Template, Tuple, Bag) :- turn_(Tuple, inp, Goal), bagof(Template, Goal, Bag). bagof_rdp(Template, Tuple, Bag) :- turn_(Tuple, rdp, Goal), bagof(Template, Goal, Bag). A:- module(lists, [ member/2, memberchk/2, select/3, selectchk/3, append/2, append/3, subtract/3, union/3, intersection/3, is_set/1, nth1/3, nth0/3, nth1/4, nth0/4, last/2, same_length/2, transpose/2, sum_list/2, max_list/2, min_list/2, % SWI list_sum/2, list_max/2, list_min/2, % Modern list_to_set/2, length/2, reverse/2, exclude/3, include/3, permutation/2, foldl/4, foldl/5, foldl/6, flatten/2, list_to_conjunction/2, maplist/2, maplist/3, maplist/4, maplist/5, maplist/6, maplist/7, maplist/8, tasklist/2, tasklist/3, tasklist/4, tasklist/5, tasklist/6, tasklist/7, tasklist/8 ]). list_to_conjunction(List0, T) :- reverse(List0, List), toconjunction_(List, true, T). toconjunction_([], In, In). toconjunction_([H|T], true, Out) :- !, Out2 = H, toconjunction_(T, Out2, Out). toconjunction_([H|T], In, Out) :- Out2 = (H, In), toconjunction_(T, Out2, Out). conjunction_to_list(T, List) :- tolist_(T, List). tolist_((T1,T2), [T1|Rest]) :- !, tolist_(T2, Rest). tolist_(T, [T|[]]). :- help(list_to_conjunction(?list,?list), [iso(false), desc('Does as it says.')]). flatten(List, FlatList) :- flatten_(List, [], FlatList0), !, FlatList = FlatList0. flatten_(Var, Tl, [Var|Tl]) :- var(Var), !. flatten_([], Tl, Tl) :- !. flatten_([Hd|Tl], Tail, List) :- !, flatten_(Hd, FlatHeadTail, List), flatten_(Tl, Tail, FlatHeadTail). flatten_(NonList, Tl, [NonList|Tl]). :- help(flatten(?list,?list), [iso(false), desc('Does as it says.')]). reverse(Xs, Ys) :- ( nonvar(Xs) -> reverse_(Xs, Ys, [], Xs) ; reverse_(Ys, Xs, [], Ys) ). reverse_([], [], YsRev, YsRev). reverse_([_|Xs], [Y1|Ys], YsPreludeRev, Xss) :- reverse_(Xs, Ys, [Y1|YsPreludeRev], Xss). :- help(reverse(?list,?list), [iso(false), desc('Reverse one list to make another.')]). append([], []). append([L0|Ls0], Ls) :- append(L0, Rest, Ls), append(Ls0, Rest). :- help(append(?list,?list), [iso(false), desc('The concatention of a list of lists to make a new one.')]). append([], R, R). append([X|L], R, [X|S]) :- append(L, R, S). :- help(append(?term,?term,?term), [iso(false), desc('The concatenation of two lists to make a third.')]). memberchk(E, List) :- '$memberchk'(E, List, Tail), ( nonvar(Tail) -> true ; Tail = [_|_], memberchk(E, Tail) ). :- help(memberchk(?term,?term), [iso(false), desc('Is element a member of the list.')]). member(El, [H|T]) :- member_(T, El, H). member_(_, El, El). member_([H|T], El, _) :- member_(T, El, H). :- help(member(?term,?term), [iso(false), desc('Is element a member of the list.')]). selectchk(X, L, Rest) :- select(X, L, Rest), !. :- help(selectchk(+term,?term,?term), [iso(false), desc('Deterministically remove element from list to make a new one.')]). select(X, [Head|Tail], Rest) :- select3_(Tail, Head, X, Rest). select3_(Tail, Head, Head, Tail). select3_([Head2|Tail], Head, X, [Head|Rest]) :- select3_(Tail, Head2, X, Rest). :- help(select(+term,+term, ?term), [iso(false), desc('Remove element from a list to make a new one.')]). subtract([], _, []) :- !. subtract([H|T], L2, L3) :- memberchk(H, L2), !, subtract(T, L2, L3). subtract([H|T1], L2, [H|T3]) :- subtract(T1, L2, T3). :- help(subtract(+list,+list,-list), [iso(false), desc('Delete all elements from set to make a new one.')]). union([], L, L). union([H|T], Y, Z):- member(H, Y), !, union(T, Y, Z). union([H|T], Y, [H|Z]):- union(T, Y, Z). :- help(union(+list,+list,-list), [iso(false), desc('The union of two sets to produce a third.')]). intersection([], _, []). intersection([H|T], Y, [H|Z]) :- member(H, Y), !, intersection(T, Y, Z). intersection([_|T], Y, Z) :- intersection(T, Y, Z). :- help(intersection(+list,+list,-list), [iso(false), desc('The intersection of two sets to produce a third.')]). %% nth0(?N, ?Ls, ?E). % % Succeeds if in the N position of the list Ls, we found the element E. The elements start counting from zero. % % ``` % ?- nth0(2, [1,2,3,4], 3). % true. % ``` nth0(N, Es0, E) :- nonvar(N), '$skip_max_list'(Skip, N, Es0,Es1), !, ( Skip == N -> Es1 = [E|_] ; ( var(Es1) ; Es1 = [_|_] ) % a partial or infinite list -> R is N-Skip, skipn(R,Es1,Es2), Es2 = [E|_] ). nth0(N, Es0, E) :- can_be(not_less_than_zero, N), Es0 = [E0|Es1], nth0_el(0,N, E0,E, Es1). skipn(N0, Es0,Es) :- N0>0, N1 is N0-1, Es0 = [_|Es1], skipn(N1, Es1,Es). skipn(0, Es,Es). nth0_el(N0,N, E0,E, Es0) :- Es0 == [], !, % indexing N0 = N, E0 = E. nth0_el(N,N, E,E, _). nth0_el(N0,N, _,E, [E0|Es0]) :- N1 is N0+1, nth0_el(N1,N, E0,E, Es0). %% nth1(?N, ?Ls, ?E). % % Succeeds if in the N position of the list Ls, we found the element E. The elements start counting from one. % % ``` % ?- nth1(2, [1,2,3,4], 2). % true. % ``` nth1(N, Es0, E) :- N \== 0, nth0(N, [_|Es0], E), N \== 0. skipn(N0, Es0,Es, Xs0,Xs) :- N0>0, N1 is N0-1, Es0 = [E|Es1], Xs0 = [E|Xs1], skipn(N1, Es1,Es, Xs1,Xs). skipn(0, Es,Es, Xs,Xs). %% nth0(?N, ?Ls, ?E, ?Rs). % % Succeeds if in the N position of the list Ls, we found the element E and the rest of the list is Rs. The elements start counting from zero. % % ``` % ?- nth0(2, [1,2,3,4], 3, [1,2,4]). % true. % ``` nth0(N, Es0, E, Es) :- integer(N), N >= 0, !, skipn(N, Es0,Es1, Es,Es2), Es1 = [E|Es2]. nth0(N, Es0, E, Es) :- can_be(not_less_than_zero, N), Es0 = [E0|Es1], nth0_elx(0,N, E0,E, Es1, Es). nth0_elx(N0,N, E0,E, Es0, Es) :- Es0 == [], !, N0 = N, E0 = E, Es0 = Es. nth0_elx(N,N, E,E, Es, Es). nth0_elx(N0,N, E0,E, [E1|Es0], [E0|Es]) :- N1 is N0+1, nth0_elx(N1,N, E1,E, Es0, Es). % p.p.8.5 %% nth1(?N, ?Ls, ?E, ?Rs). % % Succeeds if in the N position of the list Ls, we found the element E and the rest of the list is Rs. The elements start counting from one. % % ``` % ?- nth1(2, [1,2,3,4], 2, [1,3,4]). % true. % ``` nth1(N, Es0, E, Es) :- N \== 0, nth0(N, [_|Es0], E, [_|Es]), N \== 0. :- help(nth0(?integer,?term,?term), [iso(false), desc('Indexed element (from 0) into list.')]). :- help(nth0(?integer,?term,?term,?term), [iso(false), desc('Indexed element (from 0) into list with remainder.')]). :- help(nth1(?integer,?term,?term), [iso(false), desc('Indexed element (from 1) into list.')]). :- help(nth1(?integer,+term,?term,?term), [iso(false), desc('Indexed element (from 1) into list with remainder.')]). last([H|T], Last) :- last_(T, H, Last). last_([], Last, Last). last_([H|T], _, Last) :- last_(T, H, Last). :- help(last(+list,-term), [iso(false)]). same_length([], []). same_length([_|As], [_|Bs]) :- same_length(As, Bs). :- help(same_length(?list,?list), [iso(false), desc('Are two list the same length.')]). list_sum(Xs, Sum) :- list_sum_(Xs, 0, Sum). sum_list(Xs, Sum) :- list_sum_(Xs, 0, Sum). :- help(sum_list(+list,?integer), [iso(false), deprecated(true), desc('Add all values of a list.')]). list_sum_([], Sum0, Sum) :- Sum = Sum0. list_sum_([H|T], Sum0, Sum) :- Sum1 is Sum0 + H, list_sum_(T, Sum1, Sum). :- help(list_sum(+list,?integer), [iso(false), desc('Add all values of a list.')]). list_max([H|T], Max) :- list_max_(T, H, Max). list_max([], _) :- fail. max_list([H|T], Max) :- list_max_(T, H, Max). max_list([], _) :- fail. :- help(max_list(+list,?integer), [iso(false), deprecated(true), desc('Highest value in list.')]). list_max_([], Max0, Max) :- Max = Max0. list_max_([H|T], Max0, Max) :- Max1 is max(H, Max0), list_max_(T, Max1, Max). :- help(list_max(+list,?integer), [iso(false), desc('Highest value in list.')]). list_min([H|T], Min) :- list_min_(T, H, Min). list_min([], _) :- fail. min_list([H|T], Min) :- list_min_(T, H, Min). min_list([], _) :- fail. :- help(min_list(+list,?integer), [iso(false), deprecated(true), desc('Lowest value in list.')]). list_min_([], Min0, Min) :- Min = Min0. list_min_([H|T], Min0, Min) :- Min1 is min(H, Min0), list_min_(T, Min1, Min). :- help(list_min(+list,?integer), [iso(false), desc('Lowest value in list.')]). list_to_set(Ls0, Ls) :- maplist(with_var, Ls0, LVs0), keysort(LVs0, LVs), same_elements(LVs), pick_firsts(LVs0, Ls). pick_firsts([], []). pick_firsts([E-V|EVs], Fs0) :- ( V == visited -> Fs0 = Fs ; V = visited, Fs0 = [E|Fs] ), pick_firsts(EVs, Fs). with_var(E, E-_). same_elements([]). same_elements([EV|EVs]) :- foldl(unify_same, EVs, EV, _). unify_same(E-V, Prev-Var, E-V) :- ( Prev == E -> Var = V ; true ). is_set(Set) :- '$skip_list'(Len, Set, Tail), Tail == [], sort(Set, Sorted), length(Sorted, Len) . :- help(is_set(+list), [iso(false), desc('Is it a set.')]). length(Xs0, N) :- '$skip_max_list'(M, N, Xs0,Xs), !, ( Xs == [] -> N = M ; nonvar(Xs) -> var(N), Xs = [_|_], resource_error(finite_memory,length/2) ; nonvar(N) -> R is N-M, length_rundown(Xs, R) ; N == Xs -> failingvarskip(Xs), resource_error(finite_memory,length/2) ; length_addendum(Xs, N, M) ). length(_, N) :- integer(N), !, domain_error(not_less_than_zero, N, length/2). length(_, N) :- type_error(integer, N, length/2). length_rundown(Xs, 0) :- !, Xs = []. length_rundown(Vs, N) :- '$unattributed_var'(Vs), % unconstrained !, '$det_length_rundown'(Vs, N). length_rundown([_|Xs], N) :- % force unification N1 is N-1, length(Xs, N1). % maybe some new info on Xs failingvarskip(Xs) :- '$unattributed_var'(Xs), % unconstrained !. failingvarskip([_|Xs0]) :- % force unification '$skip_max_list'(_, _, Xs0,Xs), ( nonvar(Xs) -> Xs = [_|_] ; failingvarskip(Xs) ). length_addendum([], N, N). length_addendum([_|Xs], N, M) :- M1 is M + 1, length_addendum(Xs, N, M1). :- help(length(?term,?integer), [iso(false), desc('Number of elements in list.')]). list_first_rest([L|Ls], L, Ls). transpose_(_, Fs, Lists0, Lists) :- maplist(list_first_rest, Lists0, Fs, Lists). lists_transpose_([], []). lists_transpose_([L|Ls], Ts) :- maplist(same_length(L), Ls), foldl(transpose_, L, Ts, [L|Ls], _). transpose(Ls, Ts) :- lists_transpose_(Ls, Ts). :- help(transpose(?list,?list), [iso(false), desc('Transpose list of lists.')]). foldl(G, L, V0, V) :- foldl_(L, G, V0, V). foldl_([], _, V, V). foldl_([H|T], G, V0, V) :- call(G, H, V0, V1), foldl_(T, G, V1, V). foldl(G, L1, L2, V0, V) :- foldl_(L1, L2, G, V0, V). foldl_([], [], _, V, V). foldl_([H1|T1], [H2|T2], G, V0, V) :- call(G, H1, H2, V0, V1), foldl_(T1, T2, G, V1, V). foldl(G, L1, L2, L3, V0, V) :- foldl_(L1, L2, L3, G, V0, V). foldl_([], [], [], _, V, V). foldl_([H1|T1], [H2|T2], [H3|T3], G, V0, V) :- call(G, H1, H2, H3, V0, V1), foldl_(T1, T2, T3, G, V1, V). :- help(foldl(:callable,+list,+var,-var), [iso(false)]). :- help(foldl(:callable,+list,+list,+var,-var), [iso(false)]). :- help(foldl(:callable,+list,+list,+list,+var,-var), [iso(false)]). :- meta_predicate(foldl(3, ?, ?, ?)). :- meta_predicate(foldl(4, ?, ?, ?, ?)). :- meta_predicate(foldl(5, ?, ?, ?, ?, ?)). :- meta_predicate(foldl(6, ?, ?, ?, ?, ?, ?)). include(G, L, Included) :- include_(L, G, Included). include_([], _, []). include_([X1|Xs1], P, Included) :- ( call(P, X1) -> Included = [X1|Included1] ; Included = Included1 ), include_(Xs1, P, Included1). :- help(include(:callable,?list), [iso(false)]). :- meta_predicate(include(2, ?, ?)). exclude(G, L, Included) :- exclude_(L, G, Included). exclude_([], _, []). exclude_([X1|Xs1], P, Included) :- ( call(P, X1) -> Included = Included1 ; Included = [X1|Included1] ), exclude_(Xs1, P, Included1). :- help(exclude(:callable,?list), [iso(false)]). :- meta_predicate(exclude(2, ?, ?)). permutation(Xs, Ys) :- '$skip_max_list'(Xlen, _, Xs, XTail), '$skip_max_list'(Ylen, _, Ys, YTail), ( XTail == [], YTail == [] % both proper lists -> Xlen == Ylen ; var(XTail), YTail == [] % partial, proper -> length(Xs, Ylen) ; XTail == [], var(YTail) % proper, partial -> length(Ys, Xlen) ; var(XTail), var(YTail) % partial, partial -> length(Xs, Len), length(Ys, Len) ; must_be(list, Xs), % either is not a list must_be(list, Ys) ), perm_(Xs, Ys). perm_([], []). perm_(List, [First|Perm]) :- select(First, List, Rest), perm_(Rest, Perm). :- help(permutation(?list,?list), [iso(false)]). :- use_module(library(gensym)). maplist(G, L) :- maplist_(L, G). maplist_([], _). maplist_([E|T], G) :- call(G, E), maplist_(T, G). maplist(G, L1, L2) :- maplist_(L1, L2, G). maplist_([], [], _). maplist_([E1|T1], [E2|T2], G) :- call(G, E1, E2), maplist_(T1, T2, G). maplist(G, L1, L2, L3) :- maplist_(L1, L2, L3, G). maplist_([], [], [], _). maplist_([E1|T1], [E2|T2], [E3|T3], G) :- call(G, E1, E2, E3), maplist_(T1, T2, T3, G). maplist(G, L1, L2, L3, L4) :- maplist_(L1, L2, L3, L4, G). maplist_([], [], [], [], _). maplist_([E1|T1], [E2|T2], [E3|T3], [E4|T4], G) :- call(G, E1, E2, E3, E4), maplist_(T1, T2, T3, T4, G). maplist(G, L1, L2, L3, L4, L5) :- maplist_(L1, L2, L3, L4, L5, G). maplist_([], [], [], [], [], _). maplist_([E1|T1], [E2|T2], [E3|T3], [E4|T4], [E5|T5], G) :- call(G, E1, E2, E3, E4, E5), maplist_(T1, T2, T3, T4, T5, G). maplist(G, L1, L2, L3, L4, L5, L6) :- maplist_(L1, L2, L3, L4, L5, L6, G). maplist_([], [], [], [], [], [], _). maplist_([E1|T1], [E2|T2], [E3|T3], [E4|T4], [E5|T5], [E6|T6], G) :- call(G, E1, E2, E3, E4, E5, E6), maplist_(T1, T2, T3, T4, T5, T6, G). maplist(G, L1, L2, L3, L4, L5, L6, L7) :- maplist_(L1, L2, L3, L4, L5, L6, L7, G). maplist_([], [], [], [], [], [], [], _). maplist_([E1|T1], [E2|T2], [E3|T3], [E4|T4], [E5|T5], [E6|T6], [E7|T7], G) :- call(G, E1, E2, E3, E4, E5, E6, E7), maplist_(T1, T2, T3, T4, T5, T6, T7, G). :- meta_predicate(maplist(1, ?)). :- meta_predicate(maplist(2, ?, ?)). :- meta_predicate(maplist(3, ?, ?, ?)). :- meta_predicate(maplist(4, ?, ?, ?, ?)). :- meta_predicate(maplist(5, ?, ?, ?, ?, ?)). :- meta_predicate(maplist(6, ?, ?, ?, ?, ?, ?)). :- meta_predicate(maplist(7, ?, ?, ?, ?, ?, ?, ?)). :- help(maplist(:callable,+list), [iso(false)]). :- help(maplist(:callable,+list,+list), [iso(false)]). :- help(maplist(:callable,+list,+list,+list), [iso(false)]). :- help(maplist(:callable,+list,+list,+list,+list), [iso(false)]). :- help(maplist(:callable,+list,+list,+list,+list,+list), [iso(false)]). :- help(maplist(:callable,+list,+list,+list,+list,+list,+list), [iso(false)]). :- help(maplist(:callable,+list,+list,+list,+list,+list,+list,+list), [iso(false)]). tasklist(G, L) :- tasklist_(L, G). tasklist_([], _) :- wait. tasklist_([E|T], G) :- call_task(G, E), tasklist_(T, G). tasklist(G, L1, L2) :- tasklist_(L1, L2, G). tasklist_([], [], _) :- wait. tasklist_([E1|T1], [E2|T2], G) :- call_task(G, E1, E2), tasklist_(T1, T2, G). tasklist(G, L1, L2, L3) :- tasklist_(L1, L2, L3, G). tasklist_([], [], [], _) :- wait. tasklist_([E1|T1], [E2|T2], [E3|T3], G) :- call_task(G, E1, E2, E3), tasklist_(T1, T2, T3, G). tasklist(G, L1, L2, L3, L4) :- tasklist_(L1, L2, L3, L4, G). tasklist_([], [], [], [], _) :- wait. tasklist_([E1|T1], [E2|T2], [E3|T3], [E4|T4], G) :- call_task(G, E1, E2, E3, E4), tasklist_(T1, T2, T3, T4, G). tasklist(G, L1, L2, L3, L4, L5) :- tasklist_(L1, L2, L3, L4, L5, G). tasklist_([], [], [], [], [], _) :- wait. tasklist_([E1|T1], [E2|T2], [E3|T3], [E4|T4], [E5|T5], G) :- call_task(G, E1, E2, E3, E4, E5), tasklist_(T1, T2, T3, T4, T5, G). tasklist(G, L1, L2, L3, L4, L5, L6) :- tasklist_(L1, L2, L3, L4, L5, L6, G). tasklist_([], [], [], [], [], [], _) :- wait. tasklist_([E1|T1], [E2|T2], [E3|T3], [E4|T4], [E5|T5], [E6|T6], G) :- call_task(G, E1, E2, E3, E4, E5, E6), tasklist_(T1, T2, T3, T4, T5, T6, G). tasklist(G, L1, L2, L3, L4, L5, L6, L7) :- tasklist_(L1, L2, L3, L4, L5, L6, L7, G). tasklist_([], [], [], [], [], [], [], _) :- wait. tasklist_([E1|T1], [E2|T2], [E3|T3], [E4|T4], [E5|T5], [E6|T6], [E7|T7], G) :- call_task(G, E1, E2, E3, E4, E5, E6, E7), tasklist_(T1, T2, T3, T4, T5, T6, T7, G). :- meta_predicate(tasklist(1, ?)). :- meta_predicate(tasklist(2, ?, ?)). :- meta_predicate(tasklist(3, ?, ?, ?)). :- meta_predicate(tasklist(4, ?, ?, ?, ?)). :- meta_predicate(tasklist(5, ?, ?, ?, ?, ?)). :- meta_predicate(tasklist(6, ?, ?, ?, ?, ?, ?)). :- meta_predicate(tasklist(7, ?, ?, ?, ?, ?, ?, ?)). :- help(tasklist(:callable,+list), [iso(false)]). :- help(tasklist(:callable,+list,+list), [iso(false)]). :- help(tasklist(:callable,+list,+list,+list), [iso(false)]). :- help(tasklist(:callable,+list,+list,+list,+list), [iso(false)]). :- help(tasklist(:callable,+list,+list,+list,+list,+list), [iso(false)]). :- help(tasklist(:callable,+list,+list,+list,+list,+list,+list), [iso(false)]). :- help(tasklist(:callable,+list,+list,+list,+list,+list,+list,+list), [iso(false)]). K/* Author: Jan Wielemaker E-mail: J.Wielemaker@vu.nl WWW: http://www.swi-prolog.org Copyright (c) 2001-2014, University of Amsterdam VU University Amsterdam All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ :- module(ordsets, [ is_ordset/1, % @Term list_to_ord_set/2, % +List, -OrdSet ord_add_element/3, % +Set, +Element, -NewSet ord_del_element/3, % +Set, +Element, -NewSet ord_selectchk/3, % +Item, ?Set1, ?Set2 ord_intersect/2, % +Set1, +Set2 (test non-empty) ord_intersect/3, % +Set1, +Set2, -Intersection ord_intersection/3, % +Set1, +Set2, -Intersection ord_intersection/4, % +Set1, +Set2, -Intersection, -Diff ord_disjoint/2, % +Set1, +Set2 ord_subtract/3, % +Set, +Delete, -Remaining ord_union/2, % +SetOfOrdSets, -Set ord_union/3, % +Set1, +Set2, -Union ord_union/4, % +Set1, +Set2, -Union, -New ord_subset/2, % +Sub, +Super (test Sub is in Super) % Non-Quintus extensions ord_empty/1, % ?Set ord_memberchk/2, % +Element, +Set, ord_symdiff/3, % +Set1, +Set2, ?Diff % SICSTus extensions ord_seteq/2, % +Set1, +Set2 ord_intersection/2 % +PowerSet, -Intersection ]). :- use_module(library(lists)). /** Ordered set manipulation Ordered sets are lists with unique elements sorted to the standard order of terms (see `sort/2`). Exploiting ordering, many of the set operations can be expressed in order N rather than N^2 when dealing with unordered sets that may contain duplicates. The library(ordsets) is available in a number of Prolog implementations. Our predicates are designed to be compatible with common practice in the Prolog community. Some of these predicates match directly to corresponding list operations. It is advised to use the versions from this library to make clear you are operating on ordered sets. An exception is `member/2`. See `ord_memberchk/2`. The ordsets library is based on the standard order of terms. This implies it can handle all Prolog terms, including variables. Note however, that the ordering is not stable if a term inside the set is further instantiated. Also note that variable ordering changes if variables in the set are unified with each other or a variable in the set is unified with a variable that is _older_ than the newest variable in the set. In practice, this implies that it is allowed to use member(X, OrdSet) on an ordered set that holds variables only if X is a fresh variable. In other cases one should cease using it as an ordset because the order it relies on may have been changed. */ %% is_ordset(@Term) is semidet. % % True if Term is an ordered set. All predicates in this library % expect ordered sets as input arguments. Failing to fullfil this % assumption results in undefined behaviour. Typically, ordered % sets are created by predicates from this library, `sort/2` or % `setof/3`. is_ordset(Term) :- '$skip_max_list'(_, _, Term, Tail), Tail == [], %% is_list(Term), is_ordset2(Term). is_ordset2([]). is_ordset2([H|T]) :- is_ordset3(T, H). is_ordset3([], _). is_ordset3([H2|T], H) :- H2 @> H, is_ordset3(T, H2). %% ord_empty(?List) is semidet. % % True when List is the empty ordered set. Simply unifies list % with the empty list. Not part of Quintus. ord_empty([]). %% ord_seteq(+Set1, +Set2) is semidet. % % True if Set1 and Set2 have the same elements. As both are % canonical sorted lists, this is the same as `==/2`. ord_seteq(Set1, Set2) :- Set1 == Set2. %% list_to_ord_set(+List, -OrdSet) is det. % % Transform a list into an ordered set. This is the same as % sorting the list. list_to_ord_set(List, Set) :- sort(List, Set). %% ord_intersect(+Set1, +Set2) is semidet. % % True if both ordered sets have a non-empty intersection. ord_intersect([H1|T1], L2) :- ord_intersect_(L2, H1, T1). ord_intersect_([H2|T2], H1, T1) :- compare(Order, H1, H2), ord_intersect__(Order, H1, T1, H2, T2). ord_intersect__(<, _H1, T1, H2, T2) :- ord_intersect_(T1, H2, T2). ord_intersect__(=, _H1, _T1, _H2, _T2). ord_intersect__(>, H1, T1, _H2, T2) :- ord_intersect_(T2, H1, T1). %% ord_disjoint(+Set1, +Set2) is semidet. % % True if Set1 and Set2 have no common elements. This is the % negation of `ord_intersect/2`. ord_disjoint(Set1, Set2) :- \+ ord_intersect(Set1, Set2). %% ord_intersect(+Set1, +Set2, -Intersection) % % Intersection holds the common elements of Set1 and Set2. % % This predicate is *deprecated*. Use `ord_intersection/3` ord_intersect(Set1, Set2, Intersection) :- oset_int(Set1, Set2, Intersection). %% ord_intersection(+PowerSet, -Intersection) % % Intersection of a powerset. True when Intersection is an ordered % set holding all elements common to all sets in PowerSet. ord_intersection(PowerSet, Intersection) :- key_by_length(PowerSet, Pairs), keysort(Pairs, [_-S|Sorted]), l_int(Sorted, S, Intersection). key_by_length([], []). key_by_length([H|T0], [L-H|T]) :- length(H, L), key_by_length(T0, T). l_int([], S, S). l_int([_-H|T], S0, S) :- ord_intersection(S0, H, S1), l_int(T, S1, S). %% ord_intersection(+Set1, +Set2, -Intersection) is det. % % Intersection holds the common elements of Set1 and Set2. Uses % `ord_disjoint/2` if Intersection is bound to `[]` on entry. ord_intersection(Set1, Set2, Intersection) :- ( Intersection == [] -> ord_disjoint(Set1, Set2) ; oset_int(Set1, Set2, Intersection) ). %% ord_intersection(+Set1, +Set2, ?Intersection, ?Difference) is det. % % Intersection and difference between two ordered sets. % Intersection is the intersection between Set1 and Set2, while % Difference is defined by `ord_subtract(Set2, Set1, Difference)`. ord_intersection([], L, [], L) :- !. ord_intersection([_|_], [], [], []) :- !. ord_intersection([H1|T1], [H2|T2], Intersection, Difference) :- compare(Diff, H1, H2), ord_intersection2(Diff, H1, T1, H2, T2, Intersection, Difference). ord_intersection2(=, H1, T1, _H2, T2, [H1|T], Difference) :- ord_intersection(T1, T2, T, Difference). ord_intersection2(<, _, T1, H2, T2, Intersection, Difference) :- ord_intersection(T1, [H2|T2], Intersection, Difference). ord_intersection2(>, H1, T1, H2, T2, Intersection, [H2|HDiff]) :- ord_intersection([H1|T1], T2, Intersection, HDiff). %% ord_add_element(+Set1, +Element, ?Set2) is det. % % Insert an element into the set. This is the same as % `ord_union(Set1, [Element], Set2)`. ord_add_element(Set1, Element, Set2) :- oset_addel(Set1, Element, Set2). %% ord_del_element(+Set, +Element, -NewSet) is det. % % Delete an element from an ordered set. This is the same as % `ord_subtract(Set, [Element], NewSet)`. ord_del_element(Set, Element, NewSet) :- oset_delel(Set, Element, NewSet). %% ord_selectchk(+Item, ?Set1, ?Set2) is semidet. % % `selectchk/3`, specialised for ordered sets. Is true when % select(Item, Set1, Set2) and Set1, Set2 are both sorted lists % without duplicates. This implementation is only expected to work % for Item ground and either Set1 or Set2 ground. The "chk" suffix % is meant to remind you of `memberchk/2`, which also expects its % first argument to be ground. `ord_selectchk(X, S, T) => % ord_memberchk(X, S) & \+ ord_memberchk(X, T).` % % Author: Richard O'Keefe ord_selectchk(Item, [X|Set1], [X|Set2]) :- X @< Item, !, ord_selectchk(Item, Set1, Set2). ord_selectchk(Item, [Item|Set1], Set1) :- ( Set1 == [] -> true ; Set1 = [Y|_] -> Item @< Y ). %% ord_memberchk(+Element, +OrdSet) is semidet. % % True if Element is a member of OrdSet, compared using ==. Note % that _enumerating_ elements of an ordered set can be done using % `member/2`. % % Some Prolog implementations also provide `ord_member/2`, with the % same semantics as `ord_memberchk/2`. We believe that having a % semidet `ord_member/2` is unacceptably inconsistent with the \*\_chk % convention. Portable code should use `ord_memberchk/2` or % `member/2`. % % Author: Richard O'Keefe ord_memberchk(Item, [X1,X2,X3,X4|Xs]) :- !, compare(R4, Item, X4), ( R4 = (>) -> ord_memberchk(Item, Xs) ; R4 = (<) -> compare(R2, Item, X2), ( R2 = (>) -> Item == X3 ; R2 = (<) -> Item == X1 ;/* R2 = (=), Item == X2 */ true ) ;/* R4 = (=) */ true ). ord_memberchk(Item, [X1,X2|Xs]) :- !, compare(R2, Item, X2), ( R2 = (>) -> ord_memberchk(Item, Xs) ; R2 = (<) -> Item == X1 ;/* R2 = (=) */ true ). ord_memberchk(Item, [X1]) :- Item == X1. %% ord_subset(+Sub, +Super) is semidet. % % Is true if all elements of Sub are in Super ord_subset([], _). ord_subset([H1|T1], [H2|T2]) :- compare(Order, H1, H2), ord_subset_(Order, H1, T1, T2). ord_subset_(>, H1, T1, [H2|T2]) :- compare(Order, H1, H2), ord_subset_(Order, H1, T1, T2). ord_subset_(=, _, T1, T2) :- ord_subset(T1, T2). %% ord_subtract(+InOSet, +NotInOSet, -Diff) is det. % % Diff is the set holding all elements of InOSet that are not in % NotInOSet. ord_subtract(InOSet, NotInOSet, Diff) :- oset_diff(InOSet, NotInOSet, Diff). %% ord_union(+SetOfSets, -Union) is det. % % True if Union is the union of all elements in the superset % SetOfSets. Each member of SetOfSets must be an ordered set, the % sets need not be ordered in any way. ord_union([], []). ord_union([Set|Sets], Union) :- length([Set|Sets], NumberOfSets), ord_union_all(NumberOfSets, [Set|Sets], Union, []). ord_union_all(N, Sets0, Union, Sets) :- ( N =:= 1 -> Sets0 = [Union|Sets] ; N =:= 2 -> Sets0 = [Set1,Set2|Sets], ord_union(Set1,Set2,Union) ; A is N>>1, Z is N-A, ord_union_all(A, Sets0, X, Sets1), ord_union_all(Z, Sets1, Y, Sets), ord_union(X, Y, Union) ). %% ord_union(+Set1, +Set2, ?Union) is det. % % Union is the union of Set1 and Set2 ord_union(Set1, Set2, Union) :- oset_union(Set1, Set2, Union). %% ord_union(+Set1, +Set2, -Union, -New) is det. % % True iff `ord_union(Set1, Set2, Union)` and % `ord_subtract(Set2, Set1, New)`. ord_union([], Set2, Set2, Set2). ord_union([H|T], Set2, Union, New) :- ord_union_1(Set2, H, T, Union, New). ord_union_1([], H, T, [H|T], []). ord_union_1([H2|T2], H, T, Union, New) :- compare(Order, H, H2), ord_union(Order, H, T, H2, T2, Union, New). ord_union(<, H, T, H2, T2, [H|Union], New) :- ord_union_2(T, H2, T2, Union, New). ord_union(>, H, T, H2, T2, [H2|Union], [H2|New]) :- ord_union_1(T2, H, T, Union, New). ord_union(=, H, T, _, T2, [H|Union], New) :- ord_union(T, T2, Union, New). ord_union_2([], H2, T2, [H2|T2], [H2|T2]). ord_union_2([H|T], H2, T2, Union, New) :- compare(Order, H, H2), ord_union(Order, H, T, H2, T2, Union, New). %% ord_symdiff(+Set1, +Set2, ?Difference) is det. % % Is true when Difference is the symmetric difference of Set1 and % Set2. I.e., Difference contains all elements that are not in the % intersection of Set1 and Set2. The semantics is the same as the % sequence below (but the actual implementation requires only a % single scan). % % ``` % ord_union(Set1, Set2, Union), % ord_intersection(Set1, Set2, Intersection), % ord_subtract(Union, Intersection, Difference). % ``` % % For example: % % ``` % ?- ord_symdiff([1,2], [2,3], X). % X = [1,3]. % ``` ord_symdiff([], Set2, Set2). ord_symdiff([H1|T1], Set2, Difference) :- ord_symdiff(Set2, H1, T1, Difference). ord_symdiff([], H1, T1, [H1|T1]). ord_symdiff([H2|T2], H1, T1, Difference) :- compare(Order, H1, H2), ord_symdiff(Order, H1, T1, H2, T2, Difference). ord_symdiff(<, H1, Set1, H2, T2, [H1|Difference]) :- ord_symdiff(Set1, H2, T2, Difference). ord_symdiff(=, _, T1, _, T2, Difference) :- ord_symdiff(T1, T2, Difference). ord_symdiff(>, H1, T1, H2, Set2, [H2|Difference]) :- ord_symdiff(Set2, H1, T1, Difference). /* The osets library on which ordsets depends. Author: Jon Jagger E-mail: J.R.Jagger@shu.ac.uk Copyright (c) 1993-2011, Jon Jagger All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* Ordered set manipulation This library defines set operations on sets represented as ordered lists. @author Jon Jagger @deprecated Use the de-facto library ordsets.pl */ %% oset_is(+OSet) % check that OSet in correct format (standard order) oset_is(-) :- !, fail. % var filter oset_is([]). oset_is([H|T]) :- oset_is(T, H). oset_is(-, _) :- !, fail. % var filter oset_is([], _H). oset_is([H|T], H0) :- H0 @< H, % use standard order oset_is(T, H). %% oset_union(+OSet1, +OSet2, -Union). oset_union([], Union, Union). oset_union([H1|T1], L2, Union) :- union2(L2, H1, T1, Union). union2([], H1, T1, [H1|T1]). union2([H2|T2], H1, T1, Union) :- compare(Order, H1, H2), union3(Order, H1, T1, H2, T2, Union). union3(<, H1, T1, H2, T2, [H1|Union]) :- union2(T1, H2, T2, Union). union3(=, H1, T1, _H2, T2, [H1|Union]) :- oset_union(T1, T2, Union). union3(>, H1, T1, H2, T2, [H2|Union]) :- union2(T2, H1, T1, Union). %% oset_int(+OSet1, +OSet2, -Int) % ordered set intersection oset_int([], _Int, []). oset_int([H1|T1], L2, Int) :- isect2(L2, H1, T1, Int). isect2([], _H1, _T1, []). isect2([H2|T2], H1, T1, Int) :- compare(Order, H1, H2), isect3(Order, H1, T1, H2, T2, Int). isect3(<, _H1, T1, H2, T2, Int) :- isect2(T1, H2, T2, Int). isect3(=, H1, T1, _H2, T2, [H1|Int]) :- oset_int(T1, T2, Int). isect3(>, H1, T1, _H2, T2, Int) :- isect2(T2, H1, T1, Int). %% oset_diff(+InOSet, +NotInOSet, -Diff) % ordered set difference oset_diff([], _Not, []). oset_diff([H1|T1], L2, Diff) :- diff21(L2, H1, T1, Diff). diff21([], H1, T1, [H1|T1]). diff21([H2|T2], H1, T1, Diff) :- compare(Order, H1, H2), diff3(Order, H1, T1, H2, T2, Diff). diff12([], _H2, _T2, []). diff12([H1|T1], H2, T2, Diff) :- compare(Order, H1, H2), diff3(Order, H1, T1, H2, T2, Diff). diff3(<, H1, T1, H2, T2, [H1|Diff]) :- diff12(T1, H2, T2, Diff). diff3(=, _H1, T1, _H2, T2, Diff) :- oset_diff(T1, T2, Diff). diff3(>, H1, T1, _H2, T2, Diff) :- diff21(T2, H1, T1, Diff). %% oset_dunion(+SetofSets, -DUnion) % distributed union oset_dunion([], []). oset_dunion([H|T], DUnion) :- oset_dunion(T, H, DUnion). oset_dunion([], DUnion, DUnion). oset_dunion([H|T], DUnion0, DUnion) :- oset_union(H, DUnion0, DUnion1), oset_dunion(T, DUnion1, DUnion). %% oset_dint(+SetofSets, -DInt) % distributed intersection oset_dint([], []). oset_dint([H|T], DInt) :- dint(T, H, DInt). dint([], DInt, DInt). dint([H|T], DInt0, DInt) :- oset_int(H, DInt0, DInt1), dint(T, DInt1, DInt). %! oset_power(+Set, -PSet) % % True when PSet is the powerset of Set. That is, Pset is a set of % all subsets of Set, where each subset is a proper ordered set. oset_power(S, PSet) :- reverse(S, R), pset(R, [[]], PSet0), sort(PSet0, PSet). % The powerset of a set is the powerset of a set of one smaller, % together with the set of one smaller where each subset is extended % with the new element. Note that this produces the elements of the set % in reverse order. Hence the reverse in oset_power/2. pset([], PSet, PSet). pset([H|T], PSet0, PSet) :- happ(PSet0, H, PSet1), pset(T, PSet1, PSet). happ([], _, []). happ([S|Ss], H, [[H|S],S|Rest]) :- happ(Ss, H, Rest). %% oset_addel(+Set, +El, -Add) % ordered set element addition oset_addel([], El, [El]). oset_addel([H|T], El, Add) :- compare(Order, H, El), addel(Order, H, T, El, Add). addel(<, H, T, El, [H|Add]) :- oset_addel(T, El, Add). addel(=, H, T, _El, [H|T]). addel(>, H, T, El, [El,H|T]). %% oset_delel(+Set, +El, -Del) % ordered set element deletion oset_delel([], _El, []). oset_delel([H|T], El, Del) :- compare(Order, H, El), delel(Order, H, T, El, Del). delel(<, H, T, El, [H|Del]) :- oset_delel(T, El, Del). delel(=, _H, T, _El, T). delel(>, H, T, _El, [H|T]). /** Reasoning about pairs. Pairs are Prolog terms with principal functor `(-)/2`. A pair often has the form `Key-Value`. The predicates of this library relate pairs to keys and values. */ :- module(pairs, [pairs_keys_values/3, pairs_keys/2, pairs_values/2, group_pairs_by_key/2, map_list_to_pairs/3]). :- meta_predicate(map_list_to_pairs(2, ?, ?)). %% pairs_keys_values(?Pairs, ?Keys, ?Values) % % The first argument is a list of Pairs, the second the corresponding % Keys, and the third argument the corresponding values. pairs_keys_values([], [], []). pairs_keys_values([A-B|ABs], [A|As], [B|Bs]) :- pairs_keys_values(ABs, As, Bs). %% pairs_keys(?Pairs, ?Keys) % % Same as `pairs_keys_values(Pairs, Keys, _)`. pairs_keys(Ps, Ks) :- pairs_keys_values(Ps, Ks, _). %% pairs_values(?Pairs, ?Values) % % Same as `pairs_keys_values(Pairs, _, Values)`. pairs_values(Ps, Vs) :- pairs_keys_values(Ps, _, Vs). map_list_to_pairs(Pred, Ls, Ps) :- map_list_to_pairs2(Ls, Pred, Ps). map_list_to_pairs2([], _, []). map_list_to_pairs2([H|T0], Pred, [K-H|T]) :- call(Pred, H, K), map_list_to_pairs2(T0, Pred, T). group_pairs_by_key([], []). group_pairs_by_key([K-V|KVs0], [K-[V|Vs]|KVs]) :- same_key(K, KVs0, Vs, KVs1), group_pairs_by_key(KVs1, KVs). same_key(K0, [K1-V|KVs0], [V|Vs], KVs) :- K0 == K1, !, same_key(K0, KVs0, Vs, KVs). same_key(_, KVs, [], KVs). /** Pure I/O. Our goal is to encourage the use of definite clause grammars (DCGs) for describing strings. The predicates `phrase_from_file/[2,3]`, `phrase_to_file/[2,3]` and `phrase_to_stream/2` let us apply DCGs transparently to files and streams, and therefore decouple side-effects from declarative descriptions. */ :- module(pio, [phrase_from_file/2, phrase_from_file/3, phrase_to_file/2, phrase_to_file/3, phrase_to_stream/2 ]). :- use_module(library(dcgs)). :- use_module(library(error)). :- use_module(library(lists), [member/2, maplist/2]). :- use_module(library(charsio), [get_n_chars/3]). :- meta_predicate(phrase_from_file(2, ?)). :- meta_predicate(phrase_from_file(2, ?, ?)). :- meta_predicate(phrase_to_file(2, ?)). :- meta_predicate(phrase_to_file(2, ?, ?)). :- meta_predicate(phrase_to_stream(2, ?)). phrase_from_file(NT, File) :- phrase_from_file(NT, File, []). phrase_from_file(NT, File, Options) :- ( var(File) -> instantiation_error(phrase_from_file/3) ; must_be(list, Options), ( member(Var, Options), var(Var) -> instantiation_error(phrase_from_file/3) ; member(type(Type), Options) -> must_be(atom, Type), member(Type, [text,binary]) ; Type = text ), setup_call_cleanup( open(File, read, Stream, [mmap(Ms)|Options]), (copy_term(NT, NT2), NT2=NT, phrase(NT2, Ms, [])), close(Stream) ) ). %% phrase_to_stream(+GRBody, +Stream) % % Emit the list of characters described by the grammar rule body % GRBody to Stream. % % An ideal implementation of `phrase_to_stream/2` writes each % character as soon as it becomes known and no choice-points remain, % and thus avoids the manifestation of the entire string in memory. % See [#691](https://github.com/mthom/scryer-prolog/issues/691) for % more information. % % The current preliminary implementation is provided so that Prolog % programmers can already get used to describing output with DCGs, % and then writing it to a file when necessary. This simple % implementation suffices as long as the entire contents can be % represented in memory, and thus covers a large number of use cases. phrase_to_stream(GRBody, Stream) :- phrase(GRBody, Cs), must_be(chars, Cs), ( stream_property(Stream, type(binary)) -> ( '$first_non_octet'(Cs, N) -> domain_error(octet_character, N, phrase_to_stream/2) ; true ) ; true ), % we use a specialised internal predicate that uses only a % single "write" operation for efficiency. It is equivalent to % maplist(put_char(Stream), Cs). It also works for binary streams. '$put_chars'(Stream, Cs). phrase_to_file(GRBody, File) :- phrase_to_file(GRBody, File, []). phrase_to_file(GRBody, File, Options) :- setup_call_cleanup( open(File, write, Stream, Options), phrase_to_stream(GRBody, Stream), close(Stream) ). :- module(random, [ maybe/0, maybe/1, maybe/2, random_integer/3, set_random/1]). set_random(seed(random)) :- wall_time(Seed), set_seed(Seed), !. set_random(seed(Seed)) :- set_seed(Seed). maybe(K, N) :- P is K / N, random(F), F < P. maybe(P) :- random(F), F < P. maybe :- random(F), F < 0.5. random_integer(Lower, Upper, R) :- var(R), ( (var(Lower) ; var(Upper)) -> instantiation_error(random_integer/3) ; \+ integer(Lower) -> type_error(integer, Lower, random_integer/3) ; \+ integer(Upper) -> type_error(integer, Upper, random_integer/3) ; Upper > Lower, random(R0), R is floor((Upper - Lower) * R0 + Lower) ).  :- module(raylib, [ 'InitWindow'/3, 'WindowShouldClose'/1, 'SetTargetFPS'/1, 'GetWindowPosition'/1, 'GetScreenWidth'/1, 'GetScreenHeight'/1, 'IsKeyPressed'/2, 'BeginDrawing'/0, 'ClearBackground'/1, 'DrawText'/5, 'DrawFPS'/2, 'DrawCircle'/4, 'DrawCircleV'/3, 'EndDrawing'/0, 'CloseWindow'/0 ]). :- foreign_struct(float2, [float,float]). :- foreign_struct(float4, [float,float,float,float]). :- foreign_struct(matrix2, [matrix,matrix]). :- foreign_struct(char32, [uint64,uint64,uint64,uint64]). :- foreign_struct(color, [uint8,uint8,uint8,uint8]). :- foreign_struct(vector2, [float,float]). :- foreign_struct(vector3, [float,float,float]). :- foreign_struct(vector4, [float,float,float,float]). :- foreign_struct(quaternion, [float,float,float,float]). :- foreign_struct(matrix, [ float,float,float,float, float,float,float,float, float,float,float,float, float,float,float,float ]). :- foreign_struct(rectangle, [float,float,float,float]). :- foreign_struct(image, [ptr,sint,sint,sint,sint]). :- foreign_struct(texture, [uint,sint,sint,sint,sint]). :- foreign_struct(texture2d, [uint,sint,sint,sint,sint]). :- foreign_struct(texturecubemap, [uint,sint,sint,sint,sint]). :- foreign_struct(rendertexture, [uint,texture,texture]). :- foreign_struct(rendertexture2d, [uint,texture,texture]). :- foreign_struct(npatchinfo, [rectangle,sint,sint,sint,sint,sint]). :- foreign_struct(glyphinfo, [sint,sint,sint,sint,image]). :- foreign_struct(font, [sint,sint,sint,texture2d,ptr,ptr]). :- foreign_struct(camera3d, [vector3,vector3,vector3,float,sint]). :- foreign_struct(camera, [vector3,vector3,vector3,float,sint]). :- foreign_struct(camera2d, [vector2,vector2,float,float]). :- foreign_struct(mesh, [sint,sint,ptr,ptr,ptr,ptr,ptr,ptr,ptr,ptr,ptr,ptr,ptr,uint,ptr]). :- foreign_struct(shader, [uint,ptr]). :- foreign_struct(materialmap, [texture2d,color,float]). :- foreign_struct(material, [shader,ptr,float4]). :- foreign_struct(transform, [vector3,quaternion,vector3]). :- foreign_struct(boneinfo, [char32,sint]). :- foreign_struct(model, [matrix,sint,sint,ptr,ptr,ptr,sint,ptr,ptr]). :- foreign_struct(modelaninimation, [sint,sint,ptr]). :- foreign_struct(ray, [vector3,vector3]). :- foreign_struct(raycollision, [bool,float,vector,vector3]). :- foreign_struct(boundingbox, [vector3,vector3]). :- foreign_struct(wave, [uint,uint,uint,uint,ptr]). :- foreign_struct(audiostream, [ptr,ptr,uint,uint,uint]). :- foreign_struct(sound, [audiosound,uint]). :- foreign_struct(music, [audiostream,uint,bool,sint,ptr]). :- foreign_struct(vrdeviceinfo, [sint,sint,float,float,float,float,float,float,float4,float4]). :- foreign_struct(vrdevicestereoconfig, [matrix2,matrix2,float2,float2,float2,float2,float2,float2]). :- foreign_struct(filepathlist, [uint,uint,ptr]). :- use_foreign_module('libraylib.so', [ 'InitWindow'([sint,sint,cstr], void), 'SetTargetFPS'([sint], void), 'WindowShouldClose'([], bool), 'GetWindowPosition'([], vector2), 'GetScreenWidth'([], sint), 'GetScreenHeight'([], sint), 'IsKeyPressed'([sint], bool), 'BeginDrawing'([], void), 'ClearBackground'([color], void), 'DrawText'([cstr,sint,sint,sint,color], void), 'DrawFPS'([sint,sint], void), 'DrawCircle'([sint,sint,float,color], void), 'DrawCircleV'([vector2,float,color], void), 'EndDrawing'([], void), 'CloseWindow'([], void) ]). v/* This code implements Red-Black trees as described in: "Introduction to Algorithms", Second Edition Cormen, Leiserson, Rivest, and Stein, MIT Press Author: Vitor Santos Costa */ :- module(c_rbtrees, [rb_new/1, rb_empty/1, % ?T rb_lookup/3, % +Key, -Value, +T rb_update/4, % +T, +Key, +NewVal, -TN rb_update/5, % +T, +Key, ?OldVal, +NewVal, -TN rb_apply/4, % +T, +Key, :G, -TN rb_lookupall/3, % +Key, -Value, +T rb_insert/4, % +T0, +Key, ?Value, -TN rb_insert_new/4, % +T0, +Key, ?Value, -TN rb_delete/3, % +T, +Key, -TN rb_delete/4, % +T, +Key, -Val, -TN rb_visit/2, % +T, -Pairs rb_visit/3, rb_keys/2, % +T, +Keys rb_keys/3, rb_map/2, rb_map/3, rb_partial_map/4, rb_clone/3, rb_clone/4, rb_min/3, rb_max/3, rb_del_min/4, rb_del_max/4, rb_next/4, rb_previous/4, list_to_rbtree/2, ord_list_to_rbtree/2, is_rbtree/1, rb_size/2, rb_in/3 ]). /** Red black trees Red-Black trees are balanced search binary trees. They are named because nodes can be classified as either red or black. The code we include is based on "Introduction to Algorithms", second edition, by Cormen, Leiserson, Rivest and Stein. The library includes routines to insert, lookup and delete elements in the tree. A Red black tree is represented as a term t(Nil, Tree), where Nil is the Nil-node, a node shared for each nil-node in the tree. Any node has the form colour(Left, Key, Value, Right), where _colour_ is one of =red= or =black=. @author Vitor Santos Costa, Jan Wielemaker */ :- use_module(library('dialect/commons')). :- meta_predicate rb_map(+,2,-), rb_partial_map(+,+,2,-), rb_apply(+,+,2,-). :- hmtype rbtree(K,V) ---> t(tree(K,V),tree(K,V)). :- hmtype tree(K,V) ---> black(tree(K,V),K,V,tree(K,V)) ; red(tree(K,V),K,V,tree(K,V)) ; ''. :- hmtype cmp ---> (=) ; (<) ; (>). :- pred rb_new(rbtree(_K,_V)). :- pred rb_empty(rbtree(_K,_V)). :- pred rb_lookup(K,V,rbtree(K,V)). :- pred lookup(K,V, tree(K,V)). :- pred lookup(cmp, K, V, tree(K,V)). :- pred rb_min(rbtree(K,V),K,V). :- pred min(tree(K,V),K,V). :- pred rb_max(rbtree(K,V),K,V). :- pred max(tree(K,V),K,V). :- pred rb_next(rbtree(K,V),K,pair(K,V),V). :- pred next(tree(K,V),K,pair(K,V),V,tree(K,V)). % create an empty tree. %% rb_new(-T) is det. % % Create a new Red-Black tree. % % @deprecated Use rb_empty/1. rb_new(t(Nil,Nil)) :- Nil = black('',_,_,''). %% rb_empty(?T) is semidet. % % Succeeds if T is an empty Red-Black tree. rb_empty(t(Nil,Nil)) :- Nil = black('',_,_,''). %% rb_lookup(+Key, -Value, +T) is semidet. % % Backtrack through all elements with key Key in the Red-Black % tree T, returning for each the value Value. rb_lookup(Key, Val, t(_,Tree)) :- lookup(Key, Val, Tree). lookup(_, _, black('',_,_,'')) :- !, fail. lookup(Key, Val, Tree) :- arg(2,Tree,KA), compare(Cmp,KA,Key), lookup(Cmp,Key,Val,Tree). lookup(>, K, V, Tree) :- arg(1,Tree,NTree), lookup(K, V, NTree). lookup(<, K, V, Tree) :- arg(4,Tree,NTree), lookup(K, V, NTree). lookup(=, _, V, Tree) :- arg(3,Tree,V). %% rb_min(+T, -Key, -Value) is semidet. % % Key is the minimum key in T, and is associated with Val. rb_min(t(_,Tree), Key, Val) :- min(Tree, Key, Val). min(red(black('',_,_,_),Key,Val,_), Key, Val) :- !. min(black(black('',_,_,_),Key,Val,_), Key, Val) :- !. min(red(Right,_,_,_), Key, Val) :- min(Right,Key,Val). min(black(Right,_,_,_), Key, Val) :- min(Right,Key,Val). %% rb_max(+T, -Key, -Value) is semidet. % % Key is the maximal key in T, and is associated with Val. rb_max(t(_,Tree), Key, Val) :- max(Tree, Key, Val). max(red(_,Key,Val,black('',_,_,_)), Key, Val) :- !. max(black(_,Key,Val,black('',_,_,_)), Key, Val) :- !. max(red(_,_,_,Left), Key, Val) :- max(Left,Key,Val). max(black(_,_,_,Left), Key, Val) :- max(Left,Key,Val). %% rb_next(+T, +Key, -Next,-Value) is semidet. % % Next is the next element after Key in T, and is associated with % Val. rb_next(t(_,Tree), Key, Next, Val) :- next(Tree, Key, Next, Val, []). next(black('',_,_,''), _, _, _, _) :- !, fail. next(Tree, Key, Next, Val, Candidate) :- arg(2,Tree,KA), arg(3,Tree,VA), compare(Cmp,KA,Key), next(Cmp, Key, KA, VA, Next, Val, Tree, Candidate). next(>, K, KA, VA, NK, V, Tree, _) :- arg(1,Tree,NTree), next(NTree,K,NK,V,KA-VA). next(<, K, _, _, NK, V, Tree, Candidate) :- arg(4,Tree,NTree), next(NTree,K,NK,V,Candidate). next(=, _, _, _, NK, Val, Tree, Candidate) :- arg(4,Tree,NTree), ( min(NTree, NK, Val) -> true ; Candidate = (NK-Val) ). %% rb_previous(+T, +Key, -Previous, -Value) is semidet. % % Previous is the previous element after Key in T, and is % associated with Val. rb_previous(t(_,Tree), Key, Previous, Val) :- previous(Tree, Key, Previous, Val, []). previous(black('',_,_,''), _, _, _, _) :- !, fail. previous(Tree, Key, Previous, Val, Candidate) :- arg(2,Tree,KA), arg(3,Tree,VA), compare(Cmp,KA,Key), previous(Cmp, Key, KA, VA, Previous, Val, Tree, Candidate). previous(>, K, _, _, NK, V, Tree, Candidate) :- arg(1,Tree,NTree), previous(NTree,K,NK,V,Candidate). previous(<, K, KA, VA, NK, V, Tree, _) :- arg(4,Tree,NTree), previous(NTree,K,NK,V,KA-VA). previous(=, _, _, _, K, Val, Tree, Candidate) :- arg(1,Tree,NTree), ( max(NTree, K, Val) -> true ; Candidate = (K-Val) ). %% rb_update(+T, +Key, +NewVal, -TN) is semidet. %% rb_update(+T, +Key, ?OldVal, +NewVal, -TN) is semidet. % % Tree TN is tree T, but with value for Key associated with % NewVal. Fails if it cannot find Key in T. rb_update(t(Nil,OldTree), Key, OldVal, Val, t(Nil,NewTree)) :- update(OldTree, Key, OldVal, Val, NewTree). rb_update(t(Nil,OldTree), Key, Val, t(Nil,NewTree)) :- update(OldTree, Key, _, Val, NewTree). update(black(Left,Key0,Val0,Right), Key, OldVal, Val, NewTree) :- Left \= [], compare(Cmp,Key0,Key), (Cmp == (=) -> OldVal = Val0, NewTree = black(Left,Key0,Val,Right) ; Cmp == (>) -> NewTree = black(NewLeft,Key0,Val0,Right), update(Left, Key, OldVal, Val, NewLeft) ; NewTree = black(Left,Key0,Val0,NewRight), update(Right, Key, OldVal, Val, NewRight) ). update(red(Left,Key0,Val0,Right), Key, OldVal, Val, NewTree) :- compare(Cmp,Key0,Key), (Cmp == (=) -> OldVal = Val0, NewTree = red(Left,Key0,Val,Right) ; Cmp == (>) -> NewTree = red(NewLeft,Key0,Val0,Right), update(Left, Key, OldVal, Val, NewLeft) ; NewTree = red(Left,Key0,Val0,NewRight), update(Right, Key, OldVal, Val, NewRight) ). %% rb_apply(+T, +Key, :G, -TN) is semidet. % % If the value associated with key Key is Val0 in T, and if % call(G,Val0,ValF) holds, then TN differs from T only in that Key % is associated with value ValF in tree TN. Fails if it cannot % find Key in T, or if call(G,Val0,ValF) is not satisfiable. rb_apply(t(Nil,OldTree), Key, Goal, t(Nil,NewTree)) :- apply(OldTree, Key, Goal, NewTree). %apply(black('',_,_,''), _, _, _) :- !, fail. apply(black(Left,Key0,Val0,Right), Key, Goal, black(NewLeft,Key0,Val,NewRight)) :- Left \= [], compare(Cmp,Key0,Key), (Cmp == (=) -> NewLeft = Left, NewRight = Right, call(Goal,Val0,Val) ; Cmp == (>) -> NewRight = Right, Val = Val0, apply(Left, Key, Goal, NewLeft) ; NewLeft = Left, Val = Val0, apply(Right, Key, Goal, NewRight) ). apply(red(Left,Key0,Val0,Right), Key, Goal, red(NewLeft,Key0,Val,NewRight)) :- compare(Cmp,Key0,Key), ( Cmp == (=) -> NewLeft = Left, NewRight = Right, call(Goal,Val0,Val) ; Cmp == (>) -> NewRight = Right, Val = Val0, apply(Left, Key, Goal, NewLeft) ; NewLeft = Left, Val = Val0, apply(Right, Key, Goal, NewRight) ). %% rb_in(?Key, ?Val, +Tree) is nondet. % % True if Key-Val appear in Tree. Uses indexing if Key is bound. rb_in(Key, Val, t(_,T)) :- var(Key), !, enum(Key, Val, T). rb_in(Key, Val, t(_,T)) :- lookup(Key, Val, T). enum(Key, Val, black(L,K,V,R)) :- L \= '', enum_cases(Key, Val, L, K, V, R). enum(Key, Val, red(L,K,V,R)) :- enum_cases(Key, Val, L, K, V, R). enum_cases(Key, Val, L, _, _, _) :- enum(Key, Val, L). enum_cases(Key, Val, _, Key, Val, _). enum_cases(Key, Val, _, _, _, R) :- enum(Key, Val, R). %% rb_lookupall(+Key, -Value, +T) % % Lookup all elements with key Key in the red-black tree T, % returning the value Value. rb_lookupall(Key, Val, t(_,Tree)) :- lookupall(Key, Val, Tree). lookupall(_, _, black('',_,_,'')) :- !, fail. lookupall(Key, Val, Tree) :- arg(2,Tree,KA), compare(Cmp,KA,Key), lookupall(Cmp,Key,Val,Tree). lookupall(>, K, V, Tree) :- arg(4,Tree,NTree), rb_lookupall(K, V, NTree). lookupall(=, _, V, Tree) :- arg(3,Tree,V). lookupall(=, K, V, Tree) :- arg(1,Tree,NTree), lookupall(K, V, NTree). lookupall(<, K, V, Tree) :- arg(1,Tree,NTree), lookupall(K, V, NTree). /******************************* * TREE INSERTION * *******************************/ % We don't use parent nodes, so we may have to fix the root. %% rb_insert(+T0, +Key, ?Value, -TN) % % Add an element with key Key and Value to the tree T0 creating a % new red-black tree TN. Duplicated elements are not allowed. rb_insert(t(Nil,Tree0),Key,Val,t(Nil,Tree)) :- insert(Tree0,Key,Val,Nil,Tree). insert(Tree0,Key,Val,Nil,Tree) :- insert2(Tree0,Key,Val,Nil,TreeI,_), fix_root(TreeI,Tree). % % Cormen et al present the algorithm as % (1) standard tree insertion; % (2) from the viewpoint of the newly inserted node: % partially fix the tree; % move upwards % until reaching the root. % % We do it a little bit different: % % (1) standard tree insertion; % (2) move upwards: % when reaching a black node; % if the tree below may be broken, fix it. % We take advantage of Prolog unification % to do several operations in a single go. % % % actual insertion % insert2(black('',_,_,''), K, V, Nil, T, Status) :- !, T = red(Nil,K,V,Nil), Status = not_done. insert2(red(L,K0,V0,R), K, V, Nil, NT, Flag) :- ( K @< K0 -> NR = R, NT = red(NL,K0,V0,R), insert2(L, K, V, Nil, NL, Flag) ; K == K0 -> NT = red(L,K0,V,R), Flag = done ; NT = red(L,K0,V0,NR), insert2(R, K, V, Nil, NR, Flag) ). insert2(black(L,K0,V0,R), K, V, Nil, NT, Flag) :- ( K @< K0 -> insert2(L, K, V, Nil, IL, Flag0), fix_left(Flag0, black(IL,K0,V0,R), NT, Flag) ; K == K0 -> NT = black(L,K0,V,R), Flag = done ; insert2(R, K, V, Nil, IR, Flag0), fix_right(Flag0, black(L,K0,V0,IR), NT, Flag) ). % We don't use parent nodes, so we may have to fix the root. %% rb_insert_new(+T0, +Key, ?Value, -TN) % % Add a new element with key Key and Value to the tree T0 creating a % new red-black tree TN. Duplicated elements are not allowed. rb_insert_new(t(Nil,Tree0),Key,Val,t(Nil,Tree)) :- insert_new(Tree0,Key,Val,Nil,Tree). insert_new(Tree0,Key,Val,Nil,Tree) :- insert_new_2(Tree0,Key,Val,Nil,TreeI,_), fix_root(TreeI,Tree). % % actual insertion, copied from insert2 % insert_new_2(black('',_,_,''), K, V, Nil, T, Status) :- !, T = red(Nil,K,V,Nil), Status = not_done. insert_new_2(red(L,K0,V0,R), K, V, Nil, NT, Flag) :- ( K @< K0 -> NR = R, NT = red(NL,K0,V0,R), insert_new_2(L, K, V, Nil, NL, Flag) ; K == K0 -> fail ; NT = red(L,K0,V0,NR), insert_new_2(R, K, V, Nil, NR, Flag) ). insert_new_2(black(L,K0,V0,R), K, V, Nil, NT, Flag) :- ( K @< K0 -> insert_new_2(L, K, V, Nil, IL, Flag0), fix_left(Flag0, black(IL,K0,V0,R), NT, Flag) ; K == K0 -> fail ; insert_new_2(R, K, V, Nil, IR, Flag0), fix_right(Flag0, black(L,K0,V0,IR), NT, Flag) ). % % make sure the root is always black. % fix_root(black(L,K,V,R),black(L,K,V,R)). fix_root(red(L,K,V,R),black(L,K,V,R)). % % How to fix if we have inserted on the left % fix_left(done,T,T,done) :- !. fix_left(not_done,Tmp,Final,Done) :- fix_left(Tmp,Final,Done). % % case 1 of RB: just need to change colors. % fix_left(black(red(Al,AK,AV,red(Be,BK,BV,Ga)),KC,VC,red(De,KD,VD,Ep)), red(black(Al,AK,AV,red(Be,BK,BV,Ga)),KC,VC,black(De,KD,VD,Ep)), not_done) :- !. fix_left(black(red(red(Al,KA,VA,Be),KB,VB,Ga),KC,VC,red(De,KD,VD,Ep)), red(black(red(Al,KA,VA,Be),KB,VB,Ga),KC,VC,black(De,KD,VD,Ep)), not_done) :- !. % % case 2 of RB: got a knee so need to do rotations % fix_left(black(red(Al,KA,VA,red(Be,KB,VB,Ga)),KC,VC,De), black(red(Al,KA,VA,Be),KB,VB,red(Ga,KC,VC,De)), done) :- !. % % case 3 of RB: got a line % fix_left(black(red(red(Al,KA,VA,Be),KB,VB,Ga),KC,VC,De), black(red(Al,KA,VA,Be),KB,VB,red(Ga,KC,VC,De)), done) :- !. % % case 4 of RB: nothing to do % fix_left(T,T,done). % % How to fix if we have inserted on the right % fix_right(done,T,T,done) :- !. fix_right(not_done,Tmp,Final,Done) :- fix_right(Tmp,Final,Done). % % case 1 of RB: just need to change colors. % fix_right(black(red(Ep,KD,VD,De),KC,VC,red(red(Ga,KB,VB,Be),KA,VA,Al)), red(black(Ep,KD,VD,De),KC,VC,black(red(Ga,KB,VB,Be),KA,VA,Al)), not_done) :- !. fix_right(black(red(Ep,KD,VD,De),KC,VC,red(Ga,Ka,Va,red(Be,KB,VB,Al))), red(black(Ep,KD,VD,De),KC,VC,black(Ga,Ka,Va,red(Be,KB,VB,Al))), not_done) :- !. % % case 2 of RB: got a knee so need to do rotations % fix_right(black(De,KC,VC,red(red(Ga,KB,VB,Be),KA,VA,Al)), black(red(De,KC,VC,Ga),KB,VB,red(Be,KA,VA,Al)), done) :- !. % % case 3 of RB: got a line % fix_right(black(De,KC,VC,red(Ga,KB,VB,red(Be,KA,VA,Al))), black(red(De,KC,VC,Ga),KB,VB,red(Be,KA,VA,Al)), done) :- !. % % case 4 of RB: nothing to do. % fix_right(T,T,done). % % simplified processor % % pretty_print(t(_,T)) :- pretty_print(T,6). pretty_print(black('',_,_,''),_) :- !. pretty_print(red(L,K,_,R),D) :- DN is D+6, pretty_print(L,DN), format("~t~a:~d~*|~n",[r,K,D]), pretty_print(R,DN). pretty_print(black(L,K,_,R),D) :- DN is D+6, pretty_print(L,DN), format("~t~a:~d~*|~n",[b,K,D]), pretty_print(R,DN). rb_delete(t(Nil,T), K, t(Nil,NT)) :- delete(T, K, _, NT, _). %% rb_delete(+T, +Key, -TN). %% rb_delete(+T, +Key, -Val, -TN). % % Delete element with key Key from the tree T, returning the value % Val associated with the key and a new tree TN. rb_delete(t(Nil,T), K, V, t(Nil,NT)) :- delete(T, K, V0, NT, _), V = V0. % % I am afraid our representation is not as nice for delete % delete(red(L,K0,V0,R), K, V, NT, Flag) :- K @< K0, !, delete(L, K, V, NL, Flag0), fixup_left(Flag0,red(NL,K0,V0,R),NT, Flag). delete(red(L,K0,V0,R), K, V, NT, Flag) :- K @> K0, !, delete(R, K, V, NR, Flag0), fixup_right(Flag0,red(L,K0,V0,NR),NT, Flag). delete(red(L,_,V,R), _, V, OUT, Flag) :- % K == K0, delete_red_node(L,R,OUT,Flag). delete(black(L,K0,V0,R), K, V, NT, Flag) :- K @< K0, !, delete(L, K, V, NL, Flag0), fixup_left(Flag0,black(NL,K0,V0,R),NT, Flag). delete(black(L,K0,V0,R), K, V, NT, Flag) :- K @> K0, !, delete(R, K, V, NR, Flag0), fixup_right(Flag0,black(L,K0,V0,NR),NT, Flag). delete(black(L,_,V,R), _, V, OUT, Flag) :- % K == K0, delete_black_node(L,R,OUT,Flag). %% rb_del_min(+T, -Key, -Val, -TN) % % Delete the least element from the tree T, returning the key Key, % the value Val associated with the key and a new tree TN. rb_del_min(t(Nil,T), K, Val, t(Nil,NT)) :- del_min(T, K, Val, Nil, NT, _). del_min(red(black('',_,_,_),K,V,R), K, V, Nil, OUT, Flag) :- !, delete_red_node(Nil,R,OUT,Flag). del_min(red(L,K0,V0,R), K, V, Nil, NT, Flag) :- del_min(L, K, V, Nil, NL, Flag0), fixup_left(Flag0,red(NL,K0,V0,R), NT, Flag). del_min(black(black('',_,_,_),K,V,R), K, V, Nil, OUT, Flag) :- !, delete_black_node(Nil,R,OUT,Flag). del_min(black(L,K0,V0,R), K, V, Nil, NT, Flag) :- del_min(L, K, V, Nil, NL, Flag0), fixup_left(Flag0,black(NL,K0,V0,R),NT, Flag). %% rb_del_max(+T, -Key, -Val, -TN) % % Delete the largest element from the tree T, returning the key % Key, the value Val associated with the key and a new tree TN. rb_del_max(t(Nil,T), K, Val, t(Nil,NT)) :- del_max(T, K, Val, Nil, NT, _). del_max(red(L,K,V,black('',_,_,_)), K, V, Nil, OUT, Flag) :- !, delete_red_node(L,Nil,OUT,Flag). del_max(red(L,K0,V0,R), K, V, Nil, NT, Flag) :- del_max(R, K, V, Nil, NR, Flag0), fixup_right(Flag0,red(L,K0,V0,NR),NT, Flag). del_max(black(L,K,V,black('',_,_,_)), K, V, Nil, OUT, Flag) :- !, delete_black_node(L,Nil,OUT,Flag). del_max(black(L,K0,V0,R), K, V, Nil, NT, Flag) :- del_max(R, K, V, Nil, NR, Flag0), fixup_right(Flag0,black(L,K0,V0,NR), NT, Flag). delete_red_node(L1,L2,L1,done) :- L1 == L2, !. delete_red_node(black('',_,_,''),R,R,done) :- !. delete_red_node(L,black('',_,_,''),L,done) :- !. delete_red_node(L,R,OUT,Done) :- delete_next(R,NK,NV,NR,Done0), fixup_right(Done0,red(L,NK,NV,NR),OUT,Done). delete_black_node(L1,L2,L1,not_done) :- L1 == L2, !. delete_black_node(black('',_,_,''),red(L,K,V,R),black(L,K,V,R),done) :- !. delete_black_node(black('',_,_,''),R,R,not_done) :- !. delete_black_node(red(L,K,V,R),black('',_,_,''),black(L,K,V,R),done) :- !. delete_black_node(L,black('',_,_,''),L,not_done) :- !. delete_black_node(L,R,OUT,Done) :- delete_next(R,NK,NV,NR,Done0), fixup_right(Done0,black(L,NK,NV,NR),OUT,Done). delete_next(red(black('',_,_,''),K,V,R),K,V,R,done) :- !. delete_next(black(black('',_,_,''),K,V,red(L1,K1,V1,R1)), K,V,black(L1,K1,V1,R1),done) :- !. delete_next(black(black('',_,_,''),K,V,R),K,V,R,not_done) :- !. delete_next(red(L,K,V,R),K0,V0,OUT,Done) :- delete_next(L,K0,V0,NL,Done0), fixup_left(Done0,red(NL,K,V,R),OUT,Done). delete_next(black(L,K,V,R),K0,V0,OUT,Done) :- delete_next(L,K0,V0,NL,Done0), fixup_left(Done0,black(NL,K,V,R),OUT,Done). fixup_left(done,T,T,done). fixup_left(not_done,T,NT,Done) :- fixup2(T,NT,Done). % % case 1: x moves down, so we have to try to fix it again. % case 1 -> 2,3,4 -> done % fixup2(black(black(Al,KA,VA,Be),KB,VB,red(black(Ga,KC,VC,De),KD,VD,black(Ep,KE,VE,Fi))), black(T1,KD,VD,black(Ep,KE,VE,Fi)),done) :- !, fixup2(red(black(Al,KA,VA,Be),KB,VB,black(Ga,KC,VC,De)), T1, _). % % case 2: x moves up, change one to red % fixup2(red(black(Al,KA,VA,Be),KB,VB,black(black(Ga,KC,VC,De),KD,VD,black(Ep,KE,VE,Fi))), black(black(Al,KA,VA,Be),KB,VB,red(black(Ga,KC,VC,De),KD,VD,black(Ep,KE,VE,Fi))),done) :- !. fixup2(black(black(Al,KA,VA,Be),KB,VB,black(black(Ga,KC,VC,De),KD,VD,black(Ep,KE,VE,Fi))), black(black(Al,KA,VA,Be),KB,VB,red(black(Ga,KC,VC,De),KD,VD,black(Ep,KE,VE,Fi))),not_done) :- !. % % case 3: x stays put, shift left and do a 4 % fixup2(red(black(Al,KA,VA,Be),KB,VB,black(red(Ga,KC,VC,De),KD,VD,black(Ep,KE,VE,Fi))), red(black(black(Al,KA,VA,Be),KB,VB,Ga),KC,VC,black(De,KD,VD,black(Ep,KE,VE,Fi))), done) :- !. fixup2(black(black(Al,KA,VA,Be),KB,VB,black(red(Ga,KC,VC,De),KD,VD,black(Ep,KE,VE,Fi))), black(black(black(Al,KA,VA,Be),KB,VB,Ga),KC,VC,black(De,KD,VD,black(Ep,KE,VE,Fi))), done) :- !. % % case 4: rotate left, get rid of red % fixup2(red(black(Al,KA,VA,Be),KB,VB,black(C,KD,VD,red(Ep,KE,VE,Fi))), red(black(black(Al,KA,VA,Be),KB,VB,C),KD,VD,black(Ep,KE,VE,Fi)), done). fixup2(black(black(Al,KA,VA,Be),KB,VB,black(C,KD,VD,red(Ep,KE,VE,Fi))), black(black(black(Al,KA,VA,Be),KB,VB,C),KD,VD,black(Ep,KE,VE,Fi)), done). fixup_right(done,T,T,done). fixup_right(not_done,T,NT,Done) :- fixup3(T,NT,Done). % % case 1: x moves down, so we have to try to fix it again. % case 1 -> 2,3,4 -> done % fixup3(black(red(black(Fi,KE,VE,Ep),KD,VD,black(De,KC,VC,Ga)),KB,VB,black(Be,KA,VA,Al)), black(black(Fi,KE,VE,Ep),KD,VD,T1),done) :- !, fixup3(red(black(De,KC,VC,Ga),KB,VB,black(Be,KA,VA,Al)),T1,_). % % case 2: x moves up, change one to red % fixup3(red(black(black(Fi,KE,VE,Ep),KD,VD,black(De,KC,VC,Ga)),KB,VB,black(Be,KA,VA,Al)), black(red(black(Fi,KE,VE,Ep),KD,VD,black(De,KC,VC,Ga)),KB,VB,black(Be,KA,VA,Al)), done) :- !. fixup3(black(black(black(Fi,KE,VE,Ep),KD,VD,black(De,KC,VC,Ga)),KB,VB,black(Be,KA,VA,Al)), black(red(black(Fi,KE,VE,Ep),KD,VD,black(De,KC,VC,Ga)),KB,VB,black(Be,KA,VA,Al)), not_done):- !. % % case 3: x stays put, shift left and do a 4 % fixup3(red(black(black(Fi,KE,VE,Ep),KD,VD,red(De,KC,VC,Ga)),KB,VB,black(Be,KA,VA,Al)), red(black(black(Fi,KE,VE,Ep),KD,VD,De),KC,VC,black(Ga,KB,VB,black(Be,KA,VA,Al))), done) :- !. fixup3(black(black(black(Fi,KE,VE,Ep),KD,VD,red(De,KC,VC,Ga)),KB,VB,black(Be,KA,VA,Al)), black(black(black(Fi,KE,VE,Ep),KD,VD,De),KC,VC,black(Ga,KB,VB,black(Be,KA,VA,Al))), done) :- !. % % case 4: rotate right, get rid of red % fixup3(red(black(red(Fi,KE,VE,Ep),KD,VD,C),KB,VB,black(Be,KA,VA,Al)), red(black(Fi,KE,VE,Ep),KD,VD,black(C,KB,VB,black(Be,KA,VA,Al))), done). fixup3(black(black(red(Fi,KE,VE,Ep),KD,VD,C),KB,VB,black(Be,KA,VA,Al)), black(black(Fi,KE,VE,Ep),KD,VD,black(C,KB,VB,black(Be,KA,VA,Al))), done). % % whole list % %% rb_visit(+T, -Pairs) % % Pairs is an infix visit of tree T, where each element of Pairs % is of the form K-Val. rb_visit(t(_,T),Lf) :- visit(T,[],Lf). rb_visit(t(_,T),L0,Lf) :- visit(T,L0,Lf). visit(black('',_,_,_),L,L) :- !. visit(red(L,K,V,R),L0,Lf) :- visit(L,[K-V|L1],Lf), visit(R,L0,L1). visit(black(L,K,V,R),L0,Lf) :- visit(L,[K-V|L1],Lf), visit(R,L0,L1). :- meta_predicate rb_map(?,:,?). % this is not strictly required :- meta_predicate map(?,:,?,?). % this is required. %% rb_map(+T, :Goal) is semidet. % % True if call(Goal, Value) is true for all nodes in T. rb_map(t(Nil,Tree),Goal,t(Nil,NewTree)) :- map(Tree,Goal,NewTree,Nil). map(black('',_,_,''),_,Nil,Nil) :- !. map(red(L,K,V,R),Goal,red(NL,K,NV,NR),Nil) :- call(Goal,V,NV), !, map(L,Goal,NL,Nil), map(R,Goal,NR,Nil). map(black(L,K,V,R),Goal,black(NL,K,NV,NR),Nil) :- call(Goal,V,NV), !, map(L,Goal,NL,Nil), map(R,Goal,NR,Nil). :- meta_predicate rb_map(?,:). % this is not strictly required :- meta_predicate map(?,:). % this is required. %% rb_map(+T, :G, -TN) is semidet. % % For all nodes Key in the tree T, if the value associated with % key Key is Val0 in tree T, and if call(G,Val0,ValF) holds, then % the value associated with Key in TN is ValF. Fails if % call(G,Val0,ValF) is not satisfiable for all Var0. rb_map(t(_,Tree),Goal) :- map(Tree,Goal). map(black('',_,_,''),_) :- !. map(red(L,_,V,R),Goal) :- call(Goal,V), !, map(L,Goal), map(R,Goal). map(black(L,_,V,R),Goal) :- call(Goal,V), !, map(L,Goal), map(R,Goal). %% rb_clone(+T, -NT, -Pairs) % % "Clone" the red-back tree into a new tree with the same keys as % the original but with all values set to unbound values. Nodes is % a list containing all new nodes as pairs K-V. rb_clone(t(Nil,T),t(Nil,NT),Ns) :- clone(T,Nil,NT,Ns,[]). clone(black('',_,_,''),Nil,Nil,Ns,Ns) :- !. clone(red(L,K,_,R),Nil,red(NL,K,NV,NR),NsF,Ns0) :- clone(L,Nil,NL,NsF,[K-NV|Ns1]), clone(R,Nil,NR,Ns1,Ns0). clone(black(L,K,_,R),Nil,black(NL,K,NV,NR),NsF,Ns0) :- clone(L,Nil,NL,NsF,[K-NV|Ns1]), clone(R,Nil,NR,Ns1,Ns0). rb_clone(t(Nil,T),ONs,t(Nil,NT),Ns) :- clone(T,Nil,ONs,[],NT,Ns,[]). clone(black('',_,_,''),Nil,ONs,ONs,Nil,Ns,Ns) :- !. clone(red(L,K,V,R),Nil,ONsF,ONs0,red(NL,K,NV,NR),NsF,Ns0) :- clone(L,Nil,ONsF,[K-V|ONs1],NL,NsF,[K-NV|Ns1]), clone(R,Nil,ONs1,ONs0,NR,Ns1,Ns0). clone(black(L,K,V,R),Nil,ONsF,ONs0,black(NL,K,NV,NR),NsF,Ns0) :- clone(L,Nil,ONsF,[K-V|ONs1],NL,NsF,[K-NV|Ns1]), clone(R,Nil,ONs1,ONs0,NR,Ns1,Ns0). %% rb_partial_map(+T, +Keys, :G, -TN) % % For all nodes Key in Keys, if the value associated with key Key % is Val0 in tree T, and if call(G,Val0,ValF) holds, then the % value associated with Key in TN is ValF. Fails if or if % call(G,Val0,ValF) is not satisfiable for all Var0. Assumes keys % are not repeated. rb_partial_map(t(Nil,T0), Map, Goal, t(Nil,TF)) :- partial_map(T0, Map, [], Nil, Goal, TF). rb_partial_map(t(Nil,T0), Map, Map0, Goal, t(Nil,TF)) :- partial_map(T0, Map, Map0, Nil, Goal, TF). partial_map(T,[],[],_,_,T) :- !. partial_map(black('',_,_,_),Map,Map,Nil,_,Nil) :- !. partial_map(red(L,K,V,R),Map,MapF,Nil,Goal,red(NL,K,NV,NR)) :- partial_map(L,Map,MapI,Nil,Goal,NL), ( MapI == [] -> NR = R, NV = V, MapF = [] ; MapI = [K1|MapR], ( K == K1 -> ( call(Goal,V,NV) -> true ; NV = V ), MapN = MapR ; NV = V, MapN = MapI ), partial_map(R,MapN,MapF,Nil,Goal,NR) ). partial_map(black(L,K,V,R),Map,MapF,Nil,Goal,black(NL,K,NV,NR)) :- partial_map(L,Map,MapI,Nil,Goal,NL), ( MapI == [] -> NR = R, NV = V, MapF = [] ; MapI = [K1|MapR], ( K == K1 -> ( call(Goal,V,NV) -> true ; NV = V ), MapN = MapR ; NV = V, MapN = MapI ), partial_map(R,MapN,MapF,Nil,Goal,NR) ). % % whole keys % %% rb_keys(+T, -Keys) % % Keys is unified with an ordered list of all keys in the % Red-Black tree T. rb_keys(t(_,T),Lf) :- keys(T,[],Lf). rb_keys(t(_,T),L0,Lf) :- keys(T,L0,Lf). keys(black('',_,_,''),L,L) :- !. keys(red(L,K,_,R),L0,Lf) :- keys(L,[K|L1],Lf), keys(R,L0,L1). keys(black(L,K,_,R),L0,Lf) :- keys(L,[K|L1],Lf), keys(R,L0,L1). %% list_to_rbtree(+L, -T) is det. % % T is the red-black tree corresponding to the mapping in list L. list_to_rbtree(List, T) :- sort(List,Sorted), ord_list_to_rbtree(Sorted, T). %% ord_list_to_rbtree(+L, -T) is det. % % T is the red-black tree corresponding to the mapping in ordered % list L. ord_list_to_rbtree([], t(Nil,Nil)) :- !, Nil = black('', _, _, ''). ord_list_to_rbtree([K-V], t(Nil,black(Nil,K,V,Nil))) :- !, Nil = black('', _, _, ''). ord_list_to_rbtree(List, t(Nil,Tree)) :- Nil = black('', _, _, ''), Ar =.. [seq|List], functor(Ar,_,L), Height is truncate(log(L)/log(2)), construct_rbtree(1, L, Ar, Height, Nil, Tree). construct_rbtree(L, M, _, _, Nil, Nil) :- M < L, !. construct_rbtree(L, L, Ar, Depth, Nil, Node) :- !, arg(L, Ar, K-Val), build_node(Depth, Nil, K, Val, Nil, Node). construct_rbtree(I0, Max, Ar, Depth, Nil, Node) :- I is (I0+Max)//2, arg(I, Ar, K-Val), build_node(Depth, Left, K, Val, Right, Node), I1 is I-1, NewDepth is Depth-1, construct_rbtree(I0, I1, Ar, NewDepth, Nil, Left), I2 is I+1, construct_rbtree(I2, Max, Ar, NewDepth, Nil, Right). build_node( 0, Left, K, Val, Right, red(Left, K, Val, Right)) :- !. build_node( _, Left, K, Val, Right, black(Left, K, Val, Right)). %% rb_size(+T, -Size) is det. % % Size is the number of elements in T. rb_size(t(_,T),Size) :- size(T,0,Size). size(black('',_,_,_),Sz,Sz) :- !. size(red(L,_,_,R),Sz0,Szf) :- Sz1 is Sz0+1, size(L,Sz1,Sz2), size(R,Sz2,Szf). size(black(L,_,_,R),Sz0,Szf) :- Sz1 is Sz0+1, size(L,Sz1,Sz2), size(R,Sz2,Szf). %% is_rbtree(?Term) is semidet. % % True if Term is a valide Red-Black tree. % % @tbd Catch variables. is_rbtree(X) :- var(X), !, fail. is_rbtree(t(Nil,Nil)) :- !. is_rbtree(t(_,T)) :- catch(rbtree1(T), msg(_,_), fail). is_rbtree(X,_) :- var(X), !, fail. is_rbtree(T,Goal) :- catch(rbtree1(T), msg(S,Args), (once(Goal),format(S,Args))). % % This code checks if a tree is ordered and a rbtree % % rbtree(t(_,black('',_,_,''))) :- !. rbtree(t(_,T)) :- catch(rbtree1(T),msg(S,Args),format(S,Args)). rbtree1(black(L,K,_,R)) :- find_path_blacks(L, 0, Bls), check_rbtree(L,-inf,K,Bls), check_rbtree(R,K,+inf,Bls). rbtree1(red(_,_,_,_)) :- throw(msg("root should be black",[])). find_path_blacks(black('',_,_,''), Bls, Bls) :- !. find_path_blacks(black(L,_,_,_), Bls0, Bls) :- Bls1 is Bls0+1, find_path_blacks(L, Bls1, Bls). find_path_blacks(red(L,_,_,_), Bls0, Bls) :- find_path_blacks(L, Bls0, Bls). check_rbtree(black('',_,_,''),Min,Max,Bls0) :- !, check_height(Bls0,Min,Max). check_rbtree(red(L,K,_,R),Min,Max,Bls) :- check_val(K,Min,Max), check_red_child(L), check_red_child(R), check_rbtree(L,Min,K,Bls), check_rbtree(R,K,Max,Bls). check_rbtree(black(L,K,_,R),Min,Max,Bls0) :- check_val(K,Min,Max), Bls is Bls0-1, check_rbtree(L,Min,K,Bls), check_rbtree(R,K,Max,Bls). check_height(0,_,_) :- !. check_height(Bls0,Min,Max) :- throw(msg("Unbalance ~d between ~w and ~w~n",[Bls0,Min,Max])). check_val(K, Min, Max) :- ( K @> Min ; Min == -inf), (K @< Max ; Max == +inf), !. check_val(K, Min, Max) :- throw(msg("not ordered: ~w not between ~w and ~w~n",[K,Min,Max])). check_red_child(black(_,_,_,_)). check_red_child(red(_,K,_,_)) :- throw(msg("must be red: ~w~n",[K])). /* %count(1,16,X), format("deleting ~d~n",[X]), new(1,a,T0), insert(T0,2,b,T1), insert(T1,3,c,T2), insert(T2,4,c,T3), insert(T3,5,c,T4), insert(T4,6,c,T5), insert(T5,7,c,T6), insert(T6,8,c,T7), insert(T7,9,c,T8), insert(T8,10,c,T9),insert(T9,11,c,T10), insert(T10,12,c,T11),insert(T11,13,c,T12),insert(T12,14,c,T13),insert(T13,15,c,T14), insert(T14,16,c,T15),delete(T15,X,T16),pretty_print(T16),rbtree(T16),fail. % count(1,16,X0), X is -X0, format("deleting ~d~n",[X]), new(-1,a,T0), insert(T0,-2,b,T1), insert(T1,-3,c,T2), insert(T2,-4,c,T3), insert(T3,-5,c,T4), insert(T4,-6,c,T5), insert(T5,-7,c,T6), insert(T6,-8,c,T7), insert(T7,-9,c,T8), insert(T8,-10,c,T9),insert(T9,-11,c,T10), insert(T10,-12,c,T11),insert(T11,-13,c,T12),insert(T12,-14,c,T13),insert(T13,-15,c,T14), insert(T14,-16,c,T15),delete(T15,X,T16),pretty_print(T16),rbtree(T16),fail. count(I,_,I). count(I,M,L) :- I < M, I1 is I+1, count(I1,M,L). test_pos :- rb_new(1,a,T0), N = 10000, build_ptree(2,N,T0,T), % pretty_print(T), rbtree(T), clean_tree(1,N,T,_), bclean_tree(N,1,T,_), count(1,N,X), ( rb_delete(T,X,TF) -> true ; abort ), % pretty_print(TF), rbtree(TF), % format("done ~d~n",[X]), fail. test_pos. build_ptree(X,X,T0,TF) :- !, rb_insert(T0,X,X,TF). build_ptree(X1,X,T0,TF) :- rb_insert(T0,X1,X1,TI), X2 is X1+1, build_ptree(X2,X,TI,TF). clean_tree(X,X,T0,TF) :- !, rb_delete(T0,X,TF), ( rbtree(TF) -> true ; abort). clean_tree(X1,X,T0,TF) :- rb_delete(T0,X1,TI), X2 is X1+1, ( rbtree(TI) -> true ; abort), clean_tree(X2,X,TI,TF). bclean_tree(X,X,T0,TF) :- !, format("cleaning ~d~n", [X]), rb_delete(T0,X,TF), ( rbtree(TF) -> true ; abort). bclean_tree(X1,X,T0,TF) :- format("cleaning ~d~n", [X1]), rb_delete(T0,X1,TI), X2 is X1-1, ( rbtree(TI) -> true ; abort), bclean_tree(X2,X,TI,TF). test_neg :- Size = 10000, rb_new(-1,a,T0), build_ntree(2,Size,T0,T), % pretty_print(T), rbtree(T), MSize is -Size, clean_tree(MSize,-1,T,_), bclean_tree(-1,MSize,T,_), count(1,Size,X), NX is -X, ( rb_delete(T,NX,TF) -> true ; abort ), % pretty_print(TF), rbtree(TF), % format("done ~d~n",[X]), fail. test_neg. build_ntree(X,X,T0,TF) :- !, X1 is -X, rb_insert(T0,X1,X1,TF). build_ntree(X1,X,T0,TF) :- NX1 is -X1, rb_insert(T0,NX1,NX1,TI), X2 is X1+1, build_ntree(X2,X,TI,TF). */ 3/** Predicates from [*Indexing dif/2*](https://arxiv.org/abs/1607.01590). Example: ``` ?- tfilter(=(a), [X,Y], Es). X = a, Y = a, Es = "aa" ; X = a, Es = "a", dif:dif(a,Y) ; Y = a, Es = "a", dif:dif(a,X) ; Es = [], dif:dif(a,X), dif:dif(a,Y). ``` */ :- module(reif, [if_/3, (=)/3, (',')/3, (;)/3, cond_t/3, dif/3, memberd_t/3, tfilter/3, tmember/2, tmember_t/3, tpartition/4]). :- use_module(library(dif)). :- meta_predicate(if_(1, 0, 0)). if_(If_1, Then_0, Else_0) :- call(If_1, T), ( T == true -> call(Then_0) ; T == false -> call(Else_0) ; nonvar(T) -> throw(error(type_error(boolean, T), _)) ; throw(error(instantiation_error, _)) ). =(X, Y, T) :- ( X == Y -> T = true ; X \= Y -> T = false ; T = true, X = Y ; T = false, dif(X, Y) ). dif(X, Y, T) :- =(X, Y, NT), non(NT, T). non(true, false). non(false, true). :- meta_predicate(tfilter(2, ?, ?)). tfilter(_, [], []). tfilter(C_2, [E|Es], Fs0) :- if_(call(C_2, E), Fs0 = [E|Fs], Fs0 = Fs), tfilter(C_2, Es, Fs). :- meta_predicate(tpartition(2, ?, ?, ?)). tpartition(P_2, Xs, Ts, Fs) :- i_tpartition(Xs, P_2, Ts, Fs). i_tpartition([], _P_2, [], []). i_tpartition([X|Xs], P_2, Ts0, Fs0) :- if_( call(P_2, X) , ( Ts0 = [X|Ts], Fs0 = Fs ) , ( Fs0 = [X|Fs], Ts0 = Ts ) ), i_tpartition(Xs, P_2, Ts, Fs). :- meta_predicate(','(1, 1, ?)). ','(A_1, B_1, T) :- if_(A_1, call(B_1, T), T = false). :- meta_predicate(';'(1, 1, ?)). ';'(A_1, B_1, T) :- if_(A_1, T = true, call(B_1, T)). :- meta_predicate(cond_t(1, 0, ?)). cond_t(If_1, Then_0, T) :- if_(If_1, ( Then_0, T = true ), T = false ). memberd_t(E, Xs, T) :- i_memberd_t(Xs, E, T). i_memberd_t([], _, false). i_memberd_t([X|Xs], E, T) :- if_( X = E, T = true, i_memberd_t(Xs, E, T) ). :- meta_predicate(tmember(2, ?)). tmember(P_2, [X|Xs]) :- if_( call(P_2, X), true, tmember(P_2, Xs) ). :- meta_predicate(tmember_t(2, ?, ?)). tmember_t(_P_2, [], false). tmember_t(P_2, [X|Xs], T) :- if_( call(P_2, X), T = true, tmember_t(P_2, Xs, T) ). ] /** Safe type tests. "si" stands for "sufficiently instantiated". It can also be read as "safe inference", so possibly also other predicates are candidates for this library. A safe type test: - throws an *instantiation error* if the argument is not sufficiently instantiated to make a sound decision - *succeeds* if the argument is of the specified type - *fails* otherwise. For instance, `atom_si(A)` yields an *instantiation error* if `A` is a variable. This is logically sound, since in that case the argument is not sufficiently instantiated to make any decision. The definitions are taken from [Safer type tests in Prolog](https://stackoverflow.com/questions/27306453/safer-type-tests-in-prolog). Examples: ``` ?- chars_si(Cs). error(instantiation_error,list_si/1). ?- chars_si([h|Cs]). error(instantiation_error,list_si/1). ?- chars_si("hello"). true. ?- chars_si(hello). false. ``` */ :- module(si, [atom_si/1, integer_si/1, atomic_si/1, list_si/1, character_si/1, term_si/1, chars_si/1, dif_si/2, when_si/2]). :- use_module(library(lists)). atom_si(A) :- functor(A, _, 0), % for the instantiation error atom(A). integer_si(I) :- functor(I, _, 0), integer(I). atomic_si(AC) :- functor(AC,_,0). % list_si(L) :- % \+ \+ length(L, _), % sort(L, _). list_si(L0) :- '$skip_max_list'(_,_, L0,L), ( nonvar(L) -> L = [] ; throw(error(instantiation_error, list_si/1)) ). character_si(Ch) :- functor(Ch,Ch,0), atom(Ch), atom_length(Ch,1). term_si(Term) :- ( ground(Term) -> acyclic_term(Term) ; throw(error(instantiation_error, term_si/1)) ). chars_si(Chs0) :- '$skip_max_list'(_,_, Chs0,Chs), ( nonvar(Chs) -> Chs == [] ; true ), % fails for infinite lists too failnochars(Chs0, Uninstantiated), ( nonvar(Uninstantiated) -> throw(error(instantiation_error, chars_si/1)) ; true ). failnochars(Chs0, U) :- ( var(Chs0) -> U = true ; Chs0 == [] -> true ; Chs0 = [Ch|Chs1], ( nonvar(Ch) -> atom(Ch), atom_length(Ch,1) ; U = true ), failnochars(Chs1, U) ). dif_si(X, Y) :- X \== Y, ( X \= Y -> true ; throw(error(instantiation_error,dif_si/2)) ). :- meta_predicate(when_si(+, 0)). %% when_si(Condition, Goal). % % Executes Goal when Condition becomes true. Throws an instantiation error if % it can't decide. when_si(Condition, Goal) :- % Taken from https://stackoverflow.com/a/40449516 ( when_condition_si(Condition) -> ( Condition -> Goal ; throw(error(instantiation_error,when_si/2)) ) ; throw(error(domain_error(when_condition_si, Condition),_)) ). when_condition_si(Cond) :- var(Cond), !, throw(error(instantiation_error,when_condition_si/2)). when_condition_si(ground(_)). when_condition_si(nonvar(_)). when_condition_si((A, B)) :- when_condition_si(A), when_condition_si(B). when_condition_si((A ; B)) :- when_condition_si(A), when_condition_si(B). :- module(sqlite3, [ sqlite3_query/4, sqlite_flag/2 ]). :- use_foreign_module('libsqlite3.so', [ sqlite3_open([cstr,-ptr], sint), sqlite3_exec([ptr,cstr,ptr,ptr,-ptr], sint), sqlite3_prepare_v2([ptr,cstr,ptr,-ptr,-ccstr], sint), sqlite3_step([ptr], sint), sqlite3_finalize([ptr], sint), sqlite3_column_count([ptr], sint), sqlite3_column_name([ptr,sint], ccstr), sqlite3_column_type([ptr,sint], sint), sqlite3_column_int64([ptr,sint], sint), sqlite3_column_double([ptr,sint], double), sqlite3_column_text([ptr,sint], ccstr), sqlite3_close([ptr], sint) ]). :- help(sqlite3_open(+atom,--stream,-integer),[iso(false),desc('Open an Sqlite3 database returning a connection (as a stream).')]). :- help(sqlite3_exec(+stream,+atom,+integer,+integer,-integer,-integer),[iso(false),desc('Execute an SQL statement on an Sqlite3 database connection')]). :- help(sqlite3_prepare_v2(+stream,+atom,+integer,-integer,-integer,-integer),[iso(false)]). :- help(sqlite3_step(+stream,-integer),[iso(false)]). :- help(sqlite3_finalize(+stream,-integer),[iso(false)]). :- help(sqlite3_column_count(+stream,-integer),[iso(false)]). :- help(sqlite3_column_name(+stream,+integer,-atom),[iso(false)]). :- help(sqlite3_column_type(+stream,+integer,-integer),[iso(false)]). :- help(sqlite3_column_int64(+stream,+integer,-integer),[iso(false)]). :- help(sqlite3_column_double(+stream,+integer,-float),[iso(false)]). :- help(sqlite3_column_text(+stream,+integer,-string),[iso(false)]). :- help(sqlite3_close(+stream,-integer),[iso(false),desc('Close an Sqlite3 database connection.')]). sqlite_flag('SQLITE_OK', 0). sqlite_flag('SQLITE_ERROR', 1). sqlite_flag('SQLITE_ABORT', 4). sqlite_flag('SQLITE_BUSY', 5). sqlite_flag('SQLITE_LOCKED', 6). sqlite_flag('SQLITE_READONLY', 8). sqlite_flag('SQLITE_FULL', 13). sqlite_flag('SQLITE_ROW', 100). sqlite_flag('SQLITE_DONE', 101). sqlite_flag('SQLITE_INTEGER', 1). sqlite_flag('SQLITE_FLOAT', 2). sqlite_flag('SQLITE_TEXT', 3). sqlite_flag('SQLITE_BLOB', 4). sqlite_flag('SQLITE_NULL', 5). :- help(sqlite_flag(+atom,-integer),[iso(false)]). % WARNING: This is experimental! sqlite3_query(Conn, Sql, Cols, Names) :- sqlite_flag('SQLITE_OK', SQLITE_OK), sqlite_flag('SQLITE_ROW', SQLITE_ROW), sqlite3_prepare_v2(Conn, Sql, -1, Statement, _, Ret), Ret =:= SQLITE_OK, repeat, ( ( sqlite3_step(Statement, Ret2), Ret2 =:= SQLITE_ROW ) -> get_row(Statement, Cols, Names) ; ( !, sqlite3_finalize(Statement, _Ret), fail ) ). :- help(sqlite3_query(+stream,+string,-list,-list),[iso(false),desc('Query an Sqlite3 database connection and return a row as a list of column values and a list of column names. Bactracking may return more rows.')]). get_col(_, 0, Cols, Cols, Names, Names) :- !. get_col(Statement, Count, Col, Cols, Name, Names) :- sqlite_flag('SQLITE_INTEGER', SQLITE_INTEGER), sqlite_flag('SQLITE_FLOAT', SQLITE_FLOAT), sqlite_flag('SQLITE_TEXT', SQLITE_TEXT), sqlite_flag('SQLITE_BLOB', SQLITE_BLOB), Count1 is Count - 1, sqlite3_column_name(Statement, Count1, NewName), sqlite3_column_type(Statement, Count1, Type), ( Type =:= SQLITE_INTEGER -> sqlite3_column_int64(Statement, Count1, Value) ; Type =:= SQLITE_FLOAT -> sqlite3_column_double(Statement, Count1, Value) ; Type =:= SQLITE_TEXT -> sqlite3_column_text(Statement, Count1, Value) ; Type =:= SQLITE_BLOB -> sqlite3_column_text(Statement, Count1, Value) ; Value = '(void)' ), get_col(Statement, Count1, [Value|Col], Cols, [NewName|Name], Names). get_row(Statement, Cols, Names) :- sqlite3_column_count(Statement, Count), get_col(Statement, Count, [], Cols, [], Names).  % Modified from Scryer prolog /** This library provides predicates for reasoning about time. */ :- module(time, [current_time/1, format_time//2 ]). :- use_module(library(format)). :- use_module(library(iso_ext)). :- use_module(library(error)). :- use_module(library(dcgs)). :- use_module(library(lists)). %% current_time(-T) % % Yields the current system time _T_ in an opaque form, called a % _time stamp_. Use `format_time//2` to describe strings that contain % attributes of the time stamp. current_time(T) :- posix_time(Epoch), posix_localtime(Epoch, TM), posix_strftime('[''Y''="%Y",m="%m",d="%d",''H''="%H",''M''="%M",''S''="%S",y="%y",b="%b",''B''="%B",a="%a",''A''="%A",w="%w",u="%u",''U''="%U",''W''="%W",j="%j",''D''="%D",x="%x",finis]', T0, TM), read_from_chars(T0, T). %% format_time(FormatString, TimeStamp)// % % The nonterminal format_time//2 describes a list of characters that % are formatted according to a format string. Usage: % % ``` % phrase(format_time(FormatString, TimeStamp), Cs) % ``` % % TimeStamp represents a moment in time in an opaque form, as for % example obtained by `current_time/1`. % % FormatString is a list of characters that are interpreted literally, % except for the following specifiers (and possibly more in the future): % % | `%Y` | year of the time stamp. Example: 2020. | % | `%m` | month number (01-12), zero-padded to 2 digits | % | `%d` | day number (01-31), zero-padded to 2 digits | % | `%H` | hour number (00-24), zero-padded to 2 digits | % | `%M` | minute number (00-59), zero-padded to 2 digits | % | `%S` | second number (00-60), zero-padded to 2 digits | % | `%b` | abbreviated month name, always 3 letters | % | `%a` | abbreviated weekday name, always 3 letters | % | `%A` | full weekday name | % | `%j` | day of the year (001-366), zero-padded to 3 digits | % | `%%` | the literal `%` | % % Example: % % ``` % ?- current_time(T), phrase(format_time("%d.%m.%Y (%H:%M:%S)", T), Cs). % T = [...], Cs = "11.06.2020 (00:24:32)". % ``` format_time([], _) --> []. format_time(['%','%'|Fs], T) --> !, "%", format_time(Fs, T). format_time(['%',Spec|Fs], T) --> !, ( { member(Spec=Value, T) } -> seq(Value) ; { domain_error(time_specifier, Spec, format_time//2) } ), format_time(Fs, T). format_time([F|Fs], T) --> [F], format_time(Fs, T). N/* Author: R.A.O'Keefe, Vitor Santos Costa, Jan Wielemaker E-mail: J.Wielemaker@vu.nl WWW: http://www.swi-prolog.org Copyright (c) 1984-2021, VU University Amsterdam CWI, Amsterdam SWI-Prolog Solutions .b.v All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ :- module(ugraphs, [ add_edges/3, % +Graph, +Edges, -NewGraph add_vertices/3, % +Graph, +Vertices, -NewGraph complement/2, % +Graph, -NewGraph compose/3, % +LeftGraph, +RightGraph, -NewGraph del_edges/3, % +Graph, +Edges, -NewGraph del_vertices/3, % +Graph, +Vertices, -NewGraph edges/2, % +Graph, -Edges neighbors/3, % +Vertex, +Graph, -Vertices neighbours/3, % +Vertex, +Graph, -Vertices reachable/3, % +Vertex, +Graph, -Vertices top_sort/2, % +Graph, -Sort top_sort/3, % +Graph, -Sort0, -Sort transitive_closure/2, % +Graph, -Closure transpose_ugraph/2, % +Graph, -NewGraph vertices/2, % +Graph, -Vertices vertices_edges_to_ugraph/3, % +Vertices, +Edges, -Graph ugraph_union/3, % +Graph1, +Graph2, -Graph connect_ugraph/3 % +Graph1, -Start, -Graph ]). /** Graph manipulation library The S-representation of a graph is a list of (vertex-neighbours) pairs, where the pairs are in standard order (as produced by keysort) and the neighbours of each vertex are also in standard order (as produced by sort). This form is convenient for many calculations. A new UGraph from raw data can be created using `vertices_edges_to_ugraph/3`. Adapted to support some of the functionality of the SICStus ugraphs library by Vitor Santos Costa. Ported from YAP 5.0.1 to SWI-Prolog by Jan Wielemaker. Ported from SWI-Prolog to Scryer by [Adrián Arroyo Calle](https://adrianistan.eu) License: BSD-2 or Artistic 2.0 */ :- use_module(library(lists)). :- use_module(library(pairs)). :- use_module(library(ordsets)). %% vertices(+Graph, -Vertices) % % Unify Vertices with all vertices appearing in Graph. Example: % % ``` % ?- vertices([1-[3,5],2-[4],3-[],4-[5],5-[]], L). % L = [1, 2, 3, 4, 5] % ``` vertices([], []) :- !. vertices([Vertex-_|Graph], [Vertex|Vertices]) :- vertices(Graph, Vertices). %% vertices_edges_to_ugraph(+Vertices, +Edges, -UGraph) is det. % % Create a UGraph from Vertices and edges. Given a graph with a % set of Vertices and a set of Edges, Graph must unify with the % corresponding S-representation. Note that the vertices without % edges will appear in Vertices but not in Edges. Moreover, it is % sufficient for a vertice to appear in Edges. % % ``` % ?- vertices_edges_to_ugraph([],[1-3,2-4,4-5,1-5], L). % L = [1-[3,5], 2-[4], 3-[], 4-[5], 5-[]] % ``` % % In this case all vertices are defined implicitly. The next % example shows three unconnected vertices: % % ``` % ?- vertices_edges_to_ugraph([6,7,8],[1-3,2-4,4-5,1-5], L). % L = [1-[3,5], 2-[4], 3-[], 4-[5], 5-[], 6-[], 7-[], 8-[]] % ``` vertices_edges_to_ugraph(Vertices, Edges, Graph) :- sort(Edges, EdgeSet), p_to_s_vertices(EdgeSet, IVertexBag), append(Vertices, IVertexBag, VertexBag), sort(VertexBag, VertexSet), p_to_s_group(VertexSet, EdgeSet, Graph). %% add_vertices(+Graph, +Vertices, -NewGraph) % % Unify NewGraph with a new graph obtained by adding the list of % Vertices to Graph. Example: % % ``` % ?- add_vertices([1-[3,5],2-[]], [0,1,2,9], NG). % NG = [0-[], 1-[3,5], 2-[], 9-[]] % ``` % replace with real msort/2 when available msort_(List, Sorted) :- pairs_keys(Pairs, List), keysort(Pairs, SortedPairs), pairs_keys(SortedPairs, Sorted). add_vertices(Graph, Vertices, NewGraph) :- % msort/2 not available in Scryer Prolog yet: msort(Vertices, V1), msort_(Vertices, V1), add_vertices_to_s_graph(V1, Graph, NewGraph). add_vertices_to_s_graph(L, [], NL) :- !, add_empty_vertices(L, NL). add_vertices_to_s_graph([], L, L) :- !. add_vertices_to_s_graph([V1|VL], [V-Edges|G], NGL) :- compare(Res, V1, V), add_vertices_to_s_graph(Res, V1, VL, V, Edges, G, NGL). add_vertices_to_s_graph(=, _, VL, V, Edges, G, [V-Edges|NGL]) :- add_vertices_to_s_graph(VL, G, NGL). add_vertices_to_s_graph(<, V1, VL, V, Edges, G, [V1-[]|NGL]) :- add_vertices_to_s_graph(VL, [V-Edges|G], NGL). add_vertices_to_s_graph(>, V1, VL, V, Edges, G, [V-Edges|NGL]) :- add_vertices_to_s_graph([V1|VL], G, NGL). add_empty_vertices([], []). add_empty_vertices([V|G], [V-[]|NG]) :- add_empty_vertices(G, NG). %% del_vertices(+Graph, +Vertices, -NewGraph) is det. % % Unify NewGraph with a new graph obtained by deleting the list of % Vertices and all the edges that start from or go to a vertex in % Vertices to the Graph. Example: % % ``` % ?- del_vertices([1-[3,5],2-[4],3-[],4-[5],5-[],6-[],7-[2,6],8-[]], % [2,1], % NL). % NL = [3-[],4-[5],5-[],6-[],7-[6],8-[]] % ``` del_vertices(Graph, Vertices, NewGraph) :- sort(Vertices, V1), % JW: was msort ( V1 = [] -> Graph = NewGraph ; del_vertices(Graph, V1, V1, NewGraph) ). del_vertices(G, [], V1, NG) :- !, del_remaining_edges_for_vertices(G, V1, NG). del_vertices([], _, _, []). del_vertices([V-Edges|G], [V0|Vs], V1, NG) :- compare(Res, V, V0), split_on_del_vertices(Res, V,Edges, [V0|Vs], NVs, V1, NG, NGr), del_vertices(G, NVs, V1, NGr). del_remaining_edges_for_vertices([], _, []). del_remaining_edges_for_vertices([V0-Edges|G], V1, [V0-NEdges|NG]) :- ord_subtract(Edges, V1, NEdges), del_remaining_edges_for_vertices(G, V1, NG). split_on_del_vertices(<, V, Edges, Vs, Vs, V1, [V-NEdges|NG], NG) :- ord_subtract(Edges, V1, NEdges). split_on_del_vertices(>, V, Edges, [_|Vs], Vs, V1, [V-NEdges|NG], NG) :- ord_subtract(Edges, V1, NEdges). split_on_del_vertices(=, _, _, [_|Vs], Vs, _, NG, NG). %% add_edges(+Graph, +Edges, -NewGraph) % % Unify NewGraph with a new graph obtained by adding the list of Edges % to Graph. Example: % % ``` % ?- add_edges([1-[3,5],2-[4],3-[],4-[5], % 5-[],6-[],7-[],8-[]], % [1-6,2-3,3-2,5-7,3-2,4-5], % NL). % NL = [1-[3,5,6], 2-[3,4], 3-[2], 4-[5], % 5-[7], 6-[], 7-[], 8-[]] % ``` add_edges(Graph, Edges, NewGraph) :- p_to_s_graph(Edges, G1), ugraph_union(Graph, G1, NewGraph). %% ugraph_union(+Graph1, +Graph2, -NewGraph) % % NewGraph is the union of Graph1 and Graph2. Example: % % ``` % ?- ugraph_union([1-[2],2-[3]],[2-[4],3-[1,2,4]],L). % L = [1-[2], 2-[3,4], 3-[1,2,4]] % ``` ugraph_union(Set1, [], Set1) :- !. ugraph_union([], Set2, Set2) :- !. ugraph_union([Head1-E1|Tail1], [Head2-E2|Tail2], Union) :- compare(Order, Head1, Head2), ugraph_union(Order, Head1-E1, Tail1, Head2-E2, Tail2, Union). ugraph_union(=, Head-E1, Tail1, _-E2, Tail2, [Head-Es|Union]) :- ord_union(E1, E2, Es), ugraph_union(Tail1, Tail2, Union). ugraph_union(<, Head1, Tail1, Head2, Tail2, [Head1|Union]) :- ugraph_union(Tail1, [Head2|Tail2], Union). ugraph_union(>, Head1, Tail1, Head2, Tail2, [Head2|Union]) :- ugraph_union([Head1|Tail1], Tail2, Union). %% del_edges(+Graph, +Edges, -NewGraph) % % Unify NewGraph with a new graph obtained by removing the list of % Edges from Graph. Notice that no vertices are deleted. Example: % % ``` % ?- del_edges([1-[3,5],2-[4],3-[],4-[5],5-[],6-[],7-[],8-[]], % [1-6,2-3,3-2,5-7,3-2,4-5,1-3], % NL). % NL = [1-[5],2-[4],3-[],4-[],5-[],6-[],7-[],8-[]] % ``` del_edges(Graph, Edges, NewGraph) :- p_to_s_graph(Edges, G1), graph_subtract(Graph, G1, NewGraph). %% graph_subtract(+Set1, +Set2, ?Difference) % % Is based on `ord_subtract/3` graph_subtract(Set1, [], Set1) :- !. graph_subtract([], _, []). graph_subtract([Head1-E1|Tail1], [Head2-E2|Tail2], Difference) :- compare(Order, Head1, Head2), graph_subtract(Order, Head1-E1, Tail1, Head2-E2, Tail2, Difference). graph_subtract(=, H-E1, Tail1, _-E2, Tail2, [H-E|Difference]) :- ord_subtract(E1,E2,E), graph_subtract(Tail1, Tail2, Difference). graph_subtract(<, Head1, Tail1, Head2, Tail2, [Head1|Difference]) :- graph_subtract(Tail1, [Head2|Tail2], Difference). graph_subtract(>, Head1, Tail1, _, Tail2, Difference) :- graph_subtract([Head1|Tail1], Tail2, Difference). %% edges(+Graph, -Edges) % % Unify Edges with all edges appearing in Graph. Example: % % ``` % ?- edges([1-[3,5],2-[4],3-[],4-[5],5-[]], L). % L = [1-3, 1-5, 2-4, 4-5] % ``` edges(Graph, Edges) :- s_to_p_graph(Graph, Edges). p_to_s_graph(P_Graph, S_Graph) :- sort(P_Graph, EdgeSet), p_to_s_vertices(EdgeSet, VertexBag), sort(VertexBag, VertexSet), p_to_s_group(VertexSet, EdgeSet, S_Graph). p_to_s_vertices([], []). p_to_s_vertices([A-Z|Edges], [A,Z|Vertices]) :- p_to_s_vertices(Edges, Vertices). p_to_s_group([], _, []). p_to_s_group([Vertex|Vertices], EdgeSet, [Vertex-Neibs|G]) :- p_to_s_group(EdgeSet, Vertex, Neibs, RestEdges), p_to_s_group(Vertices, RestEdges, G). p_to_s_group([V1-X|Edges], V2, [X|Neibs], RestEdges) :- V1 == V2, !, p_to_s_group(Edges, V2, Neibs, RestEdges). p_to_s_group(Edges, _, [], Edges). s_to_p_graph([], []) :- !. s_to_p_graph([Vertex-Neibs|G], P_Graph) :- s_to_p_graph(Neibs, Vertex, P_Graph, Rest_P_Graph), s_to_p_graph(G, Rest_P_Graph). s_to_p_graph([], _, P_Graph, P_Graph) :- !. s_to_p_graph([Neib|Neibs], Vertex, [Vertex-Neib|P], Rest_P) :- s_to_p_graph(Neibs, Vertex, P, Rest_P). %% transitive_closure(+Graph, -Closure) % % Generate the graph Closure as the transitive closure of Graph. % Example: % % ``` % ?- transitive_closure([1-[2,3],2-[4,5],4-[6]],L). % L = [1-[2,3,4,5,6], 2-[4,5,6], 4-[6]] % ``` transitive_closure(Graph, Closure) :- warshall(Graph, Graph, Closure). warshall([], Closure, Closure) :- !. warshall([V-_|G], E, Closure) :- memberchk(V-Y, E), % Y := E(v) warshall(E, V, Y, NewE), warshall(G, NewE, Closure). warshall([X-Neibs|G], V, Y, [X-NewNeibs|NewG]) :- memberchk(V, Neibs), !, ord_union(Neibs, Y, NewNeibs), warshall(G, V, Y, NewG). warshall([X-Neibs|G], V, Y, [X-Neibs|NewG]) :- !, warshall(G, V, Y, NewG). warshall([], _, _, []). %% transpose_ugraph(Graph, NewGraph) is det. % % Unify NewGraph with a new graph obtained from Graph by replacing % all edges of the form V1-V2 by edges of the form V2-V1. The cost % is O(|V|\*log(|V|)). Notice that an undirected graph is its own % transpose. Example: % % ``` % ?- transpose([1-[3,5],2-[4],3-[],4-[5], % 5-[],6-[],7-[],8-[]], NL). % NL = [1-[],2-[],3-[1],4-[2],5-[1,4],6-[],7-[],8-[]] % ``` transpose_ugraph(Graph, NewGraph) :- edges(Graph, Edges), vertices(Graph, Vertices), flip_edges(Edges, TransposedEdges), vertices_edges_to_ugraph(Vertices, TransposedEdges, NewGraph). flip_edges([], []). flip_edges([Key-Val|Pairs], [Val-Key|Flipped]) :- flip_edges(Pairs, Flipped). %% compose(+LeftGraph, +RightGraph, -NewGraph) % % Compose NewGraph by connecting the _drains_ of LeftGraph to the % _sources_ of RightGraph. Example: % % ``` % ?- compose([1-[2],2-[3]],[2-[4],3-[1,2,4]],L). % L = [1-[4], 2-[1,2,4], 3-[]] % ``` compose(G1, G2, Composition) :- vertices(G1, V1), vertices(G2, V2), ord_union(V1, V2, V), compose(V, G1, G2, Composition). compose([], _, _, []) :- !. compose([Vertex|Vertices], [Vertex-Neibs|G1], G2, [Vertex-Comp|Composition]) :- !, compose1(Neibs, G2, [], Comp), compose(Vertices, G1, G2, Composition). compose([Vertex|Vertices], G1, G2, [Vertex-[]|Composition]) :- compose(Vertices, G1, G2, Composition). compose1([V1|Vs1], [V2-N2|G2], SoFar, Comp) :- compare(Rel, V1, V2), !, compose1(Rel, V1, Vs1, V2, N2, G2, SoFar, Comp). compose1(_, _, Comp, Comp). compose1(<, _, Vs1, V2, N2, G2, SoFar, Comp) :- !, compose1(Vs1, [V2-N2|G2], SoFar, Comp). compose1(>, V1, Vs1, _, _, G2, SoFar, Comp) :- !, compose1([V1|Vs1], G2, SoFar, Comp). compose1(=, V1, Vs1, V1, N2, G2, SoFar, Comp) :- ord_union(N2, SoFar, Next), compose1(Vs1, G2, Next, Comp). %% top_sort(+Graph, -Sorted) is semidet. % % Sorted is a topological sorted list of nodes in Graph. A % toplogical sort is possible if the graph is connected and % acyclic. In the example we show how topological sorting works % for a linear graph: % % ``` % ?- top_sort([1-[2], 2-[3], 3-[]], L). % L = [1, 2, 3] % ``` top_sort(Graph, Sorted) :- vertices_and_zeros(Graph, Vertices, Counts0), count_edges(Graph, Vertices, Counts0, Counts1), select_zeros(Counts1, Vertices, Zeros), top_sort(Zeros, Sorted, Graph, Vertices, Counts1). %% top_sort(+Graph, -Sorted, ?Tail) is semidet. % % The predicate `top_sort/3` is a difference list version of % `top_sort/2`. top_sort(Graph, Sorted0, Sorted) :- vertices_and_zeros(Graph, Vertices, Counts0), count_edges(Graph, Vertices, Counts0, Counts1), select_zeros(Counts1, Vertices, Zeros), top_sort(Zeros, Sorted, Sorted0, Graph, Vertices, Counts1). vertices_and_zeros([], [], []) :- !. vertices_and_zeros([Vertex-_|Graph], [Vertex|Vertices], [0|Zeros]) :- vertices_and_zeros(Graph, Vertices, Zeros). count_edges([], _, Counts, Counts) :- !. count_edges([_-Neibs|Graph], Vertices, Counts0, Counts2) :- incr_list(Neibs, Vertices, Counts0, Counts1), count_edges(Graph, Vertices, Counts1, Counts2). incr_list([], _, Counts, Counts) :- !. incr_list([V1|Neibs], [V2|Vertices], [M|Counts0], [N|Counts1]) :- V1 == V2, !, N is M+1, incr_list(Neibs, Vertices, Counts0, Counts1). incr_list(Neibs, [_|Vertices], [N|Counts0], [N|Counts1]) :- incr_list(Neibs, Vertices, Counts0, Counts1). select_zeros([], [], []) :- !. select_zeros([0|Counts], [Vertex|Vertices], [Vertex|Zeros]) :- !, select_zeros(Counts, Vertices, Zeros). select_zeros([_|Counts], [_|Vertices], Zeros) :- select_zeros(Counts, Vertices, Zeros). top_sort([], [], Graph, _, Counts) :- !, vertices_and_zeros(Graph, _, Counts). top_sort([Zero|Zeros], [Zero|Sorted], Graph, Vertices, Counts1) :- graph_memberchk(Zero-Neibs, Graph), decr_list(Neibs, Vertices, Counts1, Counts2, Zeros, NewZeros), top_sort(NewZeros, Sorted, Graph, Vertices, Counts2). top_sort([], Sorted0, Sorted0, Graph, _, Counts) :- !, vertices_and_zeros(Graph, _, Counts). top_sort([Zero|Zeros], [Zero|Sorted], Sorted0, Graph, Vertices, Counts1) :- graph_memberchk(Zero-Neibs, Graph), decr_list(Neibs, Vertices, Counts1, Counts2, Zeros, NewZeros), top_sort(NewZeros, Sorted, Sorted0, Graph, Vertices, Counts2). graph_memberchk(Element1-Edges, [Element2-Edges2|_]) :- Element1 == Element2, !, Edges = Edges2. graph_memberchk(Element, [_|Rest]) :- graph_memberchk(Element, Rest). decr_list([], _, Counts, Counts, Zeros, Zeros) :- !. decr_list([V1|Neibs], [V2|Vertices], [1|Counts1], [0|Counts2], Zi, Zo) :- V1 == V2, !, decr_list(Neibs, Vertices, Counts1, Counts2, [V2|Zi], Zo). decr_list([V1|Neibs], [V2|Vertices], [N|Counts1], [M|Counts2], Zi, Zo) :- V1 == V2, !, M is N-1, decr_list(Neibs, Vertices, Counts1, Counts2, Zi, Zo). decr_list(Neibs, [_|Vertices], [N|Counts1], [N|Counts2], Zi, Zo) :- decr_list(Neibs, Vertices, Counts1, Counts2, Zi, Zo). %% neighbours(+Vertex, +Graph, -Neigbours) is det. % % Neigbours is a sorted list of the neighbours of Vertex in Graph. % Example: % % ``` % ?- neighbours(4,[1-[3,5],2-[4],3-[], % 4-[1,2,7,5],5-[],6-[],7-[],8-[]], NL). % NL = [1,2,7,5] % ``` %% neighbors(+Vertex, +Graph, -Neigbours) is det. % % Same as `neighbours/3`. neighbors(Vertex, Graph, Neig) :- neighbours(Vertex, Graph, Neig). neighbours(V,[V0-Neig|_],Neig) :- V == V0, !. neighbours(V,[_|G],Neig) :- neighbours(V,G,Neig). %% connect_ugraph(+UGraphIn, -Start, -UGraphOut) is det. % % Adds Start as an additional vertex that is connected to all vertices % in UGraphIn. This can be used to create an topological sort for a % not connected graph. Start is before any vertex in UGraphIn in the % standard order of terms. No vertex in UGraphIn can be a variable. % % Can be used to order a not-connected graph as follows: % % ``` % top_sort_unconnected(Graph, Vertices) :- % ( top_sort(Graph, Vertices) % -> true % ; connect_ugraph(Graph, Start, Connected), % top_sort(Connected, Ordered0), % Ordered0 = [Start|Vertices] % ). % ``` connect_ugraph([], 0, []) :- !. connect_ugraph(Graph, Start, [Start-Vertices|Graph]) :- vertices(Graph, Vertices), Vertices = [First|_], before(First, Start). %% before(+Term, -Before) is det. % % Unify Before to a term that comes before Term in the standard % order of terms. % % Throws `instantiation_error` if Term is unbound. before(X, _) :- var(X), !, instantiation_error(X). before(Number, Start) :- number(Number), !, Start is Number - 1. before(_, 0). %% complement(+UGraphIn, -UGraphOut) % % UGraphOut is a ugraph with an edge between all vertices that are % _not_ connected in UGraphIn and all edges from UGraphIn removed. % Example: % % ``` % ?- complement([1-[3,5],2-[4],3-[], % 4-[1,2,7,5],5-[],6-[],7-[],8-[]], NL). % NL = [1-[2,4,6,7,8],2-[1,3,5,6,7,8],3-[1,2,4,5,6,7,8], % 4-[3,5,6,8],5-[1,2,3,4,6,7,8],6-[1,2,3,4,5,7,8], % 7-[1,2,3,4,5,6,8],8-[1,2,3,4,5,6,7]] % ``` % TODO: Simple two-step algorithm. You could be smarter, I suppose. complement(G, NG) :- vertices(G,Vs), complement(G,Vs,NG). complement([], _, []). complement([V-Ns|G], Vs, [V-INs|NG]) :- ord_add_element(Ns,V,Ns1), ord_subtract(Vs,Ns1,INs), complement(G, Vs, NG). %% reachable(+Vertex, +UGraph, -Vertices) % % True when Vertices is an ordered set of vertices reachable in % UGraph, including Vertex. Example: % % ``` % ?- reachable(1,[1-[3,5],2-[4],3-[],4-[5],5-[]],V). % V = [1, 3, 5] % ``` reachable(N, G, Rs) :- reachable([N], G, [N], Rs). reachable([], _, Rs, Rs). reachable([N|Ns], G, Rs0, RsF) :- neighbours(N, G, Nei), ord_union(Rs0, Nei, Rs1, D), append(Ns, D, Nsi), reachable(Nsi, G, Rs1, RsF). /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Written in February 2021 by Adrián Arroyo (adrian.arroyocalle@gmail.com) Part of Scryer-Prolog I place this code in the public domain. Use it in any way you want. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ /** This library provides reasoning and working with [UUID](https://en.wikipedia.org/wiki/Universally_unique_identifier) (only version 4 right now). There are three predicates: * `uuidv4/1`, to generate a new UUIDv4 * `uuidv4_string/1`, to generate a new UUIDv4 in string hex representation * `uuid_string/2`, to converte between UUID list of bytes and UUID hex representation Examples: ``` ?- uuidv4(X). X = [42,147,248,242,117,196,79,2,129,159|...]. ?- uuidv4_string(X). X = "428499fc-76e3-4240- ...". ?- uuidv4(X), uuid_string(X, S). X = [173,12,244,152,139,118,64,139,137,4|...], S = "ad0cf498-8b76-408b- ...". ?- uuid_string(X, "61ae692e-eaf6-4199-8dd3-9f01db70a20b"). X = [97,174,105,46,234,246,65,153,141,211|...]. */ :- module(uuid, [ uuidv4/1, uuidv4_string/1, uuid_string/2 ]). :- use_module(library(crypto)). :- use_module(library(dcgs)). :- use_module(library(lists)). /* An UUID is made of 16 bytes, composed of 5 sections: time_low - 4 time_mid - 2 time_hi_and_version - 2 clock_seq_hi_and_res_clock_seq_low - 2 node - 6 UUID v4 can be generated from a set of 16 random bytes: https://www.rfc-archive.org/getrfc.php?rfc=4122#gsc.tab=0 (section 4.4) */ %% uuidv4(-Uuid). % % Generates a new UUID v4 (random). It unifies with a list of bytes. uuidv4(Uuid) :- crypto_n_random_bytes(16, Bytes), Bytes = [B1, B2, B3, B4, B5, B6, B7, B8, B9, B10, B11, B12, B13, B14, B15, B16], byte_bits(B9, BitsClockSeqHi0), BitsClockSeqHi0 = [_X7, _X6, X5, X4, X3, X2, X1, X0], NewBitsClockSeqHi0 = [1, 0, X5, X4, X3, X2, X1, X0], byte_bits(NewClockSeqHi0, NewBitsClockSeqHi0), byte_bits(B7, BitsTimeHi), BitsTimeHi = [_Y7, _Y6, _Y5, _Y4, Y3, Y2, Y1, Y0], NewBitsTimeHi = [0, 1, 0, 0, Y3, Y2, Y1, Y0], byte_bits(NewTimeHi, NewBitsTimeHi), Uuid = [B1, B2, B3, B4, B5, B6, NewTimeHi, B8, NewClockSeqHi0, B10, B11, B12, B13, B14, B15, B16]. %% uuidv4_string(-UuidString). % % Generates a new UUID v4 (random). It unifies with a string representation of the UUID. % It is equivalent of calling `uuidv4/1` followed by `uuid_string/2`. uuidv4_string(String) :- uuidv4(Uuid), uuid_string(Uuid, String). %% uuid_string(?UuidBytes, ?UuidString). % % Translates between the bytes representation and the string representation of the same UUID. uuid_string(Uuid, String) :- Uuid = [B1, B2, B3, B4, B5, B6, B7, B8, B9, B10, B11, B12, B13, B14, B15, B16], phrase(uuid_([S1, S2, S3, S4, S5]), String), hex_bytes(S1, [B1, B2, B3, B4]), hex_bytes(S2, [B5, B6]), hex_bytes(S3, [B7, B8]), hex_bytes(S4, [B9, B10]), hex_bytes(S5, [B11, B12, B13, B14, B15, B16]). uuid_([S1, S2, S3, S4, S5]) --> { length(S1, 8), length(S2, 4), length(S3, 4), length(S4, 4), length(S5, 12) }, S1, "-", S2, "-", S3, "-", S4, "-", S5. byte_bits(Byte, Bits) :- \+ var(Byte), byte_bits_(Byte, Bits), length(Bits, 8),!. byte_bits(Byte, Bits) :- \+ var(Bits), length(Bits, 8), byte_bits__(Byte, Bits),!. byte_bits_(0, [0]). byte_bits_(1, [1]). byte_bits_(Byte, Bits) :- R is Byte // 2, M is Byte mod 2, byte_bits_(R, Bits0), append(Bits0, [M], Bits). byte_bits__(0, []). byte_bits__(Byte, Bits) :- length(Bits, N), Bits = [Bit|Bits0], byte_bits__(Byte0, Bits0), Byte is Byte0 + Bit*(2 ^ (N-1)). ! /** Provides the predicate `when/2`. */ :- module(when, [when/2]). :- use_module(library(atts)). :- use_module(library(dcgs)). :- use_module(library(lists)). :- use_module(library(lambda)). :- use_module(library(format)). :- use_module(library(debug)). :- attribute when_list/1. :- meta_predicate(when(+, 0)). %% when(Condition, Goal). % % Executes Goal when Condition becomes true. % Condition may consist of `ground(T)`, `nonvar(T)`, `C1,C2`, `C1;C2`. when(Condition, Goal) :- ( when_condition(Condition) -> ( Condition -> Goal ; term_variables(Condition, Vars), maplist( [Goal, Condition]+\Var^( get_atts(Var, when_list(Whens0)) -> Whens = [when(Condition, Goal) | Whens0], put_atts(Var, when_list(Whens)) ; put_atts(Var, when_list([when(Condition, Goal)])) ), Vars ) ) ; throw(error(domain_error(when_condition, Condition),_)) ). when_condition(Cond) :- % Should this be delayed? var(Cond), !, throw(error(instantiation_error,when_condition/1)). when_condition(ground(_)). when_condition(nonvar(_)). when_condition((A, B)) :- when_condition(A), when_condition(B). when_condition((A ; B)) :- when_condition(A), when_condition(B). remove_goal([], _, []). remove_goal([G0|G0s], Goal, Goals) :- ( G0 == Goal -> remove_goal(G0s, Goal, Goals) ; Goals = [G0|Goals1], remove_goal(G0s, Goal, Goals1) ). vars_remove_goal(Vars, Goal) :- maplist( Goal+\Var^( get_atts(Var, when_list(Whens0)) -> remove_goal(Whens0, Goal, Whens), ( Whens = [] -> put_atts(Var, -when_list(_)) ; put_atts(Var, when_list(Whens)) ) ; true ), Vars ). reinforce_goal(Goal0, Goal) :- Goal = ( term_variables(Goal0, Vars), when:vars_remove_goal(Vars, Goal0), Goal0 ). verify_attributes(Var, Value, Goals) :- ( get_atts(Var, when_list(Whens)) -> ( var(Value) -> ( get_atts(Value, when_list(WhensValue)) -> append(Whens, WhensValue, WhensNew), put_atts(Value, when_list(WhensNew)) ; put_atts(Value, when_list(Whens)) ), Goals = [] ; maplist(reinforce_goal, Whens, Goals) ) ; Goals = [] ). gather_when_goals([], _) --> []. gather_when_goals([When|Whens], Var) --> ( { term_variables(When, [V0|_]), Var == V0 } -> [when:When] ; [] ), gather_when_goals(Whens, Var). attribute_goals(Var) --> { get_atts(Var, when_list(Whens)) }, gather_when_goals(Whens, Var), { put_atts(Var, -when_list(_)) }. @@&@@A,A(sAA 2B 3B ;B PB pRBpgBuB W0W@WYPY0Y8Y@Y[r[r !"#$% FHF@FpW#F[r %,3?MX[rePvBgvBzvB[r0YvB8YWWA B7#@B8`BnMВB]`BSvBРB BB< оBI B[rB3 B-`BB :Bu J0C_ Zh C#v|CprC0 2C`6CH\r@\r8\r*9CM3`;CVNx\rhp\r>Ch\r`\rEC\r\r!\r;@ICG`QC_\r\r\r\r\r\r\r=\rb\r}\r\r\rPC6C  \r C-X\rGP\rj\rКC0\r(\rC\r[r[r [rBLWRa@CYhCWPpCgCDDpD D+P D`DP\rD%*0D<DI"D ["Dm"D z\r@.D%p.D6D>DFD 0TDcWD `[D  0iDc% lD3 tDH yDZ }Dh Dz  D  D pD @D D ЫD  D  D d+ ]r:  ]r@G#H WS W^ k @+Ey @/E" {E E Eb  @E E pE` ЋE `E Eu pE E (  E= 0ER 0Eg 0E| 0E 0E 0EG E: EJ EJ `E  E E зE  `Ew, `E6 E@ EO E\ Y Ee E o  F z F F F #Ff 'FF @-F6 2FF 7FV 0=F 1 PFFl A OFL pUFV 0[Ftb `Fn eF:z kFj pFr vF {F: ЀF2 FB `FS FJ F: PF`F@F/pF , F : FrHF) VF dF qF> F> @F0 pG G! G p(G{ 3Gup4G EGuEG "QGm7aGuEaGZ0qGuhqGwvG |G:GGЌGM  GE pGE G! GF !@G6 6hW;pW@xWEWJWOWUWW[WLWaWgWmWs~GG`G G0GPGPG$G 0G|G+G 9G:GGVGj`H {@#Hm+Hf0,Hs,Hp.H~3Hi`6H09H;Hy`>H AH+DH:FHFIH``PNHkh` RH@UHZHlp_H~eH rH5WWW H*%H)8 HL H] H9n`HHHH@H  H`HHH#H2H=HFHYHW dXpX|H HH H H[HH_ H=PH' HEH,कFHa褕{`H2H0HuHu0HjH:H: HHf 0HjH,@Hf=IbN IaIwI@I IP I`I@IIII(;&IfM -I]/Ir`3I6I$ :Ix>IDI0JIFOItSIUI\I3ؤGФOȤjpcI kI`rIPvI|zIII$pIs8SvI3 I/I I Ia II@I@I,#=_x pwpI @Iu I. II}JqJ! JG0J@JZJ wJm h`J@JV K3K<  !K +K>K40FKK@ZKQ ccKqx uKyK KJK:PK KK `K K `K!K/K <KJ L]@L q`L0$L*L1L 8L VLp]LPuLR-)L:@LWLmLL LLL=MM .M'5M0 ?M8/0GM8@pNMVX]XdXkv\M~_MhM  tM Mf PMMM `M~M!  M1 MA M<L @M;g M>M*} M%  MM[ @M9 Mr M M{M2M2  N N!N'!`Nm8!NT! N d! N~! N:!N!N!@NM!N}!NF!`N!0N" "NY"%N*"p(Nq9"+NP"/Nb"P3Nt"7N":N">N"BN'"FN@"KN"OND#UN# ZN(#^N[<#dNO#iN_#qNo#wN#0}N#ЀN{#PN#pN#N#0N3#pN#PN6$N!$N0$ N>$N'V$Ni$N$N$N$N$Nj%PN% N'% NA%O S%O9l% O%'O%@7`N7Tb7Po7L7H7D7@7<7874708,#8(08 E8S8$i8 x888\8X888899+9;9R9覕`9즕u9ক9䦕99999S9 S~` S9p SN9 S: S: S"6:SK:PSd:Sr:SW:@!S:,S :AS :: XP:wS: XP:;;X;!;S);PS3;S<;S}X;Si;0Sy;PSV;S[;;S;S;S ;siS ;pS/";Sg <dT( )<WT% :8<U<pX[<Xb<Xi<q<zT<@{T<P}T <Tz<pT <PT <T:/<PTd=@cUn![X%=X+=4= UH=(^=0tir=0~0U{=PU)=U=$=@=X==UW=@X(= U;0U= U  >'>D>@U"T>pU p>y>x p>h>X[X>pX%=X9>MV>8tiXX>>@_V>`V >nV ?tV&?`wVz;?}VS?V l?w?V ??IV??V!?V?V-?V?V"?V?V @ #X@V0@V?@V W@>#X^@h@p@Ww@ W@*X @ W@*X @ W5)X @@ W@)X @` W@(XA W&A(X2A WMA(XYA WrA'X~A WA WAPW!AHtiA)XA)XAWyAk)XAW BLtiB*X)Bp*X5BP*XAB0*XMB *X YB)X eB)X qB@4WzB5(XB02XD2X2XUD2XCD3XD3XD3XL3Xa 3Xg(3XDDDD DDDEEEE%E+Eb 3EG nBGGUWGPRjbGpuG0WEGnW6G+XG0lBGlBG,GnBGTpP+G0M] GWGPjBGQ HPWH@gg+H1o@!;H iBBH+XKHiBTH[rA@W)F@U\H@oBdH0rBqHE% HqBHgBH B9H`uBH`iNH`RHuBHHH@hBH0mBH0VHMVHqBI[V$<&SDI0W!/I Sc:IqNIU \IRmIrBI@iiI0kBInBIPIpR7ISKI$ImBI RJ0 SJRAJ(W='JsB/JWQ ;JJJSTJ0U_JRlqJ0DyJ JC(JTkJP)JV1JмDJJKWKpVZ!KpW'-KPtB5KhBLmWVL&WaLhLuL`\V.LL̫L0NSLRLPNVLboL0OV LPhBLWLmBLo MCMUM$MpcC6MpW3CMPmBKM8S_M Z jM%W9wMqB|M0WMsBMMG`lBM@WM@lBM WZM0WMTzM LWMmBN`YcNWj#NWV*N ?N W#JN@ZSXNhN R;rN7j)NM NjBNVy N@UfN`RN VNpWs[K`oBN@nBN\V3NrBNS-NjBOEuO0nBOp)S"O0S,O`IWVPPKV`Xo; ZViB`VPhShV&S~V૕Vp?SVVVjBViBG@iBV`BVVArVUV@\VVWW V*W`QA6W0U fSd@W tBGW`SPW0T aWoBgWq{W<WpUWSQWlWPMVWiBWRmW@PrW䬕WpgBX`WXS!"XXC-XAV5XȬ>X7jrQPUXX rBBW(gX`tByXn>X U\XSTX![rXUXRXocXVMXUXoYUQYW~&YWd1YU8YPSEYRY ^VZYiBaY0jBgYPSqY0qByYjCZYpXYXSvYYSYW'YSYprBUhBY0TMO@jBYpBZWZo,ZM =ZHKZuBVZuWlZ+XvZPiBTPlB~ZoBZAq ZiBZiBZS-ZW ZWZR)ZmBZYMZԬZpS[0tBQlB [̬[gB[ث-[ C<[YJ[SS[tB_[e*k[P%WJw[[0PV[>O[TM?[ЍS9[iB[P0CI[@pi[W[qB\[r \tB\`"\@rB8\B\GO\lBV\`S1d\Ыn\S~\`S\pR\`YV\Nq\sB\h\S\U\nB\`gi]I]']W;]PWlE]S VmBP]#VF []Si]йWdz][r]pB]PT]`Sa]@D6]`ti]@pB]qB]lB]ppB^S^W..^nW6C^@`WN^S[^`Vq^W^^nB^pW^tW^@Um"^p^T^pW ^bW_V="_м2_S* L =_[MRM_{DX_dk_`jBr_Wu~_VC'_ VL_W_@V_f_SqdPkB_`U_*C_`VS` Il`p(S-`@ V:`C`bWPoBR`КU]`f`S5u`0` ti`iB` S`IV` 0Vv`$ti`q`Hu` C ai!a`pB(aUM1a =aLSJaHH[aEhaUrapkBa`pg a Vad`a SaoBagBaS9aWlaPWa0WbMA bV3!b S*bPsB1boBY0U:bWLFbrBMbrB[b0"Wwlb ubsB|bpV"b`q] b`iBbȫb U'bhBb`kB$RV2bUbsBbpB cpW!c`&WW-cR]=c'WHclBLc`ZCacpBc`csBcTcܬcCWcKVcJnctBd`Ud:S.daSCPgBq@e&OQe+XYe`CjhetirePuB|eUe@W7egZA eДSeSeVW[ sBHSe@%T2eoBeW0eSOeSfwBf@Sfe 7"f R+fpSA8f CGfkBMfsB_f`+j rfd fPWffIffTfBSff pAfFWf`Wg`P1g*I-g`rB7g쬕Gg@WTgpU3\g2qogvWtgpg쫕gpgnT%g#W_gg`HHhUhU!hW2hCmGh(tiMh@q_hmBkh@+jhShPUEhnBhWhSfRhػh@&ZAhPRdi&W$i(iW9ipB@iWUitB^ieiWti@kBzi`9CijBi`BikBiRCiVwisBixjW(jPrB2jS7HflB;jRFIj UMWjphB_j Ujj@S~jjBjbS2j6SljC#GD8j@W2j`Pr! jVjj WjnBjPkkQkWpk47kpoB=k@tiGkPWUk0]C9hkuBukpjB}k SokpSvk0kkBkW-kCk+XVDk0iBkWk2q kجltilD4l1oHlYlflq ylyWlEGlUlgBlNSlsBl@Hplplp VwmnB mpBmU!mhB*moBeV80m uB=mWHm UUm`W-lm)SjzmjBmS&mTmrBmSTmPRm+XhUdmRgmoBmpnBncWn}gnWu.n@sB3nhB;nкWHnUQPnq3`nSknp2EeznkBnlBaSn0SnUklBnlBnoBn@n@Sn@CnXn@S9nĬn RG"opU 3o`q NFo>qXoPUR*SiBdoxWQwo`nBotio@PoлW$o%WooMStoR8o CoVoSVopuBo`pDp[rprB)p`qB>prBLp@uBUp@ASnhp軕p`U[H6V p@UppOqvHU pDp`W pp`mBpНUpPVq ,XqqpC4qCIq`WeZqWhqЬpqpqPqBqtBq@XoqmBqkBq]SxqpiBq@W4q jBqr`8prPWS"r@j\D2r0BK=rS_HrPU,Sr WarpaSKqr諕rrWUr`IrU rPYr,XrpV#rhBrS\r,Xr*C,rCsisrB's0XS6sjB  oSX[r=s0oBBsVHsiIRSXskB]s?jqs0s mBsQsRs`Y@sU?s $ > : ; 9 I : ;9  : ;9 I8  : ;9 I8  : ;9  : ;9 I : ;9 I &I .? : ;9 ' I@B  : ;9 I : ;9 IB4: ;9 IB1RB UX YW 11B U4141B 1U.: ;9 ' I : ;9 I4: ;9 I  Iwwevepwpv-QR--*0*U t4-@-$u4-! t4-@-$x4-!*t4-@-$x4-!-QR-;-f-(@-@NZ[WkZ[RZPQafPQ6;-f-@NZ[WkZ[6R0f(0@0 9; -4f -4Y(^@NZWkZk^YSCN[Wk[S9ITIOQfTP xr%t!Q[T#QCPTWzT[[PTP#(P1TtP P (T @z $ &P @z $ & @z $ &3?q(@/0( 1$#/?' $ &k| p $ &| z $ &QQPP,pW6Rp0:=@3 j pW Kzl Ze u<=<~=0 Xg=Y<v  :Z =;]< %< 8> Yg,= ;=f 9=<<=> k<.~Y ʭ<< ; =~J <>~=f X.  t. .JGNU C17 14.3.0 -mtune=generic -march=x86-64 -g -g -g -O2 -O2 -O2 -fbuilding-libgcc -fno-stack-protector -fpic -fexceptions -fnon-call-exceptions -fvisibility=hidden/jenkins/jobs/oi-userland/workspace/components/developer/gcc-14/gcc-releases-gcc-14.3.0/libgcc/libgcc2.c/jenkins/jobs/oi-userland/workspace/components/developer/gcc-14/build/amd64/x86_64-pc-solaris2.11/libgccshort unsigned int__int128 unsignedcomplex doublelong long unsigned int__udivmodti4short intcomplex _Float128long long int__int128__divti3complex _Float16DWstructDWunioncomplex long doubleUTItypeUDItypecomplex floathighunsigned char/jenkins/jobs/oi-userland/workspace/components/developer/gcc-14/build/amd64/x86_64-pc-solaris2.11/libgcc/jenkins/jobs/oi-userland/workspace/components/developer/gcc-14/gcc-releases-gcc-14.3.0/libgcclibgcc2.hlibgcc2.c.interp.eh_frame_hdr.eh_frame.SUNW_syminfo.hash.SUNW_ldynsym.dynsym.dynstr.SUNW_version.SUNW_versym.SUNW_dynsymsort.SUNW_reloc.rela.plt.text.init.fini.rodata.got.dynamic.fini_array.init_array.data.tm_clone_table.bss.symtab.strtab.comment.debug_info.debug_abbrev.debug_loc.debug_aranges.debug_ranges.debug_line.debug_str.debug_line_str.shstrtab@ p@$p&@&!oB@/A5o,A,FC (sA(sYK"AEeSo2B2ao3B3xno;B;PBPBpRBpRpgBpguBuk@ W 0W0@W@h YPPYP0Y08Y8@Y@A [r[1[r[1a#@[18R 2v0r2 22#h2(.20=2KP2W092sb02r 2|