From faad26c7b7866fe5dee4add690e08898873a8215 Mon Sep 17 00:00:00 2001 From: miettinen Date: Mon, 27 Jan 2014 10:07:38 +0000 Subject: [PATCH] Unit validation for functions in Sysdyn: unit definitions for built-in functions and propagation of available functions (also user-defined) information within the unit parser (refs #4320). git-svn-id: https://www.simantics.org/svn/simantics/sysdyn/trunk@28714 ac1ea38d-2e2b-0410-8846-a27921b304fc --- org.simantics.sysdyn.ontology/graph.tg | Bin 165463 -> 174006 bytes .../graph/ModelicaArrayFunctions.pgraph | 47 ++++++++ .../graph/ModelicaFunctions.pgraph | 78 ++++++++++++ .../graph/Sysdyn.pgraph | 1 + .../graph/SysdynFunctions.pgraph | 18 +++ .../graph/VensimFunctions.pgraph | 50 ++++++++ .../org/simantics/sysdyn/SysdynResource.java | 6 + .../properties/widgets/ShortcutTabWidget.java | 32 ++++- .../expressions/CompletionProcessor.java | 4 +- .../sysdyn/ui/utils/NameValidator.java | 2 +- .../sysdyn/ui/validation/UnitFunction.java | 10 +- .../src/org/simantics/sysdyn/TestParser.java | 3 +- .../representation/utils/UnitUtils.java | 15 ++- .../sysdyn/unitParser/UnitCheckingNode.java | 6 +- .../sysdyn/unitParser/nodes/AddOp.java | 6 +- .../sysdyn/unitParser/nodes/Arithmetic.java | 8 +- .../unitParser/nodes/ArrayDefinition.java | 7 +- .../nodes/ComponentReferenceFull.java | 10 +- .../sysdyn/unitParser/nodes/Divide.java | 6 +- .../sysdyn/unitParser/nodes/Factor.java | 8 +- .../sysdyn/unitParser/nodes/ForIndex.java | 4 +- .../sysdyn/unitParser/nodes/FunctionCall.java | 4 +- .../sysdyn/unitParser/nodes/IfThenElse.java | 6 +- .../unitParser/nodes/Multiplication.java | 6 +- .../sysdyn/unitParser/nodes/Power.java | 6 +- .../sysdyn/unitParser/nodes/RelOp.java | 6 +- .../sysdyn/unitParser/nodes/Relation.java | 8 +- .../sysdyn/unitParser/nodes/Term.java | 6 +- .../sysdyn/unitParser/nodes/Value.java | 6 +- .../org/simantics/sysdyn/utils}/Function.java | 111 ++++++------------ 30 files changed, 354 insertions(+), 126 deletions(-) rename {org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/expressions => org.simantics.sysdyn/src/org/simantics/sysdyn/utils}/Function.java (72%) diff --git a/org.simantics.sysdyn.ontology/graph.tg b/org.simantics.sysdyn.ontology/graph.tg index afa595a6e4d2dfbdce0ff3b4c4f8fb787af6c971..130ecefff6f26226ed31a108d800b43ac917dda6 100644 GIT binary patch literal 174006 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 literal 165463 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 z zeQ-VBY5ISgYIbYMKUn=| zKSlZ{_@n-514sVJ>i-yLkNp48_`eqR>q`8C5?>Qo*6a66j6SLV>`M4!AFsxFEU&TlJaccT4mobP zcUC{9#A6+2rxg1c=Q{Mt@^3R)Zk6nqOOc-KwR+As%bf3)xj$Owe7DT?Z5eAR;*(2! zN{P81ZTZtn%(ZXr*asp$x5Vd{7<*5ozo^96+amiVCBC%8mzDT($Nu_@y`BC%UsvKE zl$d+9)no6BxM;ukhrKhhWABU@dt1cCc=+<%4{d$L_<1|_w#Z(Lx3?Gb!Sk^teKDWB zo%@@u4||PpaXpvy1AB6EF~6~Q(e4@7(unVfng6z#we#O@i}Sw-c!{4VG0y%`|9)HIXG;8s691{h&zJbc692u#uax+o;Kf+q zdLEq$#vF{e8JO>f`ES})H^DXG45!Vy@%-u2xSk{^b};h5zC5o7U54p@q2USOPQ$bx z3jdqI|CvrJto1=lR{zzF9H&^9jVF*sUD+YQF6VI3`wP*?W(U>AP}8D@P48fO0vF!ezzto1=lj_L#Z`cPN4zlk@?gHqF0L7krC-J20{?9Ya@tA9v_Bm!epcU5ffR?QOW&FW@JWy9Q zJJ@CX_cqM>_A<=+W|{h+71sKoB}esveSN4a+tc));{#T`jQ<{nS>Ntv{6FW|k3YtO zc0c|oD|#J&_!hg4KgJ?r#3Ev}RoIUA%u;)1lz4hz8E>#3Z)mgKOn*5)!BKyw8D_k9 zHO&6+5?IC$?DrRxrQO$uvf0i-&-YE)PKN34vw_7Q*!x3S+Py!N%|2t=&v=8Q_U~wz z{&zrmU9adX*^d`uN%rG~vZB}Vf^V_wcp;V%qpuO8t-^M^wlB2@zI=PxKJ4|%GG1Wc zUud&!O@Fyw!K#<}`6+)u#TABoq;4AVcZ zjedS0wq!p)Fm_}=KTuZmIzQlB>^eU%b`cl;{dpICkL+l>u$?cPmfDB0@$IL-jRVVk z0sH<#o8cPn`_KIs?8}b^Z)lkFV*|tVkG`p1;tlrkMp@c@eJGo)7xXfIQw-DJx`D+X z*!x3S+Py!N&DIHe@i*Bp{Y?ri{=nWJ%F^!rp=`Fci3j(4u=Y>p!$iaMzZS~teu3DL z{d~aKko|l>S<&l!fN!zue8AX53|++Nd&FqFu$>QUqP{T|_x_#!*C;W@FtU#?@wgI? zEirsYVl>B>8W=`tKFqa9lwf_`XZ+-XHo# zy{@l@>NQ@7RaT?F;{Fk7vhQDES8kkC*tNd4f{XU2bHTashcsEs^ZN+P;*WOgk8J&+ zQ@+2iqdYrV=;i!F*7&i%R6ZUh!6j*Vg4Jz8ea}o`k@(**BtA3s9p8^{)T#OUqkg~ zJks}JFUEsfvXAG?67TNV$7?^w8jtjYm>DneZ{j6f^jGTpFEsC>i!MUM3F?Rhs>R@aBtsp~C0z}d^}+sC@!3I4dA(*KnBZSa=( zvjfKIdDy|VZO|VKPP)D03eFYn*t=Mkc8y{LO1s7nWrcNq?HaShk9v(C>Zabu5A8~^NBQ}~_M)vk8ON0_>=g(P~yLWZT!GKeu!I2yT%V?g>C$3xA7xyTC88xO}&pF+MZ&M z@cmeg7%cFY$Y> z#D4_a_f;zb)}oV2vlVDcFzCW{&l|z_!rt8Fi6;{LwG5k3f|ZkS^^0JfY?7_|l&p zU$UJqWSt*qJN^6f$j;#3gz^%+~0aQ^x!85+g6tKL#%1 zopwS0Ft`|x#`nPwmiXS1{_eoCo_-3}`EduzlXX1D6|Cbu2YkCZ55DSH>*xIg?dp&B zzrx$O=fw@`Z!_gzaU7M0-IwQlB5Qf-Z#Cur;W#P}dsLpR<*C2Ll;^bt9F->*@sRkC zwLJAVoASJ#fK{LVq+lCA+O@pui+D=BZlXVTf5-28_($85GTvkzpW_SG@t+I6(X@xx zAF!4e|76=AvbKl%ADi+oIgZN19+f9+dFpQf7waoM4}5)ze+1TeOosi3CBDwo|03*Q zUmx{kEzkK#*7{X%<9V&|$Ll3H@<+D*$m&n^*5ChQ@4Un7Dz3GEii#_}1VYG;2q4?C znlZ&-z!*cE(1HyKaR@nAfc;gpiQld+)v9-1K(SzV}@- zYi7+@A{dhUe1BX$k8J(+TC>)gHD%A9z0W?cgM2B99O`U!SVkAkmq)AQa`e-A6e_C`nG1}FB&)*e~yslK)M zN@I`bZ*XFdZ0(WNp6XkBuQ2v_{skxY$krZN?Ww-C_j1U!J)zrS8L=dcx+aWV3fuNZ z`Ow}cICJ^AnfkFmyfovNnEZSfa&VF#vds_K+h3^qHa{;m z_PAaGC-%tJ9$D?FzO{Ef$xsZE(Ssz@N@pFv7Z@@k{_~UwlZ2ghdpXytG&o=hHj`HBd9@*L>pXApAs&DP# z9FpYcna2LtU>_Xp^L#_L_Q`5r^{xG97<*qud2q1D`jf3avf5L9YwzjC-d9i_toFD+ zFKq2muJ%-4?HvUDr$Mgc;UVCsX8aVex7V=*@@w(C2`^&!d%YkjHzaAW_i z8NV&#w`Y8VXB!XgX?;|#tmT!}zOwfp_Nz~ZebhPh*Uvjn>IeB=to21KEFbEx?ENjI zJ+xVf_X!yzcZr<&r@r=woK;`j@1f9tu!;Y3jzheMdG_(j`3CwL51(=BxW@Q{OxWfd z@{q3;kUz-y`>f-{ALN>k>W92s^FjSR#vgQrtv|}Oy}Ug5Uk3fFjsMR$R)11I$aVa6 zZ1HmSuljcU%|?Bh&&Vo21?6X=zYfUADwpdk!zIpFWbGeAp0z$&UguxNw>$Gsw*Ge+ z|B!WnRWAMwi+{59Pgeh0-uj=0T<5DpVSg(6Tli_mYEQ1mArJZod%3qC^fms&Aa9%b z>UhVYf5R5#$$UfBc)dKd|8dZtgxuG!bd+aXAIiOd$ z$yT3i^_wQYpF;fLP@f^szP$8D$~C{Lul6p3{wkZgA2s$q;yAGfd18;O_EcZ(aXfA{_CD-b?aB2N5gPwGpy^(Cu4)wlK@80E}ehh@|)VZ@d&Yzu4q(d* zFU$uEj)i@&o)2XFJiy5B4mmiHUvA_aZ{S3ZHV*mtAmre%-t!##JKOJmM*acENxmW1 ze9QWRtoc@bpKsYeh0Wma{jdjCe=1MxQ?B-?f2pb8-7@ZRto5z_5BL(4_v5w9e3EVd zAZvd(AM(v6zV|uS@^XHKJSk7s_*CE4cN65=-q7u^4Bx`O{Uu(?y*j|U+Se{rn+ zm-mV~?t%EQt_#n*fVDpIybHKv9S+^e{oiqJRv*i(k7d@!GV5cR^|8$QSY~~|Nqs2y z_30=(d8iNP+YM%Yy4JDwpN@}#&qjHzFKm&M`hr7!ecjc*=0M|-=TDHEpzq5DduKs* zMzk;UJNiJW5BWaY$=D|}K6zfr@@nW9mggbB9cQBa!T6uP!FvC+dMy}r*8a=BpD_BS zu#V@PRev$;-yL?2gg$bu^w$@SZbhB=?1&xH1Rw_~lJ=tCaLvk#FqKdP_w!#L?U!PvXW zajZEN+;8&nPRE)LIp0Gb%CmlC?{A^%ABgdewTG-5Ujcoa&*hoEVbKRC{tc@< z)Q97Navx6z=M%$Kp5K;b{(Ce3hQ&TO@o!k=!9V7`4$7_n<1>H9W&R9{J#gaBu*!qK z{os#s>kn(xFrME5IatTD^e?i`&&&^5`y=(S=2zz0J>kndFGU>=#osxrzK=)FU+mZF zkJl4qZGVmjvhV*LIOlcT&BT9$V=XV^3G$>oS>soIJDv(-@9nS$PVA9wJY=<}`qm!S z%pt#TgFSF!k8JIc)t>5Gdq*34Z-qT@us7t{+M`_UslK&`HdQ&>mSZ3=a-A@8mvE6W zVo&7oEv)UIv+Ao{?J282WsOH!qoiuhdDvz;*V_ofrG!-qb%j>kIZwLtshwJi9gD%KiF2e_#<0?_&fM}9m-O! z{>VJ%Sbt!(C;lk6{?J!dF8;{YA2|4XEy_}^{>Yf~wY>DF|1_gdCjS22ydcXTIQV1# zpxovU<3#0>KeEjqIOOj&C`-BKkK7r{cXWX(vAjI5S&l5%?_{(ApVyWB6>yc?yZ=Pl zDt^iT!1w}JKkfN%_#3~pUHyBsNBdkuX}q*AZ0wVReW(f>`@-HnZCC${U(X9)j*TCH@8{_Q>XZByzQ<`qthbjlEakZ*Z`Ou_0{jQLgq>U+rP+ zR{vn+FLxa3?^*N9>le{SpOyOu_W}PNznZU?Io5cnOLn^3{Xm%=a&& ze)Yc{SAXUDfAtq&{Hi^^zqI;uu#czuWAM*1{%O>g{`o_5J%aIA1&8uK%9!@7{3qZa z7<g^?Sbj_rZ+u%brm-VcLc~tp7V5hwBB_4f2q`FL?IxOWi+f}-&wxJ_nftxfPZ}Nqe+aJlAZ`IfS$oBb& zvG+p9i9N^@dt|kz`qtiujlCD(Z*XFdY~v%VJ=M4NK4|PcAAf_B{zcaL{zG1__Ne~> zQ~r65RbTQ2c@hs<%d5VP=l#asbMZGgu}8M`Bda~txAxv=>|KYy!NDHepKR@s)t>5G zd$$;S&%xi|#2(q&Bda~txAxv^>^&QQgA;pXYmcnpD&p!=ucVWQ`Y#EwSLN4e`U>&vgS`& z^Q)}+S7!UXE5^g;LlZtCW325HIr1i~{e$!KjV7PC9;v=F<9C3)e)a8;-;nX!GJZ>B znQz{NGH=CtfNL4(RxQI;!tg~7{@(2Qc$B{@{)X-98>3w8zrrx<^K$$?$)Eq8>^Rta zf|vXEjaFX-ei_R9{K~WDmS2#`pXb?+7e31^<&{-m`GsEY`z!aesxOW4@_n<_ml%Eo z_{A}vD(WVz`M(ByJwDU#->=#IPsbWRZBrf?wuQ6u`aV6$74(%CpeS>q^FhbcGk!+K zoKLL&voq%WO1ZCp$3q;4@j96Ckk{At(DKS^Us?StYkbNYzh}0U#G{N{C(K;1&9wjU zd;?DU59Q{4wN>zHJY%=3DAwxce`V zp-y4^zcb?-Gk#abH)Z^8&pQ4YAMN|`$IqrFtmRd%_LbGYvc~6`ZDH-P?&R=%$|)JM zKU^L2BkeH@?!)=!XeXr$#V~}5*jJkV0_keM3@5VZyx*hu3-e`-2k-LOZ zcVQpDT#wd`zahv+GaiXtUI{t4d>rz_xdgh^t)=ijv+mzI*7}wX0N0|NfAcqyKhQA! zUjh5eVIT86Z3{mf%()h^lJ)cURg@L^-5|%jDE2AWd>~fQ_w_B`75o6mwf^*XdB*pT zEcFG4`a-w5CDy0=H;#in*7ts~JfBafUS^p7?i-o!MSm0FODqv1c!V=w|Z|= zzh5~{>UU8rFZsOCF!OmqWXUHuze2HB1iMl6@*o199@0t1EnDIR#OFqG&e$cI+YwGt)$4ULpiRC4q8w@j_ zXGfNNf!5+$1ksE!#WcSY;2m73#PK@@XJyxT871&91Ymt5BT z!?wsZ|Hxg!s9VB_P1v@_37P*@84pL6_5p|bLAQ#Wg!=u|aZlm~w(Tg5pq`1^_D#9v>uC;41~@|sWjBWwRg-N_-pC@XT!FMNqy^NYGCjM#*2 zKH)3GLx0OM?u{(@1c&-Tw|cy(-;W&!d+aahtAW|yk2OqxcaJRj1c!X0Eakx;%2tmt z{(j^**r&gqXixHq+=P50)+$-^iMo?RK2cWWnosx=x#kmfPZ+TY+k6(8f2!>vvQvFa7h*hH3xE$dXTR$S2BD9{izf^$6qd2aXeecZ&8T zpNFHo_D{rGC2Kwl$0466D{{>ze38TY3UyByu?gFJ9+vq>9}4lYzK2AXe1b#$*xwE| z_4~f#P@efbD3+Ie9%z{Mp`-eePjJX5%2FQup=@>ks4w>RGfaC+Ba1z7u!pjg2YV=6 zT@v-h-eSYFw1*w%2D@(5xcPM4_#S&of&sTmi_<^^@nb?YU=-O$4UJwvApEF zY?%25s=nkK81jv>lm~w(Tlr_yr@hKQ48vaK?~!SbtoB$|81o>nmsqy)HxvIi9cw&n zzsg^uJ+@!ve_&7B55Wm*`yrQPZ9kS3xoRBQWVTNQ ztofpDNABmVAOkK2etP;16Xhzl-`}@3)3&?>CXf9yr)T zS;~Vwl&$>Q#Q!zNN<x_N0CO8|8ibu|)hi>KjCjKuwPU8Pw zEHC-`u3_d2bF%77zQ7@0C`)v-q< z01o+wuE=%%r9H|u|Hxg!>|a)n*o19+d?xe%>B!O^;7}jvRz79w!+5|+eLiWJ?ePi2 ztl!5YOa8zie<(|N@Q1RMk41fHkB=Iry^ll|d*EOXWhoE#P`2`66F=(%PU8QNVcP#7 z%4>U|uH?`j&=tA12W*L4+XJ~v7beRE{VCphF2WhoE-P`2_Wlm~w(TX}`?$N2-C_XhFSj?nEJ!Eu+|^3l0*Gb zR^(cL+NWIWk649meV?ECdtS!RjV$#Ahx$Uda$T%XH|J|`QlIA-X8(D%VbY5#F1pNLIZ^NG5XLq1Vf|7P;mVbx#+*6TO23#*%Ql4 z{;oF6{LMy|{DDLMP?qxG4`nMeQD5xsHcWfFB8xq6u!pjg2YV=6nKtpi$8i$>RJ14U z(MI{@$Upls>Rthd{6m)bti}X zqO8cZf5Vr^HNU8P!iY`S=5t5pe|u!fA2`$px|MCFJ~uf|>Qj&9C4ZxanZJ?9l0R_B zAIef5{Gn`RYt$EeHN&*`z{p|`9PFVi<-s1xR<4NpV($TlY47sLVh@j+6SG741v^TW6U0JTtQ76CCo1 zvK8`i=nqf9-zZx-!}xoP)DG&Zo zwz4|vi@g&J)84AcVhK7_kZ4eBL?pe`Ll- zM3#JlL;avzxs$2iYaA!_J3N+`{&|>T<`X$qeaR;{#C#qc z?MXflLV3+6Vy%!hpQt-Ix|RJ+ zeO~2Q^`$=h#qyHBrG}ZmC6Oh6;E+F*r9AjU*~(($@0E@de~Y3$iGLx=YyJ>x1sw7P zU2<5@!nVjYUu+NRD$)uZ-7aygK6*8FPGE`|MwqyHn<~1Xj*_ z*$MwB<8NmC*^ED!@jEl-{BGjmUTnfI$oT0QKQ7~kWZcfUk@5X9z9{2!GsapciEl7t z%>9WRb63I`I|-w&2y6e~{Dw9O{geH@E3(W-;LyL>ex0U&zrt}S&;HmE%gcDG8m9e9 zWEoH3FrHAB^573;D`n&F<&G17Fc%p1%m2i$jwi%Q4&w=bid^R(*cQ2tAJ&!n%8Z4q z`MN9kACWnJ%YTo|e33PN>X!dz;zxfYt3A#?<-Z!{T#PXhwHGrBKP^0+)-bdb+ydc$hJLx8(IASCbF~#IMfHat~V0-%le;zQ7@V=$3zC;(w82wI})daV#(S!kiuC%-0ViOTNG%Unom?@Q1SH z9~gfxbR6t4U*C`RB>wN=*mCs$r{RCZS_X%FL6;oz1=}Lm{IIUnS7t0^o3HOi7JuJ~ zEcpV5_@P_=wu%1*j@6#z>sztBO=IwP;V` z|0;AeUx>8~4*7yEIphnrMXvc_U8%3kSjaYCUx_UKz8qQd1rG5;xBMj&|MMKHJ;~P> zV|mHf7Ys9BpN}m00*8E|Eakx;%9cN8{5{uk;_tK3p2Ytd=xDwWYZ)B!1zmE;7i^1M z^TWDQUzxFxZN5GoS^Rw}vg8XK;)ibelP3P_9IHLa*C%3m$=AmXGhZKzEcpV5e4#Am z!5_+&KWh9v$8qBCBhjA3|6%B8z7T5}9P$NSa>y5Ki(K==x>8@6v5;-PJ``E}eK6w> zM3(%4Lw%rIe!r>DvmL8_$=~~8dCA``hMB+jMwa}6L;g^f^573;%kPQ$V((_dwD<1F zVhiq19PFVi<-s1xmfvae@eIdFKHd@SNxpA@j}1;?-X2-vds}2_e{iTT zbjxow^?kZywI}WWmRMf$`)0$;@0%h^e!(HXC`)YJI z$=@ptGk>p$EcpY6{Glx6!5_+&UvB(8#c|^AWznA0=cUlm{2|sdS^FpIP7e7*S&?i1 zgfEe6{#bYFD>F8-&F4!Zi~kpAe0^leCpgp(y5$#{`f-ea)xPBOg@&2G7i9eWjByU_ zKCx6~hdwy5hjU)wLm|J;Fzs`W@5Oj!+w%NKJ`T*>Lzf)#f!Gp8YzZSaVa?b5 z9G5SLJ&rxZR(`he&v>3?nDIO_vh){lh!15c5AmUF8S_x6|C1bt`W^s=-@vrbF{%9p zxfj;{g0>}x{=%54ul)tSM6Uhg`iz-7mRC7rC2KzJ3PzrlrT-w$38POaOaEaX(e_}Q zJlWLuagJ4A`VVptnDu>P#!tu?eJ14ZQP2m6^2{H61U?k}Si`jc82oDgVLW7w7rNw- z54MkG#Fj8(6V`mO|InWHANKD@n|Ns-9O7fVs6$}J_elI|dn0$k+TLgja%gYXpZeO~ zuq|?JPqqd1l^GjZ<7N9kBC@nEd{zJEe&w7A4(}sld}Lp~V~b~RKjt~Sj6GHaOjXYi~2 z1-io8U!Y44`9*9ABesMQo3Q4e{e||mzaX~qZWAxshMdH^%P`}c#;^7lz9bV!eK?-LYESw{%`ofpz>KfR_yNWq`feGV z*hAZd`HkmGaCjf*L7w-={B;bDbAG1W*I(8I_c!*~o|prJea44Ap!zH;yc8cdPkqeP)d$2#!KKx4T$VK_SCO;hC;1ECSdmqEB z&!za){)4t5hyDXyk!$~fEs<+~VOvvQnX!;HKK7SOB1?bS99jAcIP@3jmN%LBIlq9_ zp0wA+hMDtw8)khjiY)mDhy0@~<-s4ymM@I@a=mbYVcI)Cve*L$dnikJu!pkc^Gy64 zkKiQ!dl{zvd*WB~kGhgW{-G;!%|C33T=UJ`QD2#Lv&`7YwmmjRmiD+uWN8m@s1J0@ z=bHLlrM4*5b^%7Z_YEw3^Dcs>Fr{!TGW`zPa9^M%;RAz#oH`Q4DuYw8@6v5;-PAXAonofuj21rG5;x4hcKKkhh`KLC6}EHC|Qm0{LrII`pm9P)*-lm~w( zTSl31eZlnrIPo`VnDz(otNB8#5{iiw(_Pso@4}HytT;r3~{$VJ8ys^)G;#?W*KgDsd@8yYo=m-0%Z|xsj z3h!@R&<%T*7i7FJ<3$;xos#lPGG6Mqg#TrIfY_+7%y;!C{JV^QpYb0v{!_+(&iF4W z^SdjoKYmw6!sr(XBX0?_f0+0?*uItz_w4&`iQ|oO-=8{EuB_#i)xNU&SJwEHHGbtv z=1=SE<^28(8xOx*BVo;->i;Q|YyMTP?W3&ir>yPknSGi5!uQQpGw#Zm{paqnzi_Mx z`~1rMa17)+pFp<^4)Y(zsxbV@{u#zr8RIz2e^)xz@-kmwE(_!BTFAj+ydB`#&KH#X z`pG$ijCKq2MFCd*A(Y3OQ2T$!)hToD!OH17Va!Fs+P{wU?EQBn&qR6y?LOJWc=ZbZ^-!d8NW1R zp08{?kIZ;F<9f!IW_-_#*JX^gOyX}KW40aR(R?Gf@E*aHKd4RkY%)eO{tmV5;!{2|8EcXAF z@n19kpXjedU9$Hlw#e#_WxW{X_>W^i?iNBvk7Jom@_$L|v*!ZI^S^d!#S^cprIPv$R$l~vZ z8UG;T?;C&AC96N$BC9`^1t~KkAazA8nD<`lBtf`eRve;_q{j#ouQ${!GT7HvXtfR)4fbR(~uDPW*i;viSRC#-GUeSl<~WaKkAazA8nD< zAIpLhe>X-JfA7rr9U0$X{85*z{%DJ={#X{A_<`lBtf`eRve;_tf1;_o>b zKRe@R8GqCzt3TQzt3Q?nC;pxpS^PaCUcb;;_Fw#e#_Wx?|hh+R<W{X_>W^i?iND#%;%_G7-5KvP{-{e&@w7M%DS zk1YPiGTxc-mBt@+$?A``$m)+}!HK^{WbwBnYujA>YujA)<4@snf@=1EdDQw zEdI|2tACayTmNMBPg`X5Pg`X5$NHa#Uu`eu&oXmmnXy}@Ewb8Mh`;Y?_+E~~_iZir z+=KRjZuc_qMx#H3zt1szF8eK$2=6>s`j>G+k6Ea>6J_EnU!`@x-KVt=VuL5`C?_tLwzldG*m%^pS%JPe$e|P+U zrk8u>_oa#c0OWVU-^>m5`|*1UevkFs2l>(Xn{|OaeBU4AJsrPVKkA%TDs{XM`UU=f zzvuUY?*_ibvFdlc$ICz9_QN|q1YUz*wa0v6P6+qkp5!>R#{r&IpY6dpMB794wLMs; z6OFwmIu7>e5Axuj_Q+~a_0=BR7i|&lUmoOG^IiQlm~Eu(L0gs?D_PqIwi0H3t(^S< z9P&SyG2^##mgTRHUvgua@z93mkL6cp%rT|yPZ?R`UEx{#4{cFy`wz#U`lpPn{ubiz zUc>ayKBw~IJZt}_F8i^!SN%cCQkHUC{;pt+x4_@%=b=A6-f?Ju_Fs+zEzkBRdw&a6 zU)%pM$T05*dyjJ*>~X&3dBNHvt3B1X_Kt{h@okx9$=aWCW~`KJeUHT7cfzmw=bUhe ziTAONL%d!d^jUxChj>-r#=D=f_h{&XgS`VhtAE;~T4^h1$*`;rUlD{FaW+V3`U_7%%4OV;?=Upeo3uD;H3^$l=~I>>iBQ||3|{?h9! z@67nhj1SM4{ma^8`&eduEHl5BnNQ1zF=4ikmG7T1^JC>`mxP&rE3c&7@wbfsnDMVO z{&~hf%=p_Ge>vkXW&FjAzmW0gGyYu0pUwC)8GkzCPi6ekj6a<5TQYug#=d`Pf9iO7 zCci%8=V$z^jGvbAQ#0mxH0{~(sEi+(@xwEINXC0IZf87}aW)=0wq^1MW_(4)56JlP zjPIZEr5SI^_@a!@%XnkP=VrVi5Gs`^xSmyc0aP{CrHeMqOthNy=2W9L)>mw;wd+N_pT{q*PfbrY+r`w5x<6c?kg67~ZN+q7 zvAZ#~qgc7|f^&+~ifR1vuXU5#r^jIs2b%TzC@i#!t@WbTEH*Z$>f7s+MQgISxLzBh zy~%pJ-DoxYv9v!`LhITzHQ8vQITq}2+y;%+AwM~lcdgENIOBng`!ZgZ@o^a+lkr_M zK3I7FOPYdn!5b7XdXtJ$oNOrg5%w7_C1 zaM*?>@-|tcLMmS%^5QmF>J-gG(WXAJsi8~Q`26YGBZ{l^TGLZO?P?sWjcspDqJxdQ5?2>%))rScMz3}OpNcSk!7g7q z$b7hlbUzKBrZ-Q?$;5pMx>2Jk(jjfZl$ypToiYOc~ zhvduiO1?C&sCr1{W{*Hp5o$KJIXoAwmqlqBd1bA!F_UW}(qytk#~QWEG)koMVHQ=N=yzy;H^MYfWu?r;3#hmldb2b@k+=-Yl4=`WPmBR2rkH>jsJYVWo@L zoqthpd#p84?{ft=BY%AbW-i2zY^GU!h?#aVJ+ZqsIqG#` zDAU@}8pC;F1QX*_tvSUk-6~ zbe(Q=FFv+iY+1K{^Ttaz;3}r;lSzwnT`E6aZobfQ=%$qCmRNstws8*kZbGfb-jZ8w z+4jL+?DIjh4dLg5_r^ThIhC-lsOek0Vg{=!Xj)MBKS)Z_O_NnV@DPuHLA z@lLlUT8d@bw#N2pw-7@}&lRQhccgk(O-}jx{lj|fmRFpXe11DyB3p22ZL(3@%F|u9 zTljf-_d<=kdx^Euxn1aG`)3hO7d>ty;Pf_KFM78%Cfie(WXGn*n{44JI$72;#}J@k z%bLDo&E-XpX!#|)oGd3=Sd`R9({j49Z@_%flli!n(zbKVGG3gGy#qgteehy9vn#Pr zOtz-5sK%+<&0`@FUoYim(SzmnR$hH% zO~hDS8O+1<)+kma9x3DkKur3YW(8Iz1*qKE2F>UIxj45z)HM-F|RFbcGza(|ofHG`PblKb@B+ z0c;UE<~B@qFmk_O2Gt`6oY}m&)-o8?hzNnI0SK#mXYpO zH7l@^n)+qlZal&f)^F4y>&E%m@@av+_EWv@xYDF#&62bRvQqN{Pl zY4W5blP3rrdU3ryJ%%$^3}INq1IaeJBsHufQL@-V1goLMY3m=z*G2WPRTj;(HSbSn5ynfZR+t`z>@u}T)?8floYkOlC{_>_| zrR6JI$TFDwPo0YwFy;;)xc*-{_u)bLsf6 zL}Md0ej$fCH*!xH_~S%lJvH0~W#{^_*7PXQU4^Qbb=2_Ntm~#{8ely=?jXy>K1v0XSDb$p`2?6{wf_bV)clF6j8g%I$t_$|`{MGNrY?eA6@8S;qwBvE^K-kXjKFsQO zyTSL6^XA&NXx4DI3g_Li)^=PzQ4Bn@cN)`iBQl#Erp47q@n=Z(*BG%=}W!-}!7^ zva|tlZM&HHrxKHs@}`ip~CF zBQ}Si8c%P|7Y0qOXphv!aC56MmEPPf+S6OvEUXI~q`#muV}S#!#>*p|51|_+?NEo& z#8g4lx=V+-XZ+vQHQCRG-a`fMZ3EAZ-YObJ5G-Bp1 z#fF*M_{3O!4X>2M=L{BJqpd0IG4Mb3AU*$6MMSvS!$!v*s2&>DL(ARfC>J%AaoeS< zpA_mGN2~8Z5B!9~I_{KB0zWR}A)Ys?AIkGxJ z^OiZUHd~(@gfbr3sk$3s^DA$fZI8}2z4BYc@`;-!>LZP9jk-%Ls@B4sNSs8{8oa5A zyVAA76)mv)cO_!Pq+ETYiwtw1nGxIKq2Fm^@$GNXSDqxwI{w`@`mx#g*Co9j>a%Qx zmq_96vs$gOdaa2AFP8&PDslF94^>>?Pe;A(fr@4Eyfojl6(}1|T>4}M_t^&fZ|@To zl~>tXR^0;WfGcaeYW-uFdHOHh%G@D!4--8j(PuEKSBvCm+?&Ai&(9~=cfvL5bZxA0 zwJc(BgP}Sjdi%-K1_f^QHF1BH$9Fl);r=zQ`q2cGOp2s?gB!0nPyua%*Ty)}j=F*&`_%`^0c-&~onAL<-D|3Drz)@Fw7-zcM?*E)<*8nz=j!T(Nfpl% zdKatcYq)v-YUxRF?wS?7+(4DNAE%D7sRkxn=Am~OQ^~UB6ODo4zG9ZQ&&3xNR}8Gg zrrS1LqD{>%yZxDQdqrnw^Te*+Y1oCop5rHabh|%ElTqj$8W>&%Ep(-gNrKJ^iQAAI zKTBwLo41g5N!Q*KFJ+`p7-kxFxl^yZZ$b{|*X@&a+_{m*uXqB&CRM8#h9L0)! z3TIN0H8DmRe_RL*+Rb$k zCXTjjNxCF7ede%&sjorS5LL`@8;^EzStW^A3#k~Hove?*q03?oV+d6jmm{rl_dMWy z#o2w_##cU@%y(|Bu1b1O*#4>}+h5f_(RyeJOQSg^Oy2t4Yqq57e`2;=E}`7!`X!ek z)#JjbIX0=c+oYP}%FnGQHqBEdnfT_OCU5^V=Pqhj=F?ny0^m+KpXGG>TAa_^4qCjY zQ{^+$@>9KYQoB0|y&A2zy{U5={tS0Z*i1FIbjIYQj@;ebq+M4IaVK*ZXZU7)yIdaO zK3+J6+hh%1GWGMZIZP249oX1!6+JwG?Bddj;}_3Cxra35AU1>DLD=RtZ!x&6hu!!v ziFrqs6Ya+43Q?VIn)`Vpjnj(lxgw_X&?ILEg|3F5VBxM;?@jZVw? zh{Z+4KQ%hBgHLlK+wOD$18upY!|YwR`PaaxiiPivVg%*da{bEw9)Iw}7h)=g*0_s% zzln|2G*??Ouk2B6JXGA4hacvU;YzrTTZD6#!`iLA%CDmO`!U?-D1QNTwo+%jHp|VA z$@;`tZ3H>mI=ggHdkDc~-LzeEJ+r+Pa$Z@t`4B{V760-(I^wH+0gqg;lF~W+vQFaH zCt`T7M9iT4pf9Zd&ykpUgO~EoH;W@~#Iu#NYnKe;hp;ii9tIjLJTNT}GU6GZ8Khxt zv8{%=OV^@v>SHF92Vdtdvey;ZCfUcj5SNljClO^l_!h`Z#<2tY6sb zsc{_3C9c$PLgV0+JC0mqlXth=Db7t0S^c2QfZYk!SeY4^nUb?r{HNB^PyX4JhqHYSaYr#?wR0X z3hNoJh+QKiJ80Y{9!OOam`@qF3D;fy^B^Di)^h0e?$#UUTh_%m*z9T^_ZLUt5A%!e zG3xmsOwoAwrY_6#QJg;U^s>y>IHhfCjEx~5vUPwk>)4SUo0SQ5xv8kTgf$zd*mr1f zOvoah8-Zw1r!?AVkKiHNy4%-{D|DyCI@&!^J|h%j=E*iZsxX37V7_KW-B~T<%k=|# zvnN1zg~RJ+T+aCYo4IK4V#VF#g=UoGt}J?^Sn2Bq&nP{wMFQ%rpnSCQMKs=WH! z8)VW?$$kXp@LR!|YMOrwJlc#Je;pyATcawqap60!|+-z-N zOPCu6`1lq^7OtqJg?#g1Ov{+`>gch!Cxo;jr|~*=q=qGj3)mdR0^))THy7BQ;TZDM zEsSl%W#A-7BYOD8ZN+SB8cRC#i5f3leH~F218HPOePkyZQ7#{mco~3v78^@7c*MhP zQU}=Vt@m&5XHvCVuA^e*Ikb!|+$=DGyOTO+a%AfpHY?o+S*mh^7=E5+GF)~1-J!UqR)eLWMpyGU)EzqoZ1?@qO`B*p=;!_kWoHahJ-!elxk%gpH| z%x0WU{GBROE~#>u55l;`YJ4kpncYl|Q_>s>;e5-F-o$%6Ol9K%!!d(2~Yc6_Tt%-+tYlwbGLmTS}#-o z&orJo`Cn+eq}`CiTWhxy*l_L+*;=-_S!z#*{oEn!o(gzv* z0}{G(bjR*9E%=2*79)MV@EuOu>ymW18|=}^t2J#4ew4aj@coo4FBQHETXC=JnvHI0 zgA1Dl?wO+CV8J&tGw#zk81J$eGPjxh<#)PDl9@3~oxI0nuF_Lgx1f@lP_EnJqmoz! zEcjX$#`A>zoWJ19ne;iDmCCadJ@>K9P`S!8MEdxWKi9bKA}fK5xkc=EEv8!h*dFfC zb(Z+Ycw&-_i~FwR%Rn(Ei5hE!~49v!SlbkvpBM0n^!e#1{NJy;LeYdBNIjB$ zafGcEt-!J#S>VZGeDrBfGcs~wap%VtoIe2BPt^@(Tno7kWkzC>DE1{H>XUNy6zHU6X-BO|;OD-5WSY-NhJ|@O*?OZVS?pe-DR55-(CGVTU87Xz$>aEw5D9 zVDBF_38@JnQH8feAlmd+GM_37VWEXM$F!&Y(_6UMVEbwcus_ts-cIykDmzc$=)jjr z7tC+P&G+C!<-W-{2(QMdY)+2fTj=2>Jdiubtw#4b)AU@AdQh3Omaeb-qOEpWnBtX<*YGMGCg|6+Ml+uFjG zmRsJ;N=R|aKGg=iU{@wRIaKVVM6aFctqyu8BzhB>-jMK(6?{yxIovxv)HgjWSvdy} zWZ^tn8^z5fF3aSTSaUvf#5*Fkw7Xg4?p)zf8`-~@9vZ+W3FV@myJ>!0!}Rugv2uc+ zAf4reG12Jfryu?O8~2hKJj>@^JA)5L`uTx^{^AloY=$WdF|!b4K^6Apjuo~z-EA?P zC{P?XO>kL`fEWmhtmTLV$9v*y1&ZJuHJZG%)+ zgobj@4CtBDJ&XMK5>x9(p#MDFoUOolQdfkzttpP|{mh1`Cge#qhuDkc6VEG#Vyo`sE2k=V-nUvFnbh*|P|L%T;|B{p zwp5EVs@4)m{zW~Z@gJz?fk}Y-g}|34#}^4bzg*ke_K#((+bZ{l{RPEdX9Otnp0>H( zz{6)7<(VuDJSS>LVa54*96!y1Wn1m~R=jpKgcD3xZnm>37Ica@ds|;(ye;92X(w zf7m3I|EfKy{6ER@KZoOgN{;_t=Jbw5EX}95x@7R8bMLS!&DU8ctOJD1ux;s zzfH37tB@tP)#s#p&ogfUY8UJDnH62t%MCC0p@?z_E%55`kIdL#l4Uas-nzB?Z# zPKhyG$Q4PdZr8mIRH@!OjlM2{@4_FvAH_qM8CX$0gujdBPMI~@TPB5!h<~C-vl;X= zL;KXiTmrJX@;My;5gawddLy7Km&w^G-ly549g!Zql(-%UpCw?e;l8^qdg-9GJW7PP0wrO)#Jq!G~9=DMZiE=}yI#dSfH zmntwzZg9@mS)nO2!oGLZ6|tkPK+^ibXd7w3q00@h!R}Z`^)ddhbkY@jchVJdyLiQ% zoz%;2Lnpn>O?rDeD2+GbZN#B9Lxb)f;<oB~6sD+zGoRYtibnP#OuI+9YXxDc8^7kLdEi-o} z3imZ&Q+NOE9pPJ%OHbWv`eZDhPGb2)h{bKoYb+lTtq1V7>)x@13-$Se$ra|0=0oD= zN}kir?(NJ_(IfkZ`qC&X8!mbv6^CErEF&+*7e zkgGgw8mujvaH>zu`p*H%vb)Kvg<-b|thNnPIt6 zJYh(IU0d)Dw6)ld^m!Y?z5NrGo$BxH<2+HU>MK_F6({jL@%AL=ZwYPj=H&Prgsv@( zHfq~>3&LM&>5!>m(c}bvftO|5zsSHZ{^UACCROvfSKk)9@R*I9CWArlhHyFK-e?*Y zG_uQr_}%^1lVX?GTs701-2U*EW?%Di-ceo0;mqajYo%%nv>1-ODkQ<(g|M=hiS{c> zc-1gIwmdc4YdfPm!K)~&b=~52wBD9ag7QUcNqU$G-fnD$X3i}5H&)|;G_2$1$PQB> z4~@~1OOrfW%-x^zOC;czlwyJ|#H*dp_pcV{XSFBMp#5h}H}I*n=4O5zy6scv<_XOV z7U4~-mu1D?d&L#j%oTW0Zr$YeHhLYOa?PGEu$pr_Y@x@pEnY0a>a2;kfViLXb#mOy zCC?6`XC+0RF7*6PKFipPdlF4__9mwc^mv?y?8M>bfIdxnU!iwEG2YxqN!>+G}n8ojvA&%p7K#L>Fk`Ns7X7R5dx$OqD)*+6s2aTP`hGsjj`3GWu} zY4^2dl~uH_Vded-!)NYg+CdK+pTsr9Fee`=xRMJ}JTvcSo-JTJr7r(sWv2PwwG|hs zDC`Td1L5|h7TO~$-3q%Yka5y_sxT3uTIHM#Rpei-x(};C%o)#)&D26 z^{_l!SBGr5`v*Ft-Ti{cmt@Mi^<2qaYd0=Tc3h{wBk7@QGq#W)cQ0Q<91o$7Nv-tw zmEm|JIlfKk=B2ph-n+AJUEf)K>p4nfs^Peek1=NocxVu1>Uee!^SZQZy9mW`%4^|? ziLeh+?35(@I}PH|Wqw4G4`!g(a4s>oQ28+)3~WBlEoVxGR-DyWte1JzeL7b*PQn}% zKQk194mXAIK<#)NOJ9s}_vcys6IuEf9C>J6h9Y{4@a9fp~4n7|!pUP4Qe2S0Fn2!d+|s zl>NATcEx#MEVw}Ti%WM*&jI)v0(Xt0hWsZe-0ss>d6yP<%6Pf#Zjp=Y_&E!<#7<~q z0JQiZ44($U`&F)%4{pgPZ|OdyUT??CVsxi0M(1n;*Bt9H-R_LbPRvsce^1E;;M-{v z-C+?ovID->{ELp^7BScs@G0QB$9$r#J~L9Eu$zCB^U5Yvq1dUFps06UA0GMTJu>`# z7XI#wi|s3u`mwoiY8hK-~?GC zpLoqRJP)!lQ0hdKk{fdg)gcJR}^8!2^EeFdkg5ZGMP z2irBw7p}pVt#ys<|6jjsZJaUoHh0J73O75*>v-){k_=+Mfj7?-!oJJdC)D!)x7lMu z4VSU<2^)0!uaDGt)KP#llCDcHqMu{PZq&_+4$elc^5k znT$KGoLV=_1g$To3U>pzmeK|-wzwypoDqEfYqHpL4W#@8$dp@c*GDhsg6ooGfpD># z2XOq}$?@<`*zyI*ardChtEz4g^fj=O@Z-T=a-^x%m1P+6^KHIzR3?*bWA5D~K7xjt zHR4HupFC$mxv$|*CBd7$58$p-*a-fT9`0~5-Hz{E(sJx^Q#CwK%%ul%? zy-Vc{N!y$yG@})X4WbVpqq5RJVx9KB4LH|I38&vsG%j(t=#rKGPPr0f-#RmiXKjcx zd9z9R6w!K1m)mifW7BcoJ7;={f`x`FEDfO-y0{-Pj#t;?#5If)Fm8OW^W)8J|6@q_ zMrTinkJV|PU}NX2vpFMycfD8G?@syaFc8qr@{~<@s}{%fFdolwyKS*oo}*tO6yt4T za}JvV_@p47gOnE@OFv_$fKm4;QBGw1#t=?lt`*neOJD$@OwmMx$jIoyCSK^!JT$>Znd*6Q$!u0 z&|J5|=s;!tmc|uWrC_o|b6wFye^SB?-nGTLOf1vaNl6zwA#|}-$?-vc3 zg=3uT(CMb|NlrZI&xm7;(n(IoR}am#?ZG>!!?=HnZ0^~!XVo=*drr9Knrr-;vDk(C zj*x^Tg>8*heR7+wKglUR66k))?)fTRH5Q_EZOQEy<++xVv>#T!-y*9{H_0li?%F^{ zVVrbuv)oOP^NlmJt&Pm^YL3&9d%CFiHoRJI;53z+8_6`!qgSW-ZI_^5gyt#+7PPr{5=L`U~K0uuJ?TZPN+Haq8 zwM0ssx-WhP;wji?$~|Uw+uAlf&%h40K)j!PJH69F*X_zvSxPMp$>;0dV5}sEyYEqJ z^D7`R+5A%u-2Jx12kpO$_957jc|w{55RulwZcFQR=w zr~pFd*D%1&pGCqt_yd31C&TU~8HwS|wZ<3>yC=P9*dO@az8LQAmzSJN5g6;}Z14*< z7qsz7cD&qqb}?=MjZ8LV&!YpoS$O+t_ey@_ss3~>#Z{EN>r-B7EN>`TRG+~PA-|rX zy^wlhdd0nymwO|86 z;4Pv=vkM=@zz&(%kEIq|DAjYiopRqyOLi{8E$Auto?8i6igw8-X8vUjIz>(Djo^>) z6*vt4A71jgER_x{gAMdgL^c2M^o+0uSI zw6s$W;jjIP`z=Oy+2q?8e3%^6pgP6KqIgb&Mi-BDF1{4+roes!n-<*7gI&RN#g(%! zrY$YzvC6`A`qD$to#YTB;1_#t#zrO%E|P<|`a#0+euxXV;n)&6wgie7;qqMGV2Gm~ zaum&k}~1|HKde=cC5tC7#(_ zL2Xc>T?jN{(<LclRa3 zx>H8RBDZIPYuKqSH)a>2i?TgilS}xiWxWDH%dW5k=l=#dGVFh{X(}D$`W`+G_C+P1 zWENalim4`dmP}*tz>%e_1=y_q_3M<&&#er687t|)m$_g`_a>R0!x&h4VEl4pJm!j* zgiONr5gZ-|?~mcZ&$-8bP&!-$OCeY<+qdjIP(4Hr%Sp$LUpLDf$%RLqTO@NinQMMH zP{!p#J3ri64rTL$%s-WMemF=J^ZCKeICg$G)cHUi!u%k!V8zT2ZdTc=o-)H#7A19; zxutudp9)({-+grZ8H1gL$Qmyv2RrLfhM(@`$*j}SjT=vV@pT6$ zmkw@MRHj-`TlRmG3%@9GA6F1;6#nr41trNTaY;#%$_CMV^YEgQB%FWxpIezd<{Fu@ z3aA`*0Tx&CRNDEC?e29UoGEsd8U2x zxTH_+`||AA|Ld){qqp7}Eyf>ry4#oK*%AK>%QLrxnsa$3mrVQ3u{?7ZZhI|T zvpkz?f}dmQb>zQ$=_TvLN^)uTA6R;Ed8A7dF1^Ty__G3+T4Y@s$+8S=^?4Dc`drG8 zRi8^Go{6kJS@n6wA*((w0PWI>GRtx?iDSAnV{HG1rB~@EGPUf}H%R?RiX44*xVPlL zDm4Fcsvn9TzHo`(XC1%T>IeJo@q1F_F2>`w#+0*bzM8c3T~S+dPLRoVfO~7yKGo2@ zvGK^%AHJQ-I&+^bS_o$ph^KGtbIrQlmi+nxKlXzPxTC^D_9F=MeY+_3J$CSGiO?Uu zCjJjuUmqJoli;DI=G1`yU^Ap&73o4;lTaW5e`VhTWo45&FS?<7gFxto?&Cj8?3hFV@0N%bVMXYNBaYp)&($y8 zC`GFB#b2d&D&UK~O79Rje*QZhxP=tf73i7Q)Y+{O+^uX*;Tvze zekHnhqzmDet#+X|+bG_oFoRvg{HDH%7Is6~9#7ShH1iY%nz>fs*m>K-eu*g5pQL4J=!pt6 z^aO#s&1(o3uiR>5G>_AAG~zz^f&N7!j}giIQ-J$~RdYL2=w@;MFh}W8YLjLjslXO~ zguwiP>7_VKy6IX?K1{99s#jVtOd^&g}_qk9ByOK7E8SI*7A zGYT}aTi{lLktd(|mAK5Bn`E_$(`twEKm-Q;!p`4^sj$$1yLP~!8F z?sGi&QV84y;g?Ow8xL!I1dA`t^xyHmwZDMv%VkSEep7Vm{&MRW5?*3&k@ydF-oo%|MfBC z`H2WYe!AR5rTKKz&+>I=ZJJ}zzxP{>WWm4DS8&(%0lc4mqQAXsJ3P1XrsHAhvRFUKZ|TE}EAcJX#m44NJbZ@Fk=iGk8vdYs-}AC!<;v3+EjkV1@S+ZWo9#8D zBWra!otT~+6UEVy0exO{0Q2rZPgEa?>iCukENk$L9ln_ex7MU&vwe(Fo*dm4jPqvy z?p2~Rbjm5G3=9qr3=gk_#>)0A9!s8CnHEKia}^yP92^{gEIPSuT5H-!=mdU)x*q6v zHYRVS@lJzVg9%HT=EC!eyqZ?J!G=)}SQ zSKhfbM{!&M7;HyC9KYuw4;zICT;5&vy=PQNDGUOW2yhIJNh&X^U4d1WS!!7V_EY{t zenS3ezSBM3JF82D5R4xp6=>#6_nE$&d-t5y)`U{Bal;Wsm5wSlgXw_%N6~rL0ykqD zjS8wwK**e;$Ounu>zZ3Sz6j@i&v ztj3x=C+Yoc{%U74o8>(j@#B1s%~wTRtu%eTvx)9+gELJCCs9sm3ARcM(b#zEDVBT= zbj#-jFR*W4pQ@kFRUDDp|B%5*f3h>tYZ^z#(&lVf(Q&0ty{Icu+?3e46sK{}8BIq{ zHlwRgXM7nLz7c-)bRqMW4zM|=M*7-YK7d|%1gzSOFm#_DJsU0O&(DO*x6x-lNZ%Kp z`Q%`}T*?F$+xj{=b|>;d`ii~^1TQEQF9^SN`>R{Gv;B=dKAmoVGhckS(h*XCgzhhC zPxVYFH=AyY6EIosk`LqQp}4Z2;fF)%^+ClUh2^XG3P39g+VYh_^+Ef7`)tZ-nN-?( zxWrpY@#N|?h+0iZkCvqL=v)bLCc4%a-=fz!9F1-~5*wztL2vetC!EQH&o|*DlvCuD zHl`5|6OU8KuuL^`x<-#Z3prgL6Vnj)NLz35l&yGW4!hlk@M#(UzK>UBgY+BsienbL zSFPES)ebn%!>9$aS6AJ**L`<`2+Q`t%jL2UOD+h*ez+*mPFif2F=5E)wKUqaP2mJu z*99fEUl4nPk5}$ceIjDQ8Z&Nu)GKMfdJJn>)sDUL%B^}`@Gdlb8RNKB(Vl^PVRkl~ zX54y)HisUBL@IKajrwLxB*8^4 zE)uiM=HIUifzEN)#5fob=Z4n#vC*wH17p?LwJme#a! zYbz@Oj;4euSX&d}ONb>l4gFqCS1m{EASG13hB8pm#n7~(_LQQyB9tJP#xblmd6|xe zMl!^XnF?hB_9V^6HHDlD7p?^@>I7tho-C$y;Ci<1HsAIhb_91e>0-M!*0!)wp-XX? zPf~Cq+;qt9wkzc-{T9G%f`XH85%XJfz+se3)iucXN3*qiLJsM^c3{N^ZP7M8ic8d< z+~}xR_( zYgnt1jY0D}f+KZfq9oB9cv+2g6bvjfFqxYQiWC$ed{TqW6?UhvSn*8#i_4cd-(0q zljUdopAw|bYg#2pof9v7v`-M5XKQDBUD!=KKub>i^7q2;|8XJxqkLYHn#-v4R#PVD zFR=7Vopq$kd224Ok7hrnl@1b>%DT%&Uj8bb*iOB?eD&&$uOB_QdX?udbEKcEyrflP z{fi3ED^vx}mjC>-@hssgm{q#_*RS6$hJXFHw;tSl^p`L92F%Cc%dbD*zk74AIojI# z#@^hLF!bQzpYQPbyWZN`yT3UoQTkpW{mx?Y{M)1Hi!BPKKz)i`6FJr?Y`rUy{v777 zwnDFVjinDtEOlqI1XKG95`=}XKkbL-sZr5!U@1Q83};&mhMwh zBM*Y*?TnPxss)H=z#@SmPANd+z#jmjYLvqw0%k2yObg6=+c;?^Kxc_VOKt0YP^JS$ z?;Bv6(bA}=R4}HVAIm&goDeWD4{8{h2STQ;miVV1D}Oi&C^7AoZ3%Ru*^p!CQ#CeC z!-zBjYCYPYm?mm1THhJ>tfRs*40BjX_N zX_^oR#}ZQ-LsAx;1BS=TBsQStfe>o<{66%%rp3CKJj1L#&}{f zC73isdMa&0*sql%T8#0+lu$QlZ&F={QIo1_X3$EvWcV9qFXL+s{3G}jD@3A#DBxfK zj360LK(LQMp>7N109BFE6B?nYrtbv3xl$eq5_0O0SsAYcjVhs~6H!_q12l^0NT%5k zjjJ>xLj<8n0~nZA58JVUVp0j1+qyLFN(O~Oyw(QTg!V|+k`ORTNM8sA|FcQB9ZFc# zBOs{6Cv5N;9GK<|Hn*v2BFaoAC}SEg?NY%dnL|9j7==-eh(RF!ignxYZ)?cf(l&t};C8JPp{a;db4hNI1gH(gE|w zoFSVuA!!d;jm{gT*l)Qp>#OUHgQ~_SYw&zJ<>=ns`+2_vsSDSW4Chqv3)w<9N!hp# z7?6#>B_uyZ|98*of8KIYOp?d7FL^gb85j9FAZ^juc(m5XKc&0jy&I3u>0`>xf3k}Y zQmubpSj}-sA57?bcG{3*M>lTXS@0C>=^nfx9mp#(8DzAX7Us_~Dkfkpf!oF(>xlee zt><4<_?WcJ%xD3L@D=F1Y|8?@pbMb#t@k^D2;nKay^ON;I yJg= 0.""" MAF.ndims.A : SYSDYN.SysdynModelicaFunction.Input SYSDYN.Variable.type "Real" SYSDYN.SysdynModelicaFunction.optional false + SYSDYN.SysdynModelicaFunction.unit "ANY" SYSDYN.SysdynModelicaFunction.outputs _ : L0.List @L0.list MAF.ndims.result : SYSDYN.SysdynModelicaFunction.Output SYSDYN.Variable.type "Integer" + SYSDYN.SysdynModelicaFunction.unit "1" @@ -105,13 +113,16 @@ Integer n[:] = size(A); // = {8,4,5}""" MAF.size.A : SYSDYN.SysdynModelicaFunction.Input SYSDYN.Variable.type "Real" SYSDYN.SysdynModelicaFunction.optional false + SYSDYN.SysdynModelicaFunction.unit "ANY" MAF.size.i : SYSDYN.SysdynModelicaFunction.Input SYSDYN.Variable.type "Real" SYSDYN.SysdynModelicaFunction.optional true + SYSDYN.SysdynModelicaFunction.unit "1" SYSDYN.SysdynModelicaFunction.outputs _ : L0.List @L0.list MAF.size.result : SYSDYN.SysdynModelicaFunction.Output SYSDYN.Variable.type "Real" + SYSDYN.SysdynModelicaFunction.unit "1" @@ -131,6 +142,7 @@ The constructor function array(A,B,C,...) constructs an array from its arguments MAF.array.A : SYSDYN.SysdynModelicaFunction.VariableLengthInput SYSDYN.Variable.type "Real" SYSDYN.SysdynModelicaFunction.optional false + SYSDYN.SysdynModelicaFunction.unit "'p" SYSDYN.SysdynModelicaFunction.VariableLengthInput.shownLabels _ : L0.List @L0.list MAF.array.A.A : L0.String @@ -140,6 +152,7 @@ The constructor function array(A,B,C,...) constructs an array from its arguments @L0.list MAF.array.result : SYSDYN.SysdynModelicaFunction.Output SYSDYN.Variable.type "Real" + SYSDYN.SysdynModelicaFunction.unit "'p" @@ -162,9 +175,11 @@ Real[2,6] r2 = cat(2, r1, 2*r1);""" MAF.cat.k : SYSDYN.SysdynModelicaFunction.Input SYSDYN.Variable.type "Real" SYSDYN.SysdynModelicaFunction.optional false + SYSDYN.SysdynModelicaFunction.unit "1" MAF.cat.A : SYSDYN.SysdynModelicaFunction.VariableLengthInput SYSDYN.Variable.type "Real" SYSDYN.SysdynModelicaFunction.optional false + SYSDYN.SysdynModelicaFunction.unit "'p" SYSDYN.SysdynModelicaFunction.VariableLengthInput.shownLabels _ : L0.List @L0.list MAF.cat.A.A : L0.String @@ -174,6 +189,7 @@ Real[2,6] r2 = cat(2, r1, 2*r1);""" @L0.list MAF.cat.result : SYSDYN.SysdynModelicaFunction.Output SYSDYN.Variable.type "Real" + SYSDYN.SysdynModelicaFunction.unit "'p" @@ -188,6 +204,7 @@ Returns the n1 x n2 x n3 x ... Integer array with all elements equal to zero (ni MAF.zeros.n : SYSDYN.SysdynModelicaFunction.VariableLengthInput SYSDYN.Variable.type "Real" SYSDYN.SysdynModelicaFunction.optional false + SYSDYN.SysdynModelicaFunction.unit "1" SYSDYN.SysdynModelicaFunction.VariableLengthInput.shownLabels _ : L0.List @L0.list MAF.zeros.n.n1 : L0.String @@ -197,6 +214,7 @@ Returns the n1 x n2 x n3 x ... Integer array with all elements equal to zero (ni @L0.list MAF.zeros.o : SYSDYN.SysdynModelicaFunction.Output SYSDYN.Variable.type "Integer" + SYSDYN.SysdynModelicaFunction.unit "1" SYSDYN.SysdynModelicaFunction.modelicaFunctionInterface """ input Integer n annotation(__OpenModelica_varArgs = true); output Integer o[:];""" @@ -213,6 +231,7 @@ Return the n1 x n2 x n3 x ... Integer array with all elements equal to one (ni > MAF.ones.n : SYSDYN.SysdynModelicaFunction.VariableLengthInput SYSDYN.Variable.type "Integer" SYSDYN.SysdynModelicaFunction.optional false + SYSDYN.SysdynModelicaFunction.unit "1" SYSDYN.SysdynModelicaFunction.VariableLengthInput.shownLabels _ : L0.List @L0.list MAF.ones.n.n1 : L0.String @@ -222,6 +241,7 @@ Return the n1 x n2 x n3 x ... Integer array with all elements equal to one (ni > @L0.list MAF.ones.o : SYSDYN.SysdynModelicaFunction.Output SYSDYN.Variable.type "Integer" + SYSDYN.SysdynModelicaFunction.unit "1" SYSDYN.SysdynModelicaFunction.modelicaFunctionInterface """ input Integer n annotation(__OpenModelica_varArgs = true); output Integer o[:];""" @@ -244,9 +264,11 @@ Boolean vb[3] = fill(true,3); // = {true, true, true}""" MAF.fill.s : SYSDYN.SysdynModelicaFunction.Input SYSDYN.Variable.type "Real" SYSDYN.SysdynModelicaFunction.optional false + SYSDYN.SysdynModelicaFunction.unit "'p" MAF.fill.n : SYSDYN.SysdynModelicaFunction.VariableLengthInput SYSDYN.Variable.type "Integer" SYSDYN.SysdynModelicaFunction.optional false + SYSDYN.SysdynModelicaFunction.unit "1" SYSDYN.SysdynModelicaFunction.VariableLengthInput.shownLabels _ : L0.List @L0.list MAF.fill.n.n1 : L0.String @@ -256,6 +278,7 @@ Boolean vb[3] = fill(true,3); // = {true, true, true}""" @L0.list MAF.fill.o : SYSDYN.SysdynModelicaFunction.Output SYSDYN.Variable.type "Real" + SYSDYN.SysdynModelicaFunction.unit "'p" SYSDYN.SysdynModelicaFunction.modelicaFunctionInterface """ input OpenModelica.Internal.BuiltinType s; input Integer n annotation(__OpenModelica_varArgs = true); output OpenModelica.Internal.BuiltinType o[:];""" @@ -273,10 +296,12 @@ Returns the n x n Integer identity matrix, with ones on the diagonal and zeros a MAF.identity.n : SYSDYN.SysdynModelicaFunction.Input SYSDYN.Variable.type "Integer " SYSDYN.SysdynModelicaFunction.optional false + SYSDYN.SysdynModelicaFunction.unit "1" SYSDYN.SysdynModelicaFunction.outputs _ : L0.List @L0.list MAF.identity.outArray : SYSDYN.SysdynModelicaFunction.Output SYSDYN.Variable.type "Integer " + SYSDYN.SysdynModelicaFunction.unit "1" SYSDYN.SysdynModelicaFunction.modelicaFunctionInterface """ input Integer n; output Integer[n,n] outArray;""" @@ -293,10 +318,12 @@ Returns a square matrix with the elements of vector v on the diagonal and all ot MAF.diagonal.v : SYSDYN.SysdynModelicaFunction.Input SYSDYN.Variable.type "Real" SYSDYN.SysdynModelicaFunction.optional false + SYSDYN.SysdynModelicaFunction.unit "'p" SYSDYN.SysdynModelicaFunction.outputs _ : L0.List @L0.list MAF.diagonal.result : SYSDYN.SysdynModelicaFunction.Output SYSDYN.Variable.type "Real" + SYSDYN.SysdynModelicaFunction.unit "'p" @@ -316,16 +343,20 @@ Real v[:] = linspace(1,7,4); // = {1, 3, 5, 7}""" MAF.linspace.x1 : SYSDYN.SysdynModelicaFunction.Input SYSDYN.Variable.type "Real" SYSDYN.SysdynModelicaFunction.optional false + SYSDYN.SysdynModelicaFunction.unit "'p" MAF.linspace.x2 : SYSDYN.SysdynModelicaFunction.Input SYSDYN.Variable.type "Real" SYSDYN.SysdynModelicaFunction.optional false + SYSDYN.SysdynModelicaFunction.unit "'p" MAF.linspace.n : SYSDYN.SysdynModelicaFunction.Input SYSDYN.Variable.type "Integer" SYSDYN.SysdynModelicaFunction.optional false + SYSDYN.SysdynModelicaFunction.unit "1" SYSDYN.SysdynModelicaFunction.outputs _ : L0.List @L0.list MAF.linspace.v : SYSDYN.SysdynModelicaFunction.Output SYSDYN.Variable.type "Real" + SYSDYN.SysdynModelicaFunction.unit "'p" SYSDYN.SysdynModelicaFunction.modelicaFunctionInterface """ input Real x1 "start"; input Real x2 "end"; input Integer n "number"; @@ -344,10 +375,12 @@ Returns the smallest element of array expression A.""" MAF.min.A : SYSDYN.SysdynModelicaFunction.Input SYSDYN.Variable.type "Real" SYSDYN.SysdynModelicaFunction.optional false + SYSDYN.SysdynModelicaFunction.unit "'p" SYSDYN.SysdynModelicaFunction.outputs _ : L0.List @L0.list MAF.min.result : SYSDYN.SysdynModelicaFunction.Output SYSDYN.Variable.type "Real" + SYSDYN.SysdynModelicaFunction.unit "'p" @@ -362,10 +395,12 @@ Returns the largest element of array expression A.""" MAF.max.A : SYSDYN.SysdynModelicaFunction.Input SYSDYN.Variable.type "Real" SYSDYN.SysdynModelicaFunction.optional false + SYSDYN.SysdynModelicaFunction.unit "'p" SYSDYN.SysdynModelicaFunction.outputs _ : L0.List @L0.list MAF.max.result : SYSDYN.SysdynModelicaFunction.Output SYSDYN.Variable.type "Real" + SYSDYN.SysdynModelicaFunction.unit "'p" @@ -391,10 +426,12 @@ sum(i for i in 1:10) // Gives 1+2+...+10=55 MAF.sum.A : SYSDYN.SysdynModelicaFunction.Input SYSDYN.Variable.type "Real" SYSDYN.SysdynModelicaFunction.optional false + SYSDYN.SysdynModelicaFunction.unit "'p" SYSDYN.SysdynModelicaFunction.outputs _ : L0.List @L0.list MAF.sum.result : SYSDYN.SysdynModelicaFunction.Output SYSDYN.Variable.type "Real" + SYSDYN.SysdynModelicaFunction.unit "'p" @@ -419,10 +456,12 @@ Example: MAF.product.A : SYSDYN.SysdynModelicaFunction.Input SYSDYN.Variable.type "Real" SYSDYN.SysdynModelicaFunction.optional false + SYSDYN.SysdynModelicaFunction.unit "ANY" SYSDYN.SysdynModelicaFunction.outputs _ : L0.List @L0.list MAF.product.result : SYSDYN.SysdynModelicaFunction.Output SYSDYN.Variable.type "Real" + SYSDYN.SysdynModelicaFunction.unit "ANY" @@ -437,10 +476,12 @@ Permutes the first two dimensions of array A. It is an error, if array A does no MAF.transpose.A : SYSDYN.SysdynModelicaFunction.Input SYSDYN.Variable.type "Real" SYSDYN.SysdynModelicaFunction.optional false + SYSDYN.SysdynModelicaFunction.unit "'p" SYSDYN.SysdynModelicaFunction.outputs _ : L0.List @L0.list MAF.transpose.result : SYSDYN.SysdynModelicaFunction.Output SYSDYN.Variable.type "Real" + SYSDYN.SysdynModelicaFunction.unit "'p" @@ -458,13 +499,16 @@ cross(x,y) = vector( [ x[2]*y[3]-x[3]*y[2]; MAF.cross.x : SYSDYN.SysdynModelicaFunction.Input SYSDYN.Variable.type "Real" SYSDYN.SysdynModelicaFunction.optional false + SYSDYN.SysdynModelicaFunction.unit "'p" MAF.cross.y : SYSDYN.SysdynModelicaFunction.Input SYSDYN.Variable.type "Real" SYSDYN.SysdynModelicaFunction.optional false + SYSDYN.SysdynModelicaFunction.unit "'q" SYSDYN.SysdynModelicaFunction.outputs _ : L0.List @L0.list MAF.cross.result : SYSDYN.SysdynModelicaFunction.Output SYSDYN.Variable.type "Real" + SYSDYN.SysdynModelicaFunction.unit "'p*'q" @@ -483,7 +527,10 @@ skew(x) = [ 0 , -x[3], x[2]; MAF.skew.x : SYSDYN.SysdynModelicaFunction.Input SYSDYN.Variable.type "Real" SYSDYN.SysdynModelicaFunction.optional false + SYSDYN.SysdynModelicaFunction.unit "'p" SYSDYN.SysdynModelicaFunction.outputs _ : L0.List @L0.list MAF.skew.result : SYSDYN.SysdynModelicaFunction.Output SYSDYN.Variable.type "Real" + SYSDYN.SysdynModelicaFunction.unit "'p" + \ No newline at end of file diff --git a/org.simantics.sysdyn.ontology/graph/ModelicaFunctions.pgraph b/org.simantics.sysdyn.ontology/graph/ModelicaFunctions.pgraph index 21e2f7d2..942591ad 100644 --- a/org.simantics.sysdyn.ontology/graph/ModelicaFunctions.pgraph +++ b/org.simantics.sysdyn.ontology/graph/ModelicaFunctions.pgraph @@ -16,10 +16,12 @@ Returns the absolute value of v. Is expanded into "(if v >= 0 then v else -v)" ( MF.abs.v : SYSDYN.SysdynModelicaFunction.Input SYSDYN.Variable.type "Real" SYSDYN.SysdynModelicaFunction.optional false + SYSDYN.SysdynModelicaFunction.unit "'p" SYSDYN.SysdynModelicaFunction.outputs _ : L0.List @L0.list MF.abs.result : SYSDYN.SysdynModelicaFunction.Output SYSDYN.Variable.type "Real" + SYSDYN.SysdynModelicaFunction.unit "'p" @@ -34,10 +36,12 @@ Returns the inverse of cos of u, with -1 <= u <= +1. Argument u needs to be an I MF.acos.u : SYSDYN.SysdynModelicaFunction.Input SYSDYN.Variable.type "Real" SYSDYN.SysdynModelicaFunction.optional false + SYSDYN.SysdynModelicaFunction.unit "ANY" SYSDYN.SysdynModelicaFunction.outputs _ : L0.List @L0.list MF.acos.y : SYSDYN.SysdynModelicaFunction.Output SYSDYN.Variable.type "Real" + SYSDYN.SysdynModelicaFunction.unit "1" SYSDYN.SysdynModelicaFunction.modelicaFunctionInterface """ input Real u; output Real y;""" @@ -54,10 +58,12 @@ Returns the inverse of sin of u, with -1 <= u <= +1. Argument u needs to be an I MF.asin.u : SYSDYN.SysdynModelicaFunction.Input SYSDYN.Variable.type "Real" SYSDYN.SysdynModelicaFunction.optional false + SYSDYN.SysdynModelicaFunction.unit "ANY" SYSDYN.SysdynModelicaFunction.outputs _ : L0.List @L0.list MF.asin.y : SYSDYN.SysdynModelicaFunction.Output SYSDYN.Variable.type "Real" + SYSDYN.SysdynModelicaFunction.unit "1" SYSDYN.SysdynModelicaFunction.modelicaFunctionInterface """ input Real u; output Real y;""" @@ -74,10 +80,12 @@ Returns the inverse of tan of u, with -INF < u < INF. Argument u needs to be an MF.atan.u : SYSDYN.SysdynModelicaFunction.Input SYSDYN.Variable.type "Real" SYSDYN.SysdynModelicaFunction.optional false + SYSDYN.SysdynModelicaFunction.unit "ANY" SYSDYN.SysdynModelicaFunction.outputs _ : L0.List @L0.list MF.atan.y : SYSDYN.SysdynModelicaFunction.Output SYSDYN.Variable.type "Real" + SYSDYN.SysdynModelicaFunction.unit "1" SYSDYN.SysdynModelicaFunction.modelicaFunctionInterface """ input Real u; output Real y;""" @@ -94,13 +102,16 @@ Returns y = atan2(u1,u2) such that tan(y) = u1/u2 and y is in the range -pi < y MF.atan2.u1 : SYSDYN.SysdynModelicaFunction.Input SYSDYN.Variable.type "Real" SYSDYN.SysdynModelicaFunction.optional false + SYSDYN.SysdynModelicaFunction.unit "'p" MF.atan2.u2 : SYSDYN.SysdynModelicaFunction.Input SYSDYN.Variable.type "Real" SYSDYN.SysdynModelicaFunction.optional false + SYSDYN.SysdynModelicaFunction.unit "'p" SYSDYN.SysdynModelicaFunction.outputs _ : L0.List @L0.list MF.atan2.y : SYSDYN.SysdynModelicaFunction.Output SYSDYN.Variable.type "Real" + SYSDYN.SysdynModelicaFunction.unit "1" SYSDYN.SysdynModelicaFunction.modelicaFunctionInterface """ input Real u1; input Real u2; output Real z;""" @@ -118,10 +129,12 @@ Returns the smallest integer not less than x (i.e. the closest integer above x). MF.ceil.x : SYSDYN.SysdynModelicaFunction.Input SYSDYN.Variable.type "Real" SYSDYN.SysdynModelicaFunction.optional false + SYSDYN.SysdynModelicaFunction.unit "'p" SYSDYN.SysdynModelicaFunction.outputs _ : L0.List @L0.list MF.ceil.y : SYSDYN.SysdynModelicaFunction.Output SYSDYN.Variable.type "Real" + SYSDYN.SysdynModelicaFunction.unit "'p" SYSDYN.SysdynModelicaFunction.modelicaFunctionInterface """ input Real x; output Real y;""" @@ -138,10 +151,12 @@ Returns the cosine of u, with -INF < u < INF Argument u needs to be an Integer o MF.ceil.u : SYSDYN.SysdynModelicaFunction.Input SYSDYN.Variable.type "Real" SYSDYN.SysdynModelicaFunction.optional false + SYSDYN.SysdynModelicaFunction.unit "ANY" SYSDYN.SysdynModelicaFunction.outputs _ : L0.List @L0.list MF.ceil.y : SYSDYN.SysdynModelicaFunction.Output SYSDYN.Variable.type "Real" + SYSDYN.SysdynModelicaFunction.unit "1" SYSDYN.SysdynModelicaFunction.modelicaFunctionInterface """ input Real u; output Real y;""" @@ -158,10 +173,12 @@ Returns the cosh of u, with -INF < u < INF. Argument u needs to be an Integer or MF.cosh.u : SYSDYN.SysdynModelicaFunction.Input SYSDYN.Variable.type "Real" SYSDYN.SysdynModelicaFunction.optional false + SYSDYN.SysdynModelicaFunction.unit "ANY" SYSDYN.SysdynModelicaFunction.outputs _ : L0.List @L0.list MF.cosh.y : SYSDYN.SysdynModelicaFunction.Output SYSDYN.Variable.type "Real" + SYSDYN.SysdynModelicaFunction.unit "1" SYSDYN.SysdynModelicaFunction.modelicaFunctionInterface """ input Real u; output Real y;""" @@ -179,16 +196,20 @@ Returns "expr(time - delayTime)" for time > time.start + delayTime and "expr(tim MF.delay.expr : SYSDYN.SysdynModelicaFunction.Input SYSDYN.Variable.type "Real" SYSDYN.SysdynModelicaFunction.optional false + SYSDYN.SysdynModelicaFunction.unit "'p" MF.delay.delayTime : SYSDYN.SysdynModelicaFunction.Input SYSDYN.Variable.type "Real" SYSDYN.SysdynModelicaFunction.optional false + SYSDYN.SysdynModelicaFunction.unit "TIME" MF.delay.delayMax : SYSDYN.SysdynModelicaFunction.Input SYSDYN.Variable.type "Real" SYSDYN.SysdynModelicaFunction.optional true + SYSDYN.SysdynModelicaFunction.unit "TIME" SYSDYN.SysdynModelicaFunction.outputs _ : L0.List @L0.list MF.delay.result : SYSDYN.SysdynModelicaFunction.Output SYSDYN.Variable.type "Real" + SYSDYN.SysdynModelicaFunction.unit "'p" @@ -209,10 +230,12 @@ equation MF.der.expr : SYSDYN.SysdynModelicaFunction.Input SYSDYN.Variable.type "Real" SYSDYN.SysdynModelicaFunction.optional false + SYSDYN.SysdynModelicaFunction.unit "'p" SYSDYN.SysdynModelicaFunction.outputs _ : L0.List @L0.list MF.der.dexpr : SYSDYN.SysdynModelicaFunction.Output SYSDYN.Variable.type "Real" + SYSDYN.SysdynModelicaFunction.unit "'p/TIME" SYSDYN.SysdynModelicaFunction.modelicaFunctionInterface """ input Real expr(unit = "'p"); output Real dexpr(unit = "'p/s");""" @@ -229,13 +252,16 @@ Returns the algebraic quotient x/y with any fractional part discarted (also know MF.div.x : SYSDYN.SysdynModelicaFunction.Input SYSDYN.Variable.type "Real" SYSDYN.SysdynModelicaFunction.optional false + SYSDYN.SysdynModelicaFunction.unit "'p" MF.div.y : SYSDYN.SysdynModelicaFunction.Input SYSDYN.Variable.type "Real" SYSDYN.SysdynModelicaFunction.optional false + SYSDYN.SysdynModelicaFunction.unit "'q" SYSDYN.SysdynModelicaFunction.outputs _ : L0.List @L0.list MF.div.result : SYSDYN.SysdynModelicaFunction.Output SYSDYN.Variable.type "Real" + SYSDYN.SysdynModelicaFunction.unit "'p/'q" @@ -250,10 +276,12 @@ Returns true when the value of the boolean expression b changes. Expanded into ( MF.edge.b : SYSDYN.SysdynModelicaFunction.Input SYSDYN.Variable.type "Boolean" SYSDYN.SysdynModelicaFunction.optional false + SYSDYN.SysdynModelicaFunction.unit "1" SYSDYN.SysdynModelicaFunction.outputs _ : L0.List @L0.list MF.edge.edgeEvent : SYSDYN.SysdynModelicaFunction.Output SYSDYN.Variable.type "Boolean" + SYSDYN.SysdynModelicaFunction.unit "1" SYSDYN.SysdynModelicaFunction.modelicaFunctionInterface """ input Boolean b; output Boolean edgeEvent;""" @@ -270,10 +298,12 @@ Returns the base e exponential of u, with -INF < u < INF Argument u needs to be MF.exp.u : SYSDYN.SysdynModelicaFunction.Input SYSDYN.Variable.type "Real" SYSDYN.SysdynModelicaFunction.optional false + SYSDYN.SysdynModelicaFunction.unit "ANY" SYSDYN.SysdynModelicaFunction.outputs _ : L0.List @L0.list MF.exp.y : SYSDYN.SysdynModelicaFunction.Output SYSDYN.Variable.type "Real" + SYSDYN.SysdynModelicaFunction.unit "1" SYSDYN.SysdynModelicaFunction.modelicaFunctionInterface """ input Real u(unit = "1"); output Real y(unit = "1");""" @@ -290,10 +320,12 @@ Returns the largest integer not greater than x (i.e. the closest integer below x MF.floor.x : SYSDYN.SysdynModelicaFunction.Input SYSDYN.Variable.type "Real" SYSDYN.SysdynModelicaFunction.optional false + SYSDYN.SysdynModelicaFunction.unit "'p" SYSDYN.SysdynModelicaFunction.outputs _ : L0.List @L0.list MF.floor.y : SYSDYN.SysdynModelicaFunction.Output SYSDYN.Variable.type "Real" + SYSDYN.SysdynModelicaFunction.unit "'p" SYSDYN.SysdynModelicaFunction.modelicaFunctionInterface """ input Real x; output Real y;""" @@ -311,6 +343,7 @@ Returns true during the initialization phase and false otherwise.""" @L0.list MF.initial.isInitial : SYSDYN.SysdynModelicaFunction.Output SYSDYN.Variable.type "Boolean" + SYSDYN.SysdynModelicaFunction.unit "1" SYSDYN.SysdynModelicaFunction.modelicaFunctionInterface """ output Boolean isInitial;""" @@ -326,10 +359,12 @@ Returns the base e logarithm of u, with u > 0. Argument u needs to be an Integer MF.log.u : SYSDYN.SysdynModelicaFunction.Input SYSDYN.Variable.type "Real" SYSDYN.SysdynModelicaFunction.optional false + SYSDYN.SysdynModelicaFunction.unit "ANY" SYSDYN.SysdynModelicaFunction.outputs _ : L0.List @L0.list MF.log.y : SYSDYN.SysdynModelicaFunction.Output SYSDYN.Variable.type "Real" + SYSDYN.SysdynModelicaFunction.unit "1" SYSDYN.SysdynModelicaFunction.modelicaFunctionInterface """ input Real u(unit = "1"); output Real y(unit = "1");""" @@ -346,10 +381,12 @@ Returns the base 10 logarithm of u, with u > 0. Argument u needs to be an Intege MF.log10.u : SYSDYN.SysdynModelicaFunction.Input SYSDYN.Variable.type "Real" SYSDYN.SysdynModelicaFunction.optional false + SYSDYN.SysdynModelicaFunction.unit "ANY" SYSDYN.SysdynModelicaFunction.outputs _ : L0.List @L0.list MF.log10.y : SYSDYN.SysdynModelicaFunction.Output SYSDYN.Variable.type "Real" + SYSDYN.SysdynModelicaFunction.unit "1" SYSDYN.SysdynModelicaFunction.modelicaFunctionInterface """ input Real u(unit = "1"); output Real y(unit = "1");""" @@ -372,13 +409,16 @@ max(i^2 for i in {3,7,6}) // = 49""" MF.max.x : SYSDYN.SysdynModelicaFunction.Input SYSDYN.Variable.type "Real" SYSDYN.SysdynModelicaFunction.optional false + SYSDYN.SysdynModelicaFunction.unit "'p" MF.max.y : SYSDYN.SysdynModelicaFunction.Input SYSDYN.Variable.type "Real" SYSDYN.SysdynModelicaFunction.optional false + SYSDYN.SysdynModelicaFunction.unit "'p" SYSDYN.SysdynModelicaFunction.outputs _ : L0.List @L0.list MF.max.result : SYSDYN.SysdynModelicaFunction.Output SYSDYN.Variable.type "Real" + SYSDYN.SysdynModelicaFunction.unit "'p" @@ -399,13 +439,16 @@ min(i^2 for i in {3,7,6}) // = 9""" MF.min.x : SYSDYN.SysdynModelicaFunction.Input SYSDYN.Variable.type "Real" SYSDYN.SysdynModelicaFunction.optional false + SYSDYN.SysdynModelicaFunction.unit "'p" MF.min.y : SYSDYN.SysdynModelicaFunction.Input SYSDYN.Variable.type "Real" SYSDYN.SysdynModelicaFunction.optional false + SYSDYN.SysdynModelicaFunction.unit "'p" SYSDYN.SysdynModelicaFunction.outputs _ : L0.List @L0.list MF.min.result : SYSDYN.SysdynModelicaFunction.Output SYSDYN.Variable.type "Real" + SYSDYN.SysdynModelicaFunction.unit "'p" @@ -420,13 +463,16 @@ Returns the integer modulus of x/y: mod(x,y) = x - floor(x/y) * y.""" MF.mod.x : SYSDYN.SysdynModelicaFunction.Input SYSDYN.Variable.type "Real" SYSDYN.SysdynModelicaFunction.optional false + SYSDYN.SysdynModelicaFunction.unit "'p" MF.mod.y : SYSDYN.SysdynModelicaFunction.Input SYSDYN.Variable.type "Real" SYSDYN.SysdynModelicaFunction.optional false + SYSDYN.SysdynModelicaFunction.unit "'ANY" SYSDYN.SysdynModelicaFunction.outputs _ : L0.List @L0.list MF.mod.result : SYSDYN.SysdynModelicaFunction.Output SYSDYN.Variable.type "Real" + SYSDYN.SysdynModelicaFunction.unit "'p" @@ -444,10 +490,12 @@ If you want a condition to be checked only on time steps, use noEvent. MF.noEvent.expr : SYSDYN.SysdynModelicaFunction.Input SYSDYN.Variable.type "Real" SYSDYN.SysdynModelicaFunction.optional false + SYSDYN.SysdynModelicaFunction.unit "ANY" SYSDYN.SysdynModelicaFunction.outputs _ : L0.List @L0.list MF.noEvent.result : SYSDYN.SysdynModelicaFunction.Output SYSDYN.Variable.type "Real" + SYSDYN.SysdynModelicaFunction.unit "1" @@ -467,10 +515,14 @@ A new event is triggered if at least for one variable v "pre(v) <> v" after the MF.pre.y : SYSDYN.SysdynModelicaFunction.Input SYSDYN.Variable.type "Real" SYSDYN.SysdynModelicaFunction.optional false + SYSDYN.SysdynModelicaFunction.unit "'p" SYSDYN.SysdynModelicaFunction.outputs _ : L0.List @L0.list MF.pre.result : SYSDYN.SysdynModelicaFunction.Output SYSDYN.Variable.type "Real" + SYSDYN.SysdynModelicaFunction.unit "'p" + + MF.rem : SYSDYN.SysdynModelicaFunction L0.HasDescription """rem(x, y) @@ -483,13 +535,16 @@ Returns the integer remainder of x/y: rem(x,y) = x - div(x,y) * y.""" MF.rem.x : SYSDYN.SysdynModelicaFunction.Input SYSDYN.Variable.type "Real" SYSDYN.SysdynModelicaFunction.optional false + SYSDYN.SysdynModelicaFunction.unit "'p" MF.rem.y : SYSDYN.SysdynModelicaFunction.Input SYSDYN.Variable.type "Real" SYSDYN.SysdynModelicaFunction.optional false + SYSDYN.SysdynModelicaFunction.unit "ANY" SYSDYN.SysdynModelicaFunction.outputs _ : L0.List @L0.list MF.rem.result : SYSDYN.SysdynModelicaFunction.Output SYSDYN.Variable.type "Real" + SYSDYN.SysdynModelicaFunction.unit "'p" @@ -504,13 +559,16 @@ Returns true and triggers time events at times start + i * interval (i=0,1,...). MF.sample.start : SYSDYN.SysdynModelicaFunction.Input SYSDYN.Variable.type "Real" SYSDYN.SysdynModelicaFunction.optional false + SYSDYN.SysdynModelicaFunction.unit "TIME" MF.sample.interval : SYSDYN.SysdynModelicaFunction.Input SYSDYN.Variable.type "Real" SYSDYN.SysdynModelicaFunction.optional false + SYSDYN.SysdynModelicaFunction.unit "TIME" SYSDYN.SysdynModelicaFunction.outputs _ : L0.List @L0.list MF.sample.isSample : SYSDYN.SysdynModelicaFunction.Output SYSDYN.Variable.type "Boolean" + SYSDYN.SysdynModelicaFunction.unit "1" SYSDYN.SysdynModelicaFunction.modelicaFunctionInterface """ parameter input Real start(fixed = false); parameter input Real interval(fixed = false); output Boolean isSample;""" @@ -551,16 +609,20 @@ sa = sb;""" MF.semiLinear.x : SYSDYN.SysdynModelicaFunction.Input SYSDYN.Variable.type "Real" SYSDYN.SysdynModelicaFunction.optional false + SYSDYN.SysdynModelicaFunction.unit "'p" MF.semiLinear.positiveSlope : SYSDYN.SysdynModelicaFunction.Input SYSDYN.Variable.type "Real" SYSDYN.SysdynModelicaFunction.optional false + SYSDYN.SysdynModelicaFunction.unit "'q" MF.semiLinear.negativeSlope : SYSDYN.SysdynModelicaFunction.Input SYSDYN.Variable.type "Real" SYSDYN.SysdynModelicaFunction.optional false + SYSDYN.SysdynModelicaFunction.unit "'q" SYSDYN.SysdynModelicaFunction.outputs _ : L0.List @L0.list MF.semiLinear.result : SYSDYN.SysdynModelicaFunction.Output SYSDYN.Variable.type "Real" + SYSDYN.SysdynModelicaFunction.unit "'p*'q" SYSDYN.SysdynModelicaFunction.modelicaFunctionInterface """ input Real x; input Real positiveSlope; input Real negativeSlope; @@ -579,10 +641,12 @@ Returns -1 if v is negative, 1 if v is positive. Expanded into "(if v > 0 then 1 MF.sign.v : SYSDYN.SysdynModelicaFunction.Input SYSDYN.Variable.type "Real" SYSDYN.SysdynModelicaFunction.optional false + SYSDYN.SysdynModelicaFunction.unit "ANY" SYSDYN.SysdynModelicaFunction.outputs _ : L0.List @L0.list MF.sign.result : SYSDYN.SysdynModelicaFunction.Output SYSDYN.Variable.type "Integer" + SYSDYN.SysdynModelicaFunction.unit "1" SYSDYN.SysdynModelicaFunction.modelicaFunctionInterface """ input Real v; output Integer result;""" @@ -599,10 +663,12 @@ Returns the sine of u, with -INF < u < INF. Argument u needs to be an Integer or MF.sin.u : SYSDYN.SysdynModelicaFunction.Input SYSDYN.Variable.type "Real" SYSDYN.SysdynModelicaFunction.optional false + SYSDYN.SysdynModelicaFunction.unit "ANY" SYSDYN.SysdynModelicaFunction.outputs _ : L0.List @L0.list MF.sin.y : SYSDYN.SysdynModelicaFunction.Output SYSDYN.Variable.type "Real" + SYSDYN.SysdynModelicaFunction.unit "1" SYSDYN.SysdynModelicaFunction.modelicaFunctionInterface """ input Real x; output Real y;""" @@ -619,10 +685,12 @@ Returns the sinh of u, with -INF < u < INF. Argument u needs to be an Integer or MF.sinh.u : SYSDYN.SysdynModelicaFunction.Input SYSDYN.Variable.type "Real" SYSDYN.SysdynModelicaFunction.optional false + SYSDYN.SysdynModelicaFunction.unit "ANY" SYSDYN.SysdynModelicaFunction.outputs _ : L0.List @L0.list MF.sinh.y : SYSDYN.SysdynModelicaFunction.Output SYSDYN.Variable.type "Real" + SYSDYN.SysdynModelicaFunction.unit "1" SYSDYN.SysdynModelicaFunction.modelicaFunctionInterface """ input Real x; output Real y;""" @@ -640,13 +708,16 @@ The only allowed types for expr in smooth are: real expressions, arrays of allow MF.smooth.p : SYSDYN.SysdynModelicaFunction.Input SYSDYN.Variable.type "Real" SYSDYN.SysdynModelicaFunction.optional false + SYSDYN.SysdynModelicaFunction.unit "1" MF.smooth.expr : SYSDYN.SysdynModelicaFunction.Input SYSDYN.Variable.type "Real" SYSDYN.SysdynModelicaFunction.optional false + SYSDYN.SysdynModelicaFunction.unit "'p" SYSDYN.SysdynModelicaFunction.outputs _ : L0.List @L0.list MF.smooth.result : SYSDYN.SysdynModelicaFunction.Output SYSDYN.Variable.type "Real" + SYSDYN.SysdynModelicaFunction.unit "'p" @@ -661,10 +732,12 @@ Square root of v. The value of v must be greater or equal to 0 or an assertion e MF.sqrt.v : SYSDYN.SysdynModelicaFunction.Input SYSDYN.Variable.type "Real" SYSDYN.SysdynModelicaFunction.optional false + SYSDYN.SysdynModelicaFunction.unit "ANY" SYSDYN.SysdynModelicaFunction.outputs _ : L0.List @L0.list MF.sqrt.y : SYSDYN.SysdynModelicaFunction.Output SYSDYN.Variable.type "Real" + SYSDYN.SysdynModelicaFunction.unit "ANY" SYSDYN.SysdynModelicaFunction.modelicaFunctionInterface """ input Real v(unit = "'p"); output Real y(unit = "'p(1/2)");""" @@ -681,10 +754,12 @@ Returns the tangent of u, with -INF < u < INF (if u is a multiple of (2n-1)*pi/2 MF.tan.u : SYSDYN.SysdynModelicaFunction.Input SYSDYN.Variable.type "Real" SYSDYN.SysdynModelicaFunction.optional false + SYSDYN.SysdynModelicaFunction.unit "ANY" SYSDYN.SysdynModelicaFunction.outputs _ : L0.List @L0.list MF.tan.y : SYSDYN.SysdynModelicaFunction.Output SYSDYN.Variable.type "Real" + SYSDYN.SysdynModelicaFunction.unit "1" SYSDYN.SysdynModelicaFunction.modelicaFunctionInterface """ input Real u; output Real y;""" @@ -701,10 +776,12 @@ Returns the tanh of u, with -INF < u < INF. Argument u needs to be an Integer or MF.tanh.u : SYSDYN.SysdynModelicaFunction.Input SYSDYN.Variable.type "Real" SYSDYN.SysdynModelicaFunction.optional false + SYSDYN.SysdynModelicaFunction.unit "ANY" SYSDYN.SysdynModelicaFunction.outputs _ : L0.List @L0.list MF.tanh.y : SYSDYN.SysdynModelicaFunction.Output SYSDYN.Variable.type "Real" + SYSDYN.SysdynModelicaFunction.unit "1" SYSDYN.SysdynModelicaFunction.modelicaFunctionInterface """ input Real x; output Real y;""" @@ -722,5 +799,6 @@ Returns true at the end of a successful simulation.""" @L0.list MF.terminal.isTerminal : SYSDYN.SysdynModelicaFunction.Output SYSDYN.Variable.type "Boolean" + SYSDYN.SysdynModelicaFunction.unit "1" SYSDYN.SysdynModelicaFunction.modelicaFunctionInterface """ output Boolean isTerminal;""" \ No newline at end of file diff --git a/org.simantics.sysdyn.ontology/graph/Sysdyn.pgraph b/org.simantics.sysdyn.ontology/graph/Sysdyn.pgraph index b14b917b..4fc523d6 100644 --- a/org.simantics.sysdyn.ontology/graph/Sysdyn.pgraph +++ b/org.simantics.sysdyn.ontology/graph/Sysdyn.pgraph @@ -324,6 +324,7 @@ SYSDYN.SysdynModelicaFunctionLibrary -- SYSDYN.SysdynModelicaFunction.definition --> L0.String -- SYSDYN.SysdynModelicaFunction.unit --> L0.String -- SYSDYN.SysdynModelicaFunction.optional --> L0.Boolean functions = Function.getAllBuiltInFunctions(graph); + result = UnitUtils.matchUnits(left, right, functions, UnitUtils.allowEquivalents(graph, model)); if(result != null) issues.add(new ModuleStandardIssue(SR.Validations_ModuleOutputUnitWarning, module, output, reference)); } @@ -139,7 +141,8 @@ public class UnitFunction { continue; String left = graph.getPossibleRelatedValue(variable, SR.Variable_unit); String right = graph.getPossibleRelatedValue(reference, SR.Variable_unit); - result = UnitUtils.matchUnits(left, right, UnitUtils.allowEquivalents(graph, model)); + ArrayList functions = Function.getAllBuiltInFunctions(graph); + result = UnitUtils.matchUnits(left, right, functions, UnitUtils.allowEquivalents(graph, model)); if(result != null) issues.add(new ModuleStandardIssue(SR.Validations_ModuleInputUnitWarning, module, variable, reference)); } @@ -230,7 +233,8 @@ public class UnitFunction { return "No unit defined for " + NameUtils.getSafeName(graph, rightResource); SysdynModel model = ModelUtils.getModel(graph, leftResource); - String result = UnitUtils.matchUnits(left, right, UnitUtils.allowEquivalents(graph, model)); + ArrayList functions = Function.getAllBuiltInFunctions(graph); + String result = UnitUtils.matchUnits(left, right, functions, UnitUtils.allowEquivalents(graph, model)); if(result != null) result = prefix + result + suffix; diff --git a/org.simantics.sysdyn/src/org/simantics/sysdyn/TestParser.java b/org.simantics.sysdyn/src/org/simantics/sysdyn/TestParser.java index 95393832..86b3245c 100644 --- a/org.simantics.sysdyn/src/org/simantics/sysdyn/TestParser.java +++ b/org.simantics.sysdyn/src/org/simantics/sysdyn/TestParser.java @@ -20,6 +20,7 @@ import org.simantics.sysdyn.unitParser.UnitCheckingException; import org.simantics.sysdyn.unitParser.UnitCheckingNode; import org.simantics.sysdyn.unitParser.UnitParser; import org.simantics.sysdyn.unitParser.nodes.UnitResult; +import org.simantics.sysdyn.utils.Function; public class TestParser { @@ -60,7 +61,7 @@ public class TestParser { UnitCheckingNode node = (UnitCheckingNode) parser.expr(); try { - UnitResult u = node.getUnits(units, allowEquivalents); + UnitResult u = node.getUnits(units, Function.getAllBuiltInFunctions(), allowEquivalents); System.out.println("Result: " + u.getCleanFullUnit()); } catch (UnitCheckingException e) { e.printStackTrace(); diff --git a/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/utils/UnitUtils.java b/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/utils/UnitUtils.java index 4949b478..04369f79 100644 --- a/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/utils/UnitUtils.java +++ b/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/utils/UnitUtils.java @@ -13,6 +13,7 @@ package org.simantics.sysdyn.representation.utils; import java.io.StringReader; +import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; import java.util.Set; @@ -38,6 +39,7 @@ import org.simantics.sysdyn.unitParser.UnitCheckingNode; import org.simantics.sysdyn.unitParser.UnitParser; import org.simantics.sysdyn.unitParser.nodes.ComponentReferenceFull; import org.simantics.sysdyn.unitParser.nodes.UnitResult; +import org.simantics.sysdyn.utils.Function; public class UnitUtils { @@ -52,7 +54,7 @@ public class UnitUtils { HashMap units = UnitUtils.findUnits(graph, model, configuration, components); try { - node.getUnits(units, allowEquivalents(graph, model)); + node.getUnits(units, Function.getAllBuiltInFunctions(graph), allowEquivalents(graph, model)); } catch (UnitCheckingException e) { return e.getMessage(); } catch (DatabaseException e) { @@ -107,9 +109,10 @@ public class UnitUtils { leftReader.close(); try { + ArrayList functions = Function.getAllBuiltInFunctions(graph); boolean allowEquivalents = allowEquivalents(graph, model); - UnitResult rightUnits = right.getUnits(units, allowEquivalents); - UnitResult leftUnits = left.getUnits(null, allowEquivalents); + UnitResult rightUnits = right.getUnits(units, functions, allowEquivalents); + UnitResult leftUnits = left.getUnits(null, functions, allowEquivalents); if(!rightUnits.equals(leftUnits)) return leftUnits.getCleanFullUnit() + " != " + rightUnits.getCleanFullUnit(); @@ -213,7 +216,7 @@ public class UnitUtils { } - public static String matchUnits(String left, String right, boolean allowEquivalents) throws DatabaseException { + public static String matchUnits(String left, String right, ArrayList functions, boolean allowEquivalents) throws DatabaseException { if(left == null || right == null || left.isEmpty() || right.isEmpty()) return "No unit defined"; @@ -230,8 +233,8 @@ public class UnitUtils { rightReader.close(); try { - UnitResult leftUnits = leftNode.getUnits(null, allowEquivalents); - UnitResult rightUnits = rightNode.getUnits(null, allowEquivalents); + UnitResult leftUnits = leftNode.getUnits(null, functions, allowEquivalents); + UnitResult rightUnits = rightNode.getUnits(null, functions, allowEquivalents); if(!rightUnits.equals(leftUnits)) return leftUnits.getCleanFullUnit() + " != " + rightUnits.getCleanFullUnit(); diff --git a/org.simantics.sysdyn/src/org/simantics/sysdyn/unitParser/UnitCheckingNode.java b/org.simantics.sysdyn/src/org/simantics/sysdyn/unitParser/UnitCheckingNode.java index 2233c88e..5a711256 100644 --- a/org.simantics.sysdyn/src/org/simantics/sysdyn/unitParser/UnitCheckingNode.java +++ b/org.simantics.sysdyn/src/org/simantics/sysdyn/unitParser/UnitCheckingNode.java @@ -12,9 +12,11 @@ *******************************************************************************/ package org.simantics.sysdyn.unitParser; +import java.util.ArrayList; import java.util.HashMap; import org.simantics.sysdyn.unitParser.nodes.UnitResult; +import org.simantics.sysdyn.utils.Function; public class UnitCheckingNode extends SimpleNode { @@ -23,7 +25,7 @@ public class UnitCheckingNode extends SimpleNode { super(id); } - public UnitResult getUnits(HashMap units, boolean allowEquivalents) throws UnitCheckingException{ + public UnitResult getUnits(HashMap units, ArrayList functions, boolean allowEquivalents) throws UnitCheckingException{ UnitResult result = new UnitResult(allowEquivalents); if(jjtGetNumChildren() == 0){ @@ -31,7 +33,7 @@ public class UnitCheckingNode extends SimpleNode { result.append(node); } else { for(int i = 0; i < jjtGetNumChildren(); i++) { - result.appendResult(((UnitCheckingNode)jjtGetChild(i)).getUnits(units, allowEquivalents)); + result.appendResult(((UnitCheckingNode)jjtGetChild(i)).getUnits(units, functions, allowEquivalents)); } } return result; diff --git a/org.simantics.sysdyn/src/org/simantics/sysdyn/unitParser/nodes/AddOp.java b/org.simantics.sysdyn/src/org/simantics/sysdyn/unitParser/nodes/AddOp.java index 026b8a1c..6aafee9c 100644 --- a/org.simantics.sysdyn/src/org/simantics/sysdyn/unitParser/nodes/AddOp.java +++ b/org.simantics.sysdyn/src/org/simantics/sysdyn/unitParser/nodes/AddOp.java @@ -12,11 +12,13 @@ *******************************************************************************/ package org.simantics.sysdyn.unitParser.nodes; +import java.util.ArrayList; import java.util.HashMap; import org.simantics.sysdyn.unitParser.UnitCheckingException; import org.simantics.sysdyn.unitParser.UnitCheckingNode; import org.simantics.sysdyn.unitParser.nodes.UnitResult.UnitType; +import org.simantics.sysdyn.utils.Function; /** * See UnitCheckingNodeFactory for mapping @@ -31,8 +33,8 @@ public class AddOp extends UnitCheckingNode { } @Override - public UnitResult getUnits(HashMap units, boolean allowEquivalents) throws UnitCheckingException { - UnitResult result = super.getUnits(units, allowEquivalents); + public UnitResult getUnits(HashMap units, ArrayList functions, boolean allowEquivalents) throws UnitCheckingException { + UnitResult result = super.getUnits(units, functions, allowEquivalents); result.setUnitType(UnitType.OPERATOR); return result; } diff --git a/org.simantics.sysdyn/src/org/simantics/sysdyn/unitParser/nodes/Arithmetic.java b/org.simantics.sysdyn/src/org/simantics/sysdyn/unitParser/nodes/Arithmetic.java index 396bcb1d..44bb2e21 100644 --- a/org.simantics.sysdyn/src/org/simantics/sysdyn/unitParser/nodes/Arithmetic.java +++ b/org.simantics.sysdyn/src/org/simantics/sysdyn/unitParser/nodes/Arithmetic.java @@ -12,11 +12,13 @@ *******************************************************************************/ package org.simantics.sysdyn.unitParser.nodes; +import java.util.ArrayList; import java.util.HashMap; import org.simantics.sysdyn.unitParser.UnitCheckingException; import org.simantics.sysdyn.unitParser.UnitCheckingNode; import org.simantics.sysdyn.unitParser.nodes.UnitResult.UnitType; +import org.simantics.sysdyn.utils.Function; /** * See UnitCheckingNodeFactory for mapping @@ -32,7 +34,7 @@ public class Arithmetic extends UnitCheckingNode { @Override - public UnitResult getUnits(HashMap units, boolean allowEquivalents) throws UnitCheckingException { + public UnitResult getUnits(HashMap units, ArrayList functions, boolean allowEquivalents) throws UnitCheckingException { UnitResult result = new UnitResult(allowEquivalents); UnitCheckingNode base = null; @@ -41,12 +43,12 @@ public class Arithmetic extends UnitCheckingNode { for(int i = 0; i < jjtGetNumChildren(); i++) { candidateNode = ((UnitCheckingNode)jjtGetChild(i)); - UnitResult candidateUnits = candidateNode.getUnits(units, allowEquivalents); + UnitResult candidateUnits = candidateNode.getUnits(units, functions, allowEquivalents); if(candidateUnits.getUnitType() == UnitType.OPERATOR) { continue; } else if(base == null || result.getUnitType() == UnitType.SCALAR || result.getUnitType() == UnitType.ANY) { base = ((UnitCheckingNode)jjtGetChild(i)); - result.appendResult(base.getUnits(units, allowEquivalents)); + result.appendResult(base.getUnits(units, functions, allowEquivalents)); continue; } else if(candidateUnits.getUnitType() == UnitType.SCALAR) { continue; diff --git a/org.simantics.sysdyn/src/org/simantics/sysdyn/unitParser/nodes/ArrayDefinition.java b/org.simantics.sysdyn/src/org/simantics/sysdyn/unitParser/nodes/ArrayDefinition.java index 7b300b21..9754bd3e 100644 --- a/org.simantics.sysdyn/src/org/simantics/sysdyn/unitParser/nodes/ArrayDefinition.java +++ b/org.simantics.sysdyn/src/org/simantics/sysdyn/unitParser/nodes/ArrayDefinition.java @@ -18,6 +18,7 @@ import java.util.HashMap; import org.simantics.sysdyn.unitParser.UnitCheckingException; import org.simantics.sysdyn.unitParser.UnitCheckingNode; import org.simantics.sysdyn.unitParser.nodes.UnitResult.UnitType; +import org.simantics.sysdyn.utils.Function; /** * See UnitCheckingNodeFactory for mapping @@ -33,7 +34,7 @@ public class ArrayDefinition extends UnitCheckingNode { @Override - public UnitResult getUnits(HashMap units, boolean allowEquivalents) throws UnitCheckingException { + public UnitResult getUnits(HashMap units, ArrayList functions, boolean allowEquivalents) throws UnitCheckingException { UnitResult result = new UnitResult(allowEquivalents); result.setUnitType(UnitType.SCALAR); @@ -43,13 +44,13 @@ public class ArrayDefinition extends UnitCheckingNode { FunctionArguments functionArguments = (FunctionArguments) jjtGetChild(0); for(UnitCheckingNode candidateNode : gatherExpressions(functionArguments, new ArrayList())) { - UnitResult candidateUnits = candidateNode.getUnits(units, allowEquivalents); + UnitResult candidateUnits = candidateNode.getUnits(units, functions, allowEquivalents); if(candidateUnits.getUnitType() == UnitType.SCALAR) { continue; } else if(base == null) { base = candidateNode; UnitType oldUnitType = result.getUnitType(); - result.appendResult(base.getUnits(units, allowEquivalents)); + result.appendResult(base.getUnits(units, functions, allowEquivalents)); /* * Make sure unit type persist diff --git a/org.simantics.sysdyn/src/org/simantics/sysdyn/unitParser/nodes/ComponentReferenceFull.java b/org.simantics.sysdyn/src/org/simantics/sysdyn/unitParser/nodes/ComponentReferenceFull.java index c110fcb2..21b01648 100644 --- a/org.simantics.sysdyn/src/org/simantics/sysdyn/unitParser/nodes/ComponentReferenceFull.java +++ b/org.simantics.sysdyn/src/org/simantics/sysdyn/unitParser/nodes/ComponentReferenceFull.java @@ -13,6 +13,7 @@ package org.simantics.sysdyn.unitParser.nodes; import java.io.StringReader; +import java.util.ArrayList; import java.util.HashMap; import org.simantics.sysdyn.unitParser.ParseException; @@ -20,6 +21,7 @@ import org.simantics.sysdyn.unitParser.UnitCheckingException; import org.simantics.sysdyn.unitParser.UnitCheckingNode; import org.simantics.sysdyn.unitParser.UnitParser; import org.simantics.sysdyn.unitParser.nodes.UnitResult.UnitType; +import org.simantics.sysdyn.utils.Function; /** * See UnitCheckingNodeFactory for mapping @@ -33,12 +35,12 @@ public class ComponentReferenceFull extends UnitCheckingNode { super(id); } - protected UnitResult parseUnits(String units, boolean allowEquivalents) { + protected UnitResult parseUnits(String units, ArrayList functions, boolean allowEquivalents) { StringReader sr = new StringReader(units); UnitParser parser = new UnitParser(sr); try { UnitCheckingNode node = (UnitCheckingNode) parser.expr(); - return node.getUnits(null, allowEquivalents); + return node.getUnits(null, functions, allowEquivalents); } catch (ParseException e) { e.printStackTrace(); } catch (UnitCheckingException e) { @@ -48,7 +50,7 @@ public class ComponentReferenceFull extends UnitCheckingNode { } @Override - public UnitResult getUnits(HashMap units, boolean allowEquivalents) throws UnitCheckingException { + public UnitResult getUnits(HashMap units, ArrayList functions, boolean allowEquivalents) throws UnitCheckingException { String node = printNode(); if("dmnl".equals(node)) { @@ -61,7 +63,7 @@ public class ComponentReferenceFull extends UnitCheckingNode { if(!units.containsKey(node) || units.get(node) == null) throw new UnitCheckingException("No units defined for " + node); else { - return parseUnits(units.get(node), allowEquivalents); + return parseUnits(units.get(node), functions, allowEquivalents); } } else { UnitResult result = new UnitResult(allowEquivalents); diff --git a/org.simantics.sysdyn/src/org/simantics/sysdyn/unitParser/nodes/Divide.java b/org.simantics.sysdyn/src/org/simantics/sysdyn/unitParser/nodes/Divide.java index 2c090ea2..c2061059 100644 --- a/org.simantics.sysdyn/src/org/simantics/sysdyn/unitParser/nodes/Divide.java +++ b/org.simantics.sysdyn/src/org/simantics/sysdyn/unitParser/nodes/Divide.java @@ -12,11 +12,13 @@ *******************************************************************************/ package org.simantics.sysdyn.unitParser.nodes; +import java.util.ArrayList; import java.util.HashMap; import org.simantics.sysdyn.unitParser.UnitCheckingException; import org.simantics.sysdyn.unitParser.UnitCheckingNode; import org.simantics.sysdyn.unitParser.nodes.UnitResult.UnitType; +import org.simantics.sysdyn.utils.Function; /** * See UnitCheckingNodeFactory for mapping @@ -31,8 +33,8 @@ public class Divide extends UnitCheckingNode { } @Override - public UnitResult getUnits(HashMap units, boolean allowEquivalents) throws UnitCheckingException { - UnitResult result = super.getUnits(units, allowEquivalents); + public UnitResult getUnits(HashMap units, ArrayList functions, boolean allowEquivalents) throws UnitCheckingException { + UnitResult result = super.getUnits(units, functions, allowEquivalents); result.setUnitType(UnitType.OPERATOR); return result; } diff --git a/org.simantics.sysdyn/src/org/simantics/sysdyn/unitParser/nodes/Factor.java b/org.simantics.sysdyn/src/org/simantics/sysdyn/unitParser/nodes/Factor.java index 369f67b6..fc92f871 100644 --- a/org.simantics.sysdyn/src/org/simantics/sysdyn/unitParser/nodes/Factor.java +++ b/org.simantics.sysdyn/src/org/simantics/sysdyn/unitParser/nodes/Factor.java @@ -12,12 +12,14 @@ *******************************************************************************/ package org.simantics.sysdyn.unitParser.nodes; +import java.util.ArrayList; import java.util.HashMap; import org.simantics.sysdyn.unitParser.Token; import org.simantics.sysdyn.unitParser.UnitCheckingException; import org.simantics.sysdyn.unitParser.UnitCheckingNode; import org.simantics.sysdyn.unitParser.nodes.UnitResult.UnitType; +import org.simantics.sysdyn.utils.Function; /** * See UnitCheckingNodeFactory for mapping @@ -32,7 +34,7 @@ public class Factor extends UnitCheckingNode { } @Override - public UnitResult getUnits(HashMap units, boolean allowEquivalents) throws UnitCheckingException { + public UnitResult getUnits(HashMap units, ArrayList functions, boolean allowEquivalents) throws UnitCheckingException { UnitResult result = new UnitResult(allowEquivalents); UnitCheckingNode current = null; @@ -41,7 +43,7 @@ public class Factor extends UnitCheckingNode { for(int i = 0; i < jjtGetNumChildren(); i++) { current = ((UnitCheckingNode)jjtGetChild(i)); - UnitResult currentUnits = current.getUnits(units, allowEquivalents); + UnitResult currentUnits = current.getUnits(units, functions, allowEquivalents); if(currentUnits.getUnitType() == UnitType.ANY) { result = new UnitResult(allowEquivalents); @@ -59,7 +61,7 @@ public class Factor extends UnitCheckingNode { UnitType unitType = currentUnits.getUnitType(); if(unitType == UnitType.SCALAR) { int exponent; - UnitResult baseUnits = base.getUnits(units, allowEquivalents); + UnitResult baseUnits = base.getUnits(units, functions, allowEquivalents); try { exponent = Integer.valueOf(currentUnits.getFullUnit()); } catch (NumberFormatException e) { diff --git a/org.simantics.sysdyn/src/org/simantics/sysdyn/unitParser/nodes/ForIndex.java b/org.simantics.sysdyn/src/org/simantics/sysdyn/unitParser/nodes/ForIndex.java index 4a185f7b..40889a10 100644 --- a/org.simantics.sysdyn/src/org/simantics/sysdyn/unitParser/nodes/ForIndex.java +++ b/org.simantics.sysdyn/src/org/simantics/sysdyn/unitParser/nodes/ForIndex.java @@ -12,10 +12,12 @@ *******************************************************************************/ package org.simantics.sysdyn.unitParser.nodes; +import java.util.ArrayList; import java.util.HashMap; import org.simantics.sysdyn.unitParser.UnitCheckingException; import org.simantics.sysdyn.unitParser.UnitCheckingNode; +import org.simantics.sysdyn.utils.Function; /** * See UnitCheckingNodeFactory for mapping @@ -30,7 +32,7 @@ public class ForIndex extends UnitCheckingNode { } @Override - public UnitResult getUnits(HashMap units, boolean allowEquivalents) throws UnitCheckingException { + public UnitResult getUnits(HashMap units, ArrayList functions, boolean allowEquivalents) throws UnitCheckingException { return new UnitResult(allowEquivalents); } diff --git a/org.simantics.sysdyn/src/org/simantics/sysdyn/unitParser/nodes/FunctionCall.java b/org.simantics.sysdyn/src/org/simantics/sysdyn/unitParser/nodes/FunctionCall.java index a99be2ec..fb04557a 100644 --- a/org.simantics.sysdyn/src/org/simantics/sysdyn/unitParser/nodes/FunctionCall.java +++ b/org.simantics.sysdyn/src/org/simantics/sysdyn/unitParser/nodes/FunctionCall.java @@ -12,11 +12,13 @@ *******************************************************************************/ package org.simantics.sysdyn.unitParser.nodes; +import java.util.ArrayList; import java.util.HashMap; import org.simantics.sysdyn.unitParser.UnitCheckingException; import org.simantics.sysdyn.unitParser.UnitCheckingNode; import org.simantics.sysdyn.unitParser.nodes.UnitResult.UnitType; +import org.simantics.sysdyn.utils.Function; /** * See UnitCheckingNodeFactory for mapping @@ -31,7 +33,7 @@ public class FunctionCall extends UnitCheckingNode { } @Override - public UnitResult getUnits(HashMap units, boolean allowEquivalents) throws UnitCheckingException { + public UnitResult getUnits(HashMap units, ArrayList functions, boolean allowEquivalents) throws UnitCheckingException { UnitResult result = new UnitResult(allowEquivalents); result.setUnitType(UnitType.ANY); return result; diff --git a/org.simantics.sysdyn/src/org/simantics/sysdyn/unitParser/nodes/IfThenElse.java b/org.simantics.sysdyn/src/org/simantics/sysdyn/unitParser/nodes/IfThenElse.java index 4234acaa..05c36d9b 100644 --- a/org.simantics.sysdyn/src/org/simantics/sysdyn/unitParser/nodes/IfThenElse.java +++ b/org.simantics.sysdyn/src/org/simantics/sysdyn/unitParser/nodes/IfThenElse.java @@ -12,10 +12,12 @@ *******************************************************************************/ package org.simantics.sysdyn.unitParser.nodes; +import java.util.ArrayList; import java.util.HashMap; import org.simantics.sysdyn.unitParser.UnitCheckingException; import org.simantics.sysdyn.unitParser.UnitCheckingNode; +import org.simantics.sysdyn.utils.Function; /** * See UnitCheckingNodeFactory for mapping @@ -31,14 +33,14 @@ public class IfThenElse extends UnitCheckingNode { @Override - public UnitResult getUnits(HashMap units, boolean allowEquivalents) throws UnitCheckingException { + public UnitResult getUnits(HashMap units, ArrayList functions, boolean allowEquivalents) throws UnitCheckingException { UnitResult base = null; UnitCheckingNode baseNode = null; UnitCheckingNode candidateNode = null; for(int i = 0; i < jjtGetNumChildren(); i++) { candidateNode = ((UnitCheckingNode)jjtGetChild(i)); - UnitResult candidateUnits = candidateNode.getUnits(units, allowEquivalents); + UnitResult candidateUnits = candidateNode.getUnits(units, functions, allowEquivalents); if(!(candidateNode instanceof Condition)) { diff --git a/org.simantics.sysdyn/src/org/simantics/sysdyn/unitParser/nodes/Multiplication.java b/org.simantics.sysdyn/src/org/simantics/sysdyn/unitParser/nodes/Multiplication.java index 43b13aae..57f28f79 100644 --- a/org.simantics.sysdyn/src/org/simantics/sysdyn/unitParser/nodes/Multiplication.java +++ b/org.simantics.sysdyn/src/org/simantics/sysdyn/unitParser/nodes/Multiplication.java @@ -12,11 +12,13 @@ *******************************************************************************/ package org.simantics.sysdyn.unitParser.nodes; +import java.util.ArrayList; import java.util.HashMap; import org.simantics.sysdyn.unitParser.UnitCheckingException; import org.simantics.sysdyn.unitParser.UnitCheckingNode; import org.simantics.sysdyn.unitParser.nodes.UnitResult.UnitType; +import org.simantics.sysdyn.utils.Function; /** * See UnitCheckingNodeFactory for mapping @@ -31,8 +33,8 @@ public class Multiplication extends UnitCheckingNode { } @Override - public UnitResult getUnits(HashMap units, boolean allowEquivalents) throws UnitCheckingException { - UnitResult result = super.getUnits(units, allowEquivalents); + public UnitResult getUnits(HashMap units, ArrayList functions, boolean allowEquivalents) throws UnitCheckingException { + UnitResult result = super.getUnits(units, functions, allowEquivalents); result.setUnitType(UnitType.OPERATOR); return result; } diff --git a/org.simantics.sysdyn/src/org/simantics/sysdyn/unitParser/nodes/Power.java b/org.simantics.sysdyn/src/org/simantics/sysdyn/unitParser/nodes/Power.java index ab1d9adf..8d90de3a 100644 --- a/org.simantics.sysdyn/src/org/simantics/sysdyn/unitParser/nodes/Power.java +++ b/org.simantics.sysdyn/src/org/simantics/sysdyn/unitParser/nodes/Power.java @@ -11,11 +11,13 @@ *******************************************************************************/ package org.simantics.sysdyn.unitParser.nodes; +import java.util.ArrayList; import java.util.HashMap; import org.simantics.sysdyn.unitParser.UnitCheckingException; import org.simantics.sysdyn.unitParser.UnitCheckingNode; import org.simantics.sysdyn.unitParser.nodes.UnitResult.UnitType; +import org.simantics.sysdyn.utils.Function; /** * See UnitCheckingNodeFactory for mapping @@ -29,8 +31,8 @@ public class Power extends UnitCheckingNode { } @Override - public UnitResult getUnits(HashMap units, boolean allowEquivalents) throws UnitCheckingException { - UnitResult result = super.getUnits(units, allowEquivalents); + public UnitResult getUnits(HashMap units, ArrayList functions, boolean allowEquivalents) throws UnitCheckingException { + UnitResult result = super.getUnits(units, functions, allowEquivalents); result.setUnitType(UnitType.OPERATOR); return result; } diff --git a/org.simantics.sysdyn/src/org/simantics/sysdyn/unitParser/nodes/RelOp.java b/org.simantics.sysdyn/src/org/simantics/sysdyn/unitParser/nodes/RelOp.java index d7a62ade..56b4138f 100644 --- a/org.simantics.sysdyn/src/org/simantics/sysdyn/unitParser/nodes/RelOp.java +++ b/org.simantics.sysdyn/src/org/simantics/sysdyn/unitParser/nodes/RelOp.java @@ -12,11 +12,13 @@ *******************************************************************************/ package org.simantics.sysdyn.unitParser.nodes; +import java.util.ArrayList; import java.util.HashMap; import org.simantics.sysdyn.unitParser.UnitCheckingException; import org.simantics.sysdyn.unitParser.UnitCheckingNode; import org.simantics.sysdyn.unitParser.nodes.UnitResult.UnitType; +import org.simantics.sysdyn.utils.Function; /** * See UnitCheckingNodeFactory for mapping @@ -31,8 +33,8 @@ public class RelOp extends UnitCheckingNode { } @Override - public UnitResult getUnits(HashMap units, boolean allowEquivalents) throws UnitCheckingException { - UnitResult result = super.getUnits(units, allowEquivalents); + public UnitResult getUnits(HashMap units, ArrayList functions, boolean allowEquivalents) throws UnitCheckingException { + UnitResult result = super.getUnits(units, functions, allowEquivalents); result.setUnitType(UnitType.OPERATOR); return result; } diff --git a/org.simantics.sysdyn/src/org/simantics/sysdyn/unitParser/nodes/Relation.java b/org.simantics.sysdyn/src/org/simantics/sysdyn/unitParser/nodes/Relation.java index 2fd22f3b..5831092b 100644 --- a/org.simantics.sysdyn/src/org/simantics/sysdyn/unitParser/nodes/Relation.java +++ b/org.simantics.sysdyn/src/org/simantics/sysdyn/unitParser/nodes/Relation.java @@ -12,10 +12,12 @@ *******************************************************************************/ package org.simantics.sysdyn.unitParser.nodes; +import java.util.ArrayList; import java.util.HashMap; import org.simantics.sysdyn.unitParser.UnitCheckingException; import org.simantics.sysdyn.unitParser.UnitCheckingNode; +import org.simantics.sysdyn.utils.Function; /** * See UnitCheckingNodeFactory for mapping @@ -30,7 +32,7 @@ public class Relation extends UnitCheckingNode { } @Override - public UnitResult getUnits(HashMap units, boolean allowEquivalents) throws UnitCheckingException { + public UnitResult getUnits(HashMap units, ArrayList functions, boolean allowEquivalents) throws UnitCheckingException { UnitResult result = new UnitResult(allowEquivalents); UnitCheckingNode base = null; @@ -42,14 +44,14 @@ public class Relation extends UnitCheckingNode { base = ((UnitCheckingNode)jjtGetChild(1)); if(base instanceof Arithmetic) { - result.appendResult(base.getUnits(units, allowEquivalents)); + result.appendResult(base.getUnits(units, functions, allowEquivalents)); for(int i = 2; i < jjtGetNumChildren(); i = i + 2) { candidateNode = ((UnitCheckingNode)jjtGetChild(i)); if(!(candidateNode instanceof Value)) { operator = ((UnitCheckingNode)jjtGetChild(i-1)); - UnitResult candidateUnits = candidateNode.getUnits(units, allowEquivalents); + UnitResult candidateUnits = candidateNode.getUnits(units, functions, allowEquivalents); if(!result.equals(candidateUnits)) { result.equals(candidateUnits); throw new UnitCheckingException("Not equals exception: " + diff --git a/org.simantics.sysdyn/src/org/simantics/sysdyn/unitParser/nodes/Term.java b/org.simantics.sysdyn/src/org/simantics/sysdyn/unitParser/nodes/Term.java index 344cf7eb..dfdcc54e 100644 --- a/org.simantics.sysdyn/src/org/simantics/sysdyn/unitParser/nodes/Term.java +++ b/org.simantics.sysdyn/src/org/simantics/sysdyn/unitParser/nodes/Term.java @@ -12,12 +12,14 @@ *******************************************************************************/ package org.simantics.sysdyn.unitParser.nodes; +import java.util.ArrayList; import java.util.HashMap; import org.simantics.sysdyn.unitParser.Token; import org.simantics.sysdyn.unitParser.UnitCheckingException; import org.simantics.sysdyn.unitParser.UnitCheckingNode; import org.simantics.sysdyn.unitParser.nodes.UnitResult.UnitType; +import org.simantics.sysdyn.utils.Function; /** * See UnitCheckingNodeFactory for mapping @@ -32,7 +34,7 @@ public class Term extends UnitCheckingNode { } @Override - public UnitResult getUnits(HashMap units, boolean allowEquivalents) throws UnitCheckingException { + public UnitResult getUnits(HashMap units, ArrayList functions, boolean allowEquivalents) throws UnitCheckingException { UnitResult result = new UnitResult(allowEquivalents); UnitCheckingNode current = null; @@ -41,7 +43,7 @@ public class Term extends UnitCheckingNode { for(int i = 0; i < jjtGetNumChildren(); i++) { current = ((UnitCheckingNode)jjtGetChild(i)); - UnitResult currentUnits = current.getUnits(units, allowEquivalents); + UnitResult currentUnits = current.getUnits(units, functions, allowEquivalents); if(currentUnits.getUnitType() == UnitType.ANY) { result = new UnitResult(allowEquivalents); diff --git a/org.simantics.sysdyn/src/org/simantics/sysdyn/unitParser/nodes/Value.java b/org.simantics.sysdyn/src/org/simantics/sysdyn/unitParser/nodes/Value.java index 7e26c569..e0edb445 100644 --- a/org.simantics.sysdyn/src/org/simantics/sysdyn/unitParser/nodes/Value.java +++ b/org.simantics.sysdyn/src/org/simantics/sysdyn/unitParser/nodes/Value.java @@ -12,11 +12,13 @@ *******************************************************************************/ package org.simantics.sysdyn.unitParser.nodes; +import java.util.ArrayList; import java.util.HashMap; import org.simantics.sysdyn.unitParser.UnitCheckingException; import org.simantics.sysdyn.unitParser.UnitCheckingNode; import org.simantics.sysdyn.unitParser.nodes.UnitResult.UnitType; +import org.simantics.sysdyn.utils.Function; /** * See UnitCheckingNodeFactory for mapping @@ -31,8 +33,8 @@ public class Value extends UnitCheckingNode { } @Override - public UnitResult getUnits(HashMap units, boolean allowEquivalents) throws UnitCheckingException { - UnitResult result = super.getUnits(units, allowEquivalents); + public UnitResult getUnits(HashMap units, ArrayList functions, boolean allowEquivalents) throws UnitCheckingException { + UnitResult result = super.getUnits(units, functions, allowEquivalents); result.setUnitType(UnitType.SCALAR); return result; } diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/expressions/Function.java b/org.simantics.sysdyn/src/org/simantics/sysdyn/utils/Function.java similarity index 72% rename from org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/expressions/Function.java rename to org.simantics.sysdyn/src/org/simantics/sysdyn/utils/Function.java index 6ddacd64..b01c62f6 100644 --- a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/expressions/Function.java +++ b/org.simantics.sysdyn/src/org/simantics/sysdyn/utils/Function.java @@ -1,12 +1,8 @@ -package org.simantics.sysdyn.ui.properties.widgets.expressions; +package org.simantics.sysdyn.utils; import java.util.ArrayList; import java.util.Collection; -import org.eclipse.jface.resource.ImageDescriptor; -import org.eclipse.jface.resource.LocalResourceManager; -import org.eclipse.swt.graphics.Device; -import org.eclipse.swt.graphics.Image; import org.simantics.databoard.Bindings; import org.simantics.db.ReadGraph; import org.simantics.db.Resource; @@ -17,7 +13,6 @@ import org.simantics.db.exception.DatabaseException; import org.simantics.db.request.Read; import org.simantics.layer0.Layer0; import org.simantics.sysdyn.SysdynResource; -import org.simantics.sysdyn.ui.Activator; import org.simantics.ui.SimanticsUI; @@ -34,6 +29,12 @@ public class Function implements Comparable{ private final String parameterList; private final String description; + public static class Parameter { + public String name; + public String unit = "1"; + public boolean variableLength = false; + } + public enum Type { USER_DEFINED, SHARED, @@ -43,64 +44,14 @@ public class Function implements Comparable{ VENSIM } - /** - * Get the icon image for each type of Modelica function. - * @param rm LocalResourceManager for which the image is created. - * @param function Modelica function - * @return Image to be shown e.g. in assistive text feed and ShortcutTab - */ - public static Image getImage(LocalResourceManager rm, Function function) { - switch (function.getType()) { - case USER_DEFINED: - return rm.createImage(ImageDescriptor.createFromURL(Activator.getDefault().getBundle().getResource("icons/function.png"))); - case SHARED: - return rm.createImage(ImageDescriptor.createFromURL(Activator.getDefault().getBundle().getResource("icons/functionLink.png"))); - case VENSIM: - return rm.createImage(ImageDescriptor.createFromURL(Activator.getDefault().getBundle().getResource("icons/vensimFunction.png"))); - case SYSDYN: - return rm.createImage(ImageDescriptor.createFromURL(Activator.getDefault().getBundle().getResource("icons/sysdynFunction.png"))); - case MODELICA: - return rm.createImage(ImageDescriptor.createFromURL(Activator.getDefault().getBundle().getResource("icons/modelicaFunction.png"))); - case MODELICA_ARRAY: - return rm.createImage(ImageDescriptor.createFromURL(Activator.getDefault().getBundle().getResource("icons/modelicaArrayFunction.png"))); - default: - return null; - } - } - - /** - * Get the icon image for each type of Modelica function. - * @param device Device for which the image is used. - * @param function Modelica function - * @return Image to be shown e.g. in assistive text feed and ShortcutTab - */ - @Deprecated - public static Image getImage(Device device, Function function) { - switch (function.getType()) { - case USER_DEFINED: - return ImageDescriptor.createFromURL(Activator.getDefault().getBundle().getResource("icons/function.png")).createImage(device); - case SHARED: - return ImageDescriptor.createFromURL(Activator.getDefault().getBundle().getResource("icons/functionLink.png")).createImage(device); - case VENSIM: - return ImageDescriptor.createFromURL(Activator.getDefault().getBundle().getResource("icons/vensimFunction.png")).createImage(device); - case SYSDYN: - return ImageDescriptor.createFromURL(Activator.getDefault().getBundle().getResource("icons/sysdynFunction.png")).createImage(device); - case MODELICA: - return ImageDescriptor.createFromURL(Activator.getDefault().getBundle().getResource("icons/modelicaFunction.png")).createImage(device); - case MODELICA_ARRAY: - return ImageDescriptor.createFromURL(Activator.getDefault().getBundle().getResource("icons/modelicaArrayFunction.png")).createImage(device); - default: - return null; - } - } - - public Function(String name, String parameterList, Type type, String description){ + public Function(String name, ArrayList parameterList, Type type, String description){ this.name = new String(name); this.type = type; - if (parameterList != null) - this.parameterList = new String(parameterList); + String parameterListString = parameterListToString(parameterList); + if (parameterListString != null) + this.parameterList = new String(parameterListString); else this.parameterList = new String(""); @@ -109,6 +60,17 @@ public class Function implements Comparable{ else this.description = null; } + + public static String parameterListToString(ArrayList parameterList) { + String inputStr = null; + for (Parameter p : parameterList) { + if (inputStr == null) + inputStr = new String(p.name); + else + inputStr += ", " + p.name; + } + return inputStr; + } public String getParameterList() { return parameterList; @@ -141,34 +103,33 @@ public class Function implements Comparable{ * @return String in which the paramters are ", " delimited * @throws DatabaseException */ - public static String getFunctionInputs(ReadGraph graph, SysdynResource sr, Resource r) throws DatabaseException { + public static ArrayList getFunctionInputs(ReadGraph graph, SysdynResource sr, Resource r) throws DatabaseException { Resource inputs = graph.getPossibleObject(r, sr.SysdynModelicaFunction_inputs); - String inputStr = null; + ArrayList inputParameters = new ArrayList(); if (inputs != null) { for (Resource input : ListUtils.toList(graph, inputs)) { - String inputName = null; + Parameter inputParameter = new Parameter(); if (graph.isInstanceOf(input, sr.SysdynModelicaFunction_VariableLengthInput)) { - inputName = ""; + inputParameter.name = ""; + inputParameter.variableLength = true; Resource shownLabels = graph.getPossibleObject( input, sr.SysdynModelicaFunction_VariableLengthInput_shownLabels); if (shownLabels != null) { for (Resource label : ListUtils.toList(graph, shownLabels)) { - inputName += NameUtils.getSafeName(graph, label); - inputName += ", "; + inputParameter.name += NameUtils.getSafeName(graph, label); + inputParameter.name += ", "; } } - inputName += "..."; + inputParameter.name += "..."; } else { - inputName = NameUtils.getSafeName(graph, input); + inputParameter.name = NameUtils.getSafeName(graph, input); } - if (inputStr == null) - inputStr = new String(inputName); - else - inputStr += ", " + inputName; + + inputParameters.add(inputParameter); } } - return inputStr; + return inputParameters; } public static String getFunctionDescription(ReadGraph graph, Resource r) throws DatabaseException { @@ -191,9 +152,9 @@ public class Function implements Comparable{ Resource functionLibrary = graph.getPossibleResource(functionTypeUri); for(Resource r : graph.syncRequest(new ObjectsWithType(functionLibrary, l0.ConsistsOf, sr.SysdynModelicaFunction))) { String name = NameUtils.getSafeName(graph, r); - String inputStr = getFunctionInputs(graph, sr, r); + ArrayList inputs = getFunctionInputs(graph, sr, r); String description = getFunctionDescription(graph, r); - functions.add(new Function(name, inputStr, functionType, description)); + functions.add(new Function(name, inputs, functionType, description)); } return functions; } -- 2.47.1