From 0a61fbdb379fc3ecbb86e50e882dddbe30b0aa56 Mon Sep 17 00:00:00 2001 From: RipplB Date: Fri, 1 Nov 2024 19:36:22 +0100 Subject: [PATCH] LTL checking capability Add possibility of checking LTL properties with CEGAR. CFA is now extended with optional accepting edges. Classes are available that convert LTL string to such CFA. --- build.gradle.kts | 2 +- buildSrc/gradle.properties | 5 +- buildSrc/src/main/kotlin/Deps.kt | 2 + lib/jhoafparser-1.1.1.jar | Bin 0 -> 268695 bytes settings.gradle.kts | 2 + .../cfa/analysis/utils/CfaVisualizer.java | 79 +++-- .../main/java/hu/bme/mit/theta/cfa/CFA.java | 60 ++-- .../hu/bme/mit/theta/cfa/CFAVarChanger.kt | 32 +- .../mit/theta/analysis/unit/UnitInitFunc.java | 13 +- subprojects/common/common/build.gradle.kts | 5 + .../common/process/SimpleProcessRunner.kt | 66 ++++ subprojects/common/ltl-cli/build.gradle.kts | 23 ++ .../kotlin/common/ltl/cli/LtlCliOptions.kt | 44 +++ subprojects/common/ltl/build.gradle.kts | 32 ++ .../common/ltl/src/main/antlr/LTLGrammar.g4 | 138 ++++++++ .../common/cfa/buchi/Ltl2BuchiTransformer.kt | 27 ++ .../cfa/buchi/hoa/APGeneratorVisitor.kt | 190 +++++++++++ .../common/cfa/buchi/hoa/BuchiBuilder.kt | 189 +++++++++++ .../common/cfa/buchi/hoa/ExternalLtl2Hoaf.kt | 25 ++ .../common/cfa/buchi/hoa/LTLExprVisitor.kt | 233 ++++++++++++++ .../cfa/buchi/hoa/Ltl2BuchiThroughHoaf.kt | 46 +++ .../theta/common/cfa/buchi/hoa/Ltl2Hoaf.kt | 21 ++ .../common/cfa/buchi/hoa/Ltl2HoafFromDir.kt | 30 ++ .../common/cfa/buchi/hoa/ToStringVisitor.kt | 298 ++++++++++++++++++ .../hu/bme/mit/theta/common/ltl/LtlChecker.kt | 178 +++++++++++ .../common/ltl/LtlCheckTestWithCfaExpl.kt | 108 +++++++ .../common/ltl/LtlCheckTestWithCfaPred.kt | 131 ++++++++ .../common/ltl/LtlCheckTestWithXstsExpl.kt | 115 +++++++ .../common/ltl/LtlCheckTestWithXstsPred.kt | 156 +++++++++ .../src/test/resources/cfa/counter2inf.cfa | 12 + .../src/test/resources/cfa/counter5inf.cfa | 12 + .../ltl/src/test/resources/cfa/indicator.cfa | 14 + .../resources/cfa/indicator_multiassign.cfa | 12 + .../ltl/src/test/resources/cfa/wave_flag.cfa | 9 + .../ltl/src/test/resources/cfa/wave_flags.cfa | 18 ++ .../test/resources/hoa/%21%28%21+F+ap0%29.hoa | 18 ++ .../test/resources/hoa/%21%28F+G+ap0%29.hoa | 16 + .../src/test/resources/hoa/%21%28F+ap0%29.hoa | 14 + .../hoa/%21%28G+%28ap0+-%3E+F+ap1%29%29.hoa | 16 + .../hoa/%21%28G+%28ap0+-%3E+X+ap1%29%29.hoa | 18 ++ .../test/resources/hoa/%21%28G+F+ap0%29.hoa | 16 + .../src/test/resources/hoa/%21%28G+ap0%29.hoa | 18 ++ .../src/test/resources/xsts/counter3inf.xsts | 12 + .../src/test/resources/xsts/counter50.xsts | 16 + .../src/test/resources/xsts/counter6to7.xsts | 13 + .../ltl/src/test/resources/xsts/forever5.xsts | 9 + .../resources/xsts/randomincreasingeven.xsts | 14 + .../src/test/resources/xsts/simple_color.xsts | 24 ++ .../src/test/resources/xsts/simple_types.xsts | 16 + .../test/resources/xsts/trafficlight_v2.xsts | 169 ++++++++++ .../ltl/src/test/resources/xsts/weather.xsts | 104 ++++++ .../test/resources/xsts/weather_noinit.xsts | 106 +++++++ .../resources/xsts/weather_withprops.xsts | 105 ++++++ .../analysis/util/XstsCombineExtractUtils.kt | 15 +- subprojects/xsts/xsts-cli/build.gradle.kts | 3 + .../bme/mit/theta/xsts/cli/XstsCliLtlCegar.kt | 143 +++++++++ .../hu/bme/mit/theta/xsts/cli/XstsCliMain.kt | 40 ++- .../mit/theta/xsts/passes/NormalizerPass.kt | 74 +++++ .../hu/bme/mit/theta/xsts/passes/XstsPass.kt | 23 ++ .../mit/theta/xsts/utils/XSTSVarChanger.kt | 0 60 files changed, 3226 insertions(+), 103 deletions(-) create mode 100644 lib/jhoafparser-1.1.1.jar rename subprojects/cfa/cfa/src/main/{kotlin => java}/hu/bme/mit/theta/cfa/CFAVarChanger.kt (57%) create mode 100644 subprojects/common/common/src/main/java/hu/bme/mit/theta/common/process/SimpleProcessRunner.kt create mode 100644 subprojects/common/ltl-cli/build.gradle.kts create mode 100644 subprojects/common/ltl-cli/src/main/kotlin/common/ltl/cli/LtlCliOptions.kt create mode 100644 subprojects/common/ltl/build.gradle.kts create mode 100644 subprojects/common/ltl/src/main/antlr/LTLGrammar.g4 create mode 100644 subprojects/common/ltl/src/main/kotlin/hu/bme/mit/theta/common/cfa/buchi/Ltl2BuchiTransformer.kt create mode 100644 subprojects/common/ltl/src/main/kotlin/hu/bme/mit/theta/common/cfa/buchi/hoa/APGeneratorVisitor.kt create mode 100644 subprojects/common/ltl/src/main/kotlin/hu/bme/mit/theta/common/cfa/buchi/hoa/BuchiBuilder.kt create mode 100644 subprojects/common/ltl/src/main/kotlin/hu/bme/mit/theta/common/cfa/buchi/hoa/ExternalLtl2Hoaf.kt create mode 100644 subprojects/common/ltl/src/main/kotlin/hu/bme/mit/theta/common/cfa/buchi/hoa/LTLExprVisitor.kt create mode 100644 subprojects/common/ltl/src/main/kotlin/hu/bme/mit/theta/common/cfa/buchi/hoa/Ltl2BuchiThroughHoaf.kt create mode 100644 subprojects/common/ltl/src/main/kotlin/hu/bme/mit/theta/common/cfa/buchi/hoa/Ltl2Hoaf.kt create mode 100644 subprojects/common/ltl/src/main/kotlin/hu/bme/mit/theta/common/cfa/buchi/hoa/Ltl2HoafFromDir.kt create mode 100644 subprojects/common/ltl/src/main/kotlin/hu/bme/mit/theta/common/cfa/buchi/hoa/ToStringVisitor.kt create mode 100644 subprojects/common/ltl/src/main/kotlin/hu/bme/mit/theta/common/ltl/LtlChecker.kt create mode 100644 subprojects/common/ltl/src/test/kotlin/hu/bme/mit/theta/common/ltl/LtlCheckTestWithCfaExpl.kt create mode 100644 subprojects/common/ltl/src/test/kotlin/hu/bme/mit/theta/common/ltl/LtlCheckTestWithCfaPred.kt create mode 100644 subprojects/common/ltl/src/test/kotlin/hu/bme/mit/theta/common/ltl/LtlCheckTestWithXstsExpl.kt create mode 100644 subprojects/common/ltl/src/test/kotlin/hu/bme/mit/theta/common/ltl/LtlCheckTestWithXstsPred.kt create mode 100644 subprojects/common/ltl/src/test/resources/cfa/counter2inf.cfa create mode 100644 subprojects/common/ltl/src/test/resources/cfa/counter5inf.cfa create mode 100644 subprojects/common/ltl/src/test/resources/cfa/indicator.cfa create mode 100644 subprojects/common/ltl/src/test/resources/cfa/indicator_multiassign.cfa create mode 100644 subprojects/common/ltl/src/test/resources/cfa/wave_flag.cfa create mode 100644 subprojects/common/ltl/src/test/resources/cfa/wave_flags.cfa create mode 100644 subprojects/common/ltl/src/test/resources/hoa/%21%28%21+F+ap0%29.hoa create mode 100644 subprojects/common/ltl/src/test/resources/hoa/%21%28F+G+ap0%29.hoa create mode 100644 subprojects/common/ltl/src/test/resources/hoa/%21%28F+ap0%29.hoa create mode 100644 subprojects/common/ltl/src/test/resources/hoa/%21%28G+%28ap0+-%3E+F+ap1%29%29.hoa create mode 100644 subprojects/common/ltl/src/test/resources/hoa/%21%28G+%28ap0+-%3E+X+ap1%29%29.hoa create mode 100644 subprojects/common/ltl/src/test/resources/hoa/%21%28G+F+ap0%29.hoa create mode 100644 subprojects/common/ltl/src/test/resources/hoa/%21%28G+ap0%29.hoa create mode 100644 subprojects/common/ltl/src/test/resources/xsts/counter3inf.xsts create mode 100644 subprojects/common/ltl/src/test/resources/xsts/counter50.xsts create mode 100644 subprojects/common/ltl/src/test/resources/xsts/counter6to7.xsts create mode 100644 subprojects/common/ltl/src/test/resources/xsts/forever5.xsts create mode 100644 subprojects/common/ltl/src/test/resources/xsts/randomincreasingeven.xsts create mode 100644 subprojects/common/ltl/src/test/resources/xsts/simple_color.xsts create mode 100644 subprojects/common/ltl/src/test/resources/xsts/simple_types.xsts create mode 100644 subprojects/common/ltl/src/test/resources/xsts/trafficlight_v2.xsts create mode 100644 subprojects/common/ltl/src/test/resources/xsts/weather.xsts create mode 100644 subprojects/common/ltl/src/test/resources/xsts/weather_noinit.xsts create mode 100644 subprojects/common/ltl/src/test/resources/xsts/weather_withprops.xsts create mode 100644 subprojects/xsts/xsts-cli/src/main/kotlin/hu/bme/mit/theta/xsts/cli/XstsCliLtlCegar.kt create mode 100644 subprojects/xsts/xsts/src/main/java/hu/bme/mit/theta/xsts/passes/NormalizerPass.kt create mode 100644 subprojects/xsts/xsts/src/main/java/hu/bme/mit/theta/xsts/passes/XstsPass.kt rename subprojects/xsts/xsts/src/main/{kotlin => java}/hu/bme/mit/theta/xsts/utils/XSTSVarChanger.kt (100%) diff --git a/build.gradle.kts b/build.gradle.kts index e5be05ea9b..3b60d44bbc 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -29,7 +29,7 @@ buildscript { allprojects { group = "hu.bme.mit.theta" - version = "6.7.0" + version = "6.8.0" apply(from = rootDir.resolve("gradle/shared-with-buildSrc/mirrors.gradle.kts")) } diff --git a/buildSrc/gradle.properties b/buildSrc/gradle.properties index efb2dbd0eb..144d0ea9d7 100644 --- a/buildSrc/gradle.properties +++ b/buildSrc/gradle.properties @@ -17,7 +17,7 @@ javaVersion=17 kotlinVersion=1.9.25 shadowVersion=7.1.2 -antlrVersion=4.9.2 +antlrVersion=4.12.0 guavaVersion=31.1-jre jcommanderVersion=1.72 z3Version=4.5.0 @@ -41,4 +41,5 @@ javasmtVersion=4.1.1 sosylabVersion=0.3000-569-g89796f98 cliktVersion=4.4.0 spotlessVersion=6.25.0 -kamlVersion=0.59.0 \ No newline at end of file +kamlVersion=0.59.0 +nuprocessVersion=2.0.6 diff --git a/buildSrc/src/main/kotlin/Deps.kt b/buildSrc/src/main/kotlin/Deps.kt index 5fc6cc9b53..9c869af882 100644 --- a/buildSrc/src/main/kotlin/Deps.kt +++ b/buildSrc/src/main/kotlin/Deps.kt @@ -81,4 +81,6 @@ object Deps { val clikt = "com.github.ajalt.clikt:clikt:${Versions.clikt}" val kaml = "com.charleskorn.kaml:kaml:${Versions.kaml}" + + val nuprocess = "com.zaxxer:nuprocess:${Versions.nuprocess}" } diff --git a/lib/jhoafparser-1.1.1.jar b/lib/jhoafparser-1.1.1.jar new file mode 100644 index 0000000000000000000000000000000000000000..750256100b9df09eb292d87c5df0f98fb5b97b4c GIT binary patch literal 268695 zcmaI7bBw4#`z$!NZQHhO+qP}nwt2?3ZQIrv+cSH?&f}P(to|x$?&_o- z1!-Uq6aWYa2mtxkCozEk&j$$r0w61@B1kJKCr1A>2><{Lpdbwn@gD@x{|!_4KTbyZ zhxmUc%L>X#iis+#(8-FSPWC_rGavx$^Cq~DTZF$cOAO3_iHJBl(}w4Kng{mfed;nzSDEM^=D z*X#EO>5vo=jLgs3p3T}mA+{|31^Z9ED0D0XcK@nz_&5IFdgcCqiv<7>wlK6aHLt-JdLIz4Jo-?SWl9+eGuUU^@o$9_Gg zVa>M#htHjc0p<7*_d=bB!Gq#- zogg2oLwQ)^P@~hJGY^f*xQp1}{qj|4CSUBUOjkj4w=j+FeC>%8bRlh)Vm0w@ zh+{UBevfisvEa*j6XTkN^`clolFy(}5V3dP}@@1TeV|lbrL)f@iy}VmEgt8ClB5wyrlqg53ke@wS$%@YYt0adL#wevE!%q*rly{1NI0 zU?sE@(%iB$H9(!CS7}liyDZn)by8I?faVVPH%`}0N>C;0_MQAc0*M(bTHpNPzqQA|p7CJAmcRbIzxLqj zY%>+;R4WpCl_ z>+XlQgz+=2lRmqu)>xU7ytr~*IG!pgvjlTXq7NJWIbnsBe4y9N+R~H_w$9?wUBULw zMHS_&zm2LKy^ANd_V;-Fc!saj`@INXTjiS-8;#4?>7aKqUz)tp>5#qLq_x#u2VF2u z_OVR2R87C=uE;HIaMtpU)-S7NYSq~A64p1n7(7XBnlf6j(Un7)_vl(DdFPs0W2<5G z)mvtpXgu7Y4IlkF1LiCFUBNb2x71u|b;*>b()y9a99iP_KB}Bdefj>LncsvYs}Rsn zUK0@_Vpf?k5*&(J^dBxynU$`8>&-+CeG)HoLOAtjuE$QN&pDv~l7BSgE3Hvpb z%O(AF*6%dop2HF2orjqWo2-q9qixtx``Ny`T~xi`LVsDEK>s*!ZfyH3qMV7Ewbit_ z&$b#mihP{r=gQ1#{kD_mp1owMi0JV1ztz2&Bw6~-#O~uElX%=bk=C@44N9BO$E7#Z z*NB0HRO#~)6>cqPwz9x@+^~<3iyJela;X$CHO1yCv!d9xC^eer9EO{?P9*8l6(bs9 zLDe>|%+)Soxz+1P6QCJ7>@vA0)$EFb*uGr^jh}j}SN>8E>Caij*|irWj(8~BMKLwa zX9uNimPm&~ndb|+%#R+WNz(Bb=%W&8%pXW(MN|kbrs^$$d`IspXiTui`1LSOw9AY^MK*GqBjv}i0TX&IR0yhN}?-s|Ld z(@c77rOt|Ij-NY2p5VPTI!mHg$eitfzoWj3X+4}oqLQ)pYA9T2{^}RVcPCAhis`hL z!?krK_-GIyZ2<&kpGb~SC&^0OL3DN&DC1Qhpe1adRzAd#+(4$aT|&*Dan`b>+kH^_ zI$NaG`3RBBatf?S_rc*fX{myhN%fP!5)Q}njbf}!##IGCz?TTnB1>Qq*I^?0Q zVUSNJV?Y6d2kXkIiBByx;X|7Vs{V`qt{Rw3Whg0yX>PKeK&!W+A2%(NnwZiE?r55e zfNe1x=a)IVL{p>O5a;uE^1K*aw}}(=QI_Ol-nKzT-TR!3!%4Q!!JlMHR}AShHW{{C zNQ*0xs|IFffNZ)JXJ#;(rDXb2g*54ywA6Eatv>SzAF@27ZTOoNlKzGGMTqZqlB2gM zb;HNw-P%+x6!Or5AkM+5F%t$%6b5zb!dXhMrzul_K5`UUlRgXJs$d8GagTtiiUql9 zb7v|5%|_B#YW&lP^W$;#3B7S5iUz?ARGWYc!3@?|qSX?VC;*O2AG@`H_`{H(aT8^( zJ0J>YrlTeViRe(8u1~hdCc4yVY*!a zNnYOp;z*QCc9j2BRUZ3=(a@Ow1ZKNy5@whf>JadVSg^*j#qRCKNt1_|%!PHWw8eu2 zqNeZ0qQ^7o5}Wz>i!_xZW^nKLQY7m}Qv7H{H+ZIDc1^upj;54B{8iuKpSXz7J*@loJ=NyP z+KLf;{_+yd40E}s`3@Q@!jyKgbE~S#)|1B^ZsGYdnzR`qum-<`>Mv*-ptSLqU<}IT z?nK?d9w1>=)+TS^^_mx=tDgd5K%|iSFy+{pmxNFRzvFrD`;;wQK0@3gT8y!$S8$UKG3Jh-0 zB8Q31G!rNcIHY4bG3>2-tF%~T;XeN~X8~J2AG91sO1&`05B)~pZY8M*=&i!rtN z5KT!LW`<%l>AJ9LI8v13@g$MM=&O=Z@*Yc71`Q>Pc|NoVL>}2PdDVo?BjHDx7d2gl z%@UKYX`)-PA(Ph!{fB}9APfLoV5p-%O9D@SzAZ(Cmyt-K)NTFa$&%d|e5MrhykY}f{Nb5XHb zPi_`Y>Mrhr(WFb-8X9_e65u|T=u)Z2Kq}gwfN|k6)Km9<_}K!?FCk`5jhOK%T9STX z1AYFM&0_aozspU$&8R7k=~ipn_4!6|xUm^s4r`$sWU%^})ouht2^fjxi!P>a^(f-r zy^riwA$#$YiEOkk&J?yMA!Pw)mq2378Ydx3m8BbBo1215T7``0%&&<_`~?#iBqIRf z&S{`{Fr@-y1_q2GvzVkPn8!&CdI|lg0s4>%a?B^-GT_k$F04>6u!UDZ%VF_y6977e zfoso3RYK%5c0!^i_DGj4?Ys()sA0<~rQigYw9ZG!t)Ae|flhv3g+W=*r!=?4ta>|9L!q`R><~HG^N8 z=o0^m0{83g%F>ai6MqAYy9qBOkftvpUNjHic8kF+R2g^^xqxCL-=(mSz|=@5SQZSk zN+*pDa4Sww1>l=8J|r>y;J2GFi%64s$x>4nUkWRd-g?uCmBPtH8^xfv-tQn;nINA> zF?Vf#Y>F<#B#)_ko2#ywaMI+0!@5YAqmbi6PHi(6Y;L7Hn4y!f+Zi+-?XOWywqBG7 zJ~LG!A7*MZ-qu9T*`TM9miak$0x8KkjqRtA6IvP4=5eOGIz0y=1gj!#E^Q*BcOSqD zA<2fR(N#^#Fl(Zg@^_%b^d%)o39MJo z5w0sCp4~@sJqd#M9(?x zJcSH?ht_Q8n3|@>%omCAKeDD^aR)Y+jk>M@?f9v#cuPpGq=JwMDx|nc3Hde%Qg?B~ zS~r=EKSQOU+mKWhqxKrlHc?}8=>`Orl}JRIXq3}H7pEfTFqzm!qY97+$$!wog>#I< zwoH_>*uzS1OOiIaT3tr{OOG?Ra3vSaDAZnWc#J?Iyy!gKFm1&)S+20H#N@~FSeux! zQ@`j|WGtTvkIl(K<0Ogg*h^8vIcBa6%KBIQd+>~savM(bq5FkKg<-D{KG0Kl9#fzo zPdc#0(wFhLeur7Tx!J~{Gov|(_b#%H0n-2>U;j-O{2fFbFaGS&hc|_X)nIrny1R$h zM?JH6Fjpn_FI08tYI&<&CR@lh%du9gDn5g|ctNK{rOY@%@V|!wl8_w##(=0Q_Ep|v znN&@rn5dp|Zsm;A_2HBF?M zG<5D2t1If`INoWru8W`fBD8Em;Y+9oucgUIvQ|&24Gm8no^D~KF~eoY#suwCiWNQ_CZt(Km@mhk|1+)Fz>Y!f-lUF1GWKES&hTw}bDozat`>tE&--^daH zs8AOAIbcE-Oel2PmN|RDfWq${ehXF$^;7*<|BFf^FxY5Nf65HsXoCDfWPiYB7-3gE)R0qwZ=BiL=p&&R1{xnZg zgAYKev`CjGfn58$-dFu#^n!@vPzkd05M_ojVWa_jDZ7=1BD1rgo_~Z@*0V%1L2{J2 zz#5dLsqzYRoYAA}qIrmmvHXXU3%p7Fse1dTmN6P`QGSuS=%9j-AX9c~B;GnU5k_i& zGsP~SsJJ!4k+?ESu}B4le!iu7VIdHzB2n?awD;+$Vpy3tMx*gHAucHU0`2;nE?^&r7ZPqzPakvqi4UHmLI)$xc`Dr645fJ1dxMr8sFk(vG`RK zPS31hw!jd2vL2G(K}Y%2Hq|Z`1LlG)pjg&09}padU6p4(Jot}3e2NpfChm0S8si^M z0kvh0!TJs(2Xv@smKaU2X6eV~PCj#<`_)BCTc0$&^h1Ib1sOf5)9F{8VZ~`ivoTb% zkiH}jkB0|$7{~cMathsuCH#aLVc|J1Sh{yh-<-+MeWvHc$Z5f#`|a>CdVoCWFU|&e z(N&w$HyN{neIP(3qWd2Z@wQe|y^lNcA~_)c$e-~q{O1vWD@R;SMz`i716_DLbzQj^ zET_Bkq!YkJ)7MzKC?26f+O-aa0bRL2iXd~DCgUi6+$`d?d(E~q3mNDY{Hu^whq*55 zf_gy>(l>de--MAK1Yrz;?uvW$H0GfZXKIyi$!Uz2ca$MMtGoh z$KLwG^R){)+T$tFK^M0O-FLfR3@Kn~i!vCw>1}|Pnp|Z-e!zm%OQgh=_NUI|rdg&a zA<5;dok=2yIDD?j8d4dZgt{%ZbSvXzCtqNKDXZ9TaM+rHkE$S=? zZA*ZU{(hWRH`IPc!Z+0{JCp450S0FHW!)Y7+ifm3?{ULyq!WqBoVcedFRaOrqfX7v zH0zoc=}=tA!G%zPUquw9lJVHgtrP^OH>mG#rTd|5vui&TN4XnQk!Q*vgQu7+=FnLc z>tv>XqeJi9ZPOW%bQLLtt=8E;7`M7vip#+W>BFXKyE$C&JuLmqWREO?R9afc- z7?Un!`lWUycRh24DT2t0f2)_QQmw$qfNbxqeeV#R(G3G&O`A9-t&lCZa*t?yMH2E$ zvh^c0hqgbb=Hohx@S>1B7cS=_iahK$f#wCFSsJ+P{-WaVxd%F{khhyAILA5oo0b!d zc@|Bs;l`;K`Jm-Y-^Db!i*ZRQS@$5-+!rnDab!iY0-46n zvX#7Z`Xs9H-KMy7mBDafQK!J!T7;%QMU;zwJa=HstWl9niUo^4T*X$Ej6Jq{Ys3XM z9dQOOCp{)W)V3aTNr_leY%e6TM|U2?{o!4feCY6^6jw%ANvpz{D59x62e*`iaVV>q z%OzImpW~?9R{))1pwnN=jz-{cQ@RqWHw+4dd}xQ5hxa`0203_}ZPEB#?+18})vmZ+ zod6IZ+BnRTmdEYsNV!piyfL)(>ire3klzU;5u&r3=f6Rp9_&B!{^UC;+3riA{&utw zGkM&ppbh5%L@FO+V`9i_YAyncSK3s3*GodyDG2l4Cl@IJE&7p=laf6iygs}M3m{{u zz)sq6!jIX4>JEN4w{3EpFRaqQmFfOOPIGgJ07{j{tMMe0KJ`&9i4Hb#@y1xxSik-_ zS0w~(V>CI0>pRq>BbU78P2gGtv^EOq$7mh1+pT`b+ciY$q2&#chX1B%uCJu+cX=4; z3?#U$NW(tJzIz8GHm3g8+{6@6-X~zh(lLB?hGNHpurxnry0$Ok){SR{rp>? zf&!kWrFGhalaj)-Hw4!jDzdxt^GD=RzE^>w=myxuPELuCuL1O83;u})y0LvWq%mY0 z*h(6S82)^#=?$v-j9x$J1$@g!yTx~OJss%nWsI4L^rs#eb<@|8iEp1WE*unHN0htS zAGe;QEX4ex>TVwb8jfun3pDSjpW!ZY^i;VElZ%44bA8`Daf@dGG(lr~!|?r+H8B@b zQag`y)3lDfSfBVHM1UoK*P$A*e+byj(&S(qrJ6qrh;jYUBMDjQZBLl!h=rZ z0SA4H3UU!3`*cy@-2O9SDUxYlNM_3rgAIX}+ArSPB>tZjW39OA-SV<)gUgnvvMul9 zLQy0R>WC+kS@Hw7&#iJD1tsKjJx;;ebnbN3(vF(ZZeLCjbWzAAW)(qWA%M@&mt9To z)m2jZM0{JNi)7G^cI3EMa4&Fg&o4RLNpm1zdeYx@&9mc!!KJvMQt8w{Yn}+k9AKJF zEOI-?olaBJ%3fqkR=2UWngs$Sjean2H3>tC9bl}b<+&spxq=X0p#1;sRvpnH*%$Jnp4BscK!R z)#)y+KVY_n8_t=Fb+&*MfYnrIO3pAf0TZfnuRkp_-s+VNFT+!c_=G^g9Wmhqj!g0}doC|HHHP)$t z`D~UWCGtJUj<$4R9y2!0Cv!7JPNuP~&G9cR&JkK2!go{EYwR~*37m}h56er`H~t=A z0Bh{Iao-Iy09m>1WbW&ElXJ6$#8EC6q0y?2QtkefXjS6YF?+4I&BR$#A;0>kjEcXb z=?zotPyijB(D}0UN7}OzTj%1CNFftpIw*h{B@-`UW{2BTWg}W zJxg!%{S)BdFc5FfKcfdZwg~(97ZSqcKpP(NnB1uG zlp7QtKqc7_FA?+z&K7BhLb&)B@=hha?<5{RDko?@d_7+FQBY<9Xbj_8A?I9{DOa5E z0o*s%&Ad^Fw|XUu9@kG31fN>!;H47|fsFSbY7e;evRv|)2`aGmN*35t2Y#KfGLJpS zej0>akxzR0j~#BBc`l&nNm2x|!UAP;KjR;ft#vO|&(b{I#4CuuIdlBZ#*!3p$Juzu z-mn-S0b`f=VQF<~4hUr5L-Z>ueT}ApF&}P%@}Vjp)NV`|*}gh#N9w^|dGU-Lb1nE?RwR zH|a2EBuB$4(#Lj787%sQ-i^HrQuFHFM|uIi;WR(u!ZSjA6aiM)A5}&NMwTR5k4#Ia zK}Rfh%!$ptN}=l05f2W@()kZTnSBisYr+5cOb*j8EMcOx_55um)CbZTj~9H$xO{56 zhNh3AG!{6a=aYoR{A0IeQqn57d0bkPjWeyaRiK@Wo8{F0gw!rcR)^My?^~vt5-bcN z@I2@#goqVLa1#bJ-kBgYXdtdpyK($lmg%Jcm4LBVR;T}aY7Z694%|@ zEkU0E-_}&z>Rj;?=lg8bbX-Pa6j+}AxF|!;OW|E-p$W0?4pmnIJ(yj-akZq&Knjlw}7%tndBcxy)CtZFyVOf= z7xZ_q%BB{@1>x|$7jST4Sd7n>?)KhoO?_8{kpH`&50!qYRyr4P@a~N=_&uhz&sCS8 zEYw0c>B5;+$wh^)F~GUOfWZ%ObkKIU*?y2nf@ZOH)UsA}TrJYB>L9F_wo|&Ak0TQl zXiT~ro34~DRfQR1)V3IX$1v^W=10|Q%O2Gqd$)rk=snJFKh5Joe_x#VW}hL*2&*9? zV2AOW-bX#{f|aE;EMiin8{Ba0QY)|(>?p!hBh0oEw-&NAB|Bf>LJiW#crspV?f#tg z{k-FY&<^e=wL{ISkA5CzHc#d!*U}%@w%hm2l%XwMRhLJYZ}%TmaKFl=N2IK=%v)QM zuSZ|)tV4L#3o5owQF3tf5JOZ>g3<1dPM_)WCbugxT_3b&(UXT%FzhB+V&^1{_&a6Tr3J)X&5JyxUT|Xbye{)%$=g<>ufrOv z0U&@j1?rFA!UGayJunz%$AD04nr8C#Hx%6h%gnH~3ZLr%{%X^Ce^9QI&c2heXoD#%kRFS$zJtD;Nk z4I?q#f$OIg@i3^I*32WR_fZ^@pE8_)wtMIK_g>^uARDE8HwZ zdFYXW-C}IK#X9R`0I$w!i!PM$0?$9U;p4P9_GLo*uleD4JRf3f65JTw_&SqETFRdZ z@}F9f+id3+4)`i(;!^w`-^fsBox6klIFJl`qZ?2t!SWEh%xqpCV1pNJaokge8JtX4 zwEUJ@Hn=J^NVf<`Ppaq9Nv~3{I#~F@>Hs}mjc8R#@0TIvKOH?y`C>~K=Pw7$TkU-? z*IoA~=Z^!zbpw`0ID*>Q}AFSBnQZzC}l zKv=G0{&>GfhCZJLw_{83$>HEx*E{CioqgpK;P&_f-V97GYam;90qBVncX08O&m19~*)&Grx{Jq%S*sF}t#MWX&Xbh#h%6+lxrk zorwy5?;gxqS)XGU-#a!jG4LD`$q0Sr$s2n#*8=Y!uVacC5gF3XJ~%si51fHf=Qs_z zpYJz_s?eLSGpgZ~2FvSuv2|nV@X7iYE|w&;%-&xdY=gHOz|7~Tqq}kRk$OI?*z*3l zI!yRwN1qEOR__BT7bs2JJ5irsjuAt|f!M!Lh#uV|+B7UbxAD#S#6ba^Vz-j({W2fR zZ_d9gg(DXsaB%+p`SbLfL%%XcF6R7kd{fl4`LPk;wAgu$7gC@N&8V{rUEFv3xPCJx zh=juk!Ni?dzBoPjb3}yurO&3Bfw?>J^yF{wAH0!xxzDhP=5)6bkv~5X$|d;cByJ*O zk(dPGP9|tn5Sm@jOhVRGT46^#_G^48{NB#&#)e&3yfHM&GQYoeGQ~44KGI)Cu2{Ny zd~%X43_$t_tWDxdtrImkP#^)Ro=iPZA0T|$mkY6rCdZUV*pO`_cC76yGp|;;zfxK zLfnTG*u5p`>7DGiU>+-hJFQU3AD1o;R1__$~6FyBb7uDhx`6pXs#mo&F5kSn!xhGh>4kWtP0j}$(aWyuQt2{1=L|cULPnD;*3#Vm+<)Ts-RbP~Q6JWwN46@G9E`st9a*fMQWkYmw1$cbxC=eA1pwjq;^LemE$_2~dSN^?o0gXU{wLR;xI*(Ke2l z2!#`Pbx`7&_p@ih^!EELO9qD99O3sY=_~7e;zqn1piOmx=qQmtw6fng9%=ai^b)tn zE`Pr)I80_oJBEEtV;C3LyuQ@$?2pX6-LjTobvX&0L$PK_9paN&GV1L2n@b;5z}ho& z(rmwy6AHK89zEBlHz?sZ&(4IrJmQX7QKyqJ!mi+FY5b;h6@7wd>o=&TQU1na69%jP=V z5cmx7XXT6jKhY&V4I;HL5&(cA^ZyoI`cEWL*3jD2%+kixHcl2gNB~82tyljZjZO)p zRF$ATA*nHRl0+%n1f%>*&8&J)e;@(mn(lQQ8oV*!W~h2ybomTdS&Cv_6>m{FWtcBB zvpX7dZ5Av}5YHx>WX8wo=C9!k9&jCqy(r{zkrF!yDa2B9q`zbA=%y}K!Bs2{C$-R@c5iPXM4I!nU-TCf8=>IJ1cNH|M@L$na z|22{b_V2HfsGx|fXpQQY(-9kt@0xm!c$e{n+h#9GSFY8P$I*_Cj=mXrd^3b-HKn4k z(ySL5zP>_IaT$W0xd)M7_)0|FG zCC|Mq4K1gnD$zyx>;Za%I?@`f(z@sFSe*U$jV zxCp4U5~ux2>pjQ`Ar&VZn~-J6B>X{11&J$?M`LO5#8!GdJGM?Dv?8C9sG0>$R*jlw z2z9FB3B+I_oOrDPXIuEHE!v{Svt_+s3>{C~0H(w}uQ=b!h$Iv5=wCqbeLV~a{G>Jp z*E?*dQE-ca4qV=3f3m|4J;+s}ee|-^zffYQUic}i>quDQp2gyb>nQrCms49aSQj(6 zy(LqoUQNB+#>%T1_LlOv2~^fK80pbXMGxR~1cT2b4_`^Ri|~(C?;mt1jM;VebZXSo zcIgrg66u%k@26C{Mh%*DcIxPm^+a3`I6ZPt$a97wQbR6M4?>pc5begkxa8%ePz~g( zoWw0>%OFfQYrn-sY%9LnRNf5!ys732oK#2R9`#Y)W7&Owv3n3aLOfGRiN82Zu@$db zockVZW+0eTnLlK(jm6&#a^O$bC>c02<;d@!J||Gts~0Jv4%>V@mi=s1T7w@4KiEg( zz>*2=X;1Y6sJ8;Qs2NCPS5s8p(^BUHefCGA%CD@I-ju?B_H)C2dl!lZT*kHkRHxo} zm8DY{PIAwb7=8CNgd?6)n{I#7@+m~&HvCQ?V3%v0?&oGU9&is-9!y&D%XPI#<^{ zl9*(i8sl}hB7|Eu9}u;b!R*WkTMTtpVdJr3w$Mnt+l3qGKXpdrlHp z#ES!fWd>gIro1m874R%2cBIR8=@#AP>4T89+ggSZCt(?q^EaJHT<_(KBxexU!OjTmumK5s8U@mUbql z9&{Eiwl=vMw)RJCNI$ju10Mkdg2WXQt>HtXhzKUxGdI_4g6yJo-(r%@Be0~EM5bfE zKY4_dqH#@fS|AZN_okE>oUzc)KGCp-9U{7si#bNP)HdK+2`!gomVS{k!d)>|51 zD^n}))$_5av9Z@>sLW`+xpUPX^^~~0#-bzK#8;m7==c6+?ZOkMd8)Y@Idi>gS@c?3 zw@HH;n3o}3`IudbgDOHAn|7tDL|s)N*;i)yCcF1`Luj4GXx3}p3rRc6MiWQTyMMEU z7pQj*CgA>^FST*IjqaW2)_=xomSMSdB4_8rlR^B&AD5w{PAkT+W}J2H?s`(F)hO(y z->VO*G}+|u!&a-3X^47G%T8wMN!5EeGEMc*D0^nyR^`kw2i{g6vNcZ;!(f5uEdaRY zx~@;}+85TpX9(yhx=DG0dS!@l0w#j$|jea$iRqwFrE$EUnHg?gjSJ z8a2hhv+Vey-vRj1-DpLIq&hSr;4(5-v@%IPaI-w8WNl$Pq&+Sei@?08?Qe}+(P${f z;0$SI`5sW?o$W*>gb*qv5f-T_Mgd}JNe(!s%{gGr#Ne0E1EowLxCB1XK#C;3D$yI`u zTr^D68k!Z|gX(7B5^7z(ll2zC#WM35to2~{=;Cg}Y7`P?r?y(Q6H7ECmAu~AVeYB%p}>k90y zvR-J_{?po<{GedXUYmFIkSH4GqY5KdMr3ge5L{v+0pDR0rwNy8-3v)5=Kx&eo zbkt*k;1jj;!U=>&qZTn5am3g!CnzXLssPvP zfMw&CjM#nder^S05wAL^iMU!|QSm0l0LT>JR;tG?^{DiQ^5$`0CCw(V+Tz`W){%(z zQA@3<5<^|OHmYmvN|K%0`}*Uk*`BnW?Y=8yP;Volrcz(G4~yo1veO(e0uMi7mb_1k zdmXaod##c;HC;2Se1Rhv6tsinR%q}5X4!)TMMGL%fuLe#Oj;ksaUo*J8YO-wzt`N| z4t~zhzwHNoM|Kwsju}e;f54K_>u<21lTCl+FHV0T=Tij#hSLwPCmwtwNHNx6ASTbc z4TNFcOs~eb32rKrkDYS1`_WU9O};?*AO=48~K&%WEQ#&zf!j#TG6xWcx zez;*@I+Z|SlGB!aHQBVK012nAGl68qCSC8&jF3sT<>lwT;*fW`;ouXG={w`uO+wZV zsaAIXXgUZkwht7&jlEouggmK82`gSoiz&4TXSB1pYpX^5H)+*O6NjA(jy=jC*aX`T zT#oGPlMs0X8@jNYIx=Q!w--nH&v?5}JYo=BA5`(mBxNB9##D@$-^{b)cE=+TT=^^1 zwy?bK*}51T9$WQ?gz}J4WSmwJ==@AAxy~VII<1TRbFe)3Sq2-)vRUyqQJF69LobG9 zYPDb23bQ@C^HP}?#Vbh?b#eG?sL#nzyq!1AxOy$Q^TttRaoW^hNn&HK!?{9IN7l`O zMcrm^qiPKo?XmvFcyZe?Y-TJc>U?^g&+{liuD}W)&^JrI5Lae{m&(2E>AucOKMdV9oC62?!ONG za;Ewa`V4e-{5**0e}^7DV{6D@U*VR)R&k{zka#J1=B6M#^exB>sYxV7aach7>d*Ks zSj#K>I&ZhRP(IqnJdC7kq>IXD88xdS(T>|-u;*>D)9_f7Y+cnM!Az`VJ3%5{F!|th z^Q}$MyYGM#s+@(nzHB-DUfv~~S50-1$YJGN!Q+I>8CTU^yi)bLE`iYjYU}~$xpyzF z{|=ECe!}?UG(|uhJ1!d@rLZH`mvzK=`wC^V95Mn5SV<=pE`!jT%n6}wM(}KMLlKv>jLzCQ7fhrfJm?N>xOX8h?)@94I*okR` z01QUkXjgK-3V-g_$Fk}TH?m}86z3fzTl1yJSe60D=Fd*A$=+k2GU9SL!mTabyYet} zeCbLAgpVe6`xu&tXZ-m_@mijsbtK{a^qGHc;ZlZ*n%_v;C1d^Y@Af=^qeu?ZKT!G=KK=##k9P=+sbbjv z*U?h&uMO@0Yz&b8#~4@{x*0P4#~08UJ3FVQ?b&ZKAdKa2^$jA~TR=3IL*{7_Sd&XB zMz)%hcaWfss&AlEWWV&?CZR0YrJQ_)9L~M^Y{Tb=`##IwKAm;F85V+BMWIpGnI&MG zj~76HA3Q(T@A(0yKJ>!ptHi|xEz&7Vkb0n=8wgqw*(XI2Q2andDICCcvt$0!37RHc zPBtp^Xz4DqrLV9VB7ar1X;gZBTg_os?b-IT39^(^|7Fl zt$_>tZpYN#?d;^r#9_4_9AuxL1rbir9aWQecHLFF7K*`kxb>xIS)+Ud&3@VJRTNvW zKoO0-XAPf56+Z?JgM@aiFKgckDt4Fi;rzfX+_Ul)nPrB@@qg5pW|t&z%l-Lj!?~4A z{v5!QQC!p@wP@0EjJ6Qu4(ty;?RGhX2LbY_42CIhPPxm`g49z_2ss-i#*`mbo!4cw z)>b4C2;^t3MxwqmvlHFO>O*L!aX}Z+auYDo*@3 zr(I?bC-|xsr2o_6UF&zPPI?8ps?G!FO32Xn zU{)?kA`sM^7r8^a{X}*>%MYlk$H25|sw}$Wd58n?rKvtgVA=G%%c5M&?C)TCv5=Xc z^k=j*F(xiUK0!rk2-=JDWfSyq4*00CBuS^Yfgj@h)`AJqu7iT4=|X&CKdADNtki9VRq*vNlFO;QnH>hiBQ0@xy9e7*A9S$Lh-1hXIZyKoM_?P-G3**F0ZG@+xd4b z|CeBQ@Av75sAFT@R_>P~^B}*bQOTydrtGgjc8@o&)YM?*pxkw#67d0l51!_;!CCWD zsswu@+hniZmDLA5@%*^!y{3&-ix=-lGv!HT(b+Q%s~L$^Y9Ah^_ju|Ch3SQBm2EBB zD>mty?N!6hBvE!y3{oqN^L;)d=6$i=Y9n8SswQ-_=&h-um1CQ#HD`~lO-E|NzOLqx zKBJ$%`{#`jky|BOC(ZB)%hnwTWl~pqV zmLsRwHeqwq9n0~w(!`Sk<{>n3d-&^>Ck%RQry5$_Q{ErF{(VrBZaRN$s^E*$w+<1d0%C z>YpjIo(Xs$FR+Oii4s|QOh`>?%h~~y^$yGZRiS=tbatz*H|9U4i+_!Lna9Kd zy%r&%5=TKfI8fC1AXL{(ZOMp~=M7_N`~6C-sw4xn1VcL2Dsm$>Y}_1~!JjRXKef=n zxOVb3Mi(D*IuNQlw+G`ED=8@h@GX(NJ5#_uCs|ZeQ$;Hed+bh0(5S!YrTWKVpIQ|S zrtJ)1iuwFrR-d5O=({??cOjYE>ns!EV2t6+B=+Wp}sEPb4XTe#ziR zG$rc8_3Ytp#T;Y5a^>YrjS zriHaM!1H8FX;7EOkmij1MQWCQio7$)c-T^Q8L?@*8OX8+1%Qxt; zxV#t|x^l=^XuE@4bgjwZdZ`Y@?%8LzJM|L86YzO!&n3O}sRw`0A3w#&izZp-Nw~T3 zL;UqitUt^uN}}vBn6k>M%AG_^L%}8u!fT8a56R~A9Tloa!G}7XD0uthGk7s^Zku|E zQXz1aY7ukDjvz9QS44p*fMAzIgKh3-w96tLjIyWkN(Y(rVD0dhS9mvWn!_|V#mkxN zm9Q?CIUBD(XiY1A<(;Zt^P9MkPp}VWO~f2HRQITpa&<2eF{M?7>J%$!tviB~RaQB< zDb$r$R=6*r)}fQFIkp*I6twN^xTf*706O+vU`WZ#kxy_ib}E!1Rq9pRAgh_^iXAr^;{`(mkAxqplhx8M%Knal(bc`yeu7P0PW; zXTW8C4+1h)rYw+trJK;4Z|(rDrmk9SF|sK&`oz98Ui6&ORLH&yk^oH#nNXEx)F*f- zcwgFCVB>X=noCfT&7__S6W>9~ykKre0S9e^`E-U-MUAdJTU4T?-od%knC$7cPWF_; z{)MD2ViJX3UazxSQt+I8{>XKG@4nZtuS=eqYWqh|8kpURgqcV;h5f3^WBdYA@#VKa zPQ&9d_xvWlRCVo8&yTF^a55z|rEa{mUIwkw2BrX}gN1vvH_ULO>5R~C{hDx~i2}PP z@*&Ve{JjAGrFWf(>n|B;YR;p#pdY_!wq-I8VS1=*N(hDL8_6OhJeyyT1=cQ-kMv6> zuv`HL+4Meh&V4436~VH|bXX~Jp}Ey*kQ^Orp&*l0O?|H7aUUc)R6wRj=Ki!4*<9`m zPss8yhSkb31R)8*8H&#S0W)OqQYB3U9WsG>eq>)*(qQBRL8~Aikqy|tJHA1VJwl)4 zqcqsKwg6RaiU+*tThU+5TlQVVIWBl{LJ{b?gdVc%Zk@ajuIZ_1547rH{^qYU3%Q$u zzG4w*K=F*3Vw!XB2cbjZL=_H5S&wDK++eP3+==XZu!nv}h#;s5if*LGs^<+pUNb6p zWL}9gl#Og*LprE>tirCmHTt@v=pqMN2Am2IJUzk5L;v1G6+_gZnxwe{6>etQWsylS zcZ|HnTQW%-3MUF1d_JTE}Kq z$;cI=59X2mU*nID#OKa?(jcr*kFKg?lPW14+Him8+pV&qjqEOpZ!Z{X-!WdZoJl4Oq z+$4W=<+j?{lC~&!k*J*M1Fn<;gX}{`Jj$nXa8nr3SO;tCW=@n&!mtk@{bywDZmo?# ze!*h=J4OC4*4{Blv|!oyY}>YN+qSXWwr$(CZQHiJ+qT`kTeHtOZ)V;-Z|;fvVLq%_ zU#cQ1Vr5nSGuJP(c(c6@UIenXijG>%`;KoT9XC)s*>w&yIwSCkO>}|K-qdn%$^#@q zN+5$8<7G|ivM;o=!q?8cE^b-5qFJ8aGRnj_B07csv@TtXh(Hw{5f=JP5^YSYmgYyB zlM!S;O%n$kL8GxZl0ZRv$F=*PDMwn4iCT%?vg2WL4;NJUBXSpOUUbd08Pp{e25?5jbvuTx9m7n)E6g}gV5I}CQ`EnjL5#Q-l zvqBn4%|9M!t#R=bOQy4dHGhEw%XrcxnPZ{+ZIohExrf|n1{ERR77OV9O9oL1HgQI- zAzwx2UB{8wIJib`y-5l=6}7l|Twjc_v~c;#yX3$g;#jn!K-<#8bY!Ab zV3F8j9~Q0`SL5~%rNHV+BA(r;Cm~9Yd-+(`w(ELFj=@*-A4_;;Te#32uX8K2Eu{^C z->7aJQ%I?SpAT;d#wx7He!k9z&ZQmL6e&@@RgpOv6|ITQK2+=4iL{~Eo^#Vg9jrEa zlTm;-sy&m~%^ZqDld^5Ai?k79)K)Nv~E8A1DYrk+Fdi6xeN29D4}&Vt5(jUh_~y~lM?Ft z<0gCYzUGjo_~X!ir0nU>OUTN-y+yt2Awrvw7$59p1{njlC9VZXc~rS)lWXc=!2DP; zEo1o3Uk-0`c0$c4w9y9#FUiNoBUJGsGHq|}ysol`k?CGk7YnenhLQQ?d)WOxLy$w; zZ#}}!6Q#KQ_{Nkj)$6o^Me^v#uk+NAo#Cv<_R?bE33MK;_tq21Fn!=O{qZ9y&0Keb z{xE_#Le&>mD+u5^@=WrCR9)g?e2?IQaMJiT^5lcUF-u3+WDxdJyxyX=^Q>MP!ViWAl z;p=zEro&1DAnfE-A-3N=`*p4RP1EFpFQO;@ddU{^}6Zlra()tY8^PHmr4FD^XVa6l9 z`M@Z^v(SDEI|u&K#m9-OJz6u2lxO9+9Ey!E{{TG(?qpjp^7c@ih|d|(<_gY)0W4Y$ zd#)>Tw`fsnIb9lswfnGOAK0D|ZaxdL{q7HpsZ;C>chS90tcbPDm3{?iH#`}(lCV3K zy?7sh1srGuOFC)*D+6|rygzKFqsq8pt&00>HdN_*M36kb{c1nx-y2l7FxA!&STUJ| z@WiEblelLOj_uh>;N3*WDeg?>&;@V4?9pi<-U_Ug=iD&V7`7%f;~m*O^c|9dj|zLx0&NqLuLCMQgF)B}urF z){pQ|Oi-oTa}#bkzd%Fh5(KWg_v?_Gaklw=xUJb0gm@s_YRH4;{I2dw2m0Qw>jRbm zgU`_pj}u3>eKt8?PHL32COdGpe(<_%$pnQTKty(?=^fl{ux#KKNi&B{)!wXA^prWw zt*FTpLxHwZnZh*8!3FXBh0Uri9#{L=aXD6tFwn_6sLX35td|DPnJ-e}BkO*SvWR@! zV(M(Hw&V41ln!9FE!C_PtJaGI?b~>eCE+#1LJC4=;*|2+xYhkMrRbknYZ(n z1yB+1xzuz8DiIhR`Svak_4{D{88?ZTpD&&%Igbf;Y6RJbn$5Ww*)Fhv&CO<2+0<|u zoIE4hQp>#aT3t^&@krZTmT6X>P|4Lk2)Ieks7Ns*7i&V`<(b3W8N;&6#4LAk_X2jGMj+7>B)CZTL_W{p{rF^85nh1wxHdf$3HiQHP!LFn2> z>%1e(qTh{&tKh=klROjXHT`DNm*8v%nwWVLx8j9-DeSiABYOHdN#5cwS@aEozXaj6 zO3{&^{;}!mwarLTP>v)}$}K7`R7NXy(Mrfh9u80pX2o($W}UI^vS_>hJ~duf$>swg z=F^mho+?Y3(5V$$r=^*~Lhze;ul;bexN3+rUTuwA7zeFdM@G}fn-%4$v}cXujGNut z+f#J}nE=@y+2GYwqk|kIEeWA0?!5;O-u`8sT(bwsJ?JUZyM~86fko!v?BM;-k+$hTyker)S;ePU`qlth;x?$n)?i#&9L1WmaoLI62Xmlu7(Z06E-n&ZRZ3c`Vmw z_EGlR30eJb1DOGYZaibMQ&MhjI7FcyTdUXvB)urt#{pxBzc-!Z+p1anH!>KY}3+El25;)Lr`*T~={XCn?D|(J)py~2675ilBEbFz>ssyE_NdAwsCoOqYTZb8crp#y((~^sOKAc_-tb6svLN^ePbOvkd zH}c8o97^5RWo8-y_9x+3)5guFUWy)_crVdc`_snQQK>l}8m?D+?bs*+AtfV(RdC>q z@B6f3J$P`i;Y-z^IPO%c!8BG}hrZXpXjnx%coNp?YWp&e_5UHjsG$E4`Y{(ydR*^vaca)XVLMXHxYKD{YW&`6&x4KupHOggf~w8>n4CL&MWvbkMinL%NkUX3Pb#fwq6kETIf^4D zWspvr7UU?&tu&Ev#*0XnCTGV~S_nonAw^ICutZ2nflz?;=89e$f|8#v?SvR4^yTNI z@IYZ9q3AgP30^2Pvw2)LIAD<}(vZCPxJkFwLfx;?LF$4w*pOD)o&K3%Cw9uFztz_q zcaZ9eQc#3u6R1OIFc)a^AasWuC_aTUUSj%&Vviy zH|d9P!o(PfFuU?8^nKDrpyjhFRQ4=8d~CJU+}BMLvUjQH1BbK%?%|sO#zyHiZ)Ar3 z-D%>}(9QGrG}O!+SIOjzgA!%M-w(%(WmU?x;0^%a0Y3rK2b9(%N{oS(GF?Zxu?bS` zk(ad9;X|=-)?PX| zzu70IoLPc?3}A9b;oQ;YyYqa(`WP0vhOaw2A3HRQiGdr2>a=DD=9FUPSnj+|hlH?K zjk|G0^miIOxGWigxEL-qQPcp{-Q3_mczt6s#AFqLm+lbzuc{~W>bF@z()5|B1r~0G zwS^yc?GHa~I-#!oi+!`mX~ZZUe*8q|@~s2+fIFQ)cXk+S&C7(T0ay6u7s`rq6$xdE zGCA47(xvQu(`vL&b;C;>KO;~_J2*~9s}n7&>ZRGK>x3awJ>u6FzjBuIna;|0TnFv# z2^$ce0l&FM^5^RlgKW5dFxnkKNvoo8$giRSGuCjnIN38JsLl@)cVyCAAIStRjaC4Z zLow+yZVtOzF=Y_Vt$1uEVEe7${RE7m*F{0I{2@pM)PT{$6(EIBTnf()8x5JUKlLr} zjrQ;dPtxP7N5O8Jf5ZoYjxIIK+Q)b7ZEP{c%h}c$+kdk=PY+*b^V5CFNe!5PJOG`o zY;=Bhi8XWyhab%82=-hK({>;UN64NNjvS*`15&}zz^)!Nm9u6(`G{tP zMO0?=HvrYWg3A1su{PJx^md~=MWF|$ z4!85xHUw}eN?e=Xx)YBJ=DhmaEQ;VH0qWZiwh|~{9$C?~bfu+@g!f)ls{VF8tgcpb zgtIica*|eRk%>?qsXj2#kL<)#53rP95-c3<_R`tWmB92pFb?3c3l4T zYL`4w__!0Xr2eU$MC2vnN}Sb<<(}33tg{v!fOeNQt|TUTG$L~X+cNPF{v6gg+>45BE(;rGC*Kj5Ak=mX$`H|uZUGU z;HG1vjY(e45eE1{Y2-6CFC4c0^wFqPoP0B z>6=?SrU$&lphk_^({-bvDK~BT8RP95U7gfHTr2?d;(T3CG&Dg z%WU!W(@U5u=XhT2#pfo?s}yj5V_mUcQL9`h~BSqz55UBD?>D&n8|1 zrJ$L*s{-W>m^;OL*Q|ceRkf(g0rsW({Jb~X#f-cvzVZHOzJ0kt_jRShXf6Nk@9~30 znqTK0rComKFrpb{9=Bye^4*^gX1SEmI47%8R}K$kdigmtXNu^pOgFL!_+apJHZywz z);-g6E2dvf*_yZ&IIJn#EOYmvr^gMP=7(o$wwGHB0SZ-zM!)Ge6n)cRy0i1(4j~&? zwF$3&iK}s*VVq#6Bdv2#upQ>E>X32M=EYa@t;DFNvctH^jAwN}?v2Z5GbmBGzwAgKG; zp@jcfy1aGlBC=KUH;W}qNE|npXnAexExcIY+udB+F{G~HWx4+#9PcAqYcRL)lu-wK zqe1aS@^Se7aeCM$6>Q$}Xj--^`4-@IJu>lCIF#+P#T5}?@&qBu+4lxYH?SMxxEn0w zrM6DgzzZsrius17XNBUIo=Fla8|8Pp&^?m_6z3`SM>AVLp-gDwCw=G3_A=`1$JMXyFV z1BN+-MQa$qN9;B##STl3jmK}_AW-<~)ZgJt+Zb)j1wZ)~Bg27bnTG26)6>}vsPASJ zRX9&WRggS#)Q$1D1~%rhMWYm?3tTq%uwB&b?9D5)=}mau^q?Am0=@XE>nD+(Zda zL}fwqcu$4iq-FYt(#yJYCIUN`$J*!!$6H8MOY9U3H`K#x`=$VX14Grj6^{?$^x%Og zn%IqaxU|M}?{WH_r?+mxK#*wZV{D5Q8J{$}tW~BXNS66vgdAUFZaM=qfl`N3q8b4a zfi=nD)lnBQpFOenfbUYePBfK$?A{FY?UL?FYc6*a`k}(`K$NcL-ES7{@_c=@g_X|7 zW2t7Gzev@uCAMfxFr4C%(4R%89bFgIS`8N<_(Rmv-rKA?!|ZAU1IJH%@g8h#4}7!# zLviOGf%A|<0{~>v{wKx#Uw_2^OL6~$3HjR)I5vv`fj6zLzIj7S5RPP%j+1rsc*AH8 z4BOtw+BnO4k>W>pGd(6Lv}U75fh0XG#|M?po|AVQk-cm4#{uX#rxF-x0WIYg|b955Lw!iDr< zPVh% z!&0%X`gh*J^oLPcOPnJ4DCvThGspOxrnHgMnY5V{ajLcM=REN4^~sU-mmcY)KGHDZb2^L!eO3)l@)W~e*^z^H>csC~U~%8Y#v zX<4PlfOJNG$q+jRju-_`KwjHiJiP)Mf4tPJD=UKn3ijD;Uy%3MOc!E~>AE!50Mm2Z znp9a)$n{qk2lUk97q{@o9dh?RFm5AGO+q$UU0B`(^0r4(y!!9*!%+yi&pfPA08uEqKt6uA7aj<$K= zfnxNeeE({P(=lKUn8~5+cfKD)aJ_(@XMFG_!jLj`uK)stXDd za*7H-N|YI*9uXZC0gdk%46B>S~4>g@Lw? z0fADi^TC>5N7=&%2g`;b)zP2B&4I&(2g^h~iJza@hP?Ffe&Xz>TPS(cJnk%_W}jlH#nsRs!oosqSHlT%Ehjr@`V%Gi$^^(9-Bj0ol)u=zGH zgbPvc0tUG=qyu~~9P8hL;Y+&ere@jA0&gO{DoDoBJHStcQKzyA7Rz6Y-#@2oUN^j_ zFFSU-ec6D&#>CJ(rcL5Uyh95?Bi2;3)9i&OWhtYSQdPE;9Ks3;wd`_!->|ypzk2cU zL%3r^D4Z%*^FR8i+s}EU2NOl&>@IDR2k1*&*)bR6Z`K}i-Xn(^S9}Hvu0M6LaHzWR zEa2d{i2OdmP3x7>WNh122q0AEhtZhA4{j~zbo6eu+$0L`FoT}rgwj6UGp?D7oz?}mp?)hcaL0n0bb3VavbwZ41nL;W$+ z^)~OL`Y)R{tYlW0EUo37Xw5E|zm2xWX&1k`1zuB*A0A*#f?4PcBYDJ~BS}R2cg*UW z>el5Yyp!c0P$CyS;g8=Dl!K9pRUnm#Wsob0rx8lS-T;xu^}(8sJhsFFx+T&KgFXo> ze-p7c07vlzNH2?7{+?zkl|+yCsW@Q5`a!tx3{^sE53D+ZN&#^8EIZdyQ=*e4jiTVs z`S>R{m<%b)i~n~YHvX@gga7Zw_?%6*xG^cc!??xU45`f6ND5C{P;KB4${G-&oVT=MQwNhaZOI8}fH>5GV+`c8q0|W|fR4HbdMklN zriY%NwQw_NLn1V}l5rc8p|laxXMUFZ5Gc%OBEmr$d&bgLu1%{YduhW$15<}tUT1p4 zlg{jysh6^&(BHPurYug@7Ogt^m;Oa1WL_=Sf^NtDjHZ@yJEnf^FfHP%_0AltD&kZn zX1Fsl=htJlMjXjWh!{mnKxI?Te!_UB8Sm)s4of(@Ahg53$6Yi|M0R92M?nud>#E(u zrhrScIm#;s8{}SGptGsRUZ7I5jn+5PcRW{F@a8UUGiXX!ZZR@eixZr}KZ^sifyBf2 zPB?lJ;H^|Y>D6LuAWfQ{pm08Msv5(K`!};XufE{}R6AOR6XmesN@{_)7RtU_-$3lb&a<*GO+YcD>a zs;zKG4kPg`5y;XsIv&sU~Qq+XKXTJ0(EHK^lgl8o{EY8j0OczMiob=8#Fy7}Hn1LTAJK50T1 z*```7*4uFpBI*n~p)agQPMB;k)Nh?xmF0k`35P7+$HBD?!sEYW`FBdOADT5LZ)Y{;GelsiI7Hpda> z>j=d`SxhL>;cddL9_SFNEzeF@*sX4_dZyVsKlm}4kfbm5`*n<8@aV93yBFYo!5dDi zwy5gh7exRj$XO$obgIsd$}g!I{U~GCGKvoB2A+~+IUDN>tid*RRniWKWG-M)DhkFH zOR0hiP-|RGft7jLt%e#;I93w7tf3tChOgHt3V0*%O*TXCWDI=r8sM;n2;{Rti)<07 zvh*ceyeRksCQ9{tgx5>HPn@szSn)ePypcS6FuzfN?^wZ4U^7vGQ_*;S1LIcRvDsjR zsOfyY0RvFI6JR}vvUeKC-r$SZ@FveVx(bOni(!hvLWNm+GJp5zBLysE|8m6cA#HT*CuFw^Z=iBy>&UMwOTl5f6 za`fc^Ari!Mk54q$7pXCmGWrFkxN!JWdQhxO({&=LRdorq zw~}nq&8F%$Np{4+d8kM7ioISIV}sb$h8Zz zbtM2-v#BQ9z!4JqaIY`3G~cv}Tm0A-DDGhwyP~KD!Ok)BE0&+Wv{%+%|x? z)?9pe#aM0nd6~>%28oi>VTewlrKGx6lWkYkZIVQ`gXkl&^=)S~Zv2ui)O=ztyUr{$ zuHc9ORij3E4ChE3bL@k~{J zL!Io$Fr4I(4S8mtvu5-k;7Cf6XZ}gTNT^yUNsCWF z=DT$hbDVjN*Uh$kx)^>q7u>Yo}SW%ZMDtp zqf<#E`KkxSlAX28wO(W{OSv&otVp788*@|(^GLI5K;Md)m8x!pY*q)NwwVUjj$v{h zBv6qh60LAK68h)eUEn+w$DA(%Q)#uV$H@RB^Lk>%-uBxxu`F`c2;J<3RkVYMu8e-{ zX}P4|-Y$AEB4*}}*JM)?We+eD&|3x+!k)FC1rLfQcPvrt!UucvF3ug$)L|xr|KN%& zi#-ogfWX}hrbLIfhIHyF_o1)^GZZ@rk@80KGBMk+VS4FS_6dLHEsT@0Rp(My2JAz6 zs$p}4=dtT`%Sq1bW=?N64luc)mM|^@hGp7xJS)jv zX9O0Ky`+P5rke$t3Qcv(;1~1NtL@bjmbdao&kwaka)vA4+PJE&*cySisBJi z?*bnVMCkAhned;8!;W5TeiI2aX?o1$n0)ChWtTPdnSEdJV4IzLbCbo`j>lN2==47Z z^H=&9T!kl-U)rk9VX@^La!I#QD}4NW$)gXr^x@imb%Y1H^Qwvpipvh@Q(Vq67wuuF zxK#|8rpJg&hu^vDFjoajRULzung$rbTsKqotQL3@%A-(2eR`ITd0t@&*cs#-43jYW z^Xxu)!Pt0lM2L*WV=0|2?AO=0Q3dYb%9aSOIu|}H(pa`)rWL9et;v~`np{WDVbxCv47>U`{>Ja$~njRewnA|2YiPH zh2?oCi2c_Ic{0`=WQHP~tT*)!8FHuE>kN5p?d_9gS)jJDoV~@znB>;jXQ-lPsCgF` zVB=S{*BHu<=zwN!(Q7TX#w1qk9X#B~Nm{3cm`GETT9dofs8C56(5(cPqBNVt1X5;4 zlA_Y&3Ijdv?=WX&BLuOphu$;~Lu(2XIL_UJUe81qr%Y6%*9sPiCIL>i$ePlaA9 z%u6I$by}i_Xh@i}x|+;7ScT-^4&ikijON`~M;;h$)+lo)z3b3>*W(s~uKV@_RUy<~2MgwiPoBDU*N zv9M{<&a_K2CK)mMQ7O$pofl7HR+5}ek|TMkc~Q1D+5`oLYvD)0;pv>Is!<^Rk%~_d zU_)qwrKCjxrIohgG?L!pEgUn$9&@p=Br+vw4Hiwdnb0u1W05g<%?0LwHP?oMLp|-g z+azMF+7I_D{QPW)dN?CiR(s{15BT+YWLUtWDx8T9iK9#I7>=F7ZVPouT@c}`2D4d@|XyG9j15Yz^C zwZx;U`uzGE*1XTFa9%^f@@s@YJc_f zyeGvba3aK2sw0v3B;D zAi4>Bg{XE^7;7mY$|Wf2%}Z{e8l@c+weJ>p2AjaVBZ{3zb=a4^`8OkHZaxyn4^v=4| z;}YMIYTlz3zGZsvB1G(VPFF#Q{D|S-e)V9@y2ytanX!9Av5JV}TJ!DRmT$f;UxT+v zV+@$zW+MSc_-t4)N!$-qKE>wqSQ+Xks+nzNHl-KZC7a#`{b-&inmB+5`291(wXqy^Y%J_~>*J}A?)l8*6FeO+#>ZR3iQ%h^}qNY_%>-xh%%gP2d zU@PPCMB79FgYy5CRgk=H`^Ztr9L4N&)KFAVQrM~vQ^Zsku~EI` zy~3Y=YSikjgQX7JeJDuJoe`_=X-~GmU0Uuwd=V!t0(mj}sW6NH zRSyU2D!dJUx;39>5c|Vkk~|pWQKwegSLoK$R(AFA@}oUN(Y(T~MrKF`ITz zB#6wT0dfvgWfUua0!E?3`WIo0e5RB|>9`2$E~qT4c_zA+d8Z(AclaVFSdNuKi{L4u z0K->;1Vw8(D?(h@LGV>eg8<16N{kI8E0QDewH8~5A$1lSNRUeb$XrsMK1kpI>E@ZZiI~}%l+YoH*T=H}HjvPw*+7dVb)|uABNM6~z4w`2n6AAL9>hK+ML&;m zKV?Za6)f6n8cMJ?q}#u0*dX8(-WD?|6q9M{PX}h-JCKhBH;Us9iEGxqdj+piU);cXw7a;91s5usWY+Ge z!?DoFQ%|`}bzwm7N?Hi5sRjA`cgY7CU`U+$USQZ}`qlWy=59oq*fDn@SP^G~FZ$By zdQ7p05obiuBuC_hQ$nBiAeuw!p;$J?g80Ufsq7lazfny4W?IFofcDdO;$Z1er0Ok> zi$_E&*$=^xxlK}nkjdcI$!1D9Kd;1_y}GR7pFxUJUhK`C>cGhz zK+oHCmC~+PLa#f>W=cHBS`E4)aN8G)-<$pOaFfs$iIUKkkmNM}P$v}$XyddcI!Ps^ zLfL6-fYS^cYML&B9w>a|TfDG<1UMzj4G&nqckZ|XoA&Kq5 z2x^YZ|BWd|oD{fht`wdrV@VeKoh93ut>#qfxq&V@d-SYDVW^b6A+sTcGdt${#!Ol^ z3~LB&Sw=0hK{jZIUKFtimsDF^WxOVz{v=t+dTvSB5$fPvQ+~pwc+97G@!WU-MmC^+ zZ@#$N97F>{-tKL1h=*_{)2Rs86=BO}LGCkItW~^DI#c7ECD}H02B$e3ClB_*DEs#5 zY}&jO^1_U>B`-g<{#H?~JB;82(*#coLlQ_^^@qebgMle%NU5&!vs=%fHgGDrH=tf` z5A*2$SVEyS;D^M+**~{xuxJ*&9+nUAQKEK@#!4=v7w;mIzUY>U0P1Bh`}XECpRT0aw6c_^#1(ix(xY4 z6fs5?>#5SyrqqcdKx70Np!O$k9I-7AKxPKr49B2s6EjD z2=}8}kIga5dZ{6 zwP_^YEtbI%;oHPCb@?zz{+Y{HsTLA5o{`!rt@>As<4oXj8tt=_nv-j2)+uY*&vIeO zIFysQjcLPgAF*WEgG@~caIX{;weO_}#wn)Dfo6SPjD%6=o39pW%np^)w1dn7GSi8n zBG&yAG`!9s2kAB`JP3J?#PT$WL92sR)VF6ljQw^O%9kDuWNf8}(z#-DWu>U9n&^@2ofX>52|?9;NCu#y<)>U+NN zy0tdPE(DJ)CgC@vxEpaoyg`cD334Ymz7VGy%xsl8VRpJf!0JO1uJFHTBg5s170vV7 zJtxkB((Y(u_yuz~HG3-77dfj0&495rUh@KTQkLl--9#up?A^9Hc_6~4ey!yLG zo)gO{-8YS!oGm>S2LxhHMSZ|12;94SeUyET=-QfT{H2g4u02Y(Mk=buu@|BB9A19o zmgqzJszT@ya7JB&JU+2s7$Y(Ob&fyE$@^yIqgLq=YYv1v{pjwc0JDb-Fk3!2BVb&y zgr^vFS95o~JSRkxoq}V!xsObL;P{+|AICYP6GJ~Cw<&x=5qIF!$R3YxMCgLn2TOaE zOL_b67a7Ir6s0w_EF>$*)X7L|9PmbmLme+hi?PsG+HEe&86&e<@ley90nqY4sYvZnL;zBfX4-eJK2C_5cP#?O~0je|LkRL*C2h|8_l8aL z0HHH*PY)G8IR_QSRLn;d!>gm1_QZL31+4x{vQvGZJd%If9?;X>3x43=NqLASRADD^ z-)Z-13_9g8Ie#Mv@)!_Oaoy?r))L$_A@ss+W#o~EYtf3BfY(wpMQZD$I|8Vt zPMyM|2F{=jEW=sj2*lHa_(th#f}gB|)UN6#8VE5h5M}HHFb2h=KtvRc`=BTf+dp@+ zFvA_-fU`{M7~>3gz@T(+ka3(kH*)5poa6<@ZMGfl=3`7M zx{~cz6A9d(e8|yRDa2G#7;RRZa`?mAg6WH)yi!t5 zeVe8@F?V4*!5P*@1vx1Gcq}6K7MZ`C>nj}6Ic^5n#Y8*vq>shgIUD%Kl#M%~90u1Z zA|XZcZ2uyV;2idZPyB%X8gwMwD?;a7SbuaUZ&kq)ZEyVHyi_`+X`R(@3_YbuG1Yje zhyFF28;0wpe}o3=40@*L`6!S!JYPE$_Z z%1bknP=lP~A<0Stp5M^c1`Xcw@|~&SJsAy8oDF*da+>iDfp~X_A|=%GSJ5b}J1pLQ z9dg{p?K@a*lH1%X%4c;tbeH`CO2qu(6SKLGuuoV+cR=1Fs!qAfjpUMIFON?%ve6k@ z@&euJgiWR!`EokWNB7v97ti6N$_39Dn#N+rtSqH|?dGjNQ z?b_xk=T%#u$RcE36EyXyt6}M!0c`0*qUxNXOH5OE*(y&+r}&=Z)jec$s!`z+{-qFa z5|d^-U(`~$ZFQZ)9}W_{5r(`cq1C?^_RXD_(5Og}NxRx;ANC@29_^ zvQ_o8$1^7$Ke5mqe^Lp6BNPvr7ZLv!o6{%v0d8AjZ-EjUP`$6wWTdY*^zD!INI-ogR-2B~V5Dy{^c{@!2tj>h zR-3k}PG|qcXxC`yI}`a1OMT*2oz9;fVAz}3IKSN*!uFy(&85Ydc$G7vN9nipo~5C? ze<uK-KERwz@K459C5I{-{6D!DRxwcAGL3&ZB zK?Bt=7Ap?+3Itj{1*t%6R~~?uGSHS8w7mmAprsAqu(jDn#;VK*cAjxEb5=G<*3t_H z4JX~U(`3BTUv!+y}Fl=A5?~y zq>ADp66u}S1ajIvG<^?F{L`v8@AYDF_CgA32dhrQ6D5}^5qr+;PIdmAsSA7*{fKv&zCgPpBxaVN5#aX`-Yz@Ra zQ*h7OT#LEojwSSDITvMHiMN;L5*9hp=*aKbheq{=W{dMkuaSOkWquNwZ9WmqEHS1t zZjPaUkV?zxotFFXo0fsotMCSyo*~4)xv2EM7ZQHhO%p^B^uXE42|Ni&d@a)d$UK4#mFnu%y%Co!q^IO=?frbFtWfP98a!)GTSug;sN1EgVrlieSrgQR z27loU5p-U2g?qj@W^=?y$7(~=>b*;NjyF|`>lK-L3h0+ZPvh{|s{0K$2Wo*{q{NA% zP=UsQ*Hh?6VPxb0K14E1jgz9Qej@SlFcWGvT58+K$-bdw^#auz)7~-Tt}v$nbGWO!D{s@U^xN>TV;t;{Y?Q`zZQRx{m=lb2MT|4} zt_FCu9or3PFf#nzAHygrM|LS}+XHjrC|^4PiLd^O4nvIM-(Wiom34O*T7s6+-jTG2 z=Wovo+8hz=j$-2+5!A4Un;{p%*}Awmgv_suO@N7FvHhLTba}7}r_GPW*+zKxRKK@p z^1t}nr*1bw3@Kxd_1jm%C|yaQUhnn77v~XV3N??=XCW$*KK~lgIuSj#-+l`i5x#kt z|3g^)*ZDim-@%BAZq|2a`ra1#`cb8#twghiJ2)O9^ z(KN0sOA9G#_%xvkQ8d)n3~Kpe#~q!26cYCc(kF8BA>-PcbKB+U&!3Yk7XX!AcYwwfY(B~+kQyK> zK+8cE$V)&J<58T9I_?kz=Nn?g0U5`;LP-Hu^cB>BaWSzI$Q+dR*E=X(cXk_i-6x3^ zbUt>{DyhNuyY7<#ha7&@X| zGC{j|eJpE6e}wW=V+760f+++UjH0bn%&X3#OM=99*soi+pQ=o*Q;_l zVJu89T0M^YyCpa8WqUPB6`6?uQDJ8V>>O{qFkj$J&D-7V znVte5(Q)=saI!3=j8u4psj}%qCH%|gOQTz|{CO0Zxs9B4x^_0OprI37#4WK*;q0=o>8m*&=jCKY=0_Th72RVyPW^Ht4kFQJKsdC6>Q=hL zRpx^OA3!TW`|lsjP<|DUM=rVd9nDYuqSdg2zOVqo(8+0BAzYeyBhc}iMy|}=6!j=^ z#_n2MM;O9i@@CFOx=Eo#B-&L52^G?XO4#6! z(MJhqFQD^`mJ@6t$XNc_?@dn=&Hb79AV$C?eEJ!nK(2}+Xrn=?g4BsIjJwgR;~D<(0ttS@ z3AZPU-KWbI@qRK)_$vZ`R0u{+%D)0eup(~DeEig^0f^*0Xz+<(@@XG~6CfR@DA+G( z|AI`0?prE_AyZ$^);~2bxdSv+JI*#;wF~r)fWA81GSHP%eJ8D@?_!tu5n^$H{xdGMF$*5nZ1nk_9(!KEO zNkUx$Y|Gav;>+t9GIfGeo!I+cwn6kCByS-=pffFpC;9**+Hbn92o_7K zMq=WpgTxUVVuTY7z#l1$VJBIiY9M{Zcn`*g%>H`0h-S#rM8ourX&Pnce$Ke(n&y6f zn%>6i2Bb0|hr)EApCBy%S@;vrKgf?RTIi^jP8jtT<25dgGWZE0=je3EtX?fp^1 zpMUFZf!?gqWWA`~{MLH;f?;9_o~Pl}JD5{@p8U2-v#jm1zf3;`CwV=Hov>}pU$1e9 z!=IsEyRut*9`k4mR44@7ZX7vb_1juCx?^pNaI*g~$%>_;UweLauN|$DjA!MDr+?h? z!w2s+Zt&7X+$A$=X)-w&dt;q!CITT_}ym+Ja8(1q*69x+rf588P zTO+P#%%t$mt%>^{N&kJIe%}D}{}o((@8N&!%Kr(}|B6wi^?z__zA}yCwdbtxH{1)U zsT=Y6@~s*v3a!HQ6!CxND$Qsl)xhSSl8~fFO}Tp9d3R5)pl4Ija+N6d)G|gzF**;S zXaBLmzI9&b+>R@A{rUSAThbQ#>J!fLFrRa6DVc1|1Y&N-?Sgf9wH9 z=rQq)-z(t6n-lbO+o2`{%^=PrEX@%9CS}rEy73DVFO@cPm9L^5jiF>X2>auqe$-ZG zpb?mBAi{_Fo7xoWZ&TOP#?2U*=11p<-&ZC1)y?L!%v%94rJqTrhza8PSsqeq^$C z3Arw&gU4b&1u}wzTNzg1V`7Tz%wtsul4hJYMkKkUQzr&0Y3?ARU&SQb{R#yg4@{lw z^hwBgZ!&k4*uz3%&k6zrTrDAVTA?i0%jGN7lp>qvZ{|iM{R1B_{+0u`ml-G6R!tN< z>Vz%C+4tkwMnx3r(o%XDdyb)B9_RkovK0xz21 z!YJ}=X+FHEqmXgX{mC+7Z$4Mq8SbhZwWZOTU`8jOEpjC50vVp-a9XLZLX4#pibJbq z)X&uMO}Rb&RStzE6D zhLOOm8Ivr_qA1RVEs8IO?~X{66ECL|VFjF)>u%x|!kq{@BT;Cl&HtTCV+^5@?GkGF zV;41~M$M1(LfemZqY;F7gL;vrjCW2jNAZon@WODyZef?GK9e7L$^d=p7BgZFO(Z#; zQ;6vR2Aib@_#zPUexlsqe=Cvw5#=Iwch11ec)w66zqWV^$YsY-X2)h{$Ghs%T}eKDpd!6sCErBOf5DZM$-blWKPl-}vkGC} z!kk+k+%tUtmEhcku>(z%vgB`yV~cL^h=DgQoY z;{Q#`l+rgaw*0@0_rN%Li*Hi&@RvucQM{|ww1!ohMC6kcG9JucJ^?Iqpk5r5YS|3< zYJ0_K;d*Y+1dbf85uxps8^2Sgm6x$Nz z!D7V5PRWnjQM=@QT*38wULkchoUm5bbdtRftrI14*@D#N$+&r6h=Myf-YH^#rwvmw zUU+2`(N*XmfpV__y=!8_H7!h`T5M_=;8J+u9J0CtQvxo0+p1H8pt5W#N3v(a`tCo$ zU#=umAo%WfC2>q)q=Ko^@${np`(6H4u5c739Ihcn{x}U7XC#IBLR_a2NWT$fo(W5b zxGRw_b0SIlk8}?mOERXE*<~?$b{_WC&bW!^l!{=kP;Y;xjM5pdw4n9YIB|d0X+9N_ zXF@j8{kc?mcfGkTFkRTXI(PY)9pBOn8v2sG7mChTEAd2Q$}n)5xqh?uH_<6#?b%2> zO}`b}_7QXrRq_FH<2&bEd7VB}RnwhNeF0nNc>#G>rjaBHZ~X%k&Ss$|ipY#58eb7; zOpx%MKPekHYPM}#Fwz38Tg2(1%Ugt(iY)cQKb6Dm@;4Yd`cX2*5j<~?ygUO8`rNGhBl-UzHS_Dv3@m*FFE+aXMcAFoQ=#R@VcU!@P;ruo&Rfkrbo@@<4 zFq9_O-=!F?oy{*dVx9*{=HD}{ZtM1S1i2FkRjH90;rydl%M+?jZ<<~XUMdGEoP@o4 z2Y0MK^Fw^!X(RlZ9{hQXMhaOGq)W*;O3U(4AeY)g>j(OloI;4BQyF3L=hn=z2&jEmq#($hC1*hXU}!cU#a6{ zI~IP84%~RQarb&AR9`%U4%s`!n@AS}CYG7u!~D!f;fX~=FGR+apV&t`0VUHQq)lQ0 zdykmGEQm&--@yL?IR(>4`;)u(2Lxz)Ey_V3dcgEgT^Webp%_%i@t70fgubCYa)N9c zU-Z!+TX>43k*sQGNvI-^F5B^9|S|h65U;dcQ4(fydq# ze4XM9@_(d0x^H*gSsA8drY>L6% zF1~`0R2~x6EN2)9G9YZdZ>Rkv6&Oc)riL@0h-?`~CI2ehmP(F9YC#P#p;0-xmSFSf)qS zlQf^{DwtwNF9qSClL8Gzf}#bJgKJ0MMdTjut%Y`(2%x0(xIYQ7)z_$TG5838&qUv` zH=N*CfL98zX2%SGGjHInagl=7-+)mB`b)$&S5KrD7BVJhNJ_Ces7@m{2OY(T*mZh) z^xV?27;?yzf!&IuS{-!rY!S-YW?^b_sF9re2hxvsA~FpglcEQ9$n-tNHR?*%^3>C< z6ti=)%{}+ZB<6;`5EjXnq%s`Hb%qHh)`bi@seT^v-uYE#{%OHhlxCJ8SVcVYDVftH zH!F(q)VG2{izZwghfSOlt$y9*w}8{KsX&AXq6g=yqWW7mU50c6gWeBi5QGH!>uvN3`UH6dq*8b?C2W5A6gqw5NKeXYI&{#3o;;?j?&eI@nrS)e zN0j>GV=1s`k(Lt8NfKS}gP=`B7!}pIQBj=o^<)Nfde|ZvDWZ1SLMvc+s*Ngd z#8$ezM{yErEcX2p5X#uFkXAY3>XFCgEAlR)qqM^#Gk6?A)o~(+^B|96lBUm1Bm}0{ z0&ATc-c=4Z?!1%i@5|l_bo(1f8!Tg`+66+_gEA*-WCWDU1e8!UN+r7bE>!JR#^@R^ z7-y+o1;O!}xjknEZurnnhlAD7AWs`6#G5EQCKRtY2EJWVUm)_BJ3z>(KA_YwqUpA> z@pXp#8>nyQaPuztspYX&s!>zV@;U@iQmxhrUr3VWkfXVL1OmiTd}0Gp*+h4S<(cMO zD5H>r&AI`jwg+!3`q;%Y6bCSW$|O)q(W9ICRLV6HcZ96r$)SIOW(7k~)g~;I@u5&CM=1MmXi&H%`npvQj}zzB>3*2PHTT^>SNdf*~fmJ(@@v1OV%hx zi2(9k`8_8zRDo{2!L)RQOx{!8Fz?AK?~9HfY@;b!2IJ*OgXke@K7Ab+!DZwdSf#ID zll9tY+d?*2YC7f}kt6Onz8j4{5ns4!J?XZMF)1$T#k^Fxp2DsyKFkOHqg*kk8eg@!I^Gq#2vZ7g}(&gNoCiK@EYoSPg#5dncfng?^7P#E~oUcP7K)4M_$MD zKFhdb?W%fy{+^W@jr?N~cDJI=f$Hbd)_7vb(j`Z}t1#+V^Rz>B!+tC`5jp1oH`;-T zf97=Ipde=QcK4L_r{GF(neY9dwIP>K)V|@jO-SH>tPTGi?j!Jh=ZvwwwXmzLy|IIX znT_@Ttr7nl_fh%2OSRO7?Iv&+Yek5av=2SfP9PcKS>P8aGS7*&i*aV7_8QzH`m4Hh z1bq-*kLp+S?M9>#NebT_*D=@gA=mMSgZrQ3V?-b23RC*vR~VWdk)V$BxGe=c%{Wj< zH^^|LD>1SXIwdMbCD?QSADo>eco-i#J=<{K#u+m^@|IliK(e;mf7l>|QCfX%R33Nq7Lu*EZmMdi{SjSXNUcJ1QT9QINk|bXlcW+}_NN~TLrd6siU1ra zRjhUqxf)@66c)>9+Dee{($Eh!BjgsT(?St(+Fj`w34Zp0S?-C69hsc`r17RRM#CnjHe=1ZC4Ci^BoN8p{jNn{HYAbp zV<4JG*`GIft~)XU@Q;ErM>-m-=9OxUHU&fpa$LvQSb`e7UkgW65W zqQcneD8%e^ROqERsE9=I({#DN7Rh-}{Z!_~#)LU5GRB;0D{ZgZWhjsUzqa(c7IV?+ zA3d@DmV`D*3pR&cM`QOp{b))&h*A%tgI8X?GfbjX1`E6{(_9x0g4ni3kJZp$>*BexNM1*9HH9p@g`P za7;IV->Z+|4}+8Zt_QIwy`I?)t>O$H;T~^}_ilp<1C1_9LG$Zr&Blq`frVGn zr8C<5Cp+H0Fz^6<_C62%YsQURii2tfd^i`ekS)5Q9tJ71%!KL!@OxMfreC%=y%a*w zU^{4?>|T})udffA)p;P(BWy0Cm?{pCXGy?@J_^5k$xi9%0C}Ho6-F@xu$W*k%C1|I ztP-&<-fzCL$B|w|GSUzT#KeGK$O5pCvou1YY9TWCZASQQfhY0-CznuPM3@gJYfD7% zRvOd?x!UD{+>YkVtAfocid+xoqm~-| zivR?+a&Z(WR|p9x01=mxERGNYze2=1+GoOgVJ+k-k4LRixmISCTiMv9KwXJ105nJN z1gK(BzO=NK`Z+t*V8}V|obf~}DgAqUGyQ^Ob%bL+vvu2T_Acg*WUI@{|BykfATFVCKts4J%04KUp3TgT1@r2 z?SQW(Hk!Q>nrDBI4M$A44f_p97xldC*n>*|7xBTVlH~v+90M<9|8W2e^lMejvG6f8 zi|2HZAzVd|K4%y0C44{!nbCkR0d}+gLR2y~S+AWwr~a_G+3*EM^L_$O@ulnPH|F|B zE(5oAUzFgbqJo{W?Gg8}!=RrXl#J~h7?4`&{5hy!V(FDg#b zq2jtE6a>6a`NxPk?CaZG>B!z;g1{A(wfdM7i@zwoaVPCgxTV}mb_1t4TkJsG-uW*R ztD0aL6Q(yHjr$qCWVEvz=T~-z>95%oHBX*NjZH4qVy4qeM4RU>lIt96YS9ktHy{(x^rkAW6x&15OsgP9R2v>S6pvMkMxbgiDdQB9XlDA&+7m1dUJ^Tm1Y z6I*=IeN99xZ4~U!obd>#&E45FN=14hB;bB9iS?`~*d=%v5ASVW*hei`WaA$7&7Nd? z_sKR-!fTCUsQhyJiRHOG?CZ@$&Gue>nPv~pX5O1)*fwGoycl|IBA%N%-Cuf}pZL|f zxjd<4r1gj!dr3xp7cyrxc8OvWFuycpTN0bV2|loDReIweUeN(hWA!|U4xk?v!QH)@ z$tGMdIrpBy-p2B)TL_0!ZsRFeFQ0?n^I!TmDostykt%8~eqp;vF6&fs=9Q$pfZvtZ;3cMy43)VOzMu_PvjM$ZNXFs%6t=2}~o%l6Q^B$XTY?Flh@?+vJET?+Zf zSj?OZpe?Z9D&q4Z+v|kDbE%KhVDkN-VVe!)CU6aYu#V9QN3ITy$%b~r;i~&qkFAHY z-awQ3VJMA+xhdj>{PNNe3+OQGr_Fpp-Ll`a>ev_JGrAt+A$88357ph*CiV8`%xuxo z5u!U7ke*woUc&A>c6BzeZwBuZ^!M+T6FN7;ToBNKd{ml1MVr_-n-t{v9X)if(ZXFr zi@=3I26JZFE0;?vS0erTO%EEdxy_2%X1C+CMjhW)RYO5uVL=Ib0c&8hx^Du13)S+j zES4(+Acgb6EY_029;m!PVa$Y5MT6?hRHEJ&Opxn@8aJ${e-c0^0o(NDBqhX6CZNKh z@xoQ1tdP1|AVV2sT7ZgS1t+|W=a0HiBK2oY>9jUIzaon%mRR<&_i8K3FANnWlrKYm zdPKG7E)bKg0`rpS#-7lR^j6n?%$#j+(n;%J2aFo-;4E+>)R4CD$`Li3q1>A;jrD}I ze zmq-oz>}$19I6+%1+7_Ipzq}F{Nt!H>&9ps1O7q1qMaIZ14SFA*hn?K$p`9mc^hkMO zopUiV$p}{}dSM#?Bht-)KqJA9Yso6xziK^>Hx{c zq|JA&1ypy0WV`GL=;Z(@mMYo9JrDXYP29th>@zKkzLPHL<3$4)Tnw!zt#>dAm1>ku z!#SyK>k$zdC0h#~0sG*?F)q^G~YC)opP8X3beQ;Mzn^3cskAyM{rA??M`8+ri7s|VYpi9Ej&H6 z!;O6MS;OqJbuQ)ASZw|=g-!q+gQG)eUN#4a)DBf97pm9|KU4oiB(%WP$>mP(1H+7? z=SmfQSD*HSFoh?tb`~P|6r`NLKQ#Km0~W(MJ9yFoQ01Q9Ppm6=x}E`J5D7CnH|GMB z#*l%3yBY<@IX`;b73*a~5An0`K-V2AP!!f}oK1&?J*!h7TYW0^u-L8@a(F5yn<8Jc9KQBW$=Qy!U=AVnu7GsVfMSDzAB08tVql?!yY}70%&CdnujD=N9+&){C3v zRIHxTG;nN04wGUtWO(u+7_=zXt{O><7#GnlW7u-;cGJ$gnl4M(ljXiue(1;$7e~1Q z?G$0B;tj^v{PjW=Z69?x<SE3=VKBpCo_a@i^xD>cb;N^Oh%oYy}>jE0+~uGQpz1$8?b6kZsFPJ^U;aN{eg!=C~l=Wus|`; z{5U5-8Ip=JXu8HURt?svIq*?=GbS zAm<{p)Pl%EImw0cch8~m0=qRfeQjZvZQlP;rVVe8W+PM1t?|d$$oM8%y}$3FO1+WF zVj@-b6AKsdwL*a^bpi}yd;CmvjW!2NK|8HRK8J2zCdVnqS#j&@d#nKtv9_0KME6be zQN{dg%<&CxKmY*zE8X;8ZA1-itR0-JjP3se--qO1>h}NsiI^0Abx zABD%i@sOZlWUxKQuR%vGkryjOoL)Ii>8A?u?Y5(fMv$dTS}M8k3mi`juO|TBn5&74 znT3l_W4fjDljreWCgb+RH81aPz#cHmgB@Ww9VE3AxzdzB0|__LsTA)S6h#nPBC|Um`#pO8g%E>uZp!h`OWG5zc-?3iG2xX~j=XF?; z=QNBm=_RRJb1l=7~ObLjF8D7=$)JU$k2$wH~ z5;s3i9(w!duULFv^*!9^AflwtT>ln<^8lVY!Ado2rZm)rf*J@Abg*+l^ zzm2wKM&--}R+}eKI^>Vduh7KriATLWh$ZPIb+@84Xi;n4zVDE1_?_uI-ji2+BcpJZblYml+XL!j=w$=-$$!KH*AW ztU%H()o+wLZKO<#hx#vunQgO_xe#0 z*aKT@#At?W$kcpWjR#XbPgS~pZFET1a3vf9ay7j02pEBWs}&4|mU4daON4NVPu!X1 z?J+i_WV(LZM88x8yJd9$V=E9zL{!mj^t%Ke7={t9rb zXnx6lK7_#Sfu`P-H44|6^sEX*hno@z1=Pem0p@2bjv?yPB1@LN?K>jZ8}OI>0dcCm zUhawY*OX?P(|LXtx?_RFRH@)5F`v!q-!A-BmKEUV&Bsf@L5MUL4mXjp&U(z5e4QOl3sAgb z7sEe06y~20Th78_X~|$T4TL#x40CFKnAKZWUZpp}3QVpsT0{7Na~*I%{v@=4M5}rk z-WDg%fRdK0RK*1DHHeqp5*6_DM|>b%U=brjGx3)$6HvUV6~&T7-_5U{Y<5H)30@`n zpB}6PSLIdV)Ryfvv4m;r*d*}%pIkL_kiZxl7UY3d!T*4A<>-W6@sqi$H!&f2P1sTr zD|m{xU zHXt3NyRdAokV}IR=WM=aaOc#pkf{h|=Ljl&oaV5@H0em6|B0mf2@&>keMcVI_xAq# zukx?HcYpU){_EIMmQ?(vcw9k7-=M?3Q&wn^gvodyn{doZeh>x-K;}8?l zZ-OK+_e2S7C7VD70HQWqH!+yas~Xn=daU0#vXA1Ewmbm!T@xNQ0$F3&FexAOObV4w zYrK(Gj2b027Zb%szzB~ta(2OP)6VHLCa`8}(wx}uAJedx=e4l)<7C~p?B-omT2J~@{Pcj4X`E`Z3U@tDOVql*Sh)cCP0@V; zrC$$J+{%A9Emg~a29-eD_}lIvruRTHl{xdu&-SThR02=M3^(}~U5z1WvJ(lm>Q-3e z1r1}t6pnJNc=4Y@oLzZ8oG=xJJ%t49n1R;O_DZDqU)grIx%IpvV~^J+g}%Rb(&{Igmww+OV-o@f=!965m+5 z5j(;hJo8(Tfq10qVO;E5sD{ZC?LowA;gTQRAa^(&Kai|CpY0)hD{W;2-)|U{yMwY3 z+?*how<%@}f34?e=hL3{#HLlFwvadA*y`-Nql(~D#FNfA3#ejP;##qyp|ayNL7;cY zqR*ZS+Y`G=BY3L!)8@MnbG;$Ms&00GE%)bDTe#x6f7lYjbd~P1&i;U~*^q4TZ*e|& zD6yG=3r>D&s%TJSQ>~9UAE_O4=T-vn1ivJsC`M_dfk;}Gx5;(+F*Lr@$ZwmwYxi)~ zBc%4=g5{0gDXyd?Cd$*pO-t|l{*nzvdq=nizFQ;vtJuy>aPBvaB%UuO{1XC}trF$~ z+Q&b)u#n6jHjD2;2=sq((*Hfn{C{(R$l04&JO1|&PGMaFm>z+ z)m}b2nXr6`iW~^uJo6Iuy5*<|}VU{fbjhjT0Jdn5jQm8KS=Ae$vbPX$y)*B>s-0Xi?k}YqAyqMwe z>4oDF)g5uoL@%HTgV&Q4+xBXgCy-*%$LgcIG^-P(%e-MI8;QvJCqWrzFo4hbJ16J= z$DB<0zi1==`9c3m%AM+FuHPd7Z&`+T4@S(NFdz^=Nk9z57(|5lfHjaKkVgDKddX;5 z~xoFqf@mpsY{on%(uPfvS^G3nG$*XsGl;*hY4{O?foEAl$u7X_}9Ni~<3hS9$ zR2-LgTllL*yX=H^UGJ~5pz7CO7v~&Zx%+^pFv55Xw=q${PF#8W@;K3_D@FV199@O` zb~xKhwc2am0>kkf&M$I-nH^EVX$Ab&1rOH$R)=;Op0 z$>p#m)qxIiend)(D6%az&>%KV3?TW&74H68;gHU$qv>49tlJ|mAC^cNnu&9>0OcAt z_$cZLh_YR{kbr$m4P_S54bb)UFLEkEtTPCu2BOX`$~D{%N})$!MG|M6MF|s*FU9Af zy0%t7;^L$@kqM-3T$36iNS`p0B(hxjT%P2V)iYo+2?TGVVvY1>oHfLR98%g;O=Yo`O-s7;eg;sbE?rSvrYRi$@$n&%`|cH&&te=%D2=mQ zAY6zglA<4Y?*LTDz1v%&Ux+l2Yu)fLM^(I*pTsU!Bdh3r+ECDk#Ks!~VCBH2PZGbYrewx`T+&2?LpWzJ7{n35!?@?FDiETfGTXclhaPJhr7cE`dlK{~@XLjvHiz1@z088NeYz)DyO7~gs*gQwWe#hZ?vN>SO*FUZ9{;3l^vv`d#YqIb`A6Lo1vqS9T^r>=$& zzSNJ6IrR7hs&*#SdZ~13pvKp<`xV)Pwo0SS*pRZwt}HbQM22aYadO32W(pNMf2WRx z9Z_hOnvWL7VrFJKJ(3A;j|NDoY1W7f;nqfF9i4}LMz&00_X5bmiK$dtI;V#F%2HdQ z#Ny<=No8+O@NHBC9^S6tYm1fZVM(=Kw>|gyt<0ggLW}4h9_xTju*xfw%Gh+?e*kz7 z25$F_sh;;y|AYWrN{y`mmzkHBh(#tGQ4A5Zyt^4^&Q}^IE__hv#N+9hT8p+{51ZIJ zzcXIerJi|;kfB7>#g8V(J@^Z2jDi2=+AKP-i0w!K^RL`AeE{?4;e?U2LOgbO1tM2; z0^M%9t4`Vi^S9DAm0O6$8^?b0>rGm^TC`X=%6mNja0RweaBT8SuiT~P-5Qep)xR4I za)QIVmDn>yP3FWNyUwkdb0($<3Y3~>MrsFxtLUmWQc2`{Mz~bn(?N(io;O%9AwI@l zQo3q6uwPWsqQ|d%h!8(ms7c@alXUrzy8E{ENbG3*z`sWdHyW;(Jp;@*tehR3YV6mK z2&3fIR64i3v!ru>M!wcG7+veK)Fm2OC$|fQ5l#egVq!xi6E1^*i6pUu`6+qO$IJ`& zmAHlpd=5Pl3>je#;4t1Pd6x31dLG817SC`Y`N{eZB;4-gyJkutIY#IQw;wP%!}rIbe@6Fu#TRO0c-hx%zh@n3 z7F@^qjvyMe%%`05>kl#x@Vzp;o3$u2jc zb#p8+KEXaghi(}nZu?VeV6&#Q&A)0>BJIHv>{`ON+vNR~)kaxig}tyi3T9a816tu<&AOmq%5$KTD(Na#YLxQkgX`i*dr{NCm8ZE3My>4a-u zWvreiI^eyD*(2iyi^ql~rs*gO34^zkDEI9%&I*W^OWj{wwWo=+eHgStG_(d5v?m%c zrM&Ts1rn}@SLqV_nQw4~_WlH1VL#@SO%epB`QF( zpcG!S&g)K=cV>)T&GV!U7S(rq8ZOaIMICruXv;FI^>6WW!5knkc5B+7g<1c?rnSN* zHS##gVarB6b!Q7t0aTsq|28C6-N(@K=g^W&Jx}>_uB}u_6--kQ7d`^Jo-2xz+!C!%B1C$tga)&fepr;-u0E;hSP?g38u zFa?t|kCNoHs)n_&mTZlV&grC;Pc`jSzpiJ>Dr;_9Yu9=uB`?1%?Q+Er+Mgcyu6FR; z?t>}A9<0XH)R>;an%c@z*y5bfI0RfWMFXi0`50+FS?b4ilOZ$M8tUou$tCt1mtYfj z$iU>-k!$GDYK#_VFkF=*D)qFjWj#0Ha>dT@Jcpwh&Tmy}-T9=Si_e&oCEdjL((wYa zDUwvZnscN()6p9J&{^@QRBCEWdCFY${`XJm=HXO&$Um*>dZkP9$zW%;9S)~ShrfBY z9&0QP-@agiXL#-|)$gnV@=w|8PTa;id(3~+@Beo4o`N;-@AotQLvVcTYV4F{)!5&p z0rgdK)s(%h)5nHwYqq#+L_0B541j2bk^mP)7Wk-y!R6DssuXtvl3BEtB1l?n72`2) z|06@X12QoSSglyaXo@?$BM~>y%0b*X)ZaSZ(_SP-W!K3xWP>yOjd-Cl&X3Uypg;WF^;)o^+)hmSu@KUq)h!dfNvO=mi$S>ZU(*?v@yM1B7N6 zsy}QuFm zz-)xE70YT56#770QD^Hz*R3PF+jA2nW0)Qg+bYH-{jO=1M;r3}80m4YzQ zkYTTp(cUbpfat_Aj;dzeqVR3#!f5LDEQdO3cN7#G*{>MAcRqZ5x-G+7B{zqyx7P^c zp3$l@WAFk9DJEWILZq~Wzcr4Xzgh-&P=6K9ui<0ui2~!#WkeNroEa2f>{%Nrs~BCA|)gPrysiifZk}As`3!N zyC$%23GUy6AOD*|Tk#us`!CUIrmCh3vNFnN5w&!>3^{d!8im4PQc++YgkQpv95D3* zNueGfZTtZdj+n{bM1g`_FZ33Fa#soM+d(*2h(wt)wb!#~>xPF(97((xR(qTM(L`!z z_s6Bzlc(w1bocL1&>gxin7wcBND*2c$eqQXXPN2CK(3vT5(tqYw+37xAVLV@1+Hp4 z%!#JUt}Ro7X~8h?SnwS1>bP4FJ$fFDAv9`STTnZf z09&y$CK_${NU<4(rYMrjL>HMYO*xdK6$UAN7ze`=5-?Lq>6tMzF*D5g{B2aZc4CW4 z7HR@sCD#Ppn2X2{1y%x!14=Z=$U~sSNkxfK2{k62w@<-u<`F9#7UZ|*@e)k{rf)rg z0?fJe(=x+H9dwTmd31zk%JhL|ru^cK7H!`s;!r>w0+=uh)!k29V|h#|N{z6eu*#CF zV!bDkEh8FbRjGg*B>#uAbBgY?+tz%=wr$%^Dz>St+`nfyYL`Djrz2uB#SXs_bYegpaammKWrZ#|QvwtmG(V{{I+w*k;G3OiC1+NWTd^o-dLn>F4N z^`oyA&Zn^73NjEY5lWI^ZRhoN0jhSF_fOYS(oA@rw-l-@H{UeMYPrtb1r%w!Mh>oQE2!3B91HSZ7MP}sMI^?M;*8OtA1L+xF9q27D96JwRl|{|w zmrd#_(ro|CXM zT;&nJV3Vt1eyC1s&L1XMBluqaYOga$ChXGpqDC1z$RVaBl$XeEXu94Jy7tVeatu!+ z5n-lB2SNa5$u0f`HXX@I-@D*E)bPez({tHlc6~8 z%2(bfjo^Fy%v)a_UF4riq<-o~l2j;-4YA^Cv8s!o)Aa(xT%5Bmw>zBislKZ2>+S(m zsnWL1*;j6$X$8iy?j&Y5WGymtYl`8UhxqF3wu~qe`Fz7)7Gj};x!*{T@)#buSKvDA zN?j9>u;0&aIDM(5U9MpngrQdjgmgW?o*pJGJc4Br&I5uOqwy^A9OFiSSPv0f_AR{@ zpN#W`0i_ z4aX`V)LZB=<9g;E(d3Bi$@=mUV}MVmC$^ZhB7-%=)L8?IW}P_*YpGWcaxRz|0WS`W`hA32z-AAi0FB8mZ zLrFNEn6i%v^O0lm>T_(nEPah2o?+7N!uXr1_Zs-ydffW)S3bIe<{2j}9^;|}1+BTu zMXB{(YIVjt*T>g(hyyp{hmH)-9BU!=Gg~Cm4|pbtN$$8fvrB!*B+Ii8g{Hs?`sn9}$=Wln*}bl(U~T=8@M}DHD(1 zChV}Izc7NIQk4&v*4qT8@${Q!>VHB0={JLjA~_h}=@G;KUj(85d)Y2&=VJN~$HCIj zRvf-s5Of`Y%9;R`rbFDD$oPDq>Sj_T7aq~%D?&V-cs$-RnZ8j*3s#|f@h!v(SXNr+8NZ^$9^-bXj1fu$P0)Z9Q@?rDXyMpH;>FnrwBW>VailBlY) znnh=d4sZ!tFTzRJ)c$Zgl8}=hcV4~D+W5<8jiy?R@dP-Z^m6|4odWP&(b*F37%$@|>lkVyG*=K6`%;z1d{eYS9Y9Qe%8yV!Q#57kZJA zaaqBfqu}}5yZHBu+VXH+EyHGET=bL}p`%(IoSWK>`cUf2RV^olZr0HGE>72BwX3Sb zc5>Y}s*(nV7!gENFfwkuc<#oS>!yEyqLvDuAfzH$54hz$-z{>E zLS>br9lpbSyoA|hc-v#qb$rABT#|WGQ?Ql*I~AR?PFb7#{34Z5gH7wWNV0*2Nkg!f z^eIU8D<0_c0c6pq%-1HmTwyL;G`Iv7thEbfVJiuX(p|*t|pqE^n3Y60Q05KI6Jis;bPqTEu9B7W)WiHC5NeiS^9ztrn>I&WV17P@b9W z2xZ|`al1yiJR}v&F+;2cw+08^(H4R12hN zf?;MFES?12s8x1vo9A}wZtH)2yy5(Mxho7;+(JP_+3(lE2uwR2^aXN6%9glGg#gBf zmH;5e-yNdx`%i==5y1H9q0Wai{USpG@>z+Vt*12*9YX9uw0xz0sUP|D9}j~iSb4ou z<>(pVAnq9^p|^!p0JUNMGtpvX4O>`#O{YAbj9OWx8Q);5C8ZZhyI5tK+Af)tFFtwF z?9`w^eO6(|@>trEJStUWbQvNc#jt6z&|Gy2H(aA}^xJLlG~HQfX#64m@Qjx0!quqy z{8>$EeF++N9>$AD@1pH8YaVVp$22WYzFJwfP=_kvju9`@{n)}Hxu3`0j4G@r$<87& z`JlwCnlck?;ZL$nG-7B`R#gBsrC5%Tc1L_{j#F*Y^;niAI_q$_x^#*f{bk8~S_I1N zxc>v&q6u>2^nv2ebP}Gp1a?bGsg8N}nQxNHCpx1J&ww-V1MM20NJvLxUXqU6kcaBB z6gv?O3oZLACywAI*xVctfS$`tkm(T8*evo&*tn3qb*-64oAazmiIxIQ-XiI zR7yEAp}M!eon{vul!m#7mmvp6+1Zz3H*RK|jT)`0^w~$8tU|q0MO8t{GSo_zQKh!D zYtq(HKWVUI(7shK7+HQ0Qbd8K3$* zjOMga_!Ny;96P7RQl;SbF;yAndY+oAeil4tQZ_hVQe4PL7%m8moBu*7O&_yut|ywT>3r`wVXt_&6;?8UPM?xYA>3!P5fb_H;XRb?$;@~kM2?i3eax!`jw#7$bJaAG+=3|3#9&MfO z;djX5wuVuh_KH1;K5%;k=B0DES>6%#`oyun2rvai)K3tJsX9Rx@V!D`=5WqP3=uxx zG5=&U@QM(!uyx1wgXsJ=xK2k24@2ObQD$XOz>r9662Z`qTR}-1dXEul6~Wk`3w#FR zcgg=0xw^Yrz#XHq@WXH9v-m3vYic#r<;LEonz0J010Ja%0I?-bs!ZZsPVoa2g))RH zJoRwD|JmVnW=xqj;e&hic3;ZYtB@UTwIm*->wM6X#Qc-Nqf*ZMS0#Qh)-?rzkI!9h zUM{IgA4!2s{$`KV7%MSHEZkL`N*_C5DIbo4gxk#DI4Jw*$h0dYv2=v?HjejF!u<>E zpBfp=%oNi3T_elBiRAz9)dJW5uto}7m>OHF8QNHySi1Zlws^AAw$#7akV-p}l_LQ*)yrBZ+V^vYeXtIM4W;c6AH% z0Vsxz3NnY zxrDJ?RQl^ELxPCEH^~V>_QDVn7;AZ9xHm}ovRsauch+`wWEYAP`L@Q|bVns%)Yg|GNTUt)!D0m&{1A9~!KQ)&cMgCEND8 z6mct^dG~5PeBkiK4Ai#?hQ-@m%=Gr{&$Cg*Nq|=2> z_1+X4Yz22KJ%DW0g$EXxtD}uYBi%}_BQ`_>7v3MchTD7@5R8rLO)g;e7 zk06Z1Y$CQkt){+))P3(Crsf!HcvFV+G{{*)a1SDN<>XE%tuc1oYDMAf_cNNdSI2*O z%R|p>EPG4(DX8Vp(S6MqJ1i+miE4!wx=^ZfO`|ZO$kYy(o^9&Hu)}DvO8M|Boi4FB zV#Q)W(@d#FQ%k}K80&zg$d6bIovJwou?x%Xk&r?*LBAK6AP618<#8i*CMa+_KArBfJyiYj)l&6ZqEHmM6 zc>&PBbr^E|C*|pX%MG}pzU2nXr(5YJdgKVm;K0G4n1sP52|s{}Xn`aNC4T)tcBAE- z>LLY6Oy^`VbQIjGsFtqQ22;O4zFYuE5i1S1plfYfX}>(#H`6z3RX3|49SNNFaMDRyj_mw{P;C~U_{Xss0H5@JPoUbyLJJ}1K!q{-j5D0 z2+_htBu)U&1j%Ay?tmTy8AKU`83Yfmjb&q8m)#E!ZqC9P*53|0V_cWm{|f8I)b^`C z1eV^&fhkBD(Zl( z@Xi>&UA_Mu*P|DNz+u1=Q{j$c>#s^bMEmwAB?8qS#zTRFq0hBpl5J@IiEAJ*g2U&$ zK!L+&N3dLjobT^NfdcAx7|?%}`b$wizTF0Byaju;Xdlsm@+{BxSWoV>Pq%13V*Tcx zcL-ez1nK(%RDWco)P_h!W!%E4OlI@va!M6y}h?kLdiS;LC>!m!rrN6vZcgfUWX% zR0c$Hc(-~{xC{aJL&0>-uaMKRqY#x+%_09D;U>l&Xmg3e_N6?7YnHJ9hyv%Qq&Hfs z*@>$>WG20bac{6&#urb^GTF;W(~_C91siEaqUTEn9a=Q==dR#Cg!*7tBbtUDcP$5K zT=G_PAwmxU?;{3I4#?>emON-Krd7!&*u{`lo)AX#FRqy3Pzh@857=(O9&q0SMm{OFSh*LF{=BO_& zn#j^qwhCs7Gbe6EjA+7}(D{fm^n>kF}Vm92Zu;kdIMK3{}GUZtJMD zscOD>@!{wTY{L8tKdqYJ7eGXw)aDk1$pQeWAEG$8fJ8!CLILMC^U4A%&;* z6*ym~4IZNPBQ4|EH>4B+h>##t7(I;j74s2dVAVTkQd(i$I|kW0 zk?at*56Cf6NbT<@UNt2B)-`x=%wHF_q9tdJ&@^p_sv zpj|xCh^akAzBAu~u|yCQGb>TPS&AQg{j4%JO1e1(YFyZcI z-6cQOC>bsNC8pM-GW{l^?PKVN9$)tHrEzop zhy!bj$_lGzkJ@yrXsv~ipDm9%*Ek7{$+fgJ*@&fmlVUp&gjW=Au_+dK4j2}p8K%3^ zdVLlXc(EzGREzEF&hW^i4hh`*Me4MsFY46b?b>RNZ!#LK<#F5beTP<>G z8G)*y#l^351no2U1n4+UC?TD59Kh+=CE~-GfnYWu z+d|1J$dQz@=M6PCTm0n}=ImreTG%Uf7m$6$oxq*>@1rKCP(`z{JN6IFklq0v>Moeu zIQLTK>H+V&9%z5#JD{N6hhT))bCR4Vgg+V~@_V_|A29sN`_6x2q4n%cu0*ge8C{ST-V6R{sFilt-7!@#&7#*0$O!JUEuORG+Wp1jKu2h-GmPs4R)Q5c> zGpNzS!NWAl4jga;2wT)Djp8|@eO^t#$}~NQP-mY)xAqkr!n6-Mp(eL+W12jTZ>qb{ z(aSlJBg;tVIl2JRtfc6XVrb&~7E%%w8pJ6TM(Lc{R*b5&qexR4%3C@sa76&LV1Tqk z6SW$0ACpF49GQCpz`9;?_{k#_a99_0RIZE8QA{?kNS4K|vWf&bk;NOw$Fb-9Fi%{S zyRlWFL8hi0_hf%+ByB zo0R66JTAuDccP_e#hnbG<2Yws5qR=gVK`PPA%!=FKZGqgP@z>EZXE_!wK0)*Iy;WZ z1TeXKbBc-Y{Nj-45fW$S?l>z&a~FZJ($-W=zLCXaawohf(K%wT4N%DnJ(7%Ex1BM8 zJ6fVAX;v1BAGuHHZ9ps7XP>5Hklpfozz&TFi7;zhmsPrh+EE>;k7qo`fKI$FI6e|I zMcGyzB2B4mL!vrc!d%{je`zyei|dRsF3<+qC#0Ic-DwKS5_F#I#BpEZG?0;ykyp~% zSW>%HE0Cahai64~b08&VA`cQ4uxHo+U8D+*kR8C-H5ReMWH?$~1awxDV8X-|Z`J?A zvF}T6lM1Qj@;e$%w%xD?xhC2-uV{2=0eoUvTNn*4jmS?u#Y?2E=mQGJ@!^PcowPiB zinUi6ke)k?Pp%!gw1B4@4hLQfEi+bWtW-so22?m%V|~MYtnt=~eEjahsE#4YB1XUSuc8 z3A3Q^fz6mGYmYHV$Hit=+y5@%LVlbmI95x5QEry#rw2hJr{{fFF(w#-^?s2koyRt) z;OtX52P)w(!n?7{NTK#*+ENSc$9bvsYubjB=b)zH4AZakwF}rjU;um1l0y;Kpp2KQQ1L+(=~cwhnP$F z6C?|YDFT?;A?Bz&ll?E#C3%EU*};6N_M&~LiZ$vMqNua?xDvp%O_HTAgUPz9q7w|2 z%T^^c^|p39F1w6u$*QlB4)JU?Z2Ix2l2X#qveKiMT4+n~z$RtFcZel$rtBo3E+-z^0~e z7RkEYCo#F%JEmCaZgjSynD3mBZK?6&w4vQZq^0Or)2G>z5sL)y?6^ZF$v%67CaugE zJ6ADvwU$(wS37y6CqM;Nhtf>+!=*`O*wd(#dIqBtv8CEV7J88mh@LHKV8)1fW^2Tv z%ZtN^U|GwMZ`#|qN6p;@Vtriv34gVNCF>!58x*f_#JGhfONAg{ubWf;t+_2TPI=L`{};($0toh*IoQ%rnTQpJ}-ZUv5M+xCpq ze}MtJw_+KHleH~07SKpVzME#h-rOZE!B?{5ZS$eYA{h4z~4 z<^5xn^q>R9u$HEDff3fEmp`xT_;6X(v z{*oMpp}MqA$z1SzyDsyj$ha(IM23tvA9brc5c*5DuQ6b+blZs=VBxFHQ>d28s@U}0 z%WjZ+%jO`0qu zKM6ut&Ey-$0)_|et&y`kXY@+9GAkil^z`?iYtw@j;Zs?ESn zc@#D;0q(cMkN5VZ@m_D7#a-GeO!-}>tS3gTa(S>T<5znfH_-yIwIR=3a>VJG!^ zH|iOr@Y8#u3nBVGHp=tsSFGtf)W_n`d(zui;Ox}j-tsT55Ag$E!@HN_d3?5w+NkHW zd3=tI+URFc;8q`VYHhW2+w#GJ^B>t`IHIVd#(AH<3>U`zQUX83Ou8o7N7MziC!7bW3877cmP>>8Q~(*=Q^ACCRRDfs1VZnF)ew=FHo*F9 z#n0H2(E!7)3YcDk83YfXAA?^5<>^Pj5M7z2@e(@s4vJaH~a;)|E2O`Pg}$> zSU09o+JBc|G)rQ@LmX|rwmw3FrmIlzm76uXq;s_SBlcI2h`S&MYJZ`I3<+sQBqaPO z68Sr2h!b-B1c*Y2gFm1xR@t7kKEJVd%)nSA#M%c#W)0*MeqgA%=E5$`C0tSk_t!YE z64oo(QQQv1fFUNl_(2q`Nb6P*B#LE(BIkyNQA&QkP^`5SN7ezA7ivkvJIYf5$Q@la zw^rF#4Cg1`BSj>9hSV>j9 z^uvQ?6Q$+qnY9e@$M^|&HM`sFk63H4+I$+TQ|0jSQbglzCgnTSpgGbY z&D7CmYPoO?9b4%_)&$CS!ymSWG{xnP6v#+M;i}Iyk2`Evwd0v^xd8i?SLq6~wc#b& z=h)_#`K$mDrk4T;1b*@Bof}sgcIEdV{VEW>&+FC8%2MTbO|_lvQ-$}3t0#<0}KI@HWf>osGs&$A)&z&AN;Z}muXZg%i*6WhzK%q`+Jh1w0hg@4LHHt0K&!-0e z#O(J~Kw%&v{^NGI&K3siUnc_~fDxkvXJUEh;=mcaT+W1~CA>+RuptyhMV(|ZG7malHq z`slrBDAno}W4jJwTvcC{OsoMG*6@=!Y1nzUGjWNdcjjx^u5UTdK;V^)ZbB*fV%BAs zk4O|+HYuTuz@^6RFmLy>ym6AWJkRFNV~rQSv9AaNEzKhx+jZHO@|x*$R2=!!>!?>i zsft^cfqres&<<=-Lu`!rs{`~O>^cCPJ*O>^_+be5Ja7a{6qrdHIiN9t zD2(4vmamMpeI9S8eHkb!(HF*U&QV)*qg+MYR6WxJ>m3~X%BW>rl7A*o z65tqvRUFYx41*J-P|1xTB_hoo7Sa}I%26Y{n^dQ|2-1qRiQ1SaF z_nEqY;rEm8Q1!ri`)>!OJ=nTpR{Qktx&NTnrjlzTw4-Q`vr?RKMaq(r^q0f4R;8Kd zR@0sxe!lVV6x()aH8|qUu-SY7cOT-izYw)qAi$cG;=14*;Ri=bE~esEB)!^%W-k+0 z<`MfXT#jOC<_yrDPw$@d-lt9+RV=bE%ei5mls6=fW34|wh1fG^ z()KY!Q7!o8ZNRuA<9LhyJ6YQheg_`Lk%4xY$B=6Wtn$u|6ND!p?lvUbgTM#jHq84T z=xiXjFY*s!R{+AG<5nzi=Xg=9kw5QG%VTpDKVG>LZ=ttog)uxISloss{N*o9*g>vv zHnd`t#VG#RC_Q;YO^&zsrfM!5j%S-k>g_Yl5Y3YLMwvo$Z|FwZLiJ*7zQ}KQsVxh; z_k~$*#&YF$<6oFgb5nzti9xU7&PaUnN3*p`FZQcASUj^bG83O&Y-V<4s_A)WMtt%I z0-}enjHxfy^siQvzvg2fvjbKiAU1shLOlEk7<2Sp$ofSN_sFd5BA-9GEqo0nGWV(+F}T0vd<{@dwe5 zG0gO8mp49aY{Q*~v}{4{gOHW*egY?k39E<^cL;j1M?F-u5cMTB~( zp=T>dVa0@cxuKj=;Q85}Rfqw>BMfl5i)AV5cpy59_OfP4t_& zNAtj92SYr7Ysm3-DL`=%**)}3`n8F1Vqn0WMd4Ebf}Dz|5K zvp3Usv+1Soq^w0kaUIvo$^_{!;ZYAwwfUe)MzUo@+A^c_koBzH=mGXN6Ay&lYu~@U8ulnu-n?vnCWbh@^L@_-5LKYkBa> zU2PixM@0IpaWu5S$n|NMcEROFP)*^BWQ!_+sXpI6^5olM^4%94pVlvdd)Y&3j0CDv zxO%`Jec6v%vcIcHUzZVIaERzQ-pPiVJ}42@`=7& zz$Ui)5JXy(@L&dcYp^6k=o-`mb!tsP`dMJBk??J@HX+`_>>jdNa0CG7y);gYFu;RD zTHB9N08G7c`ssJx;j@ z+}=R1H+NJsf}nMHUfnQ~ge^NRyrahqYtnW+eIC3NHjLdUDsg18RpC2A(PUrUyE%_T z;v=V+jD>Wdi75T{`%J-J&v#zdL&Kh>!e=C_7fHNpbG&(p)x^1Nu-F;u9;i1A9Iq`H zl&TsR!W*gB^O~X|T`GJw_yIwbS932$ADtfWgE-4z$vj|vO4RU7gMc

>)i)-H&is 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

