From 03cc82d33dfe106fac6b8e2f93ff62dfe64fac37 Mon Sep 17 00:00:00 2001 From: Mysaa Date: Tue, 28 Nov 2023 17:38:25 +0100 Subject: [PATCH] Fixed CYK --- .gitignore | 3 + CategoriesGramaticalesCombinatoire.ods | Bin 29926 -> 28323 bytes test.ipynb | 1890 ++++++++++++++++-------- 3 files changed, 1267 insertions(+), 626 deletions(-) diff --git a/.gitignore b/.gitignore index 4f38e59..82d1b3a 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,6 @@ # Lock files from libreoffice .~lock* + +# Jupyter Notebooks +.ipynb_checkpoints/ diff --git a/CategoriesGramaticalesCombinatoire.ods b/CategoriesGramaticalesCombinatoire.ods index 378d3e1f8cc9278070c85dd58536fe2e63835163..1a1f10acd2fd6864df80ed64808c1d2abe21e7fe 100644 GIT binary patch delta 26629 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 f=*uFT1uB|J9cw=?#>8#wC9OI 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 delta 28214 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 z z|KNEtqHj%c;EK3&_UHHNeO(>oeCk=xwPhMBatbDv~C2m>%EO(`K9&CKcAZu^m6~4dbwM|FPe86MCs~0Fy#ASv#fXJW04^5E3YG!ZgJQr z_zBM0>#5tcQBHqV;ZJq%X)`Y!T^^{pV1lP;q3E;KXPvkCE!h+Cac0TF>sH=H%^A05 zOpPmW?Mv8oplum*ZvWi+xh{P=dvjdotF~Oe=Ke!8ruCRW!osqLJB1D9E6bO!jc;z) za6ctw5x1`L^(9kGj|*_yakL+QC(&N#r{Zu&Y{`74t|`SErzQV#QPg3aqFLp|GJj%+ zXcp77>@>%9U1ez<8*?3neRoaW;CYbifyPJ1dmJ$t%Is?{+>CMKo_%hjZ#}27p7}qn zx|S6p*PG^u<%qWkFXeoE`2GI`9{VXx(IR)GtX7}NJaXOf1goaSCf}=muY9j$=joWe zTr&6QjZiJcB1io%h1x4;?#*CR3UfFmn9}CWrp$HFyqLxHh5+xWb(6)CKS~y*e0lR$ zw%mH#`VZ+3bPiv;+PZf4^}F_~+Se|x=a1fB9>5g`>)>|%T|Fz+* z{QK*N%T{pTzIg9rpl;5VGwlIJ(F|(qQUYCFKRseu^wA|HSuZWC~6!@MP+% zc`)40aZaeCH zI1pRkqn_uh*DokH+pf^XTh8?73bx$DnVyd4y}g(mp6bo~wLxUVnk^2mBv~7SR-V~l zX!!Jb<)3Mhe;-#)-fZBk)Hr{pRs+{B;aT!qR(UwRQ`EVz<3RFHrOLZcguM=ZJkn#n z$l#!N%a7O%3X6Z~dGjB=5Mt@PzvGji^@CTl*gsf^e6Fv$)f5rC;i%Ni;Dy)bx6Sn8 zRM6^Jrl)O_!z8m){1eBDh&1O_7oN3EGBNLtv{ITE9Hg(*e&@N1g^J?o*M(88TFciO zoeW7|7BPWw&kmtkr#<$n8cqDR=#WdJ=S}^|JB34L`Ec3AJh>hGr02BI(X>;_vZ_px zzGoFrzcuB*w~k?My_e`AKX3I6!HTFayOmyKW?KFTd2-Rk*?vYtM_0du&%*Wv(FazQ z+&cY6S+s+SD>RU{p0UaG#b%2cscONk>aE6s&XUK^FYa0O z;gr}@Yo_%%vHMgjloRTugDbNp8T{+j{&(x`HM0ZLb??mQu~~ko-nHI0FO^~LayiC@ zN-;B)5AC!u^h}OXeCNZ;zblKi@&^BogB|TMkA0*6rY_A$`H;E#W2#@%k0e=Nn~ih# zDEQiJ^_-URXeL|DPm5?V#${V==IWkQ4lN3t4d1<~MGq#$lzRT! zYt$P%(Q%#6{Ojig%uk-%bTa2){YlqIuE>hC@M&MxdFXKqP3H1UYCN$@r7}}(mvZN_ z&?+}!@t%%ib9;3@4HmxH4kyn0EsC|O%y)aCsca(oq^MZ$=7HJUUv@oR{<2Z(C?Zro}!PjAvJ#q%2(OK;RP8)=2C-yutr**PzjEcmE~GB+Guo~F@`B|H*>$c?UTLhcrzTHhEm^cyDW~YZ z?M_D43dJ60<;NjAx~EONb3Zgd?bdYFgExOpuRkrU{qO&gs5e`bdLH*C)(EX`Xs>5H zQpR|O{lIPOrp23;Eq3j0NapxEcZPUlvidXE2P-V~rOSS#Pu;U|*5nOy{j#%atmo!6 zew+K(ePf#5E~OxQe1vxHlo7i|{5cC^&_&UKfVGm($erFZQU*d^4n@F}xR zTh->%6aPH>9lp2r)!W?DH;eagocw&7@T%J`0%hg*H;c>e$x+n4RWCK=*t)V?>sI_( zv_Id7yw{G6jwtM%P zy8^Z9XL7go#0h3EJ-*c`=O;@v&#R@An7``%yME_j{)*j`uS{h>!v8(&3!84G)VG5F zv&<*I%2PFcb2s&y-JRRQ4W{{<7?wYK8FcZ%?_d2v=5O;)Z{KYCeDnECs~HNvYG?I6 z`&)l1_qliPO`GL6Sr`m|uHmW7Z_fKX^HuDkb=!CT-DR|tx3uEt)5p^rKQ<<`&1tXZ zS}Br zD-F26u3PU~m3q}?-d&4>x88*pN()z}D8;T-dldP}wf?`P*rBTOpvC243^^|UQ$s2> z_gsn=)wvhDUpDISlL_8l^E2aqbpKm_&vf;SaMAV&?`phvm!5Q3^1a*fu&(?oQ?pNd z8awvXDMv~+rM%eL$9z#uF@se%?#Z(Qt2x=X{ABEW-?E1LOr-XqJ#%tZzun*8KFfTX zRGN8SMeeRi1xy0*Qb70NRW2Ss<=?#x-RpN%)j^f z{~hKvE);C>NSX5~jOFn|`#Da{t?{q#MaLc7U>0Td%vzvm=e65^7yqrV+kfZRw1-x& z>^l#xznuEb>(Yidr%u}KQeL`|`H1y|^WP`z|9Z4bU;1;HU$nWoeL~aw8lg?nUwQgx z_wV1kGgJN4(}q69{#P>(6sGi_JZ$%^?gh`I|90A?^5^C=3);HhD4D1(?_$Gc8SXFP zDPJ7JWL|0F^=_g1$)hheYMfMWzfr$%PpO-p|Bed#-}a!!vih>?%fE9mFwE&jYb>LT zRq}wwDpN~JGV{{Gqm^%C-WNTx5c*%|Kk?D!Sl`r!7EiS+D$$!ZGS3v)u<_*l{6id% zowr3q_9^CXIbWz>Hi>5@OMx1*#qRR@)$z+7oyaQPerxT!ZO1=tzn`XPSK(s9=TQ>3 zs&3sBzJMna69s-gSG{h?zkgcY?jOg^jigxRR`GXEZ_!9Rrj1gQJj>q+1lx+lN{VW&J5UJ6SDHksmN+i z+r#yaCY8(lFMlbn(#c$%o}Qk1bGOP@4->9G-?gR%rg!O1sY#sm_|nl!e5YT=*F^K2 zNb-+Mw0@rvFdmSl;ev;$mzP zGqv^7*>KOkhjPx(-(Qqiy7pn$EW^cjSiQs#Dc1Q0A1rb8XD{mh<8$%4b5(Ln#8+9l z73wBxTf84Nd}J-ye)5+4?bwso=e#$MKmIm?xu3Ovh51p&&52JIhd%D-yc_p^>9OiK zbMI|s^Mc=>DBu6FKKW#*a?iwq{vLS_PT6y*pH*)+X39TGnVS79<@oJe48J^d-kI;5 zpL24Lx!Oxr-mu5V8U%V0LUtvXI7aLBop^lA#hLwVM7#PnLA95rpB9>*pKRJ>aW5$1 z*pB1LvToNMTYQ8zPPyR8xTr+P^+a;ZF2h%@1zDfn7?Yyvj;vk&@lU-mqjFn@^+BBj zNm-1Cc20lI+bHd~&qu%Vt`YwpbCFX#6DK!q3fVB%a8?VO|DQ=tcRp(ztYFB@yR^RU z@1~_9qQZ4YSQH(s;-@PG+K4=O=yZm8k;^Oj_x22&|IAxNkKR%-@iFMRJ;ATY^-adS zB&E#{RtfvOaGP#pWoc*it7sE@{dLU)AGjB1Psm$yO5D5jwgz*ubW7%r(ja`<3L-hyGE1NZMt9ceWUX4I3o$Re#beh|IM3`A66HA{p5}2NP+Lq_5{^0 zQQ?~RX>Z8Xh4r6}NwBcC$=L#8{W zR!58LJTsY%A{c(R2+Ah)KM$BD?Y}*JeZOL>T)FVvmf)@=L9=ghfzl5dcpYU9blm4* z304z}Wc(S`CHVP3M%bPO=9TX^)Tw^Xe)n3wK4FcYO6>LxJ4GV4f4bCP?04vdTBh(p z#YLKU!Mx)aBU4w{JbZyeaHX#Gm`F{p&w8b)9_Q;Z_t`KKVp)XV3Xo zj$ae3{w#hq`%rg5+;N{fFDE?jHj{kj^69Z|q_D-7pIOQ_1tJS}p1Im_?}OVpDw)7Z`nTFUHnhx-naStW?%2U|32@--?`ST^@=xY&lYN#{=deu=5M}o z?(12f3(8GvcVw@hbdM>4!L}k#nxUuqk;Rk!w?cPc_J8{G{edry_1p~1yB3aq>g zQ4YlimU7#~&pwsR#bFTr;K-$UF2C}mm`HAPBAMDq4e!R=v?80@GiD3_qeQiIT7yEem z){@q3XC-f_ZD%M5Ud!DxYs2^Yy&3V*34Bs)%OA{oxkiGH`b&enR%lbZT1 zq9P(9B6ciB`#;ujZ{d7U`JIg=VE)M;dXM+y?N!sCzJFcOkK#|8nhwPa?~3tXpH;6N zxBlmzyxoO%qN-cw==4CopTw>21uRrssKecpcMv8lOugCOq z)qmYqLCkYEIoyhxlhG`dv6eR^;K%KQ=ifbwU!eHzz5I`}88^>MhbUaT{`u1$zMhlD zuFBH`9*Qq~`seSg7mI5gW5YTZ9IgMCqbedIQV()2DlU5Pxn7K6*X+IV3%i%!p0)AC zl`zlxuIJxh^-R}4DLMV-joC+kS7a})J7ILqDs_HE_{aY|ZR<_vcwOD}>)Q#l-_w%6 zynnBCbzSa`*n}IQ?~B?d2G-W>DDk(Ny!pdH|HkaNSj!t`u{GB=-dUBo>{k8W)#1-_ z*_Y^kW~){_cCY4+xBrLBhu22_%{zMFS@N&Rb??`GaxIRz&gyo*NIQM*w4MLfZMd~# zrCHv-lzYwnCnVJ$Dl|DV-oDTByY8Fd8owpULgEjt|KHyIo%`P!$BDbYbN_#I*e0pq z+T_{RIVQLEgg-5@zIRhhV&nS5jt@)XZ>tA?w%a;2_uA#BE02aJU>$*ALZ4Y$+X9CsF%ieQzg|jm-1O~wBXXsRP_$P%5H#uJh207o! z395$m=NK567&w?27#M7fYHl+yFq{nV32|j)WaQ;#;O6EQ5@L{+W)Kz@mXVQBRb|l8 zVK6XYu(V`QR#w*5);2LQv9YmnaA5HAVh9dqh>K%LPiM%^W+*OZsH(oH=tAFJ8QQ_3F)=H}BoM_weDv zr%s)^eEIU7J9i#Ge*F6N>rbCP{rmTifq~)w|NoArFYhogC@^@sIEGZ*db_u?>9I%A zvdp(a2FBgV(bn}@mU)@!rkB=TnY(#MetG@>LD^AkkJcnXm5PVW zGv&YSmYlKKHn91#$Q+CFWsm;sxyEDvcS@#`CVJz8N+~nb_Z!b$`SSOkUph&D9_=muY(nM%zYvno-y&oEUg+=^Hm}} z70aXFe-TyNU}tbR{Ou!yxo2iM8P2+OBDOGVJ(K+XbNUXCc3-rg_IT4nlhcI-PBXq& zJp8&>{xPdWiZkQnnJ$(`*6q6|KShoEmtyJtw6jrr6h1FnSX_MBBG9-&>B>vL_=N>= zzv{~_^2`kA*t|qr?bc1JsSWp3d_AveHs%W2en?rlN|`55&w}@Y{#Bnifx=5upI=dP zYq64A|DC<{W2VT5V}ci%t}}NWecg#SEI-1t?y{_)h?iMRiDY;IXo|5|;1e1X*6 z>8Vd1sn#8w`KHx)n)&;P>8%+)`OihGqt$OF1@?4er^-LuCM&;D)%X^Z#S&gZtndqW%1Ts-?{hTOYuK5_TIOOez$1H{t9RAwem4sv4Q2$ zQLkfuzO37MIb6a_KA^Yl_bclt^?e0iDj%~o*)yI@c1YyAQJ!`2vIkQ==SQo_(&u>e zJyd_a{_D7~a)EZ+_Ia6AilQyc4iqo6xz3l7$z*sa@9}{PbAL*`Hm&b1%-+#oy6RTu zmXB)29v?o`x?O*NjOT~$2eDN@Gp_CITEUU6ah3J?tG1o;uU`Lskt1xb-}GSZyrqJ1 zGMxd5@{`3JTR(3TxL+s~sCMe^zGg1RV|(-jcc)HjE1ISF((SzXq3>7nERH9Jq%9R) zoA}`LPW|q*n_@fL5@Yxpig(p?)KA>^Jt(aErPtB#ektv#7jFH2e)_L-WLf@u^^oXK za}N5b_T|nNisw38y!P$f-L>7Ta$bIZz3j!=7``8o?ycz(|L(VV&*e$@x}3<*7HK8rTxKa1+_qN@qbn>IFM8?>kXTB)izU=ed36;-wo^F2R<9_*Yv;XZ??~mHf*{JP0yl-hr*yzhbRuVAeY>A?rO z#I`KZmh^e~r0T2D<_@?1MbRlHm!fQF% z92E7c7A@JaC%m@){a5cT&s+Q&uW!D=_a~<=VosC@d%V(RnO|SKT91}SW@yRhfBvBL zx8t(zg`R7fw_Lmeqvkl7uMu?IGd05KKa_hNkPyDRUb>wfo7HRCKzn^V)e73IK{h!nK2YpX0^s9gM!6I|U<0~@9 z%>!$W&b<6~)1C-*tI+9dx9o^WKVQYQyiRtx*3Tlf%i$Z&mE~PNu=r7qqK%E8r_hAX z)|cHc)}1R;VTn6<$>)`H_LIK)M-R->*YZa#FZ24<_4@U>u-$^K2ZV2N3z!LuRP1KE zxcJc{DmG7dCIJU;QO>%b?j@O*`4`PyCg7tM%oSjPK3jV5ysYegZ+$ zf9={lm-#~t$BBvJoiAfP*mhi5{HTT{-Fnr>Mdd$#9bVOVe1Y($9WtBvGID=O-Hn4jU^3<@3gSXl8_T>j#cGsW#rUI%sYzpVS1t(4S_Fa!P>yOm% zrpM=fobobJM0Dk!gGUUucTM`ZcJ}>Sx^rE_1Fn4E)W7i1&cJEwzuj50v`%7~{Y+5qv(k zvt9A*ZK-prAN!@=`khPNZ5kExT_ZNEWm)*kdab@iv&2M>9UC?_!EgRB`S%^PQ%|!0wYUwpjW`M!jUOqk)!^z!}BO~1}H zUh`x5vkb18(NA>5mH+rjYZfx7?g^OU+F=$yyDdenFjH+Ix4*s6xt+(?E3H|-HsgM2 ztG&nhaAB8Y!d9)f*6f#1pID$JmYM5#{>l@Pu$8U6RelEbz0uF+*|^N%b_z1P*7;0w z;_*A*ZqzTon3r&?A~$393$Jibk4-G;ho+m}(w94Z(@*!IN_=--sFI%y!wW@Y(GwS& zZ#Ks3&e^#_&?3#!S>V)#sV%*Ws%NQkaw&=&QdE_Xe(rQFb1KIVn|tg3S)IFe_1Mx2 zk&ZVW-`Mab(W%@tu%({&8T+9~rx+!_Pg_?%pQ3njjnj(9lJXx-yb{>n)jr zSj?|kMv2DnepnMLH2;`qlKYV-9eZY(>~(uIds6AFt0(2zmWyo=@cXn?^i%SjV~guD z1Z`fPdKmsbBwRqpqAqsrB8ATvzIZ%V^>R+SEvg%IlH=q#w^q$a-M;JzOO5K*_&!^8 zf3x2bwKq0x0*_p#q%G>1wpMuk>*E{G)kj%mikN-jy(Vxdx!96H4KB(;sf#c6R=d;aX6;)}jQ)%_j~E?Sngf8MZ1olX%x z6#iz1=IKQ*UyA4yMYmQhNo`qd{`c;OQn^{1ZPm`b@ANLJ{8a5T=Tmj_Mm6i7wkqc~ z&$X!cpObD4$&tSwz3C468|d$py;S+_2OEpbweS18j5qC^vG`AA!L0m3y{8N9R@`F| z)ZZm^FJ+7O8udwgKK;|N@U&he8xc19Px+JCCoBcLSL~f&wp)Ln`bvpF#m5&ot?V1} z_~*DP&1ZYQOjd9L+XJoO)~WsKnv5L$lm9z$d)7PdzIvjgsNH;7)5S9l^+&4Ttm^f8 zYI44*_;TNb&0iOo-_4S;3DoXTuJsYC^?9{x=DaBiOa5v$$F8|-(pM!kXLeaj0oxqQ z`ZI#hi&W;sEO0!yW$CUBGrfPD%Tk}C<};6Z`MoX5;&X&PJ;|`x>A?JGOJ~NVg3ae_ z3(qB0@V&mXrCwS3oZz3wmbbf0ZAEa(ulRvZg!Lh}E(`Sn^EvL9f^)8A z8r7T1-n+-R{M!S~f>(zG9o)LMB$&Oie)QvEacZr z@cO>{wfVjCCq$HXf1G$d=kY0ydvzY!9ZhC$ncU~dCAU9sejrm4Z#GLy`TMqx!sC9W zYrXj7zofcu-?dQd)RUb0>J0I7g+^0Vf8ME#UG*vSy5!QBl}&|8juQjBSPpgOoK?~2 zkj zk`!?w>SMat9NETu4-yNGUD&Ys?7}eiuRF~mJENs$=0ytl2;J^c?Ojk{mg+Mj?Zl0* z`*N1$?-ZLJ9XM~Ye9wFV^{0yz=OorUTku9|D}H6WSFii{_`#QrYc<6kLmG+$=0rae zIyuvON38Mm71_@wDYBSf*YC`@H*06hqq#R6mHbYLEt}i;dY!;Iljm1pU%p%5 zb)r4dM#FENMyj^x+UaX=m=$+kSZT72i_0nZ?w4y;l}pOc#svLiP%oR%u{r(XsRNon zW$J6rn{Bu$=#^hHWnn`?*yNB6vbVw7n&2Rqxw)LY3A#l8tp;LqCy`` z&GLK``RD3sjwPa`i<)9D7C)GBy&`?>fy0H2D+`J) zJGq1z&SGxK)t~)x`yGy=|97uBoc zPF+3UYW(O_K>Xt?OWErm7Op7{u66x>qW3}i$KVG&>%8_o5>vO1KGphE{ zLD(RqFQQKO+(X`lQ=it`-CkqTzSdXgWAnMp8S%~=miB0D{V?Ukj^$TRnNEHA>+-p4 z>7LH-?tY#0=EtOvkm5xiFPe{+AF33b-qY!mRvb9}#iBQ}H0GIK>@F>+o~o4$92w-4t*0p}9Ixf9k; zo$$cM{>dU^~P5lp6Dwtoo&1CuQ-b`<`%^td+KYs3+ za_Gra-t_h6uIbx^%csSDQ1x`QXqDg3HM9PWY(d-+RZF8qLYC7T(pwAiT-2Xrzg#H7 z6|7*eHm9&}?V-aw>t-I z-gnE+AH2{ZZvAb>T>sl0YoBG-&k;9u>e1kQyxqe5qGwp-oSSXMCl|k9TQ0=Z-}fOy ze~!&a7&c3`%u>a;2Rc}t=EzXjg z&biIt_WOD{qiNBe{Vx`YpIVr(_ImVdlgI-0IpT$$opXd_>MLryFL(L5NnOA9;0nX5 zYd2?|;X7j9dFr2Se@XSRn?jb|g`y@tJS%P=Iq$aj&rz%TvQvS-52`=0E*A1T=sDLU za(Upo{r2a&cd*3oDQBt;oW6#$Wfx2S#zn%Pw*HyWA|XFbtHFld(2r@?)n=x(BGF6U zUi|)|GN!uKy;4yx+()y16HB|{YW34MX4)srjq32fFkh@@rMb(bwUgZ!?Dh}IJEFSQ z?6pCk6uXqkjR5^clcj3kdOhafRV~A|bXAsQd!=OCOcu>$UzU8i82|ZVxrO*PnblII z(R5sR)@v~aT+`sSoOF4_v$;)?j|(KBYmZP8=7eDtQDT6S=w_^$`fKl0M0MH8#)=QMrJ zG&rYY92zlU>pjNwXDx~k*W5XfeMaP@Q`7zxDrbZoIWKZw=bxs@Is4x4&}!TI$jOGq zD*9osHZ{+9G;87Qg{j|GwS9m8yt}LO)BgLntvp|+6jtqBxkN4du6#PHWORDJc%{cv zmjy;bTzl*f*_oQ?if|wKv0VPhelB(H>`x7MPLxc&_c3Vqk{xrxXZD8#b#R5%-MMY` z_0^W1V!>HTDYj9s|5<28RIa=-;o@S_P@<{o1zdy^5oqyRA{byI%sk?=00Y=-}bc=uRo;%I+^7^ASHCoF$ zVo(AbJfZneV0Temv(Z_xm&0=?}W+&0ka~HOQt&oRx+qFzeu^x zGRM(f;F#*)oBy2VczqCmKgWh+=Yc!s*M0`3dp~Wgf0sYkZTAB0OB*6fPqLKHD34R& z`~0Ie^hD8$IdZ2Lw;R9TF@xh-j{gA0|sP-OjCCl0A?0dG)t_H)1$nr-ulh%V{WXedjyV+amPUZRz(*_y5oP z<$vU7aaKLc>^tgf*Q)*zOW*l@+G5?69xorT|IG^Z$mfoFy@9j!+Q;YjqdCn^i(M&x zFy~lXq2A%AF*<*^Ma|;fs;8}svT_b>d=Y+Y|85@P$05@%XI{zCx)CcT@#)k4aD{Vs zzCYYlVPnzwT-WV*-l(yTIrGv{_huG;4U73_&gXI5DcjHM-)Ov>bHdRdbF~UKubOedRbG7yQ-HF|G2vNG zDZDLahg(l(y(v^K+h$zfev!+#(c{*M9lxX1n-{l;*s6N$IAUFy{?}@@!ehA!Nq1cS zJ>UL1$Zp~xWB|J7>FHlCeYpyYL`c7aw08~-$+-06HVlIp*rtY#Gi_4e^uUM@aU z#Xo0>@S_q#8BAw6h`;;BtUCuryW5U+#xGhe_vDa7KEZC*`JJ~iy_~M@>rH`gw;{K|0 zEputSWOVvZUcY7w=?5la@eh~8aE7dED%h4Y_af_a+clR@*yu<+&&es9=RM#2>YS2} zIZuBF$1W-S#KNq2EV4%V%%5XctZP;m)L)aH^CCyIKb!r-ONq5D?dyZ~M?9Bh6P

