diff --git a/build/pil_parser.js b/build/pil_parser.js index 641f286..dae802f 100644 --- a/build/pil_parser.js +++ b/build/pil_parser.js @@ -72,14 +72,12 @@ } */ var pil_parser = (function(){ -var o=function(k,v,o,l){for(o=o||{},l=k.length;l--;o[k[l]]=v);return o},$V0=[6,8,31,55,56,61,62,74,77,79,80,82,83,137,154],$V1=[1,30],$V2=[1,31],$V3=[1,21],$V4=[1,23],$V5=[1,24],$V6=[1,27],$V7=[1,28],$V8=[1,25],$V9=[1,26],$Va=[1,22],$Vb=[1,29],$Vc=[1,40],$Vd=[1,41],$Ve=[26,68,95,143],$Vf=[2,216],$Vg=[1,43],$Vh=[1,44],$Vi=[1,45],$Vj=[1,49],$Vk=[1,50],$Vl=[1,52],$Vm=[1,51],$Vn=[1,89],$Vo=[1,111],$Vp=[1,110],$Vq=[1,134],$Vr=[1,88],$Vs=[2,38],$Vt=[1,133],$Vu=[1,84],$Vv=[1,105],$Vw=[1,85],$Vx=[1,129],$Vy=[1,128],$Vz=[1,132],$VA=[1,135],$VB=[1,124],$VC=[1,125],$VD=[1,126],$VE=[1,119],$VF=[1,96],$VG=[1,127],$VH=[1,131],$VI=[1,109],$VJ=[1,94],$VK=[1,95],$VL=[1,112],$VM=[1,113],$VN=[1,114],$VO=[1,115],$VP=[1,116],$VQ=[1,117],$VR=[1,101],$VS=[1,102],$VT=[1,121],$VU=[1,103],$VV=[1,97],$VW=[1,98],$VX=[1,99],$VY=[1,107],$VZ=[1,123],$V_=[2,67],$V$=[1,153],$V01=[1,138],$V11=[1,141],$V21=[1,142],$V31=[1,143],$V41=[1,144],$V51=[1,145],$V61=[1,146],$V71=[1,147],$V81=[1,148],$V91=[1,149],$Va1=[1,150],$Vb1=[1,151],$Vc1=[1,152],$Vd1=[6,8,30,31,55,56,61,62,74,77,79,80,82,83,108,137,154],$Ve1=[6,8,30,31,48,53,55,56,58,61,62,64,65,74,77,79,80,82,83,87,107,108,118,137,146,147,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,171,172,173,174,175,176,177],$Vf1=[2,256],$Vg1=[1,165],$Vh1=[1,166],$Vi1=[6,8,30,31,51,55,56,61,62,64,74,77,79,80,82,83,107,108,127,137,154],$Vj1=[6,8,30,31,55,56,61,62,64,74,77,79,80,82,83,107,108,137,154],$Vk1=[2,56],$Vl1=[1,175],$Vm1=[1,178],$Vn1=[1,179],$Vo1=[1,180],$Vp1=[1,181],$Vq1=[1,182],$Vr1=[21,24,26,28,30,31,45,46,49,51,55,56,61,62,68,70,71,72,73,74,77,78,79,80,82,83,95,96,100,101,104,108,109,110,111,113,116,119,121,123,129,137,141,142,143,154,170,171,172,178,180],$Vs1=[1,189],$Vt1=[8,30,108],$Vu1=[1,197],$Vv1=[1,191],$Vw1=[1,192],$Vx1=[1,193],$Vy1=[1,194],$Vz1=[1,195],$VA1=[1,196],$VB1=[1,198],$VC1=[1,199],$VD1=[1,200],$VE1=[1,201],$VF1=[1,202],$VG1=[1,203],$VH1=[1,204],$VI1=[1,205],$VJ1=[1,206],$VK1=[1,207],$VL1=[1,208],$VM1=[1,209],$VN1=[1,210],$VO1=[1,211],$VP1=[1,212],$VQ1=[1,213],$VR1=[8,21,24,26,28,30,31,45,46,49,51,55,56,61,62,68,70,71,72,73,74,77,78,79,80,82,83,95,96,100,101,104,108,109,110,111,113,114,116,119,121,123,129,137,141,142,143,154,170,171,172,178,180],$VS1=[1,223],$VT1=[1,225],$VU1=[2,309],$VV1=[1,229],$VW1=[1,230],$VX1=[1,232],$VY1=[1,233],$VZ1=[1,234],$V_1=[1,235],$V$1=[1,239],$V02=[1,238],$V12=[1,240],$V22=[1,242],$V32=[1,244],$V42=[1,249],$V52=[1,259],$V62=[1,260],$V72=[1,258],$V82=[8,30,107,108],$V92=[1,269],$Va2=[1,268],$Vb2=[1,264],$Vc2=[1,265],$Vd2=[1,266],$Ve2=[1,267],$Vf2=[6,8,30,31,48,53,55,56,58,61,62,64,65,74,77,79,80,82,83,87,107,108,118,121,123,127,131,132,133,137,146,147,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,171,172,173,174,175,176,177],$Vg2=[2,338],$Vh2=[1,274],$Vi2=[1,273],$Vj2=[1,276],$Vk2=[1,282],$Vl2=[1,287],$Vm2=[1,292],$Vn2=[6,8,30,31,46,48,53,55,56,58,61,62,64,65,74,77,79,80,82,83,87,107,108,118,121,123,127,131,132,133,137,146,147,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,171,172,173,174,175,176,177,180],$Vo2=[6,8,25,28,30,31,46,48,51,53,55,56,58,61,62,64,65,74,77,79,80,82,83,87,107,108,118,121,123,127,131,132,133,137,146,147,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,171,172,173,174,175,176,177,180],$Vp2=[2,346],$Vq2=[1,307],$Vr2=[48,64],$Vs2=[6,8,26,28,30,31,48,51,53,55,56,58,61,62,64,65,68,74,77,79,80,82,83,87,107,108,118,137,146,147,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,171,172,173,174,175,176,177],$Vt2=[6,8,30,31,55,56,61,62,74,77,79,80,82,83,107,108,137,154],$Vu2=[1,328],$Vv2=[1,340],$Vw2=[48,53,64],$Vx2=[8,21,24,26,28,31,45,46,49,51,55,56,61,62,68,70,71,72,73,74,77,78,79,80,82,83,95,96,100,101,104,108,109,110,111,113,121,123,129,137,141,142,143,154,170,171,172,178,180],$Vy2=[1,374],$Vz2=[1,378],$VA2=[1,379],$VB2=[1,384],$VC2=[1,385],$VD2=[26,31,46,62,68,70,71,72,74,78,95,121,123,141,142,143,170,171,172,178,180],$VE2=[1,388],$VF2=[1,397],$VG2=[2,192],$VH2=[2,243],$VI2=[1,426],$VJ2=[1,430],$VK2=[8,30,64,107,108],$VL2=[2,195],$VM2=[8,30,53,64,107,108,127],$VN2=[53,64],$VO2=[1,451],$VP2=[1,452],$VQ2=[6,8,30,31,48,53,55,56,58,61,62,64,65,74,77,79,80,82,83,87,107,108,118,137,146,147,154,155,156,157,158,159,160,161,162,163,164,165,166,167],$VR2=[6,8,28,30,31,48,53,55,56,58,61,62,64,65,74,77,79,80,82,83,87,107,108,118,137,146,147,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,171,172,173,174,175,176,177],$VS2=[6,8,30,31,48,53,55,56,58,61,62,64,65,74,77,79,80,82,83,87,108,118,137,146,147,154,162,163,167],$VT2=[6,8,30,31,48,53,55,56,58,61,62,64,65,74,77,79,80,82,83,87,108,118,137,146,147,154,163,167],$VU2=[6,8,30,31,48,53,55,56,58,61,62,64,65,74,77,79,80,82,83,87,107,108,118,137,146,147,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,171,172],$VV2=[6,8,30,31,48,53,55,56,58,61,62,64,65,74,77,79,80,82,83,87,107,108,118,137,146,147,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,171,172,173,174,175,176],$VW2=[1,483],$VX2=[30,64],$VY2=[1,486],$VZ2=[30,53,64],$V_2=[6,8,28,30,31,46,48,51,53,55,56,58,61,62,64,65,74,77,79,80,82,83,87,107,108,118,137,146,147,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,171,172,173,174,175,176,177],$V$2=[1,495],$V03=[1,497],$V13=[2,41],$V23=[8,107],$V33=[1,527],$V43=[1,551],$V53=[6,8,25,28,30,31,46,48,51,53,55,56,58,61,62,64,65,74,77,79,80,82,83,87,107,108,118,121,123,127,131,132,133,137,146,147,151,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,171,172,173,174,175,176,177,180],$V63=[1,575],$V73=[1,576],$V83=[1,577],$V93=[53,64,65],$Va3=[2,242],$Vb3=[1,579],$Vc3=[8,30],$Vd3=[8,30,51,53,64,107,108,127],$Ve3=[6,8,30,31,46,48,51,53,55,56,58,61,62,64,65,74,77,79,80,82,83,87,107,108,118,121,123,127,131,132,133,137,146,147,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,171,172,173,174,175,176,177,180],$Vf3=[6,8,30,31,48,55,56,61,62,64,74,77,79,80,82,83,107,108,137,154],$Vg3=[53,58,64,65],$Vh3=[6,8,21,24,26,28,30,31,45,46,49,51,55,56,61,62,68,70,71,72,73,74,77,78,79,80,82,83,95,96,100,101,104,108,109,110,111,113,114,116,119,121,123,129,137,141,142,143,154,170,171,172,178,180],$Vi3=[1,669],$Vj3=[1,677],$Vk3=[1,678],$Vl3=[1,716],$Vm3=[58,64],$Vn3=[30,116,119]; -var parser = {trace: function trace () { - Jison.print.apply(null, arguments); - }, +var o=function(k,v,o,l){for(o=o||{},l=k.length;l--;o[k[l]]=v);return o},$V0=[6,8,20,21,26,33,57,58,63,64,72,73,74,75,76,79,80,81,82,84,85,139],$V1=[1,39],$V2=[1,33],$V3=[1,34],$V4=[1,23],$V5=[1,35],$V6=[1,36],$V7=[1,37],$V8=[1,32],$V9=[1,25],$Va=[1,26],$Vb=[1,38],$Vc=[1,29],$Vd=[1,30],$Ve=[1,27],$Vf=[1,28],$Vg=[1,24],$Vh=[1,47],$Vi=[1,49],$Vj=[1,50],$Vk=[28,70,97,145],$Vl=[2,219],$Vm=[1,52],$Vn=[1,53],$Vo=[1,54],$Vp=[1,58],$Vq=[1,59],$Vr=[1,61],$Vs=[1,60],$Vt=[6,8,20,21,26,32,33,57,58,63,64,72,73,74,75,76,79,80,81,82,84,85,109,110,139],$Vu=[1,68],$Vv=[1,75],$Vw=[1,74],$Vx=[1,76],$Vy=[1,73],$Vz=[1,81],$VA=[1,92],$VB=[1,121],$VC=[1,151],$VD=[1,152],$VE=[1,144],$VF=[1,143],$VG=[1,120],$VH=[2,40],$VI=[1,116],$VJ=[1,137],$VK=[1,117],$VL=[1,161],$VM=[1,157],$VN=[1,158],$VO=[1,159],$VP=[1,128],$VQ=[1,160],$VR=[1,141],$VS=[1,126],$VT=[1,127],$VU=[1,145],$VV=[1,146],$VW=[1,147],$VX=[1,148],$VY=[1,149],$VZ=[1,150],$V_=[1,133],$V$=[1,134],$V01=[1,154],$V11=[1,135],$V21=[1,142],$V31=[1,129],$V41=[1,130],$V51=[1,131],$V61=[1,139],$V71=[1,156],$V81=[2,69],$V91=[1,180],$Va1=[1,165],$Vb1=[1,168],$Vc1=[1,169],$Vd1=[1,170],$Ve1=[1,171],$Vf1=[1,172],$Vg1=[1,173],$Vh1=[1,174],$Vi1=[1,175],$Vj1=[1,176],$Vk1=[1,177],$Vl1=[1,178],$Vm1=[1,179],$Vn1=[6,8,20,21,26,32,33,57,58,63,64,72,73,74,75,76,79,80,81,82,84,85,110,139],$Vo1=[6,8,20,21,26,32,33,50,55,57,58,60,63,64,66,67,72,73,74,75,76,79,80,81,82,84,85,88,109,110,120,139,148,149,157,158,159,160,161,162,163,164,165,166,167,168,169,170,171,173,174,175,176,177,178,179],$Vp1=[2,259],$Vq1=[1,193],$Vr1=[1,194],$Vs1=[6,8,20,21,26,32,33,53,57,58,63,64,66,72,73,74,75,76,79,80,81,82,84,85,109,110,129,139],$Vt1=[6,8,20,21,26,32,33,57,58,63,64,66,72,73,74,75,76,79,80,81,82,84,85,109,110,139],$Vu1=[2,353],$Vv1=[2,58],$Vw1=[1,198],$Vx1=[1,199],$Vy1=[2,198],$Vz1=[6,8,20,21,26,32,33,55,57,58,63,64,66,72,73,74,75,76,79,80,81,82,84,85,109,110,129,139],$VA1=[2,195],$VB1=[1,202],$VC1=[6,8,20,21,26,27,30,32,33,48,50,53,55,57,58,60,63,64,66,67,72,73,74,75,76,79,80,81,82,84,85,88,109,110,120,123,125,129,133,134,135,139,148,149,157,158,159,160,161,162,163,164,165,166,167,168,169,170,171,173,174,175,176,177,178,179,182],$VD1=[1,221],$VE1=[1,224],$VF1=[1,225],$VG1=[1,226],$VH1=[1,227],$VI1=[1,228],$VJ1=[20,21,23,26,28,30,32,33,47,48,51,53,57,58,63,64,70,72,73,74,75,76,79,80,81,82,84,85,97,98,102,103,106,110,111,112,113,115,118,121,123,125,131,139,143,144,145,156,172,173,174,180,182],$VK1=[1,235],$VL1=[8,32,110],$VM1=[1,243],$VN1=[1,237],$VO1=[1,238],$VP1=[1,239],$VQ1=[1,240],$VR1=[1,241],$VS1=[1,242],$VT1=[1,244],$VU1=[1,245],$VV1=[1,246],$VW1=[1,247],$VX1=[1,248],$VY1=[1,249],$VZ1=[1,250],$V_1=[1,251],$V$1=[1,252],$V02=[1,253],$V12=[1,254],$V22=[1,255],$V32=[1,256],$V42=[1,257],$V52=[1,258],$V62=[1,259],$V72=[8,20,21,23,26,28,30,32,33,47,48,51,53,57,58,63,64,70,72,73,74,75,76,79,80,81,82,84,85,97,98,102,103,106,110,111,112,113,115,116,118,121,123,125,131,139,143,144,145,156,172,173,174,180,182],$V82=[1,269],$V92=[1,271],$Va2=[2,312],$Vb2=[1,275],$Vc2=[1,276],$Vd2=[1,278],$Ve2=[1,279],$Vf2=[1,280],$Vg2=[1,281],$Vh2=[1,285],$Vi2=[1,284],$Vj2=[1,286],$Vk2=[1,288],$Vl2=[1,290],$Vm2=[1,304],$Vn2=[1,305],$Vo2=[1,303],$Vp2=[6,8,20,21,26,32,33,50,55,57,58,60,63,64,66,67,72,73,74,75,76,79,80,81,82,84,85,88,109,110,120,123,125,129,133,134,135,139,148,149,157,158,159,160,161,162,163,164,165,166,167,168,169,170,171,173,174,175,176,177,178,179],$Vq2=[2,341],$Vr2=[1,312],$Vs2=[1,311],$Vt2=[1,314],$Vu2=[1,317],$Vv2=[1,320],$Vw2=[1,323],$Vx2=[6,8,20,21,26,32,33,48,50,55,57,58,60,63,64,66,67,72,73,74,75,76,79,80,81,82,84,85,88,109,110,120,123,125,129,133,134,135,139,148,149,157,158,159,160,161,162,163,164,165,166,167,168,169,170,171,173,174,175,176,177,178,179,182],$Vy2=[50,66],$Vz2=[6,8,20,21,26,28,30,32,33,50,53,55,57,58,60,63,64,66,67,70,72,73,74,75,76,79,80,81,82,84,85,88,109,110,120,139,148,149,157,158,159,160,161,162,163,164,165,166,167,168,169,170,171,173,174,175,176,177,178,179],$VA2=[1,349],$VB2=[1,358],$VC2=[1,359],$VD2=[55,66],$VE2=[1,381],$VF2=[50,55,66],$VG2=[8,20,21,23,26,28,30,33,47,48,51,53,57,58,63,64,70,72,73,74,75,76,79,80,81,82,84,85,97,98,102,103,106,110,111,112,113,115,123,125,131,139,143,144,145,156,172,173,174,180,182],$VH2=[1,415],$VI2=[1,419],$VJ2=[1,420],$VK2=[1,425],$VL2=[1,426],$VM2=[28,33,48,64,70,72,73,74,76,80,97,123,125,143,144,145,172,173,174,180,182],$VN2=[1,429],$VO2=[2,246],$VP2=[1,460],$VQ2=[1,475],$VR2=[1,493],$VS2=[6,8,20,21,26,27,30,32,33,48,50,53,55,57,58,60,63,64,66,67,72,73,74,75,76,79,80,81,82,84,85,88,109,110,120,123,125,129,133,134,135,139,148,149,153,157,158,159,160,161,162,163,164,165,166,167,168,169,170,171,173,174,175,176,177,178,179,182],$VT2=[6,8,20,21,26,32,33,53,55,57,58,63,64,66,72,73,74,75,76,79,80,81,82,84,85,109,110,129,139],$VU2=[6,8,20,21,26,32,33,50,55,57,58,60,63,64,66,67,72,73,74,75,76,79,80,81,82,84,85,88,109,110,120,139,148,149,157,158,159,160,161,162,163,164,165,166,167,168,169],$VV2=[6,8,20,21,26,30,32,33,50,55,57,58,60,63,64,66,67,72,73,74,75,76,79,80,81,82,84,85,88,109,110,120,139,148,149,157,158,159,160,161,162,163,164,165,166,167,168,169,170,171,173,174,175,176,177,178,179],$VW2=[6,8,20,21,26,32,33,50,55,57,58,60,63,64,66,67,72,73,74,75,76,79,80,81,82,84,85,88,110,120,139,148,149,164,165,169],$VX2=[6,8,20,21,26,32,33,50,55,57,58,60,63,64,66,67,72,73,74,75,76,79,80,81,82,84,85,88,110,120,139,148,149,165,169],$VY2=[6,8,20,21,26,32,33,50,55,57,58,60,63,64,66,67,72,73,74,75,76,79,80,81,82,84,85,88,109,110,120,139,148,149,157,158,159,160,161,162,163,164,165,166,167,168,169,170,171,173,174],$VZ2=[6,8,20,21,26,32,33,50,55,57,58,60,63,64,66,67,72,73,74,75,76,79,80,81,82,84,85,88,109,110,120,139,148,149,157,158,159,160,161,162,163,164,165,166,167,168,169,170,171,173,174,175,176,177,178],$V_2=[1,510],$V$2=[32,66],$V03=[1,513],$V13=[32,55,66],$V23=[6,8,20,21,26,30,32,33,48,50,53,55,57,58,60,63,64,66,67,72,73,74,75,76,79,80,81,82,84,85,88,109,110,120,139,148,149,157,158,159,160,161,162,163,164,165,166,167,168,169,170,171,173,174,175,176,177,178,179],$V33=[1,522],$V43=[1,524],$V53=[2,43],$V63=[8,109],$V73=[1,550],$V83=[1,597],$V93=[1,598],$Va3=[1,599],$Vb3=[55,66,67],$Vc3=[2,245],$Vd3=[1,601],$Ve3=[8,32],$Vf3=[6,8,20,21,26,32,33,48,50,53,55,57,58,60,63,64,66,67,72,73,74,75,76,79,80,81,82,84,85,88,109,110,120,123,125,129,133,134,135,139,148,149,157,158,159,160,161,162,163,164,165,166,167,168,169,170,171,173,174,175,176,177,178,179,182],$Vg3=[6,8,20,21,26,32,33,50,57,58,63,64,66,72,73,74,75,76,79,80,81,82,84,85,109,110,139],$Vh3=[55,60,66,67],$Vi3=[6,8,20,21,23,26,28,30,32,33,47,48,51,53,57,58,63,64,70,72,73,74,75,76,79,80,81,82,84,85,97,98,102,103,106,110,111,112,113,115,116,118,121,123,125,131,139,143,144,145,156,172,173,174,180,182],$Vj3=[1,687],$Vk3=[1,694],$Vl3=[1,695],$Vm3=[1,728],$Vn3=[60,66],$Vo3=[32,118,121]; +var parser = {trace: function trace () { }, yy: {}, -symbols_: {"error":2,"all_top_level_blocks":3,"top_level_blocks":4,"lopcs":5,"EOF":6,"top_level_block":7,"CS":8,"subproof_definition":9,"proof_definition":10,"function_definition":11,"include_directive":12,"col_declaration":13,"challenge_declaration":14,"public_declaration":15,"public_table_declaration":16,"proof_value_declaration":17,"subproof_value_declaration":18,"constant_definition":19,"use_directive":20,"USE":21,"name_reference":22,"no_closed_container_definition":23,"CONTAINER":24,"ALIAS":25,"IDENTIFIER":26,"closed_container_definition":27,"{":28,"declare_block":29,"}":30,"PROOF":31,"statement_block":32,"non_delimited_statement":33,"statement_closed":34,"lcs":35,"statement_no_closed":36,"statement_list":37,"statement_list_closed":38,"declare_list":39,"when_boundary":40,"FIRST":41,"LAST":42,"FRAME":43,"codeblock_closed":44,"WHEN":45,"(":46,"expression":47,")":48,"HINT":49,"data_object":50,"[":51,"data_array":52,"]":53,"function":54,"FUNCTION":55,"PRIVATE":56,"arguments":57,":":58,"return_type_list":59,"return_type":60,"FINAL":61,"SUBPROOF":62,"arguments_list":63,",":64,"DOTS_FILL":65,"argument":66,"basic_type":67,"REFERENCE":68,"type_array":69,"INT":70,"FE":71,"EXPR":72,"CONST":73,"COL":74,"WITNESS":75,"FIXED":76,"CHALLENGE":77,"T_STRING":78,"PROOF_VALUE":79,"SUBPROOF_VALUE":80,"AIR_VALUE":81,"PUBLIC":82,"PUBLIC_TABLE":83,"declare_item":84,"variable_declaration":85,"codeblock_no_closed":86,"===":87,"delayed_function_call":88,"data_value":89,"function_call":90,"name_optional_index":91,"multiple_expression_list":92,"delayed_function_event":93,"defined_scopes":94,"AIR":95,"ON":96,"variable_assignment":97,"variable_multiple_assignment":98,"return_statement":99,"CONTINUE":100,"BREAK":101,"in_expression":102,"expression_list":103,"FOR":104,"for_init":105,"variable_assignment_list":106,"IN":107,"WHILE":108,"DO":109,"ONCE":110,"SWITCH":111,"case_body":112,"IF":113,"ELSE":114,"case_list":115,"DEFAULT":116,"case_value":117,"DOTS_RANGE":118,"CASE":119,"for_assignation":120,"INC":121,"name_id":122,"DEC":123,"variable_type_declaration":124,"variable_declaration_list":125,"variable_declaration_item":126,"=":127,"variable_declaration_array":128,"RETURN":129,"assign_operation":130,"+=":131,"-=":132,"*=":133,"left_variable_multiple_assignment_list":134,"left_variable_multiple_assignment":135,"sequence_definition":136,"INCLUDE":137,"flexible_string":138,"stage_definition":139,"STAGE":140,"NUMBER":141,"STRING":142,"TEMPLATE_STRING":143,"sequence_list":144,"sequence":145,"DOTS_ARITH_SEQ":146,"DOTS_GEOM_SEQ":147,"declaration_array":148,"col_declaration_item":149,"col_declaration_ident":150,".":151,"col_declaration_list":152,"AGGREGATE":153,"CONSTANT":154,"EQ":155,"NE":156,"LT":157,"GT":158,"LE":159,"GE":160,"IS":161,"AND":162,"?":163,"B_AND":164,"B_OR":165,"B_XOR":166,"OR":167,"SHL":168,"SHR":169,"!":170,"+":171,"-":172,"*":173,"%":174,"/":175,"\\\\":176,"POW":177,"POSITIONAL_PARAM":178,"casting":179,"'":180,"array_index":181,"name_reference_right":182,"$accept":0,"$end":1}, -terminals_: {2:"error",6:"EOF",8:"CS",21:"USE",24:"CONTAINER",25:"ALIAS",26:"IDENTIFIER",28:"{",30:"}",31:"PROOF",41:"FIRST",42:"LAST",43:"FRAME",45:"WHEN",46:"(",48:")",49:"HINT",51:"[",53:"]",55:"FUNCTION",56:"PRIVATE",58:":",61:"FINAL",62:"SUBPROOF",64:",",65:"DOTS_FILL",68:"REFERENCE",70:"INT",71:"FE",72:"EXPR",73:"CONST",74:"COL",75:"WITNESS",76:"FIXED",77:"CHALLENGE",78:"T_STRING",79:"PROOF_VALUE",80:"SUBPROOF_VALUE",81:"AIR_VALUE",82:"PUBLIC",83:"PUBLIC_TABLE",87:"===",95:"AIR",96:"ON",100:"CONTINUE",101:"BREAK",104:"FOR",107:"IN",108:"WHILE",109:"DO",110:"ONCE",111:"SWITCH",113:"IF",114:"ELSE",116:"DEFAULT",118:"DOTS_RANGE",119:"CASE",121:"INC",123:"DEC",127:"=",129:"RETURN",131:"+=",132:"-=",133:"*=",137:"INCLUDE",140:"STAGE",141:"NUMBER",142:"STRING",143:"TEMPLATE_STRING",146:"DOTS_ARITH_SEQ",147:"DOTS_GEOM_SEQ",151:".",153:"AGGREGATE",154:"CONSTANT",155:"EQ",156:"NE",157:"LT",158:"GT",159:"LE",160:"GE",161:"IS",162:"AND",163:"?",164:"B_AND",165:"B_OR",166:"B_XOR",167:"OR",168:"SHL",169:"SHR",170:"!",171:"+",172:"-",173:"*",174:"%",175:"/",176:"\\\\",177:"POW",178:"POSITIONAL_PARAM",180:"'"}, -productions_: [0,[3,3],[4,3],[4,0],[5,2],[5,0],[7,1],[7,1],[7,1],[7,1],[7,1],[7,1],[7,1],[7,1],[7,1],[7,1],[7,1],[20,2],[23,2],[23,4],[27,5],[27,7],[10,4],[33,1],[33,2],[33,1],[33,2],[37,1],[37,2],[37,1],[38,2],[38,3],[38,3],[38,1],[38,2],[38,2],[38,1],[32,1],[32,0],[29,1],[29,2],[29,0],[35,2],[35,1],[40,1],[40,1],[40,1],[34,1],[34,5],[34,3],[34,4],[34,4],[34,3],[34,1],[34,1],[34,3],[54,2],[54,3],[11,11],[11,9],[11,7],[11,8],[11,9],[11,9],[57,1],[57,3],[57,1],[57,0],[63,3],[63,1],[66,2],[66,2],[66,3],[66,3],[67,1],[67,1],[67,1],[67,2],[67,2],[67,2],[67,2],[67,2],[67,1],[67,1],[67,2],[67,1],[67,1],[67,1],[67,1],[67,1],[67,1],[59,3],[59,1],[69,3],[69,2],[60,1],[60,2],[39,3],[39,1],[84,1],[84,1],[84,1],[84,1],[84,1],[84,1],[84,1],[84,1],[36,1],[36,1],[36,1],[36,1],[36,3],[36,1],[36,1],[36,1],[36,1],[36,1],[36,1],[36,1],[36,1],[36,1],[89,1],[89,3],[89,3],[50,5],[50,3],[50,3],[50,1],[52,3],[52,1],[90,4],[93,1],[94,1],[94,1],[94,1],[88,7],[86,1],[86,1],[86,1],[86,1],[86,1],[86,1],[102,1],[102,3],[44,9],[44,7],[44,5],[44,6],[44,6],[44,3],[44,5],[44,5],[44,7],[112,3],[112,5],[117,3],[117,5],[117,1],[117,3],[115,5],[115,4],[120,1],[120,2],[120,2],[120,2],[120,2],[105,1],[105,1],[105,1],[105,1],[85,1],[85,2],[124,2],[124,2],[124,2],[124,2],[124,2],[124,4],[124,4],[124,4],[124,4],[124,4],[124,4],[124,8],[124,8],[124,8],[124,8],[124,8],[128,2],[128,3],[128,3],[128,4],[126,1],[126,2],[125,3],[125,1],[99,1],[99,2],[99,4],[130,1],[130,1],[130,1],[130,1],[134,3],[134,2],[134,1],[135,3],[135,5],[98,3],[98,5],[97,3],[97,3],[106,3],[106,1],[12,2],[139,4],[139,0],[138,1],[138,1],[136,3],[136,4],[136,5],[136,6],[144,3],[144,5],[144,5],[144,5],[144,9],[144,9],[144,4],[144,4],[144,6],[144,6],[144,1],[144,3],[145,3],[145,3],[145,5],[145,5],[145,7],[145,2],[145,3],[145,1],[92,0],[92,3],[92,5],[92,3],[92,1],[103,4],[103,3],[103,2],[103,1],[148,2],[148,3],[148,3],[148,4],[149,1],[149,2],[150,1],[150,1],[150,1],[150,3],[150,3],[152,3],[152,1],[13,3],[13,5],[13,4],[13,4],[13,6],[13,6],[14,3],[15,4],[15,2],[16,16],[16,14],[17,2],[18,6],[9,9],[9,8],[9,5],[19,4],[19,5],[47,3],[47,3],[47,3],[47,3],[47,3],[47,3],[47,3],[47,3],[47,3],[47,5],[47,3],[47,3],[47,3],[47,3],[47,3],[47,3],[47,2],[47,3],[47,3],[47,3],[47,3],[47,3],[47,3],[47,3],[47,2],[47,2],[47,1],[47,2],[47,2],[47,2],[47,2],[47,1],[47,1],[47,3],[47,1],[47,1],[47,1],[179,4],[179,4],[179,4],[179,4],[179,4],[179,5],[179,5],[179,5],[179,5],[179,5],[122,2],[122,3],[122,5],[122,3],[122,2],[122,3],[122,5],[122,3],[122,1],[91,1],[91,2],[181,4],[181,3],[22,3],[22,3],[22,3],[22,1],[22,3],[22,1],[22,3],[182,3],[182,3],[182,1],[182,1]], +symbols_: {"error":2,"all_top_level_blocks":3,"top_level_blocks":4,"lopcs":5,"EOF":6,"top_level_block":7,"CS":8,"subproof_definition":9,"proof_definition":10,"function_definition":11,"include_directive":12,"col_declaration":13,"challenge_declaration":14,"public_declaration":15,"public_table_declaration":16,"proof_value_declaration":17,"subproof_value_declaration":18,"variable_declaration":19,"DEBUGGER":20,"PRAGMA":21,"use_directive":22,"USE":23,"name_reference":24,"no_closed_container_definition":25,"CONTAINER":26,"ALIAS":27,"IDENTIFIER":28,"closed_container_definition":29,"{":30,"declare_block":31,"}":32,"PROOF":33,"statement_block":34,"non_delimited_statement":35,"statement_closed":36,"lcs":37,"statement_no_closed":38,"statement_list":39,"statement_list_closed":40,"declare_list":41,"when_boundary":42,"FIRST":43,"LAST":44,"FRAME":45,"codeblock_closed":46,"WHEN":47,"(":48,"expression":49,")":50,"HINT":51,"data_object":52,"[":53,"data_array":54,"]":55,"function":56,"FUNCTION":57,"PRIVATE":58,"arguments":59,":":60,"return_type_list":61,"return_type":62,"FINAL":63,"SUBPROOF":64,"arguments_list":65,",":66,"DOTS_FILL":67,"argument":68,"basic_type":69,"REFERENCE":70,"type_array":71,"INT":72,"FE":73,"EXPR":74,"CONST":75,"COL":76,"WITNESS":77,"FIXED":78,"CHALLENGE":79,"T_STRING":80,"PROOF_VALUE":81,"SUBPROOF_VALUE":82,"AIR_VALUE":83,"PUBLIC":84,"PUBLIC_TABLE":85,"declare_item":86,"codeblock_no_closed":87,"===":88,"delayed_function_call":89,"constant_definition":90,"data_value":91,"function_call":92,"name_optional_index":93,"multiple_expression_list":94,"delayed_function_event":95,"defined_scopes":96,"AIR":97,"ON":98,"variable_assignment":99,"variable_multiple_assignment":100,"return_statement":101,"CONTINUE":102,"BREAK":103,"in_expression":104,"expression_list":105,"FOR":106,"for_init":107,"variable_assignment_list":108,"IN":109,"WHILE":110,"DO":111,"ONCE":112,"SWITCH":113,"case_body":114,"IF":115,"ELSE":116,"case_list":117,"DEFAULT":118,"case_value":119,"DOTS_RANGE":120,"CASE":121,"for_assignation":122,"INC":123,"name_id":124,"DEC":125,"variable_type_declaration":126,"variable_declaration_list":127,"variable_declaration_item":128,"=":129,"variable_declaration_array":130,"RETURN":131,"assign_operation":132,"+=":133,"-=":134,"*=":135,"left_variable_multiple_assignment_list":136,"left_variable_multiple_assignment":137,"sequence_definition":138,"INCLUDE":139,"flexible_string":140,"stage_definition":141,"STAGE":142,"NUMBER":143,"STRING":144,"TEMPLATE_STRING":145,"sequence_list":146,"sequence":147,"DOTS_ARITH_SEQ":148,"DOTS_GEOM_SEQ":149,"declaration_array":150,"col_declaration_item":151,"col_declaration_ident":152,".":153,"col_declaration_list":154,"AGGREGATE":155,"CONSTANT":156,"EQ":157,"NE":158,"LT":159,"GT":160,"LE":161,"GE":162,"IS":163,"AND":164,"?":165,"B_AND":166,"B_OR":167,"B_XOR":168,"OR":169,"SHL":170,"SHR":171,"!":172,"+":173,"-":174,"*":175,"%":176,"/":177,"\\\\":178,"POW":179,"POSITIONAL_PARAM":180,"casting":181,"'":182,"array_index":183,"expression_index":184,"name_reference_right":185,"$accept":0,"$end":1}, +terminals_: {2:"error",6:"EOF",8:"CS",20:"DEBUGGER",21:"PRAGMA",23:"USE",26:"CONTAINER",27:"ALIAS",28:"IDENTIFIER",30:"{",32:"}",33:"PROOF",43:"FIRST",44:"LAST",45:"FRAME",47:"WHEN",48:"(",50:")",51:"HINT",53:"[",55:"]",57:"FUNCTION",58:"PRIVATE",60:":",63:"FINAL",64:"SUBPROOF",66:",",67:"DOTS_FILL",70:"REFERENCE",72:"INT",73:"FE",74:"EXPR",75:"CONST",76:"COL",77:"WITNESS",78:"FIXED",79:"CHALLENGE",80:"T_STRING",81:"PROOF_VALUE",82:"SUBPROOF_VALUE",83:"AIR_VALUE",84:"PUBLIC",85:"PUBLIC_TABLE",88:"===",97:"AIR",98:"ON",102:"CONTINUE",103:"BREAK",106:"FOR",109:"IN",110:"WHILE",111:"DO",112:"ONCE",113:"SWITCH",115:"IF",116:"ELSE",118:"DEFAULT",120:"DOTS_RANGE",121:"CASE",123:"INC",125:"DEC",129:"=",131:"RETURN",133:"+=",134:"-=",135:"*=",139:"INCLUDE",142:"STAGE",143:"NUMBER",144:"STRING",145:"TEMPLATE_STRING",148:"DOTS_ARITH_SEQ",149:"DOTS_GEOM_SEQ",153:".",155:"AGGREGATE",156:"CONSTANT",157:"EQ",158:"NE",159:"LT",160:"GT",161:"LE",162:"GE",163:"IS",164:"AND",165:"?",166:"B_AND",167:"B_OR",168:"B_XOR",169:"OR",170:"SHL",171:"SHR",172:"!",173:"+",174:"-",175:"*",176:"%",177:"/",178:"\\\\",179:"POW",180:"POSITIONAL_PARAM",182:"'"}, +productions_: [0,[3,3],[4,3],[4,0],[5,2],[5,0],[7,1],[7,1],[7,1],[7,1],[7,1],[7,1],[7,1],[7,1],[7,1],[7,1],[7,1],[7,1],[7,1],[22,2],[25,2],[25,4],[29,5],[29,7],[10,4],[35,1],[35,2],[35,1],[35,2],[39,1],[39,2],[39,1],[40,2],[40,3],[40,3],[40,1],[40,2],[40,2],[40,1],[34,1],[34,0],[31,1],[31,2],[31,0],[37,2],[37,1],[42,1],[42,1],[42,1],[36,1],[36,5],[36,3],[36,4],[36,4],[36,3],[36,1],[36,1],[36,3],[56,2],[56,3],[11,11],[11,9],[11,7],[11,8],[11,9],[11,9],[59,1],[59,3],[59,1],[59,0],[65,3],[65,1],[68,2],[68,2],[68,3],[68,3],[69,1],[69,1],[69,1],[69,2],[69,2],[69,2],[69,2],[69,2],[69,1],[69,1],[69,2],[69,1],[69,1],[69,1],[69,1],[69,1],[69,1],[61,3],[61,1],[71,3],[71,2],[62,1],[62,2],[41,3],[41,1],[86,1],[86,1],[86,1],[86,1],[86,1],[86,1],[86,1],[38,1],[38,1],[38,1],[38,1],[38,3],[38,1],[38,1],[38,1],[38,1],[38,1],[38,1],[38,1],[38,1],[38,1],[91,1],[91,3],[91,3],[52,5],[52,3],[52,3],[52,1],[54,3],[54,1],[92,4],[95,1],[96,1],[96,1],[96,1],[89,7],[87,1],[87,1],[87,1],[87,1],[87,1],[87,1],[104,1],[104,3],[46,9],[46,7],[46,5],[46,6],[46,6],[46,3],[46,5],[46,5],[46,7],[46,1],[46,1],[114,3],[114,6],[119,3],[119,5],[119,1],[119,3],[117,5],[117,4],[122,1],[122,2],[122,2],[122,2],[122,2],[107,1],[107,1],[107,1],[107,1],[19,1],[19,2],[126,2],[126,2],[126,2],[126,2],[126,2],[126,4],[126,4],[126,4],[126,4],[126,4],[126,4],[126,8],[126,8],[126,8],[126,8],[126,8],[130,2],[130,3],[130,3],[130,4],[128,1],[128,2],[127,3],[127,1],[101,1],[101,2],[101,4],[132,1],[132,1],[132,1],[132,1],[136,3],[136,2],[136,1],[137,3],[137,5],[100,3],[100,5],[99,3],[99,3],[108,3],[108,1],[12,2],[141,4],[141,0],[140,1],[140,1],[138,3],[138,4],[138,5],[138,6],[146,3],[146,5],[146,5],[146,5],[146,9],[146,9],[146,4],[146,4],[146,6],[146,6],[146,1],[146,3],[147,3],[147,3],[147,5],[147,5],[147,7],[147,2],[147,3],[147,1],[94,0],[94,3],[94,5],[94,3],[94,1],[105,4],[105,3],[105,2],[105,1],[150,2],[150,3],[150,3],[150,4],[151,1],[151,2],[152,1],[152,1],[152,1],[152,3],[152,3],[154,3],[154,1],[13,3],[13,5],[13,4],[13,4],[13,6],[13,6],[14,3],[15,4],[15,2],[16,16],[16,14],[17,2],[18,6],[9,9],[9,8],[9,5],[90,4],[90,5],[49,3],[49,3],[49,3],[49,3],[49,3],[49,3],[49,3],[49,3],[49,3],[49,5],[49,3],[49,3],[49,3],[49,3],[49,3],[49,3],[49,2],[49,3],[49,3],[49,3],[49,3],[49,3],[49,3],[49,3],[49,2],[49,2],[49,1],[49,2],[49,2],[49,2],[49,2],[49,1],[49,1],[49,3],[49,1],[49,1],[49,1],[181,4],[181,4],[181,4],[181,4],[181,4],[181,5],[181,5],[181,5],[181,5],[181,5],[124,2],[124,3],[124,5],[124,3],[124,2],[124,3],[124,5],[124,3],[124,1],[93,1],[93,2],[184,1],[184,3],[184,2],[184,2],[183,4],[183,3],[24,3],[24,3],[24,3],[24,1],[24,3],[24,1],[24,3],[185,3],[185,3],[185,1],[185,1]], performAction: function anonymous(yytext, yyleng, yylineno, yy, yystate /* action[1] */, $$ /* vstack */, _$ /* lstack */) { /* this == yyval */ @@ -94,813 +92,831 @@ break; case 3: this.$ = [] break; -case 6: case 7: case 8: case 9: case 10: case 11: case 12: case 13: case 14: case 15: case 16: case 27: case 29: case 53: case 54: case 64: case 99: case 100: case 101: case 102: case 103: case 104: case 105: case 106: case 108: case 109: case 113: case 114: case 115: case 116: case 117: case 118: case 119: case 120: case 121: case 131: case 132: case 133: case 134: case 136: case 137: case 139: case 142: case 161: case 167: case 168: case 169: case 192: case 242: case 256: case 307: case 338: +case 6: case 7: case 8: case 9: case 10: case 11: case 12: case 13: case 14: case 15: case 16: case 29: case 31: case 55: case 56: case 66: case 101: case 102: case 103: case 104: case 105: case 106: case 107: case 109: case 110: case 113: case 114: case 115: case 116: case 117: case 118: case 119: case 120: case 121: case 122: case 132: case 133: case 134: case 135: case 137: case 138: case 140: case 143: case 164: case 170: case 171: case 172: case 195: case 245: case 259: case 310: case 341: case 344: this.$ = $$[$0] break; -case 17: +case 17: case 154: + this.$ = { type: 'debugger' } +break; +case 18: case 155: + this.$ = { type: 'pragma', value: $$[$0] } +break; +case 19: this.$ = { type: 'use', name: $$[$0].name } break; -case 18: +case 20: this.$ = { type: 'container', name: $$[$0].name, alias: false, statements: false } break; -case 19: +case 21: this.$ = { type: 'container', name: $$[$0-2].name, alias: $$[$0], statements: false } break; -case 20: +case 22: this.$ = { type: 'container', name: $$[$0-3].name, alias: false, statements: $$[$0-1].statements } break; -case 21: +case 23: this.$ = { type: 'container', name: $$[$0-5].name, alias: $$[$0-3], statements: $$[$0-1].statements } break; -case 22: +case 24: this.$ = { type: 'proof', statements: $$[$0-1].statements } break; -case 23: case 37: case 39: case 166: +case 25: case 39: case 41: case 169: this.$ = $$[$0]; break; -case 24: case 40: +case 26: case 42: this.$ = $$[$0-1]; break; -case 26: case 122: case 123: case 143: case 153: case 316: +case 28: case 123: case 124: case 144: case 156: case 319: this.$ = $$[$0-1] break; -case 28: +case 30: this.$ = $$[$0-1]; this.$.statements.push($$[$0]); break; -case 30: +case 32: this.$ = { ...$$[$0-1], statements: [ ...$$[$0-1].statements, $$[$0] ] } break; -case 31: case 32: +case 33: case 34: this.$ = { ...$$[$0-2], statements: [ ...$$[$0-2].statements, $$[$0-1] ] } break; -case 33: case 98: case 213: +case 35: case 100: case 216: this.$ = { statements: [$$[$0]] } break; -case 34: case 35: +case 36: case 37: this.$ = { statements: [$$[$0-1]] } break; -case 44: +case 46: this.$ = { boundary: 'first' } break; -case 45: +case 47: this.$ = { boundary: 'last' } break; -case 46: +case 48: this.$ = { boundary: 'frame' } break; -case 47: +case 49: this.$ = { type: 'code', statements: $$[$0] }; break; -case 48: +case 50: this.$ = { type: 'when', statements: $$[$0-1], expression: $$[$0-2] } break; -case 49: +case 51: this.$ = { ...$$[$0-1], type: 'when', statements: $$[$0] } break; -case 50: +case 52: this.$ = { type: 'hint', name: $$[$0-3], data: $$[$0-1] } break; -case 51: +case 53: this.$ = { type: 'hint', name: $$[$0-3], data: $$[$0-1] } break; -case 52: +case 54: this.$ = { type: 'hint', name: $$[$0-2], data: $$[$0-1] } break; -case 55: +case 57: this.$ = { type: 'scope_definition', ...$$[$0-1] }; break; -case 56: +case 58: this.$ = {private: false, funcname: $$[$0]} break; -case 57: +case 59: this.$ = {private: true, funcname: $$[$0]} break; -case 58: +case 60: this.$ = { ...$$[$0-10], type: 'function_definition', final: false, ...$$[$0-8], returns: $$[$0-4], ...$$[$0-1] } break; -case 59: +case 61: this.$ = { ...$$[$0-8], type: 'function_definition', final: false, ...$$[$0-6], returns: $$[$0-3], ...$$[$0-1] } break; -case 60: +case 62: this.$ = { ...$$[$0-6], type: 'function_definition', final: false, ...$$[$0-4], returns: false, ...$$[$0-1] } break; -case 61: +case 63: this.$ = { ...$$[$0-6], type: 'function_definition', final: 'air', ...$$[$0-4], returns: false, ...$$[$0-1] } break; -case 62: +case 64: this.$ = { ...$$[$0-6], type: 'function_definition', final: 'proof', ...$$[$0-4], returns: false, ...$$[$0-1] } break; -case 63: +case 65: this.$ = { ...$$[$0-6], type: 'function_definition', final: 'subproof', ...$$[$0-4], returns: false, ...$$[$0-1] } break; -case 65: +case 67: this.$ = $$[$0-2]; this.$.vargs = true break; -case 66: +case 68: this.$ = { args: [], varargs: false } break; -case 67: +case 69: this.$ = { args: [], varargs: false } break; -case 68: +case 70: this.$ = $$[$0-2]; this.$.args.push($$[$0]) break; -case 69: +case 71: this.$ = { args: [ $$[$0] ] } break; -case 70: +case 72: this.$ = { type: $$[$0-1].type, name: $$[$0], reference: false, dim: 0 } break; -case 71: +case 73: this.$ = { type: $$[$0-1].type, name: $$[$0], reference: true, dim: 0 } break; -case 72: +case 74: this.$ = { type: $$[$0-2].type, name: $$[$0-1], reference: false, dim: $$[$0].dim } break; -case 73: +case 75: this.$ = { type: $$[$0-2].type, name: $$[$0-1], reference: true, dim: $$[$0].dim } break; -case 74: +case 76: this.$ = { type: 'int' } break; -case 75: +case 77: this.$ = { type: 'fe' } break; -case 76: +case 78: this.$ = { type: 'expr' } break; -case 77: +case 79: this.$ = { type: 'int', const: true } break; -case 78: +case 80: this.$ = { type: 'fe', const: true } break; -case 79: +case 81: this.$ = { type: 'expr', const: true } break; -case 80: +case 82: this.$ = { type: 'witness' } break; -case 81: +case 83: this.$ = { type: 'fixed' } break; -case 82: +case 84: this.$ = { type: 'challenge' } break; -case 83: +case 85: this.$ = { type: 'string' } break; -case 84: +case 86: this.$ = { type: 'string', const: true } break; -case 85: +case 87: this.$ = { type: 'proof' } break; -case 86: +case 88: this.$ = { type: 'subproof' } break; -case 87: +case 89: this.$ = { type: 'air' } break; -case 88: +case 90: this.$ = { type: 'public' } break; -case 89: +case 91: this.$ = { type: 'publicTable' } break; -case 90: +case 92: this.$ = { type: 'function' } break; -case 91: +case 93: this.$ = {returns: [...$$[$0-2], $$[$0]]} break; -case 92: +case 94: this.$.returns = [$$[$0]] break; -case 93: +case 95: this.$ = {dim: $$[$0-2].dim + 1} break; -case 94: +case 96: this.$ = {dim: 1} break; -case 95: +case 97: this.$ = { type: $$[$0].type, dim: 0 } break; -case 96: +case 98: this.$ = { type: $$[$0-1].type, dim: $$[$0].dim } break; -case 97: case 212: +case 99: case 215: this.$ = $$[$0-2]; this.$.statements.push($$[$0]); break; -case 107: +case 108: this.$ = { type: 'code', statements: $$[$0] } break; -case 110: - this.$ = { type: 'expr', expr: $$[$0] } -break; case 111: - this.$ = { type: 'constraint', left: $$[$0-2], right: $$[$0] } + this.$ = { type: 'expr', expr: $$[$0] } break; case 112: - this.$ = {...$$[$0], type: 'delayed_function_call'} -break; -case 124: - this.$ = $$[$0-4]; this.$.data[$$[$0-2]] = $$[$0] + this.$ = { type: 'constraint', left: $$[$0-2], right: $$[$0] } break; case 125: - this.$ = $$[$0-2]; this.$.data[$$[$0]] = runtime_expr({ type: 'expr', op: 'reference', next: false, name: $$[$0] }) + this.$ = $$[$0-4]; this.$.data[$$[$0-2]] = $$[$0] break; case 126: - this.$ = { type: 'object', data: {}}; this.$.data[$$[$0-2]] = $$[$0] + this.$ = $$[$0-2]; this.$.data[$$[$0]] = ExpressionFactory.fromObject({type: 'reference', name: $$[$0] }) break; case 127: - this.$ = { type: 'object', data: {}}; this.$.data[$$[$0]] = runtime_expr({ type: 'expr', op: 'reference', next: false, name: $$[$0] }) + this.$ = { type: 'object', data: {}}; this.$.data[$$[$0-2]] = $$[$0] break; case 128: - this.$ = $$[$0-2]; this.$.data.push($$[$0]) + this.$ = {data: {}}; this.$.data[$$[$0]] = ExpressionFactory.fromObject({type: 'reference', name: $$[$0] }) break; case 129: - this.$ = { type: 'array', data: [ $$[$0] ] } + this.$ = $$[$0-2]; this.$.data.push($$[$0]) break; case 130: - this.$ = { op: 'call', function: $$[$0-3], arguments: $$[$0-1].values } + this.$ = { type: 'array', data: [ $$[$0] ] } break; -case 135: - this.$ = { op: 'delayed_call', event: $$[$0-5], scope: $$[$0-4], function: $$[$0-3], arguments: $$[$0-1].values } +case 131: + this.$ = { type: 'call', function: $$[$0-3], args: $$[$0-1] } break; -case 138: +case 136: + this.$ = { type: 'delayed_function_call', event: $$[$0-5], scope: $$[$0-4], function: $$[$0-3], args: $$[$0-1] } +break; +case 139: this.$ = {...$$[$0], ...$$[$01]} break; -case 140: +case 141: this.$ = { type: 'continue' } break; -case 141: +case 142: this.$ = { type: 'break' } break; -case 144: +case 145: this.$ = { type: 'for', init: $$[$0-6], condition: $$[$0-4], increment: $$[$0-2].statements, statements: $$[$0] } break; -case 145: +case 146: this.$ = { type: 'for_in', init: $$[$0-4], list: $$[$0-2], statements: $$[$0] } break; -case 146: +case 147: this.$ = { type: 'while', condition: $$[$0-2], statements: $$[$0] } break; -case 147: case 148: +case 148: case 149: this.$ = { type: 'do', condition: $$[$0-1], statements: $$[$0-4] } break; -case 149: - this.$ = { ...$$[$0-1], type: 'once', statements: $$[$0] } -break; case 150: - this.$ = $$[$0-4] + this.$ = { ...$$[$0-1], type: 'once', statements: $$[$0] } break; case 151: - this.$ = {type:'if', conditions: [{type: 'if', expression: $$[$0-2], statements: $$[$0] }] } + this.$ = { type: 'switch', value: $$[$0-2], cases: $$[$0].cases } break; case 152: + this.$ = {type:'if', conditions: [{type: 'if', expression: $$[$0-2], statements: $$[$0] }] } +break; +case 153: this.$ = { type:'if', conditions: [{type: 'if', expression: $$[$0-4], statements: $$[$0-2] }, {type: 'else', statements: $$[$0]}]} break; -case 154: - this.$ = $$[$0-3]; this.$.cases.push({ else: true, statements: $$[$0-1] }) +case 157: + this.$ = $$[$0-4]; this.$.cases.push({ default: true, statements: implicit_scope($$[$0-1]) }) break; -case 155: case 223: case 244: case 249: +case 158: case 226: case 252: this.$ = $$[$0-2]; this.$.values.push($$[$0]) break; -case 156: +case 159: this.$ = $$[$0-4]; this.$.values.push({ from: $$[$0-2], to: $$[$0] }) break; -case 157: +case 160: this.$ = { values: [$$[$0]] } break; -case 158: +case 161: this.$ = { values: [{ from: $$[$0-2], to: $$[$0] }] } break; -case 159: - this.$ = $$[$0-4]; this.$.cases.push({condition: $$[$0-2], statements: $$[$0] }) +case 162: + this.$ = $$[$0-4]; this.$.cases.push({condition: $$[$0-2], statements: implicit_scope($$[$0].statements) }) break; -case 160: - this.$ = {cases: [{ condition: $$[$0-2], statements: $$[$0] }]} +case 163: + this.$ = {cases: [{ condition: $$[$0-2], statements: implicit_scope($$[$0].statements) }]} break; -case 162: +case 165: this.$ = { ...$$[$0], type: 'variable_increment', pre: 1n, post: 0n } break; -case 163: +case 166: this.$ = { ...$$[$0], type: 'variable_increment', pre: -1n, post: 0n } break; -case 164: +case 167: this.$ = { ...$$[$0-1], type: 'variable_increment', pre: 0n, post: 1n } break; -case 165: +case 168: this.$ = { ...$$[$0-1], type: 'variable_increment', pre: 0n, post: -1n } break; -case 170: +case 173: this.$ = {...$$[$0], const: false} break; -case 171: +case 174: this.$ = {...$$[$0], const: true } break; -case 172: +case 175: this.$ = { type: 'variable_declaration', vtype: 'int', items: $$[$0].items } break; -case 173: +case 176: this.$ = { type: 'variable_declaration', vtype: 'fe', items: $$[$0].items } break; -case 174: +case 177: this.$ = { type: 'variable_declaration', vtype: 'expr', items: $$[$0].items } break; -case 175: +case 178: this.$ = { type: 'variable_declaration', vtype: 'string', items: $$[$0].items } break; -case 176: +case 179: this.$ = { type: 'variable_declaration', vtype: 'function', items: $$[$0].items } break; -case 177: +case 180: this.$ = { type: 'variable_declaration', vtype: 'int', items: [$$[$0-2]], init: [$$[$0]] } break; -case 178: +case 181: this.$ = { type: 'variable_declaration', vtype: 'fe', items: [$$[$0-2]], init: [$$[$0]] } break; -case 179: +case 182: this.$ = { type: 'variable_declaration', vtype: 'expr', items: [$$[$0-2]], init: [$$[$0]] } break; -case 180: +case 183: this.$ = { type: 'variable_declaration', vtype: 'string', items: [$$[$0-2]], init: [$$[$0]] } break; -case 181: +case 184: this.$ = { type: 'variable_declaration', vtype: 'function', items: [$$[$0-2]], init: [$$[$0]] } break; -case 182: +case 185: this.$ = { type: 'variable_declaration', vtype: 'container', items: [$$[$0-2]], init: [$$[$0]] } break; -case 183: +case 186: this.$ = { type: 'variable_declaration', vtype: 'int', items: $$[$0-5].items, init: $$[$0-1] } break; -case 184: +case 187: this.$ = { type: 'variable_declaration', vtype: 'fe', items: $$[$0-5].items, init: $$[$0-1] } break; -case 185: +case 188: this.$ = { type: 'variable_declaration', vtype: 'expr', items: $$[$0-5].items, init: $$[$0-1] } break; -case 186: +case 189: this.$ = { type: 'variable_declaration', vtype: 'string', items: $$[$0-5].items, init: $$[$0-1] } break; -case 187: +case 190: this.$ = { type: 'variable_declaration', vtype: 'container', items: $$[$0-5].items, init: $$[$0-1] } break; -case 188: +case 191: this.$ = { dim: 1, lengths: [null]} break; -case 189: +case 192: this.$ = { dim: 1, lengths: [$$[$0-1]]} break; -case 190: +case 193: this.$ = $$[$0-2]; ++this.$.dim; this.$.lengths.push(null) break; -case 191: +case 194: this.$ = $$[$0-3]; ++this.$.dim; this.$.lengths.push($$[$0-1]) break; -case 193: case 340: +case 196: case 343: this.$ = { ...$$[$0-1], ...$$[$0] } break; -case 194: +case 197: this.$ = $$[$0-2]; this.$.items.push({...$$[$0], _d_:1}); break; -case 195: +case 198: this.$ = {items: [{...$$[$0], _d_:2}]} break; -case 196: +case 199: this.$ = { type: 'return', value: null } break; -case 197: +case 200: this.$ = { type: 'return', value: $$[$0] } break; -case 198: +case 201: this.$ = { type: 'return', values: $$[$0-1] } break; -case 199: +case 202: this.$ = { type: 'assign' } break; -case 200: +case 203: this.$ = { type: 'increment' } break; -case 201: +case 204: this.$ = { type: 'substract' } break; -case 202: +case 205: this.$ = { type: 'product' } break; -case 203: +case 206: this.$ = $$[$0-2]; this.$.names.push($$[$0-2]) break; -case 204: +case 207: this.$ = $$[$0-1]; this.$.names.push({ type: 'ignore' }) break; -case 205: +case 208: this.$ = { names: [$$[$0]] } break; -case 206: +case 209: this.$ = $$[$0-2] break; -case 207: +case 210: this.$ = $$[$0-4]; this.$.names.push({ type: 'ignore' }) break; -case 208: +case 211: this.$ = {type: 'assign', name: $$[$0-2], value: $$[$0] } break; -case 209: +case 212: this.$ = {type: 'assign', name: $$[$0-4], value: $$[$0-2] } break; -case 210: +case 213: this.$ = { type: 'assign', assign: $$[$0-1].type, name: $$[$0-2], value: $$[$0] } break; -case 211: +case 214: this.$ = { type: 'assign', name: $$[$0-2], value: $$[$0] } break; -case 214: +case 217: this.$ = { type: 'include', file: $$[$0] } break; -case 215: +case 218: this.$ = { stage: $$[$0-1] } break; -case 216: +case 219: this.$ = { stage: DEFAULT_STAGE } break; -case 217: +case 220: this.$ = { type: 'string', value: $$[$0] } break; -case 218: +case 221: this.$ = { type: 'string', template: true, value: $$[$0] } break; -case 219: +case 222: this.$ = {type: 'sequence', values: $$[$0-1].values} break; -case 220: +case 223: this.$ = {type: 'sequence', values: [{type: 'padding_seq', value: $$[$0-2]}] } break; -case 221: +case 224: this.$ = {type: 'sequence', values: [{type: 'repeat_seq', value: $$[$0-3], times: $$[$0]}]} break; -case 222: +case 225: this.$ = {type: 'sequence', values: [{type: 'padding_seq', value: {type: 'repeat_seq', value: $$[$0-4], times: $$[$0-1]}}]} break; -case 224: +case 227: this.$ = $$[$0-4]; this.$.values.push({type: 'repeat_seq', value: $$[$0-2], times: $$[$0]}) break; -case 225: +case 228: this.$ = $$[$0-4]; this.$.values.push({type: 'arith_seq', t1: this.$.values.pop(), t2: $$[$0-2], tn: $$[$0]}) break; -case 226: +case 229: this.$ = $$[$0-4]; this.$.values.push({type: 'geom_seq', t1: this.$.values.pop(), t2: $$[$0-2], tn: $$[$0]}) break; -case 227: +case 230: this.$ = $$[$0-8]; this.$.values.push({type: 'arith_seq', t1: this.$.values.pop(), t2: {type: 'repeat_seq', value: $$[$0-6], times: $$[$0-4]}, tn: {type: 'repeat_seq', value: $$[$0-2], times: $$[$0]}}) break; -case 228: +case 231: this.$ = $$[$0-8]; this.$.values.push({type: 'geom_seq', t1: this.$.values.pop(), t2: {type: 'repeat_seq', value: $$[$0-6], times: $$[$0-4]}, tn: {type: 'repeat_seq', value: $$[$0-2], times: $$[$0]}}) break; -case 229: +case 232: this.$ = $$[$0-3]; this.$.values.push({type: 'arith_seq', t1: this.$.values.pop(), t2: $$[$0-1], tn: false}) break; -case 230: +case 233: this.$ = $$[$0-3]; this.$.values.push({type: 'geom_seq', t1: this.$.values.pop(), t2: $$[$0-1], tn: false}) break; -case 231: +case 234: this.$ = $$[$0-5]; this.$.values.push({type: 'arith_seq', t1: this.$.values.pop(), t2: {type: 'repeat_seq', value: $$[$0-3], times: $$[$0-1]}, tn: false}) break; -case 232: +case 235: this.$ = $$[$0-5]; this.$.values.push({type: 'geom_seq', t1: this.$.values.pop(), t2: {type: 'repeat_seq', value: $$[$0-3], times: $$[$0-1]}, tn: false}) break; -case 233: +case 236: this.$ = { type: 'seq_list', values: [$$[$0]] } break; -case 234: +case 237: this.$ = { type: 'seq_list', values: [{type: 'repeat_seq', value: $$[$0-2], times: $$[$0]}] } break; -case 235: +case 238: this.$ = {type: 'repeat_seq', value: $$[$0-2], times: $$[$0]} break; -case 236: +case 239: this.$ = {type: 'range_seq', from: $$[$0-2], to: $$[$0]} break; -case 237: +case 240: this.$ = {type: 'range_seq', from: $$[$0-4], to: $$[$0-2], times: $$[$0]} break; -case 238: +case 241: this.$ = {type: 'range_seq', from: $$[$0-4], to: $$[$0], times: $$[$0-2]} break; -case 239: +case 242: this.$ = {type: 'range_seq', from: $$[$0-6], to: $$[$0-2], times: $$[$0-4], toTimes: $$[$0]} break; -case 240: +case 243: this.$ = {type: 'padding_seq', value: $$[$0-1]} break; -case 241: +case 244: this.$ = {type: 'seq_list', values: [$$[$0-1]]} break; -case 243: - this.$ = {values: []} -break; -case 245: - this.$ = $$[$0-4]; this.$.values.push({ type: 'expression_list', values: $$[$0-1].values }) -break; case 246: - this.$ = { type: 'expression_list', values: $$[$0-1].values } + this.$ = ExpressionFactory.fromObject({ type: 'expression_list', values: [], __debug: 0 }); break; case 247: - this.$ = { type: 'expression_list', values: [$$[$0]] } + this.$ = $$[$0-2]; this.$.pushItem(ExpressionFactory.fromObject($$[$0])); break; case 248: - this.$ = $$[$0-3]; this.$.values.push({ type: 'append', value: $$[$0] }) + this.$ = $$[$0-4]; this.$.pushItem(ExpressionFactory.fromObject($$[$0-1])); +break; +case 249: + this.$ = ExpressionFactory.fromObject({ type: 'expression_list', values: + [ExpressionFactory.fromObject($$[$0-1])], __debug: 4}); break; case 250: - this.$ = { type: 'expression_list', values: [{ type: 'append', value: $$[$0]}] } + this.$ = ExpressionFactory.fromObject({ type: 'expression_list', values: [$$[$0]], __debug: 3 }); break; case 251: + this.$ = $$[$0-3]; this.$.values.push($$[$0].insert('spread')) +break; +case 253: + this.$ = { type: 'expression_list', values: [$$[$0].insert('spread')] } +break; +case 254: this.$ = { type: 'expression_list', values: [$$[$0]] } break; -case 252: +case 255: this.$ = { dim: 1, lengths: [null] } break; -case 253: +case 256: this.$ = { dim: 1, lengths: [$$[$0-1]] } break; -case 254: +case 257: this.$ = { ...$$[$0-2], dim: $$[$0-2].dim + 1, lengths: [...$$[$0-2].lengths, null] } break; -case 255: +case 258: this.$ = { ...$$[$0-3], dim: $$[$0-3].dim + 1, lengths: [...$$[$0-3].lengths, $$[$0-1]] } break; -case 257: +case 260: this.$ = {...$$[$0-1], ...$$[$0]} break; -case 258: case 346: case 348: case 352: case 353: +case 261: case 353: case 355: case 359: case 360: this.$ = { name: $$[$0] } break; -case 259: - this.$ = { name: $$[$0], reference: true } -break; -case 260: - this.$ = { name: $$[$0], template: true } -break; -case 261: - this.$ = { name: 'air.'+$$[$0] } -break; case 262: - this.$ = { name: 'air.'+$$[$0], template: true } + this.$ = { name: $$[$0], reference: true } break; case 263: - this.$ = { items: [ ...$$[$0-2].items, $$[$0] ] } + this.$ = { name: $$[$0], template: true } break; case 264: - this.$ = { items: [$$[$0]] } + this.$ = { name: 'air.'+$$[$0] } break; case 265: - this.$ = { type: 'col_declaration', items: $$[$0].items, stage: $$[$0-1].stage }; + this.$ = { name: 'air.'+$$[$0], template: true } break; case 266: - this.$ = { type: 'col_declaration', items: [$$[$0-2]], stage: $$[$0-3].stage, init: $$[$0] } + this.$ = { items: [ ...$$[$0-2].items, $$[$0] ] } break; case 267: - this.$ = { type: 'witness_col_declaration', items: $$[$0].items, stage: $$[$0-1].stage } + this.$ = { items: [$$[$0]] } break; case 268: - this.$ = { type: 'fixed_col_declaration', items: $$[$0].items, stage: $$[$0-1].stage } + this.$ = { type: 'col_declaration', items: $$[$0].items, stage: $$[$0-1].stage }; break; case 269: - this.$ = { type: 'fixed_col_declaration', items: [$$[$0-2]], stage: $$[$0-3].stage, init: $$[$0] } + this.$ = { type: 'col_declaration', items: [$$[$0-2]], stage: $$[$0-3].stage, init: $$[$0] } break; case 270: - this.$ = { type: 'fixed_col_declaration', items: [$$[$0-2]], stage: $$[$0-3].stage, sequence: $$[$0] } + this.$ = { type: 'witness_col_declaration', items: $$[$0].items, stage: $$[$0-1].stage } break; case 271: - this.$ = { type: 'challenge_declaration', items: $$[$0].items, stage: $$[$0-1].stage } + this.$ = { type: 'fixed_col_declaration', items: $$[$0].items, stage: $$[$0-1].stage } break; case 272: - this.$ = { type: 'public_declaration', items: [$$[$0-2]], init: $$[$0] } + this.$ = { type: 'fixed_col_declaration', items: [$$[$0-2]], stage: $$[$0-3].stage, init: $$[$0] } break; case 273: - this.$ = { type: 'public_declaration', items: $$[$0].items } + this.$ = { type: 'fixed_col_declaration', items: [$$[$0-2]], stage: $$[$0-3].stage, sequence: $$[$0] } break; case 274: - this.$ = { type: 'public_table_declaration', aggregateType: $$[$0-12], aggregateFunction: $$[$0-10], name: $$[$0-6], args: $$[$0-8], cols: $$[$0-4], rows: $$[$0-1]} + this.$ = { type: 'challenge_declaration', items: $$[$0].items, stage: $$[$0-1].stage } break; case 275: - this.$ = { type: 'public_table_declaration', aggregateType: $$[$0-10], aggregateFunction: $$[$0-8], name: $$[$0-6], args: [], cols: $$[$0-4], rows: $$[$0-1]} + this.$ = { type: 'public_declaration', items: [$$[$0-2]], init: $$[$0] } break; case 276: - this.$ = { type: 'proof_value_declaration', items: $$[$0].items } + this.$ = { type: 'public_declaration', items: $$[$0].items } break; case 277: - this.$ = { type: 'subproof_value_declaration', aggregateType: $$[$0-2], items: $$[$0].items } + this.$ = { type: 'public_table_declaration', aggregateType: $$[$0-12], aggregateFunction: $$[$0-10], name: $$[$0-6], args: $$[$0-8], cols: $$[$0-4], rows: $$[$0-1]} break; case 278: - this.$ = { type: 'subproof_definition', aggregate: true, name: $$[$0-6], rows: $$[$0-4], statements: $$[$0-1].statements } + this.$ = { type: 'public_table_declaration', aggregateType: $$[$0-10], aggregateFunction: $$[$0-8], name: $$[$0-6], args: [], cols: $$[$0-4], rows: $$[$0-1]} break; case 279: - this.$ = { type: 'subproof_definition', aggregate: false, name: $$[$0-6], rows: $$[$0-4], statements: $$[$0-1].statements } + this.$ = { type: 'proof_value_declaration', items: $$[$0].items } break; case 280: - this.$ = { type: 'subproof_block', aggregate: false, name: $$[$0-3], statements: $$[$0-1].statements } + this.$ = { type: 'subproof_value_declaration', aggregateType: $$[$0-2], items: $$[$0].items } break; case 281: - this.$ = { type: 'constant_definition', name: $$[$0-2], value: $$[$0] } + this.$ = { type: 'subproof_definition', aggregate: true, name: $$[$0-6], rows: $$[$0-4], statements: $$[$0-1].statements } break; case 282: - this.$ = { type: "constant_definition", name: $$[$0-3], sequence: $$[$0], ...$$[$0-2] } + this.$ = { type: 'subproof_definition', aggregate: false, name: $$[$0-6], rows: $$[$0-4], statements: $$[$0-1].statements } break; case 283: - this.$ = insert_expr($$[$0-2], 'eq', $$[$0]) + this.$ = { type: 'subproof_block', aggregate: false, name: $$[$0-3], statements: $$[$0-1].statements } break; case 284: - this.$ = insert_expr($$[$0-2], 'ne', $$[$0]) + this.$ = { type: 'constant_definition', name: $$[$0-2], value: $$[$0] } break; case 285: - this.$ = insert_expr($$[$0-2], 'lt', $$[$0]) + this.$ = { type: "constant_definition", name: $$[$0-3], sequence: $$[$0], ...$$[$0-2] } break; case 286: - this.$ = insert_expr($$[$0-2], 'gt', $$[$0]) + this.$ = $$[$0-2].insert('eq', ExpressionFactory.fromObject($$[$0])) break; case 287: - this.$ = insert_expr($$[$0-2], 'le', $$[$0]) + this.$ = $$[$0-2].insert('ne', ExpressionFactory.fromObject($$[$0])) break; case 288: - this.$ = insert_expr($$[$0-2], 'ge', $$[$0]) + this.$ = $$[$0-2].insert('lt', ExpressionFactory.fromObject($$[$0])) break; case 289: - this.$ = insert_expr($$[$0-2], 'in', $$[$0]) + this.$ = $$[$0-2].insert('gt', ExpressionFactory.fromObject($$[$0])) break; case 290: - this.$ = insert_expr($$[$0-2], 'is', runtime_expr({op: 'type', vtype: $$[$0].type, dim: $$[$0].dim})) + this.$ = $$[$0-2].insert('le', ExpressionFactory.fromObject($$[$0])) break; case 291: - this.$ = insert_expr($$[$0-2], 'and', $$[$0]) + this.$ = $$[$0-2].insert('ge', ExpressionFactory.fromObject($$[$0])) break; case 292: - this.$ = insert_expr($$[$0-4], 'if', $$[$0-2], $$[$0]) + this.$ = $$[$0-2].insert('in', ExpressionFactory.fromObject($$[$0])) break; case 293: - this.$ = insert_expr($$[$0-2], 'band', $$[$0]) + this.$ = $$[$0-2].insert('is', ExpressionFactory.fromObject({type: 'istype', vtype: $$[$0].type, dim: $$[$0].dim})); break; case 294: - this.$ = insert_expr($$[$0-2], 'bor', $$[$0]) + this.$ = $$[$0-2].insert('and', ExpressionFactory.fromObject($$[$0])) break; case 295: - this.$ = insert_expr($$[$0-2], 'bxor', $$[$0]) + this.$ = $$[$0-4].insert('if', [ExpressionFactory.fromObject($$[$0-2]), ExpressionFactory.fromObject($$[$0])]) break; case 296: - this.$ = insert_expr($$[$0-2], 'or', $$[$0]) + this.$ = $$[$0-2].insert('band', ExpressionFactory.fromObject($$[$0])) break; case 297: - this.$ = insert_expr($$[$0-2], 'shl', $$[$0]) + this.$ = $$[$0-2].insert('bor', ExpressionFactory.fromObject($$[$0])) break; case 298: - this.$ = insert_expr($$[$0-2], 'shr', $$[$0]) + this.$ = $$[$0-2].insert('bxor', ExpressionFactory.fromObject($$[$0])) break; case 299: - this.$ = insert_expr($$[$0], 'not') + this.$ = $$[$0-2].insert('or', ExpressionFactory.fromObject($$[$0])) break; case 300: - this.$ = insert_expr($$[$0-2], 'add', $$[$0]) + this.$ = $$[$0-2].insert('shl', ExpressionFactory.fromObject($$[$0])) break; case 301: - this.$ = insert_expr($$[$0-2], 'sub', $$[$0]) + this.$ = $$[$0-2].insert('shr', ExpressionFactory.fromObject($$[$0])) break; case 302: - this.$ = insert_expr($$[$0-2], 'mul', $$[$0]) + this.$ = $$[$0].insert('not') break; case 303: - this.$ = insert_expr($$[$0-2], 'mod', $$[$0]) + this.$ = $$[$0-2].insert('add', ExpressionFactory.fromObject($$[$0])) break; case 304: - this.$ = insert_expr($$[$0-2], 'div', $$[$0]) + this.$ = $$[$0-2].insert('sub', ExpressionFactory.fromObject($$[$0])) break; case 305: - this.$ = insert_expr($$[$0-2], 'intdiv', $$[$0]) + this.$ = $$[$0-2].insert('mul', ExpressionFactory.fromObject($$[$0])) break; case 306: - this.$ = insert_expr($$[$0-2], 'pow', $$[$0]) + this.$ = $$[$0-2].insert('mod', ExpressionFactory.fromObject($$[$0])) +break; +case 307: + this.$ = $$[$0-2].insert('div', ExpressionFactory.fromObject($$[$0])) break; case 308: - this.$ = insert_expr($$[$0], 'neg') + this.$ = $$[$0-2].insert('intdiv', ExpressionFactory.fromObject($$[$0])) break; case 309: - this.$ = runtime_expr({ type: 'expr', op: 'reference', next: false, ...$$[$0] }) -break; -case 310: - this.$ = runtime_expr({ type: 'expr', op: 'reference', next: false, ...$$[$0], inc: 'pre'}) + this.$ = $$[$0-2].insert('pow', ExpressionFactory.fromObject($$[$0])) break; case 311: - this.$ = runtime_expr({ type: 'expr', op: 'reference', next: false, ...$$[$0], dec: 'pre'}) + this.$ = $$[$0].insert('neg') break; case 312: - this.$ = runtime_expr({ type: 'expr', op: 'reference', next: false, ...$$[$0-1], inc: 'post'}) + this.$ = ExpressionFactory.fromObject({ type: 'reference', ...$$[$0] }) break; case 313: - this.$ = runtime_expr({ type: 'expr', op: 'reference', next: false, ...$$[$0-1], dec: 'post'}) + this.$ = ExpressionFactory.fromObject({ type: 'reference', ...$$[$0], inc: 'pre'}) break; case 314: - this.$ = new Expression(); this.$.setValue(BigInt($$[$0])) + this.$ = ExpressionFactory.fromObject({ type: 'reference', ...$$[$0], dec: 'pre'}) break; case 315: - this.$ = runtime_expr({...$$[$0], op: 'string'}) + this.$ = ExpressionFactory.fromObject({ type: 'reference', ...$$[$0-1], inc: 'post'}) +break; +case 316: + this.$ = ExpressionFactory.fromObject({ type: 'reference', ...$$[$0-1], dec: 'post'}) break; -case 317: case 319: - this.$ = runtime_expr({...$$[$0]}) +case 317: + this.$ = ExpressionFactory.fromObject({ type: 'number', value: BigInt($$[$0])}) break; case 318: - this.$ = runtime_expr({position: $$[$0], op: 'positional_param'}) + this.$ = ExpressionFactory.fromObject({...$$[$0], type: 'string'}) break; -case 320: - this.$ = { op: 'cast', cast: 'int', value: $$[$0-1]} +case 320: case 322: + this.$ = ExpressionFactory.fromObject({...$$[$0]}) break; case 321: - this.$ = { op: 'cast', cast: 'fe', value: $$[$0-1] } -break; -case 322: - this.$ = { op: 'cast', cast: 'expr', value: $$[$0-1] } + this.$ = ExpressionFactory.fromObject({position: $$[$0], type: 'positional_param'}) break; case 323: - this.$ = { op: 'cast', cast: 'col', value: $$[$0-1] } + this.$ = { type: 'cast', cast: 'int', value: $$[$0-1]} break; case 324: - this.$ = { op: 'cast', cast: 'string', value: $$[$0-1] } + this.$ = { type: 'cast', cast: 'fe', value: $$[$0-1] } break; case 325: - this.$ = { ...$$[$0-3], op: 'cast', cast: 'int', value: $$[$0-1] } + this.$ = { type: 'cast', cast: 'expr', value: $$[$0-1] } break; case 326: - this.$ = { ...$$[$0-3], op: 'cast', cast: 'fe', value: $$[$0-1] } + this.$ = { type: 'cast', cast: 'col', value: $$[$0-1] } break; case 327: - this.$ = { ...$$[$0-3], op: 'cast', cast: 'expr', value: $$[$0-1] } + this.$ = { type: 'cast', cast: 'string', value: $$[$0-1] } break; case 328: - this.$ = { ...$$[$0-3], op: 'cast', cast: 'col', value: $$[$0-1] } + this.$ = { ...$$[$0-3], type: 'cast', cast: 'int', value: $$[$0-1] } break; case 329: - this.$ = { ...$$[$0-3], op: 'cast', cast: 'string', value: $$[$0-1] } + this.$ = { ...$$[$0-3], type: 'cast', cast: 'fe', value: $$[$0-1] } break; case 330: - this.$ = { ...$$[$0-1], next:1 } + this.$ = { ...$$[$0-3], type: 'cast', cast: 'expr', value: $$[$0-1] } break; case 331: - this.$ = { ...$$[$0-2], next: Number($$[$0]) } + this.$ = { ...$$[$0-3], type: 'cast', cast: 'col', value: $$[$0-1] } break; case 332: - this.$ = { ...$$[$0-4], next:$$[$0-1] } + this.$ = { ...$$[$0-3], type: 'cast', cast: 'string', value: $$[$0-1] } break; case 333: - this.$ = { ...$$[$0-2], next: runtime_expr({position: $$[$0], op: 'positional_param'}) } + this.$ = { ...$$[$0-1], rowOffset: ExpressionFactory.fromObject({type: 'row_offset', value: 1, current: $$[$0-1] }) } break; case 334: - this.$ = { ...$$[$0], prior:1 } + this.$ = { ...$$[$0-2], rowOffset: ExpressionFactory.fromObject({type: 'row_offset', value: Number($$[$0]), current: $$[$0-2] }) } break; case 335: - this.$ = { ...$$[$0], prior: Number($$[$0-2]) } + this.$ = { ...$$[$0-4], rowOffset: ExpressionFactory.fromObject({type: 'row_offset', value: $$[$0-1], current: $$[$0-4] }) } break; case 336: - this.$ = { ...$$[$0], prior:$$[$0-3] } + this.$ = { ...$$[$0-2], rowOffset: ExpressionFactory.fromObject({type: 'row_offset', current: $$[$0-2], + value: ExpressionFactory.fromObject({position: $$[$0], type: 'positional_param'})}) } break; case 337: - this.$ = { ...$$[$0], prior:runtime_expr({position: $$[$0-2], op: 'positional_param'}) } + this.$ = { ...$$[$0], rowOffset: ExpressionFactory.fromObject({type: 'row_offset', value: 1, prior: true, current: $$[$0] }) } +break; +case 338: + this.$ = { ...$$[$0], rowOffset: ExpressionFactory.fromObject({type: 'row_offset', value: Number($$[$0-2]), prior: true, current: $$[$0] }) } break; case 339: + this.$ = { ...$$[$0], rowOffset: ExpressionFactory.fromObject({type: 'row_offset', value: $$[$0-3], prior: true, current: $$[$0] }) } +break; +case 340: + this.$ = { ...$$[$0], rowOffset: ExpressionFactory.fromObject({type: 'row_offset', current: $$[$0], prior: true, + value: ExpressionFactory.fromObject({position: $$[$0-2], type: 'positional_param'})}) } +break; +case 342: this.$ = { ...$$[$0], dim: 0 } break; -case 341: +case 345: + this.$ = ExpressionFactory.fromObject({type: 'range_index', from: $$[$0-2], to: $$[$0]}); +break; +case 346: + this.$ = ExpressionFactory.fromObject({type: 'range_index', from: $$[$0-1]}); +break; +case 347: + this.$ = ExpressionFactory.fromObject({type: 'range_index', to: $$[$0]}); +break; +case 348: this.$ = { dim: $$[$0-3].dim + 1, indexes: [...$$[$0-3].indexes, $$[$0-1]] } break; -case 342: +case 349: this.$ = { dim: 1, indexes: [$$[$0-1]]} break; -case 343: +case 350: this.$ = { name: 'air.' + $$[$0].name } break; -case 344: +case 351: this.$ = { name: 'subproof.' + $$[$0].name } break; -case 345: +case 352: this.$ = { name: 'proof.' + $$[$0].name } break; -case 347: case 349: +case 354: case 356: this.$ = { name: $$[$0-2] + '.' + $$[$0].name } break; -case 350: case 351: +case 357: case 358: this.$ = { name: $$[$0-2].name + '.' + $$[$0] } break; } }, -table: [o($V0,[2,3],{3:1,4:2}),{1:[3]},o($V0,[2,5],{5:3}),{6:[1,4],7:5,8:[1,6],9:7,10:8,11:9,12:10,13:11,14:12,15:13,16:14,17:15,18:16,19:17,31:[1,19],54:20,55:$V1,56:$V2,61:$V3,62:[1,18],74:$V4,77:$V5,79:$V6,80:$V7,82:$V8,83:$V9,137:$Va,154:$Vb},{1:[2,1]},o($V0,[2,2]),o($V0,[2,4]),o($V0,[2,6]),o($V0,[2,7]),o($V0,[2,8]),o($V0,[2,9]),o($V0,[2,10]),o($V0,[2,11]),o($V0,[2,12]),o($V0,[2,13]),o($V0,[2,14]),o($V0,[2,15]),o($V0,[2,16]),{26:[1,33],153:[1,32]},{28:[1,34]},{46:[1,35]},{31:[1,37],54:36,55:$V1,56:$V2,62:[1,38]},{138:39,142:$Vc,143:$Vd},o($Ve,$Vf,{139:42,75:$Vg,76:$Vh,140:$Vi}),o($Ve,$Vf,{139:46,140:$Vi}),{26:$Vj,68:$Vk,95:$Vl,143:$Vm,149:53,150:47,152:48},{153:[1,54]},{26:$Vj,68:$Vk,95:$Vl,143:$Vm,149:53,150:56,152:55},{153:[1,57]},{26:[1,58]},{26:[1,59]},{55:[1,60]},{26:[1,61]},{28:[1,63],46:[1,62]},{8:$Vn,11:86,12:75,13:71,14:72,15:76,16:77,17:78,18:79,19:80,20:82,21:$Vo,22:130,23:81,24:$Vp,26:$Vq,27:87,28:$Vr,30:$Vs,31:$Vt,32:64,34:68,35:69,36:67,37:65,38:66,44:83,45:$Vu,46:$Vv,47:73,49:$Vw,51:$Vx,54:20,55:$Vy,56:$V2,61:$V3,62:$Vz,68:$VA,70:$VB,71:$VC,72:$VD,73:$VE,74:$VF,77:$V5,78:$VG,79:$V6,80:$V7,82:$V8,83:$V9,85:90,86:70,88:74,90:106,91:122,95:$VH,96:$VI,97:91,98:92,99:93,100:$VJ,101:$VK,104:$VL,108:$VM,109:$VN,110:$VO,111:$VP,113:$VQ,121:$VR,122:100,123:$VS,124:118,129:$VT,135:120,137:$Va,138:104,141:$VU,142:$Vc,143:$Vd,154:$Vb,170:$VV,171:$VW,172:$VX,178:$VY,179:108,180:$VZ},{48:$V_,55:$V$,57:136,63:137,65:$V01,66:139,67:140,70:$V11,71:$V21,72:$V31,73:$V41,74:$V51,77:$V61,78:$V71,79:$V81,80:$V91,81:$Va1,82:$Vb1,83:$Vc1},{46:[1,154]},{54:155,55:$V1,56:$V2},{54:156,55:$V1,56:$V2},o($Vd1,[2,214]),o($Ve1,[2,217]),o($Ve1,[2,218]),{26:$Vj,68:$Vk,95:$Vl,143:$Vm,149:53,150:158,152:157},o($Ve,$Vf,{139:159,140:$Vi}),o($Ve,$Vf,{139:160,140:$Vi}),{46:[1,161]},{26:$Vj,68:$Vk,95:$Vl,143:$Vm,149:53,150:56,152:162},o([6,8,30,31,55,56,61,62,64,74,77,79,80,82,83,108,137,154],$Vf1,{148:164,51:$Vg1,127:[1,163]}),o($Vd1,[2,273],{64:$Vh1}),o($Vi1,[2,258]),o($Vi1,[2,259]),o($Vi1,[2,260]),{151:[1,167]},o($Vj1,[2,264]),{46:[1,168]},o($Vd1,[2,276],{64:$Vh1}),o($Vj1,$Vf1,{148:164,51:$Vg1}),{46:[1,169]},{51:$Vg1,127:[1,170],148:171},{46:$Vk1},{26:[1,172]},{46:[1,173]},{22:130,26:$Vq,31:$Vt,46:$Vv,47:176,62:$Vz,65:$Vl1,68:$VA,70:$Vm1,71:$Vn1,72:$Vo1,74:$Vp1,78:$Vq1,90:106,91:122,95:$VH,103:174,121:$VR,122:177,123:$VS,138:104,141:$VU,142:$Vc,143:$Vd,170:$VV,171:$VW,172:$VX,178:$VY,179:108,180:$VZ},{8:$Vn,11:86,12:75,13:71,14:72,15:76,16:77,17:78,18:79,19:80,20:82,21:$Vo,22:130,23:81,24:$Vp,26:$Vq,27:87,28:$Vr,30:$Vs,31:$Vt,32:183,34:68,35:69,36:67,37:65,38:66,44:83,45:$Vu,46:$Vv,47:73,49:$Vw,51:$Vx,54:20,55:$Vy,56:$V2,61:$V3,62:$Vz,68:$VA,70:$VB,71:$VC,72:$VD,73:$VE,74:$VF,77:$V5,78:$VG,79:$V6,80:$V7,82:$V8,83:$V9,85:90,86:70,88:74,90:106,91:122,95:$VH,96:$VI,97:91,98:92,99:93,100:$VJ,101:$VK,104:$VL,108:$VM,109:$VN,110:$VO,111:$VP,113:$VQ,121:$VR,122:100,123:$VS,124:118,129:$VT,135:120,137:$Va,138:104,141:$VU,142:$Vc,143:$Vd,154:$Vb,170:$VV,171:$VW,172:$VX,178:$VY,179:108,180:$VZ},{30:[1,184]},{30:[2,37]},{11:86,12:75,13:71,14:72,15:76,16:77,17:78,18:79,19:80,20:82,21:$Vo,22:130,23:81,24:$Vp,26:$Vq,27:87,28:$Vr,30:[2,27],31:$Vt,34:186,36:185,44:83,45:$Vu,46:$Vv,47:73,49:$Vw,51:$Vx,54:20,55:$Vy,56:$V2,61:$V3,62:$Vz,68:$VA,70:$VB,71:$VC,72:$VD,73:$VE,74:$VF,77:$V5,78:$VG,79:$V6,80:$V7,82:$V8,83:$V9,85:90,86:70,88:74,90:106,91:122,95:$VH,96:$VI,97:91,98:92,99:93,100:$VJ,101:$VK,104:$VL,108:$VM,109:$VN,110:$VO,111:$VP,113:$VQ,121:$VR,122:100,123:$VS,124:118,129:$VT,135:120,137:$Va,138:104,141:$VU,142:$Vc,143:$Vd,154:$Vb,170:$VV,171:$VW,172:$VX,178:$VY,179:108,180:$VZ},{8:$Vn,30:[2,29],35:187},o($Vr1,[2,33],{35:188,8:$Vn}),o($Vr1,[2,36],{8:$Vs1}),o($Vt1,[2,107]),o($Vt1,[2,108]),o($Vt1,[2,109]),o($Vt1,[2,110],{87:[1,190],107:$Vu1,155:$Vv1,156:$Vw1,157:$Vx1,158:$Vy1,159:$Vz1,160:$VA1,161:$VB1,162:$VC1,163:$VD1,164:$VE1,165:$VF1,166:$VG1,167:$VH1,168:$VI1,169:$VJ1,171:$VK1,172:$VL1,173:$VM1,174:$VN1,175:$VO1,176:$VP1,177:$VQ1}),o($Vt1,[2,112]),o($Vt1,[2,113]),o($Vt1,[2,114]),o($Vt1,[2,115]),o($Vt1,[2,116]),o($Vt1,[2,117]),o($Vt1,[2,118]),o($Vt1,[2,119]),o($Vt1,[2,120]),o($VR1,[2,47]),{40:215,41:[1,216],42:[1,217],43:[1,218],46:[1,214]},{22:130,26:$Vq,28:[1,219],31:$Vt,46:$Vv,47:221,51:[1,220],62:$Vz,68:$VA,70:$Vm1,71:$Vn1,72:$Vo1,74:$Vp1,78:$Vq1,90:106,91:122,95:$VH,121:$VR,122:177,123:$VS,138:104,141:$VU,142:$Vc,143:$Vd,170:$VV,171:$VW,172:$VX,178:$VY,179:108,180:$VZ},o($VR1,[2,53]),o($VR1,[2,54]),{8:$Vn,11:86,12:75,13:71,14:72,15:76,16:77,17:78,18:79,19:80,20:82,21:$Vo,22:130,23:81,24:$Vp,26:$Vq,27:87,28:$Vr,30:$Vs,31:$Vt,32:222,34:68,35:69,36:67,37:65,38:66,44:83,45:$Vu,46:$Vv,47:73,49:$Vw,51:$Vx,54:20,55:$Vy,56:$V2,61:$V3,62:$Vz,68:$VA,70:$VB,71:$VC,72:$VD,73:$VE,74:$VF,77:$V5,78:$VG,79:$V6,80:$V7,82:$V8,83:$V9,85:90,86:70,88:74,90:106,91:122,95:$VH,96:$VI,97:91,98:92,99:93,100:$VJ,101:$VK,104:$VL,108:$VM,109:$VN,110:$VO,111:$VP,113:$VQ,121:$VR,122:100,123:$VS,124:118,129:$VT,135:120,137:$Va,138:104,141:$VU,142:$Vc,143:$Vd,154:$Vb,170:$VV,171:$VW,172:$VX,178:$VY,179:108,180:$VZ},o($VR1,[2,43]),o($Vt1,[2,136]),o($Vt1,[2,137]),o($Vt1,[2,138]),o($Vt1,[2,139]),o($Vt1,[2,140]),o($Vt1,[2,141]),o($Ve,$Vf,{139:42,69:224,46:$VS1,51:$VT1,75:$Vg,76:$Vh,140:$Vi}),{22:130,26:$Vq,31:$Vt,46:$Vv,47:226,62:$Vz,68:$VA,70:$Vm1,71:$Vn1,72:$Vo1,74:$Vp1,78:$Vq1,90:106,91:122,95:$VH,121:$VR,122:177,123:$VS,138:104,141:$VU,142:$Vc,143:$Vd,170:$VV,171:$VW,172:$VX,178:$VY,179:108,180:$VZ},{22:130,26:$Vq,31:$Vt,46:$Vv,47:227,62:$Vz,68:$VA,70:$Vm1,71:$Vn1,72:$Vo1,74:$Vp1,78:$Vq1,90:106,91:122,95:$VH,121:$VR,122:177,123:$VS,138:104,141:$VU,142:$Vc,143:$Vd,170:$VV,171:$VW,172:$VX,178:$VY,179:108,180:$VZ},{22:130,26:$Vq,31:$Vt,46:$Vv,47:228,62:$Vz,68:$VA,70:$Vm1,71:$Vn1,72:$Vo1,74:$Vp1,78:$Vq1,90:106,91:122,95:$VH,121:$VR,122:177,123:$VS,138:104,141:$VU,142:$Vc,143:$Vd,170:$VV,171:$VW,172:$VX,178:$VY,179:108,180:$VZ},o([8,30,87,107,108,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,171,172,173,174,175,176,177],$VU1,{130:231,121:$VV1,123:$VW1,127:$VX1,131:$VY1,132:$VZ1,133:$V_1}),{22:130,26:$Vq,31:$Vt,46:$V$1,62:$Vz,68:$VA,91:237,95:$VH,122:236,141:$V02,178:$V12,180:$VZ},{22:130,26:$Vq,31:$Vt,46:$V$1,62:$Vz,68:$VA,91:237,95:$VH,122:241,141:$V02,178:$V12,180:$VZ},o($Ve1,[2,314],{180:$V22}),o($Ve1,[2,315]),{22:130,26:$Vq,31:$Vt,46:$Vv,47:243,62:$Vz,68:$VA,70:$Vm1,71:$Vn1,72:$Vo1,74:$Vp1,78:$Vq1,90:106,91:122,95:$VH,121:$VR,122:177,123:$VS,138:104,141:$VU,142:$Vc,143:$Vd,170:$VV,171:$VW,172:$VX,178:$VY,179:108,180:$VZ},o($Ve1,[2,317]),o($Ve1,[2,318],{180:$V32}),o($Ve1,[2,319]),{61:[1,246],93:245},{22:247,26:$Vq,31:$Vt,51:$V42,62:$Vz,68:$VA,95:$VH,126:248},{22:250,26:$Vq,31:$Vt,62:$Vz,68:$VA,95:$VH},{46:[1,251]},{46:[1,252]},{8:$Vn,11:86,12:75,13:71,14:72,15:76,16:77,17:78,18:79,19:80,20:82,21:$Vo,22:130,23:81,24:$Vp,26:$Vq,27:87,28:$Vr,31:$Vt,33:253,34:255,35:256,36:254,44:83,45:$Vu,46:$Vv,47:73,49:$Vw,51:$Vx,54:20,55:$Vy,56:$V2,61:$V3,62:$Vz,68:$VA,70:$VB,71:$VC,72:$VD,73:$VE,74:$VF,77:$V5,78:$VG,79:$V6,80:$V7,82:$V8,83:$V9,85:90,86:70,88:74,90:106,91:122,95:$VH,96:$VI,97:91,98:92,99:93,100:$VJ,101:$VK,104:$VL,108:$VM,109:$VN,110:$VO,111:$VP,113:$VQ,121:$VR,122:100,123:$VS,124:118,129:$VT,135:120,137:$Va,138:104,141:$VU,142:$Vc,143:$Vd,154:$Vb,170:$VV,171:$VW,172:$VX,178:$VY,179:108,180:$VZ},{31:$V52,62:$V62,94:257,95:$V72},{46:[1,261]},{46:[1,262]},o($V82,[2,170]),{24:$V92,55:$Va2,70:$Vb2,71:$Vc2,72:$Vd2,78:$Ve2,124:263},{127:[1,270]},o($Vt1,[2,196],{138:104,90:106,179:108,91:122,22:130,122:177,47:271,26:$Vq,31:$Vt,46:$Vv,51:[1,272],62:$Vz,68:$VA,70:$Vm1,71:$Vn1,72:$Vo1,74:$Vp1,78:$Vq1,95:$VH,121:$VR,123:$VS,141:$VU,142:$Vc,143:$Vd,170:$VV,171:$VW,172:$VX,178:$VY,180:$VZ}),o($Vf2,$Vg2,{46:$Vh2,180:$Vi2}),{22:130,26:$Vq,31:$Vt,62:$Vz,68:$VA,91:275,95:$VH},{22:281,26:$Vq,31:$Vt,46:$Vj2,51:[1,280],62:$Vz,68:$VA,69:277,95:$VH,125:278,126:279},{22:281,26:$Vq,31:$Vt,46:$Vk2,51:[1,286],62:$Vz,68:$VA,69:283,95:$VH,125:284,126:285},{22:281,26:$Vq,31:$Vt,46:$Vl2,51:[1,291],62:$Vz,68:$VA,69:288,95:$VH,125:289,126:290},{22:281,26:$Vq,31:$Vt,46:$Vm2,51:[1,296],62:$Vz,68:$VA,69:293,95:$VH,125:294,126:295},{22:281,26:[1,297],31:$Vt,62:$Vz,68:$VA,95:$VH,125:298,126:299},{22:130,26:$Vq,31:$Vt,46:$V$1,62:$Vz,68:$VA,91:237,95:$VH,122:301,134:300,141:$V02,178:$V12,180:$VZ},o($Vn2,[2,339],{181:302,51:[1,303]}),{151:[1,304]},{151:[1,305]},{151:[1,306]},o($Vo2,$Vp2,{151:$Vq2}),o($Vo2,[2,348],{151:[1,308]}),{48:[1,309]},{48:[2,64],64:[1,310]},{48:[2,66]},o($Vr2,[2,69]),{26:[1,311],68:[1,312]},o($Vs2,[2,74]),o($Vs2,[2,75]),o($Vs2,[2,76]),{70:[1,313],71:[1,314],72:[1,315],78:[1,316]},{75:[1,317],76:[1,318]},o($Vs2,[2,82]),o($Vs2,[2,83]),o($Vs2,[2,85]),o($Vs2,[2,86]),o($Vs2,[2,87]),o($Vs2,[2,88]),o($Vs2,[2,89]),o($Vs2,[2,90]),{48:$V_,55:$V$,57:319,63:137,65:$V01,66:139,67:140,70:$V11,71:$V21,72:$V31,73:$V41,74:$V51,77:$V61,78:$V71,79:$V81,80:$V91,81:$Va1,82:$Vb1,83:$Vc1},{46:[1,320]},{46:[1,321]},o($Vt2,[2,265],{64:$Vh1}),o($Vj1,$Vf1,{148:164,51:$Vg1,127:[1,322]}),{26:$Vj,68:$Vk,95:$Vl,143:$Vm,149:53,150:56,152:323},{26:$Vj,68:$Vk,95:$Vl,143:$Vm,149:53,150:325,152:324},{141:[1,326]},o($Vd1,[2,271],{64:$Vh1}),{22:130,26:$Vq,31:$Vt,46:$Vv,47:327,62:$Vz,68:$VA,70:$Vm1,71:$Vn1,72:$Vo1,74:$Vp1,78:$Vq1,90:106,91:122,95:$VH,121:$VR,122:177,123:$VS,138:104,141:$VU,142:$Vc,143:$Vd,170:$VV,171:$VW,172:$VX,178:$VY,179:108,180:$VZ},o($Vj1,[2,257],{51:$Vu2}),{22:130,26:$Vq,31:$Vt,46:$Vv,47:330,53:[1,329],62:$Vz,68:$VA,70:$Vm1,71:$Vn1,72:$Vo1,74:$Vp1,78:$Vq1,90:106,91:122,95:$VH,121:$VR,122:177,123:$VS,138:104,141:$VU,142:$Vc,143:$Vd,170:$VV,171:$VW,172:$VX,178:$VY,179:108,180:$VZ},{26:$Vj,68:$Vk,95:$Vl,143:$Vm,149:331,150:56},{26:[1,332],143:[1,333]},{26:[1,334]},{26:[1,335]},{22:130,26:$Vq,31:$Vt,46:$Vv,47:336,62:$Vz,68:$VA,70:$Vm1,71:$Vn1,72:$Vo1,74:$Vp1,78:$Vq1,90:106,91:122,95:$VH,121:$VR,122:177,123:$VS,138:104,141:$VU,142:$Vc,143:$Vd,170:$VV,171:$VW,172:$VX,178:$VY,179:108,180:$VZ},{51:$Vu2,127:[1,337]},{46:[2,57]},{22:130,26:$Vq,31:$Vt,46:$Vv,47:176,62:$Vz,65:$Vl1,68:$VA,70:$Vm1,71:$Vn1,72:$Vo1,74:$Vp1,78:$Vq1,90:106,91:122,95:$VH,103:338,121:$VR,122:177,123:$VS,138:104,141:$VU,142:$Vc,143:$Vd,170:$VV,171:$VW,172:$VX,178:$VY,179:108,180:$VZ},{48:[1,339],64:$Vv2},{22:130,26:$Vq,31:$Vt,46:$Vv,47:341,62:$Vz,68:$VA,70:$Vm1,71:$Vn1,72:$Vo1,74:$Vp1,78:$Vq1,90:106,91:122,95:$VH,121:$VR,122:177,123:$VS,138:104,141:$VU,142:$Vc,143:$Vd,170:$VV,171:$VW,172:$VX,178:$VY,179:108,180:$VZ},o($Vw2,[2,251],{107:$Vu1,155:$Vv1,156:$Vw1,157:$Vx1,158:$Vy1,159:$Vz1,160:$VA1,161:$VB1,162:$VC1,163:$VD1,164:$VE1,165:$VF1,166:$VG1,167:$VH1,168:$VI1,169:$VJ1,171:$VK1,172:$VL1,173:$VM1,174:$VN1,175:$VO1,176:$VP1,177:$VQ1}),o($Ve1,$VU1,{121:$VV1,123:$VW1}),{46:$Vj2,51:$VT1,69:277},{46:$Vk2,51:$VT1,69:283},{46:$Vl2,51:$VT1,69:288},{46:$VS1,51:$VT1,69:224},{46:$Vm2,51:$VT1,69:293},{30:[1,342]},o($V0,[2,22]),{8:$Vn,30:[2,28],35:343},o($Vr1,[2,30],{35:344,8:$Vn}),o($Vr1,[2,35],{8:$Vs1}),o($Vr1,[2,34],{8:$Vs1}),o($VR1,[2,42]),{22:130,26:$Vq,31:$Vt,46:$Vv,47:345,62:$Vz,68:$VA,70:$Vm1,71:$Vn1,72:$Vo1,74:$Vp1,78:$Vq1,90:106,91:122,95:$VH,121:$VR,122:177,123:$VS,138:104,141:$VU,142:$Vc,143:$Vd,170:$VV,171:$VW,172:$VX,178:$VY,179:108,180:$VZ},{22:130,26:$Vq,31:$Vt,46:$Vv,47:346,62:$Vz,68:$VA,70:$Vm1,71:$Vn1,72:$Vo1,74:$Vp1,78:$Vq1,90:106,91:122,95:$VH,121:$VR,122:177,123:$VS,138:104,141:$VU,142:$Vc,143:$Vd,170:$VV,171:$VW,172:$VX,178:$VY,179:108,180:$VZ},{22:130,26:$Vq,31:$Vt,46:$Vv,47:347,62:$Vz,68:$VA,70:$Vm1,71:$Vn1,72:$Vo1,74:$Vp1,78:$Vq1,90:106,91:122,95:$VH,121:$VR,122:177,123:$VS,138:104,141:$VU,142:$Vc,143:$Vd,170:$VV,171:$VW,172:$VX,178:$VY,179:108,180:$VZ},{22:130,26:$Vq,31:$Vt,46:$Vv,47:348,62:$Vz,68:$VA,70:$Vm1,71:$Vn1,72:$Vo1,74:$Vp1,78:$Vq1,90:106,91:122,95:$VH,121:$VR,122:177,123:$VS,138:104,141:$VU,142:$Vc,143:$Vd,170:$VV,171:$VW,172:$VX,178:$VY,179:108,180:$VZ},{22:130,26:$Vq,31:$Vt,46:$Vv,47:349,62:$Vz,68:$VA,70:$Vm1,71:$Vn1,72:$Vo1,74:$Vp1,78:$Vq1,90:106,91:122,95:$VH,121:$VR,122:177,123:$VS,138:104,141:$VU,142:$Vc,143:$Vd,170:$VV,171:$VW,172:$VX,178:$VY,179:108,180:$VZ},{22:130,26:$Vq,31:$Vt,46:$Vv,47:350,62:$Vz,68:$VA,70:$Vm1,71:$Vn1,72:$Vo1,74:$Vp1,78:$Vq1,90:106,91:122,95:$VH,121:$VR,122:177,123:$VS,138:104,141:$VU,142:$Vc,143:$Vd,170:$VV,171:$VW,172:$VX,178:$VY,179:108,180:$VZ},{22:130,26:$Vq,31:$Vt,46:$Vv,47:351,62:$Vz,68:$VA,70:$Vm1,71:$Vn1,72:$Vo1,74:$Vp1,78:$Vq1,90:106,91:122,95:$VH,121:$VR,122:177,123:$VS,138:104,141:$VU,142:$Vc,143:$Vd,170:$VV,171:$VW,172:$VX,178:$VY,179:108,180:$VZ},{22:130,26:$Vq,31:$Vt,46:$Vv,47:352,62:$Vz,68:$VA,70:$Vm1,71:$Vn1,72:$Vo1,74:$Vp1,78:$Vq1,90:106,91:122,95:$VH,121:$VR,122:177,123:$VS,138:104,141:$VU,142:$Vc,143:$Vd,170:$VV,171:$VW,172:$VX,178:$VY,179:108,180:$VZ},{55:$V$,60:353,67:354,70:$V11,71:$V21,72:$V31,73:$V41,74:$V51,77:$V61,78:$V71,79:$V81,80:$V91,81:$Va1,82:$Vb1,83:$Vc1},{22:130,26:$Vq,31:$Vt,46:$Vv,47:355,62:$Vz,68:$VA,70:$Vm1,71:$Vn1,72:$Vo1,74:$Vp1,78:$Vq1,90:106,91:122,95:$VH,121:$VR,122:177,123:$VS,138:104,141:$VU,142:$Vc,143:$Vd,170:$VV,171:$VW,172:$VX,178:$VY,179:108,180:$VZ},{22:130,26:$Vq,31:$Vt,46:$Vv,47:356,62:$Vz,68:$VA,70:$Vm1,71:$Vn1,72:$Vo1,74:$Vp1,78:$Vq1,90:106,91:122,95:$VH,121:$VR,122:177,123:$VS,138:104,141:$VU,142:$Vc,143:$Vd,170:$VV,171:$VW,172:$VX,178:$VY,179:108,180:$VZ},{22:130,26:$Vq,31:$Vt,46:$Vv,47:357,62:$Vz,68:$VA,70:$Vm1,71:$Vn1,72:$Vo1,74:$Vp1,78:$Vq1,90:106,91:122,95:$VH,121:$VR,122:177,123:$VS,138:104,141:$VU,142:$Vc,143:$Vd,170:$VV,171:$VW,172:$VX,178:$VY,179:108,180:$VZ},{22:130,26:$Vq,31:$Vt,46:$Vv,47:358,62:$Vz,68:$VA,70:$Vm1,71:$Vn1,72:$Vo1,74:$Vp1,78:$Vq1,90:106,91:122,95:$VH,121:$VR,122:177,123:$VS,138:104,141:$VU,142:$Vc,143:$Vd,170:$VV,171:$VW,172:$VX,178:$VY,179:108,180:$VZ},{22:130,26:$Vq,31:$Vt,46:$Vv,47:359,62:$Vz,68:$VA,70:$Vm1,71:$Vn1,72:$Vo1,74:$Vp1,78:$Vq1,90:106,91:122,95:$VH,121:$VR,122:177,123:$VS,138:104,141:$VU,142:$Vc,143:$Vd,170:$VV,171:$VW,172:$VX,178:$VY,179:108,180:$VZ},{22:130,26:$Vq,31:$Vt,46:$Vv,47:360,62:$Vz,68:$VA,70:$Vm1,71:$Vn1,72:$Vo1,74:$Vp1,78:$Vq1,90:106,91:122,95:$VH,121:$VR,122:177,123:$VS,138:104,141:$VU,142:$Vc,143:$Vd,170:$VV,171:$VW,172:$VX,178:$VY,179:108,180:$VZ},{22:130,26:$Vq,31:$Vt,46:$Vv,47:361,62:$Vz,68:$VA,70:$Vm1,71:$Vn1,72:$Vo1,74:$Vp1,78:$Vq1,90:106,91:122,95:$VH,121:$VR,122:177,123:$VS,138:104,141:$VU,142:$Vc,143:$Vd,170:$VV,171:$VW,172:$VX,178:$VY,179:108,180:$VZ},{22:130,26:$Vq,31:$Vt,46:$Vv,47:362,62:$Vz,68:$VA,70:$Vm1,71:$Vn1,72:$Vo1,74:$Vp1,78:$Vq1,90:106,91:122,95:$VH,121:$VR,122:177,123:$VS,138:104,141:$VU,142:$Vc,143:$Vd,170:$VV,171:$VW,172:$VX,178:$VY,179:108,180:$VZ},{22:130,26:$Vq,31:$Vt,46:$Vv,47:363,62:$Vz,68:$VA,70:$Vm1,71:$Vn1,72:$Vo1,74:$Vp1,78:$Vq1,90:106,91:122,95:$VH,121:$VR,122:177,123:$VS,138:104,141:$VU,142:$Vc,143:$Vd,170:$VV,171:$VW,172:$VX,178:$VY,179:108,180:$VZ},{22:130,26:$Vq,31:$Vt,46:$Vv,47:364,62:$Vz,68:$VA,70:$Vm1,71:$Vn1,72:$Vo1,74:$Vp1,78:$Vq1,90:106,91:122,95:$VH,121:$VR,122:177,123:$VS,138:104,141:$VU,142:$Vc,143:$Vd,170:$VV,171:$VW,172:$VX,178:$VY,179:108,180:$VZ},{22:130,26:$Vq,31:$Vt,46:$Vv,47:365,62:$Vz,68:$VA,70:$Vm1,71:$Vn1,72:$Vo1,74:$Vp1,78:$Vq1,90:106,91:122,95:$VH,121:$VR,122:177,123:$VS,138:104,141:$VU,142:$Vc,143:$Vd,170:$VV,171:$VW,172:$VX,178:$VY,179:108,180:$VZ},{22:130,26:$Vq,31:$Vt,46:$Vv,47:366,62:$Vz,68:$VA,70:$Vm1,71:$Vn1,72:$Vo1,74:$Vp1,78:$Vq1,90:106,91:122,95:$VH,121:$VR,122:177,123:$VS,138:104,141:$VU,142:$Vc,143:$Vd,170:$VV,171:$VW,172:$VX,178:$VY,179:108,180:$VZ},{22:130,26:$Vq,31:$Vt,46:$Vv,47:367,62:$Vz,68:$VA,70:$Vm1,71:$Vn1,72:$Vo1,74:$Vp1,78:$Vq1,90:106,91:122,95:$VH,121:$VR,122:177,123:$VS,138:104,141:$VU,142:$Vc,143:$Vd,170:$VV,171:$VW,172:$VX,178:$VY,179:108,180:$VZ},{22:130,26:$Vq,31:$Vt,46:$Vv,47:368,62:$Vz,68:$VA,70:$Vm1,71:$Vn1,72:$Vo1,74:$Vp1,78:$Vq1,90:106,91:122,95:$VH,121:$VR,122:177,123:$VS,138:104,141:$VU,142:$Vc,143:$Vd,170:$VV,171:$VW,172:$VX,178:$VY,179:108,180:$VZ},{22:130,26:$Vq,31:$Vt,46:$Vv,47:369,62:$Vz,68:$VA,70:$Vm1,71:$Vn1,72:$Vo1,74:$Vp1,78:$Vq1,90:106,91:122,95:$VH,121:$VR,122:177,123:$VS,138:104,141:$VU,142:$Vc,143:$Vd,170:$VV,171:$VW,172:$VX,178:$VY,179:108,180:$VZ},{22:130,26:$Vq,31:$Vt,46:$Vv,47:370,62:$Vz,68:$VA,70:$Vm1,71:$Vn1,72:$Vo1,74:$Vp1,78:$Vq1,90:106,91:122,95:$VH,121:$VR,122:177,123:$VS,138:104,141:$VU,142:$Vc,143:$Vd,170:$VV,171:$VW,172:$VX,178:$VY,179:108,180:$VZ},{8:$Vn,11:86,12:75,13:71,14:72,15:76,16:77,17:78,18:79,19:80,20:82,21:$Vo,22:130,23:81,24:$Vp,26:$Vq,27:87,28:$Vr,31:$Vt,33:371,34:255,35:256,36:372,44:83,45:$Vu,46:$Vv,47:73,49:$Vw,51:$Vx,54:20,55:$Vy,56:$V2,61:$V3,62:$Vz,68:$VA,70:$VB,71:$VC,72:$VD,73:$VE,74:$VF,77:$V5,78:$VG,79:$V6,80:$V7,82:$V8,83:$V9,85:90,86:70,88:74,90:106,91:122,95:$VH,96:$VI,97:91,98:92,99:93,100:$VJ,101:$VK,104:$VL,108:$VM,109:$VN,110:$VO,111:$VP,113:$VQ,121:$VR,122:100,123:$VS,124:118,129:$VT,135:120,137:$Va,138:104,141:$VU,142:$Vc,143:$Vd,154:$Vb,170:$VV,171:$VW,172:$VX,178:$VY,179:108,180:$VZ},o($Vx2,[2,44]),o($Vx2,[2,45]),o($Vx2,[2,46]),{26:$Vy2,50:373},{22:130,26:$Vq,28:$Vz2,31:$Vt,46:$Vv,47:377,51:$VA2,52:375,62:$Vz,68:$VA,70:$Vm1,71:$Vn1,72:$Vo1,74:$Vp1,78:$Vq1,89:376,90:106,91:122,95:$VH,121:$VR,122:177,123:$VS,138:104,141:$VU,142:$Vc,143:$Vd,170:$VV,171:$VW,172:$VX,178:$VY,179:108,180:$VZ},{8:[1,380],107:$Vu1,155:$Vv1,156:$Vw1,157:$Vx1,158:$Vy1,159:$Vz1,160:$VA1,161:$VB1,162:$VC1,163:$VD1,164:$VE1,165:$VF1,166:$VG1,167:$VH1,168:$VI1,169:$VJ1,171:$VK1,172:$VL1,173:$VM1,174:$VN1,175:$VO1,176:$VP1,177:$VQ1},{30:[1,381]},{22:130,26:$Vq,31:$Vt,46:$Vv,47:382,62:$Vz,68:$VA,70:$Vm1,71:$Vn1,72:$Vo1,74:$Vp1,78:$Vq1,90:106,91:122,95:$VH,121:$VR,122:177,123:$VS,138:104,141:$VU,142:$Vc,143:$Vd,170:$VV,171:$VW,172:$VX,178:$VY,179:108,180:$VZ},{46:[1,383],51:$VB2},{53:$VC2},o($Ve1,[2,299]),o($Ve1,[2,307]),o($Ve1,[2,308]),o($Ve1,[2,312]),o($Ve1,[2,313]),{22:130,26:$Vq,31:$Vt,46:$Vv,47:386,62:$Vz,68:$VA,70:$Vm1,71:$Vn1,72:$Vo1,74:$Vp1,78:$Vq1,90:106,91:122,95:$VH,121:$VR,122:177,123:$VS,138:104,141:$VU,142:$Vc,143:$Vd,170:$VV,171:$VW,172:$VX,178:$VY,179:108,180:$VZ},o($VD2,[2,199],{136:387,51:$VE2}),o($VD2,[2,200]),o($VD2,[2,201]),o($VD2,[2,202]),o($Ve1,[2,310]),o($Vf2,$Vg2,{180:$Vi2}),{180:$V22},{22:130,26:$Vq,31:$Vt,46:$Vv,47:389,62:$Vz,68:$VA,70:$Vm1,71:$Vn1,72:$Vo1,74:$Vp1,78:$Vq1,90:106,91:122,95:$VH,121:$VR,122:177,123:$VS,138:104,141:$VU,142:$Vc,143:$Vd,170:$VV,171:$VW,172:$VX,178:$VY,179:108,180:$VZ},{180:$V32},o($Ve1,[2,311]),{22:130,26:$Vq,31:$Vt,62:$Vz,68:$VA,91:390,95:$VH},{48:[1,391],107:$Vu1,155:$Vv1,156:$Vw1,157:$Vx1,158:$Vy1,159:$Vz1,160:$VA1,161:$VB1,162:$VC1,163:$VD1,164:$VE1,165:$VF1,166:$VG1,167:$VH1,168:$VI1,169:$VJ1,171:$VK1,172:$VL1,173:$VM1,174:$VN1,175:$VO1,176:$VP1,177:$VQ1},{22:130,26:$Vq,31:$Vt,62:$Vz,68:$VA,91:392,95:$VH},{31:$V52,62:$V62,94:393,95:$V72},o([31,62,95],[2,131]),o($Vt1,[2,18],{128:396,25:[1,394],28:[1,395],51:$VF2,127:$VG2}),{127:[1,398]},{22:281,26:$Vq,31:$Vt,62:$Vz,68:$VA,95:$VH,125:399,126:400},o($Vt1,[2,17]),{13:405,22:130,24:$V92,26:$Vq,31:$Vt,46:$V$1,55:$Va2,62:$Vz,68:$VA,70:$Vb2,71:$Vc2,72:$Vd2,73:$VE,74:$V4,78:$Ve2,85:402,91:237,95:$VH,97:403,105:401,122:404,124:118,141:$V02,178:$V12,180:$VZ},{22:130,26:$Vq,31:$Vt,46:$Vv,47:406,62:$Vz,68:$VA,70:$Vm1,71:$Vn1,72:$Vo1,74:$Vp1,78:$Vq1,90:106,91:122,95:$VH,121:$VR,122:177,123:$VS,138:104,141:$VU,142:$Vc,143:$Vd,170:$VV,171:$VW,172:$VX,178:$VY,179:108,180:$VZ},{108:[1,407]},{8:$Vn,35:409,108:[1,408]},o([21,24,26,28,30,31,45,46,49,51,55,56,61,62,68,70,71,72,73,74,77,78,79,80,82,83,95,96,100,101,104,108,109,110,111,113,114,116,119,121,123,129,137,141,142,143,154,170,171,172,178,180],[2,23],{35:410,8:$Vn}),o($VR1,[2,25]),{8:$Vn,11:86,12:75,13:71,14:72,15:76,16:77,17:78,18:79,19:80,20:82,21:$Vo,22:130,23:81,24:$Vp,26:$Vq,27:87,28:$Vr,31:$Vt,33:411,34:255,35:256,36:372,44:83,45:$Vu,46:$Vv,47:73,49:$Vw,51:$Vx,54:20,55:$Vy,56:$V2,61:$V3,62:$Vz,68:$VA,70:$VB,71:$VC,72:$VD,73:$VE,74:$VF,77:$V5,78:$VG,79:$V6,80:$V7,82:$V8,83:$V9,85:90,86:70,88:74,90:106,91:122,95:$VH,96:$VI,97:91,98:92,99:93,100:$VJ,101:$VK,104:$VL,108:$VM,109:$VN,110:$VO,111:$VP,113:$VQ,121:$VR,122:100,123:$VS,124:118,129:$VT,135:120,137:$Va,138:104,141:$VU,142:$Vc,143:$Vd,154:$Vb,170:$VV,171:$VW,172:$VX,178:$VY,179:108,180:$VZ},o($Vx2,[2,132]),o($Vx2,[2,133]),o($Vx2,[2,134]),{22:130,26:$Vq,31:$Vt,46:$Vv,47:412,62:$Vz,68:$VA,70:$Vm1,71:$Vn1,72:$Vo1,74:$Vp1,78:$Vq1,90:106,91:122,95:$VH,121:$VR,122:177,123:$VS,138:104,141:$VU,142:$Vc,143:$Vd,170:$VV,171:$VW,172:$VX,178:$VY,179:108,180:$VZ},{22:130,26:$Vq,31:$Vt,46:$Vv,47:413,62:$Vz,68:$VA,70:$Vm1,71:$Vn1,72:$Vo1,74:$Vp1,78:$Vq1,90:106,91:122,95:$VH,121:$VR,122:177,123:$VS,138:104,141:$VU,142:$Vc,143:$Vd,170:$VV,171:$VW,172:$VX,178:$VY,179:108,180:$VZ},o($V82,[2,171]),{22:281,26:$Vq,31:$Vt,51:[1,414],62:$Vz,68:$VA,95:$VH,125:278,126:279},{22:281,26:$Vq,31:$Vt,51:[1,415],62:$Vz,68:$VA,95:$VH,125:284,126:285},{22:281,26:$Vq,31:$Vt,51:[1,416],62:$Vz,68:$VA,95:$VH,125:289,126:290},{22:281,26:$Vq,31:$Vt,51:[1,417],62:$Vz,68:$VA,95:$VH,125:294,126:295},{22:281,26:$Vq,31:$Vt,62:$Vz,68:$VA,95:$VH,125:298,126:299},{22:281,26:$Vq,31:$Vt,51:$V42,62:$Vz,68:$VA,95:$VH,126:248},{22:130,26:$Vq,31:$Vt,51:[1,419],62:$Vz,68:$VA,90:418,91:420,95:$VH},o($Vt1,[2,197],{107:$Vu1,155:$Vv1,156:$Vw1,157:$Vx1,158:$Vy1,159:$Vz1,160:$VA1,161:$VB1,162:$VC1,163:$VD1,164:$VE1,165:$VF1,166:$VG1,167:$VH1,168:$VI1,169:$VJ1,171:$VK1,172:$VL1,173:$VM1,174:$VN1,175:$VO1,176:$VP1,177:$VQ1}),{22:130,26:$Vq,31:$Vt,46:$Vv,47:176,62:$Vz,65:$Vl1,68:$VA,70:$Vm1,71:$Vn1,72:$Vo1,74:$Vp1,78:$Vq1,90:106,91:122,95:$VH,103:421,121:$VR,122:177,123:$VS,138:104,141:$VU,142:$Vc,143:$Vd,170:$VV,171:$VW,172:$VX,178:$VY,179:108,180:$VZ},o($Vf2,[2,330],{46:[1,423],141:[1,422],178:[1,424]}),o($Vr2,$VH2,{138:104,90:106,179:108,91:122,22:130,122:177,92:425,47:427,26:$Vq,31:$Vt,46:$Vv,51:$VI2,62:$Vz,68:$VA,70:$Vm1,71:$Vn1,72:$Vo1,74:$Vp1,78:$Vq1,95:$VH,121:$VR,123:$VS,141:$VU,142:$Vc,143:$Vd,170:$VV,171:$VW,172:$VX,178:$VY,180:$VZ}),o($Vf2,[2,334]),{22:130,26:$Vq,31:$Vt,46:$Vv,47:428,62:$Vz,68:$VA,70:$Vm1,71:$Vn1,72:$Vo1,74:$Vp1,78:$Vq1,90:106,91:122,95:$VH,121:$VR,122:177,123:$VS,138:104,141:$VU,142:$Vc,143:$Vd,170:$VV,171:$VW,172:$VX,178:$VY,179:108,180:$VZ},{46:[1,429],51:$VB2},o($V82,[2,172],{64:$VJ2}),o($VK2,$VL2,{127:[1,431]}),{22:281,26:$Vq,31:$Vt,53:$VC2,62:$Vz,68:$VA,95:$VH,125:432,126:400},o($VM2,$VG2,{128:396,51:$VF2}),{22:130,26:$Vq,31:$Vt,46:$Vv,47:433,62:$Vz,68:$VA,70:$Vm1,71:$Vn1,72:$Vo1,74:$Vp1,78:$Vq1,90:106,91:122,95:$VH,121:$VR,122:177,123:$VS,138:104,141:$VU,142:$Vc,143:$Vd,170:$VV,171:$VW,172:$VX,178:$VY,179:108,180:$VZ},{46:[1,434],51:$VB2},o($V82,[2,173],{64:$VJ2}),o($VK2,$VL2,{127:[1,435]}),{22:281,26:$Vq,31:$Vt,53:$VC2,62:$Vz,68:$VA,95:$VH,125:436,126:400},{22:130,26:$Vq,31:$Vt,46:$Vv,47:437,62:$Vz,68:$VA,70:$Vm1,71:$Vn1,72:$Vo1,74:$Vp1,78:$Vq1,90:106,91:122,95:$VH,121:$VR,122:177,123:$VS,138:104,141:$VU,142:$Vc,143:$Vd,170:$VV,171:$VW,172:$VX,178:$VY,179:108,180:$VZ},{46:[1,438],51:$VB2},o($V82,[2,174],{64:$VJ2}),o($VK2,$VL2,{127:[1,439]}),{22:281,26:$Vq,31:$Vt,53:$VC2,62:$Vz,68:$VA,95:$VH,125:440,126:400},{22:130,26:$Vq,31:$Vt,46:$Vv,47:441,62:$Vz,68:$VA,70:$Vm1,71:$Vn1,72:$Vo1,74:$Vp1,78:$Vq1,90:106,91:122,95:$VH,121:$VR,122:177,123:$VS,138:104,141:$VU,142:$Vc,143:$Vd,170:$VV,171:$VW,172:$VX,178:$VY,179:108,180:$VZ},{46:[1,442],51:$VB2},o($V82,[2,175],{64:$VJ2}),o($VK2,$VL2,{127:[1,443]}),{22:281,26:$Vq,31:$Vt,53:$VC2,62:$Vz,68:$VA,95:$VH,125:444,126:400},o([8,30,51,64,108,127],$Vp2,{46:$Vk1,151:$Vq2}),o($V82,[2,176],{64:$VJ2}),o($VK2,$VL2,{127:[1,445]}),{53:[1,446],64:[1,447]},o($VN2,[2,205]),o($Vn2,[2,340],{51:[1,448]}),{22:130,26:$Vq,31:$Vt,46:$Vv,47:449,62:$Vz,68:$VA,70:$Vm1,71:$Vn1,72:$Vo1,74:$Vp1,78:$Vq1,90:106,91:122,95:$VH,121:$VR,122:177,123:$VS,138:104,141:$VU,142:$Vc,143:$Vd,170:$VV,171:$VW,172:$VX,178:$VY,179:108,180:$VZ},{26:$VO2,143:$VP2,182:450},{26:$VO2,143:$VP2,182:453},{26:$VO2,143:$VP2,182:454},{26:$VO2,143:$VP2,182:455},{26:$VO2,143:$VP2,182:456},{28:[1,458],58:[1,457]},{55:$V$,65:[1,459],66:460,67:140,70:$V11,71:$V21,72:$V31,73:$V41,74:$V51,77:$V61,78:$V71,79:$V81,80:$V91,81:$Va1,82:$Vb1,83:$Vc1},o($Vr2,[2,70],{69:461,51:$VT1}),o($Vr2,[2,71],{69:462,51:$VT1}),o($Vs2,[2,77]),o($Vs2,[2,78]),o($Vs2,[2,79]),o($Vs2,[2,84]),o($Vs2,[2,80]),o($Vs2,[2,81]),{48:[1,463]},{48:$V_,55:$V$,57:464,63:137,65:$V01,66:139,67:140,70:$V11,71:$V21,72:$V31,73:$V41,74:$V51,77:$V61,78:$V71,79:$V81,80:$V91,81:$Va1,82:$Vb1,83:$Vc1},{48:$V_,55:$V$,57:465,63:137,65:$V01,66:139,67:140,70:$V11,71:$V21,72:$V31,73:$V41,74:$V51,77:$V61,78:$V71,79:$V81,80:$V91,81:$Va1,82:$Vb1,83:$Vc1},{22:130,26:$Vq,31:$Vt,46:$Vv,47:466,62:$Vz,68:$VA,70:$Vm1,71:$Vn1,72:$Vo1,74:$Vp1,78:$Vq1,90:106,91:122,95:$VH,121:$VR,122:177,123:$VS,138:104,141:$VU,142:$Vc,143:$Vd,170:$VV,171:$VW,172:$VX,178:$VY,179:108,180:$VZ},o($Vt2,[2,267],{64:$Vh1}),o($Vt2,[2,268],{64:$Vh1}),o($Vj1,$Vf1,{148:164,51:$Vg1,127:[1,467]}),{48:[1,468]},o($Vd1,[2,272],{107:$Vu1,155:$Vv1,156:$Vw1,157:$Vx1,158:$Vy1,159:$Vz1,160:$VA1,161:$VB1,162:$VC1,163:$VD1,164:$VE1,165:$VF1,166:$VG1,167:$VH1,168:$VI1,169:$VJ1,171:$VK1,172:$VL1,173:$VM1,174:$VN1,175:$VO1,176:$VP1,177:$VQ1}),{22:130,26:$Vq,31:$Vt,46:$Vv,47:470,53:[1,469],62:$Vz,68:$VA,70:$Vm1,71:$Vn1,72:$Vo1,74:$Vp1,78:$Vq1,90:106,91:122,95:$VH,121:$VR,122:177,123:$VS,138:104,141:$VU,142:$Vc,143:$Vd,170:$VV,171:$VW,172:$VX,178:$VY,179:108,180:$VZ},o($Vi1,[2,252]),{53:[1,471],107:$Vu1,155:$Vv1,156:$Vw1,157:$Vx1,158:$Vy1,159:$Vz1,160:$VA1,161:$VB1,162:$VC1,163:$VD1,164:$VE1,165:$VF1,166:$VG1,167:$VH1,168:$VI1,169:$VJ1,171:$VK1,172:$VL1,173:$VM1,174:$VN1,175:$VO1,176:$VP1,177:$VQ1},o($Vj1,[2,263]),o($Vi1,[2,261]),o($Vi1,[2,262]),{64:[1,472]},{48:[1,473]},o($Vd1,[2,281],{107:$Vu1,155:$Vv1,156:$Vw1,157:$Vx1,158:$Vy1,159:$Vz1,160:$VA1,161:$VB1,162:$VC1,163:$VD1,164:$VE1,165:$VF1,166:$VG1,167:$VH1,168:$VI1,169:$VJ1,171:$VK1,172:$VL1,173:$VM1,174:$VN1,175:$VO1,176:$VP1,177:$VQ1}),{51:$VE2,136:474},{48:[1,475],64:$Vv2},{28:[1,476]},{22:130,26:$Vq,31:$Vt,46:$Vv,47:478,62:$Vz,65:[1,477],68:$VA,70:$Vm1,71:$Vn1,72:$Vo1,74:$Vp1,78:$Vq1,90:106,91:122,95:$VH,121:$VR,122:177,123:$VS,138:104,141:$VU,142:$Vc,143:$Vd,170:$VV,171:$VW,172:$VX,178:$VY,179:108,180:$VZ},o($Vw2,[2,250],{107:$Vu1,155:$Vv1,156:$Vw1,157:$Vx1,158:$Vy1,159:$Vz1,160:$VA1,161:$VB1,162:$VC1,163:$VD1,164:$VE1,165:$VF1,166:$VG1,167:$VH1,168:$VI1,169:$VJ1,171:$VK1,172:$VL1,173:$VM1,174:$VN1,175:$VO1,176:$VP1,177:$VQ1}),o($V0,[2,280]),o($Vr1,[2,32],{8:$Vs1}),o($Vr1,[2,31],{8:$Vs1}),o($Vt1,[2,111],{107:$Vu1,155:$Vv1,156:$Vw1,157:$Vx1,158:$Vy1,159:$Vz1,160:$VA1,161:$VB1,162:$VC1,163:$VD1,164:$VE1,165:$VF1,166:$VG1,167:$VH1,168:$VI1,169:$VJ1,171:$VK1,172:$VL1,173:$VM1,174:$VN1,175:$VO1,176:$VP1,177:$VQ1}),o($VQ2,[2,283],{168:$VI1,169:$VJ1,171:$VK1,172:$VL1,173:$VM1,174:$VN1,175:$VO1,176:$VP1,177:$VQ1}),o($VQ2,[2,284],{168:$VI1,169:$VJ1,171:$VK1,172:$VL1,173:$VM1,174:$VN1,175:$VO1,176:$VP1,177:$VQ1}),o($VQ2,[2,285],{168:$VI1,169:$VJ1,171:$VK1,172:$VL1,173:$VM1,174:$VN1,175:$VO1,176:$VP1,177:$VQ1}),o($VQ2,[2,286],{168:$VI1,169:$VJ1,171:$VK1,172:$VL1,173:$VM1,174:$VN1,175:$VO1,176:$VP1,177:$VQ1}),o($VQ2,[2,287],{168:$VI1,169:$VJ1,171:$VK1,172:$VL1,173:$VM1,174:$VN1,175:$VO1,176:$VP1,177:$VQ1}),o($VQ2,[2,288],{168:$VI1,169:$VJ1,171:$VK1,172:$VL1,173:$VM1,174:$VN1,175:$VO1,176:$VP1,177:$VQ1}),o([6,8,30,31,48,53,55,56,58,61,62,64,65,74,77,79,80,82,83,87,107,108,118,137,146,147,154,161,162,163,164,165,166,167],[2,289],{155:$Vv1,156:$Vw1,157:$Vx1,158:$Vy1,159:$Vz1,160:$VA1,168:$VI1,169:$VJ1,171:$VK1,172:$VL1,173:$VM1,174:$VN1,175:$VO1,176:$VP1,177:$VQ1}),o($Ve1,[2,290]),o($VR2,[2,95],{69:479,51:$VT1}),o($VS2,[2,291],{107:$Vu1,155:$Vv1,156:$Vw1,157:$Vx1,158:$Vy1,159:$Vz1,160:$VA1,161:$VB1,164:$VE1,165:$VF1,166:$VG1,168:$VI1,169:$VJ1,171:$VK1,172:$VL1,173:$VM1,174:$VN1,175:$VO1,176:$VP1,177:$VQ1}),{58:[1,480],107:$Vu1,155:$Vv1,156:$Vw1,157:$Vx1,158:$Vy1,159:$Vz1,160:$VA1,161:$VB1,162:$VC1,163:$VD1,164:$VE1,165:$VF1,166:$VG1,167:$VH1,168:$VI1,169:$VJ1,171:$VK1,172:$VL1,173:$VM1,174:$VN1,175:$VO1,176:$VP1,177:$VQ1},o($VS2,[2,293],{107:$Vu1,155:$Vv1,156:$Vw1,157:$Vx1,158:$Vy1,159:$Vz1,160:$VA1,161:$VB1,164:$VE1,165:$VF1,166:$VG1,168:$VI1,169:$VJ1,171:$VK1,172:$VL1,173:$VM1,174:$VN1,175:$VO1,176:$VP1,177:$VQ1}),o($VS2,[2,294],{107:$Vu1,155:$Vv1,156:$Vw1,157:$Vx1,158:$Vy1,159:$Vz1,160:$VA1,161:$VB1,164:$VE1,165:$VF1,166:$VG1,168:$VI1,169:$VJ1,171:$VK1,172:$VL1,173:$VM1,174:$VN1,175:$VO1,176:$VP1,177:$VQ1}),o($VS2,[2,295],{107:$Vu1,155:$Vv1,156:$Vw1,157:$Vx1,158:$Vy1,159:$Vz1,160:$VA1,161:$VB1,164:$VE1,165:$VF1,166:$VG1,168:$VI1,169:$VJ1,171:$VK1,172:$VL1,173:$VM1,174:$VN1,175:$VO1,176:$VP1,177:$VQ1}),o($VT2,[2,296],{107:$Vu1,155:$Vv1,156:$Vw1,157:$Vx1,158:$Vy1,159:$Vz1,160:$VA1,161:$VB1,162:$VC1,164:$VE1,165:$VF1,166:$VG1,168:$VI1,169:$VJ1,171:$VK1,172:$VL1,173:$VM1,174:$VN1,175:$VO1,176:$VP1,177:$VQ1}),o($VS2,[2,297],{107:$Vu1,155:$Vv1,156:$Vw1,157:$Vx1,158:$Vy1,159:$Vz1,160:$VA1,161:$VB1,164:$VE1,165:$VF1,166:$VG1,168:$VI1,169:$VJ1,171:$VK1,172:$VL1,173:$VM1,174:$VN1,175:$VO1,176:$VP1,177:$VQ1}),o($VT2,[2,298],{107:$Vu1,155:$Vv1,156:$Vw1,157:$Vx1,158:$Vy1,159:$Vz1,160:$VA1,161:$VB1,162:$VC1,164:$VE1,165:$VF1,166:$VG1,168:$VI1,169:$VJ1,171:$VK1,172:$VL1,173:$VM1,174:$VN1,175:$VO1,176:$VP1,177:$VQ1}),o($VU2,[2,300],{173:$VM1,174:$VN1,175:$VO1,176:$VP1,177:$VQ1}),o($VU2,[2,301],{173:$VM1,174:$VN1,175:$VO1,176:$VP1,177:$VQ1}),o($VV2,[2,302],{177:$VQ1}),o($VV2,[2,303],{177:$VQ1}),o($VV2,[2,304],{177:$VQ1}),o($VV2,[2,305],{177:$VQ1}),o($Ve1,[2,306]),{48:[1,481],107:$Vu1,155:$Vv1,156:$Vw1,157:$Vx1,158:$Vy1,159:$Vz1,160:$VA1,161:$VB1,162:$VC1,163:$VD1,164:$VE1,165:$VF1,166:$VG1,167:$VH1,168:$VI1,169:$VJ1,171:$VK1,172:$VL1,173:$VM1,174:$VN1,175:$VO1,176:$VP1,177:$VQ1},o($VR1,[2,49]),{8:$Vn,35:409},{30:[1,482],64:$VW2},o($VX2,[2,127],{58:[1,484]}),{53:[1,485],64:$VY2},o($VN2,[2,129]),o($VZ2,[2,121],{107:$Vu1,155:$Vv1,156:$Vw1,157:$Vx1,158:$Vy1,159:$Vz1,160:$VA1,161:$VB1,162:$VC1,163:$VD1,164:$VE1,165:$VF1,166:$VG1,167:$VH1,168:$VI1,169:$VJ1,171:$VK1,172:$VL1,173:$VM1,174:$VN1,175:$VO1,176:$VP1,177:$VQ1}),{26:$Vy2,50:487},{22:130,26:$Vq,28:$Vz2,31:$Vt,46:$Vv,47:377,51:$VA2,52:488,62:$Vz,68:$VA,70:$Vm1,71:$Vn1,72:$Vo1,74:$Vp1,78:$Vq1,89:376,90:106,91:122,95:$VH,121:$VR,122:177,123:$VS,138:104,141:$VU,142:$Vc,143:$Vd,170:$VV,171:$VW,172:$VX,178:$VY,179:108,180:$VZ},o($VR1,[2,52]),o($VR1,[2,55]),{48:[1,489],107:$Vu1,155:$Vv1,156:$Vw1,157:$Vx1,158:$Vy1,159:$Vz1,160:$VA1,161:$VB1,162:$VC1,163:$VD1,164:$VE1,165:$VF1,166:$VG1,167:$VH1,168:$VI1,169:$VJ1,171:$VK1,172:$VL1,173:$VM1,174:$VN1,175:$VO1,176:$VP1,177:$VQ1},{22:130,26:$Vq,31:$Vt,46:$Vv,47:490,62:$Vz,68:$VA,70:$Vm1,71:$Vn1,72:$Vo1,74:$Vp1,78:$Vq1,90:106,91:122,95:$VH,121:$VR,122:177,123:$VS,138:104,141:$VU,142:$Vc,143:$Vd,170:$VV,171:$VW,172:$VX,178:$VY,179:108,180:$VZ},{53:[1,491]},o($V_2,[2,94]),o([8,30,48,64,108],[2,210],{107:$Vu1,155:$Vv1,156:$Vw1,157:$Vx1,158:$Vy1,159:$Vz1,160:$VA1,161:$VB1,162:$VC1,163:$VD1,164:$VE1,165:$VF1,166:$VG1,167:$VH1,168:$VI1,169:$VJ1,171:$VK1,172:$VL1,173:$VM1,174:$VN1,175:$VO1,176:$VP1,177:$VQ1}),o([8,30,48,64,107,108],[2,211]),{22:130,26:$Vq,31:$Vt,46:$Vv,47:494,51:$V$2,62:$Vz,68:$VA,70:$Vm1,71:$Vn1,72:$Vo1,74:$Vp1,78:$Vq1,90:106,91:122,95:$VH,121:$VR,122:177,123:$VS,138:104,141:$VU,142:$Vc,143:$Vd,144:492,145:493,170:$VV,171:$VW,172:$VX,178:$VY,179:108,180:$VZ},{48:[1,496],107:$Vu1,155:$Vv1,156:$Vw1,157:$Vx1,158:$Vy1,159:$Vz1,160:$VA1,161:$VB1,162:$VC1,163:$VD1,164:$VE1,165:$VF1,166:$VG1,167:$VH1,168:$VI1,169:$VJ1,171:$VK1,172:$VL1,173:$VM1,174:$VN1,175:$VO1,176:$VP1,177:$VQ1},o($Vf2,[2,335]),o($Ve1,[2,316],{180:$V03}),o($Vf2,[2,337]),{22:130,26:$Vq,31:$Vt,62:$Vz,68:$VA,91:498,95:$VH},{26:[1,499]},{13:503,14:504,15:505,16:506,17:507,18:508,19:509,24:$V92,29:500,30:$V13,39:501,55:$Va2,70:$Vb2,71:$Vc2,72:$Vd2,73:$VE,74:$V4,77:$V5,78:$Ve2,79:$V6,80:$V7,82:$V8,83:$V9,84:502,85:510,124:118,154:$Vb},o($VM2,[2,193],{51:[1,511]}),{22:130,26:$Vq,31:$Vt,46:$Vv,47:513,53:[1,512],62:$Vz,68:$VA,70:$Vm1,71:$Vn1,72:$Vo1,74:$Vp1,78:$Vq1,90:106,91:122,95:$VH,121:$VR,122:177,123:$VS,138:104,141:$VU,142:$Vc,143:$Vd,170:$VV,171:$VW,172:$VX,178:$VY,179:108,180:$VZ},{22:130,26:$Vq,31:$Vt,46:$Vv,47:514,62:$Vz,68:$VA,70:$Vm1,71:$Vn1,72:$Vo1,74:$Vp1,78:$Vq1,90:106,91:122,95:$VH,121:$VR,122:177,123:$VS,138:104,141:$VU,142:$Vc,143:$Vd,170:$VV,171:$VW,172:$VX,178:$VY,179:108,180:$VZ},{53:[1,515],64:$VJ2},o($VN2,$VL2),{8:[1,516],107:[1,517]},o($V23,[2,166]),o($V23,[2,167]),o($V23,[2,168],{130:231,127:$VX1,131:$VY1,132:$VZ1,133:$V_1}),o($V23,[2,169]),{48:[1,518],107:$Vu1,155:$Vv1,156:$Vw1,157:$Vx1,158:$Vy1,159:$Vz1,160:$VA1,161:$VB1,162:$VC1,163:$VD1,164:$VE1,165:$VF1,166:$VG1,167:$VH1,168:$VI1,169:$VJ1,171:$VK1,172:$VL1,173:$VM1,174:$VN1,175:$VO1,176:$VP1,177:$VQ1},{46:[1,519]},{46:[1,520]},o($VR1,[2,26]),o($VR1,[2,24]),o($VR1,[2,149]),{48:[1,521],107:$Vu1,155:$Vv1,156:$Vw1,157:$Vx1,158:$Vy1,159:$Vz1,160:$VA1,161:$VB1,162:$VC1,163:$VD1,164:$VE1,165:$VF1,166:$VG1,167:$VH1,168:$VI1,169:$VJ1,171:$VK1,172:$VL1,173:$VM1,174:$VN1,175:$VO1,176:$VP1,177:$VQ1},{48:[1,522],107:$Vu1,155:$Vv1,156:$Vw1,157:$Vx1,158:$Vy1,159:$Vz1,160:$VA1,161:$VB1,162:$VC1,163:$VD1,164:$VE1,165:$VF1,166:$VG1,167:$VH1,168:$VI1,169:$VJ1,171:$VK1,172:$VL1,173:$VM1,174:$VN1,175:$VO1,176:$VP1,177:$VQ1},{22:281,26:$Vq,31:$Vt,62:$Vz,68:$VA,95:$VH,125:432,126:400},{22:281,26:$Vq,31:$Vt,62:$Vz,68:$VA,95:$VH,125:436,126:400},{22:281,26:$Vq,31:$Vt,62:$Vz,68:$VA,95:$VH,125:440,126:400},{22:281,26:$Vq,31:$Vt,62:$Vz,68:$VA,95:$VH,125:444,126:400},o($Vt1,[2,208]),{22:130,26:$Vq,31:$Vt,46:$Vv,47:176,62:$Vz,65:$Vl1,68:$VA,70:$Vm1,71:$Vn1,72:$Vo1,74:$Vp1,78:$Vq1,90:106,91:122,95:$VH,103:523,121:$VR,122:177,123:$VS,138:104,141:$VU,142:$Vc,143:$Vd,170:$VV,171:$VW,172:$VX,178:$VY,179:108,180:$VZ},{46:$Vh2},{53:[1,524],64:$Vv2},o($Vf2,[2,331]),{22:130,26:$Vq,31:$Vt,46:$Vv,47:525,62:$Vz,68:$VA,70:$Vm1,71:$Vn1,72:$Vo1,74:$Vp1,78:$Vq1,90:106,91:122,95:$VH,121:$VR,122:177,123:$VS,138:104,141:$VU,142:$Vc,143:$Vd,170:$VV,171:$VW,172:$VX,178:$VY,179:108,180:$VZ},o($Vf2,[2,333]),{48:[1,526],64:$V33},{22:130,26:$Vq,31:$Vt,46:$Vv,47:176,62:$Vz,65:$Vl1,68:$VA,70:$Vm1,71:$Vn1,72:$Vo1,74:$Vp1,78:$Vq1,90:106,91:122,95:$VH,103:528,121:$VR,122:177,123:$VS,138:104,141:$VU,142:$Vc,143:$Vd,170:$VV,171:$VW,172:$VX,178:$VY,179:108,180:$VZ},o($Vr2,[2,247],{107:$Vu1,155:$Vv1,156:$Vw1,157:$Vx1,158:$Vy1,159:$Vz1,160:$VA1,161:$VB1,162:$VC1,163:$VD1,164:$VE1,165:$VF1,166:$VG1,167:$VH1,168:$VI1,169:$VJ1,171:$VK1,172:$VL1,173:$VM1,174:$VN1,175:$VO1,176:$VP1,177:$VQ1}),{48:[1,529],107:$Vu1,155:$Vv1,156:$Vw1,157:$Vx1,158:$Vy1,159:$Vz1,160:$VA1,161:$VB1,162:$VC1,163:$VD1,164:$VE1,165:$VF1,166:$VG1,167:$VH1,168:$VI1,169:$VJ1,171:$VK1,172:$VL1,173:$VM1,174:$VN1,175:$VO1,176:$VP1,177:$VQ1},{22:130,26:$Vq,31:$Vt,46:$Vv,47:530,62:$Vz,68:$VA,70:$Vm1,71:$Vn1,72:$Vo1,74:$Vp1,78:$Vq1,90:106,91:122,95:$VH,121:$VR,122:177,123:$VS,138:104,141:$VU,142:$Vc,143:$Vd,170:$VV,171:$VW,172:$VX,178:$VY,179:108,180:$VZ},{22:281,26:$Vq,31:$Vt,62:$Vz,68:$VA,95:$VH,126:531},{22:130,26:$Vq,31:$Vt,46:$Vv,47:532,62:$Vz,68:$VA,70:$Vm1,71:$Vn1,72:$Vo1,74:$Vp1,78:$Vq1,90:106,91:122,95:$VH,121:$VR,122:177,123:$VS,138:104,141:$VU,142:$Vc,143:$Vd,170:$VV,171:$VW,172:$VX,178:$VY,179:108,180:$VZ},{53:[1,533],64:$VJ2},{48:[1,534],107:$Vu1,155:$Vv1,156:$Vw1,157:$Vx1,158:$Vy1,159:$Vz1,160:$VA1,161:$VB1,162:$VC1,163:$VD1,164:$VE1,165:$VF1,166:$VG1,167:$VH1,168:$VI1,169:$VJ1,171:$VK1,172:$VL1,173:$VM1,174:$VN1,175:$VO1,176:$VP1,177:$VQ1},{22:130,26:$Vq,31:$Vt,46:$Vv,47:535,62:$Vz,68:$VA,70:$Vm1,71:$Vn1,72:$Vo1,74:$Vp1,78:$Vq1,90:106,91:122,95:$VH,121:$VR,122:177,123:$VS,138:104,141:$VU,142:$Vc,143:$Vd,170:$VV,171:$VW,172:$VX,178:$VY,179:108,180:$VZ},{22:130,26:$Vq,31:$Vt,46:$Vv,47:536,62:$Vz,68:$VA,70:$Vm1,71:$Vn1,72:$Vo1,74:$Vp1,78:$Vq1,90:106,91:122,95:$VH,121:$VR,122:177,123:$VS,138:104,141:$VU,142:$Vc,143:$Vd,170:$VV,171:$VW,172:$VX,178:$VY,179:108,180:$VZ},{53:[1,537],64:$VJ2},{48:[1,538],107:$Vu1,155:$Vv1,156:$Vw1,157:$Vx1,158:$Vy1,159:$Vz1,160:$VA1,161:$VB1,162:$VC1,163:$VD1,164:$VE1,165:$VF1,166:$VG1,167:$VH1,168:$VI1,169:$VJ1,171:$VK1,172:$VL1,173:$VM1,174:$VN1,175:$VO1,176:$VP1,177:$VQ1},{22:130,26:$Vq,31:$Vt,46:$Vv,47:539,62:$Vz,68:$VA,70:$Vm1,71:$Vn1,72:$Vo1,74:$Vp1,78:$Vq1,90:106,91:122,95:$VH,121:$VR,122:177,123:$VS,138:104,141:$VU,142:$Vc,143:$Vd,170:$VV,171:$VW,172:$VX,178:$VY,179:108,180:$VZ},{22:130,26:$Vq,31:$Vt,46:$Vv,47:540,62:$Vz,68:$VA,70:$Vm1,71:$Vn1,72:$Vo1,74:$Vp1,78:$Vq1,90:106,91:122,95:$VH,121:$VR,122:177,123:$VS,138:104,141:$VU,142:$Vc,143:$Vd,170:$VV,171:$VW,172:$VX,178:$VY,179:108,180:$VZ},{53:[1,541],64:$VJ2},{48:[1,542],107:$Vu1,155:$Vv1,156:$Vw1,157:$Vx1,158:$Vy1,159:$Vz1,160:$VA1,161:$VB1,162:$VC1,163:$VD1,164:$VE1,165:$VF1,166:$VG1,167:$VH1,168:$VI1,169:$VJ1,171:$VK1,172:$VL1,173:$VM1,174:$VN1,175:$VO1,176:$VP1,177:$VQ1},{22:130,26:$Vq,31:$Vt,46:$Vv,47:543,62:$Vz,68:$VA,70:$Vm1,71:$Vn1,72:$Vo1,74:$Vp1,78:$Vq1,90:106,91:122,95:$VH,121:$VR,122:177,123:$VS,138:104,141:$VU,142:$Vc,143:$Vd,170:$VV,171:$VW,172:$VX,178:$VY,179:108,180:$VZ},{22:130,26:$Vq,31:$Vt,46:$Vv,47:544,62:$Vz,68:$VA,70:$Vm1,71:$Vn1,72:$Vo1,74:$Vp1,78:$Vq1,90:106,91:122,95:$VH,121:$VR,122:177,123:$VS,138:104,141:$VU,142:$Vc,143:$Vd,170:$VV,171:$VW,172:$VX,178:$VY,179:108,180:$VZ},{53:[1,545],64:$VJ2},{22:130,26:$Vq,31:$Vt,46:$Vv,47:546,62:$Vz,68:$VA,70:$Vm1,71:$Vn1,72:$Vo1,74:$Vp1,78:$Vq1,90:106,91:122,95:$VH,121:$VR,122:177,123:$VS,138:104,141:$VU,142:$Vc,143:$Vd,170:$VV,171:$VW,172:$VX,178:$VY,179:108,180:$VZ},{127:[2,206]},o($VN2,[2,204],{22:130,91:237,122:548,26:$Vq,31:$Vt,46:$V$1,62:$Vz,65:[1,547],68:$VA,95:$VH,141:$V02,178:$V12,180:$VZ}),{22:130,26:$Vq,31:$Vt,46:$Vv,47:549,62:$Vz,68:$VA,70:$Vm1,71:$Vn1,72:$Vo1,74:$Vp1,78:$Vq1,90:106,91:122,95:$VH,121:$VR,122:177,123:$VS,138:104,141:$VU,142:$Vc,143:$Vd,170:$VV,171:$VW,172:$VX,178:$VY,179:108,180:$VZ},{53:[1,550],107:$Vu1,155:$Vv1,156:$Vw1,157:$Vx1,158:$Vy1,159:$Vz1,160:$VA1,161:$VB1,162:$VC1,163:$VD1,164:$VE1,165:$VF1,166:$VG1,167:$VH1,168:$VI1,169:$VJ1,171:$VK1,172:$VL1,173:$VM1,174:$VN1,175:$VO1,176:$VP1,177:$VQ1},o($Vo2,[2,343],{151:$V43}),o($V53,[2,352]),o($V53,[2,353]),o($Vo2,[2,344],{151:$V43}),o($Vo2,[2,345],{151:$V43}),o($Vo2,[2,347],{151:$V43}),o($Vo2,[2,349],{151:$V43}),{51:[1,552],55:$V$,60:553,67:354,70:$V11,71:$V21,72:$V31,73:$V41,74:$V51,77:$V61,78:$V71,79:$V81,80:$V91,81:$Va1,82:$Vb1,83:$Vc1},{8:$Vn,11:86,12:75,13:71,14:72,15:76,16:77,17:78,18:79,19:80,20:82,21:$Vo,22:130,23:81,24:$Vp,26:$Vq,27:87,28:$Vr,30:$Vs,31:$Vt,32:554,34:68,35:69,36:67,37:65,38:66,44:83,45:$Vu,46:$Vv,47:73,49:$Vw,51:$Vx,54:20,55:$Vy,56:$V2,61:$V3,62:$Vz,68:$VA,70:$VB,71:$VC,72:$VD,73:$VE,74:$VF,77:$V5,78:$VG,79:$V6,80:$V7,82:$V8,83:$V9,85:90,86:70,88:74,90:106,91:122,95:$VH,96:$VI,97:91,98:92,99:93,100:$VJ,101:$VK,104:$VL,108:$VM,109:$VN,110:$VO,111:$VP,113:$VQ,121:$VR,122:100,123:$VS,124:118,129:$VT,135:120,137:$Va,138:104,141:$VU,142:$Vc,143:$Vd,154:$Vb,170:$VV,171:$VW,172:$VX,178:$VY,179:108,180:$VZ},{48:[2,65]},o($Vr2,[2,68]),o($Vr2,[2,72],{51:$VB2}),o($Vr2,[2,73],{51:$VB2}),{28:[1,555]},{48:[1,556]},{48:[1,557]},o($Vd1,[2,266],{107:$Vu1,155:$Vv1,156:$Vw1,157:$Vx1,158:$Vy1,159:$Vz1,160:$VA1,161:$VB1,162:$VC1,163:$VD1,164:$VE1,165:$VF1,166:$VG1,167:$VH1,168:$VI1,169:$VJ1,171:$VK1,172:$VL1,173:$VM1,174:$VN1,175:$VO1,176:$VP1,177:$VQ1}),{22:130,26:$Vq,31:$Vt,46:$Vv,47:558,51:$VE2,62:$Vz,68:$VA,70:$Vm1,71:$Vn1,72:$Vo1,74:$Vp1,78:$Vq1,90:106,91:122,95:$VH,121:$VR,122:177,123:$VS,136:559,138:104,141:$VU,142:$Vc,143:$Vd,170:$VV,171:$VW,172:$VX,178:$VY,179:108,180:$VZ},o($Ve,[2,215]),o($Vi1,[2,254]),{53:[1,560],107:$Vu1,155:$Vv1,156:$Vw1,157:$Vx1,158:$Vy1,159:$Vz1,160:$VA1,161:$VB1,162:$VC1,163:$VD1,164:$VE1,165:$VF1,166:$VG1,167:$VH1,168:$VI1,169:$VJ1,171:$VK1,172:$VL1,173:$VM1,174:$VN1,175:$VO1,176:$VP1,177:$VQ1},o($Vi1,[2,253]),{26:[1,561]},{26:$Vj,68:$Vk,95:$Vl,143:$Vm,149:53,150:56,152:562},o($Vd1,[2,282]),{28:[1,563]},{8:$Vn,11:86,12:75,13:71,14:72,15:76,16:77,17:78,18:79,19:80,20:82,21:$Vo,22:130,23:81,24:$Vp,26:$Vq,27:87,28:$Vr,30:$Vs,31:$Vt,32:564,34:68,35:69,36:67,37:65,38:66,44:83,45:$Vu,46:$Vv,47:73,49:$Vw,51:$Vx,54:20,55:$Vy,56:$V2,61:$V3,62:$Vz,68:$VA,70:$VB,71:$VC,72:$VD,73:$VE,74:$VF,77:$V5,78:$VG,79:$V6,80:$V7,82:$V8,83:$V9,85:90,86:70,88:74,90:106,91:122,95:$VH,96:$VI,97:91,98:92,99:93,100:$VJ,101:$VK,104:$VL,108:$VM,109:$VN,110:$VO,111:$VP,113:$VQ,121:$VR,122:100,123:$VS,124:118,129:$VT,135:120,137:$Va,138:104,141:$VU,142:$Vc,143:$Vd,154:$Vb,170:$VV,171:$VW,172:$VX,178:$VY,179:108,180:$VZ},{22:130,26:$Vq,31:$Vt,46:$Vv,47:565,62:$Vz,68:$VA,70:$Vm1,71:$Vn1,72:$Vo1,74:$Vp1,78:$Vq1,90:106,91:122,95:$VH,121:$VR,122:177,123:$VS,138:104,141:$VU,142:$Vc,143:$Vd,170:$VV,171:$VW,172:$VX,178:$VY,179:108,180:$VZ},o($Vw2,[2,249],{107:$Vu1,155:$Vv1,156:$Vw1,157:$Vx1,158:$Vy1,159:$Vz1,160:$VA1,161:$VB1,162:$VC1,163:$VD1,164:$VE1,165:$VF1,166:$VG1,167:$VH1,168:$VI1,169:$VJ1,171:$VK1,172:$VL1,173:$VM1,174:$VN1,175:$VO1,176:$VP1,177:$VQ1}),o($VR2,[2,96],{51:$VB2}),{22:130,26:$Vq,31:$Vt,46:$Vv,47:566,62:$Vz,68:$VA,70:$Vm1,71:$Vn1,72:$Vo1,74:$Vp1,78:$Vq1,90:106,91:122,95:$VH,121:$VR,122:177,123:$VS,138:104,141:$VU,142:$Vc,143:$Vd,170:$VV,171:$VW,172:$VX,178:$VY,179:108,180:$VZ},{8:$Vn,11:86,12:75,13:71,14:72,15:76,16:77,17:78,18:79,19:80,20:82,21:$Vo,22:130,23:81,24:$Vp,26:$Vq,27:87,28:$Vr,31:$Vt,33:567,34:255,35:256,36:372,44:83,45:$Vu,46:$Vv,47:73,49:$Vw,51:$Vx,54:20,55:$Vy,56:$V2,61:$V3,62:$Vz,68:$VA,70:$VB,71:$VC,72:$VD,73:$VE,74:$VF,77:$V5,78:$VG,79:$V6,80:$V7,82:$V8,83:$V9,85:90,86:70,88:74,90:106,91:122,95:$VH,96:$VI,97:91,98:92,99:93,100:$VJ,101:$VK,104:$VL,108:$VM,109:$VN,110:$VO,111:$VP,113:$VQ,121:$VR,122:100,123:$VS,124:118,129:$VT,135:120,137:$Va,138:104,141:$VU,142:$Vc,143:$Vd,154:$Vb,170:$VV,171:$VW,172:$VX,178:$VY,179:108,180:$VZ},o($VR1,[2,50]),{26:[1,568]},{22:130,26:$Vq,28:$Vz2,31:$Vt,46:$Vv,47:377,51:$VA2,62:$Vz,68:$VA,70:$Vm1,71:$Vn1,72:$Vo1,74:$Vp1,78:$Vq1,89:569,90:106,91:122,95:$VH,121:$VR,122:177,123:$VS,138:104,141:$VU,142:$Vc,143:$Vd,170:$VV,171:$VW,172:$VX,178:$VY,179:108,180:$VZ},o($VR1,[2,51]),{22:130,26:$Vq,28:$Vz2,31:$Vt,46:$Vv,47:377,51:$VA2,62:$Vz,68:$VA,70:$Vm1,71:$Vn1,72:$Vo1,74:$Vp1,78:$Vq1,89:570,90:106,91:122,95:$VH,121:$VR,122:177,123:$VS,138:104,141:$VU,142:$Vc,143:$Vd,170:$VV,171:$VW,172:$VX,178:$VY,179:108,180:$VZ},{30:[1,571],64:$VW2},{53:[1,572],64:$VY2},o($Ve1,[2,323]),{48:[1,573],107:$Vu1,155:$Vv1,156:$Vw1,157:$Vx1,158:$Vy1,159:$Vz1,160:$VA1,161:$VB1,162:$VC1,163:$VD1,164:$VE1,165:$VF1,166:$VG1,167:$VH1,168:$VI1,169:$VJ1,171:$VK1,172:$VL1,173:$VM1,174:$VN1,175:$VO1,176:$VP1,177:$VQ1},o($V_2,[2,93]),{53:[1,574],64:$V63},o($VN2,[2,233],{58:$V73,65:$V83}),o($V93,$Va3,{58:[1,578],107:$Vu1,118:$Vb3,155:$Vv1,156:$Vw1,157:$Vx1,158:$Vy1,159:$Vz1,160:$VA1,161:$VB1,162:$VC1,163:$VD1,164:$VE1,165:$VF1,166:$VG1,167:$VH1,168:$VI1,169:$VJ1,171:$VK1,172:$VL1,173:$VM1,174:$VN1,175:$VO1,176:$VP1,177:$VQ1}),{22:130,26:$Vq,31:$Vt,46:$Vv,47:494,51:$V$2,62:$Vz,68:$VA,70:$Vm1,71:$Vn1,72:$Vo1,74:$Vp1,78:$Vq1,90:106,91:122,95:$VH,121:$VR,122:177,123:$VS,138:104,141:$VU,142:$Vc,143:$Vd,144:580,145:493,170:$VV,171:$VW,172:$VX,178:$VY,179:108,180:$VZ},{180:$V03},{22:130,26:$Vq,31:$Vt,62:$Vz,68:$VA,91:581,95:$VH},{46:[1,582]},o($Vt1,[2,19],{28:[1,583]}),{30:[1,584]},{8:$Vn,30:[2,39],35:585},o($Vc3,[2,98]),o($Vc3,[2,99]),o($Vc3,[2,100]),o($Vc3,[2,101]),o($Vc3,[2,102]),o($Vc3,[2,103]),o($Vc3,[2,104]),o($Vc3,[2,105]),o($Vc3,[2,106]),{22:130,26:$Vq,31:$Vt,46:$Vv,47:587,53:[1,586],62:$Vz,68:$VA,70:$Vm1,71:$Vn1,72:$Vo1,74:$Vp1,78:$Vq1,90:106,91:122,95:$VH,121:$VR,122:177,123:$VS,138:104,141:$VU,142:$Vc,143:$Vd,170:$VV,171:$VW,172:$VX,178:$VY,179:108,180:$VZ},o($Vd3,[2,188]),{53:[1,588],107:$Vu1,155:$Vv1,156:$Vw1,157:$Vx1,158:$Vy1,159:$Vz1,160:$VA1,161:$VB1,162:$VC1,163:$VD1,164:$VE1,165:$VF1,166:$VG1,167:$VH1,168:$VI1,169:$VJ1,171:$VK1,172:$VL1,173:$VM1,174:$VN1,175:$VO1,176:$VP1,177:$VQ1},o($Vt1,[2,182],{107:$Vu1,155:$Vv1,156:$Vw1,157:$Vx1,158:$Vy1,159:$Vz1,160:$VA1,161:$VB1,162:$VC1,163:$VD1,164:$VE1,165:$VF1,166:$VG1,167:$VH1,168:$VI1,169:$VJ1,171:$VK1,172:$VL1,173:$VM1,174:$VN1,175:$VO1,176:$VP1,177:$VQ1}),{127:[1,589]},{22:130,26:$Vq,31:$Vt,46:$Vv,47:590,62:$Vz,68:$VA,70:$Vm1,71:$Vn1,72:$Vo1,74:$Vp1,78:$Vq1,90:106,91:122,95:$VH,121:$VR,122:177,123:$VS,138:104,141:$VU,142:$Vc,143:$Vd,170:$VV,171:$VW,172:$VX,178:$VY,179:108,180:$VZ},{22:130,26:$Vq,31:$Vt,46:$Vv,47:592,51:[1,593],62:$Vz,68:$VA,70:$Vm1,71:$Vn1,72:$Vo1,74:$Vp1,78:$Vq1,90:106,91:122,95:$VH,102:591,121:$VR,122:177,123:$VS,138:104,141:$VU,142:$Vc,143:$Vd,170:$VV,171:$VW,172:$VX,178:$VY,179:108,180:$VZ},{8:$Vn,11:86,12:75,13:71,14:72,15:76,16:77,17:78,18:79,19:80,20:82,21:$Vo,22:130,23:81,24:$Vp,26:$Vq,27:87,28:$Vr,31:$Vt,33:594,34:255,35:256,36:372,44:83,45:$Vu,46:$Vv,47:73,49:$Vw,51:$Vx,54:20,55:$Vy,56:$V2,61:$V3,62:$Vz,68:$VA,70:$VB,71:$VC,72:$VD,73:$VE,74:$VF,77:$V5,78:$VG,79:$V6,80:$V7,82:$V8,83:$V9,85:90,86:70,88:74,90:106,91:122,95:$VH,96:$VI,97:91,98:92,99:93,100:$VJ,101:$VK,104:$VL,108:$VM,109:$VN,110:$VO,111:$VP,113:$VQ,121:$VR,122:100,123:$VS,124:118,129:$VT,135:120,137:$Va,138:104,141:$VU,142:$Vc,143:$Vd,154:$Vb,170:$VV,171:$VW,172:$VX,178:$VY,179:108,180:$VZ},{22:130,26:$Vq,31:$Vt,46:$Vv,47:595,62:$Vz,68:$VA,70:$Vm1,71:$Vn1,72:$Vo1,74:$Vp1,78:$Vq1,90:106,91:122,95:$VH,121:$VR,122:177,123:$VS,138:104,141:$VU,142:$Vc,143:$Vd,170:$VV,171:$VW,172:$VX,178:$VY,179:108,180:$VZ},{22:130,26:$Vq,31:$Vt,46:$Vv,47:596,62:$Vz,68:$VA,70:$Vm1,71:$Vn1,72:$Vo1,74:$Vp1,78:$Vq1,90:106,91:122,95:$VH,121:$VR,122:177,123:$VS,138:104,141:$VU,142:$Vc,143:$Vd,170:$VV,171:$VW,172:$VX,178:$VY,179:108,180:$VZ},{28:[1,598],112:597},{8:$Vn,11:86,12:75,13:71,14:72,15:76,16:77,17:78,18:79,19:80,20:82,21:$Vo,22:130,23:81,24:$Vp,26:$Vq,27:87,28:$Vr,31:$Vt,33:599,34:255,35:256,36:372,44:83,45:$Vu,46:$Vv,47:73,49:$Vw,51:$Vx,54:20,55:$Vy,56:$V2,61:$V3,62:$Vz,68:$VA,70:$VB,71:$VC,72:$VD,73:$VE,74:$VF,77:$V5,78:$VG,79:$V6,80:$V7,82:$V8,83:$V9,85:90,86:70,88:74,90:106,91:122,95:$VH,96:$VI,97:91,98:92,99:93,100:$VJ,101:$VK,104:$VL,108:$VM,109:$VN,110:$VO,111:$VP,113:$VQ,121:$VR,122:100,123:$VS,124:118,129:$VT,135:120,137:$Va,138:104,141:$VU,142:$Vc,143:$Vd,154:$Vb,170:$VV,171:$VW,172:$VX,178:$VY,179:108,180:$VZ},{53:[1,600],64:$Vv2},o($Vt1,[2,198]),{48:[1,601],107:$Vu1,155:$Vv1,156:$Vw1,157:$Vx1,158:$Vy1,159:$Vz1,160:$VA1,161:$VB1,162:$VC1,163:$VD1,164:$VE1,165:$VF1,166:$VG1,167:$VH1,168:$VI1,169:$VJ1,171:$VK1,172:$VL1,173:$VM1,174:$VN1,175:$VO1,176:$VP1,177:$VQ1},o($Ve1,[2,130]),{22:130,26:$Vq,31:$Vt,46:$Vv,47:602,51:[1,603],62:$Vz,68:$VA,70:$Vm1,71:$Vn1,72:$Vo1,74:$Vp1,78:$Vq1,90:106,91:122,95:$VH,121:$VR,122:177,123:$VS,138:104,141:$VU,142:$Vc,143:$Vd,170:$VV,171:$VW,172:$VX,178:$VY,179:108,180:$VZ},{53:[1,604],64:$Vv2},o($Ve1,[2,320]),{48:[1,605],107:$Vu1,155:$Vv1,156:$Vw1,157:$Vx1,158:$Vy1,159:$Vz1,160:$VA1,161:$VB1,162:$VC1,163:$VD1,164:$VE1,165:$VF1,166:$VG1,167:$VH1,168:$VI1,169:$VJ1,171:$VK1,172:$VL1,173:$VM1,174:$VN1,175:$VO1,176:$VP1,177:$VQ1},o([8,30,53,64,107,108],[2,194]),o($Vt1,[2,177],{107:$Vu1,155:$Vv1,156:$Vw1,157:$Vx1,158:$Vy1,159:$Vz1,160:$VA1,161:$VB1,162:$VC1,163:$VD1,164:$VE1,165:$VF1,166:$VG1,167:$VH1,168:$VI1,169:$VJ1,171:$VK1,172:$VL1,173:$VM1,174:$VN1,175:$VO1,176:$VP1,177:$VQ1}),{127:[1,606]},o($Ve1,[2,321]),{48:[1,607],107:$Vu1,155:$Vv1,156:$Vw1,157:$Vx1,158:$Vy1,159:$Vz1,160:$VA1,161:$VB1,162:$VC1,163:$VD1,164:$VE1,165:$VF1,166:$VG1,167:$VH1,168:$VI1,169:$VJ1,171:$VK1,172:$VL1,173:$VM1,174:$VN1,175:$VO1,176:$VP1,177:$VQ1},o($Vt1,[2,178],{107:$Vu1,155:$Vv1,156:$Vw1,157:$Vx1,158:$Vy1,159:$Vz1,160:$VA1,161:$VB1,162:$VC1,163:$VD1,164:$VE1,165:$VF1,166:$VG1,167:$VH1,168:$VI1,169:$VJ1,171:$VK1,172:$VL1,173:$VM1,174:$VN1,175:$VO1,176:$VP1,177:$VQ1}),{127:[1,608]},o($Ve1,[2,322]),{48:[1,609],107:$Vu1,155:$Vv1,156:$Vw1,157:$Vx1,158:$Vy1,159:$Vz1,160:$VA1,161:$VB1,162:$VC1,163:$VD1,164:$VE1,165:$VF1,166:$VG1,167:$VH1,168:$VI1,169:$VJ1,171:$VK1,172:$VL1,173:$VM1,174:$VN1,175:$VO1,176:$VP1,177:$VQ1},o($Vt1,[2,179],{107:$Vu1,155:$Vv1,156:$Vw1,157:$Vx1,158:$Vy1,159:$Vz1,160:$VA1,161:$VB1,162:$VC1,163:$VD1,164:$VE1,165:$VF1,166:$VG1,167:$VH1,168:$VI1,169:$VJ1,171:$VK1,172:$VL1,173:$VM1,174:$VN1,175:$VO1,176:$VP1,177:$VQ1}),{127:[1,610]},o($Ve1,[2,324]),{48:[1,611],107:$Vu1,155:$Vv1,156:$Vw1,157:$Vx1,158:$Vy1,159:$Vz1,160:$VA1,161:$VB1,162:$VC1,163:$VD1,164:$VE1,165:$VF1,166:$VG1,167:$VH1,168:$VI1,169:$VJ1,171:$VK1,172:$VL1,173:$VM1,174:$VN1,175:$VO1,176:$VP1,177:$VQ1},o($Vt1,[2,180],{107:$Vu1,155:$Vv1,156:$Vw1,157:$Vx1,158:$Vy1,159:$Vz1,160:$VA1,161:$VB1,162:$VC1,163:$VD1,164:$VE1,165:$VF1,166:$VG1,167:$VH1,168:$VI1,169:$VJ1,171:$VK1,172:$VL1,173:$VM1,174:$VN1,175:$VO1,176:$VP1,177:$VQ1}),{127:[1,612]},o($Vt1,[2,181],{107:$Vu1,155:$Vv1,156:$Vw1,157:$Vx1,158:$Vy1,159:$Vz1,160:$VA1,161:$VB1,162:$VC1,163:$VD1,164:$VE1,165:$VF1,166:$VG1,167:$VH1,168:$VI1,169:$VJ1,171:$VK1,172:$VL1,173:$VM1,174:$VN1,175:$VO1,176:$VP1,177:$VQ1}),{53:[1,613]},o($VN2,[2,203]),{53:[1,614],107:$Vu1,155:$Vv1,156:$Vw1,157:$Vx1,158:$Vy1,159:$Vz1,160:$VA1,161:$VB1,162:$VC1,163:$VD1,164:$VE1,165:$VF1,166:$VG1,167:$VH1,168:$VI1,169:$VJ1,171:$VK1,172:$VL1,173:$VM1,174:$VN1,175:$VO1,176:$VP1,177:$VQ1},o($Ve3,[2,342]),{26:[1,615],143:[1,616]},{55:$V$,59:617,60:618,67:354,70:$V11,71:$V21,72:$V31,73:$V41,74:$V51,77:$V61,78:$V71,79:$V81,80:$V91,81:$Va1,82:$Vb1,83:$Vc1},{28:[1,619]},{30:[1,620]},{8:$Vn,11:86,12:75,13:71,14:72,15:76,16:77,17:78,18:79,19:80,20:82,21:$Vo,22:130,23:81,24:$Vp,26:$Vq,27:87,28:$Vr,30:$Vs,31:$Vt,32:621,34:68,35:69,36:67,37:65,38:66,44:83,45:$Vu,46:$Vv,47:73,49:$Vw,51:$Vx,54:20,55:$Vy,56:$V2,61:$V3,62:$Vz,68:$VA,70:$VB,71:$VC,72:$VD,73:$VE,74:$VF,77:$V5,78:$VG,79:$V6,80:$V7,82:$V8,83:$V9,85:90,86:70,88:74,90:106,91:122,95:$VH,96:$VI,97:91,98:92,99:93,100:$VJ,101:$VK,104:$VL,108:$VM,109:$VN,110:$VO,111:$VP,113:$VQ,121:$VR,122:100,123:$VS,124:118,129:$VT,135:120,137:$Va,138:104,141:$VU,142:$Vc,143:$Vd,154:$Vb,170:$VV,171:$VW,172:$VX,178:$VY,179:108,180:$VZ},{28:[1,622]},{28:[1,623]},o($Vd1,[2,269],{107:$Vu1,155:$Vv1,156:$Vw1,157:$Vx1,158:$Vy1,159:$Vz1,160:$VA1,161:$VB1,162:$VC1,163:$VD1,164:$VE1,165:$VF1,166:$VG1,167:$VH1,168:$VI1,169:$VJ1,171:$VK1,172:$VL1,173:$VM1,174:$VN1,175:$VO1,176:$VP1,177:$VQ1}),o($Vt2,[2,270]),o($Vi1,[2,255]),{48:[1,625],64:[1,624]},o($Vd1,[2,277],{64:$Vh1}),{8:$Vn,11:86,12:75,13:71,14:72,15:76,16:77,17:78,18:79,19:80,20:82,21:$Vo,22:130,23:81,24:$Vp,26:$Vq,27:87,28:$Vr,30:$Vs,31:$Vt,32:626,34:68,35:69,36:67,37:65,38:66,44:83,45:$Vu,46:$Vv,47:73,49:$Vw,51:$Vx,54:20,55:$Vy,56:$V2,61:$V3,62:$Vz,68:$VA,70:$VB,71:$VC,72:$VD,73:$VE,74:$VF,77:$V5,78:$VG,79:$V6,80:$V7,82:$V8,83:$V9,85:90,86:70,88:74,90:106,91:122,95:$VH,96:$VI,97:91,98:92,99:93,100:$VJ,101:$VK,104:$VL,108:$VM,109:$VN,110:$VO,111:$VP,113:$VQ,121:$VR,122:100,123:$VS,124:118,129:$VT,135:120,137:$Va,138:104,141:$VU,142:$Vc,143:$Vd,154:$Vb,170:$VV,171:$VW,172:$VX,178:$VY,179:108,180:$VZ},{30:[1,627]},o($Vw2,[2,248],{107:$Vu1,155:$Vv1,156:$Vw1,157:$Vx1,158:$Vy1,159:$Vz1,160:$VA1,161:$VB1,162:$VC1,163:$VD1,164:$VE1,165:$VF1,166:$VG1,167:$VH1,168:$VI1,169:$VJ1,171:$VK1,172:$VL1,173:$VM1,174:$VN1,175:$VO1,176:$VP1,177:$VQ1}),o([6,8,30,31,48,53,55,56,58,61,62,64,65,74,77,79,80,82,83,87,108,118,137,146,147,154],[2,292],{107:$Vu1,155:$Vv1,156:$Vw1,157:$Vx1,158:$Vy1,159:$Vz1,160:$VA1,161:$VB1,162:$VC1,163:$VD1,164:$VE1,165:$VF1,166:$VG1,167:$VH1,168:$VI1,169:$VJ1,171:$VK1,172:$VL1,173:$VM1,174:$VN1,175:$VO1,176:$VP1,177:$VQ1}),o($VR1,[2,48]),o($VX2,[2,125],{58:[1,628]}),o($VX2,[2,126]),o($VN2,[2,128]),o($VZ2,[2,122]),o($VZ2,[2,123]),o($Ve1,[2,328]),o($Vf3,[2,219],{58:[1,630],65:[1,629]}),{22:130,26:$Vq,31:$Vt,46:$Vv,47:632,51:$V$2,62:$Vz,68:$VA,70:$Vm1,71:$Vn1,72:$Vo1,74:$Vp1,78:$Vq1,90:106,91:122,95:$VH,121:$VR,122:177,123:$VS,138:104,141:$VU,142:$Vc,143:$Vd,145:631,170:$VV,171:$VW,172:$VX,178:$VY,179:108,180:$VZ},{22:130,26:$Vq,31:$Vt,46:$Vv,47:633,62:$Vz,68:$VA,70:$Vm1,71:$Vn1,72:$Vo1,74:$Vp1,78:$Vq1,90:106,91:122,95:$VH,121:$VR,122:177,123:$VS,138:104,141:$VU,142:$Vc,143:$Vd,170:$VV,171:$VW,172:$VX,178:$VY,179:108,180:$VZ},o($Vg3,[2,240]),{22:130,26:$Vq,31:$Vt,46:$Vv,47:634,62:$Vz,68:$VA,70:$Vm1,71:$Vn1,72:$Vo1,74:$Vp1,78:$Vq1,90:106,91:122,95:$VH,121:$VR,122:177,123:$VS,138:104,141:$VU,142:$Vc,143:$Vd,170:$VV,171:$VW,172:$VX,178:$VY,179:108,180:$VZ},{22:130,26:$Vq,31:$Vt,46:$Vv,47:635,62:$Vz,68:$VA,70:$Vm1,71:$Vn1,72:$Vo1,74:$Vp1,78:$Vq1,90:106,91:122,95:$VH,121:$VR,122:177,123:$VS,138:104,141:$VU,142:$Vc,143:$Vd,170:$VV,171:$VW,172:$VX,178:$VY,179:108,180:$VZ},{53:[1,636],64:$V63},o($Vf2,[2,336]),o($Vr2,$VH2,{138:104,90:106,179:108,91:122,22:130,122:177,47:427,92:637,26:$Vq,31:$Vt,46:$Vv,51:$VI2,62:$Vz,68:$VA,70:$Vm1,71:$Vn1,72:$Vo1,74:$Vp1,78:$Vq1,95:$VH,121:$VR,123:$VS,141:$VU,142:$Vc,143:$Vd,170:$VV,171:$VW,172:$VX,178:$VY,180:$VZ}),{13:503,14:504,15:505,16:506,17:507,18:508,19:509,24:$V92,29:638,30:$V13,39:501,55:$Va2,70:$Vb2,71:$Vc2,72:$Vd2,73:$VE,74:$V4,77:$V5,78:$Ve2,79:$V6,80:$V7,82:$V8,83:$V9,84:502,85:510,124:118,154:$Vb},o($VR1,[2,20]),{8:$Vs1,13:503,14:504,15:505,16:506,17:507,18:508,19:509,24:$V92,30:[2,40],55:$Va2,70:$Vb2,71:$Vc2,72:$Vd2,73:$VE,74:$V4,77:$V5,78:$Ve2,79:$V6,80:$V7,82:$V8,83:$V9,84:639,85:510,124:118,154:$Vb},o($Vd3,[2,190]),{53:[1,640],107:$Vu1,155:$Vv1,156:$Vw1,157:$Vx1,158:$Vy1,159:$Vz1,160:$VA1,161:$VB1,162:$VC1,163:$VD1,164:$VE1,165:$VF1,166:$VG1,167:$VH1,168:$VI1,169:$VJ1,171:$VK1,172:$VL1,173:$VM1,174:$VN1,175:$VO1,176:$VP1,177:$VQ1},o($Vd3,[2,189]),{51:[1,641]},{8:[1,642],107:$Vu1,155:$Vv1,156:$Vw1,157:$Vx1,158:$Vy1,159:$Vz1,160:$VA1,161:$VB1,162:$VC1,163:$VD1,164:$VE1,165:$VF1,166:$VG1,167:$VH1,168:$VI1,169:$VJ1,171:$VK1,172:$VL1,173:$VM1,174:$VN1,175:$VO1,176:$VP1,177:$VQ1},{48:[1,643]},{48:[2,142],107:$Vu1,155:$Vv1,156:$Vw1,157:$Vx1,158:$Vy1,159:$Vz1,160:$VA1,161:$VB1,162:$VC1,163:$VD1,164:$VE1,165:$VF1,166:$VG1,167:$VH1,168:$VI1,169:$VJ1,171:$VK1,172:$VL1,173:$VM1,174:$VN1,175:$VO1,176:$VP1,177:$VQ1},{22:130,26:$Vq,31:$Vt,46:$Vv,47:176,62:$Vz,65:$Vl1,68:$VA,70:$Vm1,71:$Vn1,72:$Vo1,74:$Vp1,78:$Vq1,90:106,91:122,95:$VH,103:644,121:$VR,122:177,123:$VS,138:104,141:$VU,142:$Vc,143:$Vd,170:$VV,171:$VW,172:$VX,178:$VY,179:108,180:$VZ},o($VR1,[2,146]),{48:[1,645],107:$Vu1,155:$Vv1,156:$Vw1,157:$Vx1,158:$Vy1,159:$Vz1,160:$VA1,161:$VB1,162:$VC1,163:$VD1,164:$VE1,165:$VF1,166:$VG1,167:$VH1,168:$VI1,169:$VJ1,171:$VK1,172:$VL1,173:$VM1,174:$VN1,175:$VO1,176:$VP1,177:$VQ1},{48:[1,646],107:$Vu1,155:$Vv1,156:$Vw1,157:$Vx1,158:$Vy1,159:$Vz1,160:$VA1,161:$VB1,162:$VC1,163:$VD1,164:$VE1,165:$VF1,166:$VG1,167:$VH1,168:$VI1,169:$VJ1,171:$VK1,172:$VL1,173:$VM1,174:$VN1,175:$VO1,176:$VP1,177:$VQ1},o($VR1,[2,150]),{115:647,119:[1,648]},o([8,21,24,26,28,30,31,45,46,49,51,55,56,61,62,68,70,71,72,73,74,77,78,79,80,82,83,95,96,100,101,104,108,109,110,111,113,116,119,121,123,129,137,141,142,143,154,170,171,172,178,180],[2,151],{114:[1,649]}),o($Vt1,[2,209]),o($Vf2,[2,332]),o($Vr2,[2,244],{107:$Vu1,155:$Vv1,156:$Vw1,157:$Vx1,158:$Vy1,159:$Vz1,160:$VA1,161:$VB1,162:$VC1,163:$VD1,164:$VE1,165:$VF1,166:$VG1,167:$VH1,168:$VI1,169:$VJ1,171:$VK1,172:$VL1,173:$VM1,174:$VN1,175:$VO1,176:$VP1,177:$VQ1}),{22:130,26:$Vq,31:$Vt,46:$Vv,47:176,62:$Vz,65:$Vl1,68:$VA,70:$Vm1,71:$Vn1,72:$Vo1,74:$Vp1,78:$Vq1,90:106,91:122,95:$VH,103:650,121:$VR,122:177,123:$VS,138:104,141:$VU,142:$Vc,143:$Vd,170:$VV,171:$VW,172:$VX,178:$VY,179:108,180:$VZ},o($Vr2,[2,246]),o($Ve1,[2,325]),{51:[1,651]},o($Ve1,[2,326]),{51:[1,652]},o($Ve1,[2,327]),{51:[1,653]},o($Ve1,[2,329]),{51:[1,654]},{127:[2,207]},o($Ve3,[2,341]),o($V53,[2,350]),o($V53,[2,351]),{53:[1,655],64:[1,656]},o($VN2,[2,92]),{8:$Vn,11:86,12:75,13:71,14:72,15:76,16:77,17:78,18:79,19:80,20:82,21:$Vo,22:130,23:81,24:$Vp,26:$Vq,27:87,28:$Vr,30:$Vs,31:$Vt,32:657,34:68,35:69,36:67,37:65,38:66,44:83,45:$Vu,46:$Vv,47:73,49:$Vw,51:$Vx,54:20,55:$Vy,56:$V2,61:$V3,62:$Vz,68:$VA,70:$VB,71:$VC,72:$VD,73:$VE,74:$VF,77:$V5,78:$VG,79:$V6,80:$V7,82:$V8,83:$V9,85:90,86:70,88:74,90:106,91:122,95:$VH,96:$VI,97:91,98:92,99:93,100:$VJ,101:$VK,104:$VL,108:$VM,109:$VN,110:$VO,111:$VP,113:$VQ,121:$VR,122:100,123:$VS,124:118,129:$VT,135:120,137:$Va,138:104,141:$VU,142:$Vc,143:$Vd,154:$Vb,170:$VV,171:$VW,172:$VX,178:$VY,179:108,180:$VZ},o($Vh3,[2,60]),{30:[1,658]},{8:$Vn,11:86,12:75,13:71,14:72,15:76,16:77,17:78,18:79,19:80,20:82,21:$Vo,22:130,23:81,24:$Vp,26:$Vq,27:87,28:$Vr,30:$Vs,31:$Vt,32:659,34:68,35:69,36:67,37:65,38:66,44:83,45:$Vu,46:$Vv,47:73,49:$Vw,51:$Vx,54:20,55:$Vy,56:$V2,61:$V3,62:$Vz,68:$VA,70:$VB,71:$VC,72:$VD,73:$VE,74:$VF,77:$V5,78:$VG,79:$V6,80:$V7,82:$V8,83:$V9,85:90,86:70,88:74,90:106,91:122,95:$VH,96:$VI,97:91,98:92,99:93,100:$VJ,101:$VK,104:$VL,108:$VM,109:$VN,110:$VO,111:$VP,113:$VQ,121:$VR,122:100,123:$VS,124:118,129:$VT,135:120,137:$Va,138:104,141:$VU,142:$Vc,143:$Vd,154:$Vb,170:$VV,171:$VW,172:$VX,178:$VY,179:108,180:$VZ},{8:$Vn,11:86,12:75,13:71,14:72,15:76,16:77,17:78,18:79,19:80,20:82,21:$Vo,22:130,23:81,24:$Vp,26:$Vq,27:87,28:$Vr,30:$Vs,31:$Vt,32:660,34:68,35:69,36:67,37:65,38:66,44:83,45:$Vu,46:$Vv,47:73,49:$Vw,51:$Vx,54:20,55:$Vy,56:$V2,61:$V3,62:$Vz,68:$VA,70:$VB,71:$VC,72:$VD,73:$VE,74:$VF,77:$V5,78:$VG,79:$V6,80:$V7,82:$V8,83:$V9,85:90,86:70,88:74,90:106,91:122,95:$VH,96:$VI,97:91,98:92,99:93,100:$VJ,101:$VK,104:$VL,108:$VM,109:$VN,110:$VO,111:$VP,113:$VQ,121:$VR,122:100,123:$VS,124:118,129:$VT,135:120,137:$Va,138:104,141:$VU,142:$Vc,143:$Vd,154:$Vb,170:$VV,171:$VW,172:$VX,178:$VY,179:108,180:$VZ},{22:130,26:$Vq,31:$Vt,46:$Vv,47:176,62:$Vz,65:$Vl1,68:$VA,70:$Vm1,71:$Vn1,72:$Vo1,74:$Vp1,78:$Vq1,90:106,91:122,95:$VH,103:661,121:$VR,122:177,123:$VS,138:104,141:$VU,142:$Vc,143:$Vd,170:$VV,171:$VW,172:$VX,178:$VY,179:108,180:$VZ},{26:[1,662]},{30:[1,663]},o($V0,[2,279]),{22:130,26:$Vq,28:$Vz2,31:$Vt,46:$Vv,47:377,51:$VA2,62:$Vz,68:$VA,70:$Vm1,71:$Vn1,72:$Vo1,74:$Vp1,78:$Vq1,89:664,90:106,91:122,95:$VH,121:$VR,122:177,123:$VS,138:104,141:$VU,142:$Vc,143:$Vd,170:$VV,171:$VW,172:$VX,178:$VY,179:108,180:$VZ},o($Vf3,[2,220]),{22:130,26:$Vq,31:$Vt,46:$Vv,47:665,62:$Vz,68:$VA,70:$Vm1,71:$Vn1,72:$Vo1,74:$Vp1,78:$Vq1,90:106,91:122,95:$VH,121:$VR,122:177,123:$VS,138:104,141:$VU,142:$Vc,143:$Vd,170:$VV,171:$VW,172:$VX,178:$VY,179:108,180:$VZ},o($VN2,[2,223],{58:$V73,65:$V83}),o($V93,$Va3,{58:[1,666],107:$Vu1,118:$Vb3,146:[1,667],147:[1,668],155:$Vv1,156:$Vw1,157:$Vx1,158:$Vy1,159:$Vz1,160:$VA1,161:$VB1,162:$VC1,163:$VD1,164:$VE1,165:$VF1,166:$VG1,167:$VH1,168:$VI1,169:$VJ1,171:$VK1,172:$VL1,173:$VM1,174:$VN1,175:$VO1,176:$VP1,177:$VQ1}),o($Vg3,[2,235],{107:$Vu1,155:$Vv1,156:$Vw1,157:$Vx1,158:$Vy1,159:$Vz1,160:$VA1,161:$VB1,162:$VC1,163:$VD1,164:$VE1,165:$VF1,166:$VG1,167:$VH1,168:$VI1,169:$VJ1,171:$VK1,172:$VL1,173:$VM1,174:$VN1,175:$VO1,176:$VP1,177:$VQ1}),o($VN2,[2,234],{107:$Vu1,118:$Vi3,155:$Vv1,156:$Vw1,157:$Vx1,158:$Vy1,159:$Vz1,160:$VA1,161:$VB1,162:$VC1,163:$VD1,164:$VE1,165:$VF1,166:$VG1,167:$VH1,168:$VI1,169:$VJ1,171:$VK1,172:$VL1,173:$VM1,174:$VN1,175:$VO1,176:$VP1,177:$VQ1}),o($V93,[2,236],{58:[1,670],107:$Vu1,155:$Vv1,156:$Vw1,157:$Vx1,158:$Vy1,159:$Vz1,160:$VA1,161:$VB1,162:$VC1,163:$VD1,164:$VE1,165:$VF1,166:$VG1,167:$VH1,168:$VI1,169:$VJ1,171:$VK1,172:$VL1,173:$VM1,174:$VN1,175:$VO1,176:$VP1,177:$VQ1}),o($Vg3,[2,241]),{48:[1,671],64:$V33},{30:[1,672]},o($Vc3,[2,97]),o($Vd3,[2,191]),{22:130,26:$Vq,31:$Vt,46:$Vv,47:176,62:$Vz,65:$Vl1,68:$VA,70:$Vm1,71:$Vn1,72:$Vo1,74:$Vp1,78:$Vq1,90:106,91:122,95:$VH,103:673,121:$VR,122:177,123:$VS,138:104,141:$VU,142:$Vc,143:$Vd,170:$VV,171:$VW,172:$VX,178:$VY,179:108,180:$VZ},{22:130,26:$Vq,31:$Vt,46:$V$1,62:$Vz,68:$VA,91:237,95:$VH,97:676,106:674,120:675,121:$Vj3,122:679,123:$Vk3,141:$V02,178:$V12,180:$VZ},{8:$Vn,11:86,12:75,13:71,14:72,15:76,16:77,17:78,18:79,19:80,20:82,21:$Vo,22:130,23:81,24:$Vp,26:$Vq,27:87,28:$Vr,31:$Vt,33:680,34:255,35:256,36:372,44:83,45:$Vu,46:$Vv,47:73,49:$Vw,51:$Vx,54:20,55:$Vy,56:$V2,61:$V3,62:$Vz,68:$VA,70:$VB,71:$VC,72:$VD,73:$VE,74:$VF,77:$V5,78:$VG,79:$V6,80:$V7,82:$V8,83:$V9,85:90,86:70,88:74,90:106,91:122,95:$VH,96:$VI,97:91,98:92,99:93,100:$VJ,101:$VK,104:$VL,108:$VM,109:$VN,110:$VO,111:$VP,113:$VQ,121:$VR,122:100,123:$VS,124:118,129:$VT,135:120,137:$Va,138:104,141:$VU,142:$Vc,143:$Vd,154:$Vb,170:$VV,171:$VW,172:$VX,178:$VY,179:108,180:$VZ},{53:[1,681],64:$Vv2},o($VR1,[2,147]),o($VR1,[2,148]),{30:[1,682],116:[1,683],119:[1,684]},{22:130,26:$Vq,31:$Vt,46:$Vv,47:686,62:$Vz,68:$VA,70:$Vm1,71:$Vn1,72:$Vo1,74:$Vp1,78:$Vq1,90:106,91:122,95:$VH,117:685,121:$VR,122:177,123:$VS,138:104,141:$VU,142:$Vc,143:$Vd,170:$VV,171:$VW,172:$VX,178:$VY,179:108,180:$VZ},{8:$Vn,11:86,12:75,13:71,14:72,15:76,16:77,17:78,18:79,19:80,20:82,21:$Vo,22:130,23:81,24:$Vp,26:$Vq,27:87,28:$Vr,31:$Vt,33:687,34:255,35:256,36:372,44:83,45:$Vu,46:$Vv,47:73,49:$Vw,51:$Vx,54:20,55:$Vy,56:$V2,61:$V3,62:$Vz,68:$VA,70:$VB,71:$VC,72:$VD,73:$VE,74:$VF,77:$V5,78:$VG,79:$V6,80:$V7,82:$V8,83:$V9,85:90,86:70,88:74,90:106,91:122,95:$VH,96:$VI,97:91,98:92,99:93,100:$VJ,101:$VK,104:$VL,108:$VM,109:$VN,110:$VO,111:$VP,113:$VQ,121:$VR,122:100,123:$VS,124:118,129:$VT,135:120,137:$Va,138:104,141:$VU,142:$Vc,143:$Vd,154:$Vb,170:$VV,171:$VW,172:$VX,178:$VY,179:108,180:$VZ},{53:[1,688],64:$Vv2},{22:130,26:$Vq,31:$Vt,46:$Vv,47:176,62:$Vz,65:$Vl1,68:$VA,70:$Vm1,71:$Vn1,72:$Vo1,74:$Vp1,78:$Vq1,90:106,91:122,95:$VH,103:689,121:$VR,122:177,123:$VS,138:104,141:$VU,142:$Vc,143:$Vd,170:$VV,171:$VW,172:$VX,178:$VY,179:108,180:$VZ},{22:130,26:$Vq,31:$Vt,46:$Vv,47:176,62:$Vz,65:$Vl1,68:$VA,70:$Vm1,71:$Vn1,72:$Vo1,74:$Vp1,78:$Vq1,90:106,91:122,95:$VH,103:690,121:$VR,122:177,123:$VS,138:104,141:$VU,142:$Vc,143:$Vd,170:$VV,171:$VW,172:$VX,178:$VY,179:108,180:$VZ},{22:130,26:$Vq,31:$Vt,46:$Vv,47:176,62:$Vz,65:$Vl1,68:$VA,70:$Vm1,71:$Vn1,72:$Vo1,74:$Vp1,78:$Vq1,90:106,91:122,95:$VH,103:691,121:$VR,122:177,123:$VS,138:104,141:$VU,142:$Vc,143:$Vd,170:$VV,171:$VW,172:$VX,178:$VY,179:108,180:$VZ},{22:130,26:$Vq,31:$Vt,46:$Vv,47:176,62:$Vz,65:$Vl1,68:$VA,70:$Vm1,71:$Vn1,72:$Vo1,74:$Vp1,78:$Vq1,90:106,91:122,95:$VH,103:692,121:$VR,122:177,123:$VS,138:104,141:$VU,142:$Vc,143:$Vd,170:$VV,171:$VW,172:$VX,178:$VY,179:108,180:$VZ},{28:[1,693]},{55:$V$,60:694,67:354,70:$V11,71:$V21,72:$V31,73:$V41,74:$V51,77:$V61,78:$V71,79:$V81,80:$V91,81:$Va1,82:$Vb1,83:$Vc1},{30:[1,695]},o($Vh3,[2,61]),{30:[1,696]},{30:[1,697]},{48:[1,698],64:$Vv2},{51:[1,699]},o($V0,[2,278]),o($VX2,[2,124]),o($Vf3,[2,221],{65:[1,700],155:$Vv1,156:$Vw1,157:$Vx1,158:$Vy1,159:$Vz1,160:$VA1,161:$VB1,162:$VC1,163:$VD1,164:$VE1,165:$VF1,166:$VG1,167:$VH1,168:$VI1,169:$VJ1,171:$VK1,172:$VL1,173:$VM1,174:$VN1,175:$VO1,176:$VP1,177:$VQ1}),{22:130,26:$Vq,31:$Vt,46:$Vv,47:701,62:$Vz,68:$VA,70:$Vm1,71:$Vn1,72:$Vo1,74:$Vp1,78:$Vq1,90:106,91:122,95:$VH,121:$VR,122:177,123:$VS,138:104,141:$VU,142:$Vc,143:$Vd,170:$VV,171:$VW,172:$VX,178:$VY,179:108,180:$VZ},o($VN2,[2,229],{138:104,90:106,179:108,91:122,22:130,122:177,47:702,26:$Vq,31:$Vt,46:$Vv,62:$Vz,68:$VA,70:$Vm1,71:$Vn1,72:$Vo1,74:$Vp1,78:$Vq1,95:$VH,121:$VR,123:$VS,141:$VU,142:$Vc,143:$Vd,170:$VV,171:$VW,172:$VX,178:$VY,180:$VZ}),o($VN2,[2,230],{138:104,90:106,179:108,91:122,22:130,122:177,47:703,26:$Vq,31:$Vt,46:$Vv,62:$Vz,68:$VA,70:$Vm1,71:$Vn1,72:$Vo1,74:$Vp1,78:$Vq1,95:$VH,121:$VR,123:$VS,141:$VU,142:$Vc,143:$Vd,170:$VV,171:$VW,172:$VX,178:$VY,180:$VZ}),{22:130,26:$Vq,31:$Vt,46:$Vv,47:704,62:$Vz,68:$VA,70:$Vm1,71:$Vn1,72:$Vo1,74:$Vp1,78:$Vq1,90:106,91:122,95:$VH,121:$VR,122:177,123:$VS,138:104,141:$VU,142:$Vc,143:$Vd,170:$VV,171:$VW,172:$VX,178:$VY,179:108,180:$VZ},{22:130,26:$Vq,31:$Vt,46:$Vv,47:705,62:$Vz,68:$VA,70:$Vm1,71:$Vn1,72:$Vo1,74:$Vp1,78:$Vq1,90:106,91:122,95:$VH,121:$VR,122:177,123:$VS,138:104,141:$VU,142:$Vc,143:$Vd,170:$VV,171:$VW,172:$VX,178:$VY,179:108,180:$VZ},o($Vt1,[2,135]),o($VR1,[2,21]),{53:[1,706],64:$Vv2},{48:[1,707],64:[1,708]},o($Vr2,[2,213]),o($Vr2,[2,161]),{22:130,26:$Vq,31:$Vt,46:$V$1,62:$Vz,68:$VA,91:237,95:$VH,122:709,141:$V02,178:$V12,180:$VZ},{22:130,26:$Vq,31:$Vt,46:$V$1,62:$Vz,68:$VA,91:237,95:$VH,122:710,141:$V02,178:$V12,180:$VZ},{121:[1,711],123:[1,712],127:$VX1,130:231,131:$VY1,132:$VZ1,133:$V_1},o($VR1,[2,145]),{48:[2,143]},o($VR1,[2,153]),{8:$Vn,11:86,12:75,13:71,14:72,15:76,16:77,17:78,18:79,19:80,20:82,21:$Vo,22:130,23:81,24:$Vp,26:$Vq,27:87,28:$Vr,31:$Vt,34:68,35:69,36:67,37:713,38:66,44:83,45:$Vu,46:$Vv,47:73,49:$Vw,51:$Vx,54:20,55:$Vy,56:$V2,61:$V3,62:$Vz,68:$VA,70:$VB,71:$VC,72:$VD,73:$VE,74:$VF,77:$V5,78:$VG,79:$V6,80:$V7,82:$V8,83:$V9,85:90,86:70,88:74,90:106,91:122,95:$VH,96:$VI,97:91,98:92,99:93,100:$VJ,101:$VK,104:$VL,108:$VM,109:$VN,110:$VO,111:$VP,113:$VQ,121:$VR,122:100,123:$VS,124:118,129:$VT,135:120,137:$Va,138:104,141:$VU,142:$Vc,143:$Vd,154:$Vb,170:$VV,171:$VW,172:$VX,178:$VY,179:108,180:$VZ},{22:130,26:$Vq,31:$Vt,46:$Vv,47:686,62:$Vz,68:$VA,70:$Vm1,71:$Vn1,72:$Vo1,74:$Vp1,78:$Vq1,90:106,91:122,95:$VH,117:714,121:$VR,122:177,123:$VS,138:104,141:$VU,142:$Vc,143:$Vd,170:$VV,171:$VW,172:$VX,178:$VY,179:108,180:$VZ},{58:[1,715],64:$Vl3},o($Vm3,[2,157],{107:$Vu1,118:[1,717],155:$Vv1,156:$Vw1,157:$Vx1,158:$Vy1,159:$Vz1,160:$VA1,161:$VB1,162:$VC1,163:$VD1,164:$VE1,165:$VF1,166:$VG1,167:$VH1,168:$VI1,169:$VJ1,171:$VK1,172:$VL1,173:$VM1,174:$VN1,175:$VO1,176:$VP1,177:$VQ1}),o($VR1,[2,152]),o($Vr2,[2,245]),{53:[1,718],64:$Vv2},{53:[1,719],64:$Vv2},{53:[1,720],64:$Vv2},{53:[1,721],64:$Vv2},{8:$Vn,11:86,12:75,13:71,14:72,15:76,16:77,17:78,18:79,19:80,20:82,21:$Vo,22:130,23:81,24:$Vp,26:$Vq,27:87,28:$Vr,30:$Vs,31:$Vt,32:722,34:68,35:69,36:67,37:65,38:66,44:83,45:$Vu,46:$Vv,47:73,49:$Vw,51:$Vx,54:20,55:$Vy,56:$V2,61:$V3,62:$Vz,68:$VA,70:$VB,71:$VC,72:$VD,73:$VE,74:$VF,77:$V5,78:$VG,79:$V6,80:$V7,82:$V8,83:$V9,85:90,86:70,88:74,90:106,91:122,95:$VH,96:$VI,97:91,98:92,99:93,100:$VJ,101:$VK,104:$VL,108:$VM,109:$VN,110:$VO,111:$VP,113:$VQ,121:$VR,122:100,123:$VS,124:118,129:$VT,135:120,137:$Va,138:104,141:$VU,142:$Vc,143:$Vd,154:$Vb,170:$VV,171:$VW,172:$VX,178:$VY,179:108,180:$VZ},o($VN2,[2,91]),o($Vh3,[2,59]),o($Vh3,[2,62]),o($Vh3,[2,63]),{26:[1,723]},{22:130,26:$Vq,31:$Vt,46:$Vv,47:724,62:$Vz,68:$VA,70:$Vm1,71:$Vn1,72:$Vo1,74:$Vp1,78:$Vq1,90:106,91:122,95:$VH,121:$VR,122:177,123:$VS,138:104,141:$VU,142:$Vc,143:$Vd,170:$VV,171:$VW,172:$VX,178:$VY,179:108,180:$VZ},o($Vf3,[2,222]),o($VN2,[2,224],{107:$Vu1,118:$Vi3,146:[1,725],147:[1,726],155:$Vv1,156:$Vw1,157:$Vx1,158:$Vy1,159:$Vz1,160:$VA1,161:$VB1,162:$VC1,163:$VD1,164:$VE1,165:$VF1,166:$VG1,167:$VH1,168:$VI1,169:$VJ1,171:$VK1,172:$VL1,173:$VM1,174:$VN1,175:$VO1,176:$VP1,177:$VQ1}),o($VN2,[2,225],{107:$Vu1,155:$Vv1,156:$Vw1,157:$Vx1,158:$Vy1,159:$Vz1,160:$VA1,161:$VB1,162:$VC1,163:$VD1,164:$VE1,165:$VF1,166:$VG1,167:$VH1,168:$VI1,169:$VJ1,171:$VK1,172:$VL1,173:$VM1,174:$VN1,175:$VO1,176:$VP1,177:$VQ1}),o($VN2,[2,226],{107:$Vu1,155:$Vv1,156:$Vw1,157:$Vx1,158:$Vy1,159:$Vz1,160:$VA1,161:$VB1,162:$VC1,163:$VD1,164:$VE1,165:$VF1,166:$VG1,167:$VH1,168:$VI1,169:$VJ1,171:$VK1,172:$VL1,173:$VM1,174:$VN1,175:$VO1,176:$VP1,177:$VQ1}),o($V93,[2,238],{58:[1,727],107:$Vu1,155:$Vv1,156:$Vw1,157:$Vx1,158:$Vy1,159:$Vz1,160:$VA1,161:$VB1,162:$VC1,163:$VD1,164:$VE1,165:$VF1,166:$VG1,167:$VH1,168:$VI1,169:$VJ1,171:$VK1,172:$VL1,173:$VM1,174:$VN1,175:$VO1,176:$VP1,177:$VQ1}),o($Vg3,[2,237],{107:$Vu1,155:$Vv1,156:$Vw1,157:$Vx1,158:$Vy1,159:$Vz1,160:$VA1,161:$VB1,162:$VC1,163:$VD1,164:$VE1,165:$VF1,166:$VG1,167:$VH1,168:$VI1,169:$VJ1,171:$VK1,172:$VL1,173:$VM1,174:$VN1,175:$VO1,176:$VP1,177:$VQ1}),o($V82,[2,187]),{8:$Vn,11:86,12:75,13:71,14:72,15:76,16:77,17:78,18:79,19:80,20:82,21:$Vo,22:130,23:81,24:$Vp,26:$Vq,27:87,28:$Vr,31:$Vt,33:728,34:255,35:256,36:372,44:83,45:$Vu,46:$Vv,47:73,49:$Vw,51:$Vx,54:20,55:$Vy,56:$V2,61:$V3,62:$Vz,68:$VA,70:$VB,71:$VC,72:$VD,73:$VE,74:$VF,77:$V5,78:$VG,79:$V6,80:$V7,82:$V8,83:$V9,85:90,86:70,88:74,90:106,91:122,95:$VH,96:$VI,97:91,98:92,99:93,100:$VJ,101:$VK,104:$VL,108:$VM,109:$VN,110:$VO,111:$VP,113:$VQ,121:$VR,122:100,123:$VS,124:118,129:$VT,135:120,137:$Va,138:104,141:$VU,142:$Vc,143:$Vd,154:$Vb,170:$VV,171:$VW,172:$VX,178:$VY,179:108,180:$VZ},{22:130,26:$Vq,31:$Vt,46:$V$1,62:$Vz,68:$VA,91:237,95:$VH,97:676,120:729,121:$Vj3,122:679,123:$Vk3,141:$V02,178:$V12,180:$VZ},o($Vr2,[2,162]),o($Vr2,[2,163]),o($Vr2,[2,164]),o($Vr2,[2,165]),{30:[1,730]},{58:[1,731],64:$Vl3},{8:$Vn,11:86,12:75,13:71,14:72,15:76,16:77,17:78,18:79,19:80,20:82,21:$Vo,22:130,23:81,24:$Vp,26:$Vq,27:87,28:$Vr,31:$Vt,34:68,35:69,36:733,38:732,44:83,45:$Vu,46:$Vv,47:73,49:$Vw,51:$Vx,54:20,55:$Vy,56:$V2,61:$V3,62:$Vz,68:$VA,70:$VB,71:$VC,72:$VD,73:$VE,74:$VF,77:$V5,78:$VG,79:$V6,80:$V7,82:$V8,83:$V9,85:90,86:70,88:74,90:106,91:122,95:$VH,96:$VI,97:91,98:92,99:93,100:$VJ,101:$VK,104:$VL,108:$VM,109:$VN,110:$VO,111:$VP,113:$VQ,121:$VR,122:100,123:$VS,124:118,129:$VT,135:120,137:$Va,138:104,141:$VU,142:$Vc,143:$Vd,154:$Vb,170:$VV,171:$VW,172:$VX,178:$VY,179:108,180:$VZ},{22:130,26:$Vq,31:$Vt,46:$Vv,47:734,62:$Vz,68:$VA,70:$Vm1,71:$Vn1,72:$Vo1,74:$Vp1,78:$Vq1,90:106,91:122,95:$VH,121:$VR,122:177,123:$VS,138:104,141:$VU,142:$Vc,143:$Vd,170:$VV,171:$VW,172:$VX,178:$VY,179:108,180:$VZ},{22:130,26:$Vq,31:$Vt,46:$Vv,47:735,62:$Vz,68:$VA,70:$Vm1,71:$Vn1,72:$Vo1,74:$Vp1,78:$Vq1,90:106,91:122,95:$VH,121:$VR,122:177,123:$VS,138:104,141:$VU,142:$Vc,143:$Vd,170:$VV,171:$VW,172:$VX,178:$VY,179:108,180:$VZ},o($V82,[2,183]),o($V82,[2,184]),o($V82,[2,185]),o($V82,[2,186]),{30:[1,736]},{51:[1,737]},{53:[1,738],107:$Vu1,155:$Vv1,156:$Vw1,157:$Vx1,158:$Vy1,159:$Vz1,160:$VA1,161:$VB1,162:$VC1,163:$VD1,164:$VE1,165:$VF1,166:$VG1,167:$VH1,168:$VI1,169:$VJ1,171:$VK1,172:$VL1,173:$VM1,174:$VN1,175:$VO1,176:$VP1,177:$VQ1},o($VN2,[2,231],{138:104,90:106,179:108,91:122,22:130,122:177,47:739,26:$Vq,31:$Vt,46:$Vv,62:$Vz,68:$VA,70:$Vm1,71:$Vn1,72:$Vo1,74:$Vp1,78:$Vq1,95:$VH,121:$VR,123:$VS,141:$VU,142:$Vc,143:$Vd,170:$VV,171:$VW,172:$VX,178:$VY,180:$VZ}),o($VN2,[2,232],{138:104,90:106,179:108,91:122,22:130,122:177,47:740,26:$Vq,31:$Vt,46:$Vv,62:$Vz,68:$VA,70:$Vm1,71:$Vn1,72:$Vo1,74:$Vp1,78:$Vq1,95:$VH,121:$VR,123:$VS,141:$VU,142:$Vc,143:$Vd,170:$VV,171:$VW,172:$VX,178:$VY,180:$VZ}),{22:130,26:$Vq,31:$Vt,46:$Vv,47:741,62:$Vz,68:$VA,70:$Vm1,71:$Vn1,72:$Vo1,74:$Vp1,78:$Vq1,90:106,91:122,95:$VH,121:$VR,122:177,123:$VS,138:104,141:$VU,142:$Vc,143:$Vd,170:$VV,171:$VW,172:$VX,178:$VY,179:108,180:$VZ},o($VR1,[2,144]),o($Vr2,[2,212]),o($VR1,[2,154]),{8:$Vn,11:86,12:75,13:71,14:72,15:76,16:77,17:78,18:79,19:80,20:82,21:$Vo,22:130,23:81,24:$Vp,26:$Vq,27:87,28:$Vr,31:$Vt,34:68,35:69,36:733,38:742,44:83,45:$Vu,46:$Vv,47:73,49:$Vw,51:$Vx,54:20,55:$Vy,56:$V2,61:$V3,62:$Vz,68:$VA,70:$VB,71:$VC,72:$VD,73:$VE,74:$VF,77:$V5,78:$VG,79:$V6,80:$V7,82:$V8,83:$V9,85:90,86:70,88:74,90:106,91:122,95:$VH,96:$VI,97:91,98:92,99:93,100:$VJ,101:$VK,104:$VL,108:$VM,109:$VN,110:$VO,111:$VP,113:$VQ,121:$VR,122:100,123:$VS,124:118,129:$VT,135:120,137:$Va,138:104,141:$VU,142:$Vc,143:$Vd,154:$Vb,170:$VV,171:$VW,172:$VX,178:$VY,179:108,180:$VZ},o($Vn3,[2,160],{54:20,86:70,13:71,14:72,47:73,88:74,12:75,15:76,16:77,17:78,18:79,19:80,23:81,20:82,44:83,11:86,27:87,85:90,97:91,98:92,99:93,122:100,138:104,90:106,179:108,124:118,135:120,91:122,22:130,34:186,36:743,21:$Vo,24:$Vp,26:$Vq,28:$Vr,31:$Vt,45:$Vu,46:$Vv,49:$Vw,51:$Vx,55:$Vy,56:$V2,61:$V3,62:$Vz,68:$VA,70:$VB,71:$VC,72:$VD,73:$VE,74:$VF,77:$V5,78:$VG,79:$V6,80:$V7,82:$V8,83:$V9,95:$VH,96:$VI,100:$VJ,101:$VK,104:$VL,108:$VM,109:$VN,110:$VO,111:$VP,113:$VQ,121:$VR,123:$VS,129:$VT,137:$Va,141:$VU,142:$Vc,143:$Vd,154:$Vb,170:$VV,171:$VW,172:$VX,178:$VY,180:$VZ}),{8:$Vn,35:187},o($Vm3,[2,155],{107:$Vu1,118:[1,744],155:$Vv1,156:$Vw1,157:$Vx1,158:$Vy1,159:$Vz1,160:$VA1,161:$VB1,162:$VC1,163:$VD1,164:$VE1,165:$VF1,166:$VG1,167:$VH1,168:$VI1,169:$VJ1,171:$VK1,172:$VL1,173:$VM1,174:$VN1,175:$VO1,176:$VP1,177:$VQ1}),o($Vm3,[2,158],{107:$Vu1,155:$Vv1,156:$Vw1,157:$Vx1,158:$Vy1,159:$Vz1,160:$VA1,161:$VB1,162:$VC1,163:$VD1,164:$VE1,165:$VF1,166:$VG1,167:$VH1,168:$VI1,169:$VJ1,171:$VK1,172:$VL1,173:$VM1,174:$VN1,175:$VO1,176:$VP1,177:$VQ1}),o($Vh3,[2,58]),{22:130,26:$Vq,31:$Vt,46:$Vv,47:745,62:$Vz,68:$VA,70:$Vm1,71:$Vn1,72:$Vo1,74:$Vp1,78:$Vq1,90:106,91:122,95:$VH,121:$VR,122:177,123:$VS,138:104,141:$VU,142:$Vc,143:$Vd,170:$VV,171:$VW,172:$VX,178:$VY,179:108,180:$VZ},{51:[1,746]},{58:[1,747],107:$Vu1,155:$Vv1,156:$Vw1,157:$Vx1,158:$Vy1,159:$Vz1,160:$VA1,161:$VB1,162:$VC1,163:$VD1,164:$VE1,165:$VF1,166:$VG1,167:$VH1,168:$VI1,169:$VJ1,171:$VK1,172:$VL1,173:$VM1,174:$VN1,175:$VO1,176:$VP1,177:$VQ1},{58:[1,748],107:$Vu1,155:$Vv1,156:$Vw1,157:$Vx1,158:$Vy1,159:$Vz1,160:$VA1,161:$VB1,162:$VC1,163:$VD1,164:$VE1,165:$VF1,166:$VG1,167:$VH1,168:$VI1,169:$VJ1,171:$VK1,172:$VL1,173:$VM1,174:$VN1,175:$VO1,176:$VP1,177:$VQ1},o($Vg3,[2,239],{107:$Vu1,155:$Vv1,156:$Vw1,157:$Vx1,158:$Vy1,159:$Vz1,160:$VA1,161:$VB1,162:$VC1,163:$VD1,164:$VE1,165:$VF1,166:$VG1,167:$VH1,168:$VI1,169:$VJ1,171:$VK1,172:$VL1,173:$VM1,174:$VN1,175:$VO1,176:$VP1,177:$VQ1}),o($Vn3,[2,159],{54:20,86:70,13:71,14:72,47:73,88:74,12:75,15:76,16:77,17:78,18:79,19:80,23:81,20:82,44:83,11:86,27:87,85:90,97:91,98:92,99:93,122:100,138:104,90:106,179:108,124:118,135:120,91:122,22:130,34:186,36:743,21:$Vo,24:$Vp,26:$Vq,28:$Vr,31:$Vt,45:$Vu,46:$Vv,49:$Vw,51:$Vx,55:$Vy,56:$V2,61:$V3,62:$Vz,68:$VA,70:$VB,71:$VC,72:$VD,73:$VE,74:$VF,77:$V5,78:$VG,79:$V6,80:$V7,82:$V8,83:$V9,95:$VH,96:$VI,100:$VJ,101:$VK,104:$VL,108:$VM,109:$VN,110:$VO,111:$VP,113:$VQ,121:$VR,123:$VS,129:$VT,137:$Va,141:$VU,142:$Vc,143:$Vd,154:$Vb,170:$VV,171:$VW,172:$VX,178:$VY,180:$VZ}),{8:$Vn,35:343},{22:130,26:$Vq,31:$Vt,46:$Vv,47:749,62:$Vz,68:$VA,70:$Vm1,71:$Vn1,72:$Vo1,74:$Vp1,78:$Vq1,90:106,91:122,95:$VH,121:$VR,122:177,123:$VS,138:104,141:$VU,142:$Vc,143:$Vd,170:$VV,171:$VW,172:$VX,178:$VY,179:108,180:$VZ},{53:[1,750],107:$Vu1,155:$Vv1,156:$Vw1,157:$Vx1,158:$Vy1,159:$Vz1,160:$VA1,161:$VB1,162:$VC1,163:$VD1,164:$VE1,165:$VF1,166:$VG1,167:$VH1,168:$VI1,169:$VJ1,171:$VK1,172:$VL1,173:$VM1,174:$VN1,175:$VO1,176:$VP1,177:$VQ1},{22:130,26:$Vq,31:$Vt,46:$Vv,47:751,62:$Vz,68:$VA,70:$Vm1,71:$Vn1,72:$Vo1,74:$Vp1,78:$Vq1,90:106,91:122,95:$VH,121:$VR,122:177,123:$VS,138:104,141:$VU,142:$Vc,143:$Vd,170:$VV,171:$VW,172:$VX,178:$VY,179:108,180:$VZ},{22:130,26:$Vq,31:$Vt,46:$Vv,47:752,62:$Vz,68:$VA,70:$Vm1,71:$Vn1,72:$Vo1,74:$Vp1,78:$Vq1,90:106,91:122,95:$VH,121:$VR,122:177,123:$VS,138:104,141:$VU,142:$Vc,143:$Vd,170:$VV,171:$VW,172:$VX,178:$VY,179:108,180:$VZ},{22:130,26:$Vq,31:$Vt,46:$Vv,47:753,62:$Vz,68:$VA,70:$Vm1,71:$Vn1,72:$Vo1,74:$Vp1,78:$Vq1,90:106,91:122,95:$VH,121:$VR,122:177,123:$VS,138:104,141:$VU,142:$Vc,143:$Vd,170:$VV,171:$VW,172:$VX,178:$VY,179:108,180:$VZ},o($Vm3,[2,156],{107:$Vu1,155:$Vv1,156:$Vw1,157:$Vx1,158:$Vy1,159:$Vz1,160:$VA1,161:$VB1,162:$VC1,163:$VD1,164:$VE1,165:$VF1,166:$VG1,167:$VH1,168:$VI1,169:$VJ1,171:$VK1,172:$VL1,173:$VM1,174:$VN1,175:$VO1,176:$VP1,177:$VQ1}),{51:[1,754]},{53:[1,755],107:$Vu1,155:$Vv1,156:$Vw1,157:$Vx1,158:$Vy1,159:$Vz1,160:$VA1,161:$VB1,162:$VC1,163:$VD1,164:$VE1,165:$VF1,166:$VG1,167:$VH1,168:$VI1,169:$VJ1,171:$VK1,172:$VL1,173:$VM1,174:$VN1,175:$VO1,176:$VP1,177:$VQ1},o($VN2,[2,227],{107:$Vu1,155:$Vv1,156:$Vw1,157:$Vx1,158:$Vy1,159:$Vz1,160:$VA1,161:$VB1,162:$VC1,163:$VD1,164:$VE1,165:$VF1,166:$VG1,167:$VH1,168:$VI1,169:$VJ1,171:$VK1,172:$VL1,173:$VM1,174:$VN1,175:$VO1,176:$VP1,177:$VQ1}),o($VN2,[2,228],{107:$Vu1,155:$Vv1,156:$Vw1,157:$Vx1,158:$Vy1,159:$Vz1,160:$VA1,161:$VB1,162:$VC1,163:$VD1,164:$VE1,165:$VF1,166:$VG1,167:$VH1,168:$VI1,169:$VJ1,171:$VK1,172:$VL1,173:$VM1,174:$VN1,175:$VO1,176:$VP1,177:$VQ1}),{22:130,26:$Vq,31:$Vt,46:$Vv,47:756,62:$Vz,68:$VA,70:$Vm1,71:$Vn1,72:$Vo1,74:$Vp1,78:$Vq1,90:106,91:122,95:$VH,121:$VR,122:177,123:$VS,138:104,141:$VU,142:$Vc,143:$Vd,170:$VV,171:$VW,172:$VX,178:$VY,179:108,180:$VZ},o($Vd1,[2,275]),{53:[1,757],107:$Vu1,155:$Vv1,156:$Vw1,157:$Vx1,158:$Vy1,159:$Vz1,160:$VA1,161:$VB1,162:$VC1,163:$VD1,164:$VE1,165:$VF1,166:$VG1,167:$VH1,168:$VI1,169:$VJ1,171:$VK1,172:$VL1,173:$VM1,174:$VN1,175:$VO1,176:$VP1,177:$VQ1},o($Vd1,[2,274])], -defaultActions: {4:[2,1],59:[2,56],65:[2,37],138:[2,66],172:[2,57],446:[2,206],459:[2,65],613:[2,207],681:[2,143]}, +table: [o($V0,[2,3],{3:1,4:2}),{1:[3]},o($V0,[2,5],{5:3}),{6:[1,4],7:5,8:[1,6],9:7,10:8,11:9,12:10,13:11,14:12,15:13,16:14,17:15,18:16,19:17,20:[1,18],21:[1,19],26:$V1,33:[1,21],56:22,57:$V2,58:$V3,63:$V4,64:[1,20],72:$V5,73:$V6,74:$V7,75:$V8,76:$V9,79:$Va,80:$Vb,81:$Vc,82:$Vd,84:$Ve,85:$Vf,126:31,139:$Vg},{1:[2,1]},o($V0,[2,2]),o($V0,[2,4]),o($V0,[2,6]),o($V0,[2,7]),o($V0,[2,8]),o($V0,[2,9]),o($V0,[2,10]),o($V0,[2,11]),o($V0,[2,12]),o($V0,[2,13]),o($V0,[2,14]),o($V0,[2,15]),o($V0,[2,16]),o($V0,[2,17]),o($V0,[2,18]),{28:[1,41],155:[1,40]},{30:[1,42]},{48:[1,43]},{33:[1,45],56:44,57:$Vh,58:$V3,64:[1,46]},{140:48,144:$Vi,145:$Vj},o($Vk,$Vl,{141:51,77:$Vm,78:$Vn,142:$Vo}),o($Vk,$Vl,{141:55,142:$Vo}),{28:$Vp,70:$Vq,97:$Vr,145:$Vs,151:62,152:56,154:57},{155:[1,63]},{28:$Vp,70:$Vq,97:$Vr,145:$Vs,151:62,152:65,154:64},{155:[1,66]},o($Vt,[2,173]),{26:$V1,57:$Vu,72:$V5,73:$V6,74:$V7,80:$Vb,126:67},{24:72,28:[1,69],33:$Vv,64:$Vw,70:$Vx,97:$Vy,127:70,128:71},{57:[1,77]},{24:72,28:$Vz,33:$Vv,53:[1,80],64:$Vw,70:$Vx,97:$Vy,127:78,128:79},{24:72,28:$Vz,33:$Vv,53:[1,84],64:$Vw,70:$Vx,97:$Vy,127:82,128:83},{24:72,28:$Vz,33:$Vv,53:[1,87],64:$Vw,70:$Vx,97:$Vy,127:85,128:86},{24:72,28:$Vz,33:$Vv,53:[1,90],64:$Vw,70:$Vx,97:$Vy,127:88,128:89},{24:72,28:$Vz,33:$Vv,53:$VA,64:$Vw,70:$Vx,97:$Vy,128:91},{28:[1,93]},{30:[1,95],48:[1,94]},{8:$VB,11:118,12:107,13:103,14:104,15:108,16:109,17:110,18:111,19:122,20:$VC,21:$VD,22:114,23:$VE,24:162,25:113,26:$VF,28:$Vz,29:119,30:$VG,32:$VH,33:$Vv,34:96,36:100,37:101,38:99,39:97,40:98,46:115,47:$VI,48:$VJ,49:105,51:$VK,53:$VL,56:22,57:$V2,58:$V3,63:$V4,64:$Vw,70:$Vx,72:$VM,73:$VN,74:$VO,75:$V8,76:$VP,79:$Va,80:$VQ,81:$Vc,82:$Vd,84:$Ve,85:$Vf,87:102,89:106,90:112,92:138,93:155,97:$Vy,98:$VR,99:123,100:124,101:125,102:$VS,103:$VT,106:$VU,110:$VV,111:$VW,112:$VX,113:$VY,115:$VZ,123:$V_,124:132,125:$V$,126:31,131:$V01,137:153,139:$Vg,140:136,143:$V11,144:$Vi,145:$Vj,156:$V21,172:$V31,173:$V41,174:$V51,180:$V61,181:140,182:$V71},{50:$V81,57:$V91,59:163,65:164,67:$Va1,68:166,69:167,72:$Vb1,73:$Vc1,74:$Vd1,75:$Ve1,76:$Vf1,79:$Vg1,80:$Vh1,81:$Vi1,82:$Vj1,83:$Vk1,84:$Vl1,85:$Vm1},{48:[1,181]},{56:182,57:$Vh,58:$V3},{56:183,57:$Vh,58:$V3},{28:[1,184]},o($Vn1,[2,217]),o($Vo1,[2,220]),o($Vo1,[2,221]),{28:$Vp,70:$Vq,97:$Vr,145:$Vs,151:62,152:186,154:185},o($Vk,$Vl,{141:187,142:$Vo}),o($Vk,$Vl,{141:188,142:$Vo}),{48:[1,189]},{28:$Vp,70:$Vq,97:$Vr,145:$Vs,151:62,152:65,154:190},o([6,8,20,21,26,32,33,57,58,63,64,66,72,73,74,75,76,79,80,81,82,84,85,110,139],$Vp1,{150:192,53:$Vq1,129:[1,191]}),o($Vn1,[2,276],{66:$Vr1}),o($Vs1,[2,261]),o($Vs1,[2,262]),o($Vs1,[2,263]),{153:[1,195]},o($Vt1,[2,267]),{48:[1,196]},o($Vn1,[2,279],{66:$Vr1}),o($Vt1,$Vp1,{150:192,53:$Vq1}),{48:[1,197]},o($Vt,[2,174]),{24:72,28:$Vz,33:$Vv,64:$Vw,70:$Vx,97:$Vy,127:70,128:71},o([6,8,20,21,26,32,33,53,57,58,63,64,66,72,73,74,75,76,79,80,81,82,84,85,110,129,139],$Vu1,{48:$Vv1,153:$Vw1}),o($Vt,[2,179],{66:$Vx1}),o($Vt1,$Vy1,{129:[1,200]}),o($Vz1,$VA1,{130:201,53:$VB1}),{153:[1,203]},{153:[1,204]},{153:[1,205]},o($VC1,[2,355],{153:[1,206]}),{28:[1,207]},o($Vt,[2,175],{66:$Vx1}),o($Vt1,$Vy1,{129:[1,208]}),{24:72,28:$Vz,33:$Vv,64:$Vw,70:$Vx,97:$Vy,127:209,128:210},o($VC1,$Vu1,{153:$Vw1}),o($Vt,[2,176],{66:$Vx1}),o($Vt1,$Vy1,{129:[1,211]}),{24:72,28:$Vz,33:$Vv,64:$Vw,70:$Vx,97:$Vy,127:212,128:210},o($Vt,[2,177],{66:$Vx1}),o($Vt1,$Vy1,{129:[1,213]}),{24:72,28:$Vz,33:$Vv,64:$Vw,70:$Vx,97:$Vy,127:214,128:210},o($Vt,[2,178],{66:$Vx1}),o($Vt1,$Vy1,{129:[1,215]}),{24:72,28:$Vz,33:$Vv,64:$Vw,70:$Vx,97:$Vy,127:216,128:210},{129:[1,217]},{24:72,28:$Vz,33:$Vv,64:$Vw,70:$Vx,97:$Vy,127:218,128:210},{48:[1,219]},{24:162,28:$Vz,33:$Vv,48:$VJ,49:222,64:$Vw,67:$VD1,70:$Vx,72:$VE1,73:$VF1,74:$VG1,76:$VH1,80:$VI1,92:138,93:155,97:$Vy,105:220,123:$V_,124:223,125:$V$,140:136,143:$V11,144:$Vi,145:$Vj,172:$V31,173:$V41,174:$V51,180:$V61,181:140,182:$V71},{8:$VB,11:118,12:107,13:103,14:104,15:108,16:109,17:110,18:111,19:122,20:$VC,21:$VD,22:114,23:$VE,24:162,25:113,26:$VF,28:$Vz,29:119,30:$VG,32:$VH,33:$Vv,34:229,36:100,37:101,38:99,39:97,40:98,46:115,47:$VI,48:$VJ,49:105,51:$VK,53:$VL,56:22,57:$V2,58:$V3,63:$V4,64:$Vw,70:$Vx,72:$VM,73:$VN,74:$VO,75:$V8,76:$VP,79:$Va,80:$VQ,81:$Vc,82:$Vd,84:$Ve,85:$Vf,87:102,89:106,90:112,92:138,93:155,97:$Vy,98:$VR,99:123,100:124,101:125,102:$VS,103:$VT,106:$VU,110:$VV,111:$VW,112:$VX,113:$VY,115:$VZ,123:$V_,124:132,125:$V$,126:31,131:$V01,137:153,139:$Vg,140:136,143:$V11,144:$Vi,145:$Vj,156:$V21,172:$V31,173:$V41,174:$V51,180:$V61,181:140,182:$V71},{32:[1,230]},{32:[2,39]},{11:118,12:107,13:103,14:104,15:108,16:109,17:110,18:111,19:122,20:$VC,21:$VD,22:114,23:$VE,24:162,25:113,26:$VF,28:$Vz,29:119,30:$VG,32:[2,29],33:$Vv,36:232,38:231,46:115,47:$VI,48:$VJ,49:105,51:$VK,53:$VL,56:22,57:$V2,58:$V3,63:$V4,64:$Vw,70:$Vx,72:$VM,73:$VN,74:$VO,75:$V8,76:$VP,79:$Va,80:$VQ,81:$Vc,82:$Vd,84:$Ve,85:$Vf,87:102,89:106,90:112,92:138,93:155,97:$Vy,98:$VR,99:123,100:124,101:125,102:$VS,103:$VT,106:$VU,110:$VV,111:$VW,112:$VX,113:$VY,115:$VZ,123:$V_,124:132,125:$V$,126:31,131:$V01,137:153,139:$Vg,140:136,143:$V11,144:$Vi,145:$Vj,156:$V21,172:$V31,173:$V41,174:$V51,180:$V61,181:140,182:$V71},{8:$VB,32:[2,31],37:233},o($VJ1,[2,35],{37:234,8:$VB}),o($VJ1,[2,38],{8:$VK1}),o($VL1,[2,108]),o($VL1,[2,109]),o($VL1,[2,110]),o($VL1,[2,111],{88:[1,236],109:$VM1,157:$VN1,158:$VO1,159:$VP1,160:$VQ1,161:$VR1,162:$VS1,163:$VT1,164:$VU1,165:$VV1,166:$VW1,167:$VX1,168:$VY1,169:$VZ1,170:$V_1,171:$V$1,173:$V02,174:$V12,175:$V22,176:$V32,177:$V42,178:$V52,179:$V62}),o($VL1,[2,113]),o($VL1,[2,114]),o($VL1,[2,115]),o($VL1,[2,116]),o($VL1,[2,117]),o($VL1,[2,118]),o($VL1,[2,119]),o($VL1,[2,120]),o($VL1,[2,121]),o($V72,[2,49]),{42:261,43:[1,262],44:[1,263],45:[1,264],48:[1,260]},{24:162,28:$Vz,30:[1,265],33:$Vv,48:$VJ,49:267,53:[1,266],64:$Vw,70:$Vx,72:$VE1,73:$VF1,74:$VG1,76:$VH1,80:$VI1,92:138,93:155,97:$Vy,123:$V_,124:223,125:$V$,140:136,143:$V11,144:$Vi,145:$Vj,172:$V31,173:$V41,174:$V51,180:$V61,181:140,182:$V71},o($V72,[2,55]),o($V72,[2,56]),{8:$VB,11:118,12:107,13:103,14:104,15:108,16:109,17:110,18:111,19:122,20:$VC,21:$VD,22:114,23:$VE,24:162,25:113,26:$VF,28:$Vz,29:119,30:$VG,32:$VH,33:$Vv,34:268,36:100,37:101,38:99,39:97,40:98,46:115,47:$VI,48:$VJ,49:105,51:$VK,53:$VL,56:22,57:$V2,58:$V3,63:$V4,64:$Vw,70:$Vx,72:$VM,73:$VN,74:$VO,75:$V8,76:$VP,79:$Va,80:$VQ,81:$Vc,82:$Vd,84:$Ve,85:$Vf,87:102,89:106,90:112,92:138,93:155,97:$Vy,98:$VR,99:123,100:124,101:125,102:$VS,103:$VT,106:$VU,110:$VV,111:$VW,112:$VX,113:$VY,115:$VZ,123:$V_,124:132,125:$V$,126:31,131:$V01,137:153,139:$Vg,140:136,143:$V11,144:$Vi,145:$Vj,156:$V21,172:$V31,173:$V41,174:$V51,180:$V61,181:140,182:$V71},o($V72,[2,45]),o($VL1,[2,137]),o($VL1,[2,138]),o($VL1,[2,139]),o($VL1,[2,140]),o($VL1,[2,141]),o($VL1,[2,142]),o($Vk,$Vl,{141:51,71:270,48:$V82,53:$V92,77:$Vm,78:$Vn,142:$Vo}),{24:162,28:$Vz,33:$Vv,48:$VJ,49:272,64:$Vw,70:$Vx,72:$VE1,73:$VF1,74:$VG1,76:$VH1,80:$VI1,92:138,93:155,97:$Vy,123:$V_,124:223,125:$V$,140:136,143:$V11,144:$Vi,145:$Vj,172:$V31,173:$V41,174:$V51,180:$V61,181:140,182:$V71},{24:162,28:$Vz,33:$Vv,48:$VJ,49:273,64:$Vw,70:$Vx,72:$VE1,73:$VF1,74:$VG1,76:$VH1,80:$VI1,92:138,93:155,97:$Vy,123:$V_,124:223,125:$V$,140:136,143:$V11,144:$Vi,145:$Vj,172:$V31,173:$V41,174:$V51,180:$V61,181:140,182:$V71},{24:162,28:$Vz,33:$Vv,48:$VJ,49:274,64:$Vw,70:$Vx,72:$VE1,73:$VF1,74:$VG1,76:$VH1,80:$VI1,92:138,93:155,97:$Vy,123:$V_,124:223,125:$V$,140:136,143:$V11,144:$Vi,145:$Vj,172:$V31,173:$V41,174:$V51,180:$V61,181:140,182:$V71},o([8,32,88,109,110,157,158,159,160,161,162,163,164,165,166,167,168,169,170,171,173,174,175,176,177,178,179],$Va2,{132:277,123:$Vb2,125:$Vc2,129:$Vd2,133:$Ve2,134:$Vf2,135:$Vg2}),{24:162,28:$Vz,33:$Vv,48:$Vh2,64:$Vw,70:$Vx,93:283,97:$Vy,124:282,143:$Vi2,180:$Vj2,182:$V71},{24:162,28:$Vz,33:$Vv,48:$Vh2,64:$Vw,70:$Vx,93:283,97:$Vy,124:287,143:$Vi2,180:$Vj2,182:$V71},o($Vo1,[2,317],{182:$Vk2}),o($Vo1,[2,318]),{24:162,28:$Vz,33:$Vv,48:$VJ,49:289,64:$Vw,70:$Vx,72:$VE1,73:$VF1,74:$VG1,76:$VH1,80:$VI1,92:138,93:155,97:$Vy,123:$V_,124:223,125:$V$,140:136,143:$V11,144:$Vi,145:$Vj,172:$V31,173:$V41,174:$V51,180:$V61,181:140,182:$V71},o($Vo1,[2,320]),o($Vo1,[2,321],{182:$Vl2}),o($Vo1,[2,322]),{63:[1,292],95:291},{28:[1,293]},{24:294,28:$Vz,33:$Vv,53:$VA,64:$Vw,70:$Vx,97:$Vy,128:91},{24:295,28:$Vz,33:$Vv,64:$Vw,70:$Vx,97:$Vy},{48:[1,296]},{48:[1,297]},{8:$VB,11:118,12:107,13:103,14:104,15:108,16:109,17:110,18:111,19:122,20:$VC,21:$VD,22:114,23:$VE,24:162,25:113,26:$VF,28:$Vz,29:119,30:$VG,33:$Vv,35:298,36:300,37:301,38:299,46:115,47:$VI,48:$VJ,49:105,51:$VK,53:$VL,56:22,57:$V2,58:$V3,63:$V4,64:$Vw,70:$Vx,72:$VM,73:$VN,74:$VO,75:$V8,76:$VP,79:$Va,80:$VQ,81:$Vc,82:$Vd,84:$Ve,85:$Vf,87:102,89:106,90:112,92:138,93:155,97:$Vy,98:$VR,99:123,100:124,101:125,102:$VS,103:$VT,106:$VU,110:$VV,111:$VW,112:$VX,113:$VY,115:$VZ,123:$V_,124:132,125:$V$,126:31,131:$V01,137:153,139:$Vg,140:136,143:$V11,144:$Vi,145:$Vj,156:$V21,172:$V31,173:$V41,174:$V51,180:$V61,181:140,182:$V71},{33:$Vm2,64:$Vn2,96:302,97:$Vo2},{48:[1,306]},{48:[1,307]},o($V72,[2,154]),o($V72,[2,155]),{129:[1,308]},o($VL1,[2,199],{140:136,92:138,181:140,93:155,24:162,124:223,49:309,28:$Vz,33:$Vv,48:$VJ,53:[1,310],64:$Vw,70:$Vx,72:$VE1,73:$VF1,74:$VG1,76:$VH1,80:$VI1,97:$Vy,123:$V_,125:$V$,143:$V11,144:$Vi,145:$Vj,172:$V31,173:$V41,174:$V51,180:$V61,182:$V71}),o($Vp2,$Vq2,{48:$Vr2,182:$Vs2}),{24:162,28:$Vz,33:$Vv,64:$Vw,70:$Vx,93:313,97:$Vy},{24:72,28:$Vz,33:$Vv,48:$Vt2,53:[1,316],64:$Vw,70:$Vx,71:315,97:$Vy,127:78,128:79},{24:72,28:$Vz,33:$Vv,48:$Vu2,53:[1,319],64:$Vw,70:$Vx,71:318,97:$Vy,127:82,128:83},{24:72,28:$Vz,33:$Vv,48:$Vv2,53:[1,322],64:$Vw,70:$Vx,71:321,97:$Vy,127:85,128:86},{24:72,28:$Vz,33:$Vv,48:$Vw2,53:[1,325],64:$Vw,70:$Vx,71:324,97:$Vy,127:88,128:89},{24:162,28:$Vz,33:$Vv,48:$Vh2,64:$Vw,70:$Vx,93:283,97:$Vy,124:327,136:326,143:$Vi2,180:$Vj2,182:$V71},o($Vx2,[2,342],{183:328,53:[1,329]}),{50:[1,330]},{50:[2,66],66:[1,331]},{50:[2,68]},o($Vy2,[2,71]),{28:[1,332],70:[1,333]},o($Vz2,[2,76]),o($Vz2,[2,77]),o($Vz2,[2,78]),{72:[1,334],73:[1,335],74:[1,336],80:[1,337]},{77:[1,338],78:[1,339]},o($Vz2,[2,84]),o($Vz2,[2,85]),o($Vz2,[2,87]),o($Vz2,[2,88]),o($Vz2,[2,89]),o($Vz2,[2,90]),o($Vz2,[2,91]),o($Vz2,[2,92]),{50:$V81,57:$V91,59:340,65:164,67:$Va1,68:166,69:167,72:$Vb1,73:$Vc1,74:$Vd1,75:$Ve1,76:$Vf1,79:$Vg1,80:$Vh1,81:$Vi1,82:$Vj1,83:$Vk1,84:$Vl1,85:$Vm1},{48:[1,341]},{48:[1,342]},{48:$Vv1},o($Vt,[2,268],{66:$Vr1}),o($Vt1,$Vp1,{150:192,53:$Vq1,129:[1,343]}),{28:$Vp,70:$Vq,97:$Vr,145:$Vs,151:62,152:65,154:344},{28:$Vp,70:$Vq,97:$Vr,145:$Vs,151:62,152:346,154:345},{143:[1,347]},o($Vn1,[2,274],{66:$Vr1}),{24:162,28:$Vz,33:$Vv,48:$VJ,49:348,64:$Vw,70:$Vx,72:$VE1,73:$VF1,74:$VG1,76:$VH1,80:$VI1,92:138,93:155,97:$Vy,123:$V_,124:223,125:$V$,140:136,143:$V11,144:$Vi,145:$Vj,172:$V31,173:$V41,174:$V51,180:$V61,181:140,182:$V71},o($Vt1,[2,260],{53:$VA2}),{24:162,28:$Vz,33:$Vv,48:$VJ,49:351,55:[1,350],64:$Vw,70:$Vx,72:$VE1,73:$VF1,74:$VG1,76:$VH1,80:$VI1,92:138,93:155,97:$Vy,123:$V_,124:223,125:$V$,140:136,143:$V11,144:$Vi,145:$Vj,172:$V31,173:$V41,174:$V51,180:$V61,181:140,182:$V71},{28:$Vp,70:$Vq,97:$Vr,145:$Vs,151:352,152:65},{28:[1,353],145:[1,354]},{28:[1,355]},{28:[1,356]},{28:$VB2,145:$VC2,185:357},{24:72,28:$Vz,33:$Vv,64:$Vw,70:$Vx,97:$Vy,128:360},{24:162,28:$Vz,33:$Vv,48:$VJ,49:361,64:$Vw,70:$Vx,72:$VE1,73:$VF1,74:$VG1,76:$VH1,80:$VI1,92:138,93:155,97:$Vy,123:$V_,124:223,125:$V$,140:136,143:$V11,144:$Vi,145:$Vj,172:$V31,173:$V41,174:$V51,180:$V61,181:140,182:$V71},o($Vz1,[2,196],{53:[1,362]}),{24:162,28:$Vz,33:$Vv,48:$VJ,49:364,55:[1,363],64:$Vw,70:$Vx,72:$VE1,73:$VF1,74:$VG1,76:$VH1,80:$VI1,92:138,93:155,97:$Vy,123:$V_,124:223,125:$V$,140:136,143:$V11,144:$Vi,145:$Vj,172:$V31,173:$V41,174:$V51,180:$V61,181:140,182:$V71},{28:$VB2,145:$VC2,185:365},{28:$VB2,145:$VC2,185:366},{28:$VB2,145:$VC2,185:367},{28:$VB2,145:$VC2,185:368},{48:[2,59]},{24:162,28:$Vz,33:$Vv,48:$VJ,49:369,64:$Vw,70:$Vx,72:$VE1,73:$VF1,74:$VG1,76:$VH1,80:$VI1,92:138,93:155,97:$Vy,123:$V_,124:223,125:$V$,140:136,143:$V11,144:$Vi,145:$Vj,172:$V31,173:$V41,174:$V51,180:$V61,181:140,182:$V71},{55:[1,370],66:$Vx1},o($VD2,$Vy1),{24:162,28:$Vz,33:$Vv,48:$VJ,49:371,64:$Vw,70:$Vx,72:$VE1,73:$VF1,74:$VG1,76:$VH1,80:$VI1,92:138,93:155,97:$Vy,123:$V_,124:223,125:$V$,140:136,143:$V11,144:$Vi,145:$Vj,172:$V31,173:$V41,174:$V51,180:$V61,181:140,182:$V71},{55:[1,372],66:$Vx1},{24:162,28:$Vz,33:$Vv,48:$VJ,49:373,64:$Vw,70:$Vx,72:$VE1,73:$VF1,74:$VG1,76:$VH1,80:$VI1,92:138,93:155,97:$Vy,123:$V_,124:223,125:$V$,140:136,143:$V11,144:$Vi,145:$Vj,172:$V31,173:$V41,174:$V51,180:$V61,181:140,182:$V71},{55:[1,374],66:$Vx1},{24:162,28:$Vz,33:$Vv,48:$VJ,49:375,64:$Vw,70:$Vx,72:$VE1,73:$VF1,74:$VG1,76:$VH1,80:$VI1,92:138,93:155,97:$Vy,123:$V_,124:223,125:$V$,140:136,143:$V11,144:$Vi,145:$Vj,172:$V31,173:$V41,174:$V51,180:$V61,181:140,182:$V71},{55:[1,376],66:$Vx1},{24:162,28:$Vz,33:$Vv,48:$VJ,49:377,64:$Vw,70:$Vx,72:$VE1,73:$VF1,74:$VG1,76:$VH1,80:$VI1,92:138,93:155,97:$Vy,123:$V_,124:223,125:$V$,140:136,143:$V11,144:$Vi,145:$Vj,172:$V31,173:$V41,174:$V51,180:$V61,181:140,182:$V71},{55:[1,378],66:$Vx1},{24:162,28:$Vz,33:$Vv,48:$VJ,49:222,64:$Vw,67:$VD1,70:$Vx,72:$VE1,73:$VF1,74:$VG1,76:$VH1,80:$VI1,92:138,93:155,97:$Vy,105:379,123:$V_,124:223,125:$V$,140:136,143:$V11,144:$Vi,145:$Vj,172:$V31,173:$V41,174:$V51,180:$V61,181:140,182:$V71},{50:[1,380],66:$VE2},{24:162,28:$Vz,33:$Vv,48:$VJ,49:382,64:$Vw,70:$Vx,72:$VE1,73:$VF1,74:$VG1,76:$VH1,80:$VI1,92:138,93:155,97:$Vy,123:$V_,124:223,125:$V$,140:136,143:$V11,144:$Vi,145:$Vj,172:$V31,173:$V41,174:$V51,180:$V61,181:140,182:$V71},o($VF2,[2,254],{109:$VM1,157:$VN1,158:$VO1,159:$VP1,160:$VQ1,161:$VR1,162:$VS1,163:$VT1,164:$VU1,165:$VV1,166:$VW1,167:$VX1,168:$VY1,169:$VZ1,170:$V_1,171:$V$1,173:$V02,174:$V12,175:$V22,176:$V32,177:$V42,178:$V52,179:$V62}),o($Vo1,$Va2,{123:$Vb2,125:$Vc2}),{48:$Vt2,53:$V92,71:315},{48:$Vu2,53:$V92,71:318},{48:$Vv2,53:$V92,71:321},{48:$V82,53:$V92,71:270},{48:$Vw2,53:$V92,71:324},{32:[1,383]},o($V0,[2,24]),{8:$VB,32:[2,30],37:384},o($VJ1,[2,32],{37:385,8:$VB}),o($VJ1,[2,37],{8:$VK1}),o($VJ1,[2,36],{8:$VK1}),o($V72,[2,44]),{24:162,28:$Vz,33:$Vv,48:$VJ,49:386,64:$Vw,70:$Vx,72:$VE1,73:$VF1,74:$VG1,76:$VH1,80:$VI1,92:138,93:155,97:$Vy,123:$V_,124:223,125:$V$,140:136,143:$V11,144:$Vi,145:$Vj,172:$V31,173:$V41,174:$V51,180:$V61,181:140,182:$V71},{24:162,28:$Vz,33:$Vv,48:$VJ,49:387,64:$Vw,70:$Vx,72:$VE1,73:$VF1,74:$VG1,76:$VH1,80:$VI1,92:138,93:155,97:$Vy,123:$V_,124:223,125:$V$,140:136,143:$V11,144:$Vi,145:$Vj,172:$V31,173:$V41,174:$V51,180:$V61,181:140,182:$V71},{24:162,28:$Vz,33:$Vv,48:$VJ,49:388,64:$Vw,70:$Vx,72:$VE1,73:$VF1,74:$VG1,76:$VH1,80:$VI1,92:138,93:155,97:$Vy,123:$V_,124:223,125:$V$,140:136,143:$V11,144:$Vi,145:$Vj,172:$V31,173:$V41,174:$V51,180:$V61,181:140,182:$V71},{24:162,28:$Vz,33:$Vv,48:$VJ,49:389,64:$Vw,70:$Vx,72:$VE1,73:$VF1,74:$VG1,76:$VH1,80:$VI1,92:138,93:155,97:$Vy,123:$V_,124:223,125:$V$,140:136,143:$V11,144:$Vi,145:$Vj,172:$V31,173:$V41,174:$V51,180:$V61,181:140,182:$V71},{24:162,28:$Vz,33:$Vv,48:$VJ,49:390,64:$Vw,70:$Vx,72:$VE1,73:$VF1,74:$VG1,76:$VH1,80:$VI1,92:138,93:155,97:$Vy,123:$V_,124:223,125:$V$,140:136,143:$V11,144:$Vi,145:$Vj,172:$V31,173:$V41,174:$V51,180:$V61,181:140,182:$V71},{24:162,28:$Vz,33:$Vv,48:$VJ,49:391,64:$Vw,70:$Vx,72:$VE1,73:$VF1,74:$VG1,76:$VH1,80:$VI1,92:138,93:155,97:$Vy,123:$V_,124:223,125:$V$,140:136,143:$V11,144:$Vi,145:$Vj,172:$V31,173:$V41,174:$V51,180:$V61,181:140,182:$V71},{24:162,28:$Vz,33:$Vv,48:$VJ,49:392,64:$Vw,70:$Vx,72:$VE1,73:$VF1,74:$VG1,76:$VH1,80:$VI1,92:138,93:155,97:$Vy,123:$V_,124:223,125:$V$,140:136,143:$V11,144:$Vi,145:$Vj,172:$V31,173:$V41,174:$V51,180:$V61,181:140,182:$V71},{24:162,28:$Vz,33:$Vv,48:$VJ,49:393,64:$Vw,70:$Vx,72:$VE1,73:$VF1,74:$VG1,76:$VH1,80:$VI1,92:138,93:155,97:$Vy,123:$V_,124:223,125:$V$,140:136,143:$V11,144:$Vi,145:$Vj,172:$V31,173:$V41,174:$V51,180:$V61,181:140,182:$V71},{57:$V91,62:394,69:395,72:$Vb1,73:$Vc1,74:$Vd1,75:$Ve1,76:$Vf1,79:$Vg1,80:$Vh1,81:$Vi1,82:$Vj1,83:$Vk1,84:$Vl1,85:$Vm1},{24:162,28:$Vz,33:$Vv,48:$VJ,49:396,64:$Vw,70:$Vx,72:$VE1,73:$VF1,74:$VG1,76:$VH1,80:$VI1,92:138,93:155,97:$Vy,123:$V_,124:223,125:$V$,140:136,143:$V11,144:$Vi,145:$Vj,172:$V31,173:$V41,174:$V51,180:$V61,181:140,182:$V71},{24:162,28:$Vz,33:$Vv,48:$VJ,49:397,64:$Vw,70:$Vx,72:$VE1,73:$VF1,74:$VG1,76:$VH1,80:$VI1,92:138,93:155,97:$Vy,123:$V_,124:223,125:$V$,140:136,143:$V11,144:$Vi,145:$Vj,172:$V31,173:$V41,174:$V51,180:$V61,181:140,182:$V71},{24:162,28:$Vz,33:$Vv,48:$VJ,49:398,64:$Vw,70:$Vx,72:$VE1,73:$VF1,74:$VG1,76:$VH1,80:$VI1,92:138,93:155,97:$Vy,123:$V_,124:223,125:$V$,140:136,143:$V11,144:$Vi,145:$Vj,172:$V31,173:$V41,174:$V51,180:$V61,181:140,182:$V71},{24:162,28:$Vz,33:$Vv,48:$VJ,49:399,64:$Vw,70:$Vx,72:$VE1,73:$VF1,74:$VG1,76:$VH1,80:$VI1,92:138,93:155,97:$Vy,123:$V_,124:223,125:$V$,140:136,143:$V11,144:$Vi,145:$Vj,172:$V31,173:$V41,174:$V51,180:$V61,181:140,182:$V71},{24:162,28:$Vz,33:$Vv,48:$VJ,49:400,64:$Vw,70:$Vx,72:$VE1,73:$VF1,74:$VG1,76:$VH1,80:$VI1,92:138,93:155,97:$Vy,123:$V_,124:223,125:$V$,140:136,143:$V11,144:$Vi,145:$Vj,172:$V31,173:$V41,174:$V51,180:$V61,181:140,182:$V71},{24:162,28:$Vz,33:$Vv,48:$VJ,49:401,64:$Vw,70:$Vx,72:$VE1,73:$VF1,74:$VG1,76:$VH1,80:$VI1,92:138,93:155,97:$Vy,123:$V_,124:223,125:$V$,140:136,143:$V11,144:$Vi,145:$Vj,172:$V31,173:$V41,174:$V51,180:$V61,181:140,182:$V71},{24:162,28:$Vz,33:$Vv,48:$VJ,49:402,64:$Vw,70:$Vx,72:$VE1,73:$VF1,74:$VG1,76:$VH1,80:$VI1,92:138,93:155,97:$Vy,123:$V_,124:223,125:$V$,140:136,143:$V11,144:$Vi,145:$Vj,172:$V31,173:$V41,174:$V51,180:$V61,181:140,182:$V71},{24:162,28:$Vz,33:$Vv,48:$VJ,49:403,64:$Vw,70:$Vx,72:$VE1,73:$VF1,74:$VG1,76:$VH1,80:$VI1,92:138,93:155,97:$Vy,123:$V_,124:223,125:$V$,140:136,143:$V11,144:$Vi,145:$Vj,172:$V31,173:$V41,174:$V51,180:$V61,181:140,182:$V71},{24:162,28:$Vz,33:$Vv,48:$VJ,49:404,64:$Vw,70:$Vx,72:$VE1,73:$VF1,74:$VG1,76:$VH1,80:$VI1,92:138,93:155,97:$Vy,123:$V_,124:223,125:$V$,140:136,143:$V11,144:$Vi,145:$Vj,172:$V31,173:$V41,174:$V51,180:$V61,181:140,182:$V71},{24:162,28:$Vz,33:$Vv,48:$VJ,49:405,64:$Vw,70:$Vx,72:$VE1,73:$VF1,74:$VG1,76:$VH1,80:$VI1,92:138,93:155,97:$Vy,123:$V_,124:223,125:$V$,140:136,143:$V11,144:$Vi,145:$Vj,172:$V31,173:$V41,174:$V51,180:$V61,181:140,182:$V71},{24:162,28:$Vz,33:$Vv,48:$VJ,49:406,64:$Vw,70:$Vx,72:$VE1,73:$VF1,74:$VG1,76:$VH1,80:$VI1,92:138,93:155,97:$Vy,123:$V_,124:223,125:$V$,140:136,143:$V11,144:$Vi,145:$Vj,172:$V31,173:$V41,174:$V51,180:$V61,181:140,182:$V71},{24:162,28:$Vz,33:$Vv,48:$VJ,49:407,64:$Vw,70:$Vx,72:$VE1,73:$VF1,74:$VG1,76:$VH1,80:$VI1,92:138,93:155,97:$Vy,123:$V_,124:223,125:$V$,140:136,143:$V11,144:$Vi,145:$Vj,172:$V31,173:$V41,174:$V51,180:$V61,181:140,182:$V71},{24:162,28:$Vz,33:$Vv,48:$VJ,49:408,64:$Vw,70:$Vx,72:$VE1,73:$VF1,74:$VG1,76:$VH1,80:$VI1,92:138,93:155,97:$Vy,123:$V_,124:223,125:$V$,140:136,143:$V11,144:$Vi,145:$Vj,172:$V31,173:$V41,174:$V51,180:$V61,181:140,182:$V71},{24:162,28:$Vz,33:$Vv,48:$VJ,49:409,64:$Vw,70:$Vx,72:$VE1,73:$VF1,74:$VG1,76:$VH1,80:$VI1,92:138,93:155,97:$Vy,123:$V_,124:223,125:$V$,140:136,143:$V11,144:$Vi,145:$Vj,172:$V31,173:$V41,174:$V51,180:$V61,181:140,182:$V71},{24:162,28:$Vz,33:$Vv,48:$VJ,49:410,64:$Vw,70:$Vx,72:$VE1,73:$VF1,74:$VG1,76:$VH1,80:$VI1,92:138,93:155,97:$Vy,123:$V_,124:223,125:$V$,140:136,143:$V11,144:$Vi,145:$Vj,172:$V31,173:$V41,174:$V51,180:$V61,181:140,182:$V71},{24:162,28:$Vz,33:$Vv,48:$VJ,49:411,64:$Vw,70:$Vx,72:$VE1,73:$VF1,74:$VG1,76:$VH1,80:$VI1,92:138,93:155,97:$Vy,123:$V_,124:223,125:$V$,140:136,143:$V11,144:$Vi,145:$Vj,172:$V31,173:$V41,174:$V51,180:$V61,181:140,182:$V71},{8:$VB,11:118,12:107,13:103,14:104,15:108,16:109,17:110,18:111,19:122,20:$VC,21:$VD,22:114,23:$VE,24:162,25:113,26:$VF,28:$Vz,29:119,30:$VG,33:$Vv,35:412,36:300,37:301,38:413,46:115,47:$VI,48:$VJ,49:105,51:$VK,53:$VL,56:22,57:$V2,58:$V3,63:$V4,64:$Vw,70:$Vx,72:$VM,73:$VN,74:$VO,75:$V8,76:$VP,79:$Va,80:$VQ,81:$Vc,82:$Vd,84:$Ve,85:$Vf,87:102,89:106,90:112,92:138,93:155,97:$Vy,98:$VR,99:123,100:124,101:125,102:$VS,103:$VT,106:$VU,110:$VV,111:$VW,112:$VX,113:$VY,115:$VZ,123:$V_,124:132,125:$V$,126:31,131:$V01,137:153,139:$Vg,140:136,143:$V11,144:$Vi,145:$Vj,156:$V21,172:$V31,173:$V41,174:$V51,180:$V61,181:140,182:$V71},o($VG2,[2,46]),o($VG2,[2,47]),o($VG2,[2,48]),{28:$VH2,52:414},{24:162,28:$Vz,30:$VI2,33:$Vv,48:$VJ,49:418,53:$VJ2,54:416,64:$Vw,70:$Vx,72:$VE1,73:$VF1,74:$VG1,76:$VH1,80:$VI1,91:417,92:138,93:155,97:$Vy,123:$V_,124:223,125:$V$,140:136,143:$V11,144:$Vi,145:$Vj,172:$V31,173:$V41,174:$V51,180:$V61,181:140,182:$V71},{8:[1,421],109:$VM1,157:$VN1,158:$VO1,159:$VP1,160:$VQ1,161:$VR1,162:$VS1,163:$VT1,164:$VU1,165:$VV1,166:$VW1,167:$VX1,168:$VY1,169:$VZ1,170:$V_1,171:$V$1,173:$V02,174:$V12,175:$V22,176:$V32,177:$V42,178:$V52,179:$V62},{32:[1,422]},{24:162,28:$Vz,33:$Vv,48:$VJ,49:423,64:$Vw,70:$Vx,72:$VE1,73:$VF1,74:$VG1,76:$VH1,80:$VI1,92:138,93:155,97:$Vy,123:$V_,124:223,125:$V$,140:136,143:$V11,144:$Vi,145:$Vj,172:$V31,173:$V41,174:$V51,180:$V61,181:140,182:$V71},{48:[1,424],53:$VK2},{55:$VL2},o($Vo1,[2,302]),o($Vo1,[2,310]),o($Vo1,[2,311]),o($Vo1,[2,315]),o($Vo1,[2,316]),{24:162,28:$Vz,33:$Vv,48:$VJ,49:427,64:$Vw,70:$Vx,72:$VE1,73:$VF1,74:$VG1,76:$VH1,80:$VI1,92:138,93:155,97:$Vy,123:$V_,124:223,125:$V$,140:136,143:$V11,144:$Vi,145:$Vj,172:$V31,173:$V41,174:$V51,180:$V61,181:140,182:$V71},o($VM2,[2,202],{138:428,53:$VN2}),o($VM2,[2,203]),o($VM2,[2,204]),o($VM2,[2,205]),o($Vo1,[2,313]),o($Vp2,$Vq2,{182:$Vs2}),{182:$Vk2},{24:162,28:$Vz,33:$Vv,48:$VJ,49:430,64:$Vw,70:$Vx,72:$VE1,73:$VF1,74:$VG1,76:$VH1,80:$VI1,92:138,93:155,97:$Vy,123:$V_,124:223,125:$V$,140:136,143:$V11,144:$Vi,145:$Vj,172:$V31,173:$V41,174:$V51,180:$V61,181:140,182:$V71},{182:$Vl2},o($Vo1,[2,314]),{24:162,28:$Vz,33:$Vv,64:$Vw,70:$Vx,93:431,97:$Vy},{50:[1,432],109:$VM1,157:$VN1,158:$VO1,159:$VP1,160:$VQ1,161:$VR1,162:$VS1,163:$VT1,164:$VU1,165:$VV1,166:$VW1,167:$VX1,168:$VY1,169:$VZ1,170:$V_1,171:$V$1,173:$V02,174:$V12,175:$V22,176:$V32,177:$V42,178:$V52,179:$V62},{24:162,28:$Vz,33:$Vv,64:$Vw,70:$Vx,93:433,97:$Vy},{33:$Vm2,64:$Vn2,96:434,97:$Vo2},o([33,64,97],[2,132]),{53:$Vq1,129:[1,435],150:436},o($VL1,[2,20],{130:201,27:[1,437],30:[1,438],53:$VB1,129:$VA1}),o($VL1,[2,19]),{13:443,19:440,24:162,26:$V1,28:$Vz,33:$Vv,48:$Vh2,57:$Vu,64:$Vw,70:$Vx,72:$V5,73:$V6,74:$V7,75:$V8,76:$V9,80:$Vb,93:283,97:$Vy,99:441,107:439,124:442,126:31,143:$Vi2,180:$Vj2,182:$V71},{24:162,28:$Vz,33:$Vv,48:$VJ,49:444,64:$Vw,70:$Vx,72:$VE1,73:$VF1,74:$VG1,76:$VH1,80:$VI1,92:138,93:155,97:$Vy,123:$V_,124:223,125:$V$,140:136,143:$V11,144:$Vi,145:$Vj,172:$V31,173:$V41,174:$V51,180:$V61,181:140,182:$V71},{110:[1,445]},{8:$VB,37:447,110:[1,446]},o([20,21,23,26,28,30,32,33,47,48,51,53,57,58,63,64,70,72,73,74,75,76,79,80,81,82,84,85,97,98,102,103,106,110,111,112,113,115,116,118,121,123,125,131,139,143,144,145,156,172,173,174,180,182],[2,25],{37:448,8:$VB}),o($V72,[2,27]),{8:$VB,11:118,12:107,13:103,14:104,15:108,16:109,17:110,18:111,19:122,20:$VC,21:$VD,22:114,23:$VE,24:162,25:113,26:$VF,28:$Vz,29:119,30:$VG,33:$Vv,35:449,36:300,37:301,38:413,46:115,47:$VI,48:$VJ,49:105,51:$VK,53:$VL,56:22,57:$V2,58:$V3,63:$V4,64:$Vw,70:$Vx,72:$VM,73:$VN,74:$VO,75:$V8,76:$VP,79:$Va,80:$VQ,81:$Vc,82:$Vd,84:$Ve,85:$Vf,87:102,89:106,90:112,92:138,93:155,97:$Vy,98:$VR,99:123,100:124,101:125,102:$VS,103:$VT,106:$VU,110:$VV,111:$VW,112:$VX,113:$VY,115:$VZ,123:$V_,124:132,125:$V$,126:31,131:$V01,137:153,139:$Vg,140:136,143:$V11,144:$Vi,145:$Vj,156:$V21,172:$V31,173:$V41,174:$V51,180:$V61,181:140,182:$V71},o($VG2,[2,133]),o($VG2,[2,134]),o($VG2,[2,135]),{24:162,28:$Vz,33:$Vv,48:$VJ,49:450,64:$Vw,70:$Vx,72:$VE1,73:$VF1,74:$VG1,76:$VH1,80:$VI1,92:138,93:155,97:$Vy,123:$V_,124:223,125:$V$,140:136,143:$V11,144:$Vi,145:$Vj,172:$V31,173:$V41,174:$V51,180:$V61,181:140,182:$V71},{24:162,28:$Vz,33:$Vv,48:$VJ,49:451,64:$Vw,70:$Vx,72:$VE1,73:$VF1,74:$VG1,76:$VH1,80:$VI1,92:138,93:155,97:$Vy,123:$V_,124:223,125:$V$,140:136,143:$V11,144:$Vi,145:$Vj,172:$V31,173:$V41,174:$V51,180:$V61,181:140,182:$V71},{24:162,28:$Vz,33:$Vv,53:[1,453],64:$Vw,70:$Vx,92:452,93:454,97:$Vy},o($VL1,[2,200],{109:$VM1,157:$VN1,158:$VO1,159:$VP1,160:$VQ1,161:$VR1,162:$VS1,163:$VT1,164:$VU1,165:$VV1,166:$VW1,167:$VX1,168:$VY1,169:$VZ1,170:$V_1,171:$V$1,173:$V02,174:$V12,175:$V22,176:$V32,177:$V42,178:$V52,179:$V62}),{24:162,28:$Vz,33:$Vv,48:$VJ,49:222,64:$Vw,67:$VD1,70:$Vx,72:$VE1,73:$VF1,74:$VG1,76:$VH1,80:$VI1,92:138,93:155,97:$Vy,105:455,123:$V_,124:223,125:$V$,140:136,143:$V11,144:$Vi,145:$Vj,172:$V31,173:$V41,174:$V51,180:$V61,181:140,182:$V71},o($Vp2,[2,333],{48:[1,457],143:[1,456],180:[1,458]}),o($Vy2,$VO2,{140:136,92:138,181:140,93:155,24:162,124:223,94:459,49:461,28:$Vz,33:$Vv,48:$VJ,53:$VP2,64:$Vw,70:$Vx,72:$VE1,73:$VF1,74:$VG1,76:$VH1,80:$VI1,97:$Vy,123:$V_,125:$V$,143:$V11,144:$Vi,145:$Vj,172:$V31,173:$V41,174:$V51,180:$V61,182:$V71}),o($Vp2,[2,337]),{24:162,28:$Vz,33:$Vv,48:$VJ,49:462,64:$Vw,70:$Vx,72:$VE1,73:$VF1,74:$VG1,76:$VH1,80:$VI1,92:138,93:155,97:$Vy,123:$V_,124:223,125:$V$,140:136,143:$V11,144:$Vi,145:$Vj,172:$V31,173:$V41,174:$V51,180:$V61,181:140,182:$V71},{48:[1,463],53:$VK2},{24:72,28:$Vz,33:$Vv,55:$VL2,64:$Vw,70:$Vx,97:$Vy,127:209,128:210},{24:162,28:$Vz,33:$Vv,48:$VJ,49:464,64:$Vw,70:$Vx,72:$VE1,73:$VF1,74:$VG1,76:$VH1,80:$VI1,92:138,93:155,97:$Vy,123:$V_,124:223,125:$V$,140:136,143:$V11,144:$Vi,145:$Vj,172:$V31,173:$V41,174:$V51,180:$V61,181:140,182:$V71},{48:[1,465],53:$VK2},{24:72,28:$Vz,33:$Vv,55:$VL2,64:$Vw,70:$Vx,97:$Vy,127:212,128:210},{24:162,28:$Vz,33:$Vv,48:$VJ,49:466,64:$Vw,70:$Vx,72:$VE1,73:$VF1,74:$VG1,76:$VH1,80:$VI1,92:138,93:155,97:$Vy,123:$V_,124:223,125:$V$,140:136,143:$V11,144:$Vi,145:$Vj,172:$V31,173:$V41,174:$V51,180:$V61,181:140,182:$V71},{48:[1,467],53:$VK2},{24:72,28:$Vz,33:$Vv,55:$VL2,64:$Vw,70:$Vx,97:$Vy,127:214,128:210},{24:162,28:$Vz,33:$Vv,48:$VJ,49:468,64:$Vw,70:$Vx,72:$VE1,73:$VF1,74:$VG1,76:$VH1,80:$VI1,92:138,93:155,97:$Vy,123:$V_,124:223,125:$V$,140:136,143:$V11,144:$Vi,145:$Vj,172:$V31,173:$V41,174:$V51,180:$V61,181:140,182:$V71},{48:[1,469],53:$VK2},{24:72,28:$Vz,33:$Vv,55:$VL2,64:$Vw,70:$Vx,97:$Vy,127:216,128:210},{55:[1,470],66:[1,471]},o($VD2,[2,208]),o($Vx2,[2,343],{53:[1,472]}),{24:162,28:$Vz,33:$Vv,48:$VJ,49:474,64:$Vw,70:$Vx,72:$VE1,73:$VF1,74:$VG1,76:$VH1,80:$VI1,92:138,93:155,97:$Vy,120:$VQ2,123:$V_,124:223,125:$V$,140:136,143:$V11,144:$Vi,145:$Vj,172:$V31,173:$V41,174:$V51,180:$V61,181:140,182:$V71,184:473},{30:[1,477],60:[1,476]},{57:$V91,67:[1,478],68:479,69:167,72:$Vb1,73:$Vc1,74:$Vd1,75:$Ve1,76:$Vf1,79:$Vg1,80:$Vh1,81:$Vi1,82:$Vj1,83:$Vk1,84:$Vl1,85:$Vm1},o($Vy2,[2,72],{71:480,53:$V92}),o($Vy2,[2,73],{71:481,53:$V92}),o($Vz2,[2,79]),o($Vz2,[2,80]),o($Vz2,[2,81]),o($Vz2,[2,86]),o($Vz2,[2,82]),o($Vz2,[2,83]),{50:[1,482]},{50:$V81,57:$V91,59:483,65:164,67:$Va1,68:166,69:167,72:$Vb1,73:$Vc1,74:$Vd1,75:$Ve1,76:$Vf1,79:$Vg1,80:$Vh1,81:$Vi1,82:$Vj1,83:$Vk1,84:$Vl1,85:$Vm1},{50:$V81,57:$V91,59:484,65:164,67:$Va1,68:166,69:167,72:$Vb1,73:$Vc1,74:$Vd1,75:$Ve1,76:$Vf1,79:$Vg1,80:$Vh1,81:$Vi1,82:$Vj1,83:$Vk1,84:$Vl1,85:$Vm1},{24:162,28:$Vz,33:$Vv,48:$VJ,49:485,64:$Vw,70:$Vx,72:$VE1,73:$VF1,74:$VG1,76:$VH1,80:$VI1,92:138,93:155,97:$Vy,123:$V_,124:223,125:$V$,140:136,143:$V11,144:$Vi,145:$Vj,172:$V31,173:$V41,174:$V51,180:$V61,181:140,182:$V71},o($Vt,[2,270],{66:$Vr1}),o($Vt,[2,271],{66:$Vr1}),o($Vt1,$Vp1,{150:192,53:$Vq1,129:[1,486]}),{50:[1,487]},o($Vn1,[2,275],{109:$VM1,157:$VN1,158:$VO1,159:$VP1,160:$VQ1,161:$VR1,162:$VS1,163:$VT1,164:$VU1,165:$VV1,166:$VW1,167:$VX1,168:$VY1,169:$VZ1,170:$V_1,171:$V$1,173:$V02,174:$V12,175:$V22,176:$V32,177:$V42,178:$V52,179:$V62}),{24:162,28:$Vz,33:$Vv,48:$VJ,49:489,55:[1,488],64:$Vw,70:$Vx,72:$VE1,73:$VF1,74:$VG1,76:$VH1,80:$VI1,92:138,93:155,97:$Vy,123:$V_,124:223,125:$V$,140:136,143:$V11,144:$Vi,145:$Vj,172:$V31,173:$V41,174:$V51,180:$V61,181:140,182:$V71},o($Vs1,[2,255]),{55:[1,490],109:$VM1,157:$VN1,158:$VO1,159:$VP1,160:$VQ1,161:$VR1,162:$VS1,163:$VT1,164:$VU1,165:$VV1,166:$VW1,167:$VX1,168:$VY1,169:$VZ1,170:$V_1,171:$V$1,173:$V02,174:$V12,175:$V22,176:$V32,177:$V42,178:$V52,179:$V62},o($Vt1,[2,266]),o($Vs1,[2,264]),o($Vs1,[2,265]),{66:[1,491]},{50:[1,492]},o($VC1,[2,354],{153:$VR2}),o($VS2,[2,359]),o($VS2,[2,360]),o([6,8,20,21,26,32,33,55,57,58,63,64,66,72,73,74,75,76,79,80,81,82,84,85,109,110,139],[2,197]),o($Vn1,[2,184],{109:$VM1,157:$VN1,158:$VO1,159:$VP1,160:$VQ1,161:$VR1,162:$VS1,163:$VT1,164:$VU1,165:$VV1,166:$VW1,167:$VX1,168:$VY1,169:$VZ1,170:$V_1,171:$V$1,173:$V02,174:$V12,175:$V22,176:$V32,177:$V42,178:$V52,179:$V62}),{24:162,28:$Vz,33:$Vv,48:$VJ,49:495,55:[1,494],64:$Vw,70:$Vx,72:$VE1,73:$VF1,74:$VG1,76:$VH1,80:$VI1,92:138,93:155,97:$Vy,123:$V_,124:223,125:$V$,140:136,143:$V11,144:$Vi,145:$Vj,172:$V31,173:$V41,174:$V51,180:$V61,181:140,182:$V71},o($VT2,[2,191]),{55:[1,496],109:$VM1,157:$VN1,158:$VO1,159:$VP1,160:$VQ1,161:$VR1,162:$VS1,163:$VT1,164:$VU1,165:$VV1,166:$VW1,167:$VX1,168:$VY1,169:$VZ1,170:$V_1,171:$V$1,173:$V02,174:$V12,175:$V22,176:$V32,177:$V42,178:$V52,179:$V62},o($VC1,[2,350],{153:$VR2}),o($VC1,[2,351],{153:$VR2}),o($VC1,[2,352],{153:$VR2}),o($VC1,[2,356],{153:$VR2}),o($Vn1,[2,180],{109:$VM1,157:$VN1,158:$VO1,159:$VP1,160:$VQ1,161:$VR1,162:$VS1,163:$VT1,164:$VU1,165:$VV1,166:$VW1,167:$VX1,168:$VY1,169:$VZ1,170:$V_1,171:$V$1,173:$V02,174:$V12,175:$V22,176:$V32,177:$V42,178:$V52,179:$V62}),{129:[1,497]},o($Vn1,[2,181],{109:$VM1,157:$VN1,158:$VO1,159:$VP1,160:$VQ1,161:$VR1,162:$VS1,163:$VT1,164:$VU1,165:$VV1,166:$VW1,167:$VX1,168:$VY1,169:$VZ1,170:$V_1,171:$V$1,173:$V02,174:$V12,175:$V22,176:$V32,177:$V42,178:$V52,179:$V62}),{129:[1,498]},o($Vn1,[2,182],{109:$VM1,157:$VN1,158:$VO1,159:$VP1,160:$VQ1,161:$VR1,162:$VS1,163:$VT1,164:$VU1,165:$VV1,166:$VW1,167:$VX1,168:$VY1,169:$VZ1,170:$V_1,171:$V$1,173:$V02,174:$V12,175:$V22,176:$V32,177:$V42,178:$V52,179:$V62}),{129:[1,499]},o($Vn1,[2,183],{109:$VM1,157:$VN1,158:$VO1,159:$VP1,160:$VQ1,161:$VR1,162:$VS1,163:$VT1,164:$VU1,165:$VV1,166:$VW1,167:$VX1,168:$VY1,169:$VZ1,170:$V_1,171:$V$1,173:$V02,174:$V12,175:$V22,176:$V32,177:$V42,178:$V52,179:$V62}),{129:[1,500]},o($Vn1,[2,185],{109:$VM1,157:$VN1,158:$VO1,159:$VP1,160:$VQ1,161:$VR1,162:$VS1,163:$VT1,164:$VU1,165:$VV1,166:$VW1,167:$VX1,168:$VY1,169:$VZ1,170:$V_1,171:$V$1,173:$V02,174:$V12,175:$V22,176:$V32,177:$V42,178:$V52,179:$V62}),{129:[1,501]},{50:[1,502],66:$VE2},{30:[1,503]},{24:162,28:$Vz,33:$Vv,48:$VJ,49:505,64:$Vw,67:[1,504],70:$Vx,72:$VE1,73:$VF1,74:$VG1,76:$VH1,80:$VI1,92:138,93:155,97:$Vy,123:$V_,124:223,125:$V$,140:136,143:$V11,144:$Vi,145:$Vj,172:$V31,173:$V41,174:$V51,180:$V61,181:140,182:$V71},o($VF2,[2,253],{109:$VM1,157:$VN1,158:$VO1,159:$VP1,160:$VQ1,161:$VR1,162:$VS1,163:$VT1,164:$VU1,165:$VV1,166:$VW1,167:$VX1,168:$VY1,169:$VZ1,170:$V_1,171:$V$1,173:$V02,174:$V12,175:$V22,176:$V32,177:$V42,178:$V52,179:$V62}),o($V0,[2,283]),o($VJ1,[2,34],{8:$VK1}),o($VJ1,[2,33],{8:$VK1}),o($VL1,[2,112],{109:$VM1,157:$VN1,158:$VO1,159:$VP1,160:$VQ1,161:$VR1,162:$VS1,163:$VT1,164:$VU1,165:$VV1,166:$VW1,167:$VX1,168:$VY1,169:$VZ1,170:$V_1,171:$V$1,173:$V02,174:$V12,175:$V22,176:$V32,177:$V42,178:$V52,179:$V62}),o($VU2,[2,286],{170:$V_1,171:$V$1,173:$V02,174:$V12,175:$V22,176:$V32,177:$V42,178:$V52,179:$V62}),o($VU2,[2,287],{170:$V_1,171:$V$1,173:$V02,174:$V12,175:$V22,176:$V32,177:$V42,178:$V52,179:$V62}),o($VU2,[2,288],{170:$V_1,171:$V$1,173:$V02,174:$V12,175:$V22,176:$V32,177:$V42,178:$V52,179:$V62}),o($VU2,[2,289],{170:$V_1,171:$V$1,173:$V02,174:$V12,175:$V22,176:$V32,177:$V42,178:$V52,179:$V62}),o($VU2,[2,290],{170:$V_1,171:$V$1,173:$V02,174:$V12,175:$V22,176:$V32,177:$V42,178:$V52,179:$V62}),o($VU2,[2,291],{170:$V_1,171:$V$1,173:$V02,174:$V12,175:$V22,176:$V32,177:$V42,178:$V52,179:$V62}),o([6,8,20,21,26,32,33,50,55,57,58,60,63,64,66,67,72,73,74,75,76,79,80,81,82,84,85,88,109,110,120,139,148,149,163,164,165,166,167,168,169],[2,292],{157:$VN1,158:$VO1,159:$VP1,160:$VQ1,161:$VR1,162:$VS1,170:$V_1,171:$V$1,173:$V02,174:$V12,175:$V22,176:$V32,177:$V42,178:$V52,179:$V62}),o($Vo1,[2,293]),o($VV2,[2,97],{71:506,53:$V92}),o($VW2,[2,294],{109:$VM1,157:$VN1,158:$VO1,159:$VP1,160:$VQ1,161:$VR1,162:$VS1,163:$VT1,166:$VW1,167:$VX1,168:$VY1,170:$V_1,171:$V$1,173:$V02,174:$V12,175:$V22,176:$V32,177:$V42,178:$V52,179:$V62}),{60:[1,507],109:$VM1,157:$VN1,158:$VO1,159:$VP1,160:$VQ1,161:$VR1,162:$VS1,163:$VT1,164:$VU1,165:$VV1,166:$VW1,167:$VX1,168:$VY1,169:$VZ1,170:$V_1,171:$V$1,173:$V02,174:$V12,175:$V22,176:$V32,177:$V42,178:$V52,179:$V62},o($VW2,[2,296],{109:$VM1,157:$VN1,158:$VO1,159:$VP1,160:$VQ1,161:$VR1,162:$VS1,163:$VT1,166:$VW1,167:$VX1,168:$VY1,170:$V_1,171:$V$1,173:$V02,174:$V12,175:$V22,176:$V32,177:$V42,178:$V52,179:$V62}),o($VW2,[2,297],{109:$VM1,157:$VN1,158:$VO1,159:$VP1,160:$VQ1,161:$VR1,162:$VS1,163:$VT1,166:$VW1,167:$VX1,168:$VY1,170:$V_1,171:$V$1,173:$V02,174:$V12,175:$V22,176:$V32,177:$V42,178:$V52,179:$V62}),o($VW2,[2,298],{109:$VM1,157:$VN1,158:$VO1,159:$VP1,160:$VQ1,161:$VR1,162:$VS1,163:$VT1,166:$VW1,167:$VX1,168:$VY1,170:$V_1,171:$V$1,173:$V02,174:$V12,175:$V22,176:$V32,177:$V42,178:$V52,179:$V62}),o($VX2,[2,299],{109:$VM1,157:$VN1,158:$VO1,159:$VP1,160:$VQ1,161:$VR1,162:$VS1,163:$VT1,164:$VU1,166:$VW1,167:$VX1,168:$VY1,170:$V_1,171:$V$1,173:$V02,174:$V12,175:$V22,176:$V32,177:$V42,178:$V52,179:$V62}),o($VW2,[2,300],{109:$VM1,157:$VN1,158:$VO1,159:$VP1,160:$VQ1,161:$VR1,162:$VS1,163:$VT1,166:$VW1,167:$VX1,168:$VY1,170:$V_1,171:$V$1,173:$V02,174:$V12,175:$V22,176:$V32,177:$V42,178:$V52,179:$V62}),o($VX2,[2,301],{109:$VM1,157:$VN1,158:$VO1,159:$VP1,160:$VQ1,161:$VR1,162:$VS1,163:$VT1,164:$VU1,166:$VW1,167:$VX1,168:$VY1,170:$V_1,171:$V$1,173:$V02,174:$V12,175:$V22,176:$V32,177:$V42,178:$V52,179:$V62}),o($VY2,[2,303],{175:$V22,176:$V32,177:$V42,178:$V52,179:$V62}),o($VY2,[2,304],{175:$V22,176:$V32,177:$V42,178:$V52,179:$V62}),o($VZ2,[2,305],{179:$V62}),o($VZ2,[2,306],{179:$V62}),o($VZ2,[2,307],{179:$V62}),o($VZ2,[2,308],{179:$V62}),o($Vo1,[2,309]),{50:[1,508],109:$VM1,157:$VN1,158:$VO1,159:$VP1,160:$VQ1,161:$VR1,162:$VS1,163:$VT1,164:$VU1,165:$VV1,166:$VW1,167:$VX1,168:$VY1,169:$VZ1,170:$V_1,171:$V$1,173:$V02,174:$V12,175:$V22,176:$V32,177:$V42,178:$V52,179:$V62},o($V72,[2,51]),{8:$VB,37:447},{32:[1,509],66:$V_2},o($V$2,[2,128],{60:[1,511]}),{55:[1,512],66:$V03},o($VD2,[2,130]),o($V13,[2,122],{109:$VM1,157:$VN1,158:$VO1,159:$VP1,160:$VQ1,161:$VR1,162:$VS1,163:$VT1,164:$VU1,165:$VV1,166:$VW1,167:$VX1,168:$VY1,169:$VZ1,170:$V_1,171:$V$1,173:$V02,174:$V12,175:$V22,176:$V32,177:$V42,178:$V52,179:$V62}),{28:$VH2,52:514},{24:162,28:$Vz,30:$VI2,33:$Vv,48:$VJ,49:418,53:$VJ2,54:515,64:$Vw,70:$Vx,72:$VE1,73:$VF1,74:$VG1,76:$VH1,80:$VI1,91:417,92:138,93:155,97:$Vy,123:$V_,124:223,125:$V$,140:136,143:$V11,144:$Vi,145:$Vj,172:$V31,173:$V41,174:$V51,180:$V61,181:140,182:$V71},o($V72,[2,54]),o($V72,[2,57]),{50:[1,516],109:$VM1,157:$VN1,158:$VO1,159:$VP1,160:$VQ1,161:$VR1,162:$VS1,163:$VT1,164:$VU1,165:$VV1,166:$VW1,167:$VX1,168:$VY1,169:$VZ1,170:$V_1,171:$V$1,173:$V02,174:$V12,175:$V22,176:$V32,177:$V42,178:$V52,179:$V62},{24:162,28:$Vz,33:$Vv,48:$VJ,49:517,64:$Vw,70:$Vx,72:$VE1,73:$VF1,74:$VG1,76:$VH1,80:$VI1,92:138,93:155,97:$Vy,123:$V_,124:223,125:$V$,140:136,143:$V11,144:$Vi,145:$Vj,172:$V31,173:$V41,174:$V51,180:$V61,181:140,182:$V71},{55:[1,518]},o($V23,[2,96]),o([8,32,50,66,110],[2,213],{109:$VM1,157:$VN1,158:$VO1,159:$VP1,160:$VQ1,161:$VR1,162:$VS1,163:$VT1,164:$VU1,165:$VV1,166:$VW1,167:$VX1,168:$VY1,169:$VZ1,170:$V_1,171:$V$1,173:$V02,174:$V12,175:$V22,176:$V32,177:$V42,178:$V52,179:$V62}),o([8,32,50,66,109,110],[2,214]),{24:162,28:$Vz,33:$Vv,48:$VJ,49:521,53:$V33,64:$Vw,70:$Vx,72:$VE1,73:$VF1,74:$VG1,76:$VH1,80:$VI1,92:138,93:155,97:$Vy,123:$V_,124:223,125:$V$,140:136,143:$V11,144:$Vi,145:$Vj,146:519,147:520,172:$V31,173:$V41,174:$V51,180:$V61,181:140,182:$V71},{50:[1,523],109:$VM1,157:$VN1,158:$VO1,159:$VP1,160:$VQ1,161:$VR1,162:$VS1,163:$VT1,164:$VU1,165:$VV1,166:$VW1,167:$VX1,168:$VY1,169:$VZ1,170:$V_1,171:$V$1,173:$V02,174:$V12,175:$V22,176:$V32,177:$V42,178:$V52,179:$V62},o($Vp2,[2,338]),o($Vo1,[2,319],{182:$V43}),o($Vp2,[2,340]),{24:162,28:$Vz,33:$Vv,64:$Vw,70:$Vx,93:525,97:$Vy},{24:162,28:$Vz,33:$Vv,48:$VJ,49:526,64:$Vw,70:$Vx,72:$VE1,73:$VF1,74:$VG1,76:$VH1,80:$VI1,92:138,93:155,97:$Vy,123:$V_,124:223,125:$V$,140:136,143:$V11,144:$Vi,145:$Vj,172:$V31,173:$V41,174:$V51,180:$V61,181:140,182:$V71},{53:$VA2,129:[1,527]},{28:[1,528]},{13:532,14:533,15:534,16:535,17:536,18:537,19:538,26:$V1,31:529,32:$V53,41:530,57:$Vu,72:$V5,73:$V6,74:$V7,75:$V8,76:$V9,79:$Va,80:$Vb,81:$Vc,82:$Vd,84:$Ve,85:$Vf,86:531,126:31},{8:[1,539],109:[1,540]},o($V63,[2,169]),o($V63,[2,170]),o($V63,[2,171],{132:277,129:$Vd2,133:$Ve2,134:$Vf2,135:$Vg2}),o($V63,[2,172]),{50:[1,541],109:$VM1,157:$VN1,158:$VO1,159:$VP1,160:$VQ1,161:$VR1,162:$VS1,163:$VT1,164:$VU1,165:$VV1,166:$VW1,167:$VX1,168:$VY1,169:$VZ1,170:$V_1,171:$V$1,173:$V02,174:$V12,175:$V22,176:$V32,177:$V42,178:$V52,179:$V62},{48:[1,542]},{48:[1,543]},o($V72,[2,28]),o($V72,[2,26]),o($V72,[2,150]),{50:[1,544],109:$VM1,157:$VN1,158:$VO1,159:$VP1,160:$VQ1,161:$VR1,162:$VS1,163:$VT1,164:$VU1,165:$VV1,166:$VW1,167:$VX1,168:$VY1,169:$VZ1,170:$V_1,171:$V$1,173:$V02,174:$V12,175:$V22,176:$V32,177:$V42,178:$V52,179:$V62},{50:[1,545],109:$VM1,157:$VN1,158:$VO1,159:$VP1,160:$VQ1,161:$VR1,162:$VS1,163:$VT1,164:$VU1,165:$VV1,166:$VW1,167:$VX1,168:$VY1,169:$VZ1,170:$V_1,171:$V$1,173:$V02,174:$V12,175:$V22,176:$V32,177:$V42,178:$V52,179:$V62},o($VL1,[2,211]),{24:162,28:$Vz,33:$Vv,48:$VJ,49:222,64:$Vw,67:$VD1,70:$Vx,72:$VE1,73:$VF1,74:$VG1,76:$VH1,80:$VI1,92:138,93:155,97:$Vy,105:546,123:$V_,124:223,125:$V$,140:136,143:$V11,144:$Vi,145:$Vj,172:$V31,173:$V41,174:$V51,180:$V61,181:140,182:$V71},{48:$Vr2},{55:[1,547],66:$VE2},o($Vp2,[2,334]),{24:162,28:$Vz,33:$Vv,48:$VJ,49:548,64:$Vw,70:$Vx,72:$VE1,73:$VF1,74:$VG1,76:$VH1,80:$VI1,92:138,93:155,97:$Vy,123:$V_,124:223,125:$V$,140:136,143:$V11,144:$Vi,145:$Vj,172:$V31,173:$V41,174:$V51,180:$V61,181:140,182:$V71},o($Vp2,[2,336]),{50:[1,549],66:$V73},{24:162,28:$Vz,33:$Vv,48:$VJ,49:222,64:$Vw,67:$VD1,70:$Vx,72:$VE1,73:$VF1,74:$VG1,76:$VH1,80:$VI1,92:138,93:155,97:$Vy,105:551,123:$V_,124:223,125:$V$,140:136,143:$V11,144:$Vi,145:$Vj,172:$V31,173:$V41,174:$V51,180:$V61,181:140,182:$V71},o($Vy2,[2,250],{109:$VM1,157:$VN1,158:$VO1,159:$VP1,160:$VQ1,161:$VR1,162:$VS1,163:$VT1,164:$VU1,165:$VV1,166:$VW1,167:$VX1,168:$VY1,169:$VZ1,170:$V_1,171:$V$1,173:$V02,174:$V12,175:$V22,176:$V32,177:$V42,178:$V52,179:$V62}),{50:[1,552],109:$VM1,157:$VN1,158:$VO1,159:$VP1,160:$VQ1,161:$VR1,162:$VS1,163:$VT1,164:$VU1,165:$VV1,166:$VW1,167:$VX1,168:$VY1,169:$VZ1,170:$V_1,171:$V$1,173:$V02,174:$V12,175:$V22,176:$V32,177:$V42,178:$V52,179:$V62},{24:162,28:$Vz,33:$Vv,48:$VJ,49:553,64:$Vw,70:$Vx,72:$VE1,73:$VF1,74:$VG1,76:$VH1,80:$VI1,92:138,93:155,97:$Vy,123:$V_,124:223,125:$V$,140:136,143:$V11,144:$Vi,145:$Vj,172:$V31,173:$V41,174:$V51,180:$V61,181:140,182:$V71},{50:[1,554],109:$VM1,157:$VN1,158:$VO1,159:$VP1,160:$VQ1,161:$VR1,162:$VS1,163:$VT1,164:$VU1,165:$VV1,166:$VW1,167:$VX1,168:$VY1,169:$VZ1,170:$V_1,171:$V$1,173:$V02,174:$V12,175:$V22,176:$V32,177:$V42,178:$V52,179:$V62},{24:162,28:$Vz,33:$Vv,48:$VJ,49:555,64:$Vw,70:$Vx,72:$VE1,73:$VF1,74:$VG1,76:$VH1,80:$VI1,92:138,93:155,97:$Vy,123:$V_,124:223,125:$V$,140:136,143:$V11,144:$Vi,145:$Vj,172:$V31,173:$V41,174:$V51,180:$V61,181:140,182:$V71},{50:[1,556],109:$VM1,157:$VN1,158:$VO1,159:$VP1,160:$VQ1,161:$VR1,162:$VS1,163:$VT1,164:$VU1,165:$VV1,166:$VW1,167:$VX1,168:$VY1,169:$VZ1,170:$V_1,171:$V$1,173:$V02,174:$V12,175:$V22,176:$V32,177:$V42,178:$V52,179:$V62},{24:162,28:$Vz,33:$Vv,48:$VJ,49:557,64:$Vw,70:$Vx,72:$VE1,73:$VF1,74:$VG1,76:$VH1,80:$VI1,92:138,93:155,97:$Vy,123:$V_,124:223,125:$V$,140:136,143:$V11,144:$Vi,145:$Vj,172:$V31,173:$V41,174:$V51,180:$V61,181:140,182:$V71},{50:[1,558],109:$VM1,157:$VN1,158:$VO1,159:$VP1,160:$VQ1,161:$VR1,162:$VS1,163:$VT1,164:$VU1,165:$VV1,166:$VW1,167:$VX1,168:$VY1,169:$VZ1,170:$V_1,171:$V$1,173:$V02,174:$V12,175:$V22,176:$V32,177:$V42,178:$V52,179:$V62},{24:162,28:$Vz,33:$Vv,48:$VJ,49:559,64:$Vw,70:$Vx,72:$VE1,73:$VF1,74:$VG1,76:$VH1,80:$VI1,92:138,93:155,97:$Vy,123:$V_,124:223,125:$V$,140:136,143:$V11,144:$Vi,145:$Vj,172:$V31,173:$V41,174:$V51,180:$V61,181:140,182:$V71},{129:[2,209]},o($VD2,[2,207],{24:162,93:283,124:561,28:$Vz,33:$Vv,48:$Vh2,64:$Vw,67:[1,560],70:$Vx,97:$Vy,143:$Vi2,180:$Vj2,182:$V71}),{24:162,28:$Vz,33:$Vv,48:$VJ,49:474,64:$Vw,70:$Vx,72:$VE1,73:$VF1,74:$VG1,76:$VH1,80:$VI1,92:138,93:155,97:$Vy,120:$VQ2,123:$V_,124:223,125:$V$,140:136,143:$V11,144:$Vi,145:$Vj,172:$V31,173:$V41,174:$V51,180:$V61,181:140,182:$V71,184:562},{55:[1,563]},{55:[2,344],109:$VM1,120:[1,564],157:$VN1,158:$VO1,159:$VP1,160:$VQ1,161:$VR1,162:$VS1,163:$VT1,164:$VU1,165:$VV1,166:$VW1,167:$VX1,168:$VY1,169:$VZ1,170:$V_1,171:$V$1,173:$V02,174:$V12,175:$V22,176:$V32,177:$V42,178:$V52,179:$V62},{24:162,28:$Vz,33:$Vv,48:$VJ,49:565,64:$Vw,70:$Vx,72:$VE1,73:$VF1,74:$VG1,76:$VH1,80:$VI1,92:138,93:155,97:$Vy,123:$V_,124:223,125:$V$,140:136,143:$V11,144:$Vi,145:$Vj,172:$V31,173:$V41,174:$V51,180:$V61,181:140,182:$V71},{53:[1,566],57:$V91,62:567,69:395,72:$Vb1,73:$Vc1,74:$Vd1,75:$Ve1,76:$Vf1,79:$Vg1,80:$Vh1,81:$Vi1,82:$Vj1,83:$Vk1,84:$Vl1,85:$Vm1},{8:$VB,11:118,12:107,13:103,14:104,15:108,16:109,17:110,18:111,19:122,20:$VC,21:$VD,22:114,23:$VE,24:162,25:113,26:$VF,28:$Vz,29:119,30:$VG,32:$VH,33:$Vv,34:568,36:100,37:101,38:99,39:97,40:98,46:115,47:$VI,48:$VJ,49:105,51:$VK,53:$VL,56:22,57:$V2,58:$V3,63:$V4,64:$Vw,70:$Vx,72:$VM,73:$VN,74:$VO,75:$V8,76:$VP,79:$Va,80:$VQ,81:$Vc,82:$Vd,84:$Ve,85:$Vf,87:102,89:106,90:112,92:138,93:155,97:$Vy,98:$VR,99:123,100:124,101:125,102:$VS,103:$VT,106:$VU,110:$VV,111:$VW,112:$VX,113:$VY,115:$VZ,123:$V_,124:132,125:$V$,126:31,131:$V01,137:153,139:$Vg,140:136,143:$V11,144:$Vi,145:$Vj,156:$V21,172:$V31,173:$V41,174:$V51,180:$V61,181:140,182:$V71},{50:[2,67]},o($Vy2,[2,70]),o($Vy2,[2,74],{53:$VK2}),o($Vy2,[2,75],{53:$VK2}),{30:[1,569]},{50:[1,570]},{50:[1,571]},o($Vn1,[2,269],{109:$VM1,157:$VN1,158:$VO1,159:$VP1,160:$VQ1,161:$VR1,162:$VS1,163:$VT1,164:$VU1,165:$VV1,166:$VW1,167:$VX1,168:$VY1,169:$VZ1,170:$V_1,171:$V$1,173:$V02,174:$V12,175:$V22,176:$V32,177:$V42,178:$V52,179:$V62}),{24:162,28:$Vz,33:$Vv,48:$VJ,49:572,53:$VN2,64:$Vw,70:$Vx,72:$VE1,73:$VF1,74:$VG1,76:$VH1,80:$VI1,92:138,93:155,97:$Vy,123:$V_,124:223,125:$V$,138:573,140:136,143:$V11,144:$Vi,145:$Vj,172:$V31,173:$V41,174:$V51,180:$V61,181:140,182:$V71},o($Vk,[2,218]),o($Vs1,[2,257]),{55:[1,574],109:$VM1,157:$VN1,158:$VO1,159:$VP1,160:$VQ1,161:$VR1,162:$VS1,163:$VT1,164:$VU1,165:$VV1,166:$VW1,167:$VX1,168:$VY1,169:$VZ1,170:$V_1,171:$V$1,173:$V02,174:$V12,175:$V22,176:$V32,177:$V42,178:$V52,179:$V62},o($Vs1,[2,256]),{28:[1,575]},{28:$Vp,70:$Vq,97:$Vr,145:$Vs,151:62,152:65,154:576},{28:[1,577],145:[1,578]},o($VT2,[2,193]),{55:[1,579],109:$VM1,157:$VN1,158:$VO1,159:$VP1,160:$VQ1,161:$VR1,162:$VS1,163:$VT1,164:$VU1,165:$VV1,166:$VW1,167:$VX1,168:$VY1,169:$VZ1,170:$V_1,171:$V$1,173:$V02,174:$V12,175:$V22,176:$V32,177:$V42,178:$V52,179:$V62},o($VT2,[2,192]),{53:[1,580]},{53:[1,581]},{53:[1,582]},{53:[1,583]},{53:[1,584]},{30:[1,585]},{8:$VB,11:118,12:107,13:103,14:104,15:108,16:109,17:110,18:111,19:122,20:$VC,21:$VD,22:114,23:$VE,24:162,25:113,26:$VF,28:$Vz,29:119,30:$VG,32:$VH,33:$Vv,34:586,36:100,37:101,38:99,39:97,40:98,46:115,47:$VI,48:$VJ,49:105,51:$VK,53:$VL,56:22,57:$V2,58:$V3,63:$V4,64:$Vw,70:$Vx,72:$VM,73:$VN,74:$VO,75:$V8,76:$VP,79:$Va,80:$VQ,81:$Vc,82:$Vd,84:$Ve,85:$Vf,87:102,89:106,90:112,92:138,93:155,97:$Vy,98:$VR,99:123,100:124,101:125,102:$VS,103:$VT,106:$VU,110:$VV,111:$VW,112:$VX,113:$VY,115:$VZ,123:$V_,124:132,125:$V$,126:31,131:$V01,137:153,139:$Vg,140:136,143:$V11,144:$Vi,145:$Vj,156:$V21,172:$V31,173:$V41,174:$V51,180:$V61,181:140,182:$V71},{24:162,28:$Vz,33:$Vv,48:$VJ,49:587,64:$Vw,70:$Vx,72:$VE1,73:$VF1,74:$VG1,76:$VH1,80:$VI1,92:138,93:155,97:$Vy,123:$V_,124:223,125:$V$,140:136,143:$V11,144:$Vi,145:$Vj,172:$V31,173:$V41,174:$V51,180:$V61,181:140,182:$V71},o($VF2,[2,252],{109:$VM1,157:$VN1,158:$VO1,159:$VP1,160:$VQ1,161:$VR1,162:$VS1,163:$VT1,164:$VU1,165:$VV1,166:$VW1,167:$VX1,168:$VY1,169:$VZ1,170:$V_1,171:$V$1,173:$V02,174:$V12,175:$V22,176:$V32,177:$V42,178:$V52,179:$V62}),o($VV2,[2,98],{53:$VK2}),{24:162,28:$Vz,33:$Vv,48:$VJ,49:588,64:$Vw,70:$Vx,72:$VE1,73:$VF1,74:$VG1,76:$VH1,80:$VI1,92:138,93:155,97:$Vy,123:$V_,124:223,125:$V$,140:136,143:$V11,144:$Vi,145:$Vj,172:$V31,173:$V41,174:$V51,180:$V61,181:140,182:$V71},{8:$VB,11:118,12:107,13:103,14:104,15:108,16:109,17:110,18:111,19:122,20:$VC,21:$VD,22:114,23:$VE,24:162,25:113,26:$VF,28:$Vz,29:119,30:$VG,33:$Vv,35:589,36:300,37:301,38:413,46:115,47:$VI,48:$VJ,49:105,51:$VK,53:$VL,56:22,57:$V2,58:$V3,63:$V4,64:$Vw,70:$Vx,72:$VM,73:$VN,74:$VO,75:$V8,76:$VP,79:$Va,80:$VQ,81:$Vc,82:$Vd,84:$Ve,85:$Vf,87:102,89:106,90:112,92:138,93:155,97:$Vy,98:$VR,99:123,100:124,101:125,102:$VS,103:$VT,106:$VU,110:$VV,111:$VW,112:$VX,113:$VY,115:$VZ,123:$V_,124:132,125:$V$,126:31,131:$V01,137:153,139:$Vg,140:136,143:$V11,144:$Vi,145:$Vj,156:$V21,172:$V31,173:$V41,174:$V51,180:$V61,181:140,182:$V71},o($V72,[2,52]),{28:[1,590]},{24:162,28:$Vz,30:$VI2,33:$Vv,48:$VJ,49:418,53:$VJ2,64:$Vw,70:$Vx,72:$VE1,73:$VF1,74:$VG1,76:$VH1,80:$VI1,91:591,92:138,93:155,97:$Vy,123:$V_,124:223,125:$V$,140:136,143:$V11,144:$Vi,145:$Vj,172:$V31,173:$V41,174:$V51,180:$V61,181:140,182:$V71},o($V72,[2,53]),{24:162,28:$Vz,30:$VI2,33:$Vv,48:$VJ,49:418,53:$VJ2,64:$Vw,70:$Vx,72:$VE1,73:$VF1,74:$VG1,76:$VH1,80:$VI1,91:592,92:138,93:155,97:$Vy,123:$V_,124:223,125:$V$,140:136,143:$V11,144:$Vi,145:$Vj,172:$V31,173:$V41,174:$V51,180:$V61,181:140,182:$V71},{32:[1,593],66:$V_2},{55:[1,594],66:$V03},o($Vo1,[2,326]),{50:[1,595],109:$VM1,157:$VN1,158:$VO1,159:$VP1,160:$VQ1,161:$VR1,162:$VS1,163:$VT1,164:$VU1,165:$VV1,166:$VW1,167:$VX1,168:$VY1,169:$VZ1,170:$V_1,171:$V$1,173:$V02,174:$V12,175:$V22,176:$V32,177:$V42,178:$V52,179:$V62},o($V23,[2,95]),{55:[1,596],66:$V83},o($VD2,[2,236],{60:$V93,67:$Va3}),o($Vb3,$Vc3,{60:[1,600],109:$VM1,120:$Vd3,157:$VN1,158:$VO1,159:$VP1,160:$VQ1,161:$VR1,162:$VS1,163:$VT1,164:$VU1,165:$VV1,166:$VW1,167:$VX1,168:$VY1,169:$VZ1,170:$V_1,171:$V$1,173:$V02,174:$V12,175:$V22,176:$V32,177:$V42,178:$V52,179:$V62}),{24:162,28:$Vz,33:$Vv,48:$VJ,49:521,53:$V33,64:$Vw,70:$Vx,72:$VE1,73:$VF1,74:$VG1,76:$VH1,80:$VI1,92:138,93:155,97:$Vy,123:$V_,124:223,125:$V$,140:136,143:$V11,144:$Vi,145:$Vj,146:602,147:520,172:$V31,173:$V41,174:$V51,180:$V61,181:140,182:$V71},{182:$V43},{24:162,28:$Vz,33:$Vv,64:$Vw,70:$Vx,93:603,97:$Vy},{48:[1,604]},o($VL1,[2,284],{109:$VM1,157:$VN1,158:$VO1,159:$VP1,160:$VQ1,161:$VR1,162:$VS1,163:$VT1,164:$VU1,165:$VV1,166:$VW1,167:$VX1,168:$VY1,169:$VZ1,170:$V_1,171:$V$1,173:$V02,174:$V12,175:$V22,176:$V32,177:$V42,178:$V52,179:$V62}),{53:$VN2,138:605},o($VL1,[2,21],{30:[1,606]}),{32:[1,607]},{8:$VB,32:[2,41],37:608},o($Ve3,[2,100]),o($Ve3,[2,101]),o($Ve3,[2,102]),o($Ve3,[2,103]),o($Ve3,[2,104]),o($Ve3,[2,105]),o($Ve3,[2,106]),o($Ve3,[2,107]),{24:162,28:$Vz,33:$Vv,48:$VJ,49:609,64:$Vw,70:$Vx,72:$VE1,73:$VF1,74:$VG1,76:$VH1,80:$VI1,92:138,93:155,97:$Vy,123:$V_,124:223,125:$V$,140:136,143:$V11,144:$Vi,145:$Vj,172:$V31,173:$V41,174:$V51,180:$V61,181:140,182:$V71},{24:162,28:$Vz,33:$Vv,48:$VJ,49:611,53:[1,612],64:$Vw,70:$Vx,72:$VE1,73:$VF1,74:$VG1,76:$VH1,80:$VI1,92:138,93:155,97:$Vy,104:610,123:$V_,124:223,125:$V$,140:136,143:$V11,144:$Vi,145:$Vj,172:$V31,173:$V41,174:$V51,180:$V61,181:140,182:$V71},{8:$VB,11:118,12:107,13:103,14:104,15:108,16:109,17:110,18:111,19:122,20:$VC,21:$VD,22:114,23:$VE,24:162,25:113,26:$VF,28:$Vz,29:119,30:$VG,33:$Vv,35:613,36:300,37:301,38:413,46:115,47:$VI,48:$VJ,49:105,51:$VK,53:$VL,56:22,57:$V2,58:$V3,63:$V4,64:$Vw,70:$Vx,72:$VM,73:$VN,74:$VO,75:$V8,76:$VP,79:$Va,80:$VQ,81:$Vc,82:$Vd,84:$Ve,85:$Vf,87:102,89:106,90:112,92:138,93:155,97:$Vy,98:$VR,99:123,100:124,101:125,102:$VS,103:$VT,106:$VU,110:$VV,111:$VW,112:$VX,113:$VY,115:$VZ,123:$V_,124:132,125:$V$,126:31,131:$V01,137:153,139:$Vg,140:136,143:$V11,144:$Vi,145:$Vj,156:$V21,172:$V31,173:$V41,174:$V51,180:$V61,181:140,182:$V71},{24:162,28:$Vz,33:$Vv,48:$VJ,49:614,64:$Vw,70:$Vx,72:$VE1,73:$VF1,74:$VG1,76:$VH1,80:$VI1,92:138,93:155,97:$Vy,123:$V_,124:223,125:$V$,140:136,143:$V11,144:$Vi,145:$Vj,172:$V31,173:$V41,174:$V51,180:$V61,181:140,182:$V71},{24:162,28:$Vz,33:$Vv,48:$VJ,49:615,64:$Vw,70:$Vx,72:$VE1,73:$VF1,74:$VG1,76:$VH1,80:$VI1,92:138,93:155,97:$Vy,123:$V_,124:223,125:$V$,140:136,143:$V11,144:$Vi,145:$Vj,172:$V31,173:$V41,174:$V51,180:$V61,181:140,182:$V71},{30:[1,617],114:616},{8:$VB,11:118,12:107,13:103,14:104,15:108,16:109,17:110,18:111,19:122,20:$VC,21:$VD,22:114,23:$VE,24:162,25:113,26:$VF,28:$Vz,29:119,30:$VG,33:$Vv,35:618,36:300,37:301,38:413,46:115,47:$VI,48:$VJ,49:105,51:$VK,53:$VL,56:22,57:$V2,58:$V3,63:$V4,64:$Vw,70:$Vx,72:$VM,73:$VN,74:$VO,75:$V8,76:$VP,79:$Va,80:$VQ,81:$Vc,82:$Vd,84:$Ve,85:$Vf,87:102,89:106,90:112,92:138,93:155,97:$Vy,98:$VR,99:123,100:124,101:125,102:$VS,103:$VT,106:$VU,110:$VV,111:$VW,112:$VX,113:$VY,115:$VZ,123:$V_,124:132,125:$V$,126:31,131:$V01,137:153,139:$Vg,140:136,143:$V11,144:$Vi,145:$Vj,156:$V21,172:$V31,173:$V41,174:$V51,180:$V61,181:140,182:$V71},{55:[1,619],66:$VE2},o($VL1,[2,201]),{50:[1,620],109:$VM1,157:$VN1,158:$VO1,159:$VP1,160:$VQ1,161:$VR1,162:$VS1,163:$VT1,164:$VU1,165:$VV1,166:$VW1,167:$VX1,168:$VY1,169:$VZ1,170:$V_1,171:$V$1,173:$V02,174:$V12,175:$V22,176:$V32,177:$V42,178:$V52,179:$V62},o($Vo1,[2,131]),{24:162,28:$Vz,33:$Vv,48:$VJ,49:621,53:[1,622],64:$Vw,70:$Vx,72:$VE1,73:$VF1,74:$VG1,76:$VH1,80:$VI1,92:138,93:155,97:$Vy,123:$V_,124:223,125:$V$,140:136,143:$V11,144:$Vi,145:$Vj,172:$V31,173:$V41,174:$V51,180:$V61,181:140,182:$V71},{55:[1,623],66:$VE2},o($Vo1,[2,323]),{50:[1,624],109:$VM1,157:$VN1,158:$VO1,159:$VP1,160:$VQ1,161:$VR1,162:$VS1,163:$VT1,164:$VU1,165:$VV1,166:$VW1,167:$VX1,168:$VY1,169:$VZ1,170:$V_1,171:$V$1,173:$V02,174:$V12,175:$V22,176:$V32,177:$V42,178:$V52,179:$V62},o($Vo1,[2,324]),{50:[1,625],109:$VM1,157:$VN1,158:$VO1,159:$VP1,160:$VQ1,161:$VR1,162:$VS1,163:$VT1,164:$VU1,165:$VV1,166:$VW1,167:$VX1,168:$VY1,169:$VZ1,170:$V_1,171:$V$1,173:$V02,174:$V12,175:$V22,176:$V32,177:$V42,178:$V52,179:$V62},o($Vo1,[2,325]),{50:[1,626],109:$VM1,157:$VN1,158:$VO1,159:$VP1,160:$VQ1,161:$VR1,162:$VS1,163:$VT1,164:$VU1,165:$VV1,166:$VW1,167:$VX1,168:$VY1,169:$VZ1,170:$V_1,171:$V$1,173:$V02,174:$V12,175:$V22,176:$V32,177:$V42,178:$V52,179:$V62},o($Vo1,[2,327]),{50:[1,627],109:$VM1,157:$VN1,158:$VO1,159:$VP1,160:$VQ1,161:$VR1,162:$VS1,163:$VT1,164:$VU1,165:$VV1,166:$VW1,167:$VX1,168:$VY1,169:$VZ1,170:$V_1,171:$V$1,173:$V02,174:$V12,175:$V22,176:$V32,177:$V42,178:$V52,179:$V62},{55:[1,628]},o($VD2,[2,206]),{55:[1,629]},o($Vf3,[2,349]),{24:162,28:$Vz,33:$Vv,48:$VJ,49:630,55:[2,346],64:$Vw,70:$Vx,72:$VE1,73:$VF1,74:$VG1,76:$VH1,80:$VI1,92:138,93:155,97:$Vy,123:$V_,124:223,125:$V$,140:136,143:$V11,144:$Vi,145:$Vj,172:$V31,173:$V41,174:$V51,180:$V61,181:140,182:$V71},{55:[2,347],109:$VM1,157:$VN1,158:$VO1,159:$VP1,160:$VQ1,161:$VR1,162:$VS1,163:$VT1,164:$VU1,165:$VV1,166:$VW1,167:$VX1,168:$VY1,169:$VZ1,170:$V_1,171:$V$1,173:$V02,174:$V12,175:$V22,176:$V32,177:$V42,178:$V52,179:$V62},{57:$V91,61:631,62:632,69:395,72:$Vb1,73:$Vc1,74:$Vd1,75:$Ve1,76:$Vf1,79:$Vg1,80:$Vh1,81:$Vi1,82:$Vj1,83:$Vk1,84:$Vl1,85:$Vm1},{30:[1,633]},{32:[1,634]},{8:$VB,11:118,12:107,13:103,14:104,15:108,16:109,17:110,18:111,19:122,20:$VC,21:$VD,22:114,23:$VE,24:162,25:113,26:$VF,28:$Vz,29:119,30:$VG,32:$VH,33:$Vv,34:635,36:100,37:101,38:99,39:97,40:98,46:115,47:$VI,48:$VJ,49:105,51:$VK,53:$VL,56:22,57:$V2,58:$V3,63:$V4,64:$Vw,70:$Vx,72:$VM,73:$VN,74:$VO,75:$V8,76:$VP,79:$Va,80:$VQ,81:$Vc,82:$Vd,84:$Ve,85:$Vf,87:102,89:106,90:112,92:138,93:155,97:$Vy,98:$VR,99:123,100:124,101:125,102:$VS,103:$VT,106:$VU,110:$VV,111:$VW,112:$VX,113:$VY,115:$VZ,123:$V_,124:132,125:$V$,126:31,131:$V01,137:153,139:$Vg,140:136,143:$V11,144:$Vi,145:$Vj,156:$V21,172:$V31,173:$V41,174:$V51,180:$V61,181:140,182:$V71},{30:[1,636]},{30:[1,637]},o($Vn1,[2,272],{109:$VM1,157:$VN1,158:$VO1,159:$VP1,160:$VQ1,161:$VR1,162:$VS1,163:$VT1,164:$VU1,165:$VV1,166:$VW1,167:$VX1,168:$VY1,169:$VZ1,170:$V_1,171:$V$1,173:$V02,174:$V12,175:$V22,176:$V32,177:$V42,178:$V52,179:$V62}),o($Vt,[2,273]),o($Vs1,[2,258]),{50:[1,639],66:[1,638]},o($Vn1,[2,280],{66:$Vr1}),o($VS2,[2,357]),o($VS2,[2,358]),o($VT2,[2,194]),{24:162,28:$Vz,33:$Vv,48:$VJ,49:222,64:$Vw,67:$VD1,70:$Vx,72:$VE1,73:$VF1,74:$VG1,76:$VH1,80:$VI1,92:138,93:155,97:$Vy,105:640,123:$V_,124:223,125:$V$,140:136,143:$V11,144:$Vi,145:$Vj,172:$V31,173:$V41,174:$V51,180:$V61,181:140,182:$V71},{24:162,28:$Vz,33:$Vv,48:$VJ,49:222,64:$Vw,67:$VD1,70:$Vx,72:$VE1,73:$VF1,74:$VG1,76:$VH1,80:$VI1,92:138,93:155,97:$Vy,105:641,123:$V_,124:223,125:$V$,140:136,143:$V11,144:$Vi,145:$Vj,172:$V31,173:$V41,174:$V51,180:$V61,181:140,182:$V71},{24:162,28:$Vz,33:$Vv,48:$VJ,49:222,64:$Vw,67:$VD1,70:$Vx,72:$VE1,73:$VF1,74:$VG1,76:$VH1,80:$VI1,92:138,93:155,97:$Vy,105:642,123:$V_,124:223,125:$V$,140:136,143:$V11,144:$Vi,145:$Vj,172:$V31,173:$V41,174:$V51,180:$V61,181:140,182:$V71},{24:162,28:$Vz,33:$Vv,48:$VJ,49:222,64:$Vw,67:$VD1,70:$Vx,72:$VE1,73:$VF1,74:$VG1,76:$VH1,80:$VI1,92:138,93:155,97:$Vy,105:643,123:$V_,124:223,125:$V$,140:136,143:$V11,144:$Vi,145:$Vj,172:$V31,173:$V41,174:$V51,180:$V61,181:140,182:$V71},{24:162,28:$Vz,33:$Vv,48:$VJ,49:222,64:$Vw,67:$VD1,70:$Vx,72:$VE1,73:$VF1,74:$VG1,76:$VH1,80:$VI1,92:138,93:155,97:$Vy,105:644,123:$V_,124:223,125:$V$,140:136,143:$V11,144:$Vi,145:$Vj,172:$V31,173:$V41,174:$V51,180:$V61,181:140,182:$V71},{8:$VB,11:118,12:107,13:103,14:104,15:108,16:109,17:110,18:111,19:122,20:$VC,21:$VD,22:114,23:$VE,24:162,25:113,26:$VF,28:$Vz,29:119,30:$VG,32:$VH,33:$Vv,34:645,36:100,37:101,38:99,39:97,40:98,46:115,47:$VI,48:$VJ,49:105,51:$VK,53:$VL,56:22,57:$V2,58:$V3,63:$V4,64:$Vw,70:$Vx,72:$VM,73:$VN,74:$VO,75:$V8,76:$VP,79:$Va,80:$VQ,81:$Vc,82:$Vd,84:$Ve,85:$Vf,87:102,89:106,90:112,92:138,93:155,97:$Vy,98:$VR,99:123,100:124,101:125,102:$VS,103:$VT,106:$VU,110:$VV,111:$VW,112:$VX,113:$VY,115:$VZ,123:$V_,124:132,125:$V$,126:31,131:$V01,137:153,139:$Vg,140:136,143:$V11,144:$Vi,145:$Vj,156:$V21,172:$V31,173:$V41,174:$V51,180:$V61,181:140,182:$V71},{32:[1,646]},o($VF2,[2,251],{109:$VM1,157:$VN1,158:$VO1,159:$VP1,160:$VQ1,161:$VR1,162:$VS1,163:$VT1,164:$VU1,165:$VV1,166:$VW1,167:$VX1,168:$VY1,169:$VZ1,170:$V_1,171:$V$1,173:$V02,174:$V12,175:$V22,176:$V32,177:$V42,178:$V52,179:$V62}),o([6,8,20,21,26,32,33,50,55,57,58,60,63,64,66,67,72,73,74,75,76,79,80,81,82,84,85,88,110,120,139,148,149],[2,295],{109:$VM1,157:$VN1,158:$VO1,159:$VP1,160:$VQ1,161:$VR1,162:$VS1,163:$VT1,164:$VU1,165:$VV1,166:$VW1,167:$VX1,168:$VY1,169:$VZ1,170:$V_1,171:$V$1,173:$V02,174:$V12,175:$V22,176:$V32,177:$V42,178:$V52,179:$V62}),o($V72,[2,50]),o($V$2,[2,126],{60:[1,647]}),o($V$2,[2,127]),o($VD2,[2,129]),o($V13,[2,123]),o($V13,[2,124]),o($Vo1,[2,331]),o($Vg3,[2,222],{60:[1,649],67:[1,648]}),{24:162,28:$Vz,33:$Vv,48:$VJ,49:651,53:$V33,64:$Vw,70:$Vx,72:$VE1,73:$VF1,74:$VG1,76:$VH1,80:$VI1,92:138,93:155,97:$Vy,123:$V_,124:223,125:$V$,140:136,143:$V11,144:$Vi,145:$Vj,147:650,172:$V31,173:$V41,174:$V51,180:$V61,181:140,182:$V71},{24:162,28:$Vz,33:$Vv,48:$VJ,49:652,64:$Vw,70:$Vx,72:$VE1,73:$VF1,74:$VG1,76:$VH1,80:$VI1,92:138,93:155,97:$Vy,123:$V_,124:223,125:$V$,140:136,143:$V11,144:$Vi,145:$Vj,172:$V31,173:$V41,174:$V51,180:$V61,181:140,182:$V71},o($Vh3,[2,243]),{24:162,28:$Vz,33:$Vv,48:$VJ,49:653,64:$Vw,70:$Vx,72:$VE1,73:$VF1,74:$VG1,76:$VH1,80:$VI1,92:138,93:155,97:$Vy,123:$V_,124:223,125:$V$,140:136,143:$V11,144:$Vi,145:$Vj,172:$V31,173:$V41,174:$V51,180:$V61,181:140,182:$V71},{24:162,28:$Vz,33:$Vv,48:$VJ,49:654,64:$Vw,70:$Vx,72:$VE1,73:$VF1,74:$VG1,76:$VH1,80:$VI1,92:138,93:155,97:$Vy,123:$V_,124:223,125:$V$,140:136,143:$V11,144:$Vi,145:$Vj,172:$V31,173:$V41,174:$V51,180:$V61,181:140,182:$V71},{55:[1,655],66:$V83},o($Vp2,[2,339]),o($Vy2,$VO2,{140:136,92:138,181:140,93:155,24:162,124:223,49:461,94:656,28:$Vz,33:$Vv,48:$VJ,53:$VP2,64:$Vw,70:$Vx,72:$VE1,73:$VF1,74:$VG1,76:$VH1,80:$VI1,97:$Vy,123:$V_,125:$V$,143:$V11,144:$Vi,145:$Vj,172:$V31,173:$V41,174:$V51,180:$V61,182:$V71}),o($VL1,[2,285]),{13:532,14:533,15:534,16:535,17:536,18:537,19:538,26:$V1,31:657,32:$V53,41:530,57:$Vu,72:$V5,73:$V6,74:$V7,75:$V8,76:$V9,79:$Va,80:$Vb,81:$Vc,82:$Vd,84:$Ve,85:$Vf,86:531,126:31},o($V72,[2,22]),{8:$VK1,13:532,14:533,15:534,16:535,17:536,18:537,19:538,26:$V1,32:[2,42],57:$Vu,72:$V5,73:$V6,74:$V7,75:$V8,76:$V9,79:$Va,80:$Vb,81:$Vc,82:$Vd,84:$Ve,85:$Vf,86:658,126:31},{8:[1,659],109:$VM1,157:$VN1,158:$VO1,159:$VP1,160:$VQ1,161:$VR1,162:$VS1,163:$VT1,164:$VU1,165:$VV1,166:$VW1,167:$VX1,168:$VY1,169:$VZ1,170:$V_1,171:$V$1,173:$V02,174:$V12,175:$V22,176:$V32,177:$V42,178:$V52,179:$V62},{50:[1,660]},{50:[2,143],109:$VM1,157:$VN1,158:$VO1,159:$VP1,160:$VQ1,161:$VR1,162:$VS1,163:$VT1,164:$VU1,165:$VV1,166:$VW1,167:$VX1,168:$VY1,169:$VZ1,170:$V_1,171:$V$1,173:$V02,174:$V12,175:$V22,176:$V32,177:$V42,178:$V52,179:$V62},{24:162,28:$Vz,33:$Vv,48:$VJ,49:222,64:$Vw,67:$VD1,70:$Vx,72:$VE1,73:$VF1,74:$VG1,76:$VH1,80:$VI1,92:138,93:155,97:$Vy,105:661,123:$V_,124:223,125:$V$,140:136,143:$V11,144:$Vi,145:$Vj,172:$V31,173:$V41,174:$V51,180:$V61,181:140,182:$V71},o($V72,[2,147]),{50:[1,662],109:$VM1,157:$VN1,158:$VO1,159:$VP1,160:$VQ1,161:$VR1,162:$VS1,163:$VT1,164:$VU1,165:$VV1,166:$VW1,167:$VX1,168:$VY1,169:$VZ1,170:$V_1,171:$V$1,173:$V02,174:$V12,175:$V22,176:$V32,177:$V42,178:$V52,179:$V62},{50:[1,663],109:$VM1,157:$VN1,158:$VO1,159:$VP1,160:$VQ1,161:$VR1,162:$VS1,163:$VT1,164:$VU1,165:$VV1,166:$VW1,167:$VX1,168:$VY1,169:$VZ1,170:$V_1,171:$V$1,173:$V02,174:$V12,175:$V22,176:$V32,177:$V42,178:$V52,179:$V62},o($V72,[2,151]),{117:664,121:[1,665]},o([8,20,21,23,26,28,30,32,33,47,48,51,53,57,58,63,64,70,72,73,74,75,76,79,80,81,82,84,85,97,98,102,103,106,110,111,112,113,115,118,121,123,125,131,139,143,144,145,156,172,173,174,180,182],[2,152],{116:[1,666]}),o($VL1,[2,212]),o($Vp2,[2,335]),o($Vy2,[2,247],{109:$VM1,157:$VN1,158:$VO1,159:$VP1,160:$VQ1,161:$VR1,162:$VS1,163:$VT1,164:$VU1,165:$VV1,166:$VW1,167:$VX1,168:$VY1,169:$VZ1,170:$V_1,171:$V$1,173:$V02,174:$V12,175:$V22,176:$V32,177:$V42,178:$V52,179:$V62}),{24:162,28:$Vz,33:$Vv,48:$VJ,49:222,64:$Vw,67:$VD1,70:$Vx,72:$VE1,73:$VF1,74:$VG1,76:$VH1,80:$VI1,92:138,93:155,97:$Vy,105:667,123:$V_,124:223,125:$V$,140:136,143:$V11,144:$Vi,145:$Vj,172:$V31,173:$V41,174:$V51,180:$V61,181:140,182:$V71},o($Vy2,[2,249]),o($Vo1,[2,328]),o($Vo1,[2,329]),o($Vo1,[2,330]),o($Vo1,[2,332]),{129:[2,210]},o($Vf3,[2,348]),{55:[2,345],109:$VM1,157:$VN1,158:$VO1,159:$VP1,160:$VQ1,161:$VR1,162:$VS1,163:$VT1,164:$VU1,165:$VV1,166:$VW1,167:$VX1,168:$VY1,169:$VZ1,170:$V_1,171:$V$1,173:$V02,174:$V12,175:$V22,176:$V32,177:$V42,178:$V52,179:$V62},{55:[1,668],66:[1,669]},o($VD2,[2,94]),{8:$VB,11:118,12:107,13:103,14:104,15:108,16:109,17:110,18:111,19:122,20:$VC,21:$VD,22:114,23:$VE,24:162,25:113,26:$VF,28:$Vz,29:119,30:$VG,32:$VH,33:$Vv,34:670,36:100,37:101,38:99,39:97,40:98,46:115,47:$VI,48:$VJ,49:105,51:$VK,53:$VL,56:22,57:$V2,58:$V3,63:$V4,64:$Vw,70:$Vx,72:$VM,73:$VN,74:$VO,75:$V8,76:$VP,79:$Va,80:$VQ,81:$Vc,82:$Vd,84:$Ve,85:$Vf,87:102,89:106,90:112,92:138,93:155,97:$Vy,98:$VR,99:123,100:124,101:125,102:$VS,103:$VT,106:$VU,110:$VV,111:$VW,112:$VX,113:$VY,115:$VZ,123:$V_,124:132,125:$V$,126:31,131:$V01,137:153,139:$Vg,140:136,143:$V11,144:$Vi,145:$Vj,156:$V21,172:$V31,173:$V41,174:$V51,180:$V61,181:140,182:$V71},o($Vi3,[2,62]),{32:[1,671]},{8:$VB,11:118,12:107,13:103,14:104,15:108,16:109,17:110,18:111,19:122,20:$VC,21:$VD,22:114,23:$VE,24:162,25:113,26:$VF,28:$Vz,29:119,30:$VG,32:$VH,33:$Vv,34:672,36:100,37:101,38:99,39:97,40:98,46:115,47:$VI,48:$VJ,49:105,51:$VK,53:$VL,56:22,57:$V2,58:$V3,63:$V4,64:$Vw,70:$Vx,72:$VM,73:$VN,74:$VO,75:$V8,76:$VP,79:$Va,80:$VQ,81:$Vc,82:$Vd,84:$Ve,85:$Vf,87:102,89:106,90:112,92:138,93:155,97:$Vy,98:$VR,99:123,100:124,101:125,102:$VS,103:$VT,106:$VU,110:$VV,111:$VW,112:$VX,113:$VY,115:$VZ,123:$V_,124:132,125:$V$,126:31,131:$V01,137:153,139:$Vg,140:136,143:$V11,144:$Vi,145:$Vj,156:$V21,172:$V31,173:$V41,174:$V51,180:$V61,181:140,182:$V71},{8:$VB,11:118,12:107,13:103,14:104,15:108,16:109,17:110,18:111,19:122,20:$VC,21:$VD,22:114,23:$VE,24:162,25:113,26:$VF,28:$Vz,29:119,30:$VG,32:$VH,33:$Vv,34:673,36:100,37:101,38:99,39:97,40:98,46:115,47:$VI,48:$VJ,49:105,51:$VK,53:$VL,56:22,57:$V2,58:$V3,63:$V4,64:$Vw,70:$Vx,72:$VM,73:$VN,74:$VO,75:$V8,76:$VP,79:$Va,80:$VQ,81:$Vc,82:$Vd,84:$Ve,85:$Vf,87:102,89:106,90:112,92:138,93:155,97:$Vy,98:$VR,99:123,100:124,101:125,102:$VS,103:$VT,106:$VU,110:$VV,111:$VW,112:$VX,113:$VY,115:$VZ,123:$V_,124:132,125:$V$,126:31,131:$V01,137:153,139:$Vg,140:136,143:$V11,144:$Vi,145:$Vj,156:$V21,172:$V31,173:$V41,174:$V51,180:$V61,181:140,182:$V71},{24:162,28:$Vz,33:$Vv,48:$VJ,49:222,64:$Vw,67:$VD1,70:$Vx,72:$VE1,73:$VF1,74:$VG1,76:$VH1,80:$VI1,92:138,93:155,97:$Vy,105:674,123:$V_,124:223,125:$V$,140:136,143:$V11,144:$Vi,145:$Vj,172:$V31,173:$V41,174:$V51,180:$V61,181:140,182:$V71},{28:[1,675]},{55:[1,676],66:$VE2},{55:[1,677],66:$VE2},{55:[1,678],66:$VE2},{55:[1,679],66:$VE2},{55:[1,680],66:$VE2},{32:[1,681]},o($V0,[2,282]),{24:162,28:$Vz,30:$VI2,33:$Vv,48:$VJ,49:418,53:$VJ2,64:$Vw,70:$Vx,72:$VE1,73:$VF1,74:$VG1,76:$VH1,80:$VI1,91:682,92:138,93:155,97:$Vy,123:$V_,124:223,125:$V$,140:136,143:$V11,144:$Vi,145:$Vj,172:$V31,173:$V41,174:$V51,180:$V61,181:140,182:$V71},o($Vg3,[2,223]),{24:162,28:$Vz,33:$Vv,48:$VJ,49:683,64:$Vw,70:$Vx,72:$VE1,73:$VF1,74:$VG1,76:$VH1,80:$VI1,92:138,93:155,97:$Vy,123:$V_,124:223,125:$V$,140:136,143:$V11,144:$Vi,145:$Vj,172:$V31,173:$V41,174:$V51,180:$V61,181:140,182:$V71},o($VD2,[2,226],{60:$V93,67:$Va3}),o($Vb3,$Vc3,{60:[1,684],109:$VM1,120:$Vd3,148:[1,685],149:[1,686],157:$VN1,158:$VO1,159:$VP1,160:$VQ1,161:$VR1,162:$VS1,163:$VT1,164:$VU1,165:$VV1,166:$VW1,167:$VX1,168:$VY1,169:$VZ1,170:$V_1,171:$V$1,173:$V02,174:$V12,175:$V22,176:$V32,177:$V42,178:$V52,179:$V62}),o($Vh3,[2,238],{109:$VM1,157:$VN1,158:$VO1,159:$VP1,160:$VQ1,161:$VR1,162:$VS1,163:$VT1,164:$VU1,165:$VV1,166:$VW1,167:$VX1,168:$VY1,169:$VZ1,170:$V_1,171:$V$1,173:$V02,174:$V12,175:$V22,176:$V32,177:$V42,178:$V52,179:$V62}),o($VD2,[2,237],{109:$VM1,120:$Vj3,157:$VN1,158:$VO1,159:$VP1,160:$VQ1,161:$VR1,162:$VS1,163:$VT1,164:$VU1,165:$VV1,166:$VW1,167:$VX1,168:$VY1,169:$VZ1,170:$V_1,171:$V$1,173:$V02,174:$V12,175:$V22,176:$V32,177:$V42,178:$V52,179:$V62}),o($Vb3,[2,239],{60:[1,688],109:$VM1,157:$VN1,158:$VO1,159:$VP1,160:$VQ1,161:$VR1,162:$VS1,163:$VT1,164:$VU1,165:$VV1,166:$VW1,167:$VX1,168:$VY1,169:$VZ1,170:$V_1,171:$V$1,173:$V02,174:$V12,175:$V22,176:$V32,177:$V42,178:$V52,179:$V62}),o($Vh3,[2,244]),{50:[1,689],66:$V73},{32:[1,690]},o($Ve3,[2,99]),{24:162,28:$Vz,33:$Vv,48:$Vh2,64:$Vw,70:$Vx,93:283,97:$Vy,99:693,108:691,122:692,123:$Vk3,124:696,125:$Vl3,143:$Vi2,180:$Vj2,182:$V71},{8:$VB,11:118,12:107,13:103,14:104,15:108,16:109,17:110,18:111,19:122,20:$VC,21:$VD,22:114,23:$VE,24:162,25:113,26:$VF,28:$Vz,29:119,30:$VG,33:$Vv,35:697,36:300,37:301,38:413,46:115,47:$VI,48:$VJ,49:105,51:$VK,53:$VL,56:22,57:$V2,58:$V3,63:$V4,64:$Vw,70:$Vx,72:$VM,73:$VN,74:$VO,75:$V8,76:$VP,79:$Va,80:$VQ,81:$Vc,82:$Vd,84:$Ve,85:$Vf,87:102,89:106,90:112,92:138,93:155,97:$Vy,98:$VR,99:123,100:124,101:125,102:$VS,103:$VT,106:$VU,110:$VV,111:$VW,112:$VX,113:$VY,115:$VZ,123:$V_,124:132,125:$V$,126:31,131:$V01,137:153,139:$Vg,140:136,143:$V11,144:$Vi,145:$Vj,156:$V21,172:$V31,173:$V41,174:$V51,180:$V61,181:140,182:$V71},{55:[1,698],66:$VE2},o($V72,[2,148]),o($V72,[2,149]),{32:[1,699],118:[1,700],121:[1,701]},{24:162,28:$Vz,33:$Vv,48:$VJ,49:703,64:$Vw,70:$Vx,72:$VE1,73:$VF1,74:$VG1,76:$VH1,80:$VI1,92:138,93:155,97:$Vy,119:702,123:$V_,124:223,125:$V$,140:136,143:$V11,144:$Vi,145:$Vj,172:$V31,173:$V41,174:$V51,180:$V61,181:140,182:$V71},{8:$VB,11:118,12:107,13:103,14:104,15:108,16:109,17:110,18:111,19:122,20:$VC,21:$VD,22:114,23:$VE,24:162,25:113,26:$VF,28:$Vz,29:119,30:$VG,33:$Vv,35:704,36:300,37:301,38:413,46:115,47:$VI,48:$VJ,49:105,51:$VK,53:$VL,56:22,57:$V2,58:$V3,63:$V4,64:$Vw,70:$Vx,72:$VM,73:$VN,74:$VO,75:$V8,76:$VP,79:$Va,80:$VQ,81:$Vc,82:$Vd,84:$Ve,85:$Vf,87:102,89:106,90:112,92:138,93:155,97:$Vy,98:$VR,99:123,100:124,101:125,102:$VS,103:$VT,106:$VU,110:$VV,111:$VW,112:$VX,113:$VY,115:$VZ,123:$V_,124:132,125:$V$,126:31,131:$V01,137:153,139:$Vg,140:136,143:$V11,144:$Vi,145:$Vj,156:$V21,172:$V31,173:$V41,174:$V51,180:$V61,181:140,182:$V71},{55:[1,705],66:$VE2},{30:[1,706]},{57:$V91,62:707,69:395,72:$Vb1,73:$Vc1,74:$Vd1,75:$Ve1,76:$Vf1,79:$Vg1,80:$Vh1,81:$Vi1,82:$Vj1,83:$Vk1,84:$Vl1,85:$Vm1},{32:[1,708]},o($Vi3,[2,63]),{32:[1,709]},{32:[1,710]},{50:[1,711],66:$VE2},{53:[1,712]},o($Vt,[2,186]),o($Vt,[2,187]),o($Vt,[2,188]),o($Vt,[2,189]),o($Vt,[2,190]),o($V0,[2,281]),o($V$2,[2,125]),o($Vg3,[2,224],{67:[1,713],157:$VN1,158:$VO1,159:$VP1,160:$VQ1,161:$VR1,162:$VS1,163:$VT1,164:$VU1,165:$VV1,166:$VW1,167:$VX1,168:$VY1,169:$VZ1,170:$V_1,171:$V$1,173:$V02,174:$V12,175:$V22,176:$V32,177:$V42,178:$V52,179:$V62}),{24:162,28:$Vz,33:$Vv,48:$VJ,49:714,64:$Vw,70:$Vx,72:$VE1,73:$VF1,74:$VG1,76:$VH1,80:$VI1,92:138,93:155,97:$Vy,123:$V_,124:223,125:$V$,140:136,143:$V11,144:$Vi,145:$Vj,172:$V31,173:$V41,174:$V51,180:$V61,181:140,182:$V71},o($VD2,[2,232],{140:136,92:138,181:140,93:155,24:162,124:223,49:715,28:$Vz,33:$Vv,48:$VJ,64:$Vw,70:$Vx,72:$VE1,73:$VF1,74:$VG1,76:$VH1,80:$VI1,97:$Vy,123:$V_,125:$V$,143:$V11,144:$Vi,145:$Vj,172:$V31,173:$V41,174:$V51,180:$V61,182:$V71}),o($VD2,[2,233],{140:136,92:138,181:140,93:155,24:162,124:223,49:716,28:$Vz,33:$Vv,48:$VJ,64:$Vw,70:$Vx,72:$VE1,73:$VF1,74:$VG1,76:$VH1,80:$VI1,97:$Vy,123:$V_,125:$V$,143:$V11,144:$Vi,145:$Vj,172:$V31,173:$V41,174:$V51,180:$V61,182:$V71}),{24:162,28:$Vz,33:$Vv,48:$VJ,49:717,64:$Vw,70:$Vx,72:$VE1,73:$VF1,74:$VG1,76:$VH1,80:$VI1,92:138,93:155,97:$Vy,123:$V_,124:223,125:$V$,140:136,143:$V11,144:$Vi,145:$Vj,172:$V31,173:$V41,174:$V51,180:$V61,181:140,182:$V71},{24:162,28:$Vz,33:$Vv,48:$VJ,49:718,64:$Vw,70:$Vx,72:$VE1,73:$VF1,74:$VG1,76:$VH1,80:$VI1,92:138,93:155,97:$Vy,123:$V_,124:223,125:$V$,140:136,143:$V11,144:$Vi,145:$Vj,172:$V31,173:$V41,174:$V51,180:$V61,181:140,182:$V71},o($VL1,[2,136]),o($V72,[2,23]),{50:[1,719],66:[1,720]},o($Vy2,[2,216]),o($Vy2,[2,164]),{24:162,28:$Vz,33:$Vv,48:$Vh2,64:$Vw,70:$Vx,93:283,97:$Vy,124:721,143:$Vi2,180:$Vj2,182:$V71},{24:162,28:$Vz,33:$Vv,48:$Vh2,64:$Vw,70:$Vx,93:283,97:$Vy,124:722,143:$Vi2,180:$Vj2,182:$V71},{123:[1,723],125:[1,724],129:$Vd2,132:277,133:$Ve2,134:$Vf2,135:$Vg2},o($V72,[2,146]),{50:[2,144]},o($V72,[2,156]),{60:[1,725]},{24:162,28:$Vz,33:$Vv,48:$VJ,49:703,64:$Vw,70:$Vx,72:$VE1,73:$VF1,74:$VG1,76:$VH1,80:$VI1,92:138,93:155,97:$Vy,119:726,123:$V_,124:223,125:$V$,140:136,143:$V11,144:$Vi,145:$Vj,172:$V31,173:$V41,174:$V51,180:$V61,181:140,182:$V71},{60:[1,727],66:$Vm3},o($Vn3,[2,160],{109:$VM1,120:[1,729],157:$VN1,158:$VO1,159:$VP1,160:$VQ1,161:$VR1,162:$VS1,163:$VT1,164:$VU1,165:$VV1,166:$VW1,167:$VX1,168:$VY1,169:$VZ1,170:$V_1,171:$V$1,173:$V02,174:$V12,175:$V22,176:$V32,177:$V42,178:$V52,179:$V62}),o($V72,[2,153]),o($Vy2,[2,248]),{8:$VB,11:118,12:107,13:103,14:104,15:108,16:109,17:110,18:111,19:122,20:$VC,21:$VD,22:114,23:$VE,24:162,25:113,26:$VF,28:$Vz,29:119,30:$VG,32:$VH,33:$Vv,34:730,36:100,37:101,38:99,39:97,40:98,46:115,47:$VI,48:$VJ,49:105,51:$VK,53:$VL,56:22,57:$V2,58:$V3,63:$V4,64:$Vw,70:$Vx,72:$VM,73:$VN,74:$VO,75:$V8,76:$VP,79:$Va,80:$VQ,81:$Vc,82:$Vd,84:$Ve,85:$Vf,87:102,89:106,90:112,92:138,93:155,97:$Vy,98:$VR,99:123,100:124,101:125,102:$VS,103:$VT,106:$VU,110:$VV,111:$VW,112:$VX,113:$VY,115:$VZ,123:$V_,124:132,125:$V$,126:31,131:$V01,137:153,139:$Vg,140:136,143:$V11,144:$Vi,145:$Vj,156:$V21,172:$V31,173:$V41,174:$V51,180:$V61,181:140,182:$V71},o($VD2,[2,93]),o($Vi3,[2,61]),o($Vi3,[2,64]),o($Vi3,[2,65]),{28:[1,731]},{24:162,28:$Vz,33:$Vv,48:$VJ,49:732,64:$Vw,70:$Vx,72:$VE1,73:$VF1,74:$VG1,76:$VH1,80:$VI1,92:138,93:155,97:$Vy,123:$V_,124:223,125:$V$,140:136,143:$V11,144:$Vi,145:$Vj,172:$V31,173:$V41,174:$V51,180:$V61,181:140,182:$V71},o($Vg3,[2,225]),o($VD2,[2,227],{109:$VM1,120:$Vj3,148:[1,733],149:[1,734],157:$VN1,158:$VO1,159:$VP1,160:$VQ1,161:$VR1,162:$VS1,163:$VT1,164:$VU1,165:$VV1,166:$VW1,167:$VX1,168:$VY1,169:$VZ1,170:$V_1,171:$V$1,173:$V02,174:$V12,175:$V22,176:$V32,177:$V42,178:$V52,179:$V62}),o($VD2,[2,228],{109:$VM1,157:$VN1,158:$VO1,159:$VP1,160:$VQ1,161:$VR1,162:$VS1,163:$VT1,164:$VU1,165:$VV1,166:$VW1,167:$VX1,168:$VY1,169:$VZ1,170:$V_1,171:$V$1,173:$V02,174:$V12,175:$V22,176:$V32,177:$V42,178:$V52,179:$V62}),o($VD2,[2,229],{109:$VM1,157:$VN1,158:$VO1,159:$VP1,160:$VQ1,161:$VR1,162:$VS1,163:$VT1,164:$VU1,165:$VV1,166:$VW1,167:$VX1,168:$VY1,169:$VZ1,170:$V_1,171:$V$1,173:$V02,174:$V12,175:$V22,176:$V32,177:$V42,178:$V52,179:$V62}),o($Vb3,[2,241],{60:[1,735],109:$VM1,157:$VN1,158:$VO1,159:$VP1,160:$VQ1,161:$VR1,162:$VS1,163:$VT1,164:$VU1,165:$VV1,166:$VW1,167:$VX1,168:$VY1,169:$VZ1,170:$V_1,171:$V$1,173:$V02,174:$V12,175:$V22,176:$V32,177:$V42,178:$V52,179:$V62}),o($Vh3,[2,240],{109:$VM1,157:$VN1,158:$VO1,159:$VP1,160:$VQ1,161:$VR1,162:$VS1,163:$VT1,164:$VU1,165:$VV1,166:$VW1,167:$VX1,168:$VY1,169:$VZ1,170:$V_1,171:$V$1,173:$V02,174:$V12,175:$V22,176:$V32,177:$V42,178:$V52,179:$V62}),{8:$VB,11:118,12:107,13:103,14:104,15:108,16:109,17:110,18:111,19:122,20:$VC,21:$VD,22:114,23:$VE,24:162,25:113,26:$VF,28:$Vz,29:119,30:$VG,33:$Vv,35:736,36:300,37:301,38:413,46:115,47:$VI,48:$VJ,49:105,51:$VK,53:$VL,56:22,57:$V2,58:$V3,63:$V4,64:$Vw,70:$Vx,72:$VM,73:$VN,74:$VO,75:$V8,76:$VP,79:$Va,80:$VQ,81:$Vc,82:$Vd,84:$Ve,85:$Vf,87:102,89:106,90:112,92:138,93:155,97:$Vy,98:$VR,99:123,100:124,101:125,102:$VS,103:$VT,106:$VU,110:$VV,111:$VW,112:$VX,113:$VY,115:$VZ,123:$V_,124:132,125:$V$,126:31,131:$V01,137:153,139:$Vg,140:136,143:$V11,144:$Vi,145:$Vj,156:$V21,172:$V31,173:$V41,174:$V51,180:$V61,181:140,182:$V71},{24:162,28:$Vz,33:$Vv,48:$Vh2,64:$Vw,70:$Vx,93:283,97:$Vy,99:693,122:737,123:$Vk3,124:696,125:$Vl3,143:$Vi2,180:$Vj2,182:$V71},o($Vy2,[2,165]),o($Vy2,[2,166]),o($Vy2,[2,167]),o($Vy2,[2,168]),{8:$VB,11:118,12:107,13:103,14:104,15:108,16:109,17:110,18:111,19:122,20:$VC,21:$VD,22:114,23:$VE,24:162,25:113,26:$VF,28:$Vz,29:119,30:$VG,33:$Vv,36:100,37:101,38:99,39:738,40:98,46:115,47:$VI,48:$VJ,49:105,51:$VK,53:$VL,56:22,57:$V2,58:$V3,63:$V4,64:$Vw,70:$Vx,72:$VM,73:$VN,74:$VO,75:$V8,76:$VP,79:$Va,80:$VQ,81:$Vc,82:$Vd,84:$Ve,85:$Vf,87:102,89:106,90:112,92:138,93:155,97:$Vy,98:$VR,99:123,100:124,101:125,102:$VS,103:$VT,106:$VU,110:$VV,111:$VW,112:$VX,113:$VY,115:$VZ,123:$V_,124:132,125:$V$,126:31,131:$V01,137:153,139:$Vg,140:136,143:$V11,144:$Vi,145:$Vj,156:$V21,172:$V31,173:$V41,174:$V51,180:$V61,181:140,182:$V71},{60:[1,739],66:$Vm3},{8:$VB,11:118,12:107,13:103,14:104,15:108,16:109,17:110,18:111,19:122,20:$VC,21:$VD,22:114,23:$VE,24:162,25:113,26:$VF,28:$Vz,29:119,30:$VG,33:$Vv,36:100,37:101,38:741,40:740,46:115,47:$VI,48:$VJ,49:105,51:$VK,53:$VL,56:22,57:$V2,58:$V3,63:$V4,64:$Vw,70:$Vx,72:$VM,73:$VN,74:$VO,75:$V8,76:$VP,79:$Va,80:$VQ,81:$Vc,82:$Vd,84:$Ve,85:$Vf,87:102,89:106,90:112,92:138,93:155,97:$Vy,98:$VR,99:123,100:124,101:125,102:$VS,103:$VT,106:$VU,110:$VV,111:$VW,112:$VX,113:$VY,115:$VZ,123:$V_,124:132,125:$V$,126:31,131:$V01,137:153,139:$Vg,140:136,143:$V11,144:$Vi,145:$Vj,156:$V21,172:$V31,173:$V41,174:$V51,180:$V61,181:140,182:$V71},{24:162,28:$Vz,33:$Vv,48:$VJ,49:742,64:$Vw,70:$Vx,72:$VE1,73:$VF1,74:$VG1,76:$VH1,80:$VI1,92:138,93:155,97:$Vy,123:$V_,124:223,125:$V$,140:136,143:$V11,144:$Vi,145:$Vj,172:$V31,173:$V41,174:$V51,180:$V61,181:140,182:$V71},{24:162,28:$Vz,33:$Vv,48:$VJ,49:743,64:$Vw,70:$Vx,72:$VE1,73:$VF1,74:$VG1,76:$VH1,80:$VI1,92:138,93:155,97:$Vy,123:$V_,124:223,125:$V$,140:136,143:$V11,144:$Vi,145:$Vj,172:$V31,173:$V41,174:$V51,180:$V61,181:140,182:$V71},{32:[1,744]},{53:[1,745]},{55:[1,746],109:$VM1,157:$VN1,158:$VO1,159:$VP1,160:$VQ1,161:$VR1,162:$VS1,163:$VT1,164:$VU1,165:$VV1,166:$VW1,167:$VX1,168:$VY1,169:$VZ1,170:$V_1,171:$V$1,173:$V02,174:$V12,175:$V22,176:$V32,177:$V42,178:$V52,179:$V62},o($VD2,[2,234],{140:136,92:138,181:140,93:155,24:162,124:223,49:747,28:$Vz,33:$Vv,48:$VJ,64:$Vw,70:$Vx,72:$VE1,73:$VF1,74:$VG1,76:$VH1,80:$VI1,97:$Vy,123:$V_,125:$V$,143:$V11,144:$Vi,145:$Vj,172:$V31,173:$V41,174:$V51,180:$V61,182:$V71}),o($VD2,[2,235],{140:136,92:138,181:140,93:155,24:162,124:223,49:748,28:$Vz,33:$Vv,48:$VJ,64:$Vw,70:$Vx,72:$VE1,73:$VF1,74:$VG1,76:$VH1,80:$VI1,97:$Vy,123:$V_,125:$V$,143:$V11,144:$Vi,145:$Vj,172:$V31,173:$V41,174:$V51,180:$V61,182:$V71}),{24:162,28:$Vz,33:$Vv,48:$VJ,49:749,64:$Vw,70:$Vx,72:$VE1,73:$VF1,74:$VG1,76:$VH1,80:$VI1,92:138,93:155,97:$Vy,123:$V_,124:223,125:$V$,140:136,143:$V11,144:$Vi,145:$Vj,172:$V31,173:$V41,174:$V51,180:$V61,181:140,182:$V71},o($V72,[2,145]),o($Vy2,[2,215]),{32:[1,750]},{8:$VB,11:118,12:107,13:103,14:104,15:108,16:109,17:110,18:111,19:122,20:$VC,21:$VD,22:114,23:$VE,24:162,25:113,26:$VF,28:$Vz,29:119,30:$VG,33:$Vv,36:100,37:101,38:741,40:751,46:115,47:$VI,48:$VJ,49:105,51:$VK,53:$VL,56:22,57:$V2,58:$V3,63:$V4,64:$Vw,70:$Vx,72:$VM,73:$VN,74:$VO,75:$V8,76:$VP,79:$Va,80:$VQ,81:$Vc,82:$Vd,84:$Ve,85:$Vf,87:102,89:106,90:112,92:138,93:155,97:$Vy,98:$VR,99:123,100:124,101:125,102:$VS,103:$VT,106:$VU,110:$VV,111:$VW,112:$VX,113:$VY,115:$VZ,123:$V_,124:132,125:$V$,126:31,131:$V01,137:153,139:$Vg,140:136,143:$V11,144:$Vi,145:$Vj,156:$V21,172:$V31,173:$V41,174:$V51,180:$V61,181:140,182:$V71},o($Vo3,[2,163],{56:22,126:31,87:102,13:103,14:104,49:105,89:106,12:107,15:108,16:109,17:110,18:111,90:112,25:113,22:114,46:115,11:118,29:119,19:122,99:123,100:124,101:125,124:132,140:136,92:138,181:140,137:153,93:155,24:162,36:232,38:752,20:$VC,21:$VD,23:$VE,26:$VF,28:$Vz,30:$VG,33:$Vv,47:$VI,48:$VJ,51:$VK,53:$VL,57:$V2,58:$V3,63:$V4,64:$Vw,70:$Vx,72:$VM,73:$VN,74:$VO,75:$V8,76:$VP,79:$Va,80:$VQ,81:$Vc,82:$Vd,84:$Ve,85:$Vf,97:$Vy,98:$VR,102:$VS,103:$VT,106:$VU,110:$VV,111:$VW,112:$VX,113:$VY,115:$VZ,123:$V_,125:$V$,131:$V01,139:$Vg,143:$V11,144:$Vi,145:$Vj,156:$V21,172:$V31,173:$V41,174:$V51,180:$V61,182:$V71}),{8:$VB,37:233},o($Vn3,[2,158],{109:$VM1,120:[1,753],157:$VN1,158:$VO1,159:$VP1,160:$VQ1,161:$VR1,162:$VS1,163:$VT1,164:$VU1,165:$VV1,166:$VW1,167:$VX1,168:$VY1,169:$VZ1,170:$V_1,171:$V$1,173:$V02,174:$V12,175:$V22,176:$V32,177:$V42,178:$V52,179:$V62}),o($Vn3,[2,161],{109:$VM1,157:$VN1,158:$VO1,159:$VP1,160:$VQ1,161:$VR1,162:$VS1,163:$VT1,164:$VU1,165:$VV1,166:$VW1,167:$VX1,168:$VY1,169:$VZ1,170:$V_1,171:$V$1,173:$V02,174:$V12,175:$V22,176:$V32,177:$V42,178:$V52,179:$V62}),o($Vi3,[2,60]),{24:162,28:$Vz,33:$Vv,48:$VJ,49:754,64:$Vw,70:$Vx,72:$VE1,73:$VF1,74:$VG1,76:$VH1,80:$VI1,92:138,93:155,97:$Vy,123:$V_,124:223,125:$V$,140:136,143:$V11,144:$Vi,145:$Vj,172:$V31,173:$V41,174:$V51,180:$V61,181:140,182:$V71},{53:[1,755]},{60:[1,756],109:$VM1,157:$VN1,158:$VO1,159:$VP1,160:$VQ1,161:$VR1,162:$VS1,163:$VT1,164:$VU1,165:$VV1,166:$VW1,167:$VX1,168:$VY1,169:$VZ1,170:$V_1,171:$V$1,173:$V02,174:$V12,175:$V22,176:$V32,177:$V42,178:$V52,179:$V62},{60:[1,757],109:$VM1,157:$VN1,158:$VO1,159:$VP1,160:$VQ1,161:$VR1,162:$VS1,163:$VT1,164:$VU1,165:$VV1,166:$VW1,167:$VX1,168:$VY1,169:$VZ1,170:$V_1,171:$V$1,173:$V02,174:$V12,175:$V22,176:$V32,177:$V42,178:$V52,179:$V62},o($Vh3,[2,242],{109:$VM1,157:$VN1,158:$VO1,159:$VP1,160:$VQ1,161:$VR1,162:$VS1,163:$VT1,164:$VU1,165:$VV1,166:$VW1,167:$VX1,168:$VY1,169:$VZ1,170:$V_1,171:$V$1,173:$V02,174:$V12,175:$V22,176:$V32,177:$V42,178:$V52,179:$V62}),o($V72,[2,157]),o($Vo3,[2,162],{56:22,126:31,87:102,13:103,14:104,49:105,89:106,12:107,15:108,16:109,17:110,18:111,90:112,25:113,22:114,46:115,11:118,29:119,19:122,99:123,100:124,101:125,124:132,140:136,92:138,181:140,137:153,93:155,24:162,36:232,38:752,20:$VC,21:$VD,23:$VE,26:$VF,28:$Vz,30:$VG,33:$Vv,47:$VI,48:$VJ,51:$VK,53:$VL,57:$V2,58:$V3,63:$V4,64:$Vw,70:$Vx,72:$VM,73:$VN,74:$VO,75:$V8,76:$VP,79:$Va,80:$VQ,81:$Vc,82:$Vd,84:$Ve,85:$Vf,97:$Vy,98:$VR,102:$VS,103:$VT,106:$VU,110:$VV,111:$VW,112:$VX,113:$VY,115:$VZ,123:$V_,125:$V$,131:$V01,139:$Vg,143:$V11,144:$Vi,145:$Vj,156:$V21,172:$V31,173:$V41,174:$V51,180:$V61,182:$V71}),{8:$VB,37:384},{24:162,28:$Vz,33:$Vv,48:$VJ,49:758,64:$Vw,70:$Vx,72:$VE1,73:$VF1,74:$VG1,76:$VH1,80:$VI1,92:138,93:155,97:$Vy,123:$V_,124:223,125:$V$,140:136,143:$V11,144:$Vi,145:$Vj,172:$V31,173:$V41,174:$V51,180:$V61,181:140,182:$V71},{55:[1,759],109:$VM1,157:$VN1,158:$VO1,159:$VP1,160:$VQ1,161:$VR1,162:$VS1,163:$VT1,164:$VU1,165:$VV1,166:$VW1,167:$VX1,168:$VY1,169:$VZ1,170:$V_1,171:$V$1,173:$V02,174:$V12,175:$V22,176:$V32,177:$V42,178:$V52,179:$V62},{24:162,28:$Vz,33:$Vv,48:$VJ,49:760,64:$Vw,70:$Vx,72:$VE1,73:$VF1,74:$VG1,76:$VH1,80:$VI1,92:138,93:155,97:$Vy,123:$V_,124:223,125:$V$,140:136,143:$V11,144:$Vi,145:$Vj,172:$V31,173:$V41,174:$V51,180:$V61,181:140,182:$V71},{24:162,28:$Vz,33:$Vv,48:$VJ,49:761,64:$Vw,70:$Vx,72:$VE1,73:$VF1,74:$VG1,76:$VH1,80:$VI1,92:138,93:155,97:$Vy,123:$V_,124:223,125:$V$,140:136,143:$V11,144:$Vi,145:$Vj,172:$V31,173:$V41,174:$V51,180:$V61,181:140,182:$V71},{24:162,28:$Vz,33:$Vv,48:$VJ,49:762,64:$Vw,70:$Vx,72:$VE1,73:$VF1,74:$VG1,76:$VH1,80:$VI1,92:138,93:155,97:$Vy,123:$V_,124:223,125:$V$,140:136,143:$V11,144:$Vi,145:$Vj,172:$V31,173:$V41,174:$V51,180:$V61,181:140,182:$V71},o($Vn3,[2,159],{109:$VM1,157:$VN1,158:$VO1,159:$VP1,160:$VQ1,161:$VR1,162:$VS1,163:$VT1,164:$VU1,165:$VV1,166:$VW1,167:$VX1,168:$VY1,169:$VZ1,170:$V_1,171:$V$1,173:$V02,174:$V12,175:$V22,176:$V32,177:$V42,178:$V52,179:$V62}),{53:[1,763]},{55:[1,764],109:$VM1,157:$VN1,158:$VO1,159:$VP1,160:$VQ1,161:$VR1,162:$VS1,163:$VT1,164:$VU1,165:$VV1,166:$VW1,167:$VX1,168:$VY1,169:$VZ1,170:$V_1,171:$V$1,173:$V02,174:$V12,175:$V22,176:$V32,177:$V42,178:$V52,179:$V62},o($VD2,[2,230],{109:$VM1,157:$VN1,158:$VO1,159:$VP1,160:$VQ1,161:$VR1,162:$VS1,163:$VT1,164:$VU1,165:$VV1,166:$VW1,167:$VX1,168:$VY1,169:$VZ1,170:$V_1,171:$V$1,173:$V02,174:$V12,175:$V22,176:$V32,177:$V42,178:$V52,179:$V62}),o($VD2,[2,231],{109:$VM1,157:$VN1,158:$VO1,159:$VP1,160:$VQ1,161:$VR1,162:$VS1,163:$VT1,164:$VU1,165:$VV1,166:$VW1,167:$VX1,168:$VY1,169:$VZ1,170:$V_1,171:$V$1,173:$V02,174:$V12,175:$V22,176:$V32,177:$V42,178:$V52,179:$V62}),{24:162,28:$Vz,33:$Vv,48:$VJ,49:765,64:$Vw,70:$Vx,72:$VE1,73:$VF1,74:$VG1,76:$VH1,80:$VI1,92:138,93:155,97:$Vy,123:$V_,124:223,125:$V$,140:136,143:$V11,144:$Vi,145:$Vj,172:$V31,173:$V41,174:$V51,180:$V61,181:140,182:$V71},o($Vn1,[2,278]),{55:[1,766],109:$VM1,157:$VN1,158:$VO1,159:$VP1,160:$VQ1,161:$VR1,162:$VS1,163:$VT1,164:$VU1,165:$VV1,166:$VW1,167:$VX1,168:$VY1,169:$VZ1,170:$V_1,171:$V$1,173:$V02,174:$V12,175:$V22,176:$V32,177:$V42,178:$V52,179:$V62},o($Vn1,[2,277])], +defaultActions: {4:[2,1],97:[2,39],165:[2,68],184:[2,58],207:[2,59],470:[2,209],478:[2,67],628:[2,210],698:[2,144]}, parseError: function parseError (str, hash) { if (hash.recoverable) { this.trace(str); @@ -1051,10 +1067,12 @@ parse: function parse(input) { const DEFAULT_STAGE = 1; const util = require('util'); const Expression = require('../src/expression.js'); +const ExpressionFactory = require('../src/expression_factory.js'); function showcode(title, info) { console.log(title+` ${info.last_line}:${info.last_column}`); } +/* function runtime_expr(value) { let res = new Expression(); if (value.type) { @@ -1072,8 +1090,30 @@ function insert_expr(e, op, ...values) { // console.log(values); e.insert.apply(e, [op, ...values]); return e; -} +}*/ // console.log(`STATE ${state} ${(this.terminals_[symbol] || symbol)}`); +function implicit_scope(statements) { + if (Array.isArray(statements)) { + if (statements.length > 1) { + return {type: 'scope_definition', statements}; + } + statements = statements[0]; + } + if (typeof statements.type === 'undefined') { + return {type: 'scope_definition', ...statements}; + } + if (statements.type === 'code') { + statements.type = 'scope_definition'; + if (!Array.isArray(statements.statements)) { + statements.statements = [statements.statements]; + } + return statements; + } + if (statements.type === 'scope_definition') { + return statements; + } + return {type: 'scope_definition', statements}; +} /* generated by jison-lex 0.3.4 */ var lexer = (function(){ var lexer = ({ @@ -1408,212 +1448,216 @@ case 1: /* console.log("MULTILINE COMMENT: "+yy_.yytext); */ break; case 2: /* console.log("SINGLE LINE COMMENT: "+yy_.yytext); */ break; -case 3: return 74; +case 3: yy_.yytext = yy_.yytext.replace(/^#pragma\s+/, ''); return 21; break; -case 4: return 75; +case 4: return 76; break; -case 5: return 76; +case 5: return 77; break; -case 6: return 24; +case 6: return 78; break; -case 7: return 'DECLARE'; +case 7: return 26; break; -case 8: return 21; +case 8: return 'DECLARE'; break; -case 9: return 25; +case 9: return 23; break; -case 10: return 137; +case 10: return 27; break; -case 11: return 107; +case 11: return 139; break; -case 12: return 161; +case 12: return 109; break; -case 13: return 83; +case 13: return 163; break; -case 14: return 82; +case 14: return 85; break; -case 15: return 154 +case 15: return 84; break; -case 16: return 73 +case 16: return 156 break; -case 17: return 79 +case 17: return 75 break; -case 18: return 80 +case 18: return 81 break; -case 19: return 62 +case 19: return 82 break; -case 20: return 95 +case 20: return 64 break; -case 21: return 31 +case 21: return 97 break; -case 22: return 70 +case 22: return 33 break; -case 23: return 71 +case 23: return 72 break; -case 24: return 72 +case 24: return 73 break; -case 25: return 78 +case 25: return 74 break; -case 26: return 77 +case 26: return 80 break; -case 27: return 104 +case 27: return 79 break; -case 28: return 108 +case 28: return 106 break; -case 29: return 109 +case 29: return 110 break; -case 30: return 101 +case 30: return 111 break; -case 31: return 100 +case 31: return 103 break; -case 32: return 113 +case 32: return 102 break; -case 33: return 'ELSEIF' +case 33: return 115 break; -case 34: return 114 +case 34: return 'ELSEIF' break; -case 35: return 111 +case 35: return 116 break; -case 36: return 119 +case 36: return 113 break; -case 37: return 116 +case 37: return 121 break; -case 38: return 45 +case 38: return 118 break; -case 39: return 153 +case 39: return 47 break; -case 40: return 140 +case 40: return 155 break; -case 41: return 110 +case 41: return 142 break; -case 42: return 96 +case 42: return 112 break; -case 43: return 56 +case 43: return 98 break; -case 44: return 61 +case 44: return 58 break; -case 45: return 55 +case 45: return 63 break; -case 46: return 129 +case 46: return 57 break; -case 47: return 41 +case 47: return 131 break; -case 48: return 42 +case 48: return 43 break; -case 49: return 43 +case 49: return 44 break; -case 50: return 146 +case 50: return 45 break; -case 51: return 147 +case 51: return 20 break; -case 52: return 65 +case 52: return 148 break; -case 53: return 118 +case 53: return 149 break; -case 54: yy_.yytext = yy_.yytext.replace(/\_/g, ""); return 141; +case 54: return 67 break; -case 55: yy_.yytext = yy_.yytext.slice(1,-1); return 142; +case 55: return 120 break; -case 56: yy_.yytext = yy_.yytext.slice(1,-1); return 143; +case 56: yy_.yytext = yy_.yytext.replace(/\_/g, ""); return 143; break; -case 57: return 26; +case 57: yy_.yytext = yy_.yytext.slice(1,-1); return 144; break; -case 58: yy_.yytext = yy_.yytext.slice(1); return 68; +case 58: yy_.yytext = yy_.yytext.slice(1,-1); return 145; break; -case 59: yy_.yytext = yy_.yytext.slice(1); return 49; +case 59: return 28; break; -case 60: yy_.yytext = yy_.yytext.slice(1); return 178; +case 60: yy_.yytext = yy_.yytext.slice(1); return 70; break; -case 61: return 177; +case 61: yy_.yytext = yy_.yytext.slice(1); return 51; break; -case 62: return 121; +case 62: yy_.yytext = yy_.yytext.slice(1); return 180; break; -case 63: return 123; +case 63: return 179; break; -case 64: return 131; +case 64: return 123; break; -case 65: return 132; +case 65: return 125; break; case 66: return 133; break; -case 67: return 171; +case 67: return 134; break; -case 68: return 172; +case 68: return 135; break; case 69: return 173; break; -case 70: return "'"; +case 70: return 174; break; -case 71: return "?"; +case 71: return 175; break; -case 72: return "%"; +case 72: return "'"; break; -case 73: return "\\\\"; +case 73: return "?"; break; -case 74: return "/"; +case 74: return "%"; break; -case 75: return 8; +case 75: return "\\\\"; break; -case 76: return 64; +case 76: return "/"; break; -case 77: return 151; +case 77: return 8; break; -case 78: return 162; +case 78: return 66; break; -case 79: return 167; +case 79: return 153; break; case 80: return 164; break; -case 81: return 165; +case 81: return 169; break; case 82: return 166; break; -case 83: return 168; +case 83: return 167; +break; +case 84: return 168; +break; +case 85: return 170; break; -case 84: return 169; +case 86: return 171; break; -case 85: return 159; +case 87: return 161; break; -case 86: return 160; +case 88: return 162; break; -case 87: return 157; +case 89: return 159; break; -case 88: return 158; +case 90: return 160; break; -case 89: return 87; +case 91: return 88; break; -case 90: return 156; +case 92: return 158; break; -case 91: return 155; +case 93: return 157; break; -case 92: return 127; +case 94: return 129; break; -case 93: return 46; +case 95: return 48; break; -case 94: return 48; +case 96: return 50; break; -case 95: return 51; +case 97: return 53; break; -case 96: return 53; +case 98: return 55; break; -case 97: return 28; +case 99: return 30; break; -case 98: return 30; +case 100: return 32; break; -case 99: return '::'; +case 101: return '::'; break; -case 100: return 58; +case 102: return 60; break; -case 101: return 170; +case 103: return 172; break; -case 102: return 6; +case 104: return 6; break; -case 103: console.log("INVALID: " + yy_.yytext); return 'INVALID' +case 105: console.log("INVALID: " + yy_.yytext); return 'INVALID' break; } }, -rules: [/^(?:\s+)/,/^(?:\/\*([^*]|[\r\n]|(\*+([^*/]|[\r\n])))*\*+\/)/,/^(?:\/\/.*)/,/^(?:col\b)/,/^(?:witness\b)/,/^(?:fixed\b)/,/^(?:container\b)/,/^(?:declare\b)/,/^(?:use\b)/,/^(?:alias\b)/,/^(?:include\b)/,/^(?:in\b)/,/^(?:is\b)/,/^(?:publictable\b)/,/^(?:public\b)/,/^(?:constant\b)/,/^(?:const\b)/,/^(?:proofval\b)/,/^(?:subproofval\b)/,/^(?:subproof\b)/,/^(?:air\b)/,/^(?:proof\b)/,/^(?:int\b)/,/^(?:fe\b)/,/^(?:expr\b)/,/^(?:string\b)/,/^(?:challenge\b)/,/^(?:for\b)/,/^(?:while\b)/,/^(?:do\b)/,/^(?:break\b)/,/^(?:continue\b)/,/^(?:if\b)/,/^(?:elseif\b)/,/^(?:else\b)/,/^(?:switch\b)/,/^(?:case\b)/,/^(?:default\b)/,/^(?:when\b)/,/^(?:aggregate\b)/,/^(?:stage\b)/,/^(?:once\b)/,/^(?:on\b)/,/^(?:private\b)/,/^(?:final\b)/,/^(?:function\b)/,/^(?:return\b)/,/^(?:first\b)/,/^(?:last\b)/,/^(?:frame\b)/,/^(?:\.\.\+\.\.)/,/^(?:\.\.\*\.\.)/,/^(?:\.\.\.)/,/^(?:\.\.)/,/^(?:(0x[0-9A-Fa-f][0-9A-Fa-f_]*)|([0-9][0-9_]*))/,/^(?:"[^"]+")/,/^(?:`[^`]+`)/,/^(?:[a-zA-Z_][a-zA-Z$_0-9]*)/,/^(?:&[a-zA-Z_][a-zA-Z$_0-9]*)/,/^(?:@[a-zA-Z_][a-zA-Z$_0-9]*)/,/^(?:\$[0-9][0-9]*)/,/^(?:\*\*)/,/^(?:\+\+)/,/^(?:--)/,/^(?:\+=)/,/^(?:-=)/,/^(?:\*=)/,/^(?:\+)/,/^(?:-)/,/^(?:\*)/,/^(?:')/,/^(?:\?)/,/^(?:%)/,/^(?:\\\\)/,/^(?:\/)/,/^(?:;)/,/^(?:,)/,/^(?:\.)/,/^(?:&&)/,/^(?:\|\|)/,/^(?:&)/,/^(?:\|)/,/^(?:\^)/,/^(?:<<)/,/^(?:>>)/,/^(?:<=)/,/^(?:>=)/,/^(?:<)/,/^(?:>)/,/^(?:===)/,/^(?:!=)/,/^(?:==)/,/^(?:=)/,/^(?:\()/,/^(?:\))/,/^(?:\[)/,/^(?:\])/,/^(?:\{)/,/^(?:\})/,/^(?:::)/,/^(?::)/,/^(?:!)/,/^(?:$)/,/^(?:.)/], -conditions: {"INITIAL":{"rules":[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103],"inclusive":true}} +rules: [/^(?:\s+)/,/^(?:\/\*([^*]|[\r\n]|(\*+([^*/]|[\r\n])))*\*+\/)/,/^(?:\/\/.*)/,/^(?:#pragma\s+[^\r\n]*)/,/^(?:col\b)/,/^(?:witness\b)/,/^(?:fixed\b)/,/^(?:container\b)/,/^(?:declare\b)/,/^(?:use\b)/,/^(?:alias\b)/,/^(?:include\b)/,/^(?:in\b)/,/^(?:is\b)/,/^(?:publictable\b)/,/^(?:public\b)/,/^(?:constant\b)/,/^(?:const\b)/,/^(?:proofval\b)/,/^(?:subproofval\b)/,/^(?:subproof\b)/,/^(?:air\b)/,/^(?:proof\b)/,/^(?:int\b)/,/^(?:fe\b)/,/^(?:expr\b)/,/^(?:string\b)/,/^(?:challenge\b)/,/^(?:for\b)/,/^(?:while\b)/,/^(?:do\b)/,/^(?:break\b)/,/^(?:continue\b)/,/^(?:if\b)/,/^(?:elseif\b)/,/^(?:else\b)/,/^(?:switch\b)/,/^(?:case\b)/,/^(?:default\b)/,/^(?:when\b)/,/^(?:aggregate\b)/,/^(?:stage\b)/,/^(?:once\b)/,/^(?:on\b)/,/^(?:private\b)/,/^(?:final\b)/,/^(?:function\b)/,/^(?:return\b)/,/^(?:first\b)/,/^(?:last\b)/,/^(?:frame\b)/,/^(?:debugger\b)/,/^(?:\.\.\+\.\.)/,/^(?:\.\.\*\.\.)/,/^(?:\.\.\.)/,/^(?:\.\.)/,/^(?:(0x[0-9A-Fa-f][0-9A-Fa-f_]*)|([0-9][0-9_]*))/,/^(?:"[^"]+")/,/^(?:`[^`]+`)/,/^(?:[a-zA-Z_][a-zA-Z$_0-9]*)/,/^(?:&[a-zA-Z_][a-zA-Z$_0-9]*)/,/^(?:@[a-zA-Z_][a-zA-Z$_0-9]*)/,/^(?:\$[0-9][0-9]*)/,/^(?:\*\*)/,/^(?:\+\+)/,/^(?:--)/,/^(?:\+=)/,/^(?:-=)/,/^(?:\*=)/,/^(?:\+)/,/^(?:-)/,/^(?:\*)/,/^(?:')/,/^(?:\?)/,/^(?:%)/,/^(?:\\\\)/,/^(?:\/)/,/^(?:;)/,/^(?:,)/,/^(?:\.)/,/^(?:&&)/,/^(?:\|\|)/,/^(?:&)/,/^(?:\|)/,/^(?:\^)/,/^(?:<<)/,/^(?:>>)/,/^(?:<=)/,/^(?:>=)/,/^(?:<)/,/^(?:>)/,/^(?:===)/,/^(?:!=)/,/^(?:==)/,/^(?:=)/,/^(?:\()/,/^(?:\))/,/^(?:\[)/,/^(?:\])/,/^(?:\{)/,/^(?:\})/,/^(?:::)/,/^(?::)/,/^(?:!)/,/^(?:$)/,/^(?:.)/], +conditions: {"INITIAL":{"rules":[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105],"inclusive":true}} }); return lexer; })(); diff --git a/docs/expression.md b/docs/expression.md index 5c51243..9678933 100644 --- a/docs/expression.md +++ b/docs/expression.md @@ -14,7 +14,7 @@ And next? |fe|| |col witness|| |col fixed|| -|col (im)|| +|expression|| |challenge|| |public|| |air value|| @@ -25,4 +25,21 @@ And next? - **instance()** make a copy of expression, where __runtime values and expressions__ (variables, eq, be) are replaced - **evaluate()** calculate a single value (int, fe, bool) without replacing runtime values and expressions. For example, a condition on loop, etc.. - +```mermaid +classDiagram +ExpressionItem <-- RuntimeItem +ExpressionItem <-- ProofItem +RuntimeItem <-- ReferenceItem +RuntimeItem <-- ExpressionReference +RuntimeItem <-- ValueItem +RuntimeItem <-- StringValue +RuntimeItem <-- FunctionCall +ProofItem <-- Challenge +ProofItem <-- ProofVal +ProofItem <-- FixedCol +ProofItem <-- WitnessCol +ProofItem <-- Public +ProofItem <-- SubproofVal +ValueItem <-- IntValue +ValueItem <-- FeValue +`````` diff --git a/package.json b/package.json index a8b3e4a..5ceb23b 100644 --- a/package.json +++ b/package.json @@ -33,15 +33,16 @@ "homepage": "https://github.com/0xpolygonhermez/pilcom#readme", "devDependencies": { "chai": "^4.3.6", + "fastfile": "^0.0.20", "ffjavascript": "^0.2.55", "jison": "^0.4.18", "mocha": "^10.0.0", "nyc": "^15.1.0", "tmp-promise": "^3.0.3", - "yargs": "^17.2.1", - "fastfile": "^0.0.20" + "yargs": "^17.2.1" }, "dependencies": { + "deep-equal-in-any-order": "^2.0.6", "lodash": "^4.17.21", "long": "^5.2.3", "protobufjs": "^7.2.3" diff --git a/src/TODO.md b/src/TODO.md new file mode 100644 index 0000000..7806607 --- /dev/null +++ b/src/TODO.md @@ -0,0 +1,5 @@ +# TODO +- specifics Exception Class to manage compiler (user) errors and internal errors. +- static context value, to avoid pass on all constructors. Add Fr manager inside context, same for scope and references. +- typecast and type verification. +- second level of optimizations, for example: v1 + (v2 + col) => (v1+v2) + col, similar for prod, sub, etc.. diff --git a/src/assert.js b/src/assert.js new file mode 100644 index 0000000..1386bc8 --- /dev/null +++ b/src/assert.js @@ -0,0 +1,18 @@ +const _assert = require("chai").assert; + +function assertLog(condition, info) { + if (!condition) { + console.log(info); + } + _assert(condition); +} + +function assertReturnInstanceOf(value, cls, info) { + assertLog(value instanceof cls, [value, info]); + return value; +} +module.exports = { + assert: _assert, + assertLog, + assertReturnInstanceOf +} \ No newline at end of file diff --git a/src/assign.js b/src/assign.js index dd082f2..6a98da8 100644 --- a/src/assign.js +++ b/src/assign.js @@ -1,46 +1,52 @@ -const References = require("./references.js"); -const Expressions = require("./expressions.js"); const Expression = require("./expression.js"); +const Context = require('./context.js'); +const {assert, assertLog} = require('./assert.js'); +const NonRuntimeEvaluableItem = require('./expression_items/non_runtime_evaluable_item.js'); +const Debug = require('./debug.js'); module.exports = class Assign { - constructor (Fr, parent, context, references, expressions) { - this.Fr = Fr; - this.context = context; - this.references = references; - this.expressions = expressions; - this.parent = parent; + constructor () { } - assign (name, indexes, value) { - // console.log(value.stack[0].operands[0]); + if (Debug.active) console.log(value); + value = this.getValue(value); + if (Debug.active) console.log(value); + assert(value !== null); + return this.#assign(name, indexes, value); + } + getValue(value) { const _value = value.eval(); - if (typeof _value !== 'undefined') { - value = _value; + if (typeof _value !== 'undefined' && _value !== null && (_value instanceof NonRuntimeEvaluableItem) === false) { + return _value; } - return this.__assign(name, indexes, value); + return value; } - __assign(name, indexes, value) { - const [type, reference, array] = this.references.getTypeR(name, indexes); - const dim = (array && array.dim) ? array.dim : 0; - if (this.parent.context.sourceRef === 'assigns.pil:115') { - debugger; - } + #assign (name, indexes, value) { + // console.log(`ASSIGN(${name})[#${indexes.length ?? 0}] = ${value.constructor ? (value.constructor.name ?? typeof value):typeof value}`); + // const array = Context.references.getArray(name, indexes); + const reference = Context.references.getReference(name); + return reference.set(value, indexes); + /* + const dim = array.dim ?? 0; if (dim > 0) { + // array asignation as array or subarray copy return this.assignArray(name, indexes, value, array); } - // console.log([name, type, reference, array]); - return this.assignType(type, name, indexes, value); + console.log(value); + return Context.references.set(name, indexes, value);*/ } assignType(type, name, indexes, value) { + if (Debug.active) console.log(type); switch (type) { case 'int': return this.assignTypeInt(name, indexes, value, type); case 'expr': return this.assignTypeExpr(name, indexes, value, type); } } assignArray(name, indexes, value, array) { + console.log(`ASSIGN_ARRAY(${name})[#${indexes.length ?? 0}] = ${value.constructor ? (value.constructor.name ?? typeof value):typeof value}`); const ref = value.getAloneOperand(); let valueIndexes = value.__indexes ?? []; - const def = this.references.getDefinition(ref.name); + const def = Context.references.getDefinition(ref.name); if (array.dim != def.array.dim) { throw new Error(`different array dimension on asignation ${array.dim} vs ${def.array.dim}`); @@ -49,6 +55,7 @@ module.exports = class Assign { // array.lengths[0] != def.array.lengths[0]) { } assignArrayLevel(level, name, indexes, value, leftArray, rightArray) { + console.log(`ASSIGN_ARRAY_LEVEL(${level},${name})[#${indexes.length ?? 0}] = ${value.constructor ? (value.constructor.name ?? typeof value):typeof value}`); // console.log(['assignArrayLevel', level, name, indexes]); const len = leftArray.lengths[level]; for (let index = 0; index < len; ++index) { @@ -56,7 +63,7 @@ module.exports = class Assign { _indexes.push(index); value.pushAloneIndex(index); if (level + 1 === leftArray.dim) { - this.__assign(name, _indexes, value.evaluateAloneReference()); + this.#assign(name, _indexes, value.evaluateAloneReference()); } else { this.assignArrayLevel(level+1, name, _indexes, value, leftArray, rightArray); } @@ -64,24 +71,27 @@ module.exports = class Assign { } } assignReference (name, value) { - this.references.setReference(name, value); + console.log(`ASSIGN_REFERENCE(${level},${name}) = ${value.constructor ? (value.constructor.name ?? typeof value):typeof value}`); + Context.references.setReference(name, value); } assignTypeInt(name, indexes, value, type) { // TODO: WARNING: e2value an extra evaluation - const v = this.expressions.getValue(value); + const v = Expression.getValue(value); if (typeof v === 'number' || typeof v === 'bigint') { - return this.references.set(name, indexes, v); + return Context.references.set(name, indexes, v); } } assignTypeExpr(name, indexes, value, type) { + console.log(`ASSIGN_TYPE_EXPR(${name},${type})[#${indexes.length ?? 0}] = ${value.constructor ? (value.constructor.name ?? typeof value):typeof value}`); if (!(value instanceof Expression)) { - this.references.set(name, indexes, value); + Context.references.set(name, indexes, value); return; } - value = value.instance({simplify: true}); - - console.log(`ASSIGN ${this.context.sourceRef} ${value}`); - this.references.set(name, indexes, value); - return + value = value.instance(true); + if (Context.sourceRef === 'std_sum.pil:195') { + if (Debug.active) console.log('XXX'); + } + if (Debug.active) console.log(`ASSIGN ${Context.sourceRef} ${value}`); + Context.references.set(name, indexes, value); } } diff --git a/src/builtin/assert.js b/src/builtin/assert.js index 9d826fd..da82405 100644 --- a/src/builtin/assert.js +++ b/src/builtin/assert.js @@ -1,19 +1,25 @@ const Function = require("../function.js"); +const Context = require('../context.js'); +const ExpressionItems = require('../expression_items.js') module.exports = class Assert extends Function { constructor (parent) { super(parent, {funcname: 'assert'}); } mapArguments(s) { - if (s.arguments.length !== 1) { + console.log('############### ASSERT (prepare) ########################'); + console.log(s.args); + if (s.args.length !== 1) { throw new Error('Invalid number of parameters'); } - const arg0 = this.expressions.e2bool(s.arguments[0]); + const arg0 = s.args[0].asBool(); + console.log(arg0); if (!arg0) { - throw new Error(`Assert fails ${arg0} on ${this.parent.sourceRef}`); + throw new Error(`Assert fails ${arg0} on ${Context.sourceRef}`); } - return 0n; + return new ExpressionItems.IntValue(0n); } exec(s, mapInfo) { + console.log('############### ASSERT (exec) ########################'); return mapInfo; } } diff --git a/src/builtin/assert_eq.js b/src/builtin/assert_eq.js index a98fad0..039e898 100644 --- a/src/builtin/assert_eq.js +++ b/src/builtin/assert_eq.js @@ -1,20 +1,28 @@ const Function = require("../function.js"); +const Expression = require('../expression.js'); +const Context = require('../context.js'); +const IntValue = require('../expression_items/int_value.js'); +const {assert, assertLog} = require('../assert.js'); module.exports = class AssertEq extends Function { - constructor (parent) { - super(parent, {funcname: 'assert_eq'}); + constructor () { + super(999999, {funcname: 'assert_eq'}); } mapArguments(s) { - if (s.arguments.length !== 2) { + if (s.args.length !== 2) { throw new Error('Invalid number of parameters'); } - const arg0 = this.expressions.e2value(s.arguments[0]); - const arg1 = this.expressions.e2value(s.arguments[1]); - if (arg0 !== arg1) { - throw new Error(`Assert fails (${arg0} === ${arg1}) on ${this.parent.sourceRef}`); + assert(s.args[0] instanceof Expression); + assert(s.args[1] instanceof Expression); + const arg0 = s.args[0].eval(); + const arg1 = s.args[1].eval(); + console.log(arg0); + console.log(arg1); + if (!arg0.equals(arg1)) { + throw new Error(`Assert fails (${arg0} === ${arg1}) on ${Context.sourceRef}`); } return 0n; } exec(s, mapInfo) { - return mapInfo; + return new IntValue(mapInfo); } } diff --git a/src/builtin/assert_not_eq.js b/src/builtin/assert_not_eq.js index bc492e5..40b06d5 100644 --- a/src/builtin/assert_not_eq.js +++ b/src/builtin/assert_not_eq.js @@ -1,21 +1,23 @@ const Function = require("../function.js"); +const IntValue = require('../expression_items/int_value.js'); + module.exports = class AssertNotEq extends Function { constructor (parent) { super(parent, {funcname: 'assert_not_eq'}); } mapArguments(s) { - if (s.arguments.length !== 2) { + if (s.args.length !== 2) { throw new Error('Invalid number of parameters'); } - const arg0 = this.expressions.e2value(s.arguments[0]); - const arg1 = this.expressions.e2value(s.arguments[1]); + const arg0 = this.expressions.e2value(s.args[0]); + const arg1 = this.expressions.e2value(s.args[1]); if (arg0 === arg1) { throw new Error(`Assert fails (${arg0} !== ${arg1}) on ${this.parent.sourceRef}`); } return 0n; } exec(s, mapInfo) { - return mapInfo; + return new IntValue(mapInfo); } } diff --git a/src/builtin/cast.js b/src/builtin/cast.js new file mode 100644 index 0000000..fd133f3 --- /dev/null +++ b/src/builtin/cast.js @@ -0,0 +1,37 @@ +const Function = require("../function.js"); +const Context = require('../context.js'); +const Expression = require('../expression.js'); + +module.exports = class Cast extends Function { + constructor (parent) { + super(parent, {funcname: 'cast'}); + } + mapArguments(s) { + console.log('############### CAST (prepare) ########################'); + console.log(s.args); + if (s.args.length !== 2) { + throw new Error('Invalid number of parameters'); + } + if (typeof s.args[0] !== 'string') { + throw new Error('Invalid type of cast'); + } + const cast = s.args[0]; + let arg1 = s.args[1] instanceof Expression ? s.args[1].eval() : s.args[1]; + console.log(arg1, arg1.isBaseType, typeof arg1.asStringItem); + if (arg1 instanceof Expression) { + arg1.dump(); + arg1 = arg1.eval(); + } + switch (cast) { + case 'string': + if (arg1.isBaseType && typeof arg1.asStringItem === 'function') { + return arg1.asStringItem(); + } + } + EXIT_HERE; + } + exec(s, mapInfo) { + console.log('############### CAST (exec) ########################', mapInfo); + return mapInfo; + } +} diff --git a/src/builtin/defined.js b/src/builtin/defined.js index f8489e6..56bec3f 100644 --- a/src/builtin/defined.js +++ b/src/builtin/defined.js @@ -1,21 +1,35 @@ const Function = require("../function.js"); -const {MultiArray, ErrorIndexOutOfRange} = require("../multi_array.js"); +const MultiArray = require("../multi_array.js"); +const {IntValue} = require('../expression_items.js'); +const Exceptions = require('../exceptions.js'); module.exports = class Defined extends Function { constructor (parent) { super(parent, {funcname: 'defined'}); } mapArguments(s) { - if (s.arguments.length !== 1) { + if (s.args.length !== 1) { throw new Error('Invalid number of parameters'); } - const arg0 = s.arguments[0]; - if (arg0 && arg0.isReference()) { - const ref = arg0.getReference(); - // console.log(ref); - return this.references.isDefined(ref.name, ref.__indexes) ? 1n : 0n; + const arg0 = s.args[0]; + let value = false; + try { + if (arg0) { + value = arg0.eval(); + } + // if (arg0 && arg0.isReference()) { + // const ref = arg0.getReference(); + // return this.references.isDefined(ref.name, ref.__indexes) ? 1n : 0n; + // } + } catch (e) { + if (e instanceof Exceptions.ReferenceNotFound || e instanceof Exceptions.ReferenceNotVisible) { + console.log(`defined(${arg0.toString()}) EXCEPTION `, e.message); + } else { + throw e; + } } - return 0n; + const res = new IntValue(value !== false ? 1n : 0n); + return res; } exec(s, mapInfo) { return mapInfo; diff --git a/src/builtin/dump.js b/src/builtin/dump.js new file mode 100644 index 0000000..c817006 --- /dev/null +++ b/src/builtin/dump.js @@ -0,0 +1,18 @@ +const Function = require("../function.js"); +const Context = require('../context.js'); +const ExpressionItems = require('../expression_items.js') +module.exports = class Dump extends Function { + constructor (parent) { + super(parent, {funcname: 'dump'}); + } + mapArguments(s) { + if (s.args.length !== 1) { + throw new Error('Invalid number of parameters'); + } + return s.args[0].eval(); + } + exec(s, mapInfo) { + mapInfo.dump(); + return new ExpressionItems.IntValue(0n); + } +} diff --git a/src/builtin/error.js b/src/builtin/error.js new file mode 100644 index 0000000..abbcbf3 --- /dev/null +++ b/src/builtin/error.js @@ -0,0 +1,34 @@ +const Function = require("../function.js"); +const IntValue = require('../expression_items/int_value.js'); +const Context = require('../context.js'); + +module.exports = class Error extends Function { + constructor (parent) { + super(parent, {funcname: 'error', args: [], returns: [] }); + } + mapArguments(s) { + let texts = []; + for (const arg of s.args) { + if (typeof arg === 'string') { + texts.push(arg); + continue; + } + + const value = arg.toString(); + texts.push(value); + } + return texts; + } + exec(s, mapInfo) { + /* let caller = ''; + try { + throw new Error(); + } catch (e) { + caller = e.stack.split('\n').slice(1).join('\n'); + } + console.log(caller);*/ + const msg = mapInfo.join(' '); + console.log(`\x1B[1;35mERROR ${msg}\x1B[0m`); + throw new Error(`ERROR: ${msg} at ${Context.sourceRef}`); + } +} diff --git a/src/builtin/is_array.js b/src/builtin/is_array.js index bc5be0a..cfc072c 100644 --- a/src/builtin/is_array.js +++ b/src/builtin/is_array.js @@ -1,14 +1,15 @@ const Function = require("../function.js"); +const IntValue = require('../expression_items/int_value.js'); module.exports = class IsArray extends Function { constructor (parent) { super(parent, {funcname: 'is_array'}); } mapArguments(s) { - if (s.arguments.length !== 1) { + if (s.args.length !== 1) { throw new Error('Invalid number of parameters'); } - const arg0 = s.arguments[0]; + const arg0 = s.args[0]; if (arg0 && arg0.isReference()) { const ref = arg0.getReference(); if (!this.references.isDefined(ref.name, ref.__indexes)) { @@ -21,6 +22,6 @@ module.exports = class IsArray extends Function { return 0n; } exec(s, mapInfo) { - return mapInfo; + return new IntValue(mapInfo); } } diff --git a/src/builtin/length.js b/src/builtin/length.js index e206c8b..657c02c 100644 --- a/src/builtin/length.js +++ b/src/builtin/length.js @@ -1,25 +1,27 @@ const Function = require("../function.js"); +const StringValue = require('../expression_items/string_value.js'); +const IntValue = require('../expression_items/int_value.js'); +const util = require('util'); module.exports = class Length extends Function { constructor (parent) { super(parent, {funcname: 'length'}); } mapArguments(s) { - if (s.arguments.length !== 1) { + if (s.args.length !== 1) { throw new Error('Invalid number of parameters'); } - const arg0 = s.arguments[0]; - if (arg0 && arg0.isReference()) { - const [instance,rinfo] = this.expressions.getReferenceInfo(arg0); - const operand = arg0.getAloneOperand(); - return rinfo.array ? BigInt(rinfo.array.getLength(operand.dim)) : 0n; + const arg0 = s.args[0]; + const item = arg0.evalAsItem(); + if (item instanceof StringValue) { + return {result: BigInt(item.length)}; } - const value = this.expressions.e2value(s.arguments[0]); - if (typeof value === 'string') { - return BigInt(value.length); + if (item && item.array) { + return {result: item.array ? BigInt(item.array.getLength(0)) : 0n}; } - return 0n; + return {result: 0n}; } exec(s, mapInfo) { - return mapInfo; + const res = new IntValue(mapInfo.result); + return res; } } diff --git a/src/builtin/println.js b/src/builtin/println.js index a600169..7e954fb 100644 --- a/src/builtin/println.js +++ b/src/builtin/println.js @@ -1,17 +1,18 @@ const Function = require("../function.js"); +const IntValue = require('../expression_items/int_value.js'); module.exports = class Println extends Function { constructor (parent) { super(parent, {funcname: 'println', args: [], returns: [] }); } mapArguments(s) { let texts = []; - for (const arg of s.arguments) { + for (const arg of s.args) { if (typeof arg === 'string') { texts.push(arg); continue; } - const value = this.expressions.e2value(arg); + const value = arg.eval(); texts.push(value); } return texts; @@ -24,6 +25,7 @@ module.exports = class Println extends Function { caller = e.stack.split('\n').slice(1).join('\n'); } console.log(caller);*/ - console.log(`\x1B[1;35m[${s.debug}] ${mapInfo.join(' ')} (DEEP:${this.scope.deep})\x1B[0m`); + console.log(`\x1B[1;35mPRINTLN ${mapInfo.join(' ')}\x1B[0m`); + return new IntValue(0); } } diff --git a/src/challenges.js b/src/challenges.js new file mode 100644 index 0000000..8c6f7df --- /dev/null +++ b/src/challenges.js @@ -0,0 +1,14 @@ +const Indexable = require("./indexable.js"); +const ChallengeItem = require("./expression_items/challenge.js"); +const ChallengeDefinition = require("./definition_items/challenge.js"); +module.exports = class Challenges extends Indexable { + constructor () { + super('challenge', ChallengeDefinition, ChallengeItem); + } + getEmptyValue(id, options) { + const subproofId = options.subproofId; + const relativeId = this.values.reduce((res, spv) => spv.subproofId === subproofId ? res + 1 : res, 0); + let definition = super.getEmptyValue(id, {relativeId, ...options}); + return definition; + } +} diff --git a/src/compiler.js b/src/compiler.js index 4a3d8f3..5771d7b 100644 --- a/src/compiler.js +++ b/src/compiler.js @@ -12,6 +12,7 @@ const Indexable = require("./indexable.js"); const Ids = require("./ids.js"); const Constraints = require("./constraints.js"); const Processor = require("./processor.js"); +const Context = require("./context.js"); const { mainModule } = require("process"); @@ -30,7 +31,6 @@ class Compiler { constructor(Fr) { this.Fr = Fr; this.constants = new Definitions(Fr); - this.processor = new Processor(Fr, this); } initContext() { @@ -42,10 +42,11 @@ class Compiler { this.includePaths = (this.config && this.config.includePaths) ? (Array.isArray(this.config.includePaths) ? this.config.includePaths: [this.config.includePaths]): []; this.relativeFileName = ''; } - async compile(fileName, config = {}) { + compile(fileName, config = {}) { const isMain = true; + this.config = {...config}; this.initContext(); - this.config = config; + this.processor = new Processor(this.Fr, this, this.config); if (this.config.namespaces) { this.namespaces = {}; for (const name of this.config.namespaces) { @@ -57,7 +58,7 @@ class Compiler { this.constants.define(name, this.Fr.e(this.config.defines[name])); } } - let sts = await this.parseSource(fileName, true); + let sts = this.parseSource(fileName, true); this.processor.startExecution(sts); if (config.processorTest) { return this.processor; @@ -83,45 +84,22 @@ class Compiler { oldParseError(str, hash); }; pil_parser.Parser.prototype.parseError = myErr; - let parser = new pil_parser.Parser(); const parserPerformAction = parser.performAction; const parserStateInfo = parser.productions_; let compiler = this; - /* - state = stack[stack.length - 1]; - if (this.defaultActions[state]) { - action = this.defaultActions[state]; - } else { - if (symbol === null || typeof symbol == 'undefined') { - symbol = lex(); - } - action = table[state] && table[state][symbol]; - } - ===> - const __symbol_info__ = this.terminals_[symbol] + ( lexer.match && - lexer.match != this.terminals_[symbol] ? ` (${lexer.match})`:''); -console.log('\x1B[93mSTATE '+state+' SYMBOL '+__symbol_info__+" #"+(yylineno + 1)+"\x1B[0m"); - */ + parser.performAction = function (yytext, yyleng, yylineno, yy, yystate, $$, _$ ) { const result = parserPerformAction.apply(this, arguments); const first = _$[$$.length - 1 - parserStateInfo[yystate][1]]; const last = _$[$$.length - 1]; const sourceRef = `${compiler.relativeFileName}:${last.last_line}`; -// if (sourceRef === 'mem_align.pil:48') { -/* if (sourceRef === 'sequence.pil:5') { - console.log(arguments); - console.log(this); - console.log(yy); - console.log(yyleng); - EXIT_HERE; - }*/ - // console.log(`ST_${yystate} ${parserStateInfo[yystate][0]} ${sourceRef}`); + Context.processor.sourceRef = sourceRef; if (typeof this.$ !== 'object') { return result; } - this.$.debug = `${compiler.relativeFileName}:${last.last_line}`; + this.$.debug = `${compiler.relativeFileName}:${last.last_line}:${first.first_column}:${last.last_line}:${last.last_column}`; // this.$.__debug = `${compiler.relativeFileName} (${first.first_line}, ${first.first_column}) (${last.last_line}, ${last.last_column})`; // this.$.__contents = compiler.srcLines[first.first_line - 1].substring(first.first_column + 1, last.last_column); this.$.__yystate = `${yystate} ${yylineno}` @@ -129,19 +107,38 @@ console.log('\x1B[93mSTATE '+state+' SYMBOL '+__symbol_info__+" #"+(yylineno + 1 } return parser; } - async parseSource(fileName, isMain = false) { - - const [src, fileDir, fullFileName, relativeFileName] = await this.loadSource(fileName, isMain); + parseSource(fileName, isMain = false, options = {}) { + + let libraries = []; + if (isMain && this.config.includes) { + this.fileDir = process.cwd(); + for (const include of this.config.includes) { + libraries.push({type: 'include', file: include, debug:'', contents: this.loadInclude({file: include})}); + } + } + const [_src, fileDir, fullFileName, relativeFileName] = this.loadSource(fileName, isMain. options); + const preSrc = options.preSrc ?? ''; + const postSrc = options.postSrc ?? ''; + const src = preSrc + _src + postSrc; this.relativeFileName = relativeFileName; this.fileDir = fileDir; + const parser = this.instanceParser(src, fullFileName); - const sts = parser.parse(src); - - for (let i=0; i '\x1b['+x+'m' : (x) => ''; - - let isMain; - if (!ctx) { - ctx = { - references: {}, - publics:{}, - nCommitments: 0, - nConstants: 0, - nIm: 0, - nQ: 0, - nPublic: 0, - expressions: [], - polIdentities: [], - plookupIdentities: [], - permutationIdentities: [], - connectionIdentities: [], - namespace: "Global", - constants: {}, - Fr: Fr, - includedFiles: {}, - config, - namespaces: true, - skippedNamespaces: {}, - skippedPols: {}, - includePaths: (config && config.includePaths) ? (Array.isArray(config.includePaths) ? config.includePaths: [config.includePaths]): [] - } - isMain = true; - } else { - isMain = false; - } - - /* config example: - - { - disableUnusedError: true, - namespaces: ['Main', 'Global', 'Rom'], - defines: { N: 2 ** 18 } - } - - */ - - let fullFileName, fileDir, src; - let includePathIndex = 0; - let relativeFileName = ''; - - if (isMain && config && config.compileFromString) { - relativeFileName = fullFileName = "(string)"; - fileDir = ''; - src = fileName; - } - else { - includePaths = [...ctx.includePaths]; - const cwd = ctx.cwd ? ctx.cwd : process.cwd(); - - if (config && config.includePathFirst) { - directIncludePathIndex = includePaths.length; - includePaths.push(cwd); - } - else { - directIncludePathIndex = 0; - includePaths.unshift(cwd); - } - do { - fullFileName = path.resolve(includePaths[includePathIndex], fileName); - if (fs.existsSync(fullFileName)) break; - ++includePathIndex; - } while (includePathIndex < includePaths.length); - - if (includePathIndex != directIncludePathIndex) { - relativeFileName = fileName; - } - fileDir = path.dirname(fullFileName); - src = await fs.promises.readFile(fullFileName, "utf8") + "\n"; - } - const srcLines = src.split(/(?:\r\n|\n|\r)/); - - const myErr = function (str, hash) { - str = fullFileName + " -> " + str; - oldParseError(str, hash); - }; - pil_parser.Parser.prototype.parseError = myErr; - - const parser = new pil_parser.Parser(); - const sts = parser.parse(src); - - let pendingCommands = []; - let lastLineAllowsCommand = false; - - if (isMain && config && config.namespaces) { - ctx.namespaces = {}; - for (const name of config.namespaces) { - ctx.namespaces[name] = 0; - } - } - - if (isMain && config && config.defines && typeof config.defines === 'object') { - for (const name in config.defines) { - ctx.constants[name] = BigInt(config.defines[name]); - } - } - - if (relativeFileName === '') { - if (isMain) { - relativeFileName = path.basename(fullFileName); - ctx.basePath = fileDir; - } else { - if (fullFileName.startsWith(ctx.basePath)) { - relativeFileName = fullFileName.substring(ctx.basePath.length+1); - } else { - relativeFileName = fullFileName; - } - } - } - - for (let i=0; i0) error(s, "command not allowed before include"); - lastLineAllowsCommand = false; - } - continue; - } else if (s.type == "NAMESPACE") { - ctx.namespace = s.namespace; - const se = simplifyExpression(Fr, ctx, s.exp); - if (se.op != "number") error(s, "Size is not constant expression"); - ctx.polDeg = Number(se.value); - continue; - } - - let skip = false; - let poldef = false; - let insideIncludedDomain = false; - const ctxExprLen = ctx.expressions.length; - - try { - checkNamespace(ctx.namespace, ctx); - insideIncludedDomain = true; - if (s.type == "POLCOMMTDECLARATION") { - for (let j=0; j 3) verboseInfo += " ..."; - verboseInfo += ansiColor(0) +'\n'; - } - console.log(`NOTE: ${relativeFileName}:${s.first_line} was ignored${verboseInfo}`); - } - - if (poldef) { - console.log(`adding ${poldef} to exclude`); - ctx.skippedPols[poldef] = true; - } - while (ctxExprLen < ctx.expressions.length) { - ctx.expressions.pop(); - } - } - - if (isMain) { - if (typeof ctx.namespaces === 'object') { - let notFoundNamespaces = Object.keys(ctx.namespaces).filter(namespace => ctx.namespaces[namespace] === 0); - if (notFoundNamespaces.length) { - throw new Error('ERROR: namespaces not found: '+notFoundNamespaces.join(', ')); - } - } - - for (n in ctx.publics) { - if (ctx.publics.hasOwnProperty(n)) { - const pub = ctx.publics[n]; - if (pub.polType == "imP") { - ctx.expressions[pub.polId] = simplifyExpression(Fr, ctx, ctx.expressions[pub.polId] ); - } - } - } - for (let i=0; i2) error(ctx.expressions[i], "Degree greater than 2"); - } - for (let i=0; i2) error(e, "Degre too high"); -} - -function reduceto1(ctx, e) { - if (e.deg<=1) return; - if (e.deg>2) error(e, "Degre too high"); - e.idQ = ctx.nQ++ - e.deg = 1; -} - -// Commitmets -// Qs -// Const -// Im - - -function ctx2json(ctx) { - const out={ - nCommitments: ctx.nCommitments, - nQ: ctx.nQ, - nIm: ctx.nIm, - nConstants: ctx.nConstants, - publics: [], - references: {}, - expressions: [], - polIdentities: [], - plookupIdentities: [], - permutationIdentities: [], - connectionIdentities: [] - }; - - for (n in ctx.references) { - if (ctx.references.hasOwnProperty(n)) { - const ref = ctx.references[n]; - if (ref.isArray) { - out.references[n] = { - type: ref.type, - id: ref.id, - polDeg: ref.polDeg, - isArray: true, - len: ref.len - }; - } else { - out.references[n] = { - type: ref.type, - id: ref.id, - polDeg: ref.polDeg, - isArray: false - }; - } - } - } - - for (n in ctx.publics) { - if (ctx.publics.hasOwnProperty(n)) { - const pub = ctx.publics[n]; - out.publics[pub.id] = pub; - out.publics[pub.id].name = n; - } - } - - for (let i=0; i0)) out.deps = deps; - return out; -} diff --git a/src/compiler_legacy.js b/src/compiler_legacy.js deleted file mode 100644 index e8e3d09..0000000 --- a/src/compiler_legacy.js +++ /dev/null @@ -1,882 +0,0 @@ -// import {Expressions} from './expressions.js'; - -const path = require("path"); -const fs = require("fs"); -const pil_parser = require("../build/pil_parser.js"); -const { check } = require("yargs"); -const Scalar = require("ffjavascript").Scalar; -const Expressions = require("./expressions.js"); -const Definitions = require("./definitions.js"); -const References = require("./references.js"); -const Indexable = require("./indexable.js"); -const Ids = require("./ids.js"); -const Constraints = require("./constraints.js"); -const Processor = require("./processor.js"); -const { mainModule } = require("process"); - - -const oldParseError = pil_parser.Parser.prototype.parseError; - -class SkipNamespace extends Error { - constructor(namespace, name = false) { - super(name ? `Pol ${namespace}.${name} must be skipped` : `Namespace ${namespace} must be skipped`); - this.namespace = namespace; - this.name = name; - } -} - -class Compiler { - - constructor(Fr) { - this.Fr = Fr; - this.references = new References(Fr); - this.globalConstraints = new Constraints(Fr); - this.constraints = new Constraints(Fr); - this.constants = new Definitions(Fr); - this.publics = new Ids(Fr); - this.prover = new Ids(Fr); - this.expressions = new Expressions(Fr, this, this.references, this.publics, this.constants); - this.globalExpressions = new Expressions(Fr, this, this.references, this.publics, this.constants); - this.processor = new Processor(Fr, this, this.references, this.expressions); - } - - initContext() { - this.subproofs = {}; - this.nWitnessCols = 0; - this.nFixedCols = 0; - this.nIm = 0; - this.nQ = 0; - this.nPublic = 0; - this.polIdentities = []; - this.plookupIdentities = []; - this.permutationIdentities = []; - this.connectionIdentities = []; - this.namespace = "Global"; - this.includedFiles = {}; - this.namespaces = true; - this.skippedNamespaces = {}; - this.skippedPols = {}; - this.includePaths = (this.config && this.config.includePaths) ? (Array.isArray(this.config.includePaths) ? this.config.includePaths: [this.config.includePaths]): []; - this.relativeFileName = ''; - } - async compile(fileName, config = {}) { - const isMain = true; - this.initContext(); - - if (config) { - this.config = config; - if (this.config.namespaces) { - this.namespaces = {}; - for (const name of this.config.namespaces) { - this.namespaces[name] = 0; - } - } - if (this.config.defines && typeof this.config.defines === 'object') { - for (const name in this.config.defines) { - this.constants.define(name, this.Fr.e(this.config.defines[name])); - } - } - } else { - this.config = {}; - } - const ansiColor = this.config.color ? (x) => '\x1b['+x+'m' : (x) => ''; - - await this.parseSource(fileName, true); - console.log('\x1b[1;35m==== CONSTANTS ===='); - this.constants.dump(); - console.log('\x1b[0m'); - this.checkNotFoundNamespaces(); - this.checkUndefinedPols(); - this.simplifyAll(); - // this.checkUnusedExpressions(); - this.checkExpressionsDegree(); - this.reduceExpressions(); - return this.contextToJson(); - } - instanceParser(src, fullFileName) { - this.srcLines = src.split(/(?:\r\n|\n|\r)/); - - const myErr = function (str, hash) { - str = fullFileName + " -> " + str; - oldParseError(str, hash); - }; - pil_parser.Parser.prototype.parseError = myErr; - - let parser = new pil_parser.Parser(); - const parserPerformAction = parser.performAction; - const productions = parser.productions_; - let compiler = this; - parser.performAction = function (yytext, yyleng, yylineno, yy, yystate, $$, _$ ) { - console.log(yystate); - const result = parserPerformAction.apply(this, arguments); - const first = _$[$$.length - 1 - productions[yystate][1]]; - const last = _$[$$.length - 1]; - if (typeof this.$ !== 'object') { - if (!this.$) { - console.log(`STRANGE THINK IN STATE ${yystate} `+(typeof this.$)); - this.$ = {}; - } - else { - return result; - } - } - this.$.debug = `${compiler.relativeFileName} ${first.first_line}:${first.first_column}`; - if (typeof last.last_line != 'undefined' && last.last_line != first.first_line) { - this.$.debug += ` ${last.last_line}`; - } - if (typeof last.last_column != 'undefined') { - this.$.debug += `:${last.last_column}`; - } - /* - this.$.first_line = first.first_line; - this.$.first_column = first.first_column; - this.$.last_line = last.last_line || first.first_line; - this.$.last_column = last.last_column || first.first_column;*/ - return result; - } - return parser; - } - async parseSource(fileName, isMain = false) { - - const [src, fileDir, fullFileName, relativeFileName] = await this.loadSource(fileName, isMain); - - this.relativeFileName = relativeFileName; - this.fileDir = fileDir; - - const parser = this.instanceParser(src, fullFileName); - const sts = parser.parse(src); - - for (let i=0; i '+s.locator); - this.fileName = s.fileName = relativeFileName; - this.line = s.first_line; - console.log('S'); - console.log(s); - this.sourceRef = `${s.fileName}:${s.first_line}`; - - let skip = false; - let poldef = false; - let insideIncludedDomain = false; - - const ctxExprLen = this.expressions.length; - try { - this.checkNamespace(this.namespace); - insideIncludedDomain = true; - await this.parseStatement(s); - } catch (err) { - if (err instanceof SkipNamespace) { - skip = true; - } else { - throw err; - } - } - if (!skip) continue; - - if (insideIncludedDomain) { - let verboseInfo = ''; - if (this.config.verbose) { - verboseInfo = ':\n' + ansiColor(36) + srcLines.slice(s.first_line-1, Math.min(s.first_line+3, s.last_line)).join('\n'); - const lineStrLines = s.last_line - s.first_line + 1; - if (lineStrLines > 3) verboseInfo += " ..."; - verboseInfo += ansiColor(0) +'\n'; - } - console.log(`NOTE: ${this.relativeFileName}:${s.first_line} was ignored${verboseInfo}`); - } - - if (poldef) { - console.log(`adding ${poldef} to exclude`); - this.skippedPols[poldef] = true; - } - while (ctxExprLen < this.expressions.length) { - this.expressions.pop(); - } - } - } - async parseStatements(statements) { - for (const s of statements) { - const res = await this.parseStatement(s); - if (typeof res === 'boolean') { - return res; - } - } - } - async parseStatement(s) { - const method = ('do_'+s.type).replace(/[-_][a-z]/g, (group) => group.slice(-1).toUpperCase()); - console.log(`[${s.type}] ===> ${method}`); - if (!(method in this)) { - console.log('==== ERROR ===='); - console.log(s); - this.error(s, `Invalid line type: ${s.type}`); - } - if (this[method].constructor.name === 'AsyncFunction') { - console.log(`CALLING ASYNC FUNCTION ${method}`) - return await this[method](s); - } - console.log(`REGULAR CALLING FUNCTION ${method}`) - return this[method](s); - } - doWitnessColDeclaration(s) { - this.nWitnessCols = this.colDeclaration(s, 'witness', this.nWitnessCols); - } - doFixedColDeclaration(s) { - this.nFixedCols = this.colDeclaration(s, 'fixed', this.nFixedCols); - } - doColDeclaration(s) { - this.nIm = this.colDeclaration(s, 'im', this.nIm, true); - } - colDeclaration(s, type, nextId, reserveExpressions = false) { - console.log('*********'); - console.log(s); - for (const col of s.items) { - const colname = this.getFullName(col);; - console.log(`COL_DECLARATION(${colname}) type:${type} nextId:${nextId}`); - let ref = this.references.get(colname); - if (ref !== null) { - this.error(s, `${colname} already defined on ${ref.sourceRef}`); - } - // TODO: multidimensional-array - let len = (col.type === 'array') ? this.getExprNumber(col.expLen, s, `${colname} array size`) : 1; - const refId = reserveExpressions ? this.expressions.reserve(len) : nextId; - ref = { - type, - id: refId, - colDeg: this.colDeg, - sourceRef: s.sourceRef, - isArray: (col.type === 'array'), - }; - if (col.type === 'array') { - ref.len = len; - } - nextId += len; - this.references.define(colname, ref); - /// TODO: INIT / SEQUENCE - } - return nextId; - } - addExpression(expr) - { - this.addFilename(expr, this.relativeFileName); - return this.expressions.insert(expr); - } - updateExpression(id, expr) - { - this.addFilename(expr, this.relativeFileName); - return this.expressions.update(id, expr); - } - async doInclude(s) { - console.log(`doInclude ======${s.file.value}`); - console.log(s); - console.log([this.fileDir, s.fileName]); - const includeFile = this.asString(s.file); - const fullFileNameI = this.config.includePaths ? s.file : path.resolve(this.fileDir, includeFile); - if (!this.includedFiles[fullFileNameI]) { // If a file included twice just ignore - console.log(`doInclude ======${s.file.value}============== PROCESS`); - this.includedFiles[fullFileNameI] = true; - const previous = [this.namespace, this.cwd, this.relativeFileName, this.fileDir ]; - - this.namespace = false; - this.cwd = this.fileDir; - await this.parseSource(fullFileNameI, false); - - [this.namespace, this.cwd, this.relativeFileName, this.fileDir ] = previous; - - // TODO -> review this part - // if (pendingCommands.length>0) this.error(s, "command not allowed before include"); - // lastLineAllowsCommand = false; - } else { - console.log(`doInclude ======${s.file.value}============== IGNORE`); - } - console.log('doInclude END'); - return true; - } - async doNamespace(s) { - const subproof = s.subproof ?? false; - const namespace = s.namespace; - if (subproof !== false && !(subproof in this.subproofs)) { - this.error(s, `subproof ${s.subproof} hasn't been defined`); - } - - // TODO: verify if namespace just was declared in this case subproof must be the same - const previous = [this.namespace, this.subproof ]; - this.namespace = namespace; - this.subproof = subproof; - console.log(s); - await this.parseStatements(s.statements); - [this.namespace, this.subproof ] = previous; - } - doSubproofDefinition(s) { - const subproof = s.name ?? false; - console.log(`doSubproofDefinition ====== ${subproof}`); - if (subproof === false) { - this.error(s, `subproof not defined correctly`); - } - const subproofInfo = this.subproofs[subproof]; - if (subproofInfo !== undefined) { - this.error(s, `subproof ${subproof} has been defined previously on ${subproofInfo.sourceRef}`); - } - let rows = []; - // TO-DO: eval expressions; - this.subproofs[subproof] = { - sourceRef: this.sourceRef, - rows - }; - } - doPolDefinition(s) { - const polname = this.namespace + "." + s.name; - s.expression.poldef = polname; - const eidx = this.addExpression(s.expression); - let ref = this.references.get(polname); - if (ref !== null) { - this.error(s, `${polname} already defined on ${ref.sourceRef}`); - } - ref = { - type: 'imP', - id: eidx, - polDeg: this.polDeg, - sourceRef: s.sourceRef, - }; - this.references.define(polname, ref); - this.nIm++; - } - setPol(s) { -// const polname = this.namespace + "." + s.name; -// let ref = this.references.get(polname); - const [polname, ref, id] = this.expressions.resolveReference(s); - - if (ref.type === 'var') { - ref.value = this.expressions.e2num(s.expression); - this.references.set(polname, ref); - } else { - if (this.expressions.get(id) !== null) { - this.error(s, `multiple initializations of ${polref}`); - } - s.expression.poldef = polname; - this.updateExpression(id, s.expression); - } - } - doConstraint(s) { - console.log('********** doConstraint ********** (s.expression:)'); - let constraint = {op: 'sub', values: [s.left, s.right]}; - console.log(s); - this.expressions.toString(constraint); - let expr = this.expressions.evaluate(constraint, {update: true, Fr: this.Fr}); - console.log('********** doConstraint ********** (expr)'); - this.expressions.toString(expr); - const eidx = this.addExpression(expr); - this.constraints.push({fileName: this.relativeFileName, namespace: this.namespace, line: s.first_line, e: eidx}); - } - composePlPeIdentity(s) { - const pu = { - fileName: this.relativeFileName, - namespace: this.namespace, - line: s.first_line, - f: [], - t: [], - selF: null, - selT: null - } - s.f.forEach(expr => pu.f.push(this.addExpression(expr))); - if (s.selF) { - pu.selF = this.addExpression(s.selF); - } - s.t.forEach(expr => pu.t.push(this.addExpression(expr))); - if (s.selT) { - pu.selT = this.addExpression(s.selT); - } - if (pu.f.length != pu.t.length ) { - this.error(s, `${s.type} with diferent number of elements`); - } - return pu; - } - doPlookupIdentity(s) { - this.plookupIdentities.push(this.composePlPeIdentity(s)); - } - doPermutationIdentity(s) { - this.permutationIdentities.push(this.composePlPeIdentity(s)); - } - doConnectionIdentity(s) { - const ci = { - fileName: this.relativeFileName, - namespace: this.namespace, - line: s.first_line, - pols: [], - connections: [], - } - s.pols.forEach(expr => ci.pols.push(this.addExpression(expr))); - s.connections.forEach(expr => ci.connections.push(this.addExpression(expr))); - if (ci.pols.length != ci.connections.length ) { - this.error(s, `connection with diferent number of elements`); - } - this.connectionIdentities.push(ci); - } - getExprNumber(expr, s, title) { - console.log(expr); - const se = this.expressions.simplifyExpression(expr); - if (se.op !== 'number') { - this.error(s, title + ' is not constant expression'); - } - return Number(se.value); - } - getReferenceArrayOffset(s, pol, polname) { - if (!this.references.isDefined(polname)) { - this.error(s, `polynomial ${polname} not defined`); - } - const ref = this.references.get(polname); - - if (pol.idxExp && !ref.isArray) { - this.error(s, `${polname} is not an Array`); - } - if (!pol.idxExp && ref.isArray) { - console.log([pol, ref]); - this.error(s, `${polname}: index of an array not specified`); - } - const offset = ref.isArray ? this.getExprNumber(pol.idxExp, s, 'Index') : 0; - return [ref, offset]; - } - doFunctionDefinition(s) { - // this.functions.define() - } - doPublicDeclaration(s) { - if (this.publics.isDefined(s.name)) { - this.error(s, `name already defined ${s.name}`); - } - const polname = (s.pol.namespace === 'this' ? this.namespace : s.pol.namespace) + '.' + s.pol.name; - const [ref, offset] = this.getReferenceArrayOffset(s, s.pol, polname); - const idx = this.getExprNumber(s.idx, s, 'Index of a public'); - this.publics.define(s.name, { - polType: ref.type, - polId: Number(ref.id) + offset, - idx, - id: this.nPublic++ - }); - } - doConstantDefinition(s) { - if (this.config.defines && s.name in this.config.defines) { - console.log(`NOTICE: Ignore constant definition ${s.name} on ${this.relativeFileName}:${s.first_line} because it was pre-defined`); - return; - } - if (this.constants.isDefined(s.name)) { - this.error(s, `name already defined ${s.name}`); - } - this.constants.define(s.name, this.getExprNumber(s.value, s, `constant ${s.name} definition`)); - } - doCode(s) { - return this.processor.execute(s.statments); - } - async loadSource(fileName, isMain) { - let fullFileName, fileDir, src; - let relativeFileName = ''; - let includePathIndex = 0; - if (isMain && this.config.compileFromString) { - relativeFileName = fullFileName = "(string)"; - fileDir = ''; - src = fileName; - } - else { - let includePaths = [...this.includePaths]; - let directIncludePathIndex; - const cwd = this.cwd ? this.cwd : process.cwd(); - - if (this.config.includePathFirst) { - directIncludePathIndex = includePaths.length; - includePaths.push(cwd); - } - else { - directIncludePathIndex = 0; - includePaths.unshift(cwd); - } - do { - fullFileName = path.resolve(includePaths[includePathIndex], fileName); - if (fs.existsSync(fullFileName)) break; - ++includePathIndex; - } while (includePathIndex < includePaths.length); - - fileDir = path.dirname(fullFileName); - - if (includePathIndex != directIncludePathIndex) { - relativeFileName = fileName; - } - else { - if (isMain) { - relativeFileName = path.basename(fullFileName); - this.basePath = fileDir; - } else { - if (fullFileName.startsWith(this.basePath)) { - relativeFileName = fullFileName.substring(this.basePath.length+1); - } else { - relativeFileName = fullFileName; - } - } - } - console.log(`LOADING FILE ${fullFileName} .............`) - src = await fs.promises.readFile(fullFileName, "utf8") + "\n"; - console.log('END LOADING ...'); - } - console.log('################ BEGIN SOURCE #########################'); - console.log(src); - console.log('################ END SOURCE #########################'); - return [src, fileDir, fullFileName, relativeFileName]; - } - - reduceExpressions() { - for (const pol of this.polIdentities) { - this.expressions.reduceTo2(pol.e); - } - for (const plpe of [this.plookupIdentities, this.permutationIdentities]) { - for (const pol of plpe) { - for (const f of pol.f) { - this.expressions.reduceTo1(f); - } - if (pol.selF) { - this.expressions.reduceTo1(pol.selF); - } - for (const t of pol.t) { - this.expressions.reduceTo1(t); - } - if (pol.selT) { - this.expressions.reduceTo1(pol.selT); - } - } - } - for (const pol of this.connectionIdentities) { - for (const p of pol.pols) { - this.expressions.reduceTo1(p); - } - for (const co of pol.connections) { - this.expressions.reduceTo1(co); - } - } - } - error (l, err) { - if (err instanceof Error) { - err.message = `ERROR ${l.fileName}:${l.first_line}: ${err.message}` - throw(err); - } else { - const msg = `ERROR ${l.fileName}:${l.first_line}: ${err}`; - throw new Error(msg); - } - } - expressionToJson(e, deps) { - let main = false; - if (!deps) { - deps = []; - main = true; - } - const out = { - op: e.op - } - out.deg = e.deg; - if (e.op == 'pol') { - const polname = e.namespace + '.' + e.name - const [ref, offset] = this.getReferenceArrayOffset(e, e, polname); - out.id = Number(ref.id) + offset; - if (ref.type === 'cmP') { - out.op = 'cm'; - } else if (ref.type === 'constP') { - out.op = 'const'; - } else if (ref.type === 'imP') { - // TODO: array support on temporal - if (!main) { - deps.push(ref.id); - } - out.op = 'exp' - } - out.next = e.next; - } - if (e.op == "public") { - const ref = this.publics.get(e.name); - out.id = ref.id; - out.op = 'public'; - } - if (typeof e.idQ !== 'undefined') { - out.idQ = e.idQ; - } - if (typeof e.values !== 'undefined') { - out.values = e.values.map(value => this.expressionToJson(value, deps)); - } - if (typeof e.value !== 'undefined') { - out.value = e.value; - } - if (typeof e.const !== 'undefined') { - out.const = e.const; - } - if (main && deps.length>0) { - out.deps = deps; - } - return out; - } - contextToJson() { - let out = { - nCommitments: this.nCommitments, - nQ: this.nQ, - nIm: this.nIm, - nConstants: this.nConstants, - publics: [], - references: {}, - expressions: [], - polIdentities: [], - plookupIdentities: [], - permutationIdentities: [], - connectionIdentities: [] - }; - - for (const [name,ref] of this.references.keyValues()) { - out.references[name] = { - type: ref.type, - id: ref.id, - polDeg: ref.polDeg, - isArray: ref.isArray ? true:false }; - if (ref.isArray) { - out.references[name].len = ref.len; - } - } - - for (const [name, pub] of this.publics.keyValues()) { - out.publics[pub.id] = pub; - out.publics[pub.id].name = name; - } - - for (const expr of this.expressions) { - out.expressions.push(this.expressionToJson(expr)); - } - - for (const pi of this.polIdentities) { - out.polIdentities.push({ - e: pi.e, - fileName: pi.fileName, - line: pi.line - }); - } - - for (const ptype of ['plookupIdentities', 'permutationIdentities']) { - for (const p of this[ptype]) { - out[ptype].push({ - f: p.f, - t: p.t, - selF: p.selF, - selT: p.selT, - fileName: p.fileName, - line: p.line}); - } - } - - for (const ci of this.connectionIdentities) { - out.connectionIdentities.push({ - pols: ci.pols, - connections: ci.connections, - fileName: ci.fileName, - line: ci.line }); - } - - return out; - } - - addFilename(exp, fileName) { - exp.fileName = fileName; - if (exp.namespace === "this") exp.namespace = this.namespace; - else if (exp.namespace) this.checkNamespace(exp.namespace); - - if (exp.name) this.checkSkippedPols(exp.namespace, exp.name); - if (exp.values) { - for(let i=0; i this.namespaces[namespace] === 0); - if (notFoundNamespaces.length) { - throw new Error('ERROR: namespaces not found: '+notFoundNamespaces.join(', ')); - } - } - } - checkUndefinedPols() { - let undefined = 0; - let names = []; - for (const [name, ref] of this.references.keyValues()) { - if (ref.type !== 'imP') continue; - const len = ref.isArray ? ref.len : 1; - let fromId = ref.id; - let reported = false; - for (let index = 0; index < len; ++index ) { - if (this.expressions.get(fromId + index) !== null) continue; - ++undefined; - if (ref.isArray) console.log(`ERROR: Undefined temporal pol ${name}[${index}]`) - else console.log(`ERROR: Undefined temporal pol ${name}`) - if (reported) continue; - names.push(name); - reported = true; - } - } - if (undefined > 0) { - throw new Error(`found ${undefined} undefined pols (${names.join(',')})`); - } - } - checkUnusedExpressions() { - for (const expr of this.expressions) { - if (!expr.used) { - console.log(expr); - if (this.config.disableUnusedError) { - console.log(`WARNING: Unused expresion ${expr.poldef} on ${expr.fileName}:${expr.first_line}`); - } else { - this.error(expr, `Unused expression ${expr.poldef} `); - } - } - if (expr.deg>2) { - this.error(expr, `Degree ${expr.deg} greater than 2`); - } - } - } - checkExpressionsDegree(limit=2) { - for (const expr of this.expressions) { - if (expr.deg <= limit) continue; - this.error(expr, `Degree ${expr.deg} greater than ${limit}`); - } - } - getFullName(e) { - if (e.name === 'RESET') { - console.log(['E', e, this.namespace, this.subproof]); - } - const ns = (((e.namespace ?? 'this') === 'this') ? this.namespace : e.namespace); - const sp = (((e.subproof ?? 'this') === 'this') ? this.subproof : e.subproof); - - let name = ''; - if (sp !== '') { - name += sp + '::'; - } - if (ns !== '') { - name = ns + '.'; - } - name += e.name; - console.log(`${e.name} ==> ${name}`) - return name; - } - asString(s) { - if (typeof s === 'string') return s; - if (typeof s === 'bigint') return ''+s; - if (typeof s.type === 'string') { - return s.value; - } - if (typeof s.type === 'template') { - // TODO: resolve template ??? - return s.value; - } - this.error(s, "invalid string"); - } -} - -module.exports = async function compile(Fr, fileName, ctx, config = {}) { - - let compiler = new Compiler(Fr); - return await compiler.compile(fileName, config); -} diff --git a/src/constraints.js b/src/constraints.js index 1dc81f7..15085d6 100644 --- a/src/constraints.js +++ b/src/constraints.js @@ -1,9 +1,9 @@ +const {assert, assertLog} = require('./assert.js'); +const Expression = require('./expression.js'); +const Context = require('./context.js'); module.exports = class Constraints { - - constructor (Fr, expressions) { - this.Fr = Fr; + constructor () { this.constraints = []; - this.expressions = expressions; } clone() { @@ -16,21 +16,24 @@ module.exports = class Constraints { } get(id) { - return this.constraints[id]; + return {...this.constraints[id]}; } getExpr(id) { - return this.expressions.get(this.constraints[id].exprId); + return Context.expressions.get(this.constraints[id].exprId); } isDefined(id) { return (typeof this.constraints[id] != 'undefined'); } - getPackedExpressionId(id, container, options) { - return this.expressions.getPackedExpressionId(id, container, options); + getPackedExpressionId(id, container, options = {}) { + const res = (options.expressions ?? Context.expressions).getPackedExpressionId(id, container, options); + return res; } define(left, right, boundery, sourceRef) { + assertLog(left instanceof Expression, left); + assertLog(right instanceof Expression, right); if (left.isRuntime()) { left.dump('LEFT CONSTRAINT'); throw new Error(`left constraint has runtime no resolved elements`); @@ -43,11 +46,15 @@ module.exports = class Constraints { console.log('\x1B[31mWARNING: accessing fixed row acces\x1b[0m'); } const id = this.constraints.length; - if (right.eval() !== 0n) { + if (right.asIntDefault(false) !== 0n) { left.insert('sub', right); } + // const dumpId = Date.now(); + // left.dump(`XXXXXXXXX-${dumpId}-1`) + // left.instance().dump(`XXXXXXXXX-${dumpId}-2`); left.simplify(); - const exprId = this.expressions.insert(left); + const exprId = Context.expressions.insert(left); + console.log(`DEFINE CONSTRAINT ${sourceRef}`); return this.constraints.push({exprId, sourceRef, boundery}) - 1; } @@ -69,7 +76,6 @@ module.exports = class Constraints { } } dump (packed) { - console.log('CONSTRAINTS'); for (let index = 0; index < this.constraints.length; ++index) { console.log(this.getDebugInfo(index, packed)); } @@ -77,12 +83,13 @@ module.exports = class Constraints { getDebugInfo(index, packed, options) { const constraint = this.constraints[index]; const eid = constraint.exprId; - const peid = this.expressions.getPackedExpressionId(eid); + // const peid = Context.expressions.getPackedExpressionId(eid); + const peid = this.getPackedExpressionId(eid, packed, options); let info = `INFO ${index}: ${eid} ${peid} ${constraint.sourceRef}` options = options ?? {}; if (packed) { - info += ' ' + packed.exprToString(peid, {...options, labels: this.expressions, hideClass: true}); + info += ' ' + packed.exprToString(peid, {...options, labels: Context.expressions, hideClass: true}); } return info; } diff --git a/src/containers.js b/src/containers.js new file mode 100644 index 0000000..6d6791d --- /dev/null +++ b/src/containers.js @@ -0,0 +1,146 @@ +const Context = require('./context.js'); +const {assert, assertLog} = require('./assert.js'); +module.exports = class Containers { + constructor (parent) { + this.parent = parent; + this.containers = {}; + this.current = false; + this.uses = []; + this.aliases = []; + } + addScopeAlias(alias, value) { + // NOTE: there is no need to check for aliases because by grammatical definition, + // aliases must be an identifier + + if (this.aliases[alias]) { + throw new Error(`Alias ${alias} already defined on ${this.aliases[alias].sourceRef}`); + } + + Context.scope.addToScopeProperty('aliases', alias); + this.aliases[alias] = {container: value, sourceRef: Context.sourceRef}; + } + getAlias(alias, defaultValue) { + return this.aliases[alias] ?? defaultValue; + } + getFromAlias(alias, defaultValue) { + return this.getAlias(alias, {container: defaultValue}).container; + } + unsetAlias(aliases) { + for (const alias of aliases) { + assert(this.aliases[alias]); + delete this.aliases[alias]; + } + } + unsetUses(uses) { + let count = uses.length; + while (count > 0) { + const use1 = this.uses.pop(); + const use2 = uses.pop(); + assert(use1 === use2); + --count; + } + } + unsetProperty(property, values) { + switch (property) { + case 'aliases': return this.unsetAlias(values); + case 'uses': return this.unsetUses(values); + } + throw new Error(`unsetProperty was called with invalid property ${property}`); + } + clearScope(proofScope) { + console.log(`CLEAR-SCOPE.CONTAINERS.IN ${proofScope}`, Object.keys(this.containers).map(name => [name, this.containers[name].scope])); + this.containers = Object.keys(this.containers) + .filter(name => this.containers[name].scope !== proofScope) + .reduce((containers, name) => { containers[name] = this.containers[name]; return containers; }, {}); + console.log(`CLEAR-SCOPE.CONTAINERS.OUT ${proofScope}`, Object.keys(this.containers).map(name => [name, this.containers[name].scope])); + } + create(name, alias = false) + { + if (this.current !== false) { + throw new Error(`Container ${this.current} is open, must be closed before start new container`); + } + + // console.log(`createContainer(${name},${alias}) at ${this.context.sourceRef}`); + // if container is defined, contents is ignored but alias must be defined + if (alias) { + this.addScopeAlias(alias, name); + } + + console.log(`CREATE CONTAINER ${name}`); + // if container is defined, contents is ignored + if (this.containers[name]) { + return false; + } + + // const nameInfo = this.decodeName(name).scope; + ; + this.containers[name] = {scope: this.parent.getNameScope(name), alias, references: {}}; + console.log(this.containers[name]); + this.current = name; + return true; + } + inside() { + return this.current; + } + getCurrent() { + return this.current; + } + close(){ + this.current = false; + } + isDefined(name) { + return (this.containers[name] ?? false) !== false; + } + get (name) { + return this.containers[name] ?? false; + } + addReference(name, reference) { + if (this.current === false) { + throw new Error(`Could add reference ${name} to closed container`); + } + const container = this.containers[this.current]; + console.log(this.containers); + console.log(this.current); + if (container.references[name]) { + throw new Error(`Reference ${name} was declared previously on scope ${this.current}`); + } + container.references[name] = reference; + } + addUse(name) { + if (!this.containers[name]) { + // TODO: defined must be check containers + throw new Error(`Use not created container ${name}`); + } + Context.scope.addToScopeProperty('uses', name); + this.uses.push(name); + } + getReferenceInside(container, name, defaultValue) { + return this.#getReference(name, defaultValue, container, false); + } + getReferenceInsideCurrent(name, defaultValue) { + return this.#getReference(name, defaultValue, this.current, false); + + } + getReference(name, defaultValue) { + return this.#getReference(name, defaultValue, this.current, true); + } + #getReference(name, defaultValue, container, uses) { + // first search on specific container + let reference = false; + if (container) { + reference = this.containers[container].references[name] ?? false; + } + // if not found check other counters indicate with use + let usesIndex = this.uses.length; + while (!reference && usesIndex > 0) { + --usesIndex; + reference = this.containers[this.uses[usesIndex]].references[name] ?? false; + } + return reference ? reference : defaultValue; + } + *[Symbol.iterator]() { + for (let name in this.containers) { + yield name; + } + } +} diff --git a/src/context.js b/src/context.js index daf291c..8bd1c26 100644 --- a/src/context.js +++ b/src/context.js @@ -1,20 +1,57 @@ const {assert} = require("chai"); -const References = require("./references.js"); -const Expressions = require("./expressions.js"); -const Router = require("./router.js"); - module.exports = class Context { - constructor (Fr, processor) { + static _instance = null; + + constructor (Fr, processor, config = {}) { + assert(Context._instance === null); + Context._instance = this; this.Fr = Fr; - this.processor = processor; + this._processor = processor; this.namespace = ''; this.subproof = false; - this.stack = []; - this.config = {debug: {}}; - this.sourceRef = ''; + this.stack = []; + this.config = {debug: {}, ...config}; this.uses = []; + this.subproofName = false; + this.airId = false; + this.airN = false; + } + static get config() { + return this._instance.config; + } + static get expressions() { + return this._instance._processor.expressions; + } + static get runtime() { + return this._instance._processor.runtime; + } + static get scope() { + return this._instance._processor.scope; + } + static get sourceRef() { + return this._instance._processor.sourceRef; + } + static get sourceTag() { + return this._instance._processor.sourceRef.split('/').slice(-2).join('/'); + } + static get processor() { + return this._instance._processor; + } + static get current() { + return this._instance; + } + static get references() { + return this._instance._processor.references; + } + static get proofLevel() { + if (this.airName) { + return `AIR:${this.airName}`; + } + if (this.subproofName) { + return `SUBPROOF:${this.subproofName}`; + } + return 'PROOF'; } - setNamespace(namespace, subproof) { this.namespace = namespace; if (typeof subproof !== 'undefined') { diff --git a/src/debug.js b/src/debug.js new file mode 100644 index 0000000..a015e2f --- /dev/null +++ b/src/debug.js @@ -0,0 +1,7 @@ +const {assert} = require('./assert.js'); + +class Debug { + static active = false; +} + +module.exports = Debug; \ No newline at end of file diff --git a/src/debug_console.js b/src/debug_console.js new file mode 100644 index 0000000..98194e3 --- /dev/null +++ b/src/debug_console.js @@ -0,0 +1,47 @@ +module.exports = class DebugClass { + static logid = 0; + constructor (options = {}) { + this.originalMethod = console.log; + this.maxSourceRefLen = options.maxSourceRefLen ?? 20; + console.log = (...args) => this.consoleLog.apply(this, args); + console.stdebug = (...args) => this.stdebug.apply(this, args); + console.stclear = (...args) => this.stclear.apply(this, args); + } + static init (options = {}) { + return new DebugClass(options); + } + consoleLog (...args) { + let initiator = false; + try { + throw new Error(); + } catch (e) { + if (typeof e.stack === 'string') { + let lineIndex = 2; + for (const line of e.stack.split('\n')) { + const matches = line.match(/^\s+at\s+.*\/([^\/:]*:[0-9]+:[0-9]+)\)/); + if (!matches) continue; + --lineIndex; + if (lineIndex < 0) { + initiator = matches[1]; + break; + } + } + } + } + if (initiator === false) { + this.originalMethod.apply(console, args); + } else { + ++DebugClass.logid; + initiator = initiator.split(':').slice(0,2).join(':').replace('.js',''); + initiator = initiator.length > this.maxSourceRefLen ? ('...' + initiator.substring(-this.maxSourceRefLen+3)) : initiator.padEnd(this.maxSourceRefLen); + initiator = initiator + DebugClass.logid.toString(16).toUpperCase().padStart(10, ' ')+'L'; + this.originalMethod.apply(console, [`\x1B[30;104m${initiator} \x1B[0m`, ...args]); + } + } + stdebug(...args) { + this.consoleLog.apply(this, args); + } + stclear(...args) { + this.debuglog = []; + } +} diff --git a/src/definition_items.js b/src/definition_items.js new file mode 100644 index 0000000..3b3dbbc --- /dev/null +++ b/src/definition_items.js @@ -0,0 +1,33 @@ +const DefinitionItem = require("./definition_items/definition_item.js"); +const FeVariable = require("./definition_items/fe_variable.js"); +const IntVariable = require("./definition_items/int_variable.js"); +const ProofItem = require("./definition_items/proof_item.js"); +const Proofval = require("./definition_items/proofval.js"); +const Challenge = require("./definition_items/challenge.js"); +const Public = require("./definition_items/public.js"); +const Publictable = require("./definition_items/publictable.js"); +const RuntimeItem = require("./definition_items/runtime_item.js"); +const StringVariable = require("./definition_items/string_variable.js"); +const Subproofval = require("./definition_items/subproofval.js"); +const Variable = require("./definition_items/variable.js"); +const WitnessCol = require("./definition_items/witness_col.js"); +const FixedCol = require("./definition_items/fixed_col.js"); +const ExpressionVariable = require("./definition_items/expression_variable.js"); + +module.exports = { + DefinitionItem, + FeVariable, + FixedCol, + IntVariable, + ProofItem, + Proofval, + Challenge, + Public, + Publictable, + RuntimeItem, + StringVariable, + Subproofval, + Variable, + WitnessCol, + ExpressionVariable +} diff --git a/src/definition_items/challenge.js b/src/definition_items/challenge.js new file mode 100644 index 0000000..f1afdee --- /dev/null +++ b/src/definition_items/challenge.js @@ -0,0 +1,12 @@ +const ProofStageItem = require("./proof_stage_item.js"); +module.exports = class Challenge extends ProofStageItem { + constructor (id, data = {}) { + super(id, data.stage); + this.sourceRef = data.sourceRef; + this.label = data.label; + } + clone() { + return new Challenge(this.id, {stage: this.stage, sourceRef: this.sourceRef, + label: (this.label && typeof this.label.clone === 'function') ? this.label.clone(): this.label}); + } +} diff --git a/src/definition_items/definition_item.js b/src/definition_items/definition_item.js new file mode 100644 index 0000000..f7df7c5 --- /dev/null +++ b/src/definition_items/definition_item.js @@ -0,0 +1,72 @@ +/* cexp next ind Parent Item DefClas Definition + ---- ---- --- -------------- -------------- -------------- --------------------------------------------- + Challenge - - * ProofStageItem id ProofStageDef id + stage [used] + SubExpression - * * ProofItem id - id [const,use] + FeValue - - - ValueItem value - value (fe) [const] + IntValue * - - ValueItem value - value (bigint) [const] + FixedCol - - * ProofItem id - id [used] + FunctionCall * * ? RuntimeItem "id",argValues Function name,args,return,statements + Proofval - - * ProofItem id - id [used] + Public - - * ProofItem id - id [used] + Publictable - - * ProofItem id PublictableDef id + numCols,maxRows,aggType,rowExpressionId [used] + *PublictableCol - - * ProofItem id,colId - [const, used] + ReferenceItem * * * RuntimeItem name ? name + type, instance, etc. + StringValue * - - RuntimeItem value - value (string) [const, used] + Subproofval - - * ProofItem id SubproofvalDef id + subproofId [used] + WitnessCol - * * ProofStageItem id ProofStageDef id + stage [used] + + + Type List Item + ---------- -------------- -------------- + Challenge challenge challenges (Ids) stage Ids: new cls(id) + Expression expr exprs (Variables) value Variables: new cls(value) + SubExpression subexpr subexprs (Ids) id Ids: new cls(id) + FeValue fe fes (Variables) value Variables: new cls(value) + IntValue int ints (Variables) value Variables: new cls(value) + FixedCol fixed fixeds (FixedCols) id Ids: new cls(id) + Proofval proofvalue proofvalues (Ids) id Ids: new cls(id) + Public public publics (Ids) id Ids: new cls(id) + Publictable publictable id + *PublictableCol id,colId + ReferenceItem - references (References) name + StringValue string strings (Variables) value Variables: new cls(value) + Subproofval subproofval subproofvalues (Ids) id Ids: new cls(id) + WitnessCol witness witness (WitnessCols) id WitnessCols: new WitnessCol(id, stage) + + + + cexp: compiler expression (build) + next: allowed next + ind: allowed indexes + + ExpressionItem > ProofItem > ProofStageItem + > RuntimeItem + > ValueItem + + Array information on reference + + ArrayOf (multiarray, from: ExpressionItem) + ArrayOf (multiarray, [ExpressionItem]) = List + +*/ +module.exports = class DefinitionItem { + constructor (id, properties = {}) { + this.definition = true; + this.id = id; + this.label = properties.label; + } + toString(options) { + return `${this.label}()`; + } + dump(options) { + return this.toString(options); + } + get type() { + console.log(this); + throw new Error(`FATAL: use type obsolete-property`) + } + cloneProperties(cloned) { + cloned.id = this.id; + cloned.label = this.label; + } +} diff --git a/src/definition_items/expression_variable.js b/src/definition_items/expression_variable.js new file mode 100644 index 0000000..39e37eb --- /dev/null +++ b/src/definition_items/expression_variable.js @@ -0,0 +1,37 @@ +const Variable = require("./variable.js"); +const ExpressionClass = require('../expression_class.js'); +const Debug = require('../debug.js'); +const ValueItem = require('../expression_items/value_item.js'); +const util = require('util'); +const {assert, assertLog} = require('../assert.js'); +module.exports = class ExpressionVariable extends Variable { + constructor (id, properties = {}) { + super(id, properties); + this.value = new (ExpressionClass.get()); + } + setValue(value) { + if (Debug.active) { + console.log('================================================================'); + console.log(util.inspect(value, false, 10, true)); + console.log('================================================================'); + } + // super.setValue(value); + if (typeof value.instance === 'function') { + this.value = value.instance(); + return; + } + if (Debug.active) console.log(value); + this.value = value.clone(); + /* + if (value instanceof ExpressionClass || value instanceof ValueItem) { + this.value = value.clone(); + return; + } + console.log(this); + console.log(this.value); + console.log(value); + this.value.set(value); + // this.value._set(value); + this.value.dump('setValue');*/ + } +} diff --git a/src/definition_items/fe_variable.js b/src/definition_items/fe_variable.js new file mode 100644 index 0000000..ae0f9b9 --- /dev/null +++ b/src/definition_items/fe_variable.js @@ -0,0 +1,17 @@ +const LabelRanges = require("../label_ranges.js"); +const Variable = require("./variable.js"); + +module.exports = class FeVariable extends Variable { + constructor (value = 0n) { + super(value); + } + clone() { + return new FeVariable(this.value); + } + asInt() { + return this.value; + } + asNumber() { + return Number(this.value); + } +} diff --git a/src/definition_items/fixed_col.js b/src/definition_items/fixed_col.js new file mode 100644 index 0000000..59d09fc --- /dev/null +++ b/src/definition_items/fixed_col.js @@ -0,0 +1,71 @@ +const ProofItem = require("./proof_item.js"); +const Context = require('../context.js'); +// const Sequence = require("../sequence.js"); +module.exports = class FixedCol extends ProofItem { + constructor (id) { + super(id); + this.rows = 0; + this.sequence = null; + this.values = []; + this.fullFilled = false; + } + getId() { + return this.id; + } + isPeriodic() { + return this.rows > 0; + } + getValue(row) { + if (this.sequence === null) { + return this.values[row] + } + return this.sequence.getValue(row); + } + setValue(value) { + // REVIEW + this.set(value); + } + setRowValue(row, value) { + if (this.sequence) { + throw new Error(`setting a row value but assigned a sequence previously ${Context.sourceTag}`); + } + this.values[row] = value; + } + getRowValue(row) { + if (this.sequence) { + return this.sequence.getValue(row); + } + return this.values[row]; + } + set(value) { + // REVIEW: cyclic references + if (value instanceof Object) { + if (this.sequence !== null) { + console.log(value); + console.log(value.asInt()); + console.log(this.sequence); + this.sequence.dump(); + EXIT_HERE; + } + if (this.values.length > 0) { + EXIT_HERE; + } + this.sequence = value; + this.rows = this.sequence.size; + } + else { + console.log(value); + EXIT_HERE; + } + } + clone() { + let cloned = new FixedCol(this.id); + cloned.rows = this.rows; + cloned.values = [...this.values]; + cloned.fullFilled = this.fullFilled; + if (this.sequence) { + cloned.sequence = this.sequence.clone(); + } + return cloned; + } +} diff --git a/src/definition_items/int_variable.js b/src/definition_items/int_variable.js new file mode 100644 index 0000000..49bf708 --- /dev/null +++ b/src/definition_items/int_variable.js @@ -0,0 +1,46 @@ +const {assert, assertLog} = require('../assert.js'); +const Variable = require("./variable.js"); +const ExpressionItem = require('../expression_items/int_value.js'); +const Debug = require('../debug.js'); + +class IntVariable extends Variable { + constructor (value = 0n) { + if (typeof value === 'object' && typeof value.asInt === 'function') { + value = value.asInt(); + } + if (typeof value === 'number') { + value = BigInt(value); + } + assertLog(typeof value === 'bigint', value); + super(value); + } + setValue(value) { + if (Debug.active) console.log(value); + if (typeof value.asInt === 'function') { + value = value.asInt(); + } + if (typeof value === 'number') { + value = BigInt(value); + } + assertLog(typeof value === 'bigint', value); + super.setValue(value); + } + clone() { + return new IntValue(this.value); + } + static castTo(value) { + if (value instanceof IntValue) { + return value.value; + } + } + getItem() { + return new ExpressionItem(this.value); + } + asInt() { + return this.value; + } + asNumber() { + return Number(this.value); + } +} +module.exports = IntVariable; \ No newline at end of file diff --git a/src/definition_items/proof_item.js b/src/definition_items/proof_item.js new file mode 100644 index 0000000..d32f17a --- /dev/null +++ b/src/definition_items/proof_item.js @@ -0,0 +1,26 @@ +const DefinitionItem = require("./definition_item.js"); +module.exports = class ProofItem extends DefinitionItem { + constructor (id) { + super(); + this.id = id; + } + getId() { + return this.id; + } + getLabel(options) { + const manager = this.getManager(); + if (!manager) return ''; + return manager.getLabel(this.id, options); + } + dump(options) { + const [pre,post] = this.getNextStrings(); + options = options ?? {}; + const defaultType = options.type ? options.type : this.constructor.name; + if (!options.label && !options.hideLabel && options.dumpToString) { + options = {...options, label: this.getLabel(options)}; + } + const label = options.label ? options.label : `${defaultType}@${this.id}`; + return `${pre}${label}${post}`; + } +} + diff --git a/src/definition_items/proof_stage_item.js b/src/definition_items/proof_stage_item.js new file mode 100644 index 0000000..c259e9f --- /dev/null +++ b/src/definition_items/proof_stage_item.js @@ -0,0 +1,11 @@ +const ProofItem = require("./proof_item.js"); +module.exports = class ProofStageItem extends ProofItem { + constructor (id, stage) { + super(id); + this.stage = stage; + } + getStage() { + return this.stage; + } +} + diff --git a/src/definition_items/proofval.js b/src/definition_items/proofval.js new file mode 100644 index 0000000..5f90c12 --- /dev/null +++ b/src/definition_items/proofval.js @@ -0,0 +1,10 @@ +const ProofItem = require("./proof_item.js"); + +module.exports = class Proofval extends ProofItem { + constructor (id) { + super(id); + } + clone() { + return new Proofval(this.id); + } +} diff --git a/src/definition_items/public.js b/src/definition_items/public.js new file mode 100644 index 0000000..fdf55ef --- /dev/null +++ b/src/definition_items/public.js @@ -0,0 +1,16 @@ +const ProofItem = require("./proof_item.js"); +const PublicItem = require('../expression_items/public.js'); +module.exports = class Public extends ProofItem { + constructor (id) { + super(id); + } + get value () { + return new PublicItem(this.id); + } + getId() { + return this.id; + } + clone() { + return new Public(this.id); + } +} diff --git a/src/definition_items/publictable.js b/src/definition_items/publictable.js new file mode 100644 index 0000000..28b63f1 --- /dev/null +++ b/src/definition_items/publictable.js @@ -0,0 +1,12 @@ +const ProofItem = require("./proof_item.js"); +module.exports = class PublicTable extends ProofItem { + constructor (id) { + super(id); + } + getId() { + return this.id; + } + clone() { + return new PublicTable(this.id); + } +} diff --git a/src/definition_items/runtime_item.js b/src/definition_items/runtime_item.js new file mode 100644 index 0000000..3c03673 --- /dev/null +++ b/src/definition_items/runtime_item.js @@ -0,0 +1,20 @@ +const DefinitionItem = require("./definition_item.js"); +module.exports = class RuntimeItem extends DefinitionItem { + constructor (id, properties = {}) { + super(id, properties); + this.const = properties.const ?? false; + this.initialized = false; + } + cloneProperties(cloned) { + super.cloneProperties(cloned); + cloned.const = this.const; + cloned.initialized + } + setValue(value) { + if (this.const && this.initialized) { + throw new Error(`Setting a constant element`); + } + this.initialized = true; + } +} + diff --git a/src/definition_items/string_variable.js b/src/definition_items/string_variable.js new file mode 100644 index 0000000..7e78258 --- /dev/null +++ b/src/definition_items/string_variable.js @@ -0,0 +1,36 @@ +const {assert, assertLog} = require("../assert.js"); +const Variable = require("./variable.js"); +const StringValueItem = require("../expression_items/string_value.js"); + +class StringVariable extends Variable { + constructor (id, properties) { + super(id, properties); + const value = properties.value ?? ''; + assertLog(typeof value === 'string', value); + this.value = value; + } + getValue() { + return this.value; + } + setValue(value) { + if (typeof value.asString === 'function') { + value = value.asString(); + } + assertLog(typeof value === 'string', value); + this.value = value; + return this.value; + } + clone() { + let cloned = new StringValue(this.id); + this.cloneProperties(cloned); + } + cloneProperties(cloned) { + super.cloneProperties(cloned); + cloned.value = this.value; + } + getItem() { + return new StringValueItem(this.value); + } +} + +module.exports = StringVariable; \ No newline at end of file diff --git a/src/definition_items/subproofval.js b/src/definition_items/subproofval.js new file mode 100644 index 0000000..792cee1 --- /dev/null +++ b/src/definition_items/subproofval.js @@ -0,0 +1,21 @@ +const ProofItem = require("./proof_item.js"); +const {assert, assertLog} = require('../assert.js'); +module.exports = class Subproofval extends ProofItem { + constructor (id, data = {}) { + super(id); + const subproofId = data.subproofId ?? false; + assert(typeof data.subproofId === 'number'); + this.subproofId = subproofId; + this.aggregateType = data.aggregateType; + this.sourceRef = data.sourceRef; + this.subproofId = data.subproofId; + this.label = data.label; + this.relativeId = data.relativeId ?? false; + } + clone() { + return new Subproofval(this.id, {aggregateType: this.aggregateType, + sourceRef: this.sourceRef, + subproofId: this.subproofId, + label: (this.label && typeof this.label.clone === 'function') ? this.label.clone : this.label}); + } +} diff --git a/src/definition_items/variable.js b/src/definition_items/variable.js new file mode 100644 index 0000000..9b6f25f --- /dev/null +++ b/src/definition_items/variable.js @@ -0,0 +1,19 @@ +const RuntimeItem = require("./runtime_item.js"); +module.exports = class Variable extends RuntimeItem { + static directValue = true; + constructor (id, properties = {}) { + super(id, properties); + } + getValue() { + return this.value; + } + setValue(value) { + this.value = value; + } + toString(options) { + return `*${this.constructor.name}(${this.value})[${this.value ? this.value.constructor.name : '??'}]`; + } + clone() { + return new ValueItem(this.value); + } +} diff --git a/src/definition_items/witness_col.js b/src/definition_items/witness_col.js new file mode 100644 index 0000000..a98c899 --- /dev/null +++ b/src/definition_items/witness_col.js @@ -0,0 +1,19 @@ +const ProofStageItem = require("./proof_stage_item.js"); +const {assert, assertLog} = require('../assert.js'); +const WitnessColItem = require('../expression_items/witness_col.js') +const Debug = require('../debug.js'); +module.exports = class WitnessCol extends ProofStageItem { + constructor (id, stage = 1) { + assert(typeof id !== 'undefined'); + super(id, stage); + if (Debug.active) console.log('CONSTRUCTOR_WITNESS', id, this.id); + } + clone() { + let cloned = new WitnessCol(this.id, this.stage); + if (Debug.active) console.log('CLONE_WITNESS:', this, cloned); + return cloned; + } + get value () { + return new WitnessColItem(this.id); + } +} diff --git a/src/definitions.js b/src/definitions.js index 06b30f2..a313d21 100644 --- a/src/definitions.js +++ b/src/definitions.js @@ -1,7 +1,6 @@ module.exports = class Definitions { - constructor (Fr) { - this.Fr = Fr; + constructor () { this.definitions = {}; } get length () { diff --git a/src/dynamic_multi_array.js b/src/dynamic_multi_array.js new file mode 100644 index 0000000..8f84a36 --- /dev/null +++ b/src/dynamic_multi_array.js @@ -0,0 +1,105 @@ + +const {cloneDeep} = require('lodash'); +module.exports = class DynamicMultiArray extends MultiArray { + constructor (lengths, debug) { + // length[0] means dynamic index + this.dynamics = lengths.map(x => x == 0); + super(lengths, debug); + } + clone() { + let cloned = new DynamicMultiArray(this.lengths, this.debug); + cloned.dynamics = [...this.dynamics]; + return cloned; + } + /* + // assignation to indicate if allowed to increase one element + checkIndexes(indexes, assignation = false) { + if (indexes === null || typeof indexes === 'undefined') { + if (this.dim === 0) return true; + throw Error('Invalid index access'); // TODO: extra debug info + } else if (indexes.length !== this.dim) { + throw Error('Mismatch index valid access'); // TODO: extra debug info + } + for (let i = 0; i < indexes.length; ++i) { + if (indexes[i] < 0 || indexes[i] >= this.lengths[i]) { + throw Error(`Invalid index ${indexes[i]} on index ${i}`); // TODO: extra debug info + } + } + } + getIndexesOffset(indexes) { + return this.getIndexesTypedOffset(indexes).offset; + } + offsetToIndexes(offset) { + let level = 0; + let indexes = []; + while (level < this.dim) { + const size = this.offsets[level]; + indexes.push(Math.floor(offset/size)); + offset = offset % size; + ++level; + } + return indexes; + } + createSubArray(dim) { + return new MultiArray(this.lengths.slice(-dim)); + } + applyIndexes(obj, indexes) { + const res = this.getIndexesTypedOffset(indexes); + let dup = obj.clone() + if (dup.id) { + dup.id = dup.id + res.offset; + } + if (dup.array) { + dup.array = res.array; + } + return dup; + } + getIndexesOffset(indexes) { + if (indexes === null || typeof indexes === 'undefined') { + // TODO: review + return {offset: 0, array: this.createSubArray(this.offsets.length)}; + } + let offset = 0; + const dims = Math.min(this.offsets.length, indexes.length); + for (let idim = 0; idim < dims; ++idim) { + if (Number(indexes[idim]) >= this.lengths[idim]) return [false, idim]; + offset += this.offsets[idim] * Number(indexes[idim]); + } + return [offset, dims]; + } + isValidIndexes(indexes) { + const [offset, dims] = this.getIndexesOffset(indexes); + return (offset !== false && offset < this.size && dims === indexes.length) ? 1n : 0n; + } + getIndexesTypedOffset(indexes) { + const [offset,dims] = this.getIndexesOffset(indexes); + if (offset === false) { + throw new ErrorIndexOutOfRange(`Internal error on variable index access index:${indexes[dims]} valid range:[0-${this.lengths[dims]-1}]`); + } + if (offset >= this.size) { + throw new ErrorIndexOutOfRange(`Internal error on variable index access index:${offset} valid range:[0-${this.size-1}]`); + } + const dim = this.offsets.length - dims; + if (dim === 0) { + return {offset, array: false}; + } + // return {offset, dim, lengths: dim ? this.lengths.slice(-dim):[], array: this.createSubArray(dim)}; + return {offset, array: this.createSubArray(dim)}; + } + initOffsets(lengths) { + this.lengths = lengths; + this.dim = Array.isArray(lengths) ? lengths.length: 0 + let offsets = [1]; + let size = 1; + for (let idim = this.dim - 1; idim > 0; --idim) { + size = size * lengths[idim]; + offsets.push(size); + } + // for size multiplies first offset by length of first dimension + this.size = size * lengths[0]; + + // for offsets first index length isn't rellevant + this.offsets = offsets.reverse(); + }*/ +} + diff --git a/src/exceptions.js b/src/exceptions.js new file mode 100644 index 0000000..12e3fcb --- /dev/null +++ b/src/exceptions.js @@ -0,0 +1,9 @@ +const CannotBeCastToType = require('./exceptions/cannot_be_cast_to_type.js'); +const ReferenceNotFound = require('./exceptions/reference_not_found.js'); +const ReferenceNotVisible = require('./exceptions/reference_not_visible.js'); +const Exceptions = { + CannotBeCastToType, + ReferenceNotFound, + ReferenceNotVisible +} +module.exports = Exceptions; diff --git a/src/exceptions/cannot_be_cast_to_type.js b/src/exceptions/cannot_be_cast_to_type.js new file mode 100644 index 0000000..dfdac4d --- /dev/null +++ b/src/exceptions/cannot_be_cast_to_type.js @@ -0,0 +1,5 @@ +module.exports = class CannotBeCastToType extends Error { + constructor (castingType = false) { + super('Error casting type '+ (castingType === false ? '':' to '+castingType)); + } +} \ No newline at end of file diff --git a/src/exceptions/reference_not_found.js b/src/exceptions/reference_not_found.js new file mode 100644 index 0000000..bff0c44 --- /dev/null +++ b/src/exceptions/reference_not_found.js @@ -0,0 +1,5 @@ +module.exports = class ReferenceNotFound extends Error { + constructor (name) { + super('Error reference '+name+' not found'); + } +} \ No newline at end of file diff --git a/src/exceptions/reference_not_visible.js b/src/exceptions/reference_not_visible.js new file mode 100644 index 0000000..f748eff --- /dev/null +++ b/src/exceptions/reference_not_visible.js @@ -0,0 +1,5 @@ +module.exports = class ReferenceNotVisible extends Error { + constructor (name) { + super('Error reference '+name+' not visible/accesible'); + } +} \ No newline at end of file diff --git a/src/expression.js b/src/expression.js index e6ddc9c..53c237f 100644 --- a/src/expression.js +++ b/src/expression.js @@ -1,19 +1,32 @@ const util = require('util'); const {cloneDeep} = require('lodash'); -const {assert} = require("chai"); +const {assert, assertLog, assertReturnInstanceOf} = require('./assert.js'); +const ExpressionOperationsInfo = require('./expression_operations_info.js'); const NonRuntimeEvaluable = require('./non_runtime_evaluable.js'); -const PilItem = require('./pil_item.js'); - -const OP_VALUE = 0; -const OP_ID_REF = 1; -const OP_STACK = 2; -const OP_RUNTIME = 3; +const ExpressionItems = require("./expression_items.js"); +const ExpressionItem = ExpressionItems.ExpressionItem; +const ExpressionOperatorMethods = require('./expression_operator_methods.js'); +const Context = require('./context.js'); +const OP_VALUE = 'value'; +const OP_ID_REF = 'idref'; +const OP_STACK = 'stack'; +const OP_RUNTIME = 'runtime'; const NATIVE_REFS = ['witness', 'fixed', 'public', 'challenge', 'subproofvalue', 'proofvalue', 'publictable']; const NATIVE_OPS = ['add', 'sub', 'mul', 'neg']; const VALID_NATIVE_OPS = [false, ...NATIVE_OPS]; - -class ExpressionStackEvaluating {}; -module.exports = class Expression { +const Exceptions = require('./exceptions.js'); +const ExpressionPacker = require('./expression_packer.js'); +const ExpressionClass = require('./expression_class.js'); +const ExpressionList = require('./expression_items/expression_list.js'); +const Debug = require('./debug.js'); +const Types = require('./types.js'); +// TODO: StackPos as class + +function assertExpressionItem(value, info) { + assert((value instanceof ExpressionList) === false); + return assertReturnInstanceOf(value, ExpressionItem, info); +} +class Expression extends ExpressionItem { // op (string) // operands (array) @@ -24,105 +37,122 @@ module.exports = class Expression { // value (bingint) // offset (number) - static parent; - // TODO: add all operations as if, - static operations = { - mul: { type: 'arith', label: '*', prec: 96, args: 2, handle: (a, b) => a * b, handleFr: (Fr, a, b) => Fr.mul(a, b)}, - add: { type: 'arith', label: '+', prec: 10, args: 2, handle: (a, b) => a + b, handleFr: (Fr, a, b) => Fr.add(a, b)}, - sub: { type: 'arith', label: '-', prec: 11, args: 2, handle: (a, b) => a - b, handleFr: (Fr, a, b) => Fr.sub(a, b)}, - pow: { type: 'arith', label: '**', prec: 98, args: 2, handle: (a, b) => a ** b, handleFr: (Fr, a, b) => Fr.pow(a, b)}, - neg: { type: 'arith', label: '-', prec: 102, args: 1, handle: (a) => -a, handleFr: (Fr, a) => Fr.neg(a, b)}, - div: { type: 'arith', label: '/', prec: 94, args: 2, handle: (a, b) => a / b}, - mod: { type: 'arith', label: '%', prec: 92, args: 1, handle: (a, b) => a % b}, - gt: { type: 'cmp', label: '>', prec: 76, args: 2, handle: (a, b) => (a > b ? 1n : 0n)}, - ge: { type: 'cmp', label: '>=', prec: 72, args: 2, handle: (a, b) => (a >= b ? 1n : 0n)}, - lt: { type: 'cmp', label: '<', prec: 78, args: 2, handle: (a, b) => (a < b ? 1n : 0n)}, - le: { type: 'cmp', label: '<=', prec: 74, args: 2, handle: (a, b) => (a <= b ? 1n : 0n)}, - eq: { type: 'cmp', label: '==', prec: 66, args: 2, handle: (a, b) => (a == b ? 1n : 0n)}, - ne: { type: 'cmp', label: '!=', prec: 64, args: 2, handle: (a, b) => (a != b ? 1n : 0n)}, - and: { type: 'logical', label: '&&', prec: 46, args: 2, handle: (a, b) => (a && b ? 1n : 0n)}, - or: { type: 'logical', label: '||', prec: 44, args: 2, handle: (a, b) => (a || b ? 1n : 0n)}, - shl: { type: 'bit', label: '<<', prec: 86, args: 2, handle: (a, b) => (a << b ? 1n : 0n)}, - shr: { type: 'bit', label: '>>', prec: 84, args: 2, handle: (a, b) => (a >> b ? 1n : 0n)}, - band: { type: 'bit', label: '&', prec: 58, args: 2, handle: (a, b) => (a & b ? 1n : 0n)}, - bor: { type: 'bit', label: '|', prec: 56, args: 2, handle: (a, b) => (a | b ? 1n : 0n)}, - bxor: { type: 'bit', label: '^', prec: 54, args: 2, handle: (a, b) => (a ^ b ? 1n : 0n)}, - not: { type: 'logical', label: '!', prec: 100, args: 1, handle: (a) => (a ? 0n : 1n)}, - } + static operatorsToMethodCache = {}; + static operators = ExpressionOperatorMethods; + static unitaryOperators = ExpressionOperationsInfo.getUnitaryOperations(); + static context; constructor () { + super(); this.stack = []; this.fixedRowAccess = false; } - - static setParent (parent) { - Expression.parent = parent; + static createFrom(object) { + const res = new Expression(); + res._set(object); + return res; } - - clone() { + get isExpression() { + return true; + } + cloneInstance() { let cloned = new Expression(); cloned.fixedRowAccess = this.fixedRowAccess; cloned.pushStack(this); return cloned; } + emptyClone() { + return new Expression(); + } pushStack(e) { - if (!(e instanceof Expression)) { - throw new Error(`pushStack parameter must be an Expression`); - } + assertLog(e instanceof Expression, {e, msg:'pushStack parameter must be an Expression'}); + const count = e.stack.length; for (let index = 0; index < count; ++index) { - this.stack.push(this.cloneDeep(e.stack[index], 'pushStack')); + let stackPos = e.stack[index]; + let clonedStackPos = this.cloneStackPos(stackPos); + this.stack.push(clonedStackPos); } return count; } - - cloneDeep(e, label = '') { - const res = cloneDeep(e); - return res; + cloneStackPos(stackPos) { + if (Debug.active) console.log(stackPos); + return { op: stackPos.op, + operands: stackPos.operands.map(operand => assertExpressionItem(operand.clone()))}; } - next(dnext) { - for (let stack of this.stack) { - for (let ope of stack.operands) { - switch (ope.type) { - case OP_VALUE: - case OP_STACK: - break; - case OP_ID_REF: - const pnext = Number(ope.next); - ope.next = ope.next ? pnext + Number(dnext) : Number(dnext); - break; - case OP_RUNTIME: - throw new Error(`Instance first do next operation`); - } - } - } + applyNext(value) { + this.stack.map(stack => stack.operands.map(operand => assertExpressionItem(operand.applyNext(value)))); } - insertStack(e, pos, options = {}) { - const delta = e.stack.length; - for (let index = pos; index < this.stack.length; ++index) { - for (const ope of this.stack[index].operands) { - if (ope.type === OP_STACK && (index - ope.offset) < pos) { - ope.offset += delta; + + insertStack(expressionToInsert, stackIndex) { + assert(expressionToInsert instanceof Expression); + const delta = expressionToInsert.stack.length; + + // + // Example1: Example2: + // Insert D on stackIndex = 0 Insert D on stackIndex = 1 + // + // | C | | | | C | + // | C | | B | | C | | B | + // | B | ----> | A | | B | ----> | D | + // | A | (D,0) | D | | A | (D,1) | A | + // └───┘ └───┘ └───┘ └───┘ + // + // + // length-1 ┌───────┐ ┐ + // │ │ │ moved-block (stackIndex, length - 1) + // ├───────┤ ┘ + // │ │ <--- expressionToInsert + // │ │ (delta positions) + // stackIndex |───────┤ ┐ + // │ │ │ non-moved-block (0 .. stackIndex - 1) + // 0 └───────┘ ┘ + // + + // All stack references use relative offsets (absolute = current_pos - offset). + // Loop over stack references of moved-block to update stack references that + // reference an non-moved-block element. This offset must be increased in delta + // positions (size of expression inserted) + + for (let index = stackIndex; index < this.stack.length; ++index) { + for (const operand of this.stack[index].operands) { + if (operand instanceof ExpressionItems.StackItem === false) continue; + const offset = operand.getOffset(); + if ((index - offset) < stackIndex) { + operand.setOffset(offset + delta); } } } - for (let index = this.stack.length - 1; index >= pos; --index) { + + // + // _ ┌───────┐ ┐ + // / │ B │ │ moved-block + // / ├───────┤ ┘ + // length-1 ┌───────┐ / │ │ + // │ B │ / │ │ + // stackIndex |───────┤ |───────┤ ┐ + // │ A │ ----- │ A │ │ non-moved-block + // 0 └───────┘ └───────┘ ┘ + // + + // moving B to leave space to insert expression + for (let index = this.stack.length - 1; index >= stackIndex; --index) { this.stack[index + delta] = this.stack[index]; } + + // clone and copy stack elements of expression to insert for (let index = 0; index < delta; ++index) { - this.stack[index + pos] = this.cloneDeep(e.stack[index]); + this.stack[index + stackIndex] = this.cloneStackPos(expressionToInsert.stack[index]); } - this.fixedRowAccess = this.fixedRowAccess || e.fixedRowAccess; + + // TO REVIEW + this.fixedRowAccess = this.fixedRowAccess || expressionToInsert.fixedRowAccess; return 1; } - cloneOperand(operator) { - return cloneDeep(operator); - } - cloneAlone() { - return this.cloneOperand(this.stack[0].operands[0]); + return assertExpressionItem(this.stack[0].operands[0].clone()); } isAlone () { @@ -130,109 +160,99 @@ module.exports = class Expression { } pushAloneIndex(index) { assert(this.isAlone()); - let operand = this.getAloneOperand(); - if (typeof operand.indexes === 'undefined') { - operand.indexes = []; - operand.__indexes = []; - operand.dim = 0; - } - operand.indexes.push(index); - operand.__indexes.push(index); - ++operand.dim; + let operand = this.getAloneOperand().pushArrayIndex(index); } popAloneIndex() { assert(this.isAlone()); - let operand = this.getAloneOperand(); - --operand.dim; - operand.indexes.pop(); - return operand.__indexes.pop(); + return this.getAloneOperand().popArrayIndex(index); } getAloneOperand () { return this.stack[0].operands[0]; } cloneAloneOperand () { - return cloneDeep(this.getAloneOperand()); + return this.getAloneOperand().clone(); } isReference () { // TODO: review if best place? - return (this.isAlone() && this.stack[0].operands[0].type === OP_RUNTIME && this.stack[0].operands[0].op === 'reference'); + // TODO: review if next/prior + // return (this.isAlone() && this.stack[0].operands[0].type === OP_RUNTIME && this.stack[0].operands[0].op === 'reference' ); + return (this.isAlone() && this.stack[0].operands[0] instanceof ExpressionItems.ReferenceItem); } - - // OP_VALUE (value) - // OP_ID_REF (id, refType, next) refType = [im,witness,fixed,prover,public,((expression))] At end need to calculate next of expression - // OP_STACK (offset) NOTE: absolute_index = current_index - offset; - // OP_RUNTIME (data) - _set (operand) { if (this.stack.length) { throw new Error(`Set only could be used with empty stack`); } - this.stack.push({op: false, operands: [cloneDeep(operand)]}); - } - - setIdReference (id, refType, next) { - assert(typeof refType === 'string'); - this._set({type: OP_ID_REF, id, refType, next}); - } - - setValue (value) { - if (typeof value === 'object') { - throw new Error(`object(${value.constructor.name}) as value not allowed`); - } - this._set({type: OP_VALUE, value}); + this.stack.push({op: false, operands: [assertExpressionItem(operand.clone())]}); } - - setRuntime (value) { - if (value.type) { - throw new Error(`setRuntime value has a not allowed type property`); - } - this._set({type: OP_RUNTIME, ...value}); - } - isRuntime () { return this.stack.some(st => this.isRuntimeStackPos(st)); } isRuntimeStackPos(st) { - return ((st.op !== false && NATIVE_OPS.indexOf(st.op) < 0) || st.operands.some(ope => this.isRuntimeOperand(ope))); - } - isRuntimeOperand(ope) { - return (ope.type === OP_RUNTIME); + return ((st.op !== false && NATIVE_OPS.indexOf(st.op) < 0) || st.operands.some(operand => operand instanceof ExpressionItems.RuntimeItem)); } - insertOne (op, b) { + insertOne (op, b = false) { + if (Debug.active) console.log(`\x1B[44m======================== INSERT ONE (${op}) =================================\x1B[0m`); + if (Debug.active) console.log(util.inspect(b, false, null, true)); + assert(b === false || b instanceof Expression); const aIsEmpty = this.stack.length === 0; - const bIsEmpty = b.stack.length === 0; + const bIsEmpty = b === false || b.stack.length === 0; - if (bIsEmpty) { + if (bIsEmpty && Expression.unitaryOperators.includes(op) === false ) { throw new Error(`insert without operands`); } const aIsAlone = this.isAlone(); - const bIsAlone = b.isAlone(); + const bIsAlone = b === false || b.isAlone(); if (bIsAlone) { // aIsAlone => !aIsEmpty if (aIsAlone) { this.stack[0].op = op; - this.stack[0].operands.push(b.cloneAlone()); + // if b is false => unary operand, no second operand to add + if (b !== false) { + this.stack[0].operands.push(b.cloneAlone()); + } return this; } - let operandA = aIsEmpty ? [] : [{type: OP_STACK, offset: 1}]; - this.stack.push({op, operands: [...operandA, b.cloneAlone()]}); + // let operandA = aIsEmpty ? [] : [{type: OP_STACK, offset: 1}]; + // this.stack.push({op, operands: [...operandA, b.cloneAlone()]}); + let operandA = aIsEmpty ? [] : [new ExpressionItems.StackItem(1)]; + + const stackPos = {op, operands: operandA}; + // if b is false => unary operand, no second operand to add + if (b !== false) { + stackPos.operands.push(b.cloneAlone()); + } + this.stack.push(stackPos); return this; } // !aIsAlone (aIsEmpty?) && !bIsAlone const count = this.pushStack(b); if (aIsEmpty) { - this.stack.push({op, operands: [{type: OP_STACK, offset: 1}]}); + this.stack.push({op, operands: [new ExpressionItems.StackItem(1)]}); return this; } - this.stack.push({op, operands: [{type: OP_STACK, offset: count + 1}, {type: OP_STACK, offset: 1}]}); + this.stack.push({op, operands: [new ExpressionItems.StackItem(count + 1), new ExpressionItems.StackItem(1)]}); return this; } - insert (op, ...bs) { + insert (op, bs) { + if (Debug.active) console.log(`\x1B[41m======================== INSERT (${op}) =================================\x1B[0m`); + if (Debug.active) this.dump(); + if (Debug.active) console.log(util.inspect(bs, false, null, true)); + if (!Array.isArray(bs)) { + const res = this.insertOne(op, bs); + if (Debug.active) res.dump(); + return res; + } if (bs.length === 1) { - return this.insertOne(op, bs[0]); + const res = this.insertOne(op, bs[0]); + if (Debug.active) res.dump(); + return res; } + // verify that all bs are expressions + assert(bs.reduce((isExpression, b) => isExpression && b instanceof Expression, true)); + + const anyEmptyB = bs.some((b) => b.stack.length === 0); const aIsEmpty = this.stack.length === 0; @@ -263,158 +283,35 @@ module.exports = class Expression { } if (!aIsEmpty) { - elem = {op, operands: [{type: OP_STACK, offset: counts[0]}]}; + elem = {op, operands: [new ExpressionItems.StackItem(counts[0])]}; } let index = 0; for (const b of bs) { - elem.operands.push(b.isAlone() ? b.cloneAlone() : {type: OP_STACK, offset: counts[++index]}); + elem.operands.push(b.isAlone() ? b.cloneAlone() : new ExpressionItems.StackItem(counts[++index])); } this.stack.push(elem); return this; } evaluateAloneReference() { + if (Debug.active) this.dump(); assert(this.isAlone()); let operand = this.getAloneOperand(); - if (operand.type === OP_RUNTIME || operand.op === 'reference') { - const res = this.evaluateRuntime(operand, true); - if (!(res instanceof Expression)) { - operand.__value = res; - } - } - return operand.__value; - } - evaluateOperandValue(ope, pos, deeply, instance = false) { - if (deeply) { - if (ope.type === OP_STACK) { - const stackPos = pos-ope.offset; - this.evaluateStackPosValue(stackPos); // TODO: cache and infinite-loops - ope.__value = this.stack[stackPos].__value; - } - } else if (ope.type === OP_VALUE ) { - ope.__value = ope.value; - - } else if (ope.type === OP_ID_REF ) { - ope.__value = new NonRuntimeEvaluable(); - - } else if (ope.type === OP_RUNTIME ) { - let res = this.evaluateRuntime(ope, deeply); - // BUG: if type was an expression not apply value !! - // if (!(res instanceof Expression)) { - if (instance) { - if (res instanceof Expression && res.isAlone()) { - res = res.getAloneOperand(); - } - if (res instanceof Expression) { - ope.__value = res; - } else { - assert(!(res instanceof Expression)); - Object.keys(ope).forEach(key => delete ope[key]); - if (typeof res === 'bigint') { - ope.type = OP_VALUE; - ope.value = res; - } else { - // assert(NATIVE_REFS.includes(res.type)); - assert(NATIVE_REFS.includes(res.refType)); - ope.type = OP_ID_REF; - ope.refType = res.refType; - ope.id = res.id; - if (res.next) ope.next = res.next; - assert(typeof ope.id === 'number'); - } - delete ope.op; - } - } else { - ope.__value = res; + if (operand instanceof ExpressionItems.RuntimeItem || operand instanceof ExpressionItems.ReferenceItem) { + if (Debug.active) console.log(operand); + const res = operand.eval(); + if (Debug.active) { + console.log(res); + console.log(operand.toString()); + console.log(this.toString()); } + return res; } - } - assertInstanced() { - try { - for (let ist = 0; ist < this.stack.length; ++ist) { - const st = this.stack[ist]; - assert(VALID_NATIVE_OPS.includes(st.op), `invalid operation ${st.op} on stackpos ${ist}`); - for (let iope = 0; iope < st.operands.length; ++iope) { - const ope = st.operands[iope]; - const ref = `operand #${iope} of stackpos ${ist}`; - assert([OP_STACK, OP_VALUE, OP_ID_REF].includes(ope.type), `${ref} has invalid type ${ope.type}`); - switch (ope.type) { - case OP_STACK: - assert(typeof ope.offset === 'number', `invalid offset type (${typeof ope.offset}) on ${ref}`); - assert(ope.offset > 0, `invalid offset value (${ope.offset}) on ${ref}`); - break; - - case OP_VALUE: - assert(typeof ope.value === 'bigint', `invalid value type (${typeof ope.offset}) on ${ref}`); - break; - - case OP_ID_REF: - assert(NATIVE_REFS.includes(ope.refType), `invalid refType (${ope.refType}) on ${ref}`) - assert(typeof ope.id === 'number', `invalid ope.id type (${typeof ope.id}) on ${ref}`); - break; - - } - if (ope.indexes) { - const indexesType = typeof ope.indexes; - assert(indexesType === 'array', `${ref} has invalid indexes type ${indexesType}`); - for (let index = 0; index < ope.indexes.length; ++index) { - const indexType = typeof ope.indexes[index]; - assert(indexType === 'number', `${ref} has invalid index[${index}] type ${indexType}`); - } - } - } - } - } catch (e) { - this.dump(); - throw e; - } + return operand; } evaluateRuntime(op, deeply = false) { - let res = Expression.parent.evalRuntime(op, this, deeply); + let res = Context.expressions.evalRuntime(op, this, deeply); return res; } - instanceValues() { - for (let se of this.stack) { - for (let index = 0; index < se.operands.length; ++index) { - if (se.operands[index].type !== OP_RUNTIME) continue; - const value = se.operands[index].__value; - if (typeof value === 'bigint') { - se.operands[index] = {type: OP_VALUE, value: value}; - continue; - } - if (typeof value === 'object' && value.type && - ['constant','witness', 'fixed', 'im', 'public', 'expr', 'challenge','subproofvalue', 'proofvalue'].includes(value.type)) { - let ope = {}; - if (value.array) { - // incomplete reference, is a subarray. - ope.type = OP_RUNTIME; - ope.array = value.array; - ope.op = 'idref'; - } else { - ope.type = OP_ID_REF; - ope.array = false; - } - if (typeof value.value === 'undefined' || value.value === null) { - ope.id = value.id; - } else { - ope.id = typeof value.value === 'object' ? value.value.id : value.value; - } - assert(typeof value.type === 'string'); - ope.refType = value.type; - if (value.next) ope.next = value.next; - if (value.prior) ope.next = value.prior; - if (typeof value.row !== 'undefined') { - ope.row = value.row; - } - se.operands[index] = ope; - continue; - } - console.log(value); - console.log(se.operands[index]); -// value.dump(); - throw new Error('Invalid value'); - } - } - } getReference() { if (!this.isAlone()) { throw new Error(`Invalid expression by reference`); @@ -426,141 +323,435 @@ module.exports = class Expression { this.evaluateIndexes(dope); return dope; } - instance(options = {}) { - let dup = this.clone(); - dup.evaluateOperands(false, true); - dup.evaluateOperands(true, true); - dup.instanceExpressions(); - const top = dup.stack.length-1; - dup.evaluateStackPosValue(top, true); - dup.instanceValues(); - if (options.simplify) { - dup.simplify(); - dup.assertInstanced(); - } - return dup; - } - eval(deeply = false) { + isArray() { + // only a reference could be and array. + if (!this.isReference() || this.stack[0].operands[0].rowOffset) return false; + + let ref = this.getReference(); + if (Debug.active) console.log(ref); + EXIT_HERE; + + } + // stackResults[pos][0] contains result of this stack position, + // in stackResults[pos][1] contains a results array of this stack position operands + instance(options) { + assert(this.stack.length > 0); + if (Debug.active) { + console.log(Context.sourceRef); + this.dump("#############"); + } + let cloned = this.clone(); + options = {...options, instance: true} + let stackResults = options.stackResults ?? cloned.evaluateOperands(options); + // cloned.extendExpressions(options); + cloned.evaluateFullStack(stackResults, options); + if (Debug.active) cloned.dump('PRE-SIMPLIFY'); + cloned.simplify(); + if (Debug.active) cloned.dump('POST-SIMPLIFY'); + if (options.unroll) { + return cloned.unroll(); + } + if (options.unpackItem && cloned.isAlone()) { + const operand = cloned.getAloneOperand(); + if (operand instanceof ExpressionItem) { + return operand; + } + } + // console.log(stackResults); + // cloned.dumpStackResults(stackResults, ''); + return cloned; + } + isInstanceOf(cls) { + if (!this.isAlone()) return false; + + const operand = this.getAloneOperand(); + return (operand instanceof cls); + } + unroll(options) { + if (!this.isAlone()) return this; + + const operand = this.getAloneOperand(); + if (operand instanceof ExpressionItems.ArrayOf === false) return this; + + return operand.toArrays(); + } + evalAsValue(options) { + let res = this.eval(options); + if (res.isAlone()) { + res = res.getAloneOperand(); + } + return (res instanceof ExpressionItems.ValueItem || res instanceof ExpressionItems.StringValue) ? res : ExpressionItems.NonRuntimeEvaluableItem.get(); + } + eval(options = {}) { + assert(this.stack.length > 0); + return this.instance(options); +/* console.trace('EVAL '+this.toString()); if (this.stack.length === 0) { return this; } - if (this.stack[0].op === false) { - delete this.stack[0].operands[0].__value; + let stackResults = this.evaluateOperands(options); + this.evaluateFullStack(stackResults, options); + const res = stackResults[this.stack.length-1][0]; + if (!options.onlyAsValue && res instanceof ExpressionItems.NonRuntimeEvaluableItem) { + return this.instance({...options, stackResults}); } - this.evaluateOperands(deeply); - this.evaluateStackPosValue(this.stack.length-1); - return this.stack[this.stack.length-1].__value ?? this; + return res;*/ } - evaluateStackPosValue(pos, instance = false) { - const st = this.stack[pos]; - - this.evaluateStackPosOperands(pos, true, instance); + stackResultsToString(stackResults) { + return stackResults.map((x, index) => `#${index} ${x[0] ?? 'null'} ${x[1].map(o => o ? o.toString() : o).join(',')}`).reverse().join('\n'); + } + evaluateFullStack(stackResults, options) { + assert(this.stack.length > 0); + const evaluateId = Date.now(); + if (Debug.active) { + this.dump(`evaluateFullStack #${evaluateId} BEGIN`); + console.log("\n", this.stackResultsToString(stackResults)); + } + // console.log(util.inspect(stackResults, false, null, true)); + this.evaluateStackPos(stackResults, this.stack.length - 1, {...options, evaluateId}); + if (Debug.active) this.dump(`evaluateFullStack #${evaluateId} END`); + } + evaluateStackPos(stackResults, stackIndex, options = {}) { + assert(stackIndex < this.stack.length); + const st = this.stack[stackIndex]; + const results = stackResults[stackIndex]; + const _debugLabel = `#${options.evaluateId ?? 0} S${stackIndex}(${st.op})`; + + // if stackResult is evaluated return value; + if (results[0] !== null) { + if (Debug.active) console.log(`evaluateStackPos ${_debugLabel}`, results[0]); + return results[0]; + } + + let values = results[1].slice(0, st.operands.length); + for (let operandIndex = 0; operandIndex < st.operands.length; ++operandIndex) { + const _operandDebugLabel = `${_debugLabel} ${operandIndex}]`; + const operand = st.operands[operandIndex]; + assertLog(operand instanceof ExpressionItem, [st.op, st.operands.length, operand]); + const resultAvailable = (values[operandIndex] ?? null) != null; + if (resultAvailable) { + if (Debug.active) console.log(`evaluateStackPos ${_operandDebugLabel} ${values[operandIndex]}`) + continue; + } - delete st.__value; - const res = this.calculate(st); - if (res !== null) { - st.__value = res; + if (operand instanceof ExpressionItems.StackItem) { + values[operandIndex] = this.evaluateStackPos(stackResults, stackIndex - operand.getOffset()); + if (Debug.active) console.log(`evaluateStackPos STACK ${_operandDebugLabel} ${values[operandIndex]} ${stackIndex - operand.getOffset()}`, stackResults); + } else { + values[operandIndex] = operand.eval(options); + if (Debug.active) console.log(`evaluateStackPos NO-STACK ${_operandDebugLabel} ${values[operandIndex]}`, operand); + } + } + let value = null; + if (values.some(value => value instanceof ExpressionItems.NonRuntimeEvaluableItem)) { + value = ExpressionItems.NonRuntimeEvaluableItem.get(); + } else if (values.some(value => value === null)) { + value = null; + this.dump('value=null '+Context.sourceRef); + EXIT_HERE; + } else if (st.op === false) { + value = values[0]; + } else if (values.some(value => value.isRuntimeEvaluable() === false)) { + value = ExpressionItems.NonRuntimeEvaluableItem.get(); + } else { + value = this.applyOperation(st.op, values); + if (Debug.active) { + console.log(`evaluateStackPos/applyOperation ${_debugLabel} `); + console.log(util.inspect(values, false, null, true)); + console.log(util.inspect(value, false, null, true)); + } + if (options.instance) { + st.op = false; + st.operands = [value]; + if (Debug.active) console.log('ST.OPERANDS=[', value); + } } + return (results[0] = value); } - calculate(st) { - if (st.op === false) { - return st.operands[0].__value; + /** + * get method name used to calculate an operation between types. + * @param {string} operation - operation to apply on operators + * @param {string[]|false} types - types of operators + * */ + operatorToMethod(operation, types = false) { + const key = 'operator_' + operation + (types === false ? '' : '_' +types.slice(1).join('_')); + let method = Expression.operatorsToMethodCache[key]; + if (!method) { + method = key.replace(/(\_\w)/g, x => x[1].toUpperCase()); + Expression.operatorsToMethodCache[key] = method; + } + return method; + } + /** + * apply operation over operands values + * @param {string} operation - operation to apply on operators + * @param {string[]|false} values - array of ExpressionItems + * */ + applyOperation(operation, values) { + if (Debug.active) console.log([operation, ...values]); + const operationInfo = ExpressionOperationsInfo.get(operation); + + if (operationInfo === false) { + console.log(values); + throw new Error(`Operation ${operation} not was defined`); } - if (st.operands.some(x => (typeof x === 'object' && x.type !== OP_VALUE && typeof x.__value !== 'bigint'))) { - return null; + if (operationInfo.args !== values.length) { + throw new Error(`Invalid number of arguments on operation ${operation}, received ${values.length} values but was expected ${operationInfo.args}`); } - const opfunc = Expression.operations[st.op] ?? false; - if (opfunc === false) { - throw new Error(`NOT FOUND OPERATION (${st.op})`); + // assert all values must be an ExpressionItem + values.map(value => assertLog(value instanceof ExpressionItem, value)); + + let types = values.map(x => x.constructor.name); + + // if number of values was less than 2 (means 1, always was equals) + const equals = values.length < 2 ? true : types.every(x => x === types[0]); + let reversed = false; + let methods = []; + const onlyOneLoop = equals || !operationInfo.commutative || operationInfo.args != 2; + + // In this block try to found and operator method using types without transformations. + // First search on class of first operand, if not found search on class of second operand (*) + // (*) only if two operands and operation is commutative + + while (true) { + const method = this.operatorToMethod(operation, (equals ? false : types)); + methods.push(`${types[0]}.${method}`); + const [executed, result] = this.applyOperatorMethod(method, values); + if (executed) { + return result; + } + if (onlyOneLoop) { + break; + } + // onlyOneLoop === false => two loops, on second loop applies reverse again to + // restore original values and types, also restore value of reversed + values = values.reverse(); + types = types.reverse(); + reversed = !reversed; + if (reversed == false) { + break; + } } - const values = st.operands.map(x => x.type === 0 ? x.value : x.__value); - try { - return opfunc.handle.apply(this, values); - } catch (e) { - console.log([{op: st.op},...values]); - throw e; + // If not equals, in this block try to cast second operand to class of first operand, after that + // First search on class of first operand, if not found, try to cast first operand to class of second + // operand and search on class of second operand (*) + // (*) only if two operands and operation is commutative + let iarg = 0; + while (!equals && operationInfo.args == 2 && iarg < operationInfo.args) { + const casting = this.castingItemMethod(types[iarg]); + methods.push(casting); + const icasting = iarg ? 0:1; + if (typeof values[icasting][casting] === 'function') { + const method = this.operatorToMethod(operation); + methods.push(`> ${types[iarg]}.${method}`); + try { + const [executed, result] = this.applyOperatorMethod(method, values.map((x, index) => index === icasting ? x[casting](): x)); + if (executed) { + return result; + } + } + catch (e) { + if (e instanceof Exceptions.CannotBeCastToType === false) { + throw e; + } + } + } + ++iarg; } + + throw new Error(`Operation ${operation} not was defined by types ${types.join(',')} [${methods.join(', ')}]`); } - isRuntimeCalculable(e) { - const te = typeof e; - if (te === 'string' || te === 'number' || te === 'bigint' /* || te === 'fe' */) { - return true; + castingItemMethod(type) { + if (type === 'StringValue' || type === 'IntValue') { + type = type.slice(0, -5); } - if (te === 'object' && e.type) { - if (e.type === 'witness' && e.type === 'fixed') return false; + return 'as'+type+'Item'; + } + applyOperatorMethod (method, values) { + if (Debug.active) console.log(`########### (${values[0].constructor.name}) METHOD ${method} ###########`); + if (typeof values[0][method] === 'function') { + // instance call, first value (operand) is "this", arguments rest of values (operands) + return [true, values[0][method](...values.slice(1))]; + } else if (values[0].constructor.operators && typeof values[0].constructor.operators[method] === 'function') { + // static call with all values (operands) + return [true, values[0].constructor.operators[method](...values)]; + } + return [false, false]; + } + evaluateValue(value, options) { + if (Debug.active) console.log(value); + if (typeof value === 'undefined') { + return options ? options.default ?? 0n : 0n; + } + // stack references not replaced + // expression references not extended (inserted) + /* console.log([typeof value, value]); + if (value instanceof Expression) { + value.dump(); + }*/ + assert(value instanceof ExpressionItems.ExpressionItem); + if (value instanceof ExpressionItems.StackItem) { + return value; + } else if (value instanceof ExpressionItems.ValueItem) { + return value; + } else if (value instanceof ExpressionItems.ProofItem) { + return ExpressionItems.NonRuntimeEvaluableItem.get(); + } else if (value instanceof ExpressionItems.ReferenceItem) { + const res = Context.runtime.eval(value, {}); + return res; + } else if (value instanceof ExpressionItems.FunctionCall) { + const res = value.eval(); + return res; + } else { + console.log(value); + return value; + EXIT_HERE; } + return value; } - // this method instance the expression references to include them inside - // TODO: view how these affects to optimization. - instanceExpressions(options = {}) { - let pos = 0; - const isAlone = this.isAlone(); - while (pos < this.stack.length) { - let nextPos = true; - for (let ope of this.stack[pos].operands) { - if (ope.type !== OP_RUNTIME) continue; - if (ope.__value instanceof Expression) { - ope.type = OP_STACK; - const exprToInsert = ope.__value.instance(); - const next = typeof ope.next === 'number' ? ope.next : ope.__next; - if (next) exprToInsert.next(next); - if (isAlone) { - this.stack.pop(); - } - - const stackOffset = this.insertStack(exprToInsert, pos, options); - if (!isAlone) { - ope.offset = stackOffset; - } - nextPos = false; - break; + evaluateValues(values, options) { + // do array of evaluates, for example to evaluate + // indexes o call arguments, this method call n times + // evaluations + if (typeof values === 'undefined') { + return 0; + } + assert (Array.isArray(values)); + let result = []; + for (const value of values) { + result.push(this.evaluateValue(value, options)); + } + return result; + } + evalAsInt(options = {}) { + let value = this.evalAsValue(options); + if (value instanceof ExpressionItems.NonRuntimeEvaluableItem) { + debugger; + value = this.evalAsValue(options); + } + if (Debug.active) { + console.log(value); + console.log(this.dump()); + } + const res = value.asIntDefault(false); + if (res === false) { + console.log(value); + throw new Error(this.toString() + " isn't a number"); + } + return res; + } + evalAsBool(options = {}) { + return this.evalAsInt(options) ? true : false; + } + evalAsItem(options) { + const res = this.eval(options); + return res.isAlone() ? res.cloneAloneOperand() : res; + } + getArrayResult(results, indexes, options) { + if (Debug.active) { + console.log(results); + console.log(indexes); + } + // TODO + return results; + // this method take one of results using indexes + } + evaluateOperands(options) { + // evaluation must be from left to right (l2r) operands, inside operand + // also evaluation is l2r: prior, value, arguments (l2r), indexes (l2r) + // at end of this operand evaluation, must manage increment/decrement + // options. + + // stackResults is used to store operand evaluations needed by full stack + // evaluation. + + let stackResults = []; + for (let stpos = 0; stpos < this.stack.length; ++stpos) { + let results = [null, []]; + const st = this.stack[stpos]; + stackResults.push(results); + let operandResults = results[1]; + // console.log(st.operands); + for (let operandIndex = 0; operandIndex < st.operands.length; ++operandIndex) { + const operand = assertExpressionItem(st.operands[operandIndex]); + + // when evaluates single operands, StackItem is a reference to stack position + // and it could be evaluated when all operands are left-to-right evaluated + if (operand instanceof ExpressionItems.StackItem) { + operandResults.push(null); + continue; } - if (typeof ope.__value !== 'undefined' && !(ope.__value instanceof NonRuntimeEvaluable)) continue; - - // TODO: twice evaluations, be carefull double increment evaluations,etc.. - const res = this.evaluateRuntime(ope); - if (res instanceof Expression) { - ope.type = OP_STACK; - const exprToInsert = res.instance(); - const next = typeof ope.next === 'number' ? ope.next : ope.__next; - if (next) exprToInsert.next(next); - delete this.stack[0]; - if (isAlone) { - this.stack.pop(); - } - const stackOffset = this.insertStack(exprToInsert, pos, options); - if (!isAlone) { - ope.offset = stackOffset; + // console.log(`CALL OPERAND ${stpos}/${this.stack.length} ${operandIndex}/${st.operands.length} ${operand}`); + + // optimization to get stackResults, to avoid calculate two times when + // insert into stack the expression (1) + const result = operand.eval(options); + operandResults.push(result); + if (options.instance && result !== null) { + if (Debug.active) this.dump(`AAAA.IN stpos:${stpos}`); + if (result instanceof Expression) { + // insert expression below current position + this.insertStack(result, stpos); + st.operands[operandIndex] = new ExpressionItems.StackItem(1); + + // evaluate result, optimization (1), and after insert it + const stackResultToInsert = result.evaluateOperands(options); + stackResults.unshift(...stackResultToInsert); + + // at this moment position was increased because some elements + // are added on below positions. + stpos += result.stack.length; + if (Debug.active) this.dump('AAAA.OUT1'); + } else { + st.operands[operandIndex] = assertExpressionItem(result); + if (Debug.active) this.dump('AAAA.OUT2'); } - nextPos = false; - break; } } - if (nextPos) ++pos; + } + if (Debug.active) { + console.log("\n", this.stackResultsToString(stackResults)); + } + return stackResults; + } + _calculate(st, pos, stackResults) { + if (st.op === false) { + return stackResults[pos][0]; + } + + if (stackResults[pos][1].some(x => !(x instanceof ExpressionItems.IntValue))) { + return ExpressionItem.NonRuntimeEvaluableItem.get(); + } + + stackResults[pos][0] = this.applyOperation(st.op, stackResults[pos][1]); + return stackResults[pos][0]; + } + isRuntimeCalculable(e) { + const te = typeof e; + if (te === 'string' || te === 'number' || te === 'bigint' /* || te === 'fe' */) { + return true; + } + if (te === 'object' && e.type) { + if (e.type === 'witness' && e.type === 'fixed') return false; } } simplify() { let loop = 0; while (this.stack.length > 0) { let updated = false; + if (Debug.active) this.dump('PRE-SIMPLIFY-OPERATION'); for (const st of this.stack) { updated = this.simplifyOperation(st) || updated; } + if (Debug.active) this.dump('POST-SIMPLIFY-OPERATION'); this.compactStack(); + if (Debug.active) this.dump('POST-COMPACT'); if (!updated) break; } } - simplifyRuntimeToValue(st) { - for (let index = 0; index < st.operands.length; ++index) { - const value = st.operands[index].__value; - if (['string', 'number', 'bigint'].includes(value)) { - st.operands[index] = {type: OP_VALUE, value}; - } - } - } // this method simplify trivial operations as 0 + x or 1 * x, also // simplify operations between values, not only direct values also @@ -571,29 +762,26 @@ module.exports = class Expression { return false; } - this.simplifyRuntimeToValue(st); - const firstValue = st.operands[0].type === OP_VALUE ? st.operands[0].value : false; - const secondValue = (st.operands.length > 1 && st.operands[1].type === OP_VALUE) ? st.operands[1].value : false; + // this.simplifyRuntimeToValue(st); + const firstValue = st.operands[0] instanceof ExpressionItems.ValueItem ? st.operands[0].getValue() : false; + const secondValue = (st.operands.length > 1 && st.operands[1] instanceof ExpressionItems.ValueItem) ? st.operands[1].getValue() : false; // [op,v1,v2] ==> [v1 op v2] if (firstValue !== false && secondValue !== false) { - assert(!firstValue || (!firstValue.next && !firstValue.__next)); - assert(!secondValue || (!secondValue.next && !secondValue.__next)); - const res = this.calculate(st); - if (res === null) return false; - st.operands = [{type: OP_VALUE, value: res}]; + assert(!firstValue || !firstValue.rowOffset); + assert(!secondValue || !secondValue.rowOffset); + const res = this.applyOperation(st.op, st.operands); + st.operands = [assertExpressionItem(res)]; st.op = false; - delete st.__value; - delete st.__indexes; - delete st.__next; return true; } // [neg,value] ==> [false,-value] if (st.op === 'neg' && firstValue !== false) { - assert(!firstValue.next && !firstValue.__next); + assert(!firstValue.rowOffset); st.op = false; - st.operands[0].value = -st.operands[0].value; + st.operands[0].setValue(-st.operands[0].getValue()); + assert(st.operands[0] instanceof ExpressionItem); return true; } @@ -604,6 +792,8 @@ module.exports = class Expression { // [mul, x, 0] ==> [0] if (st.op === 'mul') { st.op = false; + // firstZero => st.operands[0] = 0 + // !firstZero => second = 0 ==> st.operands[1] = 0 st.operands = [st.operands[firstZero ? 0:1]]; return true; } @@ -632,6 +822,12 @@ module.exports = class Expression { return true; } + if (st.op === 'sub' && secondValue !== false && secondValue < 0n) { + st.op = 'add'; + st.operands[1] = new ExpressionItems.IntValue(-secondValue); + return true; + } + // TODO: be carrefull with next, prior, inc, dec // x - x = 0 ??? // (x - (- y)) = x + y @@ -654,53 +850,67 @@ module.exports = class Expression { // this method compact stack positions with one element where operation // was false, replace reference of this stack operation by directly value compactStack() { - let translate = []; - let stackPos = 0; + let translationTable = []; + let newStackIndex = 0; let stackLen = this.stack.length; + // if (Debug.active) this.dump('PRE-COMPACTSTACK'); for (let istack = 0; istack < stackLen; ++istack) { const st = this.stack[istack]; if (st.op === false) { const ope = st.operands[0]; - // two situations, for alone stack reference, use its reference and it must - // be purged - translate[istack] = ope.type === OP_STACK ? [true, translate[istack - ope.offset][1]] : [true, istack]; + // two situations for alone: + // 1 - stack reference, use its reference and purge + // 2 - single operand, use index and purge + translationTable[istack] = ope instanceof ExpressionItems.StackItem ? { purge: true, newAbsPos: translationTable[ope.getAbsolutePos(istack)].newAbsPos} : + { purge: true, newAbsPos: istack }; continue; } - translate[istack] = [false, stackPos++]; + translationTable[istack] = { purge: false, newAbsPos: newStackIndex++ }; // foreach operand if it's a stack reference, must be replaced by // new reference or by copy of reference if it was alone (no operation) for (let iope = 0; iope < st.operands.length; ++iope) { - if (st.operands[iope].type !== OP_STACK) continue; - const absolutePos = istack - st.operands[iope].offset; - const [purge, newAbsolutePos] = translate[absolutePos]; + if ((st.operands[iope] instanceof ExpressionItems.StackItem) === false) continue; + const absolutePos = st.operands[iope].getAbsolutePos(istack); + const translation = translationTable[absolutePos]; + if (Debug.active) console.log({istack, absolutePos, iope, translation}); assert(absolutePos < istack); - if (purge && this.stack[newAbsolutePos].op === false) { + if (translation.purge && this.stack[absolutePos].op === false) { // if purge and referenced position was alone, it is copied (duplicated) - this.stack[istack].operands[iope] = cloneDeep(this.stack[newAbsolutePos].operands[0]); + if (Debug.active) this.dump('XXXX'); + this.stack[istack].operands[iope] = assertExpressionItem(this.stack[absolutePos].operands[0].clone()); + if (Debug.active) this.dump('YYYY'); } else { - // stackPos - 1 is new really istack after clear simplified stack positions + // newStackIndex - 1 is new really istack after clear simplified stack positions // calculate relative position (offset) - const newOffset = (stackPos - 1) - newAbsolutePos; + const newOffset = (newStackIndex - 1) - translation.newAbsPos; assert(newOffset > 0); - this.stack[istack].operands[iope].offset = newOffset; + this.stack[istack].operands[iope].setOffset(newOffset); } } } + // special case if top of stack is alone operator, it means + // that this is the result of expression. + const topStack = this.stack[stackLen - 1]; + if (topStack.op === false && (topStack.operands[0] instanceof ExpressionItems.StackItem) === false) { + this.stack = [this.stack[stackLen - 1]]; + return true; + } + if (Debug.active) console.log(translationTable); // DEBUG: - // translate.forEach((value, index) => console.log(`#${index} => ${value}`)); + // translationTable.forEach((value, index) => console.log(`#${index} => ${value}`)); // move stackpositions to definitive positions, from end to begin to avoid // overwriting, updating last position used to remove rest of stack positions let lastPosUsed = false; for (let istack = 0; istack < stackLen; ++istack) { - const [purge, absoluteNewPos] = translate[istack]; - if (purge) continue; + const translation = translationTable[istack]; + if (translation.purge) continue; - this.stack[absoluteNewPos] = this.stack[istack]; - lastPosUsed = absoluteNewPos; + this.stack[translation.newAbsPos] = this.stack[istack]; + lastPosUsed = translation.newAbsPos; } if (lastPosUsed !== false) { this.stack.splice(lastPosUsed + 1); @@ -712,310 +922,192 @@ module.exports = class Expression { // return if expression was updated return stackLen > this.stack.length; } - evaluateOperands(deeply = false, instance = false) { - for (let index = 0; index < this.stack.length; ++index) { - this.evaluateStackPosOperands(index, deeply, instance); - } - } - evaluateStackPosOperands(pos, deeply, instance = false) { - for (let ope of this.stack[pos].operands) { - this.evaluateOperand(ope, pos, deeply, instance); - } - } - evaluateOperand(ope, pos, deeply, instance = false) { - if (!deeply) { - this.clearNext(ope); - this.evaluatePrior(ope); - this.evaluateIndexes(ope); - this.evaluateNext(ope); - // TODO: for optimizations - if (instance) { - // indexes not exists when instanced !!! - ope.next = ope.__next; - delete ope.__next; - } - } - this.evaluateOperandValue(ope, pos, deeply, instance); - if (instance) { - delete ope.indexes; - delete ope._indexes; + getCaller(stackLevels = 4) { + let caller = ''; + try { + throw new Error(); + } catch (e) { + caller = e.stack.split('\n')[stackLevels].trim().substring(3); } + return caller; } - - clearNext(ope) { - ope.__next = 0; - } - evaluatePrior(ope) { - if (typeof ope.prior === 'undefined') { - return 0; - } - ope.__next = -this.evaluateContent(ope.prior); - return ope.__next; + static dumpScope = null; + dump(title) { + const previousDumpScope = Expression.dumpScope; + Expression.dumpScope = Expression.dumpScope === null ? '' : Expression.dumpScope + ' '; + const res = this.dumpStack(`DUMP (${title ?? ''})`, this.stack); + Expression.dumpScope = previousDumpScope; + return res; } - - evaluateIndexes(ope) { - if (typeof ope.indexes === 'undefined') { - return []; - } - ope.__indexes = []; - for (let index of ope.indexes) { - ope.__indexes.push(this.evaluateContent(index)); - } - return ope.__indexes; + dumpItem(options) { + return 'Expression('+this.toString(options)+')'; } - - evaluateNext(ope) { - if (typeof ope.next === 'undefined') { - return 0; - } - const nextValue = this.evaluateContent(ope.next); - if (nextValue && ope.__next !== 0) { - // it isn't possible by grammar - throw new Error(`next and prior are incompatible between them`); - } - if (nextValue) { - ope.__next = nextValue; - } - return ope.__next; + dumpStackResults(stackResults, title = '') { + return this.dumpStack(`STACK RESULTS (${title ?? ''})`, stackResults, {stackProperty: 0, operandsProperty: 1}); } - - evaluateContent(e) { - if (typeof e === 'bigint' || typeof e === 'number' || typeof e == 'string' || typeof e == 'boolean') { - return e; - } - if (e.op == 'reference') { - return this.evaluateReference(e); - } - if (e instanceof Expression) { - return e.eval(); + dumpStack(title, stack, options = {} ) { + title = title + ' ' + this.getCaller(); + console.log((Expression.dumpScope ?? '') + `\x1B[38;5;214m|==========> ${title} <==========|\x1B[0m`); + for (let index = stack.length-1; index >=0; --index) { + this.dumpStackPos(stack[index], index, options); } - console.log(e); - EXIT_HERE; } - - evaluateReference(e) { - return Expression.parent.evaluateReference(e); + dumpStackPos(stackPos, index = false, options = {}) { + const stackProperty = options.stackProperty ?? 'op'; + const operandsProperty = options.operandsProperty ?? 'operands'; + const stackValue = stackPos[stackProperty]; + const operationInfo = (stackValue && typeof stackValue.dump === 'function') ? stackValue.dump() : stackValue; + let info = (Expression.dumpScope ?? '') + `\x1B[38;5;214m#${index === false?'':index} ${stackValue}`; + for (const operand of stackPos[operandsProperty]) { + const operandInfo = this.dumpOperand(operand, index, options); + info = info + ' [\x1B[38;5;76m' + operandInfo +'\x1B[38;5;214m]'; + } + console.log(info+'\x1B[0m'); } -/* evaluateRuntime(e) { - // function_call op:'call' function: arguments: - // positional_param op:'positional_param' position: - // casting op:'cast' cast: value: dim: ?? - }*/ - dump(title, levels = 2) { - // console.trace(); - let caller = ''; - try { - throw new Error(); - } catch (e) { - caller = e.stack.split('\n')[levels].trim().substring(3); - } - title = title ? `(${title}) `:''; - console.log(`\x1B[38;5;214m|==========> DUMP ${title}${caller} <==========|\x1B[0m`); - for (let index = this.stack.length-1; index >=0; --index) { - const st = this.stack[index]; - let info =`\x1B[38;5;214m#${index} ${st.op}`; - for (const operand of st.operands) { - info = info + ' [\x1B[38;5;76m' + this.dumpOperand(operand,index)+'\x1B[38;5;214m]'; - } - console.log(info+'\x1B[0m'); - } - } - dumpOperand(op, pos) { + dumpOperand(op, pos, options = {}) { const cType = '\x1B[38;5;76m'; const cProp = '\x1B[38;5;250m'; const cValue = '\x1B[38;5;40m'; - switch (op.type) { - case OP_VALUE: - return `${cType}VALUE ${cValue}${op.value}`; - case OP_ID_REF: - // refType, [offset], next - const next = op.next ? `${cProp}next:${cValue}${op.next}`:''; - return `${cType}ID_REF ${cProp}refType:${cValue}${op.refType} ${cProp}id:${cValue}${op.id}${next}`; - case OP_STACK: - return `${cType}STACK ${cProp}pos:${cValue}${pos - op.offset}[-${op.offset}]`; - case OP_RUNTIME: - let props = '' - for (const prop in op) { - if (prop === '__yystate' || prop === 'debug' || prop === 'type') continue; - props = props + ` ${cProp}${prop}:${cValue}${op[prop]}`; - } - return `${cType}RUNTIME${props}`; + if (op instanceof ExpressionItem) { + return op.dumpItem({...options, cType, cProp, cValue, pos}); } - return `\x1B[1;31m¿¿${op.type}??\x1B[0m`; - } - // TODO: cache of next - instanceNext(next) { - let _next = this.instance(); - } - updateOperandNext(op, next) { - assert(op.type != RUNTIME); - - if (op.type === OP_ID_REF) { - op.next += next; + if (op === null) return 'null'; + if (Array.isArray(op)) { + return '['+op.map(x => this.dumpOperand(x, pos, options)).join()+']' } + EXIT_HERE; } toString(options) { let top = this.stack.length-1; if (top < 0) { - return '(empty expression)'; + return '(Expression => String)'; } - return this.stackPosToString(top ,0, options); + const res = this.stackPosToString(top ,0, {...options, dumpToString: true}); + return res; } - stackPosToString(pos, pprec, options) { + stackPosToString(pos, parentOperation, options) { const st = this.stack[pos]; if (typeof st === 'undefined') { console.log(pos); console.log(this.stack); } + const parentPrecedence = ExpressionOperationsInfo.get(parentOperation).precedence; if (st.op === false) { - return this.operandToString(st.operands[0], pos, pprec, options); + return this.operandToString(st.operands[0], pos, st.op, options); } - const opinfo = Expression.operations[st.op]; + const operationInfo = ExpressionOperationsInfo.get(st.op); + const operationLabel = operationInfo.label; let res; if (st.operands.length === 1) { - res = Expression.operations[st.op].label + this.operandToString(st.operands[0], pos, opinfo.prec, options); + res = operationLabel + this.operandToString(st.operands[0], pos, st.op, options); } else if (st.operands.length === 2) { - res = this.operandToString(st.operands[0], pos, opinfo.prec, options) + ' ' + Expression.operations[st.op].label + ' ' + - this.operandToString(st.operands[1], pos, opinfo.prec, options); + res = this.operandToString(st.operands[0], pos, st.op, options) + ' ' + operationLabel + ' ' + + this.operandToString(st.operands[1], pos, st.op, options); + } else if (st.operands.length === 3 && st.op === 'if') { + res = '(' + this.operandToString(st.operands[0], pos, st.op, options) + ')?('+ + this.operandToString(st.operands[1], pos, st.op, options) + '):(' + + this.operandToString(st.operands[2], pos, st.op, options) + ')'; } else { + console.log(st); TODO_EXIT } - if (pprec > opinfo.prec) { + if (parentPrecedence > operationInfo.precedence || (parentOperation === 'sub' && st.op !== 'mul')) { res = '(' + res + ')'; } return res; } - operandToString(ope, pos, pprec, options) { - switch (ope.type) { - - case OP_VALUE: - return ope.value.toString(); - case OP_ID_REF: - // refType, [offset], next - let res = (Expression.parent && (!options || !options.hideLabel))? Expression.parent.getLabel(ope.refType, ope.id, options) : false; - if (!res) { - res = `${ope.refType}@${ope.id}`; - } - if (ope.next < 0) res = `${ope.next==-1?'':-ope.next}'${res}`; - if (ope.next > 0) res = `${res}'${ope.next==1?'':ope.next}`; - return res; - case OP_STACK: - if ((pos - ope.offset ) < 0) { - console.log(`invalid offset ${pos - ope.offset} pos:${pos} offset:${ope.offset}`); - } - return this.stackPosToString(pos-ope.offset, pprec, options); - case OP_RUNTIME: - if (ope.op === 'reference' && ope.name) { - return `RUNTIME{${ope.name}}` - } - return `RUNTIME{${ope.op}(${ope.name??''})}`; - //console.log(ope); - + operandToString(ope, pos, parentOperation, options) { + if (ope instanceof ExpressionItems.StackItem) { + return this.stackPosToString(pos-ope.offset, parentOperation, options); } - - } - packAlone(container, options) { - this.operandPack(container, this.getAloneOperand(), 0, options); - return container.pop(1)[0]; + return ope.toString(options); } pack(container, options) { - if (this.isAlone()) { - return this.packAlone(container, options); + const packer = new ExpressionPacker(container, this); + if (Debug.active) this.dump('PRE-PACK'); + return packer.pack(options); + } + resolve() { + const res = this.eval(); + if (res instanceof Expression) { + return res.instance({simplify: true}); } - let top = this.stack.length-1; - return this.stackPosPack(container, top, options); + return res; } - stackPosPack(container, pos, options) { - const st = this.stack[pos]; - if (st.op === false) { - this.operandPack(container, st.operands[0], pos, options); + isEmpty() { + return this.stack.length === 0; + } + asBool() { + let value = this.evalAsValue(); + // check if empty expression + if (this.isEmpty()) { return false; } - for (const ope of st.operands) { - this.operandPack(container, ope, pos, options); + assertLog((value instanceof Expression) === false, value); + if (typeof value.asBool === 'function') { + return value.asBool(); } - switch (st.op) { - case 'mul': - return container.mul(); - - case 'add': - return container.add(); - - case 'sub': - return container.sub(); - - case 'neg': - return container.neg(); - - default: - throw new Error(`Invalid operation ${st.op} on packed expression`); + if (typeof value.asInt === 'function') { + const ivalue = value.asInt(); + assert(typeof ivalue === 'bigint'); + return ivalue !== 0n; } + throw new Exceptions.CannotBeCastToType('bool'); } - - operandPack(container, ope, pos, options) { - switch (ope.type) { - case OP_VALUE: - container.pushConstant(ope.value); - break; - - case OP_ID_REF: - this.referencePack(container, ope.refType, ope.id, ope.next, ope.stage, options); - break; - - case OP_STACK: - // TODO: expression == false; - const eid = this.stackPosPack(container, pos-ope.offset, options); - if (eid !== false) { // eid === false => alone operand - container.pushExpression(eid); - } - break; - - default: - console.log(ope); - throw new Error(`Invalid reference ${ope.type} on packed expression`); - } - + asIntItem() { + return new ExpressionItems.IntValue(this.asInt()); } - referencePack(container, type, id, next, stage, options) { - switch (type) { - case 'im': - container.pushExpression(Expression.parent.getPackedExpressionId(id, container, options)); - break; - - case 'witness': - container.pushWitnessCol(id, next ?? 0, stage ?? 1); // TODO: stage - break; - - case 'fixed': - container.pushFixedCol(id, next ?? 0); - break; - - case 'public': - container.pushPublicValue(id); - break; - - case 'challenge': - container.pushChallenge(id, stage ?? 1); - break; - - case 'subproofvalue': - container.pushSubproofValue(id); - break; - - case 'proofvalue': - container.pushProofValue(id); - break; - - default: - throw new Error(`Invalid reference type ${type} to pack`); + asInt() { + let value = this.evalAsValue(); + // check if empty expression + if (this.isEmpty()) { + return 0n; + } + assertLog((value instanceof Expression) === false, value); + if (typeof value.asInt === 'function') { + return value.asInt(); } + throw new Exceptions.CannotBeCastToType('int'); } - resolve() { - const res = this.eval(); - if (res instanceof Expression) { - return res.instance({simplify: true}); + asIntDefault(defaultValue = false) { + return this._asDefault(this.asInt, defaultValue); + } + asIntItemDefault(defaultValue = false) { + return this._asDefault(this.asIntItem, defaultValue); + } + asString() { + const value = this.evalAsValue(); + if (this.isEmpty()) { + return ''; } - return res; + assertLog((value instanceof Expression) === false, value); + if (typeof value.asString === 'function') { + return value.asString(); + } + throw new Exceptions.CannotBeCastToType('string'); + } + asStringItem() { + return new ExpressionItems.StringValue(this.asString()); + } + asStringDefault(defaultValue = false) { + return this._asDefault(this.asString, defaultValue); + } + asStringItemDefault(defaultValue = false) { + return this._asDefault(this.asStringItem, defaultValue); + } + getValue() { + return this.eval(); + } + hasRuntimes() { + return this.stack.some(stackPos => stackPos.operands.some(operand => operand.isRuntime())); + } + static getType() { + return 'expr'; } } + +ExpressionItem.registerClass('Expression', Expression); +ExpressionClass.set(Expression); +Types.register('expr', Expression); +module.exports = Expression; \ No newline at end of file diff --git a/src/expression_class.js b/src/expression_class.js new file mode 100644 index 0000000..b30feda --- /dev/null +++ b/src/expression_class.js @@ -0,0 +1,18 @@ +const {assert} = require('./assert.js'); + +class ExpressionClass { + static cls = false; + static set(cls) { + this.cls = cls; + } + static get() { + assert(this.cls !== false, 'ExpressionClass no initialized'); + return this.cls; + } + static isInstance(obj) { + assert(this.cls !== false, 'ExpressionClass no initialized'); + return obj instanceof this.cls; + } +} + +module.exports = ExpressionClass; \ No newline at end of file diff --git a/src/expression_factory.js b/src/expression_factory.js new file mode 100644 index 0000000..515f10e --- /dev/null +++ b/src/expression_factory.js @@ -0,0 +1,182 @@ +const util = require('util'); +const {cloneDeep} = require('lodash'); +const Expression = require("./expression.js"); +const {ReferenceItem, IntValue, StringValue, StringTemplate, + FunctionCall, ExpressionList, RangeIndex} = require("./expression_items.js"); +const Router = require("./router.js"); +const {assert, assertLog} = require('./assert'); +const RowOffset = require('./expression_items/row_offset.js'); +const Context = require('./context.js'); +const Debug = require('./debug.js'); +module.exports = class ExpressionFactory { + + // pre function to delete property op only used by routing + static router = new Router(this, 'type', {defaultPrefix: '_from', pre: (method, obj) => delete obj.type}); + + static fromObject(obj) { + try { + return this._fromObject(obj); + } catch (e) { + // console.log(e); + if (e.message.startsWith(Context.processor.sourceRef + ':') === false) { + e.message = Context.processor.sourceRef + ': ' + e.message; + } + throw e; // new Error(); + } + } + static _fromObject(obj, options = {}) { + if (obj instanceof Expression) { + // console.log('#########', Object.keys(obj).includes('type')); + return obj; + } + // console.log(obj); + assertLog(typeof obj === 'object', obj); + assertLog(typeof obj.op === 'undefined', obj); + if (Array.isArray(obj)) { + obj = [...obj]; + } else { + obj = {...obj}; + } + + assert(obj.type !== 'object' && obj.type !== 'objects'); + if (obj.dim === 0) delete obj.dim; + + // console.log(obj); + const type = obj.type; + if (typeof type === 'undefined') { + console.log(obj); + } + let item = ExpressionFactory.router.go(obj); + + let unknownProperties = []; + for (const prop in obj) { + if (prop.startsWith('__')) continue; + if (prop === 'debug') continue; + unknownProperties.push(prop); + } + + if (unknownProperties.length > 0) { + console.log(obj); + throw new Error(`Invalid properties: ${unknownProperties.join(',')} / ${type} on ${obj.debug}`); + } + if (type === 'row_offset') { + return item; + } + if (item instanceof ExpressionList) { + return item; + } + let expr = new Expression(); + expr._set(item); + return expr; + } + static _fromObjects(objs, options = {}) { + let expressions = []; + for (const obj of objs) { + // if (Array.isArray(obj) && options.elist) { + if (Array.isArray(obj)) { + // TODO: review, better values + expressions.push(ExpressionFactory._fromExpressionList(obj)); + // expressions.push(new ExpressionList(this._fromObjects(obj, {elist: true}))); + continue; + } + if (obj instanceof Expression || obj instanceof ExpressionList) { + expressions.push(obj); + continue; + } + expressions.push(ExpressionFactory._fromObject(obj, options)); + } + return expressions; + } + static _fromExpressionList(obj) { + if (Debug.active) console.log(obj.values); + if (Debug.active) console.log(obj.__debug); + const elist = new ExpressionList(this._fromObjects(obj.values, {elist: true})); + if (Debug.active) console.log(elist); + delete obj.values; + return elist; + } + static _fromAppend(obj) { + console.log('TODO !!! '); + console.log(util.inspect(obj, false, null)); + let res = this._fromObject(obj.value); + res.transform = 'spread'; + delete obj.value; + res.dump(); + EXIT_HERE; + return res; + } + static _fromReference(obj) { + // if (obj.rowOffset) { + // console.log('ROWOFFSET.FROMREFERENCE'); + // console.log(obj.rowOffset); + // } + // console.log(obj); + let res = new ReferenceItem(obj.name, obj.indexes ?? [], obj.rowOffset); + delete obj.name; + delete obj.indexes; + delete obj.dim; + delete obj.rowOffset; + + // TODO + delete obj.inc; + return res; + } + static _fromNumber(obj) { + let res = new IntValue(obj.value); + delete obj.value; + return res; + } + static _fromString(obj) { + let res; + if (obj.template) { + res = new StringTemplate(obj.value); + console.log('TEMPLATE #####) '+obj.value); + delete obj.template; + } + else { + res = new StringValue(obj.value); + } + delete obj.value; + return res; + } + static _fromCall(obj) { + // console.log(`##### CALL ${obj.function.name} ${obj.debug}`); + // console.log(util.inspect(obj, false, 10, true)); + let res = new FunctionCall(obj.function.name, obj.args ?? [], obj.indexes ?? [], { + name: obj.function.name.debug}); + // console.log(res); + delete obj.function; + delete obj.indexes; + delete obj.dim; + delete obj.args; + return res; + } + static _fromCast(obj) { + let res = new FunctionCall('cast', [obj.cast, obj.value], []); + delete obj.name; + delete obj.cast; + delete obj.value; + // console.log(res); + return res; + } + static _fromRowOffset(obj) { + if (obj.current && obj.current.rowOffset) { + // TODO: ERROR more than rowOffset for same element. + EXIT_HERE; + } + let res = RowOffset.factory(obj.value, obj.prior ?? false); + delete obj.current; + delete obj.value; + delete obj.prior; + // console.log(res); + return res; + } + static _fromRangeIndex(obj) { + const from = obj.from ?? false; + const to = obj.to ?? false; + delete obj.from; + delete obj.to; + return new RangeIndex(from, to); + } + // TODO: positionalParams +} diff --git a/src/expression_items.js b/src/expression_items.js new file mode 100644 index 0000000..83d473e --- /dev/null +++ b/src/expression_items.js @@ -0,0 +1,51 @@ +const ExpressionItem = require("./expression_items/expression_item.js"); +const ExpressionList = require("./expression_items/expression_list.js"); +const ExpressionReference = require("./expression_items/expression_reference.js"); +const FeValue = require("./expression_items/fe_value.js"); +const IntValue = require("./expression_items/int_value.js"); +const ProofItem = require("./expression_items/proof_item.js"); +const Proofval = require("./expression_items/proofval.js"); +const Challenge = require("./expression_items/challenge.js"); +const Public = require("./expression_items/public.js"); +const Publictable = require("./expression_items/publictable.js"); +const ReferenceItem = require("./expression_items/reference_item.js"); +const RuntimeItem = require("./expression_items/runtime_item.js"); +const StackItem = require("./expression_items/stack_item.js"); +const StringTemplate = require("./expression_items/string_template.js"); +const StringValue = require("./expression_items/string_value.js"); +const Subproofval = require("./expression_items/subproofval.js"); +const ValueItem = require("./expression_items/value_item.js"); +const WitnessCol = require("./expression_items/witness_col.js"); +const ArrayOf = require("./expression_items/array_of.js"); +const FixedCol = require("./expression_items/fixed_col.js"); +const FunctionCall = require("./expression_items/function_call.js"); +const ParamItem = require("./expression_items/param_item.js"); +const RangeIndex = require("./expression_items/range_index.js"); +const NonRuntimeEvaluableItem = require('./expression_items/non_runtime_evaluable_item.js'); + +module.exports = { + ExpressionItem, + ExpressionList, + ExpressionReference, + FeValue, + FixedCol, + IntValue, + ProofItem, + Proofval, + Challenge, + Public, + Publictable, + ReferenceItem, + RuntimeItem, + StackItem, + StringTemplate, + StringValue, + Subproofval, + ValueItem, + WitnessCol, + ArrayOf, + FunctionCall, + ParamItem, + RangeIndex, + NonRuntimeEvaluableItem +} diff --git a/src/expression_items/array_of.js b/src/expression_items/array_of.js new file mode 100644 index 0000000..f4adc28 --- /dev/null +++ b/src/expression_items/array_of.js @@ -0,0 +1,82 @@ +const LabelRanges = require("../label_ranges.js"); +const RuntimeItem = require("./runtime_item.js"); +const MultiArray = require('../multi_array.js'); +const {assert, assertLog} = require('../assert.js'); +const Context = require('../context.js'); +const Types = require('../types.js'); +module.exports = class ArrayOf extends RuntimeItem { + constructor (instanceType, array, unrollLevels = 0) { + super(); + assertLog(array instanceof MultiArray, array); + this._array = array.clone(); + this.unrollLevels = unrollLevels; +// console.log(`ARRAYOF(${instanceType})[${array.lengths.map(x => x.toString(10)).join('],[')}] D${this.dim}`); + + this.instanceType = instanceType; + } + toString(options) { + return super.toString(options)+'['+this._array.lengths.join('],[')+`] D${this.dim}`; + } + get dim() { + return this._array.dim; + } + get array() { + assert(this._array !== false, 'try to access to array, but array lengths not defined'); + return this._array; + } + set array(value) { + if (this._array !== false) { + throw new Error(); + } + this._array = value; + } + get instance() { + return Context.references.getTypeInstance(this.instanceType); + } + cloneInstance() { + return new ArrayOf(this.instanceType, this._array, this.unrollLevels); + } + evalInside() { + return this.clone(); + } + getItem(indexes) { + const offset = this._array.indexesToOffset(indexes); + return this.instance.getItem(offset); + } + toArrays(indexes = []) { + let level = indexes.length; + if (level >= this._array.dim) { + return this.getItem(indexes); + } + let nextLevelLen = this._array.lengths[level]; + let res = []; + for (let nextLevelIndex = 0; nextLevelIndex < nextLevelLen; ++nextLevelIndex) { + const _indexes = [...indexes, nextLevelIndex]; + res.push(this.toArrays(_indexes)); + } + return res; + } + static getType() { + return this.instanceType; + } + operatorSpread() { + return new ArrayOf(this.instanceType, this._array, this.unrollLevels + 1); + } + isUnrolled() { + return this.unrollLevels > 0; + } + unroll() { + assert(this.unrollLevels === 1); + + if (this._array.dim > 1) { + // TODO: implement array of arrays of + EXIT_HERE; + } + let len = this._array.lengths[0]; + let res = []; + for (let index = 0; index < len; ++index) { + res.push(this.getItem([index])); + } + return res; + } +} diff --git a/src/expression_items/challenge.js b/src/expression_items/challenge.js new file mode 100644 index 0000000..893e02b --- /dev/null +++ b/src/expression_items/challenge.js @@ -0,0 +1,12 @@ +const ProofItem = require("./proof_item.js"); +module.exports = class Challenge extends ProofItem { + constructor (id) { + super(id); + } + getTag() { + return 'challenge'; + } + cloneInstance() { + return new Challenge(this.id); + } +} diff --git a/src/expression_items/expression_item.js b/src/expression_items/expression_item.js new file mode 100644 index 0000000..3b6501a --- /dev/null +++ b/src/expression_items/expression_item.js @@ -0,0 +1,203 @@ +/* cexp next ind Parent Item DefClas Definition + ---- ---- --- -------------- -------------- -------------- --------------------------------------------- + Challenge - - * ProofItem id ProofStageDef id + stage [used] + SubExpression - * * ProofItem id - id [const,use] + FeValue - - - ValueItem value - value (fe) [const] + IntValue * - - ValueItem value - value (bigint) [const] + FixedCol - - * ProofItem id - id [used] + FunctionCall * * ? RuntimeItem "id",argValues Function name,args,return,statements + Proofval - - * ProofItem id - id [used] + Public - - * ProofItem id - id [used] + Publictable - - * ProofItem id PublictableDef id + numCols,maxRows,aggType,rowExpressionId [used] + *PublictableCol - - * ProofItem id,colId - [const, used] + ReferenceItem * * * RuntimeItem name ? name + type, instance, etc. + StackItem - - - ExpressionItem offset - - + StringValue * - - RuntimeItem value - value (string) [const, used] + Subproofval - - * ProofItem id SubproofvalDef id + subproofId [used] + WitnessCol - * * ProofItem id ProofStageDef id + stage [used] + + + Type List Item + ---------- -------------- -------------- + Challenge challenge challenges (Ids) id Ids: new cls(id) + Expression expr exprs (Variables) value Variables: new cls(value) + SubExpression subexpr subexprs (Ids) id Ids: new cls(id) + FeValue fe fes (Variables) value Variables: new cls(value) + IntValue int ints (Variables) value Variables: new cls(value) + *IntValue constant constants (Indexable) value Variables: new cls(value) + FixedCol fixed fixeds (FixedCols) id Ids: new cls(id) + FunctionCall function functions (Indexable) "id",argValues + Proofval proofvalue proofvalues (Ids) id Ids: new cls(id) + Public public publics (Ids) id Ids: new cls(id) + Publictable publictable id + *PublictableCol id,colId + ReferenceItem - references (References) name + StackItem - offset + StringValue string strings (Variables) value Variables: new cls(value) + Subproofval subproofval subproofvalues (Ids) id Ids: new cls(id) + WitnessCol witness witness (WitnessCols) id WitnessCols: new WitnessCol(id, stage) + + + + cexp: compiler expression (build) + next: allowed next + ind: allowed indexes + + ExpressionItem > ProofItem + > RuntimeItem + > ValueItem + + Array information on reference + + ArrayOf (multiarray, from: ExpressionItem) + ArrayOf (multiarray, [ExpressionItem]) = List + +*/ +const Exceptions = require('../exceptions.js'); +const Debug = require('../debug.js'); +class ExpressionItem { + static _classToManager = {}; + + constructor(options = {}) { + this.options = options; + this.indexes = false; + this.label = ''; + this._ns_ = 'ExpressionItem'; + } + static registerClass(name, cls) { + ExpressionItem[name] = cls; + } + setLabel (label) { + if (Debug.active) console.log(['SETLABEL', label]); + this.label = label; + } + get dim () { + return Array.isArray(this.indexes) ? this.indexes.length : 0; + } + popArrayIndex () { + if (this.indexes === false) { + throw new Error(`try to add index to non-indexable element`); + } + if (typeof this.indexes === 'undefined') { + this.indexes = []; + } + this.indexes.push(ExpressionItem.IntValue(index)); + } + pushArrayIndex () { + if (this.indexes === false) { + throw new Error(`try to add an index to non-indexable element`); + } + if (this.dim < 1) { + throw new Error(`try to remove an index from element without indexes`); + } + return this.indexes.pop(); + } + toString(options) { + return this.getTag() + '(' + this.label + ')'; + } + dump(options) { + return this.toString(options); + } + dumpItem(options) { + return this.dump(options); + } + getTag() { + return this.constructor.name; + } + get type() { + console.log(this); + throw new Error(`FATAL: use type obsolete-property`) + } + getRowOffset() { + return this.rowOffset ? this.rowOffset.value : 0; + } + getRowOffsetStrings(options) { + if (!this.rowOffset) return ['','']; + return this.rowOffset.getStrings(); + } + static setManager(cls, manager) { + if (Debug.active) console.log(['SET_MANAGER', cls.name]); + ExpressionItem._classToManager[cls.name] = manager; + } + getManager() { + if (Debug.active) console.log(['GET_MANAGER', this.constructor.name]); + return ExpressionItem._classToManager[this.constructor.name]; + } + _asDefault(method, defaultValue = false) { + try { + return method.apply(this, [defaultValue]); + } catch (e) { + if (e instanceof Exceptions.CannotBeCastToType) { + return defaultValue; + } + throw e; + } + } + get rowOffset() { + return this._rowOffset; + } + set rowOffset(value) { + if (Debug.active) { + if (!value.isZero()) console.log(['ROWOFFSET.SET', value]); + } + this._rowOffset = value; + } + clone() { + let cloned = this.cloneInstance(); + cloned.cloneUpdate(this); + return cloned; + } + cloneUpdate(source) { + if (source.indexes) { + this.indexes = source.indexes.map(index => (typeof index === 'object' && typeof index.clone === 'function') ? index.clone() : index); + } + if (source.label) { + this.label = source.label; + } + } + evalInside(options = {}) { + throw new Error(`evalInside not defined for class ${this.constructor.name}`); + } + evalPrior(options) { + if (!this.rowOffset || !this.rowOffset.isPriorRows()) { + return false; + } + if (Debug.active) console.log(['ROWOFFSET.EVALPRIOR', this.rowOffset.value]); + return this.rowOffset.value; + } + evalNext(options) { + if (!this.rowOffset || !this.rowOffset.isNextRows()) { + return false; + } + if (Debug.active) console.log(['ROWOFFSET.EVALNEXT', this.rowOffset.value]); + return this.rowOffset.value; + } + eval(options) { + let results = {}; + const _options = options ? {...options, results} : {results}; + results.prior = this.evalPrior(options); + results.inside = this.evalInside(options); + results.next = this.evalNext(options); + return results.final ? results.final : results.inside; + } + evalAsItem(options) { + return this.clone(); + } + instance(options) { + return this.clone(); + } + isEmpty() { + // default implementation + return false; + } + isUnrolled() { + // default implementation + return false; + } + isRuntimeEvaluable() { + // default implementation + return true; + } +} + +module.exports = ExpressionItem; \ No newline at end of file diff --git a/src/expression_items/expression_list.js b/src/expression_items/expression_list.js new file mode 100644 index 0000000..c02251e --- /dev/null +++ b/src/expression_items/expression_list.js @@ -0,0 +1,68 @@ +const Exceptions = require('../exceptions.js'); +const {assert, assertLog} = require('../assert.js'); +const ExpressionItem = require('./expression_item.js'); +const MultiArray = require('../multi_array.js'); +const util = require('util'); +const Context = require('../context.js'); +class ExpressionList extends ExpressionItem { + + constructor(items, options = {}) { + super(options); + this.indexes = [items.length]; + this.label = ''; + if (options.cloneItems === false) { + this.items = items; + } else { + this.items = []; + for (const item of items) { + this.items.push(item.clone()); + } + } + this.array = new MultiArray([this.items.length]); + this._ns_ = 'ExpressionItem'; + } + dump() { + return '[' + this.items.map(x => x.toString()).join(',')+']'; + } + cloneInstance() { + return new ExpressionList(this.items, this.debug); + } + pushItem(item) { + assertLog(item instanceof ExpressionItem, item); + this.items.push(item.clone()); + this.indexes = [this.items.length]; + } + evalInside(options = {}) { + return new ExpressionList(this.items.map(x => x.eval(options))); + } + getItem(indexes) { + const index = indexes[0]; + if (index < 0 && index >= this.items.length) { + throw new Error(`Out of bounds, try to access index ${index} but list only has ${this.items.length} elements`); + } + const item = this.items[index]; + if (indexes.length === 1) { + return item; + } + return item.getItem(indexes.slice(1)); + } + instance(options) { + let _items = []; + const _options = {...options, unroll: false}; + for (const item of this.items) { + const _instanced = item.instance(_options); + if (_instanced.isAlone()) { + const _operand = _instanced.getAloneOperand(); + if (_operand.isUnrolled()) { + const unrolled = _operand.unroll(); + _items = [..._items, ...unrolled]; + continue; + } + } + _items.push(_instanced); + } + return new ExpressionList(_items, {...this.debug, cloneItems: false}); + } +} + +module.exports = ExpressionList; \ No newline at end of file diff --git a/src/expression_items/expression_reference.js b/src/expression_items/expression_reference.js new file mode 100644 index 0000000..b965335 --- /dev/null +++ b/src/expression_items/expression_reference.js @@ -0,0 +1,26 @@ +const ProofItem = require("./proof_item.js"); +const {assert, assertLog} = require('../assert.js'); +module.exports = class ExpressionReference extends ProofItem { + constructor (id, instance, options = {}) { + super(options); + this.id = id; + this.instance = instance; + } + getTag() { + return 'im'; + } + static createFrom(value, options = {}) { + assertLog(typeof options.id !== 'undefined' && typeof options.instance !== 'undefined', + {value, options, msg: 'ExpressionReference.createFrom need knows id and instance'}); + return new ExpressionReference(options.id, options.instance); + } + cloneInstance(options) { + return new ExpressionReference(this.id, this.instance, this.options); + } + evalInside(options) { + return this; + } + isRuntimeEvaluable() { + return false; + } +} diff --git a/src/expression_items/fe_value.js b/src/expression_items/fe_value.js new file mode 100644 index 0000000..8339f89 --- /dev/null +++ b/src/expression_items/fe_value.js @@ -0,0 +1,17 @@ +const LabelRanges = require("../label_ranges.js"); +const ValueItem = require("./value_item.js"); + +module.exports = class FeValue extends ValueItem { + constructor (value = 0n) { + super(value); + } + cloneInstance() { + return new FeValue(this.value); + } + asInt() { + return this.value; + } + asNumber() { + return Number(this.value); + } +} diff --git a/src/expression_items/fixed_col.js b/src/expression_items/fixed_col.js new file mode 100644 index 0000000..3cc566b --- /dev/null +++ b/src/expression_items/fixed_col.js @@ -0,0 +1,58 @@ +const ProofItem = require("./proof_item.js"); +// const Sequence = require("../sequence.js"); +module.exports = class FixedCol extends ProofItem { + constructor (id) { + super(id); + this.rows = 0; + this.sequence = null; + this.values = []; + this.fullFilled = false; + } + getId() { + return this.id; + } + isPeriodic() { + return this.rows > 0; + } + getTag() { + return 'fixed'; + } + getValue(row) { + if (this.sequence === null) { + return this.values[row] + } + return this.sequence.getValue(row); + } + set(value) { + // REVIEW: cyclic references + if (value instanceof Object) { + if (this.sequence !== null) { + EXIT_HERE; + } + if (this.values.length > 0) { + EXIT_HERE; + } + this.sequence = value; + this.rows = this.sequence.size; + } + else { + console.log(value); + EXIT_HERE; + } + } + cloneInstance() { + return new FixedCol(this.id); + } + cloneUpdate(source) { + super.cloneUpdate(source); + if (source.rowOffset) { + console.log('CLONE.ROWOFFSET'); + } + this.rows = source.rows; + this.values = [...source.values]; + this.fullFilled = source.fullFilled; + if (source.sequence) { + this.sequence = source.sequence.clone(); + } + } +} diff --git a/src/expression_items/function_call.js b/src/expression_items/function_call.js new file mode 100644 index 0000000..1039d34 --- /dev/null +++ b/src/expression_items/function_call.js @@ -0,0 +1,63 @@ +const util = require('util'); +const RuntimeItem = require("./runtime_item.js"); +const ExpressionList = require("./expression_list.js"); +const Context = require('../context.js'); +const Debug = require('../debug.js'); +const ExpressionClass = require('../expression_class.js'); +module.exports = class FunctionCall extends RuntimeItem { + constructor (name, args = [], indexes = [], options = {}) { + super(options); + this.name = name; + if (args instanceof ExpressionList) { + if (Debug.active) console.log(util.inspect(args, false, 10, true)); + args = args.items; + } + if (Debug.active) console.log(`#FCALL#${name} ${Context.sourceTag} ${args.length}`+ + util.inspect(args, false, null)); + // this.args = args.map(x => (typeof x.clone === 'function') ? x.clone() : x); + this.args = args.map(x => x.clone()); + this.indexes = indexes.map(x => (typeof x.clone === 'function') ? x.clone() : x); + if (Debug.active) { + console.log(`############## ARGS(${name},${this.args.length}) ######################`); + console.log(util.inspect(args, false, 10, true)); + this.dumpArgs(this.args, 'FCALL'); + } + + } + setFunction(funcdef) { + this.funcdef = funcdef; + } + toString(options) { + return this.dump(options); + } + dump(options) { + const indexes = this.indexes.length > 0 ? '['+this.indexes.join(',')+']':''; + const args = '(' + this.args.map(x => x.toString()).join(',') +')'; + return this.name + args + indexes; + } + cloneInstance() { + return new FunctionCall(this.name, this.args, this.indexes); + } + cloneUpdate(source) { + super.cloneUpdate(source); + this.funcdef = source.funcdef; + } + dumpArgs (args, label = '') { + args.forEach((x, index) => { + const _label = `${label}[${index}]`; + if (ExpressionClass.isInstance(x)) x.dump(_label); + else if (x instanceof ExpressionList) this.dumpArgs(x.items, _label); + else console.log(_label, x); + }); + } + evalInside(options = {}) { + if (Debug.active) { + console.log([`#FCALL.EVAL #${this.name} ${Context.sourceTag}`, this.args]); + this.dumpArgs(this.args, `CALL ${this.name}`); + } + const definition = Context.references.get(this.name, options); + const res = Context.processor.executeFunctionCall(this.name, this); + if (Debug.active) console.log(this.name, res); + return res; + } +} diff --git a/src/expression_items/int_value.js b/src/expression_items/int_value.js new file mode 100644 index 0000000..ae62181 --- /dev/null +++ b/src/expression_items/int_value.js @@ -0,0 +1,131 @@ +const {assert, assertLog} = require('../assert.js'); +const ValueItem = require("./value_item.js"); +const Types = require('../types.js'); +class IntValue extends ValueItem { + constructor (value = 0n) { + if (value instanceof IntValue) { + value = value.value; + } + if (typeof value === 'number') { + value = BigInt(value); + } + assertLog(typeof value === 'bigint', value); + super(value); + } + setValue(value) { + if (typeof value === 'number') { + value = BigInt(value); + } + assert(typeof value === 'bigint'); + this.value = value; + } + cloneInstance() { + return new IntValue(this.value); + } + static castTo(value) { + if (value instanceof IntValue) { + return value.value; + } + if (typeof value.asInt === 'function') { + return value.asInt(); + } + console.log(value); + EXIT_HERE; + } + static getType() { + return 'int'; + } + asInt() { + return this.value; + } + asIntItem() { + return this.clone(); + } + asIntDefault(defaultValue) { + return this.value; + } + asNumber() { + return Number(this.value); + } + asBool() { + return Number(this.value) != 0; + } + asStringItem() { + return new ValueItem.StringValue(this.asString()); + } + asString() { + return this.value.toString(); + } + asExpressionItem() { + let res = new ValueItem.Expression(); + res._set(this); + return res; + } + operatorAdd(valueB) { + return new IntValue(this.asInt() + valueB.asInt()); + } + operatorSub(valueB) { + return new IntValue(this.asInt() - valueB.asInt()); + } + operatorMul(valueB) { + return new IntValue(this.asInt() * valueB.asInt()); + } + operatorDiv(valueB) { + return new IntValue(this.asInt() / valueB.asInt()); + } + operatorMod(valueB) { + return new IntValue(this.asInt() % valueB.asInt()); + } + operatorNeg() { + return new IntValue(-this.asInt()); + } + operatorShl(valueB) { + return new IntValue(this.asInt() << valueB.asInt()); + } + operatorShr(valueB) { + return new IntValue(this.asInt() >> valueB.asInt()); + } + operatorBand(valueB) { + return new IntValue(this.asInt() & valueB.asInt()); + } + operatorBor(valueB) { + return new IntValue(this.asInt() | valueB.asInt()); + } + operatorBxor(valueB) { + return new IntValue(this.asInt() ^ valueB.asInt()); + } + operatorNot() { + return new IntValue(this.asInt() ? 0n : 1n); + } + operatorGt(valueB) { + return new IntValue(this.asInt() > valueB.asInt() ? 1n : 0n); + } + operatorGe(valueB) { + return new IntValue(this.asInt() >= valueB.asInt() ? 1n : 0n); + } + operatorLt(valueB) { + return new IntValue(this.asInt() < valueB.asInt() ? 1n : 0n); + } + operatorLe(valueB) { + return new IntValue(this.asInt() <= valueB.asInt() ? 1n : 0n); + } + operatorNe(valueB) { + return new IntValue(this.asInt() == valueB.asInt() ? 0n : 1n); + } + operatorAnd(valueB) { + return new IntValue((this.asInt() && valueB.asInt()) ? 1n : 0n); + } + operatorOr(valueB) { + return new IntValue((this.asInt() || valueB.asInt()) ? 1n : 0n); + } + operatorPow(valueB) { + return new IntValue(this.asInt()**valueB.asInt()); + } + operatorEq(valueB) { + return new IntValue(this.asInt() == valueB.asInt() ? 1:0); + } +} +Types.register('int', IntValue); +ValueItem.registerClass('IntValue', IntValue); + +module.exports = IntValue; \ No newline at end of file diff --git a/src/expression_items/no_evaluated_item.js b/src/expression_items/no_evaluated_item.js new file mode 100644 index 0000000..8d43883 --- /dev/null +++ b/src/expression_items/no_evaluated_item.js @@ -0,0 +1,26 @@ +const ExpressionItem = require("./expression_item.js"); + + +class NonEvaluatedItem extends ExpressionItem { + + static _singletonInstance = new NonEvaluatedItem(); + constructor () { + super(); + } + static get () { + return NonEvaluatedItem._singletonInstance; + } + clone() { + return NonEvaluatedItem._singletonInstance; + } + eval(options) { + return NonEvaluatedItem._singletonInstance;; + } + isRuntimeEvaluable() { + // not evaluated, but perhaps could be evaluated + return true; + } +} +Object.freeze(NonEvaluatedItem._singletonInstance); + +module.exports = NonEvaluatedItem; \ No newline at end of file diff --git a/src/expression_items/non_runtime_evaluable_item.js b/src/expression_items/non_runtime_evaluable_item.js new file mode 100644 index 0000000..107473c --- /dev/null +++ b/src/expression_items/non_runtime_evaluable_item.js @@ -0,0 +1,25 @@ +const ExpressionItem = require("./expression_item.js"); + + +class NonRuntimeEvaluableItem extends ExpressionItem { + + static _singletonInstance = new NonRuntimeEvaluableItem(); + constructor () { + super(); + } + static get () { + return NonRuntimeEvaluableItem._singletonInstance; + } + cloneInstance() { + return NonRuntimeEvaluableItem._singletonInstance; + } + eval(options) { + return NonRuntimeEvaluableItem._singletonInstance;; + } + isRuntimeEvaluable() { + return false; + } +} +Object.freeze(NonRuntimeEvaluableItem._singletonInstance); + +module.exports = NonRuntimeEvaluableItem; \ No newline at end of file diff --git a/src/expression_items/param_item.js b/src/expression_items/param_item.js new file mode 100644 index 0000000..6cb6d14 --- /dev/null +++ b/src/expression_items/param_item.js @@ -0,0 +1,22 @@ +const RuntimeItem = require("./runtime_item.js"); + +// NEXT FEATURE +// ParamItem is as a macro or expression template. by $, allows to define expression, +// instance it without replacing this parameter. To expand param in an expression +// expr example = (10 + $1 + 2 * $2) * $1 +// expr replaced = example(13, x + 2); +// replaced was (10 + 13 + 2 * (x + 2)) * 13 + +module.exports = class ParamItem extends RuntimeItem { + // TODO: next + constructor (id) { + super(); + this.id; + } + dump(options) { + return '$'+this.id; + } + cloneInstance() { + return new ParamItem(this.id); + } +} diff --git a/src/expression_items/proof_item.js b/src/expression_items/proof_item.js new file mode 100644 index 0000000..480ed27 --- /dev/null +++ b/src/expression_items/proof_item.js @@ -0,0 +1,48 @@ +const ExpressionItem = require("./expression_item.js"); +module.exports = class ProofItem extends ExpressionItem { + static createWithId = true; + constructor (id) { + super(); + this.id = id; + } + getId() { + return this.id; + } + getLabel(options) { + const manager = this.getManager(); + if (!manager) return ''; + return manager.getLabel(this.id, options); + } + dump(options) { + const [pre,post] = this.getRowOffsetStrings(); + options = options ?? {}; + const defaultType = options.type ? options.type : this.constructor.name; + if (!options.label && !options.hideLabel && options.dumpToString) { + options = {...options, label: this.getLabel(options)}; + } + const label = options.label ? options.label : `${defaultType}@${this.id}`; + return `${pre}${label}${post}`; + } + eval(options) { + return this.clone(); + } + isRuntimeEvaluable() { + return false; + } + cloneUpdate(source) { + super.cloneUpdate(source); + if (source.rowOffset) { + this.rowOffset = source.rowOffset.clone(); + } + } + toString(options = {}) { + const [next, prior] = this.getRowOffsetStrings(); + // console.log(['ROWOFFSET.TOSTRING', next, prior, this.label, this.constructor.name, this.rowOffset]); + let label = (options.hideClass ? '' : this.getTag() + '::') + this.label; + if (options.hideLabel || !this.label) { + label = this.getTag() + '@' + this.id; + } + return next + label + prior; + } +} + diff --git a/src/expression_items/proofval.js b/src/expression_items/proofval.js new file mode 100644 index 0000000..7758d5e --- /dev/null +++ b/src/expression_items/proofval.js @@ -0,0 +1,13 @@ +const ProofItem = require("./proof_item.js"); + +module.exports = class Proofval extends ProofItem { + constructor (id) { + super(id); + } + getTag() { + return 'proofvalue'; + } + cloneItem() { + return new Proofval(this.id); + } +} diff --git a/src/expression_items/public.js b/src/expression_items/public.js new file mode 100644 index 0000000..b5ba45a --- /dev/null +++ b/src/expression_items/public.js @@ -0,0 +1,15 @@ +const ProofItem = require("./proof_item.js"); +module.exports = class Public extends ProofItem { + constructor (id) { + super(id); + } + getId() { + return this.id; + } + getTag() { + return 'public'; + } + cloneInstance() { + return new Public(this.id); + } +} diff --git a/src/expression_items/publictable.js b/src/expression_items/publictable.js new file mode 100644 index 0000000..8b6c2b8 --- /dev/null +++ b/src/expression_items/publictable.js @@ -0,0 +1,15 @@ +const ProofItem = require("./proof_item.js"); +module.exports = class PublicTable extends ProofItem { + constructor (id) { + super(id); + } + getId() { + return this.id; + } + getTag() { + return 'publictable'; + } + cloneInstance() { + return new PublicTable(this.id); + } +} diff --git a/src/expression_items/range_index.js b/src/expression_items/range_index.js new file mode 100644 index 0000000..ef52e47 --- /dev/null +++ b/src/expression_items/range_index.js @@ -0,0 +1,16 @@ +const RuntimeItem = require("./runtime_item.js"); +const {assert, assertLog} = require('../assert.js'); +const Context = require('../context.js'); +module.exports = class RangeIndex extends RuntimeItem { + constructor (from, to) { + super(); + this.from = from !== false ? from.clone() : false; + this.to = to !== false ? to.clone(): false; + } + cloneInstance() { + return new RangeIndex(this.from, this.to); + } + evalInside() { + return this.clone(); + } +} diff --git a/src/expression_items/reference_item.js b/src/expression_items/reference_item.js new file mode 100644 index 0000000..5733945 --- /dev/null +++ b/src/expression_items/reference_item.js @@ -0,0 +1,60 @@ +const RuntimeItem = require("./runtime_item.js"); +const Context = require('../context.js'); +const RowOffset = require('./row_offset.js'); +const ExpressionItem = require('./expression_item.js'); +const Debug = require('../debug.js'); +module.exports = class ReferenceItem extends RuntimeItem { + constructor (name, indexes = [], rowOffset) { + super(); + this.name = name; + try { + this.indexes = indexes.map(index => index.clone()); + } catch (e) { + console.log(indexes); + throw e; + } + // TODO: next as expression + this.rowOffset = RowOffset.factory(rowOffset); + } + set locator (value) { + throw new Error(`setting locator on reference ${this.name} ${this.indexes.length}`); + } + dump(options) { + return 'ReferenceItem('+this.toString(options)+')'; + } + toString(options) { + const [pre,post] = this.getRowOffsetStrings(); + return `${pre}${this.name}${this.indexes.length > 0 ? '*['+this.indexes.join(',')+']':''}${post}`; + } + cloneInstance() { + // console.log(JSON.stringify(this, (key, value) => typeof value === 'bigint' ? value.toString() : value)); + let cloned = new ReferenceItem(this.name, this.indexes, this.rowOffset); + // console.log(JSON.stringify(this, (key, value) => typeof value === 'bigint' ? value.toString() : value)); + // console.log(JSON.stringify(cloned, (key, value) => typeof value === 'bigint' ? value.toString() : value)); + return cloned; + } + evalInside(options = {}) { + if (Debug.active) { + console.log(['EVALINSIDE '+this.name, options]); + console.log(this.rowOffset); + console.log(this); + if (this.rowOffset.value) { + console.log('ROWOFFSET.EVALINSIDE'); + } + } + const item = Context.references.getItem(this.name, this.indexes); + if (item.isEmpty()) { + throw new Error(`accessing to ${item.label} before his initialization at ${Context.sourceRef}`); + } + if (this.rowOffset && !this.rowOffset.isZero()) { + item.rowOffset = this.rowOffset.clone(); + } + // TODO: next + if (Debug.active) { + console.log(`REFERENCE ${this.name} [${this.indexes.join('][')}]`) + console.log(item); + console.log(item.eval()); + } + return item.eval(); + } +} diff --git a/src/expression_items/row_offset.js b/src/expression_items/row_offset.js new file mode 100644 index 0000000..4444c8f --- /dev/null +++ b/src/expression_items/row_offset.js @@ -0,0 +1,58 @@ +const {assert, assertLog} = require("../assert.js"); +class RowOffset { + static Zero; + constructor (index, prior = false) { + assert(typeof index.prior === 'undefined'); + this.index = (typeof index === 'object' && typeof index.clone === 'function') ? index.clone() : index; + assert(typeof prior === 'boolean'); + this.prior = prior; + } + get value() { + if (typeof this.index === 'number') { + return this.prior ? -this.index : this.index; + } + console.log(this.index); + EXIT_HERE; + if (this.index instanceof Expression) { + + } + } + static factory(index, prior = false) { + if (typeof index === 'undefined') { + return RowOffset.Zero; + } + if (index instanceof RowOffset) { + return index.clone(); + } + console.log(['ROWOFFSET !!!!!', index, prior]); + assert(typeof index.prior === 'undefined'); + return new RowOffset(index, prior); + } + isPriorRows() { + return this.prior && this.value !== 0; + } + isNextRows() { + return !this.prior && this.value !== 0; + } + isZero() { + return this.value == 0; + } + clone() { + return this.cloneInstance(); + } + cloneInstance () { + return new RowOffset(this.index, this.prior); + } + getStrings() { + const value = this.value; + if (!value) return ['','']; + const res = [this.prior ? `${value < -1 ? -value : ''}'`: '', this.prior ? '' : `'${value > 1 ? value : ''}`]; + console.log(['ROWOFFSET.GETSTRINGS', res]); + return res; + } +} + +RowOffset.Zero = new RowOffset(0, false); +Object.freeze(RowOffset.Zero); + +module.exports = RowOffset; \ No newline at end of file diff --git a/src/expression_items/runtime_item.js b/src/expression_items/runtime_item.js new file mode 100644 index 0000000..5ec076f --- /dev/null +++ b/src/expression_items/runtime_item.js @@ -0,0 +1,11 @@ +const LabelRanges = require("../label_ranges.js"); +const ExpressionItem = require("./expression_item.js"); +module.exports = class RuntimeItem extends ExpressionItem { + constructor(options = {}) { + super(options); + } + isRuntimeEvaluable() { + return true; + } +} + diff --git a/src/expression_items/stack_item.js b/src/expression_items/stack_item.js new file mode 100644 index 0000000..e2abf29 --- /dev/null +++ b/src/expression_items/stack_item.js @@ -0,0 +1,30 @@ +const ExpressionItem = require("./expression_item.js"); + +module.exports = class StackItem extends ExpressionItem { + constructor (offset) { + super(); + this.offset = offset; + } + getOffset() { + return this.offset; + } + setOffset(value) { + this.offset = value; + return value; + } + getAbsolutePos(currentPos) { + return currentPos - this.offset; + } + cloneInstance() { + return new StackItem(this.offset); + } + dump(options = {}) { + if (typeof options.pos == 'number') { + return `StackItem(#${options.pos- this.offset}/${this.offset})` + } + return `StackItem(${this.offset})`; + } + eval(options = {}) { + + } +} diff --git a/src/expression_items/string_template.js b/src/expression_items/string_template.js new file mode 100644 index 0000000..34bbf6d --- /dev/null +++ b/src/expression_items/string_template.js @@ -0,0 +1,38 @@ +const {assert, assertLog} = require("../assert.js"); +const RuntimeItem = require("./runtime_item.js"); +const StringValue = require("./string_value.js"); +const Context = require('../context.js'); + +class StringTemplate extends StringValue { + constructor (value = '') { + assertLog(typeof value === 'string', value); + super(value); + } + evalTemplate(options) { + return new StringValue(Context.processor.evaluateTemplate(this.value)); + } + cloneInstance() { + return new StringTemplate(this.value); + } + dump(options) { + return '`'+this.value+'`'; + } + toString(options) { + return this.evalTemplate(options); + } + getValue() { + return this.evalTemplate(); + } + asString() { + return this.asStringItem().value; + } + asStringItem() { + return this.evalTemplate(); + } + evalInside(options = {}) { + return this.evalTemplate(options); + } +} + +RuntimeItem.registerClass('StringTemplate', StringTemplate); +module.exports = StringTemplate; diff --git a/src/expression_items/string_value.js b/src/expression_items/string_value.js new file mode 100644 index 0000000..291c280 --- /dev/null +++ b/src/expression_items/string_value.js @@ -0,0 +1,50 @@ +const {assert, assertLog} = require("../assert.js"); +const RuntimeItem = require("./runtime_item.js"); +class StringValue extends RuntimeItem { + constructor (value = '') { + super(); + assertLog(typeof value === 'string', value); + this.value = value; + } + get isBaseType () { + return true; + } + toString(options) { + return this.value; + } + dump(options) { + return '"'+this.value+'"'; + } + getValue() { + return this.value; + } + setValue(value) { + assertLog(typeof value === 'string', value); + this.value = value; + return this.value; + } + asString() { + return this.value; + } + asStringItem() { + return this.clone(); + } + asBool() { + return this.value !== ""; + } + cloneInstance() { + return new StringValue(this.value); + } + operatorEq(valueB) { + return new RuntimeItem.IntValue(this.asString() === valueB.asString() ? 1:0); + } + operatorAdd(valueB) { + return new StringValue(this.asString() + valueB.asString()); + } + eval(options = {}) { + return this.clone(); + } +} + +RuntimeItem.registerClass('StringValue', StringValue); +module.exports = StringValue; diff --git a/src/expression_items/subproofval.js b/src/expression_items/subproofval.js new file mode 100644 index 0000000..14c7cea --- /dev/null +++ b/src/expression_items/subproofval.js @@ -0,0 +1,12 @@ +const ProofItem = require("./proof_item.js"); +module.exports = class Subproofval extends ProofItem { + constructor (id) { + super(id); + } + getTag() { + return 'subproofvalue'; + } + cloneInstance() { + return new Subproofval(this.id); + } +} diff --git a/src/expression_items/value_item.js b/src/expression_items/value_item.js new file mode 100644 index 0000000..cbddb84 --- /dev/null +++ b/src/expression_items/value_item.js @@ -0,0 +1,40 @@ +const ExpressionItem = require("./expression_item.js"); +module.exports = class ValueItem extends ExpressionItem { + static directValue = true; + constructor (value) { + super(); + this.value = value; + } + get isBaseType () { + return true; + } + getValue() { + return this.value; + } + setValue(value) { + this.value = value; + } + dump() { + return `${this.constructor.name}(${this.value})`; + } + cloneInstance() { + const cloned = new ValueItem(this.value); + cloned.clonenNonConstructorProperties(this); + + } + asString() { + return this.value.toString(); + } + asStringType() { + return new ExpressionItem.StringValue(this.asString()); + } + eval(options = {}) { + return this.clone(); + } + toString() { + return `${this.value}`; + } + equals(value) { + return this.constructor.name === value.constructor.name && this.value === value.value; + } +} diff --git a/src/expression_items/witness_col.js b/src/expression_items/witness_col.js new file mode 100644 index 0000000..3c8cb63 --- /dev/null +++ b/src/expression_items/witness_col.js @@ -0,0 +1,17 @@ +const ProofItem = require("./proof_item.js"); +const {assert, assertLog} = require('../assert.js'); +const Context = require('../context.js'); +const Debug = require('../debug.js'); +module.exports = class WitnessCol extends ProofItem { + constructor (id) { + assertLog(typeof id !== 'undefined', id); + super(id); + if (Debug.active) console.log('CONSTRUCTOR_WITNESS', id, this.id); + } + getTag() { + return 'witness'; + } + cloneInstance() { + return new WitnessCol(this.id); + } +} diff --git a/src/expression_operations_info.js b/src/expression_operations_info.js new file mode 100644 index 0000000..7245948 --- /dev/null +++ b/src/expression_operations_info.js @@ -0,0 +1,33 @@ +module.exports = class ExpressionOperationsInfo { + static #operations = { + mul: { type: 'arith', label: '*', precedence: 96, args: 2, commutative: true }, + add: { type: 'arith', label: '+', precedence: 10, args: 2, commutative: true }, + sub: { type: 'arith', label: '-', precedence: 11, args: 2, commutative: false }, + pow: { type: 'arith', label: '**', precedence: 98, args: 2, commutative: false }, + neg: { type: 'arith', label: '-', precedence: 102, args: 1, commutative: false }, + div: { type: 'arith', label: '/', precedence: 94, args: 2, commutative: false }, + mod: { type: 'arith', label: '%', precedence: 92, args: 2, commutative: false }, + gt: { type: 'cmp', label: '>', precedence: 76, args: 2, commutative: false }, + ge: { type: 'cmp', label: '>=', precedence: 72, args: 2, commutative: false }, + lt: { type: 'cmp', label: '<', precedence: 78, args: 2, commutative: false }, + le: { type: 'cmp', label: '<=', precedence: 74, args: 2, commutative: false }, + eq: { type: 'cmp', label: '==', precedence: 66, args: 2, commutative: true }, + ne: { type: 'cmp', label: '!=', precedence: 64, args: 2, commutative: true }, + and: { type: 'logical', label: '&&', precedence: 46, args: 2, commutative: true }, + or: { type: 'logical', label: '||', precedence: 44, args: 2, commutative: true }, + shl: { type: 'bit', label: '<<', precedence: 86, args: 2, commutative: false }, + shr: { type: 'bit', label: '>>', precedence: 84, args: 2, commutative: false }, + band: { type: 'bit', label: '&', precedence: 58, args: 2, commutative: true }, + bor: { type: 'bit', label: '|', precedence: 56, args: 2, commutative: true }, + bxor: { type: 'bit', label: '^', precedence: 54, args: 2, commutative: true }, + not: { type: 'logical', label: '!', precedence: 100, args: 1, commutative: false }, + spread: { type: 'array', label: '...', precedence: 101, args: 1, commutative: false } + }; + + static get(operation) { + return ExpressionOperationsInfo.#operations[operation] ?? false; + } + static getUnitaryOperations() { + return Object.keys(this.#operations).filter(x => this.#operations[x].args === 1); + } +}; diff --git a/src/expression_operator_methods.js b/src/expression_operator_methods.js new file mode 100644 index 0000000..0031c8a --- /dev/null +++ b/src/expression_operator_methods.js @@ -0,0 +1,33 @@ +const util = require('util'); +const {assert} = require("chai"); +const ExpressionItem = require('./expression_items/expression_item.js'); +module.exports = class ExpressionOperatorMethods { + static operatorAddIntValue(valueA, valueB) { + let res = valueA.clone(); + let expressionB = valueA.emptyClone(); + expressionB._set(valueB); + res.insert('add', expressionB); + res.simplify(); + return res; + } + static #do(operation, valueA, valueB) { + let res = valueA.clone(); + res.insert(operation, valueB); + res.simplify(); + return res; + } + + static operatorAdd(valueA, valueB) { + return this.#do('add', valueA, valueB); + } + static operatorMul(valueA, valueB) { + return this.#do('mul', valueA, valueB); + } + static operatorSub(valueA, valueB) { + return this.#do('sub', valueA, valueB); + } + static operatorEqIntValue(valueA, valueB) { + let res = valueA.eval(); + return new ExpressionItem.IntValue(res.asInt() === valueB.asInt() ? 1n : 0n); + } +} diff --git a/src/expression_packer.js b/src/expression_packer.js new file mode 100644 index 0000000..9156983 --- /dev/null +++ b/src/expression_packer.js @@ -0,0 +1,109 @@ +const {assert, assertLog} = require('./assert.js'); +const Exceptions = require('./exceptions.js'); +const ExpressionItems = require('./expression_items.js'); +const Context = require('./context.js'); +const { DefinitionItem } = require('./definition_items.js'); + +module.exports = class ExpressionPacker { + constructor(container = false, expression = false) { + this.set(container, expression); + } + set(container, expression) { + this.container = container; + this.expression = expression; + } + packAlone(options) { + this.operandPack(this.expression.getAloneOperand(), 0, options); + return this.container.pop(1)[0]; + } + pack(options) { + let top = this.expression.stack.length-1; + return this.stackPosPack(top, options); + } + stackPosPack(pos, options) { + const st = this.expression.stack[pos]; + if (st.op === false) { + this.operandPack(st.operands[0], pos, options); + return this.container.pop(1)[0]; + } + for (const ope of st.operands) { + this.operandPack(ope, pos, options); + } + switch (st.op) { + case 'mul': + return this.container.mul(); + + case 'add': + return this.container.add(); + + case 'sub': + return this.container.sub(); + + case 'neg': + return this.container.neg(); + + default: + throw new Error(`Invalid operation ${st.op} on packed expression`); + } + } + + operandPack(ope, pos, options) { + if (ope instanceof ExpressionItems.ValueItem) { + this.container.pushConstant(ope.value); + } else if (ope instanceof ExpressionItems.ProofItem) { + this.referencePack(ope, options); + } else if (ope instanceof ExpressionItems.StackItem) { + const eid = this.stackPosPack(pos-ope.getOffset(), options); + if (eid !== false) { // eid === false => alone operand + this.container.pushExpression(eid); + } + } else { + const opeType = ope instanceof Object ? ope.constructor.name : typeof ope; + throw new Error(`Invalid reference ${opeType} on packed expression`); + } + + } + referencePack(ope, options) { + // TODO stage expression + // container.pushExpression(Expression.parent.getPackedExpressionId(id, container, options)); + // break; + const id = ope.getId(); + console.log(options); + const def = Context.references.getDefinitionByItem(ope, options); + console.log(ope); + console.log(def); + assert(typeof def === 'object') + console.log(def instanceof ExpressionItems.ExpressionItem, DefinitionItem.prototype.constructor.name, Object.getPrototypeOf(def.constructor).name); + assert(def instanceof DefinitionItem); + if (ope instanceof ExpressionItems.WitnessCol) { + // container.pushWitnessCol(id, next ?? 0, stage ?? 1) + console.log(ope); + // CURRENT ERROR: in this scope definition not available. + console.log(def); + this.container.pushWitnessCol(id, ope.getRowOffset(), def.stage); + + } else if (ope instanceof ExpressionItems.FixedCol) { + // container.pushFixedCol(id, next ?? 0); + this.container.pushFixedCol(id, ope.getRowOffset()); + + } else if (ope instanceof ExpressionItems.Public) { + // container.pushPublicValue(id) + this.container.pushPublicValue(id); + + } else if (ope instanceof ExpressionItems.Challenge) { + // container.pushChallenge(id, stage ?? 1); + this.container.pushChallenge(id, def.stage); + + } else if (ope instanceof ExpressionItems.Proofval) { + // container.pushProofValue(id) + this.container.pushProofValue(id); + + } else if (ope instanceof ExpressionItems.Subproofval) { + // container.pushSubproofValue(id) + const def = Context.references.getDefinitionByItem(ope); + this.container.pushSubproofValue(def.relativeId, def.subproofId); + } else { + throw new Error(`Invalid reference class ${ope.constructor.name} to pack`); + } + } +} diff --git a/src/expression_variables.js b/src/expression_variables.js new file mode 100644 index 0000000..aa661a8 --- /dev/null +++ b/src/expression_variables.js @@ -0,0 +1,13 @@ +const {assert, assertLog} = require('./assert.js'); +const Variables = require("./variables.js"); +const ExpressionReference = require('./expression_items/expression_reference.js'); + +module.exports = class ExpressionVariables extends Variables { + + constructor (type, definitionClass, expressionItemClass, options) { + super(type, definitionClass, expressionItemClass, options); + } + getConstItem(id, properties) { + return new ExpressionReference(id, this.getItem(id, properties)); + } +} \ No newline at end of file diff --git a/src/expressions.js b/src/expressions.js index 624e8d1..8a5bd94 100644 --- a/src/expressions.js +++ b/src/expressions.js @@ -1,21 +1,15 @@ const util = require('util'); const LabelRanges = require('./label_ranges.js'); const Expression = require('./expression.js'); -const WitnessCol = require('./pil_items/witness_col.js'); +const WitnessCol = require('./expression_items/witness_col.js'); const NonRuntimeEvaluable = require('./non_runtime_evaluable.js'); - +const ExpressionPacker = require('./expression_packer.js'); +const Context = require('./context.js'); module.exports = class Expressions { - - constructor (Fr, parent, references, publics, constants) { - this.Fr = Fr; + constructor () { this.expressions = []; this.packedIds = []; - this.references = references; - this.constants = constants; - this.parent = parent; - this.context = parent.context; this.labelRanges = new LabelRanges(); - Expression.setParent(this); } clone() { let cloned = Object.assign(Object.create(Object.getPrototypeOf(this)), this); @@ -68,31 +62,6 @@ module.exports = class Expressions { insert(e) { return this.expressions.push(e) - 1; } - __toString(e) { - console.log(util.inspect(e, false, null, true /* enable colors */)) - } - - // update mode - ____eval(e, fr = false) { - if (e.op in this.operations) { - const operation = this.operations[e.op]; - const [a,b,reduced] = this.evaluateValues(e, operation.args, fr); - if (reduced) { - if (typeof a.value !== 'bigint' || typeof b.value !== 'bigint') { - throw new Error(`ERROR evaluating operation: ${a.value}[${typeof a.value}] ${operation} on ${b.value}[${typeof b.value}]`); - } - return { op: 'number', - value: fr ? operation.handleFr(fr, a.value, b.value) : operation.handle(a.value, b.value) }; - } - if (e.op === 'pow') { - // TODO: check last Scalar. - // return {simplified:true, op: "number", deg:0, value: Fr.toString(Fr.exp(Fr.e(a.value), Scalar.e(b.value))), first_line: e.first_line} - this.error(e, "Exponentiation can only be applied between constants"); - } - return e; - } - return this.router.go([e, fr]); - } checkExpression(e) { if (typeof e === 'undefined' || e.expr || !(e instanceof Expression)) { console.log(e) @@ -103,16 +72,6 @@ module.exports = class Expressions { eval(e) { return this.checkExpression(e).eval(); } - evalOperand(operand, values) { - switch (operand.type) { - case 0: - return BigInt(operand.value); - case 3: - return this.evalRuntime(operand.value); - } - console.log(operand); - EXIT_HERE; - } evalRuntime(operand, expr, deeply) { // TODO: if not runtime evaluable return null or const op = operand.op; @@ -123,110 +82,15 @@ module.exports = class Expressions { case 'idref': return this._evalIdref(operand); case 'reference': return this._evalReference(operand, expr, deeply); } + console.log(operand); + return operand.eval(); throw new Error(`Invalid runtime operation ${op}`); } - _evalString(e) { - if (e.template) return this.parent.evaluateTemplate(e.value); - return e.value; - } - eval2(e, pos, values) { - let st = e.stack[pos]; - let res; - switch (st.op) { - case false: - res = this.evalOperand(st.operands[0], values) - break; - default: - console.log(st); - EXIT_HERE; - } - values[pos] = res; - } - _evalNumber(e, fr) { - return e; - } - _evalCall(e) { - return this.parent.execCall(e); - } - _evalIdref(e) { - if (e.array) { - return e; - } - return this.evalReferenceValue(this.references.getIdRefValue(e.refType, e.id)); - } evalReference(e) { const ref = this.evalReferenceValue(e); console.log(ref); EXIT_HERE; } - evalReferenceValue(ref) { - let res = ref; - switch (ref.type) { - case 'fixed': - // DUAL, if access row was a value, if not it's an id - // TODO - if (typeof res.row === 'undefined') { - res = {refType: 'fixed', id: res.id}; - } else { - // e.parent.fixedRowAccess = true; - res = res.value.getValue(res.row); - } - if (ref.next) res.next = ref.next; - break; - case 'challenge': - res = {refType: ref.type, id: ref.id }; - break; - case 'witness': - if (res.value instanceof WitnessCol) { - res = {refType: ref.type, id: res.value.id }; - if (ref.next) res.next = ref.next; - } - break; - case 'public': - case 'proofvalue': - case 'subproofvalue': - res = {refType: ref.type, id: res.id }; - break; - case 'im': - // TODO: review next, prior - res = {...res, value: res.id}; - break; - case 'fe': - res = { op: 'number', value: BigInt(ref.value) }; - break; - case 'constant': - if (!res.array) { - res = (typeof ref.value === 'number' ? BigInt(ref.value) : ref.value); - } - break; - case 'int': - res = (typeof ref.value === 'number' ? BigInt(ref.value) : ref.value); - break; - case 'string': - res = (typeof ref.value === 'string' ? ref.value : ''); - break; - case 'expr': - if (ref.value instanceof Expression) { - res = ref.value.eval(); - if (res instanceof Expression) { - res = res.instance({simplify: true}); - } else if (res instanceof NonRuntimeEvaluable) { - res = ref.value.instance({simplify: true}); - } - } else { - res = ref; - } - break; - - default: - console.log(ref); - throw new Error(`Invalid reference type: ${ref.type}`); - } - return res; - } - _evalReference(operand, expr, deeply) { - return this.evalReferenceValue(this.resolveReference(operand, deeply)); - } evaluateValues(e, valuesCount, fr) { // TODO: check valuesCount const a = this.eval(e.values[0], fr); @@ -254,9 +118,9 @@ module.exports = class Expressions { if (type === 'im') { return this.labelRanges.getLabel(id, options); } - return this.references.getLabel(type, id, options); + return Context.references.getLabel(type, id, options); } - resolveReference(operand, deeply = false) { + _resolveReference(operand, deeply = false) { const names = this.context.getNames(operand.name); let options = {}; @@ -275,7 +139,7 @@ module.exports = class Expressions { options.postDelta = -1n; } } - let res = this.references.getTypedValue(names, operand.__indexes, options); + let res = Context.references.getTypedValue(names, operand.__indexes, options); if (typeof operand.__next !== 'undefined') { res.__next = res.next = operand.__next; } else if (typeof operand.next !== 'number' && (operand.next || operand.prior)) { @@ -285,18 +149,22 @@ module.exports = class Expressions { } return res; } - getReferenceInfo(e, options) { + _getReferenceInfo(e, options) { const names = this.context.getNames(e.getAloneOperand().name); - return this.references.getTypeInfo(names, e.__indexes, options); + return Context.references.getTypeInfo(names, e.__indexes, options); } - e2num(e, s, title = '') { + _e2num(e, s, title = '') { + DEPRECATED; return this.e2types(e, s, title, ['number','bigint']); } - e2number(e, s, title = '') { + _e2number(e, s, title = '') { + DEPRECATED; let res = this.e2types(e, s, title, ['number','bigint'], false); return Number(res); } - e2types(e, s, title, types, toBigInt = true) { + _e2types(e, s, title, types, toBigInt = true) { + DEPRECATED; + // TODO: review specify PRE/POST on expression conversion ==> refactorize !!! let res = e; if (res instanceof Expression) { @@ -315,45 +183,32 @@ module.exports = class Expressions { // const res = e.expr && e.expr instanceof Expression ? e.expr.eval() : e; return this.getValueTypes(res, s, title, types, toBigInt); } - getValueTypes(e, s, title, types, toBigInt = true) { + _getValueTypes(e, s, title, types, toBigInt = true) { const etype = typeof e; if (types.includes(etype)) { return toBigInt && etype === 'number' ? BigInt(e) : e; } this.error(s, (title ? ' ':'') + `is not constant expression (${etype}) (2)`); } - getValue(e, s, title = '') { + _getValue(e, s, title = '') { return this.getValueTypes(e, s, title, ['number','bigint','string']); } - e2value(e, s, title = '') { - return this.e2types(e, s, title, ['number','bigint','string']); - } - e2bool(e, s, title = '') { - let res = this.e2types(e, s, title, ['number','bigint','string']); - if (typeof res === 'string') { - return res !== ''; - } - if (typeof res === 'bigint') { - return res != 0n; - } - if (typeof res === 'number') { - return res != 0; - } - EXIT_HERE; - } pack(container, options) { this.packedIds = []; + const packer = new ExpressionPacker(); for (let id = 0; id < this.expressions.length; ++id) { if (typeof this.packedIds[id] !== 'undefined') continue; // already packed - const packedId = this.expressions[id].pack(container, options); + this.expressions[id].dump('PACK-EXPRESSION '); + packer.set(container, this.expressions[id]); + this.packedIds[id] = packer.pack(options); // packedId === false, means directly was a alone term. - this.packedIds[id] = packedId; } } getPackedExpressionId(id, container, options) { + console.log(id, this.packedIds, this.packedIds[id]); if (container && typeof this.packedIds[id] === 'undefined') { - const packedId = this.expressions[id].pack(container, options); - this.packedIds[id] = packedId; + const packer = new ExpressionPacker(container, this.expressions[id]); + this.packedIds[id] = packer.pack(options); } return this.packedIds[id]; } @@ -366,7 +221,7 @@ module.exports = class Expressions { this.expressions[index].dump(`EXPRESSION ${index} # ${name}`, 3); } } - clear() { + clear(label = '') { this.expressions = []; this.packedIds = []; this.labelRanges = new LabelRanges(); diff --git a/src/fixed_cols.js b/src/fixed_cols.js index 4fe42e5..0cecec0 100644 --- a/src/fixed_cols.js +++ b/src/fixed_cols.js @@ -1,45 +1,35 @@ -const LabelRanges = require("./label_ranges.js"); const Indexable = require("./indexable.js"); -const FixedCol = require("./pil_items/fixed_col.js"); +const FixedColItem = require("./expression_items/fixed_col.js"); +const FixedCol = require("./definition_items/fixed_col.js"); +const {assert, assertLog} = require('./assert.js'); +const Context = require('./context.js'); module.exports = class FixedCols extends Indexable { - constructor (Fr) { - super(Fr, 'fixed'); + constructor () { + super('fixed', FixedCol, FixedColItem); } - - getEmptyValue(id, index) { + getEmptyValue(id) { return new FixedCol(id); } - - get(id, offset) { - return this.values[id + offset] - } - - getLabel(id, options) { - return this.labelRanges.getLabel(id, options); - } - - getTypedValue(id, offset = 0) { - const res = { type: this.type, value: this.values[id + offset] }; - return res; - } - - isDefined(id) { - return (typeof this.values[id] != 'undefined') - } - - define(id, value) { - if (this.isDefined(id)) { - throw new Error(`${id} already defined on ....`) + setRowValue(id, row, value) { + const item = this.get(id); + assertLog(item, {type: this.type, definition: this.definitionClass, id, item}); + if (typeof item.setRowValue !== 'function') { + console.log({type: this.type, definition: this.definitionClass, id, item}); + throw new Error(`Invalid assignation at ${Context.sourceTag}`); + } + item.setRowValue(row, value); + if (this.debug) { + console.log(`SET ${this.constructor.name}.${this.type} @${id} ${value}`); } - this.set(id, 0, value); } - - set(id, value, control) { - if (control) { - EXIT_HERE_ONLY_TWO_PARAMETERS; + getRowValue(id, row) { + const item = this.get(id); + assertLog(item, {type: this.type, definition: this.definitionClass, id, item}); + if (typeof item.getRowValue !== 'function') { + console.log({type: this.type, definition: this.definitionClass, id, item}); + throw new Error(`Invalid access at ${Context.sourceTag}`); } - // console.log([`SET@${this.type}[${id}]`, value]); - this.values[id].set(value); + return item.getRowValue(row); } } diff --git a/src/function.js b/src/function.js index 9b528fb..8bebd50 100644 --- a/src/function.js +++ b/src/function.js @@ -1,21 +1,45 @@ const util = require('util'); const {cloneDeep} = require('lodash'); +const {assert, assertLog} = require('./assert.js'); const {FlowAbortCmd, BreakCmd, ContinueCmd, ReturnCmd} = require("./flow_cmd.js"); const Expression = require("./expression.js"); +const ExpressionItems = require("./expression_items.js"); const List = require("./list.js"); +const Context = require('./context.js'); +const Debug = require('./debug.js'); +const Types = require('./types.js'); +const {ArrayOf} = require('./expression_items.js') module.exports = class Function { - - constructor (parent, s) { - this.parent = parent; - this.references = parent.references; - this.expressions = parent.expressions; - this.scope = parent.scope; - this.name = s.funcname; - if (s.args) { - this.defineArguments(s.args); - } - this.returns = s.returns ?? [] - this.statements = s.statements ?? []; + constructor (id, data = {}) { + this.id = id; + this.initialized = [data.args, data.returns, data.statements, data.funcname].some(x => typeof x !== 'undefined'); + this.name = data.funcname; + if (data.args) { + this.defineArguments(data.args); + } + this.returns = data.returns ?? [] + this.statements = data.statements ?? []; + this.sourceRef = data.sourceRef; + } + setValue(value) { + if (Debug.active || value.name == 'multiset_assumes') { + console.log(`FUNCTION.setValue ${value.name}`, value.args); + } + if (this.initialized) { + throw new Error(`function it's initialized again`); + } + if (value instanceof Function === false) { + throw new Error(`Invalid value to setValue of function`); + } + this.initialized = value.initialized; + this.name = value.name; + // TODO: clone return types + this.args = {...value.args}; + if (Debug.active || value.name == 'multiset_assumes') { + console.log(`FUNCTION.setValue2 ${value.name}`, this.args); + } + this.returns = value.returns && Array.isArray(value.returns) ? [...value.returns] : value.returns; + this.statements = value.statements; } defineArguments(args) { this.args = {}; @@ -23,105 +47,312 @@ module.exports = class Function { const name = arg.name; if (name === '') throw new Error('Invalid argument name'); if (name in this.args) throw new Error(`Duplicated argument ${name}`); - this.args[name] = arg; - // console.log(['function', this.name, name, arg]); + // console.log('## BEGIN ARG DEFINITION ##'); + // console.log(arg); + // console.log('## END ARG DEFINITION ##'); + + this.args[name] = {type: arg.type, dim: arg.dim}; } } - mapArguments(s) { - // TODO: class o class-by-type to convert, cast, copy... between types - - /* - for (const arg of s.arguments) { - console.log(arg); - if (arg.stack && arg.stack[0]) { - console.log(arg.stack[0].operands); + // evaluate all called arguments on call scope before + // scope changes + evalArguments(args) { + let eargs = []; + let argslen = args.length ?? 0; + let argnames = Object.keys(this.args); + for (let iarg = 0; iarg < argslen; ++iarg) { + const argname = argnames[iarg] ?? 'undef'; + if (Debug.active) { + console.log(`FUNC.evalArguments ${this.name}.args[${iarg}](${argname})`, this.args[argname]); } + const arg = args[iarg]; + const _argInstanced = arg.instance({unroll: true}); + eargs.push(_argInstanced); + } + if (Debug.active) { + console.log('ARGUMENTS '+eargs.map(x => x.toString()).join(',')); + } + return eargs; + } + // mapArgument was called before enter on function visibility scope because + // inside function args "values" aren't visible. + mapArguments(s) { + if (Debug.active) console.log(s.args); + const eargs = this.evalArguments(s.args); + if (Debug.active) console.log(eargs); + const scall = this.callToString(eargs); + if (Debug.active) { + console.log(`FUNCTION.mapArguments(s.args) ${this.name}`); + console.log(util.inspect(s.args, false, null, true)); + console.log(`FUNCTION.mapArguments ${this.name}`); + console.log(util.inspect(eargs, false, null, true)); } - */ - // mapArgument was called before enter on function visibility scope because - // inside function arguments "values" aren't visible. + this.checkArgumentsTypes(eargs); + return {eargs, scall}; + } + // calculate a string to debug, with function name and list of arguments + // with its values + callToString(eargs) { let iarg = 0; + let textArgs = []; for (const name in this.args) { - // console.log(`MAP-ARGUMENTS ${this.name} (arg[${iarg}]: ${name})`); - const arg = this.args[name]; - // TODO: arrays and pol references ... - let type = arg.type; - const argDim = arg.dim ? arg.dim : 0; - if (arg.reference) { - // console.log(`${this.name}.MAP-REFERENCE`); - const ref = s.arguments[iarg].getReference(); + textArgs.push(name + ': ' + eargs[iarg].toString()); + ++iarg; + } + return this.name + '(' + textArgs.join(', ') + ')'; + } - // special case of col, could be witness, fixed or im - if (type === 'col') { - type = this.parent.references.getReferenceType(ref.name); - } - const dim = ref.array ? ref.array.dim : 0; - if (dim !== argDim) { - console.log(type); - console.log(ref); - console.log(argDim); - console.log(s.arguments[iarg].getAloneOperand()); - throw new Error(`Invalid array on ${this.parent.sourceRef}`); + // to check arguments used in call, checks if its types and dimensions match with + // the arguments defined on function + checkArgumentsTypes(args) { + let iarg = 0; + for (const name in this.args) { + // TODO: checking types and dims + /* + if (Array.isArray(args[iarg])) { + for (const arg of args[iarg]) { + arg.dump(); } - this.parent.declareReference(name, type, ref.array ? ref.array.lengths : []); - this.parent.references.setReference(name, ref); - } else if (arg.type === 'int' || arg.type === 'fe') { - if (argDim) { - s.arguments[iarg].eval(); - const ref = s.arguments[iarg].getReference(); - console.log(ref); - console.log(ref.name); - const def = this.references.getDefinition(ref.name); - const dup = def.array.applyIndex(def, ref.__indexes ?? []); + } else { + args[iarg].dump(); + }*/ + ++iarg; + } + } + getArgumentsReferences(args) { + EXIT_HERE; + let iarg = 0; + let extraInfo = ''; + for (const name in this.args) { + try { + const arg = this.args[name]; + if (name === 'cols') debugger; + // TODO: arrays and pol references ... + let type = arg.type; + const argDim = arg.dim ? arg.dim : 0; + if (arg.reference) { + assert(false); + // console.log(`${this.name}.MAP-REFERENCE`); + const ref = s.args[iarg].getReference(); - if (dup.array.dim !== argDim) { - console.log(dup.array.dim, argDim); - throw new Error(`Invalid array on ${this.parent.sourceRef}`); + // special case of col, could be witness, fixed or im + if (type === 'col') { + type = Context.references.getReferenceType(ref.name); + } + const dim = ref.array ? ref.array.dim : 0; + if (dim !== argDim) { + console.log(type); + console.log(ref); + console.log(argDim); + console.log(s.args[iarg].getAloneOperand()); + throw new Error(`Invalid array on ${Context.sourceRef}`); } + Context.processor.declareReference(name, type, ref.array ? ref.array.lengths : []); + Context.references.setReference(name, ref); + } else if (arg.type === 'int' || arg.type === 'fe') { + if (argDim) { + s.args[iarg].eval(); + const ref = s.args[iarg].getReference(); + if (Debug.active) console.log(ref); + if (Debug.active) console.log(ref.name); + const def = Context.references.getDefinition(ref.name); + const dup = def.array.applyIndexes(def, ref.__indexes ?? []); - this.parent.declareReference(name, type, dup.array ? dup.array.lengths: [], {}); - } else { - const value = this.parent.expressions.eval(s.arguments[iarg]); - // TODO: review? no referece? - this.parent.declareReference(name, type, value.array ? value.array.lengths: [], {}, value); - } - } else { - // console.log(`MAP-${arg.type}`); - // TODO: type conversion, mapping in other class - if (s.arguments[iarg].type === 'expression_list') { - // check (argDim === 1 && arg.type === 'expr') - const list = new List(this, s.arguments[iarg], false); - const values = s.arguments[iarg].values; - this.parent.declareReference(name, type, [values.length], {}); - let index = 0; - for (const value of list.values) { - // console.log(value); - this.parent.references.set(name, [index++], value instanceof Expression ? value.instance() : value); + if (dup.array.dim !== argDim) { + console.log(dup.array.dim, argDim); + throw new Error(`Invalid array on ${Context.processor.sourceRef}`); + } + + Context.processor.declareReference(name, type, dup.array ? dup.array.lengths: [], {}); + } else { + if (Debug.active) console.log([name, iarg, s.args.length]); + const value = s.args[iarg].eval(); + // TODO: review? no referece? + Context.processor.declareReference(name, type, value.array ? value.array.lengths: [], {}, value); } - } else if (!(s.arguments[iarg] instanceof Expression)) { - console.log(arg); - console.log(s.arguments[iarg]); - EXIT_HERE; } else { - const value = s.arguments[iarg].instance().getAloneOperand(); - const dim = value.array ? value.array.dim : 0; - if (dim !== argDim) { - throw new Error(`Invalid array on ${this.parent.sourceRef}`); + // console.log(`MAP-${arg.type}`); + // TODO: type conversion, mapping in other class + if (Debug.active) console.log(s.args[iarg]); + if (s.args[iarg] instanceof ExpressionItems.ExpressionList) { + // check (argDim === 1 && arg.type === 'expr') + const list = new List(this, s.args[iarg], false); + const values = s.args[iarg].items; + Context.processor.declareReference(name, type, [values.length], {}); + let index = 0; + for (const value of list.values) { + extraInfo = index; + if (Debug.active) console.log(value); + Context.references.set(name, [index++], value instanceof Expression ? value.instance() : value); + } + } else if (argDim) { + if (Debug.active) console.log(s.args[iarg].eval()); + const ref = s.args[iarg].getReference(); + const def = Context.references.getDefinition(ref.name); + const dup = def.array.applyIndexes(def, ref.__indexes ?? []); + Context.processor.declareReference(name, type, dup.array.lengths, {}); + Context.processor.assign.assign(name, dup.array.lengths, s.args[iarg]); + } else if (!(s.args[iarg] instanceof Expression)) { + if (Debug.active) console.log(arg); + if (Debug.active) console.log([this.name, iarg, s.args[iarg], s.args.length]); + EXIT_HERE; + } else { + // const value = s.args[iarg].instance().getAloneOperand(); + // const value = s.args[iarg].getAloneOperand(); + // const value = s.args[iarg].getReference(); + if (Debug.active) console.log(util.inspect(s.args[iarg], false, 10, true)); + const value = s.args[iarg].evaluateAloneReference(); + if (Debug.active) console.log(util.inspect(s.args[iarg].eval(), false, 10, true)); + if (Debug.active) console.log(util.inspect(s.args[iarg].instance(), false, 10, true)); + const dim = value.array ? value.array.dim : 0; + if (dim !== argDim) { + throw new Error(`Invalid array on ${Context.sourceRef} ${dim} != ${argDim}`); + } + if (Debug.active) console.log(util.inspect(value, false, 10, true)); + Context.processor.declareReference(name, type, value.array ? value.array.lengths: [], {}, value); } - this.parent.declareReference(name, type, value.array ? value.array.lengths: [], {}, value); } + ++iarg; + } catch (e) { + console.log(`ERROR mapping parameter ${name} ${extraInfo} of function ${this.name} on ${Context.sourceRef}`); + throw e; } + } + return false; + } + declareAndInitializeArguments(eargs) { + Context.processor.sourceRef = this.sourceRef; + let iarg = 0; + for (const name in this.args) { + this.setArgument(name, eargs[iarg]); ++iarg; } + } + setArgument(name, value) { + const arg = this.args[name]; + if (Debug.active) { + console.log(name); + console.log(arg); + console.log(value.dim); + let values = Array.isArray(value) ? value : [value]; + for (const v of values) { + if (typeof v.dump === 'function') v.dump(`${this.name}(...${name}...) ${Context.sourceRef}`); + else console.log(v); + } + } + + let lengths = []; + if (value.array) { + lengths = value.array.lengths; + } else if (Array.isArray(value)) { + lengths = [value.length]; + } + + // REVIEW: use arg.type, but perphaps we need to do a casting + if (lengths.length !== arg.dim) { + console.log(arg); + console.log(value.dim); + throw new Error(`Invalid match dimensions on parameter ${name} (${lengths.length} !== ${arg.dim})`); + } + if (Debug.active) { + console.log(`${this.name}.${name} = ${value.constructor.name}`); + console.log('KKK2KKK', name, lengths, value.constructor.name, value.toString()); + } + Context.references.declare(name, arg.type, lengths, {sourceRef: this.sourceRef}, value); + if (Debug.active && name === '__cols') { + console.log(Context.references.get(name, [0])); + Context.references.get(name, [0]).value.dump('__cols[0]'); + console.log(Context.references.get(name, [1])); + Context.references.get(name, [1]).value.dump('__cols[1]'); + } + + // TODO: arrays. + /* + let type = arg.type; + const argDim = arg.dim ? arg.dim : 0; + } else if (arg.type === 'int' || arg.type === 'fe') { + if (argDim) { + s.args[iarg].eval(); + const ref = s.args[iarg].getReference(); + console.log(ref); + console.log(ref.name); + const def = Context.references.getDefinition(ref.name); + const dup = def.array.applyIndexes(def, ref.__indexes ?? []); + + if (dup.array.dim !== argDim) { + console.log(dup.array.dim, argDim); + throw new Error(`Invalid array on ${Context.processor.sourceRef}`); + } + + Context.processor.declareReference(name, type, dup.array ? dup.array.lengths: [], {}); + } else { + console.log([name, iarg, s.args.length]); + const value = s.args[iarg].eval(); + // TODO: review? no referece? + Context.processor.declareReference(name, type, value.array ? value.array.lengths: [], {}, value); + } + } else { + // console.log(`MAP-${arg.type}`); + // TODO: type conversion, mapping in other class + console.log(s.args[iarg]); + if (s.args[iarg] instanceof ExpressionItems.ExpressionList) { + // check (argDim === 1 && arg.type === 'expr') + const list = new List(this, s.args[iarg], false); + const values = s.args[iarg].items; + Context.processor.declareReference(name, type, [values.length], {}); + let index = 0; + for (const value of list.values) { + extraInfo = index; + console.log(value); + Context.references.set(name, [index++], value instanceof Expression ? value.instance() : value); + } + } else if (argDim) { + console.log(s.args[iarg].eval()); + const ref = s.args[iarg].getReference(); + const def = Context.references.getDefinition(ref.name); + const dup = def.array.applyIndexes(def, ref.__indexes ?? []); + Context.processor.declareReference(name, type, dup.array.lengths, {}); + Context.processor.assign.assign(name, dup.array.lengths, s.args[iarg]); + } else if (!(s.args[iarg] instanceof Expression)) { + console.log(arg); + console.log([this.name, iarg, s.args[iarg], s.args.length]); + EXIT_HERE; + } else { + // const value = s.args[iarg].instance().getAloneOperand(); + // const value = s.args[iarg].getAloneOperand(); + // const value = s.args[iarg].getReference(); + console.log(util.inspect(s.args[iarg], false, 10, true)); + const value = s.args[iarg].evaluateAloneReference(); + console.log(util.inspect(s.args[iarg].eval(), false, 10, true)); + console.log(util.inspect(s.args[iarg].instance(), false, 10, true)); + const dim = value.array ? value.array.dim : 0; + if (dim !== argDim) { + throw new Error(`Invalid array on ${Context.sourceRef} ${dim} != ${argDim}`); + } + console.log(util.inspect(value, false, 10, true)); + Context.processor.declareReference(name, type, value.array ? value.array.lengths: [], {}, value); + } + } + ++iarg; + } catch (e) { + console.log(`ERROR mapping parameter ${name} ${extraInfo} of function ${this.name} on ${Context.sourceRef}`); + throw e; + } + }*/ return false; } - exec(s, mapInfo) { - let res = this.parent.execute(this.statements, `FUNCTION ${this.name}`); + exec(callInfo, mapInfo) { + this.declareAndInitializeArguments(mapInfo.eargs); + if (Debug.active) console.log(Context.constructor.name); + let res = Context.processor.execute(this.statements, `FUNCTION ${this.name}`); if (res instanceof ReturnCmd) { - this.parent.traceLog('[TRACE-BROKE-RETURN]', '38;5;75;48;5;16'); + Context.processor.traceLog('[TRACE-BROKE-RETURN]', '38;5;75;48;5;16'); const resvalue = res.value.eval(); return resvalue; } return res; } + toString() { + return `[Function ${this.name}${this.args ? '(' + Object.keys(this.args).join(',') + ')': ''}]`; + } } diff --git a/src/ids.js b/src/ids.js index dcd7fdf..e187c9f 100644 --- a/src/ids.js +++ b/src/ids.js @@ -1,10 +1,14 @@ -const LabelRanges = require("./label_ranges.js"); +const LabelRanges = require('./label_ranges.js'); +const ExpressionItem = require('./expression_items/expression_item.js'); +const {assert,assertLog} = require('./assert.js'); module.exports = class Ids { - constructor (type) { + constructor (type, definitionClass, itemClass) { this.lastId = 0; this.datas = []; this.type = type; + this.definitionClass = definitionClass; + this.itemClass = itemClass; this.labelRanges = new LabelRanges(); } get length() { @@ -31,9 +35,13 @@ module.exports = class Ids { get(id, offset) { return this.getTypedValue(id, offset) } - getTypedValue(id, offset = 0) { - return { type: this.type, value: id + offset, data: this.datas[id + offset] }; + OBSOLETE; + return this.getItem(id, offset); + } + getItem(id, offset = 0) { + // return { type: this.type, value: id + offset, data: this.datas[id + offset] }; + return new this.itemClass(id + offset); } isDefined(id) { diff --git a/src/indexable.js b/src/indexable.js index 3a9dbfa..da1023a 100644 --- a/src/indexable.js +++ b/src/indexable.js @@ -1,11 +1,19 @@ const LabelRanges = require("./label_ranges.js"); +const {cloneDeep} = require('lodash'); +const {assert, assertLog} = require('./assert.js'); +const ExpressionItem = require('./expression_items/expression_item.js'); +const Debug = require('./debug.js'); +const Context = require('./context.js'); module.exports = class Indexable { - - constructor (Fr, type, rtype) { - this.Fr = Fr; + constructor (type, definitionClass, expressionItemClass, options = {}) { + this.expressionItemClass = expressionItemClass ?? false; + this.expressionItemConstClass = options.constClass ?? expressionItemClass; + this.definitionClass = definitionClass ?? false; this.values = []; this.type = type; - this.rtype = rtype ?? type; + this.options = options ?? {} + this.rtype = this.options.rtype ?? type; + assertLog(this.expressionItemClass.prototype instanceof ExpressionItem, expressionItemClass); this.labelRanges = new LabelRanges(); this.debug = false; } @@ -28,21 +36,29 @@ module.exports = class Indexable { return cloned; } - clear() { + clear(label = '') { + if (Debug.active) console.log(`CLEARING ${label} (${this.type})`); this.values = []; this.labelRanges = new LabelRanges(); } getType(id) { return this.rtype; } - getEmptyValue(id, data) { + getEmptyValue(id, data = {}) { + if (this.definitionClass) { + return new this.definitionClass(id, data); + } return null; } reserve(count, label, multiarray, data) { + if (this.type === 'subproofvalue' && Debug.active) { + console.log(['SUBPROOFVALUE-R', data]); + } const id = this.values.length; for (let index = 0; index < count; ++index) { const absoluteIndex = index + id; - this.values[absoluteIndex] = this.getEmptyValue(absoluteIndex, data); + const _label = label + (multiarray ? multiarray.offsetToIndexesString(index) : ''); + this.values[absoluteIndex] = this.getEmptyValue(absoluteIndex, {...data, label: _label}); if (this.debug) { console.log(`INIT ${this.constructor.name}.${this.type} @${absoluteIndex} (${id}+${index}) ${this.values[absoluteIndex]} LABEL:${label}`); } @@ -52,28 +68,53 @@ module.exports = class Indexable { } return id; } - + // get definition object get(id) { - const res = this.values[id] ?? this.undefined; - /* if (typeof res === 'number') { - console.log([id, this.type, res]); - throw new Error('Invalid value'); - }*/ - if (this.debug) { - console.log(`GET ${this.constructor.name}.${this.type} @${id} ${res}`); + let res = this.values[id]; + if (res === null) { + return this.getEmptyValue(id); } return res; } + getConstItem(id, properties) { + // by default getConstItem return same as getItem but with property const = true. + return this.getItem(id, {...properties, const: true}); + } + // get expression item to add in a expression + getItem(id, properties = {}) { + let res = this.values[id]; + const isConst = (properties.const && this.expressionItemConstClass); + const itemClass = isConst ? this.expressionItemConstClass : this.expressionItemClass; + if (Debug.active) { + console.log([id, itemClass.name, properties, this.expressionItemConstClass, res]); + console.log([id, itemClass.name, properties, this.expressionItemConstClass, res.constructor ? res.constructor.name :res.name, res.value ? res.value.constructor.name : '', res]); + } + if (isConst && typeof res.getConstItem === 'function') { + return res.getConstItem(); + } + if (typeof res.getItem === 'function') { + return res.getItem(); + } + if (!itemClass || res instanceof itemClass) { + return res; + } + if (typeof res.value !== 'undefined' && res.value instanceof itemClass) { + return res.value.clone(); + } + if (typeof res.value === 'undefined') { + if (this.expressionItemClass.createWithId) { + return new itemClass(id); + } + return new itemClass(); + } + assertLog(typeof itemClass.createFrom === 'function', [this.type, this.constructor.name, itemClass, res, res.value]); + return itemClass.createFrom(res.value, {id, instance: this}); + } getLabel(id, options) { return this.labelRanges.getLabel(id, options); } - getTypedValue(id) { - const res = { type: this.rtype, value: this.get(id) }; - return res; - } - isDefined(id) { return (typeof this.values[id] != 'undefined') } @@ -84,13 +125,19 @@ module.exports = class Indexable { } this.set(id, value); } - + getLastId() { + return this.values.length === 0 ? false : this.values.length - 1; + } + getNextId() { + return this.values.length; + } set(id, value) { - if (typeof value === 'number') { - console.log([id, this.type, value]); - throw new Error('Invalid value'); + const item = this.get(id); + assertLog(item, {type: this.type, definition: this.definitionClass, id, item}); + if (typeof item.setValue !== 'function') { + throw new Error(`Invalid assignation at ${Context.sourceRef}`); } - this.values[id] = value; + item.setValue(value); if (this.debug) { console.log(`SET ${this.constructor.name}.${this.type} @${id} ${value}`); } @@ -104,7 +151,7 @@ module.exports = class Indexable { *[Symbol.iterator]() { for (let index = 0; index < this.values.length; ++index) { - yield this.values[index] ?? this.undefined; + yield this.get(index); } } @@ -130,4 +177,44 @@ module.exports = class Indexable { console.log(`${index}: ${this.values[index]}`); } } + countByProperty(property) { + let res = {}; + for (let index = 0; index < this.values.length; ++index) { + const value = this.get(index); + const key = value[property]; + res[key] = (res[key] ?? 0) + 1; + } + return res; + } + getPropertyValues(property) { + let res = []; + let isArray = Array.isArray(property); + const properties = isArray ? property : [property]; + for (let index = 0; index < this.values.length; ++index) { + let value; + let pvalues = []; + for (const _property of properties) { + const definition = this.get(index); + if (Debug.active) console.log(definition); + value = _property === 'id' ? definition.id ?? index : definition[_property]; + if (isArray) { + pvalues.push(value); + } + } + res.push(isArray ? pvalues : value); + } + return res; + } + getPropertiesString(properties, options = {}) { + let res = []; + for (let index = 0; index < this.values.length; ++index) { + const definition = this.get(index); + let propValues = []; + for (const property of properties) { + propValues.push(definition[property] ?? ''); + } + res.push(this.getLabel(id)+'@'+id+':'+propValues.join(',')); + } + return res.join('#'); + } } diff --git a/src/iterator.js b/src/iterator.js index 799976e..9141f47 100644 --- a/src/iterator.js +++ b/src/iterator.js @@ -1,4 +1,5 @@ const Expression = require("./expression.js"); +const {assert, assertLog} = require('./assert.js'); module.exports = class Iterator { @@ -7,13 +8,15 @@ module.exports = class Iterator { } setExpression(expr) { console.log(expr); - if (expr instanceof Expression === false || expr.isReference() === false) { + if ((expr instanceof Expression) === false || expr.isReference() === false) { throw new Error(`Invalid iterator`); } this.index = 0; - this.expr = expr.instance(); - this.reference = this.expr.getReference(); - this.count = this.reference.array.getLength(0); + this.expr = expr.eval(); + console.log(this.expr); + assertLog(this.expr.array, this.expr); + // this.reference = this.expr.getReference(); + // this.count = this.reference.array.getLength(0); } goFirst() { this.index = 0; @@ -42,7 +45,7 @@ module.exports = class Iterator { } getValue() { - return this.reference.array.applyIndex(this.reference, [this.index]); + return this.expr.array.applyIndexes(this.expr, [this.index]); } *[Symbol.iterator]() { diff --git a/src/label_ranges.js b/src/label_ranges.js index 30d72fe..8ec5d85 100644 --- a/src/label_ranges.js +++ b/src/label_ranges.js @@ -35,6 +35,11 @@ module.exports = class LabelRanges { } return cloned; } + dump() { + for (const range of this.ranges) { + console.log(`[${range.from}-${range.to}] ${range.label}`); + } + } *[Symbol.iterator]() { for (let index = 0; index < this.ranges.length; ++index) { diff --git a/src/list.js b/src/list.js index 3512d9f..3dbdbc5 100644 --- a/src/list.js +++ b/src/list.js @@ -1,6 +1,7 @@ +const Context = require('./context.js'); const Router = require("./router.js"); const Expression = require("./expression.js"); - +const {ExpressionList} = require('./expression_items.js'); module.exports = class List { // TODO: Review compiler estructures @@ -29,6 +30,14 @@ module.exports = class List { if (e instanceof Expression) { return this._extendExpr(e); } + if (e instanceof ExpressionList) { + let res = []; + for (const item of e.items) { + res.push(this._resolve(item)); + } + return res; + } + console.log(e); return this.router.go(e); } _extendAppend(e) { @@ -61,7 +70,7 @@ module.exports = class List { _extendAppendReferences(e) { console.log("================= appendReferences =================="); let values = []; - const info = Expression.parent.getReferenceInfo(e.value); + const info = Context.expressions.getReferenceInfo(e.value); let element = e.value.instance().getAloneOperand(); if (!element.array || element.array.dim < 1) { throw new Error(`Could not extend and append a non array element`) diff --git a/src/multi_array.js b/src/multi_array.js index ead76e0..02b28a7 100644 --- a/src/multi_array.js +++ b/src/multi_array.js @@ -1,12 +1,59 @@ - -const {cloneDeep} = require('lodash'); +const {assert, assertLog} = require('./assert.js'); +const Debug = require('./debug.js'); class MultiArray { - constructor (lengths, debug) { - this.debug = debug || ''; + static ErrorIndexOutOfRange = class extends Error { + } + constructor (lengths, options = {}) { + // baseOffset is accumulated offset, means parentOffset + new offset. + this.baseOffset = options.baseOffset ?? 0; + assertLog(Array.isArray(lengths), lengths); + assertLog(lengths.every(x => typeof x === 'number'), lengths); this.initOffsets(lengths); + + // if parentInitizalized means need to extract + if (options.parentInitialized) { + // calculate relative offset from parent because initialized contains only + // parent initialized values. + const offset = this.baseOffset - options.parentOffset ?? 0; + this.initialized = options.parentInitialized.slice(offset, offset + this.size); + } else { + this.initialized = options.initialized ?? []; + } + } + toDebugString() { + return '['+ this.lengths.join(',')+']'; } clone() { - return new MultiArray(this.lengths, this.debug); + const cloned = new MultiArray(this.lengths, { + baseOffset: this.baseOffset, + initialized: [...this.initialized]}); + return cloned; + } + createSubArray(indexes, locatorOffset, from = false, to = false) { + let [offset, dims] = this.getIndexesOffset(indexes); + const dim = this.offsets.length - dims; + let _lengths = this.lengths.slice(-dim); + if (from !== false || to !== false) { + assert(dim === 1); + if (to === false) { + assert(from < _lengths[0]); + _lengths[0] = _lengths[0] - to; + offset += to + } else if (from === false) { + assert(to < _lengths[0]); + _lengths[0] = to + 1; + } else { + assert(to < _lengths[0] && from < _lengths[0] && from <= to); + _lengths[0] = to - from + 1; + offset += from + } + console.log(this.lengths, dim, _lengths, offset, from, to); + } + const cloned = new MultiArray(_lengths, { + baseOffset: this.baseOffset + offset + locatorOffset, + parentOffset: this.baseOffset, + parentInitialized: this.initialized }); + return cloned; } checkIndexes(indexes) { if (indexes === null || typeof indexes === 'undefined') { @@ -21,9 +68,17 @@ class MultiArray { } } } - getIndexesOffset(indexes) { + getLocator(baseLocator, indexes = []) { + const offset = this.indexesToOffset(indexes); + return baseLocator + offset; + } + // review + __getIndexesOffset(indexes) { return this.getIndexesTypedOffset(indexes).offset; } + offsetToIndexesString(offset) { + return '['+this.offsetToIndexes(offset).join('][')+']'; + } offsetToIndexes(offset) { let level = 0; let indexes = []; @@ -35,11 +90,11 @@ class MultiArray { } return indexes; } - createSubArray(dim) { - return new MultiArray(this.lengths.slice(-dim)); - } - applyIndex(obj, indexes) { + applyIndexes(obj, indexes) { const res = this.getIndexesTypedOffset(indexes); + if (res.array === false && typeof obj.getItem === 'function') { + return obj.getItem(indexes); + } let dup = obj.clone() if (dup.id) { dup.id = dup.id + res.offset; @@ -49,9 +104,28 @@ class MultiArray { } return dup; } + isFullIndexed(indexes) { + return (indexes.length === this.dim); + } + locatorIndexesApply(locatorId, indexes) { + if (Debug.active) console.log([locatorId, indexes, this.dim, this.lengths]); + const [offset, dims] = this.getIndexesOffset(indexes); + if (Debug.active) console.log([offset, dims]); + if ((this.dim - dims) > 0) { + throw new Error(`ERROR ON ARRAY ${offset} ${dims} ${this.dim}`); + } + return locatorId + offset; + } + indexesToOffset(indexes) { + assert(indexes && Array.isArray(indexes)); + const [offset, dim] = this.getIndexesOffset(indexes); + assert(this.offsets.length === indexes.length); + return offset; + } getIndexesOffset(indexes) { if (indexes === null || typeof indexes === 'undefined') { // TODO: review + EXIT_HERE; return {offset: 0, array: this.createSubArray(this.offsets.length)}; } let offset = 0; @@ -60,7 +134,7 @@ class MultiArray { if (Number(indexes[idim]) >= this.lengths[idim]) return [false, idim]; offset += this.offsets[idim] * Number(indexes[idim]); } - return [offset, dims]; + return [offset + this.baseOffset, dims]; } isValidIndexes(indexes) { const [offset, dims] = this.getIndexesOffset(indexes); @@ -78,6 +152,7 @@ class MultiArray { if (dim === 0) { return {offset, array: false}; } + EXIT_HERE; // return {offset, dim, lengths: dim ? this.lengths.slice(-dim):[], array: this.createSubArray(dim)}; return {offset, array: this.createSubArray(dim)}; } @@ -105,10 +180,14 @@ class MultiArray { getLength(dim = 0) { return this.lengths[dim] ?? 0; } + isInitialized(indexes) { + const offset = this.indexesToOffset(indexes); + return this.initialized[offset] ?? false; + } + markAsInitialized(indexes) { + const offset = this.indexesToOffset(indexes); + this.initialized[offset] = true; + } } -class ErrorIndexOutOfRange extends Error { - -} - -module.exports = { MultiArray, ErrorIndexOutOfRange }; +module.exports = MultiArray; diff --git a/src/packed_expressions.js b/src/packed_expressions.js index 31a057d..6a1cb65 100644 --- a/src/packed_expressions.js +++ b/src/packed_expressions.js @@ -40,8 +40,8 @@ module.exports = class PackedExpressions { pushChallenge (idx, stage = 1) { this.values.push({challenge: {stage, idx}}); } - pushSubproofValue (idx) { - this.values.push({subproofValue: {idx}}); + pushSubproofValue (idx, subproofId) { + this.values.push({subproofValue: {idx, subproofId}}); } pushProofValue (idx) { this.values.push({proofValue: {idx}}); @@ -66,6 +66,7 @@ module.exports = class PackedExpressions { } exprToString(id, options) { const expr = this.expressions[id]; + console.log([id, expr, this.expressions.length]); const [op] = Object.keys(expr); let opes = []; for (const ope of Object.values(expr[op])) { @@ -120,20 +121,21 @@ module.exports = class PackedExpressions { } } - getLabel(type, id, options) { - options = options ?? {}; - const labels = options.labels; - const labelsByType = options.labelsByType; - let label; - if (labelsByType && typeof labelsByType[type] === 'object' && typeof labelsByType[type].getLabel === 'function') { - label = labelsByType[type].getLabel(id, options); - } else if (typeof labels === 'object' && typeof labels.getLabel === 'function') { - label = labels.getLabel(type, id, options); + getLabel(type, id, options = {}) { + const labelSources = [(options.labelsByType ?? {})[type], options.labels]; + let args = [id, options]; + for (const labels of labelSources) { + if (labels) { + if (typeof labels === 'function') { + return labels.apply(null, args); + } + if (typeof labels.getLabel === 'function') { + return labels.getLabel.apply(labels, args); + } + } + args.unshift(type); } - if (!label) { - label = `${type}@${id}`; - } - return label; + return label = `${type}@${id}`; } *[Symbol.iterator]() { diff --git a/src/pil.js b/src/pil.js index 796af5a..387df9d 100755 --- a/src/pil.js +++ b/src/pil.js @@ -6,17 +6,23 @@ const version = require("../package").version; const compile = require("./compiler.js"); const ffjavascript = require("ffjavascript"); const tty = require('tty'); +const debugConsole = require('./debug_console.js').init(); const argv = require("yargs") .version(version) .usage("pil -o [-P ]") + .alias("e", "exec") .alias("o", "output") .alias("P", "config") .alias("v", "verbose") .alias("I", "include") + .option("nofixed") + .alias("l", "lib") .alias("f", "includePathFirst") .argv; +Error.stackTraceLimit = Infinity; + async function run() { let inputFile; if (argv._.length == 0) { @@ -33,7 +39,7 @@ async function run() { const fileName = path.basename(fullFileName, ".pil"); const outputFile = typeof(argv.output) === "string" ? argv.output : fileName + ".json"; - const config = typeof(argv.config) === "string" ? JSON.parse(fs.readFileSync(argv.config.trim())) : {}; + let config = typeof(argv.config) === "string" ? JSON.parse(fs.readFileSync(argv.config.trim())) : {}; if (argv.verbose) { config.verbose = true; @@ -41,9 +47,18 @@ async function run() { config.color = tty.isatty(process.stdout.fd); } } - + if (argv.nofixed) { + config.fixed = false; + } + // only execute + if (argv.exec || argv.output === 'none') { + config.protoOut = false; + } const F = new ffjavascript.F1Field((1n<<64n)-(1n<<32n)+1n ); + if (argv.lib) { + config.includes = argv.lib.split(','); + } if (argv.include) { config.includePaths = argv.include.split(','); } @@ -51,6 +66,7 @@ async function run() { if (argv.includePathFirst) { config.includePathFirst = true; } + console.log(config); const out = await compile(F, fullFileName, null, config); console.log(out); /* @@ -66,39 +82,9 @@ async function run() { // await fs.promises.writeFile(outputFile.trim(), JSON.stringify(out, null, 1) + "\n", "utf8"); } -const originalMethod = console.log -const maxSourceRefLen = 20; -console.log = (...args) => { - let initiator = false; - try { - throw new Error(); - } catch (e) { - if (typeof e.stack === 'string') { - let isFirst = true; - for (const line of e.stack.split('\n')) { - const matches = line.match(/^\s+at\s+.*\/([^\/:]*:[0-9]+:[0-9]+)\)/); - if (matches) { - if (!isFirst) { // first line - current function - // second line - caller (what we are looking for) - initiator = matches[1]; - break; - } - isFirst = false; - } - } - } - } - if (initiator === false) { - originalMethod.apply(console, args); - } else { - initiator = initiator.split(':').slice(0,2).join(':').replace('.js',''); - initiator = initiator.length > maxSourceRefLen ? ('...' + initiator.substring(-maxSourceRefLen+3)) : initiator.padEnd(maxSourceRefLen); - originalMethod.apply(console, [`\x1B[30;104m${initiator} \x1B[0m`, ...args]); - } -} run().then(()=> { - process.exit(0); + process.exitCode = 0; }, (err) => { console.log(err.stack); if (err.pos) { @@ -106,5 +92,5 @@ run().then(()=> { } else { console.log(err.message); } - process.exit(1); + process.exitCode = 1; }); diff --git a/src/pil_items/fixed_col.js b/src/pil_items/fixed_col.js deleted file mode 100644 index 600d16c..0000000 --- a/src/pil_items/fixed_col.js +++ /dev/null @@ -1,40 +0,0 @@ -const LabelRanges = require("../label_ranges.js"); -const Sequence = require("../sequence.js"); -const PilItem = require("../pil_item.js"); -module.exports = class FixedCol extends PilItem { - constructor (id) { - super(id); - this.rows = 0; - this.sequence = null; - this.values = []; - this.fullFilled = false; - } - getId() { - return this.id; - } - isPeriodic() { - return this.rows > 0; - } - getValue(row) { - if (this.sequence === null) { - return this.values[row] - } - return this.sequence.getValue(row); - } - set(value) { - if (value instanceof Sequence) { - if (this.sequence !== null) { - EXIT_HERE; - } - if (this.values.length > 0) { - EXIT_HERE; - } - this.sequence = value; - this.rows = this.sequence.values.length; - } - else { - console.log(value); - EXIT_HERE; - } - } -} diff --git a/src/pil_items/proofvalue.js b/src/pil_items/proofvalue.js deleted file mode 100644 index 38efd82..0000000 --- a/src/pil_items/proofvalue.js +++ /dev/null @@ -1,10 +0,0 @@ -const LabelRanges = require("../label_ranges.js"); -const PilItem = require("../pil_item.js") -module.exports = class Proofvalue extends PilItem { - constructor (id) { - super(id); - } - getId() { - return this.id; - } -} diff --git a/src/pil_items/public.js b/src/pil_items/public.js deleted file mode 100644 index 58636d0..0000000 --- a/src/pil_items/public.js +++ /dev/null @@ -1,10 +0,0 @@ -const LabelRanges = require("../label_ranges.js"); -const PilItem = require("../pil_item.js") -module.exports = class Public extends PilItem { - constructor (id) { - super(id); - } - getId() { - return this.id; - } -} diff --git a/src/pil_items/publictable.js b/src/pil_items/publictable.js deleted file mode 100644 index 39b33ed..0000000 --- a/src/pil_items/publictable.js +++ /dev/null @@ -1,10 +0,0 @@ -const LabelRanges = require("../label_ranges.js"); -const PilItem = require("../pil_item.js") -module.exports = class PublicTable extends PilItem { - constructor (id) { - super(id); - } - getId() { - return this.id; - } -} diff --git a/src/pil_items/subproofvalue.js b/src/pil_items/subproofvalue.js deleted file mode 100644 index c031123..0000000 --- a/src/pil_items/subproofvalue.js +++ /dev/null @@ -1,10 +0,0 @@ -const LabelRanges = require("../label_ranges.js"); -const PilItem = require("../pil_item.js") -module.exports = class Subproofvalue extends PilItem { - constructor (id) { - super(id); - } - getId() { - return this.id; - } -} diff --git a/src/pil_items/witness_col.js b/src/pil_items/witness_col.js deleted file mode 100644 index eed7065..0000000 --- a/src/pil_items/witness_col.js +++ /dev/null @@ -1,11 +0,0 @@ -const LabelRanges = require("../label_ranges.js"); -const PilItem = require("../pil_item.js") -module.exports = class WitnessCol extends PilItem { - constructor (id, stage = 1) { - super(id); - this.stage = stage; - } - getId() { - return this.id; - } -} diff --git a/src/pil_parser.jison b/src/pil_parser.jison index c1e6ee4..f5f97d4 100644 --- a/src/pil_parser.jison +++ b/src/pil_parser.jison @@ -8,6 +8,7 @@ \s+ { /* skip whitespace */ } \/\*([^*]|[\r\n]|(\*+([^*/]|[\r\n])))*\*+\/ { /* console.log("MULTILINE COMMENT: "+yytext); */ } \/\/.* { /* console.log("SINGLE LINE COMMENT: "+yytext); */ } +\#pragma\s+[^\r\n]* { yytext = yytext.replace(/^#pragma\s+/, ''); return 'PRAGMA'; } col { return 'COL'; } witness { return 'WITNESS'; } @@ -61,6 +62,7 @@ return { return 'RETURN' } first { return 'FIRST' } last { return 'LAST' } frame { return 'FRAME' } +debugger { return 'DEBUGGER' } \.\.\+\.\. { return 'DOTS_ARITH_SEQ' } \.\.\*\.\. { return 'DOTS_GEOM_SEQ' } @@ -165,10 +167,12 @@ frame { return 'FRAME' } const DEFAULT_STAGE = 1; const util = require('util'); const Expression = require('../src/expression.js'); +const ExpressionFactory = require('../src/expression_factory.js'); function showcode(title, info) { console.log(title+` ${info.last_line}:${info.last_column}`); } +/* function runtime_expr(value) { let res = new Expression(); if (value.type) { @@ -186,8 +190,30 @@ function insert_expr(e, op, ...values) { // console.log(values); e.insert.apply(e, [op, ...values]); return e; -} +}*/ // console.log(`STATE ${state} ${(this.terminals_[symbol] || symbol)}`); +function implicit_scope(statements) { + if (Array.isArray(statements)) { + if (statements.length > 1) { + return {type: 'scope_definition', statements}; + } + statements = statements[0]; + } + if (typeof statements.type === 'undefined') { + return {type: 'scope_definition', ...statements}; + } + if (statements.type === 'code') { + statements.type = 'scope_definition'; + if (!Array.isArray(statements.statements)) { + statements.statements = [statements.statements]; + } + return statements; + } + if (statements.type === 'scope_definition') { + return statements; + } + return {type: 'scope_definition', statements}; +} %} %start all_top_level_blocks @@ -245,8 +271,17 @@ top_level_block | subproof_value_declaration { $$ = $1 } - | constant_definition +/* | constant_definition + { $$ = $1 } +*/ + | variable_declaration { $$ = $1 } + + | DEBUGGER + { $$ = { type: 'debugger' }} + + | PRAGMA + { $$ = { type: 'pragma', value: $1 }} ; use_directive @@ -559,9 +594,9 @@ declare_item | subproof_value_declaration { $$ = $1 } - | constant_definition +/* | constant_definition { $$ = $1 } - +*/ | variable_declaration { $$ = $1 } ; @@ -583,7 +618,7 @@ statement_no_closed { $$ = { type: 'constraint', left: $1, right: $3 } } | delayed_function_call - { $$ = {...$1, type: 'delayed_function_call'} } + { $$ = $1 } | include_directive { $$ = $1 } @@ -627,13 +662,13 @@ data_object { $$ = $1; $$.data[$3] = $5 } | data_object ',' IDENTIFIER - { $$ = $1; $$.data[$3] = runtime_expr({ type: 'expr', op: 'reference', next: false, name: $3 }) } + { $$ = $1; $$.data[$3] = ExpressionFactory.fromObject({type: 'reference', name: $3 }) } | IDENTIFIER ':' data_value { $$ = { type: 'object', data: {}}; $$.data[$1] = $3 } | IDENTIFIER - { $$ = { type: 'object', data: {}}; $$.data[$1] = runtime_expr({ type: 'expr', op: 'reference', next: false, name: $1 }) } + { $$ = {data: {}}; $$.data[$1] = ExpressionFactory.fromObject({type: 'reference', name: $1 }) } ; data_array @@ -646,7 +681,7 @@ data_array function_call : name_optional_index '(' multiple_expression_list ')' - { $$ = { op: 'call', function: $1, arguments: $3.values } } + { $$ = { type: 'call', function: $1, args: $3 } } ; delayed_function_event @@ -669,7 +704,7 @@ defined_scopes delayed_function_call : ON delayed_function_event defined_scopes name_optional_index '(' multiple_expression_list ')' - { $$ = { op: 'delayed_call', event: $2, scope: $3, function: $4, arguments: $6.values } } + { $$ = { type: 'delayed_function_call', event: $2, scope: $3, function: $4, args: $6 } } ; @@ -721,21 +756,28 @@ codeblock_closed { $$ = { ...$2, type: 'once', statements: $3 } } | SWITCH '(' expression ')' case_body - { $$ = $1 } + { $$ = { type: 'switch', value: $3, cases: $5.cases } } | IF '(' expression ')' non_delimited_statement %prec IF_NO_ELSE { $$ = {type:'if', conditions: [{type: 'if', expression: $3, statements: $5 }] } } | IF '(' expression ')' non_delimited_statement ELSE non_delimited_statement { $$ = { type:'if', conditions: [{type: 'if', expression: $3, statements: $5 }, {type: 'else', statements: $7}]} } + + | DEBUGGER + { $$ = { type: 'debugger' }} + + | PRAGMA + { $$ = { type: 'pragma', value: $1 }} + ; case_body : '{' case_list '}' { $$ = $2 } - | '{' case_list DEFAULT statement_list '}' - { $$ = $2; $$.cases.push({ else: true, statements: $4 }) } + | '{' case_list DEFAULT ':' statement_list '}' + { $$ = $2; $$.cases.push({ default: true, statements: implicit_scope($5) }) } ; case_value @@ -754,10 +796,10 @@ case_value case_list : case_list CASE case_value ':' statement_list_closed - { $$ = $1; $$.cases.push({condition: $3, statements: $5 }) } + { $$ = $1; $$.cases.push({condition: $3, statements: implicit_scope($5.statements) }) } | CASE case_value ':' statement_list_closed - { $$ = {cases: [{ condition: $2, statements: $4 }]} } + { $$ = {cases: [{ condition: $2, statements: implicit_scope($4.statements) }]} } ; for_assignation @@ -1060,30 +1102,35 @@ sequence multiple_expression_list : %empty %prec EMPTY - { $$ = {values: []} } + { $$ = ExpressionFactory.fromObject({ type: 'expression_list', values: [], __debug: 0 }); } | multiple_expression_list ',' expression %prec ',' - { $$ = $1; $$.values.push($3) } + { $$ = $1; $$.pushItem(ExpressionFactory.fromObject($3)); } | multiple_expression_list ',' '[' expression_list ']' %prec ',' - { $$ = $1; $$.values.push({ type: 'expression_list', values: $4.values }) } + { $$ = $1; $$.pushItem(ExpressionFactory.fromObject($4)); } +// { $$ = $1; $$.pushItem(ExpressionFactory.fromObject({ type: 'expression_list', values: $4.values, __debug: 1 })); } | '[' expression_list ']' %prec NO_EMPTY - { $$ = { type: 'expression_list', values: $2.values } } + { $$ = ExpressionFactory.fromObject({ type: 'expression_list', values: + [ExpressionFactory.fromObject($2)], __debug: 4}); } +// [ExpressionFactory.fromObject({ type: 'expression_list', values: [$2.values], __debug: 2})], __debug: 4}); console.log('A',$$) } | expression - { $$ = { type: 'expression_list', values: [$1] } } + { $$ = ExpressionFactory.fromObject({ type: 'expression_list', values: [$1], __debug: 3 }); } ; expression_list : expression_list ',' DOTS_FILL expression %prec ',' - { $$ = $1; $$.values.push({ type: 'append', value: $4 }) } +// { $$ = $1; $$.values.push({ type: 'append', value: $4 }) } + { $$ = $1; $$.values.push($4.insert('spread')) } | expression_list ',' expression %prec ',' { $$ = $1; $$.values.push($3) } | DOTS_FILL expression - { $$ = { type: 'expression_list', values: [{ type: 'append', value: $2}] } } +// { $$ = { type: 'expression_list', values: [{ type: 'append', value: $2}] } } + { $$ = { type: 'expression_list', values: [$2.insert('spread')] } } | expression { $$ = { type: 'expression_list', values: [$1] } } @@ -1218,115 +1265,116 @@ constant_definition /* */ expression : expression EQ expression - { $$ = insert_expr($1, 'eq', $3) } + { $$ = $1.insert('eq', ExpressionFactory.fromObject($3)) } | expression NE expression - { $$ = insert_expr($1, 'ne', $3) } + { $$ = $1.insert('ne', ExpressionFactory.fromObject($3)) } | expression LT expression - { $$ = insert_expr($1, 'lt', $3) } + { $$ = $1.insert('lt', ExpressionFactory.fromObject($3)) } | expression GT expression - { $$ = insert_expr($1, 'gt', $3) } + { $$ = $1.insert('gt', ExpressionFactory.fromObject($3)) } | expression LE expression - { $$ = insert_expr($1, 'le', $3) } + { $$ = $1.insert('le', ExpressionFactory.fromObject($3)) } | expression GE expression - { $$ = insert_expr($1, 'ge', $3) } + { $$ = $1.insert('ge', ExpressionFactory.fromObject($3)) } | expression IN expression %prec IN - { $$ = insert_expr($1, 'in', $3) } + { $$ = $1.insert('in', ExpressionFactory.fromObject($3)) } | expression IS return_type %prec IS - { $$ = insert_expr($1, 'is', runtime_expr({op: 'type', vtype: $3.type, dim: $3.dim})) } + { $$ = $1.insert('is', ExpressionFactory.fromObject({type: 'istype', vtype: $3.type, dim: $3.dim})); } | expression AND expression %prec AND - { $$ = insert_expr($1, 'and', $3) } + { $$ = $1.insert('and', ExpressionFactory.fromObject($3)) } | expression '?' expression ':' expression %prec '?' - { $$ = insert_expr($1, 'if', $3, $5) } + { $$ = $1.insert('if', [ExpressionFactory.fromObject($3), ExpressionFactory.fromObject($5)]) } +// { $$ = $1.insert('if', ExpressionFactory.fromObjects($3, $5)) } | expression B_AND expression %prec AND - { $$ = insert_expr($1, 'band', $3) } + { $$ = $1.insert('band', ExpressionFactory.fromObject($3)) } | expression B_OR expression %prec AND - { $$ = insert_expr($1, 'bor', $3) } + { $$ = $1.insert('bor', ExpressionFactory.fromObject($3)) } | expression B_XOR expression %prec AND - { $$ = insert_expr($1, 'bxor', $3) } + { $$ = $1.insert('bxor', ExpressionFactory.fromObject($3)) } | expression OR expression %prec OR - { $$ = insert_expr($1, 'or', $3) } + { $$ = $1.insert('or', ExpressionFactory.fromObject($3)) } | expression SHL expression %prec AND - { $$ = insert_expr($1, 'shl', $3) } + { $$ = $1.insert('shl', ExpressionFactory.fromObject($3)) } | expression SHR expression %prec OR - { $$ = insert_expr($1, 'shr', $3) } + { $$ = $1.insert('shr', ExpressionFactory.fromObject($3)) } | '!' expression %prec '!' - { $$ = insert_expr($2, 'not') } + { $$ = $2.insert('not') }) | expression '+' expression %prec '+' - { $$ = insert_expr($1, 'add', $3) } + { $$ = $1.insert('add', ExpressionFactory.fromObject($3)) } | expression '-' expression %prec '-' - { $$ = insert_expr($1, 'sub', $3) } + { $$ = $1.insert('sub', ExpressionFactory.fromObject($3)) } | expression '*' expression %prec '*' - { $$ = insert_expr($1, 'mul', $3) } + { $$ = $1.insert('mul', ExpressionFactory.fromObject($3)) } | expression '%' expression %prec '%' - { $$ = insert_expr($1, 'mod', $3) } + { $$ = $1.insert('mod', ExpressionFactory.fromObject($3)) } | expression '/' expression %prec '/' - { $$ = insert_expr($1, 'div', $3) } + { $$ = $1.insert('div', ExpressionFactory.fromObject($3)) } | expression '\\' expression %prec '\\' - { $$ = insert_expr($1, 'intdiv', $3) } + { $$ = $1.insert('intdiv', ExpressionFactory.fromObject($3)) } | expression POW expression %prec POW - { $$ = insert_expr($1, 'pow', $3) } + { $$ = $1.insert('pow', ExpressionFactory.fromObject($3)) } | '+' expression %prec UPLUS { $$ = $2 } | '-' expression %prec UMINUS - { $$ = insert_expr($2, 'neg') } + { $$ = $2.insert('neg') } - | name_id %prec EMPTY - { $$ = runtime_expr({ type: 'expr', op: 'reference', next: false, ...$1 }) } + | name_id + { $$ = ExpressionFactory.fromObject({ type: 'reference', ...$1 }) } | INC name_id - { $$ = runtime_expr({ type: 'expr', op: 'reference', next: false, ...$2, inc: 'pre'}) } + { $$ = ExpressionFactory.fromObject({ type: 'reference', ...$2, inc: 'pre'}) } | DEC name_id - { $$ = runtime_expr({ type: 'expr', op: 'reference', next: false, ...$2, dec: 'pre'}) } + { $$ = ExpressionFactory.fromObject({ type: 'reference', ...$2, dec: 'pre'}) } | name_id INC %prec INC_LEFT - { $$ = runtime_expr({ type: 'expr', op: 'reference', next: false, ...$1, inc: 'post'}) } + { $$ = ExpressionFactory.fromObject({ type: 'reference', ...$1, inc: 'post'}) } | name_id DEC %prec DEC_LEFT - { $$ = runtime_expr({ type: 'expr', op: 'reference', next: false, ...$1, dec: 'post'}) } + { $$ = ExpressionFactory.fromObject({ type: 'reference', ...$1, dec: 'post'}) } | NUMBER %prec EMPTY - { $$ = new Expression(); $$.setValue(BigInt($1)) } + { $$ = ExpressionFactory.fromObject({ type: 'number', value: BigInt($1)}) } | flexible_string %prec EMPTY - { $$ = runtime_expr({...$1, op: 'string'}) } + { $$ = ExpressionFactory.fromObject({...$1, type: 'string'}) } | '(' expression ')' { $$ = $2 } | function_call - { $$ = runtime_expr({...$1}) } + { $$ = ExpressionFactory.fromObject({...$1}) } | POSITIONAL_PARAM - { $$ = runtime_expr({position: $1, op: 'positional_param'}) } + { $$ = ExpressionFactory.fromObject({position: $1, type: 'positional_param'}) } | casting - { $$ = runtime_expr({...$1}) } + { $$ = ExpressionFactory.fromObject({...$1}) } ; @@ -1334,60 +1382,62 @@ expression casting : INT '(' expression ')' - { $$ = { op: 'cast', cast: 'int', value: $3} } + { $$ = { type: 'cast', cast: 'int', value: $3} } | FE '(' expression ')' - { $$ = { op: 'cast', cast: 'fe', value: $3 } } + { $$ = { type: 'cast', cast: 'fe', value: $3 } } | EXPR '(' expression ')' - { $$ = { op: 'cast', cast: 'expr', value: $3 } } + { $$ = { type: 'cast', cast: 'expr', value: $3 } } | COL '(' expression ')' - { $$ = { op: 'cast', cast: 'col', value: $3 } } + { $$ = { type: 'cast', cast: 'col', value: $3 } } | T_STRING '(' expression ')' - { $$ = { op: 'cast', cast: 'string', value: $3 } } + { $$ = { type: 'cast', cast: 'string', value: $3 } } | INT type_array '(' expression ')' - { $$ = { ...$2, op: 'cast', cast: 'int', value: $4 } } + { $$ = { ...$2, type: 'cast', cast: 'int', value: $4 } } | FE type_array '(' expression ')' - { $$ = { ...$2, op: 'cast', cast: 'fe', value: $4 } } + { $$ = { ...$2, type: 'cast', cast: 'fe', value: $4 } } | EXPR type_array '(' expression ')' - { $$ = { ...$2, op: 'cast', cast: 'expr', value: $4 } } + { $$ = { ...$2, type: 'cast', cast: 'expr', value: $4 } } | COL type_array '(' expression ')' - { $$ = { ...$2, op: 'cast', cast: 'col', value: $4 } } + { $$ = { ...$2, type: 'cast', cast: 'col', value: $4 } } | T_STRING type_array '(' expression ')' - { $$ = { ...$2, op: 'cast', cast: 'string', value: $4 } } + { $$ = { ...$2, type: 'cast', cast: 'string', value: $4 } } ; name_id : name_optional_index "'" %prec NEXT - { $$ = { ...$1, next:1 } } + { $$ = { ...$1, rowOffset: ExpressionFactory.fromObject({type: 'row_offset', value: 1, current: $1 }) } } | name_optional_index "'" NUMBER - { $$ = { ...$1, next: Number($3) } } + { $$ = { ...$1, rowOffset: ExpressionFactory.fromObject({type: 'row_offset', value: Number($3), current: $1 }) } } | name_optional_index "'" '(' expression ')' - { $$ = { ...$1, next:$4 } } + { $$ = { ...$1, rowOffset: ExpressionFactory.fromObject({type: 'row_offset', value: $4, current: $1 }) } } | name_optional_index "'" POSITIONAL_PARAM - { $$ = { ...$1, next: runtime_expr({position: $3, op: 'positional_param'}) } } + { $$ = { ...$1, rowOffset: ExpressionFactory.fromObject({type: 'row_offset', current: $1, + value: ExpressionFactory.fromObject({position: $3, type: 'positional_param'})}) } } | "'" name_optional_index %prec LOWER_PREC - { $$ = { ...$2, prior:1 } } + { $$ = { ...$2, rowOffset: ExpressionFactory.fromObject({type: 'row_offset', value: 1, prior: true, current: $2 }) } } | NUMBER "'" name_optional_index - { $$ = { ...$3, prior: Number($1) } } + { $$ = { ...$3, rowOffset: ExpressionFactory.fromObject({type: 'row_offset', value: Number($1), prior: true, current: $3 }) } } | '(' expression ')' "'" name_optional_index - { $$ = { ...$5, prior:$2 } } + { $$ = { ...$5, rowOffset: ExpressionFactory.fromObject({type: 'row_offset', value: $2, prior: true, current: $5 }) } } | POSITIONAL_PARAM "'" name_optional_index - { $$ = { ...$3, prior:runtime_expr({position: $1, op: 'positional_param'}) } } + { $$ = { ...$3, rowOffset: ExpressionFactory.fromObject({type: 'row_offset', current: $3, prior: true, + value: ExpressionFactory.fromObject({position: $1, type: 'positional_param'})}) } } | name_optional_index %prec EMPTY { $$ = $1 } @@ -1401,11 +1451,25 @@ name_optional_index { $$ = { ...$1, ...$2 } } ; +expression_index + : expression + { $$ = $1 } + + | expression DOTS_RANGE expression + { $$ = ExpressionFactory.fromObject({type: 'range_index', from: $1, to: $3}); } + + | expression DOTS_RANGE + { $$ = ExpressionFactory.fromObject({type: 'range_index', from: $1}); } + + | DOTS_RANGE expression + { $$ = ExpressionFactory.fromObject({type: 'range_index', to: $2}); } + ; + array_index - : array_index '[' expression ']' + : array_index '[' expression_index ']' { $$ = { dim: $1.dim + 1, indexes: [...$1.indexes, $3] } } - | '[' expression ']' + | '[' expression_index ']' { $$ = { dim: 1, indexes: [$2]} } ; diff --git a/src/processor.js b/src/processor.js index f348ab0..7640577 100644 --- a/src/processor.js +++ b/src/processor.js @@ -1,4 +1,4 @@ -const {assert} = require("chai"); +const {assert, assertLog} = require('./assert.js'); const Scope = require("./scope.js"); const Expressions = require("./expressions.js"); const Expression = require("./expression.js"); @@ -20,80 +20,104 @@ const PackedExpressions = require("./packed_expressions.js"); const ProtoOut = require("./proto_out.js"); const FixedCols = require("./fixed_cols.js"); const WitnessCols = require("./witness_cols.js"); +const SubproofValues = require("./subproof_values.js"); const Iterator = require("./iterator.js"); const Context = require("./context.js"); +const Runtime = require("./runtime.js"); +// const FunctionCall = require("./function_call.js"); const {FlowAbortCmd, BreakCmd, ContinueCmd, ReturnCmd} = require("./flow_cmd.js") +// const {ReferenceItem, ExpressionItem, FeValue, IntValue, ProofItem, Proofval, Subproofval, Challenge, Public, ProofStageItem, +// ExpressionReference, StringValue, FixedCol, WitnessCol } = require("./expression_items.js"); + +const ExpressionItems = require("./expression_items.js"); +const ExpressionItem = ExpressionItems.ExpressionItem; +const DefinitionItems = require("./definition_items.js"); const fs = require('fs'); const { log2, getKs, getRoots } = require("./utils.js"); const Hints = require('./hints.js'); const util = require('util'); +const Debug = require('./debug.js'); +const Transpiler = require('./transpiler.js'); +const MAX_SWITCH_CASE_RANGE = 512; module.exports = class Processor { - constructor (Fr, parent, references, expressions) { + constructor (Fr, parent, config = {}) { + this.sourceRef = '(processor constructor)'; this.compiler = parent; this.trace = true; this.Fr = Fr; - this.context = new Context(this.Fr, this); - this.scope = new Scope(this.Fr); - this.references = new References(Fr, this.context, this.scope); + this.prime = Fr.p; + this.references = new References(); + this.scope = new Scope(); + this.runtime = new Runtime(); + this.context = new Context(this.Fr, this, config); + this.nextStatementTranspile = false; + this.nextStatementFixed = false; + console.log(config); + this.scope.mark('proof'); this.delayedCalls = {}; + this.timers = {}; this.airId = 0; this.subproofId = 0; - this.ints = new Variables(Fr, 'int'); + this.ints = new Variables('int', DefinitionItems.IntVariable, ExpressionItems.IntValue); this.references.register('int', this.ints); - this.fes = new Variables(Fr, 'fe'); + this.fes = new Variables('fe', DefinitionItems.FeVariable, ExpressionItems.FeValue); this.references.register('fe', this.fes); - this.strings = new Variables(Fr, 'string'); + this.strings = new Variables('string', DefinitionItems.StringVariable, ExpressionItems.StringValue); this.references.register('string', this.strings); - this.vexprs = new Variables(Fr, 'expr'); - this.references.register('expr', this.vexprs); + this.exprs = new Variables('expr', DefinitionItems.ExpressionVariable, Expression, {constClass: ExpressionItems.ExpressionReference}); + this.references.register('expr', this.exprs); - this.lexprs = new Variables(Fr, 'lexpr'); - this.references.register('lexpr', this.lexprs); + // this.lexprs = new Variables('lexpr', Expression); + // this.references.register('lexpr', this.lexprs); - this.fixeds = new FixedCols(Fr); + this.fixeds = new FixedCols(); + ExpressionItem.setManager(ExpressionItems.FixedCol, this.fixeds); this.fixeds.runtimeRows = true; this.references.register('fixed', this.fixeds); - this.witness = new WitnessCols(Fr); + this.witness = new WitnessCols(); + ExpressionItem.setManager(ExpressionItems.WitnessCol, this.witness); this.references.register('witness', this.witness); - this.constants = new Indexable(Fr, 'constant', 'int'); - this.references.register('constant', this.constants); +// this.constants = new Indexable('constant', IntValue); +// this.references.register('constant', this.constants); - this.publics = new Ids('public'); + this.publics = new Indexable('public', DefinitionItems.Public, ExpressionItems.Public); + ExpressionItem.setManager(ExpressionItems.Public, this.publics); this.references.register('public', this.publics); - this.challenges = new Ids('challenge'); + this.challenges = new Indexable('challenge', DefinitionItems.Challenge, ExpressionItems.Challenge); + ExpressionItem.setManager(ExpressionItems.Challenge, this.challenges); this.references.register('challenge', this.challenges); - this.proofvalues = new Ids('proofvalue'); + this.proofvalues = new Indexable('proofvalue', DefinitionItems.Proofval, ExpressionItems.Proofval); + ExpressionItem.setManager(ExpressionItems.Proofval, this.proofvalues); this.references.register('proofvalue', this.proofvalues); - this.subproofvalues = new Ids('subproofvalue'); + this.subproofvalues = new SubproofValues(); + ExpressionItem.setManager(ExpressionItems.Subproofval, this.subproofvalues); this.references.register('subproofvalue', this.subproofvalues); -// this.imCols = new Indexable(Fr, 'im'); -// this.references.register('im', this.imCols); - - this.functions = new Indexable(Fr, 'function'); + this.functions = new Indexable('function', Function, ExpressionItems.FunctionCall); + ExpressionItem.setManager(ExpressionItems.FunctionCall, this.functions); this.references.register('function', this.functions); - this.subproofs = new Subproofs(Fr, this.context); + this.subproofs = new Subproofs(); - this.expressions = new Expressions(Fr, this, this.references, this.publics, this.constants); - this.globalExpressions = new Expressions(Fr, this, this.references, this.publics, this.constants); + this.expressions = new Expressions(); + this.globalExpressions = new Expressions(); - this.references.register('im', this.expressions); + // this.references.register('im', this.expressions); - this.constraints = new Constraints(Fr, this.expressions); - this.globalConstraints = new Constraints(Fr, this.globalExpressions); + this.constraints = new Constraints(); + this.globalConstraints = new Constraints(); this.assign = new Assign(Fr, this, this.context, this.references, this.expressions); this.hints = new Hints(Fr, this.expressions); @@ -103,21 +127,31 @@ module.exports = class Processor { this.functionDeep = 0; this.callstack = []; // TODO this.breakpoints = ['expr.pil:26']; + this.sourceRef = '(built-in-class)'; this.loadBuiltInClass(); this.scopeType = 'proof'; this.currentSubproof = false; + + this.sourceRef = '(init)'; + + this.proto = new ProtoOut(this.Fr); + this.proto.setupPilOut('noname'); + + this.transpiler = new Transpiler({processor: this}); } loadBuiltInClass() { const filenames = fs.readdirSync(__dirname + '/builtin'); this.builtIn = {}; for (const filename of filenames) { if (!filename.endsWith('.js')) continue; - if (this.context.config.debug.builtInLoad) { + if (Context.config.debug.builtInLoad) { console.log(`Loading builtin ${filename}.....`); } + if (Debug.active) console.log(filename); const builtInCls = require(__dirname + '/builtin/'+ filename); const builtInObj = new builtInCls(this); this.builtIn[builtInObj.name] = builtInObj; + this.references.declare(builtInObj.name, 'function', [], [], builtInObj); } } insideFunction() { @@ -134,85 +168,47 @@ module.exports = class Processor { assert(bits === this.log2(value+1n)); // if (value > 0n) console.log([value-1n, bits, this.log2(value-1n)]); } + this.sourceRef = '(start-execution)'; // TODO: use a constant this.references.declare('N', 'int', [], { global: true, sourceRef: this.sourceRef }); this.references.declare('BITS', 'int', [], { global: true, sourceRef: this.sourceRef }); + this.references.declare('PRIME', 'int', [], { global: true, sourceRef: this.sourceRef }); this.references.declare('__SUBPROOF__', 'string', [], { global: true, sourceRef: this.sourceRef }); this.scope.pushInstanceType('proof'); + this.sourceRef = '(execution)'; this.execute(statements); + this.sourceRef = '(subproof-execution)'; this.executeSubproofs(); this.finalProofScope(); this.scope.popInstanceType(); - this.generateOut(); + this.generateProtoOut(); } executeSubproofs() { for (const name of this.subproofs) { this.executeSubproof(name, this.subproofs.get(name)); } } - generateOut() + generateProtoOut() { - //packed.dump(); - // this.constraints.dump(packed); - // this.fixeds.dump(); - - let proto = new ProtoOut(this.Fr); - proto.setupPilOut('myFirstPil'); - let subproofId = 0; - proto.setSubproofvalues(this.subproofvalues.getPropertyValues(['id', 'aggregateType', 'subproofId'])); - proto.setPublics(this.publics); - proto.setProofvalues(this.proofvalues); - proto.setChallenges(this.challenges); - for (const subproofName of this.subproofs) { - const subproof = this.subproofs.get(subproofName); - proto.setSubproof(subproofName, subproof.aggregate); - let airId = 0; - for (const airName of subproof.airs) { - console.log(`SUBPROOF(${subproofName},${airName})`); - const air = subproof.airs.get(airName); - const bits = log2(Number(air.rows)); - proto.setAir(airName, air.rows); - proto.setFixedCols(air.fixeds); - // expression: constraint, hint, operand (expression) - let packed = new PackedExpressions(); - // this.expressions.pack(packed); - air.expressions.pack(packed); - proto.setConstraints(air.constraints, packed, - { labelsByType: { - witness: air.witness.labelRanges, - fixed: air.fixeds.labelRanges, - } - }); - proto.setWitnessCols(air.witness); - proto.setSymbolsFromLabels(air.witness.labelRanges, 'witness', {airId, subproofId}); - proto.setSymbolsFromLabels(air.fixeds.labelRanges, 'fixed', {airId, subproofId}); - proto.setExpressions(packed); - proto.addHints(air.hints, packed, { - subproofId, - airId - }); - ++airId; - } - ++subproofId; - } + if (Context.config.protoOut === false) return; + this.proto.setPublics(this.publics); + this.proto.setProofvalues(this.proofvalues); + this.proto.setChallenges(this.challenges); let packed = new PackedExpressions(); - // this.expressions.pack(packed); this.globalExpressions.pack(packed); - proto.setGlobalConstraints(this.globalConstraints, packed); - proto.setGlobalExpressions(packed); - proto.setGlobalSymbols(this.references); - proto.encode(); - proto.saveToFile('tmp/pilout.ptb'); - // stageWidths - // expressions - - // publics - // this.imCols.dump(); + this.proto.setGlobalConstraints(this.globalConstraints, packed); + this.proto.setGlobalExpressions(packed); + this.proto.setGlobalSymbols(this.references); + this.proto.encode(); + this.proto.saveToFile('tmp/pilout.ptb'); } traceLog(text, color = '') { if (!this.trace) return; - if (color) console.log(`\x1B[${color}m${text}\x1B[0m`); - else console.log(text); + if (Debug.active) { + console.log([Expression.constructor.name]); + if (color) console.log(`\x1B[${color}m${text}\x1B[0m`); + else console.log(text); + } } execute(statements, label = '') { const __executeCounter = this.executeCounter++; @@ -233,56 +229,122 @@ module.exports = class Processor { } executeStatement(st) { const __executeStatementCounter = this.executeStatementCounter++; + let activeTranspile = this.nextStatementTranspile; + if (activeTranspile) { + this.transpile = true; + this.nextStatementTranspile = false; + } this.traceLog(`[TRACE] #${__executeStatementCounter} ${st.debug ?? ''} (DEEP:${this.scope.deep})`, '38;5;75'); - this.sourceRef = st.debug ?? ''; - this.context.sourceRef = this.sourceRef - // console.log(`SOURCE ${this.sourceRef}`); + + this.sourceRef = st.debug ? (st.debug.split(':').slice(0,2).join(':') ?? ''):''; if (typeof st.type === 'undefined') { console.log(st); this.error(st, `Invalid statement (without type)`); } - // console.log(`## DEBUG ## ${this.executeCounter}.${this.executeStatementCounter} ${st.debug}` ); const method = ('exec_'+st.type).replace(/[-_][a-z]/g, (group) => group.slice(-1).toUpperCase()); + if (Debug.active) console.log(`## DEBUG ## ${this.executeCounter}.${this.executeStatementCounter} ${method} ${st.debug}` ); if (!(method in this)) { console.log('==== ERROR ===='); - this.error(st, `Invalid statement type: ${st.type}`); + this.error(st, `Invalid statement type: ${st.type}`); } let res; try { if (this.breakpoints.includes(st.debug)) { debugger; } - res = this[method](st); + if (this.transpile) { + this.transpiler.transpile(st); + EXIT_HERE; + } else { + res = this[method](st); + } } catch (e) { + // console.log([Expression.constructor.name]); console.log("EXCEPTION ON "+st.debug+" ("+this.callstack.join(' > ')+")"); + if (activeTranspile) { + this.transpile = false; + } throw e; } + if (activeTranspile) { + this.transpile = false; + } return res; } + execPragma(st) { + const params = st.value.split(/\s+/); + const instr = params[0] ?? false; + switch (instr) { + case 'debug': + if (params[1] === 'on') Debug.active = true; + else if (params[1] === 'off') Debug.active = false; + break; + case 'exit': + EXIT_HERE; + break; + case 'timer': { + const name = params[1] ?? false; + const action = params[2] ?? 'start'; + if (action === 'start') { + this.timers[name] = process.hrtime(); + } else if (action === 'end') { + const now = process.hrtime(); + const start = this.timers[name] ?? now; + const milliseconds = (now[0] - start[0]) * 1000 + Math.floor((now[1] - start[1])/1000000); + console.log(`=========================> TIMER ${name} ${milliseconds} ms <===============================`); + } + break; + } + case 'debugger': + debugger; + break; + case 'transpile': + this.nextStatementTranspile = true; + break; + case 'fixed': + this.nextStatementFixed = true; + break; + } + + } execProof(st) { this.scope.pushInstanceType('proof'); this.execute(st.statements); this.scope.popInstanceType(); } - execCall(st) { - const name = st.function.name; - const func = this.builtIn[name] ?? (this.references.getTypedValue(name) || {}).value; + executeFunctionCall(name, callinfo) { + const func = this.builtIn[name] ?? this.references.get(name); + if (Debug.active) { + console.log(`CALL ${name}`); + console.log(callinfo); + } if (func) { - this.callstack.push(st.debug); + const mapInfo = func.mapArguments(callinfo); + // console.log(mapInfo); + // console.log(func.constructor.name); + // callinfo.dumpArgs(mapInfo.eargs, 'CALLINFO'); + this.callstack.push(mapInfo.scall ?? name); ++this.functionDeep; this.scope.push(); - const mapInfo = func.mapArguments(st); this.references.pushVisibilityScope(); - const res = func.exec(st, mapInfo); + const res = func.exec(callinfo, mapInfo); this.references.popVisibilityScope(); this.scope.pop(); --this.functionDeep; this.callstack.pop(); - return res; + if (Debug.active) console.log(`END CALL ${name}`, res); + return typeof res === 'undefined' ? new ExpressionItems.IntValue() : res; } - this.error(st, `Undefined function statement type: ${name}`); + this.error({}, `Undefined function ${name}`); + } + execCall(st) { + const name = st.function.name; + if (Debug.active) console.log(`CALL (EXEC) ${name}`); + const res = this.executeFunctionCall(name, st); + if (Debug.active) console.log(`END CALL (EXEC) ${name}`); + return res; } execAssign(st) { // type: number(int), fe, string, col, challenge, public, prover, @@ -290,22 +352,43 @@ module.exports = class Processor { // TODO: move to assign class const indexes = this.decodeIndexes(st.name.indexes) const names = this.context.getNames(st.name.name); +// if (st.value.type === 'sequence') { + if (st.value instanceof ExpressionItems.ExpressionList) { + const sequence = new Sequence(this, st.value, ExpressionItems.IntValue.castTo(this.references.get('N'))); + sequence.extend(); + if (Debug.active) console.log(sequence.size); + if (Debug.active) console.log(sequence.toString()); + EXIT_HERE; + } + if (Debug.active) console.log(st.value); + if (Debug.active) st.value.dump('@@@@@@@@@@@@@@@@@@'); + const expr2 = st.value.instance(); + if (Debug.active) expr2.dump('@^^@------/'); if (st.name.reference) { assert(indexes.length === 0); - this.assign.assignReference(names, st.value.instance()); + const assignedValue = st.value.instance(); + if (Debug.active) console.log(assignedValue); + this.assign.assignReference(names, assignedValue); return; } + if (Debug.active) console.log(st.value); this.assign.assign(names, indexes, st.value); + if (Debug.active) console.log(`ASSIGN ${st.name.name} = ${st.value.toString()} \x1B[0;90m[${Context.sourceTag}]\x1B[0m`); // this.references.set(st.name.name, [], this.expressions.eval(st.value)); } execHint(s) { const name = s.name; - console.log(util.inspect(s.data, false, null, true)); + if (Debug.active) console.log(util.inspect(s.data, false, null, true)); const res = this.processHintData(s.data); - console.log(util.inspect(res, false, null, true)); + if (Debug.active) console.log(util.inspect(res, false, null, true)); this.hints.define(name, res); } processHintData(hdata) { + if (hdata instanceof Expression) { + const value = hdata.eval(); + if (typeof value === 'bigint') return value; + return hdata.instance(); + } if (hdata.type === 'array') { let result = []; for (const item of hdata.data) { @@ -321,25 +404,21 @@ module.exports = class Processor { } return result; } - if (hdata instanceof Expression) { - const value = hdata.eval(); - if (typeof value === 'bigint') return value; - return hdata.instance(); - } - console.log(hdata); + if (Debug.active) console.log(hdata); EXIT_HERE; } execIf(s) { for (let icond = 0; icond < s.conditions.length; ++icond) { const cond = s.conditions[icond]; if ((icond === 0) !== (cond.type === 'if')) { - throw new Exception('first position must be an if, and if only could be on first position'); + throw new Error('first position must be an if, and if only could be on first position'); } if (cond.type === 'else' && icond !== (s.conditions.length-1)) { - throw new Exception('else only could be on last position'); + throw new Error('else only could be on last position'); } + if (Debug.active) console.log(cond); - if (typeof cond.expression !== 'undefined' && this.expressions.e2bool(cond.expression) !== true) { + if (typeof cond.expression !== 'undefined' && cond.expression.evalAsBool() !== true) { continue; } this.scope.push(); @@ -348,15 +427,87 @@ module.exports = class Processor { return res; } } + prepareSwitchCase(s) { + let values = {}; + // s.cases.map((x,i) => {console.log(`#### CASE ${i} ####`); console.log(util.inspect(x.statements, false, 2000, true))}); + for (let index = 0; index < s.cases.length; ++index) { + const _case = s.cases[index]; + if (_case.condition && _case.condition.values) { + for (const value of _case.condition.values) { + if (value instanceof Expression) { + const _key = value.asInt(); + if (typeof values[_key] !== 'undefined') { + throw new Error(`Switch-case value ${_key} duplicated`); + } + values[_key] = index; + } else if (value.from && value.to && value.from instanceof Expression && value.to instanceof Expression) { + const _from = value.from.asInt(); + const _to = value.to.asInt(); + if ((_to - _from) < MAX_SWITCH_CASE_RANGE) { + while (_from <= _to) { + if (typeof values[_from] !== 'undefined') { + throw new Error(`Switch-case value ${_from} duplicated`); + } + values[_from] = index; + ++_from; + } + } else { + throw new Error(`Switch-case range too big ${from}..${to} (${_to-_from}) max: ${MAX_SWITCH_CASE_RANGE}`); + } + } else { + console.log(value); + EXIT_HERE; + } + } + _case.__cached_values = values; + } else if (_case.default) { + if (typeof values[false] !== 'undefined') { + throw new Error(`Switch-case DEFAULT duplicated`); + } + values[false] = index; + } else { + console.log(_case); + EXIT_HERE; + } + } + s.__cached_values = values; + } + execSwitch(s) { + // switch must cases value must be constant values + // TODO: check no constant variable values + if (!s.__cached_values) { + this.prepareSwitchCase(s); + } + assert(s.value instanceof Expression); + const value = s.value.asInt(); + let caseIndex = false; + if (typeof s.__cached_values[value] !== 'undefined') { + caseIndex = s.__cached_values[value]; + } else if (typeof s.__cached_values[false] !== 'undefined') { + caseIndex = s.__cached_values[false]; + } + if (caseIndex !== false) { + this.scope.push(); + this.execute(s.cases[caseIndex].statements, `SWITCH CASE ${value} ${this.sourceRef}`); + this.scope.pop(); + } + } execWhile(s) { let index = 0; - while (this.expressions.e2bool(s.condition)) { + let result = false; + while (true) { this.scope.push(); - this.execute(s.statements, `WHILE ${this.sourceRef} I:${index}`); + const whileCond = s.condition.eval().asBool(); + if (!whileCond) { + this.scope.pop(); + break; + } + result = this.execute(s.statements, `WHILE ${this.sourceRef} I:${index}`); ++index; this.scope.pop(); - if (res === false) break; + if (result instanceof BreakCmd) break; } + return result; } execUse(s) { const name = this.expandTemplates(s.name); @@ -384,23 +535,33 @@ module.exports = class Processor { return result; } execFor(s) { + if (Debug.active) console.log('EXEC-FOR'); let result; this.scope.push(); this.execute(s.init, `FOR ${this.sourceRef} INIT`); let index = 0; - while (this.expressions.e2bool(s.condition)) { + // while (this.expressions.e2bool(s.condition)) { + while (true) { + if (index % 10000 === 0 && index) { + console.log(`inside FOR ${this.sourceRef} index:${index}`); + } + const loopCond = s.condition.eval().asBool(); + if (Debug.active) console.log('FOR.CONDITION', loopCond, s.condition.toString(), s.condition); + if (!loopCond) break; // if only one statement, scope will not create. // if more than one statement, means a scope_definition => scope creation result = this.execute(s.statements, `FOR ${this.sourceRef} I:${index}`); ++index; if (result instanceof BreakCmd) break; + if (Debug.active) console.log('INCREMENT', s.increment); this.execute(s.increment); } this.scope.pop(); return result; } execForIn(s) { - if (s.list && s.list.type === 'expression_list') { + if (Debug.active) console.log(s); + if (s.list && s.list instanceof ExpressionItems.ExpressionList) { return this.execForInList(s); } return this.execForInExpression(s); @@ -461,8 +622,8 @@ module.exports = class Processor { } execForInExpression(s) { // s.list.expr.dump(); - console.log(s); - console.log(s.list); + if (Debug.active) console.log(s); + if (Debug.active) console.log(s.list); let it = new Iterator(s.list); this.scope.push(); this.execute(s.init,`FOR-IN-EXPRESSION ${this.sourceRef} INIT`); @@ -501,18 +662,24 @@ module.exports = class Processor { throw new Error(msg); } execInclude(s) { - if (s.contents !== false) { - return this.execute(s.contents); + if (!s.contents) { + const sts = this.compiler.loadInclude(s, {preSrc: 'subproof __(2**2) {\n', postSrc: '\n};\n'}); + s.contents = sts[0].statements; } + return this.execute(s.contents); } execFunctionDefinition(s) { + if (Debug.active) console.log('FUNCTION '+s.funcname); let func = new Function(this, s); - this.references.declare(func.name, 'function'); + this.references.declare(func.name, 'function', [], {sourceRef: Context.sourceRef}); this.references.set(func.name, [], func); } getExprNumber(expr, s, title) { - // expr.expr.dump(); - const se = this.expressions.eval(expr); + if (Debug.active) { + console.log(s); + expr.dump(); + } + const se = ExpressionItems.IntValue.castTo(expr.eval()); if (typeof se !== 'bigint') { // if (se.op !== 'number') { console.log('ERROR'); @@ -543,7 +710,7 @@ module.exports = class Processor { assert(e.type === 'expression_list'); let values = []; for (const value of e.values) { - values.push(this.e2value(value)); + values.push(value.evalAsInt()); } return values; } @@ -580,7 +747,7 @@ module.exports = class Processor { this.checkRows(subproofRows); // TODO: Fr inside context - const subproof = new Subproof(this.context, subproofRows, s.statements, s.aggregate ?? false); + const subproof = new Subproof(subproofRows, s.statements, s.aggregate ?? false); this.subproofs.define(subproofName, subproof, `subproof ${subproofName} has been defined previously on ${this.context.sourceRef}`); } execSubproofBlock(s) { @@ -597,20 +764,37 @@ module.exports = class Processor { executeSubproof(subproofName, subproof) { this.currentSubproof = subproof; this.scope.pushInstanceType('subproof'); + this.context.subproofName = subproofName; + // proto.setSubproofvalues(this.subproofvalues.getPropertyValues(['id', 'aggregateType', 'subproofId'])); + const subproofId = this.proto.setSubproof(subproofName, subproof.aggregate); + Context.subproofId = this.subproofId; for (const airRows of subproof.rows) { + console.log(`BEGIN AIR ${subproofName} (${airRows})`); // #${this.airId}`); this.rows = airRows; - console.log(`BEGIN AIR ${subproofName} (${airRows}) #${this.airId}`); + // TODO: context is global? const air = new Air(this.Fr, this.context, airRows); const airName = subproofName + (subproof.rows.length > 1 ? `_${air.bits}`:''); + const airId = this.proto.setAir(airName, airRows); + Context.airId = airId; + Context.airName = airName; + subproof.airs.define(airName, air); + // TO-DO loop with different rows + console.log([air.bits, air.rows, Expression.constructor.name]); + // create built-in constants - this.references.set('N', [], BigInt(air.rows)); - this.references.set('BITS', [], BigInt(air.bits)); + this.references.set('N', [], air.rows); + this.references.set('BITS', [], air.bits); + this.references.set('PRIME', [], this.prime); this.references.set('__SUBPROOF__', [], subproofName); +/* this.references.set('N', [], new ExpressionItems.IntValue(air.rows)); + this.references.set('BITS', [], new ExpressionItems.IntValue(air.bits)); + this.references.set('__SUBPROOF__', [], new ExpressionItems.StringValue(subproofName));*/ + this.context.push(false, subproofName); this.scope.pushInstanceType('air'); subproof.airStart(); @@ -622,32 +806,68 @@ module.exports = class Processor { } this.finalAirScope(); subproof.airEnd(); - air.witness = this.witness.clone(); - air.fixeds = this.fixeds.clone(); - air.expressions = this.expressions.clone(); - air.constraints = this.constraints.clone(); - air.constraints.expressions = air.expressions; - air.hints = this.hints.clone(); - air.hints.expressions = air.expressions; - this.clearAirScope(); + + // pilout generation + // setting id of proofitems used, be carefull with challenge (stage not defined) + + // const subproof = this.subproofs.get(subproofName); + // proto.setSubproof(subproofName, subproof.aggregate); + // clearing air scope + this.subproofProtoOut(subproofId, airId) + + this.clearAirScope(airName); this.constraints = new Constraints(this.Fr, this.expressions); this.scope.popInstanceType(['witness', 'fixed', 'im']); this.context.pop(); console.log(`END AIR ${subproofName} (${airRows}) #${this.airId}`); + Context.airId = false; + Context.airName = false; ++this.airId; } this.finalSubproofScope(); + if (!Context.config.protoOut) { + this.proto.setSubproofValues(this.subproofvalues.getAggreationTypesBySubproofId(subproofId)); + } this.scope.popInstanceType(); this.currentSubproof = false; + Context.subproofName = false; + this.references.clearScope('subproof'); ++this.subproofId; } + subproofProtoOut(subproofId, airId) { + if (!Context.config.protoOut) return; + + let packed = new PackedExpressions(); + this.proto.setFixedCols(this.fixeds); + this.proto.setWitnessCols(this.witness); + // this.expressions.pack(packed, {instances: [air.fixeds, air.witness]}); + this.expressions.pack(packed, {instances: [this.fixeds, this.witness]}); + this.proto.setConstraints(this.constraints, packed, + { + labelsByType: { + witness: this.witness.labelRanges, + fixed: this.fixeds.labelRanges, + subproofvalue: (id, options) => this.subproofvalues.getRelativeLabel(subproofId, id, options) + }, + expressions: this.expressions + }); + const info = {airId, subproofId}; + this.proto.setSymbolsFromLabels(this.witness.labelRanges, 'witness', info); + this.proto.setSymbolsFromLabels(this.fixeds.labelRanges, 'fixed', info); + this.proto.setExpressions(packed); + this.proto.addHints(this.hints, packed, { + subproofId, + airId + }); + } finalAirScope() { this.callDelayedFunctions('air', 'final'); } - clearAirScope() { - this.references.clearType('fixed'); - this.references.clearType('witness'); - this.expressions.clear(); + clearAirScope(label = '') { + this.references.clearType('fixed', label); + this.references.clearType('witness', label); + this.references.clearScope('air'); + this.expressions.clear(label); this.hints.clear(); } finalSubproofScope() { @@ -657,11 +877,13 @@ module.exports = class Processor { this.callDelayedFunctions('proof', 'final'); } callDelayedFunctions(scope, event) { + if (Debug.active) console.log(this.delayedCalls); if (typeof this.delayedCalls[scope] === 'undefined' || typeof this.delayedCalls[scope][event] === 'undefined') { return false; } for (const fname in this.delayedCalls[scope][event]) { - this.execCall({ op: 'call', function: {name: fname}, arguments: [] }); + if (Debug.active) console.log(`CALL DELAYED(${scope},${event}) FUNCTION ${fname}`); + this.execCall({ op: 'call', function: {name: fname}, args: [] }); } } execWitnessColDeclaration(s) { @@ -673,17 +895,43 @@ module.exports = class Processor { const colname = this.context.getFullName(col.name); // console.log(`COL_FIXED_DECLARATION(${colname})`); const lengths = this.decodeLengths(col); - let init = s.sequence; + let init = s.sequence ?? null; let seq = null; if (init) { - seq = new Sequence(this, init, this.references.get('N')); + // console.log('###################################################'); + // console.log('###################################################'); + // console.log('###################################################'); + // console.log('###################################################'); + // console.log('###################################################'); + seq = new Sequence(this, init, ExpressionItems.IntValue.castTo(this.references.get('N'))); + // console.log('##################################################'); + // console.log('##### ############################################'); + // console.log('#### ############################################'); + // console.log('### ##'); + // console.log('## ##'); + // console.log('### ##'); + // console.log('#### ############################################'); + // console.log('##### ############################################'); + // console.log('##################################################'); // console.log(`Extending fixed col ${colname} ...`); - seq.extend(); + if (Context.config.fixed !== false) seq.extend(); // console.log('SEQ:'+seq.values.join(',')); + // console.log('##################################################'); + // console.log('############################################ #####'); + // console.log('############################################ ####'); + // console.log('## ###'); + // console.log('## ##'); + // console.log('## ###'); + // console.log('############################################ ####'); + // console.log('############################################ #####'); + // console.log('##################################################'); } this.declareFullReference(colname, 'fixed', lengths, {global}, seq); } } + execDebugger(s) { + debugger; + } execColDeclaration(s) { // intermediate column const global = s.global ?? false; @@ -733,7 +981,7 @@ module.exports = class Processor { const scope = s.scope; const fname = s.function.name; const event = s.event; - if (s.arguments.length > 0) { + if (s.args.length > 0) { throw new Error('delayed function call arguments are not yet supported'); } if (event !== 'final') { @@ -754,7 +1002,8 @@ module.exports = class Processor { this.delayedCalls[scope][event][fname].sourceRefs.push(this.context.sourceRef); } execExpr(s) { - this.expressions.eval(s.expr); + s.expr.eval(); + // this.expressions.eval(s.expr); } decodeNameAndLengths(s) { return [s.name, this.decodeLengths(s)]; @@ -763,7 +1012,7 @@ module.exports = class Processor { let values = []; if (indexes) { for (const index of indexes) { - values.push(this.expressions.e2number(index)); + values.push(Number(index.evalAsInt())); } } return values; @@ -805,12 +1054,16 @@ module.exports = class Processor { s.executed = true; return this.execute(s.statements,`CODE ${this.sourceRef}`); } - console.log(`Ignore once section because it has already executed ${s.debug}`); + if (Debug.active) console.log(`Ignore once section because it has already executed ${s.debug}`); } execConstraint(s) { const scopeType = this.scope.getInstanceType(); let id, expr, prefix = ''; + assertLog(s.left instanceof Expression, s.left); + assertLog(s.right instanceof Expression, s.right); + const left = s.left.instance(); + const right = s.right.instance(); if (scopeType === 'air') { id = this.constraints.define(s.left.instance({simplify: true}), s.right.instance({simplify: true}),false,this.sourceRef); expr = this.constraints.getExpr(id); @@ -821,22 +1074,27 @@ module.exports = class Processor { } else { throw new Error(`Constraint definition on invalid scope (${scopeType}) ${this.context.sourceRef}`); } - console.log(`\x1B[1;36;44m${prefix}CONSTRAINT > ${expr.toString({hideClass:true, hideLabel:false})} === 0 (${this.sourceRef})\x1B[0m`); - console.log(`\x1B[1;36;44m${prefix}CONSTRAINT (RAW)> ${expr.toString({hideClass:true, hideLabel:true})} === 0 (${this.sourceRef})\x1B[0m`); + console.log(`\x1B[1;36;44m${prefix}CONSTRAINT [${Context.proofLevel}] > ${expr.toString({hideClass:true, hideLabel:false})} === 0 (${this.sourceRef})\x1B[0m`); + console.log(`\x1B[1;36;44m${prefix}CONSTRAINT [${Context.proofLevel}] (RAW) > ${expr.toString({hideClass:true, hideLabel:true})} === 0 (${this.sourceRef})\x1B[0m`); } execVariableIncrement(s) { // REVIEW used only inside loop (increment) in other cases was an expression const name = s.name; const value = this.references.get(name, []); - this.references.set(name, [], value + s.pre + s.post); + // REVIEW: could be an expression (if expression x+1+1 = x+2) + const intValue = value.getValue(); + if (Debug.active) console.log(`INCREMENT ${s.name} = ${intValue} + ${s.pre + s.post} = ${intValue + s.pre + s.post}`); + // console.log(s.pre, s.post, value.getValue()); + this.references.set(name, [], intValue + s.pre + s.post); } execVariableDeclaration(s) { + if (Debug.active) console.log('VARIABLE DECLARATION '+Context.sourceRef+' init:'+s.init); const init = typeof s.init !== 'undefined'; -// console.log(s); const count = s.items.length; + const inits = (init && s.init.type === 'expression_list') ? s.init.values : s.init; - if (init && s.init.length !== count) { - this.error(s, `Mismatch between len of variables (${count}) and len of their inits (${s.init.length})`); + if (init && inits.length !== count) { + this.error(s, `Mismatch between len of variables (${count}) and len of their inits (${inits.length})`); } for (let index = 0; index < count; ++index) { @@ -846,17 +1104,26 @@ module.exports = class Processor { const scope = s.scope ?? false; let initValue = null; if (init) { - if (s.vtype === 'expr') { - // s.init[index].expr.dump('INIT1 '+name); - initValue = this.expressions.instance(s.init[index]); - // initValue.dump('INIT2 '+name); - } - else { - initValue = this.expressions.e2value(s.init[index]); + if (Debug.active) console.log(name, s.vtype, Context.sourceRef); + switch (s.vtype) { + case 'expr': + initValue = inits[index].eval(); + break; + case 'int': + initValue = inits[index].eval().asIntItem(); + break; + case 'string': + initValue = new ExpressionItems.StringValue(this.expressions.e2value(inits[index])); + break; } + if (Debug.active) console.log(name, s.vtype, initValue.toString ? initValue.toString() : initValue); + } + this.references.declare(name, s.vtype, lengths, { scope, sourceRef, const: s.const ?? false }, initValue); + if (initValue !== null) { + const initValueText = typeof initValue.toString === 'function' ? initValue.toString() : initValue; + if (Debug.active) console.log(`ASSIGN(DECL) ${name} = ${initValueText} \x1B[0;90m[${Context.sourceTag}]\x1B[0m`); + // this.references.set(name, [], initValue); } - this.references.declare(name, s.vtype, lengths, { scope, sourceRef }, initValue); - // if (initValue !== null) this.references.set(name, [], initValue); } } execConstantDefinition(s) { @@ -872,9 +1139,10 @@ module.exports = class Processor { throw new Error(`Array size mismatch on initialization ${asize} vs ${ssize}`); } // TODO, check sizes before extends - const values = seq.extend(); - for (let index = 0; index < values.length; ++index) { - this.references.set(s.name, def.array.offsetToIndexes(index), values[index]); + seq.extend(); + const seqSize = seq.getSize(); + for (let index = 0; index < seqSize; ++index) { + this.references.set(s.name, def.array.offsetToIndexes(index), seq.getValue(index)); } } else { this.references.declare(s.name, 'constant', [], { sourceRef: this.sourceRef }); @@ -902,9 +1170,22 @@ module.exports = class Processor { lindex = m.index + m[0].length; } const lastS = template.substring(lindex); - const codeTags = tags.map((x, index) => 'constant ____'+index+' = '+x.expr+";").join("\n"); + + // create a tag for each substitution string + const codeTags = tags.map((x, index) => 'expr ____'+index+' = '+x.expr+";").join("\n"); + + // compile a list of tags to created its associated expressions + // this expressions aren't executed, only compiled for this reason + // we don't need create a context. const compiledTags = this.compiler.parseExpression(codeTags); - return compiledTags.map((e, index) => tags[index].pre + this.e2value(e.value)).join('')+lastS; + + // evaluating different init of each tag + const stringTags = compiledTags.map(e => e.init[0].eval().asString()); + + // replace on string each tag for its value + const evaluatedTemplate = stringTags.map((s, index) => tags[index].pre + s).join('')+lastS; + if (Debug.active) console.log(`TEMPLATE "${template}" ==> "${evaluatedTemplate}"`); + return evaluatedTemplate; } evaluateExpression(e){ // TODO @@ -918,10 +1199,14 @@ module.exports = class Processor { throw new Error('Return is called out of function scope'); } const res = s.value.instance(); + if (Debug.active) { + console.log(res); + console.log(res.eval()); + } this.traceLog(`[RETURN.END ${sourceRef}] ${this.scope.deep}`); return new ReturnCmd(res); } e2value(e, s, title) { - return this.expressions.e2value(e, s, title); + return e.evalAsValue(); } } diff --git a/src/proto_out.js b/src/proto_out.js index 23f9ee9..612b2b9 100644 --- a/src/proto_out.js +++ b/src/proto_out.js @@ -133,6 +133,7 @@ module.exports = class ProtoOut { encode() { console.log(['PROTO.CHALLENGES', this.pilOut.numChallenges]); + fs.writeFileSync('tmp/pilout.pre.log', util.inspect(this.pilOut, false, null, false)); let message = this.PilOut.fromObject(this.pilOut); fs.writeFileSync('tmp/pilout.log', util.inspect(this.pilOut, false, null, false)); this.data = this.PilOut.encode(message).finish(); @@ -142,14 +143,20 @@ module.exports = class ProtoOut { fs.writeFileSync(filename, this.data); } setAir(name, rows) { + const airId = this.currentSubproof.airs.length; this.currentAir = {name, numRows: Number(rows)}; this.currentSubproof.airs.push(this.currentAir); + return airId; } setSubproof(name, aggregable = false) { // TODO: Add subproof value this.currentSubproof = {name, aggregable, airs: []}; const subproofId = this.pilOut.subproofs.length; this.pilOut.subproofs.push(this.currentSubproof); - this.currentSubproof.subproofvalues = this.spvId2Proto.filter(value => value[2] === subproofId).map(value => { return {aggType: SPV_AGGREGATIONS.indexOf(value[1])}}); + return subproofId; + } + setSubproofValues(aggregations) { + // this.currentSubproof.subproofvalues = this.spvId2Proto.filter(value => value[2] === subproofId).map(value => { return {aggType: SPV_AGGREGATIONS.indexOf(value[1])}}); + this.currentSubproof.subproofvalues = aggregations.map(aggregation => { return {aggType: SPV_AGGREGATIONS.indexOf(aggregation)}}); } // use for all subproof values, of all subproofs @@ -157,6 +164,7 @@ module.exports = class ProtoOut { this.spvId2Proto = []; let subproofBaseId = []; for (const [id, aggregation, subproofId] of values) { + console.log([id, aggregation, subproofId]); let baseId = subproofBaseId[subproofId] ?? false; if (baseId === false) { baseId = id; @@ -181,7 +189,7 @@ module.exports = class ProtoOut { _setSymbols(symbols, data = {}) { for(const [name, ref] of symbols) { const arrayInfo = ref.array ? ref.array : {dim: 0, lengths: []}; - const sym2proto = this.symbolType2Proto(ref.type, ref.locator); + const sym2proto = this.symbolType2Proto(ref.type, ref.locator, ref); let payout = { name, dim: arrayInfo.dim, @@ -194,7 +202,7 @@ module.exports = class ProtoOut { } } - symbolType2Proto(type, id) { + symbolType2Proto(type, id, ref) { switch(type) { case 'im': return {type: REF_TYPE_IM_COL, id}; @@ -210,8 +218,8 @@ module.exports = class ProtoOut { return {type: REF_TYPE_WITNESS_COL, id: protoId, stage}; } case 'subproofvalue': { - const [protoId, aggregation, subproofId] = this.spvId2Proto[id]; - return {type: REF_TYPE_SUBPROOF_VALUE, id: protoId, subproofId}; + const def = ref.instance.get(id); + return {type: REF_TYPE_SUBPROOF_VALUE, id: def.relativeId, subproofId: ref.data.subproofId}; } case 'proofvalue': return {type: REF_TYPE_PROOF_VALUE, id}; @@ -266,8 +274,10 @@ module.exports = class ProtoOut { const property = periodic ? 'periodicCols':'fixedCols'; const airCols = this.setupAirProperty(property); + console.log(cols.constructor.name); const colType = periodic ? 'P':'F'; for (const col of cols) { + console.log(col.constructor.name); const colIsPeriodic = col.isPeriodic() && col.rows < rows; if (colIsPeriodic !== periodic) continue; const _rows = periodic ? col.rows : rows; @@ -366,27 +376,19 @@ module.exports = class ProtoOut { ope.witnessCol.stage = stage; } break; - case 'subproofValue': { - // translate index of subproof because it's relative to subproof - const id = ope.subproofValue.idx; - const [protoId, aggregation, subproofId] = this.spvId2Proto[id] ?? [false,false,false]; - if (protoId === false) { - console.log(ope); - throw new Error(`Translate: Found invalid subproofvalue ${id}`); - } - ope.subproofValue.idx = protoId; - ope.subproofValue.subproofId = subproofId; - } + case 'subproofValue': + // subproof no need translate idx because put index from begining + // ope.subproofValue.aggType = SPV_AGGREGATIONS.indexOf(ope.subproofValue.aggType) break; case 'challenge': { - const id = ope.challenge.idx; + /* const id = ope.challenge.idx; const [protoId, stage] = this.challengeId2Proto[id] ?? [false, false]; if (protoId === false) { console.log(ope); throw new Error(`Translate: Found invalid subproofvalue ${id}`); } ope.challenge.idx = protoId; - ope.challenge.stage = stage; + ope.challenge.stage = stage;*/ } break; case 'constant': @@ -408,15 +410,17 @@ module.exports = class ProtoOut { for (const [index, constraint] of constraints.keyValues()) { const packedExpressionId = constraints.getPackedExpressionId(constraint.exprId, packed); let payload = { expressionIdx: { idx: packedExpressionId }, - debugLine: constraints.getDebugInfo(index, packed) }; + debugLine: '###'+constraints.getDebugInfo(index, packed) }; this.pilOut.constraints.push(payload); } } - setConstraints(constraints, packed, options) { + setConstraints(constraints, packed, options = {}) { let airConstraints = this.setupAirProperty('constraints'); for (const [index, constraint] of constraints.keyValues()) { let payload; + console.log([index, constraint]); const debugLine = constraints.getDebugInfo(index, packed, options); + console.log(`DEBUGLINE: ${debugLine}`); const packedExpressionId = constraints.getPackedExpressionId(constraint.exprId, packed, options); switch (constraint.boundery) { case false: @@ -465,9 +469,12 @@ module.exports = class ProtoOut { toHintField(hdata, options = {}) { const path = options.path ?? ''; // check if an alone expression to use and translate its single operand - if (hdata && typeof hdata.isAlone === 'function') { - const operand = hdata.packAlone(options.packed, options); + if (hdata && typeof hdata.pack === 'function') { + console.log('HINT', typeof hdata.toString() ? hdata.constructor.name + ' ==> ' + hdata.toString() : hdata); + const operand = hdata.pack(options.packed, options); + console.log('HINT', operand); this.translate(operand); + console.log('HINT', operand); return { operand }; } if (typeof hdata === 'object' && hdata.constructor.name === 'ExpressionId') { @@ -483,6 +490,7 @@ module.exports = class ProtoOut { for (let index = 0; index < hdata.length; ++index) { result.push(this.toHintField(hdata[index], {...options, path: path + '[' + index + ']'})); } + console.log('HINT',result); return { hintFieldArray: { hintFields: Array.isArray(result) ? result : [result] }}; } if (typeof hdata === 'bigint' || typeof hdata === 'number') { @@ -497,10 +505,11 @@ module.exports = class ProtoOut { const value = this.toHintField(hdata[name], {...options, path: path + '.' + name}); result.push({...value, name}); } + console.log('HINT',result); return { hintFieldArray: { hintFields: Array.isArray(result) ? result : [result] }}; } console.log(hdata); - throw new Error(`Invalid hint-data (type:${typeof data}) on cloneHint of ${path}`); + throw new Error(`Invalid hint-data (type:${typeof hdata}/${(hdata.constructor ?? {name:''}).name}) on cloneHint of ${path}`); } bint2uint8(value, bytes = 0) { let result = new Uint8Array(this.uint8size); @@ -522,6 +531,7 @@ module.exports = class ProtoOut { return Buffer.alloc(0); } + console.log(value); const buf = Buffer.alloc(32); buf.writeBigInt64BE(value >> 64n*3n, 0); buf.writeBigUInt64BE((value >> 64n*2n) & 0xFFFFFFFFFFFFFFFFn, 8); diff --git a/src/reference.js b/src/reference.js new file mode 100644 index 0000000..56c408c --- /dev/null +++ b/src/reference.js @@ -0,0 +1,214 @@ +const {assert, assertLog} = require('./assert.js'); +const MultiArray = require("./multi_array.js"); +const ArrayOf = require('./expression_items/array_of.js'); +const RangeIndex = require('./expression_items/range_index.js'); +const IntValue = require('./expression_items/int_value.js'); +const Context = require('./context.js'); +const Debug = require('./debug.js'); +/** + * @property {MultiArray} array + */ + +class Reference { + + constructor (name, type, isReference, array, id, instance, scopeId, properties) { + this.name = name; + this.type = type; + assert(typeof isReference === 'boolean'); + this.isReference = isReference; + this.array = array; + this.locator = id; + this.scopeId = scopeId; + this.instance = instance; + this.initialized = false; + for (const property in properties) { + assert(typeof this[property] === 'undefined'); + if (Debug.active) if (property === 'const') console.log(['CONST ********', properties[property]]); + this[property] = properties[property]; + } + } + isValidIndexes(indexes = []) { + // if (!Array.isArray(indexes) || indexes.length == 0) return true; + if (!Array.isArray(indexes)) return false; + if (indexes.length == 0) return true; + if (!this.array) return false; + return this.array.isValidIndexes(indexes); + } + markAsInitialized(indexes = []) { + if (indexes.length === 0 || !this.array) { + assert(this.initialized === false); + this.initialized = true; + } + else { + this.array.markAsInitialized(indexes); + } + } + isInitialized(indexes = []) { + return (indexes.length === 0 || !this.array) ? this.initialized : this.array.isInitialized(indexes); + } + getId(indexes = []) { + if (Debug.active) { + console.log(`getId ${this.name} ${Array.isArray(indexes) ? '[' + indexes.join(',') + ']':indexes} ${this.array ? this.array.toDebugString():''}`); + } + if (indexes.length > 0 && !this.array) { + throw new Error(`Accessing to index, but not an array ${this.name} ${Context.sourceTag}`); + } + // return (indexes.length > 0 || this.array) ? this.array.getLocator(this.locator, indexes) : this.locator; + return this.array ? this.array.getLocator(this.locator, indexes) : this.locator; + } + set (value, indexes = [], options = {}) { + if (Debug.active) console.stdebug(`set(${this.name}, [${indexes.join(',')}]`); + assert(value !== null); // to detect obsolete legacy uses + if (!this.array || this.array.isFullIndexed(indexes)) { + return this.setOneItem(value, indexes, options); + } + this.setArrayLevel(0, indexes, value, options); + // At this point, it's a array initilization + } + setArrayLevel(level, indexes, value, options = {}) { + if (Debug.active) console.log(`setArrayLevel(${this.name} ${level}, [${indexes.join(',')}] ${Context.sourceRef}`); + const len = this.array.lengths[level]; + for (let index = 0; index < len; ++index) { + let _indexes = [...indexes]; + _indexes.push(index); + if (level + 1 === this.array.dim) { + if (Array.isArray(value)) { +// console.log('native', _indexes[level], _indexes); + this.setOneItem(value[_indexes[level]], _indexes, options); + } else { + const _item = value.getItem(_indexes); +// console.log('getItem', _indexes, _item); + this.setOneItem(_item, _indexes, options); + } + continue; + } + this.setArrayLevel(level+1, _indexes, value, options); + } + } + // setting by only one element + setOneItem(value, indexes, options = {}) { + if (!this.isInitialized(indexes)) { + return this.#doInit(value, indexes); + } else if (options.doInit) { + // called as doInit:true but it's initizalized before + throw new Error('value initialized'); + } + const [row, id] = this.getRowAndId(indexes); + if (this.const) { + // TODO: more info + throw new Error(`setting ${this.name} a const element on ${Context.sourceRef}`); + } + if (row !== false) this.instance.setRowValue(id, row, value); + else this.instance.set(id, value); + } + #doInit(value, indexes) { + const [row, id] = this.getRowAndId(indexes); + assert(id !== null); + if (row !== false) { + this.instance.setRowValue(id, row, value); + } else { + this.instance.set(id, value); + } + this.markAsInitialized(indexes); + } + init (value, indexes = [], options = {}) { + assert(value !== null); // to detect obsolete legacy uses + this.set(value, indexes, {...options, doInit: true}); + } + static getArrayAndSize(lengths) { + // TODO: dynamic arrays, call to factory, who decides? + if (lengths && lengths.length) { + let array = new MultiArray(lengths); + return [array, array.size]; + } + return [false, 1]; + } + get (indexes = []) { + const [row, id] = this.getRowAndId(indexes); + if (row !== false) { + return this.instance.getRowValue(id, row); + } + return this.instance.get(id); + } + getRowAndId(indexes = []) { + if (!this.instance.runtimeRows || indexes.length === 0) { + return [false, this.getId(indexes)]; + } + if (!this.array) { + if (indexes.length === 1) { + return [indexes[0], this.getId(indexes.slice(0, -1))]; + } + throw new Error(`Accessing to index, but not an array ${this.name} ${Context.sourceTag}`); + } + if ((this.array.dim + 1) === indexes.length) { + return [row, this.getId(indexes).slice(0,-1)]; + } + // other cases managed by getId because they aren't row access + return [row, this.getId(indexes)]; + } + + getItem(indexes, options = {}) { + let locator = this.locator; + let label = options.label; + + if (Debug.active) { + console.log(indexes); + console.log(this); + } + // indexes evaluation + let evaluatedIndexes = []; + let fromIndex = false; + let toIndex = false; + if (Array.isArray(indexes) && indexes.length > 0) { + for (let index = 0; index < indexes.length; ++index) { + if (indexes[index].isInstanceOf(RangeIndex)) { + if (index + 1 !== indexes.length) { + throw new Error(`Range index is valid only in last index ${Context.sourceRef}`); + } + const rangeIndex = indexes[index].getAloneOperand(); + fromIndex = rangeIndex.from === false ? false : Number(rangeIndex.from.asInt()); + toIndex = rangeIndex.to === false ? false : Number(rangeIndex.to.asInt()); + continue; + } + evaluatedIndexes.push(indexes[index].asInt()); + } + if (label) label = label + '['+evaluatedIndexes.join('],[')+']'; + } + + // if array is defined + let res = false; + if (this.array) { + if (this.array.isFullIndexed(evaluatedIndexes)) { + // full access => result an item (non subarray) + locator = this.array.locatorIndexesApply(this.locator, evaluatedIndexes); + } else { + // parcial access => result a subarray + res = new ArrayOf(this.type, this.array.createSubArray(evaluatedIndexes, locator, fromIndex, toIndex)); + } + } else if (evaluatedIndexes.length === 1 && this.instance.runtimeRows) { + res = this.instance.getRowValue(locator, evaluatedIndexes[0], options); + if (typeof res === 'undefined') { + throw Error(`ERROR: Row ${evaluatedIndexes[0]} of ${options.label} isn't initialized`); + } + } else if (evaluatedIndexes.length > 0) { + console.log('C'); + console.log(evaluatedIndexes); + console.log(this); + throw new Error('try to access to index on non-array value'); + } + if (typeof res === 'bigint' || typeof res === 'number') { + res = new IntValue(res); + } + if (res === false) { + res = this.const ? this.instance.getConstItem(locator, options) : this.instance.getItem(locator, options); + } + + if (label) { + res.setLabel(label); + } else res.setLabel('___'); + + return res; + } +} + +module.exports = Reference; \ No newline at end of file diff --git a/src/references.js b/src/references.js index 385ae55..26bad0d 100644 --- a/src/references.js +++ b/src/references.js @@ -1,92 +1,62 @@ -const {assert} = require("chai"); -const {MultiArray} = require("./multi_array.js"); +const {assert, assertLog} = require('./assert.js'); +const MultiArray = require("./multi_array.js"); const Expression = require("./expression.js"); +const {ExpressionItem, ArrayOf} = require("./expression_items.js"); +const Reference = require('./reference.js'); +const Containers = require('./containers.js'); +const Context = require('./context.js'); +const Exceptions = require('./exceptions.js'); +const Debug = require('./debug.js'); module.exports = class References { - constructor (Fr, context, scope) { - this.Fr = Fr; - this.definitions = {}; + constructor () { + this.references = {}; this.types = {}; - this.context = context; - this.scope = scope; this.visibilityScope = 0; this.visibilityStack = []; - this.containers = {}; - this.currentContainer = false; - this.scope.setReferences(this); - this.aliases = {}; - this.uses = []; - } - addScopeAlias(alias, value) { - // NOTE: there is no need to check for aliases because by grammatical definition, - // aliases must be an identifier - - if (this.aliases[alias]) { - throw new Error(`Alias ${alias} already defined on ${this.aliases[alias].sourceRef}`); - } - - this.scope.addToScopeProperty('aliases', alias); - this.aliases[alias] = {container: value, sourceRef: this.context.sourceRef}; - } - getAlias(alias, defaultValue) { - return this.aliases[alias] ?? defaultValue; - } - unsetAlias(aliases) { - for (const alias of aliases) { - assert(this.aliases[alias]); - delete this.aliases[alias]; - } - } - unsetUses(uses) { - let count = uses.length; - while (count > 0) { - const use1 = this.uses.pop(); - const use2 = uses.pop(); - assert(use1 === use2); - --count; - } - } - unsetProperty(property, values) { - switch (property) { - case 'aliases': return this.unsetAlias(values); - case 'uses': return this.unsetUses(values); - } - throw new Error(`unsetProperty was called with invalid property ${property}`); - } - createContainer(name, alias = false) - { - if (this.currentContainer !== false) { - throw new Error(`Container ${this.currentContainer} is open, must be closed before start new container`); - } - - // console.log(`createContainer(${name},${alias}) at ${this.context.sourceRef}`); - // if container is defined, contents is ignored but alias must be defined - if (alias) { - this.addScopeAlias(alias, name); + this.containers = new Containers(this); + } + getDefinitionByItem(item, options = {}) { + let instance = null; + const instances = [...(options.instances ?? []), ...Object.values(this.types).map(x => x.instance)]; + for (const _instance of instances) { + if (Debug.active) console.log(_instance); + if (_instance.expressionItemClass === item.constructor) { + instance = _instance; + break; + } } - - console.log(`CREATE CONTAINER ${name}`); - // if container is defined, contents is ignored - if (this.containers[name]) { + if (Debug.active) console.log(instance, item.id); + const res = instance.get ? instance.get(item.id): false; + if (Debug.active) console.log(res); + return res; + } +/* getDefinition(name, indexes) { + const reference = this.getReference(name); + const id = reference.getId(indexes); + }*/ + getArray(name, indexes) { + const reference = this.getReference(name); + if (!reference.array) { return false; } - + return reference.array.applyIndexes(reference, indexes); + } + getNameScope(name) { const nameInfo = this.decodeName(name); - this.containers[name] = {scope: nameInfo.scope, alias, definitions: {}}; - this.currentContainer = name; - return true; + return nameInfo.scope; + } + createContainer(name, alias = false) { + return this.containers.create(name, alias); } - closeContainer() - { - this.currentContainer = false; + closeContainer() { + this.containers.close(); } - pushVisibilityScope() - { + pushVisibilityScope() { this.visibilityStack.push(this.visibilityScope); - this.visibilityScope = this.scope.deep; + this.visibilityScope = Context.scope.deep; } - popVisibilityScope() - { + popVisibilityScope() { if (this.visibilityStack.length < 1) { throw new Error(`invalid popVisibilitScope`); } @@ -101,39 +71,43 @@ module.exports = class References { instance } } - clearType(type) { + clearType(type, label) { const typeInfo = this.types[type]; if (typeof typeInfo === 'undefined') { throw new Error(`type ${type} not registered`); } - typeInfo.instance.clear(); + typeInfo.instance.clear(label); // TODO: remove references - for (const name in this.definitions) { - if (this.definitions[name].type !== type) continue; - delete this.definitions[name]; + for (const name in this.references) { + if (this.references[name].type !== type) continue; + delete this.references[name]; } } + clearScope(proofScope) { + this.containers.clearScope(proofScope); + } isReferencedType(type) { return type.at(0) === '&' } getReferencedType(type) { return this.isReferencedType(type) ? type.substring(1):type; } - - _getRegisteredType (type) { - const reference = this.isReferencedType(type); - const finalType = this.getReferencedType(type); - const tdata = this.types[finalType]; - if (typeof tdata === 'undefined') { - throw new Error(`unknown type ${type} [${finalType}]`); + getTypeDefinition(type) { + const typedef = this.types[type] ?? null; + if (typedef === null) { + throw new Error(`Invalid or unregistered type ${type}`); } - if (reference) { - tdata.reference = true; - tdata.referencedType = finalType; + return typedef; + } + getTypeInstance(type) { + const typedef = this.types[type] ?? null; + if (typedef === null) { + throw new Error(`Invalid or unregistered type ${type}`); } - return tdata; + return typedef.instance; } decodeName (name) { + assert(typeof name === 'string'); const parts = name.split('.'); let scope = false; if (parts.length === 1) { @@ -145,157 +119,207 @@ module.exports = class References { const absoluteScope = isProofScope || isSubproofScope || isAirScope; let res = {isProofScope, isSubproofScope, isAirScope, absoluteScope, parts}; if (absoluteScope) { + // if absolute scope (proof, subproof or air) and has more than 2 parts, means at least 3 parts, + // the middle part was container. if (parts.length > 2) { return {...res, scope: parts[0], name: parts.slice(-1), container: parts.slice(0, -1).join('.')}; } - return {...res, scope: parts[0], static: true, name: parts.slice(1).join('.')}; + // if absolute, but only 2 or less parts, no container specified. + return {...res, scope: parts[0], isStatic: true, name: parts.slice(1).join('.')}; } + // if no absolute scope, could be an alias if it has 2 parts. return {...res, scope, name}; } - getArrayAndSize(lengths) { - if (lengths && lengths.length) { - let array = new MultiArray(lengths); - return [array, array.size]; + normalizeType(type) { + if (this.isReferencedType(type)) { + return [true, this.getReferencedType(type)]; + } + return [false, type]; + } + getGlobalScope(name, useCurrentContainer = true) { + const res = this.decodeName(name); + if (res.absoluteScope) { + if (res.isProofScope) return 'proof'; + if (res.isSubproofScope) return 'subproof'; + if (res.isAirScope) return 'air'; } - return [false, 1]; + if (useCurrentContainer) { + this.containers.getCurrent(); + } + return false; } - declare (name, type, lengths = [], data = null, initValue = null) { + checkAndGetContainer(nameInfo){ + const container = this.containers.getCurrent(); + if (container && nameInfo.scope !== false) { + throw new Error(`Static reference ${nameInfo.name} inside container not allowed`); + } + // containers are scope-free. + return container; + } + isStaticDeclaredPreviously(nameInfo, existingReference) { + if (!nameInfo.isStatic) return false; + // only created and init once + if (existingReference) { + if (existingReference.isStatic) { + return true; + } + throw new Error(`Static reference ${nameInfo.name} has been defined on non-static scope`); + } + return false; + } + prepareScope(nameInfo, type, existingReference) { + if (nameInfo.isStatic) { + return [Context.scope.declare(nameInfo.name, type, false, nameInfo.scope), nameInfo.scope]; + } + + const scopeId = this.hasScope(type) ? Context.scope.declare(nameInfo.name, type, existingReference, false) : 0; + if (nameInfo.name === 'Main.jmp') { + console.log(scopeId); + console.log(existingReference); + // EXIT_HERE; + } + // scope(name, def) => exception !!! + // => scopeId; + if (existingReference !== false && this.isVisible(existingReference)) { + if (existingReference.scopeId === scopeId || existingReference.scope === false || scopeId === false) { + throw new Error(`At ${Context.sourceRef} is defined ${nameInfo.name}, but ${existingReference.name} as ${existingReference.type} was defined previously on ${existingReference.data.sourceRef}`) + } + } + return [scopeId, false]; + } + declare(name, type, lengths = [], options = {}, initValue = null) { assert(typeof name === 'string'); assert(!name.includes('::object')); assert(!name.includes('.object')); const nameInfo = this.decodeName(name); - console.log(`DECLARE_REFERENCE ${name} ==> ${nameInfo.name} ${type} []${lengths.length} scope:${nameInfo.scope} #${this.scope.deep}`, data); + if (name === 'Main.jmp') { console.log(nameInfo); } + // console.log(`DECLARE_REFERENCE ${name} ==> ${nameInfo.name} ${type} ${lengths.length ? '[' + lengths.join(',') + '] ': ''}scope:${nameInfo.scope} #${Context.scope.deep} ${initValue}[type: ${initValue instanceof Object ? initValue.constructor.name : typeof initValue}]`, options); - let [array, size] = this.getArrayAndSize(lengths); + let [array, size] = Reference.getArrayAndSize(lengths); + if (Debug.active) console.log(name, lengths, array, size); - const def = this.definitions[nameInfo.name]; - let scopeId; - let scope = false; + let refname = nameInfo.name; + let internalReference = false; + if (nameInfo.absoluteScope === false && nameInfo.parts.length === 2) { + const _ref = this.references[nameInfo.parts[1]] ?? false; + internalReference = _ref; + } + const existingReference = this.references[nameInfo.name] ?? internalReference; + // When reference is reference to other reference, caller put & before type name (ex: &int) - if (this.currentContainer !== false) { - if (nameInfo.scope !== false) { - throw new Error(`Static reference ${name} inside container not allowed`); - } - } else if (nameInfo.static) { - // only created and init once - if (def) { - if (!def.static) { - throw new Error(`Static reference ${name} has been defined on non-static scope`); - } - // nothing to do (important: static scope) - return def.locator; - } - scope = nameInfo.scope; - scopeId = this.scope.declare(nameInfo.name, type, false, scope); - } else { - scopeId = this.hasScope(type) ? this.scope.declare(nameInfo.name, type, def ?? false, scope) : 0; + const [isReference, finalType] = this.normalizeType(type); + + let scopeId = 0; + let scope = false; - // scope(name, def) => exception !!! - // => scopeId; - if (typeof def !== 'undefined' && def.scopeId === scopeId) { - throw new Error(`${name} was defined previously on ${def.data.sourceRef}`) + const container = this.checkAndGetContainer(nameInfo); + if (!container) { + if (this.isStaticDeclaredPreviously(nameInfo, existingReference)) { + return existingReference.getId(); } + [scopeId, scope] = this.prepareScope(nameInfo, finalType, existingReference); } - // When reference is reference to other reference, caller put & before type name (ex: &int) - const reference = this.isReferencedType(type); - - const tdata = reference ? {} : this._getRegisteredType(type); - const id = reference ? null : tdata.instance.reserve(size, nameInfo.name, array, data); - const cdef = { - type, - array, - reference, - referencedType: reference ? type.substring(1) : false, // to define valid referenced type - locator: id, - scopeId, - scope, - container: this.currentContainer, - static: nameInfo.static ?? false, - data - } - if (this.currentContainer === false) { - this.definitions[nameInfo.name] = cdef; + + const instance = this.getTypeInstance(finalType); + + /* take constant property from options, the rest is data information */ + const constProperty = options.const ?? false; + let data = {...options}; + delete data.const; + + const refProperties = {container, scope, isStatic: nameInfo.isStatic, data, const: constProperty}; + + + // TODO: reserve need array for labels? + const id = isReference ? null : instance.reserve(size, nameInfo.name, array, data); + + const reference = new Reference(nameInfo.name, type, isReference, array, id, instance, scopeId, refProperties); + + if (container) { + this.containers.addReference(nameInfo.name, reference); } else { - console.log(name); - console.log(`ADD TO CONTAINER ${this.currentContainer} ${nameInfo.name}`); - if (name === 'Byte4.gsum_result') EXIT_HERE; - this.containers[this.currentContainer].definitions[nameInfo.name] = cdef; + this.references[nameInfo.name] = reference; } if (initValue !== null) { - this.set(nameInfo.name, [], initValue); + if (Debug.active) { + if (initValue && typeof initValue.toString === 'function') console.log(initValue.toString()); + else console.log(initValue); + } + reference.init(initValue); } return id; } isDefined(name, indexes = []) { - let def = this.getDefinition(name, false); - let found = Boolean(def); - /* - const names = this.context.getNames(name); - let found = false; - let def; - for (const _name of names) { - def = this.definitions[_name] ?? false; - if (def) { - found = _name; - break; - } - } - - console.log(def); - console.log(this.visibilityScope); - if (def.scopeId && def.type !== 'constant' && def.scopeId < this.visibilityScope) { - return false; - } -*/ - if (found !== false) { - if (Array.isArray(indexes) && indexes.length > 0) { - return def.array ? def.array.isValidIndexes(indexes) : false; - } - return true; - } - - return false; + const reference = this.getReference(name, false); + if (!reference) return false; + return reference.isValidIndexes(indexes); } hasScope(type) { // TODO: inside function ?? - // TODO: col reference - // return ['im', 'witness', 'fixed', 'public', 'prover', 'challenge'].includes(type) === false; - return ['public', 'proofvalue', 'challenge', 'subproofvalue'].includes(type) === false; + return ['public', 'proofvalue', 'challenge', 'subproofvalue', 'publictable'].includes(type) === false; } get (name, indexes = []) { - const [instance, info] = this._getInstanceAndLocator(name, indexes); - return instance.get(info.locator + info.offset); + assertLog(typeof name === 'string', name); + if (Debug.active) console.log('GET', name, indexes); + + // getReference produce an exception if name not found + return this.getReference(name).get(indexes); } getIdRefValue(type, id) { - const tdata = this._getRegisteredType(type); - return tdata.instance.getTypedValue(id); + return this.getTypeDefinition(type).instance.getItem(id); } getLabel(type, id, options) { - const instance = this.types[type].instance; - return instance.getLabel(id, {type, ...options}); + return this.getTypeDefinition(type).instance.getLabel(id, {type, ...options}); } getTypeR(name, indexes, options) { - const [instance, info] = this._getInstanceAndLocator(name, indexes); - return [instance.getType(info.locator + info.offset), info.reference, info.array ?? false]; + const reference = this.getReference(name); + const item = reference.getItem(indexes); + return [item, reference.isReference]; } - getTypedValue (name, indexes, options) { + getItem(name, indexes, options) { + + assert(typeof name === 'string' || (Array.isArray(name) && name.length > 0)); + + if (Debug.active) console.log(indexes); indexes = indexes ?? []; options = options ?? {}; - if (typeof indexes === 'undefined') indexes = []; + const reference = this.getReference(name); + // TODO: if reference is a 'reference' check if name is correct + const item = reference.getItem(indexes, {...options, label: reference.name}); + + if (options.preDelta) { + EXIT_HERE; + console.log(typeof tvalue.value); + assert(typeof tvalue.value === 'number' || typeof tvalue.value === 'bigint'); + tvalue.value += options.preDelta; + instance.set(info.locator + info.offset, tvalue.value); + } + if (options.postDelta) { + EXIT_HERE; + assert(typeof tvalue.value === 'number' || typeof tvalue.value === 'bigint'); + instance.set(info.locator + info.offset, tvalue.value + options.postDelta); + } + return item; const [instance, info, def] = this._getInstanceAndLocator(name, indexes); let tvalue; if (info.array) { // array info, could not be resolved - tvalue = {type: info.type ?? def.type, id: info.locator + info.offset }; + console.log('***** ARRAY ******'); + tvalue = new ArrayOf(instance.cls, info.locator + info.offset, info.type ?? def.type, instance); } else { // no array could be resolved + console.log([instance.constructor.name, info.type]); tvalue = instance.getTypedValue(info.locator + info.offset, 0, info.type); } + // TODO: review + if (info.type !== 'function') { + assertLog(tvalue instanceof ExpressionItem, {name, infotype: info.type, tvalue}); + } if (typeof info.row !== 'undefined') { tvalue.row = info.row; } @@ -329,101 +353,164 @@ module.exports = class References { } return tvalue; } + _getTypedValue (name, indexes, options) { + indexes = indexes ?? []; + options = options ?? {}; + + if (typeof indexes === 'undefined') indexes = []; + + const [instance, info, def] = this._getInstanceAndLocator(name, indexes); + let tvalue; + if (info.array) { + // array info, could not be resolved + console.log('***** ARRAY ******'); + tvalue = new ArrayOf(instance.cls, info.locator + info.offset, info.type ?? def.type, instance); + } else { + // no array could be resolved + console.log([instance.constructor.name, info.type]); + tvalue = instance.getTypedValue(info.locator + info.offset, 0, info.type); + } + // TODO: review + if (info.type !== 'function') { + assertLog(tvalue instanceof ExpressionItem, {name, infotype: info.type, tvalue}); + } + if (typeof info.row !== 'undefined') { + tvalue.row = info.row; + } + if (!info.array) { + tvalue.id = info.locator; + } + if (options.full) { + tvalue.locator = info.locator; + tvalue.instance = instance; + tvalue.offset = info.offset; + } + if (info.dim) { + tvalue.dim = info.dim; +// tvalue.arrayType = info.arrayType; + tvalue.lengths = info.lengths; + } + if (info.array) { + tvalue.dim = 'DEPRECATED'; + tvalue.lengths = 'DEPRECATED'; + tvalue.array = info.array; + } + if (options.preDelta) { + if (Debug.active) console.log(typeof tvalue.value); + assert(typeof tvalue.value === 'number' || typeof tvalue.value === 'bigint'); + tvalue.value += options.preDelta; + instance.set(info.locator + info.offset, tvalue.value); + } + if (options.postDelta) { + assert(typeof tvalue.value === 'number' || typeof tvalue.value === 'bigint'); + instance.set(info.locator + info.offset, tvalue.value + options.postDelta); + } + return tvalue; + } getTypeInfo (name, indexes = []) { return this._getInstanceAndLocator(name, indexes); } addUse(name) { - if (!this.containers[name]) { - // TODO: defined must be check containers - throw new Exception(`Use not created container ${name}`); - } - this.scope.addToScopeProperty('uses', name); - this.uses.push(name); + this.containers.addUse(name); } searchDefinition(name) { const subnames = name.split('.'); - const container = subnames.length > 1 ? subnames.slice(0, -1).join('.') : false; + const explicitContainer = subnames.length > 1 ? subnames.slice(0, -1).join('.') : false; const lname = subnames[subnames.length - 1]; - if (name === 'air.gw1') { - console.log({subnames, container, lname}); - } - let def = false; - - if (this.currentContainer !== false && !container) { - def = this.containers[this.currentContainer].definitions[lname]; - } - if (!def && container) { - if (['proof', 'subproof', 'air'].includes(container)) { - const scopeId = this.scope.getScopeId(container); - if (name === 'air.gw1') { - console.log(scopeId); - } + let reference = false; + if (!explicitContainer) { + reference = this.containers.getReferenceInsideCurrent(lname, false); + } else { + if (['proof', 'subproof', 'air'].includes(explicitContainer)) { + const scopeId = Context.scope.getScopeId(explicitContainer); if (scopeId === false) { - throw new Error(`not found scope ${container}`); + throw new Error(`not found scope ${explicitContainer}`); } - def = this.definitions[lname]; - if (name === 'air.gw1') { - console.log(def); + reference = this.references[lname]; + if (explicitContainer === 'air' && !reference) { + reference = this.references[Context.airName+'.'+lname]; } - if (def && def.scopeId !== scopeId) { - throw new Error(`Not match declaration scope and accessing scope (${container}) of ${name}`); + if (reference && reference.scopeId !== scopeId) { + throw new Error(`Not match declaration scope and accessing scope (${containerName}) of ${name}`); } } - if (!def && this.containers[container]) { - def = this.containers[container].definitions[lname]; + if (!reference && this.containers.isDefined(explicitContainer)) { + reference = this.containers.getReferenceInside(explicitContainer, lname, false); } } - if (!def) { - def = this.definitions[name]; + if (!reference) { + reference = this.references[name] ?? false; } - let iuse = this.uses.length; - while (!def && iuse > 0) { - --iuse; - def = this.containers[this.uses[iuse]].definitions[name]; + if (!reference) { + this.containers.getReference(name, false); } - return def; + return reference; } isVisible(def) { - return !def.scopeId || def.type === 'constant' || def.scopeId >= this.visibilityScope; // || def.scopeId <= this.scope.getScopeId('air'); - } - getDefinition(name, defaultValue) { - // debugger; - const nameInfo = this.decodeName(Array.isArray(name) ? name[0]:name); - let names; + if (Debug.active) console.log('ISVISIBLE', (def.constructor ?? {name: '_'}).name, def); + return !def.scopeId || !this.hasScope(def.type) || ['constant', 'function'].includes(def.type) || + def.scopeId >= this.visibilityScope; // || def.scopeId <= Context.scope.getScopeId('air'); + } + /** + * + * @param {string|string[]} name + * @param {*} defaultValue + * @param {Object} debug + * @returns {Reference} + */ + getReference(name, defaultValue, debug = {}) { + // if more than one name is sent, use the first one (mainName). Always first name it's directly + // name defined on source code, second optionally could be name with subproof, because as symbol is + // stored with full name. + const mainName = Array.isArray(name) ? name[0]:name; + const nameInfo = this.decodeName(mainName); + let names = false; + if (nameInfo.scope !== false) { - names = [Array.isArray(name) ? name[0]:name]; + // if scope is specified on mainName, the other names don't make sense + names = [mainName]; } else if (!nameInfo.absoluteScope && nameInfo.parts.length == 2) { - // console.log(['getScopeAlias',nameInfo.parts[0]]); - const container = this.getAlias(nameInfo.parts[0], {container: false}).container; + // absoluteScope means that first scope was proof, subproof or air. If a non absolute + // scope is defined perhaps was an alias. + const container = this.containers.getFromAlias(nameInfo.parts[0], false); if (container) { + // if it's an alias associated with container, replace alias with + // container associated. names = [container + '.' + nameInfo.parts.slice(1).join('.')]; } } + + if (Debug.active) console.log(names); if (!names) { - names = this.context.getNames(name); + names = Context.current.getNames(name); } - // console.log(`getDefinition(${name}) on ${this.context.sourceRef} = [${names.join(', ')}]`); - let def; + + if (Debug.active) console.log(names); + // console.log(`getReference(${name}) on ${this.context.sourceRef} = [${names.join(', ')}]`); + let reference = false; for (const name of names) { - def = this.searchDefinition(name); - if (typeof def !== 'undefined') break; + reference = this.searchDefinition(name); + if (reference) break; } - if (typeof def === 'undefined') { - if (typeof defaultValue !== 'undefined') return defaultValue; - throw new Error(`Reference ${names.join(',')} not found`); + if (!reference) { + if (typeof defaultValue !== 'undefined') return defaultValue; + throw new Exceptions.ReferenceNotFound(names.join(',')); } // constants are visible inside functions - if (this.isVisible(def) === false) { + if (!nameInfo.absoluteScope && this.isVisible(reference) === false) { + console.log(reference); + console.log(name); + console.log(nameInfo); if (typeof defaultValue !== 'undefined') return defaultValue; - throw new Error(`Reference ${names.join(',')} not visible from current scope`); + throw new Exceptions.ReferenceNotVisible(names.join(',')); } - return def; + return reference; } _getInstanceAndLocator (name, indexes) { - const def = this.getDefinition(name); + const def = this.getReference(name); // TODO: partial access !!! // TODO: control array vs indexes const tdata = this._getRegisteredType(def.type); @@ -451,69 +538,72 @@ module.exports = class References { return [tdata.instance, {locator: def.locator, ...extraInfo}, def]; } getReferenceType (name) { - let dest = this.getDefinition(name); - return dest.type ?? false; + return this.getReference(name, {type: false}).type; } setReference (name, value) { - let dest = this.getDefinition(name); - const _value = value instanceof Expression ? value.getAloneOperand() : value; + let reference = this.getReference(name); // TODO: reference not knows operand types - if (_value.type === 3) { - assert(!_value.next); - if (_value.op === 'reference') { - assert(!_value.array); - const src = this.getDefinition(_value.name); + if (value instanceof Expression) { + value = value.getAloneOperand(); + if (value instanceof ReferenceItem) { + assert(!value.next); + assert(!value.array); + const src = this.getReference(value.name); if (src.array) { - const __array = src.array.getIndexesTypedOffset(_value.__indexes); - dest.array = __array.array; - dest.locator = src.locator + __array.offset; + const __array = src.array.getIndexesTypedOffset(value.__indexes); + reference.array = __array.array; + reference.locator = src.locator + __array.offset; } else { - dest.array = false; - dest.locator = src.locator; + reference.array = false; + reference.locator = src.locator; } - dest.type = src.type; - dest.scope = src.scope; - dest.scopeId = src.scopeId; - } else if (_value.op === 'idref') { - dest.locator = _value.id; - dest.type = _value.refType; - dest.scope = false; - dest.scopeId = false; - dest.array = _value.array; + reference.type = src.type; + reference.scope = src.scope; + reference.scopeId = src.scopeId; + } else if (value instanceof ProofItem) { + reference.locator = value.id; + reference.type = value.refType; + reference.scope = false; + reference.scopeId = false; + reference.array = value.array; } + } else if (value instanceof ProofItem) { + assert(!value.__next); + reference.locator = value.id; + reference.type = value.refType; } else { - assert(_value.type == 1); - assert(!_value.__next); - dest.locator = _value.id; - dest.type = _value.refType; + throw new Error(`Invalid reference`); } } - restore (name, cdef) { - this.definitions[name] = cdef; + restore (name, reference) { + this.references[name] = reference; } set (name, indexes, value) { - // console.log({name, indexes, value}); - // if (name === 'N_MAX') debugger; - const [instance, info] = this._getInstanceAndLocator(name, indexes); - return instance.set(info.locator + info.offset, value); - } + if (Debug.active) console.log('SET', name, indexes, value); + assert(value !== null); // to detect obsolete legacy uses + // getReference produce an exception if name not found + const reference = this.getReference(name); + reference.set(value, indexes); + } unset(name) { - let def = this.definitions[name]; + let def = this.references[name]; if (def.array) delete def.array; - delete this.definitions[name]; + delete this.references[name]; + } + unsetProperty(property, values) { + this.containers.unsetProperty(property, values); } - *[Symbol.iterator]() { - for (let index in this.definitions) { + for (let index in this.references) { yield index; } } *keyValuesOfTypes(types) { - for (let index in this.definitions) { - const def = this.definitions[index]; + for (let index in this.references) { + const def = this.references[index]; // console.log({index, ...def}); if (!types.includes(def.type)) continue; yield [index, def]; @@ -521,19 +611,19 @@ module.exports = class References { } *values() { - for (let index in this.definitions) { - yield this.definitions[index]; + for (let index in this.references) { + yield this.references[index]; } } *keyValues() { - for (let index in this.definitions) { - yield [index, this.definitions[index]]; + for (let index in this.references) { + yield [index, this.references[index]]; } } dump () { - for (let name in this.definitions) { - const def = this.definitions[index]; + for (let name in this.references) { + const def = this.references[index]; const indexes = def.array === false ? '': def.multiarray.getLengths().join(','); // console.log(`${name.padEnd(30)}|${def.type.padEnd(10)}|${indexes}`); } diff --git a/src/runtime.js b/src/runtime.js new file mode 100644 index 0000000..e89a75f --- /dev/null +++ b/src/runtime.js @@ -0,0 +1,55 @@ +const util = require('util'); +const Expression = require('./expression.js'); +const NonRuntimeEvaluable = require('./non_runtime_evaluable.js'); +const {assert, assertLog} = require('./assert.js'); +const ExpressionItems = require("./expression_items.js"); +const Context = require('./context.js'); + +module.exports = class Runtime { + + eval(operand, options) { + + if (operand instanceof ExpressionItems.ReferenceItem || operand instanceof ExpressionItems.FunctionCall) { + return this.resolveReference(operand, options); + } + // TODO: if not runtime evaluable return null or + const op = operand.op; + switch (op) { + case 'string': return this.evalString(operand); + case 'number': return this.evalNumber(operand); + case 'call': return this.evalCall(operand); + case 'idref': return this.evalIdref(operand); +// case 'reference': return this.evalReference(operand, expr, options); + case 'reference': return this.resolveReference(operand, options); + } + throw new Error(`Invalid runtime operation ${op}`); + } + resolveReference(operand, options) { + const names = Context.current.getNames(operand.name); + + let getTypeValueOptions = {}; + if (operand.inc === 'pre') { + getTypeValueOptions.preDelta = 1n; + } + if (operand.inc === 'post') { + getTypeValueOptions.postDelta = 1n; + } + if (operand.dec === 'pre') { + getTypeValueOptions.preDelta = -1n; + + } + if (operand.dec === 'post') { + getTypeValueOptions.postDelta = -1n; + } + let res = Context.references.getItem(names, operand.__indexes ?? [], options); + if (typeof operand.__next !== 'undefined') { + res.__next = res.next = operand.__next; + } else if (typeof operand.next !== 'number' && (operand.next || operand.prior)) { + console.log(operand); + throw new Error(`INTERNAL: next and prior must be previouly evaluated`); + } else if (typeof operand.next === 'number' && operand.next) { + res.next = operand.next; + } + return res; + } +} diff --git a/src/scope.js b/src/scope.js index c5445ed..554d9a4 100644 --- a/src/scope.js +++ b/src/scope.js @@ -1,6 +1,7 @@ +const Context = require('./context.js'); +const {assert, assertLog} = require('./assert.js'); module.exports = class Scope { - constructor (Fr) { - this.Fr = Fr; + constructor () { this.deep = 0; this.shadows = [{}]; this.properties = [{}]; @@ -22,9 +23,6 @@ module.exports = class Scope { } } } - setReferences(references) { - this.references = references; - } addToScopeProperty(property, value) { if (typeof this.properties[this.deep][property] === 'undefined') { this.properties[this.deep][property] = [value]; @@ -62,19 +60,20 @@ module.exports = class Scope { // console.log(`POP ${name}`); // console.log(shadows[name]); if (shadows[name].ref === false) { - if (!exclude) this.references.unset(name); + if (!exclude) Context.references.unset(name); } else { // I could not 'update' reference name, because was an excluded type. This situation // was an error because could exists same name in scope linked. if (exclude) { throw new Error(`Excluded type ${shadows[name].type} has shadow reference called ${name}`); } - this.references.restore(name, shadows[name].ref); + Context.references.restore(name, shadows[name].ref); } } this.shadows[this.deep] = {}; for (const property in this.properties[this.deep]) { - this.references.unsetProperty(property, this.properties[this.deep][property]); + assertLog(typeof Context.references.unsetProperty === 'function', Context.references.constructor.name); + Context.references.unsetProperty(property, this.properties[this.deep][property]); } this.properties[this.deep] = {}; --this.deep; @@ -104,21 +103,4 @@ module.exports = class Scope { this.pop(excludeTypes); return this.instanceType; } - *[Symbol.iterator]() { - for (let index in this.references) { - yield index; - } - } - - *values() { - for (let index in this.references) { - yield this.references[index]; - } - } - - *keyValues() { - for (let index in this.references) { - yield [index, this.references[index]]; - } - } } diff --git a/src/sequence.js b/src/sequence.js index a084f55..892e473 100644 --- a/src/sequence.js +++ b/src/sequence.js @@ -1,7 +1,9 @@ -const chai = require("chai"); -const assert = chai.assert; +const {assert, assertLog} = require("./assert.js"); const Router = require("./router.js"); const Expression = require("./expression.js"); +const Values = require('./values.js'); +const Debug = require('./debug.js'); +const vm = require('vm'); const MAX_ELEMS_GEOMETRIC_SEQUENCE = 300; class SequencePadding { @@ -11,6 +13,8 @@ class SequencePadding { } } module.exports = class Sequence { + #values; + static cacheGeomN = []; // TODO: Review compiler estructures // TODO: iterator of values without "extend" @@ -19,23 +23,36 @@ module.exports = class Sequence { constructor (parent, expression, maxSize) { this.parent = parent; - this.values = []; + this.#values = new Values(); this.padding = false; this.expression = expression; this.router = new Router(this, 'type', {pre: this.preRoute}); + this.maxSize = typeof maxSize === 'undefined' ? false : Number(maxSize); this.paddingCycleSize = false; this.paddingSize = 0; this.extendPos = 0; this.debug = ''; this.valueCounter = 0; + this.varIndex = 0; this.sizeOf(expression); } + clone() { + let cloned = new Sequence(this.parent, this.expression, this.maxSize); + if (Debug.active) console.log(['CLONED', this.maxSize, cloned.maxSize]); + this.#values.mutable = false; + cloned.#values = this.#values.clone(); + return cloned; + } preRoute(method, e) { if (e.debug) this.debug = e.debug; } getValue(index) { - return this.values[index]; + return this.#values.getValue(index); + } + #setValue(index, value) { + ++this.valueCounter; + return this.#values.__setValue(index, value); } setValue(index, value) { /* assert(this.extendPos >= 0 && (this.maxSize === false || this.extendPos < this.maxSize), @@ -44,29 +61,43 @@ module.exports = class Sequence { if ((index >= 0 && (this.maxSize === false || index < this.maxSize) === false)) { console.log(`\x1B[33mERROR Invalid value of extendPos:${index} maxSize:${this.maxSize} ${this.debug}\x1B[0m`); } - if (typeof this.values[index] !== 'undefined') { + if (typeof this.#values.getValue(index) !== 'undefined') { console.log(`\x1B[33mERROR Rewrite index position:${index} ${this.debug}\x1B[0m`); } ++this.valueCounter; - return this.values[index] = value; + return this.#values.setValue(index, value); } sizeOf(e) { this.paddingCycleSize = false; this.paddingSize = 0; const size = this._sizeOf(e); assert(size >= this.paddingCycleSize, `size(${size}) < paddingCycleSize(${this.paddingCycleSize})`); + if (Debug.active) { + console.log(['SIZE(MAXSIZE)', this.maxSize]); + console.log(['SIZE(paddingCycleSize)', this.paddingCycleSize]); + console.log(['SIZE(paddingSize)', this.paddingSize]); + } if (this.paddingCycleSize) { this.paddingSize = this.maxSize - (size - this.paddingCycleSize); this.size = size - this.paddingCycleSize + this.paddingSize; } else { this.size = size; } - + if (Debug.active) console.log(['SIZE', this.size]); return this.size; } _sizeOf(e) { if (e instanceof Expression) return 1; - else return this.router.go(e, '_sizeOf'); + switch (e.type) { + case 'sequence': return this._sizeOfSequence(e); + case 'padding_seq': return this._sizeOfPaddingSeq(e); + case 'seq_list': return this._sizeOfSeqList(e); + case 'repeat_seq': return this._sizeOfRepeatSeq(e); + case 'range_seq': return this._sizeOfRangeSeq(e); + case 'arith_seq': return this._sizeOfArithSeq(e); + case 'geom_seq': return this._sizeOfGeomSeq(e); + } + throw new Error(`Invalid sequence type ${e.type} sizeof`); } _sizeOfSeqList(e) { let size = 0; @@ -79,7 +110,8 @@ module.exports = class Sequence { return this._sizeOfSeqList(e); } _sizeOfRepeatSeq(e) { - const times = Number(this.parent.getExprNumber(e.times)); + const times = this.toNumber(this.parent.getExprNumber(e.times)); + if (Debug.active) console.log(['times', times]); return times * this._sizeOf(e.value); } setPaddingSize(size) { @@ -96,17 +128,21 @@ module.exports = class Sequence { return this.setPaddingSize(this._sizeOf(e.value)); } getRangeSeqInfo(e) { - const fromTimes = e.times ? Number(this.e2num(e.times)): 1; - const toTimes = e.toTimes ? Number(this.e2num(e.toTimes)): fromTimes; + const fromTimes = e.times ? this.toNumber(this.e2num(e.times)): 1; + const toTimes = e.toTimes ? this.toNumber(this.e2num(e.toTimes)): fromTimes; + if (Debug.active) console.log(['fromTimes', fromTimes, 'toTimes', toTimes]); if (fromTimes !== toTimes) { throw new Error(`In range sequence, from(${fromTimes}) and to(${toTimes}) must be same`); } return [this.e2num(e.from), this.e2num(e.to), fromTimes]; } getTermSeqInfo(e) { - const t1Times = e.t1.times ? Number(this.e2num(e.t1.times)): 1; - const t2Times = e.t2.times ? Number(this.e2num(e.t2.times)): 1; - const tnTimes = e.tn.times === false ? false : (e.tn.times ? Number(this.e2num(e.t2.times)): 1); + if (e._cache_getTermSeqInfo) return e._cache_getTermSeqInfo; + + const t1Times = e.t1.times ? this.toNumber(this.e2num(e.t1.times)): 1; + const t2Times = e.t2.times ? this.toNumber(this.e2num(e.t2.times)): 1; + const tnTimes = e.tn.times === false ? false : (e.tn.times ? this.toNumber(this.e2num(e.t2.times)): 1); + if (Debug.active) console.log(['t1Times', t1Times, 't2Times', t2Times, 'tnTimes', tnTimes]); if (t1Times !== t2Times && (tnTimes === false || tnTimes === t2Times)) { throw new Error(`In term sequence, t1(${t1Times}), t2(${t2Times})`+ (tnTimes === false ? '':` and tn(${tbTimes}`)+'must be same'); @@ -118,13 +154,13 @@ module.exports = class Sequence { if (t1 === t2) { throw new Error(`In term sequence, t1(${t1}), t2(${t2}) must be different`); } - - return [t1, t2, tn, t1Times]; + e._cache_getTermSeqInfo = [t1, t2, tn, t1Times]; + return e._cache_getTermSeqInfo; } _sizeOfRangeSeq(e) { // TODO review if negative, fe? const [fromValue, toValue, times] = this.getRangeSeqInfo(e); - return Number(toValue > fromValue ? toValue - fromValue + 1n : toValue - fromValue + 1n) * times; + return this.toNumber(toValue > fromValue ? toValue - fromValue + 1n : toValue - fromValue + 1n) * times; } _sizeOfArithSeq(e) { const [t1, t2, tn, times] = this.getTermSeqInfo(e); @@ -134,7 +170,7 @@ module.exports = class Sequence { if ((delta > 0 && tn < t2) || (delta < 0 && tn > t2) || (distance % delta !== 0n)) { throw new Error(`Invalid terms of arithmetic sequence ${t1},${t2}...${tn} at ${this.debug}`); } - return Number(distance/delta + 2n) * times; + return this.toNumber(distance/delta + 2n) * times; } else { return this.setPaddingSize(2); @@ -148,24 +184,24 @@ module.exports = class Sequence { const tfinal = tn === false ? t1 + delta * BigInt(this.paddingSize): tn + delta; console.log({tag: 'XXXXX', tn, tfinal, paddingSize: this.paddingSize}); let value = t1;*/ - const count = tn === false ? this.paddingSize : times * (Number(((tn - t1) / delta)) + 1); + const count = tn === false ? this.paddingSize : times * (this.toNumber(((tn - t1) / delta)) + 1); const finalExtendPos = this.extendPos + count; // console.log({t1, t2, delta, tn, extendPos: this.extendPos, count, finalExtendPos, paddingSize: this.paddingSize}); let value = t1; while (this.extendPos < finalExtendPos) { for (let itimes = 0; itimes < times && this.extendPos < finalExtendPos; ++itimes) { - this.setValue(this.extendPos++,value); + this.#setValue(this.extendPos++,value); } value = value + delta; } return count; } calculateGeomN(ratio, ti, tf) { - const ratioAsNum = Number(ratio); + const ratioAsNum = this.toNumber(ratio); const rn = tf/ti; if (rn <= Number.MAX_SAFE_INTEGER) { - return BigInt(Math.round(Math.log(Number(rn))/Math.log(ratioAsNum))); + return BigInt(Math.round(Math.log(this.toNumber(rn))/Math.log(ratioAsNum))); } const key = [ratio, rn].join('_'); @@ -193,7 +229,7 @@ module.exports = class Sequence { value = value / chunkValues[index]; n = n + chunks[index]; } - n = n + BigInt(Math.round(Math.log(Number(value))/Math.log(ratioAsNum))); + n = n + BigInt(Math.round(Math.log(this.toNumber(value))/Math.log(ratioAsNum))); Sequence.cacheGeomN[key] = n; return n; } @@ -240,7 +276,7 @@ module.exports = class Sequence { // console.log({padding, calculateSize, ti, tf, ratio, n, t1, t2, tn}); throw new Error(`ERROR geometric seq calculation ${tf} !== ${ti} * (${ratio} ** ${BigInt(n)})`); } - return [Number(n) + 1, reverse, ti, tf, ratio]; + return [this.toNumber(n) + 1, reverse, ti, tf, ratio]; } _sizeOfGeomSeq(e) { const [t1, t2, tn, times] = this.getTermSeqInfo(e); @@ -250,7 +286,7 @@ module.exports = class Sequence { const [count, reverse, ti, tf, ratio] = this.getGeomInfo(t1, t2, tn, times, true); return tn === false ? count : count * times; } - _extendGeomSeq(e) { + _extendGeomSeq(e) { const [t1, t2, _tn, times] = this.getTermSeqInfo(e); const [_count, reverse, ti, tf, ratio] = this.getGeomInfo(t1, t2, _tn, times); @@ -269,7 +305,7 @@ module.exports = class Sequence { while (remaingValues > 0 && itimes > 0) { --remaingValues; --itimes; - this.setValue(this.extendPos, value); + this.#setValue(this.extendPos, value); this.extendPos = this.extendPos + (reverse ? -1:1); } itimes = times; @@ -291,21 +327,44 @@ module.exports = class Sequence { assert(times > 0); while (value <= toValue) { for (let itimes = 0; itimes < times; ++itimes) { - this.setValue(this.extendPos++, value); + this.#setValue(this.extendPos++, value); } value = (value + delta) * ratio; } return this.extendPos - initialExtendPos; } + _gcodeRangeSeq(e) { + const [fromValue, toValue, times] = this.getRangeSeqInfo(e); + const delta = fromValue > toValue ? -1n:1n; + const v = this.createCodeVariable('_v'); + let code = `for(let ${v}=${fromValue}n;${v}<=${toValue}n;${v}=${v}${delta > 0n?'+'+delta:delta}n){`; + if (times === 1) { + code += `__values.push(${v});}\n`; + } else { + const v2 = this.createCodeVariable(); + code += `for(let ${v2}=0;${v2}<${times};++${v2}){__values.push(${v})}}\n;`; + } + const count = times * (Number((toValue - fromValue) / delta) + 1); + return [code, count]; + } + extend() { - this.values = new Array(this.size); + if (Debug.active) console.log(this.size); this.extendPos = 0; - this._extend(this.expression); - return this.values; + const [code, count] = this._gcode(this.expression); + let __values = []; + const context = {__values} + vm.createContext(context); + vm.runInContext(code, context); + this.#values.__setValues(__values); + this.#values.mutable = false; } verify() { - console.log(this.toString()); - console.log([this.extendPos, this.size]); + if (Debug.active) { + console.log(this.toString()); + console.log([this.extendPos, this.size]); + console.log(['SIZE', this.size]); + } assert(this.valueCounter === this.size); for (let index = 0; index < size; ++index) { assert(this.values[index] === 'bigint', `type of index ${index} not bigint (${typeof this.values[index]}) ${value}`); @@ -315,7 +374,31 @@ module.exports = class Sequence { if (e instanceof Expression) { return this._extendExpr(e); } - return this.router.go(e, '_extend'); + switch (e.type) { + case 'sequence': return this._extendSequence(e); + case 'padding_seq': return this._extendPaddingSeq(e); + case 'seq_list': return this._extendSeqList(e); + case 'repeat_seq': return this._extendRepeatSeq(e); + case 'range_seq': return this._extendRangeSeq(e); + case 'arith_seq': return this._extendArithSeq(e); + case 'geom_seq': return this._extendGeomSeq(e); + } + throw new Error(`Invalid sequence type ${e.type} extend`); + } + _gcode(e) { + if (e instanceof Expression) { + return this._gcodeExpr(e); + } + switch (e.type) { + case 'sequence': return this._gcodeSequence(e); + case 'padding_seq': return this._gcodePaddingSeq(e); + case 'seq_list': return this._gcodeSeqList(e); + case 'repeat_seq': return this._gcodeRepeatSeq(e); + case 'range_seq': return this._gcodeRangeSeq(e); + case 'arith_seq': return this._gcodeArithSeq(e); + case 'geom_seq': return this._gcodeGeomSeq(e); + } + throw new Error(`Invalid sequence type ${e.type} gcode`); } _extendSeqList(e) { let count = 0; @@ -324,10 +407,23 @@ module.exports = class Sequence { } return count; } + _gcodeSeqList(e) { + let count = 0; + let code = e.values.length > 1 ? '{' : ''; + for(const value of e.values) { + const [_code, _count] = this._gcode(value); + count += _count; + code += _code; + } + return [code + (e.values.length > 1 ? '}' : ''), count]; + } _extendSequence(e) { return this._extendSeqList(e); } - _extendPaddingSeq(e) { + _gcodeSequence(e) { + return this._gcodeSeqList(e); + } + _extendPaddingSeq(e) { let from = this.extendPos; let seqSize = this._extend(e.value); let remaingValues = this.paddingSize - seqSize; @@ -344,27 +440,68 @@ module.exports = class Sequence { let upto = remaingValues >= seqSize ? seqSize : remaingValues; // console.log(`SETTING UPTO ${upto} ${remaingValues} ${seqSize}`); for (let index = 0; index < upto; ++index) { - this.setValue(this.extendPos++, this.values[from + index]); + this.#setValue(this.extendPos++, this.#values.getValue(from + index)); } remaingValues = remaingValues - upto; } return this.paddingSize; } - _extendExpr(e) { + _gcodePaddingSeq(e) { + // TODO: if last element it's a padding, not need to fill and after when access to + // a position applies an module over index. + const [_code, seqSize] = this._gcode(e.value); + let remaingValues = this.paddingSize - seqSize; + if (remaingValues < 0) { + throw new Error(`In padding range must be space at least for one time sequence at ${this.debug}`); + } + if (seqSize < 1) { + console.log(e.value); + throw new Error(`Sequence must be at least one element at ${this.debug}`); + } + if (remaingValues === 0) { + return [_code. seqSize]; + } + let code = `{${_code}`; + if (remaingValues > 0) { + const v1 = this.createCodeVariable(); + const base = this.createCodeVariable('_b'); + code += `let ${base}=__values.length-${seqSize};for (let ${v1}=0;${v1}<${remaingValues};++${v1}){__values.push(__values[${base}+${v1}]);}`; + } + code += '}\n'; + return [code, seqSize + remaingValues]; + } + _extendExpr(e) { const num = this.e2num(e); - this.setValue(this.extendPos++, num); + this._values[this.extendPos++] = num; return 1; } + _gcodeExpr(e) { + // no cache + const num = this.e2num(e); + return [`__values.push(${num}n);\n`, 1]; + } + createCodeVariable(prefix = '_i') { + return prefix+(++this.varIndex); + } _extendRepeatSeq(e) { let count = 0; const times = this.e2num(e.times); for (let itime = 0; itime < times; ++itime) { - // console.log('SETTING PRE COUNT '+count); count += this._extend(e.value); - // console.log('SETTING POST COUNT '+count); } return count; } + _gcodeRepeatSeq(e) { + if (!e.__cache) { + const times = this.e2num(e.times); + const [_code, _count] = this._gcode(e.value); + const v = this.createCodeVariable(); + const code = `for (let ${v}=0;${v}<${times};++${v}){${_code}}`; + const count = _count * Number(times); + e.__cache = [code, count]; + } + return e.__cache; + } e2num(e) { if (typeof e === 'bigint' || typeof e === 'number') { return e; @@ -384,6 +521,14 @@ module.exports = class Sequence { return {type: vdata.type, value: vdata.values[offset] }; } */ toString() { - return this.values.join(','); + return this.#values.toString(); } -} + toNumber(value) { + if (Debug.active) console.log(value); + let nvalue = Number(value); + if (nvalue === NaN || isNaN(nvalue)) { + throw new Error(`Invalid number ${value}`); + } + return nvalue; + } +} \ No newline at end of file diff --git a/src/subproof.js b/src/subproof.js index 186ed12..523c177 100644 --- a/src/subproof.js +++ b/src/subproof.js @@ -1,11 +1,10 @@ const Definitions = require("./definitions.js"); const Airs = require("./airs.js"); const Air = require("./air.js") - +const Context = require('./context.js'); module.exports = class Subproof { - constructor (context, rows, statements, aggregate) { - this.context = context; + constructor (rows, statements, aggregate) { this.rows = rows; // array of rows this.blocks = [statements]; this.airs = new Airs(this); @@ -27,10 +26,14 @@ module.exports = class Subproof { } airEnd() { if (!this.insideFirstAir) { - const spvNonDeclared = Object.keys(this.spvDeclaredInsideThisAir).filter(name => this.spvDeclaredInsideThisAir[name] === false); - if (spvNonDeclared.length > 0) { - throw new Error(``); - } + /* const spvNonDeclared = Object.keys(this.spvDeclaredInsideThisAir).filter(name => this.spvDeclaredInsideThisAir[name] === false); + console.log(spvNonDeclared); + for (const name of spvNonDeclared) { + console.log(Context.references.getReference(name)); + console.log(Context.references.getReference(name+'__')); + // console.log(spvNonDeclared, Context.airName); + // throw new Error(``); + }*/ } this.insideFirstAir = false; this.insideAir = false; @@ -42,8 +45,13 @@ module.exports = class Subproof { } if (this.insideFirstAir) { // this.colDeclaration(s, 'subproofvalue', true, false, {aggregateType: s.aggregateType}); - const res = this.context.processor.references.declare(name, 'subproofvalue', lengths, data); + console.log(['SUBPROOFVALUE', name,lengths, data]); + const res = Context.references.declare(name, 'subproofvalue', lengths, data); + console.log(Context.references.getNameScope(name)); + console.log(Context.references.containers.getCurrent()) + console.log(Context.references.containers.get(Context.references.containers.getCurrent())); this.spvDeclaredInFirstAir[name] = {res, lengths: [...lengths]}; + console.log(res); return res; } diff --git a/src/subproof_values.js b/src/subproof_values.js new file mode 100644 index 0000000..37a2f9d --- /dev/null +++ b/src/subproof_values.js @@ -0,0 +1,24 @@ +const Indexable = require("./indexable.js"); +const SubproofvalItem = require("./expression_items/subproofval.js"); +const SubproofvalDefinition = require("./definition_items/subproofval.js"); +module.exports = class SubproofValues extends Indexable { + + constructor () { + super('subproofvalue', SubproofvalDefinition, SubproofvalItem) + } + getRelativeLabel(subproofId, id, options) { + // TODO: arrays + const value = this.values.find(x => x.relativeId == id && x.subproofId == subproofId); + + return value ? value.label : `subproofvalue(${subproofId},${id})`; + } + getEmptyValue(id, options) { + const subproofId = options.subproofId; + const relativeId = this.values.reduce((res, spv) => spv.subproofId === subproofId ? res + 1 : res, 0); + let definition = super.getEmptyValue(id, {relativeId, ...options}); + return definition; + } + getAggreationTypesBySubproofId(subproofId) { + return this.values.filter(x => x.subproofId == subproofId).map(x => x.aggregateType); + } +} diff --git a/src/subproofs.js b/src/subproofs.js index 0fe24ab..a966b8c 100644 --- a/src/subproofs.js +++ b/src/subproofs.js @@ -1,9 +1,15 @@ const Definitions = require("./definitions.js"); module.exports = class Subproofs extends Definitions { - - constructor (Fr, context) { - super(Fr) - this.context = context; + constructor () { + super(); + } + getEmptyValue(id, options) { + const subproofId = options.subproofId; + const relativeId = this.values.reduce((res, spv) => spv.subproofId === subproofId ? res + 1 : res, 0); + console.log(relativeId); + EXIT_HERE; + let definition = super.getEmptyValue(id, {relativeId, ...options}); + return definition; } } diff --git a/src/transpiler.js b/src/transpiler.js new file mode 100644 index 0000000..f0b5120 --- /dev/null +++ b/src/transpiler.js @@ -0,0 +1,207 @@ +module.exports = class Transpiler { + constructor(config = {}) { + this.processor = config.processor; + this.config = config; + } + transpile(st) { + console.log(st); + this.declared = {}; + const code = this.#transpile(st); + console.log(code); + EXIT_HERE; + return code; + } + #transpile(st) { + console.log(st); + switch(st.type) { + case 'for': return this.#transpileFor(st); + case 'code': return this.#transpile(st.statements); + case 'variable_declaration': return this.#transpileVariableDeclaration(st); + case 'variable_increment': return this.#transpileVariableIncrement(st); + case 'scope_definition': return this.#transpileScopeDefinition(st); + case 'expr': return this.#transpileExpr(st); + case 'switch': return this.#transpileSwitchCase(st); + case 'assign': return this.#transpileAssign(st); + case 'if': return this.#transpileIf(st); + } + throw new Error(`not known how transpile ${st.type}`); + } + #transpileIf(st) { + let code = ''; + let first = true; + for (const cond of st.conditions) { + if (cond.type === 'if') { + if (first) code += 'if ('; + else code += 'else if ('; + code += cond.expression.toString() + ')'; + } else if (cond.type === 'else') { + code += ' else '; + } else { + EXIT_HERE; + } + code += this.#transpile(cond.statements); + first = false; + } + return code; + } + #transpileSwitchCase(st) { + let code = 'switch ('+st.value.toString()+') {\n'; + let ccases = []; + console.log(st); + for (const _case of st.cases) { + if (_case.condition.values) { + let cvalues = []; + for (const cvalue of _case.condition.values) { + cvalues.push(cvalue.toString()); + } + code += '\n\tcase '+cvalues.join()+':\n'; + } else if (_case.default) { + code += '\n\tdefault:\n'; + } else { + console.log(_case); + EXIT_HERE; + } + code += this.#transpile(_case.statements)+';\nbreak;\n'; + } + code += '}\n'; + return code; + } + #transpileExpr(st) { + return st.expr.toString(); + } + #transpileFor(st) { + let code = '{'; + const inits = Array.isArray(st.init) ? st.init : [st.init]; + const cinits = []; + for (const init of inits) { + cinits.push(this.#transpile(init)); + } + const cincrements = []; + for (const increment of st.increment) { + cincrements.push(this.#transpile(increment)); + } + code += 'for ('+cinits.join()+';'+st.condition.toString()+';'+cincrements.join()+') {\n'; + code += this.#transpile(st.statements) + '\n}'; + return code; + } + #transpileVariableDeclaration(st) { + let code = ''; + if (st.vtype !== 'string' && st.vtype !== 'int') { + throw new Error(`declaration type ${st.vtype} not supported on transpilation`); + } + console.log(st.items); + console.log(st.init); + code += st.const ? 'const ':'let '; + if (st.init) { + const initlen = st.init.type === 'expression_list' ? st.init.values.length : st.init.length; + if (st.items.length !== initlen) { + throw new Error(`mistmatch lengths ${st.items.length} vs ${initlen}`); + } + } + if (st.items.length === 1) { + code += st.items[0].name; + } else { + code += '[' + st.items.map(x => x.name).join() + ']'; + } + if (st.init) { + if (st.init.length === 1) { + code += `=${st.init[0].toString()}`; + } else if (st.init.type === 'expression_list') { + const inits = []; + for (const init of st.init.values) { + inits.push(init.toString()); + } + code += '=['+inits.join()+']'; + } else { + EXIT_HERE; + } + } + return code; + } + f() + {for (let i=0;i < N;++i) { + {let [a,b,cin,plast,c,cout,op]=[A*[i],B*[i],CIN*[i],LAST*[i],0,0,OP*[i]]; + println(i); + switch (op) { + + case 0: + {c=(cin + a + b) & 255; + cout=(cin + a + b) >> 8}; + break; + + case 1: + {cout=((a - cin) >= b)?(0):(1); + c=((256 * cout + a) - cin) - b}; + break; + + case 2,3:{ + if (a < b){ + cout=1; + c=plast + } else if (a == b) { + cout=cin; + c=plast * cin + }; + if (op == 3 && plast && (a & 128) != (b & 128)){ + c=a & 128; + cout=c + } + }; + break; + + case 4: { + if (a == b && !cin) c=plast; else cout=1; + cout=(plast)?(!cout):(cout)}; + break; + + case 5: + {c=a & b; + cout=cin || c}; + break; + + case 6: + {c=a | b}; + break; + + case 7: + {c=a ^ b}; + break; + } + ; + C[i]=c; + COUT[i]=c} + } + } + #transpileReference(ref) { + let code = ref.name; + if (!ref.dim) { + return code; + } + const cindexes = []; + for (const index of ref.indexes) { + cindexes.push(index.toString()); + } + return code + '['+ cindexes.join('][')+']'; + } + #transpileAssign(st) { + return this.#transpileReference(st.name) + '=' + st.value.toString(); + } + #transpileVariableIncrement(st) { + if (!st.dim) { + if (st.pre === 1n) { + return '++'+st.name; + } + if (st.post === 1n) { + return st.name+'++'; + } + } + throw new Error(`Traspilation not supported by pre:${st.pre}, post:${st.post}, dim:${dim}`); + } + #transpileScopeDefinition(st) { + let codes = []; + for (const statement of st.statements) { + codes.push(this.#transpile(statement)); + } + return '{'+codes.join(';\n')+'}'; + } +} \ No newline at end of file diff --git a/src/types.js b/src/types.js new file mode 100644 index 0000000..1b1973f --- /dev/null +++ b/src/types.js @@ -0,0 +1,24 @@ +// class to register differents types + +module.exports = class Types { + static types = {}; + + static register(type, cls) { + if (typeof this.types[type] !== 'undefined') { + throw new Error(`Type ${type} already defined with class ${this.types[type]}`); + } + this.types[type] = cls; + } + static get(type) { + if (typeof this.types[type] === 'undefined') { + throw new Error(`Type ${type} not defined`); + } + return this.types[type]; + } + static getTypeFromClass(cls) { + for (const type in this.types) { + if (this.types[type] === cls) return type; + } + return false; + } +} diff --git a/src/values.js b/src/values.js new file mode 100644 index 0000000..c59386b --- /dev/null +++ b/src/values.js @@ -0,0 +1,59 @@ +const {assert, assertLog} = require("./assert.js"); + +module.exports = class Values { + #values; + #mutable; + constructor () { + this.#values = []; + this.#mutable = true; + } + get mutable() { + return this.#mutable; + } + set mutable(value) { + let _value = Boolean(value); + if (_value === this.#mutable) { + return; + } + if (value) { + this.cloneValues(); + } + this.#mutable = value; + } + clone(cloneValues = false, cloneEachValue = true) { + let cloned = new Values(); + cloned.#values = this.#values; + if (this.#mutable || cloneValues) { + cloned.cloneValues(cloneEachValue); + } else { + cloned.#mutable = false; + } + return cloned; + } + cloneValues(cloneEachValue = true) { + console.log('\x1B[1;33m************** CLONEVALUES *****************\x1B[0m'); + let _values = this.#values; + this.#values = []; + for(const _value of _values) { + this.#values.push((cloneEachValue && _value && typeof _value.clone === 'function') ?_value.clone() : _value); + } + } + setValue(irow, value) { + if (!this.#mutable) { + throw new Error(`modifying an inmutable values irow = ${row} and value = ${value}`); + } + this.#values[irow] = value; + } + __setValue(irow, value) { + this.#values[irow] = value; + } + getValue(irow) { + return this.#values[irow]; + } + toString() { + return this.#values.join(); + } + __setValues(values) { + this.#values = values; + } +} diff --git a/src/variable.js b/src/variable.js index dda1fe9..8d38b0c 100644 --- a/src/variable.js +++ b/src/variable.js @@ -1,10 +1,10 @@ module.exports = class Variable { - constructor (Fr, value, vtype, lengths, debug) { + constructor (Fr, value, vtype, lengths, options) { super(Fr); this.values = []; this.type = vtype; this.lengths = lengths; - this.debug = debug; + this.options = options; this.calculateOffsets(this.lengths); } getValue(indexes) { diff --git a/src/variables.js b/src/variables.js index 3cd379f..d74af30 100644 --- a/src/variables.js +++ b/src/variables.js @@ -1,12 +1,9 @@ +const {assert, assertLog} = require('./assert.js'); const Indexable = require("./indexable.js"); module.exports = class Variables extends Indexable { - constructor (Fr, type) { - super(Fr, type); - this.undefined = 0n; - } - getEmptyValue(id) { - return 0; + constructor (type, definitionClass, expressionItemClass, options) { + super(type, definitionClass, expressionItemClass, options); } } diff --git a/src/witness_cols.js b/src/witness_cols.js index 8ddaa21..f91ca2c 100644 --- a/src/witness_cols.js +++ b/src/witness_cols.js @@ -1,19 +1,14 @@ -const LabelRanges = require("./label_ranges.js"); const Indexable = require("./indexable.js"); -const WitnessCol = require("./pil_items/witness_col.js"); +const WitnessColItem = require("./expression_items/witness_col.js"); +const WitnessCol = require("./definition_items/witness_col.js"); module.exports = class WitnessCols extends Indexable { - constructor (Fr) { - super(Fr, 'witness'); + constructor () { + super('witness', WitnessCol, WitnessColItem); } - - getEmptyValue(id, data = {}) { - const col = new WitnessCol(id, data.stage ?? 1); - return col; + getEmptyValue(id, options) { + let _options = options ?? {}; + return new WitnessCol(id, _options.stage ?? 1); } -/* - set(id, offset, value) { - console.log([`SET@${this.type}[${id}]`, value]); - this.values[id] = value; - }*/ + } diff --git a/test/pil2/collection/expressions.pil b/test/pil2/collection/expressions.pil new file mode 100644 index 0000000..1354ff2 --- /dev/null +++ b/test/pil2/collection/expressions.pil @@ -0,0 +1,42 @@ +subproof ExpressionTest(2**16) { + + col witness x[4],z; + col fixed Y[4]; + Y[0] = [1..5]...; + col fixed _Y = [1..5]...; + const int k; + const expr isZero = (1 - Y[0]); + k = 10; + const expr b = 13 + 6 * Y[1]; + expr a; + a = 10 + 5 * Y[2]; + a = a + 100; + a = a + 2 * isZero; + a = a - isZero; + a === 0; + 5 * Y[3]' + x[1] + 2 * x[0] + 3 * x[2] + 18 * z === x[1]; + /* + expr ex = x[0] + 2 * x[1] + 4 * x[2] + 2 ** 3 * x[3]; + + ex === 0; + + int k = 10; + expr a = 1; + string s = "1"; + + + ex === 0; + assert(k == 10); + assert(a == 1); + assert(string(1) == "1"); + assert(string(a) == "1"); + assert(string(a) == s); + + a = a + 1; + dump(a); + a = a * 10; + dump(a); + s = s + "hello"; + s = s + k; + s = s + a;*/ +} \ No newline at end of file diff --git a/test/pil2/components/expression.test.js b/test/pil2/components/expression.test.js index 01de6e6..ac5fdd1 100644 --- a/test/pil2/components/expression.test.js +++ b/test/pil2/components/expression.test.js @@ -1,251 +1,141 @@ -const chai = require("chai"); +const { F1Field } = require("ffjavascript"); +const fs = require("fs"); +const path = require("path"); +const util = require('util'); +var tmp = require('tmp-promise'); +const Expression = require('../../../src/expression.js'); +const ExpressionItems = require('../../../src/expression_items.js'); + +const deepEqualInAnyOrder = require('deep-equal-in-any-order'); +const chai = require('chai'); const assert = chai.assert; -const src = __dirname + "/../../../src/"; -const Expression = require(src + 'expression.js'); +const expect = chai.expect; +chai.use(deepEqualInAnyOrder); +const debugConsole = require('../../../src/debug_console.js').init(); - -const toJSON = function (obj) { - return JSON.stringify(obj, (_, v) => typeof v === 'bigint' ? v.toString() : v); -} - -describe("Expression", async function () { +describe("Expressions", async function () { this.timeout(10000000); - - it("Basic test", async () => { - let e = new Expression(); - assert.equal(e.isAlone(), false); - - e.setValue(0); - assert.equal(e.isAlone(), true); - - assert.throws(() => {e.setValue(0)}, Error, 'Set only could be used with empty stack'); - assert.throws(() => {e.setRuntime({name: 'mary', indexes: [1], next: 2})}, Error, 'Set only could be used with empty stack'); - assert.throws(() => {e.setIdReference(10, 'imC', 0, 2)}, Error, 'Set only could be used with empty stack'); - - let expected = [{op: false, operands: [{type: 0, value: 0}]}]; - assert.equal(toJSON(e.stack), toJSON(expected)); - - e = new Expression(); - - assert.equal(e.isAlone(), false); - - e.setRuntime({name: 'joe', indexes: [5], next: 7}); - assert.equal(e.isAlone(), true); - - assert.throws(() => {e.setValue(0)}, Error, 'Set only could be used with empty stack'); - assert.throws(() => {e.setRuntime({name: 'mary', indexes: [1], next: 2})}, Error, 'Set only could be used with empty stack'); - assert.throws(() => {e.setIdReference(10, 'imC', 0, 2)}, Error, 'Set only could be used with empty stack'); - - expected = [{op: false, operands: [{type: 3, name: 'joe', indexes: [5], next: 7}]}]; - assert.equal(toJSON(e.stack), toJSON(expected)); - - e = new Expression(); - - assert.equal(e.isAlone(), false); - - e.setIdReference(12, 'witness', 1, -1); - assert.equal(e.isAlone(), true); - - assert.throws(() => {e.setValue(0)}, Error, 'Set only could be used with empty stack'); - assert.throws(() => {e.setRuntime({name: 'mary', indexes: [1], next: 2})}, Error, 'Set only could be used with empty stack'); - assert.throws(() => {e.setIdReference(10, 'imC', 0, 2)}, Error, 'Set only could be used with empty stack'); - - expected = [{op: false, operands: [{type:1, id: 12, refType: 'witness', offset: 1, next: -1}]}]; - assert.equal(toJSON(e.stack), toJSON(expected)); - }); - - it("Insert test", async () => { - let a = new Expression(); - assert.equal(a.isAlone(), false); - - a.setValue(10); - assert.equal(a.isAlone(), true); - - let b = new Expression(); - b.setValue(20); - - a.insert('+', b); - let expected = [{op:'+',operands:[{type:0, value: 10},{type:0, value: 20}]}]; - assert.equal(toJSON(a.stack), toJSON(expected)); - - b.stack[0].operands[0].value = 30; - assert.equal(toJSON(a.stack), toJSON(expected)); - - a.insert('*', b); - expected = [...expected, {op:'*',operands:[{type:2, offset:1},{type:0, value: 30}]}]; - assert.equal(toJSON(a.stack), toJSON(expected)); - - a.insert('-', a); - let count = expected.length; - expected = [...expected, ...expected, {op:'-',operands:[{type:2, offset:count+1},{type:2, offset: 1}]}]; - assert.equal(toJSON(a.stack), toJSON(expected)); - }); - it("Direct insert test", async () => { - let a = new Expression(); - a.setValue(10); - - let b = new Expression(); - b.setValue(20); - - let c = new Expression(); - c.insert('+', a, b); - let expected = [{op:'+',operands:[{type:0, value:10},{type:0, value: 20}]}]; - assert.equal(toJSON(c.stack), toJSON(expected)); - - b.stack[0].operands[0].value = 30; - assert.equal(toJSON(c.stack), toJSON(expected)); - - c.insert('*', b); - expected = [...expected, {op:'*',operands:[{type:2, offset:1},{type:0, value: 30}]}]; - assert.equal(toJSON(c.stack), toJSON(expected)); - - c.insert('-', c); - let count = expected.length; - expected = [...expected, ...expected, {op:'-',operands:[{type:2, offset:count+1},{type:2, offset: 1}]}]; - assert.equal(toJSON(c.stack), toJSON(expected)); - - d = new Expression(); - d.insert('neg', a); - expected = [{op:'neg',operands:[{type:0, value:10}]}]; - assert.equal(toJSON(d.stack), toJSON(expected)); + const F = new F1Field(0xffffffff00000001n); + + function checkScopeDefine(scope, name, value) { + scope.define(name, value); + assert.equal(value, scope.get(name)); + assert.equal(true, scope.isDefined(name)); + } + function checkScopeSet(scope, name, value) { + scope.set(name, value); + assert.equal(value, scope.get(name)); + assert.equal(true, scope.isDefined(name)); + } + it("Empty expressions", async () => { + const e1 = new Expression(); + expect(e1.asIntItem()).to.deep.equalInAnyOrder(new ExpressionItems.IntValue(0n)); + // expect(e1.asFeItem()).to.deep.equalInAnyOrder(new ExpressionItems.FeValue(0n)); + expect(e1.asStringItem()).to.deep.equalInAnyOrder(new ExpressionItems.StringValue('')); + assert.equal(0n, e1.asInt()); + // assert.equal(0n, e1.asFe()); + assert.equal('', e1.asString()); + assert.equal(false, e1.asBool()); + expect(e1).to.deep.equalInAnyOrder(new Expression()); }) - - it("Multiple insert test", async () => { - let a = new Expression(); - a.setValue(10); - - let b = new Expression(); - b.setValue(20); - - let c = new Expression(); - c.insert('+', a, b); - let expected = [{op:'+',operands:[{type:0, value:10},{type:0, value: 20}]}]; - assert.equal(toJSON(c.stack), toJSON(expected)); - - b.stack[0].operands[0].value = 30; - assert.equal(toJSON(c.stack), toJSON(expected)); - - c.insert('*', b); - expected = [...expected, {op:'*',operands:[{type:2, offset:1},{type:0, value: 30}]}]; - assert.equal(toJSON(c.stack), toJSON(expected)); - - c.insert('-', c); - let count = expected.length; - expected = [...expected, ...expected, {op:'-',operands:[{type:2, offset:count+1},{type:2, offset: 1}]}]; - assert.equal(toJSON(c.stack), toJSON(expected)); - - - let d1 = new Expression(); - d1.setRuntime({name: 'JohnSmith', indexes: [2,5,7], next: 10}); - - let d2 = new Expression(); - d2.setIdReference(103, 'fe', -18746, 0); - - - - let d = new Expression(); - d.insert('+', d1, d2); - let expectedD = [{op:'+',operands:[{type:3, name: 'JohnSmith', indexes: [2, 5, 7], next: 10}, - {type:1, id: 103, refType: 'fe', offset: -18746, next: 0}]}]; - expected = expectedD; - assert.equal(toJSON(d.stack), toJSON(expected)); - - a.insert('*', d); - expected = [{op:false,operands:[{type:0, value: 10}]},...expected, {op:'*',operands:[{type:2, offset: 2},{type:2, offset: 1}]}]; - assert.equal(toJSON(a.stack), toJSON(expected)); - - a = new Expression(); - a.insert('fx', d); - expected = [...expectedD, {op:'fx',operands:[{type:2, offset: 1}]}]; - assert.equal(toJSON(a.stack), toJSON(expected)); + it("Setting as int", async () => { + { + const e1 = new Expression(); + e1._set(new ExpressionItems.IntValue(10n)); + expect(e1.asIntItem()).to.deep.equalInAnyOrder(new ExpressionItems.IntValue(10n)); + assert.equal(10n, e1.asInt()); + assert.equal(true, e1.asBool()); + } + { + const e2 = new Expression(); + e2._set(new ExpressionItems.IntValue(0n)); + expect(e2.asIntItem()).to.deep.equalInAnyOrder(new ExpressionItems.IntValue(0n)); + assert.equal(0n, e2.asInt()); + assert.equal(false, e2.asBool()); + } }) - - it("Clone test", async () => { - let a = new Expression(); - a.setValue(10); - - let b = new Expression(); - b.setRuntime({name: 'Joe', indexes: [2, 10, 13], next: -10}); - - let c = new Expression(); - c.insert('+', a, b); - let expected = [{op:'+',operands:[{type:0, value: 10},{type:3, name: "Joe", indexes: [2, 10, 13], next: -10}]}]; - assert.equal(toJSON(c.stack), toJSON(expected)); - - b.stack[0].operands[0].indexes[2] = 30; - assert.equal(toJSON(c.stack), toJSON(expected)); - - b = new Expression(); - b.setIdReference(100, 'int', 180, -13); - - c.insert('*', b); - expected = [...expected, {op:'*',operands:[{type:2, offset:1},{type:1, id: 100, refType: 'int', offset:180, next: -13}]}]; - assert.equal(toJSON(c.stack), toJSON(expected)); - - d = c.clone(); - assert.equal(toJSON(d.stack), toJSON(expected)); - c.stack[0].operands[0].type = 29; - c.stack[0].operands[1].type = 18; - c.stack[0].op = 'xx'; - c.stack[1].operands[0].type = 56; - c.stack[1].operands[1].type = 57; - c.stack[1].op = 'yy'; - assert.equal(toJSON(d.stack), toJSON(expected)); - - // clone himself - d = d.clone(); - assert.equal(toJSON(d.stack), toJSON(expected)); + it("Setting as string", async () => { + { + const e1 = new Expression(); + const stringExample = "Hello, world !!"; + e1._set(new ExpressionItems.StringValue(stringExample)); + expect(e1.asStringItem()).to.deep.equalInAnyOrder(new ExpressionItems.StringValue(stringExample)); + assert.equal(stringExample, e1.asString()); + assert.equal(true, e1.asBool()); + } + { + const e2 = new Expression(); + const emptyString = ""; + e2._set(new ExpressionItems.StringValue(emptyString)); + expect(e2.asStringItem()).to.deep.equalInAnyOrder(new ExpressionItems.StringValue(emptyString)); + assert.equal(emptyString, e2.asString()); + assert.equal(false, e2.asBool()); + } }) - - it("Insert himself", async () => { - let a = new Expression(); - a.setValue(10); - - a.insert('+', a, a); - let expectedA = {op:'+',operands:[{type:0, value: 10},{type:0, value: 10},{type:0, value: 10}]}; - let expected = [expectedA]; - assert.equal(toJSON(a.stack), toJSON(expected)); - - let b = new Expression(); - b.setValue(38); - b.insert('*', a, a); - expected = [{op:false, operands:[{type:0, value:38}]},...expected, ...expected, {op:'*',operands:[{type:2, offset: 3},{type:2, offset:2},{type:2, offset:1}]}]; - assert.equal(toJSON(b.stack), toJSON(expected)); - - b.insert('**', a, a); - expected = [...expected, expectedA, expectedA, {op:'**',operands:[{type:2, offset:3},{type:2, offset:2},{type:2, offset:1}]}]; - assert.equal(toJSON(b.stack), toJSON(expected)); + // TODO: settinga as template + it("Adding", async () => { + const e1 = new Expression(); + e1._set(new ExpressionItems.IntValue(10n)); + expect(e1.asIntItem()).to.deep.equalInAnyOrder(new ExpressionItems.IntValue(10n)); + assert.equal(10n, e1.asInt()); + assert.equal(true, e1.asBool()); }) - - it("Exceptions test", async () => { - let a = new Expression(); - a.setValue(10); - assert.throws(() => {a.pushStack(0)}, Error, 'pushStack parameter must be an Expression'); - assert.throws(() => {a.pushStack(this)}, Error, 'pushStack parameter must be an Expression'); - assert.throws(() => {a.pushStack()}, Error, 'pushStack parameter must be an Expression'); - - let b = new Expression(); - assert.throws(() => {a.insert('+', b)}, Error, 'insert without operands'); - - let b2 = new Expression(); - assert.throws(() => {a.insert('+', b, b2)}, Error, 'insert without operands'); - assert.throws(() => {b2.setValue(b)}, Error, 'object(Expression) as value not allowed'); +/* + it("Basic test", async () => { + const F = new F1Field(0xffffffff00000001n); + let scope = new Scope(F); + + assert.equal(false, scope.isDefined('myFirstVar')); + scope.define('myFirstVar', 13); + assert.equal(13, scope.get('myFirstVar')); + assert.equal(true, scope.isDefined('myFirstVar')); + scope.set('myFirstVar', 14); + assert.equal(14, scope.get('myFirstVar')); }); - - it("Unary insert", async () => { - let a = new Expression(); - a.setValue(10); - let expected = [{op:false, operands:[{type:0, value: 10}]}]; - assert.equal(toJSON(a.stack), toJSON(expected)); - - a.insert('not'); - expected = [{op:'not', operands:[{type:0, value: 10}]}]; - assert.equal(toJSON(a.stack), toJSON(expected)); - - a.insert('not'); - expected = [...expected, {op:'not', operands:[{type:2, offset: 1}]}]; - assert.equal(toJSON(a.stack), toJSON(expected)); - }) - - + it("Scope Test", async () => { + const F = new F1Field(0xffffffff00000001n); + let scope = new Scope(F); + + assert.equal(false, scope.isDefined('myFirstVar')); + scope.define('myFirstVar', 13); + assert.equal(13, scope.get('myFirstVar')); + assert.equal(true, scope.isDefined('myFirstVar')); + scope.push(); + assert.equal(13, scope.get('myFirstVar')); + assert.equal(true, scope.isDefined('myFirstVar')); + scope.set('myFirstVar', 14); + assert.equal(14, scope.get('myFirstVar')); + scope.define('myFirstVar', 20); + assert.equal(20, scope.get('myFirstVar')); + assert.equal(true, scope.isDefined('myFirstVar')); + scope.define('mySecondVar', 25); + assert.equal(25, scope.get('mySecondVar')); + assert.equal(true, scope.isDefined('mySecondVar')); + scope.set('mySecondVar', 27); + assert.equal(27, scope.get('mySecondVar')); + assert.throws( + () => scope.define('myFirstVar', 50), + 'myFirstVar already defined on this scope ....' + ); + assert.equal(20, scope.get('myFirstVar')); + assert.equal(true, scope.isDefined('myFirstVar')); + scope.pop(); + assert.equal(14, scope.get('myFirstVar')); + assert.equal(true, scope.isDefined('myFirstVar')); + }); + it("Scope Pop destroy variables", async () => { + const F = new F1Field(0xffffffff00000001n); + let scope = new Scope(F); + + scope.push(); + checkScopeDefine(scope, 'mySecondVar', 25); + checkScopeSet(scope, 'mySecondVar', 27); + scope.pop(); + assert.equal(false, scope.isDefined('mySecondVar')); + assert.equal(null, scope.get('mySecondVar')); + assert.throws( + () => scope.set('mySecondVar', 29), + 'mySecondVar not defined on this scope ....' + ); + });*/ }); \ No newline at end of file diff --git a/test/pil2/components/expression_build.test.js b/test/pil2/components/expression_build.test.js new file mode 100644 index 0000000..01de6e6 --- /dev/null +++ b/test/pil2/components/expression_build.test.js @@ -0,0 +1,251 @@ +const chai = require("chai"); +const assert = chai.assert; +const src = __dirname + "/../../../src/"; +const Expression = require(src + 'expression.js'); + + +const toJSON = function (obj) { + return JSON.stringify(obj, (_, v) => typeof v === 'bigint' ? v.toString() : v); +} + +describe("Expression", async function () { + this.timeout(10000000); + + it("Basic test", async () => { + let e = new Expression(); + assert.equal(e.isAlone(), false); + + e.setValue(0); + assert.equal(e.isAlone(), true); + + assert.throws(() => {e.setValue(0)}, Error, 'Set only could be used with empty stack'); + assert.throws(() => {e.setRuntime({name: 'mary', indexes: [1], next: 2})}, Error, 'Set only could be used with empty stack'); + assert.throws(() => {e.setIdReference(10, 'imC', 0, 2)}, Error, 'Set only could be used with empty stack'); + + let expected = [{op: false, operands: [{type: 0, value: 0}]}]; + assert.equal(toJSON(e.stack), toJSON(expected)); + + e = new Expression(); + + assert.equal(e.isAlone(), false); + + e.setRuntime({name: 'joe', indexes: [5], next: 7}); + assert.equal(e.isAlone(), true); + + assert.throws(() => {e.setValue(0)}, Error, 'Set only could be used with empty stack'); + assert.throws(() => {e.setRuntime({name: 'mary', indexes: [1], next: 2})}, Error, 'Set only could be used with empty stack'); + assert.throws(() => {e.setIdReference(10, 'imC', 0, 2)}, Error, 'Set only could be used with empty stack'); + + expected = [{op: false, operands: [{type: 3, name: 'joe', indexes: [5], next: 7}]}]; + assert.equal(toJSON(e.stack), toJSON(expected)); + + e = new Expression(); + + assert.equal(e.isAlone(), false); + + e.setIdReference(12, 'witness', 1, -1); + assert.equal(e.isAlone(), true); + + assert.throws(() => {e.setValue(0)}, Error, 'Set only could be used with empty stack'); + assert.throws(() => {e.setRuntime({name: 'mary', indexes: [1], next: 2})}, Error, 'Set only could be used with empty stack'); + assert.throws(() => {e.setIdReference(10, 'imC', 0, 2)}, Error, 'Set only could be used with empty stack'); + + expected = [{op: false, operands: [{type:1, id: 12, refType: 'witness', offset: 1, next: -1}]}]; + assert.equal(toJSON(e.stack), toJSON(expected)); + }); + + it("Insert test", async () => { + let a = new Expression(); + assert.equal(a.isAlone(), false); + + a.setValue(10); + assert.equal(a.isAlone(), true); + + let b = new Expression(); + b.setValue(20); + + a.insert('+', b); + let expected = [{op:'+',operands:[{type:0, value: 10},{type:0, value: 20}]}]; + assert.equal(toJSON(a.stack), toJSON(expected)); + + b.stack[0].operands[0].value = 30; + assert.equal(toJSON(a.stack), toJSON(expected)); + + a.insert('*', b); + expected = [...expected, {op:'*',operands:[{type:2, offset:1},{type:0, value: 30}]}]; + assert.equal(toJSON(a.stack), toJSON(expected)); + + a.insert('-', a); + let count = expected.length; + expected = [...expected, ...expected, {op:'-',operands:[{type:2, offset:count+1},{type:2, offset: 1}]}]; + assert.equal(toJSON(a.stack), toJSON(expected)); + }); + it("Direct insert test", async () => { + let a = new Expression(); + a.setValue(10); + + let b = new Expression(); + b.setValue(20); + + let c = new Expression(); + c.insert('+', a, b); + let expected = [{op:'+',operands:[{type:0, value:10},{type:0, value: 20}]}]; + assert.equal(toJSON(c.stack), toJSON(expected)); + + b.stack[0].operands[0].value = 30; + assert.equal(toJSON(c.stack), toJSON(expected)); + + c.insert('*', b); + expected = [...expected, {op:'*',operands:[{type:2, offset:1},{type:0, value: 30}]}]; + assert.equal(toJSON(c.stack), toJSON(expected)); + + c.insert('-', c); + let count = expected.length; + expected = [...expected, ...expected, {op:'-',operands:[{type:2, offset:count+1},{type:2, offset: 1}]}]; + assert.equal(toJSON(c.stack), toJSON(expected)); + + d = new Expression(); + d.insert('neg', a); + expected = [{op:'neg',operands:[{type:0, value:10}]}]; + assert.equal(toJSON(d.stack), toJSON(expected)); + }) + + it("Multiple insert test", async () => { + let a = new Expression(); + a.setValue(10); + + let b = new Expression(); + b.setValue(20); + + let c = new Expression(); + c.insert('+', a, b); + let expected = [{op:'+',operands:[{type:0, value:10},{type:0, value: 20}]}]; + assert.equal(toJSON(c.stack), toJSON(expected)); + + b.stack[0].operands[0].value = 30; + assert.equal(toJSON(c.stack), toJSON(expected)); + + c.insert('*', b); + expected = [...expected, {op:'*',operands:[{type:2, offset:1},{type:0, value: 30}]}]; + assert.equal(toJSON(c.stack), toJSON(expected)); + + c.insert('-', c); + let count = expected.length; + expected = [...expected, ...expected, {op:'-',operands:[{type:2, offset:count+1},{type:2, offset: 1}]}]; + assert.equal(toJSON(c.stack), toJSON(expected)); + + + let d1 = new Expression(); + d1.setRuntime({name: 'JohnSmith', indexes: [2,5,7], next: 10}); + + let d2 = new Expression(); + d2.setIdReference(103, 'fe', -18746, 0); + + + + let d = new Expression(); + d.insert('+', d1, d2); + let expectedD = [{op:'+',operands:[{type:3, name: 'JohnSmith', indexes: [2, 5, 7], next: 10}, + {type:1, id: 103, refType: 'fe', offset: -18746, next: 0}]}]; + expected = expectedD; + assert.equal(toJSON(d.stack), toJSON(expected)); + + a.insert('*', d); + expected = [{op:false,operands:[{type:0, value: 10}]},...expected, {op:'*',operands:[{type:2, offset: 2},{type:2, offset: 1}]}]; + assert.equal(toJSON(a.stack), toJSON(expected)); + + a = new Expression(); + a.insert('fx', d); + expected = [...expectedD, {op:'fx',operands:[{type:2, offset: 1}]}]; + assert.equal(toJSON(a.stack), toJSON(expected)); + }) + + it("Clone test", async () => { + let a = new Expression(); + a.setValue(10); + + let b = new Expression(); + b.setRuntime({name: 'Joe', indexes: [2, 10, 13], next: -10}); + + let c = new Expression(); + c.insert('+', a, b); + let expected = [{op:'+',operands:[{type:0, value: 10},{type:3, name: "Joe", indexes: [2, 10, 13], next: -10}]}]; + assert.equal(toJSON(c.stack), toJSON(expected)); + + b.stack[0].operands[0].indexes[2] = 30; + assert.equal(toJSON(c.stack), toJSON(expected)); + + b = new Expression(); + b.setIdReference(100, 'int', 180, -13); + + c.insert('*', b); + expected = [...expected, {op:'*',operands:[{type:2, offset:1},{type:1, id: 100, refType: 'int', offset:180, next: -13}]}]; + assert.equal(toJSON(c.stack), toJSON(expected)); + + d = c.clone(); + assert.equal(toJSON(d.stack), toJSON(expected)); + c.stack[0].operands[0].type = 29; + c.stack[0].operands[1].type = 18; + c.stack[0].op = 'xx'; + c.stack[1].operands[0].type = 56; + c.stack[1].operands[1].type = 57; + c.stack[1].op = 'yy'; + assert.equal(toJSON(d.stack), toJSON(expected)); + + // clone himself + d = d.clone(); + assert.equal(toJSON(d.stack), toJSON(expected)); + }) + + it("Insert himself", async () => { + let a = new Expression(); + a.setValue(10); + + a.insert('+', a, a); + let expectedA = {op:'+',operands:[{type:0, value: 10},{type:0, value: 10},{type:0, value: 10}]}; + let expected = [expectedA]; + assert.equal(toJSON(a.stack), toJSON(expected)); + + let b = new Expression(); + b.setValue(38); + b.insert('*', a, a); + expected = [{op:false, operands:[{type:0, value:38}]},...expected, ...expected, {op:'*',operands:[{type:2, offset: 3},{type:2, offset:2},{type:2, offset:1}]}]; + assert.equal(toJSON(b.stack), toJSON(expected)); + + b.insert('**', a, a); + expected = [...expected, expectedA, expectedA, {op:'**',operands:[{type:2, offset:3},{type:2, offset:2},{type:2, offset:1}]}]; + assert.equal(toJSON(b.stack), toJSON(expected)); + }) + + it("Exceptions test", async () => { + let a = new Expression(); + a.setValue(10); + assert.throws(() => {a.pushStack(0)}, Error, 'pushStack parameter must be an Expression'); + assert.throws(() => {a.pushStack(this)}, Error, 'pushStack parameter must be an Expression'); + assert.throws(() => {a.pushStack()}, Error, 'pushStack parameter must be an Expression'); + + let b = new Expression(); + assert.throws(() => {a.insert('+', b)}, Error, 'insert without operands'); + + let b2 = new Expression(); + assert.throws(() => {a.insert('+', b, b2)}, Error, 'insert without operands'); + assert.throws(() => {b2.setValue(b)}, Error, 'object(Expression) as value not allowed'); + }); + + it("Unary insert", async () => { + let a = new Expression(); + a.setValue(10); + let expected = [{op:false, operands:[{type:0, value: 10}]}]; + assert.equal(toJSON(a.stack), toJSON(expected)); + + a.insert('not'); + expected = [{op:'not', operands:[{type:0, value: 10}]}]; + assert.equal(toJSON(a.stack), toJSON(expected)); + + a.insert('not'); + expected = [...expected, {op:'not', operands:[{type:2, offset: 1}]}]; + assert.equal(toJSON(a.stack), toJSON(expected)); + }) + + +}); \ No newline at end of file diff --git a/test/components/scope.test.js b/test/pil2/components/scope.test.js similarity index 98% rename from test/components/scope.test.js rename to test/pil2/components/scope.test.js index 4017e93..bcf7f68 100644 --- a/test/components/scope.test.js +++ b/test/pil2/components/scope.test.js @@ -4,7 +4,7 @@ const fs = require("fs"); const path = require("path"); const assert = chai.assert; var tmp = require('tmp-promise'); -const Scope = require('../../src/scope.js'); +const Scope = require('../../../src/scope.js'); describe("Scope", async function () { this.timeout(10000000); diff --git a/test/pil2/features/basic_functions.pil b/test/pil2/features/basic_functions.pil new file mode 100644 index 0000000..a7cfa61 --- /dev/null +++ b/test/pil2/features/basic_functions.pil @@ -0,0 +1,76 @@ +subproof Functions(2**23) { + col witness w; + int values[12][20]; + + function defer_definition_2(int b, int a) { + // b = vb, a = va + // a <= vb | b <= vb (now a value is vb, definition at same time) + // [a,b] <= [vb,va] + return sum1(a, b); + } + + function defer_definition(int a, int b) { + return sum1(a, b); + } + + function stotal_ (int a[]): int { + return sum(0, a); + } + function stotal (int a[]): int { + return stotal_(a); + } + function sum1(int a, int b) : int { + return a + b; + } + + function sum(int a, int bs[]) : int { + int total = a; + int count_ = a; + int count = length(bs); + for (int index = 0; index < count; index = index + 1) { + int count__ = index; + // total = sum1(total, bs[index]); + total = total + bs[index]; + } + int count___ = 34; + return total; + } + + function fact(int k): int { + if (k < 2) { + return 1; + } + return k * fact(k - 1); + } + + function procedure(int value) { + col witness p1; + + p1 === value; + } + int k[10]; + k[0] = 109; + expr e1 = 12; + int res = sum1(18, e1); + assert_eq(res, 30); + int res2 = sum(20, values[7]); + assert_eq(res2, 20); + + int res3 = sum(25, k); + assert_eq(res3, 109 + 25); + + int k2[4]; + k2[0] = 110; + k2[1] = 220; + k2[2] = 330; + k2[3] = 440; + + int res4 = stotal(k2); + assert_eq(res4, 1100); + + int res5 = defer_definition(13, 35); + assert_eq(res5, 48); + + int res6 = defer_definition_2(13, 35); + assert_eq(res6, 48); +} \ No newline at end of file diff --git a/test/pil2/features/compressed.pil b/test/pil2/features/compressed.pil new file mode 100644 index 0000000..830a3ee --- /dev/null +++ b/test/pil2/features/compressed.pil @@ -0,0 +1,96 @@ +subproof Compress(2**23) { + col witness a,b,c,d; + challenge stage(2) alpha; + // challenge stage(2) beta; + + expr e = a; + println("e=",e); + for (int i = 0; i < 3; i = i + 1) { + e = e * alpha + b; + println("e=",e); + } + e = e * 24 + c; + println("e=",e); + e = 0; + + expr cols[10]; + cols[0] = a; + cols[1] = b; + cols[2] = c; + // println(cols[0], cols[1], cols[2]); + + // FAIL e = (e + cols[0])*alpha; + // expr k = (e + cols[0])*alpha; + // println("e,k=",k); + + for (int icol = 0; icol < 3; icol = icol + 1) { + // FAIL e = (e + cols[icol])*alpha; + e = (e + cols[icol])*alpha; + // OK e = (e + alpha)*cols[icol]; + println("e=",e); + } + +/* + int opid = 73; + expr cols_compressed = 0; + println("cols", cols); + println("length(cols)", length(cols)); + println("cols[0]", cols[0]); + for (int icol = 0; icol < length(cols); icol = icol + 1) { + println("cols_compressed", cols_compressed, "icol", icol, "cols[icol]", cols[icol]); + expr pcols_compressed = cols_compressed; + cols_compressed = (pcols_compressed + cols[icol]) * 18; + println("cols_compressed (out)", cols_compressed); + } + + println("KKKKKK cols_compressed", cols_compressed); + // the opid is added to avoid soundness issues between different PIOP checks + cols_compressed = (cols_compressed + opid) + beta; + cols_compressed === 20; + + cols_compressed = 0; +// println("cols_compressed", cols_compressed, "icol", icol, "cols[icol]", cols[icol]); + cols_compressed = (cols_compressed + cols[0]) * 18; + //println("cols_compressed (out)", cols_compressed); + + //icol = icol + 1; + // println("cols_compressed", cols_compressed, "icol", icol, "cols[icol]", cols[icol]); + cols_compressed = (cols_compressed + cols[1]) * 18; + // println("cols_compressed (out)", cols_compressed); + + // icol = icol + 1; + // println("cols_compressed", cols_compressed, "icol", icol, "cols[icol]", cols[icol]); + cols_compressed = (cols_compressed + cols[2]) * 18; + // println("cols_compressed (out)", cols_compressed); + + cols_compressed = (cols_compressed + opid) + beta; + // println("cols_compressed (out)", cols_compressed); + + cols_compressed === 30; +*/ +/* + + function compress_cols(int opid, expr cols[]): expr { + expr cols_compressed = 0; + println("cols", cols); + println("length(cols)", length(cols)); + println("cols[0]", cols[0]); +// for (int icol = length(cols) - 1; icol >= 0; icol = icol - 1) { + for (int icol = 0; icol < length(cols); icol = icol + 1) { + println("cols_compressed", cols_compressed, "icol", icol, "cols[icol]", cols[icol]); + cols_compressed = (cols_compressed + cols[icol]) * 18; + println("cols_compressed (out)", cols_compressed); + // cols_compressed = cols_compressed + cols[icol]; + } + + println("KKKKKK cols_compressed", cols_compressed); + // the opid is added to avoid soundness issues between different PIOP checks + cols_compressed = (cols_compressed + opid) + beta; + cols_compressed === 17; + return cols_compressed; + } + + expr result = compress_cols(13, [a, b, c]); + println("result=", result); +*/ +} \ No newline at end of file diff --git a/test/pil2/features/expressions.pil b/test/pil2/features/expressions.pil index 0b284a6..cc53330 100644 --- a/test/pil2/features/expressions.pil +++ b/test/pil2/features/expressions.pil @@ -3,7 +3,7 @@ subproof Expressions(2**16) { col witness byteIn; col witness bits[8]; - expr byteFromBits = 0; + expr byteFromBits = 22; for (int i = 0; i < 8; ++i) { byteFromBits = byteFromBits + bits[i] * 2**i; // bits[i] * (1 - bits[i]) === 0; diff --git a/test/pil2/std2/std_mset_lookup_range.pil b/test/pil2/std2/std_mset_lookup_range.pil new file mode 100644 index 0000000..7cad09d --- /dev/null +++ b/test/pil2/std2/std_mset_lookup_range.pil @@ -0,0 +1,331 @@ +private function init_challenges() { + if (!defined(std_alpha)) { + challenge stage(2) std_alpha; + } + if (!defined(std_beta)) { + challenge stage(2) std_beta; + } +} +/* +function multiset_assumes(int opid, expr cols[]) { + piop_update(0, 0, opid, 1, cols); +} + +function multiset_proves(int opid, expr cols[]) { + piop_update(1, 0, opid, 1, cols); +} +*/ +function multiset_assumes(int opid, expr sel, expr __cols[]) { + piop_update(0, 0, opid, sel, __cols); +} + +function multiset_proves(int opid, expr sel, expr cols[]) { + piop_update(1, 0, opid, sel, cols); +} + +/* +function lookup_assumes(int opid, expr cols[]) { + piop_update(0, 1, opid, 1, cols); +} + +function lookup_proves(int opid, expr cols[]) { + piop_update(1, 1, opid, 1, cols); +} +*/ + +// Right now, we assumes that the user proves the multiplicity counter. +// However, we could let the user to only give us the selector and the columns, and we compute the multiplicity counter. +function lookup_assumes(int opid, expr mul_count, expr cols[]) { + piop_update(0, 1, opid, mul_count, cols); +} + +function lookup_proves(int opid, expr mul_count, expr cols[]) { + piop_update(1, 1, opid, mul_count, cols); +} + +/* +// To support vector range checks, we would need to compute a table of all permutations of the range [min,max-1]. +function range_check(int opid, expr cols[], int min, int max) { + for (int i = 0; i < length(cols); i = i + 1) { + piop_update(0, 1, opid, 1, cols[i]); + } + + col fixed RANGE = [min,min+1..+..max-1]; // QUESTION: Does this still work if max - min > N? + // col witness mul_count = compute_multiplicities(cols, RANGE); + piop_update(1, 1, opid, mul_count, RANGE); +} +*/ + +function range_check(int opid, expr sels[], expr cols[], int min, int max) { + for (int i = 0; i < length(cols); i = i + 1) { + piop_update(0, 1, opid, sels[i], cols[i]); + } + + col fixed RANGE = [min,min+1..+..max-1]; + // col witness mul_count = compute_multiplicities(cols, RANGE); + piop_update(1, 1, opid, mul_count, RANGE); +} + +// QUESTION: Can the following O(n³) algorithm be implemented faster? +/** + * Given columns C₀,...,Cₙ₋₁, and a range, computes the multiplicity counter: + · mul_count[i] = Σⱼ |{k : Cⱼ[k] = range[i]}| + * @param cols + * @param range + */ +private function compute_multiplicities(expr cols[], expr range) { + expr mul_count[length(range)] = 0; // [0,0,...,0] + for (int i = 0; i < length(range); i = i + 1) { + for (int j = 0; j < length(cols); j = j + 1) { + for (int k = 0; k < length(cols[j]); k = k + 1) { + if (cols[j][k] == range[i]) { + mul_count[i] = mul_count[i] + 1; + } + } + } + } + // Note: We do not need to normalize the result, since a range has no repeated elements. + return mul_count; +} + +/** + * Verifies the number of columns of same PIOP check (assumes, proves) is the same. + * @param opid (unique) identifier of the PIOP check + * @param cols_count number of columns of the PIOP check + * @param proves 1 if proves, 0 if assumes + */ +private function check_opid_and_cols(int proves, int type, int opid, int cols_count) { + + if (cols_count < 1) { + error(`The number of columns of PIOP #${opid} must be at least 1`); + } + + container proof.std.piop alias piop { + // FIX: dynamic arrays not ready + int opids_count = 0; + int opids[100]; + expr gsum = 0; // Resulting sum of every subproof and every air. + // Declared as expression (unknown at runtime), but used as field element. + } + + container subproof.std.piop { + subproofval aggregate(sum) gsum_result; + } + + container air.std.piop { + // FIX: dynamic arrays not ready + int gsum_assumes_count = 0; + expr gsum_assumes_sel[100]; + expr gsum_assumes[100]; + + int gsum_proves_count = 0; + expr gsum_proves_type[100]; + expr gsum_proves_sel[100]; + expr gsum_proves[100]; + } + + container proof.std.piop.`id${opid}` alias piopid { + int cols; + int proves = 0; + int assumes = 0; + } + + if (piopid.cols == 0) { + // first time called + piopid.cols = cols_count; + // add opid on a list to verify at final + piop.opids[piop.opids_count] = opid; + piop.opids_count = piop.opids_count + 1; + } else if (piopid.cols != cols_count) { + error(`The number of columns of PIOP #${opid} must be ${piopid.cols} but was ${cols_count}`); + } + + if (proves) { + piopid.proves = piopid.proves + 1; + } else { + piopid.assumes = piopid.assumes + 1; + } +} + +/** + * Given columns C₁,...,Cₙ, reduces the vector PIOP to a single column PIOP. + * @param opid (unique) identifier of the PIOP + * @param cols columns of the PIOP + * @return [opid + C₁·α + C₂·α² + ... + Cₙ·αⁿ] + β + */ +private function compress_cols(int opid, expr cols[]): expr { + expr cols_compressed = 0; + for (int icol = length(cols) - 1; icol >= 0; icol = icol - 1) { + cols_compressed = (cols_compressed + cols[icol]) * std_alpha; + } + + // the opid is added to avoid soundness issues between different PIOP checks + cols_compressed = (cols_compressed + opid) + std_beta; + return cols_compressed; +} + +/** + * Given columns C₀,...,Cₙ₋₁, and multiplicity counter M, it 1] defines the constraints at the air level, 2] updates the values at the subproof level, and 3] updates the constraints at the proof level. + * @param proves boolean indicating if updating a proves or a assumes + * @param type if 1, it is a lookup or a range check; if 0, it is a multiset + * @param opid (unique) identifier of the PIOP + * @param sel selector of the PIOP + * @param cols columns of the PIOP + */ +private function piop_update(int proves, int type, int opid, expr sel, expr cols[]) { + // verify if correct opid and cols + check_opid_and_cols(proves, type, opid, length(cols)); + + init_challenges(); + + // selected vector to simple column reduction + expr cols_compressed = compress_cols(opid, cols); + + use air.std.piop; + if (proves) { + // adding all sums of proves called in this air + gsum_proves_type[gsum_proves_count] = type; + gsum_proves_sel[gsum_proves_count] = sel; + gsum_proves[gsum_proves_count] = cols_compressed; + gsum_proves_count = gsum_proves_count + 1; + } else { + // adding all sums of assumes called in this air + gsum_assumes_sel[gsum_assumes_count] = sel; + gsum_assumes[gsum_assumes_count] = cols_compressed; + gsum_assumes_count = gsum_assumes_count + 1; + } + + // QUESTION: Should the user proves the multiplicity counter? Or we should compute it? + // 0] computes the multiplicity counter for lookups and range checks + // on final air compute_multiplicities_lookup_range(); + + // 1] look for repeated proves/assumes's in both lookups and range checks and, if found, optimize + // on final air lookup_range_proves_batch(); + + // 2] define constraints at the air level + on final air PIOP_air(); + + // 3] update values at the subproof level + on final subproof PIOP_subproof(); + + // 4] update constraints at the proof level + on final proof PIOP_proof(); +} +/* +// QUESTION: Can the following O(n²) algorithm be implemented faster? +// Given the proves, it "merges" the repeated ones through their associated multiplicity counters. +private function lookup_range_proves_batch() { + use air.std.piop; + + // int len = length(gsum_proves); + int len = gsum_proves_count; + + for (int i = 0; i < len; i = i + 1) { + for (int j = 0; j < len; j = j + 1) { + if (i == j) continue; + // It two proves are the same, add their multiplicity counters to one and remove the other + if (gsum_proves[j] == gsum_proves[i] && gsum_proves_type[j] == 1) { + gsum_proves_sel[i] = gsum_proves_sel[i] + gsum_proves_sel[j]; + + gsum_proves[j] = gsum_proves[len-1]; + gsum_proves_sel[j] = gsum_proves_sel[len-1]; + gsum_proves.pop(); // QUESTION: Will array pop be implemented? + gsum_proves_sel.pop(); + } + } + } +} +*/ + +private function PIOP_air() { + use air.std.piop; + + col witness stage(2) gsum; + + // mt1 mt2 mt3 mf1 mf2 mf3 + // gsum === 'gsum * (1 - L1) + ------- + ------- + ------- - ------- - ------- - ------- + // t1 t2 t3 f1 f2 f3 + + col fixed L1 = [1,0...]; + + expr LHS = 1; + expr RHS1 = 0; + + col witness gsP[gsum_proves_count]; + for (int i = 0; i < gsum_proves_count; i = i + 1) { + gsP[i] === gsum_proves[i]; + } + col witness gsA[gsum_assumes_count]; + for (int i = 0; i < gsum_assumes_count; i = i + 1) { + gsA[i] === gsum_assumes[i]; + } + + // for (int i = 0; i < length(gsum_proves); i = i + 1) { + for (int i = 0; i < gsum_proves_count; i = i + 1) { + LHS = LHS * gsP[i]; + + expr tmp = gsum_proves_sel[i]; + // for (int j = 0; j < length(gsum_proves); j = j + 1) { + for (int j = 0; j < gsum_proves_count; j = j + 1) { + if (j != i) tmp = tmp * gsP[j]; + } + RHS1 = RHS1 + tmp; + } + + // expr RHS2a = LHS; + col witness RHS2a; + RHS2a === LHS; + expr RHS2b = 0; + // for (int i = 0; i < length(gsum_assumes); i = i + 1) { + for (int i = 0; i < gsum_assumes_count; i = i + 1) { + LHS = LHS * gsA[i]; + RHS1 = RHS1 * gsA[i]; + + expr tmp = gsum_assumes_sel[i]; + // for (int j = 0; j < length(gsum_assumes); j = j + 1) { + for (int j = 0; j < gsum_assumes_count; j = j + 1) { + if (j != i) tmp = tmp * gsA[j]; + } + RHS2b = RHS2b + tmp; + } + + expr RHS2 = RHS2a * RHS2b; + expr RHS = RHS1 - RHS2; + + (gsum - 'gsum * (1 - L1)) * LHS === RHS; + L1' * (gsum - subproof.std.piop.gsum_result) === 0; +} + +private function PIOP_subproof() { + proof.std.piop.gsum = proof.std.piop.gsum + subproof.std.piop.gsum_result; +} + +private function PIOP_proof() { + check_was_completed(); + + proof.std.piop.gsum === 0; +} + +private function check_was_completed() { +/* + for (int opid in proof.std.piop.opids) { + use proof.std.piop.`id${opid}`; + if (assumes == 0) { + error(`PIOP #${opid} defined without assumes`); + } + if (proves == 0) { + error(`PIOP #${opid} defined without proves`); + } + }*/ + + for (int index = 0; index < proof.std.piop.opids_count; index = index + 1) { + int opid = proof.std.piop.opids[index]; + use proof.std.piop.`id${opid}`; + if (assumes == 0) { + error(`PIOP #${opid} defined without require`); + } + if (proves == 0) { + error(`PIOP #${opid} defined without provide`); + } + } +} \ No newline at end of file diff --git a/test/pil2/vadcop-fibonacci-proofman/module.pil b/test/pil2/vadcop-fibonacci-proofman/module.pil index 08bd7a2..3a5c0ea 100644 --- a/test/pil2/vadcop-fibonacci-proofman/module.pil +++ b/test/pil2/vadcop-fibonacci-proofman/module.pil @@ -1,4 +1,4 @@ -constant MODULE_ID = 1; +const int MODULE_ID = 1; subproof Module(2**4) { diff --git a/test/pil2/vadcop-fibonacci-std/fibonacci.pil b/test/pil2/vadcop-fibonacci-std/fibonacci.pil new file mode 100644 index 0000000..0d46e4f --- /dev/null +++ b/test/pil2/vadcop-fibonacci-std/fibonacci.pil @@ -0,0 +1,24 @@ +include "../vadcop/std_sum.pil" +include "module.pil"; + +public mod; +public in1; +public in2; +public out; + +subproof aggregate Fibonacci(2**16, 2**18) { + + subproofval aggregate(sum) gsum_fibonacci; + + col fixed L1 = [1,0...]; + col witness a,b; + + (b' - a) * (1 - L1') === 0; + L1 * (b - in1) === 0; + L1 * (a - in2) === 0; + L1' * (a - out) === 0; + // multiset_require(MODULE_ID, 1, [a*a + b*b, a' * (1 - L1'2) + out * L1'2]) + multiset_require(MODULE_ID, 1, [a*a + b*b, a']) +}; + + diff --git a/test/pil2/vadcop-fibonacci-std/module.pil b/test/pil2/vadcop-fibonacci-std/module.pil new file mode 100644 index 0000000..420d39e --- /dev/null +++ b/test/pil2/vadcop-fibonacci-std/module.pil @@ -0,0 +1,15 @@ +const int MODULE_ID = 1; + +subproof Module(2**16) { + + subproofval aggregate(sum) gsum_module; + + col fixed L1 = [1,0...]; + col witness x, q, x_mod; + + // TODO: verify range checks and x_mod < mod + x === q * mod + x_mod; + + + multiset_provide(MODULE_ID, 1, [x, x_mod]); +} \ No newline at end of file diff --git a/test/pil2/vadcop-fibonacci-std2/fibonacci.pil b/test/pil2/vadcop-fibonacci-std2/fibonacci.pil new file mode 100644 index 0000000..b63b722 --- /dev/null +++ b/test/pil2/vadcop-fibonacci-std2/fibonacci.pil @@ -0,0 +1,24 @@ +include "../std2/std_mset_lookup_range.pil" +include "module.pil"; + +public mod; +public in1; +public in2; +public out; + +subproof aggregate Fibonacci(2**16, 2**18) { + + subproofval aggregate(sum) gsum_fibonacci; + + col fixed L1 = [1,0...]; + col witness a,b; + + (b' - a) * (1 - L1') === 0; + L1 * (b - in1) === 0; + L1 * (a - in2) === 0; + L1' * (a - out) === 0; + + multiset_assumes(MODULE_ID, 1, [a*a + b*b, a']) +}; + + diff --git a/test/pil2/vadcop-fibonacci-std2/module.pil b/test/pil2/vadcop-fibonacci-std2/module.pil new file mode 100644 index 0000000..0a3c378 --- /dev/null +++ b/test/pil2/vadcop-fibonacci-std2/module.pil @@ -0,0 +1,15 @@ +const int MODULE_ID = 1; + +subproof Module(2**16) { + + subproofval aggregate(sum) gsum_module; + + col fixed L1 = [1,0...]; + col witness x, q, x_mod; + + // TODO: verify range checks and x_mod < mod + x === q * mod + x_mod; + + + multiset_proves(MODULE_ID, 1, [x, x_mod]); +} \ No newline at end of file diff --git a/test/pil2/vadcop-fibonacci/module.pil b/test/pil2/vadcop-fibonacci/module.pil index e316dd1..ec57706 100644 --- a/test/pil2/vadcop-fibonacci/module.pil +++ b/test/pil2/vadcop-fibonacci/module.pil @@ -1,4 +1,4 @@ -constant MODULE_ID = 1; +const int MODULE_ID = 1; subproof Module(2**16) { diff --git a/test/pil2/vadcop/byte4.pil b/test/pil2/vadcop/byte4.pil index be47ee9..ab7c80b 100644 --- a/test/pil2/vadcop/byte4.pil +++ b/test/pil2/vadcop/byte4.pil @@ -22,5 +22,5 @@ subproof Byte4(2**16) { } byteFromBits === byteIn; - multiset_proves(BYTE4_ID, result, [out]); + multiset_provide(BYTE4_ID, result, [out, byteIn]); } \ No newline at end of file diff --git a/test/pil2/zkevm-etrog/README.md b/test/pil2/zkevm-etrog/README.md new file mode 100644 index 0000000..c460abd --- /dev/null +++ b/test/pil2/zkevm-etrog/README.md @@ -0,0 +1,38 @@ +### PIL2 Migration +|ID|subproof|pil2|tools|executor|notes| +|---|----|----|-----|----|----| +|1|main|90%|-|0%|| +|2|rom|80%|0%|-|tool: zkasm => pil| +|4|mem|90%|-|0%|| +|5|mem_align|80%|-|0%|| +|6|range_32|50%|-|0%|| +|10|arith|30%|0%|0%|pending: equation generation from pil and last features added (alias free,diff points)| +|20|binary|90%|-|0%|| +|20|binary (one_row)|90%|-|-|alternative, no generate executor| +|21|binary_ops_table|90%|-|-|| +|40-42|padding_pg|90%|-|0%|| +|45|poseidong|95%|-|0%|| +|50-52|padding_kk|0%|-|0%|| +|55|padding_kkbit|0%|-|0%|| +|56|keccakf|90%|0%|0%|tool: script/circuit => pil| +|57|keccakf_table|90%|-|-|| +||bits2field|-|-|-|deleted, integrated inside keccakf +|60-62|padding_sha256|0%|-|0%|| +|65|padding_sha256bit|10%|-|0%|| +|66|sha256f|80%|0%|0%|tool: script/circuit => pil| +|67|sha256f_table|90%|-|-|| +||bits2field_sha256|-|-|-|deleted, integrated inside sha256f +|90|storage|80%|-|%0|| +|91|storage_rom|100%|100%|-|tool: zkasm => pil| +|92|climb_key|90%|-|0%|| +|93|climb_key_table|100%|100%|-|tool: validate/generate constants| + +### TOOLS +|tool|status|notes| +|---|----|----| +|zkasm_rom2pil|0%|used to generate pil from rom.json| +|equation2pil|0%|generate equation pols with prior/next window| +|keccakf_script2pil|0%|used to generate pil from keccak script json| +|sha256_script2pil|0%|used to generate pil from sha256 script json| +|zkasm_storagerom2pil|100%|used to generate pil from storage-rom.json| +|climbkey_table|100%|used to verify complex climbkey fixed columns| diff --git a/test/pil2/zkevm-etrog/arith.pil b/test/pil2/zkevm-etrog/arith.pil new file mode 100644 index 0000000..9d20d12 --- /dev/null +++ b/test/pil2/zkevm-etrog/arith.pil @@ -0,0 +1,4297 @@ + +/* + Equations: + + EQ0: A(x1) * B(y1) + C(x2) = D (y2) * 2 ** 256 + op (y3) - selEq[0] + + EQ1: s * x2 - s * x1 - y2 + y1 + (q0 * p1) lambda - ADD - selEq[1] + EQ2: 2 * s * y1 - 3 * x1 * x1 + (q0 * p1) lambda - DBL - selEq[2] + EQ3: s * s - x1 - x2 - x3 + (q1 * p1) x3 - selEq[3] + EQ4: s * x1 - s * x3 - y1 - y3 + (q2 * p1) y3 - selEq[3] + + EQ5: x1 * x2 - y1 * y2 - x3 + (q1 * p2) - selEq[4] + EQ6: y1 * x2 + x1 * y2 - y3 + (q2 * p2) - selEq[4] + + EQ7: x1 + x2 - x3 + (q1 * p2) - selEq[5] + EQ8: y1 + y2 - y3 + (q2 * p2) - selEq[5] + + EQ9: x1 - x2 - x3 + (q1 * p2) - selEq[6] + EQ10: y1 - y2 - y3 + (q2 * p2) - selEq[6] + + where p1 refers to the base field order of: + · Secp256k1: 0xFFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFE FFFF FC2F + and p2 refers to the base field order of: + · BN254: 0x3064 4E72 E131 A029 B850 45B6 8181 585D 9781 6A91 6871 CA8D 3C20 8C16 D87C FD47 +*/ +include "tools.pil"; + +subproof Arith(2**23) { + + col witness x1_y1; // clocks(cl) 0..15 => x1[15-cl] 16..31 => y1[31-cl] + col witness x2_y2; // clocks(cl) 0..15 => x2[15-cl] 16..31 => y2[31-cl] + col witness x2_y3; // clocks(cl) 0..15 => x3[15-cl] 16..31 => y3[31-cl] + col witness s2_q0; // clocks(cl) 0..15 => s[15-cl] 16..31 => q0[31-cl] + col witness q1_q2; // clocks(cl) 0..15 => q1[15-cl] 16..31 => q2[31-cl] + + col fixed C16OF32 = [1:16,0:16]...; + + // FEATURE: + // · Verify that the x1,x2 are different when adding different elliptic curve points (EQ1,EQ3,EQ4). + + // PRE: + // · x1,x2,y1,y2 are alias free for EQ[1..10] + + // In the first 16 clocks of 32-clock cycle we have: x2[0]-x1[0], x2[1]-x1[1], ..., x2[15]-x1[15] + // In the last 16 clocks of 32-clock cycle we set all values to 0. + const expr xDeltaChunk = (xy2 - xy1) * C16OF32; + + // Inverse of current xDeltaChunk. Used to verify that xDeltaChunk is ≠ 0, i.e., when x1[i] ≠ x2[i]. + // This inverse only needs to be calculated one time by cycle. + col witness xDeltaChunkInverse; + + // Intermediate pol to indicate that x1 is different from x2 in the current chunk. + // IMPORTANT: xChunkDifferent == 1 ==> x1[i] ≠ x2[i] + // xChunkDifferent == 0 does not imply anything, x1[i] ≠ x2[i] or x1[i] == x2[i]. + // xChunkDifferent was binary, only when xDeltaChunkInverse === inv(xDeltaChunk), its value is 1. + const expr xChunkDifferent = xDeltaChunk * xDeltaChunkInverse; + + // Important, binary constraint + xChunkDifferent * (1 - xChunkDifferent) = 0; + + // xDeltaChunk xDeltaChunkInverse xChunkDifferent + // ----------- ------------------ ----------------------- + // 0 any 0 * any = 0 OK (A) + // x (≠ 0) 0 x * 0 = 0 OK (B) + // x (≠ 0) inv(x) x * inv(x) = 1 OK (C) + // x (≠ 0) y ≠ {inv(x),0} x * y = k (≠ 0,1) FAILS (D) + // + // (A) and (C) are the standard cases, but (B) was introduced to avoid calculate the inverse when + // it is not necessary. xChunkDifferent is well calculed because it's 1 only when x ≠ 0 and inverse + // it's calculated. + + // xAreDifferent is used to indicate that in current clock we knows that x1 and x2 are different + const witness xAreDifferent; + + // Binary constraint + xAreDifferent * (1 - xAreDifferent) = 0; + + // In first clock of 16-clock cycle, xAreDifferent should not be considered + // Constraint to force next value of xAreDifferent + + xAreDifferent' = xAreDifferent * (1 - Global.CLK32[0] - Global.CLK32[16]) + xChunkDifferent; + + // xAreDifferent CLK0+CLK16 xChunkDifferent xAreDifferent' + // ------------- ---------- --------------- -------------- + // 0 0 0 0 OK + // 0 0 1 1 OK + // 0 1 0 1 OK + // 0 1 1 1 OK + // 1 0 0 1 OK + // 1 0 1 2 FAILS (A) + // 1 1 0 1 OK + // 1 1 1 1 OK + // + // xChunkDifferent = 0 ==> (x2[i] - x1[i]) = 0 + // xChunkDifferent = 1 ==> (x2[i] - x1[i]) ≠ 0 ==> x1 and x2 are different + // (A) forbidden, executor must control this situation, because expending an + // unnecessary inverse. + + (xAreDifferent - selEq[1]) * Global.CLK32[16] = 0; + + // COST: 2 commit, 2 im, 0 constant, 4 constraints + + + // FEATURE: + // + // Verify that the result of Secp256k1 addition (EQ1/EQ2,EQ3,EQ4) is free of aliases, i.e. that x3,y3 ∊ [0, p-1] + // Verify that the result of 𝔽p² = 𝔽p[u]/(u² + 1) multiplication, addition and subtraction (EQ5,EQ6 || EQ7,EQ8 || EQ9,EQ10) + // is free of aliases, i.e. that x3,y3 ∊ [0, p-1] + // + // Here, p refers, respectively, to the base field order of any of the following elliptic curves: + // + // Secp256k1: 0xFFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFE FFFF FC2F + // BN254: 0x3064 4E72 E131 A029 B850 45B6 8181 585D 9781 6A91 6871 CA8D 3C20 8C16 D87C FD47 + // + // Strategy: Compare from the most significant chunk to the least significant chunk of x3 and y3 (A). On each chunk, + // chunkLtPrime indicates whether the chunk is smaller than the FPEC chunk. valueLtPrime indicates if any + // previous chunk was smaller than the FPEC chunk, which implies that x3 and y3 are smaller than prime. + // + // (A) In the first 16 clocks of 32-clock cycle, it is verified that x3 ∊ [0, p-1] + // In the last 16 clocks of 32-clock cycle, it is verified that y3 ∊ [0, p-1] + // + // k x chunks equals (B) ==> 1 x chunk lower ==> (15 - k) x any 16 bits value + // + // (B) I must verify that the chunks are equal or smaller, never greater at this point. If a malicious prover (MP) + // claims they are equal when they are actually smaller, that's its issue. At the end, there must be at least one + // smaller chunk to ensure a smaller value. + // + // k x chunks = chunkPrime ==> 1 x chunk ∊ [0, chunkPrime-1] ==> (15 - k) x chunk ∊ [0, 0xFFFF] + // + // CLK0 CLK1 CLK2 CLK3 CLK4 CLK5 CLK6 CLK7 CLK8 CLK9 CLK10 CLK11 CLK12 CLK13 CLK14 CLK15 + // chunkPrime(0..15) = [0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFF, 0xFC2F] + // chunkPrime(0..15) - 1 = [0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFD, 0xFFFE, 0xFC2E] + // chunkPrime(0..15) = [0x3064, 0x4e72, 0xe131, 0xa029, 0xb850, 0x45b6, 0x8181, 0x585d, 0x9781, 0x6a91, 0x6871, 0xca8d, 0x3c20, 0x8c16, 0xd87c, 0xfd47] + // chunkPrime(0..15) - 1 = [0x3063, 0x4e71, 0xe130, 0xa028, 0xb84f, 0x45b5, 0x8180, 0x585c, 0x9780, 0x6a90, 0x6870, 0xca8c, 0x3c1f, 0x8c15, 0xd87b, 0xfd46] + // + // different Secp256k1 prime chunks [0xFFFF, 0xFFFE, 0xFFFD, 0xFC2F, 0xFC2E] + // different BN254 prime chunks [0x3064, 0x4e72, 0xe131, 0xa029, 0xb850, 0x45b6, 0x8181, 0x585d, 0x9781, 0x6a91, 0x6871, 0xca8d, 0x3c20, 0x8c16, 0xd87c, 0xfd47, + // 0x3063, 0x4e71, 0xe130, 0xa028, 0xb84f, 0x45b5, 0x8180, 0x585c, 0x9780, 0x6a90, 0x6870, 0xca8c, 0x3c1f, 0x8c15, 0xd87b, 0xfd46] + + // CLK0 CLK1 CLK2 CLK3 CLK4 CLK5 CLK6 CLK7 CLK8 CLK9 CLK10 CLK11 CLK12 CLK13 CLK14 CLK15 + // Secp256k1: 0xFFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF fffe FFFF fc2f + // BN254: 0x3064 4e72 e131 a029 b850 45b6 8181 585d 9781 6a91 6871 ca8d 3c20 8c16 d87c fd47 + // + // RANGE_SEL P_RANGE BASE + // / 0 [0,0xFFFF] CLK0, ..., CLK12, CLK14 + // | 1 [0,0xFFFE] CLK13 + // Secp256k1 | 2 [0,0xFFFD] + // | 3 [0,0xFC2F] CLK15 + // \ 4 [0,0xFC2E] + // / 5 [0,0x3064] CLK0 + // | 6 [0,0x3063] + // | 7 [0,0x4e72] CLK1 + // | 8 [0,0x4e71] + // | 9 [0,0xe131] CLK2 + // | 10 [0,0xe130] + // | 11 [0,0xa029] CLK3 + // | 12 [0,0xa028] + // | 13 [0,0xb850] CLK4 + // | 14 [0,0xb84f] + // | 15 [0,0x45b6] CLK5 + // | 16 [0,0x45b5] + // | 17 [0,0x8181] CLK6 + // | 18 [0,0x8180] + // | 19 [0,0x585d] CLK7 + // BN254 | 20 [0,0x585c] + // | 21 [0,0x9781] CLK8 + // | 22 [0,0x9780] + // | 23 [0,0x6a91] CLK9 + // | 24 [0,0x6a90] + // | 25 [0,0x6871] CLK10 + // | 26 [0,0x6870] + // | 27 [0,0xca8d] CLK11 + // | 28 [0,0xca8c] + // | 29 [0,0x3c20] CLK12 + // | 30 [0,0x3c1f] + // | 31 [0,0x8c16] CLK13 + // | 32 [0,0x8c15] + // | 33 [0,0xd87c] CLK14 + // | 34 [0,0xd87b] + // | 35 [0,0xfd47] CLK15 + // \ 36 [0,0xfd46] + // + // pRangeSecp256k1 = (CLK13 + 3 * CLK15 + chunkLtPrime) * selEq[3] + // pRangeBN254 = (5 * CLK0 + 7 * CLK1 + 9 * CLK2 + 11 * CLK3 + 13 * CLK4 + 15 * CLK5 + 17 * CLK6 + 19 * CLK7 + 21 * CLK8 + 23 * CLK9 + 25 * CLK10 + 27 * CLK11 + 29 * CLK12 + 31 * CLK13 + 33 * CLK14 + 35 * CLK15) * (selEq[4] + selEq[5] + selEq[6]) + // pRange = (pRangeSecp256k1 + pRangeBN254) * (1 - valueLtPrime) + // + // CLK pRange pRange + // [selEq[3] = 1, chunkLtPrime = 0] [selEq[3] = 1, chunkLtPrime = 1] + // + // + // 0 0 + 3 * 0 + 0 = 0 0 + 3 * 0 + 1 = 1 + // : : : + // 12 0 + 3 * 0 + 0 = 0 0 + 3 * 0 + 1 = 1 + // 13 1 + 3 * 0 + 0 = 1 1 + 3 * 0 + 1 = 2 + // 14 0 + 3 * 0 + 0 = 0 0 + 3 * 0 + 1 = 1 + // 15 0 + 3 * 1 + 0 = 3 0 + 3 * 1 + 1 = 4 + // + // valueLtPrime' = valueLtPrime * (1 - CLK0 - CLK16) + chunkLtPrime + // + // valueLtPrime chunkLtPrime CLK0+CLK16 valueLtPrime' + // + // 0 0 0 0 OK + // 0 1 0 1 OK + // 1 0 0 1 OK + // 1 1 0 2 FAILS, valueLtPrime not binary (D) + // + // 0 0 1 0 OK + // 0 1 1 1 OK + // 1 0 1 0 OK + // 1 1 1 1 OK (E) + // + // (D) when valueLtPrime = 0 ==> chunkLtPrime must be zero, if not it FAILS + // (E) on clocks 0 and 16, current value of valueLtPrime isn't considered + // + // + // Examples (Secp256k1 prime): + // ┌──────── pRange + // ┌── max_value │ ┌───── chunkLtPrime + // │ ┌─ example │ │ ┌── valueLtPrime + // │ │ │ │ │ + // CLK0 0xFFFF 0xFFFF 0 0 0 + // CLK1 0xFFFF 0xFF00 1 1 0 // RANGE [0, 0xFFFE] + // CLK2 0xFFFF 0x0000 0 0 1 + // CLK3 0xFFFF 0x0000 0 0 1 + // CLK4 0xFFFF 0xFFFF 0 0 1 + // : + // CLK15 0xFC2F 0xFFFF 0 0 1 + // CLK16 0xFFFF 0xFFFF 0 0 1 + // + // + // ┌──────── pRange + // ┌── max_value │ ┌───── chunkLtPrime + // │ ┌─ example │ │ ┌── valueLtPrime + // │ │ │ │ │ + // CLK0 0xFFFF 0xFFFF 0 0 0 + // CLK1 0xFFFF 0xFFFF 0 0 0 + // CLK2 0xFFFF 0xFFFF 0 0 0 + // : + // CLK12 0xFFFF 0xFFFF 0 0 0 + // CLK13 0xFFFE 0xFFFF 1 0 0 // CLK13 == 1 RANGE [0, 0xFFFE] + // CLK14 0xFFFF 0xFFFF 0 0 0 + // CLK15 0xFC2F 0xFC00 4 1 0 // CLK15 == 1 RANGE [0, 0xFC2F] + // CLK16 0xFFFF 0xFFFF 0 0 1 + + // valueLtPrime indicates whether, at this point, we know that the value is smaller than the prime. + // If selEq[3],selEq[4],selEq[5],selEq[6] = 0, it must be 0. + col witness valueLtPrime; + + // chunkLtPrime indicates whether the current value chunk is smaller than the prime chunk. + // If selEq[3],selEq[4],selEq[5],selEq[6] = 0 or valueLtPrime = 1, it must be 0. + col witness chunkLtPrime; + + // binary constraints + chunkLtPrime * (1 - chunkLtPrime) = 0; + valueLtPrime * (1 - valueLtPrime) = 0; + + // This constraint applies to the next value of valueLtPrime. At the beginning of each 16-clock cycle, + // valueLtPrime is ignored because it refers to the previous value. + valueLtPrime' = valueLtPrime * (1 - Global.CLK32[0] - Global.CLK32[16]) + chunkLtPrime; + + // This constraint is used to verify (and to enforce) that at the end of a 16-clock cycle, valueLtPrime is equal to 1. + // This constraint is applied when one of selEq[3],selEq[4],selEq[5],selEq[6] equals 1. + (valueLtPrime' - selEq[3] - selEq[4] - selEq[5] - selEq[6]) * (Global.CLK32[15] + Global.CLK32[31]) = 0; + + col fixed RANGE_SEL = [0:2**16], + [1:2**16-1,0], + [2:2**16-2,0:2], + [3:2**16-976,0:97], + [4:2**16-977,0:97], + [5:2**16-53147,0:53147], + [6:2**16-53146,0:53146], + [7:2**16-45453,0:45453], + [8:2**16-45452,0:45452], + [9:2**16-7886,0:7886], + [10:2**16-7885,0:7885], + [11:2**16-24534,0:24534], + [12:2**16-24533,0:24533], + [13:2**16-18351,0:18351], + [14:2**16-18350,0:18350], + [15:2**16-47689,0:47689], + [16:2**16-47688,0:476887], + [17:2**16-32382,0:323828], + [18:2**16-32381,0:323819], + [19:2**16-42914,0:429140], + [20:2**16-42913,0:429131], + [21:2**16-26750,0:267502], + [22:2**16-26749,0:267493], + [23:2**16-38254,0:382544], + [24:2**16-38253,0:382535], + [25:2**16-38798,0:387986], + [26:2**16-38797,0:3879], + [27:2**16-13682,0:1368], + [28:2**16-13681,0:1368], + [29:2**16-50143,0:5014], + [30:2**16-50142,0:5014], + [31:2**16-29673,0:2967], + [32:2**16-29672,0:2967], + [33:2**16-10115,0:1011], + [34:2**16-10114,0:1011], + [35:2**16-696,0:69], + [36:2**16-695,0:69]...; + + // range to be looked up for each chunk and for each prime + const expr pRangeSecp256k1 = (Global.CLK32[13] + Global.CLK32[29] + 3 * (Global.CLK32[15] + Global.CLK32[31]) + chunkLtPrime) * selEq[3]; + const expr pRangeBN254 = (5 * (Global.CLK32[0] + Global.CLK32[16]) + 7 * (Global.CLK32[1] + Global.CLK32[17]) + 9 * (Global.CLK32[2] + Global.CLK32[18]) + + 11 * (Global.CLK32[3] + Global.CLK32[19]) + 13 * (Global.CLK32[4] + Global.CLK32[20]) + 15 * (Global.CLK32[5] + Global.CLK32[21]) + + 17 * (Global.CLK32[6] + Global.CLK32[22]) + 19 * (Global.CLK32[7] + Global.CLK32[23]) + 21 * (Global.CLK32[8] + Global.CLK32[24]) + + 23 * (Global.CLK32[9] + Global.CLK32[25]) + 25 * (Global.CLK32[10] + Global.CLK32[26]) + 27 * (Global.CLK32[11] + Global.CLK32[27]) + + 29 * (Global.CLK32[12] + Global.CLK32[28]) + 31 * (Global.CLK32[13] + Global.CLK32[29]) + 33 * (Global.CLK32[14] + Global.CLK32[30]) + + 35 * (Global.CLK32[15] + Global.CLK32[31]) + chunkLtPrime) * (selEq[4] + selEq[5] + selEq[6]); + + // lookup with RANGE_SEL as first column and BYTE2 as second column + {(pRangeSecp256k1 + pRangeBN254) * (1 - valueLtPrime), x3[15]*Global.CLK32[0] + x3[14]*Global.CLK32[1] + x3[13]*Global.CLK32[2] + x3[12]*Global.CLK32[3] + x3[11]*Global.CLK32[4] + x3[10]*Global.CLK32[5] + x3[9]*Global.CLK32[6] + x3[8]*Global.CLK32[7] + + x3[7]*Global.CLK32[8] + x3[6]*Global.CLK32[9] + x3[5]*Global.CLK32[10] + x3[4]*Global.CLK32[11] + x3[3]*Global.CLK32[12] + x3[2]*Global.CLK32[13] + x3[1]*Global.CLK32[14] + x3[0]*Global.CLK32[15] + + y3[15]*Global.CLK32[16] + y3[14]*Global.CLK32[17] + y3[13]*Global.CLK32[18] + y3[12]*Global.CLK32[19] + y3[11]*Global.CLK32[20] + y3[10]*Global.CLK32[21] + y3[9]*Global.CLK32[22] + y3[8]*Global.CLK32[23] + + y3[7]*Global.CLK32[24] + y3[6]*Global.CLK32[25] + y3[5]*Global.CLK32[26] + y3[4]*Global.CLK32[27] + y3[3]*Global.CLK32[28] + y3[2]*Global.CLK32[29] + y3[1]*Global.CLK32[30] + y3[0]*Global.CLK32[31]} in {RANGE_SEL, Global.BYTE2}; + + // x1'i2nX(0,3) + + range_check(x1_y1, 0, 2**16-1); + range_check(x2_y2, 0, 2**16-1); + range_check(x3_y3, 0, 2**16-1); + // TODO q0 range check 22 bits !!! + range_check(s_q0, 0, 2**16-1); + range_check(q1_q2, 0, 2**22-1); + + /******* + * + * EQ0: A(x1) * B(y1) + C(x2) = D (y2) * 2 ** 256 + op (y3) + * + *******/ + + // pol eq0_0 = + // (x1[0] * y1[0]) + // + x2[0] - y3[0]; + + const expr eq0_0 = + (x1_y1'(i2nX(0,0)) * x1_y1'(i2nY(0,0))) + + x2_y2'(i2nX(0,0)) * x3_y3'(i2nY(0,0)); + + pol eq0_1 = + (x1[0] * y1[1]) + + (x1[1] * y1[0]) + + x2[1] - y3[1]; + + pol eq0_2 = + (x1[0] * y1[2]) + + (x1[1] * y1[1]) + + (x1[2] * y1[0]) + + x2[2] - y3[2]; + + pol eq0_3 = + (x1[0] * y1[3]) + + (x1[1] * y1[2]) + + (x1[2] * y1[1]) + + (x1[3] * y1[0]) + + x2[3] - y3[3]; + + pol eq0_4 = + (x1[0] * y1[4]) + + (x1[1] * y1[3]) + + (x1[2] * y1[2]) + + (x1[3] * y1[1]) + + (x1[4] * y1[0]) + + x2[4] - y3[4]; + + pol eq0_5 = + (x1[0] * y1[5]) + + (x1[1] * y1[4]) + + (x1[2] * y1[3]) + + (x1[3] * y1[2]) + + (x1[4] * y1[1]) + + (x1[5] * y1[0]) + + x2[5] - y3[5]; + + pol eq0_6 = + (x1[0] * y1[6]) + + (x1[1] * y1[5]) + + (x1[2] * y1[4]) + + (x1[3] * y1[3]) + + (x1[4] * y1[2]) + + (x1[5] * y1[1]) + + (x1[6] * y1[0]) + + x2[6] - y3[6]; + + pol eq0_7 = + (x1[0] * y1[7]) + + (x1[1] * y1[6]) + + (x1[2] * y1[5]) + + (x1[3] * y1[4]) + + (x1[4] * y1[3]) + + (x1[5] * y1[2]) + + (x1[6] * y1[1]) + + (x1[7] * y1[0]) + + x2[7] - y3[7]; + + pol eq0_8 = + (x1[0] * y1[8]) + + (x1[1] * y1[7]) + + (x1[2] * y1[6]) + + (x1[3] * y1[5]) + + (x1[4] * y1[4]) + + (x1[5] * y1[3]) + + (x1[6] * y1[2]) + + (x1[7] * y1[1]) + + (x1[8] * y1[0]) + + x2[8] - y3[8]; + + pol eq0_9 = + (x1[0] * y1[9]) + + (x1[1] * y1[8]) + + (x1[2] * y1[7]) + + (x1[3] * y1[6]) + + (x1[4] * y1[5]) + + (x1[5] * y1[4]) + + (x1[6] * y1[3]) + + (x1[7] * y1[2]) + + (x1[8] * y1[1]) + + (x1[9] * y1[0]) + + x2[9] - y3[9]; + + pol eq0_10 = + (x1[0] * y1[10]) + + (x1[1] * y1[9]) + + (x1[2] * y1[8]) + + (x1[3] * y1[7]) + + (x1[4] * y1[6]) + + (x1[5] * y1[5]) + + (x1[6] * y1[4]) + + (x1[7] * y1[3]) + + (x1[8] * y1[2]) + + (x1[9] * y1[1]) + + (x1[10] * y1[0]) + + x2[10] - y3[10]; + + pol eq0_11 = + (x1[0] * y1[11]) + + (x1[1] * y1[10]) + + (x1[2] * y1[9]) + + (x1[3] * y1[8]) + + (x1[4] * y1[7]) + + (x1[5] * y1[6]) + + (x1[6] * y1[5]) + + (x1[7] * y1[4]) + + (x1[8] * y1[3]) + + (x1[9] * y1[2]) + + (x1[10] * y1[1]) + + (x1[11] * y1[0]) + + x2[11] - y3[11]; + + pol eq0_12 = + (x1[0] * y1[12]) + + (x1[1] * y1[11]) + + (x1[2] * y1[10]) + + (x1[3] * y1[9]) + + (x1[4] * y1[8]) + + (x1[5] * y1[7]) + + (x1[6] * y1[6]) + + (x1[7] * y1[5]) + + (x1[8] * y1[4]) + + (x1[9] * y1[3]) + + (x1[10] * y1[2]) + + (x1[11] * y1[1]) + + (x1[12] * y1[0]) + + x2[12] - y3[12]; + + pol eq0_13 = + (x1[0] * y1[13]) + + (x1[1] * y1[12]) + + (x1[2] * y1[11]) + + (x1[3] * y1[10]) + + (x1[4] * y1[9]) + + (x1[5] * y1[8]) + + (x1[6] * y1[7]) + + (x1[7] * y1[6]) + + (x1[8] * y1[5]) + + (x1[9] * y1[4]) + + (x1[10] * y1[3]) + + (x1[11] * y1[2]) + + (x1[12] * y1[1]) + + (x1[13] * y1[0]) + + x2[13] - y3[13]; + + pol eq0_14 = + (x1[0] * y1[14]) + + (x1[1] * y1[13]) + + (x1[2] * y1[12]) + + (x1[3] * y1[11]) + + (x1[4] * y1[10]) + + (x1[5] * y1[9]) + + (x1[6] * y1[8]) + + (x1[7] * y1[7]) + + (x1[8] * y1[6]) + + (x1[9] * y1[5]) + + (x1[10] * y1[4]) + + (x1[11] * y1[3]) + + (x1[12] * y1[2]) + + (x1[13] * y1[1]) + + (x1[14] * y1[0]) + + x2[14] - y3[14]; + + pol eq0_15 = + (x1[0] * y1[15]) + + (x1[1] * y1[14]) + + (x1[2] * y1[13]) + + (x1[3] * y1[12]) + + (x1[4] * y1[11]) + + (x1[5] * y1[10]) + + (x1[6] * y1[9]) + + (x1[7] * y1[8]) + + (x1[8] * y1[7]) + + (x1[9] * y1[6]) + + (x1[10] * y1[5]) + + (x1[11] * y1[4]) + + (x1[12] * y1[3]) + + (x1[13] * y1[2]) + + (x1[14] * y1[1]) + + (x1[15] * y1[0]) + + x2[15] - y3[15]; + + pol eq0_16 = + (x1[1] * y1[15]) + + (x1[2] * y1[14]) + + (x1[3] * y1[13]) + + (x1[4] * y1[12]) + + (x1[5] * y1[11]) + + (x1[6] * y1[10]) + + (x1[7] * y1[9]) + + (x1[8] * y1[8]) + + (x1[9] * y1[7]) + + (x1[10] * y1[6]) + + (x1[11] * y1[5]) + + (x1[12] * y1[4]) + + (x1[13] * y1[3]) + + (x1[14] * y1[2]) + + (x1[15] * y1[1]) + - y2[0]; + + pol eq0_17 = + (x1[2] * y1[15]) + + (x1[3] * y1[14]) + + (x1[4] * y1[13]) + + (x1[5] * y1[12]) + + (x1[6] * y1[11]) + + (x1[7] * y1[10]) + + (x1[8] * y1[9]) + + (x1[9] * y1[8]) + + (x1[10] * y1[7]) + + (x1[11] * y1[6]) + + (x1[12] * y1[5]) + + (x1[13] * y1[4]) + + (x1[14] * y1[3]) + + (x1[15] * y1[2]) + - y2[1]; + + pol eq0_18 = + (x1[3] * y1[15]) + + (x1[4] * y1[14]) + + (x1[5] * y1[13]) + + (x1[6] * y1[12]) + + (x1[7] * y1[11]) + + (x1[8] * y1[10]) + + (x1[9] * y1[9]) + + (x1[10] * y1[8]) + + (x1[11] * y1[7]) + + (x1[12] * y1[6]) + + (x1[13] * y1[5]) + + (x1[14] * y1[4]) + + (x1[15] * y1[3]) + - y2[2]; + + pol eq0_19 = + (x1[4] * y1[15]) + + (x1[5] * y1[14]) + + (x1[6] * y1[13]) + + (x1[7] * y1[12]) + + (x1[8] * y1[11]) + + (x1[9] * y1[10]) + + (x1[10] * y1[9]) + + (x1[11] * y1[8]) + + (x1[12] * y1[7]) + + (x1[13] * y1[6]) + + (x1[14] * y1[5]) + + (x1[15] * y1[4]) + - y2[3]; + + pol eq0_20 = + (x1[5] * y1[15]) + + (x1[6] * y1[14]) + + (x1[7] * y1[13]) + + (x1[8] * y1[12]) + + (x1[9] * y1[11]) + + (x1[10] * y1[10]) + + (x1[11] * y1[9]) + + (x1[12] * y1[8]) + + (x1[13] * y1[7]) + + (x1[14] * y1[6]) + + (x1[15] * y1[5]) + - y2[4]; + + pol eq0_21 = + (x1[6] * y1[15]) + + (x1[7] * y1[14]) + + (x1[8] * y1[13]) + + (x1[9] * y1[12]) + + (x1[10] * y1[11]) + + (x1[11] * y1[10]) + + (x1[12] * y1[9]) + + (x1[13] * y1[8]) + + (x1[14] * y1[7]) + + (x1[15] * y1[6]) + - y2[5]; + + pol eq0_22 = + (x1[7] * y1[15]) + + (x1[8] * y1[14]) + + (x1[9] * y1[13]) + + (x1[10] * y1[12]) + + (x1[11] * y1[11]) + + (x1[12] * y1[10]) + + (x1[13] * y1[9]) + + (x1[14] * y1[8]) + + (x1[15] * y1[7]) + - y2[6]; + + pol eq0_23 = + (x1[8] * y1[15]) + + (x1[9] * y1[14]) + + (x1[10] * y1[13]) + + (x1[11] * y1[12]) + + (x1[12] * y1[11]) + + (x1[13] * y1[10]) + + (x1[14] * y1[9]) + + (x1[15] * y1[8]) + - y2[7]; + + pol eq0_24 = + (x1[9] * y1[15]) + + (x1[10] * y1[14]) + + (x1[11] * y1[13]) + + (x1[12] * y1[12]) + + (x1[13] * y1[11]) + + (x1[14] * y1[10]) + + (x1[15] * y1[9]) + - y2[8]; + + pol eq0_25 = + (x1[10] * y1[15]) + + (x1[11] * y1[14]) + + (x1[12] * y1[13]) + + (x1[13] * y1[12]) + + (x1[14] * y1[11]) + + (x1[15] * y1[10]) + - y2[9]; + + pol eq0_26 = + (x1[11] * y1[15]) + + (x1[12] * y1[14]) + + (x1[13] * y1[13]) + + (x1[14] * y1[12]) + + (x1[15] * y1[11]) + - y2[10]; + + pol eq0_27 = + (x1[12] * y1[15]) + + (x1[13] * y1[14]) + + (x1[14] * y1[13]) + + (x1[15] * y1[12]) + - y2[11]; + + pol eq0_28 = + (x1[13] * y1[15]) + + (x1[14] * y1[14]) + + (x1[15] * y1[13]) + - y2[12]; + + pol eq0_29 = + (x1[14] * y1[15]) + + (x1[15] * y1[14]) + - y2[13]; + + pol eq0_30 = + (x1[15] * y1[15]) + - y2[14]; + + pol eq0_31 = - y2[15]; + + + /******* + * + * EQ1: s * x2 - s * x1 - y2 + y1 - p * (q0 - offset) = 0 + * + *******/ + + pol eq1_0 = + (s[0] * x2[0] - s[0] * x1[0] - 64559 * q0[0]) + - y2[0] + y1[0]; + + pol eq1_1 = + (s[0] * x2[1] - s[0] * x1[1] - 64559 * q0[1]) + + (s[1] * x2[0] - s[1] * x1[0] - 65535 * q0[0]) + - y2[1] + y1[1]; + + pol eq1_2 = + (s[0] * x2[2] - s[0] * x1[2] - 64559 * q0[2]) + + (s[1] * x2[1] - s[1] * x1[1] - 65535 * q0[1]) + + (s[2] * x2[0] - s[2] * x1[0] - 65534 * q0[0]) + - y2[2] + y1[2]; + + pol eq1_3 = + (s[0] * x2[3] - s[0] * x1[3] - 64559 * q0[3]) + + (s[1] * x2[2] - s[1] * x1[2] - 65535 * q0[2]) + + (s[2] * x2[1] - s[2] * x1[1] - 65534 * q0[1]) + + (s[3] * x2[0] - s[3] * x1[0] - 65535 * q0[0]) + - y2[3] + y1[3]; + + pol eq1_4 = + (s[0] * x2[4] - s[0] * x1[4] - 64559 * q0[4]) + + (s[1] * x2[3] - s[1] * x1[3] - 65535 * q0[3]) + + (s[2] * x2[2] - s[2] * x1[2] - 65534 * q0[2]) + + (s[3] * x2[1] - s[3] * x1[1] - 65535 * q0[1]) + + (s[4] * x2[0] - s[4] * x1[0] - 65535 * q0[0]) + - y2[4] + y1[4]; + + pol eq1_5 = + (s[0] * x2[5] - s[0] * x1[5] - 64559 * q0[5]) + + (s[1] * x2[4] - s[1] * x1[4] - 65535 * q0[4]) + + (s[2] * x2[3] - s[2] * x1[3] - 65534 * q0[3]) + + (s[3] * x2[2] - s[3] * x1[2] - 65535 * q0[2]) + + (s[4] * x2[1] - s[4] * x1[1] - 65535 * q0[1]) + + (s[5] * x2[0] - s[5] * x1[0] - 65535 * q0[0]) + - y2[5] + y1[5]; + + pol eq1_6 = + (s[0] * x2[6] - s[0] * x1[6] - 64559 * q0[6]) + + (s[1] * x2[5] - s[1] * x1[5] - 65535 * q0[5]) + + (s[2] * x2[4] - s[2] * x1[4] - 65534 * q0[4]) + + (s[3] * x2[3] - s[3] * x1[3] - 65535 * q0[3]) + + (s[4] * x2[2] - s[4] * x1[2] - 65535 * q0[2]) + + (s[5] * x2[1] - s[5] * x1[1] - 65535 * q0[1]) + + (s[6] * x2[0] - s[6] * x1[0] - 65535 * q0[0]) + - y2[6] + y1[6]; + + pol eq1_7 = + (s[0] * x2[7] - s[0] * x1[7] - 64559 * q0[7]) + + (s[1] * x2[6] - s[1] * x1[6] - 65535 * q0[6]) + + (s[2] * x2[5] - s[2] * x1[5] - 65534 * q0[5]) + + (s[3] * x2[4] - s[3] * x1[4] - 65535 * q0[4]) + + (s[4] * x2[3] - s[4] * x1[3] - 65535 * q0[3]) + + (s[5] * x2[2] - s[5] * x1[2] - 65535 * q0[2]) + + (s[6] * x2[1] - s[6] * x1[1] - 65535 * q0[1]) + + (s[7] * x2[0] - s[7] * x1[0] - 65535 * q0[0]) + - y2[7] + y1[7]; + + pol eq1_8 = + (s[0] * x2[8] - s[0] * x1[8] - 64559 * q0[8]) + + (s[1] * x2[7] - s[1] * x1[7] - 65535 * q0[7]) + + (s[2] * x2[6] - s[2] * x1[6] - 65534 * q0[6]) + + (s[3] * x2[5] - s[3] * x1[5] - 65535 * q0[5]) + + (s[4] * x2[4] - s[4] * x1[4] - 65535 * q0[4]) + + (s[5] * x2[3] - s[5] * x1[3] - 65535 * q0[3]) + + (s[6] * x2[2] - s[6] * x1[2] - 65535 * q0[2]) + + (s[7] * x2[1] - s[7] * x1[1] - 65535 * q0[1]) + + (s[8] * x2[0] - s[8] * x1[0] - 65535 * q0[0]) + - y2[8] + y1[8]; + + pol eq1_9 = + (s[0] * x2[9] - s[0] * x1[9] - 64559 * q0[9]) + + (s[1] * x2[8] - s[1] * x1[8] - 65535 * q0[8]) + + (s[2] * x2[7] - s[2] * x1[7] - 65534 * q0[7]) + + (s[3] * x2[6] - s[3] * x1[6] - 65535 * q0[6]) + + (s[4] * x2[5] - s[4] * x1[5] - 65535 * q0[5]) + + (s[5] * x2[4] - s[5] * x1[4] - 65535 * q0[4]) + + (s[6] * x2[3] - s[6] * x1[3] - 65535 * q0[3]) + + (s[7] * x2[2] - s[7] * x1[2] - 65535 * q0[2]) + + (s[8] * x2[1] - s[8] * x1[1] - 65535 * q0[1]) + + (s[9] * x2[0] - s[9] * x1[0] - 65535 * q0[0]) + - y2[9] + y1[9]; + + pol eq1_10 = + (s[0] * x2[10] - s[0] * x1[10] - 64559 * q0[10]) + + (s[1] * x2[9] - s[1] * x1[9] - 65535 * q0[9]) + + (s[2] * x2[8] - s[2] * x1[8] - 65534 * q0[8]) + + (s[3] * x2[7] - s[3] * x1[7] - 65535 * q0[7]) + + (s[4] * x2[6] - s[4] * x1[6] - 65535 * q0[6]) + + (s[5] * x2[5] - s[5] * x1[5] - 65535 * q0[5]) + + (s[6] * x2[4] - s[6] * x1[4] - 65535 * q0[4]) + + (s[7] * x2[3] - s[7] * x1[3] - 65535 * q0[3]) + + (s[8] * x2[2] - s[8] * x1[2] - 65535 * q0[2]) + + (s[9] * x2[1] - s[9] * x1[1] - 65535 * q0[1]) + + (s[10] * x2[0] - s[10] * x1[0] - 65535 * q0[0]) + - y2[10] + y1[10]; + + pol eq1_11 = + (s[0] * x2[11] - s[0] * x1[11] - 64559 * q0[11]) + + (s[1] * x2[10] - s[1] * x1[10] - 65535 * q0[10]) + + (s[2] * x2[9] - s[2] * x1[9] - 65534 * q0[9]) + + (s[3] * x2[8] - s[3] * x1[8] - 65535 * q0[8]) + + (s[4] * x2[7] - s[4] * x1[7] - 65535 * q0[7]) + + (s[5] * x2[6] - s[5] * x1[6] - 65535 * q0[6]) + + (s[6] * x2[5] - s[6] * x1[5] - 65535 * q0[5]) + + (s[7] * x2[4] - s[7] * x1[4] - 65535 * q0[4]) + + (s[8] * x2[3] - s[8] * x1[3] - 65535 * q0[3]) + + (s[9] * x2[2] - s[9] * x1[2] - 65535 * q0[2]) + + (s[10] * x2[1] - s[10] * x1[1] - 65535 * q0[1]) + + (s[11] * x2[0] - s[11] * x1[0] - 65535 * q0[0]) + - y2[11] + y1[11]; + + pol eq1_12 = + (s[0] * x2[12] - s[0] * x1[12] - 64559 * q0[12]) + + (s[1] * x2[11] - s[1] * x1[11] - 65535 * q0[11]) + + (s[2] * x2[10] - s[2] * x1[10] - 65534 * q0[10]) + + (s[3] * x2[9] - s[3] * x1[9] - 65535 * q0[9]) + + (s[4] * x2[8] - s[4] * x1[8] - 65535 * q0[8]) + + (s[5] * x2[7] - s[5] * x1[7] - 65535 * q0[7]) + + (s[6] * x2[6] - s[6] * x1[6] - 65535 * q0[6]) + + (s[7] * x2[5] - s[7] * x1[5] - 65535 * q0[5]) + + (s[8] * x2[4] - s[8] * x1[4] - 65535 * q0[4]) + + (s[9] * x2[3] - s[9] * x1[3] - 65535 * q0[3]) + + (s[10] * x2[2] - s[10] * x1[2] - 65535 * q0[2]) + + (s[11] * x2[1] - s[11] * x1[1] - 65535 * q0[1]) + + (s[12] * x2[0] - s[12] * x1[0] - 65535 * q0[0]) + - y2[12] + y1[12]; + + pol eq1_13 = + (s[0] * x2[13] - s[0] * x1[13] - 64559 * q0[13]) + + (s[1] * x2[12] - s[1] * x1[12] - 65535 * q0[12]) + + (s[2] * x2[11] - s[2] * x1[11] - 65534 * q0[11]) + + (s[3] * x2[10] - s[3] * x1[10] - 65535 * q0[10]) + + (s[4] * x2[9] - s[4] * x1[9] - 65535 * q0[9]) + + (s[5] * x2[8] - s[5] * x1[8] - 65535 * q0[8]) + + (s[6] * x2[7] - s[6] * x1[7] - 65535 * q0[7]) + + (s[7] * x2[6] - s[7] * x1[6] - 65535 * q0[6]) + + (s[8] * x2[5] - s[8] * x1[5] - 65535 * q0[5]) + + (s[9] * x2[4] - s[9] * x1[4] - 65535 * q0[4]) + + (s[10] * x2[3] - s[10] * x1[3] - 65535 * q0[3]) + + (s[11] * x2[2] - s[11] * x1[2] - 65535 * q0[2]) + + (s[12] * x2[1] - s[12] * x1[1] - 65535 * q0[1]) + + (s[13] * x2[0] - s[13] * x1[0] - 65535 * q0[0]) + - y2[13] + y1[13]; + + pol eq1_14 = + (s[0] * x2[14] - s[0] * x1[14] - 64559 * q0[14]) + + (s[1] * x2[13] - s[1] * x1[13] - 65535 * q0[13]) + + (s[2] * x2[12] - s[2] * x1[12] - 65534 * q0[12]) + + (s[3] * x2[11] - s[3] * x1[11] - 65535 * q0[11]) + + (s[4] * x2[10] - s[4] * x1[10] - 65535 * q0[10]) + + (s[5] * x2[9] - s[5] * x1[9] - 65535 * q0[9]) + + (s[6] * x2[8] - s[6] * x1[8] - 65535 * q0[8]) + + (s[7] * x2[7] - s[7] * x1[7] - 65535 * q0[7]) + + (s[8] * x2[6] - s[8] * x1[6] - 65535 * q0[6]) + + (s[9] * x2[5] - s[9] * x1[5] - 65535 * q0[5]) + + (s[10] * x2[4] - s[10] * x1[4] - 65535 * q0[4]) + + (s[11] * x2[3] - s[11] * x1[3] - 65535 * q0[3]) + + (s[12] * x2[2] - s[12] * x1[2] - 65535 * q0[2]) + + (s[13] * x2[1] - s[13] * x1[1] - 65535 * q0[1]) + + (s[14] * x2[0] - s[14] * x1[0] - 65535 * q0[0]) + - y2[14] + y1[14]; + + pol eq1_15 = + (s[0] * x2[15] - s[0] * x1[15] - 64559 * q0[15]) + + (s[1] * x2[14] - s[1] * x1[14] - 65535 * q0[14]) + + (s[2] * x2[13] - s[2] * x1[13] - 65534 * q0[13]) + + (s[3] * x2[12] - s[3] * x1[12] - 65535 * q0[12]) + + (s[4] * x2[11] - s[4] * x1[11] - 65535 * q0[11]) + + (s[5] * x2[10] - s[5] * x1[10] - 65535 * q0[10]) + + (s[6] * x2[9] - s[6] * x1[9] - 65535 * q0[9]) + + (s[7] * x2[8] - s[7] * x1[8] - 65535 * q0[8]) + + (s[8] * x2[7] - s[8] * x1[7] - 65535 * q0[7]) + + (s[9] * x2[6] - s[9] * x1[6] - 65535 * q0[6]) + + (s[10] * x2[5] - s[10] * x1[5] - 65535 * q0[5]) + + (s[11] * x2[4] - s[11] * x1[4] - 65535 * q0[4]) + + (s[12] * x2[3] - s[12] * x1[3] - 65535 * q0[3]) + + (s[13] * x2[2] - s[13] * x1[2] - 65535 * q0[2]) + + (s[14] * x2[1] - s[14] * x1[1] - 65535 * q0[1]) + + (s[15] * x2[0] - s[15] * x1[0] - 65535 * q0[0]) + - y2[15] + y1[15]; + + pol eq1_16 = + (s[1] * x2[15] - s[1] * x1[15] - 65535 * q0[15]) + + (s[2] * x2[14] - s[2] * x1[14] - 65534 * q0[14]) + + (s[3] * x2[13] - s[3] * x1[13] - 65535 * q0[13]) + + (s[4] * x2[12] - s[4] * x1[12] - 65535 * q0[12]) + + (s[5] * x2[11] - s[5] * x1[11] - 65535 * q0[11]) + + (s[6] * x2[10] - s[6] * x1[10] - 65535 * q0[10]) + + (s[7] * x2[9] - s[7] * x1[9] - 65535 * q0[9]) + + (s[8] * x2[8] - s[8] * x1[8] - 65535 * q0[8]) + + (s[9] * x2[7] - s[9] * x1[7] - 65535 * q0[7]) + + (s[10] * x2[6] - s[10] * x1[6] - 65535 * q0[6]) + + (s[11] * x2[5] - s[11] * x1[5] - 65535 * q0[5]) + + (s[12] * x2[4] - s[12] * x1[4] - 65535 * q0[4]) + + (s[13] * x2[3] - s[13] * x1[3] - 65535 * q0[3]) + + (s[14] * x2[2] - s[14] * x1[2] - 65535 * q0[2]) + + (s[15] * x2[1] - s[15] * x1[1] - 65535 * q0[1]) + + 129118; + + pol eq1_17 = + (s[2] * x2[15] - s[2] * x1[15] - 65534 * q0[15]) + + (s[3] * x2[14] - s[3] * x1[14] - 65535 * q0[14]) + + (s[4] * x2[13] - s[4] * x1[13] - 65535 * q0[13]) + + (s[5] * x2[12] - s[5] * x1[12] - 65535 * q0[12]) + + (s[6] * x2[11] - s[6] * x1[11] - 65535 * q0[11]) + + (s[7] * x2[10] - s[7] * x1[10] - 65535 * q0[10]) + + (s[8] * x2[9] - s[8] * x1[9] - 65535 * q0[9]) + + (s[9] * x2[8] - s[9] * x1[8] - 65535 * q0[8]) + + (s[10] * x2[7] - s[10] * x1[7] - 65535 * q0[7]) + + (s[11] * x2[6] - s[11] * x1[6] - 65535 * q0[6]) + + (s[12] * x2[5] - s[12] * x1[5] - 65535 * q0[5]) + + (s[13] * x2[4] - s[13] * x1[4] - 65535 * q0[4]) + + (s[14] * x2[3] - s[14] * x1[3] - 65535 * q0[3]) + + (s[15] * x2[2] - s[15] * x1[2] - 65535 * q0[2]) + + 131070; + + pol eq1_18 = + (s[3] * x2[15] - s[3] * x1[15] - 65535 * q0[15]) + + (s[4] * x2[14] - s[4] * x1[14] - 65535 * q0[14]) + + (s[5] * x2[13] - s[5] * x1[13] - 65535 * q0[13]) + + (s[6] * x2[12] - s[6] * x1[12] - 65535 * q0[12]) + + (s[7] * x2[11] - s[7] * x1[11] - 65535 * q0[11]) + + (s[8] * x2[10] - s[8] * x1[10] - 65535 * q0[10]) + + (s[9] * x2[9] - s[9] * x1[9] - 65535 * q0[9]) + + (s[10] * x2[8] - s[10] * x1[8] - 65535 * q0[8]) + + (s[11] * x2[7] - s[11] * x1[7] - 65535 * q0[7]) + + (s[12] * x2[6] - s[12] * x1[6] - 65535 * q0[6]) + + (s[13] * x2[5] - s[13] * x1[5] - 65535 * q0[5]) + + (s[14] * x2[4] - s[14] * x1[4] - 65535 * q0[4]) + + (s[15] * x2[3] - s[15] * x1[3] - 65535 * q0[3]) + + 131068; + + pol eq1_19 = + (s[4] * x2[15] - s[4] * x1[15] - 65535 * q0[15]) + + (s[5] * x2[14] - s[5] * x1[14] - 65535 * q0[14]) + + (s[6] * x2[13] - s[6] * x1[13] - 65535 * q0[13]) + + (s[7] * x2[12] - s[7] * x1[12] - 65535 * q0[12]) + + (s[8] * x2[11] - s[8] * x1[11] - 65535 * q0[11]) + + (s[9] * x2[10] - s[9] * x1[10] - 65535 * q0[10]) + + (s[10] * x2[9] - s[10] * x1[9] - 65535 * q0[9]) + + (s[11] * x2[8] - s[11] * x1[8] - 65535 * q0[8]) + + (s[12] * x2[7] - s[12] * x1[7] - 65535 * q0[7]) + + (s[13] * x2[6] - s[13] * x1[6] - 65535 * q0[6]) + + (s[14] * x2[5] - s[14] * x1[5] - 65535 * q0[5]) + + (s[15] * x2[4] - s[15] * x1[4] - 65535 * q0[4]) + + 131070; + + pol eq1_20 = + (s[5] * x2[15] - s[5] * x1[15] - 65535 * q0[15]) + + (s[6] * x2[14] - s[6] * x1[14] - 65535 * q0[14]) + + (s[7] * x2[13] - s[7] * x1[13] - 65535 * q0[13]) + + (s[8] * x2[12] - s[8] * x1[12] - 65535 * q0[12]) + + (s[9] * x2[11] - s[9] * x1[11] - 65535 * q0[11]) + + (s[10] * x2[10] - s[10] * x1[10] - 65535 * q0[10]) + + (s[11] * x2[9] - s[11] * x1[9] - 65535 * q0[9]) + + (s[12] * x2[8] - s[12] * x1[8] - 65535 * q0[8]) + + (s[13] * x2[7] - s[13] * x1[7] - 65535 * q0[7]) + + (s[14] * x2[6] - s[14] * x1[6] - 65535 * q0[6]) + + (s[15] * x2[5] - s[15] * x1[5] - 65535 * q0[5]) + + 131070; + + pol eq1_21 = + (s[6] * x2[15] - s[6] * x1[15] - 65535 * q0[15]) + + (s[7] * x2[14] - s[7] * x1[14] - 65535 * q0[14]) + + (s[8] * x2[13] - s[8] * x1[13] - 65535 * q0[13]) + + (s[9] * x2[12] - s[9] * x1[12] - 65535 * q0[12]) + + (s[10] * x2[11] - s[10] * x1[11] - 65535 * q0[11]) + + (s[11] * x2[10] - s[11] * x1[10] - 65535 * q0[10]) + + (s[12] * x2[9] - s[12] * x1[9] - 65535 * q0[9]) + + (s[13] * x2[8] - s[13] * x1[8] - 65535 * q0[8]) + + (s[14] * x2[7] - s[14] * x1[7] - 65535 * q0[7]) + + (s[15] * x2[6] - s[15] * x1[6] - 65535 * q0[6]) + + 131070; + + pol eq1_22 = + (s[7] * x2[15] - s[7] * x1[15] - 65535 * q0[15]) + + (s[8] * x2[14] - s[8] * x1[14] - 65535 * q0[14]) + + (s[9] * x2[13] - s[9] * x1[13] - 65535 * q0[13]) + + (s[10] * x2[12] - s[10] * x1[12] - 65535 * q0[12]) + + (s[11] * x2[11] - s[11] * x1[11] - 65535 * q0[11]) + + (s[12] * x2[10] - s[12] * x1[10] - 65535 * q0[10]) + + (s[13] * x2[9] - s[13] * x1[9] - 65535 * q0[9]) + + (s[14] * x2[8] - s[14] * x1[8] - 65535 * q0[8]) + + (s[15] * x2[7] - s[15] * x1[7] - 65535 * q0[7]) + + 131070; + + pol eq1_23 = + (s[8] * x2[15] - s[8] * x1[15] - 65535 * q0[15]) + + (s[9] * x2[14] - s[9] * x1[14] - 65535 * q0[14]) + + (s[10] * x2[13] - s[10] * x1[13] - 65535 * q0[13]) + + (s[11] * x2[12] - s[11] * x1[12] - 65535 * q0[12]) + + (s[12] * x2[11] - s[12] * x1[11] - 65535 * q0[11]) + + (s[13] * x2[10] - s[13] * x1[10] - 65535 * q0[10]) + + (s[14] * x2[9] - s[14] * x1[9] - 65535 * q0[9]) + + (s[15] * x2[8] - s[15] * x1[8] - 65535 * q0[8]) + + 131070; + + pol eq1_24 = + (s[9] * x2[15] - s[9] * x1[15] - 65535 * q0[15]) + + (s[10] * x2[14] - s[10] * x1[14] - 65535 * q0[14]) + + (s[11] * x2[13] - s[11] * x1[13] - 65535 * q0[13]) + + (s[12] * x2[12] - s[12] * x1[12] - 65535 * q0[12]) + + (s[13] * x2[11] - s[13] * x1[11] - 65535 * q0[11]) + + (s[14] * x2[10] - s[14] * x1[10] - 65535 * q0[10]) + + (s[15] * x2[9] - s[15] * x1[9] - 65535 * q0[9]) + + 131070; + + pol eq1_25 = + (s[10] * x2[15] - s[10] * x1[15] - 65535 * q0[15]) + + (s[11] * x2[14] - s[11] * x1[14] - 65535 * q0[14]) + + (s[12] * x2[13] - s[12] * x1[13] - 65535 * q0[13]) + + (s[13] * x2[12] - s[13] * x1[12] - 65535 * q0[12]) + + (s[14] * x2[11] - s[14] * x1[11] - 65535 * q0[11]) + + (s[15] * x2[10] - s[15] * x1[10] - 65535 * q0[10]) + + 131070; + + pol eq1_26 = + (s[11] * x2[15] - s[11] * x1[15] - 65535 * q0[15]) + + (s[12] * x2[14] - s[12] * x1[14] - 65535 * q0[14]) + + (s[13] * x2[13] - s[13] * x1[13] - 65535 * q0[13]) + + (s[14] * x2[12] - s[14] * x1[12] - 65535 * q0[12]) + + (s[15] * x2[11] - s[15] * x1[11] - 65535 * q0[11]) + + 131070; + + pol eq1_27 = + (s[12] * x2[15] - s[12] * x1[15] - 65535 * q0[15]) + + (s[13] * x2[14] - s[13] * x1[14] - 65535 * q0[14]) + + (s[14] * x2[13] - s[14] * x1[13] - 65535 * q0[13]) + + (s[15] * x2[12] - s[15] * x1[12] - 65535 * q0[12]) + + 131070; + + pol eq1_28 = + (s[13] * x2[15] - s[13] * x1[15] - 65535 * q0[15]) + + (s[14] * x2[14] - s[14] * x1[14] - 65535 * q0[14]) + + (s[15] * x2[13] - s[15] * x1[13] - 65535 * q0[13]) + + 131070; + + pol eq1_29 = + (s[14] * x2[15] - s[14] * x1[15] - 65535 * q0[15]) + + (s[15] * x2[14] - s[15] * x1[14] - 65535 * q0[14]) + + 131070; + + pol eq1_30 = + (s[15] * x2[15] - s[15] * x1[15] - 65535 * q0[15]) + + 131070; + + pol eq1_31 = 131070; + + + /******* + * + * EQ2: 2 * s * y1 - 3 * x1 * x1 + p * (q0 - offset) = 0 + * + *******/ + + pol eq2_0 = + (s[0] * y1[0] + s[0] * y1[0] - x1[0] * x1[0] - x1[0] * x1[0] - x1[0] * x1[0] + 64559 * q0[0]); + + pol eq2_1 = + (s[0] * y1[1] + s[0] * y1[1] - x1[0] * x1[1] - x1[0] * x1[1] - x1[0] * x1[1] + 64559 * q0[1]) + + (s[1] * y1[0] + s[1] * y1[0] - x1[1] * x1[0] - x1[1] * x1[0] - x1[1] * x1[0] + 65535 * q0[0]); + + pol eq2_2 = + (s[0] * y1[2] + s[0] * y1[2] - x1[0] * x1[2] - x1[0] * x1[2] - x1[0] * x1[2] + 64559 * q0[2]) + + (s[1] * y1[1] + s[1] * y1[1] - x1[1] * x1[1] - x1[1] * x1[1] - x1[1] * x1[1] + 65535 * q0[1]) + + (s[2] * y1[0] + s[2] * y1[0] - x1[2] * x1[0] - x1[2] * x1[0] - x1[2] * x1[0] + 65534 * q0[0]); + + pol eq2_3 = + (s[0] * y1[3] + s[0] * y1[3] - x1[0] * x1[3] - x1[0] * x1[3] - x1[0] * x1[3] + 64559 * q0[3]) + + (s[1] * y1[2] + s[1] * y1[2] - x1[1] * x1[2] - x1[1] * x1[2] - x1[1] * x1[2] + 65535 * q0[2]) + + (s[2] * y1[1] + s[2] * y1[1] - x1[2] * x1[1] - x1[2] * x1[1] - x1[2] * x1[1] + 65534 * q0[1]) + + (s[3] * y1[0] + s[3] * y1[0] - x1[3] * x1[0] - x1[3] * x1[0] - x1[3] * x1[0] + 65535 * q0[0]); + + pol eq2_4 = + (s[0] * y1[4] + s[0] * y1[4] - x1[0] * x1[4] - x1[0] * x1[4] - x1[0] * x1[4] + 64559 * q0[4]) + + (s[1] * y1[3] + s[1] * y1[3] - x1[1] * x1[3] - x1[1] * x1[3] - x1[1] * x1[3] + 65535 * q0[3]) + + (s[2] * y1[2] + s[2] * y1[2] - x1[2] * x1[2] - x1[2] * x1[2] - x1[2] * x1[2] + 65534 * q0[2]) + + (s[3] * y1[1] + s[3] * y1[1] - x1[3] * x1[1] - x1[3] * x1[1] - x1[3] * x1[1] + 65535 * q0[1]) + + (s[4] * y1[0] + s[4] * y1[0] - x1[4] * x1[0] - x1[4] * x1[0] - x1[4] * x1[0] + 65535 * q0[0]); + + pol eq2_5 = + (s[0] * y1[5] + s[0] * y1[5] - x1[0] * x1[5] - x1[0] * x1[5] - x1[0] * x1[5] + 64559 * q0[5]) + + (s[1] * y1[4] + s[1] * y1[4] - x1[1] * x1[4] - x1[1] * x1[4] - x1[1] * x1[4] + 65535 * q0[4]) + + (s[2] * y1[3] + s[2] * y1[3] - x1[2] * x1[3] - x1[2] * x1[3] - x1[2] * x1[3] + 65534 * q0[3]) + + (s[3] * y1[2] + s[3] * y1[2] - x1[3] * x1[2] - x1[3] * x1[2] - x1[3] * x1[2] + 65535 * q0[2]) + + (s[4] * y1[1] + s[4] * y1[1] - x1[4] * x1[1] - x1[4] * x1[1] - x1[4] * x1[1] + 65535 * q0[1]) + + (s[5] * y1[0] + s[5] * y1[0] - x1[5] * x1[0] - x1[5] * x1[0] - x1[5] * x1[0] + 65535 * q0[0]); + + pol eq2_6 = + (s[0] * y1[6] + s[0] * y1[6] - x1[0] * x1[6] - x1[0] * x1[6] - x1[0] * x1[6] + 64559 * q0[6]) + + (s[1] * y1[5] + s[1] * y1[5] - x1[1] * x1[5] - x1[1] * x1[5] - x1[1] * x1[5] + 65535 * q0[5]) + + (s[2] * y1[4] + s[2] * y1[4] - x1[2] * x1[4] - x1[2] * x1[4] - x1[2] * x1[4] + 65534 * q0[4]) + + (s[3] * y1[3] + s[3] * y1[3] - x1[3] * x1[3] - x1[3] * x1[3] - x1[3] * x1[3] + 65535 * q0[3]) + + (s[4] * y1[2] + s[4] * y1[2] - x1[4] * x1[2] - x1[4] * x1[2] - x1[4] * x1[2] + 65535 * q0[2]) + + (s[5] * y1[1] + s[5] * y1[1] - x1[5] * x1[1] - x1[5] * x1[1] - x1[5] * x1[1] + 65535 * q0[1]) + + (s[6] * y1[0] + s[6] * y1[0] - x1[6] * x1[0] - x1[6] * x1[0] - x1[6] * x1[0] + 65535 * q0[0]); + + pol eq2_7 = + (s[0] * y1[7] + s[0] * y1[7] - x1[0] * x1[7] - x1[0] * x1[7] - x1[0] * x1[7] + 64559 * q0[7]) + + (s[1] * y1[6] + s[1] * y1[6] - x1[1] * x1[6] - x1[1] * x1[6] - x1[1] * x1[6] + 65535 * q0[6]) + + (s[2] * y1[5] + s[2] * y1[5] - x1[2] * x1[5] - x1[2] * x1[5] - x1[2] * x1[5] + 65534 * q0[5]) + + (s[3] * y1[4] + s[3] * y1[4] - x1[3] * x1[4] - x1[3] * x1[4] - x1[3] * x1[4] + 65535 * q0[4]) + + (s[4] * y1[3] + s[4] * y1[3] - x1[4] * x1[3] - x1[4] * x1[3] - x1[4] * x1[3] + 65535 * q0[3]) + + (s[5] * y1[2] + s[5] * y1[2] - x1[5] * x1[2] - x1[5] * x1[2] - x1[5] * x1[2] + 65535 * q0[2]) + + (s[6] * y1[1] + s[6] * y1[1] - x1[6] * x1[1] - x1[6] * x1[1] - x1[6] * x1[1] + 65535 * q0[1]) + + (s[7] * y1[0] + s[7] * y1[0] - x1[7] * x1[0] - x1[7] * x1[0] - x1[7] * x1[0] + 65535 * q0[0]); + + pol eq2_8 = + (s[0] * y1[8] + s[0] * y1[8] - x1[0] * x1[8] - x1[0] * x1[8] - x1[0] * x1[8] + 64559 * q0[8]) + + (s[1] * y1[7] + s[1] * y1[7] - x1[1] * x1[7] - x1[1] * x1[7] - x1[1] * x1[7] + 65535 * q0[7]) + + (s[2] * y1[6] + s[2] * y1[6] - x1[2] * x1[6] - x1[2] * x1[6] - x1[2] * x1[6] + 65534 * q0[6]) + + (s[3] * y1[5] + s[3] * y1[5] - x1[3] * x1[5] - x1[3] * x1[5] - x1[3] * x1[5] + 65535 * q0[5]) + + (s[4] * y1[4] + s[4] * y1[4] - x1[4] * x1[4] - x1[4] * x1[4] - x1[4] * x1[4] + 65535 * q0[4]) + + (s[5] * y1[3] + s[5] * y1[3] - x1[5] * x1[3] - x1[5] * x1[3] - x1[5] * x1[3] + 65535 * q0[3]) + + (s[6] * y1[2] + s[6] * y1[2] - x1[6] * x1[2] - x1[6] * x1[2] - x1[6] * x1[2] + 65535 * q0[2]) + + (s[7] * y1[1] + s[7] * y1[1] - x1[7] * x1[1] - x1[7] * x1[1] - x1[7] * x1[1] + 65535 * q0[1]) + + (s[8] * y1[0] + s[8] * y1[0] - x1[8] * x1[0] - x1[8] * x1[0] - x1[8] * x1[0] + 65535 * q0[0]); + + pol eq2_9 = + (s[0] * y1[9] + s[0] * y1[9] - x1[0] * x1[9] - x1[0] * x1[9] - x1[0] * x1[9] + 64559 * q0[9]) + + (s[1] * y1[8] + s[1] * y1[8] - x1[1] * x1[8] - x1[1] * x1[8] - x1[1] * x1[8] + 65535 * q0[8]) + + (s[2] * y1[7] + s[2] * y1[7] - x1[2] * x1[7] - x1[2] * x1[7] - x1[2] * x1[7] + 65534 * q0[7]) + + (s[3] * y1[6] + s[3] * y1[6] - x1[3] * x1[6] - x1[3] * x1[6] - x1[3] * x1[6] + 65535 * q0[6]) + + (s[4] * y1[5] + s[4] * y1[5] - x1[4] * x1[5] - x1[4] * x1[5] - x1[4] * x1[5] + 65535 * q0[5]) + + (s[5] * y1[4] + s[5] * y1[4] - x1[5] * x1[4] - x1[5] * x1[4] - x1[5] * x1[4] + 65535 * q0[4]) + + (s[6] * y1[3] + s[6] * y1[3] - x1[6] * x1[3] - x1[6] * x1[3] - x1[6] * x1[3] + 65535 * q0[3]) + + (s[7] * y1[2] + s[7] * y1[2] - x1[7] * x1[2] - x1[7] * x1[2] - x1[7] * x1[2] + 65535 * q0[2]) + + (s[8] * y1[1] + s[8] * y1[1] - x1[8] * x1[1] - x1[8] * x1[1] - x1[8] * x1[1] + 65535 * q0[1]) + + (s[9] * y1[0] + s[9] * y1[0] - x1[9] * x1[0] - x1[9] * x1[0] - x1[9] * x1[0] + 65535 * q0[0]); + + pol eq2_10 = + (s[0] * y1[10] + s[0] * y1[10] - x1[0] * x1[10] - x1[0] * x1[10] - x1[0] * x1[10] + 64559 * q0[10]) + + (s[1] * y1[9] + s[1] * y1[9] - x1[1] * x1[9] - x1[1] * x1[9] - x1[1] * x1[9] + 65535 * q0[9]) + + (s[2] * y1[8] + s[2] * y1[8] - x1[2] * x1[8] - x1[2] * x1[8] - x1[2] * x1[8] + 65534 * q0[8]) + + (s[3] * y1[7] + s[3] * y1[7] - x1[3] * x1[7] - x1[3] * x1[7] - x1[3] * x1[7] + 65535 * q0[7]) + + (s[4] * y1[6] + s[4] * y1[6] - x1[4] * x1[6] - x1[4] * x1[6] - x1[4] * x1[6] + 65535 * q0[6]) + + (s[5] * y1[5] + s[5] * y1[5] - x1[5] * x1[5] - x1[5] * x1[5] - x1[5] * x1[5] + 65535 * q0[5]) + + (s[6] * y1[4] + s[6] * y1[4] - x1[6] * x1[4] - x1[6] * x1[4] - x1[6] * x1[4] + 65535 * q0[4]) + + (s[7] * y1[3] + s[7] * y1[3] - x1[7] * x1[3] - x1[7] * x1[3] - x1[7] * x1[3] + 65535 * q0[3]) + + (s[8] * y1[2] + s[8] * y1[2] - x1[8] * x1[2] - x1[8] * x1[2] - x1[8] * x1[2] + 65535 * q0[2]) + + (s[9] * y1[1] + s[9] * y1[1] - x1[9] * x1[1] - x1[9] * x1[1] - x1[9] * x1[1] + 65535 * q0[1]) + + (s[10] * y1[0] + s[10] * y1[0] - x1[10] * x1[0] - x1[10] * x1[0] - x1[10] * x1[0] + 65535 * q0[0]); + + pol eq2_11 = + (s[0] * y1[11] + s[0] * y1[11] - x1[0] * x1[11] - x1[0] * x1[11] - x1[0] * x1[11] + 64559 * q0[11]) + + (s[1] * y1[10] + s[1] * y1[10] - x1[1] * x1[10] - x1[1] * x1[10] - x1[1] * x1[10] + 65535 * q0[10]) + + (s[2] * y1[9] + s[2] * y1[9] - x1[2] * x1[9] - x1[2] * x1[9] - x1[2] * x1[9] + 65534 * q0[9]) + + (s[3] * y1[8] + s[3] * y1[8] - x1[3] * x1[8] - x1[3] * x1[8] - x1[3] * x1[8] + 65535 * q0[8]) + + (s[4] * y1[7] + s[4] * y1[7] - x1[4] * x1[7] - x1[4] * x1[7] - x1[4] * x1[7] + 65535 * q0[7]) + + (s[5] * y1[6] + s[5] * y1[6] - x1[5] * x1[6] - x1[5] * x1[6] - x1[5] * x1[6] + 65535 * q0[6]) + + (s[6] * y1[5] + s[6] * y1[5] - x1[6] * x1[5] - x1[6] * x1[5] - x1[6] * x1[5] + 65535 * q0[5]) + + (s[7] * y1[4] + s[7] * y1[4] - x1[7] * x1[4] - x1[7] * x1[4] - x1[7] * x1[4] + 65535 * q0[4]) + + (s[8] * y1[3] + s[8] * y1[3] - x1[8] * x1[3] - x1[8] * x1[3] - x1[8] * x1[3] + 65535 * q0[3]) + + (s[9] * y1[2] + s[9] * y1[2] - x1[9] * x1[2] - x1[9] * x1[2] - x1[9] * x1[2] + 65535 * q0[2]) + + (s[10] * y1[1] + s[10] * y1[1] - x1[10] * x1[1] - x1[10] * x1[1] - x1[10] * x1[1] + 65535 * q0[1]) + + (s[11] * y1[0] + s[11] * y1[0] - x1[11] * x1[0] - x1[11] * x1[0] - x1[11] * x1[0] + 65535 * q0[0]); + + pol eq2_12 = + (s[0] * y1[12] + s[0] * y1[12] - x1[0] * x1[12] - x1[0] * x1[12] - x1[0] * x1[12] + 64559 * q0[12]) + + (s[1] * y1[11] + s[1] * y1[11] - x1[1] * x1[11] - x1[1] * x1[11] - x1[1] * x1[11] + 65535 * q0[11]) + + (s[2] * y1[10] + s[2] * y1[10] - x1[2] * x1[10] - x1[2] * x1[10] - x1[2] * x1[10] + 65534 * q0[10]) + + (s[3] * y1[9] + s[3] * y1[9] - x1[3] * x1[9] - x1[3] * x1[9] - x1[3] * x1[9] + 65535 * q0[9]) + + (s[4] * y1[8] + s[4] * y1[8] - x1[4] * x1[8] - x1[4] * x1[8] - x1[4] * x1[8] + 65535 * q0[8]) + + (s[5] * y1[7] + s[5] * y1[7] - x1[5] * x1[7] - x1[5] * x1[7] - x1[5] * x1[7] + 65535 * q0[7]) + + (s[6] * y1[6] + s[6] * y1[6] - x1[6] * x1[6] - x1[6] * x1[6] - x1[6] * x1[6] + 65535 * q0[6]) + + (s[7] * y1[5] + s[7] * y1[5] - x1[7] * x1[5] - x1[7] * x1[5] - x1[7] * x1[5] + 65535 * q0[5]) + + (s[8] * y1[4] + s[8] * y1[4] - x1[8] * x1[4] - x1[8] * x1[4] - x1[8] * x1[4] + 65535 * q0[4]) + + (s[9] * y1[3] + s[9] * y1[3] - x1[9] * x1[3] - x1[9] * x1[3] - x1[9] * x1[3] + 65535 * q0[3]) + + (s[10] * y1[2] + s[10] * y1[2] - x1[10] * x1[2] - x1[10] * x1[2] - x1[10] * x1[2] + 65535 * q0[2]) + + (s[11] * y1[1] + s[11] * y1[1] - x1[11] * x1[1] - x1[11] * x1[1] - x1[11] * x1[1] + 65535 * q0[1]) + + (s[12] * y1[0] + s[12] * y1[0] - x1[12] * x1[0] - x1[12] * x1[0] - x1[12] * x1[0] + 65535 * q0[0]); + + pol eq2_13 = + (s[0] * y1[13] + s[0] * y1[13] - x1[0] * x1[13] - x1[0] * x1[13] - x1[0] * x1[13] + 64559 * q0[13]) + + (s[1] * y1[12] + s[1] * y1[12] - x1[1] * x1[12] - x1[1] * x1[12] - x1[1] * x1[12] + 65535 * q0[12]) + + (s[2] * y1[11] + s[2] * y1[11] - x1[2] * x1[11] - x1[2] * x1[11] - x1[2] * x1[11] + 65534 * q0[11]) + + (s[3] * y1[10] + s[3] * y1[10] - x1[3] * x1[10] - x1[3] * x1[10] - x1[3] * x1[10] + 65535 * q0[10]) + + (s[4] * y1[9] + s[4] * y1[9] - x1[4] * x1[9] - x1[4] * x1[9] - x1[4] * x1[9] + 65535 * q0[9]) + + (s[5] * y1[8] + s[5] * y1[8] - x1[5] * x1[8] - x1[5] * x1[8] - x1[5] * x1[8] + 65535 * q0[8]) + + (s[6] * y1[7] + s[6] * y1[7] - x1[6] * x1[7] - x1[6] * x1[7] - x1[6] * x1[7] + 65535 * q0[7]) + + (s[7] * y1[6] + s[7] * y1[6] - x1[7] * x1[6] - x1[7] * x1[6] - x1[7] * x1[6] + 65535 * q0[6]) + + (s[8] * y1[5] + s[8] * y1[5] - x1[8] * x1[5] - x1[8] * x1[5] - x1[8] * x1[5] + 65535 * q0[5]) + + (s[9] * y1[4] + s[9] * y1[4] - x1[9] * x1[4] - x1[9] * x1[4] - x1[9] * x1[4] + 65535 * q0[4]) + + (s[10] * y1[3] + s[10] * y1[3] - x1[10] * x1[3] - x1[10] * x1[3] - x1[10] * x1[3] + 65535 * q0[3]) + + (s[11] * y1[2] + s[11] * y1[2] - x1[11] * x1[2] - x1[11] * x1[2] - x1[11] * x1[2] + 65535 * q0[2]) + + (s[12] * y1[1] + s[12] * y1[1] - x1[12] * x1[1] - x1[12] * x1[1] - x1[12] * x1[1] + 65535 * q0[1]) + + (s[13] * y1[0] + s[13] * y1[0] - x1[13] * x1[0] - x1[13] * x1[0] - x1[13] * x1[0] + 65535 * q0[0]); + + pol eq2_14 = + (s[0] * y1[14] + s[0] * y1[14] - x1[0] * x1[14] - x1[0] * x1[14] - x1[0] * x1[14] + 64559 * q0[14]) + + (s[1] * y1[13] + s[1] * y1[13] - x1[1] * x1[13] - x1[1] * x1[13] - x1[1] * x1[13] + 65535 * q0[13]) + + (s[2] * y1[12] + s[2] * y1[12] - x1[2] * x1[12] - x1[2] * x1[12] - x1[2] * x1[12] + 65534 * q0[12]) + + (s[3] * y1[11] + s[3] * y1[11] - x1[3] * x1[11] - x1[3] * x1[11] - x1[3] * x1[11] + 65535 * q0[11]) + + (s[4] * y1[10] + s[4] * y1[10] - x1[4] * x1[10] - x1[4] * x1[10] - x1[4] * x1[10] + 65535 * q0[10]) + + (s[5] * y1[9] + s[5] * y1[9] - x1[5] * x1[9] - x1[5] * x1[9] - x1[5] * x1[9] + 65535 * q0[9]) + + (s[6] * y1[8] + s[6] * y1[8] - x1[6] * x1[8] - x1[6] * x1[8] - x1[6] * x1[8] + 65535 * q0[8]) + + (s[7] * y1[7] + s[7] * y1[7] - x1[7] * x1[7] - x1[7] * x1[7] - x1[7] * x1[7] + 65535 * q0[7]) + + (s[8] * y1[6] + s[8] * y1[6] - x1[8] * x1[6] - x1[8] * x1[6] - x1[8] * x1[6] + 65535 * q0[6]) + + (s[9] * y1[5] + s[9] * y1[5] - x1[9] * x1[5] - x1[9] * x1[5] - x1[9] * x1[5] + 65535 * q0[5]) + + (s[10] * y1[4] + s[10] * y1[4] - x1[10] * x1[4] - x1[10] * x1[4] - x1[10] * x1[4] + 65535 * q0[4]) + + (s[11] * y1[3] + s[11] * y1[3] - x1[11] * x1[3] - x1[11] * x1[3] - x1[11] * x1[3] + 65535 * q0[3]) + + (s[12] * y1[2] + s[12] * y1[2] - x1[12] * x1[2] - x1[12] * x1[2] - x1[12] * x1[2] + 65535 * q0[2]) + + (s[13] * y1[1] + s[13] * y1[1] - x1[13] * x1[1] - x1[13] * x1[1] - x1[13] * x1[1] + 65535 * q0[1]) + + (s[14] * y1[0] + s[14] * y1[0] - x1[14] * x1[0] - x1[14] * x1[0] - x1[14] * x1[0] + 65535 * q0[0]); + + pol eq2_15 = + (s[0] * y1[15] + s[0] * y1[15] - x1[0] * x1[15] - x1[0] * x1[15] - x1[0] * x1[15] + 64559 * q0[15]) + + (s[1] * y1[14] + s[1] * y1[14] - x1[1] * x1[14] - x1[1] * x1[14] - x1[1] * x1[14] + 65535 * q0[14]) + + (s[2] * y1[13] + s[2] * y1[13] - x1[2] * x1[13] - x1[2] * x1[13] - x1[2] * x1[13] + 65534 * q0[13]) + + (s[3] * y1[12] + s[3] * y1[12] - x1[3] * x1[12] - x1[3] * x1[12] - x1[3] * x1[12] + 65535 * q0[12]) + + (s[4] * y1[11] + s[4] * y1[11] - x1[4] * x1[11] - x1[4] * x1[11] - x1[4] * x1[11] + 65535 * q0[11]) + + (s[5] * y1[10] + s[5] * y1[10] - x1[5] * x1[10] - x1[5] * x1[10] - x1[5] * x1[10] + 65535 * q0[10]) + + (s[6] * y1[9] + s[6] * y1[9] - x1[6] * x1[9] - x1[6] * x1[9] - x1[6] * x1[9] + 65535 * q0[9]) + + (s[7] * y1[8] + s[7] * y1[8] - x1[7] * x1[8] - x1[7] * x1[8] - x1[7] * x1[8] + 65535 * q0[8]) + + (s[8] * y1[7] + s[8] * y1[7] - x1[8] * x1[7] - x1[8] * x1[7] - x1[8] * x1[7] + 65535 * q0[7]) + + (s[9] * y1[6] + s[9] * y1[6] - x1[9] * x1[6] - x1[9] * x1[6] - x1[9] * x1[6] + 65535 * q0[6]) + + (s[10] * y1[5] + s[10] * y1[5] - x1[10] * x1[5] - x1[10] * x1[5] - x1[10] * x1[5] + 65535 * q0[5]) + + (s[11] * y1[4] + s[11] * y1[4] - x1[11] * x1[4] - x1[11] * x1[4] - x1[11] * x1[4] + 65535 * q0[4]) + + (s[12] * y1[3] + s[12] * y1[3] - x1[12] * x1[3] - x1[12] * x1[3] - x1[12] * x1[3] + 65535 * q0[3]) + + (s[13] * y1[2] + s[13] * y1[2] - x1[13] * x1[2] - x1[13] * x1[2] - x1[13] * x1[2] + 65535 * q0[2]) + + (s[14] * y1[1] + s[14] * y1[1] - x1[14] * x1[1] - x1[14] * x1[1] - x1[14] * x1[1] + 65535 * q0[1]) + + (s[15] * y1[0] + s[15] * y1[0] - x1[15] * x1[0] - x1[15] * x1[0] - x1[15] * x1[0] + 65535 * q0[0]); + + pol eq2_16 = + (s[1] * y1[15] + s[1] * y1[15] - x1[1] * x1[15] - x1[1] * x1[15] - x1[1] * x1[15] + 65535 * q0[15]) + + (s[2] * y1[14] + s[2] * y1[14] - x1[2] * x1[14] - x1[2] * x1[14] - x1[2] * x1[14] + 65534 * q0[14]) + + (s[3] * y1[13] + s[3] * y1[13] - x1[3] * x1[13] - x1[3] * x1[13] - x1[3] * x1[13] + 65535 * q0[13]) + + (s[4] * y1[12] + s[4] * y1[12] - x1[4] * x1[12] - x1[4] * x1[12] - x1[4] * x1[12] + 65535 * q0[12]) + + (s[5] * y1[11] + s[5] * y1[11] - x1[5] * x1[11] - x1[5] * x1[11] - x1[5] * x1[11] + 65535 * q0[11]) + + (s[6] * y1[10] + s[6] * y1[10] - x1[6] * x1[10] - x1[6] * x1[10] - x1[6] * x1[10] + 65535 * q0[10]) + + (s[7] * y1[9] + s[7] * y1[9] - x1[7] * x1[9] - x1[7] * x1[9] - x1[7] * x1[9] + 65535 * q0[9]) + + (s[8] * y1[8] + s[8] * y1[8] - x1[8] * x1[8] - x1[8] * x1[8] - x1[8] * x1[8] + 65535 * q0[8]) + + (s[9] * y1[7] + s[9] * y1[7] - x1[9] * x1[7] - x1[9] * x1[7] - x1[9] * x1[7] + 65535 * q0[7]) + + (s[10] * y1[6] + s[10] * y1[6] - x1[10] * x1[6] - x1[10] * x1[6] - x1[10] * x1[6] + 65535 * q0[6]) + + (s[11] * y1[5] + s[11] * y1[5] - x1[11] * x1[5] - x1[11] * x1[5] - x1[11] * x1[5] + 65535 * q0[5]) + + (s[12] * y1[4] + s[12] * y1[4] - x1[12] * x1[4] - x1[12] * x1[4] - x1[12] * x1[4] + 65535 * q0[4]) + + (s[13] * y1[3] + s[13] * y1[3] - x1[13] * x1[3] - x1[13] * x1[3] - x1[13] * x1[3] + 65535 * q0[3]) + + (s[14] * y1[2] + s[14] * y1[2] - x1[14] * x1[2] - x1[14] * x1[2] - x1[14] * x1[2] + 65535 * q0[2]) + + (s[15] * y1[1] + s[15] * y1[1] - x1[15] * x1[1] - x1[15] * x1[1] - x1[15] * x1[1] + 65535 * q0[1]) + - 258236; + + pol eq2_17 = + (s[2] * y1[15] + s[2] * y1[15] - x1[2] * x1[15] - x1[2] * x1[15] - x1[2] * x1[15] + 65534 * q0[15]) + + (s[3] * y1[14] + s[3] * y1[14] - x1[3] * x1[14] - x1[3] * x1[14] - x1[3] * x1[14] + 65535 * q0[14]) + + (s[4] * y1[13] + s[4] * y1[13] - x1[4] * x1[13] - x1[4] * x1[13] - x1[4] * x1[13] + 65535 * q0[13]) + + (s[5] * y1[12] + s[5] * y1[12] - x1[5] * x1[12] - x1[5] * x1[12] - x1[5] * x1[12] + 65535 * q0[12]) + + (s[6] * y1[11] + s[6] * y1[11] - x1[6] * x1[11] - x1[6] * x1[11] - x1[6] * x1[11] + 65535 * q0[11]) + + (s[7] * y1[10] + s[7] * y1[10] - x1[7] * x1[10] - x1[7] * x1[10] - x1[7] * x1[10] + 65535 * q0[10]) + + (s[8] * y1[9] + s[8] * y1[9] - x1[8] * x1[9] - x1[8] * x1[9] - x1[8] * x1[9] + 65535 * q0[9]) + + (s[9] * y1[8] + s[9] * y1[8] - x1[9] * x1[8] - x1[9] * x1[8] - x1[9] * x1[8] + 65535 * q0[8]) + + (s[10] * y1[7] + s[10] * y1[7] - x1[10] * x1[7] - x1[10] * x1[7] - x1[10] * x1[7] + 65535 * q0[7]) + + (s[11] * y1[6] + s[11] * y1[6] - x1[11] * x1[6] - x1[11] * x1[6] - x1[11] * x1[6] + 65535 * q0[6]) + + (s[12] * y1[5] + s[12] * y1[5] - x1[12] * x1[5] - x1[12] * x1[5] - x1[12] * x1[5] + 65535 * q0[5]) + + (s[13] * y1[4] + s[13] * y1[4] - x1[13] * x1[4] - x1[13] * x1[4] - x1[13] * x1[4] + 65535 * q0[4]) + + (s[14] * y1[3] + s[14] * y1[3] - x1[14] * x1[3] - x1[14] * x1[3] - x1[14] * x1[3] + 65535 * q0[3]) + + (s[15] * y1[2] + s[15] * y1[2] - x1[15] * x1[2] - x1[15] * x1[2] - x1[15] * x1[2] + 65535 * q0[2]) + - 262140; + + pol eq2_18 = + (s[3] * y1[15] + s[3] * y1[15] - x1[3] * x1[15] - x1[3] * x1[15] - x1[3] * x1[15] + 65535 * q0[15]) + + (s[4] * y1[14] + s[4] * y1[14] - x1[4] * x1[14] - x1[4] * x1[14] - x1[4] * x1[14] + 65535 * q0[14]) + + (s[5] * y1[13] + s[5] * y1[13] - x1[5] * x1[13] - x1[5] * x1[13] - x1[5] * x1[13] + 65535 * q0[13]) + + (s[6] * y1[12] + s[6] * y1[12] - x1[6] * x1[12] - x1[6] * x1[12] - x1[6] * x1[12] + 65535 * q0[12]) + + (s[7] * y1[11] + s[7] * y1[11] - x1[7] * x1[11] - x1[7] * x1[11] - x1[7] * x1[11] + 65535 * q0[11]) + + (s[8] * y1[10] + s[8] * y1[10] - x1[8] * x1[10] - x1[8] * x1[10] - x1[8] * x1[10] + 65535 * q0[10]) + + (s[9] * y1[9] + s[9] * y1[9] - x1[9] * x1[9] - x1[9] * x1[9] - x1[9] * x1[9] + 65535 * q0[9]) + + (s[10] * y1[8] + s[10] * y1[8] - x1[10] * x1[8] - x1[10] * x1[8] - x1[10] * x1[8] + 65535 * q0[8]) + + (s[11] * y1[7] + s[11] * y1[7] - x1[11] * x1[7] - x1[11] * x1[7] - x1[11] * x1[7] + 65535 * q0[7]) + + (s[12] * y1[6] + s[12] * y1[6] - x1[12] * x1[6] - x1[12] * x1[6] - x1[12] * x1[6] + 65535 * q0[6]) + + (s[13] * y1[5] + s[13] * y1[5] - x1[13] * x1[5] - x1[13] * x1[5] - x1[13] * x1[5] + 65535 * q0[5]) + + (s[14] * y1[4] + s[14] * y1[4] - x1[14] * x1[4] - x1[14] * x1[4] - x1[14] * x1[4] + 65535 * q0[4]) + + (s[15] * y1[3] + s[15] * y1[3] - x1[15] * x1[3] - x1[15] * x1[3] - x1[15] * x1[3] + 65535 * q0[3]) + - 262136; + + pol eq2_19 = + (s[4] * y1[15] + s[4] * y1[15] - x1[4] * x1[15] - x1[4] * x1[15] - x1[4] * x1[15] + 65535 * q0[15]) + + (s[5] * y1[14] + s[5] * y1[14] - x1[5] * x1[14] - x1[5] * x1[14] - x1[5] * x1[14] + 65535 * q0[14]) + + (s[6] * y1[13] + s[6] * y1[13] - x1[6] * x1[13] - x1[6] * x1[13] - x1[6] * x1[13] + 65535 * q0[13]) + + (s[7] * y1[12] + s[7] * y1[12] - x1[7] * x1[12] - x1[7] * x1[12] - x1[7] * x1[12] + 65535 * q0[12]) + + (s[8] * y1[11] + s[8] * y1[11] - x1[8] * x1[11] - x1[8] * x1[11] - x1[8] * x1[11] + 65535 * q0[11]) + + (s[9] * y1[10] + s[9] * y1[10] - x1[9] * x1[10] - x1[9] * x1[10] - x1[9] * x1[10] + 65535 * q0[10]) + + (s[10] * y1[9] + s[10] * y1[9] - x1[10] * x1[9] - x1[10] * x1[9] - x1[10] * x1[9] + 65535 * q0[9]) + + (s[11] * y1[8] + s[11] * y1[8] - x1[11] * x1[8] - x1[11] * x1[8] - x1[11] * x1[8] + 65535 * q0[8]) + + (s[12] * y1[7] + s[12] * y1[7] - x1[12] * x1[7] - x1[12] * x1[7] - x1[12] * x1[7] + 65535 * q0[7]) + + (s[13] * y1[6] + s[13] * y1[6] - x1[13] * x1[6] - x1[13] * x1[6] - x1[13] * x1[6] + 65535 * q0[6]) + + (s[14] * y1[5] + s[14] * y1[5] - x1[14] * x1[5] - x1[14] * x1[5] - x1[14] * x1[5] + 65535 * q0[5]) + + (s[15] * y1[4] + s[15] * y1[4] - x1[15] * x1[4] - x1[15] * x1[4] - x1[15] * x1[4] + 65535 * q0[4]) + - 262140; + + pol eq2_20 = + (s[5] * y1[15] + s[5] * y1[15] - x1[5] * x1[15] - x1[5] * x1[15] - x1[5] * x1[15] + 65535 * q0[15]) + + (s[6] * y1[14] + s[6] * y1[14] - x1[6] * x1[14] - x1[6] * x1[14] - x1[6] * x1[14] + 65535 * q0[14]) + + (s[7] * y1[13] + s[7] * y1[13] - x1[7] * x1[13] - x1[7] * x1[13] - x1[7] * x1[13] + 65535 * q0[13]) + + (s[8] * y1[12] + s[8] * y1[12] - x1[8] * x1[12] - x1[8] * x1[12] - x1[8] * x1[12] + 65535 * q0[12]) + + (s[9] * y1[11] + s[9] * y1[11] - x1[9] * x1[11] - x1[9] * x1[11] - x1[9] * x1[11] + 65535 * q0[11]) + + (s[10] * y1[10] + s[10] * y1[10] - x1[10] * x1[10] - x1[10] * x1[10] - x1[10] * x1[10] + 65535 * q0[10]) + + (s[11] * y1[9] + s[11] * y1[9] - x1[11] * x1[9] - x1[11] * x1[9] - x1[11] * x1[9] + 65535 * q0[9]) + + (s[12] * y1[8] + s[12] * y1[8] - x1[12] * x1[8] - x1[12] * x1[8] - x1[12] * x1[8] + 65535 * q0[8]) + + (s[13] * y1[7] + s[13] * y1[7] - x1[13] * x1[7] - x1[13] * x1[7] - x1[13] * x1[7] + 65535 * q0[7]) + + (s[14] * y1[6] + s[14] * y1[6] - x1[14] * x1[6] - x1[14] * x1[6] - x1[14] * x1[6] + 65535 * q0[6]) + + (s[15] * y1[5] + s[15] * y1[5] - x1[15] * x1[5] - x1[15] * x1[5] - x1[15] * x1[5] + 65535 * q0[5]) + - 262140; + + pol eq2_21 = + (s[6] * y1[15] + s[6] * y1[15] - x1[6] * x1[15] - x1[6] * x1[15] - x1[6] * x1[15] + 65535 * q0[15]) + + (s[7] * y1[14] + s[7] * y1[14] - x1[7] * x1[14] - x1[7] * x1[14] - x1[7] * x1[14] + 65535 * q0[14]) + + (s[8] * y1[13] + s[8] * y1[13] - x1[8] * x1[13] - x1[8] * x1[13] - x1[8] * x1[13] + 65535 * q0[13]) + + (s[9] * y1[12] + s[9] * y1[12] - x1[9] * x1[12] - x1[9] * x1[12] - x1[9] * x1[12] + 65535 * q0[12]) + + (s[10] * y1[11] + s[10] * y1[11] - x1[10] * x1[11] - x1[10] * x1[11] - x1[10] * x1[11] + 65535 * q0[11]) + + (s[11] * y1[10] + s[11] * y1[10] - x1[11] * x1[10] - x1[11] * x1[10] - x1[11] * x1[10] + 65535 * q0[10]) + + (s[12] * y1[9] + s[12] * y1[9] - x1[12] * x1[9] - x1[12] * x1[9] - x1[12] * x1[9] + 65535 * q0[9]) + + (s[13] * y1[8] + s[13] * y1[8] - x1[13] * x1[8] - x1[13] * x1[8] - x1[13] * x1[8] + 65535 * q0[8]) + + (s[14] * y1[7] + s[14] * y1[7] - x1[14] * x1[7] - x1[14] * x1[7] - x1[14] * x1[7] + 65535 * q0[7]) + + (s[15] * y1[6] + s[15] * y1[6] - x1[15] * x1[6] - x1[15] * x1[6] - x1[15] * x1[6] + 65535 * q0[6]) + - 262140; + + pol eq2_22 = + (s[7] * y1[15] + s[7] * y1[15] - x1[7] * x1[15] - x1[7] * x1[15] - x1[7] * x1[15] + 65535 * q0[15]) + + (s[8] * y1[14] + s[8] * y1[14] - x1[8] * x1[14] - x1[8] * x1[14] - x1[8] * x1[14] + 65535 * q0[14]) + + (s[9] * y1[13] + s[9] * y1[13] - x1[9] * x1[13] - x1[9] * x1[13] - x1[9] * x1[13] + 65535 * q0[13]) + + (s[10] * y1[12] + s[10] * y1[12] - x1[10] * x1[12] - x1[10] * x1[12] - x1[10] * x1[12] + 65535 * q0[12]) + + (s[11] * y1[11] + s[11] * y1[11] - x1[11] * x1[11] - x1[11] * x1[11] - x1[11] * x1[11] + 65535 * q0[11]) + + (s[12] * y1[10] + s[12] * y1[10] - x1[12] * x1[10] - x1[12] * x1[10] - x1[12] * x1[10] + 65535 * q0[10]) + + (s[13] * y1[9] + s[13] * y1[9] - x1[13] * x1[9] - x1[13] * x1[9] - x1[13] * x1[9] + 65535 * q0[9]) + + (s[14] * y1[8] + s[14] * y1[8] - x1[14] * x1[8] - x1[14] * x1[8] - x1[14] * x1[8] + 65535 * q0[8]) + + (s[15] * y1[7] + s[15] * y1[7] - x1[15] * x1[7] - x1[15] * x1[7] - x1[15] * x1[7] + 65535 * q0[7]) + - 262140; + + pol eq2_23 = + (s[8] * y1[15] + s[8] * y1[15] - x1[8] * x1[15] - x1[8] * x1[15] - x1[8] * x1[15] + 65535 * q0[15]) + + (s[9] * y1[14] + s[9] * y1[14] - x1[9] * x1[14] - x1[9] * x1[14] - x1[9] * x1[14] + 65535 * q0[14]) + + (s[10] * y1[13] + s[10] * y1[13] - x1[10] * x1[13] - x1[10] * x1[13] - x1[10] * x1[13] + 65535 * q0[13]) + + (s[11] * y1[12] + s[11] * y1[12] - x1[11] * x1[12] - x1[11] * x1[12] - x1[11] * x1[12] + 65535 * q0[12]) + + (s[12] * y1[11] + s[12] * y1[11] - x1[12] * x1[11] - x1[12] * x1[11] - x1[12] * x1[11] + 65535 * q0[11]) + + (s[13] * y1[10] + s[13] * y1[10] - x1[13] * x1[10] - x1[13] * x1[10] - x1[13] * x1[10] + 65535 * q0[10]) + + (s[14] * y1[9] + s[14] * y1[9] - x1[14] * x1[9] - x1[14] * x1[9] - x1[14] * x1[9] + 65535 * q0[9]) + + (s[15] * y1[8] + s[15] * y1[8] - x1[15] * x1[8] - x1[15] * x1[8] - x1[15] * x1[8] + 65535 * q0[8]) + - 262140; + + pol eq2_24 = + (s[9] * y1[15] + s[9] * y1[15] - x1[9] * x1[15] - x1[9] * x1[15] - x1[9] * x1[15] + 65535 * q0[15]) + + (s[10] * y1[14] + s[10] * y1[14] - x1[10] * x1[14] - x1[10] * x1[14] - x1[10] * x1[14] + 65535 * q0[14]) + + (s[11] * y1[13] + s[11] * y1[13] - x1[11] * x1[13] - x1[11] * x1[13] - x1[11] * x1[13] + 65535 * q0[13]) + + (s[12] * y1[12] + s[12] * y1[12] - x1[12] * x1[12] - x1[12] * x1[12] - x1[12] * x1[12] + 65535 * q0[12]) + + (s[13] * y1[11] + s[13] * y1[11] - x1[13] * x1[11] - x1[13] * x1[11] - x1[13] * x1[11] + 65535 * q0[11]) + + (s[14] * y1[10] + s[14] * y1[10] - x1[14] * x1[10] - x1[14] * x1[10] - x1[14] * x1[10] + 65535 * q0[10]) + + (s[15] * y1[9] + s[15] * y1[9] - x1[15] * x1[9] - x1[15] * x1[9] - x1[15] * x1[9] + 65535 * q0[9]) + - 262140; + + pol eq2_25 = + (s[10] * y1[15] + s[10] * y1[15] - x1[10] * x1[15] - x1[10] * x1[15] - x1[10] * x1[15] + 65535 * q0[15]) + + (s[11] * y1[14] + s[11] * y1[14] - x1[11] * x1[14] - x1[11] * x1[14] - x1[11] * x1[14] + 65535 * q0[14]) + + (s[12] * y1[13] + s[12] * y1[13] - x1[12] * x1[13] - x1[12] * x1[13] - x1[12] * x1[13] + 65535 * q0[13]) + + (s[13] * y1[12] + s[13] * y1[12] - x1[13] * x1[12] - x1[13] * x1[12] - x1[13] * x1[12] + 65535 * q0[12]) + + (s[14] * y1[11] + s[14] * y1[11] - x1[14] * x1[11] - x1[14] * x1[11] - x1[14] * x1[11] + 65535 * q0[11]) + + (s[15] * y1[10] + s[15] * y1[10] - x1[15] * x1[10] - x1[15] * x1[10] - x1[15] * x1[10] + 65535 * q0[10]) + - 262140; + + pol eq2_26 = + (s[11] * y1[15] + s[11] * y1[15] - x1[11] * x1[15] - x1[11] * x1[15] - x1[11] * x1[15] + 65535 * q0[15]) + + (s[12] * y1[14] + s[12] * y1[14] - x1[12] * x1[14] - x1[12] * x1[14] - x1[12] * x1[14] + 65535 * q0[14]) + + (s[13] * y1[13] + s[13] * y1[13] - x1[13] * x1[13] - x1[13] * x1[13] - x1[13] * x1[13] + 65535 * q0[13]) + + (s[14] * y1[12] + s[14] * y1[12] - x1[14] * x1[12] - x1[14] * x1[12] - x1[14] * x1[12] + 65535 * q0[12]) + + (s[15] * y1[11] + s[15] * y1[11] - x1[15] * x1[11] - x1[15] * x1[11] - x1[15] * x1[11] + 65535 * q0[11]) + - 262140; + + pol eq2_27 = + (s[12] * y1[15] + s[12] * y1[15] - x1[12] * x1[15] - x1[12] * x1[15] - x1[12] * x1[15] + 65535 * q0[15]) + + (s[13] * y1[14] + s[13] * y1[14] - x1[13] * x1[14] - x1[13] * x1[14] - x1[13] * x1[14] + 65535 * q0[14]) + + (s[14] * y1[13] + s[14] * y1[13] - x1[14] * x1[13] - x1[14] * x1[13] - x1[14] * x1[13] + 65535 * q0[13]) + + (s[15] * y1[12] + s[15] * y1[12] - x1[15] * x1[12] - x1[15] * x1[12] - x1[15] * x1[12] + 65535 * q0[12]) + - 262140; + + pol eq2_28 = + (s[13] * y1[15] + s[13] * y1[15] - x1[13] * x1[15] - x1[13] * x1[15] - x1[13] * x1[15] + 65535 * q0[15]) + + (s[14] * y1[14] + s[14] * y1[14] - x1[14] * x1[14] - x1[14] * x1[14] - x1[14] * x1[14] + 65535 * q0[14]) + + (s[15] * y1[13] + s[15] * y1[13] - x1[15] * x1[13] - x1[15] * x1[13] - x1[15] * x1[13] + 65535 * q0[13]) + - 262140; + + pol eq2_29 = + (s[14] * y1[15] + s[14] * y1[15] - x1[14] * x1[15] - x1[14] * x1[15] - x1[14] * x1[15] + 65535 * q0[15]) + + (s[15] * y1[14] + s[15] * y1[14] - x1[15] * x1[14] - x1[15] * x1[14] - x1[15] * x1[14] + 65535 * q0[14]) + - 262140; + + pol eq2_30 = + (s[15] * y1[15] + s[15] * y1[15] - x1[15] * x1[15] - x1[15] * x1[15] - x1[15] * x1[15] + 65535 * q0[15]) + - 262140; + + pol eq2_31 = - 262140; + + + /******* + * + * EQ3: s * s - x1 - x2 - x3 - p * (q1 - offset) = 0 + * + *******/ + + pol eq3_0 = + (s[0] * s[0] - 64559 * q1[0]) + + 258236 - x1[0] - x2[0] - x3[0]; + + pol eq3_1 = + (s[0] * s[1] - 64559 * q1[1]) + + (s[1] * s[0] - 65535 * q1[0]) + + 262140 - x1[1] - x2[1] - x3[1]; + + pol eq3_2 = + (s[0] * s[2] - 64559 * q1[2]) + + (s[1] * s[1] - 65535 * q1[1]) + + (s[2] * s[0] - 65534 * q1[0]) + + 262136 - x1[2] - x2[2] - x3[2]; + + pol eq3_3 = + (s[0] * s[3] - 64559 * q1[3]) + + (s[1] * s[2] - 65535 * q1[2]) + + (s[2] * s[1] - 65534 * q1[1]) + + (s[3] * s[0] - 65535 * q1[0]) + + 262140 - x1[3] - x2[3] - x3[3]; + + pol eq3_4 = + (s[0] * s[4] - 64559 * q1[4]) + + (s[1] * s[3] - 65535 * q1[3]) + + (s[2] * s[2] - 65534 * q1[2]) + + (s[3] * s[1] - 65535 * q1[1]) + + (s[4] * s[0] - 65535 * q1[0]) + + 262140 - x1[4] - x2[4] - x3[4]; + + pol eq3_5 = + (s[0] * s[5] - 64559 * q1[5]) + + (s[1] * s[4] - 65535 * q1[4]) + + (s[2] * s[3] - 65534 * q1[3]) + + (s[3] * s[2] - 65535 * q1[2]) + + (s[4] * s[1] - 65535 * q1[1]) + + (s[5] * s[0] - 65535 * q1[0]) + + 262140 - x1[5] - x2[5] - x3[5]; + + pol eq3_6 = + (s[0] * s[6] - 64559 * q1[6]) + + (s[1] * s[5] - 65535 * q1[5]) + + (s[2] * s[4] - 65534 * q1[4]) + + (s[3] * s[3] - 65535 * q1[3]) + + (s[4] * s[2] - 65535 * q1[2]) + + (s[5] * s[1] - 65535 * q1[1]) + + (s[6] * s[0] - 65535 * q1[0]) + + 262140 - x1[6] - x2[6] - x3[6]; + + pol eq3_7 = + (s[0] * s[7] - 64559 * q1[7]) + + (s[1] * s[6] - 65535 * q1[6]) + + (s[2] * s[5] - 65534 * q1[5]) + + (s[3] * s[4] - 65535 * q1[4]) + + (s[4] * s[3] - 65535 * q1[3]) + + (s[5] * s[2] - 65535 * q1[2]) + + (s[6] * s[1] - 65535 * q1[1]) + + (s[7] * s[0] - 65535 * q1[0]) + + 262140 - x1[7] - x2[7] - x3[7]; + + pol eq3_8 = + (s[0] * s[8] - 64559 * q1[8]) + + (s[1] * s[7] - 65535 * q1[7]) + + (s[2] * s[6] - 65534 * q1[6]) + + (s[3] * s[5] - 65535 * q1[5]) + + (s[4] * s[4] - 65535 * q1[4]) + + (s[5] * s[3] - 65535 * q1[3]) + + (s[6] * s[2] - 65535 * q1[2]) + + (s[7] * s[1] - 65535 * q1[1]) + + (s[8] * s[0] - 65535 * q1[0]) + + 262140 - x1[8] - x2[8] - x3[8]; + + pol eq3_9 = + (s[0] * s[9] - 64559 * q1[9]) + + (s[1] * s[8] - 65535 * q1[8]) + + (s[2] * s[7] - 65534 * q1[7]) + + (s[3] * s[6] - 65535 * q1[6]) + + (s[4] * s[5] - 65535 * q1[5]) + + (s[5] * s[4] - 65535 * q1[4]) + + (s[6] * s[3] - 65535 * q1[3]) + + (s[7] * s[2] - 65535 * q1[2]) + + (s[8] * s[1] - 65535 * q1[1]) + + (s[9] * s[0] - 65535 * q1[0]) + + 262140 - x1[9] - x2[9] - x3[9]; + + pol eq3_10 = + (s[0] * s[10] - 64559 * q1[10]) + + (s[1] * s[9] - 65535 * q1[9]) + + (s[2] * s[8] - 65534 * q1[8]) + + (s[3] * s[7] - 65535 * q1[7]) + + (s[4] * s[6] - 65535 * q1[6]) + + (s[5] * s[5] - 65535 * q1[5]) + + (s[6] * s[4] - 65535 * q1[4]) + + (s[7] * s[3] - 65535 * q1[3]) + + (s[8] * s[2] - 65535 * q1[2]) + + (s[9] * s[1] - 65535 * q1[1]) + + (s[10] * s[0] - 65535 * q1[0]) + + 262140 - x1[10] - x2[10] - x3[10]; + + pol eq3_11 = + (s[0] * s[11] - 64559 * q1[11]) + + (s[1] * s[10] - 65535 * q1[10]) + + (s[2] * s[9] - 65534 * q1[9]) + + (s[3] * s[8] - 65535 * q1[8]) + + (s[4] * s[7] - 65535 * q1[7]) + + (s[5] * s[6] - 65535 * q1[6]) + + (s[6] * s[5] - 65535 * q1[5]) + + (s[7] * s[4] - 65535 * q1[4]) + + (s[8] * s[3] - 65535 * q1[3]) + + (s[9] * s[2] - 65535 * q1[2]) + + (s[10] * s[1] - 65535 * q1[1]) + + (s[11] * s[0] - 65535 * q1[0]) + + 262140 - x1[11] - x2[11] - x3[11]; + + pol eq3_12 = + (s[0] * s[12] - 64559 * q1[12]) + + (s[1] * s[11] - 65535 * q1[11]) + + (s[2] * s[10] - 65534 * q1[10]) + + (s[3] * s[9] - 65535 * q1[9]) + + (s[4] * s[8] - 65535 * q1[8]) + + (s[5] * s[7] - 65535 * q1[7]) + + (s[6] * s[6] - 65535 * q1[6]) + + (s[7] * s[5] - 65535 * q1[5]) + + (s[8] * s[4] - 65535 * q1[4]) + + (s[9] * s[3] - 65535 * q1[3]) + + (s[10] * s[2] - 65535 * q1[2]) + + (s[11] * s[1] - 65535 * q1[1]) + + (s[12] * s[0] - 65535 * q1[0]) + + 262140 - x1[12] - x2[12] - x3[12]; + + pol eq3_13 = + (s[0] * s[13] - 64559 * q1[13]) + + (s[1] * s[12] - 65535 * q1[12]) + + (s[2] * s[11] - 65534 * q1[11]) + + (s[3] * s[10] - 65535 * q1[10]) + + (s[4] * s[9] - 65535 * q1[9]) + + (s[5] * s[8] - 65535 * q1[8]) + + (s[6] * s[7] - 65535 * q1[7]) + + (s[7] * s[6] - 65535 * q1[6]) + + (s[8] * s[5] - 65535 * q1[5]) + + (s[9] * s[4] - 65535 * q1[4]) + + (s[10] * s[3] - 65535 * q1[3]) + + (s[11] * s[2] - 65535 * q1[2]) + + (s[12] * s[1] - 65535 * q1[1]) + + (s[13] * s[0] - 65535 * q1[0]) + + 262140 - x1[13] - x2[13] - x3[13]; + + pol eq3_14 = + (s[0] * s[14] - 64559 * q1[14]) + + (s[1] * s[13] - 65535 * q1[13]) + + (s[2] * s[12] - 65534 * q1[12]) + + (s[3] * s[11] - 65535 * q1[11]) + + (s[4] * s[10] - 65535 * q1[10]) + + (s[5] * s[9] - 65535 * q1[9]) + + (s[6] * s[8] - 65535 * q1[8]) + + (s[7] * s[7] - 65535 * q1[7]) + + (s[8] * s[6] - 65535 * q1[6]) + + (s[9] * s[5] - 65535 * q1[5]) + + (s[10] * s[4] - 65535 * q1[4]) + + (s[11] * s[3] - 65535 * q1[3]) + + (s[12] * s[2] - 65535 * q1[2]) + + (s[13] * s[1] - 65535 * q1[1]) + + (s[14] * s[0] - 65535 * q1[0]) + + 262140 - x1[14] - x2[14] - x3[14]; + + pol eq3_15 = + (s[0] * s[15] - 64559 * q1[15]) + + (s[1] * s[14] - 65535 * q1[14]) + + (s[2] * s[13] - 65534 * q1[13]) + + (s[3] * s[12] - 65535 * q1[12]) + + (s[4] * s[11] - 65535 * q1[11]) + + (s[5] * s[10] - 65535 * q1[10]) + + (s[6] * s[9] - 65535 * q1[9]) + + (s[7] * s[8] - 65535 * q1[8]) + + (s[8] * s[7] - 65535 * q1[7]) + + (s[9] * s[6] - 65535 * q1[6]) + + (s[10] * s[5] - 65535 * q1[5]) + + (s[11] * s[4] - 65535 * q1[4]) + + (s[12] * s[3] - 65535 * q1[3]) + + (s[13] * s[2] - 65535 * q1[2]) + + (s[14] * s[1] - 65535 * q1[1]) + + (s[15] * s[0] - 65535 * q1[0]) + + 262140 - x1[15] - x2[15] - x3[15]; + + pol eq3_16 = + (s[1] * s[15] - 65535 * q1[15]) + + (s[2] * s[14] - 65534 * q1[14]) + + (s[3] * s[13] - 65535 * q1[13]) + + (s[4] * s[12] - 65535 * q1[12]) + + (s[5] * s[11] - 65535 * q1[11]) + + (s[6] * s[10] - 65535 * q1[10]) + + (s[7] * s[9] - 65535 * q1[9]) + + (s[8] * s[8] - 65535 * q1[8]) + + (s[9] * s[7] - 65535 * q1[7]) + + (s[10] * s[6] - 65535 * q1[6]) + + (s[11] * s[5] - 65535 * q1[5]) + + (s[12] * s[4] - 65535 * q1[4]) + + (s[13] * s[3] - 65535 * q1[3]) + + (s[14] * s[2] - 65535 * q1[2]) + + (s[15] * s[1] - 65535 * q1[1]); + + pol eq3_17 = + (s[2] * s[15] - 65534 * q1[15]) + + (s[3] * s[14] - 65535 * q1[14]) + + (s[4] * s[13] - 65535 * q1[13]) + + (s[5] * s[12] - 65535 * q1[12]) + + (s[6] * s[11] - 65535 * q1[11]) + + (s[7] * s[10] - 65535 * q1[10]) + + (s[8] * s[9] - 65535 * q1[9]) + + (s[9] * s[8] - 65535 * q1[8]) + + (s[10] * s[7] - 65535 * q1[7]) + + (s[11] * s[6] - 65535 * q1[6]) + + (s[12] * s[5] - 65535 * q1[5]) + + (s[13] * s[4] - 65535 * q1[4]) + + (s[14] * s[3] - 65535 * q1[3]) + + (s[15] * s[2] - 65535 * q1[2]); + + pol eq3_18 = + (s[3] * s[15] - 65535 * q1[15]) + + (s[4] * s[14] - 65535 * q1[14]) + + (s[5] * s[13] - 65535 * q1[13]) + + (s[6] * s[12] - 65535 * q1[12]) + + (s[7] * s[11] - 65535 * q1[11]) + + (s[8] * s[10] - 65535 * q1[10]) + + (s[9] * s[9] - 65535 * q1[9]) + + (s[10] * s[8] - 65535 * q1[8]) + + (s[11] * s[7] - 65535 * q1[7]) + + (s[12] * s[6] - 65535 * q1[6]) + + (s[13] * s[5] - 65535 * q1[5]) + + (s[14] * s[4] - 65535 * q1[4]) + + (s[15] * s[3] - 65535 * q1[3]); + + pol eq3_19 = + (s[4] * s[15] - 65535 * q1[15]) + + (s[5] * s[14] - 65535 * q1[14]) + + (s[6] * s[13] - 65535 * q1[13]) + + (s[7] * s[12] - 65535 * q1[12]) + + (s[8] * s[11] - 65535 * q1[11]) + + (s[9] * s[10] - 65535 * q1[10]) + + (s[10] * s[9] - 65535 * q1[9]) + + (s[11] * s[8] - 65535 * q1[8]) + + (s[12] * s[7] - 65535 * q1[7]) + + (s[13] * s[6] - 65535 * q1[6]) + + (s[14] * s[5] - 65535 * q1[5]) + + (s[15] * s[4] - 65535 * q1[4]); + + pol eq3_20 = + (s[5] * s[15] - 65535 * q1[15]) + + (s[6] * s[14] - 65535 * q1[14]) + + (s[7] * s[13] - 65535 * q1[13]) + + (s[8] * s[12] - 65535 * q1[12]) + + (s[9] * s[11] - 65535 * q1[11]) + + (s[10] * s[10] - 65535 * q1[10]) + + (s[11] * s[9] - 65535 * q1[9]) + + (s[12] * s[8] - 65535 * q1[8]) + + (s[13] * s[7] - 65535 * q1[7]) + + (s[14] * s[6] - 65535 * q1[6]) + + (s[15] * s[5] - 65535 * q1[5]); + + pol eq3_21 = + (s[6] * s[15] - 65535 * q1[15]) + + (s[7] * s[14] - 65535 * q1[14]) + + (s[8] * s[13] - 65535 * q1[13]) + + (s[9] * s[12] - 65535 * q1[12]) + + (s[10] * s[11] - 65535 * q1[11]) + + (s[11] * s[10] - 65535 * q1[10]) + + (s[12] * s[9] - 65535 * q1[9]) + + (s[13] * s[8] - 65535 * q1[8]) + + (s[14] * s[7] - 65535 * q1[7]) + + (s[15] * s[6] - 65535 * q1[6]); + + pol eq3_22 = + (s[7] * s[15] - 65535 * q1[15]) + + (s[8] * s[14] - 65535 * q1[14]) + + (s[9] * s[13] - 65535 * q1[13]) + + (s[10] * s[12] - 65535 * q1[12]) + + (s[11] * s[11] - 65535 * q1[11]) + + (s[12] * s[10] - 65535 * q1[10]) + + (s[13] * s[9] - 65535 * q1[9]) + + (s[14] * s[8] - 65535 * q1[8]) + + (s[15] * s[7] - 65535 * q1[7]); + + pol eq3_23 = + (s[8] * s[15] - 65535 * q1[15]) + + (s[9] * s[14] - 65535 * q1[14]) + + (s[10] * s[13] - 65535 * q1[13]) + + (s[11] * s[12] - 65535 * q1[12]) + + (s[12] * s[11] - 65535 * q1[11]) + + (s[13] * s[10] - 65535 * q1[10]) + + (s[14] * s[9] - 65535 * q1[9]) + + (s[15] * s[8] - 65535 * q1[8]); + + pol eq3_24 = + (s[9] * s[15] - 65535 * q1[15]) + + (s[10] * s[14] - 65535 * q1[14]) + + (s[11] * s[13] - 65535 * q1[13]) + + (s[12] * s[12] - 65535 * q1[12]) + + (s[13] * s[11] - 65535 * q1[11]) + + (s[14] * s[10] - 65535 * q1[10]) + + (s[15] * s[9] - 65535 * q1[9]); + + pol eq3_25 = + (s[10] * s[15] - 65535 * q1[15]) + + (s[11] * s[14] - 65535 * q1[14]) + + (s[12] * s[13] - 65535 * q1[13]) + + (s[13] * s[12] - 65535 * q1[12]) + + (s[14] * s[11] - 65535 * q1[11]) + + (s[15] * s[10] - 65535 * q1[10]); + + pol eq3_26 = + (s[11] * s[15] - 65535 * q1[15]) + + (s[12] * s[14] - 65535 * q1[14]) + + (s[13] * s[13] - 65535 * q1[13]) + + (s[14] * s[12] - 65535 * q1[12]) + + (s[15] * s[11] - 65535 * q1[11]); + + pol eq3_27 = + (s[12] * s[15] - 65535 * q1[15]) + + (s[13] * s[14] - 65535 * q1[14]) + + (s[14] * s[13] - 65535 * q1[13]) + + (s[15] * s[12] - 65535 * q1[12]); + + pol eq3_28 = + (s[13] * s[15] - 65535 * q1[15]) + + (s[14] * s[14] - 65535 * q1[14]) + + (s[15] * s[13] - 65535 * q1[13]); + + pol eq3_29 = + (s[14] * s[15] - 65535 * q1[15]) + + (s[15] * s[14] - 65535 * q1[14]); + + pol eq3_30 = + (s[15] * s[15] - 65535 * q1[15]); + + pol eq3_31 = + 0; + + + /******* + * + * EQ4: s * x1 - s * x3 - y1 - y3 + p * (q2 - offset) = 0 + * + *******/ + + pol eq4_0 = + (s[0] * x1[0] - s[0] * x3[0] + 64559 * q2[0]) + - y1[0] - y3[0]; + + pol eq4_1 = + (s[0] * x1[1] - s[0] * x3[1] + 64559 * q2[1]) + + (s[1] * x1[0] - s[1] * x3[0] + 65535 * q2[0]) + - y1[1] - y3[1]; + + pol eq4_2 = + (s[0] * x1[2] - s[0] * x3[2] + 64559 * q2[2]) + + (s[1] * x1[1] - s[1] * x3[1] + 65535 * q2[1]) + + (s[2] * x1[0] - s[2] * x3[0] + 65534 * q2[0]) + - y1[2] - y3[2]; + + pol eq4_3 = + (s[0] * x1[3] - s[0] * x3[3] + 64559 * q2[3]) + + (s[1] * x1[2] - s[1] * x3[2] + 65535 * q2[2]) + + (s[2] * x1[1] - s[2] * x3[1] + 65534 * q2[1]) + + (s[3] * x1[0] - s[3] * x3[0] + 65535 * q2[0]) + - y1[3] - y3[3]; + + pol eq4_4 = + (s[0] * x1[4] - s[0] * x3[4] + 64559 * q2[4]) + + (s[1] * x1[3] - s[1] * x3[3] + 65535 * q2[3]) + + (s[2] * x1[2] - s[2] * x3[2] + 65534 * q2[2]) + + (s[3] * x1[1] - s[3] * x3[1] + 65535 * q2[1]) + + (s[4] * x1[0] - s[4] * x3[0] + 65535 * q2[0]) + - y1[4] - y3[4]; + + pol eq4_5 = + (s[0] * x1[5] - s[0] * x3[5] + 64559 * q2[5]) + + (s[1] * x1[4] - s[1] * x3[4] + 65535 * q2[4]) + + (s[2] * x1[3] - s[2] * x3[3] + 65534 * q2[3]) + + (s[3] * x1[2] - s[3] * x3[2] + 65535 * q2[2]) + + (s[4] * x1[1] - s[4] * x3[1] + 65535 * q2[1]) + + (s[5] * x1[0] - s[5] * x3[0] + 65535 * q2[0]) + - y1[5] - y3[5]; + + pol eq4_6 = + (s[0] * x1[6] - s[0] * x3[6] + 64559 * q2[6]) + + (s[1] * x1[5] - s[1] * x3[5] + 65535 * q2[5]) + + (s[2] * x1[4] - s[2] * x3[4] + 65534 * q2[4]) + + (s[3] * x1[3] - s[3] * x3[3] + 65535 * q2[3]) + + (s[4] * x1[2] - s[4] * x3[2] + 65535 * q2[2]) + + (s[5] * x1[1] - s[5] * x3[1] + 65535 * q2[1]) + + (s[6] * x1[0] - s[6] * x3[0] + 65535 * q2[0]) + - y1[6] - y3[6]; + + pol eq4_7 = + (s[0] * x1[7] - s[0] * x3[7] + 64559 * q2[7]) + + (s[1] * x1[6] - s[1] * x3[6] + 65535 * q2[6]) + + (s[2] * x1[5] - s[2] * x3[5] + 65534 * q2[5]) + + (s[3] * x1[4] - s[3] * x3[4] + 65535 * q2[4]) + + (s[4] * x1[3] - s[4] * x3[3] + 65535 * q2[3]) + + (s[5] * x1[2] - s[5] * x3[2] + 65535 * q2[2]) + + (s[6] * x1[1] - s[6] * x3[1] + 65535 * q2[1]) + + (s[7] * x1[0] - s[7] * x3[0] + 65535 * q2[0]) + - y1[7] - y3[7]; + + pol eq4_8 = + (s[0] * x1[8] - s[0] * x3[8] + 64559 * q2[8]) + + (s[1] * x1[7] - s[1] * x3[7] + 65535 * q2[7]) + + (s[2] * x1[6] - s[2] * x3[6] + 65534 * q2[6]) + + (s[3] * x1[5] - s[3] * x3[5] + 65535 * q2[5]) + + (s[4] * x1[4] - s[4] * x3[4] + 65535 * q2[4]) + + (s[5] * x1[3] - s[5] * x3[3] + 65535 * q2[3]) + + (s[6] * x1[2] - s[6] * x3[2] + 65535 * q2[2]) + + (s[7] * x1[1] - s[7] * x3[1] + 65535 * q2[1]) + + (s[8] * x1[0] - s[8] * x3[0] + 65535 * q2[0]) + - y1[8] - y3[8]; + + pol eq4_9 = + (s[0] * x1[9] - s[0] * x3[9] + 64559 * q2[9]) + + (s[1] * x1[8] - s[1] * x3[8] + 65535 * q2[8]) + + (s[2] * x1[7] - s[2] * x3[7] + 65534 * q2[7]) + + (s[3] * x1[6] - s[3] * x3[6] + 65535 * q2[6]) + + (s[4] * x1[5] - s[4] * x3[5] + 65535 * q2[5]) + + (s[5] * x1[4] - s[5] * x3[4] + 65535 * q2[4]) + + (s[6] * x1[3] - s[6] * x3[3] + 65535 * q2[3]) + + (s[7] * x1[2] - s[7] * x3[2] + 65535 * q2[2]) + + (s[8] * x1[1] - s[8] * x3[1] + 65535 * q2[1]) + + (s[9] * x1[0] - s[9] * x3[0] + 65535 * q2[0]) + - y1[9] - y3[9]; + + pol eq4_10 = + (s[0] * x1[10] - s[0] * x3[10] + 64559 * q2[10]) + + (s[1] * x1[9] - s[1] * x3[9] + 65535 * q2[9]) + + (s[2] * x1[8] - s[2] * x3[8] + 65534 * q2[8]) + + (s[3] * x1[7] - s[3] * x3[7] + 65535 * q2[7]) + + (s[4] * x1[6] - s[4] * x3[6] + 65535 * q2[6]) + + (s[5] * x1[5] - s[5] * x3[5] + 65535 * q2[5]) + + (s[6] * x1[4] - s[6] * x3[4] + 65535 * q2[4]) + + (s[7] * x1[3] - s[7] * x3[3] + 65535 * q2[3]) + + (s[8] * x1[2] - s[8] * x3[2] + 65535 * q2[2]) + + (s[9] * x1[1] - s[9] * x3[1] + 65535 * q2[1]) + + (s[10] * x1[0] - s[10] * x3[0] + 65535 * q2[0]) + - y1[10] - y3[10]; + + pol eq4_11 = + (s[0] * x1[11] - s[0] * x3[11] + 64559 * q2[11]) + + (s[1] * x1[10] - s[1] * x3[10] + 65535 * q2[10]) + + (s[2] * x1[9] - s[2] * x3[9] + 65534 * q2[9]) + + (s[3] * x1[8] - s[3] * x3[8] + 65535 * q2[8]) + + (s[4] * x1[7] - s[4] * x3[7] + 65535 * q2[7]) + + (s[5] * x1[6] - s[5] * x3[6] + 65535 * q2[6]) + + (s[6] * x1[5] - s[6] * x3[5] + 65535 * q2[5]) + + (s[7] * x1[4] - s[7] * x3[4] + 65535 * q2[4]) + + (s[8] * x1[3] - s[8] * x3[3] + 65535 * q2[3]) + + (s[9] * x1[2] - s[9] * x3[2] + 65535 * q2[2]) + + (s[10] * x1[1] - s[10] * x3[1] + 65535 * q2[1]) + + (s[11] * x1[0] - s[11] * x3[0] + 65535 * q2[0]) + - y1[11] - y3[11]; + + pol eq4_12 = + (s[0] * x1[12] - s[0] * x3[12] + 64559 * q2[12]) + + (s[1] * x1[11] - s[1] * x3[11] + 65535 * q2[11]) + + (s[2] * x1[10] - s[2] * x3[10] + 65534 * q2[10]) + + (s[3] * x1[9] - s[3] * x3[9] + 65535 * q2[9]) + + (s[4] * x1[8] - s[4] * x3[8] + 65535 * q2[8]) + + (s[5] * x1[7] - s[5] * x3[7] + 65535 * q2[7]) + + (s[6] * x1[6] - s[6] * x3[6] + 65535 * q2[6]) + + (s[7] * x1[5] - s[7] * x3[5] + 65535 * q2[5]) + + (s[8] * x1[4] - s[8] * x3[4] + 65535 * q2[4]) + + (s[9] * x1[3] - s[9] * x3[3] + 65535 * q2[3]) + + (s[10] * x1[2] - s[10] * x3[2] + 65535 * q2[2]) + + (s[11] * x1[1] - s[11] * x3[1] + 65535 * q2[1]) + + (s[12] * x1[0] - s[12] * x3[0] + 65535 * q2[0]) + - y1[12] - y3[12]; + + pol eq4_13 = + (s[0] * x1[13] - s[0] * x3[13] + 64559 * q2[13]) + + (s[1] * x1[12] - s[1] * x3[12] + 65535 * q2[12]) + + (s[2] * x1[11] - s[2] * x3[11] + 65534 * q2[11]) + + (s[3] * x1[10] - s[3] * x3[10] + 65535 * q2[10]) + + (s[4] * x1[9] - s[4] * x3[9] + 65535 * q2[9]) + + (s[5] * x1[8] - s[5] * x3[8] + 65535 * q2[8]) + + (s[6] * x1[7] - s[6] * x3[7] + 65535 * q2[7]) + + (s[7] * x1[6] - s[7] * x3[6] + 65535 * q2[6]) + + (s[8] * x1[5] - s[8] * x3[5] + 65535 * q2[5]) + + (s[9] * x1[4] - s[9] * x3[4] + 65535 * q2[4]) + + (s[10] * x1[3] - s[10] * x3[3] + 65535 * q2[3]) + + (s[11] * x1[2] - s[11] * x3[2] + 65535 * q2[2]) + + (s[12] * x1[1] - s[12] * x3[1] + 65535 * q2[1]) + + (s[13] * x1[0] - s[13] * x3[0] + 65535 * q2[0]) + - y1[13] - y3[13]; + + pol eq4_14 = + (s[0] * x1[14] - s[0] * x3[14] + 64559 * q2[14]) + + (s[1] * x1[13] - s[1] * x3[13] + 65535 * q2[13]) + + (s[2] * x1[12] - s[2] * x3[12] + 65534 * q2[12]) + + (s[3] * x1[11] - s[3] * x3[11] + 65535 * q2[11]) + + (s[4] * x1[10] - s[4] * x3[10] + 65535 * q2[10]) + + (s[5] * x1[9] - s[5] * x3[9] + 65535 * q2[9]) + + (s[6] * x1[8] - s[6] * x3[8] + 65535 * q2[8]) + + (s[7] * x1[7] - s[7] * x3[7] + 65535 * q2[7]) + + (s[8] * x1[6] - s[8] * x3[6] + 65535 * q2[6]) + + (s[9] * x1[5] - s[9] * x3[5] + 65535 * q2[5]) + + (s[10] * x1[4] - s[10] * x3[4] + 65535 * q2[4]) + + (s[11] * x1[3] - s[11] * x3[3] + 65535 * q2[3]) + + (s[12] * x1[2] - s[12] * x3[2] + 65535 * q2[2]) + + (s[13] * x1[1] - s[13] * x3[1] + 65535 * q2[1]) + + (s[14] * x1[0] - s[14] * x3[0] + 65535 * q2[0]) + - y1[14] - y3[14]; + + pol eq4_15 = + (s[0] * x1[15] - s[0] * x3[15] + 64559 * q2[15]) + + (s[1] * x1[14] - s[1] * x3[14] + 65535 * q2[14]) + + (s[2] * x1[13] - s[2] * x3[13] + 65534 * q2[13]) + + (s[3] * x1[12] - s[3] * x3[12] + 65535 * q2[12]) + + (s[4] * x1[11] - s[4] * x3[11] + 65535 * q2[11]) + + (s[5] * x1[10] - s[5] * x3[10] + 65535 * q2[10]) + + (s[6] * x1[9] - s[6] * x3[9] + 65535 * q2[9]) + + (s[7] * x1[8] - s[7] * x3[8] + 65535 * q2[8]) + + (s[8] * x1[7] - s[8] * x3[7] + 65535 * q2[7]) + + (s[9] * x1[6] - s[9] * x3[6] + 65535 * q2[6]) + + (s[10] * x1[5] - s[10] * x3[5] + 65535 * q2[5]) + + (s[11] * x1[4] - s[11] * x3[4] + 65535 * q2[4]) + + (s[12] * x1[3] - s[12] * x3[3] + 65535 * q2[3]) + + (s[13] * x1[2] - s[13] * x3[2] + 65535 * q2[2]) + + (s[14] * x1[1] - s[14] * x3[1] + 65535 * q2[1]) + + (s[15] * x1[0] - s[15] * x3[0] + 65535 * q2[0]) + - y1[15] - y3[15]; + + pol eq4_16 = + (s[1] * x1[15] - s[1] * x3[15] + 65535 * q2[15]) + + (s[2] * x1[14] - s[2] * x3[14] + 65534 * q2[14]) + + (s[3] * x1[13] - s[3] * x3[13] + 65535 * q2[13]) + + (s[4] * x1[12] - s[4] * x3[12] + 65535 * q2[12]) + + (s[5] * x1[11] - s[5] * x3[11] + 65535 * q2[11]) + + (s[6] * x1[10] - s[6] * x3[10] + 65535 * q2[10]) + + (s[7] * x1[9] - s[7] * x3[9] + 65535 * q2[9]) + + (s[8] * x1[8] - s[8] * x3[8] + 65535 * q2[8]) + + (s[9] * x1[7] - s[9] * x3[7] + 65535 * q2[7]) + + (s[10] * x1[6] - s[10] * x3[6] + 65535 * q2[6]) + + (s[11] * x1[5] - s[11] * x3[5] + 65535 * q2[5]) + + (s[12] * x1[4] - s[12] * x3[4] + 65535 * q2[4]) + + (s[13] * x1[3] - s[13] * x3[3] + 65535 * q2[3]) + + (s[14] * x1[2] - s[14] * x3[2] + 65535 * q2[2]) + + (s[15] * x1[1] - s[15] * x3[1] + 65535 * q2[1]) + - 129118; + + pol eq4_17 = + (s[2] * x1[15] - s[2] * x3[15] + 65534 * q2[15]) + + (s[3] * x1[14] - s[3] * x3[14] + 65535 * q2[14]) + + (s[4] * x1[13] - s[4] * x3[13] + 65535 * q2[13]) + + (s[5] * x1[12] - s[5] * x3[12] + 65535 * q2[12]) + + (s[6] * x1[11] - s[6] * x3[11] + 65535 * q2[11]) + + (s[7] * x1[10] - s[7] * x3[10] + 65535 * q2[10]) + + (s[8] * x1[9] - s[8] * x3[9] + 65535 * q2[9]) + + (s[9] * x1[8] - s[9] * x3[8] + 65535 * q2[8]) + + (s[10] * x1[7] - s[10] * x3[7] + 65535 * q2[7]) + + (s[11] * x1[6] - s[11] * x3[6] + 65535 * q2[6]) + + (s[12] * x1[5] - s[12] * x3[5] + 65535 * q2[5]) + + (s[13] * x1[4] - s[13] * x3[4] + 65535 * q2[4]) + + (s[14] * x1[3] - s[14] * x3[3] + 65535 * q2[3]) + + (s[15] * x1[2] - s[15] * x3[2] + 65535 * q2[2]) + - 131070; + + pol eq4_18 = + (s[3] * x1[15] - s[3] * x3[15] + 65535 * q2[15]) + + (s[4] * x1[14] - s[4] * x3[14] + 65535 * q2[14]) + + (s[5] * x1[13] - s[5] * x3[13] + 65535 * q2[13]) + + (s[6] * x1[12] - s[6] * x3[12] + 65535 * q2[12]) + + (s[7] * x1[11] - s[7] * x3[11] + 65535 * q2[11]) + + (s[8] * x1[10] - s[8] * x3[10] + 65535 * q2[10]) + + (s[9] * x1[9] - s[9] * x3[9] + 65535 * q2[9]) + + (s[10] * x1[8] - s[10] * x3[8] + 65535 * q2[8]) + + (s[11] * x1[7] - s[11] * x3[7] + 65535 * q2[7]) + + (s[12] * x1[6] - s[12] * x3[6] + 65535 * q2[6]) + + (s[13] * x1[5] - s[13] * x3[5] + 65535 * q2[5]) + + (s[14] * x1[4] - s[14] * x3[4] + 65535 * q2[4]) + + (s[15] * x1[3] - s[15] * x3[3] + 65535 * q2[3]) + - 131068; + + pol eq4_19 = + (s[4] * x1[15] - s[4] * x3[15] + 65535 * q2[15]) + + (s[5] * x1[14] - s[5] * x3[14] + 65535 * q2[14]) + + (s[6] * x1[13] - s[6] * x3[13] + 65535 * q2[13]) + + (s[7] * x1[12] - s[7] * x3[12] + 65535 * q2[12]) + + (s[8] * x1[11] - s[8] * x3[11] + 65535 * q2[11]) + + (s[9] * x1[10] - s[9] * x3[10] + 65535 * q2[10]) + + (s[10] * x1[9] - s[10] * x3[9] + 65535 * q2[9]) + + (s[11] * x1[8] - s[11] * x3[8] + 65535 * q2[8]) + + (s[12] * x1[7] - s[12] * x3[7] + 65535 * q2[7]) + + (s[13] * x1[6] - s[13] * x3[6] + 65535 * q2[6]) + + (s[14] * x1[5] - s[14] * x3[5] + 65535 * q2[5]) + + (s[15] * x1[4] - s[15] * x3[4] + 65535 * q2[4]) + - 131070; + + pol eq4_20 = + (s[5] * x1[15] - s[5] * x3[15] + 65535 * q2[15]) + + (s[6] * x1[14] - s[6] * x3[14] + 65535 * q2[14]) + + (s[7] * x1[13] - s[7] * x3[13] + 65535 * q2[13]) + + (s[8] * x1[12] - s[8] * x3[12] + 65535 * q2[12]) + + (s[9] * x1[11] - s[9] * x3[11] + 65535 * q2[11]) + + (s[10] * x1[10] - s[10] * x3[10] + 65535 * q2[10]) + + (s[11] * x1[9] - s[11] * x3[9] + 65535 * q2[9]) + + (s[12] * x1[8] - s[12] * x3[8] + 65535 * q2[8]) + + (s[13] * x1[7] - s[13] * x3[7] + 65535 * q2[7]) + + (s[14] * x1[6] - s[14] * x3[6] + 65535 * q2[6]) + + (s[15] * x1[5] - s[15] * x3[5] + 65535 * q2[5]) + - 131070; + + pol eq4_21 = + (s[6] * x1[15] - s[6] * x3[15] + 65535 * q2[15]) + + (s[7] * x1[14] - s[7] * x3[14] + 65535 * q2[14]) + + (s[8] * x1[13] - s[8] * x3[13] + 65535 * q2[13]) + + (s[9] * x1[12] - s[9] * x3[12] + 65535 * q2[12]) + + (s[10] * x1[11] - s[10] * x3[11] + 65535 * q2[11]) + + (s[11] * x1[10] - s[11] * x3[10] + 65535 * q2[10]) + + (s[12] * x1[9] - s[12] * x3[9] + 65535 * q2[9]) + + (s[13] * x1[8] - s[13] * x3[8] + 65535 * q2[8]) + + (s[14] * x1[7] - s[14] * x3[7] + 65535 * q2[7]) + + (s[15] * x1[6] - s[15] * x3[6] + 65535 * q2[6]) + - 131070; + + pol eq4_22 = + (s[7] * x1[15] - s[7] * x3[15] + 65535 * q2[15]) + + (s[8] * x1[14] - s[8] * x3[14] + 65535 * q2[14]) + + (s[9] * x1[13] - s[9] * x3[13] + 65535 * q2[13]) + + (s[10] * x1[12] - s[10] * x3[12] + 65535 * q2[12]) + + (s[11] * x1[11] - s[11] * x3[11] + 65535 * q2[11]) + + (s[12] * x1[10] - s[12] * x3[10] + 65535 * q2[10]) + + (s[13] * x1[9] - s[13] * x3[9] + 65535 * q2[9]) + + (s[14] * x1[8] - s[14] * x3[8] + 65535 * q2[8]) + + (s[15] * x1[7] - s[15] * x3[7] + 65535 * q2[7]) + - 131070; + + pol eq4_23 = + (s[8] * x1[15] - s[8] * x3[15] + 65535 * q2[15]) + + (s[9] * x1[14] - s[9] * x3[14] + 65535 * q2[14]) + + (s[10] * x1[13] - s[10] * x3[13] + 65535 * q2[13]) + + (s[11] * x1[12] - s[11] * x3[12] + 65535 * q2[12]) + + (s[12] * x1[11] - s[12] * x3[11] + 65535 * q2[11]) + + (s[13] * x1[10] - s[13] * x3[10] + 65535 * q2[10]) + + (s[14] * x1[9] - s[14] * x3[9] + 65535 * q2[9]) + + (s[15] * x1[8] - s[15] * x3[8] + 65535 * q2[8]) + - 131070; + + pol eq4_24 = + (s[9] * x1[15] - s[9] * x3[15] + 65535 * q2[15]) + + (s[10] * x1[14] - s[10] * x3[14] + 65535 * q2[14]) + + (s[11] * x1[13] - s[11] * x3[13] + 65535 * q2[13]) + + (s[12] * x1[12] - s[12] * x3[12] + 65535 * q2[12]) + + (s[13] * x1[11] - s[13] * x3[11] + 65535 * q2[11]) + + (s[14] * x1[10] - s[14] * x3[10] + 65535 * q2[10]) + + (s[15] * x1[9] - s[15] * x3[9] + 65535 * q2[9]) + - 131070; + + pol eq4_25 = + (s[10] * x1[15] - s[10] * x3[15] + 65535 * q2[15]) + + (s[11] * x1[14] - s[11] * x3[14] + 65535 * q2[14]) + + (s[12] * x1[13] - s[12] * x3[13] + 65535 * q2[13]) + + (s[13] * x1[12] - s[13] * x3[12] + 65535 * q2[12]) + + (s[14] * x1[11] - s[14] * x3[11] + 65535 * q2[11]) + + (s[15] * x1[10] - s[15] * x3[10] + 65535 * q2[10]) + - 131070; + + pol eq4_26 = + (s[11] * x1[15] - s[11] * x3[15] + 65535 * q2[15]) + + (s[12] * x1[14] - s[12] * x3[14] + 65535 * q2[14]) + + (s[13] * x1[13] - s[13] * x3[13] + 65535 * q2[13]) + + (s[14] * x1[12] - s[14] * x3[12] + 65535 * q2[12]) + + (s[15] * x1[11] - s[15] * x3[11] + 65535 * q2[11]) + - 131070; + + pol eq4_27 = + (s[12] * x1[15] - s[12] * x3[15] + 65535 * q2[15]) + + (s[13] * x1[14] - s[13] * x3[14] + 65535 * q2[14]) + + (s[14] * x1[13] - s[14] * x3[13] + 65535 * q2[13]) + + (s[15] * x1[12] - s[15] * x3[12] + 65535 * q2[12]) + - 131070; + + pol eq4_28 = + (s[13] * x1[15] - s[13] * x3[15] + 65535 * q2[15]) + + (s[14] * x1[14] - s[14] * x3[14] + 65535 * q2[14]) + + (s[15] * x1[13] - s[15] * x3[13] + 65535 * q2[13]) + - 131070; + + pol eq4_29 = + (s[14] * x1[15] - s[14] * x3[15] + 65535 * q2[15]) + + (s[15] * x1[14] - s[15] * x3[14] + 65535 * q2[14]) + - 131070; + + pol eq4_30 = + (s[15] * x1[15] - s[15] * x3[15] + 65535 * q2[15]) + - 131070; + + pol eq4_31 = - 131070; + + + /******* + * + * EQ5: x1 * x2 - y1 * y2 - x3 + p * (q1 - offset) = 0 + * + *******/ + + pol eq5_0 = + (x1[0] * x2[0] - y1[0] * y2[0] + 64839 * q1[0]) + - x3[0]; + + pol eq5_1 = + (x1[0] * x2[1] - y1[0] * y2[1] + 64839 * q1[1]) + + (x1[1] * x2[0] - y1[1] * y2[0] + 55420 * q1[0]) + - x3[1]; + + pol eq5_2 = + (x1[0] * x2[2] - y1[0] * y2[2] + 64839 * q1[2]) + + (x1[1] * x2[1] - y1[1] * y2[1] + 55420 * q1[1]) + + (x1[2] * x2[0] - y1[2] * y2[0] + 35862 * q1[0]) + - x3[2]; + + pol eq5_3 = + (x1[0] * x2[3] - y1[0] * y2[3] + 64839 * q1[3]) + + (x1[1] * x2[2] - y1[1] * y2[2] + 55420 * q1[2]) + + (x1[2] * x2[1] - y1[2] * y2[1] + 35862 * q1[1]) + + (x1[3] * x2[0] - y1[3] * y2[0] + 15392 * q1[0]) + - x3[3]; + + pol eq5_4 = + (x1[0] * x2[4] - y1[0] * y2[4] + 64839 * q1[4]) + + (x1[1] * x2[3] - y1[1] * y2[3] + 55420 * q1[3]) + + (x1[2] * x2[2] - y1[2] * y2[2] + 35862 * q1[2]) + + (x1[3] * x2[1] - y1[3] * y2[1] + 15392 * q1[1]) + + (x1[4] * x2[0] - y1[4] * y2[0] + 51853 * q1[0]) + - x3[4]; + + pol eq5_5 = + (x1[0] * x2[5] - y1[0] * y2[5] + 64839 * q1[5]) + + (x1[1] * x2[4] - y1[1] * y2[4] + 55420 * q1[4]) + + (x1[2] * x2[3] - y1[2] * y2[3] + 35862 * q1[3]) + + (x1[3] * x2[2] - y1[3] * y2[2] + 15392 * q1[2]) + + (x1[4] * x2[1] - y1[4] * y2[1] + 51853 * q1[1]) + + (x1[5] * x2[0] - y1[5] * y2[0] + 26737 * q1[0]) + - x3[5]; + + pol eq5_6 = + (x1[0] * x2[6] - y1[0] * y2[6] + 64839 * q1[6]) + + (x1[1] * x2[5] - y1[1] * y2[5] + 55420 * q1[5]) + + (x1[2] * x2[4] - y1[2] * y2[4] + 35862 * q1[4]) + + (x1[3] * x2[3] - y1[3] * y2[3] + 15392 * q1[3]) + + (x1[4] * x2[2] - y1[4] * y2[2] + 51853 * q1[2]) + + (x1[5] * x2[1] - y1[5] * y2[1] + 26737 * q1[1]) + + (x1[6] * x2[0] - y1[6] * y2[0] + 27281 * q1[0]) + - x3[6]; + + pol eq5_7 = + (x1[0] * x2[7] - y1[0] * y2[7] + 64839 * q1[7]) + + (x1[1] * x2[6] - y1[1] * y2[6] + 55420 * q1[6]) + + (x1[2] * x2[5] - y1[2] * y2[5] + 35862 * q1[5]) + + (x1[3] * x2[4] - y1[3] * y2[4] + 15392 * q1[4]) + + (x1[4] * x2[3] - y1[4] * y2[3] + 51853 * q1[3]) + + (x1[5] * x2[2] - y1[5] * y2[2] + 26737 * q1[2]) + + (x1[6] * x2[1] - y1[6] * y2[1] + 27281 * q1[1]) + + (x1[7] * x2[0] - y1[7] * y2[0] + 38785 * q1[0]) + - x3[7]; + + pol eq5_8 = + (x1[0] * x2[8] - y1[0] * y2[8] + 64839 * q1[8]) + + (x1[1] * x2[7] - y1[1] * y2[7] + 55420 * q1[7]) + + (x1[2] * x2[6] - y1[2] * y2[6] + 35862 * q1[6]) + + (x1[3] * x2[5] - y1[3] * y2[5] + 15392 * q1[5]) + + (x1[4] * x2[4] - y1[4] * y2[4] + 51853 * q1[4]) + + (x1[5] * x2[3] - y1[5] * y2[3] + 26737 * q1[3]) + + (x1[6] * x2[2] - y1[6] * y2[2] + 27281 * q1[2]) + + (x1[7] * x2[1] - y1[7] * y2[1] + 38785 * q1[1]) + + (x1[8] * x2[0] - y1[8] * y2[0] + 22621 * q1[0]) + - x3[8]; + + pol eq5_9 = + (x1[0] * x2[9] - y1[0] * y2[9] + 64839 * q1[9]) + + (x1[1] * x2[8] - y1[1] * y2[8] + 55420 * q1[8]) + + (x1[2] * x2[7] - y1[2] * y2[7] + 35862 * q1[7]) + + (x1[3] * x2[6] - y1[3] * y2[6] + 15392 * q1[6]) + + (x1[4] * x2[5] - y1[4] * y2[5] + 51853 * q1[5]) + + (x1[5] * x2[4] - y1[5] * y2[4] + 26737 * q1[4]) + + (x1[6] * x2[3] - y1[6] * y2[3] + 27281 * q1[3]) + + (x1[7] * x2[2] - y1[7] * y2[2] + 38785 * q1[2]) + + (x1[8] * x2[1] - y1[8] * y2[1] + 22621 * q1[1]) + + (x1[9] * x2[0] - y1[9] * y2[0] + 33153 * q1[0]) + - x3[9]; + + pol eq5_10 = + (x1[0] * x2[10] - y1[0] * y2[10] + 64839 * q1[10]) + + (x1[1] * x2[9] - y1[1] * y2[9] + 55420 * q1[9]) + + (x1[2] * x2[8] - y1[2] * y2[8] + 35862 * q1[8]) + + (x1[3] * x2[7] - y1[3] * y2[7] + 15392 * q1[7]) + + (x1[4] * x2[6] - y1[4] * y2[6] + 51853 * q1[6]) + + (x1[5] * x2[5] - y1[5] * y2[5] + 26737 * q1[5]) + + (x1[6] * x2[4] - y1[6] * y2[4] + 27281 * q1[4]) + + (x1[7] * x2[3] - y1[7] * y2[3] + 38785 * q1[3]) + + (x1[8] * x2[2] - y1[8] * y2[2] + 22621 * q1[2]) + + (x1[9] * x2[1] - y1[9] * y2[1] + 33153 * q1[1]) + + (x1[10] * x2[0] - y1[10] * y2[0] + 17846 * q1[0]) + - x3[10]; + + pol eq5_11 = + (x1[0] * x2[11] - y1[0] * y2[11] + 64839 * q1[11]) + + (x1[1] * x2[10] - y1[1] * y2[10] + 55420 * q1[10]) + + (x1[2] * x2[9] - y1[2] * y2[9] + 35862 * q1[9]) + + (x1[3] * x2[8] - y1[3] * y2[8] + 15392 * q1[8]) + + (x1[4] * x2[7] - y1[4] * y2[7] + 51853 * q1[7]) + + (x1[5] * x2[6] - y1[5] * y2[6] + 26737 * q1[6]) + + (x1[6] * x2[5] - y1[6] * y2[5] + 27281 * q1[5]) + + (x1[7] * x2[4] - y1[7] * y2[4] + 38785 * q1[4]) + + (x1[8] * x2[3] - y1[8] * y2[3] + 22621 * q1[3]) + + (x1[9] * x2[2] - y1[9] * y2[2] + 33153 * q1[2]) + + (x1[10] * x2[1] - y1[10] * y2[1] + 17846 * q1[1]) + + (x1[11] * x2[0] - y1[11] * y2[0] + 47184 * q1[0]) + - x3[11]; + + pol eq5_12 = + (x1[0] * x2[12] - y1[0] * y2[12] + 64839 * q1[12]) + + (x1[1] * x2[11] - y1[1] * y2[11] + 55420 * q1[11]) + + (x1[2] * x2[10] - y1[2] * y2[10] + 35862 * q1[10]) + + (x1[3] * x2[9] - y1[3] * y2[9] + 15392 * q1[9]) + + (x1[4] * x2[8] - y1[4] * y2[8] + 51853 * q1[8]) + + (x1[5] * x2[7] - y1[5] * y2[7] + 26737 * q1[7]) + + (x1[6] * x2[6] - y1[6] * y2[6] + 27281 * q1[6]) + + (x1[7] * x2[5] - y1[7] * y2[5] + 38785 * q1[5]) + + (x1[8] * x2[4] - y1[8] * y2[4] + 22621 * q1[4]) + + (x1[9] * x2[3] - y1[9] * y2[3] + 33153 * q1[3]) + + (x1[10] * x2[2] - y1[10] * y2[2] + 17846 * q1[2]) + + (x1[11] * x2[1] - y1[11] * y2[1] + 47184 * q1[1]) + + (x1[12] * x2[0] - y1[12] * y2[0] + 41001 * q1[0]) + - x3[12]; + + pol eq5_13 = + (x1[0] * x2[13] - y1[0] * y2[13] + 64839 * q1[13]) + + (x1[1] * x2[12] - y1[1] * y2[12] + 55420 * q1[12]) + + (x1[2] * x2[11] - y1[2] * y2[11] + 35862 * q1[11]) + + (x1[3] * x2[10] - y1[3] * y2[10] + 15392 * q1[10]) + + (x1[4] * x2[9] - y1[4] * y2[9] + 51853 * q1[9]) + + (x1[5] * x2[8] - y1[5] * y2[8] + 26737 * q1[8]) + + (x1[6] * x2[7] - y1[6] * y2[7] + 27281 * q1[7]) + + (x1[7] * x2[6] - y1[7] * y2[6] + 38785 * q1[6]) + + (x1[8] * x2[5] - y1[8] * y2[5] + 22621 * q1[5]) + + (x1[9] * x2[4] - y1[9] * y2[4] + 33153 * q1[4]) + + (x1[10] * x2[3] - y1[10] * y2[3] + 17846 * q1[3]) + + (x1[11] * x2[2] - y1[11] * y2[2] + 47184 * q1[2]) + + (x1[12] * x2[1] - y1[12] * y2[1] + 41001 * q1[1]) + + (x1[13] * x2[0] - y1[13] * y2[0] + 57649 * q1[0]) + - x3[13]; + + pol eq5_14 = + (x1[0] * x2[14] - y1[0] * y2[14] + 64839 * q1[14]) + + (x1[1] * x2[13] - y1[1] * y2[13] + 55420 * q1[13]) + + (x1[2] * x2[12] - y1[2] * y2[12] + 35862 * q1[12]) + + (x1[3] * x2[11] - y1[3] * y2[11] + 15392 * q1[11]) + + (x1[4] * x2[10] - y1[4] * y2[10] + 51853 * q1[10]) + + (x1[5] * x2[9] - y1[5] * y2[9] + 26737 * q1[9]) + + (x1[6] * x2[8] - y1[6] * y2[8] + 27281 * q1[8]) + + (x1[7] * x2[7] - y1[7] * y2[7] + 38785 * q1[7]) + + (x1[8] * x2[6] - y1[8] * y2[6] + 22621 * q1[6]) + + (x1[9] * x2[5] - y1[9] * y2[5] + 33153 * q1[5]) + + (x1[10] * x2[4] - y1[10] * y2[4] + 17846 * q1[4]) + + (x1[11] * x2[3] - y1[11] * y2[3] + 47184 * q1[3]) + + (x1[12] * x2[2] - y1[12] * y2[2] + 41001 * q1[2]) + + (x1[13] * x2[1] - y1[13] * y2[1] + 57649 * q1[1]) + + (x1[14] * x2[0] - y1[14] * y2[0] + 20082 * q1[0]) + - x3[14]; + + pol eq5_15 = + (x1[0] * x2[15] - y1[0] * y2[15] + 64839 * q1[15]) + + (x1[1] * x2[14] - y1[1] * y2[14] + 55420 * q1[14]) + + (x1[2] * x2[13] - y1[2] * y2[13] + 35862 * q1[13]) + + (x1[3] * x2[12] - y1[3] * y2[12] + 15392 * q1[12]) + + (x1[4] * x2[11] - y1[4] * y2[11] + 51853 * q1[11]) + + (x1[5] * x2[10] - y1[5] * y2[10] + 26737 * q1[10]) + + (x1[6] * x2[9] - y1[6] * y2[9] + 27281 * q1[9]) + + (x1[7] * x2[8] - y1[7] * y2[8] + 38785 * q1[8]) + + (x1[8] * x2[7] - y1[8] * y2[7] + 22621 * q1[7]) + + (x1[9] * x2[6] - y1[9] * y2[6] + 33153 * q1[6]) + + (x1[10] * x2[5] - y1[10] * y2[5] + 17846 * q1[5]) + + (x1[11] * x2[4] - y1[11] * y2[4] + 47184 * q1[4]) + + (x1[12] * x2[3] - y1[12] * y2[3] + 41001 * q1[3]) + + (x1[13] * x2[2] - y1[13] * y2[2] + 57649 * q1[2]) + + (x1[14] * x2[1] - y1[14] * y2[1] + 20082 * q1[1]) + + (x1[15] * x2[0] - y1[15] * y2[0] + 12388 * q1[0]) + - x3[15]; + + pol eq5_16 = + (x1[1] * x2[15] - y1[1] * y2[15] + 55420 * q1[15]) + + (x1[2] * x2[14] - y1[2] * y2[14] + 35862 * q1[14]) + + (x1[3] * x2[13] - y1[3] * y2[13] + 15392 * q1[13]) + + (x1[4] * x2[12] - y1[4] * y2[12] + 51853 * q1[12]) + + (x1[5] * x2[11] - y1[5] * y2[11] + 26737 * q1[11]) + + (x1[6] * x2[10] - y1[6] * y2[10] + 27281 * q1[10]) + + (x1[7] * x2[9] - y1[7] * y2[9] + 38785 * q1[9]) + + (x1[8] * x2[8] - y1[8] * y2[8] + 22621 * q1[8]) + + (x1[9] * x2[7] - y1[9] * y2[7] + 33153 * q1[7]) + + (x1[10] * x2[6] - y1[10] * y2[6] + 17846 * q1[6]) + + (x1[11] * x2[5] - y1[11] * y2[5] + 47184 * q1[5]) + + (x1[12] * x2[4] - y1[12] * y2[4] + 41001 * q1[4]) + + (x1[13] * x2[3] - y1[13] * y2[3] + 57649 * q1[3]) + + (x1[14] * x2[2] - y1[14] * y2[2] + 20082 * q1[2]) + + (x1[15] * x2[1] - y1[15] * y2[1] + 12388 * q1[1]) + - 518712; + + pol eq5_17 = + (x1[2] * x2[15] - y1[2] * y2[15] + 35862 * q1[15]) + + (x1[3] * x2[14] - y1[3] * y2[14] + 15392 * q1[14]) + + (x1[4] * x2[13] - y1[4] * y2[13] + 51853 * q1[13]) + + (x1[5] * x2[12] - y1[5] * y2[12] + 26737 * q1[12]) + + (x1[6] * x2[11] - y1[6] * y2[11] + 27281 * q1[11]) + + (x1[7] * x2[10] - y1[7] * y2[10] + 38785 * q1[10]) + + (x1[8] * x2[9] - y1[8] * y2[9] + 22621 * q1[9]) + + (x1[9] * x2[8] - y1[9] * y2[8] + 33153 * q1[8]) + + (x1[10] * x2[7] - y1[10] * y2[7] + 17846 * q1[7]) + + (x1[11] * x2[6] - y1[11] * y2[6] + 47184 * q1[6]) + + (x1[12] * x2[5] - y1[12] * y2[5] + 41001 * q1[5]) + + (x1[13] * x2[4] - y1[13] * y2[4] + 57649 * q1[4]) + + (x1[14] * x2[3] - y1[14] * y2[3] + 20082 * q1[3]) + + (x1[15] * x2[2] - y1[15] * y2[2] + 12388 * q1[2]) + - 443360; + + pol eq5_18 = + (x1[3] * x2[15] - y1[3] * y2[15] + 15392 * q1[15]) + + (x1[4] * x2[14] - y1[4] * y2[14] + 51853 * q1[14]) + + (x1[5] * x2[13] - y1[5] * y2[13] + 26737 * q1[13]) + + (x1[6] * x2[12] - y1[6] * y2[12] + 27281 * q1[12]) + + (x1[7] * x2[11] - y1[7] * y2[11] + 38785 * q1[11]) + + (x1[8] * x2[10] - y1[8] * y2[10] + 22621 * q1[10]) + + (x1[9] * x2[9] - y1[9] * y2[9] + 33153 * q1[9]) + + (x1[10] * x2[8] - y1[10] * y2[8] + 17846 * q1[8]) + + (x1[11] * x2[7] - y1[11] * y2[7] + 47184 * q1[7]) + + (x1[12] * x2[6] - y1[12] * y2[6] + 41001 * q1[6]) + + (x1[13] * x2[5] - y1[13] * y2[5] + 57649 * q1[5]) + + (x1[14] * x2[4] - y1[14] * y2[4] + 20082 * q1[4]) + + (x1[15] * x2[3] - y1[15] * y2[3] + 12388 * q1[3]) + - 286896; + + pol eq5_19 = + (x1[4] * x2[15] - y1[4] * y2[15] + 51853 * q1[15]) + + (x1[5] * x2[14] - y1[5] * y2[14] + 26737 * q1[14]) + + (x1[6] * x2[13] - y1[6] * y2[13] + 27281 * q1[13]) + + (x1[7] * x2[12] - y1[7] * y2[12] + 38785 * q1[12]) + + (x1[8] * x2[11] - y1[8] * y2[11] + 22621 * q1[11]) + + (x1[9] * x2[10] - y1[9] * y2[10] + 33153 * q1[10]) + + (x1[10] * x2[9] - y1[10] * y2[9] + 17846 * q1[9]) + + (x1[11] * x2[8] - y1[11] * y2[8] + 47184 * q1[8]) + + (x1[12] * x2[7] - y1[12] * y2[7] + 41001 * q1[7]) + + (x1[13] * x2[6] - y1[13] * y2[6] + 57649 * q1[6]) + + (x1[14] * x2[5] - y1[14] * y2[5] + 20082 * q1[5]) + + (x1[15] * x2[4] - y1[15] * y2[4] + 12388 * q1[4]) + - 123136; + + pol eq5_20 = + (x1[5] * x2[15] - y1[5] * y2[15] + 26737 * q1[15]) + + (x1[6] * x2[14] - y1[6] * y2[14] + 27281 * q1[14]) + + (x1[7] * x2[13] - y1[7] * y2[13] + 38785 * q1[13]) + + (x1[8] * x2[12] - y1[8] * y2[12] + 22621 * q1[12]) + + (x1[9] * x2[11] - y1[9] * y2[11] + 33153 * q1[11]) + + (x1[10] * x2[10] - y1[10] * y2[10] + 17846 * q1[10]) + + (x1[11] * x2[9] - y1[11] * y2[9] + 47184 * q1[9]) + + (x1[12] * x2[8] - y1[12] * y2[8] + 41001 * q1[8]) + + (x1[13] * x2[7] - y1[13] * y2[7] + 57649 * q1[7]) + + (x1[14] * x2[6] - y1[14] * y2[6] + 20082 * q1[6]) + + (x1[15] * x2[5] - y1[15] * y2[5] + 12388 * q1[5]) + - 414824; + + pol eq5_21 = + (x1[6] * x2[15] - y1[6] * y2[15] + 27281 * q1[15]) + + (x1[7] * x2[14] - y1[7] * y2[14] + 38785 * q1[14]) + + (x1[8] * x2[13] - y1[8] * y2[13] + 22621 * q1[13]) + + (x1[9] * x2[12] - y1[9] * y2[12] + 33153 * q1[12]) + + (x1[10] * x2[11] - y1[10] * y2[11] + 17846 * q1[11]) + + (x1[11] * x2[10] - y1[11] * y2[10] + 47184 * q1[10]) + + (x1[12] * x2[9] - y1[12] * y2[9] + 41001 * q1[9]) + + (x1[13] * x2[8] - y1[13] * y2[8] + 57649 * q1[8]) + + (x1[14] * x2[7] - y1[14] * y2[7] + 20082 * q1[7]) + + (x1[15] * x2[6] - y1[15] * y2[6] + 12388 * q1[6]) + - 213896; + + pol eq5_22 = + (x1[7] * x2[15] - y1[7] * y2[15] + 38785 * q1[15]) + + (x1[8] * x2[14] - y1[8] * y2[14] + 22621 * q1[14]) + + (x1[9] * x2[13] - y1[9] * y2[13] + 33153 * q1[13]) + + (x1[10] * x2[12] - y1[10] * y2[12] + 17846 * q1[12]) + + (x1[11] * x2[11] - y1[11] * y2[11] + 47184 * q1[11]) + + (x1[12] * x2[10] - y1[12] * y2[10] + 41001 * q1[10]) + + (x1[13] * x2[9] - y1[13] * y2[9] + 57649 * q1[9]) + + (x1[14] * x2[8] - y1[14] * y2[8] + 20082 * q1[8]) + + (x1[15] * x2[7] - y1[15] * y2[7] + 12388 * q1[7]) + - 218248; + + pol eq5_23 = + (x1[8] * x2[15] - y1[8] * y2[15] + 22621 * q1[15]) + + (x1[9] * x2[14] - y1[9] * y2[14] + 33153 * q1[14]) + + (x1[10] * x2[13] - y1[10] * y2[13] + 17846 * q1[13]) + + (x1[11] * x2[12] - y1[11] * y2[12] + 47184 * q1[12]) + + (x1[12] * x2[11] - y1[12] * y2[11] + 41001 * q1[11]) + + (x1[13] * x2[10] - y1[13] * y2[10] + 57649 * q1[10]) + + (x1[14] * x2[9] - y1[14] * y2[9] + 20082 * q1[9]) + + (x1[15] * x2[8] - y1[15] * y2[8] + 12388 * q1[8]) + - 310280; + + pol eq5_24 = + (x1[9] * x2[15] - y1[9] * y2[15] + 33153 * q1[15]) + + (x1[10] * x2[14] - y1[10] * y2[14] + 17846 * q1[14]) + + (x1[11] * x2[13] - y1[11] * y2[13] + 47184 * q1[13]) + + (x1[12] * x2[12] - y1[12] * y2[12] + 41001 * q1[12]) + + (x1[13] * x2[11] - y1[13] * y2[11] + 57649 * q1[11]) + + (x1[14] * x2[10] - y1[14] * y2[10] + 20082 * q1[10]) + + (x1[15] * x2[9] - y1[15] * y2[9] + 12388 * q1[9]) + - 180968; + + pol eq5_25 = + (x1[10] * x2[15] - y1[10] * y2[15] + 17846 * q1[15]) + + (x1[11] * x2[14] - y1[11] * y2[14] + 47184 * q1[14]) + + (x1[12] * x2[13] - y1[12] * y2[13] + 41001 * q1[13]) + + (x1[13] * x2[12] - y1[13] * y2[12] + 57649 * q1[12]) + + (x1[14] * x2[11] - y1[14] * y2[11] + 20082 * q1[11]) + + (x1[15] * x2[10] - y1[15] * y2[10] + 12388 * q1[10]) + - 265224; + + pol eq5_26 = + (x1[11] * x2[15] - y1[11] * y2[15] + 47184 * q1[15]) + + (x1[12] * x2[14] - y1[12] * y2[14] + 41001 * q1[14]) + + (x1[13] * x2[13] - y1[13] * y2[13] + 57649 * q1[13]) + + (x1[14] * x2[12] - y1[14] * y2[12] + 20082 * q1[12]) + + (x1[15] * x2[11] - y1[15] * y2[11] + 12388 * q1[11]) + - 142768; + + pol eq5_27 = + (x1[12] * x2[15] - y1[12] * y2[15] + 41001 * q1[15]) + + (x1[13] * x2[14] - y1[13] * y2[14] + 57649 * q1[14]) + + (x1[14] * x2[13] - y1[14] * y2[13] + 20082 * q1[13]) + + (x1[15] * x2[12] - y1[15] * y2[12] + 12388 * q1[12]) + - 377472; + + pol eq5_28 = + (x1[13] * x2[15] - y1[13] * y2[15] + 57649 * q1[15]) + + (x1[14] * x2[14] - y1[14] * y2[14] + 20082 * q1[14]) + + (x1[15] * x2[13] - y1[15] * y2[13] + 12388 * q1[13]) + - 328008; + + pol eq5_29 = + (x1[14] * x2[15] - y1[14] * y2[15] + 20082 * q1[15]) + + (x1[15] * x2[14] - y1[15] * y2[14] + 12388 * q1[14]) + - 461192; + + pol eq5_30 = + (x1[15] * x2[15] - y1[15] * y2[15] + 12388 * q1[15]) + - 160656; + + pol eq5_31 = - 99104; + + + /******* + * + * EQ6: y1 * x2 + x1 * y2 - y3 - p * (q2 - offset) = 0 + * + *******/ + + pol eq6_0 = + (y1[0] * x2[0] + x1[0] * y2[0] - 64839 * q2[0]) + + 518712 - y3[0]; + + pol eq6_1 = + (y1[0] * x2[1] + x1[0] * y2[1] - 64839 * q2[1]) + + (y1[1] * x2[0] + x1[1] * y2[0] - 55420 * q2[0]) + + 443360 - y3[1]; + + pol eq6_2 = + (y1[0] * x2[2] + x1[0] * y2[2] - 64839 * q2[2]) + + (y1[1] * x2[1] + x1[1] * y2[1] - 55420 * q2[1]) + + (y1[2] * x2[0] + x1[2] * y2[0] - 35862 * q2[0]) + + 286896 - y3[2]; + + pol eq6_3 = + (y1[0] * x2[3] + x1[0] * y2[3] - 64839 * q2[3]) + + (y1[1] * x2[2] + x1[1] * y2[2] - 55420 * q2[2]) + + (y1[2] * x2[1] + x1[2] * y2[1] - 35862 * q2[1]) + + (y1[3] * x2[0] + x1[3] * y2[0] - 15392 * q2[0]) + + 123136 - y3[3]; + + pol eq6_4 = + (y1[0] * x2[4] + x1[0] * y2[4] - 64839 * q2[4]) + + (y1[1] * x2[3] + x1[1] * y2[3] - 55420 * q2[3]) + + (y1[2] * x2[2] + x1[2] * y2[2] - 35862 * q2[2]) + + (y1[3] * x2[1] + x1[3] * y2[1] - 15392 * q2[1]) + + (y1[4] * x2[0] + x1[4] * y2[0] - 51853 * q2[0]) + + 414824 - y3[4]; + + pol eq6_5 = + (y1[0] * x2[5] + x1[0] * y2[5] - 64839 * q2[5]) + + (y1[1] * x2[4] + x1[1] * y2[4] - 55420 * q2[4]) + + (y1[2] * x2[3] + x1[2] * y2[3] - 35862 * q2[3]) + + (y1[3] * x2[2] + x1[3] * y2[2] - 15392 * q2[2]) + + (y1[4] * x2[1] + x1[4] * y2[1] - 51853 * q2[1]) + + (y1[5] * x2[0] + x1[5] * y2[0] - 26737 * q2[0]) + + 213896 - y3[5]; + + pol eq6_6 = + (y1[0] * x2[6] + x1[0] * y2[6] - 64839 * q2[6]) + + (y1[1] * x2[5] + x1[1] * y2[5] - 55420 * q2[5]) + + (y1[2] * x2[4] + x1[2] * y2[4] - 35862 * q2[4]) + + (y1[3] * x2[3] + x1[3] * y2[3] - 15392 * q2[3]) + + (y1[4] * x2[2] + x1[4] * y2[2] - 51853 * q2[2]) + + (y1[5] * x2[1] + x1[5] * y2[1] - 26737 * q2[1]) + + (y1[6] * x2[0] + x1[6] * y2[0] - 27281 * q2[0]) + + 218248 - y3[6]; + + pol eq6_7 = + (y1[0] * x2[7] + x1[0] * y2[7] - 64839 * q2[7]) + + (y1[1] * x2[6] + x1[1] * y2[6] - 55420 * q2[6]) + + (y1[2] * x2[5] + x1[2] * y2[5] - 35862 * q2[5]) + + (y1[3] * x2[4] + x1[3] * y2[4] - 15392 * q2[4]) + + (y1[4] * x2[3] + x1[4] * y2[3] - 51853 * q2[3]) + + (y1[5] * x2[2] + x1[5] * y2[2] - 26737 * q2[2]) + + (y1[6] * x2[1] + x1[6] * y2[1] - 27281 * q2[1]) + + (y1[7] * x2[0] + x1[7] * y2[0] - 38785 * q2[0]) + + 310280 - y3[7]; + + pol eq6_8 = + (y1[0] * x2[8] + x1[0] * y2[8] - 64839 * q2[8]) + + (y1[1] * x2[7] + x1[1] * y2[7] - 55420 * q2[7]) + + (y1[2] * x2[6] + x1[2] * y2[6] - 35862 * q2[6]) + + (y1[3] * x2[5] + x1[3] * y2[5] - 15392 * q2[5]) + + (y1[4] * x2[4] + x1[4] * y2[4] - 51853 * q2[4]) + + (y1[5] * x2[3] + x1[5] * y2[3] - 26737 * q2[3]) + + (y1[6] * x2[2] + x1[6] * y2[2] - 27281 * q2[2]) + + (y1[7] * x2[1] + x1[7] * y2[1] - 38785 * q2[1]) + + (y1[8] * x2[0] + x1[8] * y2[0] - 22621 * q2[0]) + + 180968 - y3[8]; + + pol eq6_9 = + (y1[0] * x2[9] + x1[0] * y2[9] - 64839 * q2[9]) + + (y1[1] * x2[8] + x1[1] * y2[8] - 55420 * q2[8]) + + (y1[2] * x2[7] + x1[2] * y2[7] - 35862 * q2[7]) + + (y1[3] * x2[6] + x1[3] * y2[6] - 15392 * q2[6]) + + (y1[4] * x2[5] + x1[4] * y2[5] - 51853 * q2[5]) + + (y1[5] * x2[4] + x1[5] * y2[4] - 26737 * q2[4]) + + (y1[6] * x2[3] + x1[6] * y2[3] - 27281 * q2[3]) + + (y1[7] * x2[2] + x1[7] * y2[2] - 38785 * q2[2]) + + (y1[8] * x2[1] + x1[8] * y2[1] - 22621 * q2[1]) + + (y1[9] * x2[0] + x1[9] * y2[0] - 33153 * q2[0]) + + 265224 - y3[9]; + + pol eq6_10 = + (y1[0] * x2[10] + x1[0] * y2[10] - 64839 * q2[10]) + + (y1[1] * x2[9] + x1[1] * y2[9] - 55420 * q2[9]) + + (y1[2] * x2[8] + x1[2] * y2[8] - 35862 * q2[8]) + + (y1[3] * x2[7] + x1[3] * y2[7] - 15392 * q2[7]) + + (y1[4] * x2[6] + x1[4] * y2[6] - 51853 * q2[6]) + + (y1[5] * x2[5] + x1[5] * y2[5] - 26737 * q2[5]) + + (y1[6] * x2[4] + x1[6] * y2[4] - 27281 * q2[4]) + + (y1[7] * x2[3] + x1[7] * y2[3] - 38785 * q2[3]) + + (y1[8] * x2[2] + x1[8] * y2[2] - 22621 * q2[2]) + + (y1[9] * x2[1] + x1[9] * y2[1] - 33153 * q2[1]) + + (y1[10] * x2[0] + x1[10] * y2[0] - 17846 * q2[0]) + + 142768 - y3[10]; + + pol eq6_11 = + (y1[0] * x2[11] + x1[0] * y2[11] - 64839 * q2[11]) + + (y1[1] * x2[10] + x1[1] * y2[10] - 55420 * q2[10]) + + (y1[2] * x2[9] + x1[2] * y2[9] - 35862 * q2[9]) + + (y1[3] * x2[8] + x1[3] * y2[8] - 15392 * q2[8]) + + (y1[4] * x2[7] + x1[4] * y2[7] - 51853 * q2[7]) + + (y1[5] * x2[6] + x1[5] * y2[6] - 26737 * q2[6]) + + (y1[6] * x2[5] + x1[6] * y2[5] - 27281 * q2[5]) + + (y1[7] * x2[4] + x1[7] * y2[4] - 38785 * q2[4]) + + (y1[8] * x2[3] + x1[8] * y2[3] - 22621 * q2[3]) + + (y1[9] * x2[2] + x1[9] * y2[2] - 33153 * q2[2]) + + (y1[10] * x2[1] + x1[10] * y2[1] - 17846 * q2[1]) + + (y1[11] * x2[0] + x1[11] * y2[0] - 47184 * q2[0]) + + 377472 - y3[11]; + + pol eq6_12 = + (y1[0] * x2[12] + x1[0] * y2[12] - 64839 * q2[12]) + + (y1[1] * x2[11] + x1[1] * y2[11] - 55420 * q2[11]) + + (y1[2] * x2[10] + x1[2] * y2[10] - 35862 * q2[10]) + + (y1[3] * x2[9] + x1[3] * y2[9] - 15392 * q2[9]) + + (y1[4] * x2[8] + x1[4] * y2[8] - 51853 * q2[8]) + + (y1[5] * x2[7] + x1[5] * y2[7] - 26737 * q2[7]) + + (y1[6] * x2[6] + x1[6] * y2[6] - 27281 * q2[6]) + + (y1[7] * x2[5] + x1[7] * y2[5] - 38785 * q2[5]) + + (y1[8] * x2[4] + x1[8] * y2[4] - 22621 * q2[4]) + + (y1[9] * x2[3] + x1[9] * y2[3] - 33153 * q2[3]) + + (y1[10] * x2[2] + x1[10] * y2[2] - 17846 * q2[2]) + + (y1[11] * x2[1] + x1[11] * y2[1] - 47184 * q2[1]) + + (y1[12] * x2[0] + x1[12] * y2[0] - 41001 * q2[0]) + + 328008 - y3[12]; + + pol eq6_13 = + (y1[0] * x2[13] + x1[0] * y2[13] - 64839 * q2[13]) + + (y1[1] * x2[12] + x1[1] * y2[12] - 55420 * q2[12]) + + (y1[2] * x2[11] + x1[2] * y2[11] - 35862 * q2[11]) + + (y1[3] * x2[10] + x1[3] * y2[10] - 15392 * q2[10]) + + (y1[4] * x2[9] + x1[4] * y2[9] - 51853 * q2[9]) + + (y1[5] * x2[8] + x1[5] * y2[8] - 26737 * q2[8]) + + (y1[6] * x2[7] + x1[6] * y2[7] - 27281 * q2[7]) + + (y1[7] * x2[6] + x1[7] * y2[6] - 38785 * q2[6]) + + (y1[8] * x2[5] + x1[8] * y2[5] - 22621 * q2[5]) + + (y1[9] * x2[4] + x1[9] * y2[4] - 33153 * q2[4]) + + (y1[10] * x2[3] + x1[10] * y2[3] - 17846 * q2[3]) + + (y1[11] * x2[2] + x1[11] * y2[2] - 47184 * q2[2]) + + (y1[12] * x2[1] + x1[12] * y2[1] - 41001 * q2[1]) + + (y1[13] * x2[0] + x1[13] * y2[0] - 57649 * q2[0]) + + 461192 - y3[13]; + + pol eq6_14 = + (y1[0] * x2[14] + x1[0] * y2[14] - 64839 * q2[14]) + + (y1[1] * x2[13] + x1[1] * y2[13] - 55420 * q2[13]) + + (y1[2] * x2[12] + x1[2] * y2[12] - 35862 * q2[12]) + + (y1[3] * x2[11] + x1[3] * y2[11] - 15392 * q2[11]) + + (y1[4] * x2[10] + x1[4] * y2[10] - 51853 * q2[10]) + + (y1[5] * x2[9] + x1[5] * y2[9] - 26737 * q2[9]) + + (y1[6] * x2[8] + x1[6] * y2[8] - 27281 * q2[8]) + + (y1[7] * x2[7] + x1[7] * y2[7] - 38785 * q2[7]) + + (y1[8] * x2[6] + x1[8] * y2[6] - 22621 * q2[6]) + + (y1[9] * x2[5] + x1[9] * y2[5] - 33153 * q2[5]) + + (y1[10] * x2[4] + x1[10] * y2[4] - 17846 * q2[4]) + + (y1[11] * x2[3] + x1[11] * y2[3] - 47184 * q2[3]) + + (y1[12] * x2[2] + x1[12] * y2[2] - 41001 * q2[2]) + + (y1[13] * x2[1] + x1[13] * y2[1] - 57649 * q2[1]) + + (y1[14] * x2[0] + x1[14] * y2[0] - 20082 * q2[0]) + + 160656 - y3[14]; + + pol eq6_15 = + (y1[0] * x2[15] + x1[0] * y2[15] - 64839 * q2[15]) + + (y1[1] * x2[14] + x1[1] * y2[14] - 55420 * q2[14]) + + (y1[2] * x2[13] + x1[2] * y2[13] - 35862 * q2[13]) + + (y1[3] * x2[12] + x1[3] * y2[12] - 15392 * q2[12]) + + (y1[4] * x2[11] + x1[4] * y2[11] - 51853 * q2[11]) + + (y1[5] * x2[10] + x1[5] * y2[10] - 26737 * q2[10]) + + (y1[6] * x2[9] + x1[6] * y2[9] - 27281 * q2[9]) + + (y1[7] * x2[8] + x1[7] * y2[8] - 38785 * q2[8]) + + (y1[8] * x2[7] + x1[8] * y2[7] - 22621 * q2[7]) + + (y1[9] * x2[6] + x1[9] * y2[6] - 33153 * q2[6]) + + (y1[10] * x2[5] + x1[10] * y2[5] - 17846 * q2[5]) + + (y1[11] * x2[4] + x1[11] * y2[4] - 47184 * q2[4]) + + (y1[12] * x2[3] + x1[12] * y2[3] - 41001 * q2[3]) + + (y1[13] * x2[2] + x1[13] * y2[2] - 57649 * q2[2]) + + (y1[14] * x2[1] + x1[14] * y2[1] - 20082 * q2[1]) + + (y1[15] * x2[0] + x1[15] * y2[0] - 12388 * q2[0]) + + 99104 - y3[15]; + + pol eq6_16 = + (y1[1] * x2[15] + x1[1] * y2[15] - 55420 * q2[15]) + + (y1[2] * x2[14] + x1[2] * y2[14] - 35862 * q2[14]) + + (y1[3] * x2[13] + x1[3] * y2[13] - 15392 * q2[13]) + + (y1[4] * x2[12] + x1[4] * y2[12] - 51853 * q2[12]) + + (y1[5] * x2[11] + x1[5] * y2[11] - 26737 * q2[11]) + + (y1[6] * x2[10] + x1[6] * y2[10] - 27281 * q2[10]) + + (y1[7] * x2[9] + x1[7] * y2[9] - 38785 * q2[9]) + + (y1[8] * x2[8] + x1[8] * y2[8] - 22621 * q2[8]) + + (y1[9] * x2[7] + x1[9] * y2[7] - 33153 * q2[7]) + + (y1[10] * x2[6] + x1[10] * y2[6] - 17846 * q2[6]) + + (y1[11] * x2[5] + x1[11] * y2[5] - 47184 * q2[5]) + + (y1[12] * x2[4] + x1[12] * y2[4] - 41001 * q2[4]) + + (y1[13] * x2[3] + x1[13] * y2[3] - 57649 * q2[3]) + + (y1[14] * x2[2] + x1[14] * y2[2] - 20082 * q2[2]) + + (y1[15] * x2[1] + x1[15] * y2[1] - 12388 * q2[1]); + + pol eq6_17 = + (y1[2] * x2[15] + x1[2] * y2[15] - 35862 * q2[15]) + + (y1[3] * x2[14] + x1[3] * y2[14] - 15392 * q2[14]) + + (y1[4] * x2[13] + x1[4] * y2[13] - 51853 * q2[13]) + + (y1[5] * x2[12] + x1[5] * y2[12] - 26737 * q2[12]) + + (y1[6] * x2[11] + x1[6] * y2[11] - 27281 * q2[11]) + + (y1[7] * x2[10] + x1[7] * y2[10] - 38785 * q2[10]) + + (y1[8] * x2[9] + x1[8] * y2[9] - 22621 * q2[9]) + + (y1[9] * x2[8] + x1[9] * y2[8] - 33153 * q2[8]) + + (y1[10] * x2[7] + x1[10] * y2[7] - 17846 * q2[7]) + + (y1[11] * x2[6] + x1[11] * y2[6] - 47184 * q2[6]) + + (y1[12] * x2[5] + x1[12] * y2[5] - 41001 * q2[5]) + + (y1[13] * x2[4] + x1[13] * y2[4] - 57649 * q2[4]) + + (y1[14] * x2[3] + x1[14] * y2[3] - 20082 * q2[3]) + + (y1[15] * x2[2] + x1[15] * y2[2] - 12388 * q2[2]); + + pol eq6_18 = + (y1[3] * x2[15] + x1[3] * y2[15] - 15392 * q2[15]) + + (y1[4] * x2[14] + x1[4] * y2[14] - 51853 * q2[14]) + + (y1[5] * x2[13] + x1[5] * y2[13] - 26737 * q2[13]) + + (y1[6] * x2[12] + x1[6] * y2[12] - 27281 * q2[12]) + + (y1[7] * x2[11] + x1[7] * y2[11] - 38785 * q2[11]) + + (y1[8] * x2[10] + x1[8] * y2[10] - 22621 * q2[10]) + + (y1[9] * x2[9] + x1[9] * y2[9] - 33153 * q2[9]) + + (y1[10] * x2[8] + x1[10] * y2[8] - 17846 * q2[8]) + + (y1[11] * x2[7] + x1[11] * y2[7] - 47184 * q2[7]) + + (y1[12] * x2[6] + x1[12] * y2[6] - 41001 * q2[6]) + + (y1[13] * x2[5] + x1[13] * y2[5] - 57649 * q2[5]) + + (y1[14] * x2[4] + x1[14] * y2[4] - 20082 * q2[4]) + + (y1[15] * x2[3] + x1[15] * y2[3] - 12388 * q2[3]); + + pol eq6_19 = + (y1[4] * x2[15] + x1[4] * y2[15] - 51853 * q2[15]) + + (y1[5] * x2[14] + x1[5] * y2[14] - 26737 * q2[14]) + + (y1[6] * x2[13] + x1[6] * y2[13] - 27281 * q2[13]) + + (y1[7] * x2[12] + x1[7] * y2[12] - 38785 * q2[12]) + + (y1[8] * x2[11] + x1[8] * y2[11] - 22621 * q2[11]) + + (y1[9] * x2[10] + x1[9] * y2[10] - 33153 * q2[10]) + + (y1[10] * x2[9] + x1[10] * y2[9] - 17846 * q2[9]) + + (y1[11] * x2[8] + x1[11] * y2[8] - 47184 * q2[8]) + + (y1[12] * x2[7] + x1[12] * y2[7] - 41001 * q2[7]) + + (y1[13] * x2[6] + x1[13] * y2[6] - 57649 * q2[6]) + + (y1[14] * x2[5] + x1[14] * y2[5] - 20082 * q2[5]) + + (y1[15] * x2[4] + x1[15] * y2[4] - 12388 * q2[4]); + + pol eq6_20 = + (y1[5] * x2[15] + x1[5] * y2[15] - 26737 * q2[15]) + + (y1[6] * x2[14] + x1[6] * y2[14] - 27281 * q2[14]) + + (y1[7] * x2[13] + x1[7] * y2[13] - 38785 * q2[13]) + + (y1[8] * x2[12] + x1[8] * y2[12] - 22621 * q2[12]) + + (y1[9] * x2[11] + x1[9] * y2[11] - 33153 * q2[11]) + + (y1[10] * x2[10] + x1[10] * y2[10] - 17846 * q2[10]) + + (y1[11] * x2[9] + x1[11] * y2[9] - 47184 * q2[9]) + + (y1[12] * x2[8] + x1[12] * y2[8] - 41001 * q2[8]) + + (y1[13] * x2[7] + x1[13] * y2[7] - 57649 * q2[7]) + + (y1[14] * x2[6] + x1[14] * y2[6] - 20082 * q2[6]) + + (y1[15] * x2[5] + x1[15] * y2[5] - 12388 * q2[5]); + + pol eq6_21 = + (y1[6] * x2[15] + x1[6] * y2[15] - 27281 * q2[15]) + + (y1[7] * x2[14] + x1[7] * y2[14] - 38785 * q2[14]) + + (y1[8] * x2[13] + x1[8] * y2[13] - 22621 * q2[13]) + + (y1[9] * x2[12] + x1[9] * y2[12] - 33153 * q2[12]) + + (y1[10] * x2[11] + x1[10] * y2[11] - 17846 * q2[11]) + + (y1[11] * x2[10] + x1[11] * y2[10] - 47184 * q2[10]) + + (y1[12] * x2[9] + x1[12] * y2[9] - 41001 * q2[9]) + + (y1[13] * x2[8] + x1[13] * y2[8] - 57649 * q2[8]) + + (y1[14] * x2[7] + x1[14] * y2[7] - 20082 * q2[7]) + + (y1[15] * x2[6] + x1[15] * y2[6] - 12388 * q2[6]); + + pol eq6_22 = + (y1[7] * x2[15] + x1[7] * y2[15] - 38785 * q2[15]) + + (y1[8] * x2[14] + x1[8] * y2[14] - 22621 * q2[14]) + + (y1[9] * x2[13] + x1[9] * y2[13] - 33153 * q2[13]) + + (y1[10] * x2[12] + x1[10] * y2[12] - 17846 * q2[12]) + + (y1[11] * x2[11] + x1[11] * y2[11] - 47184 * q2[11]) + + (y1[12] * x2[10] + x1[12] * y2[10] - 41001 * q2[10]) + + (y1[13] * x2[9] + x1[13] * y2[9] - 57649 * q2[9]) + + (y1[14] * x2[8] + x1[14] * y2[8] - 20082 * q2[8]) + + (y1[15] * x2[7] + x1[15] * y2[7] - 12388 * q2[7]); + + pol eq6_23 = + (y1[8] * x2[15] + x1[8] * y2[15] - 22621 * q2[15]) + + (y1[9] * x2[14] + x1[9] * y2[14] - 33153 * q2[14]) + + (y1[10] * x2[13] + x1[10] * y2[13] - 17846 * q2[13]) + + (y1[11] * x2[12] + x1[11] * y2[12] - 47184 * q2[12]) + + (y1[12] * x2[11] + x1[12] * y2[11] - 41001 * q2[11]) + + (y1[13] * x2[10] + x1[13] * y2[10] - 57649 * q2[10]) + + (y1[14] * x2[9] + x1[14] * y2[9] - 20082 * q2[9]) + + (y1[15] * x2[8] + x1[15] * y2[8] - 12388 * q2[8]); + + pol eq6_24 = + (y1[9] * x2[15] + x1[9] * y2[15] - 33153 * q2[15]) + + (y1[10] * x2[14] + x1[10] * y2[14] - 17846 * q2[14]) + + (y1[11] * x2[13] + x1[11] * y2[13] - 47184 * q2[13]) + + (y1[12] * x2[12] + x1[12] * y2[12] - 41001 * q2[12]) + + (y1[13] * x2[11] + x1[13] * y2[11] - 57649 * q2[11]) + + (y1[14] * x2[10] + x1[14] * y2[10] - 20082 * q2[10]) + + (y1[15] * x2[9] + x1[15] * y2[9] - 12388 * q2[9]); + + pol eq6_25 = + (y1[10] * x2[15] + x1[10] * y2[15] - 17846 * q2[15]) + + (y1[11] * x2[14] + x1[11] * y2[14] - 47184 * q2[14]) + + (y1[12] * x2[13] + x1[12] * y2[13] - 41001 * q2[13]) + + (y1[13] * x2[12] + x1[13] * y2[12] - 57649 * q2[12]) + + (y1[14] * x2[11] + x1[14] * y2[11] - 20082 * q2[11]) + + (y1[15] * x2[10] + x1[15] * y2[10] - 12388 * q2[10]); + + pol eq6_26 = + (y1[11] * x2[15] + x1[11] * y2[15] - 47184 * q2[15]) + + (y1[12] * x2[14] + x1[12] * y2[14] - 41001 * q2[14]) + + (y1[13] * x2[13] + x1[13] * y2[13] - 57649 * q2[13]) + + (y1[14] * x2[12] + x1[14] * y2[12] - 20082 * q2[12]) + + (y1[15] * x2[11] + x1[15] * y2[11] - 12388 * q2[11]); + + pol eq6_27 = + (y1[12] * x2[15] + x1[12] * y2[15] - 41001 * q2[15]) + + (y1[13] * x2[14] + x1[13] * y2[14] - 57649 * q2[14]) + + (y1[14] * x2[13] + x1[14] * y2[13] - 20082 * q2[13]) + + (y1[15] * x2[12] + x1[15] * y2[12] - 12388 * q2[12]); + + pol eq6_28 = + (y1[13] * x2[15] + x1[13] * y2[15] - 57649 * q2[15]) + + (y1[14] * x2[14] + x1[14] * y2[14] - 20082 * q2[14]) + + (y1[15] * x2[13] + x1[15] * y2[13] - 12388 * q2[13]); + + pol eq6_29 = + (y1[14] * x2[15] + x1[14] * y2[15] - 20082 * q2[15]) + + (y1[15] * x2[14] + x1[15] * y2[14] - 12388 * q2[14]); + + pol eq6_30 = + (y1[15] * x2[15] + x1[15] * y2[15] - 12388 * q2[15]); + + pol eq6_31 = + 0; + + + /******* + * + * EQ7: x1 + x2 - x3 - p * (q1 - offset) = 0 + * + *******/ + + pol eq7_0 = + ( - 64839 * q1[0]) + + 518712 + x1[0] + x2[0] - x3[0]; + + pol eq7_1 = + ( - 64839 * q1[1]) + + ( - 55420 * q1[0]) + + 443360 + x1[1] + x2[1] - x3[1]; + + pol eq7_2 = + ( - 64839 * q1[2]) + + ( - 55420 * q1[1]) + + ( - 35862 * q1[0]) + + 286896 + x1[2] + x2[2] - x3[2]; + + pol eq7_3 = + ( - 64839 * q1[3]) + + ( - 55420 * q1[2]) + + ( - 35862 * q1[1]) + + ( - 15392 * q1[0]) + + 123136 + x1[3] + x2[3] - x3[3]; + + pol eq7_4 = + ( - 64839 * q1[4]) + + ( - 55420 * q1[3]) + + ( - 35862 * q1[2]) + + ( - 15392 * q1[1]) + + ( - 51853 * q1[0]) + + 414824 + x1[4] + x2[4] - x3[4]; + + pol eq7_5 = + ( - 64839 * q1[5]) + + ( - 55420 * q1[4]) + + ( - 35862 * q1[3]) + + ( - 15392 * q1[2]) + + ( - 51853 * q1[1]) + + ( - 26737 * q1[0]) + + 213896 + x1[5] + x2[5] - x3[5]; + + pol eq7_6 = + ( - 64839 * q1[6]) + + ( - 55420 * q1[5]) + + ( - 35862 * q1[4]) + + ( - 15392 * q1[3]) + + ( - 51853 * q1[2]) + + ( - 26737 * q1[1]) + + ( - 27281 * q1[0]) + + 218248 + x1[6] + x2[6] - x3[6]; + + pol eq7_7 = + ( - 64839 * q1[7]) + + ( - 55420 * q1[6]) + + ( - 35862 * q1[5]) + + ( - 15392 * q1[4]) + + ( - 51853 * q1[3]) + + ( - 26737 * q1[2]) + + ( - 27281 * q1[1]) + + ( - 38785 * q1[0]) + + 310280 + x1[7] + x2[7] - x3[7]; + + pol eq7_8 = + ( - 64839 * q1[8]) + + ( - 55420 * q1[7]) + + ( - 35862 * q1[6]) + + ( - 15392 * q1[5]) + + ( - 51853 * q1[4]) + + ( - 26737 * q1[3]) + + ( - 27281 * q1[2]) + + ( - 38785 * q1[1]) + + ( - 22621 * q1[0]) + + 180968 + x1[8] + x2[8] - x3[8]; + + pol eq7_9 = + ( - 64839 * q1[9]) + + ( - 55420 * q1[8]) + + ( - 35862 * q1[7]) + + ( - 15392 * q1[6]) + + ( - 51853 * q1[5]) + + ( - 26737 * q1[4]) + + ( - 27281 * q1[3]) + + ( - 38785 * q1[2]) + + ( - 22621 * q1[1]) + + ( - 33153 * q1[0]) + + 265224 + x1[9] + x2[9] - x3[9]; + + pol eq7_10 = + ( - 64839 * q1[10]) + + ( - 55420 * q1[9]) + + ( - 35862 * q1[8]) + + ( - 15392 * q1[7]) + + ( - 51853 * q1[6]) + + ( - 26737 * q1[5]) + + ( - 27281 * q1[4]) + + ( - 38785 * q1[3]) + + ( - 22621 * q1[2]) + + ( - 33153 * q1[1]) + + ( - 17846 * q1[0]) + + 142768 + x1[10] + x2[10] - x3[10]; + + pol eq7_11 = + ( - 64839 * q1[11]) + + ( - 55420 * q1[10]) + + ( - 35862 * q1[9]) + + ( - 15392 * q1[8]) + + ( - 51853 * q1[7]) + + ( - 26737 * q1[6]) + + ( - 27281 * q1[5]) + + ( - 38785 * q1[4]) + + ( - 22621 * q1[3]) + + ( - 33153 * q1[2]) + + ( - 17846 * q1[1]) + + ( - 47184 * q1[0]) + + 377472 + x1[11] + x2[11] - x3[11]; + + pol eq7_12 = + ( - 64839 * q1[12]) + + ( - 55420 * q1[11]) + + ( - 35862 * q1[10]) + + ( - 15392 * q1[9]) + + ( - 51853 * q1[8]) + + ( - 26737 * q1[7]) + + ( - 27281 * q1[6]) + + ( - 38785 * q1[5]) + + ( - 22621 * q1[4]) + + ( - 33153 * q1[3]) + + ( - 17846 * q1[2]) + + ( - 47184 * q1[1]) + + ( - 41001 * q1[0]) + + 328008 + x1[12] + x2[12] - x3[12]; + + pol eq7_13 = + ( - 64839 * q1[13]) + + ( - 55420 * q1[12]) + + ( - 35862 * q1[11]) + + ( - 15392 * q1[10]) + + ( - 51853 * q1[9]) + + ( - 26737 * q1[8]) + + ( - 27281 * q1[7]) + + ( - 38785 * q1[6]) + + ( - 22621 * q1[5]) + + ( - 33153 * q1[4]) + + ( - 17846 * q1[3]) + + ( - 47184 * q1[2]) + + ( - 41001 * q1[1]) + + ( - 57649 * q1[0]) + + 461192 + x1[13] + x2[13] - x3[13]; + + pol eq7_14 = + ( - 64839 * q1[14]) + + ( - 55420 * q1[13]) + + ( - 35862 * q1[12]) + + ( - 15392 * q1[11]) + + ( - 51853 * q1[10]) + + ( - 26737 * q1[9]) + + ( - 27281 * q1[8]) + + ( - 38785 * q1[7]) + + ( - 22621 * q1[6]) + + ( - 33153 * q1[5]) + + ( - 17846 * q1[4]) + + ( - 47184 * q1[3]) + + ( - 41001 * q1[2]) + + ( - 57649 * q1[1]) + + ( - 20082 * q1[0]) + + 160656 + x1[14] + x2[14] - x3[14]; + + pol eq7_15 = + ( - 64839 * q1[15]) + + ( - 55420 * q1[14]) + + ( - 35862 * q1[13]) + + ( - 15392 * q1[12]) + + ( - 51853 * q1[11]) + + ( - 26737 * q1[10]) + + ( - 27281 * q1[9]) + + ( - 38785 * q1[8]) + + ( - 22621 * q1[7]) + + ( - 33153 * q1[6]) + + ( - 17846 * q1[5]) + + ( - 47184 * q1[4]) + + ( - 41001 * q1[3]) + + ( - 57649 * q1[2]) + + ( - 20082 * q1[1]) + + ( - 12388 * q1[0]) + + 99104 + x1[15] + x2[15] - x3[15]; + + pol eq7_16 = + ( - 55420 * q1[15]) + + ( - 35862 * q1[14]) + + ( - 15392 * q1[13]) + + ( - 51853 * q1[12]) + + ( - 26737 * q1[11]) + + ( - 27281 * q1[10]) + + ( - 38785 * q1[9]) + + ( - 22621 * q1[8]) + + ( - 33153 * q1[7]) + + ( - 17846 * q1[6]) + + ( - 47184 * q1[5]) + + ( - 41001 * q1[4]) + + ( - 57649 * q1[3]) + + ( - 20082 * q1[2]) + + ( - 12388 * q1[1]); + + pol eq7_17 = + ( - 35862 * q1[15]) + + ( - 15392 * q1[14]) + + ( - 51853 * q1[13]) + + ( - 26737 * q1[12]) + + ( - 27281 * q1[11]) + + ( - 38785 * q1[10]) + + ( - 22621 * q1[9]) + + ( - 33153 * q1[8]) + + ( - 17846 * q1[7]) + + ( - 47184 * q1[6]) + + ( - 41001 * q1[5]) + + ( - 57649 * q1[4]) + + ( - 20082 * q1[3]) + + ( - 12388 * q1[2]); + + pol eq7_18 = + ( - 15392 * q1[15]) + + ( - 51853 * q1[14]) + + ( - 26737 * q1[13]) + + ( - 27281 * q1[12]) + + ( - 38785 * q1[11]) + + ( - 22621 * q1[10]) + + ( - 33153 * q1[9]) + + ( - 17846 * q1[8]) + + ( - 47184 * q1[7]) + + ( - 41001 * q1[6]) + + ( - 57649 * q1[5]) + + ( - 20082 * q1[4]) + + ( - 12388 * q1[3]); + + pol eq7_19 = + ( - 51853 * q1[15]) + + ( - 26737 * q1[14]) + + ( - 27281 * q1[13]) + + ( - 38785 * q1[12]) + + ( - 22621 * q1[11]) + + ( - 33153 * q1[10]) + + ( - 17846 * q1[9]) + + ( - 47184 * q1[8]) + + ( - 41001 * q1[7]) + + ( - 57649 * q1[6]) + + ( - 20082 * q1[5]) + + ( - 12388 * q1[4]); + + pol eq7_20 = + ( - 26737 * q1[15]) + + ( - 27281 * q1[14]) + + ( - 38785 * q1[13]) + + ( - 22621 * q1[12]) + + ( - 33153 * q1[11]) + + ( - 17846 * q1[10]) + + ( - 47184 * q1[9]) + + ( - 41001 * q1[8]) + + ( - 57649 * q1[7]) + + ( - 20082 * q1[6]) + + ( - 12388 * q1[5]); + + pol eq7_21 = + ( - 27281 * q1[15]) + + ( - 38785 * q1[14]) + + ( - 22621 * q1[13]) + + ( - 33153 * q1[12]) + + ( - 17846 * q1[11]) + + ( - 47184 * q1[10]) + + ( - 41001 * q1[9]) + + ( - 57649 * q1[8]) + + ( - 20082 * q1[7]) + + ( - 12388 * q1[6]); + + pol eq7_22 = + ( - 38785 * q1[15]) + + ( - 22621 * q1[14]) + + ( - 33153 * q1[13]) + + ( - 17846 * q1[12]) + + ( - 47184 * q1[11]) + + ( - 41001 * q1[10]) + + ( - 57649 * q1[9]) + + ( - 20082 * q1[8]) + + ( - 12388 * q1[7]); + + pol eq7_23 = + ( - 22621 * q1[15]) + + ( - 33153 * q1[14]) + + ( - 17846 * q1[13]) + + ( - 47184 * q1[12]) + + ( - 41001 * q1[11]) + + ( - 57649 * q1[10]) + + ( - 20082 * q1[9]) + + ( - 12388 * q1[8]); + + pol eq7_24 = + ( - 33153 * q1[15]) + + ( - 17846 * q1[14]) + + ( - 47184 * q1[13]) + + ( - 41001 * q1[12]) + + ( - 57649 * q1[11]) + + ( - 20082 * q1[10]) + + ( - 12388 * q1[9]); + + pol eq7_25 = + ( - 17846 * q1[15]) + + ( - 47184 * q1[14]) + + ( - 41001 * q1[13]) + + ( - 57649 * q1[12]) + + ( - 20082 * q1[11]) + + ( - 12388 * q1[10]); + + pol eq7_26 = + ( - 47184 * q1[15]) + + ( - 41001 * q1[14]) + + ( - 57649 * q1[13]) + + ( - 20082 * q1[12]) + + ( - 12388 * q1[11]); + + pol eq7_27 = + ( - 41001 * q1[15]) + + ( - 57649 * q1[14]) + + ( - 20082 * q1[13]) + + ( - 12388 * q1[12]); + + pol eq7_28 = + ( - 57649 * q1[15]) + + ( - 20082 * q1[14]) + + ( - 12388 * q1[13]); + + pol eq7_29 = + ( - 20082 * q1[15]) + + ( - 12388 * q1[14]); + + pol eq7_30 = ( - 12388 * q1[15]); + + pol eq7_31 = + 0; + + + /******* + * + * EQ8: y1 + y2 - y3 - p * (q2 - offset) = 0 + * + *******/ + + pol eq8_0 = + ( - 64839 * q2[0]) + + 518712 + y1[0] + y2[0] - y3[0]; + + pol eq8_1 = + ( - 64839 * q2[1]) + + ( - 55420 * q2[0]) + + 443360 + y1[1] + y2[1] - y3[1]; + + pol eq8_2 = + ( - 64839 * q2[2]) + + ( - 55420 * q2[1]) + + ( - 35862 * q2[0]) + + 286896 + y1[2] + y2[2] - y3[2]; + + pol eq8_3 = + ( - 64839 * q2[3]) + + ( - 55420 * q2[2]) + + ( - 35862 * q2[1]) + + ( - 15392 * q2[0]) + + 123136 + y1[3] + y2[3] - y3[3]; + + pol eq8_4 = + ( - 64839 * q2[4]) + + ( - 55420 * q2[3]) + + ( - 35862 * q2[2]) + + ( - 15392 * q2[1]) + + ( - 51853 * q2[0]) + + 414824 + y1[4] + y2[4] - y3[4]; + + pol eq8_5 = + ( - 64839 * q2[5]) + + ( - 55420 * q2[4]) + + ( - 35862 * q2[3]) + + ( - 15392 * q2[2]) + + ( - 51853 * q2[1]) + + ( - 26737 * q2[0]) + + 213896 + y1[5] + y2[5] - y3[5]; + + pol eq8_6 = + ( - 64839 * q2[6]) + + ( - 55420 * q2[5]) + + ( - 35862 * q2[4]) + + ( - 15392 * q2[3]) + + ( - 51853 * q2[2]) + + ( - 26737 * q2[1]) + + ( - 27281 * q2[0]) + + 218248 + y1[6] + y2[6] - y3[6]; + + pol eq8_7 = + ( - 64839 * q2[7]) + + ( - 55420 * q2[6]) + + ( - 35862 * q2[5]) + + ( - 15392 * q2[4]) + + ( - 51853 * q2[3]) + + ( - 26737 * q2[2]) + + ( - 27281 * q2[1]) + + ( - 38785 * q2[0]) + + 310280 + y1[7] + y2[7] - y3[7]; + + pol eq8_8 = + ( - 64839 * q2[8]) + + ( - 55420 * q2[7]) + + ( - 35862 * q2[6]) + + ( - 15392 * q2[5]) + + ( - 51853 * q2[4]) + + ( - 26737 * q2[3]) + + ( - 27281 * q2[2]) + + ( - 38785 * q2[1]) + + ( - 22621 * q2[0]) + + 180968 + y1[8] + y2[8] - y3[8]; + + pol eq8_9 = + ( - 64839 * q2[9]) + + ( - 55420 * q2[8]) + + ( - 35862 * q2[7]) + + ( - 15392 * q2[6]) + + ( - 51853 * q2[5]) + + ( - 26737 * q2[4]) + + ( - 27281 * q2[3]) + + ( - 38785 * q2[2]) + + ( - 22621 * q2[1]) + + ( - 33153 * q2[0]) + + 265224 + y1[9] + y2[9] - y3[9]; + + pol eq8_10 = + ( - 64839 * q2[10]) + + ( - 55420 * q2[9]) + + ( - 35862 * q2[8]) + + ( - 15392 * q2[7]) + + ( - 51853 * q2[6]) + + ( - 26737 * q2[5]) + + ( - 27281 * q2[4]) + + ( - 38785 * q2[3]) + + ( - 22621 * q2[2]) + + ( - 33153 * q2[1]) + + ( - 17846 * q2[0]) + + 142768 + y1[10] + y2[10] - y3[10]; + + pol eq8_11 = + ( - 64839 * q2[11]) + + ( - 55420 * q2[10]) + + ( - 35862 * q2[9]) + + ( - 15392 * q2[8]) + + ( - 51853 * q2[7]) + + ( - 26737 * q2[6]) + + ( - 27281 * q2[5]) + + ( - 38785 * q2[4]) + + ( - 22621 * q2[3]) + + ( - 33153 * q2[2]) + + ( - 17846 * q2[1]) + + ( - 47184 * q2[0]) + + 377472 + y1[11] + y2[11] - y3[11]; + + pol eq8_12 = + ( - 64839 * q2[12]) + + ( - 55420 * q2[11]) + + ( - 35862 * q2[10]) + + ( - 15392 * q2[9]) + + ( - 51853 * q2[8]) + + ( - 26737 * q2[7]) + + ( - 27281 * q2[6]) + + ( - 38785 * q2[5]) + + ( - 22621 * q2[4]) + + ( - 33153 * q2[3]) + + ( - 17846 * q2[2]) + + ( - 47184 * q2[1]) + + ( - 41001 * q2[0]) + + 328008 + y1[12] + y2[12] - y3[12]; + + pol eq8_13 = + ( - 64839 * q2[13]) + + ( - 55420 * q2[12]) + + ( - 35862 * q2[11]) + + ( - 15392 * q2[10]) + + ( - 51853 * q2[9]) + + ( - 26737 * q2[8]) + + ( - 27281 * q2[7]) + + ( - 38785 * q2[6]) + + ( - 22621 * q2[5]) + + ( - 33153 * q2[4]) + + ( - 17846 * q2[3]) + + ( - 47184 * q2[2]) + + ( - 41001 * q2[1]) + + ( - 57649 * q2[0]) + + 461192 + y1[13] + y2[13] - y3[13]; + + pol eq8_14 = + ( - 64839 * q2[14]) + + ( - 55420 * q2[13]) + + ( - 35862 * q2[12]) + + ( - 15392 * q2[11]) + + ( - 51853 * q2[10]) + + ( - 26737 * q2[9]) + + ( - 27281 * q2[8]) + + ( - 38785 * q2[7]) + + ( - 22621 * q2[6]) + + ( - 33153 * q2[5]) + + ( - 17846 * q2[4]) + + ( - 47184 * q2[3]) + + ( - 41001 * q2[2]) + + ( - 57649 * q2[1]) + + ( - 20082 * q2[0]) + + 160656 + y1[14] + y2[14] - y3[14]; + + pol eq8_15 = + ( - 64839 * q2[15]) + + ( - 55420 * q2[14]) + + ( - 35862 * q2[13]) + + ( - 15392 * q2[12]) + + ( - 51853 * q2[11]) + + ( - 26737 * q2[10]) + + ( - 27281 * q2[9]) + + ( - 38785 * q2[8]) + + ( - 22621 * q2[7]) + + ( - 33153 * q2[6]) + + ( - 17846 * q2[5]) + + ( - 47184 * q2[4]) + + ( - 41001 * q2[3]) + + ( - 57649 * q2[2]) + + ( - 20082 * q2[1]) + + ( - 12388 * q2[0]) + + 99104 + y1[15] + y2[15] - y3[15]; + + pol eq8_16 = + ( - 55420 * q2[15]) + + ( - 35862 * q2[14]) + + ( - 15392 * q2[13]) + + ( - 51853 * q2[12]) + + ( - 26737 * q2[11]) + + ( - 27281 * q2[10]) + + ( - 38785 * q2[9]) + + ( - 22621 * q2[8]) + + ( - 33153 * q2[7]) + + ( - 17846 * q2[6]) + + ( - 47184 * q2[5]) + + ( - 41001 * q2[4]) + + ( - 57649 * q2[3]) + + ( - 20082 * q2[2]) + + ( - 12388 * q2[1]); + + pol eq8_17 = + ( - 35862 * q2[15]) + + ( - 15392 * q2[14]) + + ( - 51853 * q2[13]) + + ( - 26737 * q2[12]) + + ( - 27281 * q2[11]) + + ( - 38785 * q2[10]) + + ( - 22621 * q2[9]) + + ( - 33153 * q2[8]) + + ( - 17846 * q2[7]) + + ( - 47184 * q2[6]) + + ( - 41001 * q2[5]) + + ( - 57649 * q2[4]) + + ( - 20082 * q2[3]) + + ( - 12388 * q2[2]); + + pol eq8_18 = + ( - 15392 * q2[15]) + + ( - 51853 * q2[14]) + + ( - 26737 * q2[13]) + + ( - 27281 * q2[12]) + + ( - 38785 * q2[11]) + + ( - 22621 * q2[10]) + + ( - 33153 * q2[9]) + + ( - 17846 * q2[8]) + + ( - 47184 * q2[7]) + + ( - 41001 * q2[6]) + + ( - 57649 * q2[5]) + + ( - 20082 * q2[4]) + + ( - 12388 * q2[3]); + + pol eq8_19 = + ( - 51853 * q2[15]) + + ( - 26737 * q2[14]) + + ( - 27281 * q2[13]) + + ( - 38785 * q2[12]) + + ( - 22621 * q2[11]) + + ( - 33153 * q2[10]) + + ( - 17846 * q2[9]) + + ( - 47184 * q2[8]) + + ( - 41001 * q2[7]) + + ( - 57649 * q2[6]) + + ( - 20082 * q2[5]) + + ( - 12388 * q2[4]); + + pol eq8_20 = + ( - 26737 * q2[15]) + + ( - 27281 * q2[14]) + + ( - 38785 * q2[13]) + + ( - 22621 * q2[12]) + + ( - 33153 * q2[11]) + + ( - 17846 * q2[10]) + + ( - 47184 * q2[9]) + + ( - 41001 * q2[8]) + + ( - 57649 * q2[7]) + + ( - 20082 * q2[6]) + + ( - 12388 * q2[5]); + + pol eq8_21 = + ( - 27281 * q2[15]) + + ( - 38785 * q2[14]) + + ( - 22621 * q2[13]) + + ( - 33153 * q2[12]) + + ( - 17846 * q2[11]) + + ( - 47184 * q2[10]) + + ( - 41001 * q2[9]) + + ( - 57649 * q2[8]) + + ( - 20082 * q2[7]) + + ( - 12388 * q2[6]); + + pol eq8_22 = + ( - 38785 * q2[15]) + + ( - 22621 * q2[14]) + + ( - 33153 * q2[13]) + + ( - 17846 * q2[12]) + + ( - 47184 * q2[11]) + + ( - 41001 * q2[10]) + + ( - 57649 * q2[9]) + + ( - 20082 * q2[8]) + + ( - 12388 * q2[7]); + + pol eq8_23 = + ( - 22621 * q2[15]) + + ( - 33153 * q2[14]) + + ( - 17846 * q2[13]) + + ( - 47184 * q2[12]) + + ( - 41001 * q2[11]) + + ( - 57649 * q2[10]) + + ( - 20082 * q2[9]) + + ( - 12388 * q2[8]); + + pol eq8_24 = + ( - 33153 * q2[15]) + + ( - 17846 * q2[14]) + + ( - 47184 * q2[13]) + + ( - 41001 * q2[12]) + + ( - 57649 * q2[11]) + + ( - 20082 * q2[10]) + + ( - 12388 * q2[9]); + + pol eq8_25 = + ( - 17846 * q2[15]) + + ( - 47184 * q2[14]) + + ( - 41001 * q2[13]) + + ( - 57649 * q2[12]) + + ( - 20082 * q2[11]) + + ( - 12388 * q2[10]); + + pol eq8_26 = + ( - 47184 * q2[15]) + + ( - 41001 * q2[14]) + + ( - 57649 * q2[13]) + + ( - 20082 * q2[12]) + + ( - 12388 * q2[11]); + + pol eq8_27 = + ( - 41001 * q2[15]) + + ( - 57649 * q2[14]) + + ( - 20082 * q2[13]) + + ( - 12388 * q2[12]); + + pol eq8_28 = + ( - 57649 * q2[15]) + + ( - 20082 * q2[14]) + + ( - 12388 * q2[13]); + + pol eq8_29 = + ( - 20082 * q2[15]) + + ( - 12388 * q2[14]); + + pol eq8_30 = ( - 12388 * q2[15]); + + pol eq8_31 = + 0; + + + + /******* + * + * EQ9: x1 - x2 - x3 + p * (q1 - offset) = 0 + * + *******/ + + pol eq9_0 = + (64839 * q1[0]) + - 518712 + x1[0] - x2[0] - x3[0]; + + pol eq9_1 = + (64839 * q1[1]) + + (55420 * q1[0]) + - 443360 + x1[1] - x2[1] - x3[1]; + + pol eq9_2 = + (64839 * q1[2]) + + (55420 * q1[1]) + + (35862 * q1[0]) + - 286896 + x1[2] - x2[2] - x3[2]; + + pol eq9_3 = + (64839 * q1[3]) + + (55420 * q1[2]) + + (35862 * q1[1]) + + (15392 * q1[0]) + - 123136 + x1[3] - x2[3] - x3[3]; + + pol eq9_4 = + (64839 * q1[4]) + + (55420 * q1[3]) + + (35862 * q1[2]) + + (15392 * q1[1]) + + (51853 * q1[0]) + - 414824 + x1[4] - x2[4] - x3[4]; + + pol eq9_5 = + (64839 * q1[5]) + + (55420 * q1[4]) + + (35862 * q1[3]) + + (15392 * q1[2]) + + (51853 * q1[1]) + + (26737 * q1[0]) + - 213896 + x1[5] - x2[5] - x3[5]; + + pol eq9_6 = + (64839 * q1[6]) + + (55420 * q1[5]) + + (35862 * q1[4]) + + (15392 * q1[3]) + + (51853 * q1[2]) + + (26737 * q1[1]) + + (27281 * q1[0]) + - 218248 + x1[6] - x2[6] - x3[6]; + + pol eq9_7 = + (64839 * q1[7]) + + (55420 * q1[6]) + + (35862 * q1[5]) + + (15392 * q1[4]) + + (51853 * q1[3]) + + (26737 * q1[2]) + + (27281 * q1[1]) + + (38785 * q1[0]) + - 310280 + x1[7] - x2[7] - x3[7]; + + pol eq9_8 = + (64839 * q1[8]) + + (55420 * q1[7]) + + (35862 * q1[6]) + + (15392 * q1[5]) + + (51853 * q1[4]) + + (26737 * q1[3]) + + (27281 * q1[2]) + + (38785 * q1[1]) + + (22621 * q1[0]) + - 180968 + x1[8] - x2[8] - x3[8]; + + pol eq9_9 = + (64839 * q1[9]) + + (55420 * q1[8]) + + (35862 * q1[7]) + + (15392 * q1[6]) + + (51853 * q1[5]) + + (26737 * q1[4]) + + (27281 * q1[3]) + + (38785 * q1[2]) + + (22621 * q1[1]) + + (33153 * q1[0]) + - 265224 + x1[9] - x2[9] - x3[9]; + + pol eq9_10 = + (64839 * q1[10]) + + (55420 * q1[9]) + + (35862 * q1[8]) + + (15392 * q1[7]) + + (51853 * q1[6]) + + (26737 * q1[5]) + + (27281 * q1[4]) + + (38785 * q1[3]) + + (22621 * q1[2]) + + (33153 * q1[1]) + + (17846 * q1[0]) + - 142768 + x1[10] - x2[10] - x3[10]; + + pol eq9_11 = + (64839 * q1[11]) + + (55420 * q1[10]) + + (35862 * q1[9]) + + (15392 * q1[8]) + + (51853 * q1[7]) + + (26737 * q1[6]) + + (27281 * q1[5]) + + (38785 * q1[4]) + + (22621 * q1[3]) + + (33153 * q1[2]) + + (17846 * q1[1]) + + (47184 * q1[0]) + - 377472 + x1[11] - x2[11] - x3[11]; + + pol eq9_12 = + (64839 * q1[12]) + + (55420 * q1[11]) + + (35862 * q1[10]) + + (15392 * q1[9]) + + (51853 * q1[8]) + + (26737 * q1[7]) + + (27281 * q1[6]) + + (38785 * q1[5]) + + (22621 * q1[4]) + + (33153 * q1[3]) + + (17846 * q1[2]) + + (47184 * q1[1]) + + (41001 * q1[0]) + - 328008 + x1[12] - x2[12] - x3[12]; + + pol eq9_13 = + (64839 * q1[13]) + + (55420 * q1[12]) + + (35862 * q1[11]) + + (15392 * q1[10]) + + (51853 * q1[9]) + + (26737 * q1[8]) + + (27281 * q1[7]) + + (38785 * q1[6]) + + (22621 * q1[5]) + + (33153 * q1[4]) + + (17846 * q1[3]) + + (47184 * q1[2]) + + (41001 * q1[1]) + + (57649 * q1[0]) + - 461192 + x1[13] - x2[13] - x3[13]; + + pol eq9_14 = + (64839 * q1[14]) + + (55420 * q1[13]) + + (35862 * q1[12]) + + (15392 * q1[11]) + + (51853 * q1[10]) + + (26737 * q1[9]) + + (27281 * q1[8]) + + (38785 * q1[7]) + + (22621 * q1[6]) + + (33153 * q1[5]) + + (17846 * q1[4]) + + (47184 * q1[3]) + + (41001 * q1[2]) + + (57649 * q1[1]) + + (20082 * q1[0]) + - 160656 + x1[14] - x2[14] - x3[14]; + + pol eq9_15 = + (64839 * q1[15]) + + (55420 * q1[14]) + + (35862 * q1[13]) + + (15392 * q1[12]) + + (51853 * q1[11]) + + (26737 * q1[10]) + + (27281 * q1[9]) + + (38785 * q1[8]) + + (22621 * q1[7]) + + (33153 * q1[6]) + + (17846 * q1[5]) + + (47184 * q1[4]) + + (41001 * q1[3]) + + (57649 * q1[2]) + + (20082 * q1[1]) + + (12388 * q1[0]) + - 99104 + x1[15] - x2[15] - x3[15]; + + pol eq9_16 = + (55420 * q1[15]) + + (35862 * q1[14]) + + (15392 * q1[13]) + + (51853 * q1[12]) + + (26737 * q1[11]) + + (27281 * q1[10]) + + (38785 * q1[9]) + + (22621 * q1[8]) + + (33153 * q1[7]) + + (17846 * q1[6]) + + (47184 * q1[5]) + + (41001 * q1[4]) + + (57649 * q1[3]) + + (20082 * q1[2]) + + (12388 * q1[1]); + + pol eq9_17 = + (35862 * q1[15]) + + (15392 * q1[14]) + + (51853 * q1[13]) + + (26737 * q1[12]) + + (27281 * q1[11]) + + (38785 * q1[10]) + + (22621 * q1[9]) + + (33153 * q1[8]) + + (17846 * q1[7]) + + (47184 * q1[6]) + + (41001 * q1[5]) + + (57649 * q1[4]) + + (20082 * q1[3]) + + (12388 * q1[2]); + + pol eq9_18 = + (15392 * q1[15]) + + (51853 * q1[14]) + + (26737 * q1[13]) + + (27281 * q1[12]) + + (38785 * q1[11]) + + (22621 * q1[10]) + + (33153 * q1[9]) + + (17846 * q1[8]) + + (47184 * q1[7]) + + (41001 * q1[6]) + + (57649 * q1[5]) + + (20082 * q1[4]) + + (12388 * q1[3]); + + pol eq9_19 = + (51853 * q1[15]) + + (26737 * q1[14]) + + (27281 * q1[13]) + + (38785 * q1[12]) + + (22621 * q1[11]) + + (33153 * q1[10]) + + (17846 * q1[9]) + + (47184 * q1[8]) + + (41001 * q1[7]) + + (57649 * q1[6]) + + (20082 * q1[5]) + + (12388 * q1[4]); + + pol eq9_20 = + (26737 * q1[15]) + + (27281 * q1[14]) + + (38785 * q1[13]) + + (22621 * q1[12]) + + (33153 * q1[11]) + + (17846 * q1[10]) + + (47184 * q1[9]) + + (41001 * q1[8]) + + (57649 * q1[7]) + + (20082 * q1[6]) + + (12388 * q1[5]); + + pol eq9_21 = + (27281 * q1[15]) + + (38785 * q1[14]) + + (22621 * q1[13]) + + (33153 * q1[12]) + + (17846 * q1[11]) + + (47184 * q1[10]) + + (41001 * q1[9]) + + (57649 * q1[8]) + + (20082 * q1[7]) + + (12388 * q1[6]); + + pol eq9_22 = + (38785 * q1[15]) + + (22621 * q1[14]) + + (33153 * q1[13]) + + (17846 * q1[12]) + + (47184 * q1[11]) + + (41001 * q1[10]) + + (57649 * q1[9]) + + (20082 * q1[8]) + + (12388 * q1[7]); + + pol eq9_23 = + (22621 * q1[15]) + + (33153 * q1[14]) + + (17846 * q1[13]) + + (47184 * q1[12]) + + (41001 * q1[11]) + + (57649 * q1[10]) + + (20082 * q1[9]) + + (12388 * q1[8]); + + pol eq9_24 = + (33153 * q1[15]) + + (17846 * q1[14]) + + (47184 * q1[13]) + + (41001 * q1[12]) + + (57649 * q1[11]) + + (20082 * q1[10]) + + (12388 * q1[9]); + + pol eq9_25 = + (17846 * q1[15]) + + (47184 * q1[14]) + + (41001 * q1[13]) + + (57649 * q1[12]) + + (20082 * q1[11]) + + (12388 * q1[10]); + + pol eq9_26 = + (47184 * q1[15]) + + (41001 * q1[14]) + + (57649 * q1[13]) + + (20082 * q1[12]) + + (12388 * q1[11]); + + pol eq9_27 = + (41001 * q1[15]) + + (57649 * q1[14]) + + (20082 * q1[13]) + + (12388 * q1[12]); + + pol eq9_28 = + (57649 * q1[15]) + + (20082 * q1[14]) + + (12388 * q1[13]); + + pol eq9_29 = + (20082 * q1[15]) + + (12388 * q1[14]); + + pol eq9_30 = (12388 * q1[15]); + + pol eq9_31 = + 0; + + + /******* + * + * EQ10: y1 - y2 - y3 + p * (q2 - offset) = 0 + * + *******/ + + pol eq10_0 = + (64839 * q2[0]) + - 518712 + y1[0] - y2[0] - y3[0]; + + pol eq10_1 = + (64839 * q2[1]) + + (55420 * q2[0]) + - 443360 + y1[1] - y2[1] - y3[1]; + + pol eq10_2 = + (64839 * q2[2]) + + (55420 * q2[1]) + + (35862 * q2[0]) + - 286896 + y1[2] - y2[2] - y3[2]; + + pol eq10_3 = + (64839 * q2[3]) + + (55420 * q2[2]) + + (35862 * q2[1]) + + (15392 * q2[0]) + - 123136 + y1[3] - y2[3] - y3[3]; + + pol eq10_4 = + (64839 * q2[4]) + + (55420 * q2[3]) + + (35862 * q2[2]) + + (15392 * q2[1]) + + (51853 * q2[0]) + - 414824 + y1[4] - y2[4] - y3[4]; + + pol eq10_5 = + (64839 * q2[5]) + + (55420 * q2[4]) + + (35862 * q2[3]) + + (15392 * q2[2]) + + (51853 * q2[1]) + + (26737 * q2[0]) + - 213896 + y1[5] - y2[5] - y3[5]; + + pol eq10_6 = + (64839 * q2[6]) + + (55420 * q2[5]) + + (35862 * q2[4]) + + (15392 * q2[3]) + + (51853 * q2[2]) + + (26737 * q2[1]) + + (27281 * q2[0]) + - 218248 + y1[6] - y2[6] - y3[6]; + + pol eq10_7 = + (64839 * q2[7]) + + (55420 * q2[6]) + + (35862 * q2[5]) + + (15392 * q2[4]) + + (51853 * q2[3]) + + (26737 * q2[2]) + + (27281 * q2[1]) + + (38785 * q2[0]) + - 310280 + y1[7] - y2[7] - y3[7]; + + pol eq10_8 = + (64839 * q2[8]) + + (55420 * q2[7]) + + (35862 * q2[6]) + + (15392 * q2[5]) + + (51853 * q2[4]) + + (26737 * q2[3]) + + (27281 * q2[2]) + + (38785 * q2[1]) + + (22621 * q2[0]) + - 180968 + y1[8] - y2[8] - y3[8]; + + pol eq10_9 = + (64839 * q2[9]) + + (55420 * q2[8]) + + (35862 * q2[7]) + + (15392 * q2[6]) + + (51853 * q2[5]) + + (26737 * q2[4]) + + (27281 * q2[3]) + + (38785 * q2[2]) + + (22621 * q2[1]) + + (33153 * q2[0]) + - 265224 + y1[9] - y2[9] - y3[9]; + + pol eq10_10 = + (64839 * q2[10]) + + (55420 * q2[9]) + + (35862 * q2[8]) + + (15392 * q2[7]) + + (51853 * q2[6]) + + (26737 * q2[5]) + + (27281 * q2[4]) + + (38785 * q2[3]) + + (22621 * q2[2]) + + (33153 * q2[1]) + + (17846 * q2[0]) + - 142768 + y1[10] - y2[10] - y3[10]; + + pol eq10_11 = + (64839 * q2[11]) + + (55420 * q2[10]) + + (35862 * q2[9]) + + (15392 * q2[8]) + + (51853 * q2[7]) + + (26737 * q2[6]) + + (27281 * q2[5]) + + (38785 * q2[4]) + + (22621 * q2[3]) + + (33153 * q2[2]) + + (17846 * q2[1]) + + (47184 * q2[0]) + - 377472 + y1[11] - y2[11] - y3[11]; + + pol eq10_12 = + (64839 * q2[12]) + + (55420 * q2[11]) + + (35862 * q2[10]) + + (15392 * q2[9]) + + (51853 * q2[8]) + + (26737 * q2[7]) + + (27281 * q2[6]) + + (38785 * q2[5]) + + (22621 * q2[4]) + + (33153 * q2[3]) + + (17846 * q2[2]) + + (47184 * q2[1]) + + (41001 * q2[0]) + - 328008 + y1[12] - y2[12] - y3[12]; + + pol eq10_13 = + (64839 * q2[13]) + + (55420 * q2[12]) + + (35862 * q2[11]) + + (15392 * q2[10]) + + (51853 * q2[9]) + + (26737 * q2[8]) + + (27281 * q2[7]) + + (38785 * q2[6]) + + (22621 * q2[5]) + + (33153 * q2[4]) + + (17846 * q2[3]) + + (47184 * q2[2]) + + (41001 * q2[1]) + + (57649 * q2[0]) + - 461192 + y1[13] - y2[13] - y3[13]; + + pol eq10_14 = + (64839 * q2[14]) + + (55420 * q2[13]) + + (35862 * q2[12]) + + (15392 * q2[11]) + + (51853 * q2[10]) + + (26737 * q2[9]) + + (27281 * q2[8]) + + (38785 * q2[7]) + + (22621 * q2[6]) + + (33153 * q2[5]) + + (17846 * q2[4]) + + (47184 * q2[3]) + + (41001 * q2[2]) + + (57649 * q2[1]) + + (20082 * q2[0]) + - 160656 + y1[14] - y2[14] - y3[14]; + + pol eq10_15 = + (64839 * q2[15]) + + (55420 * q2[14]) + + (35862 * q2[13]) + + (15392 * q2[12]) + + (51853 * q2[11]) + + (26737 * q2[10]) + + (27281 * q2[9]) + + (38785 * q2[8]) + + (22621 * q2[7]) + + (33153 * q2[6]) + + (17846 * q2[5]) + + (47184 * q2[4]) + + (41001 * q2[3]) + + (57649 * q2[2]) + + (20082 * q2[1]) + + (12388 * q2[0]) + - 99104 + y1[15] - y2[15] - y3[15]; + + pol eq10_16 = + (55420 * q2[15]) + + (35862 * q2[14]) + + (15392 * q2[13]) + + (51853 * q2[12]) + + (26737 * q2[11]) + + (27281 * q2[10]) + + (38785 * q2[9]) + + (22621 * q2[8]) + + (33153 * q2[7]) + + (17846 * q2[6]) + + (47184 * q2[5]) + + (41001 * q2[4]) + + (57649 * q2[3]) + + (20082 * q2[2]) + + (12388 * q2[1]); + + pol eq10_17 = + (35862 * q2[15]) + + (15392 * q2[14]) + + (51853 * q2[13]) + + (26737 * q2[12]) + + (27281 * q2[11]) + + (38785 * q2[10]) + + (22621 * q2[9]) + + (33153 * q2[8]) + + (17846 * q2[7]) + + (47184 * q2[6]) + + (41001 * q2[5]) + + (57649 * q2[4]) + + (20082 * q2[3]) + + (12388 * q2[2]); + + pol eq10_18 = + (15392 * q2[15]) + + (51853 * q2[14]) + + (26737 * q2[13]) + + (27281 * q2[12]) + + (38785 * q2[11]) + + (22621 * q2[10]) + + (33153 * q2[9]) + + (17846 * q2[8]) + + (47184 * q2[7]) + + (41001 * q2[6]) + + (57649 * q2[5]) + + (20082 * q2[4]) + + (12388 * q2[3]); + + pol eq10_19 = + (51853 * q2[15]) + + (26737 * q2[14]) + + (27281 * q2[13]) + + (38785 * q2[12]) + + (22621 * q2[11]) + + (33153 * q2[10]) + + (17846 * q2[9]) + + (47184 * q2[8]) + + (41001 * q2[7]) + + (57649 * q2[6]) + + (20082 * q2[5]) + + (12388 * q2[4]); + + pol eq10_20 = + (26737 * q2[15]) + + (27281 * q2[14]) + + (38785 * q2[13]) + + (22621 * q2[12]) + + (33153 * q2[11]) + + (17846 * q2[10]) + + (47184 * q2[9]) + + (41001 * q2[8]) + + (57649 * q2[7]) + + (20082 * q2[6]) + + (12388 * q2[5]); + + pol eq10_21 = + (27281 * q2[15]) + + (38785 * q2[14]) + + (22621 * q2[13]) + + (33153 * q2[12]) + + (17846 * q2[11]) + + (47184 * q2[10]) + + (41001 * q2[9]) + + (57649 * q2[8]) + + (20082 * q2[7]) + + (12388 * q2[6]); + + pol eq10_22 = + (38785 * q2[15]) + + (22621 * q2[14]) + + (33153 * q2[13]) + + (17846 * q2[12]) + + (47184 * q2[11]) + + (41001 * q2[10]) + + (57649 * q2[9]) + + (20082 * q2[8]) + + (12388 * q2[7]); + + pol eq10_23 = + (22621 * q2[15]) + + (33153 * q2[14]) + + (17846 * q2[13]) + + (47184 * q2[12]) + + (41001 * q2[11]) + + (57649 * q2[10]) + + (20082 * q2[9]) + + (12388 * q2[8]); + + pol eq10_24 = + (33153 * q2[15]) + + (17846 * q2[14]) + + (47184 * q2[13]) + + (41001 * q2[12]) + + (57649 * q2[11]) + + (20082 * q2[10]) + + (12388 * q2[9]); + + pol eq10_25 = + (17846 * q2[15]) + + (47184 * q2[14]) + + (41001 * q2[13]) + + (57649 * q2[12]) + + (20082 * q2[11]) + + (12388 * q2[10]); + + pol eq10_26 = + (47184 * q2[15]) + + (41001 * q2[14]) + + (57649 * q2[13]) + + (20082 * q2[12]) + + (12388 * q2[11]); + + pol eq10_27 = + (41001 * q2[15]) + + (57649 * q2[14]) + + (20082 * q2[13]) + + (12388 * q2[12]); + + pol eq10_28 = + (57649 * q2[15]) + + (20082 * q2[14]) + + (12388 * q2[13]); + + pol eq10_29 = + (20082 * q2[15]) + + (12388 * q2[14]); + + pol eq10_30 = (12388 * q2[15]); + + pol eq10_31 = + 0; + + + pol eq0 = eq0_0*Global.CLK32[0] + eq0_1*Global.CLK32[1] + eq0_2*Global.CLK32[2] + eq0_3*Global.CLK32[3] + eq0_4*Global.CLK32[4] + eq0_5*Global.CLK32[5] + eq0_6*Global.CLK32[6] + eq0_7*Global.CLK32[7] + + eq0_8*Global.CLK32[8] + eq0_9*Global.CLK32[9] + eq0_10*Global.CLK32[10] + eq0_11*Global.CLK32[11] + eq0_12*Global.CLK32[12] + eq0_13*Global.CLK32[13] + eq0_14*Global.CLK32[14] + eq0_15*Global.CLK32[15] + + eq0_16*Global.CLK32[16] + eq0_17*Global.CLK32[17] + eq0_18*Global.CLK32[18] + eq0_19*Global.CLK32[19] + eq0_20*Global.CLK32[20] + eq0_21*Global.CLK32[21] + eq0_22*Global.CLK32[22] + eq0_23*Global.CLK32[23] + + eq0_24*Global.CLK32[24] + eq0_25*Global.CLK32[25] + eq0_26*Global.CLK32[26] + eq0_27*Global.CLK32[27] + eq0_28*Global.CLK32[28] + eq0_29*Global.CLK32[29] + eq0_30*Global.CLK32[30] + eq0_31*Global.CLK32[31]; + pol eq1 = eq1_0*Global.CLK32[0] + eq1_1*Global.CLK32[1] + eq1_2*Global.CLK32[2] + eq1_3*Global.CLK32[3] + eq1_4*Global.CLK32[4] + eq1_5*Global.CLK32[5] + eq1_6*Global.CLK32[6] + eq1_7*Global.CLK32[7] + + eq1_8*Global.CLK32[8] + eq1_9*Global.CLK32[9] + eq1_10*Global.CLK32[10] + eq1_11*Global.CLK32[11] + eq1_12*Global.CLK32[12] + eq1_13*Global.CLK32[13] + eq1_14*Global.CLK32[14] + eq1_15*Global.CLK32[15] + + eq1_16*Global.CLK32[16] + eq1_17*Global.CLK32[17] + eq1_18*Global.CLK32[18] + eq1_19*Global.CLK32[19] + eq1_20*Global.CLK32[20] + eq1_21*Global.CLK32[21] + eq1_22*Global.CLK32[22] + eq1_23*Global.CLK32[23] + + eq1_24*Global.CLK32[24] + eq1_25*Global.CLK32[25] + eq1_26*Global.CLK32[26] + eq1_27*Global.CLK32[27] + eq1_28*Global.CLK32[28] + eq1_29*Global.CLK32[29] + eq1_30*Global.CLK32[30] + eq1_31*Global.CLK32[31]; + pol eq2 = eq2_0*Global.CLK32[0] + eq2_1*Global.CLK32[1] + eq2_2*Global.CLK32[2] + eq2_3*Global.CLK32[3] + eq2_4*Global.CLK32[4] + eq2_5*Global.CLK32[5] + eq2_6*Global.CLK32[6] + eq2_7*Global.CLK32[7] + + eq2_8*Global.CLK32[8] + eq2_9*Global.CLK32[9] + eq2_10*Global.CLK32[10] + eq2_11*Global.CLK32[11] + eq2_12*Global.CLK32[12] + eq2_13*Global.CLK32[13] + eq2_14*Global.CLK32[14] + eq2_15*Global.CLK32[15] + + eq2_16*Global.CLK32[16] + eq2_17*Global.CLK32[17] + eq2_18*Global.CLK32[18] + eq2_19*Global.CLK32[19] + eq2_20*Global.CLK32[20] + eq2_21*Global.CLK32[21] + eq2_22*Global.CLK32[22] + eq2_23*Global.CLK32[23] + + eq2_24*Global.CLK32[24] + eq2_25*Global.CLK32[25] + eq2_26*Global.CLK32[26] + eq2_27*Global.CLK32[27] + eq2_28*Global.CLK32[28] + eq2_29*Global.CLK32[29] + eq2_30*Global.CLK32[30] + eq2_31*Global.CLK32[31]; + pol eq3 = eq3_0*Global.CLK32[0] + eq3_1*Global.CLK32[1] + eq3_2*Global.CLK32[2] + eq3_3*Global.CLK32[3] + eq3_4*Global.CLK32[4] + eq3_5*Global.CLK32[5] + eq3_6*Global.CLK32[6] + eq3_7*Global.CLK32[7] + + eq3_8*Global.CLK32[8] + eq3_9*Global.CLK32[9] + eq3_10*Global.CLK32[10] + eq3_11*Global.CLK32[11] + eq3_12*Global.CLK32[12] + eq3_13*Global.CLK32[13] + eq3_14*Global.CLK32[14] + eq3_15*Global.CLK32[15] + + eq3_16*Global.CLK32[16] + eq3_17*Global.CLK32[17] + eq3_18*Global.CLK32[18] + eq3_19*Global.CLK32[19] + eq3_20*Global.CLK32[20] + eq3_21*Global.CLK32[21] + eq3_22*Global.CLK32[22] + eq3_23*Global.CLK32[23] + + eq3_24*Global.CLK32[24] + eq3_25*Global.CLK32[25] + eq3_26*Global.CLK32[26] + eq3_27*Global.CLK32[27] + eq3_28*Global.CLK32[28] + eq3_29*Global.CLK32[29] + eq3_30*Global.CLK32[30] + eq3_31*Global.CLK32[31]; + pol eq4 = eq4_0*Global.CLK32[0] + eq4_1*Global.CLK32[1] + eq4_2*Global.CLK32[2] + eq4_3*Global.CLK32[3] + eq4_4*Global.CLK32[4] + eq4_5*Global.CLK32[5] + eq4_6*Global.CLK32[6] + eq4_7*Global.CLK32[7] + + eq4_8*Global.CLK32[8] + eq4_9*Global.CLK32[9] + eq4_10*Global.CLK32[10] + eq4_11*Global.CLK32[11] + eq4_12*Global.CLK32[12] + eq4_13*Global.CLK32[13] + eq4_14*Global.CLK32[14] + eq4_15*Global.CLK32[15] + + eq4_16*Global.CLK32[16] + eq4_17*Global.CLK32[17] + eq4_18*Global.CLK32[18] + eq4_19*Global.CLK32[19] + eq4_20*Global.CLK32[20] + eq4_21*Global.CLK32[21] + eq4_22*Global.CLK32[22] + eq4_23*Global.CLK32[23] + + eq4_24*Global.CLK32[24] + eq4_25*Global.CLK32[25] + eq4_26*Global.CLK32[26] + eq4_27*Global.CLK32[27] + eq4_28*Global.CLK32[28] + eq4_29*Global.CLK32[29] + eq4_30*Global.CLK32[30] + eq4_31*Global.CLK32[31]; + pol eq5 = eq5_0*Global.CLK32[0] + eq5_1*Global.CLK32[1] + eq5_2*Global.CLK32[2] + eq5_3*Global.CLK32[3] + eq5_4*Global.CLK32[4] + eq5_5*Global.CLK32[5] + eq5_6*Global.CLK32[6] + eq5_7*Global.CLK32[7] + + eq5_8*Global.CLK32[8] + eq5_9*Global.CLK32[9] + eq5_10*Global.CLK32[10] + eq5_11*Global.CLK32[11] + eq5_12*Global.CLK32[12] + eq5_13*Global.CLK32[13] + eq5_14*Global.CLK32[14] + eq5_15*Global.CLK32[15] + + eq5_16*Global.CLK32[16] + eq5_17*Global.CLK32[17] + eq5_18*Global.CLK32[18] + eq5_19*Global.CLK32[19] + eq5_20*Global.CLK32[20] + eq5_21*Global.CLK32[21] + eq5_22*Global.CLK32[22] + eq5_23*Global.CLK32[23] + + eq5_24*Global.CLK32[24] + eq5_25*Global.CLK32[25] + eq5_26*Global.CLK32[26] + eq5_27*Global.CLK32[27] + eq5_28*Global.CLK32[28] + eq5_29*Global.CLK32[29] + eq5_30*Global.CLK32[30] + eq5_31*Global.CLK32[31]; + pol eq6 = eq6_0*Global.CLK32[0] + eq6_1*Global.CLK32[1] + eq6_2*Global.CLK32[2] + eq6_3*Global.CLK32[3] + eq6_4*Global.CLK32[4] + eq6_5*Global.CLK32[5] + eq6_6*Global.CLK32[6] + eq6_7*Global.CLK32[7] + + eq6_8*Global.CLK32[8] + eq6_9*Global.CLK32[9] + eq6_10*Global.CLK32[10] + eq6_11*Global.CLK32[11] + eq6_12*Global.CLK32[12] + eq6_13*Global.CLK32[13] + eq6_14*Global.CLK32[14] + eq6_15*Global.CLK32[15] + + eq6_16*Global.CLK32[16] + eq6_17*Global.CLK32[17] + eq6_18*Global.CLK32[18] + eq6_19*Global.CLK32[19] + eq6_20*Global.CLK32[20] + eq6_21*Global.CLK32[21] + eq6_22*Global.CLK32[22] + eq6_23*Global.CLK32[23] + + eq6_24*Global.CLK32[24] + eq6_25*Global.CLK32[25] + eq6_26*Global.CLK32[26] + eq6_27*Global.CLK32[27] + eq6_28*Global.CLK32[28] + eq6_29*Global.CLK32[29] + eq6_30*Global.CLK32[30] + eq6_31*Global.CLK32[31]; + pol eq7 = eq7_0*Global.CLK32[0] + eq7_1*Global.CLK32[1] + eq7_2*Global.CLK32[2] + eq7_3*Global.CLK32[3] + eq7_4*Global.CLK32[4] + eq7_5*Global.CLK32[5] + eq7_6*Global.CLK32[6] + eq7_7*Global.CLK32[7] + + eq7_8*Global.CLK32[8] + eq7_9*Global.CLK32[9] + eq7_10*Global.CLK32[10] + eq7_11*Global.CLK32[11] + eq7_12*Global.CLK32[12] + eq7_13*Global.CLK32[13] + eq7_14*Global.CLK32[14] + eq7_15*Global.CLK32[15] + + eq7_16*Global.CLK32[16] + eq7_17*Global.CLK32[17] + eq7_18*Global.CLK32[18] + eq7_19*Global.CLK32[19] + eq7_20*Global.CLK32[20] + eq7_21*Global.CLK32[21] + eq7_22*Global.CLK32[22] + eq7_23*Global.CLK32[23] + + eq7_24*Global.CLK32[24] + eq7_25*Global.CLK32[25] + eq7_26*Global.CLK32[26] + eq7_27*Global.CLK32[27] + eq7_28*Global.CLK32[28] + eq7_29*Global.CLK32[29] + eq7_30*Global.CLK32[30] + eq7_31*Global.CLK32[31]; + pol eq8 = eq8_0*Global.CLK32[0] + eq8_1*Global.CLK32[1] + eq8_2*Global.CLK32[2] + eq8_3*Global.CLK32[3] + eq8_4*Global.CLK32[4] + eq8_5*Global.CLK32[5] + eq8_6*Global.CLK32[6] + eq8_7*Global.CLK32[7] + + eq8_8*Global.CLK32[8] + eq8_9*Global.CLK32[9] + eq8_10*Global.CLK32[10] + eq8_11*Global.CLK32[11] + eq8_12*Global.CLK32[12] + eq8_13*Global.CLK32[13] + eq8_14*Global.CLK32[14] + eq8_15*Global.CLK32[15] + + eq8_16*Global.CLK32[16] + eq8_17*Global.CLK32[17] + eq8_18*Global.CLK32[18] + eq8_19*Global.CLK32[19] + eq8_20*Global.CLK32[20] + eq8_21*Global.CLK32[21] + eq8_22*Global.CLK32[22] + eq8_23*Global.CLK32[23] + + eq8_24*Global.CLK32[24] + eq8_25*Global.CLK32[25] + eq8_26*Global.CLK32[26] + eq8_27*Global.CLK32[27] + eq8_28*Global.CLK32[28] + eq8_29*Global.CLK32[29] + eq8_30*Global.CLK32[30] + eq8_31*Global.CLK32[31]; + pol eq9 = eq9_0*Global.CLK32[0] + eq9_1*Global.CLK32[1] + eq9_2*Global.CLK32[2] + eq9_3*Global.CLK32[3] + eq9_4*Global.CLK32[4] + eq9_5*Global.CLK32[5] + eq9_6*Global.CLK32[6] + eq9_7*Global.CLK32[7] + + eq9_8*Global.CLK32[8] + eq9_9*Global.CLK32[9] + eq9_10*Global.CLK32[10] + eq9_11*Global.CLK32[11] + eq9_12*Global.CLK32[12] + eq9_13*Global.CLK32[13] + eq9_14*Global.CLK32[14] + eq9_15*Global.CLK32[15] + + eq9_16*Global.CLK32[16] + eq9_17*Global.CLK32[17] + eq9_18*Global.CLK32[18] + eq9_19*Global.CLK32[19] + eq9_20*Global.CLK32[20] + eq9_21*Global.CLK32[21] + eq9_22*Global.CLK32[22] + eq9_23*Global.CLK32[23] + + eq9_24*Global.CLK32[24] + eq9_25*Global.CLK32[25] + eq9_26*Global.CLK32[26] + eq9_27*Global.CLK32[27] + eq9_28*Global.CLK32[28] + eq9_29*Global.CLK32[29] + eq9_30*Global.CLK32[30] + eq9_31*Global.CLK32[31]; + pol eq10 = eq10_0*Global.CLK32[0] + eq10_1*Global.CLK32[1] + eq10_2*Global.CLK32[2] + eq10_3*Global.CLK32[3] + eq10_4*Global.CLK32[4] + eq10_5*Global.CLK32[5] + eq10_6*Global.CLK32[6] + eq10_7*Global.CLK32[7] + + eq10_8*Global.CLK32[8] + eq10_9*Global.CLK32[9] + eq10_10*Global.CLK32[10] + eq10_11*Global.CLK32[11] + eq10_12*Global.CLK32[12] + eq10_13*Global.CLK32[13] + eq10_14*Global.CLK32[14] + eq10_15*Global.CLK32[15] + + eq10_16*Global.CLK32[16] + eq10_17*Global.CLK32[17] + eq10_18*Global.CLK32[18] + eq10_19*Global.CLK32[19] + eq10_20*Global.CLK32[20] + eq10_21*Global.CLK32[21] + eq10_22*Global.CLK32[22] + eq10_23*Global.CLK32[23] + + eq10_24*Global.CLK32[24] + eq10_25*Global.CLK32[25] + eq10_26*Global.CLK32[26] + eq10_27*Global.CLK32[27] + eq10_28*Global.CLK32[28] + eq10_29*Global.CLK32[29] + eq10_30*Global.CLK32[30] + eq10_31*Global.CLK32[31]; + + pol commit selEq[7]; + + selEq[0]' * (1-Global.CLK32[31]) = selEq[0] * (1-Global.CLK32[31]); + selEq[1]' * (1-Global.CLK32[31]) = selEq[1] * (1-Global.CLK32[31]); + selEq[2]' * (1-Global.CLK32[31]) = selEq[2] * (1-Global.CLK32[31]); + selEq[3]' * (1-Global.CLK32[31]) = selEq[3] * (1-Global.CLK32[31]); + selEq[4]' * (1-Global.CLK32[31]) = selEq[4] * (1-Global.CLK32[31]); + selEq[5]' * (1-Global.CLK32[31]) = selEq[5] * (1-Global.CLK32[31]); + selEq[6]' * (1-Global.CLK32[31]) = selEq[6] * (1-Global.CLK32[31]); + + selEq[0] * (1-selEq[0]) = 0; + selEq[1] * (1-selEq[1]) = 0; + selEq[2] * (1-selEq[2]) = 0; + selEq[3] * (1-selEq[3]) = 0; + selEq[4] * (1-selEq[4]) = 0; + selEq[5] * (1-selEq[5]) = 0; + selEq[6] * (1-selEq[6]) = 0; + + + pol commit carry[3]; + + carry[0] * Global.CLK32[0] = 0; + carry[1] * Global.CLK32[0] = 0; + carry[2] * Global.CLK32[0] = 0; + + carry[0] in GL_SIGNED_22BITS; + carry[1] in GL_SIGNED_22BITS; + carry[2] in GL_SIGNED_22BITS; + + selEq[0] * (eq0 + carry[0]) = selEq[0] * carry[0]' * 2**16; + selEq[1] * (eq1 + carry[0]) = selEq[1] * carry[0]' * 2**16; + selEq[2] * (eq2 + carry[0]) = selEq[2] * carry[0]' * 2**16; + selEq[3] * (eq3 + carry[1]) = selEq[3] * carry[1]' * 2**16; + selEq[3] * (eq4 + carry[2]) = selEq[3] * carry[2]' * 2**16; + selEq[4] * (eq5 + carry[1]) = selEq[4] * carry[1]' * 2**16; + selEq[4] * (eq6 + carry[2]) = selEq[4] * carry[2]' * 2**16; + selEq[5] * (eq7 + carry[1]) = selEq[5] * carry[1]' * 2**16; + selEq[5] * (eq8 + carry[2]) = selEq[5] * carry[2]' * 2**16; + selEq[6] * (eq9 + carry[1]) = selEq[6] * carry[1]' * 2**16; + selEq[6] * (eq10 + carry[2]) = selEq[6] * carry[2]' * 2**16; +} + +// xy x15 x14 x13 x12 x11 x10 x9 x8 x7 x6 x5 x4 x3 x2 x1 x0 y15 y14 y13 y12 y11 y10 y9 y8 y7 y6 y5 y4 y3 y2 y1 y0 +// cl0 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 +// cl1 -1 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 +// cl2 -2 -1 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 +// cl3 -3 -2 -1 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 +// cl4 -4 -3 -2 -1 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 +// cl5 -5 -4 -3 -2 -1 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 +// cl6 -6 -5 -4 -3 -2 -1 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 +// cl7 -7 -6 -5 -4 -3 -2 -1 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 +// cl8 -8 -7 -6 -5 -4 -3 -2 -1 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 +// cl9 -9 -8 -7 -6 -5 -4 -3 -2 -1 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 +// cl10 -10 -9 -8 -7 -6 -5 -4 -3 -2 -1 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 +// cl11 -11 -10 -9 -8 -7 -6 -5 -4 -3 -2 -1 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 +// cl12 -12 -11 -10 -9 -8 -7 -6 -5 -4 -3 -2 -1 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 +// cl13 -13 -12 -11 -10 -9 -8 -7 -6 -5 -4 -3 -2 -1 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 +// cl14 -14 -13 -12 -11 -10 -9 -8 -7 -6 -5 -4 -3 -2 -1 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 +// cl15 -15 -14 -13 -12 -11 -10 -9 -8 -7 -6 -5 -4 -3 -2 -1 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 +// cl16 -16 -15 -14 -13 -12 -11 -10 -9 -8 -7 -6 -5 -4 -3 -2 -1 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 +// cl17 -17 -16 -15 -14 -13 -12 -11 -10 -9 -8 -7 -6 -5 -4 -3 -2 -1 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 +// cl18 -18 -17 -16 -15 -14 -13 -12 -11 -10 -9 -8 -7 -6 -5 -4 -3 -2 -1 0 1 2 3 4 5 6 7 8 9 10 11 12 13 +// cl19 -19 -18 -17 -16 -15 -14 -13 -12 -11 -10 -9 -8 -7 -6 -5 -4 -3 -2 -1 0 1 2 3 4 5 6 7 8 9 10 11 12 +// cl20 -20 -19 -18 -17 -16 -15 -14 -13 -12 -11 -10 -9 -8 -7 -6 -5 -4 -3 -2 -1 0 1 2 3 4 5 6 7 8 9 10 11 +// cl21 -21 -20 -19 -18 -17 -16 -15 -14 -13 -12 -11 -10 -9 -8 -7 -6 -5 -4 -3 -2 -1 0 1 2 3 4 5 6 7 8 9 10 +// cl22 -22 -21 -20 -19 -18 -17 -16 -15 -14 -13 -12 -11 -10 -9 -8 -7 -6 -5 -4 -3 -2 -1 0 1 2 3 4 5 6 7 8 9 +// cl23 -23 -22 -21 -20 -19 -18 -17 -16 -15 -14 -13 -12 -11 -10 -9 -8 -7 -6 -5 -4 -3 -2 -1 0 1 2 3 4 5 6 7 8 +// cl24 -24 -23 -22 -21 -20 -19 -18 -17 -16 -15 -14 -13 -12 -11 -10 -9 -8 -7 -6 -5 -4 -3 -2 -1 0 1 2 3 4 5 6 7 +// cl25 -25 -24 -23 -22 -21 -20 -19 -18 -17 -16 -15 -14 -13 -12 -11 -10 -9 -8 -7 -6 -5 -4 -3 -2 -1 0 1 2 3 4 5 6 +// cl26 -26 -25 -24 -23 -22 -21 -20 -19 -18 -17 -16 -15 -14 -13 -12 -11 -10 -9 -8 -7 -6 -5 -4 -3 -2 -1 0 1 2 3 4 5 +// cl27 -27 -26 -25 -24 -23 -22 -21 -20 -19 -18 -17 -16 -15 -14 -13 -12 -11 -10 -9 -8 -7 -6 -5 -4 -3 -2 -1 0 1 2 3 4 +// cl28 -28 -27 -26 -25 -24 -23 -22 -21 -20 -19 -18 -17 -16 -15 -14 -13 -12 -11 -10 -9 -8 -7 -6 -5 -4 -3 -2 -1 0 1 2 3 +// cl29 -29 -28 -27 -26 -25 -24 -23 -22 -21 -20 -19 -18 -17 -16 -15 -14 -13 -12 -11 -10 -9 -8 -7 -6 -5 -4 -3 -2 -1 0 1 2 +// cl30 -30 -29 -28 -27 -26 -25 -24 -23 -22 -21 -20 -19 -18 -17 -16 -15 -14 -13 -12 -11 -10 -9 -8 -7 -6 -5 -4 -3 -2 -1 0 1 +// cl31 -31 -30 -29 -28 -27 -26 -25 -24 -23 -22 -21 -20 -19 -18 -17 -16 -15 -14 -13 -12 -11 -10 -9 -8 -7 -6 -5 -4 -3 -2 -1 0 +// +// rindex = 15 - index + + +private function i2nX(int index, int clock):int { + return (15 - index) - clock; +} + + +private function i2nY(int index, int clock):int { + return (15 - index) - clock + 16; +} \ No newline at end of file diff --git a/test/pil2/zkevm-etrog/binary.pil b/test/pil2/zkevm-etrog/binary.pil new file mode 100644 index 0000000..3b55b27 --- /dev/null +++ b/test/pil2/zkevm-etrog/binary.pil @@ -0,0 +1,149 @@ +// PIL State Machine that compute 256 bits operations: + +// ope │ opcode │ cin │ carry │ last │ ROWS │ NOTES +// ─────┼────────┼─────┼───────┼──────┼───────┼─────────────────────────────────── +// ADD │ 0 │ 0 │ X │ │ 2**17 │ could use cIn to ADC +// SUB │ 1 │ 0 │ X │ │ 2**17 │ +// LT │ 2 │ 0 │ X │ X │ 2**18 │ +// SLT │ 3 │ 0 │ X │ X │ 2**18 │ +// EQ │ 4 │ 0 │ X │ X │ 2**18 │ +// AND │ 5 │ 0 │ X │ X │ 2**17 │ use carry to detect any bit one +// OR │ 6 │ 0 │ │ │ 2**16 │ +// XOR │ 7 │ 0 │ │ │ 2**16 │ +// LT4 │ 8 │ 0 │ X │ X │ 2**18 │ TOTAL = 2**20 + 2**19 => 2**21 +// ┄┄┄┄┄│┄┄┄┄┄┄┄┄│┄┄┄┄┄│┄┄┄┄┄┄┄│┄┄┄┄┄┄│┄┄┄┄┄┄┄│┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄ + + +// bytes/clk │ clk │ cols │ area │ opens │ NOTES +// ───────────┼─────┼────────────────┼──────┼───────┼─────────────────────────────────── +// 2 │ 16 │ 8 + 4*2 = 16 │ 256 │ 17 │ +// 4 │ 8 │ 8 + 4*4 = 24 │ 192 │ 9 │ +// 8 │ 4 │ 8 + 4*8 = 40 │ 160 │ 5 │ +// 16 │ 2 │ 8 + 4*16 = 76 │ 152 │ 3 │ +// 32 │ 1 │ 8 + 4*32 = 136 │ 136 │ 2 │ + +const int BINARY_ID = 20; + +subproof aggregate Binary(2**21, 2**23, 2**25) { + + col fixed CLK0 = [1,0:3]...; + const expr RESET = CLK0; + + col witness freeInA[8], freeInB[8], freeInC[8]; // 8 x 1 Byte (2 inputs, 1 output) + col witness opcode; // operation code + col witness carry[9]; // 9 chunks carries [cin:0,cout:1],[cin:1,cout:2],...,[cin:6,cout:7] + col witness result; // selector of result binary operation + + // CLK0 1,0,0...0,0|1,0,0...0,0|1,0,.... + // result 0,0,0...0,1|0,0,0...0,1|0,0,.... + // 'result 1,0,0...0,0|1,0,0...0,0|1,0,.... + (1 - CLK0) * 'result = 0; + result * (1 - result) = 0; + + ('opcode - opcode) * (1 - CLK0) === 0; + + const expr cIn = carry[0]; + const expr cOut = carry[8]; + + (1 - CLK0) * ('cOut - cIn) === 0; + + for (int index = 0; index < length(carry); index += 1) { + carry[index] * (1 - carry[index]) === 0; + } + + // LT4 (opcode = 8) + // + // This instruction operates over 4 chunks of 64 bits, so we divide the 256-bit values "a" and "b" in 4 chunks of 64 bits. It verifies + // that the 4 "a" chunks are LESS THAN the 4 "b" chunks, one-to-one. + // + // Examples: + // (0x0FFF...FFFF, 0x0FFF...FFFF, 0x0FFF...FFFF, 0x0FFF...FFFF) LT4 (0xFFFF...FFFF, 0xFFFF...FFFF, 0xFFFF...FFFF, 0xFFFF...FFFF) = 1 + // (0x0FFF...FFFF, 0x0FFF...FFFF, 0xFFFF...FFFF, 0x0FFF...FFFF) LT4 (0xFFFF...FFFF, 0xFFFF...FFFF, 0xFFFF...FFFF, 0xFFFF...FFFF) = 0 + // ^^^^^^^^^^^^^ ^^^^^^^^^^^^^ + // + // previousAreLt4: [binary value] flag (*) to indicate whether the first three chunks are lower than or not. + // It is 1 if all of the first three chunks of a are lower than those of b, and 0 otherwise. + // Before the first comparation is 0, and is set with the result of the first comparation. After that, the value is propagated. + // In particular, on the comparisons of the second and third chunks, the result of the comparison (cOut) is multiplied by its value, + // to force it being zero if some of the previous comparison are zero. It works similar to the AND operator. + // Mathematically, this is: + // first chunk --> previousAreLt4 = cOut + // second chunk --> previousAreLt4 = previousAreLt4 * cOut + // third chunk --> previousAreLt4 = previousAreLt4 * cOut + // fourth chunk --> no affects to previousAreLt4 + // + // usePreviousAreLt4: [binary value] flag (**) to use the value of previousAreLt4. It is only active if: + // (a) we are at the last byte, (b) we are in the LT4 operation and (c) it happens that cOut = 1. + // In the last clock, we have: + // · If cOut = 1, then lastChunk(a) < lastChunk(b). Then a LT4 b if the previous chunks are also lower. + // · If cOut = 0, then lastChunk(a) >= lastChunk(b). Then, it doesn't matter the previous chunks; the result of a LT4 b is cOut = 0. + // + // reset4: [binary value] flag (**) to indicate that cIn is reset each 4 clocks in the LT4 operation. + // + // NOTE: (*) Flag is validated by lookup values. + // + // NOTE: (**) To validate the flags usePreviousAreLt4, reset4, useCarry and cOut, check that the composition: + // cout + 2 * useCarry + 4 * usePreviousAreLt4 + 8 * reset4 + // is in P_FLAGS. + // After the last optimization, these flags MUST BE constrained to be binary. + // + + col witness previousAreLt4; + col witness usePreviousAreLt4; + col witness reset4; + col witness useCarry; + + previousAreLt4 * (1 - previousAreLt4) === 0; + usePreviousAreLt4 * (1 - usePreviousAreLt4) === 0; + reset4 * (1 - reset4) === 0; + useCarry * (1 - useCarry) === 0; + cOut * (1 - cOut) === 0; + + // RESET = Global.CLK32[0] + Global.CLK32[16]; + + cIn' === cOut * ( 1 - RESET' + reset4 * (Global.CLK32[3] + Global.CLK32[7] + Global.CLK32[11] + + Global.CLK32[19] + Global.CLK32[23] + Global.CLK32[27])); + + // LT4_PROPAGATE (polynomial made up of constant, binary and disjoint polynomials, therefore it's a constant and binary polynomial) + // + // Each 4 clocks this sm has processed 8 bytes = 64 bits, last clock isn't relevant last clock cOut is ignored because: + // · last cout = 0 => means LT4 = 0 (if the last chunk of a isn't lower than the last of b then we are done). + // · last cout = 1 => means last a chunk is less than b, in this path result only deepends of ge4 value. + + previousAreLt4' === (CLK0 + previousAreLt4) * cOut; + + // P_FLAGS = cOut + 2 * useCarry + 4 * usePreviousAreLt4 + 8 * reset4 + // In even byte clocks, useCarry = usePreviousAreLt4 = 0 and cOut = cMiddle, therefore P_FLAGS = cMiddle + 8 * reset4 + for (int index = 0; index < 7; ++index) { + lookup_assumes(BINARY_OPS_TABLE_ID ,1 ,[ 0, opcode, freeInA[index], freeInB[index], carry[index], freeInC[index], carry[index + 1]]); + } + lookup_assumes(BINARY_OPS_TABLE_ID ,1 ,[result, opcode, freeInA[7], freeInB[7], carry[7], freeInC[7], carry[8] + 2 * useCarry + 4 * usePreviousAreLt4 + 8 * reset4]); + + useCarry * usePreviousAreLt4 === 0; + + // a === freeInA[0] + 2**8 * freeInA[1] + 2**16 * freeInA[2] + 2**24 * freeInA[3]; + // b === freeInB[0] + 2**8 * freeInB[1] + 2**16 * freeInB[2] + 2**24 * freeInB[3]; + + // TODO: verify on each 8 clocks + // c === useCarry * cOut + usePreviousAreLt4 * previousAreLt + (1 - useCarry - usePreviousAreLt4) * (freeInC[0] + 2**8 * freeInC[1] + 2**16 * freeInC[2] + 2**24 * freeInC[3]); + + // In the last byte, when useCarry or usePreviousAreLt4 are 1, the value of c[0] needs to change + // to result (0 or 1). In the first clock, freeInC must be changed to match with the lookup + // because lookup is a static table (has a 0 for comparators), but useCarry or + // usePreviousAreLt4 are dynamic. Otherwise, useCarry and usePreviousAreLt4 are enabled only in the last byte + // (verified lookup only enabled when P_LAST = 1). + + // In the last byte, only FACTOR[7] is active, and freeInC only affects to c[7]'. + + // on last clock freeInA[7] = HSB and 3'freeInA[0] = LSB + expr a,b,c; + for (int clk = 0; clk < 4; clk += 1 ) { + for (int index = 0; index < 8; index += ) { + a = a * 256 + clk'freeInA[7-index]; + b = b * 256 + clk'freeInB[7-index]; + c = c * 256 + clk'freeInC[7-index]; + } + } + const expr opCarryOut = usePreviousAreLt * (previousAreLt4 - cOut) + cOut; + multiset_proves(BINARY_ID, result,[opcode, a, b, (useCarry + usePreviousAreLt) * (opCarryOut - c) + c, cIn, opCarryOut]); +} \ No newline at end of file diff --git a/test/pil2/zkevm-etrog/binary_one_row.pil b/test/pil2/zkevm-etrog/binary_one_row.pil new file mode 100644 index 0000000..a0c7500 --- /dev/null +++ b/test/pil2/zkevm-etrog/binary_one_row.pil @@ -0,0 +1,155 @@ +// PIL State Machine that compute 256 bits operations: + +// ope │ opcode │ cin │ carry │ last │ ROWS │ NOTES +// ─────┼────────┼─────┼───────┼──────┼───────┼─────────────────────────────────── +// ADD │ 0 │ 0 │ X │ │ 2**17 │ could use cIn to ADC +// SUB │ 1 │ 0 │ X │ │ 2**17 │ +// LT │ 2 │ 0 │ X │ X │ 2**18 │ +// SLT │ 3 │ 0 │ X │ X │ 2**18 │ +// EQ │ 4 │ 0 │ X │ X │ 2**18 │ +// AND │ 5 │ 0 │ X │ X │ 2**17 │ use carry to detect any bit one +// OR │ 6 │ 0 │ │ │ 2**16 │ +// XOR │ 7 │ 0 │ │ │ 2**16 │ +// LT4 │ 8 │ 0 │ X │ X │ 2**18 │ TOTAL = 2**20 + 2**19 => 2**21 +// ┄┄┄┄┄│┄┄┄┄┄┄┄┄│┄┄┄┄┄│┄┄┄┄┄┄┄│┄┄┄┄┄┄│┄┄┄┄┄┄┄│┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄ + + +// ope │ opcode │ cin │ carry │ last │ ROWS │ NOTES +// ─────┼────────┼─────┼───────┼──────┼───────┼─────────────────────────────────── +// ADD │ 0 │ 0 │ X │ │ 2**17 │ could use cIn to ADC +// SUB │ 1 │ 0 │ X │ │ 2**17 │ +// OR │ 6 │ 0 │ │ │ 2**16 │ +// XOR │ 7 │ 0 │ │ │ 2**16 │ +// LT │ 2 │ 0 │ X │ X │ 2**18 │ +// SLT │ 3 │ 0 │ X │ X │ 2**18 │ +// EQ │ 4 │ 0 │ X │ X │ 2**18 │ +// AND │ 5 │ 0 │ X │ X │ 2**17 │ use carry to detect any bit one +// LT4 │ 8 │ 0 │ X │ X │ 2**18 │ TOTAL = 2**20 + 2**19 => 2**21 +// ┄┄┄┄┄│┄┄┄┄┄┄┄┄│┄┄┄┄┄│┄┄┄┄┄┄┄│┄┄┄┄┄┄│┄┄┄┄┄┄┄│┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄ + + +// bytes/clk │ clk │ cols │ area │ lookups │ opens │ NOTES +// ───────────┼─────┼────────────────┼──────┼─────────┼───────┼─────────────────────────────────── +// 2 │ 16 │ 8 + 4*2 = 16 │ 256 │ 2 │ 17 │ +// 4 │ 8 │ 8 + 4*4 = 24 │ 192 │ 4 │ 9 │ +// 8 │ 4 │ 8 + 4*8 = 40 │ 160 │ 8 │ 5 │ +// 16 │ 2 │ 8 + 4*16 = 76 │ 152 │ 16 │ 3 │ +// 32 │ 1 │ 8 + 4*32 = 136 │ 136 │ 32 │ 2 │ + +const int BINARY_ID = 20; + +subproof aggregate Binary(2**21, 2**23, 2**25) { + + col witness freeInA[32], freeInB[32], freeInC[32]; // 8 x 1 Byte (2 inputs, 1 output) + col witness opcode; // operation code + col witness carry[33]; // 9 chunks carries [cin:0,cout:1],[cin:1,cout:2],...,[cin:6,cout:7] + col witness result; // selector of result binary operation + + // CLK0 1,0,0...0,0|1,0,0...0,0|1,0,.... + // result 0,0,0...0,1|0,0,0...0,1|0,0,.... + // 'result 1,0,0...0,0|1,0,0...0,0|1,0,.... + result * (1 - result) = 0; + + const expr cIn = carry[0]; + const expr cOut = carry[32]; + + for (int index = 0; index < length(carry); index += 1) { + carry[index] * (1 - carry[index]) === 0; + } + + // LT4 (opcode = 8) + // + // This instruction operates over 4 chunks of 64 bits, so we divide the 256-bit values "a" and "b" in 4 chunks of 64 bits. It verifies + // that the 4 "a" chunks are LESS THAN the 4 "b" chunks, one-to-one. + // + // Examples: + // (0x0FFF...FFFF, 0x0FFF...FFFF, 0x0FFF...FFFF, 0x0FFF...FFFF) LT4 (0xFFFF...FFFF, 0xFFFF...FFFF, 0xFFFF...FFFF, 0xFFFF...FFFF) = 1 + // (0x0FFF...FFFF, 0x0FFF...FFFF, 0xFFFF...FFFF, 0x0FFF...FFFF) LT4 (0xFFFF...FFFF, 0xFFFF...FFFF, 0xFFFF...FFFF, 0xFFFF...FFFF) = 0 + // ^^^^^^^^^^^^^ ^^^^^^^^^^^^^ + // + // previousAreLt4: [binary value] flag (*) to indicate whether the first three chunks are lower than or not. + // It is 1 if all of the first three chunks of a are lower than those of b, and 0 otherwise. + // Before the first comparation is 0, and is set with the result of the first comparation. After that, the value is propagated. + // In particular, on the comparisons of the second and third chunks, the result of the comparison (cOut) is multiplied by its value, + // to force it being zero if some of the previous comparison are zero. It works similar to the AND operator. + // Mathematically, this is: + // first chunk --> previousAreLt4 = cOut + // second chunk --> previousAreLt4 = previousAreLt4 * cOut + // third chunk --> previousAreLt4 = previousAreLt4 * cOut + // fourth chunk --> no affects to previousAreLt4 + // + // usePreviousAreLt4: [binary value] flag (**) to use the value of previousAreLt4. It is only active if: + // (a) we are at the last byte, (b) we are in the LT4 operation and (c) it happens that cOut = 1. + // In the last clock, we have: + // · If cOut = 1, then lastChunk(a) < lastChunk(b). Then a LT4 b if the previous chunks are also lower. + // · If cOut = 0, then lastChunk(a) >= lastChunk(b). Then, it doesn't matter the previous chunks; the result of a LT4 b is cOut = 0. + // + // reset4: [binary value] flag (**) to indicate that cIn is reset each 4 clocks in the LT4 operation. + // + // NOTE: (*) Flag is validated by lookup values. + // + // NOTE: (**) To validate the flags usePreviousAreLt4, reset4, useCarry and cOut, check that the composition: + // cout + 2 * useCarry + 4 * usePreviousAreLt4 + 8 * reset4 + // is in P_FLAGS. + // After the last optimization, these flags MUST BE constrained to be binary. + // + + col witness previousAreLt4; + col witness usePreviousAreLt4; + col witness reset4; + col witness useCarry; + + previousAreLt4 * (1 - previousAreLt4) === 0; + usePreviousAreLt4 * (1 - usePreviousAreLt4) === 0; + reset4 * (1 - reset4) === 0; + useCarry * (1 - useCarry) === 0; + cOut * (1 - cOut) === 0; + + // RESET = Global.CLK32[0] + Global.CLK32[16]; + + cIn' === cOut * ( 1 - RESET' + reset4 * (Global.CLK32[3] + Global.CLK32[7] + Global.CLK32[11] + + Global.CLK32[19] + Global.CLK32[23] + Global.CLK32[27])); + + // LT4_PROPAGATE (polynomial made up of constant, binary and disjoint polynomials, therefore it's a constant and binary polynomial) + // + // Each 4 clocks this sm has processed 8 bytes = 64 bits, last clock isn't relevant last clock cOut is ignored because: + // · last cout = 0 => means LT4 = 0 (if the last chunk of a isn't lower than the last of b then we are done). + // · last cout = 1 => means last a chunk is less than b, in this path result only deepends of ge4 value. + + previousAreLt4' === (CLK0 + previousAreLt4) * cOut; + + // P_FLAGS = cOut + 2 * useCarry + 4 * usePreviousAreLt4 + 8 * reset4 + // In even byte clocks, useCarry = usePreviousAreLt4 = 0 and cOut = cMiddle, therefore P_FLAGS = cMiddle + 8 * reset4 + for (int index = 0; index < 7; ++index) { + lookup_assumes(BINARY_OPS_TABLE_ID ,1 ,[ 0, opcode, freeInA[index], freeInB[index], carry[index], freeInC[index], carry[index + 1]]); + } + lookup_assumes(BINARY_OPS_TABLE_ID ,1 ,[result, opcode, freeInA[7], freeInB[7], carry[7], freeInC[7], carry[8] + 2 * useCarry + 4 * usePreviousAreLt4 + 8 * reset4]); + + useCarry * usePreviousAreLt4 === 0; + + // a === freeInA[0] + 2**8 * freeInA[1] + 2**16 * freeInA[2] + 2**24 * freeInA[3]; + // b === freeInB[0] + 2**8 * freeInB[1] + 2**16 * freeInB[2] + 2**24 * freeInB[3]; + + // TODO: verify on each 8 clocks + // c === useCarry * cOut + usePreviousAreLt4 * previousAreLt + (1 - useCarry - usePreviousAreLt4) * (freeInC[0] + 2**8 * freeInC[1] + 2**16 * freeInC[2] + 2**24 * freeInC[3]); + + // In the last byte, when useCarry or usePreviousAreLt4 are 1, the value of c[0] needs to change + // to result (0 or 1). In the first clock, freeInC must be changed to match with the lookup + // because lookup is a static table (has a 0 for comparators), but useCarry or + // usePreviousAreLt4 are dynamic. Otherwise, useCarry and usePreviousAreLt4 are enabled only in the last byte + // (verified lookup only enabled when P_LAST = 1). + + // In the last byte, only FACTOR[7] is active, and freeInC only affects to c[7]'. + + // on last clock freeInA[7] = HSB and 3'freeInA[0] = LSB + expr a,b,c; + for (int clk = 0; clk < 4; clk += 1 ) { + for (int index = 0; index < 8; index += ) { + a = a * 256 + clk'freeInA[7-index]; + b = b * 256 + clk'freeInB[7-index]; + c = c * 256 + clk'freeInC[7-index]; + } + } + const expr opCarryOut = usePreviousAreLt * (previousAreLt4 - cOut) + cOut; + multiset_proves(BINARY_ID, result,[opcode, a, b, (useCarry + usePreviousAreLt) * (opCarryOut - c) + c, cIn, opCarryOut]); +} \ No newline at end of file diff --git a/test/pil2/zkevm-etrog/binary_ops_table.pil b/test/pil2/zkevm-etrog/binary_ops_table.pil new file mode 100644 index 0000000..817e1a0 --- /dev/null +++ b/test/pil2/zkevm-etrog/binary_ops_table.pil @@ -0,0 +1,85 @@ +// PIL Binary Operations Table used by Binary +// +// ADD (OP:0) +// SUB (OP:1) +// LT (OP:2) +// SLT (OP:3) +// EQ (OP:4) +// AND (OP:5) +// OR (OP:6) +// XOR (OP:7) +// LT4 (OP:8) + +const int BINARY_OPS_TABLE_ID = 21; + +subproof aggregate BinaryOpsTable(2**23) { + + constant OP_C = 256*256*4; // 2 CarryIn + 2 LastByte = 4 (OC = OPERATION CYCLE) + constant LAST_C = 256*256*2; // 2 CarryIn + + col fixed P_A = [0..255]...; // Input A (8 bits) + col fixed P_B = [0:256..255:256]...; // Input B (8 bits) + col fixed P_OP = [0:OP_C..7:OP_C]...; // Operation (3 bits) + col fixed P_CIN = [0:256*256,1:256*256]...; // CarryIn (1 bits) + col fixed P_LAST = [0:LAST_C, 1:LAST_C]...; // Last byte (1 bits) + col fixed P_USE_CARRY = [ 0:OP_C*2, // Carry => C (1 bits) - ADD,SUB + [0:LAST_C, 1:LAST_C]:3, // - LT,SLT,AND + 0:OP_C*2 ]...; // - OR,NOP + col fixed P_C; // Output C (8 bits) + col fixed P_COUT; // CarryOut (1 bits) + + // TODO pol RESET = Global.CLK32[0] + Global.CLK32[16]; + // col fixed RESET = [1,0:15]...; + col fixed FACTOR = [1, 2**16, 0:14]; + col fixed P_FLAGS; + col fixed FACTOR[8]; + + // P_FLAGS = cOut + 2 * useCarry + 4 * usePreviousAreLt4 + 8 * reset4 + // In even byte clocks, useCarry = usePreviousAreLt4 = 0 and cOut = cMiddle, therefore P_FLAGS = cMiddle + 8 * reset4 + lockup_proves(BINARY_OPS_TABLE_ID, 1,[P_LAST, P_OPCODE, Global.BYTE_2A, Global.BYTE, P_CIN, P_C, P_FLAGS]); + + for (int i = 0; i < OP_C; ++i) { + fe [a, b, cin, plast, c, cout, op] = [P_A[i], P_B[i], P_CIN[i], P_LAST[i], 0, 0, P_OPCODE[i]]; + + switch (op) { + case 0: // ADD + c = (cin + a + b) & 0xFF; + cout = (cin + a + b) >> 8; + + case 1: // SUB + cout = ((a - cin) >= b ? 0 : 1); + c = 256 * cout + a - cin - b; + + case 2,3: // LT,SLT + if (a < b) { + cout = 1; + c = plast; + } else if (a == b) { + cout = cin; + c = plast * cin; + } + if (op == 3 && plast && (a & 0x80) != (b & 0x80)) { + c = (a & 0x80); + cout = c; + } + + case 4: // EQ + if (a == b && !cin) c = plast; + else cout = 1; + cout = plast ? !cout : cout; + + case 5: // AND + c = a & b; + cout = cin || c; + + case 6: // OR + c = a | b; + + case 7: // XOR + c = a ^ b; + + } + P_C[i] = c; + P_COUT[i] = c; + } + diff --git a/test/pil2/zkevm-etrog/climb_key.pil b/test/pil2/zkevm-etrog/climb_key.pil new file mode 100644 index 0000000..06a255d --- /dev/null +++ b/test/pil2/zkevm-etrog/climb_key.pil @@ -0,0 +1,116 @@ +const int CLIMB_KEY_ID = 92; + +// ClimbKey +// +// Description: +// ============ +// SM to correctly navigate (climb up) the given merkle tree path. Here, by correct, we mean verifying that not overflow occurs. +// The overflowing is detected by not including ALL possible combinations of values that produce an overflow in the lookup. +// +// usage: +// multiset_assumes(CLIMB_KEY_ID, selector, [keyIn[0], keyIn[1], keyIn[2], keyIn[3], level, bit, keyOut[0], keyOut[1], keyOut[2], keyOut[3]]); + +subproof ClimbKey(2**16) { + + // keyIn goldilock with 4 input keys, one by clock (CLK[i]: keyIn = keyIn[i]) + col witness keyIn; + + // keyOut four output keys, one by clock (CLK[i]: keyIn = keyOut[i]) + col witness keyOut; + + // msb_level a value of 6 bits to indicate the most significant level bits of the tree (depth), level = 0 → top of tree (root) + col witness msb_level; + + // keyIn/Out selector keySel when keySel == 0 → keyIn is the active key for current level + col witness keySel; + + // keyInChunk = Value of the current chunk (maximum 18 bits) used to verify by the lookup and in the rebuild of the key. + // Size of keyInChunk is 18 bits on CLK0, 17 bits on CLK1 and CLK2 and 12 bits for CLK3. + // keyInClunk = CLK0 * keyIn[0..17] + CLK1 * keyIn[18..34] + CLK2 * keyIn[35..51] + CLK3 * keyIn[52..63] + col witness keyInChunk; + + // Result is used to relate the storage SM with this SM via permutation + col witness result; + + // On CLK0, carryLt == bit, for the rest of clocks used to link "state" between chunks + // carryLt = carry + 2 * lt + // clin = carryLtIn, clout = carryLtOut + // + // CLK0 CLK1 CLK2 CLK3 + // ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐ + // bit─>│clin │ ┌─>│clin │ ┌─>│clin │ ┌─>│clin │ + // │ │ │ │ │ │ │ │ │ │ │ + // │ clout│───┘ │ clout│───┘ │ clout│───┘ │ clout│ + // └─────────┘ └─────────┘ └─────────┘ └─────────┘ + // + // bit is carryLt on CLK0, it's bit to add to climb up the path + + col witness carryLt; + + // clocks: CLK0, CLK1, CLK2, CLK3 + col fixed CLK3 = [0,0,0,1]...; + const expr CLK0 = 3'CLK2; + const expr CLK1 = 2'CLK2; + const expr CLK2 = 'CLK2; + + // + // Examples + // + // │ CLK │ keyIn │ keyOut │ keySel │ keyInChunk │ carryLt | h_level | result | CLK2 relative │ + // ├──────┼────────┼─────────────────────────┼────────┼────────────────┼─────────┼─────────┼────────┼───────────────┤ + // │ CLK0 │ keyIn0 │ keyOut0 (=KeyIn0) │ 0 │ keyIn1[0..17] │ bit │ 0 │ 0 │ 3'x │ + // │ CLK1 │ keyIn1 │ keyOut1 (=KeyIn1*2+bit) │ 1 │ keyIn1[18..34] │ x │ 0 │ 0 │ 2'x │ + // │ CLK2 │ keyIn2 │ keyOut2 (=KeyIn2) │ 0 │ keyIn1[35..51] │ x │ 0 │ 0 │ 'x │ + // │ CLK3 │ keyIn3 │ keyOut3 (=KeyIn3) │ 0 │ keyIn1[52..63] │ x │ h_level │ 1 │ x │ + // + // │ CLK │ keyIn │ keyOut │ keySel │ keyInChunk │ carryLt | h_level | result | CLK2 relative │ + // ├──────┼────────┼─────────────────────────┼────────┼────────────────┼─────────┼─────────┼────────┼───────────────┤ + // │ CLK0 │ keyIn0 │ keyOut0 (=KeyIn0) │ 0 │ keyIn3[0..17] │ bit │ 0 │ 0 │ 3'x │ + // │ CLK1 │ keyIn1 │ keyOut1 (=KeyIn1) │ 0 │ keyIn3[18..34] │ x │ 0 │ 0 │ 2'x │ + // │ CLK2 │ keyIn2 │ keyOut2 (=KeyIn2) │ 0 │ keyIn3[35..51] │ x │ 0 │ 0 │ 'x │ + // │ CLK3 │ keyIn3 │ keyOut3 (=KeyIn3*2+bit) │ 1 │ keyIn3[52..63] │ x │ h_level │ 1 │ x │ + + + // binary constraints + keySel * (1 - keySel) === 0; + result * (1 - result) === 0; + + // bit for each clock, on CLK0 take carryLt value, on CLK1 get the previous value of carryLt,... + const expr bit = CLK0 * carryLt + CLK1 * 'carryLt + CLK2 * 2'carry + CLK3 * 3'carry; + + // if keySel == 0 → keyOut === keyIn + // if keySel == 1 → keyOut === keyIn * 2 + bit (climb-up operation) + keyOut === keyIn + keySel * (keyIn + bit); + + const expr keySel[4] = [3'keySel, 2'keySel, 'keySel, keySel]; + const expr keyIn[4] = [3'keyIn, 2'keyIn, 'keyIn, keyIn]; + const expr keyOut[4] = [3'keyOut, 2'keyOut, 'keyOut, keyOut]; + + // 1] KeyIn rebuild using chunks, keyInBuildByChunk only is used on CLK3 + const expr keyInBuildByChunk = 3'keyInChunk + 2'keyInChunk * 2**18 + 'keyInChunk * 2**35 + keyInChunk * 2**52; + + // 2] KeyIn selected with keySel + const expr keyInSelected = keySel0 * keyIn0 + keySel1 * keyIn1 + keySel2 * keyIn2 + keySel3 * keyIn3; + + // on CLK3 check that keyIn rebuild and keyInSelect are the same → means chunks are correctly calculated. The + // range check of these chunks values is verified throw CLIMB_KEY_TABLE. + CLK3 * (keyInBuildByChunk - keyInSelected) === 0; + + // If there is something to calculate result is equal to 1 at CLK3. In restant situations result is zero. + result * (1 - CLK3) = 0; + + // CLK is a sequence to identify the current clock 0,1,2,3,0,1,2,3. + const expr CLK = CLK1 + 2 * CLK2 + 3 * CLK3; + + // CLK0 (2 bits) + keyChunk = keyIn[ 0..17] 18 bits + carry (1 bits) = 19 bits (level = 0) + // CLK1 (2 bits) + keyChunk = keyIn[18..34] 17 bits + carryLt (2 bits) = 19 bits (level = 0) + // CLK2 (2 bits) + keyChunk = keyIn[35..51] 17 bits + carryLt (2 bits) = 19 bits (level = 0) + // CLK3 (2 bits) + keyChunk = keyIn[52..63] 12 bits + carryLt (2 bits) + level (6 bits) = 20 bits (*) + // (*) more than 50% of 2**12 are invalids for these reason they aren't included in table + // total size is 4 * 2 ** 19 = 2 ** 21 + + lookup_assumes(CLIMB_KEY_TABLE_ID, 1, [CLK, level * CLK3, keyInChunk, carryLt, (1 - CLK3) * carryLt']); + + const expr lsb_level = keySel[3] * 3 + keySel[2] * 2 + keySel[1] * 3; + multiset_proves(CLIMB_KEY_ID, result, [...keyIn, ...keySel, msb_level * 4 + lsb_level, bit, ...keyOut]); +} \ No newline at end of file diff --git a/test/pil2/zkevm-etrog/climb_key_table.pil b/test/pil2/zkevm-etrog/climb_key_table.pil new file mode 100644 index 0000000..b63f74d --- /dev/null +++ b/test/pil2/zkevm-etrog/climb_key_table.pil @@ -0,0 +1,115 @@ + +const int CLIMB_KEY_TABLE_ID = 93; + +subproof ClimbKeyTable(2**21) { + + col fixed CHUNK_VALUE = [[0...0x3FFFF]:2, + [0...0x1FFFF]:4, + [0...0x1FFFF]:4, + [0...0x7FF,0...0x7FE, 0...0x7FF, 0...0x1FE]:64]...; + + col fixed MSB_LEVEL = [[0:524288], + [0:524288], + [0:524288], + [0:8191..63:8191]]...; + + + col fixed CARRY_LT_IN = [[0:262144, 1:262144], + [0:131072...3:131072], + [0:131072...3:131072], + [0:2048, 1:2047, 2: 2048, 2:2048]:64]...; + + col fixed CARRY_LT_OUT = [[[2, 0:131071, 3, 1:131071], + [0:131071, 1:131071]], + [[2:57344, 0:8192, 3:57344, 1:8192], + [2:57344, 0:8191, 3:57344, 1:8192], + [2:57345, 0:8191, 3:57345, 1:8191], + [2:57344, 0:8191, 3:57344, 1:8192]], + [[2:65536, 3:65536], + [2:65535, 0, 3:65535, 1], + [2:65536, 3:65536], + [2:65536, 3:65536]], + [2:8191]:64]...; + + col fixed CLK = [0:524288, + 1:524288, + 2:524288, + 3:524224]...; + + // + // ────┬────┬───┬──────────────┬──────────────┬───┬──────────────┬────┬───────┬────┬────────┬─────── + // CL │ CI │ L │ KEY_C (HEX) │ KEY_C (UP) │ C | KEY_C (UP&M) │ LT │ GL_C │ CO │ ROWS │ NOTES + // ────┼────┼───┼──────────────┼──────────────┼───┼──────────────┼────┼───────┼────┼────────┼─────── + // 0 │ 0 │ 0 │ 00000 │ 00000 │ 0 │ 00000 │ 1 │ 00001 │ 2 │ 1 │ + // 0 │ 0 │ 0 │ 00001..1FFFF │ 00002..3FFFE │ 0 │ 00002..3FFFE │ 0 │ 00001 │ 0 │ 131071 │ + // 0 │ 0 │ 0 │ 20000 │ 40000 │ 1 │ 00000 │ 1 │ 00001 │ 3 │ 1 │ + // 0 │ 0 │ 0 │ 20001..3FFFF │ 40002..7FFFE │ 1 │ 00002..3FFFE │ 0 │ 00001 │ 1 │ 131071 │ 262144 + // ┄┄┄┄│┄┄┄┄│┄┄┄│┄┄┄┄┄┄┄┄┄┄┄┄┄┄│┄┄┄┄┄┄┄┄┄┄┄┄┄┄│┄┄┄│┄┄┄┄┄┄┄┄┄┄┄┄┄┄│┄┄┄┄│┄┄┄┄┄┄┄│┄┄┄┄│┄┄┄┄┄┄┄┄│┄┄┄┄┄┄┄┄ + // 0 │ 1 │ 0 │ 00000..1FFFF │ 00001..3FFFF │ 0 │ 00001..3FFFF │ 0 │ 00001 │ 0 │ 131072 │ + // 0 │ 1 │ 0 │ 20000..3FFFF │ 40001..7FFFF │ 1 │ 00001..3FFFF │ 0 │ 00001 │ 1 │ 131072 │ 262144 + // ┄┄┄┄│┄┄┄┄│┄┄┄│┄┄┄┄┄┄┄┄┄┄┄┄┄┄│┄┄┄┄┄┄┄┄┄┄┄┄┄┄│┄┄┄│┄┄┄┄┄┄┄┄┄┄┄┄┄┄│┄┄┄┄│┄┄┄┄┄┄┄│┄┄┄┄│┄┄┄┄┄┄┄┄│┄┄┄┄┄┄┄┄ + // 1 │ 0 │ 0 │ 00000..0DFFF │ 00000..1BFFE │ 0 │ 00000..1BFFE │ 1 │ 1C000 │ 2 │ 57344 │ + // 1 │ 0 │ 0 │ 0E000..0FFFF │ 1C000..1FFFE │ 0 │ 1C000..1FFFE │ 0 │ 1C000 │ 0 │ 8192 │ + // 1 │ 0 │ 0 │ 10000..1DFFF │ 20000..3BFFE │ 1 │ 00000..1BFFE │ 1 │ 1C000 │ 3 │ 57344 │ + // 1 │ 0 │ 0 │ 1E000..1FFFF │ 3C000..3FFFE │ 1 │ 1C000..1FFFE │ 0 │ 1C000 │ 1 │ 8192 │ 131072 + // ┄┄┄┄│┄┄┄┄│┄┄┄│┄┄┄┄┄┄┄┄┄┄┄┄┄┄│┄┄┄┄┄┄┄┄┄┄┄┄┄┄│┄┄┄│┄┄┄┄┄┄┄┄┄┄┄┄┄┄│┄┄┄┄│┄┄┄┄┄┄┄│┄┄┄┄│┄┄┄┄┄┄┄┄│┄┄┄┄┄┄┄┄ + // 1 │ 1 │ 0 │ 00000..0DFFF │ 00001..1BFFF │ 0 │ 00001..1BFFF │ 1 │ 1C000 │ 2 │ 57344 │ + // 1 │ 1 │ 0 │ 0E000..0FFFF │ 1C001..1FFFF │ 0 │ 1C001..1FFFF │ 0 │ 1C000 │ 0 │ 8192 │ + // 1 │ 1 │ 0 │ 10000..1DFFF │ 20001..3BFFF │ 1 │ 00001..1BFFF │ 1 │ 1C000 │ 3 │ 57344 │ + // 1 │ 1 │ 0 │ 1E000..1FFFF │ 3C001..3FFFF │ 1 │ 1C001..1FFFF │ 0 │ 1C000 │ 1 │ 8192 │ 131072 + // ┄┄┄┄│┄┄┄┄│┄┄┄│┄┄┄┄┄┄┄┄┄┄┄┄┄┄│┄┄┄┄┄┄┄┄┄┄┄┄┄┄│┄┄┄│┄┄┄┄┄┄┄┄┄┄┄┄┄┄│┄┄┄┄│┄┄┄┄┄┄┄│┄┄┄┄│┄┄┄┄┄┄┄┄│┄┄┄┄┄┄┄┄ + // 1 │ 2 │ 0 │ 00000..0E000 │ 00000..1C000 │ 0 │ 00000..1C000 │ 1 │ 1C000 │ 2 │ 57345 │ + // 1 │ 2 │ 0 │ 0E001..0FFFF │ 1C002..1FFFE │ 0 │ 1C002..1FFFE │ 0 │ 1C000 │ 0 │ 8191 │ + // 1 │ 2 │ 0 │ 10000..1E000 │ 20000..3C000 │ 1 │ 00000..1C000 │ 1 │ 1C000 │ 3 │ 57345 │ + // 1 │ 2 │ 0 │ 1E001..1FFFF │ 3C002..3FFFE │ 1 │ 1C002..1FFFE │ 0 │ 1C000 │ 1 │ 8191 │ 131072 + // ┄┄┄┄│┄┄┄┄│┄┄┄│┄┄┄┄┄┄┄┄┄┄┄┄┄┄│┄┄┄┄┄┄┄┄┄┄┄┄┄┄│┄┄┄│┄┄┄┄┄┄┄┄┄┄┄┄┄┄│┄┄┄┄│┄┄┄┄┄┄┄│┄┄┄┄│┄┄┄┄┄┄┄┄│┄┄┄┄┄┄┄┄ + // 1 │ 3 │ 0 │ 00000..0DFFF │ 00001..1BFFF │ 0 │ 00001..1BFFF │ 1 │ 1C000 │ 2 │ 57344 │ + // 1 │ 3 │ 0 │ 0E000..0FFFF │ 1C001..1FFFF │ 0 │ 1C001..1FFFF │ 0 │ 1C000 │ 0 │ 8192 │ + // 1 │ 3 │ 0 │ 10000..1DFFF │ 20001..3BFFF │ 1 │ 00001..1BFFF │ 1 │ 1C000 │ 3 │ 57344 │ + // 1 │ 3 │ 0 │ 1E000..1FFFF │ 3C001..3FFFF │ 1 │ 1C001..1FFFF │ 0 │ 1C000 │ 1 │ 8192 │ 131072 + // ┄┄┄┄│┄┄┄┄│┄┄┄│┄┄┄┄┄┄┄┄┄┄┄┄┄┄│┄┄┄┄┄┄┄┄┄┄┄┄┄┄│┄┄┄│┄┄┄┄┄┄┄┄┄┄┄┄┄┄│┄┄┄┄│┄┄┄┄┄┄┄│┄┄┄┄│┄┄┄┄┄┄┄┄│┄┄┄┄┄┄┄┄ + // 2 │ 0 │ 0 │ 00000..0FFFF │ 00000..1FFFE │ 0 │ 00000..1FFFE │ 1 │ 1FFFF │ 2 │ 65536 │ + // 2 │ 0 │ 0 │ 10000..1FFFF │ 20000..3FFFE │ 1 │ 00000..1FFFE │ 1 │ 1FFFF │ 3 │ 65536 │ 131072 + // ┄┄┄┄│┄┄┄┄│┄┄┄│┄┄┄┄┄┄┄┄┄┄┄┄┄┄│┄┄┄┄┄┄┄┄┄┄┄┄┄┄│┄┄┄│┄┄┄┄┄┄┄┄┄┄┄┄┄┄│┄┄┄┄│┄┄┄┄┄┄┄│┄┄┄┄│┄┄┄┄┄┄┄┄│┄┄┄┄┄┄┄┄ + // 2 │ 1 │ 0 │ 00000..0FFFE │ 00001..1FFFD │ 0 │ 00001..1FFFD │ 1 │ 1FFFF │ 2 │ 65535 │ + // 2 │ 1 │ 0 │ 0FFFF │ 1FFFF │ 0 │ 1FFFF │ 0 │ 1FFFF │ 0 │ 1 │ + // 2 │ 1 │ 0 │ 10000..1FFFE │ 20001..3FFFD │ 1 │ 00001..1FFFD │ 1 │ 1FFFF │ 3 │ 65535 │ + // 2 │ 1 │ 0 │ 1FFFF │ 3FFFF │ 1 │ 1FFFF │ 0 │ 1FFFF │ 1 │ 1 │ 131072 + // ┄┄┄┄│┄┄┄┄│┄┄┄│┄┄┄┄┄┄┄┄┄┄┄┄┄┄│┄┄┄┄┄┄┄┄┄┄┄┄┄┄│┄┄┄│┄┄┄┄┄┄┄┄┄┄┄┄┄┄│┄┄┄┄│┄┄┄┄┄┄┄│┄┄┄┄│┄┄┄┄┄┄┄┄│┄┄┄┄┄┄┄┄ + // 2 │ 2 │ 0 │ 00000..0FFFF │ 00000..1FFFE │ 0 │ 00000..1FFFE │ 1 │ 1FFFF │ 2 │ 65536 │ + // 2 │ 2 │ 0 │ 10000..1FFFF │ 20000..3FFFE │ 1 │ 00000..1FFFE │ 1 │ 1FFFF │ 3 │ 65536 │ 131072 + // ┄┄┄┄│┄┄┄┄│┄┄┄│┄┄┄┄┄┄┄┄┄┄┄┄┄┄│┄┄┄┄┄┄┄┄┄┄┄┄┄┄│┄┄┄│┄┄┄┄┄┄┄┄┄┄┄┄┄┄│┄┄┄┄│┄┄┄┄┄┄┄│┄┄┄┄│┄┄┄┄┄┄┄┄│┄┄┄┄┄┄┄┄ + // 2 │ 3 │ 0 │ 00000..0FFFF │ 00001..1FFFF │ 0 │ 00001..1FFFF │ 1 │ 1FFFF │ 2 │ 65536 │ + // 2 │ 3 │ 0 │ 10000..1FFFF │ 20001..3FFFF │ 1 │ 00001..1FFFF │ 1 │ 1FFFF │ 3 │ 65536 │ 131072 + // ┄┄┄┄│┄┄┄┄│┄┄┄│┄┄┄┄┄┄┄┄┄┄┄┄┄┄│┄┄┄┄┄┄┄┄┄┄┄┄┄┄│┄┄┄│┄┄┄┄┄┄┄┄┄┄┄┄┄┄│┄┄┄┄│┄┄┄┄┄┄┄│┄┄┄┄│┄┄┄┄┄┄┄┄│┄┄┄┄┄┄┄┄ + // 3 │ 0 │(*)│ 00000..007FF │ 00000..00FFE │ 0 │ 00000..00FFE │ 1 │ 00FFF │ 2 │ 2048 │ 2048 + // ┄┄┄┄│┄┄┄┄│┄┄┄│┄┄┄┄┄┄┄┄┄┄┄┄┄┄│┄┄┄┄┄┄┄┄┄┄┄┄┄┄│┄┄┄│┄┄┄┄┄┄┄┄┄┄┄┄┄┄│┄┄┄┄│┄┄┄┄┄┄┄│┄┄┄┄│┄┄┄┄┄┄┄┄│┄┄┄┄┄┄┄┄ + // 3 │ 1 │(*)│ 00000..007FE │ 00001..00FFD │ 0 │ 00001..00FFD │ 1 │ 00FFF │ 2 │ 2047 │ 2047 + // ┄┄┄┄│┄┄┄┄│┄┄┄│┄┄┄┄┄┄┄┄┄┄┄┄┄┄│┄┄┄┄┄┄┄┄┄┄┄┄┄┄│┄┄┄│┄┄┄┄┄┄┄┄┄┄┄┄┄┄│┄┄┄┄│┄┄┄┄┄┄┄│┄┄┄┄│┄┄┄┄┄┄┄┄│┄┄┄┄┄┄┄┄ + // 3 │ 2 │(*)│ 00000..007FF │ 00000..00FFE │ 0 │ 00000..00FFE │ 1 │ 00FFF │ 2 │ 2048 │ 2048 + // ┄┄┄┄│┄┄┄┄│┄┄┄│┄┄┄┄┄┄┄┄┄┄┄┄┄┄│┄┄┄┄┄┄┄┄┄┄┄┄┄┄│┄┄┄│┄┄┄┄┄┄┄┄┄┄┄┄┄┄│┄┄┄┄│┄┄┄┄┄┄┄│┄┄┄┄│┄┄┄┄┄┄┄┄│┄┄┄┄┄┄┄┄ + // 3 │ 3 │(*)│ 00000..007FF │ 00001..00FFF │ 0 │ 00001..00FFF │ 1 │ 00FFF │ 2 │ 2048 │ 2048 + // ┄┄┄┄│┄┄┄┄│┄┄┄│┄┄┄┄┄┄┄┄┄┄┄┄┄┄│┄┄┄┄┄┄┄┄┄┄┄┄┄┄│┄┄┄│┄┄┄┄┄┄┄┄┄┄┄┄┄┄│┄┄┄┄│┄┄┄┄┄┄┄│┄┄┄┄│┄┄┄┄┄┄┄┄│┄┄┄┄┄┄┄┄ + // + // 262.144 * 2 + 131.072 * 8 + (2.048 * 3 + 2.047) * 64 = 2.097.088 (< 2**21 = 2.097.152) + // + // (*) msb_level (6 bits) => 64 values + // + // + // EXCLUDED VALUES (not valid values) (1) + // ────┬────┬───┬──────────────┬──────────────┬───┬──────────────┬────┬───────┬────┬────────┬─────── + // CL │ CI │ L │ KEY_C (HEX) │ KEY_C (UP) │ C | KEY_C (UP&M) │ LT │ GL_C │ CO │ ROWS │ NOTES + // ────┼────┼───┼──────────────┼──────────────┼───┼──────────────┼────┼───────┼────┼────────┼─────── + // 3 │ 0 │ 0 │ 00800..00FFF │ 01000..01FFE │ 1 │ 00000..00FFE │ 1 │ 00FFF │ 3 │ 2048 │ 2048 + // ┄┄┄┄│┄┄┄┄│┄┄┄│┄┄┄┄┄┄┄┄┄┄┄┄┄┄│┄┄┄┄┄┄┄┄┄┄┄┄┄┄│┄┄┄│┄┄┄┄┄┄┄┄┄┄┄┄┄┄│┄┄┄┄│┄┄┄┄┄┄┄│┄┄┄┄│┄┄┄┄┄┄┄┄│┄┄┄┄┄┄┄┄ + // 3 │ 1 │ 0 │ 007FF │ 00FFF │ 0 │ 00FFF │ 0 │ 00FFF │ 0 │ 1 │ + // 3 │ 1 │ 0 │ 00800..00FFE │ 01001..01FFD │ 1 │ 00001..00FFD │ 1 │ 00FFF │ 3 │ 2047 │ + // 3 │ 1 │ 0 │ 00FFF │ 01FFF │ 1 │ 00FFF │ 0 │ 00FFF │ 1 │ 1 │ 2049 + // ┄┄┄┄│┄┄┄┄│┄┄┄│┄┄┄┄┄┄┄┄┄┄┄┄┄┄│┄┄┄┄┄┄┄┄┄┄┄┄┄┄│┄┄┄│┄┄┄┄┄┄┄┄┄┄┄┄┄┄│┄┄┄┄│┄┄┄┄┄┄┄│┄┄┄┄│┄┄┄┄┄┄┄┄│┄┄┄┄┄┄┄┄ + // 3 │ 2 │ 0 │ 00800..00FFF │ 01000..01FFE │ 1 │ 00000..00FFE │ 1 │ 00FFF │ 3 │ 2048 │ 2048 + // ┄┄┄┄│┄┄┄┄│┄┄┄│┄┄┄┄┄┄┄┄┄┄┄┄┄┄│┄┄┄┄┄┄┄┄┄┄┄┄┄┄│┄┄┄│┄┄┄┄┄┄┄┄┄┄┄┄┄┄│┄┄┄┄│┄┄┄┄┄┄┄│┄┄┄┄│┄┄┄┄┄┄┄┄│┄┄┄┄┄┄┄┄ + // 3 │ 3 │ 0 │ 00800..00FFF │ 01001..01FFF │ 1 │ 00001..00FFF │ 1 │ 00FFF │ 3 │ 2048 │ 2048 + // ┄┄┄┄│┄┄┄┄│┄┄┄│┄┄┄┄┄┄┄┄┄┄┄┄┄┄│┄┄┄┄┄┄┄┄┄┄┄┄┄┄│┄┄┄│┄┄┄┄┄┄┄┄┄┄┄┄┄┄│┄┄┄┄│┄┄┄┄┄┄┄│┄┄┄┄│┄┄┄┄┄┄┄┄│┄┄┄┄┄┄┄┄ + + lookup_proves(CLIMB_KEY_TABLE_ID, 1, [CLK, MSB_LEVEL, CHUNK_VALUE, CARRY_LT_IN, CARRY_LT_OUT]); +} \ No newline at end of file diff --git a/test/pil2/zkevm-etrog/keccakf.pil b/test/pil2/zkevm-etrog/keccakf.pil new file mode 100644 index 0000000..8d0c988 --- /dev/null +++ b/test/pil2/zkevm-etrog/keccakf.pil @@ -0,0 +1,44 @@ +include "tools.pil" +include "keccakf_table.pil" + +const int KECCAKF_ID = 56 + +subproof KeccakF(2**23) { + + const int bits = 11; + const int chunks = 4; + + col fixed GATE_TYPE; + col witness in1Chunk[chunks], in2Chunk[chunks], outChunk[chunks]; + + const int FACTOR = 2**bits; + expr _in1,_in2,_out; + for (int chunk = chunks - 1; chunk >= 0; chunk -= 1) { + lookup_assumes(KECCAKF_TABLE_ID, 1, [GATE_TYPE, in1Chunk[chunk], in2Chunk[chunk], outChunk[chunk]]); + _in1 = _in1 * FACTOR + in1Chunk[chunk]; + _in2 = _in2 * FACTOR + in2Chunk[chunk]; + _out = _out * FACTOR + outChunk[chunk]; + } + const expr in1 = _in1; + const expr in2 = _in2; + const expr out = _out; + + col fixed FIELD_LATCH = [0:44,1]...; + col fixed L1 = [1,0...]; + col witness bit; + + expr bitToField = 0; + for (int index = 0; index < bits; ++index) { + bitToField += (bits - index - 1)'bit * 2**index; + } + + bit *(1-bit) === 0; + FIELD_LATCH * (bitToField - in1) === 0; + + // TODO: connections + // col constant ConnA, ConnB, ConnC, GateType; + // {in1, in2, out} connect {ConnA, ConnB, ConnC}; + + L1 * in1 === 0; // [L1] in1 == 0000...0000 + L1 (2**(bits*chunks)-1-in2) === 0; // [L1] in2 == 1111...1111 +} \ No newline at end of file diff --git a/test/pil2/zkevm-etrog/keccakf_table.pil b/test/pil2/zkevm-etrog/keccakf_table.pil new file mode 100644 index 0000000..7bb7cd2 --- /dev/null +++ b/test/pil2/zkevm-etrog/keccakf_table.pil @@ -0,0 +1,24 @@ +const int KECCAKF_TABLE_ID = 57 + +subproof KeccakFTable(2**23) { + const int bits = 11; + const int TO = (2**bits) - 1; + const int MASK = (2**bits) - 1; + const int TO2 = 2 * TO; + + col fixed GATE_TYPE = [0,1]...; + col fixed IN1 = [0:TO2..TO:TO2]...; + col fixed IN2 = [0:2..TO:2]...; + col fixed OUT; + // col fixed OUT = [IN1^IN2,(IN1^MASK) & IN2]...; + + for (int irow = 0; irow < N; irow = irow + 2) { + OUT[irow] = IN1[irow] ^ IN2[irow]; + OUT[irow+1] = (IN1[irow+1] ^ MASK) & IN2[irow+1]; + } + // GATE_TYPE: 1 bits + // IN1: 11 bits + // IN2: 11 bits + // TOTAL: 23 bits + lookup_proves(KECCAKF_TABLE_ID, 1, [GATE_TYPE, IN1, IN2, OUT]); +} \ No newline at end of file diff --git a/test/pil2/zkevm-etrog/main.pil b/test/pil2/zkevm-etrog/main.pil new file mode 100644 index 0000000..77d9ff6 --- /dev/null +++ b/test/pil2/zkevm-etrog/main.pil @@ -0,0 +1,423 @@ +include "tools.pil" +include "rom.pil" +// include "mem_align.pil"; +// include "arith.pil"; +// include "binary.pil"; +// include "poseidong.pil"; +// include "padding_pg.pil"; +// include "storage.pil"; +// include "padding_kk.pil"; +// include "mem.pil"; +// include "padding_sha256.pil"; +// hash bytes +// assumeFREE +// BitRange32 +// memAlign +// freeBits + +// TODO: only to compile alone +const int ARITH_ID = 10; +const int BINARY_ID = 20; +const int MEM_ALIGN_ID = 5; +const int MEMORY_ID = 4; +const int PADDING_KK_HASH_ID = 50; +const int PADDING_KK_LEN_DIGEST_ID = 51; +const int PADDING_PG_HASH_ID = 40; +const int PADDING_PG_DIGEST_ID = 41; +const int PADDING_PG_LEN_ID = 42; +const int PADDING_SHA256_HASH_ID = 60; +const int PADDING_SHA256_LEN_DIGEST_ID = 61; +const int POSEIDON_G_ID = 45; +const int RANGE32_ID = 6; +const int STORAGE_ID = 90; + +const int BINARY_OP_LT4 = 8; + +subproof Main(2**23) { + const int NR = 8; + + /////// State Polynomials + col witness A[NR], B[NR], C[NR], D[NR], E[NR]; // Generic Registers + col witness SR[NR]; // State Root + col witness CTX; // Call Cntext + col witness SP; // Stack Pointer + col witness PC; // EVM Program counter + col witness GAS; + col witness zkPC; // Program Counter of current micro instruction + col witness RR; // Micro code return address (subroutines) + col witness HASHPOS; + col witness RCX; + + /////// Instruction related polynomials + col witness CONST[NR]; + col witness FREE[NR]; + col witness inA, inB, inC, inROTL_C, inD, inE, inSR, inFREE, inFREE0, inCTX, inSP, inPC, inGAS, inSTEP, inRR, inHASHPOS, inRCX; + col witness setA, setB, setC, setD, setE, setSR, setCTX, setSP, setPC, setGAS, setRR, setHASHPOS, setRCX; + col witness jmp, jmpn, jmpc, jmpz, offset; + col witness incStack; + col witness isStack; + col witness isMem; + col witness ind, indRR; + col witness useCTX; + col witness carry; + + // operations + col witness mOp, mWR; + col witness sWR, sRD; + col witness arith, arithOp, arithUseCD, arithUseE; + col witness memAlignRD, memAlignWR, memAlignWR8; + col witness hashK, hashKLen, hashKDigest; + col witness hashP, hashPLen, hashPDigest; + col witness hashS, hashSLen, hashSDigest; + col witness useHashBytes, hashBytes; + col witness bin; + col witness binOp; + col witness carryIn; + col witness doAssert; + col witness repeat, call, returnJmp; + col witness assumeFREE; + + /////// Intermediary commit polynomials + col witness isNeg; + + /// Counters + col witness cntArith, cntBinary, cntMemAlign, cntKeccakF, cntSha256F, cntPoseidonG, cntPaddingPG; + col witness inCntArith, inCntBinary, inCntMemAlign, inCntKeccakF, inCntSha256F, inCntPoseidonG, inCntPaddingPG; + col witness incCounter; + + col witness jmpAddr; + col witness elseAddr; + col witness useAddrRel; + col witness useJmpAddrRel; + col witness useElseAddrRel; + + col witness useOpAsParam; + col witness useConstAsParam; + + col fixed L1 = [1,0...]; + col fixed STEP = [0..(N-1)]; + // op registers with out of expression + // av assumed value, could be op or FREE + // col witness op[NR]; + const expr op[NR]; + const expr assumeInput[NR]; + const expr zeros[NR]; + for (int index = 0; index < NR; ++index) { + expr _op = + A[index] * inA + + B[index] * inB + + C[index] * inC + + C[(index + NR - 1) % NR] * inROTL_C + + D[index] * inD + + E[index] * inE + + FREE[index] * (inFREE + inFREE0) + + SR[index] * inSR + + CONST[index]; + + if (index == 0) { + _op += + CTX * inCTX + + SP * inSP + + PC * inPC + + GAS * inGAS + + STEP * inSTEP + + RR * inRR + + HASHPOS * inHASHPOS + + cntArith * inCntArith + + cntBinary * inCntBinary + + cntMemAlign * inCntMemAlign + + cntKeccakF * inCntKeccakF + + cntSha256F * inCntSha256F + + cntPoseidonG * inCntPoseidonG + + cntPaddingPG * inCntPaddingPG + + RCX * inRCX; + } + zeros[index] = 0; + op[index] = _op; + assumeInput[index] = (1 - assumeFREE) * (op[index] - FREE[index]) + FREE[index]; + } + + /* + + ctxBase = CTX * 0x040000 ctxSize = 256K addresses * 32 bytes (256 bits) = 8MiB + + Memory Region Size isMem isStack Content + ctxBase + [0x000000 - 0x00FFFF] 2MiB 0 0 Context specific variables + ctxBase + [0x010000 - 0x000000] 2MiB 0 1 EVM Stack + ctxBase + [0x020000 - 0x03FFFF] 4MiB 1 0 EVM Memory + + */ + + const expr addrRel = ind * E[0] + indRR * RR; + const expr addr = 2**18 * useCTX * CTX + + 2**16 * isStack + isStack*SP + + 2**17 * isMem + useAddrRel * addrRel + offset; + + + // op0 check zero + col witness op0Inv; + const expr op0IsZero = 1 - op[0]*op0Inv; + op0IsZero * op[0] === 0; + + multiset_assumes(RANGE32_ID, jmpn, [isNeg * 2**32 + op[0], 32]); + isNeg * (1 - isNeg) === 0; + + // RCX check zero + col witness RCXInv; + const expr RCXIsZero = 1 - RCX * RCXInv; + RCXIsZero * RCX === 0; + + + // Calculate New State + for (int index = 0; index < NR; ++index) { + A[index]' === setA * (op[index] - A[index]) + A[index]; + B[index]' === setB * (op[index] - B[index]) + B[index]; + C[index]' === setC * (op[index] - C[index]) + C[index]; + D[index]' === setD * (op[index] - D[index]) + D[index]; + E[index]' === setE * (op[index] - E[index]) + E[index]; + SR[index]' === setSR * (op[index] - SR[index]) + SR[index]; + } + + CTX' === setCTX * (op[0] - CTX) + CTX; + SP' === setSP * (op[0] - (SP +incStack)) + (SP +incStack); + PC' === setPC * (op[0] - PC) + PC; + + // ROM constraint: call * setRR = 0 + RR' === setRR * (op[0] - RR) + call * (zkPC + 1 - RR) + RR; + GAS' === setGAS * (op[0] - GAS) + GAS; + + const expr decRCX = repeat * (1 - RCXIsZero); + RCX' === setRCX * (op[0] - (RCX-decRCX)) + (RCX-decRCX); + + HASHPOS' === setHASHPOS * (op[0] - HASHPOS) + HASHPOS + (hashK + hashP + hashS)*D[0] + useHashBytes * hashBytes; + + const expr doJmp = jmpn * isNeg + jmp + jmpc * carry + jmpz * op0IsZero + returnJmp + call; + const expr elseJmp = jmpn * (1-isNeg) + jmpc * (1-carry) + jmpz * (1-op0IsZero); + + // ROM/Zkasm constraint: useJmpAddr * returnJmp = 0 + const expr finalJmpAddr = jmpAddr + useJmpAddrRel * addrRel + returnJmp * (RR' - jmpAddr); + const expr nextNoJmpZkPC = zkPC + 1 - ((1-RCXIsZero)*repeat); + const expr finalElseAddr = elseAddr + useElseAddrRel * elseAddr; + + // if elseAddr wasn't specified on zkasm, compiler put current address + 1 + zkPC' === doJmp * (finalJmpAddr - nextNoJmpZkPC) + elseJmp * (finalElseAddr - nextNoJmpZkPC) + nextNoJmpZkPC; + + zkPC * L1 === 0; + + // public inputs + public oldStateRoot[NR]; + public oldAccInputHash[NR]; + public oldBatchNum; + public chainId; + public forkId; + + // public outputs + public newStateRoot[NR]; + public newAccInputHash[NR]; + public localExitRoot[NR]; + public newBatchNum; + + #pragma debug off + for (int index = 0; index < NR; ++index) { + (A[index] - op[index]) * doAssert === 0; + // oldStateRoot[NR] = B(NR); + L1 * (B[index] - oldStateRoot[index]) === 0; + // oldBatchNum[NR] = SP(NR); + L1 * (C[index] - oldAccInputHash[index]) === 0; + // public newStateRoot0 = SR0(%N-1); + L1' * (SR[index] - newStateRoot[index]) === 0; + // public newAccInputHash0 = D0(%N -1); + L1' * (D[index] - newAccInputHash[index]) === 0; + // public localExitRoot0 = E0(%N-1); + L1' * (E[index] - localExitRoot[index]) === 0; + } + + // public oldBatchNum = SP(0); + L1 * (SP - oldBatchNum) === 0; + + // public chainId = GAS(0); + L1 * (GAS - chainId) === 0; + + // public forkId = CTX(0); + L1 * (CTX - forkId) === 0; + + L1' * (PC - newBatchNum) === 0; + + const expr GL = 0xFFFFFFFF00000001; + const expr LSB_GL = GL & 0xFFFFFFFF; + const expr HSB_GL = GL >> 16; + + // TODO: + // const expr GL4[8] = [LSB_GL, HSB_GL, LSB_GL, HSB_GL, LSB_GL, HSB_GL, LSB_GL, HSB_GL]; + const expr GL4[8]; + GL4[0] = LSB_GL; + GL4[1] = HSB_GL; + GL4[2] = LSB_GL; + GL4[3] = HSB_GL; + GL4[4] = LSB_GL; + GL4[5] = HSB_GL; + GL4[6] = LSB_GL; + GL4[7] = HSB_GL; + + // Check that the calculated hash is well formed + + // TODO: + // multiset_assumes(BINARY_ID, WR + hashPDigest, [...op, ...GL4, [1, 0:7], BINARY_OP_LT4]); + // multiset_assumes(BINARY_ID, WR + hashPDigest, [...op, ...GL4, [1, 0:(NR-1)], BINARY_OP_LT4]); + #pragma debug off + multiset_assumes(BINARY_ID, sWR + hashPDigest, [...op, ...GL4, 1, 0, 0, 0, 0, 0, 0, 0, BINARY_OP_LT4, 1, 0]); + + // Binary: resultValidRange []...a, ...b, lOpcode, Binary.lCout]; + + // ROM lookup + + // arithEq0, arithEq1, arithEq2,,arithEq3,arithEq4,arithEq5, => arithOp + // hashP1, hashK1, hashS1 => + // ind, indR + const expr romFlags = compact_bin_cols ([ + doAssert, bin, carryIn, sRD, sWR, memAlignRD, memAlignWR, memAlignWR8, mOp, mWR, + arith, arithUseCD, arithUseCD, + hashK, hashKDigest, hashKLen, hashP, hashPDigest, hashPLen, + hashS, hashSDigest, hashSLen, useHashBytes, + isMem, isStack, useCTX, useAddrRel, + useJmpAddrRel, useElseAddrRel, jmp, jmpc, jmpn, jmpz, call, returnJmp, repeat, + setA, setB, setC, setCTX, setD, setE, + setGAS, setHASHPOS, setPC, setRCX, setRR, setSP, setSR]); + + + lookup_assumes(ROM_ID, 1, [...CONST, inA, inB, inC, inROTL_C, inD, inE, inSR, inFREE, inFREE0, + inCTX, inSP, inPC, inGAS, inHASHPOS, inSTEP, inRR, inRCX, ind, indRR, + inCntArith, inCntBinary, inCntKeccakF, inCntSha256F, + inCntMemAlign, inCntPaddingPG, inCntPoseidonG, + romFlags, offset, incStack, binOp, arithOp, hashBytes, + jmpAddr, elseAddr, zkPC]); + + col witness sKeyI[4]; + col witness sKey[4]; + + // Aritmethic State Machine + + int _i = 0; + while (_i < 10) { + println(_i); + _i = _i + 1; + } + expr arithC[NR], arithD[NR], arithE[NR]; + expr paramA[NR], paramB[NR], paramOp[NR]; + for (int i = 0; i < NR; ++i) { + arithC[i] = arithUseCD * (C[i] - A[i]) + A[i]; + arithD[i] = arithUseCD * (C[i] - B[i]) + B[i]; + arithE[i] = arithUseE * E[i]; + paramA[i] = useOpAsParam * (assumeInput[i] - A[i]) + A[i]; + paramB[i] = useConstAsParam * (CONST[i] - B[i]) + B[i]; + // if useOpAsParam, res must be zero => managed in SM too (as other flag) + paramOp[i] = (1 - useOpAsParam) * op[i]; + } + // We group arithmetic operations by the number of inputs they have + // 1] 5 inputs (A * B + C = D * 2^256 + E) + + multiset_assumes(ARITH_ID, arith, [arithOp, ...A, ...B, ...arithC, ...arithD, ...arithE, ...assumeInput]); + cntArith' === cntArith * (1 - L1) + arith; + + multiset_assumes(BINARY_ID, bin, [binOp, ...paramA, ...paramB, ...paramOp, carryIn, carry]); + cntBinary' === cntBinary * (1 - L1) + bin + sWR + hashPDigest; + + // OPTIMIZATION2EVAL: HASHPOSDIGEST = HASHPOS :HASHLEN + $ :HASHDIGEST + // optimization reuse CONST as hashBytes or use CONST_LITE to general purpose + lookup_assumes(PADDING_KK_HASH_ID, hashK, [addr, HASHPOS, useHashBytes * (hashBytes - D[0]) + D[0], ...assumeInput]); + // PaddingKK: crLatch * PaddingKK.r8valid { addr, len - rem - crLen + 1, crLen, crV0C, crV1C, crV2C, crV3C, crV4C, crV5C, crV6C, crV7C } + + multiset_assumes(PADDING_KK_LEN_DIGEST_ID, hashKLen + hashKDigest, [hashKLen, addr, ...assumeInput, hashKDigest * incCounter]); + // TODO: check if could be in same, perhaps len and Digest is in same "clock" of keccak + // TODO: if use 2 multisets, better use a lookup without selector + // REVIEW: + // PaddingKK: lastHashLen { addr, len } + // PaddingKK: lastHashDigest { addr, hash0, hash1, hash2, hash3, hash4, hash5, hash6, hash7, incCounter } + + // ERROR: cntKeccakF' = cntKeccakF * (1 - L1) + incCounter * hashKDigest; + cntKeccakF' === cntKeccakF * (1 - L1) + incCounter * hashKDigest; + + // SHA256 lookups and permutation check + + lookup_assumes(PADDING_SHA256_HASH_ID, hashS, [addr, HASHPOS, useHashBytes * (hashBytes - D[0]) + D[0], ...op]); + // PaddingKK: crLatch * PaddingKK.r8valid { addr, len - rem - crLen + 1, crLen, crV0C, crV1C, crV2C, crV3C, crV4C, crV5C, crV6C, crV7C } + + multiset_assumes(PADDING_SHA256_LEN_DIGEST_ID, hashSLen + hashSDigest, [hashSLen, addr, ...op, hashSDigest * incCounter]); + // TODO: check if could be in same, perhaps len and Digest is in same "clock" of keccak + // PaddingKK: lastHashLen { addr, len } + // PaddingKK: lastHashDigest { addr, hash0, hash1, hash2, hash3, hash4, hash5, hash6, hash7, incCounter } + + + // TODO: modify sha to be aligned with rest of hash, because currently the Sha digest's chunks are ordered + // from most to least significant. (hash0 => op7, hash1 => op6, ..) + + cntSha256F' === cntSha256F * (1 - L1) + incCounter * hashSDigest; + + // HASHP Plookpups + lookup_assumes(PADDING_PG_HASH_ID, hashS, [addr, HASHPOS, useHashBytes * (hashBytes - D[0]) + D[0], ...op]); + // lookup_proves(PADDING_PG_HASH_ID, crLatch * r8valid [addr, len - rem - crLen + 1, crLen, crV0C, crV1C, crV2C, crV3C, crV4C, crV5C, crV6C, crV7C]); + + assumeInput[1] * (hashSLen + hashKLen + hashPLen) === 0; + assumeInput[2] * (hashSLen + hashKLen + hashPLen) === 0; + assumeInput[3] * (hashSLen + hashKLen + hashPLen) === 0; + assumeInput[4] * (hashSLen + hashKLen + hashPLen) === 0; + assumeInput[5] * (hashSLen + hashKLen + hashPLen) === 0; + assumeInput[6] * (hashSLen + hashKLen + hashPLen) === 0; + assumeInput[7] * (hashSLen + hashKLen + hashPLen) === 0; + + multiset_assumes(PADDING_PG_LEN_ID, hashSLen, [addr, assumeInput[0], hashSDigest * incCounter]); + multiset_assumes(PADDING_PG_DIGEST_ID, hashSLen + hashSDigest, [hashSLen, addr, + assumeInput[0] + 2**32 * assumeInput[1], + assumeInput[2] + 2**32 * assumeInput[3], + assumeInput[4] + 2**32 * assumeInput[5], + assumeInput[6] + 2**32 * assumeInput[7], + hashSDigest * incCounter]); + // multiset_proves(PADDING_PG_LEN, lastHashLen, [addr, len]); + // multiset_proves(PADDING_PG_LEN_DIGEST_ID, lastHashDigest, [addr, ...curHash, incCounter]) + + cntPaddingPG' === cntPaddingPG * (1 - L1) + hashPDigest * incCounter; + + // TODO: modify executor + cntPoseidonG' === cntPoseidonG * (1 - L1) + (hashPDigest + sRD + sWR) * incCounter + 2 * (sRD + sWR); + + // Memory + multiset_assumes(MEMORY_ID, mOp, [addr, STEP, mWR, ...assumeInput]); + // multiset_proves(MEMORY_ID, mOp, [addr, step, mWr, ...val]); + + // Storage + + multiset_assumes(POSEIDON_G_ID, sRD + sWR, [...C, 0, 0, 0, 0, ...sKeyI]); + // multiset_proves(POSEIDON_G_ID, ,[..._in, hashType, ...cap, ...hash]); + + A[5] * (sRD + sWR) === 0; + A[6] * (sRD + sWR) === 0; + A[7] * (sRD + sWR) === 0; + // ERROR out of bounds A[8] * (sRD + sWR) === 0; + B[2] * (sRD + sWR) === 0; + B[3] * (sRD + sWR) === 0; + B[4] * (sRD + sWR) === 0; + B[5] * (sRD + sWR) === 0; + B[6] * (sRD + sWR) === 0; + B[7] * (sRD + sWR) === 0; + + // ERROR: multiset_assumes(POSEIDON_G_ID, sRD + sWR, [...A[0:4], 0, ...B[0:2], ...sKeyI, sKey]); + multiset_assumes(POSEIDON_G_ID, sRD + sWR, [...A[0..4], 0, ...B[0..1], ...sKeyI, ...sKey]); + // [...in, hashType, ...cap, ...hash] + + multiset_assumes(STORAGE_ID, sRD, [SR[0] + 2**32*SR[1], SR[2] + 2**32*SR[3], SR[4] + 2**32*SR[5], SR[6] + 2**32*SR[7], + ...sKey, ...assumeInput, 0, 0, 0, 0, incCounter]); + // STORAGE_ID,latchGet,[...oldRoot, ...rkey, ...valueLow, ...valueHigh, incCounter] + + multiset_assumes(STORAGE_ID, sWR, [SR[0] + 2**32*SR[1], SR[2] + 2**32*SR[3], SR[4] + 2**32*SR[5], SR[6] + 2**32*SR[7], + ...sKey, ...D, + op[0] + 2**32*op[1], op[2] + 2**32*op[3], op[4] + 2**32*op[5], op[6] + 2**32*op[7], + incCounter]); + // STORAGE_ID,latchSet,[...oldRoot, ...rkey, ...valueLow, ...valueHigh, ...newRoot, incCounter] + + // MemAlign + + multiset_assumes(MEM_ALIGN_ID, memAlignRD, [0, C[0], ...A, ...B, ...assumeInput, ...zeros, ...zeros]); + multiset_assumes(MEM_ALIGN_ID, memAlignWR, [1, C[0], ...A, ...B, ...assumeInput, ...D, ...E]); + + cntMemAlign' === cntMemAlign * (1 - L1) + memAlignRD + memAlignWR; +} diff --git a/test/pil2/zkevm-etrog/mem.pil b/test/pil2/zkevm-etrog/mem.pil new file mode 100644 index 0000000..675ac7b --- /dev/null +++ b/test/pil2/zkevm-etrog/mem.pil @@ -0,0 +1,57 @@ +include "global.pil"; + +subproof Mem(2**23) { + + const expr INCS = Global.STEP + 1; + const expr ISNOTLAST = (1 - Global.LLAST); + const int MAX_STEP = 2**23; + + // single: 13 cols + // double: 15 cols <== safe area if more than 26.7% of memory access are R-R,W-R for same addr and value + // for example: with 80% => double = 60% * single (safe 40% of area) + + col witness addr; + col witness step[2]; + col witness mOp, mWr; + col witness value[8]; + col witness isDouble; + col witness lastAccess; // 1 if its the last access of a given address + + // The list is sorted by [addr, step] + lastAccess * (1 - lastAccess) = 0; + isDouble * (1 - isDouble) = 0; + isDouble * (1 - mOp) = 0; + + const expr stepDelta = step[0]' + isDouble * (step[0] - step[1]) - step[0]; + + range_check(ISNOTLAST, lastAccess * (addr' - addr - stepDelta) + stepDelta, 1, MAX_STEP); + range_check(isDouble, step[1] - step[0], 1, MAX_STEP); + + + // ISNOTLAST { lastAccess * (addr' - addr - (step'-step)) + (step'-step) } in INCS; + (1 - lastAccess) * (addr' - addr) = 0; + + mOp * (1 - mOp) === 0; + mWr * (1 - mWr) === 0; + // mWr could be 1 only if mOp is 1 + (1 - mOp) * mWr = 0; + + const expr isWrite = mOp' * mWr'; + const expr rdSame = (1-isWrite) * (1-lastAccess); + const expr rdDifferent = (1-isWrite) * lastAccess; + + // lastAccess has to be 1 in the last evaluation. This is necessary to + // validate [rdDifferent * (val[0]') = 0;] correctly (in a cyclic way) + (lastAccess - 1) * (1 - ISNOTLAST) = 0; + + for (int index = 0; index < length(val); index += 1) { + rdSame * (value[index]' - value[index]) = 0; + rdDifferent * (value[index]') = 0; + } + + multiset_proves(MEM_ID, mOp, [addr, step[0], mWr, ...value]); + + // only allowed double operations: R R or W R (always same addr and value) + // second operation always is a read + multiset_proves(MEM_ID, isDouble, [addr, step[1], 0, ...value]); +} \ No newline at end of file diff --git a/test/pil2/zkevm-etrog/mem_align.pil b/test/pil2/zkevm-etrog/mem_align.pil new file mode 100644 index 0000000..6fd892e --- /dev/null +++ b/test/pil2/zkevm-etrog/mem_align.pil @@ -0,0 +1,163 @@ +subproof MemAlign() { + + /* + * OPERATIONS + * + * (m0,m1,D) => v + * (m0,m1,D,v) => (w0, w1) + * + * @m0 = addr @m1 = addr + 32 (ethereum) + * + * Ethereum => BigEndian + * m0[7],m0[6],...,m0[1],m0[0],m1[7],m1[6],...,m1[1],m1[0] + * + * inM (8 bits, 32 steps) + */ + + // 32 bytes of M0, M1 ordered from HSB to LSB (32, 31, 30, ... == M[7].3, M[7].2, M[7].1, M[7].0, M[6].3, ..) + col witness inM[2]; + + // 32 bytes of V + col witness inValueShifted; + col witness inValueSorted; + + // write 32 bytes (256 bits) + col witness wr256; + + // write 1 byte (8 bits), its special case because need to ignore + // the rest of bytes, only LSB of V was stored (on w0 with offset) + col witness wr8; + + // clk registers + // 0-7 m0[0]-m0[7] + // 8-15 m1[0]-m1[7] + // 16-23 w0[0]-w0[7] + // 23-31 w1[0]-w1[7] + col witness mw; + + // clk registers + // 0-7 v[0]-v[7] + col witness v; + + // col witness m0[8]; + // col witness m1[8]; + // col witness w0[8]; + // col witness w1[8]; + // col witness v[8]; + + // when m1 is "active", means aligned with inV + // also when wr8 = 1, used to indicate when store the LSB + col witness selM1; + + // factors to build V[] in correct way, because order of V bytes + // changes according the offset and wr8 + col witness factorV[8]; + + col witness offset; + + // BYTE_C4096 = 0 (x4096), 1 (x4096), ... , 31 (x4096), 32 (x4096), 0 (x4096), 1 (x4096), ... + col fixed BYTE_C4096 = [0:4096..255:4096]...; + + // FACTOR was same for all combinations of offset, wr8, wr256 is a f(step) + // FACTOR = 2**24, 2**16, 2**8, 1, 0 (x28) + col fixed FACTOR = [2**24, 2**16, 2**8, 1, 0:28]...; + + // FACTOR change according the combinations of offset, wr8, wr256 and step. + col fixed FACTORV[8]; + + // STEP32 + // 0 - 1023 WR256 = 0 WR8 = 0 + // 1024 - 2047 WR256 = 0 WR8 = 0 + // 2048 - 3071 WR256 = 1 WR8 = 0 + // 3072 - 4096 WR256 = 0 WR8 = 1 + col fixed WR256 = [0:2048,1:1024:0:1024]...; + col fixed WR8 = [0:3072,1:1024]...; + col fixed OFFSET = [0:32..31:32]...; + col fixed SELM1; + + col RESET = Global.CLK32[0]; + + // RangeCheck Latch Clock + // factorV Lookup (FACTORV) no yes + // wr256 Lookup (WR256) yes no + // wr8 Lookup (WR8) yes no + // offset Lookup (OFFSET) yes no + // inV RangeCheck (BYTE_C4096) no yes + // inM[0..1] RangeCheck (BYTE2A,BYTE2) no yes + // m0[0..7] Built no yes + // m1[0..7] Built no yes + // w0[0..7] Built no yes + // w1[0..7] Built no yes + // v[0..7] Built no yes + // selM1 Plookup (SELM1) no yes + + // 40 => 2 (-38) + // +2 inW[2] + // factorV 8 => 2 (-6) + // +1 inVOrdenat + // Latchs + (1 - RESET) * wr256' === (1 - RESET) * wr256; + (1 - RESET) * offset' === (1 - RESET) * offset; + (1 - RESET) * wr8' === (1 - RESET) * wr8; + + col witness resultRd; + col witness resultWr8; + col witness resultWr256; + + (1 - RESET) * resultRd === 0; + (1 - RESET) * resultWr8 === 0; + (1 - RESET) * resultWr256 === 0; + resultRd * (1 - resultRd) === 0; + resultWr8 * (1 - resultWr8) === 0; + resultWr256 * (1 - resultWr256) === 0; + + (1 - wr8) * resultWr8 === 0; + (1 - wr256) * resultWr256 === 0; + (wr8 + wr256) * resultRd === 0; + + // RangeCheck + range_check([...inM], 0, 255); + + // Plookup + lookup ([STEP32, offset', wr256', wr8', selM1, inV, ...factorV], + [STEP32, OFFSET, WR256, WR8, SELM1, BYTE_C4096, ...FACTORV]); + + // selW0 contains data to be store in w0, must be 0 in "reading mode" + // in "writting mode", in particular with wr8 only on byte must be + // stored, for this reason use selM1 that was active only one clock (in wr8 mode) + col selW0 = (1 - selM1) * wr256' + selM1 * wr8'; + + // selW1 contains data to be store in w1, must be 0 in "reading mode" + col selW1 = selM1 * wr256'; + + // NOTE: when wr8 = 1 implies wr256 = 0, check in this situations where use selM1 + // to verify that non exists collateral effects + // + // col selW0 = selM1 (because wr256 = 0 and wr8 = 1) + // + // selM1 used in col _inM, but _inM is only used on dataV + // col dataV = (1 - wr256' - wr8') * _inM + (wr256' + wr8') * inV; + // col dataV = inV (because wr256 = 0 and wr8 = 1) + // + // CONCLUSION: it's safe reuse selM1 to indicate when store byte + + // data to "write" on w, if current byte must be override by V contains inV + // if not contains inM "in reading mode" must be 0. + col dataW0 = (wr8' + wr256') * inM[0] + selW0 * (inV - inM[0]); + col dataW1 = (wr8' + wr256') * inM[1] + selW1 * (inV - inM[1]); + + for (int i=0;i<8; ++i) { + m0[i]' === (1-RESET) * m0[i] + FACTOR'(i) * inM[0]; + m1[i]' === (1-RESET) * m1[i] + FACTOR'(i) * inM[1]; + w0[i]' === (1-RESET) * w0[i] + FACTOR'(i) * dataW0; + w1[i]' === (1-RESET) * w1[i] + FACTOR'(i) * dataW1; + // factorV === f(STEP, offset, wr8) + v[i]' === (1-RESET) * v[i] + factorV[i] * dataV; + } + + // _inM contains "active" value of inM + col _inM = (1 - selM1) * inM[0] + selM1 * inM[1]; + + // contains data to store in V, could be one of inM if was reading or inV if was writting + col dataV = (1 - wr256' - wr8') * _inM + (wr256' + wr8') * inV; +} \ No newline at end of file diff --git a/test/pil2/zkevm-etrog/padding_kk.pil b/test/pil2/zkevm-etrog/padding_kk.pil new file mode 100644 index 0000000..b403b49 --- /dev/null +++ b/test/pil2/zkevm-etrog/padding_kk.pil @@ -0,0 +1,153 @@ +include "padding_kkbit.pil"; + +namespace PaddingKK(%N); + + // Polynomials that are used to compute a hash chunk + pol commit freeIn; + pol constant r8Id; + pol commit connected; + pol commit addr; + + pol constant lastBlock; + pol constant lastBlockLatch; + pol constant r8valid; + + // rem: It can be different only the first byte of a new Hash. + pol commit rem; + + rem' * (1-lastHash) = (rem-1)*(1-lastHash); + + pol commit remInv; + pol remIsZero = 1 - rem*remInv; + remIsZero*rem = 0; + + pol commit spare; + pol lastHash = lastBlock*(spare + remIsZero); + pol lastHashLatch = lastBlockLatch * (spare + remIsZero); + spare' = (spare + remIsZero)*(1-lastHash); + spare * (1 - spare) = 0; + + pol commit lastHashLen; + pol commit lastHashDigest; + + lastHashLen * (1 - lastHashLen) = 0; + lastHashDigest * (1 - lastHashDigest) = 0; + + lastHashLen * (1 - lastHashLatch) = 0; + lastHashDigest * (1 - lastHashLatch) = 0; + + pol aFreeIn = (1 - (remIsZero + spare))*freeIn + remIsZero + lastHash*0x80; + r8valid {aFreeIn, r8Id, connected} in { PaddingKKBit.r8, PaddingKKBit.r8Id, PaddingKKBit.connected }; + + connected' * ( 1-lastBlock) = connected * (1-lastBlock); + connected'*lastBlock = (1 - lastHash)*lastBlock; + + pol constant sOutId; + + lastHashLatch { + hash0, + hash1, + hash2, + hash3, + hash4, + hash5, + hash6, + hash7, + sOutId + } in { + PaddingKKBit.sOut0, + PaddingKKBit.sOut1, + PaddingKKBit.sOut2, + PaddingKKBit.sOut3, + PaddingKKBit.sOut4, + PaddingKKBit.sOut5, + PaddingKKBit.sOut6, + PaddingKKBit.sOut7, + PaddingKKBit.sOutId + }; + + pol constant forceLastHash; + (1-lastHash)*forceLastHash = 0; // Force first block to be the beggining + + pol commit len; + len' * lastHash = rem' * lastHash; + len'*(1-lastHash) = len*(1-lastHash); + + pol commit hash0, hash1, hash2, hash3, hash4, hash5, hash6, hash7; + (hash0' - hash0) * (1-lastHash) = 0; + (hash1' - hash1) * (1-lastHash) = 0; + (hash2' - hash2) * (1-lastHash) = 0; + (hash3' - hash3) * (1-lastHash) = 0; + (hash4' - hash4) * (1-lastHash) = 0; + (hash5' - hash5) * (1-lastHash) = 0; + (hash6' - hash6) * (1-lastHash) = 0; + (hash7' - hash7) * (1-lastHash) = 0; + + (addr' -addr) * (1-lastHash) = 0; + (addr' - 1 -addr) * lastHashLatch = 0; + + pol commit incCounter; + // if lastHash=0 && lastBLock=0 then incCounter'=incCounter + // if lastHash=0 && lastBLock=1 then incCounter'=incCounter+1 + // if lastHash=1 && lastBlock=1 then incCounter'=1 + incCounter' = incCounter*(1-lastBlock) + (incCounter +1)*(lastBlock-lastHash) + lastHash; + (incCounter - 1) * Global.L1 = 0; + + // chunkReader generator + + pol commit crOffset; + pol commit crLen; + + pol commit crOffsetInv; + pol crLatch = 1 - crOffset*crOffsetInv; + crOffset * crLatch = 0; + + crOffset'*(1-crLatch) = (crOffset - 1)*(1-crLatch); + crLen'*(1-crLatch) = crLen*(1-crLatch); + crLatch * crOffset' = crLatch * (crLen' -1); + + pol commit crF0, crF1, crF2, crF3, crF4, crF5, crF6, crF7; + + { crOffset, crF0, crF1, crF2, crF3, + crF4, crF5, crF6, crF7} in + { Global.STEP32, Global.BYTE_FACTOR[0], Global.BYTE_FACTOR[1], Global.BYTE_FACTOR[2], Global.BYTE_FACTOR[3], + Global.BYTE_FACTOR[4], Global.BYTE_FACTOR[5], Global.BYTE_FACTOR[6], Global.BYTE_FACTOR[7] }; + + + pol commit crV0, crV1, crV2, crV3, crV4, crV5, crV6, crV7; + + pol crV0C = crV0 + crF0 * aFreeIn; + pol crV1C = crV1 + crF1 * aFreeIn; + pol crV2C = crV2 + crF2 * aFreeIn; + pol crV3C = crV3 + crF3 * aFreeIn; + pol crV4C = crV4 + crF4 * aFreeIn; + pol crV5C = crV5 + crF5 * aFreeIn; + pol crV6C = crV6 + crF6 * aFreeIn; + pol crV7C = crV7 + crF7 * aFreeIn; + + crV0' = crV0C*(1-crLatch); + crV1' = crV1C*(1-crLatch); + crV2' = crV2C*(1-crLatch); + crV3' = crV3C*(1-crLatch); + crV4' = crV4C*(1-crLatch); + crV5' = crV5C*(1-crLatch); + crV6' = crV6C*(1-crLatch); + crV7' = crV7C*(1-crLatch); + + (1-crLatch) * lastHash = 0; // Ensure qhen a hash ends it resets the address. + + /* Read Data output + crLatch * crValid {addr, PaddingKK.len - PaddingKK.rem - PaddingKK.crLen + 1, crLen, crV0C, crV1C, crV2C, crV3C, crV4C, crV5C, crV6C, crV7C} + */ + + /* Read Len output + lastHashLatch {addr, len} + */ + + /* Read Len digest + lastHashLatch { addr, hash0, hash1, hash2, hash3, hash4, hash5, hash6, hash7 } + */ + + + + diff --git a/test/pil2/zkevm-etrog/padding_kkbit.pil b/test/pil2/zkevm-etrog/padding_kkbit.pil new file mode 100644 index 0000000..ae685cb --- /dev/null +++ b/test/pil2/zkevm-etrog/padding_kkbit.pil @@ -0,0 +1,131 @@ +/* + Padding Keccak rBit + This state machine packs the rBits in bytes (r8) + And stOut bits in 8 field Elements of 32bit slints. + It also forces the connection bettwien keccak-f blocks. + + rBit sOutBit sInBit + ● ● ● + ● ● ● + ● ● ● + ● ● ● + ● ● ● + ● ● ● + ● ● ● + ● ● ● + ● + ● ● ● + ● ● ● + ● ● ● ┌─────────────────┐ + ● ● ● │ r8 calculations │ + ● ● ● │ 9*136 = 1224 │ + ● ● ● │ │ + ● ● ● └─────────────────┘ + ● ● ● + ● r8[i*136+k] + . . . + . . . + . . . + ● ● ● + ● ● ● + ● ● ● + ● ● ● + ● ● ● + ● ● ● + ● ● ● + ● ● ● + ● + ─────────────────────────────────────────────── + ● ● + ● ● + ● ● ┌─────────────────┐ + ● ● │ capacity │ + ● ● │ connection │ + . . │ 512 │ + . . └─────────────────┘ + . . + ● ● + ● ● + ────────────────────────────────────────────── + ● + ● ┌─────────────────┐ + ● │ packet sOut │ + . │ Calculation │ + . │ 256+1 │ + . └─────────────────┘ + ● + ● + ●●●●●●●● sOut{0..7}[i] +*/ + +/* + + The output for r8 is: + + [r8, r8Id] + + The output for sOut + + [sOut0, sOut1, sOut2, sOut3, sOut4, sOut5, sOut6, sOut7, connect, sOutId] + +*/ + +include "bits2field.pil"; + +namespace PaddingKKBit(%N); + pol commit rBit, sOutBit; + + // Input connection rBit -> 1 1 0 1 0 1 1 1 X + // Fr8 -> 1 2 4 8 16 32 64 128 0 + // r8 -> 0 1 3 3 11 11 43 107 235 + //latchR8-> 0 0 0 0 0 0 0 0 1 0 0 0 0 0 + pol commit r8; + pol constant r8Id; + + pol commit connected; + pol commit sOut0, sOut1, sOut2, sOut3, sOut4, sOut5, sOut6, sOut7; + pol constant sOutId; + + pol constant latchR8; + pol constant Fr8; // Factor to add to r8 + pol constant rBitValid; // 1 when rIn can be 0 or 1 + + pol constant latchSOut; + pol constant FSOut0, FSOut1, FSOut2, FSOut3, FSOut4, FSOut5, FSOut6, FSOut7; + + r8' = r8 * (1-latchR8) + rBit*Fr8; + + sOut0' = sOut0*(1-latchSOut) + sOutBit*FSOut0; + sOut1' = sOut1*(1-latchSOut) + sOutBit*FSOut1; + sOut2' = sOut2*(1-latchSOut) + sOutBit*FSOut2; + sOut3' = sOut3*(1-latchSOut) + sOutBit*FSOut3; + sOut4' = sOut4*(1-latchSOut) + sOutBit*FSOut4; + sOut5' = sOut5*(1-latchSOut) + sOutBit*FSOut5; + sOut6' = sOut6*(1-latchSOut) + sOutBit*FSOut6; + sOut7' = sOut7*(1-latchSOut) + sOutBit*FSOut7; + + connected'*(1-latchSOut) = connected*(1-latchSOut); + connected * (1-connected) = 0; + rBit *( 1- rBit) = 0; + (1-rBitValid)*rBit = 0; // Force rBit to 0 on non used pins. + sOutBit *( 1- sOutBit) = 0; + + /* + connected, sOutBit, rBit => sInBit + 0 0 0 0 + 0 0 1 1 + 0 1 0 0 + 0 1 1 1 + 1 0 0 0 + 1 0 1 1 + 1 1 0 1 + 1 1 1 0 + */ + + pol aux_sInBit = (sOutBit - 2*sOutBit*rBit); + pol sInBit = connected * aux_sInBit + rBit; + + pol constant ConnSOutBit, ConnSInBit, ConnBits2FieldBit; + + {sOutBit, sInBit, Bits2Field.bit} connect {ConnSOutBit, ConnSInBit, ConnBits2FieldBit} + diff --git a/test/pil2/zkevm-etrog/padding_pg.pil b/test/pil2/zkevm-etrog/padding_pg.pil new file mode 100644 index 0000000..d6d860a --- /dev/null +++ b/test/pil2/zkevm-etrog/padding_pg.pil @@ -0,0 +1,109 @@ +// include "global.pil"; +include "poseidong.pil"; + +subproof PaddingPG(2**23) { + + const int BYTES_BLOCK = 56; + const int BLOCKS = N \\ BYTES_BLOCK; + + col fixed F[8]; + col fixed OFFSET = [0..32]...; + col fixed LAST_BLOCK = [[0:55, 1]:BLOCKS,0...,1]; // blocks of 56 steps, 0 in the first 55 steps and 1 in the last step of the block. + // Also the last global step was 1 to close the global cycle (allowing addr change from step N-1 to 0) + col fixed CR_VALID = [1:56*BLOCKS,0...]; // 1 for valid/complete 56 steps blocks, 0 for last smaller/incomplete block + + // Polynomials that are used to compute a hash chunk + col witness acc[8]; + col witness freeIn; + col witness addr; + col witness rem; // rem: It can be different only the first byte of a new Hash. + + range_check(freeIn, 0, 255); + rem' * (1-lastHash) === (rem-1)*(1-lastHash); + + col witness remInv; + col remIsZero = 1 - rem*remInv; + remIsZero * rem === 0; + + col witness spare; + col lastHash = lastBlock*(spare + remIsZero); + spare' === (spare + remIsZero)*(1-lastHash); + spare * (1 - spare) === 0; + + col witness lastHashLen; + col witness lastHashDigest; + + lastHashLen * (1 - lastHashLen) === 0; + lastHashDigest * (1 - lastHashDigest) === 0; + + lastHashLen * (1 - lastHash) === 0; + lastHashDigest * (1 - lastHash) === 0; + + col aFreeIn = (1 - (remIsZero + spare))*freeIn + remIsZero + lastHash*0x80; + + col accC[8]; + for (i = 0; i < 8; i += 1) { + accC[i] = acc[i] + F[i] * aFreeIn; + acc[i]' === accC[i] * (1 - LAST_BLOCK); + } + + lookup_assume(POSEIDON_G_ID, lastBlock, [...accC, ...prevHash, ...curHash]); + + col witness curHash[4]; + col witness prevHash[4]; + + for (i = 0; i < 4; i += 1) { + (1 - LAST_BLOCK) * (curHash[i]' - curHash[i]) === 0 + prevHash[i]' === LAST_BLOCK * (curHash[i] - prevHash[i]) + prevHash[i] - lastHash * curHash[i]; + } + + col witness incCounter; + // if lastHash=0 && lastBLock=0 then incCounter'=incCounter + // if lastHash=0 && lastBLock=1 then incCounter'=incCounter+1 + // if lastHash=1 && lastBlock=1 then incCounter === + incCounter' === incCounter*(1-lastBlock) + (incCounter +1)*(lastBlock-lastHash) + lastHash; + + col witness len; + len' * lastHash === rem' * lastHash; + len'*(1-lastHash) === len*(1-lastHash); + + (addr' -addr) * (1-lastHash) === 0; + + col doInc = lastHash * (1-Global.L1'); + (addr' - 1 -addr) * doInc === 0; + + // chunkReader generator + + col witness crOffset; + col witness crLen; + + col witness crOffsetInv; + col crLatch = 1 - crOffset*crOffsetInv; + crOffset * crLatch === 0; + + crOffset'*(1-crLatch) === (crOffset - 1)*(1-crLatch); + crLen'*(1-crLatch) === crLen*(1-crLatch); + crLatch * crOffset' === crLatch * (crLen' -1); + + col witness crF[8]; + lookup_check([crOffset, ...crF], + [OFFSET, ...BYTE_FACTOR]); // ?¿?¿? BYTE_FACTOR[8] + + col crVC[8]; + col witness crV[8]; + for (i = 0; i < 8; ++i) { + crVC[i] = crV[i] + crF[i] * aFreeIn; + crV[i]' === crVC[i] * (1 - crLatch); + } + + (1-crLatch) * lastHash === 0; // Ensure when a hash ends it resets the address. + + /* Read Data output + crLatch * crValid [hash0, hash1, hash2, hash3, hash4, hash5, hash6, hash7, crOffset - crLen -1, crLen, crV0C, crV1C, crV2C, crV3C, crV4C, crV5C, crV6C, crV7C] + */ + + /* Read Len output + lastHash [hash0, hash1, hash2, hash3, hash4, hash5, hash6, hash7, len] + */ + +} \ No newline at end of file diff --git a/test/pil2/zkevm-etrog/padding_sha256.pil b/test/pil2/zkevm-etrog/padding_sha256.pil new file mode 100644 index 0000000..c7d9650 --- /dev/null +++ b/test/pil2/zkevm-etrog/padding_sha256.pil @@ -0,0 +1,167 @@ +include "global.pil"; +include "padding_sha256bit.pil"; + +namespace PaddingSha256(%N); + + // Polynomials that are used to compute a hash chunk + pol commit freeIn; + pol constant r8Id; + pol commit connected; + pol commit addr; + + pol constant lastBlock; + pol constant lastBlockLatch; + pol constant r8valid; + + // rem: It can be different only the first byte of a new Hash. + pol commit rem; + + rem' * (1-lastHash) = (rem-1)*(1-lastHash); + + pol commit remInv; + pol remIsZero = 1 - rem*remInv; + remIsZero*rem = 0; + + pol commit spare; + pol lastHash = lastBlock*lengthSection; // 1 in the last row of the last block of a hash + pol lastHashLatch = lastBlockLatch*lengthSection; + spare' = (spare + remIsZero)*(1-lastHash); + spare * (1 - spare) = 0; + + pol constant PrevLengthSection; + pol commit lengthSection; + pol commit accLength; + pol constant LengthWeight; + pol startLengthSection = (spare + remIsZero)*PrevLengthSection; + lengthSection' = (lengthSection + startLengthSection)*(1-lastHash); + lengthSection * (1-lengthSection) = 0; + + pol freeIn_LengthWeight = freeIn * LengthWeight; + accLength' = accLength*(1-lastHash) + lengthSection'*freeIn_LengthWeight'; + (accLength - len*8)*lastHash = 0; + + pol commit lastHashLen; + pol commit lastHashDigest; + + lastHashLen * (1 - lastHashLen) = 0; + lastHashDigest * (1 - lastHashDigest) = 0; + + lastHashLen * (1 - lastHashLatch) = 0; + lastHashDigest * (1 - lastHashLatch) = 0; + + + pol aFreeIn = (1 - (remIsZero + spare))*freeIn + remIsZero*0x80 + lengthSection*freeIn; + r8valid {aFreeIn, r8Id, connected} in { PaddingSha256Bit.r8, PaddingSha256Bit.r8Id, PaddingSha256Bit.connected }; + + connected' * ( 1-lastBlock) = connected * (1-lastBlock); + connected'*lastBlock = (1 - lastHash)*lastBlock; + + pol constant sOutId; + + lastHashLatch { + hash0, + hash1, + hash2, + hash3, + hash4, + hash5, + hash6, + hash7, + sOutId + } in { + PaddingSha256Bit.sOut0, + PaddingSha256Bit.sOut1, + PaddingSha256Bit.sOut2, + PaddingSha256Bit.sOut3, + PaddingSha256Bit.sOut4, + PaddingSha256Bit.sOut5, + PaddingSha256Bit.sOut6, + PaddingSha256Bit.sOut7, + PaddingSha256Bit.sOutId + }; + + pol constant forceLastHash; + (1-lastHash)*forceLastHash = 0; // Force first block to be the beggining + + pol commit len; + len' * lastHash = rem' * lastHash; + len'*(1-lastHash) = len*(1-lastHash); + + pol commit hash0, hash1, hash2, hash3, hash4, hash5, hash6, hash7; + (hash0' - hash0) * (1-lastHash) = 0; + (hash1' - hash1) * (1-lastHash) = 0; + (hash2' - hash2) * (1-lastHash) = 0; + (hash3' - hash3) * (1-lastHash) = 0; + (hash4' - hash4) * (1-lastHash) = 0; + (hash5' - hash5) * (1-lastHash) = 0; + (hash6' - hash6) * (1-lastHash) = 0; + (hash7' - hash7) * (1-lastHash) = 0; + + (addr' -addr) * (1-lastHash) = 0; + (addr' - 1 -addr) * lastHashLatch = 0; + + pol commit incCounter; + // if lastHash=0 && lastBLock=0 then incCounter'=incCounter + // if lastHash=0 && lastBLock=1 then incCounter'=incCounter+1 + // if lastHash=1 && lastBlock=1 then incCounter'=1 + incCounter' = incCounter*(1-lastBlock) + (incCounter +1)*(lastBlock-lastHash) + lastHash; + (incCounter - 1) * Global.L1 = 0; + + // chunkReader generator + + pol commit crOffset; + pol commit crLen; + + pol commit crOffsetInv; + pol crLatch = 1 - crOffset*crOffsetInv; + crOffset * crLatch = 0; + + crOffset'*(1-crLatch) = (crOffset - 1)*(1-crLatch); + crLen'*(1-crLatch) = crLen*(1-crLatch); + crLatch * crOffset' = crLatch * (crLen' -1); + + pol commit crF0, crF1, crF2, crF3, crF4, crF5, crF6, crF7; + + { crOffset, crF0, crF1, crF2, crF3, + crF4, crF5, crF6, crF7} in + { Global.STEP32, Global.BYTE_FACTOR[0], Global.BYTE_FACTOR[1], Global.BYTE_FACTOR[2], Global.BYTE_FACTOR[3], + Global.BYTE_FACTOR[4], Global.BYTE_FACTOR[5], Global.BYTE_FACTOR[6], Global.BYTE_FACTOR[7] }; + + + pol commit crV0, crV1, crV2, crV3, crV4, crV5, crV6, crV7; + + pol crV0C = crV0 + crF0 * aFreeIn; + pol crV1C = crV1 + crF1 * aFreeIn; + pol crV2C = crV2 + crF2 * aFreeIn; + pol crV3C = crV3 + crF3 * aFreeIn; + pol crV4C = crV4 + crF4 * aFreeIn; + pol crV5C = crV5 + crF5 * aFreeIn; + pol crV6C = crV6 + crF6 * aFreeIn; + pol crV7C = crV7 + crF7 * aFreeIn; + + crV0' = crV0C*(1-crLatch); + crV1' = crV1C*(1-crLatch); + crV2' = crV2C*(1-crLatch); + crV3' = crV3C*(1-crLatch); + crV4' = crV4C*(1-crLatch); + crV5' = crV5C*(1-crLatch); + crV6' = crV6C*(1-crLatch); + crV7' = crV7C*(1-crLatch); + + (1-crLatch) * lastHash = 0; // Ensure qhen a hash ends it resets the address. + + /* Read Data output + crLatch * crValid {addr, PaddingSha256.len - PaddingSha256.rem - PaddingSha256.crLen + 1, crLen, crV0C, crV1C, crV2C, crV3C, crV4C, crV5C, crV6C, crV7C} + */ + + /* Read Len output + lastHashLatch {addr, len} + */ + + /* Read Len digest + lastHashLatch { addr, hash0, hash1, hash2, hash3, hash4, hash5, hash6, hash7 } + */ + + + + diff --git a/test/pil2/zkevm-etrog/padding_sha256bit.pil b/test/pil2/zkevm-etrog/padding_sha256bit.pil new file mode 100644 index 0000000..3f92fe0 --- /dev/null +++ b/test/pil2/zkevm-etrog/padding_sha256bit.pil @@ -0,0 +1,154 @@ +/* + Padding sha256 rBit + This state machine packs the rBits in bytes (r8) + And stOut bits in 8 field Elements of 32bit slints. + It also forces the connection bettwien keccak-f blocks. + + s1 s2 + ● ● + ● ● + ● ● + ● ● + ● ● + ● ● + ● ● + ● ● + ● ● ┌─────────────────┐ + ● ● │ s1 = sout(n-1) │ + ● ● │ s2 = sin(n) │ + ● ● │ 8*64 = 256 │ + ● ● └─────────────────┘ + ● ● + ● ● + ● ● + ● ● + ● ● + ● ● +─────────────────────────────────────────────── + ● ● + ● ● + ● ● + ● ● + ● ● + ● ● + ● ● + ● ● + ● + ● ● + ● ● ┌─────────────────┐ + ● ● │ s1 = rIn (1/2) │ + ● ● | s2 = sout(n) | + ● ● │ │ + ● ● │ 32*8 = 256 │ + ● ● └─────────────────┘ + ● ● + ● + . . + . . + . . + ● ● + ● ● + ● ● + ● ● + ● ● + ● ● + ● ● + ● ● + ● ●●●●●●●● sOut{0..7}[i] + ────────────────────────────────────────────── + ● + ● + ● + ● + ● + ● + ● + ● + ● + ● + ● ┌─────────────────┐ + ● │ s1 = rIn (2/2) │ + . │ │ + . │ 32*8 = 256 │ + . └─────────────────┘ + ● + ● + ● +*/ + +/* + + The output for r8 is: + + [r8, r8Id] + + The output for sOut + + [sOut0, sOut1, sOut2, sOut3, sOut4, sOut5, sOut6, sOut7, connect, sOutId] + +*/ + +include "bits2field_sha256.pil"; + +subproof PaddingSha256Bit(2**23) { + const int bits = 7 + + col fixed FIELD_LATCH = [0:6,1]...; + col witness bit; + + expr bitToField = 0; + for (int index = 0; index < bits; ++index) { + bitToField += (bits - index - 1)'bit * 2**index; + } + + bit *(1-bit) === 0; + FIELD_LATCH * (bitToField - input[0]) === 0; + + + col witness s1, s2; + + // Input connection rBit -> 1 1 0 1 0 1 1 1 X + // Fr8 -> 128 64 32 16 8 4 2 1 0 + // r8 -> 128 192 192 208 208 212 214 215 0 + //latchR8-> 0 0 0 0 0 0 0 0 1 0 0 0 0 0 + pol commit r8; + pol constant r8Id; + + pol commit connected; + pol commit sOut0, sOut1, sOut2, sOut3, sOut4, sOut5, sOut6, sOut7; + pol constant sOutId; + + pol constant latchR8; + pol constant Fr8; // Factor to add to r8 + + pol constant latchSOut; + pol constant FSOut0, FSOut1, FSOut2, FSOut3, FSOut4, FSOut5, FSOut6, FSOut7; + + r8' = r8 * (1-latchR8) + s1'*Fr8'; + + sOut0' = sOut0*(1-latchSOut) + s2'*FSOut0'; + sOut1' = sOut1*(1-latchSOut) + s2'*FSOut1'; + sOut2' = sOut2*(1-latchSOut) + s2'*FSOut2'; + sOut3' = sOut3*(1-latchSOut) + s2'*FSOut3'; + sOut4' = sOut4*(1-latchSOut) + s2'*FSOut4'; + sOut5' = sOut5*(1-latchSOut) + s2'*FSOut5'; + sOut6' = sOut6*(1-latchSOut) + s2'*FSOut6'; + sOut7' = sOut7*(1-latchSOut) + s2'*FSOut7'; + + connected'*(1-latchSOut) = connected*(1-latchSOut); + connected * (1-connected) = 0; + s1 *( 1- s1) = 0; + s2 *( 1- s2) = 0; + + + pol constant HIn; + pol constant DoConnect; + + pol muxOut = connected*(s1 - HIn) + HIn; + DoConnect*(s2-muxOut) = 0; + + pol constant ConnS1, ConnS2, ConnBits2FieldBit; + + {s1, s2, Bits2FieldSha256.bit} connect {ConnS1, ConnS2, ConnBits2FieldBit} + + diff --git a/test/pil2/zkevm-etrog/poseidong.pil b/test/pil2/zkevm-etrog/poseidong.pil new file mode 100644 index 0000000..dbb9e3b --- /dev/null +++ b/test/pil2/zkevm-etrog/poseidong.pil @@ -0,0 +1,120 @@ +const int POSEIDON_G_ID = 11; + +subproof PoseidonG(2**23) { + + const int N_ROUNDS_F = 8; + const int N_ROUNDS_P = 22; + const int N_ROUNDS = N_ROUNDS_F + N_ROUNDS_P; + const int MAX_HASHES = N \\ N_ROUNDS; + + col fixed LAST = [[0:N_ROUNDS,1]...,1]; + col fixed LATCH = [[1,0:N_ROUNDS]:MAX_HASHES,0...]; + col fixed LASTBLOCK = [0:N_ROUNDS,1]...; + col fixed PARTIAL = [0:(N_ROUNDS_F/2),1:N_ROUNDS_F,0:(N_ROUNDS_F/2)+1]...; + col fixed C[12]; + + col witness value[8], hashType, cap[3]; + col witness hash[4]; + col witness result; + + const expr a[12]; + int index = 0; + for (const expr c in [...value, hashType, cap]) { + a[index] = c + C[index]; + (value[index]' - c[index]) * (1 - LAST) === 0; + ++index; + } + + const int M_CIRC[12] = [17, 15, 41, 16, 2, 28, 13, 13, 39, 18, 34, 20]; + const int M_DIAG[12] = [8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; + + const expr x2[12], x4[12], x6[12], x7[12], b[12], c[12]; + for (int i = 0; i < 12; i += 1) { + x2[i] = a[i] * a[i]; + x4[i] = x2[i] * x2[i]; + x6[i] = x2[i] * x4[i]; + x7[i] = x6[i] * a[i]; + if (i == 0) b[0] = x7[0]; + else b[i] = PARTIAL * (a[i] - x7[i]) + x7[i]; + } + + for (int i=0; i < 12; i += 1) { + expr ce; + for (int j=0; j<12; ++j) { + ce += (M_CIRC[(12 - i + j) % 12] + (i == j ? M_DIAG[i] : 0)) * b[j]; + } + c[i] = ce; + } + + for (int i = 0; i < 4; i += 1) { + (hash[i] - value[i]) * LASTBLOCK === 0; + (hash[i] - hash[i]') * (1-LAST) === 0; + if (i > 2) continue; + } + result * (1 - result) === 0; + result * (1 - LATCH) === 0; + + C[0] = [0xb585f766f2144405, 0x7746a55f43921ad7, 0xb2fb0d31cee799b4, 0x0f6760a4803427d7, 0xe10d666650f4e012, 0x8cae14cb07d09bf1, + 0xd438539c95f63e9f, 0xef781c7ce35b4c3d, 0xcdc4a239b0c44426, 0x277fa208bf337bff, 0xe17653a29da578a1, 0xc54302f225db2c76 ]...; + C[1] = [0x86287821f722c881, 0x59cd1a8a41c18e55, 0xc3b919ad495dc574, 0xa484c4c5ef6a0781, 0x308bbd23dc5416cc, 0x6e4a40c18f30c09c, + 0x9a2eedb70d8f8cfa, 0xe360c6e0ae486f38, 0xd5c7718fbfc647fb, 0xc35eae071903ff0b, 0x849c2656969c4be7, 0xc0572c8c08cbbbad ]...; + C[2] = [0xe9fa634a21de0082, 0xf56f6d48959a600d, 0xf7d713e806391165, 0x8297132b32825daf, 0xad6805e0e30b2c8a, 0xac51d9f5fcf8535e, + 0x502ad7dc18c2ad87, 0x57a1550c110b3041, 0x66bbd30e6ce0e583, 0x0da2abef589d644e, 0xf061274fdb150d61, 0x28b8ec3ae9c29633 ]...; + C[3] = [0x92a756e67e2b9413, 0x70e741ebfee96586, 0x019d5ee2af82ec1c, 0x6f6f2ed772466352, 0x7cf416cfe7e14ca1, 0x61df517b86a46439, + 0x85dc499b11d77b75, 0x4b959b48b9c10733, 0xe8be3e5da8043e57, 0xf5c0bc1de6da8699, 0x40b12cbf09ef74bf, 0xa637093ecb2ad631 ]...; + C[4] = [0x3cc3f892184df408, 0x2e479dc157bf31bb, 0x6f49de07a6234346, 0x213ce7bede378d7b, 0x5b0431345d4dea83, 0xa2de45780344d6a1, + 0x7103aaf94a7bf308, 0x5326fc0d97279301, 0xa9ceb74fec024747, 0x27f8ec88bb21b1a3, 0xfceb4fda1ded0893, 0xfac6ff1346a41675 ]...; + C[5] = [0x7131aa45268d7d8c, 0x9351036095630f9f, 0xad535b24afc26bfb, 0x4627f5c6993e44be, 0x645cf794b8f1cc58, 0x241c70ed0af61617, + 0xacb8e076647905f1, 0x3737e9db4c4f474d, 0xe7ea5e33e75fffb6, 0x90dee49fc9bfc23a, 0xd1b1edf76bc09c92, 0x0b65481ba645c602 ]...; + C[6] = [0x99ad1aab0814283b, 0x438a7c91d416ca4d, 0xb60de3bcc5ea751c, 0xc99cab6aef6f58bc, 0x69a5ed92a72ee4ff, 0x5e7b329c1ed4ad71, + 0x5fc0ac0800144885, 0x32db829239774eca, 0x0ade699c5830f310, 0x7cc5583b10415f21, 0x85df9ed2e166d64f, 0x6604df4fee32bcb1 ]...; + C[7] = [0xeb84f608da56ef48, 0xda608834c40e603d, 0x8f97fe408061f183, 0xa93f485c96f37b89, 0x6704e8ee8f18d563, 0xcee3e9ac1e072119, + 0x510d0e65e2b470c1, 0xf6323f486b9038f0, 0x0b508cdeffa5ceef, 0xf2417089e4fb3cbd, 0x60e75c2890d15730, 0xa6217d8bf660f29c ]...; + C[8] = [0x7159cd30c3ac118e, 0x839b4e8fafead540, 0x0d3f3e5e82920adc, 0x8f7d83bddee7bba8, 0x780f2243ea071d06, 0xeb915845f3de1634, + 0xd19e120d26b6f386, 0x016ee53a7e5fecc6, 0xcb5fd54e7933e477, 0xacb8417879fd449f, 0x9c22190be7f74732, 0x5d693c1ba3ba3621 ]...; + C[9] = [0xdcef0797c2b69ec7, 0x3d639263da827b13, 0xe273fd971bc8d0e7, 0x418f02702d227ed5, 0x8c25fda3b503038c, 0x2cbaed4daec8c07c, + 0x5f58e6afcdd6ddc2, 0x284650ac5e1b0eba, 0x635b337ee819dab5, 0x9f9a036ed4f2d49f, 0xb93e260cae5c170e, 0xb0a7eae879ddb76d ]...; + C[10] = [0xd0762cbc8ca6570c, 0x34c6efb812b04bf5, 0x40bf0ab5fa14c112, 0xb6b570fc7c5740d3, 0x5a27b9002de33454, 0xb1a5b165b6d2b2d2, + 0x8722e0ace9d1be22, 0x788ee3b37e5680fb, 0x14a726661551e284, 0x98b7672f9ef3b419, 0xbb93ae776bb30e3a, 0x28fd3b046380f850 ]...; + C[11] = [0x30a4680593258387, 0x337dc00c61bd9ce1, 0xd5eca244c7a4ff1d, 0x7762638264d279bd, 0xc1e434bedeefd767, 0x0299351a53b8ec22, + 0xb2d456e4ad251b80, 0x3e9ed1fda49cea0b, 0x2972a92ba450bed8, 0x20216dd77be493de, 0xadffe8cf28449ec6, 0x1c4dbb1c4c27d243 ]...; + C[12] = [0x15a16a8a8322d458, 0x388a128b7fd9a609, 0x2300e5d6baedf0fb, 0x2f63aa8647e15104, 0xf1c36ce86ecec269, 0x27181125183970c9, + 0xe584029370dca96d, 0x4d9bbc3e02f1cfb2, 0xea35bc29692af6f8, 0x18e21b4beabb4137, 0x1e3b9fc625b554f4, 0x25d64362697828fd ]...; + C[13] = [0x5a3f1bb1c53a9645, 0xdb7f023869fb8d38, 0xb462065911d4e1fc, 0x49c24ae4437d8030, 0xd793862c112b0566, 0xaadd1106730d8feb, + 0xc43b6e0e97b0d568, 0xe29024c18ee6fca2, 0x5e50c27535b88c66, 0x10383f20a4ff9a87, 0x38e8ee9d71a45af8, 0xdd5118375bf1a9b9 ]...; + C[14] = [0x775005982d74d7f7, 0x86ab99b4dde6c8b0, 0xb1204f603f51c080, 0xef61ac8470250ecf, 0x1bbcd90f132c603f, 0x0cd1dabd964db557, + 0x11a3ae5beb9d1ec9, 0xf755bfeea585d11d, 0xa3b83250268ea4d7, 0x516306f4927c93af, 0xddb4ac49c9efa1da, 0x64bb6dec369d4418 ]...; + C[15] = [0xf9cc95c22b4c1fcc, 0x08d37f755f4ae9f6, 0xeec49b613478675b, 0xf143933aed25e0b0, 0xe4c5dd8255dfc622, 0xe7ad7756f193198e, + 0x92c2318b87fff9cb, 0x739c25f8fd73596d, 0x5636cac9f16dfed0, 0xdd8f909a938e0172, 0xc6401fe115063f5b, 0x8ad97b33f1ac1455 ]...; + C[16] = [0x0c49366bb25e8513, 0x0784d3d2f1698309, 0x530fb67ea1809a81, 0x410492299bb01f49, 0x139542347424b9ac, 0x9cb0bd5ea1a1115e, + 0x02e3f615c38f49a1, 0x985d4f4a9c5291ef, 0x775b9feafdcd26e7, 0x304265a6384f0f2d, 0x593664c39773012c, 0x4f0a2e5fb028f2ce ]...; + C[17] = [0xdd611f1000c17442, 0xd8185f9adfea4fd0, 0xef87139ca9a3ab1e, 0x3ba71336c34ee133, 0x7d3a455d56b70238, 0x660d32e130182684, + 0x297a863f48cd1f43, 0x90e0a736a751ebb7, 0x549f80ce550c4fd3, 0x0f73b2922f38bd64, 0x16bf1f73fb7a9c3f, 0x6d1f5a59005bec17 ]...; + C[18] = [0x02ff876fa5ef97c4, 0xc5cb72a2a51159b0, 0x8470f39d2d5c900e, 0x25abb3f1d39fcb76, 0x23eb8cc9b372442f, 0xd687ba55c64f6364, + 0xda8d9e90fd8ff158, 0xe3cbdc7d2fe45ea7, 0xb9a8c9b3aee52297, 0xc0d28a5c10960bd3, 0x45d7ac9b68f71a34, 0xeeb76e397069e804 ]...; + C[19] = [0x3d06c8bd1514e2d9, 0x9c9c98207cb10767, 0x65700b51aedfb5ef, 0x911f451539869408, 0x7ae6849fbc3a0ec6, 0x3bb340eba06afe7e, + 0xb46e9d8b682ea65e, 0x8dcf22f9a3b34356, 0x77bdaeda586257a7, 0xf19e400a5104d20d, 0xc368a348e46d950f, 0x9ef1cd60e679f284 ]...; + C[20] = [0xe89cd854d5d01d33, 0x5cd377dc8bb882a2, 0xa7b0fb7883eee860, 0x7684403ec392950d, 0x5fa3f06f4fed3b52, 0x8df57ac11bc04831, + 0x2db01efa1e1e1897, 0x54846de4aadb9ca2, 0xba6745385893c784, 0x541d496344d2c75b, 0xe909678474e687fe, 0xdfe89923f6c9c2ff ]...; + C[21] = [0xece5a71e0cfedc75, 0x5ff98fd5d51fe610, 0x83e8941918964615, 0x5922040b47f150c1, 0xf97d750e3dd94521, 0x5080d4c2b86f56d7, + 0xa7de115b56c78d70, 0x6a9242ac87538194, 0xf7856ef7f9173e44, 0x2265fc92feb0dc09, 0x17dfc8e4f7ba8a57, 0x9001a64209f21db8 ]...; + C[22] = [0x90004c1371b893c5, 0xb932b7cf752e5545, 0xa0b1df81b6fe59fc, 0x8ef1dd26770af2c2, 0x0541a4f9cfbeed35, 0x9e61106178bfc530, + 0xb3767e80935d8af2, 0x0098d5782065af06, 0x31d191cd5c1466c7, 0x410fefafa319ac9d, 0xbdf8f242e316c4ab, 0x9e8cd55b57637ed0 ]...; + C[23] = [0xde122bebe9a39368, 0x4d001fd58f002526, 0xca6637000eb4a9f8, 0x2f2339d624f91f78, 0x6d1a7918c80df518, 0xdf9a4939342308e9, + 0xebc2151ee6c8398c, 0x03cc2ba8a1116515, 0xd341d037e840cf83, 0x387cb5d25af4afcc, 0xbba2515f22909e87, 0x7248fe7705f38e47 ]...; + C[24] = [0x4d61e56a525d225a, 0x262e963c8da05d3d, 0x59e89b094d220ec2, 0x055d5b52b78b9c5e, 0x82b27eb33514ef99, 0xd30094ca96b7ce7b, + 0xcf5cb381cd0a1535, 0xfeed4db6919e5a7c, 0x41703f53753be59f, 0x5eeea940fcde8b6f, 0x4cd1f1b175100206, 0x4a20358574454ec0 ]...; + C[25] = [0x1478d361dbbf9fac, 0x6f02dc07d141875c, 0x296a202ed8e556a2, 0x2afd67999bf32ee5, 0x7acfd96efa95491d, 0x6798ba0c0abb2c6d, + 0x34c6f57b26c92122, 0x5736e1bad206b5de, 0x20057d2a0056521b, 0x3dea5bd5d0578bd7, 0x16e50d897d4634ac, 0x29bff3ecb9b7a6e3 ]...; + C[26] = [0x475cd3205a3bdcde, 0x18a42105c31b7e88, 0x023e7414af663068, 0x15147108121967d7, 0xe4a3dff1d7d6fef9, 0x01a8d1a588085737, + 0x11b4c74eda62beef, 0xe587cc0d69a73346, 0x1ff7327017aa2a6e, 0x594e29c42473d06b, 0xf6f31db1899b12d5, 0xc02ac5e47312d3ca ]...; + C[27] = [0xe70201e960cb78b8, 0x6f90ff3b6a65f108, 0x42747a7245e7fa84, 0xd1f507e43ab749b2, 0x1c86d265f15750cd, 0x3996ce73dd832c1c, + 0x8e7fba02983224bd, 0xba0dec7103255dd4, 0x9e9cbd781628fc5b, 0xdae8645996edd6a5, 0xdebe0853b1a1d378, 0xa49229d24d014343 ]...; + C[28] = [0x7be5b9ffda905e1c, 0xa3c95eaec244aa30, 0x0230bca8f4df0544, 0x4135c2bebfe148c6, 0x166fc0cc438a3c72, 0x3762b59a8ae83efa, + 0xe8928a4c89114750, 0x2a440b51a4945ee5, 0x80cefd2b7d99ff83, 0xbb9879c6e61fd62a, 0x6e7c8f1a84265034, 0x164bb2de1bbeddc8 ]...; + C[29] = [0xf3c12fe54d5c653b, 0x40b9e922ed9771e2, 0x551f5b0fbe7b1840, 0x25032aa7c4cb1811, 0xaaed34074b164346, 0x8ffd96bbf9c9c81d, + 0x70fc91eb5937085c, 0x7f795e2a5f915440, 0x4543d9df5476d3cb, 0xf172d73e004fc90d, 0xdfd1c4febcc81238, 0xbc8dfb627fe558fc ]...; + C[30] = [0...]; + + multiset_assumes(POSEIDON_G_ID, result, [...value, hashType, ...cap, ...hash]); +} \ No newline at end of file diff --git a/test/pil2/zkevm-etrog/range_32.pil b/test/pil2/zkevm-etrog/range_32.pil new file mode 100644 index 0000000..ddec318 --- /dev/null +++ b/test/pil2/zkevm-etrog/range_32.pil @@ -0,0 +1,9 @@ +subproof Range32(2**23) { + + col fixed CLK = [0,1]...; + col witness value; + col witness bits; + col witness result; + + result * (1 - result) === 0; +} diff --git a/test/pil2/zkevm-etrog/rom.pil b/test/pil2/zkevm-etrog/rom.pil new file mode 100644 index 0000000..c0a0aac --- /dev/null +++ b/test/pil2/zkevm-etrog/rom.pil @@ -0,0 +1,25 @@ +const int ROM_ID = 2; + +subproof Rom(2**12) { + + const int NR = 8; + + col fixed CONST[NR]; + col fixed OFFSET; + col fixed IN_A, IN_B, IN_C, IN_ROTL_C, IN_D, IN_E, IN_SR, IN_FREE, IN_FREE0, + IN_CTX, IN_SP, IN_PC, IN_GAS, IN_HASHPOS, IN_STEP, IN_RR, IN_RCX, IND, IND_RR, + IN_CNT_ARITH, IN_CNT_BINARY, IN_CNT_KECCAK_F, IN_CNT_SHA_256_F, + IN_CNT_MEM_ALIGN, IN_CNT_PADDING_PG, IN_CNT_POSEIDON_G, + INC_STACK, BIN_OP, ARITH_OP, HASH_BYTES, JMP_ADDR, ELSE_ADDR, LINE; + col fixed FLAGS; + + // include "rom_compiled.pil"; + + // repeat_last_source_line(); + lookup_proves(ROM_ID, 1, [...CONST, IN_A, IN_B, IN_C, IN_ROTL_C, IN_D, IN_E, IN_SR, IN_FREE, IN_FREE0, + IN_CTX, IN_SP, IN_PC, IN_GAS, IN_HASHPOS, IN_STEP, IN_RR, IN_RCX, IND, IND_RR, + IN_CNT_ARITH, IN_CNT_BINARY, IN_CNT_KECCAK_F, IN_CNT_SHA_256_F, + IN_CNT_MEM_ALIGN, IN_CNT_PADDING_PG, IN_CNT_POSEIDON_G, + FLAGS, OFFSET, INC_STACK, BIN_OP, ARITH_OP, HASH_BYTES, + JMP_ADDR, ELSE_ADDR, LINE]); +} \ No newline at end of file diff --git a/test/pil2/zkevm-etrog/sha256f.pil b/test/pil2/zkevm-etrog/sha256f.pil new file mode 100644 index 0000000..202d07d --- /dev/null +++ b/test/pil2/zkevm-etrog/sha256f.pil @@ -0,0 +1,43 @@ +include "tools.pil" + +const SHA256F_ID = 66; + +subproof Sha256F(2**23) { + + const int bits = 7; + const int ONES = (2**bits) - 1; + + col fixed FIELD_LATCH = [0:6,1]...; + col fixed L1 = [1,0...]; + col witness bit; + + expr bitToField = 0; + for (int index = 0; index < bits; ++index) { + bitToField += (bits - index - 1)'bit * 2**index; + } + + bit *(1-bit) === 0; + FIELD_LATCH * (bitToField - input[0]) === 0; + + col witness input[3], output; + + // GATE_TYPE => script gate sequence + // kGateType => type of gate, used to define all combinations of valid values. + // input[], output are the witness, gate used in each row defined by GATE_TYPE. + lookup_assumes(SHA256F_TABLE_ID, 1, [GATE_TYPE, ...input, output, input[2]' * CARRY_ENABLED]); + + col fixed CONN[4]; + col fixed GATE_TYPE; + col fixed CARRY_ENABLED; // 1 WHEN ADD + + // TODO: loading circuit with connections + include "sha256f_script.pil" + // wires: conections between gates + // {input[0], input[1], input[2], output} connect {Conn[0], Conn[1], Conn[2], Conn[3]}; + + // signal constant 0 (conect to use constant 0 in gate) + L1 * input[0] === 0; + + // signal constant 1 => 1 x 7 = 1111111 (conect to use constant 1 in gate) + L1 * (ONES - input[1]) === 0; +} \ No newline at end of file diff --git a/test/pil2/zkevm-etrog/sha256f_table.pil b/test/pil2/zkevm-etrog/sha256f_table.pil new file mode 100644 index 0000000..8ba1c1e --- /dev/null +++ b/test/pil2/zkevm-etrog/sha256f_table.pil @@ -0,0 +1,54 @@ +include "tools.pil" + +const int SHA256F_TABLE_ID = 67; + +subproof Sha256FTable(2**23) { + + const int bits = 7; + const int TO = 2**7 - 1; + const int TO4 = 4 * TO; + const int MASK = 2**7 - 1; + + const int GATE_XOR = 0; + const int GATE_CH = 1; + const int GATE_MAJ = 2; + const int GATE_ADD = 3; + + col fixed GATE_TYPE = [GATE_XOR, GATE_CH, GATE_MAJ, GATE_ADD]...; + col fixed IN1 = [0:TO4**2..TO:TO4**2]...; + col fixed IN2 = [0:TO4..TO:TO4]...; + col fixed IN3 = [0:4..TO:4]...; + // TODO: expressions inside fixed definition + // col fixed OUT = [IN1 ^ IN2 ^ IN3, + // (IN1 & IN2) ^ ((MASK ^ IN1) & IN3), + // (IN1 & IN2) ^ (IN1 & IN3) ^ (IN2 & IN3), + // IN1 ^ IN2 ^ IN3]...; + // col fixed CARRY_OUT = [0,0,0,(IN1 & IN2) | (IN1 & IN3) | (IN2 & IN3)]...; + col fixed OUT; + col fixed CARRY_OUT; + + for (int irow = 0; irow < N; irow += 4) { + const int in1 = IN1[irow]; + const int in2 = IN2[irow]; + const int in3 = IN3[irow]; + const int xor = in1 ^ in2 ^ in3; + + // xor + OUT[irow] = xor; + CARRY_OUT[irow] = 0; + + // ch + OUT[irow+1] = (in1 & in2) ^ ((MASK ^ in1) & in3); + CARRY_OUT[irow+1] = 0; + + // maj + OUT[irow+2] = (in1 & in2) ^ (in1 & in3) ^ (in2 & in3); + CARRY_OUT[irow+2] = 0; + + // + OUT[irow+3] = xor; + CARRY_OUT[irow+3] = 0; + } + + lookup_proves(SHA256F_TABLE_ID, 1, [GATE_TYPE, IN1, IN2, IN3, OUT, CARRY_OUT]); +} \ No newline at end of file diff --git a/test/pil2/zkevm-etrog/storage.pil b/test/pil2/zkevm-etrog/storage.pil new file mode 100644 index 0000000..3cb2030 --- /dev/null +++ b/test/pil2/zkevm-etrog/storage.pil @@ -0,0 +1,164 @@ +include "tools.pil" +include "poseidong.pil"; +include "climb_key.pil"; + +const int STORAGE_ID = 90; + +subproof Storage(2**23) { + + col witness free0, free1, free2, free3; + + // Registers + col witness hashLeft[4]; + col witness hashRight[4]; + col witness oldRoot[4]; + col witness newRoot[4]; + col witness valueLow[4]; + col witness valueHigh[4]; + col witness siblingValueHash[4]; + col witness rkey[4]; + col witness siblingRkey[4]; + col witness rkeyBit; + col witness level; + col witness pc; + + col witness inOldRoot; + col witness inNewRoot; + col witness inValueLow; + col witness inValueHigh; + col witness inSiblingValueHash; + col witness inRkey; + col witness inRkeyBit; + col witness inSiblingRkey; + col witness inFree; + col witness inRotlVh; + col witness inLevel; + + col witness setHashLeft; + col witness setHashRight; + col witness setOldRoot; + col witness setNewRoot; + col witness setValueLow; + col witness setValueHigh; + col witness setSiblingValueHash; + col witness setRkey; + col witness setSiblingRkey; + col witness setRkeyBit; + col witness setLevel; + + col witness hash; + col witness hashType; + col witness latchSet; + col witness latchGet; + col witness climbRkey; + col witness climbSiblingRkey; + col witness climbBitN; + col witness jmpz; + col witness jmpnz; + col witness jmp; + col witness const0; + col witness jmpAddress; + + col witness incCounter; + incCounter' === incCounter * (1 - latchSet - latchGet - Global.L1) + hash; + + // We assume hash and latch never goes together + // We assume first instruction is not a latch nor a hash. + + // Selectors + + const expr op[4]; + const expr climbKey[4]; + for (int index = 0; index < 4; ++index) { + op[index] = (index == 0 ? 0 : (inLevel * level + inRkeyBit * rkeyBit + const0)) + + inOldRoot * oldRoot[index] + + inNewRoot * newRoot[index] + + inValueLow * valueLow[index] + + inValueHigh * valueHigh[index] + + inSiblingValueHash * siblingValueHash[index] + + inSiblingRkey * siblingRkey[index] + + inRkey * rkey[index] + + inFree * free[index] + + inRotlVh * valueHigh[(index + 3) % 4]; + + climbKey[index] = climbRkey * rkey[index] + climbSiblingRkey * siblingRkey[index]; + // Setters + + hashLeft[index]' === setHashLeft * (op[index] - hashLeft[index]) + hashLeft[index]; + hashRight[index]' === setHashRight * (op[index] - hashRight[index]) + hashRight[index]; + oldRoot[index]' === setOldRoot * (op[index] - oldRoot[index]) + oldRoot[index]; + newRoot[index]' === setNewRoot * (op[index] - newRoot[index]) + newRoot[index]; + valueLow[index]' === setValueLow * (op[index] - valueLow[index]) + valueLow[index]; + valueHigh[index]' === setValueHigh * (op[index] - valueHigh[index]) + valueHigh[index]; + siblingValueHash[index]' === setSiblingValueHash * (op[index] - siblingValueHash[index]) + siblingValueHash[index]; + rkey[index]' === setRkey * (op[index] - rkey[index]) + rkey[index]; + siblingRkey[index]' === setSiblingRkey * (op[index] - siblingRkey[index]) + siblingRkey[index]; + } + + rkeyBit' === setRkeyBit * (op0-rkeyBit) + rkeyBit; + rkeyBit * (1 - rkeyBit) === 0; + + level' === setLevel * (op0-level) + level; + + // Instruction that guarantees that op = hash(hl, hr); the poseidon SM will do the work; the result will be feeded by free + + multiset_assumes(POSEIDON_G_ID, hash, [ ...hashLeft, ...hashRight3, hashType, 0, 0, 0, ...op0]); +/* + } is PoseidonG.result3 { + PoseidonG.in0, + PoseidonG.in1, + PoseidonG.in2, + PoseidonG.in3, + PoseidonG.in4, + PoseidonG.in5, + PoseidonG.in6, + PoseidonG.in7, + PoseidonG.hashType, + PoseidonG.cap1, + PoseidonG.cap2, + PoseidonG.cap3, + PoseidonG.hash0, + PoseidonG.hash1, + PoseidonG.hash2, + PoseidonG.hash3}; +*/ + const expr climbKeyBit = climbBitN * (1 - rkeyBit) + (1 - climbBitN) * rkeyBit; + + multiset_assumes(CLIMB_KEY_ID, climbRkey + climbSiblingRkey, [...climbKey, level, climbKeyBit, ...op0]) + /* + climbRkey + climbSiblingRkey { + climbRkey * rkey0 + climbSiblingRkey * siblingRkey0, climbRkey * rkey1 + climbSiblingRkey * siblingRkey1, climbRkey * rkey2 + climbSiblingRkey * siblingRkey2, climbRkey * rkey3 + climbSiblingRkey * siblingRkey3, + level, climbKeyBit, + op0, op1, op2, op3 + } is ClimbKey.result { + ClimbKey.key0, ClimbKey.key1, ClimbKey.key2, ClimbKey.key3, + ClimbKey.level', ClimbKey.bit, + ClimbKey.key0', ClimbKey.key1', ClimbKey.key2', ClimbKey.key3' + };*/ + + + col witness op0inv; + + const expr opIsZero === 1 - op0 * op0inv; + opIsZero * op0 === 0; + + const expr doJump === jmp + jmpz * opIsZero + jmpnz * (1 - opIsZero); + pc' === doJump * (jmpAddress - pc - 1) + pc + 1; + + pc * Global.L1 === 0; + incCounter * Global.L1 === 0; + + // Last pc' must return to be pc = 0 in order to close the program loop + // Once the work is done, the rest of instructions must be: + // if op0 = $n-1 (last instruction of the program) then pc = 0 (jump to the beginning of the program) + + const expr storageRomFlags = compact_bin_cols ([ + hash, hashType, latchGet, latchSet, climbRkey, climbSiblingRkey, climbBitN, + jmp, jmpz, jmpnz, setHashLeft, setHashRight, setLevel, setNewRoot, setOldRoot, + setRkey, setRkeyBit, setSiblingRkey, setSiblingValueHash, setValueHigh, setValueLow, + inFree, inNewRoot, inOldRoot, inRkey, inRkeyBit, inSiblingValueHash, + inValueLow, inValueHigh, inRotlVh, inLevel]); + + + lookup_assumes(STORAGE_ROM_ID, 1, [storageRomFlags, const0, jmpAddress, pc, inSiblingRkey]); +} \ No newline at end of file diff --git a/test/pil2/zkevm-etrog/storage_rom.json b/test/pil2/zkevm-etrog/storage_rom.json new file mode 100644 index 0000000..9b6b354 --- /dev/null +++ b/test/pil2/zkevm-etrog/storage_rom.json @@ -0,0 +1,3197 @@ +{ + "program": [ + { + "CONST": 0, + "setHASH_LEFT": 1, + "setHASH_RIGHT": 1, + "setOLD_ROOT": 1, + "setNEW_ROOT": 1, + "setVALUE_LOW": 1, + "setVALUE_HIGH": 1, + "setSIBLING_VALUE_HASH": 1, + "setRKEY": 1, + "setSIBLING_RKEY": 1, + "setRKEY_BIT": 1, + "setLEVEL": 1, + "line": 4, + "fileName": "storage_sm.zkasm", + "lineStr": " 0 => HASH_LEFT, HASH_RIGHT, OLD_ROOT, NEW_ROOT, VALUE_LOW, VALUE_HIGH, SIBLING_VALUE_HASH, RKEY, SIBLING_RKEY, RKEY_BIT, LEVEL" + }, + { + "freeInTag": { + "op": "functionCall", + "funcName": "isValueZero", + "params": [] + }, + "inFREE": 1, + "jmpnz": 1, + "jmpAddressLabel": "ValueIsZero", + "line": 6, + "jmpAddress": 19, + "fileName": "storage_sm.zkasm", + "lineStr": " ${isValueZero()} :JMPNZ(ValueIsZero)" + }, + { + "freeInTag": { + "op": "functionCall", + "funcName": "GetValueLow", + "params": [] + }, + "inFREE": 1, + "setVALUE_LOW": 1, + "setVALUE_HIGH": 1, + "jmpnz": 1, + "jmpAddressLabel": "ValueLowIsNonZero", + "line": 7, + "jmpAddress": 11, + "fileName": "storage_sm.zkasm", + "lineStr": " ${GetValueLow()} => VALUE_LOW,VALUE_HIGH :JMPNZ(ValueLowIsNonZero)" + }, + { + "inROTL_VH": 1, + "setVALUE_HIGH": 1, + "jmpnz": 1, + "jmpAddressLabel": "ValueLowIsNonZero", + "line": 8, + "jmpAddress": 11, + "fileName": "storage_sm.zkasm", + "lineStr": " ROTL_VH => VALUE_HIGH :JMPNZ(ValueLowIsNonZero)" + }, + { + "inROTL_VH": 1, + "setVALUE_HIGH": 1, + "jmpnz": 1, + "jmpAddressLabel": "ValueLowIsNonZero", + "line": 9, + "jmpAddress": 11, + "fileName": "storage_sm.zkasm", + "lineStr": " ROTL_VH => VALUE_HIGH :JMPNZ(ValueLowIsNonZero)" + }, + { + "inROTL_VH": 1, + "setVALUE_HIGH": 1, + "jmpnz": 1, + "jmpAddressLabel": "ValueLowIsNonZero", + "line": 10, + "jmpAddress": 11, + "fileName": "storage_sm.zkasm", + "lineStr": " ROTL_VH => VALUE_HIGH :JMPNZ(ValueLowIsNonZero)" + }, + { + "freeInTag": { + "op": "functionCall", + "funcName": "GetValueHigh", + "params": [] + }, + "inFREE": 1, + "setVALUE_HIGH": 1, + "setNEW_ROOT": 1, + "jmpnz": 1, + "jmpAddressLabel": "ValueHighIsNonZero", + "line": 13, + "jmpAddress": 12, + "fileName": "storage_sm.zkasm", + "lineStr": " ${GetValueHigh()} => VALUE_HIGH,NEW_ROOT :JMPNZ(ValueHighIsNonZero)" + }, + { + "inROTL_VH": 1, + "setVALUE_HIGH": 1, + "jmpnz": 1, + "jmpAddressLabel": "ValueHighIsNonZero", + "line": 14, + "jmpAddress": 12, + "fileName": "storage_sm.zkasm", + "lineStr": " ROTL_VH => VALUE_HIGH :JMPNZ(ValueHighIsNonZero)" + }, + { + "inROTL_VH": 1, + "setVALUE_HIGH": 1, + "jmpnz": 1, + "jmpAddressLabel": "ValueHighIsNonZero", + "line": 15, + "jmpAddress": 12, + "fileName": "storage_sm.zkasm", + "lineStr": " ROTL_VH => VALUE_HIGH :JMPNZ(ValueHighIsNonZero)" + }, + { + "inROTL_VH": 1, + "setVALUE_HIGH": 1, + "jmpnz": 1, + "jmpAddressLabel": "ValueHighIsNonZero", + "line": 16, + "jmpAddress": 12, + "fileName": "storage_sm.zkasm", + "lineStr": " ROTL_VH => VALUE_HIGH :JMPNZ(ValueHighIsNonZero)" + }, + { + "jmp": 1, + "jmpAddressLabel": "AssertFails", + "line": 17, + "jmpAddress": 285, + "fileName": "storage_sm.zkasm", + "lineStr": " :JMP(AssertFails)" + }, + { + "freeInTag": { + "op": "functionCall", + "funcName": "GetValueHigh", + "params": [] + }, + "inFREE": 1, + "setVALUE_HIGH": 1, + "jmp": 1, + "jmpAddressLabel": "ValueIsNonZero", + "line": 20, + "jmpAddress": 14, + "fileName": "storage_sm.zkasm", + "lineStr": " ${GetValueHigh()} => VALUE_HIGH :JMP(ValueIsNonZero)" + }, + { + "inNEW_ROOT": 1, + "setVALUE_HIGH": 1, + "line": 24, + "fileName": "storage_sm.zkasm", + "lineStr": " NEW_ROOT => VALUE_HIGH" + }, + { + "CONST": 0, + "setNEW_ROOT": 1, + "line": 25, + "fileName": "storage_sm.zkasm", + "lineStr": " 0 => NEW_ROOT" + }, + { + "freeInTag": { + "op": "functionCall", + "funcName": "isGet", + "params": [] + }, + "inFREE": 1, + "jmpnz": 1, + "jmpAddressLabel": "Get_NonZero", + "line": 29, + "jmpAddress": 43, + "fileName": "storage_sm.zkasm", + "lineStr": " ${isGet()} :JMPNZ(Get_NonZero)" + }, + { + "freeInTag": { + "op": "functionCall", + "funcName": "isSetUpdate", + "params": [] + }, + "inFREE": 1, + "jmpnz": 1, + "jmpAddressLabel": "Set_Update", + "line": 30, + "jmpAddress": 60, + "fileName": "storage_sm.zkasm", + "lineStr": " ${isSetUpdate()} :JMPNZ(Set_Update)" + }, + { + "freeInTag": { + "op": "functionCall", + "funcName": "isSetInsertFound", + "params": [] + }, + "inFREE": 1, + "jmpnz": 1, + "jmpAddressLabel": "Set_InsertFound", + "line": 31, + "jmpAddress": 88, + "fileName": "storage_sm.zkasm", + "lineStr": " ${isSetInsertFound()} :JMPNZ(Set_InsertFound)" + }, + { + "freeInTag": { + "op": "functionCall", + "funcName": "isSetInsertNotFound", + "params": [] + }, + "inFREE": 1, + "jmpnz": 1, + "jmpAddressLabel": "Set_InsertNotFound", + "line": 32, + "jmpAddress": 146, + "fileName": "storage_sm.zkasm", + "lineStr": " ${isSetInsertNotFound()} :JMPNZ(Set_InsertNotFound)" + }, + { + "jmp": 1, + "jmpAddressLabel": "SetAllToZero", + "line": 33, + "jmpAddress": 282, + "fileName": "storage_sm.zkasm", + "lineStr": " :JMP(SetAllToZero)" + }, + { + "freeInTag": { + "op": "functionCall", + "funcName": "isGet", + "params": [] + }, + "inFREE": 1, + "jmpnz": 1, + "jmpAddressLabel": "Get_Zero", + "line": 50, + "jmpAddress": 24, + "fileName": "storage_sm.zkasm", + "lineStr": " ${isGet()} :JMPNZ(Get_Zero)" + }, + { + "freeInTag": { + "op": "functionCall", + "funcName": "isSetDeleteFound", + "params": [] + }, + "inFREE": 1, + "jmpnz": 1, + "jmpAddressLabel": "Set_DeleteFound", + "line": 51, + "jmpAddress": 169, + "fileName": "storage_sm.zkasm", + "lineStr": " ${isSetDeleteFound()} :JMPNZ(Set_DeleteFound)" + }, + { + "freeInTag": { + "op": "functionCall", + "funcName": "isSetDeleteNotFound", + "params": [] + }, + "inFREE": 1, + "jmpnz": 1, + "jmpAddressLabel": "Set_DeleteNotFound", + "line": 52, + "jmpAddress": 240, + "fileName": "storage_sm.zkasm", + "lineStr": " ${isSetDeleteNotFound()} :JMPNZ(Set_DeleteNotFound)" + }, + { + "freeInTag": { + "op": "functionCall", + "funcName": "isSetZeroToZero", + "params": [] + }, + "inFREE": 1, + "jmpnz": 1, + "jmpAddressLabel": "Set_ZeroToZero", + "line": 53, + "jmpAddress": 279, + "fileName": "storage_sm.zkasm", + "lineStr": " ${isSetZeroToZero()} :JMPNZ(Set_ZeroToZero)" + }, + { + "jmp": 1, + "jmpAddressLabel": "SetAllToZero", + "line": 54, + "jmpAddress": 282, + "fileName": "storage_sm.zkasm", + "lineStr": " :JMP(SetAllToZero)" + }, + { + "freeInTag": { + "op": "functionCall", + "funcName": "GetRkey", + "params": [] + }, + "inFREE": 1, + "setRKEY": 1, + "line": 22, + "fileName": "storage_sm_get_zero.zkasm", + "lineStr": " ${GetRkey()} => RKEY" + }, + { + "freeInTag": { + "op": "functionCall", + "funcName": "GetIsOld0", + "params": [] + }, + "inFREE": 1, + "jmpz": 1, + "jmpAddressLabel": "GZ_LeafNode", + "line": 24, + "jmpAddress": 27, + "fileName": "storage_sm_get_zero.zkasm", + "lineStr": " ${GetIsOld0()} :JMPZ(GZ_LeafNode)" + }, + { + "jmp": 1, + "jmpAddressLabel": "GZ_IntermediateNode", + "line": 25, + "jmpAddress": 41, + "fileName": "storage_sm_get_zero.zkasm", + "lineStr": " :JMP(GZ_IntermediateNode)" + }, + { + "freeInTag": { + "op": "functionCall", + "funcName": "GetSiblingValueLow", + "params": [] + }, + "inFREE": 1, + "setHASH_LEFT": 1, + "line": 33, + "fileName": "storage_sm_get_zero.zkasm", + "lineStr": " ${GetSiblingValueLow()} => HASH_LEFT" + }, + { + "freeInTag": { + "op": "functionCall", + "funcName": "GetSiblingValueHigh", + "params": [] + }, + "inFREE": 1, + "setHASH_RIGHT": 1, + "line": 34, + "fileName": "storage_sm_get_zero.zkasm", + "lineStr": " ${GetSiblingValueHigh()} => HASH_RIGHT" + }, + { + "freeInTag": { + "op": "" + }, + "inFREE": 1, + "setHASH_RIGHT": 1, + "hash": 1, + "hashType": 0, + "line": 35, + "fileName": "storage_sm_get_zero.zkasm", + "lineStr": " $ => HASH_RIGHT :HASH0" + }, + { + "freeInTag": { + "op": "functionCall", + "funcName": "GetSiblingRkey", + "params": [] + }, + "inFREE": 1, + "setSIBLING_RKEY": 1, + "line": 37, + "fileName": "storage_sm_get_zero.zkasm", + "lineStr": " ${GetSiblingRkey()} => SIBLING_RKEY" + }, + { + "inVALUE_HIGH": 1, + "setSIBLING_VALUE_HASH": 1, + "line": 40, + "fileName": "storage_sm_get_zero.zkasm", + "lineStr": " VALUE_HIGH => SIBLING_VALUE_HASH" + }, + { + "inRKEY": 1, + "inSIBLING_RKEY": -1, + "setVALUE_HIGH": 1, + "jmpnz": 1, + "jmpAddressLabel": "GZ_SiblingRKey_RKey_differents", + "line": 46, + "jmpAddress": 37, + "fileName": "storage_sm_get_zero.zkasm", + "lineStr": " RKEY - SIBLING_RKEY => VALUE_HIGH :JMPNZ(GZ_SiblingRKey_RKey_differents)" + }, + { + "inROTL_VH": 1, + "setVALUE_HIGH": 1, + "jmpnz": 1, + "jmpAddressLabel": "GZ_SiblingRKey_RKey_differents", + "line": 47, + "jmpAddress": 37, + "fileName": "storage_sm_get_zero.zkasm", + "lineStr": " ROTL_VH => VALUE_HIGH :JMPNZ(GZ_SiblingRKey_RKey_differents)" + }, + { + "inROTL_VH": 1, + "setVALUE_HIGH": 1, + "jmpnz": 1, + "jmpAddressLabel": "GZ_SiblingRKey_RKey_differents", + "line": 48, + "jmpAddress": 37, + "fileName": "storage_sm_get_zero.zkasm", + "lineStr": " ROTL_VH => VALUE_HIGH :JMPNZ(GZ_SiblingRKey_RKey_differents)" + }, + { + "inROTL_VH": 1, + "setVALUE_HIGH": 1, + "jmpnz": 1, + "jmpAddressLabel": "GZ_SiblingRKey_RKey_differents", + "line": 49, + "jmpAddress": 37, + "fileName": "storage_sm_get_zero.zkasm", + "lineStr": " ROTL_VH => VALUE_HIGH :JMPNZ(GZ_SiblingRKey_RKey_differents)" + }, + { + "jmp": 1, + "jmpAddressLabel": "AssertFails", + "line": 52, + "jmpAddress": 285, + "fileName": "storage_sm_get_zero.zkasm", + "lineStr": " :JMP(AssertFails)" + }, + { + "inSIBLING_VALUE_HASH": 1, + "setVALUE_HIGH": 1, + "line": 57, + "fileName": "storage_sm_get_zero.zkasm", + "lineStr": " SIBLING_VALUE_HASH => VALUE_HIGH" + }, + { + "inSIBLING_RKEY": 1, + "setHASH_LEFT": 1, + "line": 62, + "fileName": "storage_sm_get_zero.zkasm", + "lineStr": " SIBLING_RKEY => HASH_LEFT" + }, + { + "freeInTag": { + "op": "" + }, + "inFREE": 1, + "setOLD_ROOT": 1, + "hash": 1, + "hashType": 1, + "line": 63, + "fileName": "storage_sm_get_zero.zkasm", + "lineStr": " $ => OLD_ROOT :HASH1" + }, + { + "jmp": 1, + "jmpAddressLabel": "GZ_InitLevel", + "line": 64, + "jmpAddress": 42, + "fileName": "storage_sm_get_zero.zkasm", + "lineStr": " :JMP(GZ_InitLevel)" + }, + { + "CONST": 0, + "setOLD_ROOT": 1, + "line": 69, + "fileName": "storage_sm_get_zero.zkasm", + "lineStr": " 0x0 => OLD_ROOT" + }, + { + "freeInTag": { + "op": "functionCall", + "funcName": "GetLevel", + "params": [] + }, + "inFREE": 1, + "setLEVEL": 1, + "jmp": 1, + "jmpAddressLabel": "Get_ClimbUp", + "line": 74, + "jmpAddress": 49, + "fileName": "storage_sm_get_zero.zkasm", + "lineStr": " ${GetLevel()} => LEVEL :JMP(Get_ClimbUp)" + }, + { + "inVALUE_LOW": 1, + "setHASH_LEFT": 1, + "line": 17, + "fileName": "storage_sm_get_non_zero.zkasm", + "lineStr": " VALUE_LOW => HASH_LEFT" + }, + { + "inVALUE_HIGH": 1, + "setHASH_RIGHT": 1, + "line": 18, + "fileName": "storage_sm_get_non_zero.zkasm", + "lineStr": " VALUE_HIGH => HASH_RIGHT" + }, + { + "freeInTag": { + "op": "" + }, + "inFREE": 1, + "setHASH_RIGHT": 1, + "hash": 1, + "hashType": 0, + "line": 19, + "fileName": "storage_sm_get_non_zero.zkasm", + "lineStr": " $ => HASH_RIGHT :HASH0" + }, + { + "freeInTag": { + "op": "functionCall", + "funcName": "GetRkey", + "params": [] + }, + "inFREE": 1, + "setRKEY": 1, + "setHASH_LEFT": 1, + "line": 22, + "fileName": "storage_sm_get_non_zero.zkasm", + "lineStr": " ${GetRkey()} => RKEY, HASH_LEFT" + }, + { + "freeInTag": { + "op": "" + }, + "inFREE": 1, + "setOLD_ROOT": 1, + "hash": 1, + "hashType": 1, + "line": 23, + "fileName": "storage_sm_get_non_zero.zkasm", + "lineStr": " $ => OLD_ROOT :HASH1" + }, + { + "freeInTag": { + "op": "functionCall", + "funcName": "GetLevel", + "params": [] + }, + "inFREE": 1, + "setLEVEL": 1, + "jmp": 1, + "jmpAddressLabel": "Get_ClimbUp", + "line": 26, + "jmpAddress": 49, + "fileName": "storage_sm_get_non_zero.zkasm", + "lineStr": " ${GetLevel()} => LEVEL :JMP(Get_ClimbUp)" + }, + { + "inLEVEL": 1, + "jmpz": 1, + "jmpAddressLabel": "GCU_Latch", + "line": 10, + "jmpAddress": 58, + "fileName": "storage_sm_get_climb_up.zkasm", + "lineStr": " LEVEL :JMPZ(GCU_Latch)" + }, + { + "inLEVEL": 1, + "CONST": -1, + "setLEVEL": 1, + "line": 11, + "fileName": "storage_sm_get_climb_up.zkasm", + "lineStr": " LEVEL - 1 => LEVEL" + }, + { + "freeInTag": { + "op": "functionCall", + "funcName": "GetNextKeyBit", + "params": [] + }, + "inFREE": 1, + "setRKEY_BIT": 1, + "jmpz": 1, + "jmpAddressLabel": "GCU_SiblingIsRight", + "line": 14, + "jmpAddress": 54, + "fileName": "storage_sm_get_climb_up.zkasm", + "lineStr": " ${GetNextKeyBit()} => RKEY_BIT :JMPZ(GCU_SiblingIsRight)" + }, + { + "freeInTag": { + "op": "functionCall", + "funcName": "GetSiblingHash", + "params": [] + }, + "inFREE": 1, + "setHASH_LEFT": 1, + "line": 19, + "fileName": "storage_sm_get_climb_up.zkasm", + "lineStr": " ${GetSiblingHash()} => HASH_LEFT" + }, + { + "inOLD_ROOT": 1, + "setHASH_RIGHT": 1, + "jmp": 1, + "jmpAddressLabel": "GCU_HashAndClimbUp", + "line": 20, + "jmpAddress": 56, + "fileName": "storage_sm_get_climb_up.zkasm", + "lineStr": " OLD_ROOT => HASH_RIGHT :JMP(GCU_HashAndClimbUp)" + }, + { + "inOLD_ROOT": 1, + "setHASH_LEFT": 1, + "line": 25, + "fileName": "storage_sm_get_climb_up.zkasm", + "lineStr": " OLD_ROOT => HASH_LEFT" + }, + { + "freeInTag": { + "op": "functionCall", + "funcName": "GetSiblingHash", + "params": [] + }, + "inFREE": 1, + "setHASH_RIGHT": 1, + "line": 26, + "fileName": "storage_sm_get_climb_up.zkasm", + "lineStr": " ${GetSiblingHash()} => HASH_RIGHT" + }, + { + "freeInTag": { + "op": "" + }, + "inFREE": 1, + "setOLD_ROOT": 1, + "hash": 1, + "hashType": 0, + "line": 30, + "fileName": "storage_sm_get_climb_up.zkasm", + "lineStr": " $ => OLD_ROOT :HASH0" + }, + { + "freeInTag": { + "op": "" + }, + "inFREE": 1, + "setRKEY": 1, + "climbRkey": 1, + "climbSiblingRkey": 0, + "climbBitN": 0, + "jmp": 1, + "jmpAddressLabel": "Get_ClimbUp", + "line": 33, + "jmpAddress": 49, + "fileName": "storage_sm_get_climb_up.zkasm", + "lineStr": " $ => RKEY :CLIMB_RKEY, JMP(Get_ClimbUp)" + }, + { + "inNEW_ROOT": 1, + "CONST": -1, + "jmpz": 1, + "jmpAddressLabel": "Set_ZeroToZero_GetZero_Return", + "line": 43, + "jmpAddress": 280, + "fileName": "storage_sm_get_climb_up.zkasm", + "lineStr": " NEW_ROOT - 1 :JMPZ(Set_ZeroToZero_GetZero_Return)" + }, + { + "latchGet": 1, + "jmp": 1, + "jmpAddressLabel": "Run", + "line": 46, + "jmpAddress": 0, + "fileName": "storage_sm_get_climb_up.zkasm", + "lineStr": " :LATCH_GET, JMP(Run)" + }, + { + "freeInTag": { + "op": "functionCall", + "funcName": "GetRkey", + "params": [] + }, + "inFREE": 1, + "setRKEY": 1, + "line": 17, + "fileName": "storage_sm_set_update.zkasm", + "lineStr": " ${GetRkey()} => RKEY" + }, + { + "freeInTag": { + "op": "functionCall", + "funcName": "GetOldValueLow", + "params": [] + }, + "inFREE": 1, + "setHASH_LEFT": 1, + "line": 21, + "fileName": "storage_sm_set_update.zkasm", + "lineStr": " ${GetOldValueLow()} => HASH_LEFT" + }, + { + "freeInTag": { + "op": "functionCall", + "funcName": "GetOldValueHigh", + "params": [] + }, + "inFREE": 1, + "setHASH_RIGHT": 1, + "line": 22, + "fileName": "storage_sm_set_update.zkasm", + "lineStr": " ${GetOldValueHigh()} => HASH_RIGHT" + }, + { + "freeInTag": { + "op": "" + }, + "inFREE": 1, + "setHASH_RIGHT": 1, + "hash": 1, + "hashType": 0, + "line": 23, + "fileName": "storage_sm_set_update.zkasm", + "lineStr": " $ => HASH_RIGHT :HASH0" + }, + { + "inRKEY": 1, + "setHASH_LEFT": 1, + "line": 26, + "fileName": "storage_sm_set_update.zkasm", + "lineStr": " RKEY => HASH_LEFT" + }, + { + "freeInTag": { + "op": "" + }, + "inFREE": 1, + "setOLD_ROOT": 1, + "hash": 1, + "hashType": 1, + "line": 27, + "fileName": "storage_sm_set_update.zkasm", + "lineStr": " $ => OLD_ROOT :HASH1" + }, + { + "inVALUE_LOW": 1, + "setHASH_LEFT": 1, + "line": 32, + "fileName": "storage_sm_set_update.zkasm", + "lineStr": " VALUE_LOW => HASH_LEFT" + }, + { + "inVALUE_HIGH": 1, + "setHASH_RIGHT": 1, + "line": 33, + "fileName": "storage_sm_set_update.zkasm", + "lineStr": " VALUE_HIGH => HASH_RIGHT" + }, + { + "freeInTag": { + "op": "" + }, + "inFREE": 1, + "setHASH_RIGHT": 1, + "hash": 1, + "hashType": 0, + "line": 34, + "fileName": "storage_sm_set_update.zkasm", + "lineStr": " $ => HASH_RIGHT :HASH0" + }, + { + "inRKEY": 1, + "setHASH_LEFT": 1, + "line": 37, + "fileName": "storage_sm_set_update.zkasm", + "lineStr": " RKEY => HASH_LEFT" + }, + { + "freeInTag": { + "op": "" + }, + "inFREE": 1, + "setNEW_ROOT": 1, + "hash": 1, + "hashType": 1, + "line": 38, + "fileName": "storage_sm_set_update.zkasm", + "lineStr": " $ => NEW_ROOT :HASH1" + }, + { + "freeInTag": { + "op": "functionCall", + "funcName": "GetLevel", + "params": [] + }, + "inFREE": 1, + "setLEVEL": 1, + "line": 43, + "fileName": "storage_sm_set_update.zkasm", + "lineStr": " ${GetLevel()} => LEVEL" + }, + { + "inLEVEL": 1, + "jmpz": 1, + "jmpAddressLabel": "SU_Latch", + "line": 48, + "jmpAddress": 87, + "fileName": "storage_sm_set_update.zkasm", + "lineStr": " LEVEL :JMPZ(SU_Latch)" + }, + { + "inLEVEL": 1, + "CONST": -1, + "setLEVEL": 1, + "line": 49, + "fileName": "storage_sm_set_update.zkasm", + "lineStr": " LEVEL - 1 => LEVEL" + }, + { + "freeInTag": { + "op": "functionCall", + "funcName": "GetNextKeyBit", + "params": [] + }, + "inFREE": 1, + "setRKEY_BIT": 1, + "jmpz": 1, + "jmpAddressLabel": "SU_SiblingIsRight", + "line": 52, + "jmpAddress": 81, + "fileName": "storage_sm_set_update.zkasm", + "lineStr": " ${GetNextKeyBit()} => RKEY_BIT :JMPZ(SU_SiblingIsRight)" + }, + { + "freeInTag": { + "op": "functionCall", + "funcName": "GetSiblingHash", + "params": [] + }, + "inFREE": 1, + "setHASH_LEFT": 1, + "line": 57, + "fileName": "storage_sm_set_update.zkasm", + "lineStr": " ${GetSiblingHash()} => HASH_LEFT" + }, + { + "inNEW_ROOT": 1, + "setHASH_RIGHT": 1, + "line": 58, + "fileName": "storage_sm_set_update.zkasm", + "lineStr": " NEW_ROOT => HASH_RIGHT" + }, + { + "freeInTag": { + "op": "" + }, + "inFREE": 1, + "setNEW_ROOT": 1, + "hash": 1, + "hashType": 0, + "line": 59, + "fileName": "storage_sm_set_update.zkasm", + "lineStr": " $ => NEW_ROOT :HASH0" + }, + { + "inOLD_ROOT": 1, + "setHASH_RIGHT": 1, + "line": 62, + "fileName": "storage_sm_set_update.zkasm", + "lineStr": " OLD_ROOT => HASH_RIGHT ; Sibling hash is already in HASH_LEFT, since previous hash" + }, + { + "freeInTag": { + "op": "" + }, + "inFREE": 1, + "setOLD_ROOT": 1, + "hash": 1, + "hashType": 0, + "line": 63, + "fileName": "storage_sm_set_update.zkasm", + "lineStr": " $ => OLD_ROOT :HASH0" + }, + { + "freeInTag": { + "op": "" + }, + "inFREE": 1, + "setRKEY": 1, + "climbRkey": 1, + "climbSiblingRkey": 0, + "climbBitN": 0, + "jmp": 1, + "jmpAddressLabel": "SU_ClimbTree", + "line": 66, + "jmpAddress": 72, + "fileName": "storage_sm_set_update.zkasm", + "lineStr": " $ => RKEY :CLIMB_RKEY, JMP(SU_ClimbTree)" + }, + { + "inNEW_ROOT": 1, + "setHASH_LEFT": 1, + "line": 71, + "fileName": "storage_sm_set_update.zkasm", + "lineStr": " NEW_ROOT => HASH_LEFT" + }, + { + "freeInTag": { + "op": "functionCall", + "funcName": "GetSiblingHash", + "params": [] + }, + "inFREE": 1, + "setHASH_RIGHT": 1, + "line": 72, + "fileName": "storage_sm_set_update.zkasm", + "lineStr": " ${GetSiblingHash()} => HASH_RIGHT" + }, + { + "freeInTag": { + "op": "" + }, + "inFREE": 1, + "setNEW_ROOT": 1, + "hash": 1, + "hashType": 0, + "line": 73, + "fileName": "storage_sm_set_update.zkasm", + "lineStr": " $ => NEW_ROOT :HASH0" + }, + { + "inOLD_ROOT": 1, + "setHASH_LEFT": 1, + "line": 76, + "fileName": "storage_sm_set_update.zkasm", + "lineStr": " OLD_ROOT => HASH_LEFT ; Sibling hash is already in HASH_RIGHT, since previous hash" + }, + { + "freeInTag": { + "op": "" + }, + "inFREE": 1, + "setOLD_ROOT": 1, + "hash": 1, + "hashType": 0, + "line": 77, + "fileName": "storage_sm_set_update.zkasm", + "lineStr": " $ => OLD_ROOT :HASH0" + }, + { + "freeInTag": { + "op": "" + }, + "inFREE": 1, + "setRKEY": 1, + "climbRkey": 1, + "climbSiblingRkey": 0, + "climbBitN": 0, + "jmp": 1, + "jmpAddressLabel": "SU_ClimbTree", + "line": 80, + "jmpAddress": 72, + "fileName": "storage_sm_set_update.zkasm", + "lineStr": " $ => RKEY :CLIMB_RKEY, JMP(SU_ClimbTree)" + }, + { + "latchSet": 1, + "jmp": 1, + "jmpAddressLabel": "Run", + "line": 86, + "jmpAddress": 0, + "fileName": "storage_sm_set_update.zkasm", + "lineStr": " :LATCH_SET, JMP(Run)" + }, + { + "freeInTag": { + "op": "functionCall", + "funcName": "GetSiblingValueLow", + "params": [] + }, + "inFREE": 1, + "setHASH_LEFT": 1, + "line": 26, + "fileName": "storage_sm_set_insert_found.zkasm", + "lineStr": " ${GetSiblingValueLow()} => HASH_LEFT" + }, + { + "freeInTag": { + "op": "functionCall", + "funcName": "GetSiblingValueHigh", + "params": [] + }, + "inFREE": 1, + "setHASH_RIGHT": 1, + "line": 27, + "fileName": "storage_sm_set_insert_found.zkasm", + "lineStr": " ${GetSiblingValueHigh()} => HASH_RIGHT" + }, + { + "freeInTag": { + "op": "" + }, + "inFREE": 1, + "setSIBLING_VALUE_HASH": 1, + "setHASH_RIGHT": 1, + "hash": 1, + "hashType": 0, + "line": 28, + "fileName": "storage_sm_set_insert_found.zkasm", + "lineStr": " $ => SIBLING_VALUE_HASH, HASH_RIGHT :HASH0" + }, + { + "freeInTag": { + "op": "functionCall", + "funcName": "GetSiblingRkey", + "params": [] + }, + "inFREE": 1, + "setSIBLING_RKEY": 1, + "line": 31, + "fileName": "storage_sm_set_insert_found.zkasm", + "lineStr": " ${GetSiblingRkey()} => SIBLING_RKEY" + }, + { + "inSIBLING_RKEY": 1, + "setHASH_LEFT": 1, + "line": 32, + "fileName": "storage_sm_set_insert_found.zkasm", + "lineStr": " SIBLING_RKEY => HASH_LEFT" + }, + { + "freeInTag": { + "op": "" + }, + "inFREE": 1, + "setOLD_ROOT": 1, + "hash": 1, + "hashType": 1, + "line": 33, + "fileName": "storage_sm_set_insert_found.zkasm", + "lineStr": " $ => OLD_ROOT :HASH1" + }, + { + "inVALUE_LOW": 1, + "setHASH_LEFT": 1, + "line": 36, + "fileName": "storage_sm_set_insert_found.zkasm", + "lineStr": " VALUE_LOW => HASH_LEFT" + }, + { + "inVALUE_HIGH": 1, + "setHASH_RIGHT": 1, + "line": 37, + "fileName": "storage_sm_set_insert_found.zkasm", + "lineStr": " VALUE_HIGH => HASH_RIGHT" + }, + { + "freeInTag": { + "op": "" + }, + "inFREE": 1, + "setHASH_RIGHT": 1, + "hash": 1, + "hashType": 0, + "line": 38, + "fileName": "storage_sm_set_insert_found.zkasm", + "lineStr": " $ => HASH_RIGHT :HASH0" + }, + { + "freeInTag": { + "op": "functionCall", + "funcName": "GetRkey", + "params": [] + }, + "inFREE": 1, + "setRKEY": 1, + "setHASH_LEFT": 1, + "line": 41, + "fileName": "storage_sm_set_insert_found.zkasm", + "lineStr": " ${GetRkey()} => RKEY, HASH_LEFT" + }, + { + "freeInTag": { + "op": "" + }, + "inFREE": 1, + "setNEW_ROOT": 1, + "hash": 1, + "hashType": 1, + "line": 42, + "fileName": "storage_sm_set_insert_found.zkasm", + "lineStr": " $ => NEW_ROOT :HASH1" + }, + { + "freeInTag": { + "op": "functionCall", + "funcName": "GetLevel", + "params": [] + }, + "inFREE": 1, + "setLEVEL": 1, + "line": 47, + "fileName": "storage_sm_set_insert_found.zkasm", + "lineStr": " ${GetLevel()} => LEVEL" + }, + { + "inLEVEL": 1, + "CONST": -1, + "setLEVEL": 1, + "line": 53, + "fileName": "storage_sm_set_insert_found.zkasm", + "lineStr": " LEVEL - 1 => LEVEL" + }, + { + "freeInTag": { + "op": "functionCall", + "funcName": "GetNextKeyBit", + "params": [] + }, + "inFREE": 1, + "setRKEY_BIT": 1, + "jmpz": 1, + "jmpAddressLabel": "SIF_SiblingIsRight1", + "line": 56, + "jmpAddress": 107, + "fileName": "storage_sm_set_insert_found.zkasm", + "lineStr": " ${GetNextKeyBit()} => RKEY_BIT :JMPZ(SIF_SiblingIsRight1) ; If next key bit is zero, then sibling is right (sibling's next key bit is 1)" + }, + { + "inOLD_ROOT": 1, + "setHASH_LEFT": 1, + "line": 61, + "fileName": "storage_sm_set_insert_found.zkasm", + "lineStr": " OLD_ROOT => HASH_LEFT" + }, + { + "inNEW_ROOT": 1, + "setHASH_RIGHT": 1, + "line": 62, + "fileName": "storage_sm_set_insert_found.zkasm", + "lineStr": " NEW_ROOT => HASH_RIGHT" + }, + { + "freeInTag": { + "op": "" + }, + "inFREE": 1, + "setNEW_ROOT": 1, + "hash": 1, + "hashType": 0, + "line": 63, + "fileName": "storage_sm_set_insert_found.zkasm", + "lineStr": " $ => NEW_ROOT :HASH0" + }, + { + "freeInTag": { + "op": "" + }, + "inFREE": 1, + "setRKEY": 1, + "climbRkey": 1, + "climbSiblingRkey": 0, + "climbBitN": 0, + "line": 66, + "fileName": "storage_sm_set_insert_found.zkasm", + "lineStr": " $ => RKEY :CLIMB_RKEY" + }, + { + "freeInTag": { + "op": "" + }, + "inFREE": 1, + "setSIBLING_RKEY": 1, + "climbRkey": 0, + "climbSiblingRkey": 1, + "climbBitN": 1, + "jmp": 1, + "jmpAddressLabel": "SIF_ClimbBranch", + "line": 67, + "jmpAddress": 112, + "fileName": "storage_sm_set_insert_found.zkasm", + "lineStr": " $ => SIBLING_RKEY :CLIMB_SIBLING_RKEY_N, JMP(SIF_ClimbBranch)" + }, + { + "inNEW_ROOT": 1, + "setHASH_LEFT": 1, + "line": 72, + "fileName": "storage_sm_set_insert_found.zkasm", + "lineStr": " NEW_ROOT => HASH_LEFT" + }, + { + "inOLD_ROOT": 1, + "setHASH_RIGHT": 1, + "line": 73, + "fileName": "storage_sm_set_insert_found.zkasm", + "lineStr": " OLD_ROOT => HASH_RIGHT" + }, + { + "freeInTag": { + "op": "" + }, + "inFREE": 1, + "setNEW_ROOT": 1, + "hash": 1, + "hashType": 0, + "line": 74, + "fileName": "storage_sm_set_insert_found.zkasm", + "lineStr": " $ => NEW_ROOT :HASH0" + }, + { + "freeInTag": { + "op": "" + }, + "inFREE": 1, + "setRKEY": 1, + "climbRkey": 1, + "climbSiblingRkey": 0, + "climbBitN": 0, + "line": 77, + "fileName": "storage_sm_set_insert_found.zkasm", + "lineStr": " $ => RKEY :CLIMB_RKEY" + }, + { + "freeInTag": { + "op": "" + }, + "inFREE": 1, + "setSIBLING_RKEY": 1, + "climbRkey": 0, + "climbSiblingRkey": 1, + "climbBitN": 1, + "line": 78, + "fileName": "storage_sm_set_insert_found.zkasm", + "lineStr": " $ => SIBLING_RKEY :CLIMB_SIBLING_RKEY_N" + }, + { + "freeInTag": { + "op": "functionCall", + "funcName": "GetTopOfBranch", + "params": [] + }, + "inFREE": 1, + "jmpz": 1, + "jmpAddressLabel": "SIF_StartOldRoot", + "line": 82, + "jmpAddress": 125, + "fileName": "storage_sm_set_insert_found.zkasm", + "lineStr": " ${GetTopOfBranch()} :JMPZ(SIF_StartOldRoot) ; If we are at the top of the branch, then go to SIF_StartOldRoot" + }, + { + "inLEVEL": 1, + "CONST": -1, + "setLEVEL": 1, + "line": 84, + "fileName": "storage_sm_set_insert_found.zkasm", + "lineStr": " LEVEL - 1 => LEVEL" + }, + { + "freeInTag": { + "op": "functionCall", + "funcName": "GetNextKeyBit", + "params": [] + }, + "inFREE": 1, + "setRKEY_BIT": 1, + "jmpz": 1, + "jmpAddressLabel": "SIF_SiblingIsRight2", + "line": 87, + "jmpAddress": 120, + "fileName": "storage_sm_set_insert_found.zkasm", + "lineStr": " ${GetNextKeyBit()} => RKEY_BIT :JMPZ(SIF_SiblingIsRight2)" + }, + { + "CONST": 0, + "setHASH_LEFT": 1, + "line": 92, + "fileName": "storage_sm_set_insert_found.zkasm", + "lineStr": " 0x0 => HASH_LEFT" + }, + { + "inNEW_ROOT": 1, + "setHASH_RIGHT": 1, + "line": 93, + "fileName": "storage_sm_set_insert_found.zkasm", + "lineStr": " NEW_ROOT => HASH_RIGHT" + }, + { + "freeInTag": { + "op": "" + }, + "inFREE": 1, + "setNEW_ROOT": 1, + "hash": 1, + "hashType": 0, + "line": 94, + "fileName": "storage_sm_set_insert_found.zkasm", + "lineStr": " $ => NEW_ROOT :HASH0" + }, + { + "freeInTag": { + "op": "" + }, + "inFREE": 1, + "setRKEY": 1, + "climbRkey": 1, + "climbSiblingRkey": 0, + "climbBitN": 0, + "line": 97, + "fileName": "storage_sm_set_insert_found.zkasm", + "lineStr": " $ => RKEY :CLIMB_RKEY" + }, + { + "freeInTag": { + "op": "" + }, + "inFREE": 1, + "setSIBLING_RKEY": 1, + "climbRkey": 0, + "climbSiblingRkey": 1, + "climbBitN": 0, + "jmp": 1, + "jmpAddressLabel": "SIF_ClimbBranch", + "line": 98, + "jmpAddress": 112, + "fileName": "storage_sm_set_insert_found.zkasm", + "lineStr": " $ => SIBLING_RKEY :CLIMB_SIBLING_RKEY, JMP(SIF_ClimbBranch)" + }, + { + "inNEW_ROOT": 1, + "setHASH_LEFT": 1, + "line": 103, + "fileName": "storage_sm_set_insert_found.zkasm", + "lineStr": " NEW_ROOT => HASH_LEFT" + }, + { + "CONST": 0, + "setHASH_RIGHT": 1, + "line": 104, + "fileName": "storage_sm_set_insert_found.zkasm", + "lineStr": " 0x0 => HASH_RIGHT" + }, + { + "freeInTag": { + "op": "" + }, + "inFREE": 1, + "setNEW_ROOT": 1, + "hash": 1, + "hashType": 0, + "line": 105, + "fileName": "storage_sm_set_insert_found.zkasm", + "lineStr": " $ => NEW_ROOT :HASH0" + }, + { + "freeInTag": { + "op": "" + }, + "inFREE": 1, + "setRKEY": 1, + "climbRkey": 1, + "climbSiblingRkey": 0, + "climbBitN": 0, + "line": 108, + "fileName": "storage_sm_set_insert_found.zkasm", + "lineStr": " $ => RKEY :CLIMB_RKEY" + }, + { + "freeInTag": { + "op": "" + }, + "inFREE": 1, + "setSIBLING_RKEY": 1, + "climbRkey": 0, + "climbSiblingRkey": 1, + "climbBitN": 0, + "jmp": 1, + "jmpAddressLabel": "SIF_ClimbBranch", + "line": 109, + "jmpAddress": 112, + "fileName": "storage_sm_set_insert_found.zkasm", + "lineStr": " $ => SIBLING_RKEY :CLIMB_SIBLING_RKEY, JMP(SIF_ClimbBranch)" + }, + { + "inSIBLING_RKEY": 1, + "setHASH_LEFT": 1, + "line": 113, + "fileName": "storage_sm_set_insert_found.zkasm", + "lineStr": " SIBLING_RKEY => HASH_LEFT" + }, + { + "inSIBLING_VALUE_HASH": 1, + "setHASH_RIGHT": 1, + "line": 114, + "fileName": "storage_sm_set_insert_found.zkasm", + "lineStr": " SIBLING_VALUE_HASH => HASH_RIGHT" + }, + { + "freeInTag": { + "op": "" + }, + "inFREE": 1, + "setOLD_ROOT": 1, + "hash": 1, + "hashType": 1, + "line": 115, + "fileName": "storage_sm_set_insert_found.zkasm", + "lineStr": " $ => OLD_ROOT :HASH1" + }, + { + "inLEVEL": 1, + "jmpz": 1, + "jmpAddressLabel": "SIF_Latch", + "line": 120, + "jmpAddress": 145, + "fileName": "storage_sm_set_insert_found.zkasm", + "lineStr": " LEVEL :JMPZ(SIF_Latch)" + }, + { + "inLEVEL": 1, + "CONST": -1, + "setLEVEL": 1, + "line": 121, + "fileName": "storage_sm_set_insert_found.zkasm", + "lineStr": " LEVEL - 1 => LEVEL" + }, + { + "freeInTag": { + "op": "functionCall", + "funcName": "GetNextKeyBit", + "params": [] + }, + "inFREE": 1, + "setRKEY_BIT": 1, + "jmpz": 1, + "jmpAddressLabel": "SIF_SiblingIsRight3", + "line": 124, + "jmpAddress": 138, + "fileName": "storage_sm_set_insert_found.zkasm", + "lineStr": " ${GetNextKeyBit()} => RKEY_BIT :JMPZ(SIF_SiblingIsRight3)" + }, + { + "inNEW_ROOT": 1, + "setHASH_RIGHT": 1, + "line": 129, + "fileName": "storage_sm_set_insert_found.zkasm", + "lineStr": " NEW_ROOT => HASH_RIGHT" + }, + { + "freeInTag": { + "op": "functionCall", + "funcName": "GetSiblingHash", + "params": [] + }, + "inFREE": 1, + "setHASH_LEFT": 1, + "line": 130, + "fileName": "storage_sm_set_insert_found.zkasm", + "lineStr": " ${GetSiblingHash()} => HASH_LEFT" + }, + { + "freeInTag": { + "op": "" + }, + "inFREE": 1, + "setNEW_ROOT": 1, + "hash": 1, + "hashType": 0, + "line": 131, + "fileName": "storage_sm_set_insert_found.zkasm", + "lineStr": " $ => NEW_ROOT :HASH0" + }, + { + "inOLD_ROOT": 1, + "setHASH_RIGHT": 1, + "line": 134, + "fileName": "storage_sm_set_insert_found.zkasm", + "lineStr": " OLD_ROOT => HASH_RIGHT" + }, + { + "freeInTag": { + "op": "" + }, + "inFREE": 1, + "setOLD_ROOT": 1, + "hash": 1, + "hashType": 0, + "line": 135, + "fileName": "storage_sm_set_insert_found.zkasm", + "lineStr": " $ => OLD_ROOT :HASH0" + }, + { + "freeInTag": { + "op": "" + }, + "inFREE": 1, + "setRKEY": 1, + "climbRkey": 1, + "climbSiblingRkey": 0, + "climbBitN": 0, + "line": 138, + "fileName": "storage_sm_set_insert_found.zkasm", + "lineStr": " $ => RKEY :CLIMB_RKEY" + }, + { + "freeInTag": { + "op": "" + }, + "inFREE": 1, + "setSIBLING_RKEY": 1, + "climbRkey": 0, + "climbSiblingRkey": 1, + "climbBitN": 0, + "jmp": 1, + "jmpAddressLabel": "SIF_ClimbTree", + "line": 139, + "jmpAddress": 128, + "fileName": "storage_sm_set_insert_found.zkasm", + "lineStr": " $ => SIBLING_RKEY :CLIMB_SIBLING_RKEY, JMP(SIF_ClimbTree)" + }, + { + "inNEW_ROOT": 1, + "setHASH_LEFT": 1, + "line": 144, + "fileName": "storage_sm_set_insert_found.zkasm", + "lineStr": " NEW_ROOT => HASH_LEFT" + }, + { + "freeInTag": { + "op": "functionCall", + "funcName": "GetSiblingHash", + "params": [] + }, + "inFREE": 1, + "setHASH_RIGHT": 1, + "line": 145, + "fileName": "storage_sm_set_insert_found.zkasm", + "lineStr": " ${GetSiblingHash()} => HASH_RIGHT" + }, + { + "freeInTag": { + "op": "" + }, + "inFREE": 1, + "setNEW_ROOT": 1, + "hash": 1, + "hashType": 0, + "line": 146, + "fileName": "storage_sm_set_insert_found.zkasm", + "lineStr": " $ => NEW_ROOT :HASH0" + }, + { + "inOLD_ROOT": 1, + "setHASH_LEFT": 1, + "line": 149, + "fileName": "storage_sm_set_insert_found.zkasm", + "lineStr": " OLD_ROOT => HASH_LEFT" + }, + { + "freeInTag": { + "op": "" + }, + "inFREE": 1, + "setOLD_ROOT": 1, + "hash": 1, + "hashType": 0, + "line": 150, + "fileName": "storage_sm_set_insert_found.zkasm", + "lineStr": " $ => OLD_ROOT :HASH0" + }, + { + "freeInTag": { + "op": "" + }, + "inFREE": 1, + "setRKEY": 1, + "climbRkey": 1, + "climbSiblingRkey": 0, + "climbBitN": 0, + "line": 153, + "fileName": "storage_sm_set_insert_found.zkasm", + "lineStr": " $ => RKEY :CLIMB_RKEY" + }, + { + "freeInTag": { + "op": "" + }, + "inFREE": 1, + "setSIBLING_RKEY": 1, + "climbRkey": 0, + "climbSiblingRkey": 1, + "climbBitN": 0, + "jmp": 1, + "jmpAddressLabel": "SIF_ClimbTree", + "line": 154, + "jmpAddress": 128, + "fileName": "storage_sm_set_insert_found.zkasm", + "lineStr": " $ => SIBLING_RKEY :CLIMB_SIBLING_RKEY, JMP(SIF_ClimbTree)" + }, + { + "latchSet": 1, + "jmp": 1, + "jmpAddressLabel": "Run", + "line": 160, + "jmpAddress": 0, + "fileName": "storage_sm_set_insert_found.zkasm", + "lineStr": " :LATCH_SET, JMP(Run)" + }, + { + "inVALUE_LOW": 1, + "setHASH_LEFT": 1, + "line": 19, + "fileName": "storage_sm_set_insert_not_found.zkasm", + "lineStr": " VALUE_LOW => HASH_LEFT" + }, + { + "inVALUE_HIGH": 1, + "setHASH_RIGHT": 1, + "line": 20, + "fileName": "storage_sm_set_insert_not_found.zkasm", + "lineStr": " VALUE_HIGH => HASH_RIGHT" + }, + { + "freeInTag": { + "op": "" + }, + "inFREE": 1, + "setHASH_RIGHT": 1, + "hash": 1, + "hashType": 0, + "line": 22, + "fileName": "storage_sm_set_insert_not_found.zkasm", + "lineStr": " $ => HASH_RIGHT :HASH0" + }, + { + "freeInTag": { + "op": "functionCall", + "funcName": "GetRkey", + "params": [] + }, + "inFREE": 1, + "setRKEY": 1, + "setHASH_LEFT": 1, + "line": 25, + "fileName": "storage_sm_set_insert_not_found.zkasm", + "lineStr": " ${GetRkey()} => RKEY, HASH_LEFT" + }, + { + "freeInTag": { + "op": "" + }, + "inFREE": 1, + "setNEW_ROOT": 1, + "hash": 1, + "hashType": 1, + "line": 26, + "fileName": "storage_sm_set_insert_not_found.zkasm", + "lineStr": " $ => NEW_ROOT :HASH1" + }, + { + "freeInTag": { + "op": "functionCall", + "funcName": "GetLevel", + "params": [] + }, + "inFREE": 1, + "setLEVEL": 1, + "line": 31, + "fileName": "storage_sm_set_insert_not_found.zkasm", + "lineStr": " ${GetLevel()} => LEVEL" + }, + { + "CONST": 0, + "setOLD_ROOT": 1, + "line": 37, + "fileName": "storage_sm_set_insert_not_found.zkasm", + "lineStr": " 0x0 => OLD_ROOT" + }, + { + "inLEVEL": 1, + "jmpz": 1, + "jmpAddressLabel": "SINF_Latch", + "line": 42, + "jmpAddress": 168, + "fileName": "storage_sm_set_insert_not_found.zkasm", + "lineStr": " LEVEL :JMPZ(SINF_Latch)" + }, + { + "inLEVEL": 1, + "CONST": -1, + "setLEVEL": 1, + "line": 43, + "fileName": "storage_sm_set_insert_not_found.zkasm", + "lineStr": " LEVEL - 1 => LEVEL" + }, + { + "freeInTag": { + "op": "functionCall", + "funcName": "GetNextKeyBit", + "params": [] + }, + "inFREE": 1, + "setRKEY_BIT": 1, + "jmpz": 1, + "jmpAddressLabel": "SINF_SiblingIsRight3", + "line": 46, + "jmpAddress": 162, + "fileName": "storage_sm_set_insert_not_found.zkasm", + "lineStr": " ${GetNextKeyBit()} => RKEY_BIT :JMPZ(SINF_SiblingIsRight3)" + }, + { + "freeInTag": { + "op": "functionCall", + "funcName": "GetSiblingHash", + "params": [] + }, + "inFREE": 1, + "setHASH_LEFT": 1, + "line": 51, + "fileName": "storage_sm_set_insert_not_found.zkasm", + "lineStr": " ${GetSiblingHash()} => HASH_LEFT" + }, + { + "inNEW_ROOT": 1, + "setHASH_RIGHT": 1, + "line": 52, + "fileName": "storage_sm_set_insert_not_found.zkasm", + "lineStr": " NEW_ROOT => HASH_RIGHT" + }, + { + "freeInTag": { + "op": "" + }, + "inFREE": 1, + "setNEW_ROOT": 1, + "hash": 1, + "hashType": 0, + "line": 54, + "fileName": "storage_sm_set_insert_not_found.zkasm", + "lineStr": " $ => NEW_ROOT :HASH0" + }, + { + "inOLD_ROOT": 1, + "setHASH_RIGHT": 1, + "line": 57, + "fileName": "storage_sm_set_insert_not_found.zkasm", + "lineStr": " OLD_ROOT => HASH_RIGHT" + }, + { + "freeInTag": { + "op": "" + }, + "inFREE": 1, + "setOLD_ROOT": 1, + "hash": 1, + "hashType": 0, + "line": 58, + "fileName": "storage_sm_set_insert_not_found.zkasm", + "lineStr": " $ => OLD_ROOT :HASH0" + }, + { + "freeInTag": { + "op": "" + }, + "inFREE": 1, + "setRKEY": 1, + "climbRkey": 1, + "climbSiblingRkey": 0, + "climbBitN": 0, + "jmp": 1, + "jmpAddressLabel": "SINF_ClimbTree", + "line": 61, + "jmpAddress": 153, + "fileName": "storage_sm_set_insert_not_found.zkasm", + "lineStr": " $ => RKEY :CLIMB_RKEY, JMP(SINF_ClimbTree)" + }, + { + "inNEW_ROOT": 1, + "setHASH_LEFT": 1, + "line": 66, + "fileName": "storage_sm_set_insert_not_found.zkasm", + "lineStr": " NEW_ROOT => HASH_LEFT" + }, + { + "freeInTag": { + "op": "functionCall", + "funcName": "GetSiblingHash", + "params": [] + }, + "inFREE": 1, + "setHASH_RIGHT": 1, + "line": 67, + "fileName": "storage_sm_set_insert_not_found.zkasm", + "lineStr": " ${GetSiblingHash()} => HASH_RIGHT" + }, + { + "freeInTag": { + "op": "" + }, + "inFREE": 1, + "setNEW_ROOT": 1, + "hash": 1, + "hashType": 0, + "line": 68, + "fileName": "storage_sm_set_insert_not_found.zkasm", + "lineStr": " $ => NEW_ROOT :HASH0" + }, + { + "inOLD_ROOT": 1, + "setHASH_LEFT": 1, + "line": 71, + "fileName": "storage_sm_set_insert_not_found.zkasm", + "lineStr": " OLD_ROOT => HASH_LEFT" + }, + { + "freeInTag": { + "op": "" + }, + "inFREE": 1, + "setOLD_ROOT": 1, + "hash": 1, + "hashType": 0, + "line": 72, + "fileName": "storage_sm_set_insert_not_found.zkasm", + "lineStr": " $ => OLD_ROOT :HASH0" + }, + { + "freeInTag": { + "op": "" + }, + "inFREE": 1, + "setRKEY": 1, + "climbRkey": 1, + "climbSiblingRkey": 0, + "climbBitN": 0, + "jmp": 1, + "jmpAddressLabel": "SINF_ClimbTree", + "line": 75, + "jmpAddress": 153, + "fileName": "storage_sm_set_insert_not_found.zkasm", + "lineStr": " $ => RKEY :CLIMB_RKEY, JMP(SINF_ClimbTree)" + }, + { + "latchSet": 1, + "jmp": 1, + "jmpAddressLabel": "Run", + "line": 81, + "jmpAddress": 0, + "fileName": "storage_sm_set_insert_not_found.zkasm", + "lineStr": " :LATCH_SET, JMP(Run)" + }, + { + "freeInTag": { + "op": "functionCall", + "funcName": "GetOldValueLow", + "params": [] + }, + "inFREE": 1, + "setHASH_LEFT": 1, + "line": 22, + "fileName": "storage_sm_set_delete_found.zkasm", + "lineStr": " ${GetOldValueLow()} => HASH_LEFT" + }, + { + "freeInTag": { + "op": "functionCall", + "funcName": "GetOldValueHigh", + "params": [] + }, + "inFREE": 1, + "setHASH_RIGHT": 1, + "line": 23, + "fileName": "storage_sm_set_delete_found.zkasm", + "lineStr": " ${GetOldValueHigh()} => HASH_RIGHT" + }, + { + "freeInTag": { + "op": "" + }, + "inFREE": 1, + "setHASH_RIGHT": 1, + "hash": 1, + "hashType": 0, + "line": 24, + "fileName": "storage_sm_set_delete_found.zkasm", + "lineStr": " $ => HASH_RIGHT :HASH0" + }, + { + "freeInTag": { + "op": "functionCall", + "funcName": "GetRkey", + "params": [] + }, + "inFREE": 1, + "setRKEY": 1, + "setHASH_LEFT": 1, + "line": 27, + "fileName": "storage_sm_set_delete_found.zkasm", + "lineStr": " ${GetRkey()} => RKEY, HASH_LEFT" + }, + { + "freeInTag": { + "op": "" + }, + "inFREE": 1, + "setOLD_ROOT": 1, + "hash": 1, + "hashType": 1, + "line": 28, + "fileName": "storage_sm_set_delete_found.zkasm", + "lineStr": " $ => OLD_ROOT :HASH1" + }, + { + "freeInTag": { + "op": "functionCall", + "funcName": "GetSiblingValueLow", + "params": [] + }, + "inFREE": 1, + "setHASH_LEFT": 1, + "line": 32, + "fileName": "storage_sm_set_delete_found.zkasm", + "lineStr": " ${GetSiblingValueLow()} => HASH_LEFT" + }, + { + "freeInTag": { + "op": "functionCall", + "funcName": "GetSiblingValueHigh", + "params": [] + }, + "inFREE": 1, + "setHASH_RIGHT": 1, + "line": 33, + "fileName": "storage_sm_set_delete_found.zkasm", + "lineStr": " ${GetSiblingValueHigh()} => HASH_RIGHT" + }, + { + "freeInTag": { + "op": "" + }, + "inFREE": 1, + "setSIBLING_VALUE_HASH": 1, + "setHASH_RIGHT": 1, + "hash": 1, + "hashType": 0, + "line": 34, + "fileName": "storage_sm_set_delete_found.zkasm", + "lineStr": " $ => SIBLING_VALUE_HASH, HASH_RIGHT :HASH0" + }, + { + "freeInTag": { + "op": "functionCall", + "funcName": "GetSiblingRkey", + "params": [] + }, + "inFREE": 1, + "setSIBLING_RKEY": 1, + "setHASH_LEFT": 1, + "line": 37, + "fileName": "storage_sm_set_delete_found.zkasm", + "lineStr": " ${GetSiblingRkey()} => SIBLING_RKEY, HASH_LEFT" + }, + { + "freeInTag": { + "op": "" + }, + "inFREE": 1, + "setNEW_ROOT": 1, + "hash": 1, + "hashType": 1, + "line": 38, + "fileName": "storage_sm_set_delete_found.zkasm", + "lineStr": " $ => NEW_ROOT :HASH1" + }, + { + "freeInTag": { + "op": "functionCall", + "funcName": "GetLevel", + "params": [] + }, + "inFREE": 1, + "setLEVEL": 1, + "line": 49, + "fileName": "storage_sm_set_delete_found.zkasm", + "lineStr": " ${GetLevel()} => LEVEL" + }, + { + "inLEVEL": 1, + "CONST": -1, + "setLEVEL": 1, + "line": 56, + "fileName": "storage_sm_set_delete_found.zkasm", + "lineStr": " LEVEL - 1 => LEVEL" + }, + { + "freeInTag": { + "op": "functionCall", + "funcName": "GetNextKeyBit", + "params": [] + }, + "inFREE": 1, + "setRKEY_BIT": 1, + "jmpz": 1, + "jmpAddressLabel": "SDF_SiblingIsRight1", + "line": 59, + "jmpAddress": 187, + "fileName": "storage_sm_set_delete_found.zkasm", + "lineStr": " ${GetNextKeyBit()} => RKEY_BIT :JMPZ(SDF_SiblingIsRight1)" + }, + { + "inNEW_ROOT": 1, + "setHASH_LEFT": 1, + "line": 64, + "fileName": "storage_sm_set_delete_found.zkasm", + "lineStr": " NEW_ROOT => HASH_LEFT" + }, + { + "inOLD_ROOT": 1, + "setHASH_RIGHT": 1, + "line": 65, + "fileName": "storage_sm_set_delete_found.zkasm", + "lineStr": " OLD_ROOT => HASH_RIGHT" + }, + { + "freeInTag": { + "op": "" + }, + "inFREE": 1, + "setOLD_ROOT": 1, + "hash": 1, + "hashType": 0, + "line": 66, + "fileName": "storage_sm_set_delete_found.zkasm", + "lineStr": " $ => OLD_ROOT :HASH0" + }, + { + "freeInTag": { + "op": "" + }, + "inFREE": 1, + "setRKEY": 1, + "climbRkey": 1, + "climbSiblingRkey": 0, + "climbBitN": 0, + "line": 68, + "fileName": "storage_sm_set_delete_found.zkasm", + "lineStr": " $ => RKEY :CLIMB_RKEY" + }, + { + "freeInTag": { + "op": "" + }, + "inFREE": 1, + "setSIBLING_RKEY": 1, + "climbRkey": 0, + "climbSiblingRkey": 1, + "climbBitN": 1, + "jmp": 1, + "jmpAddressLabel": "SDF_ClimbBranch", + "line": 72, + "jmpAddress": 192, + "fileName": "storage_sm_set_delete_found.zkasm", + "lineStr": " $ => SIBLING_RKEY :CLIMB_SIBLING_RKEY_N, JMP(SDF_ClimbBranch)" + }, + { + "inOLD_ROOT": 1, + "setHASH_LEFT": 1, + "line": 77, + "fileName": "storage_sm_set_delete_found.zkasm", + "lineStr": " OLD_ROOT => HASH_LEFT" + }, + { + "inNEW_ROOT": 1, + "setHASH_RIGHT": 1, + "line": 78, + "fileName": "storage_sm_set_delete_found.zkasm", + "lineStr": " NEW_ROOT => HASH_RIGHT" + }, + { + "freeInTag": { + "op": "" + }, + "inFREE": 1, + "setOLD_ROOT": 1, + "hash": 1, + "hashType": 0, + "line": 79, + "fileName": "storage_sm_set_delete_found.zkasm", + "lineStr": " $ => OLD_ROOT :HASH0" + }, + { + "freeInTag": { + "op": "" + }, + "inFREE": 1, + "setRKEY": 1, + "climbRkey": 1, + "climbSiblingRkey": 0, + "climbBitN": 0, + "line": 82, + "fileName": "storage_sm_set_delete_found.zkasm", + "lineStr": " $ => RKEY :CLIMB_RKEY" + }, + { + "freeInTag": { + "op": "" + }, + "inFREE": 1, + "setSIBLING_RKEY": 1, + "climbRkey": 0, + "climbSiblingRkey": 1, + "climbBitN": 1, + "line": 86, + "fileName": "storage_sm_set_delete_found.zkasm", + "lineStr": " $ => SIBLING_RKEY :CLIMB_SIBLING_RKEY_N" + }, + { + "freeInTag": { + "op": "functionCall", + "funcName": "GetTopOfBranch", + "params": [] + }, + "inFREE": 1, + "jmpz": 1, + "jmpAddressLabel": "SDF_StartNewRoot", + "line": 94, + "jmpAddress": 202, + "fileName": "storage_sm_set_delete_found.zkasm", + "lineStr": " ${GetTopOfBranch()} :JMPZ(SDF_StartNewRoot)" + }, + { + "inLEVEL": 1, + "CONST": -1, + "setLEVEL": 1, + "line": 96, + "fileName": "storage_sm_set_delete_found.zkasm", + "lineStr": " LEVEL - 1 => LEVEL" + }, + { + "freeInTag": { + "op": "functionCall", + "funcName": "GetNextKeyBit", + "params": [] + }, + "inFREE": 1, + "setRKEY_BIT": 1, + "jmpz": 1, + "jmpAddressLabel": "SDF_SiblingIsRight2", + "line": 99, + "jmpAddress": 197, + "fileName": "storage_sm_set_delete_found.zkasm", + "lineStr": " ${GetNextKeyBit()} => RKEY_BIT :JMPZ(SDF_SiblingIsRight2)" + }, + { + "CONST": 0, + "setHASH_LEFT": 1, + "line": 108, + "fileName": "storage_sm_set_delete_found.zkasm", + "lineStr": " 0x0 => HASH_LEFT" + }, + { + "inOLD_ROOT": 1, + "setHASH_RIGHT": 1, + "jmp": 1, + "jmpAddressLabel": "SDF_SiblingClimbKey2", + "line": 109, + "jmpAddress": 199, + "fileName": "storage_sm_set_delete_found.zkasm", + "lineStr": " OLD_ROOT => HASH_RIGHT :JMP(SDF_SiblingClimbKey2)" + }, + { + "inOLD_ROOT": 1, + "setHASH_LEFT": 1, + "line": 114, + "fileName": "storage_sm_set_delete_found.zkasm", + "lineStr": " OLD_ROOT => HASH_LEFT" + }, + { + "CONST": 0, + "setHASH_RIGHT": 1, + "line": 115, + "fileName": "storage_sm_set_delete_found.zkasm", + "lineStr": " 0x0 => HASH_RIGHT" + }, + { + "freeInTag": { + "op": "" + }, + "inFREE": 1, + "setOLD_ROOT": 1, + "hash": 1, + "hashType": 0, + "line": 118, + "fileName": "storage_sm_set_delete_found.zkasm", + "lineStr": " $ => OLD_ROOT :HASH0" + }, + { + "freeInTag": { + "op": "" + }, + "inFREE": 1, + "setRKEY": 1, + "climbRkey": 1, + "climbSiblingRkey": 0, + "climbBitN": 0, + "line": 120, + "fileName": "storage_sm_set_delete_found.zkasm", + "lineStr": " $ => RKEY :CLIMB_RKEY" + }, + { + "freeInTag": { + "op": "" + }, + "inFREE": 1, + "setSIBLING_RKEY": 1, + "climbRkey": 0, + "climbSiblingRkey": 1, + "climbBitN": 0, + "jmp": 1, + "jmpAddressLabel": "SDF_ClimbBranch", + "line": 121, + "jmpAddress": 192, + "fileName": "storage_sm_set_delete_found.zkasm", + "lineStr": " $ => SIBLING_RKEY :CLIMB_SIBLING_RKEY, JMP(SDF_ClimbBranch)" + }, + { + "inSIBLING_RKEY": 1, + "setHASH_LEFT": 1, + "line": 128, + "fileName": "storage_sm_set_delete_found.zkasm", + "lineStr": " SIBLING_RKEY => HASH_LEFT" + }, + { + "inSIBLING_VALUE_HASH": 1, + "setHASH_RIGHT": 1, + "line": 129, + "fileName": "storage_sm_set_delete_found.zkasm", + "lineStr": " SIBLING_VALUE_HASH => HASH_RIGHT" + }, + { + "freeInTag": { + "op": "" + }, + "inFREE": 1, + "setNEW_ROOT": 1, + "hash": 1, + "hashType": 1, + "line": 130, + "fileName": "storage_sm_set_delete_found.zkasm", + "lineStr": " $ => NEW_ROOT :HASH1" + }, + { + "inLEVEL": 1, + "jmpz": 1, + "jmpAddressLabel": "SDF_Latch", + "line": 136, + "jmpAddress": 239, + "fileName": "storage_sm_set_delete_found.zkasm", + "lineStr": " LEVEL :JMPZ(SDF_Latch)" + }, + { + "inLEVEL": 1, + "CONST": -1, + "setLEVEL": 1, + "line": 138, + "fileName": "storage_sm_set_delete_found.zkasm", + "lineStr": " LEVEL - 1 => LEVEL" + }, + { + "freeInTag": { + "op": "functionCall", + "funcName": "GetSiblingHash", + "params": [] + }, + "inFREE": 1, + "setHASH_LEFT": 1, + "setHASH_RIGHT": 1, + "setVALUE_HIGH": 1, + "jmpnz": 1, + "jmpAddressLabel": "SDF_SiblingHashIsNotZero", + "line": 142, + "jmpAddress": 212, + "fileName": "storage_sm_set_delete_found.zkasm", + "lineStr": " ${GetSiblingHash()} => HASH_LEFT, HASH_RIGHT, VALUE_HIGH :JMPNZ(SDF_SiblingHashIsNotZero) ;VH[0]" + }, + { + "inROTL_VH": 1, + "setVALUE_HIGH": 1, + "jmpnz": 1, + "jmpAddressLabel": "SDF_SiblingHashIsNotZero", + "line": 143, + "jmpAddress": 212, + "fileName": "storage_sm_set_delete_found.zkasm", + "lineStr": " ROTL_VH => VALUE_HIGH :JMPNZ(SDF_SiblingHashIsNotZero) ; VH[3]" + }, + { + "inROTL_VH": 1, + "setVALUE_HIGH": 1, + "jmpnz": 1, + "jmpAddressLabel": "SDF_SiblingHashIsNotZero", + "line": 144, + "jmpAddress": 212, + "fileName": "storage_sm_set_delete_found.zkasm", + "lineStr": " ROTL_VH => VALUE_HIGH :JMPNZ(SDF_SiblingHashIsNotZero) ; VH[2]" + }, + { + "inROTL_VH": 1, + "setVALUE_HIGH": 1, + "jmpnz": 1, + "jmpAddressLabel": "SDF_SiblingHashIsNotZero", + "line": 145, + "jmpAddress": 212, + "fileName": "storage_sm_set_delete_found.zkasm", + "lineStr": " ROTL_VH => VALUE_HIGH :JMPNZ(SDF_SiblingHashIsNotZero) ; VH[1]" + }, + { + "jmp": 1, + "jmpAddressLabel": "AssertFails", + "line": 147, + "jmpAddress": 285, + "fileName": "storage_sm_set_delete_found.zkasm", + "lineStr": " :JMP(AssertFails)" + }, + { + "CONST": 0, + "setVALUE_HIGH": 1, + "line": 150, + "fileName": "storage_sm_set_delete_found.zkasm", + "lineStr": " 0 => VALUE_HIGH" + }, + { + "freeInTag": { + "op": "functionCall", + "funcName": "GetNextKeyBit", + "params": [] + }, + "inFREE": 1, + "setRKEY_BIT": 1, + "jmpz": 1, + "jmpAddressLabel": "SDF_SiblingIsRight3", + "line": 154, + "jmpAddress": 219, + "fileName": "storage_sm_set_delete_found.zkasm", + "lineStr": " ${GetNextKeyBit()} => RKEY_BIT :JMPZ(SDF_SiblingIsRight3)" + }, + { + "inNEW_ROOT": 1, + "setHASH_RIGHT": 1, + "line": 164, + "fileName": "storage_sm_set_delete_found.zkasm", + "lineStr": " NEW_ROOT => HASH_RIGHT" + }, + { + "freeInTag": { + "op": "" + }, + "inFREE": 1, + "setNEW_ROOT": 1, + "hash": 1, + "hashType": 0, + "line": 165, + "fileName": "storage_sm_set_delete_found.zkasm", + "lineStr": " $ => NEW_ROOT :HASH0" + }, + { + "inOLD_ROOT": 1, + "setHASH_RIGHT": 1, + "line": 168, + "fileName": "storage_sm_set_delete_found.zkasm", + "lineStr": " OLD_ROOT => HASH_RIGHT" + }, + { + "freeInTag": { + "op": "" + }, + "inFREE": 1, + "setOLD_ROOT": 1, + "hash": 1, + "hashType": 0, + "line": 169, + "fileName": "storage_sm_set_delete_found.zkasm", + "lineStr": " $ => OLD_ROOT :HASH0" + }, + { + "freeInTag": { + "op": "" + }, + "inFREE": 1, + "setRKEY": 1, + "climbRkey": 1, + "climbSiblingRkey": 0, + "climbBitN": 0, + "jmp": 1, + "jmpAddressLabel": "SDF_ClimbTree", + "line": 172, + "jmpAddress": 224, + "fileName": "storage_sm_set_delete_found.zkasm", + "lineStr": " $ => RKEY :CLIMB_RKEY, JMP(SDF_ClimbTree)" + }, + { + "inNEW_ROOT": 1, + "setHASH_LEFT": 1, + "line": 178, + "fileName": "storage_sm_set_delete_found.zkasm", + "lineStr": " NEW_ROOT => HASH_LEFT" + }, + { + "freeInTag": { + "op": "" + }, + "inFREE": 1, + "setNEW_ROOT": 1, + "hash": 1, + "hashType": 0, + "line": 179, + "fileName": "storage_sm_set_delete_found.zkasm", + "lineStr": " $ => NEW_ROOT :HASH0" + }, + { + "inOLD_ROOT": 1, + "setHASH_LEFT": 1, + "line": 182, + "fileName": "storage_sm_set_delete_found.zkasm", + "lineStr": " OLD_ROOT => HASH_LEFT" + }, + { + "freeInTag": { + "op": "" + }, + "inFREE": 1, + "setOLD_ROOT": 1, + "hash": 1, + "hashType": 0, + "line": 183, + "fileName": "storage_sm_set_delete_found.zkasm", + "lineStr": " $ => OLD_ROOT :HASH0" + }, + { + "freeInTag": { + "op": "" + }, + "inFREE": 1, + "setRKEY": 1, + "climbRkey": 1, + "climbSiblingRkey": 0, + "climbBitN": 0, + "line": 186, + "fileName": "storage_sm_set_delete_found.zkasm", + "lineStr": " $ => RKEY :CLIMB_RKEY" + }, + { + "inLEVEL": 1, + "jmpz": 1, + "jmpAddressLabel": "SDF_Latch", + "line": 194, + "jmpAddress": 239, + "fileName": "storage_sm_set_delete_found.zkasm", + "lineStr": " LEVEL :JMPZ(SDF_Latch)" + }, + { + "inLEVEL": 1, + "CONST": -1, + "setLEVEL": 1, + "line": 195, + "fileName": "storage_sm_set_delete_found.zkasm", + "lineStr": " LEVEL - 1 => LEVEL" + }, + { + "freeInTag": { + "op": "functionCall", + "funcName": "GetNextKeyBit", + "params": [] + }, + "inFREE": 1, + "setRKEY_BIT": 1, + "jmpz": 1, + "jmpAddressLabel": "SDF_SiblingIsRight4", + "line": 198, + "jmpAddress": 233, + "fileName": "storage_sm_set_delete_found.zkasm", + "lineStr": " ${GetNextKeyBit()} => RKEY_BIT :JMPZ(SDF_SiblingIsRight4)" + }, + { + "freeInTag": { + "op": "functionCall", + "funcName": "GetSiblingHash", + "params": [] + }, + "inFREE": 1, + "setHASH_LEFT": 1, + "line": 203, + "fileName": "storage_sm_set_delete_found.zkasm", + "lineStr": " ${GetSiblingHash()} => HASH_LEFT" + }, + { + "inNEW_ROOT": 1, + "setHASH_RIGHT": 1, + "line": 204, + "fileName": "storage_sm_set_delete_found.zkasm", + "lineStr": " NEW_ROOT => HASH_RIGHT" + }, + { + "freeInTag": { + "op": "" + }, + "inFREE": 1, + "setNEW_ROOT": 1, + "hash": 1, + "hashType": 0, + "line": 205, + "fileName": "storage_sm_set_delete_found.zkasm", + "lineStr": " $ => NEW_ROOT :HASH0" + }, + { + "inOLD_ROOT": 1, + "setHASH_RIGHT": 1, + "line": 208, + "fileName": "storage_sm_set_delete_found.zkasm", + "lineStr": " OLD_ROOT => HASH_RIGHT" + }, + { + "freeInTag": { + "op": "" + }, + "inFREE": 1, + "setOLD_ROOT": 1, + "hash": 1, + "hashType": 0, + "line": 209, + "fileName": "storage_sm_set_delete_found.zkasm", + "lineStr": " $ => OLD_ROOT :HASH0" + }, + { + "freeInTag": { + "op": "" + }, + "inFREE": 1, + "setRKEY": 1, + "climbRkey": 1, + "climbSiblingRkey": 0, + "climbBitN": 0, + "jmp": 1, + "jmpAddressLabel": "SDF_ClimbTree", + "line": 212, + "jmpAddress": 224, + "fileName": "storage_sm_set_delete_found.zkasm", + "lineStr": " $ => RKEY :CLIMB_RKEY, JMP(SDF_ClimbTree)" + }, + { + "inNEW_ROOT": 1, + "setHASH_LEFT": 1, + "line": 217, + "fileName": "storage_sm_set_delete_found.zkasm", + "lineStr": " NEW_ROOT => HASH_LEFT" + }, + { + "freeInTag": { + "op": "functionCall", + "funcName": "GetSiblingHash", + "params": [] + }, + "inFREE": 1, + "setHASH_RIGHT": 1, + "line": 218, + "fileName": "storage_sm_set_delete_found.zkasm", + "lineStr": " ${GetSiblingHash()} => HASH_RIGHT" + }, + { + "freeInTag": { + "op": "" + }, + "inFREE": 1, + "setNEW_ROOT": 1, + "hash": 1, + "hashType": 0, + "line": 219, + "fileName": "storage_sm_set_delete_found.zkasm", + "lineStr": " $ => NEW_ROOT :HASH0" + }, + { + "inOLD_ROOT": 1, + "setHASH_LEFT": 1, + "line": 222, + "fileName": "storage_sm_set_delete_found.zkasm", + "lineStr": " OLD_ROOT => HASH_LEFT" + }, + { + "freeInTag": { + "op": "" + }, + "inFREE": 1, + "setOLD_ROOT": 1, + "hash": 1, + "hashType": 0, + "line": 223, + "fileName": "storage_sm_set_delete_found.zkasm", + "lineStr": " $ => OLD_ROOT :HASH0" + }, + { + "freeInTag": { + "op": "" + }, + "inFREE": 1, + "setRKEY": 1, + "climbRkey": 1, + "climbSiblingRkey": 0, + "climbBitN": 0, + "jmp": 1, + "jmpAddressLabel": "SDF_ClimbTree", + "line": 226, + "jmpAddress": 224, + "fileName": "storage_sm_set_delete_found.zkasm", + "lineStr": " $ => RKEY :CLIMB_RKEY, JMP(SDF_ClimbTree)" + }, + { + "latchSet": 1, + "jmp": 1, + "jmpAddressLabel": "Run", + "line": 232, + "jmpAddress": 0, + "fileName": "storage_sm_set_delete_found.zkasm", + "lineStr": " :LATCH_SET, JMP(Run)" + }, + { + "freeInTag": { + "op": "functionCall", + "funcName": "GetOldValueLow", + "params": [] + }, + "inFREE": 1, + "setHASH_LEFT": 1, + "line": 20, + "fileName": "storage_sm_set_delete_not_found.zkasm", + "lineStr": " ${GetOldValueLow()} => HASH_LEFT" + }, + { + "freeInTag": { + "op": "functionCall", + "funcName": "GetOldValueHigh", + "params": [] + }, + "inFREE": 1, + "setHASH_RIGHT": 1, + "line": 21, + "fileName": "storage_sm_set_delete_not_found.zkasm", + "lineStr": " ${GetOldValueHigh()} => HASH_RIGHT" + }, + { + "freeInTag": { + "op": "" + }, + "inFREE": 1, + "setHASH_RIGHT": 1, + "hash": 1, + "hashType": 0, + "line": 22, + "fileName": "storage_sm_set_delete_not_found.zkasm", + "lineStr": " $ => HASH_RIGHT :HASH0" + }, + { + "freeInTag": { + "op": "functionCall", + "funcName": "GetRkey", + "params": [] + }, + "inFREE": 1, + "setRKEY": 1, + "setHASH_LEFT": 1, + "line": 25, + "fileName": "storage_sm_set_delete_not_found.zkasm", + "lineStr": " ${GetRkey()} => RKEY, HASH_LEFT" + }, + { + "freeInTag": { + "op": "" + }, + "inFREE": 1, + "setOLD_ROOT": 1, + "hash": 1, + "hashType": 1, + "line": 26, + "fileName": "storage_sm_set_delete_not_found.zkasm", + "lineStr": " $ => OLD_ROOT :HASH1" + }, + { + "freeInTag": { + "op": "functionCall", + "funcName": "GetLevel", + "params": [] + }, + "inFREE": 1, + "setLEVEL": 1, + "line": 31, + "fileName": "storage_sm_set_delete_not_found.zkasm", + "lineStr": " ${GetLevel()} => LEVEL" + }, + { + "CONST": 0, + "setNEW_ROOT": 1, + "setVALUE_LOW": 1, + "setVALUE_HIGH": 1, + "line": 36, + "fileName": "storage_sm_set_delete_not_found.zkasm", + "lineStr": " 0x0 => NEW_ROOT, VALUE_LOW, VALUE_HIGH" + }, + { + "inLEVEL": 1, + "jmpz": 1, + "jmpAddressLabel": "SDNF_Latch", + "line": 39, + "jmpAddress": 278, + "fileName": "storage_sm_set_delete_not_found.zkasm", + "lineStr": " LEVEL :JMPZ(SDNF_Latch)" + }, + { + "inLEVEL": 1, + "CONST": -1, + "setLEVEL": 1, + "line": 40, + "fileName": "storage_sm_set_delete_not_found.zkasm", + "lineStr": " LEVEL - 1 => LEVEL" + }, + { + "freeInTag": { + "op": "functionCall", + "funcName": "GetSiblingLeftChildHash", + "params": [] + }, + "inFREE": 1, + "setHASH_LEFT": 1, + "line": 45, + "fileName": "storage_sm_set_delete_not_found.zkasm", + "lineStr": " ${GetSiblingLeftChildHash()} => HASH_LEFT" + }, + { + "freeInTag": { + "op": "functionCall", + "funcName": "GetSiblingRightChildHash", + "params": [] + }, + "inFREE": 1, + "setHASH_RIGHT": 1, + "line": 46, + "fileName": "storage_sm_set_delete_not_found.zkasm", + "lineStr": " ${GetSiblingRightChildHash()} => HASH_RIGHT" + }, + { + "freeInTag": { + "op": "" + }, + "inFREE": 1, + "setHASH_LEFT": 1, + "setHASH_RIGHT": 1, + "hash": 1, + "hashType": 0, + "line": 47, + "fileName": "storage_sm_set_delete_not_found.zkasm", + "lineStr": " $ => HASH_LEFT, HASH_RIGHT :HASH0" + }, + { + "freeInTag": { + "op": "functionCall", + "funcName": "GetNextKeyBit", + "params": [] + }, + "inFREE": 1, + "setRKEY_BIT": 1, + "jmpz": 1, + "jmpAddressLabel": "SDNF_SiblingIsRight3", + "line": 49, + "jmpAddress": 258, + "fileName": "storage_sm_set_delete_not_found.zkasm", + "lineStr": " ${GetNextKeyBit()} => RKEY_BIT :JMPZ(SDNF_SiblingIsRight3)" + }, + { + "inNEW_ROOT": 1, + "setHASH_RIGHT": 1, + "line": 54, + "fileName": "storage_sm_set_delete_not_found.zkasm", + "lineStr": " NEW_ROOT => HASH_RIGHT" + }, + { + "freeInTag": { + "op": "" + }, + "inFREE": 1, + "setNEW_ROOT": 1, + "hash": 1, + "hashType": 0, + "line": 57, + "fileName": "storage_sm_set_delete_not_found.zkasm", + "lineStr": " $ => NEW_ROOT :HASH0" + }, + { + "inOLD_ROOT": 1, + "setHASH_RIGHT": 1, + "line": 60, + "fileName": "storage_sm_set_delete_not_found.zkasm", + "lineStr": " OLD_ROOT => HASH_RIGHT" + }, + { + "freeInTag": { + "op": "" + }, + "inFREE": 1, + "setOLD_ROOT": 1, + "hash": 1, + "hashType": 0, + "line": 61, + "fileName": "storage_sm_set_delete_not_found.zkasm", + "lineStr": " $ => OLD_ROOT :HASH0" + }, + { + "freeInTag": { + "op": "" + }, + "inFREE": 1, + "setRKEY": 1, + "climbRkey": 1, + "climbSiblingRkey": 0, + "climbBitN": 0, + "jmp": 1, + "jmpAddressLabel": "SDNF_ClimbTree", + "line": 64, + "jmpAddress": 263, + "fileName": "storage_sm_set_delete_not_found.zkasm", + "lineStr": " $ => RKEY :CLIMB_RKEY, JMP(SDNF_ClimbTree)" + }, + { + "inNEW_ROOT": 1, + "setHASH_LEFT": 1, + "line": 70, + "fileName": "storage_sm_set_delete_not_found.zkasm", + "lineStr": " NEW_ROOT => HASH_LEFT" + }, + { + "freeInTag": { + "op": "" + }, + "inFREE": 1, + "setNEW_ROOT": 1, + "hash": 1, + "hashType": 0, + "line": 71, + "fileName": "storage_sm_set_delete_not_found.zkasm", + "lineStr": " $ => NEW_ROOT :HASH0" + }, + { + "inOLD_ROOT": 1, + "setHASH_LEFT": 1, + "line": 74, + "fileName": "storage_sm_set_delete_not_found.zkasm", + "lineStr": " OLD_ROOT => HASH_LEFT" + }, + { + "freeInTag": { + "op": "" + }, + "inFREE": 1, + "setOLD_ROOT": 1, + "hash": 1, + "hashType": 0, + "line": 75, + "fileName": "storage_sm_set_delete_not_found.zkasm", + "lineStr": " $ => OLD_ROOT :HASH0" + }, + { + "freeInTag": { + "op": "" + }, + "inFREE": 1, + "setRKEY": 1, + "climbRkey": 1, + "climbSiblingRkey": 0, + "climbBitN": 0, + "jmp": 1, + "jmpAddressLabel": "SDNF_ClimbTree", + "line": 78, + "jmpAddress": 263, + "fileName": "storage_sm_set_delete_not_found.zkasm", + "lineStr": " $ => RKEY :CLIMB_RKEY, JMP(SDNF_ClimbTree)" + }, + { + "inLEVEL": 1, + "jmpz": 1, + "jmpAddressLabel": "SDNF_Latch", + "line": 83, + "jmpAddress": 278, + "fileName": "storage_sm_set_delete_not_found.zkasm", + "lineStr": " LEVEL :JMPZ(SDNF_Latch)" + }, + { + "inLEVEL": 1, + "CONST": -1, + "setLEVEL": 1, + "line": 84, + "fileName": "storage_sm_set_delete_not_found.zkasm", + "lineStr": " LEVEL - 1 => LEVEL" + }, + { + "freeInTag": { + "op": "functionCall", + "funcName": "GetNextKeyBit", + "params": [] + }, + "inFREE": 1, + "setRKEY_BIT": 1, + "jmpz": 1, + "jmpAddressLabel": "SDNF_SiblingIsRight4", + "line": 86, + "jmpAddress": 272, + "fileName": "storage_sm_set_delete_not_found.zkasm", + "lineStr": " ${GetNextKeyBit()} => RKEY_BIT :JMPZ(SDNF_SiblingIsRight4)" + }, + { + "inNEW_ROOT": 1, + "setHASH_RIGHT": 1, + "line": 91, + "fileName": "storage_sm_set_delete_not_found.zkasm", + "lineStr": " NEW_ROOT => HASH_RIGHT" + }, + { + "freeInTag": { + "op": "functionCall", + "funcName": "GetSiblingHash", + "params": [] + }, + "inFREE": 1, + "setHASH_LEFT": 1, + "line": 92, + "fileName": "storage_sm_set_delete_not_found.zkasm", + "lineStr": " ${GetSiblingHash()} => HASH_LEFT" + }, + { + "freeInTag": { + "op": "" + }, + "inFREE": 1, + "setNEW_ROOT": 1, + "hash": 1, + "hashType": 0, + "line": 93, + "fileName": "storage_sm_set_delete_not_found.zkasm", + "lineStr": " $ => NEW_ROOT :HASH0" + }, + { + "inOLD_ROOT": 1, + "setHASH_RIGHT": 1, + "line": 96, + "fileName": "storage_sm_set_delete_not_found.zkasm", + "lineStr": " OLD_ROOT => HASH_RIGHT" + }, + { + "freeInTag": { + "op": "" + }, + "inFREE": 1, + "setOLD_ROOT": 1, + "hash": 1, + "hashType": 0, + "line": 97, + "fileName": "storage_sm_set_delete_not_found.zkasm", + "lineStr": " $ => OLD_ROOT :HASH0" + }, + { + "freeInTag": { + "op": "" + }, + "inFREE": 1, + "setRKEY": 1, + "climbRkey": 1, + "climbSiblingRkey": 0, + "climbBitN": 0, + "jmp": 1, + "jmpAddressLabel": "SDNF_ClimbTree", + "line": 100, + "jmpAddress": 263, + "fileName": "storage_sm_set_delete_not_found.zkasm", + "lineStr": " $ => RKEY :CLIMB_RKEY, JMP(SDNF_ClimbTree)" + }, + { + "inNEW_ROOT": 1, + "setHASH_LEFT": 1, + "line": 105, + "fileName": "storage_sm_set_delete_not_found.zkasm", + "lineStr": " NEW_ROOT => HASH_LEFT" + }, + { + "freeInTag": { + "op": "functionCall", + "funcName": "GetSiblingHash", + "params": [] + }, + "inFREE": 1, + "setHASH_RIGHT": 1, + "line": 106, + "fileName": "storage_sm_set_delete_not_found.zkasm", + "lineStr": " ${GetSiblingHash()} => HASH_RIGHT" + }, + { + "freeInTag": { + "op": "" + }, + "inFREE": 1, + "setNEW_ROOT": 1, + "hash": 1, + "hashType": 0, + "line": 107, + "fileName": "storage_sm_set_delete_not_found.zkasm", + "lineStr": " $ => NEW_ROOT :HASH0" + }, + { + "inOLD_ROOT": 1, + "setHASH_LEFT": 1, + "line": 110, + "fileName": "storage_sm_set_delete_not_found.zkasm", + "lineStr": " OLD_ROOT => HASH_LEFT" + }, + { + "freeInTag": { + "op": "" + }, + "inFREE": 1, + "setOLD_ROOT": 1, + "hash": 1, + "hashType": 0, + "line": 111, + "fileName": "storage_sm_set_delete_not_found.zkasm", + "lineStr": " $ => OLD_ROOT :HASH0" + }, + { + "freeInTag": { + "op": "" + }, + "inFREE": 1, + "setRKEY": 1, + "climbRkey": 1, + "climbSiblingRkey": 0, + "climbBitN": 0, + "jmp": 1, + "jmpAddressLabel": "SDNF_ClimbTree", + "line": 114, + "jmpAddress": 263, + "fileName": "storage_sm_set_delete_not_found.zkasm", + "lineStr": " $ => RKEY :CLIMB_RKEY, JMP(SDNF_ClimbTree)" + }, + { + "latchSet": 1, + "jmp": 1, + "jmpAddressLabel": "Run", + "line": 120, + "jmpAddress": 0, + "fileName": "storage_sm_set_delete_not_found.zkasm", + "lineStr": " :LATCH_SET, JMP(Run)" + }, + { + "CONST": 1, + "setNEW_ROOT": 1, + "jmp": 1, + "jmpAddressLabel": "Get_Zero", + "line": 6, + "jmpAddress": 24, + "fileName": "storage_sm_set_zero_to_zero.zkasm", + "lineStr": " 1 => NEW_ROOT :JMP(Get_Zero)" + }, + { + "inOLD_ROOT": 1, + "setNEW_ROOT": 1, + "line": 10, + "fileName": "storage_sm_set_zero_to_zero.zkasm", + "lineStr": " OLD_ROOT => NEW_ROOT" + }, + { + "latchSet": 1, + "jmp": 1, + "jmpAddressLabel": "Run", + "line": 14, + "jmpAddress": 0, + "fileName": "storage_sm_set_zero_to_zero.zkasm", + "lineStr": " :LATCH_SET, JMP(Run)" + }, + { + "CONST": 0, + "setHASH_LEFT": 1, + "setHASH_RIGHT": 1, + "setOLD_ROOT": 1, + "setNEW_ROOT": 1, + "setVALUE_LOW": 1, + "setVALUE_HIGH": 1, + "setSIBLING_VALUE_HASH": 1, + "setRKEY": 1, + "setSIBLING_RKEY": 1, + "setRKEY_BIT": 1, + "setLEVEL": 1, + "line": 68, + "fileName": "storage_sm.zkasm", + "lineStr": " 0 => HASH_LEFT, HASH_RIGHT, OLD_ROOT, NEW_ROOT, VALUE_LOW, VALUE_HIGH, SIBLING_VALUE_HASH, RKEY, SIBLING_RKEY, RKEY_BIT, LEVEL" + }, + { + "freeInTag": { + "op": "functionCall", + "funcName": "isAlmostEndPolynomial", + "params": [] + }, + "inFREE": 1, + "jmpz": 1, + "jmpAddressLabel": "NotEndPol", + "line": 72, + "jmpAddress": 283, + "fileName": "storage_sm.zkasm", + "lineStr": " ${isAlmostEndPolynomial()} :JMPZ(NotEndPol)" + }, + { + "jmp": 1, + "jmpAddressLabel": "Run", + "line": 75, + "jmpAddress": 0, + "fileName": "storage_sm.zkasm", + "lineStr": " :JMP(Run)" + }, + { + "jmp": 1, + "jmpAddressLabel": "AssertFails", + "line": 79, + "jmpAddress": 285, + "fileName": "storage_sm.zkasm", + "lineStr": " :JMP(AssertFails)" + } + ], + "labels": { + "Run": 0, + "ValueLowIsNonZero": 11, + "ValueHighIsNonZero": 12, + "ValueIsNonZero": 14, + "ValueIsZero": 19, + "Get_Zero": 24, + "GZ_Zero": 24, + "GZ_LeafNode": 27, + "GZ_SiblingRKey_RKey_differents": 37, + "GZ_IntermediateNode": 41, + "GZ_InitLevel": 42, + "Get_NonZero": 43, + "Get_ClimbUp": 49, + "GCU_SiblingIsLeft": 52, + "GCU_SiblingIsRight": 54, + "GCU_HashAndClimbUp": 56, + "GCU_Latch": 58, + "Set_Update": 60, + "SU_InitLevel": 71, + "SU_ClimbTree": 72, + "SU_SiblingIsLeft": 75, + "SU_SiblingIsRight": 81, + "SU_Latch": 87, + "Set_InsertFound": 88, + "SIF_InitLevel": 99, + "SIF_FirstIntermediateNode": 100, + "SIF_SiblingIsLeft1": 102, + "SIF_SiblingIsRight1": 107, + "SIF_ClimbBranch": 112, + "SIF_SiblingIsLeft2": 115, + "SIF_SiblingIsRight2": 120, + "SIF_StartOldRoot": 125, + "SIF_ClimbTree": 128, + "SIF_SiblingIsLeft3": 131, + "SIF_SiblingIsRight3": 138, + "SIF_Latch": 145, + "Set_InsertNotFound": 146, + "SINF_InitLevel": 151, + "SINF_StartOldRoot": 152, + "SINF_ClimbTree": 153, + "SINF_SiblingIsLeft3": 156, + "SINF_SiblingIsRight3": 162, + "SINF_Latch": 168, + "Set_DeleteFound": 169, + "SDF_InitLevel": 179, + "SDF_FirstIntermediateNode": 180, + "SDF_SiblingIsLeft1": 182, + "SDF_SiblingIsRight1": 187, + "SDF_ClimbBranch": 192, + "SDF_SiblingIsLeft2": 195, + "SDF_SiblingIsRight2": 197, + "SDF_SiblingClimbKey2": 199, + "SDF_StartNewRoot": 202, + "SDF_SiblingHashIsNotZero": 212, + "SDF_SiblingIsLeft3": 214, + "SDF_SiblingIsRight3": 219, + "SDF_ClimbTree": 224, + "SDF_SiblingIsLeft4": 227, + "SDF_SiblingIsRight4": 233, + "SDF_Latch": 239, + "Set_DeleteNotFound": 240, + "SDNF_InitLevel": 245, + "SDNF_SiblingIsLeft3": 253, + "SDNF_SiblingIsRight3": 258, + "SDNF_ClimbTree": 263, + "SDNF_SiblingIsLeft4": 266, + "SDNF_SiblingIsRight4": 272, + "SDNF_Latch": 278, + "Set_ZeroToZero": 279, + "Set_ZeroToZero_GetZero_Return": 280, + "SetAllToZero": 282, + "NotEndPol": 283, + "AssertFails": 285 + } +} diff --git a/test/pil2/zkevm-etrog/storage_rom.pil b/test/pil2/zkevm-etrog/storage_rom.pil new file mode 100644 index 0000000..ea35787 --- /dev/null +++ b/test/pil2/zkevm-etrog/storage_rom.pil @@ -0,0 +1,57 @@ +include "tools.pil" +const int STORAGE_ROM_ID = 10; + +subproof StorageRom(2**16) { + + col fixed ROM_FLAGS; + col fixed CONST0; + col fixed JMP_ADDRESS; + col fixed LINE; + col fixed IN_SIBLING_RKEY; + + include "storage_rom_compiled.pil"; + + repeat_last_source_line(); + lookup_proves(STORAGE_ROM_ID, 1, [LINE, ROM_FLAGS, CONST0, JMP_ADDRESS, IN_SIBLING_RKEY]); +} + +private function source(int line, int flags, int const0, int jmpAddress, int inSiblingRkey) { + container air.source { + int lastLine; + } + air.source.lastLine = line; + air.LINE[line] = line; + air.ROM_FLAGS[line] = flags; + air.CONST0[line] = const0; + air.JMP_ADDRESS[line] = jmpAddress; + air.IN_SIBLING_RKEY[line] = inSiblingRkey; +} + +private function repeat_last_source_line() { + int rline = air.source.lastLine; + int line = rline + 1; + // #pragma debugger + /* while (line < N) { + air.LINE[line] = air.LINE[rline]; + air.ROM_FLAGS[line] = air.ROM_FLAGS[rline]; + air.CONST0[line] = air.CONST0[rline]; + air.JMP_ADDRESS[line] = air.JMP_ADDRESS[rline]; + air.IN_SIBLING_RKEY[line] = air.IN_SIBLING_RKEY[rline]; + line = line + 1; + }*/ + const int _LINE = air.LINE[rline]; + const int _ROM_FLAGS = air.ROM_FLAGS[rline]; + const int _CONST0 = air.CONST0[rline]; + const int _JMP_ADDRESS = air.JMP_ADDRESS[rline]; + const int _IN_SIBLING_RKEY = air.IN_SIBLING_RKEY[rline]; + #pragma timer t1 start + while (line < N) { + air.LINE[line] = _LINE; + air.ROM_FLAGS[line] = _ROM_FLAGS; + air.CONST0[line] = _CONST0; + air.JMP_ADDRESS[line] = _JMP_ADDRESS; + air.IN_SIBLING_RKEY[line] = _IN_SIBLING_RKEY; + line = line + 1; + } + #pragma timer t1 end +} \ No newline at end of file diff --git a/test/pil2/zkevm-etrog/storage_rom_compiled.pil b/test/pil2/zkevm-etrog/storage_rom_compiled.pil new file mode 100644 index 0000000..4aa78d7 --- /dev/null +++ b/test/pil2/zkevm-etrog/storage_rom_compiled.pil @@ -0,0 +1,317 @@ + source( 0,0x001FFC00, 0,0,0); // #4 0 => HASH_LEFT, HASH_RIGHT, OLD_ROOT, NEW_ROOT, VALUE_LOW, VALUE_HIGH, SIBLING_VALUE_HASH, RKEY, SIBLING_RKEY, RKEY_BIT, LEVEL # flags = setHASH_LEFT, setHASH_RIGHT, setLEVEL, setNEW_ROOT, setOLD_ROOT, setRKEY, setRKEY_BIT, setSIBLING_RKEY, setSIBLING_VALUE_HASH, setVALUE_HIGH, setVALUE_LOW + source( 1,0x00200200, 0,0,0); // #6 ${isValueZero()} :JMPNZ(ValueIsZero) # flags = jmpnz, inFREE + source( 2,0x00380200, 0,0,0); // #7 ${GetValueLow()} => VALUE_LOW,VALUE_HIGH :JMPNZ(ValueLowIsNonZero) # flags = jmpnz, setVALUE_HIGH, setVALUE_LOW, inFREE + source( 3,0x20080200, 0,0,0); // #8 ROTL_VH => VALUE_HIGH :JMPNZ(ValueLowIsNonZero) # flags = jmpnz, setVALUE_HIGH, inROTL_VH + source( 4,0x20080200, 0,0,0); // #9 ROTL_VH => VALUE_HIGH :JMPNZ(ValueLowIsNonZero) # flags = jmpnz, setVALUE_HIGH, inROTL_VH + source( 5,0x20080200, 0,0,0); // #10 ROTL_VH => VALUE_HIGH :JMPNZ(ValueLowIsNonZero) # flags = jmpnz, setVALUE_HIGH, inROTL_VH + source( 6,0x00282200, 0,0,0); // #13 ${GetValueHigh()} => VALUE_HIGH,NEW_ROOT :JMPNZ(ValueHighIsNonZero) # flags = jmpnz, setNEW_ROOT, setVALUE_HIGH, inFREE + source( 7,0x20080200, 0,0,0); // #14 ROTL_VH => VALUE_HIGH :JMPNZ(ValueHighIsNonZero) # flags = jmpnz, setVALUE_HIGH, inROTL_VH + source( 8,0x20080200, 0,0,0); // #15 ROTL_VH => VALUE_HIGH :JMPNZ(ValueHighIsNonZero) # flags = jmpnz, setVALUE_HIGH, inROTL_VH + source( 9,0x20080200, 0,0,0); // #16 ROTL_VH => VALUE_HIGH :JMPNZ(ValueHighIsNonZero) # flags = jmpnz, setVALUE_HIGH, inROTL_VH + source( 10,0x00000080, 0,0,0); // #17 :JMP(AssertFails) # flags = jmp + source( 11,0x00280080, 0,0,0); // #20 ${GetValueHigh()} => VALUE_HIGH :JMP(ValueIsNonZero) # flags = jmp, setVALUE_HIGH, inFREE + source( 12,0x00480000, 0,0,0); // #24 NEW_ROOT => VALUE_HIGH # flags = setVALUE_HIGH, inNEW_ROOT + source( 13,0x00002000, 0,0,0); // #25 0 => NEW_ROOT # flags = setNEW_ROOT + source( 14,0x00200200, 0,0,0); // #29 ${isGet()} :JMPNZ(Get_NonZero) # flags = jmpnz, inFREE + source( 15,0x00200200, 0,0,0); // #30 ${isSetUpdate()} :JMPNZ(Set_Update) # flags = jmpnz, inFREE + source( 16,0x00200200, 0,0,0); // #31 ${isSetInsertFound()} :JMPNZ(Set_InsertFound) # flags = jmpnz, inFREE + source( 17,0x00200200, 0,0,0); // #32 ${isSetInsertNotFound()} :JMPNZ(Set_InsertNotFound) # flags = jmpnz, inFREE + source( 18,0x00000080, 0,0,0); // #33 :JMP(SetAllToZero) # flags = jmp + source( 19,0x00200200, 0,0,0); // #50 ${isGet()} :JMPNZ(Get_Zero) # flags = jmpnz, inFREE + source( 20,0x00200200, 0,0,0); // #51 ${isSetDeleteFound()} :JMPNZ(Set_DeleteFound) # flags = jmpnz, inFREE + source( 21,0x00200200, 0,0,0); // #52 ${isSetDeleteNotFound()} :JMPNZ(Set_DeleteNotFound) # flags = jmpnz, inFREE + source( 22,0x00200200, 0,0,0); // #53 ${isSetZeroToZero()} :JMPNZ(Set_ZeroToZero) # flags = jmpnz, inFREE + source( 23,0x00000080, 0,0,0); // #54 :JMP(SetAllToZero) # flags = jmp + + // storage_sm_get_zero.zkasm + + source( 24,0x00208000, 0,0,0); // #22 ${GetRkey()} => RKEY # flags = setRKEY, inFREE + source( 25,0x00200100, 0,0,0); // #24 ${GetIsOld0()} :JMPZ(GZ_LeafNode) # flags = jmpz, inFREE + source( 26,0x00000080, 0,0,0); // #25 :JMP(GZ_IntermediateNode) # flags = jmp + source( 27,0x00200400, 0,0,0); // #33 ${GetSiblingValueLow()} => HASH_LEFT # flags = setHASH_LEFT, inFREE + source( 28,0x00200800, 0,0,0); // #34 ${GetSiblingValueHigh()} => HASH_RIGHT # flags = setHASH_RIGHT, inFREE + source( 29,0x00200801, 0,0,0); // #35 $ => HASH_RIGHT :HASH0 # flags = hash, setHASH_RIGHT, inFREE + source( 30,0x00220000, 0,0,0); // #37 ${GetSiblingRkey()} => SIBLING_RKEY # flags = setSIBLING_RKEY, inFREE + source( 31,0x10040000, 0,0,0); // #40 VALUE_HIGH => SIBLING_VALUE_HASH # flags = setSIBLING_VALUE_HASH, inVALUE_HIGH + source( 32,0x01080200, 0,0,0); // #46 RKEY - SIBLING_RKEY => VALUE_HIGH :JMPNZ(GZ_SiblingRKey_RKey_differents) # flags = jmpnz, setVALUE_HIGH, inRKEY + source( 33,0x20080200, 0,0,0); // #47 ROTL_VH => VALUE_HIGH :JMPNZ(GZ_SiblingRKey_RKey_differents) # flags = jmpnz, setVALUE_HIGH, inROTL_VH + source( 34,0x20080200, 0,0,0); // #48 ROTL_VH => VALUE_HIGH :JMPNZ(GZ_SiblingRKey_RKey_differents) # flags = jmpnz, setVALUE_HIGH, inROTL_VH + source( 35,0x20080200, 0,0,0); // #49 ROTL_VH => VALUE_HIGH :JMPNZ(GZ_SiblingRKey_RKey_differents) # flags = jmpnz, setVALUE_HIGH, inROTL_VH + source( 36,0x00000080, 0,0,0); // #52 :JMP(AssertFails) # flags = jmp + source( 37,0x04080000, 0,0,0); // #57 SIBLING_VALUE_HASH => VALUE_HIGH # flags = setVALUE_HIGH, inSIBLING_VALUE_HASH + source( 38,0x00000400, 0,0,0); // #62 SIBLING_RKEY => HASH_LEFT # flags = setHASH_LEFT + source( 39,0x00204003, 0,0,0); // #63 $ => OLD_ROOT :HASH1 # flags = hash, hashType, setOLD_ROOT, inFREE + source( 40,0x00000080, 0,0,0); // #64 :JMP(GZ_InitLevel) # flags = jmp + source( 41,0x00004000, 0,0,0); // #69 0x0 => OLD_ROOT # flags = setOLD_ROOT + source( 42,0x00201080, 0,0,0); // #74 ${GetLevel()} => LEVEL :JMP(Get_ClimbUp) # flags = jmp, setLEVEL, inFREE + + // storage_sm_get_non_zero.zkasm + + source( 43,0x08000400, 0,0,0); // #17 VALUE_LOW => HASH_LEFT # flags = setHASH_LEFT, inVALUE_LOW + source( 44,0x10000800, 0,0,0); // #18 VALUE_HIGH => HASH_RIGHT # flags = setHASH_RIGHT, inVALUE_HIGH + source( 45,0x00200801, 0,0,0); // #19 $ => HASH_RIGHT :HASH0 # flags = hash, setHASH_RIGHT, inFREE + source( 46,0x00208400, 0,0,0); // #22 ${GetRkey()} => RKEY, HASH_LEFT # flags = setHASH_LEFT, setRKEY, inFREE + source( 47,0x00204003, 0,0,0); // #23 $ => OLD_ROOT :HASH1 # flags = hash, hashType, setOLD_ROOT, inFREE + source( 48,0x00201080, 0,0,0); // #26 ${GetLevel()} => LEVEL :JMP(Get_ClimbUp) # flags = jmp, setLEVEL, inFREE + + // storage_sm_get_climb_up.zkasm + + source( 49,0x40000100, 0,0,0); // #10 LEVEL :JMPZ(GCU_Latch) # flags = jmpz, inLEVEL + source( 50,0x40001000,-1,0,0); // #11 LEVEL - 1 => LEVEL # flags = setLEVEL, inLEVEL + source( 51,0x00210100, 0,0,0); // #14 ${GetNextKeyBit()} => RKEY_BIT :JMPZ(GCU_SiblingIsRight) # flags = jmpz, setRKEY_BIT, inFREE + source( 52,0x00200400, 0,0,0); // #19 ${GetSiblingHash()} => HASH_LEFT # flags = setHASH_LEFT, inFREE + source( 53,0x00800880, 0,0,0); // #20 OLD_ROOT => HASH_RIGHT :JMP(GCU_HashAndClimbUp) # flags = jmp, setHASH_RIGHT, inOLD_ROOT + source( 54,0x00800400, 0,0,0); // #25 OLD_ROOT => HASH_LEFT # flags = setHASH_LEFT, inOLD_ROOT + source( 55,0x00200800, 0,0,0); // #26 ${GetSiblingHash()} => HASH_RIGHT # flags = setHASH_RIGHT, inFREE + source( 56,0x00204001, 0,0,0); // #30 $ => OLD_ROOT :HASH0 # flags = hash, setOLD_ROOT, inFREE + source( 57,0x00208090, 0,0,0); // #33 $ => RKEY :CLIMB_RKEY, JMP(Get_ClimbUp) # flags = climbRkey, jmp, setRKEY, inFREE + source( 58,0x00400100,-1,0,0); // #43 NEW_ROOT - 1 :JMPZ(Set_ZeroToZero_GetZero_Return) # flags = jmpz, inNEW_ROOT + source( 59,0x00000084, 0,0,0); // #46 :LATCH_GET, JMP(Run) # flags = latchGet, jmp + + // storage_sm_set_update.zkasm + + source( 60,0x00208000, 0,0,0); // #17 ${GetRkey()} => RKEY # flags = setRKEY, inFREE + source( 61,0x00200400, 0,0,0); // #21 ${GetOldValueLow()} => HASH_LEFT # flags = setHASH_LEFT, inFREE + source( 62,0x00200800, 0,0,0); // #22 ${GetOldValueHigh()} => HASH_RIGHT # flags = setHASH_RIGHT, inFREE + source( 63,0x00200801, 0,0,0); // #23 $ => HASH_RIGHT :HASH0 # flags = hash, setHASH_RIGHT, inFREE + source( 64,0x01000400, 0,0,0); // #26 RKEY => HASH_LEFT # flags = setHASH_LEFT, inRKEY + source( 65,0x00204003, 0,0,0); // #27 $ => OLD_ROOT :HASH1 # flags = hash, hashType, setOLD_ROOT, inFREE + source( 66,0x08000400, 0,0,0); // #32 VALUE_LOW => HASH_LEFT # flags = setHASH_LEFT, inVALUE_LOW + source( 67,0x10000800, 0,0,0); // #33 VALUE_HIGH => HASH_RIGHT # flags = setHASH_RIGHT, inVALUE_HIGH + source( 68,0x00200801, 0,0,0); // #34 $ => HASH_RIGHT :HASH0 # flags = hash, setHASH_RIGHT, inFREE + source( 69,0x01000400, 0,0,0); // #37 RKEY => HASH_LEFT # flags = setHASH_LEFT, inRKEY + source( 70,0x00202003, 0,0,0); // #38 $ => NEW_ROOT :HASH1 # flags = hash, hashType, setNEW_ROOT, inFREE + source( 71,0x00201000, 0,0,0); // #43 ${GetLevel()} => LEVEL # flags = setLEVEL, inFREE + source( 72,0x40000100, 0,0,0); // #48 LEVEL :JMPZ(SU_Latch) # flags = jmpz, inLEVEL + source( 73,0x40001000,-1,0,0); // #49 LEVEL - 1 => LEVEL # flags = setLEVEL, inLEVEL + source( 74,0x00210100, 0,0,0); // #52 ${GetNextKeyBit()} => RKEY_BIT :JMPZ(SU_SiblingIsRight) # flags = jmpz, setRKEY_BIT, inFREE + source( 75,0x00200400, 0,0,0); // #57 ${GetSiblingHash()} => HASH_LEFT # flags = setHASH_LEFT, inFREE + source( 76,0x00400800, 0,0,0); // #58 NEW_ROOT => HASH_RIGHT # flags = setHASH_RIGHT, inNEW_ROOT + source( 77,0x00202001, 0,0,0); // #59 $ => NEW_ROOT :HASH0 # flags = hash, setNEW_ROOT, inFREE + source( 78,0x00800800, 0,0,0); // #62 OLD_ROOT => HASH_RIGHT ; Sibling hash is already in HASH_LEFT, since previous hash # flags = setHASH_RIGHT, inOLD_ROOT + source( 79,0x00204001, 0,0,0); // #63 $ => OLD_ROOT :HASH0 # flags = hash, setOLD_ROOT, inFREE + source( 80,0x00208090, 0,0,0); // #66 $ => RKEY :CLIMB_RKEY, JMP(SU_ClimbTree) # flags = climbRkey, jmp, setRKEY, inFREE + source( 81,0x00400400, 0,0,0); // #71 NEW_ROOT => HASH_LEFT # flags = setHASH_LEFT, inNEW_ROOT + source( 82,0x00200800, 0,0,0); // #72 ${GetSiblingHash()} => HASH_RIGHT # flags = setHASH_RIGHT, inFREE + source( 83,0x00202001, 0,0,0); // #73 $ => NEW_ROOT :HASH0 # flags = hash, setNEW_ROOT, inFREE + source( 84,0x00800400, 0,0,0); // #76 OLD_ROOT => HASH_LEFT ; Sibling hash is already in HASH_RIGHT, since previous hash # flags = setHASH_LEFT, inOLD_ROOT + source( 85,0x00204001, 0,0,0); // #77 $ => OLD_ROOT :HASH0 # flags = hash, setOLD_ROOT, inFREE + source( 86,0x00208090, 0,0,0); // #80 $ => RKEY :CLIMB_RKEY, JMP(SU_ClimbTree) # flags = climbRkey, jmp, setRKEY, inFREE + source( 87,0x00000088, 0,0,0); // #86 :LATCH_SET, JMP(Run) # flags = latchSet, jmp + + // storage_sm_set_insert_found.zkasm + + source( 88,0x00200400, 0,0,0); // #26 ${GetSiblingValueLow()} => HASH_LEFT # flags = setHASH_LEFT, inFREE + source( 89,0x00200800, 0,0,0); // #27 ${GetSiblingValueHigh()} => HASH_RIGHT # flags = setHASH_RIGHT, inFREE + source( 90,0x00240801, 0,0,0); // #28 $ => SIBLING_VALUE_HASH, HASH_RIGHT :HASH0 # flags = hash, setHASH_RIGHT, setSIBLING_VALUE_HASH, inFREE + source( 91,0x00220000, 0,0,0); // #31 ${GetSiblingRkey()} => SIBLING_RKEY # flags = setSIBLING_RKEY, inFREE + source( 92,0x00000400, 0,0,0); // #32 SIBLING_RKEY => HASH_LEFT # flags = setHASH_LEFT + source( 93,0x00204003, 0,0,0); // #33 $ => OLD_ROOT :HASH1 # flags = hash, hashType, setOLD_ROOT, inFREE + source( 94,0x08000400, 0,0,0); // #36 VALUE_LOW => HASH_LEFT # flags = setHASH_LEFT, inVALUE_LOW + source( 95,0x10000800, 0,0,0); // #37 VALUE_HIGH => HASH_RIGHT # flags = setHASH_RIGHT, inVALUE_HIGH + source( 96,0x00200801, 0,0,0); // #38 $ => HASH_RIGHT :HASH0 # flags = hash, setHASH_RIGHT, inFREE + source( 97,0x00208400, 0,0,0); // #41 ${GetRkey()} => RKEY, HASH_LEFT # flags = setHASH_LEFT, setRKEY, inFREE + source( 98,0x00202003, 0,0,0); // #42 $ => NEW_ROOT :HASH1 # flags = hash, hashType, setNEW_ROOT, inFREE + source( 99,0x00201000, 0,0,0); // #47 ${GetLevel()} => LEVEL # flags = setLEVEL, inFREE + source(100,0x40001000,-1,0,0); // #53 LEVEL - 1 => LEVEL # flags = setLEVEL, inLEVEL + source(101,0x00210100, 0,0,0); // #56 ${GetNextKeyBit()} => RKEY_BIT :JMPZ(SIF_SiblingIsRight1) ; If next key bit is zero, then sibling is right (sibling's next key bit is 1) # flags = jmpz, setRKEY_BIT, inFREE + source(102,0x00800400, 0,0,0); // #61 OLD_ROOT => HASH_LEFT # flags = setHASH_LEFT, inOLD_ROOT + source(103,0x00400800, 0,0,0); // #62 NEW_ROOT => HASH_RIGHT # flags = setHASH_RIGHT, inNEW_ROOT + source(104,0x00202001, 0,0,0); // #63 $ => NEW_ROOT :HASH0 # flags = hash, setNEW_ROOT, inFREE + source(105,0x00208010, 0,0,0); // #66 $ => RKEY :CLIMB_RKEY # flags = climbRkey, setRKEY, inFREE + source(106,0x002200E0, 0,0,0); // #67 $ => SIBLING_RKEY :CLIMB_SIBLING_RKEY_N, JMP(SIF_ClimbBranch) # flags = climbSiblingRkey, climbBitN, jmp, setSIBLING_RKEY, inFREE + source(107,0x00400400, 0,0,0); // #72 NEW_ROOT => HASH_LEFT # flags = setHASH_LEFT, inNEW_ROOT + source(108,0x00800800, 0,0,0); // #73 OLD_ROOT => HASH_RIGHT # flags = setHASH_RIGHT, inOLD_ROOT + source(109,0x00202001, 0,0,0); // #74 $ => NEW_ROOT :HASH0 # flags = hash, setNEW_ROOT, inFREE + source(110,0x00208010, 0,0,0); // #77 $ => RKEY :CLIMB_RKEY # flags = climbRkey, setRKEY, inFREE + source(111,0x00220060, 0,0,0); // #78 $ => SIBLING_RKEY :CLIMB_SIBLING_RKEY_N # flags = climbSiblingRkey, climbBitN, setSIBLING_RKEY, inFREE + source(112,0x00200100, 0,0,0); // #82 ${GetTopOfBranch()} :JMPZ(SIF_StartOldRoot) ; If we are at the top of the branch, then go to SIF_StartOldRoot # flags = jmpz, inFREE + source(113,0x40001000,-1,0,0); // #84 LEVEL - 1 => LEVEL # flags = setLEVEL, inLEVEL + source(114,0x00210100, 0,0,0); // #87 ${GetNextKeyBit()} => RKEY_BIT :JMPZ(SIF_SiblingIsRight2) # flags = jmpz, setRKEY_BIT, inFREE + source(115,0x00000400, 0,0,0); // #92 0x0 => HASH_LEFT # flags = setHASH_LEFT + source(116,0x00400800, 0,0,0); // #93 NEW_ROOT => HASH_RIGHT # flags = setHASH_RIGHT, inNEW_ROOT + source(117,0x00202001, 0,0,0); // #94 $ => NEW_ROOT :HASH0 # flags = hash, setNEW_ROOT, inFREE + source(118,0x00208010, 0,0,0); // #97 $ => RKEY :CLIMB_RKEY # flags = climbRkey, setRKEY, inFREE + source(119,0x002200A0, 0,0,0); // #98 $ => SIBLING_RKEY :CLIMB_SIBLING_RKEY, JMP(SIF_ClimbBranch) # flags = climbSiblingRkey, jmp, setSIBLING_RKEY, inFREE + source(120,0x00400400, 0,0,0); // #103 NEW_ROOT => HASH_LEFT # flags = setHASH_LEFT, inNEW_ROOT + source(121,0x00000800, 0,0,0); // #104 0x0 => HASH_RIGHT # flags = setHASH_RIGHT + source(122,0x00202001, 0,0,0); // #105 $ => NEW_ROOT :HASH0 # flags = hash, setNEW_ROOT, inFREE + source(123,0x00208010, 0,0,0); // #108 $ => RKEY :CLIMB_RKEY # flags = climbRkey, setRKEY, inFREE + source(124,0x002200A0, 0,0,0); // #109 $ => SIBLING_RKEY :CLIMB_SIBLING_RKEY, JMP(SIF_ClimbBranch) # flags = climbSiblingRkey, jmp, setSIBLING_RKEY, inFREE + source(125,0x00000400, 0,0,0); // #113 SIBLING_RKEY => HASH_LEFT # flags = setHASH_LEFT + source(126,0x04000800, 0,0,0); // #114 SIBLING_VALUE_HASH => HASH_RIGHT # flags = setHASH_RIGHT, inSIBLING_VALUE_HASH + source(127,0x00204003, 0,0,0); // #115 $ => OLD_ROOT :HASH1 # flags = hash, hashType, setOLD_ROOT, inFREE + source(128,0x40000100, 0,0,0); // #120 LEVEL :JMPZ(SIF_Latch) # flags = jmpz, inLEVEL + source(129,0x40001000,-1,0,0); // #121 LEVEL - 1 => LEVEL # flags = setLEVEL, inLEVEL + source(130,0x00210100, 0,0,0); // #124 ${GetNextKeyBit()} => RKEY_BIT :JMPZ(SIF_SiblingIsRight3) # flags = jmpz, setRKEY_BIT, inFREE + source(131,0x00400800, 0,0,0); // #129 NEW_ROOT => HASH_RIGHT # flags = setHASH_RIGHT, inNEW_ROOT + source(132,0x00200400, 0,0,0); // #130 ${GetSiblingHash()} => HASH_LEFT # flags = setHASH_LEFT, inFREE + source(133,0x00202001, 0,0,0); // #131 $ => NEW_ROOT :HASH0 # flags = hash, setNEW_ROOT, inFREE + source(134,0x00800800, 0,0,0); // #134 OLD_ROOT => HASH_RIGHT # flags = setHASH_RIGHT, inOLD_ROOT + source(135,0x00204001, 0,0,0); // #135 $ => OLD_ROOT :HASH0 # flags = hash, setOLD_ROOT, inFREE + source(136,0x00208010, 0,0,0); // #138 $ => RKEY :CLIMB_RKEY # flags = climbRkey, setRKEY, inFREE + source(137,0x002200A0, 0,0,0); // #139 $ => SIBLING_RKEY :CLIMB_SIBLING_RKEY, JMP(SIF_ClimbTree) # flags = climbSiblingRkey, jmp, setSIBLING_RKEY, inFREE + source(138,0x00400400, 0,0,0); // #144 NEW_ROOT => HASH_LEFT # flags = setHASH_LEFT, inNEW_ROOT + source(139,0x00200800, 0,0,0); // #145 ${GetSiblingHash()} => HASH_RIGHT # flags = setHASH_RIGHT, inFREE + source(140,0x00202001, 0,0,0); // #146 $ => NEW_ROOT :HASH0 # flags = hash, setNEW_ROOT, inFREE + source(141,0x00800400, 0,0,0); // #149 OLD_ROOT => HASH_LEFT # flags = setHASH_LEFT, inOLD_ROOT + source(142,0x00204001, 0,0,0); // #150 $ => OLD_ROOT :HASH0 # flags = hash, setOLD_ROOT, inFREE + source(143,0x00208010, 0,0,0); // #153 $ => RKEY :CLIMB_RKEY # flags = climbRkey, setRKEY, inFREE + source(144,0x002200A0, 0,0,0); // #154 $ => SIBLING_RKEY :CLIMB_SIBLING_RKEY, JMP(SIF_ClimbTree) # flags = climbSiblingRkey, jmp, setSIBLING_RKEY, inFREE + source(145,0x00000088, 0,0,0); // #160 :LATCH_SET, JMP(Run) # flags = latchSet, jmp + + // storage_sm_set_insert_not_found.zkasm + + source(146,0x08000400, 0,0,0); // #19 VALUE_LOW => HASH_LEFT # flags = setHASH_LEFT, inVALUE_LOW + source(147,0x10000800, 0,0,0); // #20 VALUE_HIGH => HASH_RIGHT # flags = setHASH_RIGHT, inVALUE_HIGH + source(148,0x00200801, 0,0,0); // #22 $ => HASH_RIGHT :HASH0 # flags = hash, setHASH_RIGHT, inFREE + source(149,0x00208400, 0,0,0); // #25 ${GetRkey()} => RKEY, HASH_LEFT # flags = setHASH_LEFT, setRKEY, inFREE + source(150,0x00202003, 0,0,0); // #26 $ => NEW_ROOT :HASH1 # flags = hash, hashType, setNEW_ROOT, inFREE + source(151,0x00201000, 0,0,0); // #31 ${GetLevel()} => LEVEL # flags = setLEVEL, inFREE + source(152,0x00004000, 0,0,0); // #37 0x0 => OLD_ROOT # flags = setOLD_ROOT + source(153,0x40000100, 0,0,0); // #42 LEVEL :JMPZ(SINF_Latch) # flags = jmpz, inLEVEL + source(154,0x40001000,-1,0,0); // #43 LEVEL - 1 => LEVEL # flags = setLEVEL, inLEVEL + source(155,0x00210100, 0,0,0); // #46 ${GetNextKeyBit()} => RKEY_BIT :JMPZ(SINF_SiblingIsRight3) # flags = jmpz, setRKEY_BIT, inFREE + source(156,0x00200400, 0,0,0); // #51 ${GetSiblingHash()} => HASH_LEFT # flags = setHASH_LEFT, inFREE + source(157,0x00400800, 0,0,0); // #52 NEW_ROOT => HASH_RIGHT # flags = setHASH_RIGHT, inNEW_ROOT + source(158,0x00202001, 0,0,0); // #54 $ => NEW_ROOT :HASH0 # flags = hash, setNEW_ROOT, inFREE + source(159,0x00800800, 0,0,0); // #57 OLD_ROOT => HASH_RIGHT # flags = setHASH_RIGHT, inOLD_ROOT + source(160,0x00204001, 0,0,0); // #58 $ => OLD_ROOT :HASH0 # flags = hash, setOLD_ROOT, inFREE + source(161,0x00208090, 0,0,0); // #61 $ => RKEY :CLIMB_RKEY, JMP(SINF_ClimbTree) # flags = climbRkey, jmp, setRKEY, inFREE + source(162,0x00400400, 0,0,0); // #66 NEW_ROOT => HASH_LEFT # flags = setHASH_LEFT, inNEW_ROOT + source(163,0x00200800, 0,0,0); // #67 ${GetSiblingHash()} => HASH_RIGHT # flags = setHASH_RIGHT, inFREE + source(164,0x00202001, 0,0,0); // #68 $ => NEW_ROOT :HASH0 # flags = hash, setNEW_ROOT, inFREE + source(165,0x00800400, 0,0,0); // #71 OLD_ROOT => HASH_LEFT # flags = setHASH_LEFT, inOLD_ROOT + source(166,0x00204001, 0,0,0); // #72 $ => OLD_ROOT :HASH0 # flags = hash, setOLD_ROOT, inFREE + source(167,0x00208090, 0,0,0); // #75 $ => RKEY :CLIMB_RKEY, JMP(SINF_ClimbTree) # flags = climbRkey, jmp, setRKEY, inFREE + source(168,0x00000088, 0,0,0); // #81 :LATCH_SET, JMP(Run) # flags = latchSet, jmp + + // storage_sm_set_delete_found.zkasm + + source(169,0x00200400, 0,0,0); // #22 ${GetOldValueLow()} => HASH_LEFT # flags = setHASH_LEFT, inFREE + source(170,0x00200800, 0,0,0); // #23 ${GetOldValueHigh()} => HASH_RIGHT # flags = setHASH_RIGHT, inFREE + source(171,0x00200801, 0,0,0); // #24 $ => HASH_RIGHT :HASH0 # flags = hash, setHASH_RIGHT, inFREE + source(172,0x00208400, 0,0,0); // #27 ${GetRkey()} => RKEY, HASH_LEFT # flags = setHASH_LEFT, setRKEY, inFREE + source(173,0x00204003, 0,0,0); // #28 $ => OLD_ROOT :HASH1 # flags = hash, hashType, setOLD_ROOT, inFREE + source(174,0x00200400, 0,0,0); // #32 ${GetSiblingValueLow()} => HASH_LEFT # flags = setHASH_LEFT, inFREE + source(175,0x00200800, 0,0,0); // #33 ${GetSiblingValueHigh()} => HASH_RIGHT # flags = setHASH_RIGHT, inFREE + source(176,0x00240801, 0,0,0); // #34 $ => SIBLING_VALUE_HASH, HASH_RIGHT :HASH0 # flags = hash, setHASH_RIGHT, setSIBLING_VALUE_HASH, inFREE + source(177,0x00220400, 0,0,0); // #37 ${GetSiblingRkey()} => SIBLING_RKEY, HASH_LEFT # flags = setHASH_LEFT, setSIBLING_RKEY, inFREE + source(178,0x00202003, 0,0,0); // #38 $ => NEW_ROOT :HASH1 # flags = hash, hashType, setNEW_ROOT, inFREE + source(179,0x00201000, 0,0,0); // #49 ${GetLevel()} => LEVEL # flags = setLEVEL, inFREE + source(180,0x40001000,-1,0,0); // #56 LEVEL - 1 => LEVEL # flags = setLEVEL, inLEVEL + source(181,0x00210100, 0,0,0); // #59 ${GetNextKeyBit()} => RKEY_BIT :JMPZ(SDF_SiblingIsRight1) # flags = jmpz, setRKEY_BIT, inFREE + source(182,0x00400400, 0,0,0); // #64 NEW_ROOT => HASH_LEFT # flags = setHASH_LEFT, inNEW_ROOT + source(183,0x00800800, 0,0,0); // #65 OLD_ROOT => HASH_RIGHT # flags = setHASH_RIGHT, inOLD_ROOT + source(184,0x00204001, 0,0,0); // #66 $ => OLD_ROOT :HASH0 # flags = hash, setOLD_ROOT, inFREE + source(185,0x00208010, 0,0,0); // #68 $ => RKEY :CLIMB_RKEY # flags = climbRkey, setRKEY, inFREE + source(186,0x002200E0, 0,0,0); // #72 $ => SIBLING_RKEY :CLIMB_SIBLING_RKEY_N, JMP(SDF_ClimbBranch) # flags = climbSiblingRkey, climbBitN, jmp, setSIBLING_RKEY, inFREE + source(187,0x00800400, 0,0,0); // #77 OLD_ROOT => HASH_LEFT # flags = setHASH_LEFT, inOLD_ROOT + source(188,0x00400800, 0,0,0); // #78 NEW_ROOT => HASH_RIGHT # flags = setHASH_RIGHT, inNEW_ROOT + source(189,0x00204001, 0,0,0); // #79 $ => OLD_ROOT :HASH0 # flags = hash, setOLD_ROOT, inFREE + source(190,0x00208010, 0,0,0); // #82 $ => RKEY :CLIMB_RKEY # flags = climbRkey, setRKEY, inFREE + source(191,0x00220060, 0,0,0); // #86 $ => SIBLING_RKEY :CLIMB_SIBLING_RKEY_N # flags = climbSiblingRkey, climbBitN, setSIBLING_RKEY, inFREE + source(192,0x00200100, 0,0,0); // #94 ${GetTopOfBranch()} :JMPZ(SDF_StartNewRoot) # flags = jmpz, inFREE + source(193,0x40001000,-1,0,0); // #96 LEVEL - 1 => LEVEL # flags = setLEVEL, inLEVEL + source(194,0x00210100, 0,0,0); // #99 ${GetNextKeyBit()} => RKEY_BIT :JMPZ(SDF_SiblingIsRight2) # flags = jmpz, setRKEY_BIT, inFREE + source(195,0x00000400, 0,0,0); // #108 0x0 => HASH_LEFT # flags = setHASH_LEFT + source(196,0x00800880, 0,0,0); // #109 OLD_ROOT => HASH_RIGHT :JMP(SDF_SiblingClimbKey2) # flags = jmp, setHASH_RIGHT, inOLD_ROOT + source(197,0x00800400, 0,0,0); // #114 OLD_ROOT => HASH_LEFT # flags = setHASH_LEFT, inOLD_ROOT + source(198,0x00000800, 0,0,0); // #115 0x0 => HASH_RIGHT # flags = setHASH_RIGHT + source(199,0x00204001, 0,0,0); // #118 $ => OLD_ROOT :HASH0 # flags = hash, setOLD_ROOT, inFREE + source(200,0x00208010, 0,0,0); // #120 $ => RKEY :CLIMB_RKEY # flags = climbRkey, setRKEY, inFREE + source(201,0x002200A0, 0,0,0); // #121 $ => SIBLING_RKEY :CLIMB_SIBLING_RKEY, JMP(SDF_ClimbBranch) # flags = climbSiblingRkey, jmp, setSIBLING_RKEY, inFREE + source(202,0x00000400, 0,0,0); // #128 SIBLING_RKEY => HASH_LEFT # flags = setHASH_LEFT + source(203,0x04000800, 0,0,0); // #129 SIBLING_VALUE_HASH => HASH_RIGHT # flags = setHASH_RIGHT, inSIBLING_VALUE_HASH + source(204,0x00202003, 0,0,0); // #130 $ => NEW_ROOT :HASH1 # flags = hash, hashType, setNEW_ROOT, inFREE + source(205,0x40000100, 0,0,0); // #136 LEVEL :JMPZ(SDF_Latch) # flags = jmpz, inLEVEL + source(206,0x40001000,-1,0,0); // #138 LEVEL - 1 => LEVEL # flags = setLEVEL, inLEVEL + source(207,0x00280E00, 0,0,0); // #142 ${GetSiblingHash()} => HASH_LEFT, HASH_RIGHT, VALUE_HIGH :JMPNZ(SDF_SiblingHashIsNotZero) ;VH[0] # flags = jmpnz, setHASH_LEFT, setHASH_RIGHT, setVALUE_HIGH, inFREE + source(208,0x20080200, 0,0,0); // #143 ROTL_VH => VALUE_HIGH :JMPNZ(SDF_SiblingHashIsNotZero) ; VH[3] # flags = jmpnz, setVALUE_HIGH, inROTL_VH + source(209,0x20080200, 0,0,0); // #144 ROTL_VH => VALUE_HIGH :JMPNZ(SDF_SiblingHashIsNotZero) ; VH[2] # flags = jmpnz, setVALUE_HIGH, inROTL_VH + source(210,0x20080200, 0,0,0); // #145 ROTL_VH => VALUE_HIGH :JMPNZ(SDF_SiblingHashIsNotZero) ; VH[1] # flags = jmpnz, setVALUE_HIGH, inROTL_VH + source(211,0x00000080, 0,0,0); // #147 :JMP(AssertFails) # flags = jmp + source(212,0x00080000, 0,0,0); // #150 0 => VALUE_HIGH # flags = setVALUE_HIGH + source(213,0x00210100, 0,0,0); // #154 ${GetNextKeyBit()} => RKEY_BIT :JMPZ(SDF_SiblingIsRight3) # flags = jmpz, setRKEY_BIT, inFREE + source(214,0x00400800, 0,0,0); // #164 NEW_ROOT => HASH_RIGHT # flags = setHASH_RIGHT, inNEW_ROOT + source(215,0x00202001, 0,0,0); // #165 $ => NEW_ROOT :HASH0 # flags = hash, setNEW_ROOT, inFREE + source(216,0x00800800, 0,0,0); // #168 OLD_ROOT => HASH_RIGHT # flags = setHASH_RIGHT, inOLD_ROOT + source(217,0x00204001, 0,0,0); // #169 $ => OLD_ROOT :HASH0 # flags = hash, setOLD_ROOT, inFREE + source(218,0x00208090, 0,0,0); // #172 $ => RKEY :CLIMB_RKEY, JMP(SDF_ClimbTree) # flags = climbRkey, jmp, setRKEY, inFREE + source(219,0x00400400, 0,0,0); // #178 NEW_ROOT => HASH_LEFT # flags = setHASH_LEFT, inNEW_ROOT + source(220,0x00202001, 0,0,0); // #179 $ => NEW_ROOT :HASH0 # flags = hash, setNEW_ROOT, inFREE + source(221,0x00800400, 0,0,0); // #182 OLD_ROOT => HASH_LEFT # flags = setHASH_LEFT, inOLD_ROOT + source(222,0x00204001, 0,0,0); // #183 $ => OLD_ROOT :HASH0 # flags = hash, setOLD_ROOT, inFREE + source(223,0x00208010, 0,0,0); // #186 $ => RKEY :CLIMB_RKEY # flags = climbRkey, setRKEY, inFREE + source(224,0x40000100, 0,0,0); // #194 LEVEL :JMPZ(SDF_Latch) # flags = jmpz, inLEVEL + source(225,0x40001000,-1,0,0); // #195 LEVEL - 1 => LEVEL # flags = setLEVEL, inLEVEL + source(226,0x00210100, 0,0,0); // #198 ${GetNextKeyBit()} => RKEY_BIT :JMPZ(SDF_SiblingIsRight4) # flags = jmpz, setRKEY_BIT, inFREE + source(227,0x00200400, 0,0,0); // #203 ${GetSiblingHash()} => HASH_LEFT # flags = setHASH_LEFT, inFREE + source(228,0x00400800, 0,0,0); // #204 NEW_ROOT => HASH_RIGHT # flags = setHASH_RIGHT, inNEW_ROOT + source(229,0x00202001, 0,0,0); // #205 $ => NEW_ROOT :HASH0 # flags = hash, setNEW_ROOT, inFREE + source(230,0x00800800, 0,0,0); // #208 OLD_ROOT => HASH_RIGHT # flags = setHASH_RIGHT, inOLD_ROOT + source(231,0x00204001, 0,0,0); // #209 $ => OLD_ROOT :HASH0 # flags = hash, setOLD_ROOT, inFREE + source(232,0x00208090, 0,0,0); // #212 $ => RKEY :CLIMB_RKEY, JMP(SDF_ClimbTree) # flags = climbRkey, jmp, setRKEY, inFREE + source(233,0x00400400, 0,0,0); // #217 NEW_ROOT => HASH_LEFT # flags = setHASH_LEFT, inNEW_ROOT + source(234,0x00200800, 0,0,0); // #218 ${GetSiblingHash()} => HASH_RIGHT # flags = setHASH_RIGHT, inFREE + source(235,0x00202001, 0,0,0); // #219 $ => NEW_ROOT :HASH0 # flags = hash, setNEW_ROOT, inFREE + source(236,0x00800400, 0,0,0); // #222 OLD_ROOT => HASH_LEFT # flags = setHASH_LEFT, inOLD_ROOT + source(237,0x00204001, 0,0,0); // #223 $ => OLD_ROOT :HASH0 # flags = hash, setOLD_ROOT, inFREE + source(238,0x00208090, 0,0,0); // #226 $ => RKEY :CLIMB_RKEY, JMP(SDF_ClimbTree) # flags = climbRkey, jmp, setRKEY, inFREE + source(239,0x00000088, 0,0,0); // #232 :LATCH_SET, JMP(Run) # flags = latchSet, jmp + + // storage_sm_set_delete_not_found.zkasm + + source(240,0x00200400, 0,0,0); // #20 ${GetOldValueLow()} => HASH_LEFT # flags = setHASH_LEFT, inFREE + source(241,0x00200800, 0,0,0); // #21 ${GetOldValueHigh()} => HASH_RIGHT # flags = setHASH_RIGHT, inFREE + source(242,0x00200801, 0,0,0); // #22 $ => HASH_RIGHT :HASH0 # flags = hash, setHASH_RIGHT, inFREE + source(243,0x00208400, 0,0,0); // #25 ${GetRkey()} => RKEY, HASH_LEFT # flags = setHASH_LEFT, setRKEY, inFREE + source(244,0x00204003, 0,0,0); // #26 $ => OLD_ROOT :HASH1 # flags = hash, hashType, setOLD_ROOT, inFREE + source(245,0x00201000, 0,0,0); // #31 ${GetLevel()} => LEVEL # flags = setLEVEL, inFREE + source(246,0x00182000, 0,0,0); // #36 0x0 => NEW_ROOT, VALUE_LOW, VALUE_HIGH # flags = setNEW_ROOT, setVALUE_HIGH, setVALUE_LOW + source(247,0x40000100, 0,0,0); // #39 LEVEL :JMPZ(SDNF_Latch) # flags = jmpz, inLEVEL + source(248,0x40001000,-1,0,0); // #40 LEVEL - 1 => LEVEL # flags = setLEVEL, inLEVEL + source(249,0x00200400, 0,0,0); // #45 ${GetSiblingLeftChildHash()} => HASH_LEFT # flags = setHASH_LEFT, inFREE + source(250,0x00200800, 0,0,0); // #46 ${GetSiblingRightChildHash()} => HASH_RIGHT # flags = setHASH_RIGHT, inFREE + source(251,0x00200C01, 0,0,0); // #47 $ => HASH_LEFT, HASH_RIGHT :HASH0 # flags = hash, setHASH_LEFT, setHASH_RIGHT, inFREE + source(252,0x00210100, 0,0,0); // #49 ${GetNextKeyBit()} => RKEY_BIT :JMPZ(SDNF_SiblingIsRight3) # flags = jmpz, setRKEY_BIT, inFREE + source(253,0x00400800, 0,0,0); // #54 NEW_ROOT => HASH_RIGHT # flags = setHASH_RIGHT, inNEW_ROOT + source(254,0x00202001, 0,0,0); // #57 $ => NEW_ROOT :HASH0 # flags = hash, setNEW_ROOT, inFREE + source(255,0x00800800, 0,0,0); // #60 OLD_ROOT => HASH_RIGHT # flags = setHASH_RIGHT, inOLD_ROOT + source(256,0x00204001, 0,0,0); // #61 $ => OLD_ROOT :HASH0 # flags = hash, setOLD_ROOT, inFREE + source(257,0x00208090, 0,0,0); // #64 $ => RKEY :CLIMB_RKEY, JMP(SDNF_ClimbTree) # flags = climbRkey, jmp, setRKEY, inFREE + source(258,0x00400400, 0,0,0); // #70 NEW_ROOT => HASH_LEFT # flags = setHASH_LEFT, inNEW_ROOT + source(259,0x00202001, 0,0,0); // #71 $ => NEW_ROOT :HASH0 # flags = hash, setNEW_ROOT, inFREE + source(260,0x00800400, 0,0,0); // #74 OLD_ROOT => HASH_LEFT # flags = setHASH_LEFT, inOLD_ROOT + source(261,0x00204001, 0,0,0); // #75 $ => OLD_ROOT :HASH0 # flags = hash, setOLD_ROOT, inFREE + source(262,0x00208090, 0,0,0); // #78 $ => RKEY :CLIMB_RKEY, JMP(SDNF_ClimbTree) # flags = climbRkey, jmp, setRKEY, inFREE + source(263,0x40000100, 0,0,0); // #83 LEVEL :JMPZ(SDNF_Latch) # flags = jmpz, inLEVEL + source(264,0x40001000,-1,0,0); // #84 LEVEL - 1 => LEVEL # flags = setLEVEL, inLEVEL + source(265,0x00210100, 0,0,0); // #86 ${GetNextKeyBit()} => RKEY_BIT :JMPZ(SDNF_SiblingIsRight4) # flags = jmpz, setRKEY_BIT, inFREE + source(266,0x00400800, 0,0,0); // #91 NEW_ROOT => HASH_RIGHT # flags = setHASH_RIGHT, inNEW_ROOT + source(267,0x00200400, 0,0,0); // #92 ${GetSiblingHash()} => HASH_LEFT # flags = setHASH_LEFT, inFREE + source(268,0x00202001, 0,0,0); // #93 $ => NEW_ROOT :HASH0 # flags = hash, setNEW_ROOT, inFREE + source(269,0x00800800, 0,0,0); // #96 OLD_ROOT => HASH_RIGHT # flags = setHASH_RIGHT, inOLD_ROOT + source(270,0x00204001, 0,0,0); // #97 $ => OLD_ROOT :HASH0 # flags = hash, setOLD_ROOT, inFREE + source(271,0x00208090, 0,0,0); // #100 $ => RKEY :CLIMB_RKEY, JMP(SDNF_ClimbTree) # flags = climbRkey, jmp, setRKEY, inFREE + source(272,0x00400400, 0,0,0); // #105 NEW_ROOT => HASH_LEFT # flags = setHASH_LEFT, inNEW_ROOT + source(273,0x00200800, 0,0,0); // #106 ${GetSiblingHash()} => HASH_RIGHT # flags = setHASH_RIGHT, inFREE + source(274,0x00202001, 0,0,0); // #107 $ => NEW_ROOT :HASH0 # flags = hash, setNEW_ROOT, inFREE + source(275,0x00800400, 0,0,0); // #110 OLD_ROOT => HASH_LEFT # flags = setHASH_LEFT, inOLD_ROOT + source(276,0x00204001, 0,0,0); // #111 $ => OLD_ROOT :HASH0 # flags = hash, setOLD_ROOT, inFREE + source(277,0x00208090, 0,0,0); // #114 $ => RKEY :CLIMB_RKEY, JMP(SDNF_ClimbTree) # flags = climbRkey, jmp, setRKEY, inFREE + source(278,0x00000088, 0,0,0); // #120 :LATCH_SET, JMP(Run) # flags = latchSet, jmp + + // storage_sm_set_zero_to_zero.zkasm + + source(279,0x00002080, 1,0,0); // #6 1 => NEW_ROOT :JMP(Get_Zero) # flags = jmp, setNEW_ROOT + source(280,0x00802000, 0,0,0); // #10 OLD_ROOT => NEW_ROOT # flags = setNEW_ROOT, inOLD_ROOT + source(281,0x00000088, 0,0,0); // #14 :LATCH_SET, JMP(Run) # flags = latchSet, jmp + + // storage_sm.zkasm + + source(282,0x001FFC00, 0,0,0); // #68 0 => HASH_LEFT, HASH_RIGHT, OLD_ROOT, NEW_ROOT, VALUE_LOW, VALUE_HIGH, SIBLING_VALUE_HASH, RKEY, SIBLING_RKEY, RKEY_BIT, LEVEL # flags = setHASH_LEFT, setHASH_RIGHT, setLEVEL, setNEW_ROOT, setOLD_ROOT, setRKEY, setRKEY_BIT, setSIBLING_RKEY, setSIBLING_VALUE_HASH, setVALUE_HIGH, setVALUE_LOW + source(283,0x00200100, 0,0,0); // #72 ${isAlmostEndPolynomial()} :JMPZ(NotEndPol) # flags = jmpz, inFREE + source(284,0x00000080, 0,0,0); // #75 :JMP(Run) # flags = jmp + source(285,0x00000080, 0,0,0); // #79 :JMP(AssertFails) # flags = jmp + diff --git a/test/pil2/zkevm-etrog/tools.pil b/test/pil2/zkevm-etrog/tools.pil new file mode 100644 index 0000000..ced2560 --- /dev/null +++ b/test/pil2/zkevm-etrog/tools.pil @@ -0,0 +1,16 @@ +include "../std2/std_mset_lookup_range.pil" + +function compact_bin_cols(expr cols[]) { + int factor = 1; + expr res = 0; + if (length(cols) > 63) { + // TODO: ERROR + } + // TODO: REPEATED + for (int i = 0; i < length(cols); ++i) { + res = res + factor * cols[i]; + cols[i] * (1 - cols[i]) === 0; + factor = factor * 2; + } + return res; +} \ No newline at end of file diff --git a/test/pil2/zkevm-etrog/tools/storage_rom_json_to_pil2.js b/test/pil2/zkevm-etrog/tools/storage_rom_json_to_pil2.js new file mode 100644 index 0000000..6530c36 --- /dev/null +++ b/test/pil2/zkevm-etrog/tools/storage_rom_json_to_pil2.js @@ -0,0 +1,94 @@ +const fs = require('fs'); +const { F1Field } = require("ffjavascript"); + +const Fr = new F1Field("0xFFFFFFFF00000001"); + +const INT_MIN = -(2n ** 32n) + 1n; +const INT_MAX = (2n ** 32n) - 1n; + +const ROM_FLAGS = ['hash', 'hashType', 'latchGet', 'latchSet', 'climbRkey', 'climbSiblingRkey', 'climbBitN', + 'jmp', 'jmpz', 'jmpnz', 'setHASH_LEFT', 'setHASH_RIGHT', 'setLEVEL', 'setNEW_ROOT', 'setOLD_ROOT', + 'setRKEY', 'setRKEY_BIT', 'setSIBLING_RKEY', 'setSIBLING_VALUE_HASH', 'setVALUE_HIGH', 'setVALUE_LOW', + 'inFREE', 'inNEW_ROOT', 'inOLD_ROOT', 'inRKEY', 'inRKEY_BIT', 'inSIBLING_VALUE_HASH', + 'inVALUE_LOW', 'inVALUE_HIGH', 'inROTL_VH', 'inLEVEL']; + +function loadStorageRom(StorageRomFile) { + // Init rom from file + const rawdata = fs.readFileSync(StorageRomFile); + const json = JSON.parse(rawdata); + const rom = json.program; + const JMP_ADDRESS_MAX = BigInt(rom.length - 1); + const FLAGS_DIGITS = Math.ceil(ROM_FLAGS.length / 4); + + let data = []; + let previousFileName = false; + for (let line = 0; line < rom.length; line++) { + const l = rom[line]; + + const CONST0 = typeof l.CONST === 'undefined' ? 0n : BigInt(l.CONST); + if (CONST0 && (CONST0 > INT_MAX || CONST0 < INT_MIN)) { + throw new Error(`Invalid value for CONST ${CONST0} on ${l.fileName}:${l.line}`); + } + + const JMP_ADDRESS = typeof l.JMP_ADDRESS === 'undefined' ? 0n : BigInt(l.JMP_ADDRESS); + if (JMP_ADDRESS && (JMP_ADDRESS > JMP_ADDRESS_MAX || JMP_ADDRESS < 0n)) { + throw new Error(`Invalid value for JMP_ADDRESS ${JMP_ADDRESS} on ${l.fileName}:${l.line}`); + } + + const IN_SIBLING_RKEY = typeof l.IN_SIBLING_RKEY === 'undefined' ? 0n : BigInt(l.IN_SIBLING_RKEY); + if (IN_SIBLING_RKEY && (IN_SIBLING_RKEY > INT_MAX || IN_SIBLING_RKEY < INT_MIN)) { + throw new Error(`Invalid value for IN_SIBLING_RKEY ${CONST0} on ${l.fileName}:${l.line}`); + } + + let flags = 0n; + let activeFlags = []; + let factor = 1n; + for (const flag of ROM_FLAGS) { + const bit = typeof l[flag] === 'undefined' ? 0n : BigInt(l[flag]); + if (bit !== 0n && bit !== 1n) { + throw new Error(`Invalid value for ${flag} ${bit} on ${l.fileName}:${l.line}`); + } + if (bit) activeFlags.push(flag); + flags += bit * factor; + factor = factor * 2n; + } + const extraLn = (previousFileName !== false && previousFileName !== l.fileName) ? '\n':''; + previousFileName = l.fileName; + + // [LINE, ROM_FLAGS, CONST0, JMP_ADDRESS, IN_SIBLING_RKEY]); + data.push({values: [line, '0x'+flags.toString(16).toUpperCase().padStart(FLAGS_DIGITS, '0'), CONST0, JMP_ADDRESS, IN_SIBLING_RKEY], source:l.fileName, line: l.line, linestr: l.lineStr.trimEnd(), extraLn, flags: activeFlags.join(', ')}); + } + let widths = data.length ? data[0].values.map(x => 0) : []; + let sourceWidth = 0; + let lineWidth = 0; + let lineStrWidth = 0; + let flagsWidth = 0; + for (let ldata of data) { + ldata.values = ldata.values.map(x => typeof x === 'string' ? x : x.toString()); + widths = widths.map((w, i) => w > ldata.values[i].length ? w : ldata.values[i].length); + sourceWidth = sourceWidth > ldata.source.length ? sourceWidth : ldata.source.length; + const _line = ldata.line.toString(); + lineWidth = lineWidth > _line.length ? lineWidth : _line.length; + lineStrWidth = lineStrWidth > ldata.linestr.length ? lineStrWidth : ldata.linestr.length; + flagsWidth = flagsWidth > ldata.flags.length ? flagsWidth : ldata.flags.length; + } + let lines = ''; + /* + const lineWidth = data.length.toString().length; + for (let index = 0; index < data.length; ++index) { + const ldata = data[index]; + if (ldata.extraLn) lines += '\n'; + const line = index.toString().padStart(lineWidth); + lines += `\t[LINE[${line}], ROM_FLAGS[${line}], CONST0[${line}], JMP_ADDRESS[${line}], IN_SIBLING_RKEY[${line}]] = [` + ldata.values.map((x,i) => x.padStart(widths[i])).join() + ']; // ' + ldata.source.padEnd(sourceWidth) + ' ' + ldata.linestr + '\n'; + } + */ + const twidths = widths.reduce((t,x) => t+x, 0) + 10 + widths.length - 1; + for (let index = 0; index < data.length; ++index) { + const ldata = data[index]; + if (ldata.extraLn) lines += '\n\t'+' '.repeat(twidths) + '// '+ ldata.source + '\n\n'; + lines += `\tsource(` + ldata.values.map((x,i) => x.padStart(widths[i])).join() + '); // #' + ldata.line.toString().padEnd(lineWidth) + ' ' + ldata.linestr.padEnd(lineStrWidth) + ' # flags = ' + ldata.flags + '\n'; + } + console.log(lines); +} + +loadStorageRom(__dirname + '/storage_rom.json'); diff --git a/tools/benchmark/sequence1.js b/tools/benchmark/sequence1.js new file mode 100644 index 0000000..b1c1e49 --- /dev/null +++ b/tools/benchmark/sequence1.js @@ -0,0 +1,4 @@ +let __values = []; +for(let _i1=0n;_i1<=255n;_i1=_i1+1n){__values.push(_i1)} +for(let _i2=0;_i2<16383;++_i2) { __values = __values.concat(__values.slice(-256)); } +console.log(__values.length); diff --git a/tools/benchmark/sequence2.js b/tools/benchmark/sequence2.js new file mode 100644 index 0000000..7a2d325 --- /dev/null +++ b/tools/benchmark/sequence2.js @@ -0,0 +1,6 @@ +let __values = []; +for(let _i1=0n;_i1<=255n;_i1=_i1+1n){__values.push(_i1)} +let __values1 = [...__values]; +// for(let _i2=0;_i2<16383;++_i2) { __values = __values.concat(__values1); } +for(let _i2=0;_i2<8000;++_i2) { __values = __values.concat(__values1); } +console.log(__values.length); diff --git a/tools/benchmark/sequence3.js b/tools/benchmark/sequence3.js new file mode 100644 index 0000000..5bf0ec4 --- /dev/null +++ b/tools/benchmark/sequence3.js @@ -0,0 +1,4 @@ +let __values = []; +for(let _i1=0n;_i1<=255n;_i1=_i1+1n){__values.push(_i1)}; +for(let _i2=0;_i2<8000;++_i2) { for(let _i1=0n;_i1<=255n;_i1=_i1+1n){__values.push(_i1)} } +// console.log(__values.join()); diff --git a/tools/benchmark/sequence4.js b/tools/benchmark/sequence4.js new file mode 100644 index 0000000..7f7104a --- /dev/null +++ b/tools/benchmark/sequence4.js @@ -0,0 +1,4 @@ +let __values = []; +for(let _i1=0n;_i1<=255n;_i1=_i1+1n){__values.push(_i1)} +for(let _i2=0;_i2<8000;++_i2) {let base = __values.length - 256; for(let _i1=0;_i1<=255;_i1=_i1+1){__values.push(__values[base+_i1])}} +// console.log(__values.join()); diff --git a/tools/benchmark/sequence5.js b/tools/benchmark/sequence5.js new file mode 100644 index 0000000..247fdb6 --- /dev/null +++ b/tools/benchmark/sequence5.js @@ -0,0 +1,5 @@ +let __values = []; +for(let _i1=0n;_i1<=255n;_i1=_i1+1n){__values.push(_i1)} +let base = __values.length - 256 +for(let _i2=0;_i2<2048000;++_i2) {__values.push(__values[(base+_i2)%255])} +// console.log(__values.join()); diff --git a/tools/benchmark/sequence6.js b/tools/benchmark/sequence6.js new file mode 100644 index 0000000..51d3009 --- /dev/null +++ b/tools/benchmark/sequence6.js @@ -0,0 +1,4 @@ +let __values = []; +for(let _i1=0n;_i1<=255n;_i1=_i1+1n){__values.push(_i1)} +for(let _i2=0;_i2<2048000;++_i2) {__values.push(__values[__values.length - 256])} +// console.log(__values.join()); diff --git a/tools/eval.js b/tools/eval.js new file mode 100644 index 0000000..6f05e1f --- /dev/null +++ b/tools/eval.js @@ -0,0 +1,16 @@ +const vm = require('vm'); + +class C { + runme() { + let a = 10; + let values = []; + console.log('Hi'); + const context = {values} + vm.createContext(context); + console.log(vm.runInContext('values.push(63)', context)); + console.log(values); + } +} + +let c = new C(); +c.runme(); \ No newline at end of file diff --git a/tools/sm/sm_climb_key/compact.js b/tools/sm/sm_climb_key/compact.js new file mode 100644 index 0000000..6b079a2 --- /dev/null +++ b/tools/sm/sm_climb_key/compact.js @@ -0,0 +1,70 @@ +#!/usr/bin/env node + +const path = require("path"); +const fs = require("fs"); +const tty = require('tty'); + +const argv = require("yargs") + .usage("table") + .alias("v", "verbose") + .alias("c", "clt") + .alias("m", "mask") + .argv; +function log2(value) { + let limit = 2n; + let bits = 1; + while (value >= limit) { + limit = limit * 2n; + ++bits; + } + return bits; +} + +async function run() { + let total = 0n; + let tlevel = 0n; + let loops = 0; + let _level = 255; + let level; + let bits = 26; + let mask = 2n ** BigInt(bits) - 1n; + for (let lchunk = 0; lchunk < 16; ++lchunk) { + ++loops; + level = (lchunk << 4); + let values = (2n**BigInt(255 - level) & mask)+1n; + tlevel = tlevel + values; + console.log(`${level} ${loops} ${tlevel.toString(16)} ${log2(tlevel)}`); + } + _level = level; + console.log([tlevel, log2(tlevel), loops]); + return; + total += tlevel; + loops = 0; + tlevel = 0n; + for (level = _level; level >= 207; --level) { + ++loops; + let values = 2n**BigInt((_level - level) >> 2); + tlevel = tlevel + values; + console.log(`${level} ${loops} ${tlevel.toString(16)} ${log2(tlevel)}`); + } + _level = level; + console.log([tlevel, log2(tlevel), loops]); + total += tlevel; + loops = 0; + tlevel = 0n; + for (level = _level; level >= 0; --level) { + ++loops; + let values = 2n**BigInt((_level - level) >> 2); + tlevel = tlevel + values; + console.log(`${level} ${loops} ${tlevel.toString(16)} ${log2(tlevel)}`); + } +} + + +run().then(()=> { + process.exitCode = 0; +}, (err) => { + console.log(err.stack); + console.log(err.message); + process.exitCode = 1; +}); diff --git a/tools/sm/sm_climb_key/table.js b/tools/sm/sm_climb_key/table.js new file mode 100644 index 0000000..62ec108 --- /dev/null +++ b/tools/sm/sm_climb_key/table.js @@ -0,0 +1,99 @@ +#!/usr/bin/env node + +const path = require("path"); +const fs = require("fs"); +const tty = require('tty'); +const assert = require('chai').assert; + +const argv = require("yargs") + .usage("table") + .alias("v", "verbose") + .alias("c", "clt") + .alias("m", "mask") + .argv; + +function log2(value) { + value = BigInt(value); + let limit = 2n; + let bits = 1; + while (value >= limit) { + limit = limit * 2n; + ++bits; + } + return bits; +} + +async function run() { + + const cins = [[0,1],[0,1,2,3],[0,1,2,3],[0,1,2,3]]; + const masks = [0x3FFFF, 0x1FFFF, 0x1FFFF, 0x00FFF]; + const gls = [0x00001, 0x1C000, 0x1FFFF, 0x00FFF]; + + assert(64 === masks.reduce((t, x) => t+log2(x), 0)); + assert(0xFFFFFFFF00000001n === gls.reduce((t, x, i) => t + (BigInt(x) << BigInt(masks.slice(0, i).reduce((bits, mask) => bits += log2(mask), 0))), 0n)); + + let ranges = []; + let clt = false; + let carry, lt; + + for (let index = 0; index < masks.length; ++index) { + const _gl = gls[index]; + const _glhex = _gl.toString(16).toUpperCase().padStart(5, '0'); + const _mask = masks[index]; + for (const cin of cins[index]) { + let tcount = 0; + const _lt = cin >= 2 ? 1:0; + const _carry = cin % 2 ? 1:0; + for (let value = 0; value <= (_mask+1); ++value) { + const value_ = value * 2 + _carry; + const vmask_ = value_ & _mask; + const carry_ = value_ > _mask ? 1:0; + const lt_ = (vmask_ < _gl || (vmask_ == _gl && _lt)) ? 1:0; + const clt_ = lt_ * 2 + carry_; + + if (clt === false) { + from = value; + clt = clt_; + carry = carry_; + lt = lt_; + } else if (clt !== clt_ || value > _mask) { + const to = value - 1; + const fromUp = from * 2 + _carry; + const toUp = to * 2 + _carry; + const count = to - from + 1; + tcount += count; + const ranges = [[from, to],[fromUp, toUp],[fromUp & _mask, toUp & _mask]].map( + ft => (ft[0].toString(16).toUpperCase().padStart(5, '0') + + (ft[0] == ft[1] ? '' : '..'+ft[1].toString(16).toUpperCase().padStart(5, '0'))).padEnd(12)); + console.log(`// ${index} │ ${cin} │ 0 │ ${ranges[0]} │ ${ranges[1]} │ ${carry} │ ${ranges[2]} │ ${lt} │ ${_glhex} │ ${clt} │ ${count.toString(10).padStart(6)} │ ${to == _mask ? tcount.toString(10).padStart(6):''}`); + from = value; + clt = (value > _mask) ? false : clt_; + carry = carry_; + lt = lt_; + } + } + clt = false; + console.log('// ┄┄┄┄│┄┄┄┄│┄┄┄│┄┄┄┄┄┄┄┄┄┄┄┄┄┄│┄┄┄┄┄┄┄┄┄┄┄┄┄┄│┄┄┄│┄┄┄┄┄┄┄┄┄┄┄┄┄┄│┄┄┄┄│┄┄┄┄┄┄┄│┄┄┄┄│┄┄┄┄┄┄┄┄│┄┄┄┄┄┄┄┄'); + } + } +/* + console.log("Input Pol Commitmets: " + out.nCommitments); + console.log("Q Pol Commitmets: " + out.nQ); + console.log("Constant Pols: " + out.nConstants); + console.log("Im Pols: " + out.nIm); + console.log("plookupIdentities: " + out.plookupIdentities.length); + console.log("permutationIdentities: " + out.permutationIdentities.length); + console.log("connectionIdentities: " + out.connectionIdentities.length); + console.log("polIdentities: " + out.polIdentities.length); +*/ + // await fs.promises.writeFile(outputFile.trim(), JSON.stringify(out, null, 1) + "\n", "utf8"); +} + + +run().then(()=> { + process.exitCode = 0; +}, (err) => { + console.log(err.stack); + console.log(err.message); + process.exitCode = 1; +});