Ba8jvuy__MwOTZpH4;W^BAdCj(5Di zAkim9i>?-t@GHK!S7z*nL7=`fR>JeraWr$D!xGO(LS!Ai1zTX%Yp-TrmgvAP3_)%1 zh!K=*!-k%gr+|n`AG$=Jz^+S!cMM}j)ceVlz4YWO2V5B+Cgsg=hmuZ^g1gfO{9{Gh zC8ZRQp|CH}vL_3wx6tBUiVEuxCF{g7na$-){OXMH=IDielfAp6Df-YPn)88kR!n7) zY*7`{ea6e@6Tbu>ETbKDLRPOd^5N?Z7)`piqEt=f?aS5BV^jy0j0+VWI2$NGJ}1k{ z&jLgh!U0>7;$q`o+mWrSWiB3Fxyk)(Zw4Nq^1&R>Zw(N^X~ks{g0(*0UHv5gW{AyO zrSN6X5!Cp!2P-S5Hc5|)>Iry6B^ocU!!S^%ZR!~6O__C~$h$>1Dc2lL`42P*+IUM8 z%TtOWVbg?;5(lOQocHTFqqa*lMOW~`S9AH;EMB{=cy_hi{g99+)MUDS=^FC8_{nls z_Z+yM7`nqv0$$dbqL**jS(W)DnLHU|DxgcG_`lt2y5SuJ`_TxkCI;? z{7T*W+91*8#*ub#$wxU})8WB6z($_C>DynX+F5}-LL2BZSYyQ%iWn+2)jD}Gq2@&x z+pkZCD&%oKia{QvBgP|%|EKFW2sMnEx*|}VZ zIyNxcY)S63=?)knbiiSm^g4wd{5~XDjhpqNR_75NV1)#XRu-$wss5O6F}I9eLgq2H z3`kM$IrR)wAIDjU!yW(u(@$0$b!D7fE8qKTf#D7J{q?N#k2*TKK}uxzpWj>jbN$ch z#D5Gr`XAGY3U1bpdIpYW2LD-jVP@p;&p)=Ps^Ng~W3vV8*!@l62c>mh>q;H?y|+eR zX=89P`cjBqOUZjnKp(#p==`z$F4hhO)vlZIRw#+Z%kg8gjn7&8xGt)6ZdSE+8!%^D z&|_$r2THj&``nyoabA%)S2VCYW^d2oh6fqY=l(IEA?oz8wZXMA1;h{WlX@bUlo~LC zzs*nFb$KEqXcKkCa*(`B3 zb}x!nK8RO4GmMxZr(qVtEEk71wW&rxsLKvRz5F|&{QdPVdaBjVp2uO7IpUN9eSpAm z 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 z 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 literal 0 HcmV?d00001 diff --git a/settings.gradle.kts b/settings.gradle.kts index 5421f34ea0..b7711bbe31 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -21,6 +21,8 @@ include( "common/core", "common/grammar", "common/multi-tests", + "common/ltl", + "common/ltl-cli", "frontends/c-frontend", "frontends/petrinet-frontend/petrinet-model", diff --git a/subprojects/cfa/cfa-analysis/src/main/java/hu/bme/mit/theta/cfa/analysis/utils/CfaVisualizer.java b/subprojects/cfa/cfa-analysis/src/main/java/hu/bme/mit/theta/cfa/analysis/utils/CfaVisualizer.java index 213fafdd07..87da3778b6 100644 --- a/subprojects/cfa/cfa-analysis/src/main/java/hu/bme/mit/theta/cfa/analysis/utils/CfaVisualizer.java +++ b/subprojects/cfa/cfa-analysis/src/main/java/hu/bme/mit/theta/cfa/analysis/utils/CfaVisualizer.java @@ -15,15 +15,6 @@ */ package hu.bme.mit.theta.cfa.analysis.utils; -import java.awt.Color; - -import hu.bme.mit.theta.common.container.Containers; - -import java.util.LinkedHashSet; -import java.util.Map; -import java.util.Optional; -import java.util.Set; - import hu.bme.mit.theta.analysis.Trace; import hu.bme.mit.theta.analysis.expl.ExplState; import hu.bme.mit.theta.cfa.CFA; @@ -31,16 +22,18 @@ import hu.bme.mit.theta.cfa.CFA.Loc; import hu.bme.mit.theta.cfa.analysis.CfaAction; import hu.bme.mit.theta.cfa.analysis.CfaState; +import hu.bme.mit.theta.common.container.Containers; import hu.bme.mit.theta.common.table.TableWriter; -import hu.bme.mit.theta.common.visualization.Alignment; -import hu.bme.mit.theta.common.visualization.EdgeAttributes; -import hu.bme.mit.theta.common.visualization.Graph; -import hu.bme.mit.theta.common.visualization.LineStyle; -import hu.bme.mit.theta.common.visualization.NodeAttributes; +import hu.bme.mit.theta.common.visualization.*; import hu.bme.mit.theta.common.visualization.Shape; import hu.bme.mit.theta.core.decl.Decl; import hu.bme.mit.theta.core.decl.VarDecl; import hu.bme.mit.theta.core.dsl.CoreDslManager; +import java.awt.*; +import java.util.LinkedHashSet; +import java.util.Map; +import java.util.Optional; +import java.util.Set; public final class CfaVisualizer { @@ -51,10 +44,10 @@ public final class CfaVisualizer { private static final Color LINE_COLOR = Color.BLACK; private static final LineStyle LOC_LINE_STYLE = LineStyle.NORMAL; private static final LineStyle EDGE_LINE_STYLE = LineStyle.NORMAL; + private static final LineStyle ACC_EDGE_LINE_STYLE = LineStyle.DASHED; private static final String EDGE_FONT = "courier"; - private CfaVisualizer() { - } + private CfaVisualizer() {} public static Graph visualize(final CFA cfa) { final Graph graph = new Graph(CFA_ID, CFA_LABEL); @@ -64,7 +57,7 @@ public static Graph visualize(final CFA cfa) { addLocation(graph, cfa, loc, ids); } for (final Edge edge : cfa.getEdges()) { - addEdge(graph, edge, ids); + addEdge(graph, edge, cfa.getAcceptingEdges().contains(edge), ids); } return graph; } @@ -74,16 +67,20 @@ private static void addVars(final Graph graph, final CFA cfa) { for (final VarDecl var : cfa.getVars()) { sb.append('\n').append(var.getName()).append(": ").append(var.getType()); } - final NodeAttributes attrs = NodeAttributes.builder().label(sb.toString()) - .shape(Shape.RECTANGLE) - .fillColor(FILL_COLOR).lineColor(LINE_COLOR).lineStyle(LineStyle.DASHED) - .alignment(Alignment.LEFT) - .build(); + final NodeAttributes attrs = + NodeAttributes.builder() + .label(sb.toString()) + .shape(Shape.RECTANGLE) + .fillColor(FILL_COLOR) + .lineColor(LINE_COLOR) + .lineStyle(LineStyle.DASHED) + .alignment(Alignment.LEFT) + .build(); graph.addNode(CFA_ID + "_vars", attrs); } - private static void addLocation(final Graph graph, final CFA cfa, final Loc loc, - final Map ids) { + private static void addLocation( + final Graph graph, final CFA cfa, final Loc loc, final Map ids) { final String id = LOC_ID_PREFIX + ids.size(); ids.put(loc, id); String label = loc.getName(); @@ -96,21 +93,34 @@ private static void addLocation(final Graph graph, final CFA cfa, final Loc loc, label += " (error)"; } final int peripheries = isError ? 2 : 1; - final NodeAttributes nAttrs = NodeAttributes.builder().label(label).fillColor(FILL_COLOR) - .lineColor(LINE_COLOR) - .lineStyle(LOC_LINE_STYLE).peripheries(peripheries).build(); + final NodeAttributes nAttrs = + NodeAttributes.builder() + .label(label) + .fillColor(FILL_COLOR) + .lineColor(LINE_COLOR) + .lineStyle(LOC_LINE_STYLE) + .peripheries(peripheries) + .build(); graph.addNode(id, nAttrs); } - private static void addEdge(final Graph graph, final Edge edge, final Map ids) { - final EdgeAttributes eAttrs = EdgeAttributes.builder() - .label(new CoreDslManager().writeStmt(edge.getStmt())) - .color(LINE_COLOR).lineStyle(EDGE_LINE_STYLE).font(EDGE_FONT).build(); + private static void addEdge( + final Graph graph, + final Edge edge, + final boolean accepting, + final Map ids) { + final EdgeAttributes eAttrs = + EdgeAttributes.builder() + .label(new CoreDslManager().writeStmt(edge.getStmt())) + .color(LINE_COLOR) + .lineStyle(accepting ? ACC_EDGE_LINE_STYLE : EDGE_LINE_STYLE) + .font(EDGE_FONT) + .build(); graph.addEdge(ids.get(edge.getSource()), ids.get(edge.getTarget()), eAttrs); } - public static void printTraceTable(final Trace, CfaAction> trace, - final TableWriter writer) { + public static void printTraceTable( + final Trace, CfaAction> trace, final TableWriter writer) { final Set> allVars = new LinkedHashSet<>(); for (final CfaState state : trace.getStates()) { allVars.addAll(state.getState().getDecls()); @@ -132,7 +142,8 @@ public static void printTraceTable(final Trace, CfaAction> t writer.newRow(); if (i < trace.getActions().size()) { final StringBuilder sb = new StringBuilder(); - trace.getAction(i).getStmts() + trace.getAction(i) + .getStmts() .forEach(s -> sb.append(s.toString()).append(System.lineSeparator())); writer.cell(sb.toString(), nCols); writer.newRow(); diff --git a/subprojects/cfa/cfa/src/main/java/hu/bme/mit/theta/cfa/CFA.java b/subprojects/cfa/cfa/src/main/java/hu/bme/mit/theta/cfa/CFA.java index 49c2dc1efc..ecd5e3fa90 100644 --- a/subprojects/cfa/cfa/src/main/java/hu/bme/mit/theta/cfa/CFA.java +++ b/subprojects/cfa/cfa/src/main/java/hu/bme/mit/theta/cfa/CFA.java @@ -15,22 +15,18 @@ */ package hu.bme.mit.theta.cfa; -import static com.google.common.base.Preconditions.checkArgument; -import static com.google.common.base.Preconditions.checkNotNull; -import static com.google.common.base.Preconditions.checkState; +import static com.google.common.base.Preconditions.*; import static com.google.common.collect.ImmutableSet.toImmutableSet; import static java.lang.String.format; -import java.util.*; - import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableSet; - import hu.bme.mit.theta.common.Utils; import hu.bme.mit.theta.common.container.Containers; import hu.bme.mit.theta.core.decl.VarDecl; import hu.bme.mit.theta.core.stmt.Stmt; import hu.bme.mit.theta.core.utils.StmtUtils; +import java.util.*; /** * Represents an immutable Control Flow Automata (CFA). Use the builder class to create a new @@ -45,6 +41,7 @@ public final class CFA { private final Collection> vars; private final Collection locs; private final Collection edges; + private final Collection acceptingEdges; private CFA(final Builder builder) { initLoc = builder.initLoc; @@ -52,14 +49,18 @@ private CFA(final Builder builder) { errorLoc = Optional.ofNullable(builder.errorLoc); locs = ImmutableSet.copyOf(builder.locs); edges = ImmutableList.copyOf(builder.edges); - vars = edges.stream().flatMap(e -> StmtUtils.getVars(e.getStmt()).stream()) - .collect(toImmutableSet()); + vars = + edges.stream() + .flatMap(e -> StmtUtils.getVars(e.getStmt()).stream()) + .collect(toImmutableSet()); Set varNames = Containers.createSet(); for (var v : vars) { - checkArgument(!varNames.contains(v.getName()), + checkArgument( + !varNames.contains(v.getName()), "Variable with name '" + v.getName() + "' already exists in the CFA."); varNames.add(v.getName()); } + acceptingEdges = builder.acceptingEdges; } public Loc getInitLoc() { @@ -74,9 +75,7 @@ public Optional getErrorLoc() { return errorLoc; } - /** - * Get the variables appearing on the edges of the CFA. - */ + /** Get the variables appearing on the edges of the CFA. */ public Collection> getVars() { return vars; } @@ -89,15 +88,23 @@ public Collection getEdges() { return edges; } + public Collection getAcceptingEdges() { + return acceptingEdges; + } + public static Builder builder() { return new Builder(); } @Override public String toString() { - return Utils.lispStringBuilder("process").aligned().addAll(vars).body() + return Utils.lispStringBuilder("process") + .aligned() + .addAll(vars) + .body() .addAll(locs.stream().map(this::locToString)) - .addAll(edges.stream().map(this::edgeToString)).toString(); + .addAll(edges.stream().map(this::edgeToString)) + .toString(); } private String locToString(final Loc loc) { @@ -113,9 +120,11 @@ private String locToString(final Loc loc) { } private String edgeToString(final Edge edge) { - return Utils.lispStringBuilder("edge").add(edge.getSource().getName()) + return Utils.lispStringBuilder("edge") + .add(edge.getSource().getName()) .add(edge.getTarget().getName()) - .add(edge.getStmt()).toString(); + .add(edge.getStmt()) + .toString(); } public static final class Loc { @@ -185,6 +194,7 @@ public static final class Builder { private final Collection locs; private final Collection edges; + private final Collection acceptingEdges; private final Set locNames; @@ -196,6 +206,7 @@ private Builder() { locs = Containers.createSet(); locNames = Containers.createSet(); edges = new LinkedList<>(); + acceptingEdges = Containers.createSet(); built = false; } @@ -240,7 +251,8 @@ public void setErrorLoc(final Loc errorLoc) { public Loc createLoc(final String name) { checkNotBuilt(); - checkArgument(!locNames.contains(name), + checkArgument( + !locNames.contains(name), "Location with name '" + name + "' already exists in the CFA."); final Loc loc = new Loc(name); locs.add(loc); @@ -264,14 +276,23 @@ public Edge createEdge(final Loc source, final Loc target, final Stmt stmt) { return edge; } + public void setAcceptingEdge(final Edge acceptingEdge) { + checkNotBuilt(); + checkNotNull(acceptingEdge); + checkArgument(edges.contains(acceptingEdge), "Accepting edge not present in CFA."); + acceptingEdges.add(acceptingEdge); + } + public CFA build() { checkState(initLoc != null, "Initial location must be set."); if (finalLoc != null) { - checkState(finalLoc.getOutEdges().isEmpty(), + checkState( + finalLoc.getOutEdges().isEmpty(), "Final location cannot have outgoing edges."); } if (errorLoc != null) { - checkState(errorLoc.getOutEdges().isEmpty(), + checkState( + errorLoc.getOutEdges().isEmpty(), "Error location cannot have outgoing edges."); } built = true; @@ -282,5 +303,4 @@ private void checkNotBuilt() { checkState(!built, "A CFA was already built."); } } - } diff --git a/subprojects/cfa/cfa/src/main/kotlin/hu/bme/mit/theta/cfa/CFAVarChanger.kt b/subprojects/cfa/cfa/src/main/java/hu/bme/mit/theta/cfa/CFAVarChanger.kt similarity index 57% rename from subprojects/cfa/cfa/src/main/kotlin/hu/bme/mit/theta/cfa/CFAVarChanger.kt rename to subprojects/cfa/cfa/src/main/java/hu/bme/mit/theta/cfa/CFAVarChanger.kt index e3260c6bce..5a58186c9a 100644 --- a/subprojects/cfa/cfa/src/main/kotlin/hu/bme/mit/theta/cfa/CFAVarChanger.kt +++ b/subprojects/cfa/cfa/src/main/java/hu/bme/mit/theta/cfa/CFAVarChanger.kt @@ -13,29 +13,27 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package hu.bme.mit.theta.cfa import hu.bme.mit.theta.core.decl.VarDecl import hu.bme.mit.theta.core.utils.changeVars /** - * Extension function for CFA. Creates a new CFA which looks exactly the same, but any variable whose name is present in - * the parameter gets replaced to the associated instance. + * Extension function for CFA. Creates a new CFA which looks exactly the same, but any variable + * whose name is present in the parameter gets replaced to the associated instance. */ fun CFA.copyWithReplacingVars(variableMapping: Map>): CFA { - val builder = CFA.builder() - val locationMap: Map = locs.associate { it.name to builder.createLoc(it.name) } - builder.initLoc = locationMap[initLoc.name] - if (errorLoc.isPresent) - builder.errorLoc = locationMap[errorLoc.get().name] - if (finalLoc.isPresent) - builder.finalLoc = locationMap[finalLoc.get().name] - edges.forEach { - builder.createEdge( - locationMap[it.source.name], locationMap[it.target.name], - it.stmt.changeVars(variableMapping) - ) - } - return builder.build() + val builder = CFA.builder() + val locationMap: Map = locs.associate { it.name to builder.createLoc(it.name) } + builder.initLoc = locationMap[initLoc.name] + if (errorLoc.isPresent) builder.errorLoc = locationMap[errorLoc.get().name] + if (finalLoc.isPresent) builder.finalLoc = locationMap[finalLoc.get().name] + edges.forEach { + builder.createEdge( + locationMap[it.source.name], + locationMap[it.target.name], + it.stmt.changeVars(variableMapping), + ) + } + return builder.build() } diff --git a/subprojects/common/analysis/src/main/java/hu/bme/mit/theta/analysis/unit/UnitInitFunc.java b/subprojects/common/analysis/src/main/java/hu/bme/mit/theta/analysis/unit/UnitInitFunc.java index 8efb0961b9..87326268f1 100644 --- a/subprojects/common/analysis/src/main/java/hu/bme/mit/theta/analysis/unit/UnitInitFunc.java +++ b/subprojects/common/analysis/src/main/java/hu/bme/mit/theta/analysis/unit/UnitInitFunc.java @@ -15,21 +15,19 @@ */ package hu.bme.mit.theta.analysis.unit; -import static com.google.common.base.Preconditions.checkNotNull; +import com.google.common.collect.ImmutableList; +import hu.bme.mit.theta.analysis.InitFunc; import java.util.Collection; -import com.google.common.collect.ImmutableList; - -import hu.bme.mit.theta.analysis.InitFunc; +import static com.google.common.base.Preconditions.checkNotNull; -final class UnitInitFunc implements InitFunc { +public final class UnitInitFunc implements InitFunc { private static final UnitInitFunc INSTANCE = new UnitInitFunc(); private static final Collection RESULT = ImmutableList.of(UnitState.getInstance()); - private UnitInitFunc() { - } + private UnitInitFunc() {} public static UnitInitFunc getInstance() { return INSTANCE; @@ -40,5 +38,4 @@ public Collection getInitStates(final UnitPrec prec) { checkNotNull(prec); return RESULT; } - } diff --git a/subprojects/common/common/build.gradle.kts b/subprojects/common/common/build.gradle.kts index 5f55ec589f..971b6106d4 100644 --- a/subprojects/common/common/build.gradle.kts +++ b/subprojects/common/common/build.gradle.kts @@ -15,4 +15,9 @@ */ plugins { id("java-common") + id("kotlin-common") +} + +dependencies { + implementation(Deps.nuprocess) } diff --git a/subprojects/common/common/src/main/java/hu/bme/mit/theta/common/process/SimpleProcessRunner.kt b/subprojects/common/common/src/main/java/hu/bme/mit/theta/common/process/SimpleProcessRunner.kt new file mode 100644 index 0000000000..a7964e735e --- /dev/null +++ b/subprojects/common/common/src/main/java/hu/bme/mit/theta/common/process/SimpleProcessRunner.kt @@ -0,0 +1,66 @@ +/* + * Copyright 2024 Budapest University of Technology and Economics + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package hu.bme.mit.theta.common.process + +import com.zaxxer.nuprocess.NuAbstractProcessHandler +import com.zaxxer.nuprocess.NuProcessBuilder +import java.nio.ByteBuffer +import java.util.concurrent.TimeUnit + +object SimpleProcessRunner { + + fun run(cmd: String, timeout: Long = 0): String { + val processBuilder = NuProcessBuilder(cmd.split(" ")) + val handler = ProcessHandler() + processBuilder.setProcessListener(handler) + processBuilder.start().waitFor(timeout, TimeUnit.SECONDS) + return handler.output + } + + class ProcessHandler : NuAbstractProcessHandler() { + var output: String = "" + var error: String = "" + + override fun onStdout(buffer: ByteBuffer?, closed: Boolean) { + if (!closed && buffer != null) { + val bytes = ByteArray(buffer.remaining()) + buffer[bytes] + output = String(bytes) + } + } + + override fun onStderr(buffer: ByteBuffer?, closed: Boolean) { + if (!closed && buffer != null) { + val bytes = ByteArray(buffer.remaining()) + buffer[bytes] + error = "$error\n${String(bytes)}" + } + } + + override fun onExit(statusCode: Int) { + if (statusCode == Integer.MIN_VALUE) { + throw ProcessException("Nuprocess launch error") + } + if (statusCode != 0) { + throw ProcessException( + if (error != "") error else "Process exit with non-zero code: $statusCode" + ) + } + } + } +} + +class ProcessException(err: String) : Exception(err) diff --git a/subprojects/common/ltl-cli/build.gradle.kts b/subprojects/common/ltl-cli/build.gradle.kts new file mode 100644 index 0000000000..9d77f35f1f --- /dev/null +++ b/subprojects/common/ltl-cli/build.gradle.kts @@ -0,0 +1,23 @@ +/* + * Copyright 2024 Budapest University of Technology and Economics + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +plugins { + id("kotlin-common") + id("cli-tool") +} + +dependencies { + implementation(project(":theta-analysis")) +} diff --git a/subprojects/common/ltl-cli/src/main/kotlin/common/ltl/cli/LtlCliOptions.kt b/subprojects/common/ltl-cli/src/main/kotlin/common/ltl/cli/LtlCliOptions.kt new file mode 100644 index 0000000000..2a0ab0b3b0 --- /dev/null +++ b/subprojects/common/ltl-cli/src/main/kotlin/common/ltl/cli/LtlCliOptions.kt @@ -0,0 +1,44 @@ +/* + * Copyright 2024 Budapest University of Technology and Economics + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package hu.bme.mit.theta.common.ltl.cli + +import com.github.ajalt.clikt.parameters.groups.OptionGroup +import com.github.ajalt.clikt.parameters.options.default +import com.github.ajalt.clikt.parameters.options.option +import com.github.ajalt.clikt.parameters.options.required +import com.github.ajalt.clikt.parameters.types.enum +import hu.bme.mit.theta.analysis.algorithm.loopchecker.abstraction.LoopcheckerSearchStrategy +import hu.bme.mit.theta.analysis.algorithm.loopchecker.refinement.LDGTraceCheckerStrategy + +class LtlCliOptions : + OptionGroup(name = "LTL options", help = "Options related to LTL property checking") { + val ltlExpression by option(help = "LTL expression to check").required() + val ltl2BuchiCommand by + option( + help = + "A command that runs on your system. The expression gets appended at the end of it." + + "For example, if you use SPOT, this should be: `spot ltl2tgba -f`" + ) + .required() + val searchStrategy by + option(help = "Which strategy to use for search") + .enum() + .default(LoopcheckerSearchStrategy.GDFS) + val refinerStrategy by + option(help = "Which strategy to use for search") + .enum() + .default(LDGTraceCheckerStrategy.MILANO) +} diff --git a/subprojects/common/ltl/build.gradle.kts b/subprojects/common/ltl/build.gradle.kts new file mode 100644 index 0000000000..6624b9f823 --- /dev/null +++ b/subprojects/common/ltl/build.gradle.kts @@ -0,0 +1,32 @@ +/* + * Copyright 2024 Budapest University of Technology and Economics + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +plugins { + id("java-common") + id("kotlin-common") + id("antlr-grammar") +} + +dependencies { + implementation(project(":theta-common")) + implementation(project(":theta-core")) + implementation(project(":theta-solver")) + implementation(project(":theta-analysis")) + implementation(project(":theta-cfa")) + api(project(":theta-cfa-analysis")) + testImplementation(project(":theta-solver-z3-legacy")) + testImplementation(project(":theta-xsts-analysis")) + testImplementation(project(":theta-xsts")) +} diff --git a/subprojects/common/ltl/src/main/antlr/LTLGrammar.g4 b/subprojects/common/ltl/src/main/antlr/LTLGrammar.g4 new file mode 100644 index 0000000000..e133f146ff --- /dev/null +++ b/subprojects/common/ltl/src/main/antlr/LTLGrammar.g4 @@ -0,0 +1,138 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ + +grammar LTLGrammar; + +model: + rules+=implyExpression*; + +implyExpression: + ops+=orExpr (IMPLIES ops+=orExpr)? +; + +orExpr: + ops+=andExpr (OR ops+=andExpr)* +; + +andExpr: + ops+=notExpr (AND ops+=notExpr)* +; + +notExpr: + binaryLtlExpr| + NOT ops+=notExpr +; + +binaryLtlExpr: + ltlExpr | + ops+=binaryLtlExpr type=binaryLtlOp ops+=binaryLtlExpr; + +binaryLtlOp: + M_OP | W_OP | U_OP | R_OP; + +ltlExpr: + eqExpr | + type=ltlOp ops+=ltlExpr +; + +ltlOp: + F_OP|G_OP|X_OP + ; + +eqExpr: + ops+=relationExpr (oper=eqOperator ops+=relationExpr)? +; + +eqOperator: + EQ|NEQ +; + +relationExpr: + ops+=additiveExpr (oper=relationOperator ops+=additiveExpr)? +; + +relationOperator: + LT|GT|LEQ|GEQ +; + +additiveExpr: + ops+=multiplicativeExpr (opers+=additiveOperator ops+=multiplicativeExpr)* +; + +additiveOperator: + PLUS|MINUS +; + +multiplicativeExpr: + ops+=negExpr (opers+=multiplicativeOperator ops+=negExpr)* +; + +multiplicativeOperator: + MUL|DIV|MOD +; + +negExpr: + primaryExpr| + MINUS ops+=negExpr +; + +primaryExpr: + boolLitExpr| + intLitExpr| + enumLitExpr| + parenExpr +; + +boolLitExpr: + value=BOOLLIT +; + +parenExpr: + LPAREN ops+=implyExpression RPAREN | variable +; + +intLitExpr: + value=INTLIT +; + +enumLitExpr: + type=ID DOT lit=ID +; + +variable: + name=ID +; + +AND: 'and' | '&&'; +OR: 'or' | '|' | '||'; +IMPLIES: '->' | '=>'; +NOT: 'not' | '!'; +EQ: '=' | '=='; +NEQ: '/=' | '!='; +LT: '<'; +GT: '>'; +LEQ: '<='; +GEQ: '>='; +PLUS: '+'; +MINUS: '-'; +MUL: '*'; +DIV: '/'; +MOD: '%'; +LPAREN: '('; +RPAREN: ')'; +F_OP: 'F'; +G_OP: 'G'; +U_OP: 'U'; +W_OP: 'W'; +M_OP: 'M'; +R_OP: 'R'; +X_OP: 'X'; +INTLIT: [0-9]+; +BOOLLIT: 'true' | 'false'; +ID: [a-zA-Z][a-zA-Z0-9_]*; +DOT: '.'; +WS: (' '| '\t' | '\n' | '\r') -> skip; + diff --git a/subprojects/common/ltl/src/main/kotlin/hu/bme/mit/theta/common/cfa/buchi/Ltl2BuchiTransformer.kt b/subprojects/common/ltl/src/main/kotlin/hu/bme/mit/theta/common/cfa/buchi/Ltl2BuchiTransformer.kt new file mode 100644 index 0000000000..5422c540f7 --- /dev/null +++ b/subprojects/common/ltl/src/main/kotlin/hu/bme/mit/theta/common/cfa/buchi/Ltl2BuchiTransformer.kt @@ -0,0 +1,27 @@ +/* + * Copyright 2024 Budapest University of Technology and Economics + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package hu.bme.mit.theta.common.cfa.buchi + +import hu.bme.mit.theta.cfa.CFA +import hu.bme.mit.theta.core.decl.VarDecl + +fun interface Ltl2BuchiTransformer { + + fun transform(ltl: String, variableMapping: Map>): CFA + + fun transform(ltl: String, variables: Collection>): CFA = + transform(ltl, variables.associateBy { it.name }) +} diff --git a/subprojects/common/ltl/src/main/kotlin/hu/bme/mit/theta/common/cfa/buchi/hoa/APGeneratorVisitor.kt b/subprojects/common/ltl/src/main/kotlin/hu/bme/mit/theta/common/cfa/buchi/hoa/APGeneratorVisitor.kt new file mode 100644 index 0000000000..9668c2f3fa --- /dev/null +++ b/subprojects/common/ltl/src/main/kotlin/hu/bme/mit/theta/common/cfa/buchi/hoa/APGeneratorVisitor.kt @@ -0,0 +1,190 @@ +/* + * Copyright 2024 Budapest University of Technology and Economics + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package hu.bme.mit.theta.common.cfa.buchi.hoa + +import hu.bme.mit.theta.core.decl.VarDecl +import hu.bme.mit.theta.core.type.Expr +import hu.bme.mit.theta.core.type.abstracttype.AbstractExprs +import hu.bme.mit.theta.core.type.booltype.BoolExprs +import hu.bme.mit.theta.core.type.booltype.BoolType +import hu.bme.mit.theta.core.type.enumtype.EnumLitExpr +import hu.bme.mit.theta.core.type.enumtype.EnumType +import hu.bme.mit.theta.core.type.inttype.IntExprs +import hu.bme.mit.theta.core.type.inttype.IntType +import hu.bme.mit.theta.ltl.dsl.gen.LTLGrammarBaseVisitor +import hu.bme.mit.theta.ltl.dsl.gen.LTLGrammarParser +import hu.bme.mit.theta.ltl.dsl.gen.LTLGrammarParser.* + +class APGeneratorVisitor( + private val vars: Map>, + private val enumTypes: Map, +) : LTLGrammarBaseVisitor?>() { + + override fun visitModel(ctx: ModelContext): Expr<*> { + return super.visitModel(ctx)!! + } + + override fun visitImplyExpression(ctx: ImplyExpressionContext): Expr<*> { + return if (ctx.ops.size > 1) { + BoolExprs.Imply( + visitOrExpr(ctx.ops[0]) as Expr, + visitOrExpr(ctx.ops[1]) as Expr, + ) + } else visitOrExpr(ctx.ops[0]) + } + + override fun visitOrExpr(ctx: LTLGrammarParser.OrExprContext): Expr<*> { + if (ctx.ops.size == 1) return visitAndExpr(ctx.ops[0]) + val ops: MutableList> = ArrayList() + for (child in ctx.ops) { + ops.add(visitAndExpr(child)) + } + return BoolExprs.Or(ops) + } + + override fun visitAndExpr(ctx: LTLGrammarParser.AndExprContext): Expr { + if (ctx.ops.size == 1) return visitNotExpr(ctx.ops[0]) + val ops: MutableList> = ArrayList() + for (child in ctx.ops) { + ops.add(visitNotExpr(child)) + } + return BoolExprs.And(ops) + } + + override fun visitNotExpr(ctx: LTLGrammarParser.NotExprContext): Expr { + return if (ctx.ops.size > 0) BoolExprs.Not(visitNotExpr(ctx.ops[0])) + else visitBinaryLtlExpr(ctx.binaryLtlExpr()) as Expr + } + + override fun visitBinaryLtlExpr(ctx: BinaryLtlExprContext): Expr<*> { + return visitLtlExpr(ctx.ltlExpr()) + } + + override fun visitBinaryLtlOp(ctx: BinaryLtlOpContext): Expr<*> { + return super.visitBinaryLtlOp(ctx)!! + } + + override fun visitLtlExpr(ctx: LtlExprContext): Expr<*> { + return visitEqExpr(ctx.eqExpr()) + } + + override fun visitLtlOp(ctx: LtlOpContext): Expr<*> { + return super.visitLtlOp(ctx)!! + } + + override fun visitEqExpr(ctx: EqExprContext): Expr<*> { + return if (ctx.ops.size > 1) { + if (ctx.oper.EQ() != null) + AbstractExprs.Eq(visitRelationExpr(ctx.ops[0]), visitRelationExpr(ctx.ops[1])) + else AbstractExprs.Neq(visitRelationExpr(ctx.ops[0]), visitRelationExpr(ctx.ops[1])) + } else visitRelationExpr(ctx.ops[0]) + } + + override fun visitEqOperator(ctx: EqOperatorContext): Expr<*> { + return super.visitEqOperator(ctx)!! + } + + override fun visitRelationExpr(ctx: LTLGrammarParser.RelationExprContext): Expr<*> { + return if (ctx.ops.size > 1) { + if (ctx.oper.LEQ() != null) { + AbstractExprs.Leq(visitAdditiveExpr(ctx.ops[0]), visitAdditiveExpr(ctx.ops[1])) + } else if (ctx.oper.GEQ() != null) { + AbstractExprs.Geq(visitAdditiveExpr(ctx.ops[0]), visitAdditiveExpr(ctx.ops[1])) + } else if (ctx.oper.LT() != null) { + AbstractExprs.Lt(visitAdditiveExpr(ctx.ops[0]), visitAdditiveExpr(ctx.ops[1])) + } else AbstractExprs.Gt(visitAdditiveExpr(ctx.ops[0]), visitAdditiveExpr(ctx.ops[1])) + } else visitAdditiveExpr(ctx.ops[0]) + } + + override fun visitRelationOperator(ctx: RelationOperatorContext): Expr<*> { + return super.visitRelationOperator(ctx)!! + } + + override fun visitAdditiveExpr(ctx: LTLGrammarParser.AdditiveExprContext): Expr<*> { + var res = visitMultiplicativeExpr(ctx.ops[0]) + for (i in 1 until ctx.ops.size) { + res = + if (ctx.opers[i - 1].PLUS() != null) { + AbstractExprs.Add(res, visitMultiplicativeExpr(ctx.ops[i])) + } else { + AbstractExprs.Sub(res, visitMultiplicativeExpr(ctx.ops[i])) + } + } + return res + } + + override fun visitAdditiveOperator(ctx: AdditiveOperatorContext): Expr<*> { + return super.visitAdditiveOperator(ctx)!! + } + + override fun visitMultiplicativeExpr(ctx: LTLGrammarParser.MultiplicativeExprContext): Expr<*> { + var res = visitNegExpr(ctx.ops[0]) + for (i in 1 until ctx.ops.size) { + res = + if (ctx.opers[i - 1].DIV() != null) { + AbstractExprs.Div(res, visitNegExpr(ctx.ops[i])) + } else if (ctx.opers[i - 1].MOD() != null) { + IntExprs.Mod(res as Expr, visitNegExpr(ctx.ops[i]) as Expr) + } else { + AbstractExprs.Mul(res, visitNegExpr(ctx.ops[i])) + } + } + return res + } + + override fun visitMultiplicativeOperator(ctx: MultiplicativeOperatorContext): Expr<*> { + return super.visitMultiplicativeOperator(ctx)!! + } + + override fun visitNegExpr(ctx: LTLGrammarParser.NegExprContext): Expr<*> { + return if (ctx.ops.size > 0) { + AbstractExprs.Neg(visitNegExpr(ctx.ops[0])) + } else visitPrimaryExpr(ctx.primaryExpr()) + } + + override fun visitPrimaryExpr(ctx: LTLGrammarParser.PrimaryExprContext): Expr<*> { + return if (ctx.boolLitExpr() != null) { + visitBoolLitExpr(ctx.boolLitExpr()) + } else if (ctx.intLitExpr() != null) { + visitIntLitExpr(ctx.intLitExpr()) + } else if (ctx.enumLitExpr() != null) { + visitEnumLitExpr(ctx.enumLitExpr()) + } else visitParenExpr(ctx.parenExpr()) + } + + override fun visitBoolLitExpr(ctx: BoolLitExprContext): Expr<*> { + return if (ctx.value.text == "true") BoolExprs.True() else BoolExprs.False() + } + + override fun visitParenExpr(ctx: LTLGrammarParser.ParenExprContext): Expr<*> { + return if (ctx.variable() != null) visitVariable(ctx.variable()) + else visitImplyExpression(ctx.ops[0]) + } + + override fun visitIntLitExpr(ctx: LTLGrammarParser.IntLitExprContext): Expr<*> { + return IntExprs.Int(ctx.value.text.toInt()) + } + + override fun visitEnumLitExpr(ctx: EnumLitExprContext): Expr<*> { + return EnumLitExpr.of(enumTypes[ctx.type.text], ctx.lit.text) + } + + override fun visitVariable(ctx: LTLGrammarParser.VariableContext): Expr<*> { + val decl = vars[ctx.name.text] + if (decl == null) println("Variable [" + ctx.name.text + "] not found") + return decl!!.ref + } +} diff --git a/subprojects/common/ltl/src/main/kotlin/hu/bme/mit/theta/common/cfa/buchi/hoa/BuchiBuilder.kt b/subprojects/common/ltl/src/main/kotlin/hu/bme/mit/theta/common/cfa/buchi/hoa/BuchiBuilder.kt new file mode 100644 index 0000000000..d4e5df5b8a --- /dev/null +++ b/subprojects/common/ltl/src/main/kotlin/hu/bme/mit/theta/common/cfa/buchi/hoa/BuchiBuilder.kt @@ -0,0 +1,189 @@ +/* + * Copyright 2024 Budapest University of Technology and Economics + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package hu.bme.mit.theta.common.cfa.buchi.hoa + +import hu.bme.mit.theta.cfa.CFA +import hu.bme.mit.theta.common.logging.Logger +import hu.bme.mit.theta.core.stmt.Stmts +import hu.bme.mit.theta.core.type.Expr +import hu.bme.mit.theta.core.type.booltype.BoolExprs +import hu.bme.mit.theta.core.type.booltype.BoolType +import jhoafparser.ast.AtomAcceptance +import jhoafparser.ast.AtomLabel +import jhoafparser.ast.BooleanExpression +import jhoafparser.consumer.HOAConsumer +import jhoafparser.consumer.HOAConsumerException +import java.util.function.Consumer + +class BuchiBuilder +internal constructor( + private val logger: Logger, + private val swappedExpressions: Map>, +) : HOAConsumer { + + private val builder: CFA.Builder = CFA.builder() + private var initLocNumber: Int? = null + private var aps: MutableList? = null + private val locations: MutableMap = HashMap() + + fun build(): CFA { + return builder.build() + } + + private fun getOrCreateLocation(locName: Int): CFA.Loc { + return locations.computeIfAbsent(locName) { i: Int -> builder.createLoc(i.toString()) } + } + + private fun apBoolExpressionToInternal( + booleanExpression: BooleanExpression + ): Expr { + return when (booleanExpression.type) { + BooleanExpression.Type.EXP_AND -> + BoolExprs.And( + apBoolExpressionToInternal(booleanExpression.left), + apBoolExpressionToInternal(booleanExpression.right), + ) + + BooleanExpression.Type.EXP_OR -> + BoolExprs.Or( + apBoolExpressionToInternal(booleanExpression.left), + apBoolExpressionToInternal(booleanExpression.right), + ) + + BooleanExpression.Type.EXP_NOT -> + BoolExprs.Not(apBoolExpressionToInternal(booleanExpression.left)) + BooleanExpression.Type.EXP_TRUE -> BoolExprs.True() + BooleanExpression.Type.EXP_ATOM -> + swappedExpressions[aps!![booleanExpression.atom.toString().toInt()]]!! + else -> BoolExprs.False() + } + } + + override fun parserResolvesAliases(): Boolean { + return false + } + + override fun notifyHeaderStart(s: String) { + logger.write(Logger.Level.VERBOSE, "HOA consumer header: %s%n", s) + } + + override fun setNumberOfStates(i: Int) { + logger.write(Logger.Level.VERBOSE, "HOA automaton has %d states%n", i) + } + + @Throws(HOAConsumerException::class) + override fun addStartStates(list: List) { + if (list.isEmpty()) return + if (list.size != 1 || initLocNumber != null) + throw HOAConsumerException("HOA automaton should have exactly 1 starting location%n") + initLocNumber = list[0] + } + + override fun addAlias(s: String, booleanExpression: BooleanExpression) { + // currently does not get called by the Owl library + } + + override fun setAPs(list: List) { + if (aps == null) aps = java.util.List.copyOf(list) else aps!!.addAll(list) + } + + @Throws(HOAConsumerException::class) + override fun setAcceptanceCondition( + i: Int, + booleanExpression: BooleanExpression, + ) { + logger.write(Logger.Level.VERBOSE, "Acceptance condition: %s%n", booleanExpression) + } + + override fun provideAcceptanceName(s: String, list: List) { + logger.write(Logger.Level.VERBOSE, "Acceptance name received: %s%n", s) + list.forEach( + Consumer { o: Any? -> + logger.write(Logger.Level.VERBOSE, "\tobject under acceptance: %s%n", o) + } + ) + } + + @Throws(HOAConsumerException::class) + override fun setName(s: String) { + logger.write(Logger.Level.VERBOSE, "Automaton named {}%n", s) + } + + override fun setTool(s: String, s1: String) { + logger.write(Logger.Level.VERBOSE, "Tool named %s %s%n", s, s1) + } + + override fun addProperties(list: List) { + if (list.isEmpty()) return + logger.write(Logger.Level.VERBOSE, "Properties:%n") + list.forEach(Consumer { prop: String? -> logger.write(Logger.Level.VERBOSE, "%s", prop) }) + logger.write(Logger.Level.VERBOSE, "%n") + } + + override fun addMiscHeader(s: String, list: List) { + // we don't really care for these yet + } + + override fun notifyBodyStart() { + // no action needed + } + + override fun addState( + i: Int, + s: String?, + booleanExpression: BooleanExpression?, + list: List?, + ) { + getOrCreateLocation(i) + } + + override fun addEdgeImplicit(i: Int, list: List, list1: List) { + TODO("This should only be called for state-based acceptance which is not yet supported") + } + + @Throws(HOAConsumerException::class) + override fun addEdgeWithLabel( + i: Int, + booleanExpression: BooleanExpression, + list: List, + list1: List?, + ) { + val from = getOrCreateLocation(i) + val to = getOrCreateLocation(list[0]) + val edge = + builder.createEdge(from, to, Stmts.Assume(apBoolExpressionToInternal(booleanExpression))) + if (list1 != null && !list1.isEmpty()) builder.setAcceptingEdge(edge) + } + + override fun notifyEndOfState(i: Int) { + // no action needed + } + + @Throws(HOAConsumerException::class) + override fun notifyEnd() { + if (initLocNumber == null) throw HOAConsumerException("No initial location named") + builder.initLoc = locations[initLocNumber] + } + + override fun notifyAbort() { + // never gets called yet + } + + @Throws(HOAConsumerException::class) + override fun notifyWarning(s: String) { + throw HOAConsumerException(s) + } +} diff --git a/subprojects/common/ltl/src/main/kotlin/hu/bme/mit/theta/common/cfa/buchi/hoa/ExternalLtl2Hoaf.kt b/subprojects/common/ltl/src/main/kotlin/hu/bme/mit/theta/common/cfa/buchi/hoa/ExternalLtl2Hoaf.kt new file mode 100644 index 0000000000..4b4ab5b9ae --- /dev/null +++ b/subprojects/common/ltl/src/main/kotlin/hu/bme/mit/theta/common/cfa/buchi/hoa/ExternalLtl2Hoaf.kt @@ -0,0 +1,25 @@ +/* + * Copyright 2024 Budapest University of Technology and Economics + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package hu.bme.mit.theta.common.cfa.buchi.hoa + +import hu.bme.mit.theta.common.process.SimpleProcessRunner + +class ExternalLtl2Hoaf(private val cmd: String) : Ltl2Hoaf { + + override fun transform(ltl: String): String { + return SimpleProcessRunner.run("$cmd '$ltl'", 20) + } +} diff --git a/subprojects/common/ltl/src/main/kotlin/hu/bme/mit/theta/common/cfa/buchi/hoa/LTLExprVisitor.kt b/subprojects/common/ltl/src/main/kotlin/hu/bme/mit/theta/common/cfa/buchi/hoa/LTLExprVisitor.kt new file mode 100644 index 0000000000..6d4b8b42e0 --- /dev/null +++ b/subprojects/common/ltl/src/main/kotlin/hu/bme/mit/theta/common/cfa/buchi/hoa/LTLExprVisitor.kt @@ -0,0 +1,233 @@ +/* + * Copyright 2024 Budapest University of Technology and Economics + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package hu.bme.mit.theta.common.cfa.buchi.hoa + +import hu.bme.mit.theta.ltl.dsl.gen.LTLGrammarBaseVisitor +import hu.bme.mit.theta.ltl.dsl.gen.LTLGrammarParser +import hu.bme.mit.theta.ltl.dsl.gen.LTLGrammarParser.* +import org.antlr.v4.runtime.ParserRuleContext + +/** + * Returns whether an AST element represents an LTL expression that has no temporal operators. We + * need to convert all these into atomic propositions that Spot can interpret. So in the AST, the F + * G(not err), the largest expression (not err) will be converted to atomic proposition ap0. The + * resulting LTL expression, which now Spot can interpret, is F G ap0. Whether there is an LTL + * expression, is returned by LTLExprVisitor. The link is stored in APGeneratorVisitor's result. + */ +object LTLExprVisitor : LTLGrammarBaseVisitor() { + + var ltl: HashMap = HashMap() + + override fun visitModel(ctx: ModelContext): Boolean { + return super.visitModel(ctx)!! + } + + override fun visitImplyExpression(ctx: ImplyExpressionContext): Boolean { + if (ltl[ctx] != null) return ltl[ctx]!! + for (op in ctx.ops) { + if (visitOrExpr(op)) { + ltl[ctx] = true + return true + } + } + ltl[ctx] = false + return false + } + + override fun visitAndExpr(ctx: LTLGrammarParser.AndExprContext): Boolean { + if (ltl[ctx] != null) return ltl[ctx]!! + for (op in ctx.ops) { + if (visitNotExpr(op)) { + ltl[ctx] = true + return true + } + } + ltl[ctx] = false + return false + } + + override fun visitNotExpr(ctx: LTLGrammarParser.NotExprContext): Boolean { + if (ltl[ctx] != null) return ltl[ctx]!! + for (op in ctx.ops) { + if (visitNotExpr(op)) { + ltl[ctx] = true + return true + } + } + if (ctx.binaryLtlExpr() != null && visitBinaryLtlExpr(ctx.binaryLtlExpr())) { + ltl[ctx] = true + return true + } + ltl[ctx] = false + return false + } + + override fun visitBinaryLtlExpr(ctx: BinaryLtlExprContext): Boolean { + if (ltl[ctx] != null) return ltl[ctx]!! + if (ctx.type != null) { + ltl[ctx] = true + return true + } + val child = visitLtlExpr(ctx.ltlExpr()) + ltl[ctx] = child + return child + } + + override fun visitBinaryLtlOp(ctx: BinaryLtlOpContext): Boolean { + return false + } + + override fun visitLtlExpr(ctx: LtlExprContext): Boolean { + if (ltl[ctx] != null) return ltl[ctx]!! + if (ctx.type != null) { + ltl[ctx] = true + return true + } + val child = visitEqExpr(ctx.eqExpr()) + ltl[ctx] = child + return child + } + + override fun visitLtlOp(ctx: LtlOpContext): Boolean { + return false + } + + override fun visitEqExpr(ctx: EqExprContext): Boolean { + if (ltl[ctx] != null) return ltl[ctx]!! + for (op in ctx.ops) { + if (visitRelationExpr(op)) { + ltl[ctx] = true + return true + } + } + ltl[ctx] = false + return false + } + + override fun visitEqOperator(ctx: EqOperatorContext): Boolean { + return false + } + + override fun visitRelationExpr(ctx: LTLGrammarParser.RelationExprContext): Boolean { + if (ltl[ctx] != null) return ltl[ctx]!! + for (op in ctx.ops) { + if (visitAdditiveExpr(op)) { + ltl[ctx] = true + return true + } + } + ltl[ctx] = false + return false + } + + override fun visitRelationOperator(ctx: RelationOperatorContext): Boolean { + return false + } + + override fun visitAdditiveExpr(ctx: LTLGrammarParser.AdditiveExprContext): Boolean { + if (ltl[ctx] != null) return ltl[ctx]!! + for (op in ctx.ops) { + if (visitMultiplicativeExpr(op)) { + ltl[ctx] = true + return true + } + } + ltl[ctx] = false + return false + } + + override fun visitAdditiveOperator(ctx: AdditiveOperatorContext): Boolean { + return false + } + + override fun visitMultiplicativeExpr(ctx: LTLGrammarParser.MultiplicativeExprContext): Boolean { + if (ltl[ctx] != null) return ltl[ctx]!! + for (op in ctx.ops) { + if (visitNegExpr(op)) { + ltl[ctx] = true + return true + } + } + ltl[ctx] = false + return false + } + + override fun visitMultiplicativeOperator(ctx: MultiplicativeOperatorContext): Boolean { + return false + } + + override fun visitNegExpr(ctx: LTLGrammarParser.NegExprContext): Boolean { + if (ltl[ctx] != null) return ltl[ctx]!! + for (op in ctx.ops) { + if (visitNegExpr(op)) { + ltl[ctx] = true + return true + } + } + if (ctx.primaryExpr() != null && visitPrimaryExpr(ctx.primaryExpr())) { + ltl[ctx] = true + return true + } + ltl[ctx] = false + return false + } + + override fun visitPrimaryExpr(ctx: LTLGrammarParser.PrimaryExprContext): Boolean { + if (ltl[ctx] != null) return ltl[ctx]!! + var child = false + if (ctx.boolLitExpr() != null) child = visitBoolLitExpr(ctx.boolLitExpr()) + if (ctx.intLitExpr() != null) child = visitIntLitExpr(ctx.intLitExpr()) + if (ctx.parenExpr() != null) child = visitParenExpr(ctx.parenExpr()) + ltl[ctx] = child + return child + } + + override fun visitBoolLitExpr(ctx: BoolLitExprContext): Boolean { + return false + } + + override fun visitParenExpr(ctx: LTLGrammarParser.ParenExprContext): Boolean { + if (ltl[ctx] != null) return ltl[ctx]!! + for (op in ctx.ops) { + if (visitImplyExpression(op)) { + ltl[ctx] = true + return true + } + } + ltl[ctx] = false + return false + } + + override fun visitIntLitExpr(ctx: LTLGrammarParser.IntLitExprContext): Boolean { + return false + } + + override fun visitVariable(ctx: LTLGrammarParser.VariableContext): Boolean { + return false + } + + override fun visitOrExpr(ctx: LTLGrammarParser.OrExprContext): Boolean { + if (ltl[ctx] != null) return ltl[ctx]!! + for (op in ctx.ops) { + if (visitAndExpr(op)) { + ltl[ctx] = true + return true + } + } + ltl[ctx] = false + return false + } +} diff --git a/subprojects/common/ltl/src/main/kotlin/hu/bme/mit/theta/common/cfa/buchi/hoa/Ltl2BuchiThroughHoaf.kt b/subprojects/common/ltl/src/main/kotlin/hu/bme/mit/theta/common/cfa/buchi/hoa/Ltl2BuchiThroughHoaf.kt new file mode 100644 index 0000000000..6244119cf5 --- /dev/null +++ b/subprojects/common/ltl/src/main/kotlin/hu/bme/mit/theta/common/cfa/buchi/hoa/Ltl2BuchiThroughHoaf.kt @@ -0,0 +1,46 @@ +/* + * Copyright 2024 Budapest University of Technology and Economics + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package hu.bme.mit.theta.common.cfa.buchi.hoa + +import hu.bme.mit.theta.cfa.CFA +import hu.bme.mit.theta.common.cfa.buchi.Ltl2BuchiTransformer +import hu.bme.mit.theta.common.logging.Logger +import hu.bme.mit.theta.core.decl.VarDecl +import hu.bme.mit.theta.core.type.enumtype.EnumType +import hu.bme.mit.theta.ltl.dsl.gen.LTLGrammarLexer +import hu.bme.mit.theta.ltl.dsl.gen.LTLGrammarParser +import jhoafparser.parser.HOAFParser +import org.antlr.v4.runtime.CharStreams +import org.antlr.v4.runtime.CommonTokenStream + +class Ltl2BuchiThroughHoaf(private val converter: Ltl2Hoaf, private val logger: Logger) : + Ltl2BuchiTransformer { + + override fun transform(ltl: String, namedVariables: Map>): CFA { + val variables = namedVariables.values + val modelContext = + LTLGrammarParser(CommonTokenStream(LTLGrammarLexer(CharStreams.fromString(ltl)))).model() + val enumTypes: Map = + variables.mapNotNull { it.type as? EnumType }.associateBy { it.name } + val toStringVisitor = ToStringVisitor(APGeneratorVisitor(namedVariables, enumTypes)) + val swappedLtl = toStringVisitor.visitModel(modelContext) + val negatedLtl = "!($swappedLtl)" + val hoafExpression = converter.transform(negatedLtl) + val buchiBuilder = BuchiBuilder(logger, toStringVisitor.aps) + HOAFParser.parseHOA(hoafExpression.byteInputStream(), buchiBuilder) + return buchiBuilder.build() + } +} diff --git a/subprojects/common/ltl/src/main/kotlin/hu/bme/mit/theta/common/cfa/buchi/hoa/Ltl2Hoaf.kt b/subprojects/common/ltl/src/main/kotlin/hu/bme/mit/theta/common/cfa/buchi/hoa/Ltl2Hoaf.kt new file mode 100644 index 0000000000..e0da409ba3 --- /dev/null +++ b/subprojects/common/ltl/src/main/kotlin/hu/bme/mit/theta/common/cfa/buchi/hoa/Ltl2Hoaf.kt @@ -0,0 +1,21 @@ +/* + * Copyright 2024 Budapest University of Technology and Economics + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package hu.bme.mit.theta.common.cfa.buchi.hoa + +fun interface Ltl2Hoaf { + + fun transform(ltl: String): String +} diff --git a/subprojects/common/ltl/src/main/kotlin/hu/bme/mit/theta/common/cfa/buchi/hoa/Ltl2HoafFromDir.kt b/subprojects/common/ltl/src/main/kotlin/hu/bme/mit/theta/common/cfa/buchi/hoa/Ltl2HoafFromDir.kt new file mode 100644 index 0000000000..cd27f0c9c5 --- /dev/null +++ b/subprojects/common/ltl/src/main/kotlin/hu/bme/mit/theta/common/cfa/buchi/hoa/Ltl2HoafFromDir.kt @@ -0,0 +1,30 @@ +/* + * Copyright 2024 Budapest University of Technology and Economics + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package hu.bme.mit.theta.common.cfa.buchi.hoa + +import java.net.URLEncoder +import java.nio.file.Path + +/** + * Provide a directory which contains HOAF files named as their respective LTL expression .hoa. E.g. + * if you have the hoaf representation of `F a` as `/tmp/ltls/F a.hoa`, create this class with + * `/tmp/ltls` and simply call the transform with the ltl expression. + */ +class Ltl2HoafFromDir(private val dir: String) : Ltl2Hoaf { + + override fun transform(ltl: String) = + Path.of("""$dir/${URLEncoder.encode(ltl, "UTF-8")}.hoa""").toFile().readText() +} diff --git a/subprojects/common/ltl/src/main/kotlin/hu/bme/mit/theta/common/cfa/buchi/hoa/ToStringVisitor.kt b/subprojects/common/ltl/src/main/kotlin/hu/bme/mit/theta/common/cfa/buchi/hoa/ToStringVisitor.kt new file mode 100644 index 0000000000..a97a05486a --- /dev/null +++ b/subprojects/common/ltl/src/main/kotlin/hu/bme/mit/theta/common/cfa/buchi/hoa/ToStringVisitor.kt @@ -0,0 +1,298 @@ +/* + * Copyright 2024 Budapest University of Technology and Economics + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package hu.bme.mit.theta.common.cfa.buchi.hoa + +import hu.bme.mit.theta.core.type.Expr +import hu.bme.mit.theta.core.type.booltype.BoolType +import hu.bme.mit.theta.ltl.dsl.gen.LTLGrammarBaseVisitor +import hu.bme.mit.theta.ltl.dsl.gen.LTLGrammarParser.* + +class ToStringVisitor(private val apGeneratorVisitor: APGeneratorVisitor) : + LTLGrammarBaseVisitor() { + + var aps: HashMap> = HashMap() + private var counter = 0 + + override fun visitModel(ctx: ModelContext): String { + return visitImplyExpression(ctx.implyExpression) + } + + override fun visitImplyExpression(ctx: ImplyExpressionContext): String { + if (!LTLExprVisitor.visitImplyExpression(ctx)) { + val name = generateApName() + val expr = apGeneratorVisitor.visitImplyExpression(ctx) + aps[name] = expr as Expr + return name + } + return if (ctx.ops.size > 1) { + visitOrExpr(ctx.ops[0]) + " -> " + visitOrExpr(ctx.ops[1]) + } else { + visitOrExpr(ctx.ops[0]) + } + } + + override fun visitOrExpr(ctx: OrExprContext): String { + if (!LTLExprVisitor.visitOrExpr(ctx)) { + val name = generateApName() + aps[name] = apGeneratorVisitor.visitOrExpr(ctx) as Expr + return name + } + val builder = StringBuilder() + builder.append(visitAndExpr(ctx.ops[0])) + for (i in 1 until ctx.ops.size) { + builder.append(" | ") + builder.append(visitAndExpr(ctx.ops[i])) + } + return builder.toString() + } + + override fun visitAndExpr(ctx: AndExprContext): String { + if (!LTLExprVisitor.visitAndExpr(ctx)) { + val name = generateApName() + aps[name] = apGeneratorVisitor.visitAndExpr(ctx) + return name + } + val builder = StringBuilder() + builder.append(visitNotExpr(ctx.ops[0])) + for (i in 1 until ctx.ops.size) { + builder.append(" & ") + builder.append(visitNotExpr(ctx.ops[i])) + } + return builder.toString() + } + + override fun visitNotExpr(ctx: NotExprContext): String { + if (!LTLExprVisitor.visitNotExpr(ctx)) { + val name = generateApName() + aps[name] = apGeneratorVisitor.visitNotExpr(ctx) + return name + } + return if (ctx.ops.isNotEmpty()) { + "! " + visitNotExpr(ctx.ops[0]) + } else { + visitBinaryLtlExpr(ctx.binaryLtlExpr()) + } + } + + override fun visitBinaryLtlExpr(ctx: BinaryLtlExprContext): String { + if (!LTLExprVisitor.visitBinaryLtlExpr(ctx)) { + val name = generateApName() + aps[name] = apGeneratorVisitor.visitBinaryLtlExpr(ctx) as Expr + return name + } + return if (ctx.type != null) { + (visitBinaryLtlExpr(ctx.ops[0]) + + " " + + visitBinaryLtlOp(ctx.type) + + " " + + visitBinaryLtlExpr(ctx.ops[1])) + } else { + visitLtlExpr(ctx.ltlExpr()) + } + } + + override fun visitBinaryLtlOp(ctx: BinaryLtlOpContext): String { + return if (ctx.U_OP() != null) { + "U" + } else if (ctx.M_OP() != null) { + "M" + } else if (ctx.W_OP() != null) { + "W" + } else { + "R" + } + } + + override fun visitLtlExpr(ctx: LtlExprContext): String { + if (!LTLExprVisitor.visitLtlExpr(ctx)) { + val name = generateApName() + aps[name] = apGeneratorVisitor.visitLtlExpr(ctx) as Expr + return name + } + return if (ctx.ops.size > 0) { + visitLtlOp(ctx.type) + " " + visitLtlExpr(ctx.ops[0]) + } else { + visitEqExpr(ctx.eqExpr()) + } + } + + override fun visitLtlOp(ctx: LtlOpContext): String { + return if (ctx.F_OP() != null) { + "F" + } else if (ctx.G_OP() != null) { + "G" + } else { + "X" + } + } + + override fun visitEqExpr(ctx: EqExprContext): String { + if (!LTLExprVisitor.visitEqExpr(ctx)) { + val name = generateApName() + aps[name] = apGeneratorVisitor.visitEqExpr(ctx) as Expr + return name + } + val builder = StringBuilder() + builder.append(visitRelationExpr(ctx.ops[0])) + for (i in 1 until ctx.ops.size) { + builder.append(visitEqOperator(ctx.oper)) + builder.append(visitRelationExpr(ctx.ops[i])) + } + return builder.toString() + } + + override fun visitEqOperator(ctx: EqOperatorContext): String { + return if (ctx.EQ() != null) { + "=" + } else { + "/=" + } + } + + override fun visitRelationExpr(ctx: RelationExprContext): String { + if (!LTLExprVisitor.visitRelationExpr(ctx)) { + val name = generateApName() + aps[name] = apGeneratorVisitor.visitRelationExpr(ctx) as Expr + return name + } + val builder = StringBuilder() + builder.append(visitAdditiveExpr(ctx.ops[0])) + for (i in 1 until ctx.ops.size) { + builder.append(visitRelationOperator(ctx.oper)) + builder.append(visitAdditiveExpr(ctx.ops[i])) + } + return builder.toString() + } + + override fun visitRelationOperator(ctx: RelationOperatorContext): String { + return if (ctx.LT() != null) { + "<" + } else if (ctx.GT() != null) { + ">" + } else if (ctx.LEQ() != null) { + "<=" + } else ">=" + } + + override fun visitAdditiveExpr(ctx: AdditiveExprContext): String { + if (!LTLExprVisitor.visitAdditiveExpr(ctx)) { + val name = generateApName() + aps[name] = apGeneratorVisitor.visitAdditiveExpr(ctx) as Expr + return name + } + val builder = StringBuilder() + builder.append(visitMultiplicativeExpr(ctx.ops[0])) + for (i in 1 until ctx.ops.size) { + builder.append(visitAdditiveOperator(ctx.opers[i - 1])) + builder.append(visitMultiplicativeExpr(ctx.ops[i])) + } + return builder.toString() + } + + override fun visitAdditiveOperator(ctx: AdditiveOperatorContext): String { + return if (ctx.PLUS() != null) { + "+" + } else "-" + } + + override fun visitMultiplicativeExpr(ctx: MultiplicativeExprContext): String { + if (!LTLExprVisitor.visitMultiplicativeExpr(ctx)) { + val name = generateApName() + aps[name] = apGeneratorVisitor.visitMultiplicativeExpr(ctx) as Expr + return name + } + val builder = StringBuilder() + builder.append(visitNegExpr(ctx.ops[0])) + for (i in 1 until ctx.ops.size) { + builder.append(visitMultiplicativeOperator(ctx.opers[i - 1])) + builder.append(visitNegExpr(ctx.ops[i])) + } + return builder.toString() + } + + override fun visitMultiplicativeOperator(ctx: MultiplicativeOperatorContext): String { + return if (ctx.MUL() != null) { + "*" + } else if (ctx.MOD() != null) { + "%" + } else "/" + } + + override fun visitNegExpr(ctx: NegExprContext): String { + if (!LTLExprVisitor.visitNegExpr(ctx)) { + val name = generateApName() + aps[name] = apGeneratorVisitor.visitNegExpr(ctx) as Expr + return name + } + return if (ctx.ops.size > 0) { + "- " + visitNegExpr(ctx.ops[0]) + } else { + visitPrimaryExpr(ctx.primaryExpr()) + } + } + + override fun visitPrimaryExpr(ctx: PrimaryExprContext): String { + if (!LTLExprVisitor.visitPrimaryExpr(ctx)) { + val name = generateApName() + aps[name] = apGeneratorVisitor.visitPrimaryExpr(ctx) as Expr + return name + } + return if (ctx.parenExpr() != null) { + visitParenExpr(ctx.parenExpr()) + } else if (ctx.intLitExpr() != null) { + visitIntLitExpr(ctx.intLitExpr()) + } else visitBoolLitExpr(ctx.boolLitExpr()) + } + + override fun visitBoolLitExpr(ctx: BoolLitExprContext): String { + return ctx.value.text + } + + override fun visitParenExpr(ctx: ParenExprContext): String { + if (!LTLExprVisitor.visitParenExpr(ctx)) { + val name = generateApName() + aps[name] = apGeneratorVisitor.visitParenExpr(ctx) as Expr + return name + } + return if (ctx.variable() != null) { + visitVariable(ctx.variable()) + } else { + "(" + visitImplyExpression(ctx.ops[0]) + ")" + } + } + + override fun visitIntLitExpr(ctx: IntLitExprContext): String { + if (!LTLExprVisitor.visitIntLitExpr(ctx)) { + val name = generateApName() + aps[name] = apGeneratorVisitor.visitIntLitExpr(ctx) as Expr + return name + } + return ctx.value.text + } + + override fun visitVariable(ctx: VariableContext): String { + if (!LTLExprVisitor.visitVariable(ctx)) { + val name = generateApName() + aps[name] = apGeneratorVisitor.visitVariable(ctx) as Expr + return name + } + return ctx.name.text + } + + private fun generateApName(): String { + return "ap" + (counter++) + } +} diff --git a/subprojects/common/ltl/src/main/kotlin/hu/bme/mit/theta/common/ltl/LtlChecker.kt b/subprojects/common/ltl/src/main/kotlin/hu/bme/mit/theta/common/ltl/LtlChecker.kt new file mode 100644 index 0000000000..d1d4870080 --- /dev/null +++ b/subprojects/common/ltl/src/main/kotlin/hu/bme/mit/theta/common/ltl/LtlChecker.kt @@ -0,0 +1,178 @@ +/* + * Copyright 2024 Budapest University of Technology and Economics + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package hu.bme.mit.theta.common.ltl + +import hu.bme.mit.theta.analysis.Analysis +import hu.bme.mit.theta.analysis.LTS +import hu.bme.mit.theta.analysis.Prec +import hu.bme.mit.theta.analysis.algorithm.SafetyChecker +import hu.bme.mit.theta.analysis.algorithm.SafetyResult +import hu.bme.mit.theta.analysis.algorithm.cegar.CegarChecker +import hu.bme.mit.theta.analysis.algorithm.loopchecker.AcceptancePredicate +import hu.bme.mit.theta.analysis.algorithm.loopchecker.LDGTrace +import hu.bme.mit.theta.analysis.algorithm.loopchecker.abstraction.LDGAbstractor +import hu.bme.mit.theta.analysis.algorithm.loopchecker.abstraction.LoopcheckerSearchStrategy +import hu.bme.mit.theta.analysis.algorithm.loopchecker.ldg.LDG +import hu.bme.mit.theta.analysis.algorithm.loopchecker.refinement.LDGTraceCheckerStrategy +import hu.bme.mit.theta.analysis.algorithm.loopchecker.refinement.SingleLDGTraceRefiner +import hu.bme.mit.theta.analysis.expr.ExprState +import hu.bme.mit.theta.analysis.expr.StmtAction +import hu.bme.mit.theta.analysis.expr.refinement.ItpRefutation +import hu.bme.mit.theta.analysis.expr.refinement.JoiningPrecRefiner +import hu.bme.mit.theta.analysis.expr.refinement.RefutationToPrec +import hu.bme.mit.theta.analysis.multi.MultiAnalysisSide +import hu.bme.mit.theta.analysis.multi.MultiPrec +import hu.bme.mit.theta.analysis.multi.NextSideFunctions +import hu.bme.mit.theta.analysis.multi.RefToMultiPrec +import hu.bme.mit.theta.analysis.multi.builder.stmt.StmtMultiBuilder +import hu.bme.mit.theta.analysis.multi.stmt.ExprMultiState +import hu.bme.mit.theta.analysis.multi.stmt.StmtMultiAction +import hu.bme.mit.theta.analysis.unit.UnitInitFunc +import hu.bme.mit.theta.analysis.unit.UnitPrec +import hu.bme.mit.theta.analysis.unit.UnitState +import hu.bme.mit.theta.analysis.utils.LdgVisualizer +import hu.bme.mit.theta.cfa.CFA +import hu.bme.mit.theta.cfa.analysis.* +import hu.bme.mit.theta.cfa.analysis.lts.CfaSbeLts +import hu.bme.mit.theta.cfa.analysis.prec.GlobalCfaPrec +import hu.bme.mit.theta.cfa.analysis.prec.RefutationToGlobalCfaPrec +import hu.bme.mit.theta.common.cfa.buchi.Ltl2BuchiTransformer +import hu.bme.mit.theta.common.logging.Logger +import hu.bme.mit.theta.core.decl.VarDecl +import hu.bme.mit.theta.core.type.Expr +import hu.bme.mit.theta.core.type.booltype.BoolExprs.True +import hu.bme.mit.theta.core.type.booltype.BoolType +import hu.bme.mit.theta.solver.SolverFactory + +class LtlChecker< + S : ExprState, + ControlS : ExprState, + A : StmtAction, + P : Prec, + ControlP : Prec, + DataP : Prec, + DataS : ExprState, +>( + multiSide: MultiAnalysisSide, + lts: LTS, + refToPrec: RefutationToPrec, + dataRefToPrec: RefutationToPrec, + dataAnalysis: Analysis, + ltl: String, + solverFactory: SolverFactory, + logger: Logger, + searchStrategy: LoopcheckerSearchStrategy, + refinerStrategy: LDGTraceCheckerStrategy, + ltl2BuchiTransformer: Ltl2BuchiTransformer, + variables: Collection>, + initExpr: Expr = True(), +) : + SafetyChecker< + LDG, DataS>, StmtMultiAction>, + LDGTrace, DataS>, StmtMultiAction>, + MultiPrec, DataP>, + > { + private val checker: + CegarChecker< + MultiPrec, DataP>, + LDG, DataS>, StmtMultiAction>, + LDGTrace, DataS>, StmtMultiAction>, + > + + init { + val buchiAutomaton = ltl2BuchiTransformer.transform(ltl, variables) + val cfaAnalysis: Analysis, CfaAction, CfaPrec> = + CfaAnalysis.create(buchiAutomaton.initLoc, dataAnalysis) + val buchiSide = + MultiAnalysisSide( + cfaAnalysis, + CfaInitFunc.create(buchiAutomaton.initLoc, UnitInitFunc.getInstance()), + ::cfaCombineStates, + ::cfaExtractControlState, + { it.state }, + { _ -> GlobalCfaPrec.create(UnitPrec.getInstance()) }, + ) + val product = + StmtMultiBuilder(multiSide, lts) + .addRightSide(buchiSide, CfaSbeLts.getInstance()) + .build(NextSideFunctions.Alternating(), dataAnalysis.initFunc) + val buchiRefToPrec = RefutationToGlobalCfaPrec(dataRefToPrec, buchiAutomaton.initLoc) + val multiRefToPrec = RefToMultiPrec(refToPrec, buchiRefToPrec, dataRefToPrec) + val multiAnalysis = product.side.analysis + val abstractor = + LDGAbstractor( + multiAnalysis, + product.lts, + buchiPredicate(buchiAutomaton), + searchStrategy, + logger, + ) + val refiner: + SingleLDGTraceRefiner< + ExprMultiState, DataS>, + StmtMultiAction, + MultiPrec, DataP>, + > = + SingleLDGTraceRefiner( + refinerStrategy, + solverFactory, + JoiningPrecRefiner.create(multiRefToPrec), + logger, + initExpr, + ) + val visualizer = + LdgVisualizer< + ExprMultiState, DataS>, + StmtMultiAction, + >( + { it.toString() }, + { it.toString() }, + ) + checker = CegarChecker.create(abstractor, refiner, logger, visualizer) + } + + private fun buchiPredicate( + buchiAutomaton: CFA + ): AcceptancePredicate< + ExprMultiState, DataS>, + StmtMultiAction, + > = + AcceptancePredicate( + actionPredicate = { a -> + (a?.rightAction != null && + a.rightAction.edges.any { e -> buchiAutomaton.acceptingEdges.contains(e) }) + } + ) + + override fun check( + input: MultiPrec, DataP> + ): SafetyResult< + LDG, DataS>, StmtMultiAction>, + LDGTrace, DataS>, StmtMultiAction>, + > { + return checker.check(input) + } + + fun check( + prec: P, + dataPrec: DataP, + ): SafetyResult< + LDG, DataS>, StmtMultiAction>, + LDGTrace, DataS>, StmtMultiAction>, + > { + return check(MultiPrec(prec, GlobalCfaPrec.create(dataPrec), dataPrec)) + } +} diff --git a/subprojects/common/ltl/src/test/kotlin/hu/bme/mit/theta/common/ltl/LtlCheckTestWithCfaExpl.kt b/subprojects/common/ltl/src/test/kotlin/hu/bme/mit/theta/common/ltl/LtlCheckTestWithCfaExpl.kt new file mode 100644 index 0000000000..d00d91bf49 --- /dev/null +++ b/subprojects/common/ltl/src/test/kotlin/hu/bme/mit/theta/common/ltl/LtlCheckTestWithCfaExpl.kt @@ -0,0 +1,108 @@ +/* + * Copyright 2024 Budapest University of Technology and Economics + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package hu.bme.mit.theta.common.ltl + +import hu.bme.mit.theta.analysis.algorithm.loopchecker.abstraction.LoopcheckerSearchStrategy +import hu.bme.mit.theta.analysis.algorithm.loopchecker.refinement.LDGTraceCheckerStrategy +import hu.bme.mit.theta.analysis.expl.ExplAnalysis +import hu.bme.mit.theta.analysis.expl.ExplPrec +import hu.bme.mit.theta.analysis.expl.ItpRefToExplPrec +import hu.bme.mit.theta.cfa.CFA +import hu.bme.mit.theta.cfa.analysis.CfaPrec +import hu.bme.mit.theta.cfa.analysis.config.CfaConfigBuilder +import hu.bme.mit.theta.cfa.analysis.prec.GlobalCfaPrec +import hu.bme.mit.theta.cfa.analysis.prec.RefutationToGlobalCfaPrec +import hu.bme.mit.theta.cfa.dsl.CfaDslManager +import hu.bme.mit.theta.common.cfa.buchi.hoa.Ltl2BuchiThroughHoaf +import hu.bme.mit.theta.common.cfa.buchi.hoa.Ltl2HoafFromDir +import hu.bme.mit.theta.common.logging.ConsoleLogger +import hu.bme.mit.theta.common.logging.Logger +import hu.bme.mit.theta.core.type.booltype.BoolExprs.True +import hu.bme.mit.theta.solver.Solver +import hu.bme.mit.theta.solver.z3legacy.Z3LegacySolverFactory +import junit.framework.TestCase.fail +import org.junit.Assert +import org.junit.Test +import org.junit.runner.RunWith +import org.junit.runners.Parameterized +import java.io.FileInputStream + +@RunWith(Parameterized::class) +class LtlCheckTestWithCfaExpl( + private val cfaName: String, + private val ltlExpr: String, + private val result: Boolean, +) { + + private val itpSolverFactory = Z3LegacySolverFactory.getInstance() + private val abstractionSolver: Solver = Z3LegacySolverFactory.getInstance().createSolver() + private val logger: Logger = ConsoleLogger(Logger.Level.VERBOSE) + + companion object { + @JvmStatic + @Parameterized.Parameters + fun data() = + listOf( + arrayOf("counter2inf", "G(x=1)", false), + arrayOf("counter2inf", "G(x=2)", false), + arrayOf("counter2inf", "F G(x=2)", true), + arrayOf("counter2inf", "F(x=1)", true), + arrayOf("counter2inf", "F(x=3)", false), + ) + } + + @Test + fun test() { + abstractionSolver.reset() + var cfaI: CFA? + FileInputStream(String.format("src/test/resources/cfa/%s.cfa", cfaName)).use { inputStream -> + cfaI = CfaDslManager.createCfa(inputStream) + } + if (cfaI == null) fail("Couldn't read cfa $cfaName") + val cfa = cfaI!! + val configBuilder = + CfaConfigBuilder( + CfaConfigBuilder.Domain.EXPL, + CfaConfigBuilder.Refinement.SEQ_ITP, + itpSolverFactory, + ) + .encoding(CfaConfigBuilder.Encoding.SBE) + .ExplStrategy(cfa) + val dataAnalysis = ExplAnalysis.create(abstractionSolver, True()) + val refToPrec = RefutationToGlobalCfaPrec(ItpRefToExplPrec(), cfa.initLoc) + val variables = cfa.vars + val dataInitPrec = ExplPrec.of(variables) + val initPrec: CfaPrec = GlobalCfaPrec.create(dataInitPrec) + + val checker = + LtlChecker( + configBuilder.multiSide, + configBuilder.lts, + refToPrec, + configBuilder.itpRefToPrec, + dataAnalysis, + ltlExpr, + itpSolverFactory, + logger, + LoopcheckerSearchStrategy.GDFS, + LDGTraceCheckerStrategy.MILANO, + Ltl2BuchiThroughHoaf(Ltl2HoafFromDir("src/test/resources/hoa"), logger), + variables, + ) + + Assert.assertEquals(result, checker.check(initPrec, dataInitPrec).isSafe) + } +} diff --git a/subprojects/common/ltl/src/test/kotlin/hu/bme/mit/theta/common/ltl/LtlCheckTestWithCfaPred.kt b/subprojects/common/ltl/src/test/kotlin/hu/bme/mit/theta/common/ltl/LtlCheckTestWithCfaPred.kt new file mode 100644 index 0000000000..8c95a84921 --- /dev/null +++ b/subprojects/common/ltl/src/test/kotlin/hu/bme/mit/theta/common/ltl/LtlCheckTestWithCfaPred.kt @@ -0,0 +1,131 @@ +/* + * Copyright 2024 Budapest University of Technology and Economics + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package hu.bme.mit.theta.common.ltl + +import hu.bme.mit.theta.analysis.algorithm.loopchecker.abstraction.LoopcheckerSearchStrategy +import hu.bme.mit.theta.analysis.algorithm.loopchecker.refinement.LDGTraceCheckerStrategy +import hu.bme.mit.theta.analysis.expr.ExprAction +import hu.bme.mit.theta.analysis.pred.* +import hu.bme.mit.theta.cfa.CFA +import hu.bme.mit.theta.cfa.analysis.config.CfaConfigBuilder +import hu.bme.mit.theta.cfa.analysis.prec.RefutationToGlobalCfaPrec +import hu.bme.mit.theta.cfa.dsl.CfaDslManager +import hu.bme.mit.theta.common.cfa.buchi.hoa.Ltl2BuchiThroughHoaf +import hu.bme.mit.theta.common.cfa.buchi.hoa.Ltl2HoafFromDir +import hu.bme.mit.theta.common.logging.ConsoleLogger +import hu.bme.mit.theta.common.logging.Logger +import hu.bme.mit.theta.core.type.booltype.BoolExprs.True +import hu.bme.mit.theta.solver.Solver +import hu.bme.mit.theta.solver.z3legacy.Z3LegacySolverFactory +import junit.framework.TestCase.fail +import org.junit.Assert +import org.junit.Test +import org.junit.runner.RunWith +import org.junit.runners.Parameterized +import java.io.FileInputStream + +@RunWith(Parameterized::class) +class LtlCheckTestWithCfaPred( + private val cfaName: String, + private val ltlExpr: String, + private val result: Boolean, + private val searchStrategy: LoopcheckerSearchStrategy, + private val refinerStrategy: LDGTraceCheckerStrategy, +) { + + private val itpSolverFactory = Z3LegacySolverFactory.getInstance() + private val abstractionSolver: Solver = Z3LegacySolverFactory.getInstance().createSolver() + private val logger: Logger = ConsoleLogger(Logger.Level.INFO) + + companion object { + fun data() = + listOf( + arrayOf("wave_flags", "F G(x)", false), + arrayOf("wave_flags", "F G(x and y)", false), + arrayOf("wave_flag", "G F(x)", true), + arrayOf("wave_flag", "G(x)", false), + arrayOf("wave_flag", "F G(x)", false), + arrayOf("counter5inf", "G(not(x=6))", true), + arrayOf("counter5inf", "G(x=1)", false), + arrayOf("counter5inf", "G(x=5)", false), + arrayOf("counter5inf", "F G(x=5)", true), + arrayOf("counter5inf", "F(x=1)", true), + arrayOf("counter5inf", "F(x=5)", true), + arrayOf("wave_flags", "G F(y)", true), + arrayOf("wave_flags", "F G(x)", false), + arrayOf("indicator", "G (x -> y)", true), + // arrayOf("indicator_multiassign", "G (x -> y)", true), + arrayOf("indicator", "G (x -> X (not x))", true), + arrayOf("indicator", "G (y -> X (not y))", false), + ) + + @JvmStatic + @Parameterized.Parameters(name = "{3}-{4}: {0}") + fun params() = + listOf(LoopcheckerSearchStrategy.GDFS, LoopcheckerSearchStrategy.NDFS).flatMap { search -> + listOf(LDGTraceCheckerStrategy.MILANO, LDGTraceCheckerStrategy.BOUNDED_UNROLLING).flatMap { + ref -> + data().map { arrayOf(*it, search, ref) } + } + } + } + + @Test + fun test() { + abstractionSolver.reset() + var cfaI: CFA? + FileInputStream(String.format("src/test/resources/cfa/%s.cfa", cfaName)).use { inputStream -> + cfaI = CfaDslManager.createCfa(inputStream) + } + if (cfaI == null) fail("Couldn't read cfa $cfaName") + val cfa = cfaI!! + val configBuilder = + CfaConfigBuilder( + CfaConfigBuilder.Domain.PRED_SPLIT, + CfaConfigBuilder.Refinement.SEQ_ITP, + itpSolverFactory, + ) + .encoding(CfaConfigBuilder.Encoding.SBE) + .PredStrategy(cfa) + val variables = cfa.vars + val dataAnalysis = + PredAnalysis.create( + abstractionSolver, + PredAbstractors.booleanSplitAbstractor(abstractionSolver), + True(), + ) + val refToPrec = RefutationToGlobalCfaPrec(ItpRefToPredPrec(ExprSplitters.atoms()), cfa.initLoc) + val dataInitPrec = PredPrec.of() + + val checker = + LtlChecker( + configBuilder.multiSide, + configBuilder.lts, + refToPrec, + configBuilder.itpRefToPrec, + dataAnalysis, + ltlExpr, + itpSolverFactory, + logger, + searchStrategy, + refinerStrategy, + Ltl2BuchiThroughHoaf(Ltl2HoafFromDir("src/test/resources/hoa"), logger), + variables, + ) + + Assert.assertEquals(result, checker.check(configBuilder.createInitPrec(), dataInitPrec).isSafe) + } +} diff --git a/subprojects/common/ltl/src/test/kotlin/hu/bme/mit/theta/common/ltl/LtlCheckTestWithXstsExpl.kt b/subprojects/common/ltl/src/test/kotlin/hu/bme/mit/theta/common/ltl/LtlCheckTestWithXstsExpl.kt new file mode 100644 index 0000000000..f2c0798f9f --- /dev/null +++ b/subprojects/common/ltl/src/test/kotlin/hu/bme/mit/theta/common/ltl/LtlCheckTestWithXstsExpl.kt @@ -0,0 +1,115 @@ +/* + * Copyright 2024 Budapest University of Technology and Economics + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package hu.bme.mit.theta.common.ltl + +import hu.bme.mit.theta.analysis.algorithm.loopchecker.abstraction.LoopcheckerSearchStrategy +import hu.bme.mit.theta.analysis.algorithm.loopchecker.refinement.LDGTraceCheckerStrategy +import hu.bme.mit.theta.analysis.expl.ExplPrec +import hu.bme.mit.theta.analysis.expl.ExplState +import hu.bme.mit.theta.analysis.unit.UnitPrec +import hu.bme.mit.theta.analysis.unit.UnitState +import hu.bme.mit.theta.common.cfa.buchi.hoa.Ltl2BuchiThroughHoaf +import hu.bme.mit.theta.common.cfa.buchi.hoa.Ltl2HoafFromDir +import hu.bme.mit.theta.common.logging.ConsoleLogger +import hu.bme.mit.theta.common.logging.Logger +import hu.bme.mit.theta.solver.z3legacy.Z3LegacySolverFactory +import hu.bme.mit.theta.xsts.XSTS +import hu.bme.mit.theta.xsts.analysis.XstsAction +import hu.bme.mit.theta.xsts.analysis.XstsState +import hu.bme.mit.theta.xsts.analysis.config.XstsConfigBuilder +import hu.bme.mit.theta.xsts.dsl.XstsDslManager +import hu.bme.mit.theta.xsts.passes.normalize +import junit.framework.TestCase.fail +import org.junit.Assert +import org.junit.Test +import org.junit.runner.RunWith +import org.junit.runners.Parameterized +import java.io.FileInputStream + +@RunWith(Parameterized::class) +class LtlCheckTestWithXstsExpl( + private val xstsName: String, + private val ltlExpr: String, + private val result: Boolean, +) { + + private val solverFactory = Z3LegacySolverFactory.getInstance() + private val logger: Logger = ConsoleLogger(Logger.Level.VERBOSE) + + companion object { + @JvmStatic + @Parameterized.Parameters + fun data() = + listOf( + arrayOf("counter3inf", "F G(x=3)", true), + arrayOf("counter3inf", "F(x=2)", true), + arrayOf("counter3inf", "G(x<4)", true), + arrayOf("counter3inf", "G(x=1)", false), + arrayOf("counter6to7", "G(x=1)", false), + arrayOf("counter6to7", "G(x=7)", false), + arrayOf("counter6to7", "G F(x=7)", true), + ) + } + + @Test + fun test() { + var xstsI: XSTS? + FileInputStream(String.format("src/test/resources/xsts/%s.xsts", xstsName)).use { inputStream -> + xstsI = XstsDslManager.createXsts(inputStream) + } + if (xstsI == null) fail("Couldn't read xsts $xstsName") + val xsts = normalize(xstsI) + val configBuilder: XstsConfigBuilder.ExplStrategy = + XstsConfigBuilder( + XstsConfigBuilder.Domain.EXPL, + XstsConfigBuilder.Refinement.SEQ_ITP, + solverFactory, + solverFactory, + ) + .initPrec(XstsConfigBuilder.InitPrec.EMPTY) + .ExplStrategy(xsts) + val initPrec = configBuilder.initPrec + + val checker: + LtlChecker< + XstsState, + XstsState, + XstsAction, + ExplPrec, + UnitPrec, + ExplPrec, + ExplState, + > = + LtlChecker( + configBuilder.multiSide, + configBuilder.lts, + configBuilder.itpRefToPrec, + configBuilder.itpRefToPrec, + configBuilder.dataAnalysis, + ltlExpr, + solverFactory, + logger, + LoopcheckerSearchStrategy.GDFS, + LDGTraceCheckerStrategy.MILANO, + Ltl2BuchiThroughHoaf(Ltl2HoafFromDir("src/test/resources/hoa"), logger), + xsts.vars, + xsts.initFormula, + ) + val checkResult = checker.check(initPrec, initPrec) + + Assert.assertEquals(result, checkResult.isSafe) + } +} diff --git a/subprojects/common/ltl/src/test/kotlin/hu/bme/mit/theta/common/ltl/LtlCheckTestWithXstsPred.kt b/subprojects/common/ltl/src/test/kotlin/hu/bme/mit/theta/common/ltl/LtlCheckTestWithXstsPred.kt new file mode 100644 index 0000000000..3b2b455323 --- /dev/null +++ b/subprojects/common/ltl/src/test/kotlin/hu/bme/mit/theta/common/ltl/LtlCheckTestWithXstsPred.kt @@ -0,0 +1,156 @@ +/* + * Copyright 2024 Budapest University of Technology and Economics + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package hu.bme.mit.theta.common.ltl + +import hu.bme.mit.theta.analysis.algorithm.loopchecker.abstraction.LoopcheckerSearchStrategy +import hu.bme.mit.theta.analysis.algorithm.loopchecker.refinement.LDGTraceCheckerStrategy +import hu.bme.mit.theta.analysis.pred.ExprSplitters +import hu.bme.mit.theta.analysis.pred.ItpRefToPredPrec +import hu.bme.mit.theta.common.cfa.buchi.hoa.Ltl2BuchiThroughHoaf +import hu.bme.mit.theta.common.cfa.buchi.hoa.Ltl2HoafFromDir +import hu.bme.mit.theta.common.logging.ConsoleLogger +import hu.bme.mit.theta.common.logging.Logger +import hu.bme.mit.theta.solver.Solver +import hu.bme.mit.theta.solver.z3legacy.Z3LegacySolverFactory +import hu.bme.mit.theta.xsts.XSTS +import hu.bme.mit.theta.xsts.analysis.config.XstsConfigBuilder +import hu.bme.mit.theta.xsts.dsl.XstsDslManager +import hu.bme.mit.theta.xsts.passes.normalize +import junit.framework.TestCase.fail +import org.junit.Assert +import org.junit.Test +import org.junit.runner.RunWith +import org.junit.runners.Parameterized +import java.io.FileInputStream + +@RunWith(Parameterized::class) +class LtlCheckTestWithXstsPred( + private val xstsName: String, + private val ltlExpr: String, + private val result: Boolean, + private val searchStrategy: LoopcheckerSearchStrategy, + private val refinerStrategy: LDGTraceCheckerStrategy, +) { + + private val itpSolverFactory = Z3LegacySolverFactory.getInstance() + private val abstractionSolver: Solver = Z3LegacySolverFactory.getInstance().createSolver() + private val logger: Logger = ConsoleLogger(Logger.Level.INFO) + + companion object { + private fun data() = + listOf( + arrayOf("simple_types", "F G(color = Colors.Red)", false), + arrayOf("counter3inf", "F G(x=3)", true), + arrayOf("counter3inf", "F(x=2)", true), + arrayOf("counter3inf", "G(x<4)", true), + arrayOf("counter3inf", "G(x=1)", false), + arrayOf("counter6to7", "G(x=1)", false), + arrayOf("counter6to7", "G(x=7)", false), + arrayOf("counter6to7", "G F(x=7)", true), + // arrayOf("counter50", "G(x<49)", false), + arrayOf( + "trafficlight_v2", + "G(LightCommands_displayRed -> X(not LightCommands_displayGreen))", + true, + ), + arrayOf( + "trafficlight_v2", + "G((normal = Normal.Red and (not PoliceInterrupt_police) and Control_toggle) -> X(normal = Normal.Green))", + true, + ), + arrayOf( + "trafficlight_v2", + "G(PoliceInterrupt_police -> F(LightCommands_displayYellow))", + true, + ), + arrayOf("forever5", "G(x=5)", true), + arrayOf("forever5", "F(x=6)", false), + arrayOf("randomincreasingeven", "not F(x=1)", true), + arrayOf("randomincreasingeven", "F(x>10)", true), + arrayOf("randomincreasingeven", "G(x>=0)", true), + arrayOf("simple_color", "G(envColor = Colors.Green -> X(modelColor = Colors.Blue))", true), + arrayOf( + "simple_color", + "G(envColor = Colors.Green -> X(modelColor = Colors.Green))", + false, + ), + arrayOf("simple_color", "F G(envColor = modelColor)", false), + arrayOf("weather", "G F(isClever and isWet)", false), + arrayOf("weather", "F G(not isWet)", true), + arrayOf( + "weather", + "G(time = TimeOfDay.Noon -> X(time = TimeOfDay.Noon or time = TimeOfDay.Afternoon))", + true, + ), + // arrayOf("weather", "F G(weather = Weather.Foggy -> (clothing = + // Clothing.Nothing or clothing = Clothing.Warm))", true), + // arrayOf("weather_noinit", "G F(isClever and isWet)", false), + // arrayOf("weather_noinit", "F G(not isWet)", true), + // arrayOf("weather_noinit", "G(time = TimeOfDay.Noon -> X(time = TimeOfDay.Noon + // or time = TimeOfDay.Afternoon))", true), + // arrayOf("weather_noinit", "F G(weather = Weather.Foggy -> (clothing = + // Clothing.Nothing or clothing = Clothing.Warm))", true), + ) + + @JvmStatic + @Parameterized.Parameters(name = "{3}-{4}: {0}") + fun params() = + listOf(LoopcheckerSearchStrategy.GDFS, LoopcheckerSearchStrategy.NDFS).flatMap { search -> + LDGTraceCheckerStrategy.entries.flatMap { ref -> data().map { arrayOf(*it, search, ref) } } + } + } + + @Test + fun test() { + var xstsI: XSTS? + FileInputStream("src/test/resources/xsts/$xstsName.xsts").use { inputStream -> + xstsI = XstsDslManager.createXsts(inputStream) + } + if (xstsI == null) fail("Couldn't read xsts $xstsName") + val xsts = normalize(xstsI) + val configBuilder = + XstsConfigBuilder( + XstsConfigBuilder.Domain.PRED_SPLIT, + XstsConfigBuilder.Refinement.SEQ_ITP, + itpSolverFactory, + itpSolverFactory, + ) + .initPrec(XstsConfigBuilder.InitPrec.EMPTY) + .PredStrategy(xsts) + val variables = xsts.vars + val refToPrec = ItpRefToPredPrec(ExprSplitters.atoms()) + val initPrec = configBuilder.initPrec + + val checker = + LtlChecker( + configBuilder.multiSide, + configBuilder.lts, + refToPrec, + refToPrec, + configBuilder.dataAnalysis, + ltlExpr, + itpSolverFactory, + logger, + searchStrategy, + refinerStrategy, + Ltl2BuchiThroughHoaf(Ltl2HoafFromDir("src/test/resources/hoa"), logger), + variables, + xsts.initFormula, + ) + + Assert.assertEquals(result, checker.check(initPrec, initPrec).isSafe) + } +} diff --git a/subprojects/common/ltl/src/test/resources/cfa/counter2inf.cfa b/subprojects/common/ltl/src/test/resources/cfa/counter2inf.cfa new file mode 100644 index 0000000000..81e578cc5d --- /dev/null +++ b/subprojects/common/ltl/src/test/resources/cfa/counter2inf.cfa @@ -0,0 +1,12 @@ +main process cfa { + var x : int + + init loc I + loc L0 + loc L1 + + I -> L0 { x := 0 } + L0 -> L1 { assume x < 2 } + L1 -> L0 { x := x + 1 } + L0 -> L0 { assume x = 2 } +} \ No newline at end of file diff --git a/subprojects/common/ltl/src/test/resources/cfa/counter5inf.cfa b/subprojects/common/ltl/src/test/resources/cfa/counter5inf.cfa new file mode 100644 index 0000000000..6fb102aaf8 --- /dev/null +++ b/subprojects/common/ltl/src/test/resources/cfa/counter5inf.cfa @@ -0,0 +1,12 @@ +main process cfa { + var x : int + + init loc I + loc L0 + loc L1 + + I -> L0 { x := 0 } + L0 -> L1 { assume x < 5 } + L1 -> L0 { x := x + 1 } + L0 -> L0 { assume x = 5 } +} \ No newline at end of file diff --git a/subprojects/common/ltl/src/test/resources/cfa/indicator.cfa b/subprojects/common/ltl/src/test/resources/cfa/indicator.cfa new file mode 100644 index 0000000000..c8a7062768 --- /dev/null +++ b/subprojects/common/ltl/src/test/resources/cfa/indicator.cfa @@ -0,0 +1,14 @@ +main process cfa { + var x : bool + var y : bool + + loc L0 + loc L1 + init loc L2 + loc L3 + + L0 -> L1 { y := true } + L1 -> L2 { x := true } + L2 -> L3 { x := false } + L3 -> L0 { y := false } +} \ No newline at end of file diff --git a/subprojects/common/ltl/src/test/resources/cfa/indicator_multiassign.cfa b/subprojects/common/ltl/src/test/resources/cfa/indicator_multiassign.cfa new file mode 100644 index 0000000000..8330500158 --- /dev/null +++ b/subprojects/common/ltl/src/test/resources/cfa/indicator_multiassign.cfa @@ -0,0 +1,12 @@ +main process cfa { + var x : bool + var y : bool + + loc L0 + loc L1 + init loc L2 + + L0 -> L1 { y := true } + L1 -> L2 { x := true } + L2 -> L0 { y := false x := false } +} \ No newline at end of file diff --git a/subprojects/common/ltl/src/test/resources/cfa/wave_flag.cfa b/subprojects/common/ltl/src/test/resources/cfa/wave_flag.cfa new file mode 100644 index 0000000000..77322ac49d --- /dev/null +++ b/subprojects/common/ltl/src/test/resources/cfa/wave_flag.cfa @@ -0,0 +1,9 @@ +main process cfa { + var x : bool + + init loc L0 + loc L1 + + L0 -> L1 { x := true } + L1 -> L0 { x := false } +} \ No newline at end of file diff --git a/subprojects/common/ltl/src/test/resources/cfa/wave_flags.cfa b/subprojects/common/ltl/src/test/resources/cfa/wave_flags.cfa new file mode 100644 index 0000000000..dc192bb7e5 --- /dev/null +++ b/subprojects/common/ltl/src/test/resources/cfa/wave_flags.cfa @@ -0,0 +1,18 @@ +main process cfa { + var x : bool + var y : bool + + init loc I0 + loc I1 + loc L0 + loc L1 + loc L2 + loc L3 + + I0 -> I1 { x := false } + I1 -> L0 { y := false } + L0 -> L1 { y := true } + L1 -> L2 { y := false x := true } + L2 -> L3 { y := true } + L3 -> L0 { y := false x := false } +} \ No newline at end of file diff --git a/subprojects/common/ltl/src/test/resources/hoa/%21%28%21+F+ap0%29.hoa b/subprojects/common/ltl/src/test/resources/hoa/%21%28%21+F+ap0%29.hoa new file mode 100644 index 0000000000..5feaea29ec --- /dev/null +++ b/subprojects/common/ltl/src/test/resources/hoa/%21%28%21+F+ap0%29.hoa @@ -0,0 +1,18 @@ +HOA: v1 +tool: "owl ltl2nba" "21.0" +name: "Automaton for F(ap0)" +owlArgs: "ltl2nba" "-f" "!(! F ap0)" "-o" "src/test/resources/hoa/%21%28%21+F+ap0%29.hoa" +Start: 0 +acc-name: Buchi +Acceptance: 1 Inf(0) +properties: trans-acc no-univ-branch +properties: deterministic unambiguous +properties: complete +AP: 1 "ap0" +--BODY-- +State: 0 +[!0] 0 +[0] 1 +State: 1 +[t] 1 {0} +--END-- diff --git a/subprojects/common/ltl/src/test/resources/hoa/%21%28F+G+ap0%29.hoa b/subprojects/common/ltl/src/test/resources/hoa/%21%28F+G+ap0%29.hoa new file mode 100644 index 0000000000..26792660e6 --- /dev/null +++ b/subprojects/common/ltl/src/test/resources/hoa/%21%28F+G+ap0%29.hoa @@ -0,0 +1,16 @@ +HOA: v1 +tool: "owl ltl2nba" "21.0" +name: "Automaton for G(F(!ap0))" +owlArgs: "ltl2nba" "-f" "!(F G ap0)" "-o" "src/test/resources/hoa/%21%28F+G+ap0%29.hoa" +Start: 0 +acc-name: Buchi +Acceptance: 1 Inf(0) +properties: trans-acc no-univ-branch +properties: deterministic unambiguous +properties: complete +AP: 1 "ap0" +--BODY-- +State: 0 +[!0] 0 {0} +[0] 0 +--END-- diff --git a/subprojects/common/ltl/src/test/resources/hoa/%21%28F+ap0%29.hoa b/subprojects/common/ltl/src/test/resources/hoa/%21%28F+ap0%29.hoa new file mode 100644 index 0000000000..aa31b46518 --- /dev/null +++ b/subprojects/common/ltl/src/test/resources/hoa/%21%28F+ap0%29.hoa @@ -0,0 +1,14 @@ +HOA: v1 +tool: "owl ltl2nba" "21.0" +name: "Automaton for G(!ap0)" +owlArgs: "ltl2nba" "-f" "!(F ap0)" "-o" "src/test/resources/hoa/%21%28F+ap0%29.hoa" +Start: 0 +acc-name: Buchi +Acceptance: 1 Inf(0) +properties: trans-acc no-univ-branch +properties: deterministic unambiguous +AP: 1 "ap0" +--BODY-- +State: 0 +[!0] 0 {0} +--END-- diff --git a/subprojects/common/ltl/src/test/resources/hoa/%21%28G+%28ap0+-%3E+F+ap1%29%29.hoa b/subprojects/common/ltl/src/test/resources/hoa/%21%28G+%28ap0+-%3E+F+ap1%29%29.hoa new file mode 100644 index 0000000000..5da3686644 --- /dev/null +++ b/subprojects/common/ltl/src/test/resources/hoa/%21%28G+%28ap0+-%3E+F+ap1%29%29.hoa @@ -0,0 +1,16 @@ +HOA: v1 +tool: "owl ltl2nba" "21.0" +name: "Automaton for F(((ap0) & (G(!ap1))))" +owlArgs: "ltl2nba" "-f" "!(G (ap0 -> F ap1))" "-o" "src/test/resources/hoa/%21%28G+%28ap0+-%3E+F+ap1%29%29.hoa" +Start: 0 +acc-name: Buchi +Acceptance: 1 Inf(0) +properties: trans-acc no-univ-branch +AP: 2 "ap0" "ap1" +--BODY-- +State: 0 +[t] 0 +[0 & !1] 1 +State: 1 +[!1] 1 {0} +--END-- diff --git a/subprojects/common/ltl/src/test/resources/hoa/%21%28G+%28ap0+-%3E+X+ap1%29%29.hoa b/subprojects/common/ltl/src/test/resources/hoa/%21%28G+%28ap0+-%3E+X+ap1%29%29.hoa new file mode 100644 index 0000000000..abb333bb18 --- /dev/null +++ b/subprojects/common/ltl/src/test/resources/hoa/%21%28G+%28ap0+-%3E+X+ap1%29%29.hoa @@ -0,0 +1,18 @@ +HOA: v1 +tool: "owl ltl2nba" "21.0" +name: "Automaton for F(((ap0) & (X(!ap1))))" +owlArgs: "ltl2nba" "-f" "!(G (ap0 -> X ap1))" "-o" "src/test/resources/hoa/%21%28G+%28ap0+-%3E+X+ap1%29%29.hoa" +Start: 0 +acc-name: Buchi +Acceptance: 1 Inf(0) +properties: trans-acc no-univ-branch +AP: 2 "ap0" "ap1" +--BODY-- +State: 0 +[t] 0 +[0] 1 +State: 1 +[!1] 2 +State: 2 +[t] 2 {0} +--END-- diff --git a/subprojects/common/ltl/src/test/resources/hoa/%21%28G+F+ap0%29.hoa b/subprojects/common/ltl/src/test/resources/hoa/%21%28G+F+ap0%29.hoa new file mode 100644 index 0000000000..a51520dce0 --- /dev/null +++ b/subprojects/common/ltl/src/test/resources/hoa/%21%28G+F+ap0%29.hoa @@ -0,0 +1,16 @@ +HOA: v1 +tool: "owl ltl2nba" "21.0" +name: "Automaton for F(G(!ap0))" +owlArgs: "ltl2nba" "-f" "!(G F ap0)" "-o" "src/test/resources/hoa/%21%28G+F+ap0%29.hoa" +Start: 0 +acc-name: Buchi +Acceptance: 1 Inf(0) +properties: trans-acc no-univ-branch +AP: 1 "ap0" +--BODY-- +State: 0 +[t] 0 +[!0] 1 +State: 1 +[!0] 1 {0} +--END-- diff --git a/subprojects/common/ltl/src/test/resources/hoa/%21%28G+ap0%29.hoa b/subprojects/common/ltl/src/test/resources/hoa/%21%28G+ap0%29.hoa new file mode 100644 index 0000000000..f132de74f4 --- /dev/null +++ b/subprojects/common/ltl/src/test/resources/hoa/%21%28G+ap0%29.hoa @@ -0,0 +1,18 @@ +HOA: v1 +tool: "owl ltl2nba" "21.0" +name: "Automaton for F(!ap0)" +owlArgs: "ltl2nba" "-f" "!(G ap0)" "-o" "src/test/resources/hoa/%21%28G+ap0%29.hoa" +Start: 0 +acc-name: Buchi +Acceptance: 1 Inf(0) +properties: trans-acc no-univ-branch +properties: deterministic unambiguous +properties: complete +AP: 1 "ap0" +--BODY-- +State: 0 +[0] 0 +[!0] 1 +State: 1 +[t] 1 {0} +--END-- diff --git a/subprojects/common/ltl/src/test/resources/xsts/counter3inf.xsts b/subprojects/common/ltl/src/test/resources/xsts/counter3inf.xsts new file mode 100644 index 0000000000..af2080f290 --- /dev/null +++ b/subprojects/common/ltl/src/test/resources/xsts/counter3inf.xsts @@ -0,0 +1,12 @@ +var x: integer = 0 + +trans { + assume x<3; + x:=x+1; +} or { + assume x>=3; +} + +init {} +env {} +prop{true} \ No newline at end of file diff --git a/subprojects/common/ltl/src/test/resources/xsts/counter50.xsts b/subprojects/common/ltl/src/test/resources/xsts/counter50.xsts new file mode 100644 index 0000000000..ffed019bc4 --- /dev/null +++ b/subprojects/common/ltl/src/test/resources/xsts/counter50.xsts @@ -0,0 +1,16 @@ +ctrl var x: integer = 0 + +trans { + choice { + assume x<50; + x:=x+1; + } or { + assume x == 50; + } +} + +init {} + +env {} + +prop{true} \ No newline at end of file diff --git a/subprojects/common/ltl/src/test/resources/xsts/counter6to7.xsts b/subprojects/common/ltl/src/test/resources/xsts/counter6to7.xsts new file mode 100644 index 0000000000..f331be2ee6 --- /dev/null +++ b/subprojects/common/ltl/src/test/resources/xsts/counter6to7.xsts @@ -0,0 +1,13 @@ +var x: integer = 0 + +trans { + assume x<=6; + x:=x+1; +} or { + assume x==7; + x:=x-1; +} + +init {} +env {} +prop{true} \ No newline at end of file diff --git a/subprojects/common/ltl/src/test/resources/xsts/forever5.xsts b/subprojects/common/ltl/src/test/resources/xsts/forever5.xsts new file mode 100644 index 0000000000..975cfc8f93 --- /dev/null +++ b/subprojects/common/ltl/src/test/resources/xsts/forever5.xsts @@ -0,0 +1,9 @@ +var x: integer = 5 + +trans { + x:=x; +} + +init {} +env {} +prop{true} \ No newline at end of file diff --git a/subprojects/common/ltl/src/test/resources/xsts/randomincreasingeven.xsts b/subprojects/common/ltl/src/test/resources/xsts/randomincreasingeven.xsts new file mode 100644 index 0000000000..d6f9c53796 --- /dev/null +++ b/subprojects/common/ltl/src/test/resources/xsts/randomincreasingeven.xsts @@ -0,0 +1,14 @@ +var x: integer = 0 +var y: integer = 0 + +trans { + if (y < 0) y := -y; + if (y == 0) y := 1; + if (y % 2 == 1) y := y + 1; + x:= x + y; +} +init {} +env { + havoc y; +} +prop{true} \ No newline at end of file diff --git a/subprojects/common/ltl/src/test/resources/xsts/simple_color.xsts b/subprojects/common/ltl/src/test/resources/xsts/simple_color.xsts new file mode 100644 index 0000000000..6443992dff --- /dev/null +++ b/subprojects/common/ltl/src/test/resources/xsts/simple_color.xsts @@ -0,0 +1,24 @@ +type Colors : { Red, Green, Blue} +var envColor : Colors = Red +var modelColor : Colors = Red + +trans { + choice { + assume envColor == Red; + modelColor := Green; + } or { + assume envColor == Green; + modelColor := Blue; + } or { + assume envColor == Blue; + modelColor := Red; + } +} + +init{} + +env { + havoc envColor; +} + +prop{true} \ No newline at end of file diff --git a/subprojects/common/ltl/src/test/resources/xsts/simple_types.xsts b/subprojects/common/ltl/src/test/resources/xsts/simple_types.xsts new file mode 100644 index 0000000000..3f1dda287f --- /dev/null +++ b/subprojects/common/ltl/src/test/resources/xsts/simple_types.xsts @@ -0,0 +1,16 @@ +type Abc : { A, B, C, D} +type Colors : { Red, Green, Blue} +var letter : Abc = A +var color : Colors = Red + +trans { + havoc letter; +} + +init{} + +env { + havoc color; +} + +prop{true} \ No newline at end of file diff --git a/subprojects/common/ltl/src/test/resources/xsts/trafficlight_v2.xsts b/subprojects/common/ltl/src/test/resources/xsts/trafficlight_v2.xsts new file mode 100644 index 0000000000..e2f50cef51 --- /dev/null +++ b/subprojects/common/ltl/src/test/resources/xsts/trafficlight_v2.xsts @@ -0,0 +1,169 @@ +type Main_region : { __Inactive__, Interrupted, Normal} +type Normal : { __Inactive__, Green, Red, Yellow} +type Interrupted : { __Inactive__, Black, BlinkingYellow} +var PoliceInterrupt_police : boolean = false +var LightCommands_displayRed : boolean = false +var Control_toggle : boolean = false +var LightCommands_displayYellow : boolean = false +var LightCommands_displayNone : boolean = false +var LightCommands_displayGreen : boolean = false +ctrl var main_region : Main_region = __Inactive__ +ctrl var normal : Normal = __Inactive__ +ctrl var interrupted : Interrupted = __Inactive__ +ctrl var BlackTimeout3 : integer = 500 +ctrl var BlinkingYellowTimeout4 : integer = 500 +var c : boolean = true +var b : integer = 0 +var asd : integer = 0 +var a : boolean = false + +trans { + choice { + assume ((!(((main_region == Interrupted) && (PoliceInterrupt_police == true)))) && (((main_region == Interrupted) && (interrupted == BlinkingYellow)) && (500 <= BlinkingYellowTimeout4))); + assume (interrupted == BlinkingYellow); + interrupted := Black; + assume (interrupted == Black); + BlackTimeout3 := 0; + LightCommands_displayNone := true; + } or { + assume ((!(((main_region == Interrupted) && (PoliceInterrupt_police == true)))) && (((main_region == Interrupted) && (interrupted == Black)) && (500 <= BlackTimeout3))); + assume (interrupted == Black); + interrupted := BlinkingYellow; + assume (interrupted == BlinkingYellow); + BlinkingYellowTimeout4 := 0; + LightCommands_displayYellow := true; + } or { + assume ((!(((main_region == Normal) && (PoliceInterrupt_police == true)))) && (((main_region == Normal) && (normal == Green)) && (Control_toggle == true))); + assume (normal == Green); + b := 4; + normal := Yellow; + assume (normal == Yellow); + LightCommands_displayYellow := true; + } or { + assume ((!(((main_region == Normal) && (PoliceInterrupt_police == true)))) && (((main_region == Normal) && (normal == Red)) && (Control_toggle == true))); + assume (normal == Red); + a := true; + normal := Green; + assume (normal == Green); + LightCommands_displayGreen := true; + } or { + assume ((!(((main_region == Normal) && (PoliceInterrupt_police == true)))) && (((main_region == Normal) && (normal == Yellow)) && (Control_toggle == true))); + assume (normal == Yellow); + normal := Red; + assume (normal == Red); + LightCommands_displayRed := true; + } or { + assume (((main_region == Interrupted) && (PoliceInterrupt_police == true))); + assume (main_region == Interrupted); + interrupted := __Inactive__; + main_region := Normal; + choice { + assume (normal == __Inactive__); + normal := Red; + } or { + assume !((normal == __Inactive__)); + } + assume (main_region == Normal); + choice { + assume (normal == Green); + LightCommands_displayGreen := true; + } or { + assume (normal == Red); + LightCommands_displayRed := true; + } or { + assume (normal == Yellow); + LightCommands_displayYellow := true; + } + } or { + assume (((main_region == Normal) && (PoliceInterrupt_police == true))); + assume (main_region == Normal); + choice { + assume (normal == Green); + } or { + assume (normal == Red); + a := true; + } or { + assume (normal == Yellow); + } + asd := 321; + main_region := Interrupted; + interrupted := BlinkingYellow; + assume (main_region == Interrupted); + choice { + assume (interrupted == Black); + BlackTimeout3 := 0; + LightCommands_displayNone := true; + } or { + assume (interrupted == BlinkingYellow); + BlinkingYellowTimeout4 := 0; + LightCommands_displayYellow := true; + } + } +} + +init { + c := true; + b := 0; + a := false; + asd := 0; + BlackTimeout3 := 500; + BlinkingYellowTimeout4 := 500; + normal := __Inactive__; + interrupted := __Inactive__; + PoliceInterrupt_police := false; + Control_toggle := false; + LightCommands_displayRed := false; + LightCommands_displayYellow := false; + LightCommands_displayNone := false; + LightCommands_displayGreen := false; + main_region := Normal; + choice { + assume (normal == __Inactive__); + normal := Red; + } or { + assume !((normal == __Inactive__)); + } + choice { + assume (main_region == Interrupted); + choice { + assume (interrupted == Black); + BlackTimeout3 := 0; + LightCommands_displayNone := true; + } or { + assume (interrupted == BlinkingYellow); + BlinkingYellowTimeout4 := 0; + LightCommands_displayYellow := true; + } + } or { + assume (main_region == Normal); + choice { + assume (normal == Green); + LightCommands_displayGreen := true; + } or { + assume (normal == Red); + LightCommands_displayRed := true; + } or { + assume (normal == Yellow); + LightCommands_displayYellow := true; + } + } +} + +env { + choice { + PoliceInterrupt_police := true; + } or { + PoliceInterrupt_police := false; + } + choice { + Control_toggle := true; + } or { + Control_toggle := false; + } + LightCommands_displayYellow := false; + LightCommands_displayRed := false; + LightCommands_displayNone := false; + LightCommands_displayGreen := false; +} + +prop{true} \ No newline at end of file diff --git a/subprojects/common/ltl/src/test/resources/xsts/weather.xsts b/subprojects/common/ltl/src/test/resources/xsts/weather.xsts new file mode 100644 index 0000000000..b5d9da75dc --- /dev/null +++ b/subprojects/common/ltl/src/test/resources/xsts/weather.xsts @@ -0,0 +1,104 @@ +type Weather : { Sunny , Cloudy , Rainy, Foggy } +type TimeOfDay : { Morning , Noon, Afternoon, Night } +type Clothing : { Nothing, Shorts, Warm, Waterproof } +var isWet : boolean = false +var looksOut : boolean = false +var isClever : boolean = false +var weather : Weather = Sunny +var time : TimeOfDay +var clothing : Clothing = Nothing + +trans { + choice { + assume time == Morning; + choice { + assume (looksOut == false && isClever == false); + havoc clothing; + } or { + assume (looksOut == true && isClever == false); + choice { + assume weather == Sunny; + clothing := Shorts; + } or { + assume (weather == Cloudy || weather == Foggy); + clothing := Warm; + } or { + assume weather == Rainy; + clothing := Waterproof; + } + } or { + assume (isClever == true); + choice { + assume weather == Sunny; + clothing := Shorts; + } or { + assume (weather == Cloudy || weather == Rainy); + clothing := Waterproof; + } or { + assume weather == Foggy; + clothing := Warm; + } + } + } or { + assume time == Noon; + if (isWet == true) looksOut := true; + } or { + assume time == Afternoon; + } or { + assume time == Night; + if (isWet == true) isClever := true; + clothing := Nothing; + } +} + +init { + havoc weather; + time := Morning; +} + +env { + if (clothing != Waterproof && weather == Rainy) isWet := true; + if (time == Noon || time == Night) isWet := false; + choice { + assume time == Morning; + time := Noon; + } or { + assume time == Noon; + time := Afternoon; + } or { + assume time == Afternoon; + time := Night; + } or { + assume time == Night; + time := Morning; + } + + choice { + assume time != Noon; + choice { + assume (weather == Sunny || weather == Cloudy || weather == Foggy); + choice { + weather := Cloudy; + } or { + weather := Sunny; + } or { + assume weather == Cloudy; + weather := Rainy; + } + } or { + assume (weather == Rainy); + choice { + weather := Rainy; + } or { + weather := Sunny; + } + } or { + assume time == Morning; + weather := Foggy; + } + } or { + assume time == Noon; + } + +} +prop {true} \ No newline at end of file diff --git a/subprojects/common/ltl/src/test/resources/xsts/weather_noinit.xsts b/subprojects/common/ltl/src/test/resources/xsts/weather_noinit.xsts new file mode 100644 index 0000000000..78f5efe332 --- /dev/null +++ b/subprojects/common/ltl/src/test/resources/xsts/weather_noinit.xsts @@ -0,0 +1,106 @@ +type Weather : { Sunny , Cloudy , Rainy, Foggy } +type TimeOfDay : { __init__, Morning , Noon, Afternoon, Night } +type Clothing : { Nothing, Shorts, Warm, Waterproof } +var isWet : boolean = false +var looksOut : boolean = false +var isClever : boolean = false +var weather : Weather = Sunny +var time : TimeOfDay = __init__ +var clothing : Clothing = Nothing + +trans { + choice { + assume time == Morning; + choice { + assume (looksOut == false && isClever == false); + havoc clothing; + } or { + assume (looksOut == true && isClever == false); + choice { + assume weather == Sunny; + clothing := Shorts; + } or { + assume (weather == Cloudy || weather == Foggy); + clothing := Warm; + } or { + assume weather == Rainy; + clothing := Waterproof; + } + } or { + assume (isClever == true); + choice { + assume weather == Sunny; + clothing := Shorts; + } or { + assume (weather == Cloudy || weather == Rainy); + clothing := Waterproof; + } or { + assume weather == Foggy; + clothing := Warm; + } + } + } or { + assume time == Noon; + if (isWet == true) looksOut := true; + } or { + assume time == Afternoon; + } or { + assume time == Night; + if (isWet == true) isClever := true; + clothing := Nothing; + } +} + +init { } + +env { + choice { + assume time == __init__; + time := Morning; + } or { + assume time != __init__; + if (clothing != Waterproof && weather == Rainy) isWet := true; + if (time == Noon || time == Night) isWet := false; + choice { + assume time == Morning; + time := Noon; + } or { + assume time == Noon; + time := Afternoon; + } or { + assume time == Afternoon; + time := Night; + } or { + assume time == Night; + time := Morning; + } + + choice { + assume time != Noon; + choice { + assume (weather == Sunny || weather == Cloudy || weather == Foggy); + choice { + weather := Cloudy; + } or { + weather := Sunny; + } or { + assume weather == Cloudy; + weather := Rainy; + } + } or { + assume (weather == Rainy); + choice { + weather := Rainy; + } or { + weather := Sunny; + } + } or { + assume time == Morning; + weather := Foggy; + } + } or { + assume time == Noon; + } + } +} +prop{true} \ No newline at end of file diff --git a/subprojects/common/ltl/src/test/resources/xsts/weather_withprops.xsts b/subprojects/common/ltl/src/test/resources/xsts/weather_withprops.xsts new file mode 100644 index 0000000000..4cdde5291a --- /dev/null +++ b/subprojects/common/ltl/src/test/resources/xsts/weather_withprops.xsts @@ -0,0 +1,105 @@ +type Weather : { Sunny , Cloudy , Rainy, Foggy } +type TimeOfDay : { Morning , Noon, Afternoon, Night } +type Clothing : { Nothing, Shorts, Warm, Waterproof } +var isWet : boolean = false +var looksOut : boolean = false +var isClever : boolean = false +var weather : Weather = Sunny +var time : TimeOfDay +var clothing : Clothing = Nothing + +trans { + choice { + assume time == Morning; + choice { + assume (looksOut == false && isClever == false); + havoc clothing; + } or { + assume (looksOut == true && isClever == false); + choice { + assume weather == Sunny; + clothing := Shorts; + } or { + assume (weather == Cloudy || weather == Foggy); + clothing := Warm; + } or { + assume weather == Rainy; + clothing := Waterproof; + } + } or { + assume (isClever == true); + choice { + assume weather == Sunny; + clothing := Shorts; + } or { + assume (weather == Cloudy || weather == Rainy); + clothing := Waterproof; + } or { + assume weather == Foggy; + clothing := Warm; + } + } + } or { + assume time == Noon; + if (isWet == true) looksOut := true; + } or { + assume time == Afternoon; + } or { + assume time == Night; + if (isWet == true) isClever := true; + clothing := Nothing; + } +} + +init { + havoc weather; + time := Morning; +} + +env { + if (clothing != Waterproof && weather == Rainy) isWet := true; + if (time == Noon || time == Night) isWet := false; + choice { + assume time == Morning; + time := Noon; + } or { + assume time == Noon; + time := Afternoon; + } or { + assume time == Afternoon; + time := Night; + } or { + assume time == Night; + time := Morning; + } + + choice { + assume time != Noon; + choice { + assume (weather == Sunny || weather == Cloudy || weather == Foggy); + choice { + weather := Cloudy; + } or { + weather := Sunny; + } or { + assume weather == Cloudy; + weather := Rainy; + } + } or { + assume (weather == Rainy); + choice { + weather := Rainy; + } or { + weather := Sunny; + } + } or { + assume time == Morning; + weather := Foggy; + } + } or { + assume time == Noon; + } + +} +prop{true} +ltl{G(time = TimeOfDay.Noon -> X(time = TimeOfDay.Noon or time = TimeOfDay.Afternoon))} \ No newline at end of file diff --git a/subprojects/xsts/xsts-analysis/src/main/kotlin/hu/bme/mit/theta/xsts/analysis/util/XstsCombineExtractUtils.kt b/subprojects/xsts/xsts-analysis/src/main/kotlin/hu/bme/mit/theta/xsts/analysis/util/XstsCombineExtractUtils.kt index afda5eb642..579deaab67 100644 --- a/subprojects/xsts/xsts-analysis/src/main/kotlin/hu/bme/mit/theta/xsts/analysis/util/XstsCombineExtractUtils.kt +++ b/subprojects/xsts/xsts-analysis/src/main/kotlin/hu/bme/mit/theta/xsts/analysis/util/XstsCombineExtractUtils.kt @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package hu.bme.mit.theta.xsts.analysis.util import hu.bme.mit.theta.analysis.Prec @@ -23,15 +22,21 @@ import hu.bme.mit.theta.analysis.unit.UnitState import hu.bme.mit.theta.xsts.analysis.XstsState fun xstsCombineStates(xstsState: XstsState, dataState: S): XstsState { - return XstsState.of(dataState, xstsState.lastActionWasEnv(), xstsState.isInitialized) + // TODO here initialized should be xstsState.isInitialized, but that fails + // LtlCheckTestWithXstsPred + return XstsState.of(dataState, xstsState.lastActionWasEnv(), true) } fun xstsExtractControlState(xstsState: XstsState<*>): XstsState { - return XstsState.of(UnitState.getInstance(), xstsState.lastActionWasEnv(), xstsState.isInitialized) + return XstsState.of( + UnitState.getInstance(), + xstsState.lastActionWasEnv(), + xstsState.isInitialized, + ) } fun xstsExtractDataState(xstsState: XstsState): S { - return xstsState.state + return xstsState.state } -fun

xstsExtractControlPrec(p: P): UnitPrec = UnitPrec.getInstance() \ No newline at end of file +fun

xstsExtractControlPrec(p: P): UnitPrec = UnitPrec.getInstance() diff --git a/subprojects/xsts/xsts-cli/build.gradle.kts b/subprojects/xsts/xsts-cli/build.gradle.kts index b3a2eec787..209b728b48 100644 --- a/subprojects/xsts/xsts-cli/build.gradle.kts +++ b/subprojects/xsts/xsts-cli/build.gradle.kts @@ -27,6 +27,9 @@ dependencies { implementation(project(":theta-analysis")) implementation(project(":theta-core")) implementation(project(":theta-common")) + implementation(project(":theta-ltl")) + implementation(project(":theta-ltl-cli")) + implementation(project(":theta-cfa")) implementation(project(":theta-solver")) implementation(project(":theta-solver-z3-legacy")) implementation(project(":theta-solver-z3")) diff --git a/subprojects/xsts/xsts-cli/src/main/kotlin/hu/bme/mit/theta/xsts/cli/XstsCliLtlCegar.kt b/subprojects/xsts/xsts-cli/src/main/kotlin/hu/bme/mit/theta/xsts/cli/XstsCliLtlCegar.kt new file mode 100644 index 0000000000..e405e39812 --- /dev/null +++ b/subprojects/xsts/xsts-cli/src/main/kotlin/hu/bme/mit/theta/xsts/cli/XstsCliLtlCegar.kt @@ -0,0 +1,143 @@ +/* + * Copyright 2024 Budapest University of Technology and Economics + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package hu.bme.mit.theta.xsts.cli + +import com.github.ajalt.clikt.parameters.groups.provideDelegate +import com.github.ajalt.clikt.parameters.options.default +import com.github.ajalt.clikt.parameters.options.option +import com.github.ajalt.clikt.parameters.types.enum +import com.google.common.base.Stopwatch +import hu.bme.mit.theta.analysis.algorithm.SafetyResult +import hu.bme.mit.theta.analysis.algorithm.cegar.CegarStatistics +import hu.bme.mit.theta.analysis.algorithm.loopchecker.LDGTrace +import hu.bme.mit.theta.analysis.algorithm.loopchecker.ldg.LDG +import hu.bme.mit.theta.common.cfa.buchi.hoa.ExternalLtl2Hoaf +import hu.bme.mit.theta.common.cfa.buchi.hoa.Ltl2BuchiThroughHoaf +import hu.bme.mit.theta.common.ltl.LtlChecker +import hu.bme.mit.theta.common.ltl.cli.LtlCliOptions +import hu.bme.mit.theta.solver.SolverManager +import hu.bme.mit.theta.xsts.XSTS +import hu.bme.mit.theta.xsts.analysis.config.XstsConfigBuilder +import hu.bme.mit.theta.xsts.analysis.config.XstsConfigBuilder.* +import hu.bme.mit.theta.xsts.passes.normalize +import java.util.concurrent.TimeUnit +import kotlin.system.exitProcess + +class XstsCliLtlCegar : + XstsCliBaseCommand( + name = "LTLCEGAR", + help = "Model checking using the CEGAR algorithm with an LTL property", + ) { + + private val domain: Domain by + option(help = "Abstraction domain to use").enum().default(Domain.PRED_CART) + private val refinement: Refinement by + option(help = "Refinement strategy to use").enum().default(Refinement.SEQ_ITP) + private val predsplit: PredSplit by option().enum().default(PredSplit.ATOMS) + private val refinementSolver: String? by option(help = "Use a different solver for abstraction") + private val abstractionSolver: String? by option(help = "Use a different solver for refinement") + private val initprec: InitPrec by option().enum().default(InitPrec.EMPTY) + private val ltlOptions by LtlCliOptions() + + private fun printResult( + status: SafetyResult?, out LDGTrace<*, *>?>, + xsts: XSTS, + totalTimeMs: Long, + ) { + if (!outputOptions.benchmarkMode) return + printCommonResult(status, xsts, totalTimeMs) + val stats = status.stats.orElse(CegarStatistics(0, 0, 0, 0)) as CegarStatistics + listOf( + stats.algorithmTimeMs, + stats.abstractorTimeMs, + stats.refinerTimeMs, + stats.iterations, + 0, + 0, + 0, + ) + .forEach(writer::cell) + writer.newRow() + } + + override fun run() { + try { + doRun() + } catch (e: Exception) { + printError(e) + exitProcess(1) + } + } + + private fun doRun() { + registerSolverManagers() + val abstractionSolverFactory = SolverManager.resolveSolverFactory(abstractionSolver ?: solver) + val refinementSolverFactory = SolverManager.resolveSolverFactory(refinementSolver ?: solver) + val xsts = normalize(inputOptions.loadXsts()) + val config = + XstsConfigBuilder(domain, refinement, abstractionSolverFactory, refinementSolverFactory) + .initPrec(initprec) + .predSplit(predsplit) + if (domain == Domain.EXPL) { + val configBuilder = config.ExplStrategy(xsts) + val checker = + LtlChecker( + configBuilder.multiSide, + configBuilder.lts, + configBuilder.itpRefToPrec, + configBuilder.itpRefToPrec, + configBuilder.dataAnalysis, + ltlOptions.ltlExpression, + abstractionSolverFactory, + logger, + ltlOptions.searchStrategy, + ltlOptions.refinerStrategy, + Ltl2BuchiThroughHoaf(ExternalLtl2Hoaf(ltlOptions.ltl2BuchiCommand), logger), + xsts.vars, + xsts.initFormula, + ) + val sw = Stopwatch.createStarted() + val result = checker.check(configBuilder.initPrec, configBuilder.initPrec) + sw.stop() + printResult(result, xsts, sw.elapsed(TimeUnit.MILLISECONDS)) + writeCex(result, xsts) + } + if (domain in setOf(Domain.PRED_CART, Domain.PRED_SPLIT, Domain.PRED_BOOL)) { + val configBuilder = config.PredStrategy(xsts) + val checker = + LtlChecker( + configBuilder.multiSide, + configBuilder.lts, + configBuilder.itpRefToPrec, + configBuilder.itpRefToPrec, + configBuilder.dataAnalysis, + ltlOptions.ltlExpression, + abstractionSolverFactory, + logger, + ltlOptions.searchStrategy, + ltlOptions.refinerStrategy, + Ltl2BuchiThroughHoaf(ExternalLtl2Hoaf(ltlOptions.ltl2BuchiCommand), logger), + xsts.vars, + xsts.initFormula, + ) + val sw = Stopwatch.createStarted() + val result = checker.check(configBuilder.initPrec, configBuilder.initPrec) + sw.stop() + printResult(result, xsts, sw.elapsed(TimeUnit.MILLISECONDS)) + writeCex(result, xsts) + } + } +} diff --git a/subprojects/xsts/xsts-cli/src/main/kotlin/hu/bme/mit/theta/xsts/cli/XstsCliMain.kt b/subprojects/xsts/xsts-cli/src/main/kotlin/hu/bme/mit/theta/xsts/cli/XstsCliMain.kt index 73b01a8568..2f49876547 100644 --- a/subprojects/xsts/xsts-cli/src/main/kotlin/hu/bme/mit/theta/xsts/cli/XstsCliMain.kt +++ b/subprojects/xsts/xsts-cli/src/main/kotlin/hu/bme/mit/theta/xsts/cli/XstsCliMain.kt @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package hu.bme.mit.theta.xsts.cli import com.github.ajalt.clikt.core.CliktCommand @@ -23,23 +22,32 @@ import com.github.ajalt.clikt.parameters.options.option class XstsCliMainCommand : CliktCommand() { - val algorithm by option(eager = true).deprecated( - "--algorithm switch is now deprecated, use the respective subcommands", error = true - ) - val metrics by option(eager = true).deprecated( - "--metrics switch is now deprecated, use the `metrics` subcommand", error = true - ) - val header by option(eager = true).deprecated( - "--header switch is now deprecated, use the `header` subcommand", error = true - ) - - override fun run() = Unit + val algorithm by + option(eager = true) + .deprecated( + "--algorithm switch is now deprecated, use the respective subcommands", + error = true, + ) + val metrics by + option(eager = true) + .deprecated("--metrics switch is now deprecated, use the `metrics` subcommand", error = true) + val header by + option(eager = true) + .deprecated("--header switch is now deprecated, use the `header` subcommand", error = true) + override fun run() = Unit } fun main(args: Array) = - XstsCliMainCommand().subcommands( - XstsCliCegar(), XstsCliBounded(), XstsCliMdd(), XstsCliPetrinetMdd(), XstsCliChc(), XstsCliHeader(), - XstsCliMetrics() + XstsCliMainCommand() + .subcommands( + XstsCliCegar(), + XstsCliLtlCegar(), + XstsCliBounded(), + XstsCliMdd(), + XstsCliPetrinetMdd(), + XstsCliChc(), + XstsCliHeader(), + XstsCliMetrics(), ) - .main(args) \ No newline at end of file + .main(args) diff --git a/subprojects/xsts/xsts/src/main/java/hu/bme/mit/theta/xsts/passes/NormalizerPass.kt b/subprojects/xsts/xsts/src/main/java/hu/bme/mit/theta/xsts/passes/NormalizerPass.kt new file mode 100644 index 0000000000..ee409c490e --- /dev/null +++ b/subprojects/xsts/xsts/src/main/java/hu/bme/mit/theta/xsts/passes/NormalizerPass.kt @@ -0,0 +1,74 @@ +/* + * Copyright 2024 Budapest University of Technology and Economics + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package hu.bme.mit.theta.xsts.passes + +import com.google.common.base.Preconditions.checkArgument +import hu.bme.mit.theta.core.stmt.NonDetStmt +import hu.bme.mit.theta.core.stmt.SequenceStmt +import hu.bme.mit.theta.core.stmt.SkipStmt +import hu.bme.mit.theta.core.stmt.Stmt +import hu.bme.mit.theta.xsts.XSTS + +object NormalizerPass : XstsPass { + + override fun transform(input: XSTS) = normalize(input) +} + +fun normalize(rawXsts: XSTS?): XSTS { + checkArgument(rawXsts != null, "Can't normalize null") + val xstsInput = rawXsts!! + + val normalizedInit = normalize(xstsInput.init) + val normalizedTran = normalize(xstsInput.tran) + val normalizedEnv = normalize(xstsInput.env) + + return XSTS( + xstsInput.ctrlVars, + normalizedInit, + normalizedTran, + normalizedEnv, + xstsInput.initFormula, + xstsInput.prop, + ) +} + +private fun normalize(stmt: Stmt): NonDetStmt { + val collector = mutableListOf>() + collector.add(mutableListOf()) + normalize(stmt, collector) + return NonDetStmt.of(collector.map { SequenceStmt.of(it) }.toList()) +} + +private fun normalize(stmt: Stmt, collector: MutableList>) { + when (stmt) { + is SequenceStmt -> stmt.stmts.forEach { normalize(it, collector) } + is NonDetStmt -> { + val newCollector = mutableListOf>() + stmt.stmts.forEach { nondetBranch -> + val copy = collector.copy() + normalize(nondetBranch, copy) + newCollector.addAll(copy) + } + collector.clear() + collector.addAll(newCollector) + } + + is SkipStmt -> {} + else -> collector.forEach { it.add(stmt) } + } +} + +private fun MutableList>.copy() = map { it.toMutableList() }.toMutableList() diff --git a/subprojects/xsts/xsts/src/main/java/hu/bme/mit/theta/xsts/passes/XstsPass.kt b/subprojects/xsts/xsts/src/main/java/hu/bme/mit/theta/xsts/passes/XstsPass.kt new file mode 100644 index 0000000000..dc2dfc5f07 --- /dev/null +++ b/subprojects/xsts/xsts/src/main/java/hu/bme/mit/theta/xsts/passes/XstsPass.kt @@ -0,0 +1,23 @@ +/* + * Copyright 2024 Budapest University of Technology and Economics + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package hu.bme.mit.theta.xsts.passes + +import hu.bme.mit.theta.xsts.XSTS + +fun interface XstsPass { + + fun transform(input: XSTS): XSTS +} diff --git a/subprojects/xsts/xsts/src/main/kotlin/hu/bme/mit/theta/xsts/utils/XSTSVarChanger.kt b/subprojects/xsts/xsts/src/main/java/hu/bme/mit/theta/xsts/utils/XSTSVarChanger.kt similarity index 100% rename from subprojects/xsts/xsts/src/main/kotlin/hu/bme/mit/theta/xsts/utils/XSTSVarChanger.kt rename to subprojects/xsts/xsts/src/main/java/hu/bme/mit/theta/xsts/utils/XSTSVarChanger.kt