=H(wdo}KQ~4da9rs;cqZ>_V~F@Oi;2;rY*3 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\",span,start)\n", + " \n", " bestedge = None\n", + " nedg = 0\n", + " # edges[s] is the best edge generating the category s\n", + " edges = dict()\n", " \n", " # Try all possible pairs of edges that could generate\n", " # an edge for that span\n", @@ -97,40 +126,60 @@ " lstart = start\n", " mid = start + part\n", " rend = start + span\n", - "\n", + " \n", " for left in chart.select(span=(lstart, mid)):\n", " for right in chart.select(span=(mid, rend)):\n", " # Generate all possible combinations of the two edges\n", " for rule in rules:\n", - " edgez = list(rule.apply(chart, lex, left, right))\n", - " if(len(edgez)==1):\n", - " edge = edgez[0]\n", - " edge.weight = rweight(rule) * left.weight * right.weight\n", - " edge.triple = (rule,left,right)\n", - " if (bestedge == None) or (bestedge.weight < edge.weight):\n", - " bestedge = edge\n", - " elif(len(edgez)!=0):\n", - " print(\"Too many new edges (unsupported rule used)\")\n", - " \n", + " # Can we apply the rule\n", + " if rule.can_combine(left.categ(), right.categ()):\n", + " for res in rule.combine(left.categ(), right.categ()):\n", + " # res is the new category\n", + " edge = CCGEdge(\n", + " span=(left.start(), right.end()),\n", + " categ=res,\n", + " rule=BinaryCombinatorRule(rule),\n", + " )\n", + " edge.weight = rweight(rule) * left.weight * right.weight\n", + " edge.triple = (rule,left,right)\n", + " if not(res in edges and edges[res].weight<=edge.weight):\n", + " edges[res] = edge\n", " # end for rule loop\n", " # end for right loop\n", " # end for left loop\n", " # end for part loop\n", - " return chart\n", - "\n", + " for cat in edges:\n", + " chart.insert(edges[cat], (edges[cat].triple[1], edges[cat].triple[2]))\n", + " return chart" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "metadata": {}, + "outputs": [], + "source": [ "def wpToTree(edge):\n", " if isinstance(edge,CCGLeafEdge):\n", " return Tree((edge.token(),\"Leaf\"),[Tree(edge.token(),[edge.leaf()])])\n", " else:\n", " return Tree(\n", " (chart.Token(None,edge.categ()),edge.triple[0].__str__()),\n", - " [wpToTree(t) for t in (edge.triple[1:])])\n", - "\n", + " [wpToTree(t) for t in (edge.triple[1:])])" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "metadata": {}, + "outputs": [], + "source": [ "def bestTree(tokens, lex, rules):\n", " # We build the weighgted parse tree using cky\n", " wChart = weightedParse(tokens, lex, rules)\n", " # We get the biggest edge\n", " e = list(wChart.select(start=0,end=len(tokens)))[0]\n", + " print(\"Edge count:\",len(list(wChart.select(start=0,end=len(tokens)))))\n", " # We get the tree that brought us to this edge\n", " t = wChart._trees(e, True, dict(), Tree)[0]\n", " # (wpToTree(e),e.weight)\n", @@ -146,7 +195,7 @@ }, { "cell_type": "code", - "execution_count": 4, + "execution_count": 17, "metadata": {}, "outputs": [], "source": [ @@ -154,7 +203,7 @@ "from nltk.sem.logic import Expression\n", "from nltk.ccg.api import PrimitiveCategory\n", "\n", - "def to_pseudo_entries(table, consider_semantics = False):\n", + "def to_pseudo_entries(table, consider_semantics = True):\n", " \"\"\"returns a list of lists in the format ['word', 'category', 'weight', None]\n", " if consider_semantics == false else ['word', 'category', weight, 'semantic']\n", " that is left to be converted into tokens by to_wlex_entries\"\"\"\n", @@ -182,7 +231,7 @@ " categ, _ = augParseCategory(entry[1], primitives, families, var)\n", " token = WeighedToken(token= entry[0],\n", " categ= categ,\n", - " semantics= Expression.fromstring(entry[-1]),\n", + " semantics= None if entry[-1] is None else Expression.fromstring(entry[-1]),\n", " weight= entry[2])\n", " entries[entry[0]].append(token)\n", " return entries\n", @@ -190,507 +239,20 @@ ] }, { - "cell_type": "code", - "execution_count": 9, + "cell_type": "markdown", "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "{}\n", - "\\n v.à(v,n)\n", - "\\n v.avec(v,n)\n", - "chat\n", - "\\n m.de(n,m)\n", - "dents\n", - "\\n.donne(n)\n", - "\\n m.donne(n,m)\n", - "\\n.mange(n)\n", - "\\n m.mange(n,m)\n", - "donner\n", - "\\n.donner(n)\n", - "\\n.dormir(n)\n", - "\\n.dormir(n)\n", - "elle\n", - "il\n", - "{}\n", - "{}\n", - "{}\n", - "\\n m.et(n,m)\n", - "\\x y.et(x,y)\n", - "\\v w n.et(v,w,n)\n", - "fromage\n", - "{}\n", - "{}\n", - "{}\n", - "\\P.exists x.P(x)\n", - "\\P.exists x.P(x)\n", - "\\P.exists x.P(x)\n", - "\\P.exists x.P(x)\n", - "\\P.exists x.P(x)\n", - "\\n.mangé(n)\n", - "\\n.mangé(n)\n", - "\\n.donné(n)\n", - "\\n.méchant(n)\n", - "\\n.méchant(n)\n", - "\\n.noir(n)\n", - "\\n.noir(n)\n", - "\\v n.paisiblement(v,n)\n", - "{}\n", - "{}\n", - "{}\n", - "{}\n", - "{}\n", - "{}\n", - "{}\n", - "{}\n", - "{}\n", - "{}\n", - "rat\n", - "soeur\n", - "\\n m.souhaite(m,n)\n", - "\\n m.pourchasse(m,n)\n", - "\\n m.attrappe(m,n)\n", - "souris\n", - "{}\n", - "voisin\n", - "1 le chat dort\n", - "Found derivation tree with weight 0.5599999999999999\n", - " le chat dort\n", - " (N/N) {\\P.exists x.P(x)} N {chat} (S\\N) {\\n.dormir(n)}\n", - "------------------------------------>\n", - " N {exists x.chat(x)}\n", - "----------------------------------------------------------<\n", - " S {dormir(exists x.chat(x))}\n", - "1 il dort\n", - "Found derivation tree with weight 0.7\n", - " il dort\n", - " N {il} (S\\N) {\\n.dormir(n)}\n", - "------------------------------<\n", - " S {dormir(il)}\n", - "1 le chat dort paisiblement\n", - "Found derivation tree with weight 0.39199999999999996\n", - " le chat dort paisiblement\n", - " (N/N) {\\P.exists x.P(x)} N {chat} (S\\N) {\\n.dormir(n)} ((S\\N)\\(S\\N)) {\\v n.paisiblement(v,n)}\n", - "------------------------------------>\n", - " N {exists x.chat(x)}\n", - " --------------------------------------------------------------<\n", - " (S\\N) {\\n.paisiblement(\\n.dormir(n),n)}\n", - "--------------------------------------------------------------------------------------------------<\n", - " S {paisiblement(\\n.dormir(n),exists x.chat(x))}\n", - "2 le chat noir dort\n", - "Found derivation tree with weight 0.39199999999999996\n", - " le chat noir dort\n", - " (N/N) {\\P.exists x.P(x)} N {chat} (N\\N) {\\n.noir(n)} (S\\N) {\\n.dormir(n)}\n", - " ------------------------------<\n", - " N {noir(chat)}\n", - "-------------------------------------------------------->\n", - " N {exists x.noir(chat,x)}\n", - "------------------------------------------------------------------------------<\n", - " S {dormir(exists x.noir(chat,x))}\n", - "1 le méchant chat dort\n", - "Found derivation tree with weight 0.44800000000000006\n", - " le méchant chat dort\n", - " (N/N) {\\P.exists x.P(x)} (N/N) {\\n.méchant(n)} N {chat} (S\\N) {\\n.dormir(n)}\n", - " --------------------------------->\n", - " N {méchant(chat)}\n", - "----------------------------------------------------------->\n", - " N {exists x.méchant(chat,x)}\n", - "---------------------------------------------------------------------------------<\n", - " S {dormir(exists x.méchant(chat,x))}\n", - "2 le très méchant chat dort\n", - "Found derivation tree with weight 0.35840000000000005\n", - " le très méchant chat dort\n", - " (N/N) {\\P.exists x.P(x)} ((N/N)/(N/N)) {{}} (N/N) {\\n.méchant(n)} N {chat} (S\\N) {\\n.dormir(n)}\n", - " ------------------------------------------->\n", - " (N/N) {{}(\\n.méchant(n))}\n", - " ----------------------------------------------------->\n", - " N {{}(\\n.méchant(n),chat)}\n", - "------------------------------------------------------------------------------->\n", - " N {exists x.{}(\\n.méchant(n),chat,x)}\n", - "-----------------------------------------------------------------------------------------------------<\n", - " S {dormir(exists x.{}(\\n.méchant(n),chat,x))}\n", - "7 le chat de la sœur de mon voisin dort\n", - "Found derivation tree with weight 0.11239423999999998\n", - " le chat de la sœur de mon voisin dort\n", - " (N/N) {\\P.exists x.P(x)} N {chat} ((N/N)\\N) {\\n m.de(n,m)} (N/N) {\\P.exists x.P(x)} N {soeur} ((N/N)\\N) {\\n m.de(n,m)} (N/N) {\\P.exists x.P(x)} N {voisin} (S\\N) {\\n.dormir(n)}\n", - " ------------------------------------<\n", - " (N/N) {\\m.de(chat,m)}\n", - " -------------------------------------<\n", - " (N/N) {\\m.de(soeur,m)}\n", - " -------------------------------------->\n", - " N {exists x.voisin(x)}\n", - " --------------------------------------------------------------------------->\n", - " N {de(soeur,exists x.voisin(x))}\n", - " ----------------------------------------------------------------------------------------------------->\n", - " N {exists x.de(soeur,exists x.voisin(x),x)}\n", - " ----------------------------------------------------------------------------------------------------------------------------------------->\n", - " N {de(chat,exists x.de(soeur,exists x.voisin(x),x))}\n", - "------------------------------------------------------------------------------------------------------------------------------------------------------------------->\n", - " N {exists x.de(chat,exists x.de(soeur,exists x.voisin(x),x),x)}\n", - "-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------<\n", - " S {dormir(exists x.de(chat,exists x.de(soeur,exists x.voisin(x),x),x))}\n", - "2 le chat que mon voisin lui donne mange\n", - "Found derivation tree with weight 0.14049279999999997\n", - " le chat que mon voisin lui donne mange\n", - " (N/N) {\\P.exists x.P(x)} N {chat} ((N\\N)/S) {{}} (N/N) {\\P.exists x.P(x)} N {voisin} ((S\\N)/(S\\N)) {{}} (S\\N) {\\n.donne(n)} (S\\N) {\\n.mange(n)}\n", - " -------------------------------------->\n", - " N {exists x.voisin(x)}\n", - " ----------------------------------------->\n", - " (S\\N) {{}(\\n.donne(n))}\n", - " -------------------------------------------------------------------------------<\n", - " S {{}(\\n.donne(n),exists x.voisin(x))}\n", - " ----------------------------------------------------------------------------------------------->\n", - " (N\\N) {{}({}(\\n.donne(n),exists x.voisin(x)))}\n", - " ---------------------------------------------------------------------------------------------------------<\n", - " N {{}({}(\\n.donne(n),exists x.voisin(x)),chat)}\n", - "----------------------------------------------------------------------------------------------------------------------------------->\n", - " N {exists x.{}({}(\\n.donne(n),exists x.voisin(x)),chat,x)}\n", - "--------------------------------------------------------------------------------------------------------------------------------------------------------<\n", - " S {mange(exists x.{}({}(\\n.donne(n),exists x.voisin(x)),chat,x))}\n", - "8 le chat qui dort est noir\n", - "Found derivation tree with weight 0.25087999999999994\n", - " le chat qui dort est noir\n", - " (N/N) {\\P.exists x.P(x)} N {chat} ((N\\N)/(S\\N)) {{}} (S\\N) {\\n.dormir(n)} ((S\\N)/(N/N)) {{}} (N\\N) {\\n.noir(n)}\n", - " ------------------------------------------>\n", - " (N\\N) {{}(\\n.dormir(n))}\n", - " ----------------------------------------------------<\n", - " N {{}(\\n.dormir(n),chat)}\n", - "------------------------------------------------------------------------------>\n", - " N {exists x.{}(\\n.dormir(n),chat,x)}\n", - " ---------------------------------------->\n", - " (S\\N) {{}(\\n.noir(n))}\n", - "----------------------------------------------------------------------------------------------------------------------<\n", - " S {{}(\\n.noir(n),exists x.{}(\\n.dormir(n),chat,x))}\n", - "1 le chat mange la souris\n", - "Found derivation tree with weight 0.35840000000000005\n", - " le chat mange la souris\n", - " (N/N) {\\P.exists x.P(x)} N {chat} ((S\\N)/N) {\\n m.mange(n,m)} (N/N) {\\P.exists x.P(x)} N {souris}\n", - "------------------------------------>\n", - " N {exists x.chat(x)}\n", - " -------------------------------------->\n", - " N {exists x.souris(x)}\n", - " ------------------------------------------------------------------->\n", - " (S\\N) {\\m.mange(exists x.souris(x),m)}\n", - "-------------------------------------------------------------------------------------------------------<\n", - " S {mange(exists x.souris(x),exists x.chat(x))}\n", - "1 le chat la mange\n", - "Found derivation tree with weight 0.44799999999999995\n", - " le chat la mange\n", - " (N/N) {\\P.exists x.P(x)} N {chat} ((S\\N)/((S\\N)/N)) {{}} ((S\\N)/N) {\\n m.mange(n,m)}\n", - "------------------------------------>\n", - " N {exists x.chat(x)}\n", - " ----------------------------------------------------->\n", - " (S\\N) {{}(\\n m.mange(n,m))}\n", - "-----------------------------------------------------------------------------------------<\n", - " S {{}(\\n m.mange(n,m),exists x.chat(x))}\n", - "1 il la mange\n", - "Found derivation tree with weight 0.5599999999999999\n", - " il la mange\n", - " N {il} ((S\\N)/((S\\N)/N)) {{}} ((S\\N)/N) {\\n m.mange(n,m)}\n", - " ----------------------------------------------------->\n", - " (S\\N) {{}(\\n m.mange(n,m))}\n", - "-------------------------------------------------------------<\n", - " S {{}(\\n m.mange(n,m),il)}\n", - "1 quel chat mange la souris ?\n", - "Found derivation tree with weight 0.2867200000000001\n", - " quel chat mange la souris ?\n", - " ((S/(S\\N))/N) {{}} N {chat} ((S\\N)/N) {\\n m.mange(n,m)} (N/N) {\\P.exists x.P(x)} N {souris} (S\\S) {{}}\n", - "------------------------------>\n", - " (S/(S\\N)) {{}(chat)}\n", - " -------------------------------------->\n", - " N {exists x.souris(x)}\n", - " ------------------------------------------------------------------->\n", - " (S\\N) {\\m.mange(exists x.souris(x),m)}\n", - "------------------------------------------------------------------------------------------------->\n", - " S {{}(chat,\\m.mange(exists x.souris(x),m))}\n", - "-------------------------------------------------------------------------------------------------------------<\n", - " S {{}({}(chat,\\m.mange(exists x.souris(x),m)))}\n", - "1 qui mange la souris ?\n", - "Found derivation tree with weight 0.35840000000000005\n", - " qui mange la souris ?\n", - " (S/(S\\N)) {{}} ((S\\N)/N) {\\n m.mange(n,m)} (N/N) {\\P.exists x.P(x)} N {souris} (S\\S) {{}}\n", - " -------------------------------------->\n", - " N {exists x.souris(x)}\n", - " ------------------------------------------------------------------->\n", - " (S\\N) {\\m.mange(exists x.souris(x),m)}\n", - "----------------------------------------------------------------------------------->\n", - " S {{}(\\m.mange(exists x.souris(x),m))}\n", - "-----------------------------------------------------------------------------------------------<\n", - " S {{}({}(\\m.mange(exists x.souris(x),m)))}\n", - "1 quelle souris mange le chat ?\n", - "Found derivation tree with weight 0.2867200000000001\n", - " quelle souris mange le chat ?\n", - " ((S/(S\\N))/N) {{}} N {souris} ((S\\N)/N) {\\n m.mange(n,m)} (N/N) {\\P.exists x.P(x)} N {chat} (S\\S) {{}}\n", - "-------------------------------->\n", - " (S/(S\\N)) {{}(souris)}\n", - " ------------------------------------>\n", - " N {exists x.chat(x)}\n", - " ----------------------------------------------------------------->\n", - " (S\\N) {\\m.mange(exists x.chat(x),m)}\n", - "------------------------------------------------------------------------------------------------->\n", - " S {{}(souris,\\m.mange(exists x.chat(x),m))}\n", - "-------------------------------------------------------------------------------------------------------------<\n", - " S {{}({}(souris,\\m.mange(exists x.chat(x),m)))}\n", - "1 la souris est mangée par le chat\n", - "Found derivation tree with weight 0.20070400000000002\n", - " la souris est mangée par le chat\n", - " (N/N) {\\P.exists x.P(x)} N {souris} ((S\\N)/Pp) {{}} Pp {\\n.mangé(n)} (((S\\N)\\(S\\N))/N) {{}} (N/N) {\\P.exists x.P(x)} N {chat}\n", - "-------------------------------------->\n", - " N {exists x.souris(x)}\n", - " ----------------------------------->\n", - " (S\\N) {{}(\\n.mangé(n))}\n", - " ------------------------------------>\n", - " N {exists x.chat(x)}\n", - " ------------------------------------------------------------>\n", - " ((S\\N)\\(S\\N)) {{}(exists x.chat(x))}\n", - " -----------------------------------------------------------------------------------------------<\n", - " (S\\N) {{}(exists x.chat(x),{}(\\n.mangé(n)))}\n", - "-------------------------------------------------------------------------------------------------------------------------------------<\n", - " S {{}(exists x.chat(x),{}(\\n.mangé(n)),exists x.souris(x))}\n", - "1 elle est mangée par le chat\n", - "Found derivation tree with weight 0.25088000000000005\n", - " elle est mangée par le chat\n", - " N {elle} ((S\\N)/Pp) {{}} Pp {\\n.mangé(n)} (((S\\N)\\(S\\N))/N) {{}} (N/N) {\\P.exists x.P(x)} N {chat}\n", - " ----------------------------------->\n", - " (S\\N) {{}(\\n.mangé(n))}\n", - " ------------------------------------>\n", - " N {exists x.chat(x)}\n", - " ------------------------------------------------------------>\n", - " ((S\\N)\\(S\\N)) {{}(exists x.chat(x))}\n", - " -----------------------------------------------------------------------------------------------<\n", - " (S\\N) {{}(exists x.chat(x),{}(\\n.mangé(n)))}\n", - "---------------------------------------------------------------------------------------------------------<\n", - " S {{}(exists x.chat(x),{}(\\n.mangé(n)),elle)}\n", - "1 quelle souris est mangée par le chat ?\n", - "Found derivation tree with weight 0.16056320000000004\n", - " quelle souris est mangée par le chat ?\n", - " ((S/(S\\N))/N) {{}} N {souris} ((S\\N)/Pp) {{}} Pp {\\n.mangé(n)} (((S\\N)\\(S\\N))/N) {{}} (N/N) {\\P.exists x.P(x)} N {chat} (S\\S) {{}}\n", - "-------------------------------->\n", - " (S/(S\\N)) {{}(souris)}\n", - " ----------------------------------->\n", - " (S\\N) {{}(\\n.mangé(n))}\n", - " ------------------------------------>\n", - " N {exists x.chat(x)}\n", - " ------------------------------------------------------------>\n", - " ((S\\N)\\(S\\N)) {{}(exists x.chat(x))}\n", - " -----------------------------------------------------------------------------------------------<\n", - " (S\\N) {{}(exists x.chat(x),{}(\\n.mangé(n)))}\n", - "------------------------------------------------------------------------------------------------------------------------------->\n", - " S {{}(souris,{}(exists x.chat(x),{}(\\n.mangé(n))))}\n", - "-------------------------------------------------------------------------------------------------------------------------------------------<\n", - " S {{}({}(souris,{}(exists x.chat(x),{}(\\n.mangé(n)))))}\n", - "1 le chat mange la souris avec ses dents\n", - "Found derivation tree with weight 0.16056320000000004\n", - " le chat mange la souris avec ses dents\n", - " (N/N) {\\P.exists x.P(x)} N {chat} ((S\\N)/N) {\\n m.mange(n,m)} (N/N) {\\P.exists x.P(x)} N {souris} (((S\\N)\\(S\\N))/N) {\\n v.avec(v,n)} (N/N) {\\P.exists x.P(x)} N {dents}\n", - "------------------------------------>\n", - " N {exists x.chat(x)}\n", - " -------------------------------------->\n", - " N {exists x.souris(x)}\n", - " ------------------------------------------------------------------->\n", - " (S\\N) {\\m.mange(exists x.souris(x),m)}\n", - " ------------------------------------->\n", - " N {exists x.dents(x)}\n", - " ------------------------------------------------------------------------->\n", - " ((S\\N)\\(S\\N)) {\\v.avec(v,exists x.dents(x))}\n", - " --------------------------------------------------------------------------------------------------------------------------------------------<\n", - " (S\\N) {avec(\\m.mange(exists x.souris(x),m),exists x.dents(x))}\n", - "--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------<\n", - " S {avec(\\m.mange(exists x.souris(x),m),exists x.dents(x),exists x.chat(x))}\n", - "1 le chat la mange avec ses dents\n", - "Found derivation tree with weight 0.20070400000000002\n", - " le chat la mange avec ses dents\n", - " (N/N) {\\P.exists x.P(x)} N {chat} ((S\\N)/((S\\N)/N)) {{}} ((S\\N)/N) {\\n m.mange(n,m)} (((S\\N)\\(S\\N))/N) {\\n v.avec(v,n)} (N/N) {\\P.exists x.P(x)} N {dents}\n", - "------------------------------------>\n", - " N {exists x.chat(x)}\n", - " ----------------------------------------------------->\n", - " (S\\N) {{}(\\n m.mange(n,m))}\n", - " ------------------------------------->\n", - " N {exists x.dents(x)}\n", - " ------------------------------------------------------------------------->\n", - " ((S\\N)\\(S\\N)) {\\v.avec(v,exists x.dents(x))}\n", - " ------------------------------------------------------------------------------------------------------------------------------<\n", - " (S\\N) {avec({}(\\n m.mange(n,m)),exists x.dents(x))}\n", - "------------------------------------------------------------------------------------------------------------------------------------------------------------------<\n", - " S {avec({}(\\n m.mange(n,m)),exists x.dents(x),exists x.chat(x))}\n", - "0 avec quoi le chat mange la souris ?\n", - "Pas de dérivation tout court :/\n", - "1 le rat donne un fromage à la souris\n", - "Found derivation tree with weight 0.16056320000000004\n", - " le rat donne un fromage à la souris\n", - " (N/N) {\\P.exists x.P(x)} N {rat} ((S\\N)/N) {\\n m.donne(n,m)} (N/N) {\\P.exists x.P(x)} N {fromage} (((S\\N)\\(S\\N))/N) {\\n v.à(v,n)} (N/N) {\\P.exists x.P(x)} N {souris}\n", - "----------------------------------->\n", - " N {exists x.rat(x)}\n", - " --------------------------------------->\n", - " N {exists x.fromage(x)}\n", - " -------------------------------------------------------------------->\n", - " (S\\N) {\\m.donne(exists x.fromage(x),m)}\n", - " -------------------------------------->\n", - " N {exists x.souris(x)}\n", - " ----------------------------------------------------------------------->\n", - " ((S\\N)\\(S\\N)) {\\v.à(v,exists x.souris(x))}\n", - " -------------------------------------------------------------------------------------------------------------------------------------------<\n", - " (S\\N) {à(\\m.donne(exists x.fromage(x),m),exists x.souris(x))}\n", - "------------------------------------------------------------------------------------------------------------------------------------------------------------------------------<\n", - " S {à(\\m.donne(exists x.fromage(x),m),exists x.souris(x),exists x.rat(x))}\n", - "1 un fromage est donné par le rat à la souris\n", - "Found derivation tree with weight 0.08991539200000002\n", - " un fromage est donné par le rat à la souris\n", - " (N/N) {\\P.exists x.P(x)} N {fromage} ((S\\N)/Pp) {{}} Pp {\\n.donné(n)} (((S\\N)\\(S\\N))/N) {{}} (N/N) {\\P.exists x.P(x)} N {rat} (((S\\N)\\(S\\N))/N) {\\n v.à(v,n)} (N/N) {\\P.exists x.P(x)} N {souris}\n", - "--------------------------------------->\n", - " N {exists x.fromage(x)}\n", - " ----------------------------------->\n", - " (S\\N) {{}(\\n.donné(n))}\n", - " ----------------------------------->\n", - " N {exists x.rat(x)}\n", - " ----------------------------------------------------------->\n", - " ((S\\N)\\(S\\N)) {{}(exists x.rat(x))}\n", - " ----------------------------------------------------------------------------------------------<\n", - " (S\\N) {{}(exists x.rat(x),{}(\\n.donné(n)))}\n", - " -------------------------------------->\n", - " N {exists x.souris(x)}\n", - " ----------------------------------------------------------------------->\n", - " ((S\\N)\\(S\\N)) {\\v.à(v,exists x.souris(x))}\n", - " ---------------------------------------------------------------------------------------------------------------------------------------------------------------------<\n", - " (S\\N) {à({}(exists x.rat(x),{}(\\n.donné(n))),exists x.souris(x))}\n", - "------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------<\n", - " S {à({}(exists x.rat(x),{}(\\n.donné(n))),exists x.souris(x),exists x.fromage(x))}\n", - "0 à quelle souris un fromage est donné par le rat ?\n", - "Pas de dérivation tout court :/\n", - "1 il le donne à la souris\n", - "Found derivation tree with weight 0.25088000000000005\n", - " il le donne à la souris\n", - " N {il} ((S\\N)/((S\\N)/N)) {{}} ((S\\N)/N) {\\n m.donne(n,m)} (((S\\N)\\(S\\N))/N) {\\n v.à(v,n)} (N/N) {\\P.exists x.P(x)} N {souris}\n", - " ----------------------------------------------------->\n", - " (S\\N) {{}(\\n m.donne(n,m))}\n", - " -------------------------------------->\n", - " N {exists x.souris(x)}\n", - " ----------------------------------------------------------------------->\n", - " ((S\\N)\\(S\\N)) {\\v.à(v,exists x.souris(x))}\n", - " ----------------------------------------------------------------------------------------------------------------------------<\n", - " (S\\N) {à({}(\\n m.donne(n,m)),exists x.souris(x))}\n", - "------------------------------------------------------------------------------------------------------------------------------------<\n", - " S {à({}(\\n m.donne(n,m)),exists x.souris(x),il)}\n", - "0 il le lui donne\n", - "Pas de dérivation tout court :/\n", - "1 il souhaite que mon voisin lui donne le chat\n", - "Found derivation tree with weight 0.12845056000000002\n", - " il souhaite que mon voisin lui donne le chat\n", - " N {il} ((S\\N)/N) {\\n m.souhaite(m,n)} (N/S) {{}} (N/N) {\\P.exists x.P(x)} N {voisin} ((S\\N)/(S\\N)) {{}} ((S\\N)/N) {\\n m.donne(n,m)} (N/N) {\\P.exists x.P(x)} N {chat}\n", - " -------------------------------------->\n", - " N {exists x.voisin(x)}\n", - " ------------------------------------>\n", - " N {exists x.chat(x)}\n", - " ----------------------------------------------------------------->\n", - " (S\\N) {\\m.donne(exists x.chat(x),m)}\n", - " ------------------------------------------------------------------------------------->\n", - " (S\\N) {{}(\\m.donne(exists x.chat(x),m))}\n", - " ---------------------------------------------------------------------------------------------------------------------------<\n", - " S {{}(\\m.donne(exists x.chat(x),m),exists x.voisin(x))}\n", - " --------------------------------------------------------------------------------------------------------------------------------------->\n", - " N {{}({}(\\m.donne(exists x.chat(x),m),exists x.voisin(x)))}\n", - " ----------------------------------------------------------------------------------------------------------------------------------------------------------------------->\n", - " (S\\N) {\\m.souhaite(m,{}({}(\\m.donne(exists x.chat(x),m),exists x.voisin(x))))}\n", - "-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------<\n", - " S {souhaite(il,{}({}(\\m.donne(exists x.chat(x),m),exists x.voisin(x))))}\n", - "1 il souhaite donner le chat à mon voisin\n", - "Found derivation tree with weight 0.16056320000000004\n", - " il souhaite donner le chat à mon voisin\n", - " N {il} ((S\\N)/N) {\\n m.souhaite(m,n)} (N/N) {\\n.donner(n)} (N/N) {\\P.exists x.P(x)} N {chat} (((S\\N)\\(S\\N))/N) {\\n v.à(v,n)} (N/N) {\\P.exists x.P(x)} N {voisin}\n", - " ------------------------------------>\n", - " N {exists x.chat(x)}\n", - " ---------------------------------------------------------->\n", - " N {donner(exists x.chat(x))}\n", - " ------------------------------------------------------------------------------------------>\n", - " (S\\N) {\\m.souhaite(m,donner(exists x.chat(x)))}\n", - " -------------------------------------->\n", - " N {exists x.voisin(x)}\n", - " ----------------------------------------------------------------------->\n", - " ((S\\N)\\(S\\N)) {\\v.à(v,exists x.voisin(x))}\n", - " -----------------------------------------------------------------------------------------------------------------------------------------------------------------<\n", - " (S\\N) {à(\\m.souhaite(m,donner(exists x.chat(x))),exists x.voisin(x))}\n", - "-------------------------------------------------------------------------------------------------------------------------------------------------------------------------<\n", - " S {à(\\m.souhaite(m,donner(exists x.chat(x))),exists x.voisin(x),il)}\n", - "0 le chat de mon voisin pourchasse et attrape la souris\n", - "Pas de dérivation tout court :/\n", - "2 la souris dort et le chat de mon voisin attrape la souris\n", - "Found derivation tree with weight 0.05035261952\n", - " la souris dort et le chat de mon voisin attrape la souris\n", - " (N/N) {\\P.exists x.P(x)} N {souris} (S\\N) {\\n.dormir(n)} ((S/S)\\S) {\\x y.et(x,y)} (N/N) {\\P.exists x.P(x)} N {chat} ((N/N)\\N) {\\n m.de(n,m)} (N/N) {\\P.exists x.P(x)} N {voisin} ((S\\N)/N) {\\n m.attrappe(m,n)} (N/N) {\\P.exists x.P(x)} N {souris}\n", - "-------------------------------------->\n", - " N {exists x.souris(x)}\n", - "------------------------------------------------------------<\n", - " S {dormir(exists x.souris(x))}\n", - "--------------------------------------------------------------------------------------<\n", - " (S/S) {\\y.et(dormir(exists x.souris(x)),y)}\n", - " ------------------------------------<\n", - " (N/N) {\\m.de(chat,m)}\n", - " -------------------------------------->\n", - " N {exists x.voisin(x)}\n", - " -------------------------------------------------------------------------->\n", - " N {de(chat,exists x.voisin(x))}\n", - " ---------------------------------------------------------------------------------------------------->\n", - " N {exists x.de(chat,exists x.voisin(x),x)}\n", - " -------------------------------------->\n", - " N {exists x.souris(x)}\n", - " ---------------------------------------------------------------------->\n", - " (S\\N) {\\m.attrappe(m,exists x.souris(x))}\n", - " --------------------------------------------------------------------------------------------------------------------------------------------------------------------------<\n", - " S {attrappe(exists x.de(chat,exists x.voisin(x),x),exists x.souris(x))}\n", - "---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------->\n", - " S {et(dormir(exists x.souris(x)),attrappe(exists x.de(chat,exists x.voisin(x),x),exists x.souris(x)))}\n", - "1 le chat dort et la souris dort\n", - "Found derivation tree with weight 0.17561599999999997\n", - " le chat dort et la souris dort\n", - " (N/N) {\\P.exists x.P(x)} N {chat} (S\\N) {\\n.dormir(n)} ((S/S)\\S) {\\x y.et(x,y)} (N/N) {\\P.exists x.P(x)} N {souris} (S\\N) {\\n.dormir(n)}\n", - "------------------------------------>\n", - " N {exists x.chat(x)}\n", - "----------------------------------------------------------<\n", - " S {dormir(exists x.chat(x))}\n", - "------------------------------------------------------------------------------------<\n", - " (S/S) {\\y.et(dormir(exists x.chat(x)),y)}\n", - " -------------------------------------->\n", - " N {exists x.souris(x)}\n", - " ------------------------------------------------------------<\n", - " S {dormir(exists x.souris(x))}\n", - "------------------------------------------------------------------------------------------------------------------------------------------------>\n", - " S {et(dormir(exists x.chat(x)),dormir(exists x.souris(x)))}\n", - "2 le chat et la souris dorment\n", - "Found derivation tree with weight 0.25088\n", - " le chat et la souris dorment\n", - " (N/N) {\\P.exists x.P(x)} N {chat} ((N/N)\\N) {\\n m.et(n,m)} (N/N) {\\P.exists x.P(x)} N {souris} (S\\N) {\\n.dormir(n)}\n", - " ------------------------------------<\n", - " (N/N) {\\m.et(chat,m)}\n", - " -------------------------------------->\n", - " N {exists x.souris(x)}\n", - " -------------------------------------------------------------------------->\n", - " N {et(chat,exists x.souris(x))}\n", - "---------------------------------------------------------------------------------------------------->\n", - " N {exists x.et(chat,exists x.souris(x),x)}\n", - "--------------------------------------------------------------------------------------------------------------------------<\n", - " S {dormir(exists x.et(chat,exists x.souris(x),x))}\n", - "2 le chat et la souris dorment\n", - "Found derivation tree with weight 0.25088\n", - " le chat et la souris dorment\n", - " (N/N) {\\P.exists x.P(x)} N {chat} ((N/N)\\N) {\\n m.et(n,m)} (N/N) {\\P.exists x.P(x)} N {souris} (S\\N) {\\n.dormir(n)}\n", - " ------------------------------------<\n", - " (N/N) {\\m.et(chat,m)}\n", - " -------------------------------------->\n", - " N {exists x.souris(x)}\n", - " -------------------------------------------------------------------------->\n", - " N {et(chat,exists x.souris(x))}\n", - "---------------------------------------------------------------------------------------------------->\n", - " N {exists x.et(chat,exists x.souris(x),x)}\n", - "--------------------------------------------------------------------------------------------------------------------------<\n", - " S {dormir(exists x.et(chat,exists x.souris(x),x))}\n" - ] - } - ], + "source": [ + "We create our lexicon using the data from the server" + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "metadata": {}, + "outputs": [], "source": [ "# Catégories primitives et familles\n", - "primitives = ['S', 'N', 'Pp']\n", + "primitives = ['S', 'N', 'Pp', 'pN']\n", "V = augParseCategory(\"S\\\\N\", primitives = primitives, families={})\n", "families = {'V': V}\n", "\n", @@ -699,131 +261,1207 @@ "#print(table.keys())\n", "\n", "# On le convertit en Lexique pondéré\n", - "pe = to_pseudo_entries(table, consider_semantics = True)\n", + "pe = to_pseudo_entries(table, consider_semantics = False)\n", "#print(pe)\n", "wEntries = to_wlex_entries(pseudo_entries= pe, primitives= primitives, families= families)\n", "#print([list(map(lambda x: f\"{k} : \"+ str(x) + str(x._semantics), L)) for k, L in wEntries.items()])\n", "lex = WeighedLexicon(start= 'S', primitives= primitives, families= families, entries= wEntries)\n", "\n", "\n", - "# On récupère le nombre de mots qui ont été définis\n", - "# n = len(table['MOT'])\n", - "\n", - "# On donne la liste des catégories primitives\n", - "# lexstring = ':- S,N,Pp\\n'\n", - "# On ajoute la notation V pour N\\S\n", - "# lexstring += 'V :: S\\\\N\\n'\n", - "\n", - "# On lis les données depuis le tableur en une chaine de caractère parsable\n", - "#for i in range(n):\n", - "# for j in range(3):\n", - "# if isinstance(table['Cat'+str(j)][i],str):\n", - "# for mot in table['MOT'][i].split('/'):\n", - "# lexstring+=mot+' => ' + table['Cat'+str(j)][i] + '\\n'\n", - "\n", - "# Pour inverser les slash dans le lexicon\n", - "#lexstring = lexstring.replace('\\\\','#').replace('/','\\\\').replace('#','/')\n", - "\n", - "# On crée notre lexique\n", - "# lex = lexicon.fromstring(lexstring)\n", - "\n", "# On crée le parser, on donne l'ensemble des règles qu'il est cencé connaître\n", - "parser = chart.CCGChartParser(lex, chart.DefaultRuleSet)\n", - "#parser = chart.CCGChartParser(lex, chart.ApplicationRuleSet)\n", + "from nltk.ccg.combinator import (\n", + " BackwardApplication,\n", + " BackwardBx,\n", + " BackwardComposition,\n", + " BackwardSx,\n", + " ForwardApplication,\n", + " ForwardComposition,\n", + " ForwardSubstitution\n", + ")\n", + "rulesC = [ForwardApplication,BackwardApplication] \n", + "rulesC += [ForwardComposition,BackwardComposition,BackwardBx]\n", + "rulesC += [ForwardSubstitution,BackwardSx]\n", + "rulesR = [BinaryCombinatorRule(c) for c in rulesC]\n", + "# chart.ApplicationRuleSet for only < and >\n", "\n", - "printTotal=True\n", - "printDerivations=not printTotal\n", - "\n", - "# On lit les phrases dans le fichier\n", - "with open('phrases.txt') as f:\n", - " lines = f.readlines()\n", - "\n", - " lines.append(\"le chat et la souris dorment\")\n", - " \n", - " for phrase in lines:\n", - " # On met tout en minuscule\n", - " phrase = phrase.lower().strip()\n", - " if printDerivations:\n", - " print(\"=\"*77)\n", - " print('#',phrase)\n", - " # lex = lexicon.fromstring(lexstring)\n", - " parser = chart.CCGChartParser(lex, chart.ApplicationRuleSet)\n", - "\n", - " # Et on affiche tous les arbres de dérivation trouvés\n", - " i=0\n", - " for parse in parser.parse(phrase.split()):\n", - " i+=1\n", - " if printDerivations:\n", - " chart.printCCGDerivation(parse)\n", - " \n", - " if printTotal:\n", - " print(i,phrase)\n", - " \n", - " \n", - " # On affiche la dérivation la meilleure pour l'arbre\n", - " if (i==0):\n", - " print(\"Pas de dérivation tout court :/\")\n", - " else:\n", - "\n", - " t,d = bestTree(phrase.split(), lex, chart.ApplicationRuleSet)\n", - " print(\"Found derivation tree with weight\",d)\n", - " chart.printCCGDerivation(t)" + "parser = chart.CCGChartParser(lex, rulesR)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "On lit les phrases depuis le fichier `phrases.txt`, et pour chacune, on imprime le nombre de dérivations trouvées, ainsi que le meilleur arbre de dérivation (i.e. de meilleur poids)" ] }, { "cell_type": "code", - "execution_count": 10, + "execution_count": 19, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "? => (S\\S) {{}}\n", - "attrape => ((S\\N)/N) {\\n m.attrappe(m,n)}\n", - "avec => (((S\\N)\\(S\\N))/N) {\\n v.avec(v,n)}\n", - "chat => N {chat}\n", - "de => ((N/N)\\N) {\\n m.de(n,m)}\n", - "dents => N {dents}\n", - "donne => (S\\N) {\\n.donne(n)} | ((S\\N)/N) {\\n m.donne(n,m)}\n", - "donner => N {donner} | (N/N) {\\n.donner(n)}\n", - "donné => Pp {\\n.donné(n)}\n", - "dorment => (S\\N) {\\n.dormir(n)}\n", - "dort => (S\\N) {\\n.dormir(n)}\n", - "elle => N {elle}\n", - "est => ((S\\N)/Pp) {{}} | ((S\\N)/(N/N)) {{}} | ((S\\N)/(N\\N)) {{}}\n", - "et => ((N/N)\\N) {\\n m.et(n,m)} | ((S/S)\\S) {\\x y.et(x,y)} | (((S\\N)/(S\\N))\\(S\\N)) {\\v w n.et(v,w,n)}\n", - "fromage => N {fromage}\n", - "il => N {il}\n", - "la => ((S\\N)/((S\\N)/N)) {{}} | (N/N) {\\P.exists x.P(x)}\n", - "le => ((S\\N)/((S\\N)/N)) {{}} | (N/N) {\\P.exists x.P(x)}\n", - "lui => ((S\\N)/(S\\N)) {{}}\n", - "mange => (S\\N) {\\n.mange(n)} | ((S\\N)/N) {\\n m.mange(n,m)}\n", - "mangé => Pp {\\n.mangé(n)}\n", - "mangée => Pp {\\n.mangé(n)}\n", - "mon => (N/N) {\\P.exists x.P(x)}\n", - "méchant => (N/N) {\\n.méchant(n)} | (N\\N) {\\n.méchant(n)}\n", - "noir => (N\\N) {\\n.noir(n)} | (N/N) {\\n.noir(n)}\n", - "paisiblement => ((S\\N)\\(S\\N)) {\\v n.paisiblement(v,n)}\n", - "par => (((S\\N)\\(S\\N))/N) {{}}\n", - "pourchasse => ((S\\N)/N) {\\n m.pourchasse(m,n)}\n", - "que => ((N\\N)/S) {{}} | (N/S) {{}}\n", - "quel => (((((S\\N)\\(S\\N))/N)\\(S/S))/N) {{}} | ((S/(S\\N))/N) {{}}\n", - "quelle => (((((S\\N)\\(S\\N))/N)\\(S/S))/N) {{}} | ((S/(S\\N))/N) {{}}\n", - "qui => ((N\\N)/(S\\N)) {{}} | (S/(S\\N)) {{}}\n", - "quoi => (((S/S)\\(((S\\N)\\(S\\N))/N))/N) {{}}\n", - "rat => N {rat}\n", - "ses => (N/N) {\\P.exists x.P(x)}\n", - "souhaite => ((S\\N)/N) {\\n m.souhaite(m,n)}\n", - "souris => N {souris}\n", - "sœur => N {soeur}\n", - "très => ((N/N)/(N/N)) {{}}\n", - "un => (N/N) {\\P.exists x.P(x)}\n", - "voisin => N {voisin}\n", - "à => (((S\\N)\\(S\\N))/N) {\\n v.à(v,n)}\n" + "2 found derivation for sentence: le méchant chat dort\n", + " le méchant chat dort\n", + " (N/pN) (pN/pN) pN (S\\N)\n", + " --------------->\n", + " pN\n", + "----------------------->\n", + " N\n", + "------------------------------<\n", + " S\n", + " le méchant chat dort\n", + " (N/pN) (pN/pN) pN (S\\N)\n", + "----------------->B\n", + " (N/pN)\n", + "----------------------->\n", + " N\n", + "------------------------------<\n", + " S\n", + "==> 2 0\n", + "==> 2 1\n", + "==> 2 2\n", + "==> 3 0\n", + "==> 3 1\n", + "==> 4 0\n", + "Edge count: 1\n", + "Best derivation tree has weight 0.24957917865181148\n", + " le méchant chat dort\n", + " (N/pN) (pN/pN) pN (S\\N)\n", + " --------------->\n", + " pN\n", + "----------------------->\n", + " N\n", + "------------------------------<\n", + " S\n", + "##########################################\n", + "2 found derivation for sentence: le méchant chat dort\n", + " le méchant chat dort\n", + " (N/pN) (pN/pN) pN (S\\N)\n", + " --------------->\n", + " pN\n", + "----------------------->\n", + " N\n", + "------------------------------<\n", + " S\n", + " le méchant chat dort\n", + " (N/pN) (pN/pN) pN (S\\N)\n", + "----------------->B\n", + " (N/pN)\n", + "----------------------->\n", + " N\n", + "------------------------------<\n", + " S\n", + "==> 2 0\n", + "==> 2 1\n", + "==> 2 2\n", + "==> 3 0\n", + "==> 3 1\n", + "==> 4 0\n", + "Edge count: 1\n", + "Best derivation tree has weight 0.24957917865181148\n", + " le méchant chat dort\n", + " (N/pN) (pN/pN) pN (S\\N)\n", + " --------------->\n", + " pN\n", + "----------------------->\n", + " N\n", + "------------------------------<\n", + " S\n", + "##########################################\n", + "2 found derivation for sentence: le méchant chat dort\n", + " le méchant chat dort\n", + " (N/pN) (pN/pN) pN (S\\N)\n", + " --------------->\n", + " pN\n", + "----------------------->\n", + " N\n", + "------------------------------<\n", + " S\n", + " le méchant chat dort\n", + " (N/pN) (pN/pN) pN (S\\N)\n", + "----------------->B\n", + " (N/pN)\n", + "----------------------->\n", + " N\n", + "------------------------------<\n", + " S\n", + "==> 2 0\n", + "==> 2 1\n", + "==> 2 2\n", + "==> 3 0\n", + "==> 3 1\n", + "==> 4 0\n", + "Edge count: 1\n", + "Best derivation tree has weight 0.24957917865181148\n", + " le méchant chat dort\n", + " (N/pN) (pN/pN) pN (S\\N)\n", + " --------------->\n", + " pN\n", + "----------------------->\n", + " N\n", + "------------------------------<\n", + " S\n", + "##########################################\n", + "2 found derivation for sentence: le méchant chat dort\n", + " le méchant chat dort\n", + " (N/pN) (pN/pN) pN (S\\N)\n", + " --------------->\n", + " pN\n", + "----------------------->\n", + " N\n", + "------------------------------<\n", + " S\n", + " le méchant chat dort\n", + " (N/pN) (pN/pN) pN (S\\N)\n", + "----------------->B\n", + " (N/pN)\n", + "----------------------->\n", + " N\n", + "------------------------------<\n", + " S\n", + "==> 2 0\n", + "==> 2 1\n", + "==> 2 2\n", + "==> 3 0\n", + "==> 3 1\n", + "==> 4 0\n", + "Edge count: 1\n", + "Best derivation tree has weight 0.24957917865181148\n", + " le méchant chat dort\n", + " (N/pN) (pN/pN) pN (S\\N)\n", + " --------------->\n", + " pN\n", + "----------------------->\n", + " N\n", + "------------------------------<\n", + " S\n", + "##########################################\n", + "2 found derivation for sentence: le méchant chat dort\n", + " le méchant chat dort\n", + " (N/pN) (pN/pN) pN (S\\N)\n", + " --------------->\n", + " pN\n", + "----------------------->\n", + " N\n", + "------------------------------<\n", + " S\n", + " le méchant chat dort\n", + " (N/pN) (pN/pN) pN (S\\N)\n", + "----------------->B\n", + " (N/pN)\n", + "----------------------->\n", + " N\n", + "------------------------------<\n", + " S\n", + "==> 2 0\n", + "==> 2 1\n", + "==> 2 2\n", + "==> 3 0\n", + "==> 3 1\n", + "==> 4 0\n", + "Edge count: 1\n", + "Best derivation tree has weight 0.24957917865181148\n", + " le méchant chat dort\n", + " (N/pN) (pN/pN) pN (S\\N)\n", + " --------------->\n", + " pN\n", + "----------------------->\n", + " N\n", + "------------------------------<\n", + " S\n", + "##########################################\n", + "2 found derivation for sentence: le méchant chat dort\n", + " le méchant chat dort\n", + " (N/pN) (pN/pN) pN (S\\N)\n", + " --------------->\n", + " pN\n", + "----------------------->\n", + " N\n", + "------------------------------<\n", + " S\n", + " le méchant chat dort\n", + " (N/pN) (pN/pN) pN (S\\N)\n", + "----------------->B\n", + " (N/pN)\n", + "----------------------->\n", + " N\n", + "------------------------------<\n", + " S\n", + "==> 2 0\n", + "==> 2 1\n", + "==> 2 2\n", + "==> 3 0\n", + "==> 3 1\n", + "==> 4 0\n", + "Edge count: 1\n", + "Best derivation tree has weight 0.24957917865181148\n", + " le méchant chat dort\n", + " (N/pN) (pN/pN) pN (S\\N)\n", + " --------------->\n", + " pN\n", + "----------------------->\n", + " N\n", + "------------------------------<\n", + " S\n", + "##########################################\n", + "2 found derivation for sentence: le méchant chat dort\n", + " le méchant chat dort\n", + " (N/pN) (pN/pN) pN (S\\N)\n", + " --------------->\n", + " pN\n", + "----------------------->\n", + " N\n", + "------------------------------<\n", + " S\n", + " le méchant chat dort\n", + " (N/pN) (pN/pN) pN (S\\N)\n", + "----------------->B\n", + " (N/pN)\n", + "----------------------->\n", + " N\n", + "------------------------------<\n", + " S\n", + "==> 2 0\n", + "==> 2 1\n", + "==> 2 2\n", + "==> 3 0\n", + "==> 3 1\n", + "==> 4 0\n", + "Edge count: 1\n", + "Best derivation tree has weight 0.24957917865181148\n", + " le méchant chat dort\n", + " (N/pN) (pN/pN) pN (S\\N)\n", + " --------------->\n", + " pN\n", + "----------------------->\n", + " N\n", + "------------------------------<\n", + " S\n", + "##########################################\n", + "2 found derivation for sentence: le méchant chat dort\n", + " le méchant chat dort\n", + " (N/pN) (pN/pN) pN (S\\N)\n", + " --------------->\n", + " pN\n", + "----------------------->\n", + " N\n", + "------------------------------<\n", + " S\n", + " le méchant chat dort\n", + " (N/pN) (pN/pN) pN (S\\N)\n", + "----------------->B\n", + " (N/pN)\n", + "----------------------->\n", + " N\n", + "------------------------------<\n", + " S\n", + "==> 2 0\n", + "==> 2 1\n", + "==> 2 2\n", + "==> 3 0\n", + "==> 3 1\n", + "==> 4 0\n", + "Edge count: 1\n", + "Best derivation tree has weight 0.24957917865181148\n", + " le méchant chat dort\n", + " (N/pN) (pN/pN) pN (S\\N)\n", + " --------------->\n", + " pN\n", + "----------------------->\n", + " N\n", + "------------------------------<\n", + " S\n", + "##########################################\n", + "2 found derivation for sentence: le méchant chat dort\n", + " le méchant chat dort\n", + " (N/pN) (pN/pN) pN (S\\N)\n", + " --------------->\n", + " pN\n", + "----------------------->\n", + " N\n", + "------------------------------<\n", + " S\n", + " le méchant chat dort\n", + " (N/pN) (pN/pN) pN (S\\N)\n", + "----------------->B\n", + " (N/pN)\n", + "----------------------->\n", + " N\n", + "------------------------------<\n", + " S\n", + "==> 2 0\n", + "==> 2 1\n", + "==> 2 2\n", + "==> 3 0\n", + "==> 3 1\n", + "==> 4 0\n", + "Edge count: 1\n", + "Best derivation tree has weight 0.24957917865181148\n", + " le méchant chat dort\n", + " (N/pN) (pN/pN) pN (S\\N)\n", + " --------------->\n", + " pN\n", + "----------------------->\n", + " N\n", + "------------------------------<\n", + " S\n", + "##########################################\n", + "2 found derivation for sentence: le méchant chat dort\n", + " le méchant chat dort\n", + " (N/pN) (pN/pN) pN (S\\N)\n", + " --------------->\n", + " pN\n", + "----------------------->\n", + " N\n", + "------------------------------<\n", + " S\n", + " le méchant chat dort\n", + " (N/pN) (pN/pN) pN (S\\N)\n", + "----------------->B\n", + " (N/pN)\n", + "----------------------->\n", + " N\n", + "------------------------------<\n", + " S\n", + "==> 2 0\n", + "==> 2 1\n", + "==> 2 2\n", + "==> 3 0\n", + "==> 3 1\n", + "==> 4 0\n", + "Edge count: 1\n", + "Best derivation tree has weight 0.24957917865181148\n", + " le méchant chat dort\n", + " (N/pN) (pN/pN) pN (S\\N)\n", + " --------------->\n", + " pN\n", + "----------------------->\n", + " N\n", + "------------------------------<\n", + " S\n", + "##########################################\n", + "2 found derivation for sentence: le méchant chat dort\n", + " le méchant chat dort\n", + " (N/pN) (pN/pN) pN (S\\N)\n", + " --------------->\n", + " pN\n", + "----------------------->\n", + " N\n", + "------------------------------<\n", + " S\n", + " le méchant chat dort\n", + " (N/pN) (pN/pN) pN (S\\N)\n", + "----------------->B\n", + " (N/pN)\n", + "----------------------->\n", + " N\n", + "------------------------------<\n", + " S\n", + "==> 2 0\n", + "==> 2 1\n", + "==> 2 2\n", + "==> 3 0\n", + "==> 3 1\n", + "==> 4 0\n", + "Edge count: 1\n", + "Best derivation tree has weight 0.24957917865181148\n", + " le méchant chat dort\n", + " (N/pN) (pN/pN) pN (S\\N)\n", + " --------------->\n", + " pN\n", + "----------------------->\n", + " N\n", + "------------------------------<\n", + " S\n", + "##########################################\n", + "2 found derivation for sentence: le méchant chat dort\n", + " le méchant chat dort\n", + " (N/pN) (pN/pN) pN (S\\N)\n", + " --------------->\n", + " pN\n", + "----------------------->\n", + " N\n", + "------------------------------<\n", + " S\n", + " le méchant chat dort\n", + " (N/pN) (pN/pN) pN (S\\N)\n", + "----------------->B\n", + " (N/pN)\n", + "----------------------->\n", + " N\n", + "------------------------------<\n", + " S\n", + "==> 2 0\n", + "==> 2 1\n", + "==> 2 2\n", + "==> 3 0\n", + "==> 3 1\n", + "==> 4 0\n", + "Edge count: 1\n", + "Best derivation tree has weight 0.24957917865181148\n", + " le méchant chat dort\n", + " (N/pN) (pN/pN) pN (S\\N)\n", + " --------------->\n", + " pN\n", + "----------------------->\n", + " N\n", + "------------------------------<\n", + " S\n", + "##########################################\n", + "2 found derivation for sentence: le méchant chat dort\n", + " le méchant chat dort\n", + " (N/pN) (pN/pN) pN (S\\N)\n", + " --------------->\n", + " pN\n", + "----------------------->\n", + " N\n", + "------------------------------<\n", + " S\n", + " le méchant chat dort\n", + " (N/pN) (pN/pN) pN (S\\N)\n", + "----------------->B\n", + " (N/pN)\n", + "----------------------->\n", + " N\n", + "------------------------------<\n", + " S\n", + "==> 2 0\n", + "==> 2 1\n", + "==> 2 2\n", + "==> 3 0\n", + "==> 3 1\n", + "==> 4 0\n", + "Edge count: 1\n", + "Best derivation tree has weight 0.24957917865181148\n", + " le méchant chat dort\n", + " (N/pN) (pN/pN) pN (S\\N)\n", + " --------------->\n", + " pN\n", + "----------------------->\n", + " N\n", + "------------------------------<\n", + " S\n", + "##########################################\n", + "2 found derivation for sentence: le méchant chat dort\n", + " le méchant chat dort\n", + " (N/pN) (pN/pN) pN (S\\N)\n", + " --------------->\n", + " pN\n", + "----------------------->\n", + " N\n", + "------------------------------<\n", + " S\n", + " le méchant chat dort\n", + " (N/pN) (pN/pN) pN (S\\N)\n", + "----------------->B\n", + " (N/pN)\n", + "----------------------->\n", + " N\n", + "------------------------------<\n", + " S\n", + "==> 2 0\n", + "==> 2 1\n", + "==> 2 2\n", + "==> 3 0\n", + "==> 3 1\n", + "==> 4 0\n", + "Edge count: 1\n", + "Best derivation tree has weight 0.24957917865181148\n", + " le méchant chat dort\n", + " (N/pN) (pN/pN) pN (S\\N)\n", + " --------------->\n", + " pN\n", + "----------------------->\n", + " N\n", + "------------------------------<\n", + " S\n", + "##########################################\n", + "2 found derivation for sentence: le méchant chat dort\n", + " le méchant chat dort\n", + " (N/pN) (pN/pN) pN (S\\N)\n", + " --------------->\n", + " pN\n", + "----------------------->\n", + " N\n", + "------------------------------<\n", + " S\n", + " le méchant chat dort\n", + " (N/pN) (pN/pN) pN (S\\N)\n", + "----------------->B\n", + " (N/pN)\n", + "----------------------->\n", + " N\n", + "------------------------------<\n", + " S\n", + "==> 2 0\n", + "==> 2 1\n", + "==> 2 2\n", + "==> 3 0\n", + "==> 3 1\n", + "==> 4 0\n", + "Edge count: 1\n", + "Best derivation tree has weight 0.24957917865181148\n", + " le méchant chat dort\n", + " (N/pN) (pN/pN) pN (S\\N)\n", + " --------------->\n", + " pN\n", + "----------------------->\n", + " N\n", + "------------------------------<\n", + " S\n", + "##########################################\n", + "2 found derivation for sentence: le méchant chat dort\n", + " le méchant chat dort\n", + " (N/pN) (pN/pN) pN (S\\N)\n", + " --------------->\n", + " pN\n", + "----------------------->\n", + " N\n", + "------------------------------<\n", + " S\n", + " le méchant chat dort\n", + " (N/pN) (pN/pN) pN (S\\N)\n", + "----------------->B\n", + " (N/pN)\n", + "----------------------->\n", + " N\n", + "------------------------------<\n", + " S\n", + "==> 2 0\n", + "==> 2 1\n", + "==> 2 2\n", + "==> 3 0\n", + "==> 3 1\n", + "==> 4 0\n", + "Edge count: 1\n", + "Best derivation tree has weight 0.24957917865181148\n", + " le méchant chat dort\n", + " (N/pN) (pN/pN) pN (S\\N)\n", + " --------------->\n", + " pN\n", + "----------------------->\n", + " N\n", + "------------------------------<\n", + " S\n", + "##########################################\n", + "2 found derivation for sentence: le méchant chat dort\n", + " le méchant chat dort\n", + " (N/pN) (pN/pN) pN (S\\N)\n", + " --------------->\n", + " pN\n", + "----------------------->\n", + " N\n", + "------------------------------<\n", + " S\n", + " le méchant chat dort\n", + " (N/pN) (pN/pN) pN (S\\N)\n", + "----------------->B\n", + " (N/pN)\n", + "----------------------->\n", + " N\n", + "------------------------------<\n", + " S\n", + "==> 2 0\n", + "==> 2 1\n", + "==> 2 2\n", + "==> 3 0\n", + "==> 3 1\n", + "==> 4 0\n", + "Edge count: 1\n", + "Best derivation tree has weight 0.24957917865181148\n", + " le méchant chat dort\n", + " (N/pN) (pN/pN) pN (S\\N)\n", + " --------------->\n", + " pN\n", + "----------------------->\n", + " N\n", + "------------------------------<\n", + " S\n", + "##########################################\n", + "2 found derivation for sentence: le méchant chat dort\n", + " le méchant chat dort\n", + " (N/pN) (pN/pN) pN (S\\N)\n", + " --------------->\n", + " pN\n", + "----------------------->\n", + " N\n", + "------------------------------<\n", + " S\n", + " le méchant chat dort\n", + " (N/pN) (pN/pN) pN (S\\N)\n", + "----------------->B\n", + " (N/pN)\n", + "----------------------->\n", + " N\n", + "------------------------------<\n", + " S\n", + "==> 2 0\n", + "==> 2 1\n", + "==> 2 2\n", + "==> 3 0\n", + "==> 3 1\n", + "==> 4 0\n", + "Edge count: 1\n", + "Best derivation tree has weight 0.24957917865181148\n", + " le méchant chat dort\n", + " (N/pN) (pN/pN) pN (S\\N)\n", + " --------------->\n", + " pN\n", + "----------------------->\n", + " N\n", + "------------------------------<\n", + " S\n", + "##########################################\n", + "2 found derivation for sentence: le méchant chat dort\n", + " le méchant chat dort\n", + " (N/pN) (pN/pN) pN (S\\N)\n", + " --------------->\n", + " pN\n", + "----------------------->\n", + " N\n", + "------------------------------<\n", + " S\n", + " le méchant chat dort\n", + " (N/pN) (pN/pN) pN (S\\N)\n", + "----------------->B\n", + " (N/pN)\n", + "----------------------->\n", + " N\n", + "------------------------------<\n", + " S\n", + "==> 2 0\n", + "==> 2 1\n", + "==> 2 2\n", + "==> 3 0\n", + "==> 3 1\n", + "==> 4 0\n", + "Edge count: 1\n", + "Best derivation tree has weight 0.24957917865181148\n", + " le méchant chat dort\n", + " (N/pN) (pN/pN) pN (S\\N)\n", + " --------------->\n", + " pN\n", + "----------------------->\n", + " N\n", + "------------------------------<\n", + " S\n", + "##########################################\n", + "2 found derivation for sentence: le méchant chat dort\n", + " le méchant chat dort\n", + " (N/pN) (pN/pN) pN (S\\N)\n", + " --------------->\n", + " pN\n", + "----------------------->\n", + " N\n", + "------------------------------<\n", + " S\n", + " le méchant chat dort\n", + " (N/pN) (pN/pN) pN (S\\N)\n", + "----------------->B\n", + " (N/pN)\n", + "----------------------->\n", + " N\n", + "------------------------------<\n", + " S\n", + "==> 2 0\n", + "==> 2 1\n", + "==> 2 2\n", + "==> 3 0\n", + "==> 3 1\n", + "==> 4 0\n", + "Edge count: 1\n", + "Best derivation tree has weight 0.24957917865181148\n", + " le méchant chat dort\n", + " (N/pN) (pN/pN) pN (S\\N)\n", + " --------------->\n", + " pN\n", + "----------------------->\n", + " N\n", + "------------------------------<\n", + " S\n", + "##########################################\n", + "2 found derivation for sentence: le méchant chat dort\n", + " le méchant chat dort\n", + " (N/pN) (pN/pN) pN (S\\N)\n", + " --------------->\n", + " pN\n", + "----------------------->\n", + " N\n", + "------------------------------<\n", + " S\n", + " le méchant chat dort\n", + " (N/pN) (pN/pN) pN (S\\N)\n", + "----------------->B\n", + " (N/pN)\n", + "----------------------->\n", + " N\n", + "------------------------------<\n", + " S\n", + "==> 2 0\n", + "==> 2 1\n", + "==> 2 2\n", + "==> 3 0\n", + "==> 3 1\n", + "==> 4 0\n", + "Edge count: 1\n", + "Best derivation tree has weight 0.24957917865181148\n", + " le méchant chat dort\n", + " (N/pN) (pN/pN) pN (S\\N)\n", + " --------------->\n", + " pN\n", + "----------------------->\n", + " N\n", + "------------------------------<\n", + " S\n", + "##########################################\n", + "2 found derivation for sentence: le méchant chat dort\n", + " le méchant chat dort\n", + " (N/pN) (pN/pN) pN (S\\N)\n", + " --------------->\n", + " pN\n", + "----------------------->\n", + " N\n", + "------------------------------<\n", + " S\n", + " le méchant chat dort\n", + " (N/pN) (pN/pN) pN (S\\N)\n", + "----------------->B\n", + " (N/pN)\n", + "----------------------->\n", + " N\n", + "------------------------------<\n", + " S\n", + "==> 2 0\n", + "==> 2 1\n", + "==> 2 2\n", + "==> 3 0\n", + "==> 3 1\n", + "==> 4 0\n", + "Edge count: 1\n", + "Best derivation tree has weight 0.24957917865181148\n", + " le méchant chat dort\n", + " (N/pN) (pN/pN) pN (S\\N)\n", + " --------------->\n", + " pN\n", + "----------------------->\n", + " N\n", + "------------------------------<\n", + " S\n", + "##########################################\n", + "2 found derivation for sentence: le méchant chat dort\n", + " le méchant chat dort\n", + " (N/pN) (pN/pN) pN (S\\N)\n", + " --------------->\n", + " pN\n", + "----------------------->\n", + " N\n", + "------------------------------<\n", + " S\n", + " le méchant chat dort\n", + " (N/pN) (pN/pN) pN (S\\N)\n", + "----------------->B\n", + " (N/pN)\n", + "----------------------->\n", + " N\n", + "------------------------------<\n", + " S\n", + "==> 2 0\n", + "==> 2 1\n", + "==> 2 2\n", + "==> 3 0\n", + "==> 3 1\n", + "==> 4 0\n", + "Edge count: 1\n", + "Best derivation tree has weight 0.24957917865181148\n", + " le méchant chat dort\n", + " (N/pN) (pN/pN) pN (S\\N)\n", + " --------------->\n", + " pN\n", + "----------------------->\n", + " N\n", + "------------------------------<\n", + " S\n", + "##########################################\n", + "2 found derivation for sentence: le méchant chat dort\n", + " le méchant chat dort\n", + " (N/pN) (pN/pN) pN (S\\N)\n", + " --------------->\n", + " pN\n", + "----------------------->\n", + " N\n", + "------------------------------<\n", + " S\n", + " le méchant chat dort\n", + " (N/pN) (pN/pN) pN (S\\N)\n", + "----------------->B\n", + " (N/pN)\n", + "----------------------->\n", + " N\n", + "------------------------------<\n", + " S\n", + "==> 2 0\n", + "==> 2 1\n", + "==> 2 2\n", + "==> 3 0\n", + "==> 3 1\n", + "==> 4 0\n", + "Edge count: 1\n", + "Best derivation tree has weight 0.24957917865181148\n", + " le méchant chat dort\n", + " (N/pN) (pN/pN) pN (S\\N)\n", + " --------------->\n", + " pN\n", + "----------------------->\n", + " N\n", + "------------------------------<\n", + " S\n", + "##########################################\n", + "2 found derivation for sentence: le méchant chat dort\n", + " le méchant chat dort\n", + " (N/pN) (pN/pN) pN (S\\N)\n", + " --------------->\n", + " pN\n", + "----------------------->\n", + " N\n", + "------------------------------<\n", + " S\n", + " le méchant chat dort\n", + " (N/pN) (pN/pN) pN (S\\N)\n", + "----------------->B\n", + " (N/pN)\n", + "----------------------->\n", + " N\n", + "------------------------------<\n", + " S\n", + "==> 2 0\n", + "==> 2 1\n", + "==> 2 2\n", + "==> 3 0\n", + "==> 3 1\n", + "==> 4 0\n", + "Edge count: 1\n", + "Best derivation tree has weight 0.24957917865181148\n", + " le méchant chat dort\n", + " (N/pN) (pN/pN) pN (S\\N)\n", + " --------------->\n", + " pN\n", + "----------------------->\n", + " N\n", + "------------------------------<\n", + " S\n", + "##########################################\n", + "2 found derivation for sentence: le méchant chat dort\n", + " le méchant chat dort\n", + " (N/pN) (pN/pN) pN (S\\N)\n", + " --------------->\n", + " pN\n", + "----------------------->\n", + " N\n", + "------------------------------<\n", + " S\n", + " le méchant chat dort\n", + " (N/pN) (pN/pN) pN (S\\N)\n", + "----------------->B\n", + " (N/pN)\n", + "----------------------->\n", + " N\n", + "------------------------------<\n", + " S\n", + "==> 2 0\n", + "==> 2 1\n", + "==> 2 2\n", + "==> 3 0\n", + "==> 3 1\n", + "==> 4 0\n", + "Edge count: 1\n", + "Best derivation tree has weight 0.24957917865181148\n", + " le méchant chat dort\n", + " (N/pN) (pN/pN) pN (S\\N)\n", + " --------------->\n", + " pN\n", + "----------------------->\n", + " N\n", + "------------------------------<\n", + " S\n", + "##########################################\n", + "2 found derivation for sentence: le méchant chat dort\n", + " le méchant chat dort\n", + " (N/pN) (pN/pN) pN (S\\N)\n", + " --------------->\n", + " pN\n", + "----------------------->\n", + " N\n", + "------------------------------<\n", + " S\n", + " le méchant chat dort\n", + " (N/pN) (pN/pN) pN (S\\N)\n", + "----------------->B\n", + " (N/pN)\n", + "----------------------->\n", + " N\n", + "------------------------------<\n", + " S\n", + "==> 2 0\n", + "==> 2 1\n", + "==> 2 2\n", + "==> 3 0\n", + "==> 3 1\n", + "==> 4 0\n", + "Edge count: 1\n", + "Best derivation tree has weight 0.24957917865181148\n", + " le méchant chat dort\n", + " (N/pN) (pN/pN) pN (S\\N)\n", + " --------------->\n", + " pN\n", + "----------------------->\n", + " N\n", + "------------------------------<\n", + " S\n", + "##########################################\n", + "2 found derivation for sentence: le méchant chat dort\n", + " le méchant chat dort\n", + " (N/pN) (pN/pN) pN (S\\N)\n", + " --------------->\n", + " pN\n", + "----------------------->\n", + " N\n", + "------------------------------<\n", + " S\n", + " le méchant chat dort\n", + " (N/pN) (pN/pN) pN (S\\N)\n", + "----------------->B\n", + " (N/pN)\n", + "----------------------->\n", + " N\n", + "------------------------------<\n", + " S\n", + "==> 2 0\n", + "==> 2 1\n", + "==> 2 2\n", + "==> 3 0\n", + "==> 3 1\n", + "==> 4 0\n", + "Edge count: 1\n", + "Best derivation tree has weight 0.24957917865181148\n", + " le méchant chat dort\n", + " (N/pN) (pN/pN) pN (S\\N)\n", + " --------------->\n", + " pN\n", + "----------------------->\n", + " N\n", + "------------------------------<\n", + " S\n", + "##########################################\n", + "2 found derivation for sentence: le méchant chat dort\n", + " le méchant chat dort\n", + " (N/pN) (pN/pN) pN (S\\N)\n", + " --------------->\n", + " pN\n", + "----------------------->\n", + " N\n", + "------------------------------<\n", + " S\n", + " le méchant chat dort\n", + " (N/pN) (pN/pN) pN (S\\N)\n", + "----------------->B\n", + " (N/pN)\n", + "----------------------->\n", + " N\n", + "------------------------------<\n", + " S\n", + "==> 2 0\n", + "==> 2 1\n", + "==> 2 2\n", + "==> 3 0\n", + "==> 3 1\n", + "==> 4 0\n", + "Edge count: 1\n", + "Best derivation tree has weight 0.24957917865181148\n", + " le méchant chat dort\n", + " (N/pN) (pN/pN) pN (S\\N)\n", + " --------------->\n", + " pN\n", + "----------------------->\n", + " N\n", + "------------------------------<\n", + " S\n", + "##########################################\n", + "2 found derivation for sentence: le méchant chat dort\n", + " le méchant chat dort\n", + " (N/pN) (pN/pN) pN (S\\N)\n", + " --------------->\n", + " pN\n", + "----------------------->\n", + " N\n", + "------------------------------<\n", + " S\n", + " le méchant chat dort\n", + " (N/pN) (pN/pN) pN (S\\N)\n", + "----------------->B\n", + " (N/pN)\n", + "----------------------->\n", + " N\n", + "------------------------------<\n", + " S\n", + "==> 2 0\n", + "==> 2 1\n", + "==> 2 2\n", + "==> 3 0\n", + "==> 3 1\n", + "==> 4 0\n", + "Edge count: 1\n", + "Best derivation tree has weight 0.24957917865181148\n", + " le méchant chat dort\n", + " (N/pN) (pN/pN) pN (S\\N)\n", + " --------------->\n", + " pN\n", + "----------------------->\n", + " N\n", + "------------------------------<\n", + " S\n", + "##########################################\n", + "2 found derivation for sentence: le méchant chat dort\n", + " le méchant chat dort\n", + " (N/pN) (pN/pN) pN (S\\N)\n", + " --------------->\n", + " pN\n", + "----------------------->\n", + " N\n", + "------------------------------<\n", + " S\n", + " le méchant chat dort\n", + " (N/pN) (pN/pN) pN (S\\N)\n", + "----------------->B\n", + " (N/pN)\n", + "----------------------->\n", + " N\n", + "------------------------------<\n", + " S\n", + "==> 2 0\n", + "==> 2 1\n", + "==> 2 2\n", + "==> 3 0\n", + "==> 3 1\n", + "==> 4 0\n", + "Edge count: 1\n", + "Best derivation tree has weight 0.24957917865181148\n", + " le méchant chat dort\n", + " (N/pN) (pN/pN) pN (S\\N)\n", + " --------------->\n", + " pN\n", + "----------------------->\n", + " N\n", + "------------------------------<\n", + " S\n", + "##########################################\n", + "2 found derivation for sentence: le méchant chat dort\n", + " le méchant chat dort\n", + " (N/pN) (pN/pN) pN (S\\N)\n", + " --------------->\n", + " pN\n", + "----------------------->\n", + " N\n", + "------------------------------<\n", + " S\n", + " le méchant chat dort\n", + " (N/pN) (pN/pN) pN (S\\N)\n", + "----------------->B\n", + " (N/pN)\n", + "----------------------->\n", + " N\n", + "------------------------------<\n", + " S\n", + "==> 2 0\n", + "==> 2 1\n", + "==> 2 2\n", + "==> 3 0\n", + "==> 3 1\n", + "==> 4 0\n", + "Edge count: 1\n", + "Best derivation tree has weight 0.24957917865181148\n", + " le méchant chat dort\n", + " (N/pN) (pN/pN) pN (S\\N)\n", + " --------------->\n", + " pN\n", + "----------------------->\n", + " N\n", + "------------------------------<\n", + " S\n", + "##########################################\n", + "2 found derivation for sentence: le méchant chat dort\n", + " le méchant chat dort\n", + " (N/pN) (pN/pN) pN (S\\N)\n", + " --------------->\n", + " pN\n", + "----------------------->\n", + " N\n", + "------------------------------<\n", + " S\n", + " le méchant chat dort\n", + " (N/pN) (pN/pN) pN (S\\N)\n", + "----------------->B\n", + " (N/pN)\n", + "----------------------->\n", + " N\n", + "------------------------------<\n", + " S\n", + "==> 2 0\n", + "==> 2 1\n", + "==> 2 2\n", + "==> 3 0\n", + "==> 3 1\n", + "==> 4 0\n", + "Edge count: 1\n", + "Best derivation tree has weight 0.24957917865181148\n", + " le méchant chat dort\n", + " (N/pN) (pN/pN) pN (S\\N)\n", + " --------------->\n", + " pN\n", + "----------------------->\n", + " N\n", + "------------------------------<\n", + " S\n", + "##########################################\n" ] } ], + "source": [ + "# On lit les phrases dans le fichier\n", + "with open('phrases.txt') as f:\n", + " lines = f.readlines()\n", + "\n", + " # On ajoute des phrases de test\n", + " lines.append(\"le chat et la souris dorment\")\n", + " \n", + " for phrase in lines:\n", + " # On met tout en minuscule\n", + " phrase = phrase.lower().strip()\n", + " phrase = \"le méchant chat dort\"\n", + " \n", + " # On compte les arbres de dérivation trouvés\n", + " i = len(list(parser.parse(phrase.split())))\n", + " print(i, \"found derivation for sentence:\",phrase)\n", + " g = parser.parse(phrase.split())\n", + " for t in g:\n", + " chart.printCCGDerivation(t)\n", + " \n", + " # On affiche la dérivation la meilleure pour l'arbre\n", + " if (i != 0):\n", + " t,d = bestTree(phrase.split(), lex, rulesC)\n", + " print(\"Best derivation tree has weight\",d)\n", + " chart.printCCGDerivation(t)\n", + " \n", + " print(\"#\"*42)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], "source": [ "print(lex)" ] @@ -831,9 +1469,9 @@ ], "metadata": { "kernelspec": { - "display_name": "Python 3", + "display_name": "venv", "language": "python", - "name": "python3" + "name": "venv" }, "language_info": { "codemirror_mode": { @@ -845,7 +1483,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.9.1" + "version": "3.11.2" } }, "nbformat": 4,