Linux GNU 11.4.0 Code Coverage Report


Directory: ./
Coverage: low: ≥ 0% medium: ≥ 75.0% high: ≥ 90.0%
Coverage Exec / Excl / Total
Lines: 41.2% 93 / 0 / 226
Functions: -% 0 / 1 / 1
Branches: 26.9% 7 / 0 / 26

OMCompiler/Compiler/BackEnd/MathematicaDump.mo
Line Branch Exec Source
1 /*
2 * This file is part of OpenModelica.
3 *
4 * Copyright (c) 1998-2026, Open Source Modelica Consortium (OSMC),
5 * c/o Linköpings universitet, Department of Computer and Information Science,
6 * SE-58183 Linköping, Sweden.
7 *
8 * All rights reserved.
9 *
10 * THIS PROGRAM IS PROVIDED UNDER THE TERMS OF AGPL VERSION 3 LICENSE OR
11 * THIS OSMC PUBLIC LICENSE (OSMC-PL) VERSION 1.8.
12 * ANY USE, REPRODUCTION OR DISTRIBUTION OF THIS PROGRAM CONSTITUTES
13 * RECIPIENT'S ACCEPTANCE OF THE OSMC PUBLIC LICENSE OR THE GNU AGPL
14 * VERSION 3, ACCORDING TO RECIPIENTS CHOICE.
15 *
16 * The OpenModelica software and the OSMC (Open Source Modelica Consortium)
17 * Public License (OSMC-PL) are obtained from OSMC, either from the above
18 * address, from the URLs:
19 * http://www.openmodelica.org or
20 * https://github.com/OpenModelica/ or
21 * http://www.ida.liu.se/projects/OpenModelica,
22 * and in the OpenModelica distribution.
23 *
24 * GNU AGPL version 3 is obtained from:
25 * https://www.gnu.org/licenses/licenses.html#GPL
26 *
27 * This program is distributed WITHOUT ANY WARRANTY; without
28 * even the implied warranty of MERCHANTABILITY or FITNESS
29 * FOR A PARTICULAR PURPOSE, EXCEPT AS EXPRESSLY SET FORTH
30 * IN THE BY RECIPIENT SELECTED SUBSIDIARY LICENSE CONDITIONS OF OSMC-PL.
31 *
32 * See the full OSMC Public License conditions for more details.
33 *
34 */
35
36 encapsulated package MathematicaDump
37
38 import Absyn;
39 import AbsynUtil;
40 import BackendDAE;
41 import BackendDump;
42 import BackendVariable;
43 import ComponentReference;
44 protected import ComponentReferenceBasics;
45 import DAE;
46 protected
47 import DAEDump;
48 import Expression;
49 protected import ExpressionBasics;
50 import ExpressionDump;
51 import IOStream;
52 import List;
53 import System;
54 import Util;
55 public function dumpMmaDAEStr "
56 Dumps the equations, initial equations variables and parameters on a form suitable
57 for reading into Mathematica"
58 input tuple<BackendDAE.Variables,BackendDAE.Variables,list<BackendDAE.Equation>,list<BackendDAE.Equation>> inTuple "(vars, knvars, eqsn, ieqns)";
59 output String res;
60 algorithm
61 res := match inTuple
62 local
63 BackendDAE.Variables vars,knvars;
64 list<BackendDAE.Equation> eqns,ieqns;
65 String allVarStr,s1_1,s1_2,s1_3,s1_4,s1_5,s3,s4;
66 list<String> params,inputs,states,algs,outputs;
67 case (vars,knvars,eqns,ieqns) algorithm
68
69 ✗ (states,algs,outputs,_) := printMmaVarsStr(vars);
70 ✗ (params,inputs) := printMmaParamsStr(knvars);
71 //inputs = listAppend(inputs,inputsStates); This should not happen, if a input is used as a state, index reduction should be active!
72 ✗ s1_1 := Util.stringDelimitListNonEmptyElts(states,",");
73 //print(" states: " + s1_1 + "\n");
74 ✗ s1_2 := Util.stringDelimitListNonEmptyElts(algs,",");
75 //print(" algs: " + s1_2 + "\n");
76 ✗ s1_3 := Util.stringDelimitListNonEmptyElts(outputs,",");
77 //print(" outputs: " + s1_3 + "\n");
78 ✗ s1_4 := Util.stringDelimitListNonEmptyElts(inputs,",");
79 //print(" inputs: " + s1_4 + "\n");
80 ✗ s1_5 := Util.stringDelimitListNonEmptyElts(params,",");
81 //print(" params: " + s1_5 + "\n");
82 ✗ allVarStr := "{{" + s1_1 + "},{" + s1_2 + "},{" + s1_3 + "},{" + s1_4 + "},{" + s1_5 + "}}";
83 //print(" vars: " + allVarStr + "\n");
84
85 ✗ s3 := printMmaEqnsStr(eqns,(vars,knvars));
86 ✗ s4 := printMmaEqnsStr(ieqns,(vars,knvars));
87 ✗ res := stringAppendList({"{",allVarStr,",",s3,",",s4,"}"});
88 //print(" Eqns-1-: " + s3 + "\n");
89 //print(" Eqns-2-: " + s4 + "\n");
90 then res;
91 end match;
92 end dumpMmaDAEStr;
93
94 public function printMmaEqnsStr "print equations on a form suitable for Mathematica to a string."
95 input list<BackendDAE.Equation> inEqns;
96 input tuple<BackendDAE.Variables,BackendDAE.Variables> inTuple;
97 output String res;
98 algorithm
99 res := match inEqns
100 local
101 String s1;
102 list<BackendDAE.Equation> eqns;
103 case eqns algorithm
104 28 s1 := Util.stringDelimitListNonEmptyElts(List.map1(eqns,printMmaEqnStr,inTuple),",");
105 28 res := stringAppendList({"{",s1,"}"});
106 then res;
107 end match;
108 end printMmaEqnsStr;
109
110 public function printMmaEqnStr "help function to printMmaEqnsStr"
111 input BackendDAE.Equation eqn;
112 input tuple<BackendDAE.Variables,BackendDAE.Variables> inTuple "required to find array eqns and algorithms";
113 output String str;
114 algorithm
115 str := match(eqn,inTuple)
116 local DAE.Exp e1,e2;
117 DAE.ComponentRef cr;
118 BackendDAE.Variables vars,knvars;
119 String s1,s2;
120 DAE.Algorithm alg;
121 BackendDAE.WhenEquation whenEq;
122
123 case(BackendDAE.EQUATION(exp=e1,scalar=e2),(vars,knvars)) algorithm
124 937 s1 := printExpMmaStr(e1,vars,knvars);
125 937 s2 := printExpMmaStr(e2,vars,knvars);
126 937 str := stringAppendList({s1,"==",s2});
127 then str;
128 case(BackendDAE.SOLVED_EQUATION(componentRef=cr,exp=e2),(vars,knvars)) algorithm
129 32 s1 := printComponentRefMmaStr(cr,vars,knvars);
130 32 s2 := printExpMmaStr(e2,vars,knvars);
131 32 str := stringAppendList({s1,"==",s2});
132 then str;
133 case(BackendDAE.ARRAY_EQUATION(left=e1,right=e2),(vars,knvars)) algorithm
134 ✗ s1 := printExpMmaStr(e1,vars,knvars);
135 ✗ s2 := printExpMmaStr(e2,vars,knvars);
136 ✗ str := stringAppendList({s1,"==",s2});
137 then str;
138 case(BackendDAE.RESIDUAL_EQUATION(exp = e1),(vars,knvars)) algorithm
139 ✗ s1 := printExpMmaStr(e1,vars,knvars);
140 ✗ str := stringAppendList({s1,"== 0"});
141 then str;
142
143 case (BackendDAE.ALGORITHM(alg=alg),_) algorithm
144 ✗ str := "Missing[\"Algorithm\",\""+escapeMmaString(dumpSingleAlgorithmStr(alg))+"\"]";
145 then str;
146 case (BackendDAE.WHEN_EQUATION(whenEquation = whenEq),_) algorithm
147 ✗ str := "Missing[\"When\",\""+escapeMmaString(BackendDump.whenEquationString(whenEq, true))+"\"]";
148 then str;
149 case (BackendDAE.COMPLEX_EQUATION(left=e1,right=e2),(vars,knvars))
150 algorithm
151 536 s1 := printExpMmaStr(e1,vars,knvars);
152 536 s2 := printExpMmaStr(e2,vars,knvars);
153 536 str := stringAppendList({s1,"==",s2});
154 then str;
155 end match;
156 end printMmaEqnStr;
157
158
159 /* Printing of equations and variables on Mathematica format*/
160
161 public function printExpMmaStr "Prints an expression on format suitable for Mathematica to a string"
162 input DAE.Exp e;
163 input BackendDAE.Variables vars "Required since variables should be translated from a to a[t]";
164 input BackendDAE.Variables knvars "inputs and outputs should also have [t] suffixed";
165 output String s;
166 algorithm
167 9736 s := printExp2MmaStr(e,vars,knvars);
168 end printExpMmaStr;
169
170 protected function printExp2MmaStr "Helper function to printExpMmaStr"
171 input DAE.Exp inExp;
172 input BackendDAE.Variables vars;
173 input BackendDAE.Variables knvars;
174 output String outString;
175 algorithm
176 outString:=
177 matchcontinue inExp
178 local
179 String s,s_1,s1_1,s_2,s2_1,sym,s2,s3,s3_1,s4,s_3,ifstr,thenstr,elsestr,res,fs,argstr,s_4,s_5,res2,str,crstr,dimstr,expstr,iterstr,id;
180 Integer p,p1,p2,ival,i,pstart,pstop,pe1;
181 DAE.ComponentRef cr;
182 DAE.Exp e1,e2,e,f,start,stop,step,dim,exp,iterexp,c,t;
183 DAE.Operator op;
184 Absyn.Path fcn,path;
185 list<DAE.Exp> args,es;
186 Real x,x2;
187 String fname,s1;
188 String s_11;
189 list<list<DAE.Exp>> matrix;
190 list<DAE.Exp> ae1,expLst;
191 DAE.CallAttributes call_attr;
192 list<DAE.Subscript> subs;
193
194 //case (DAE.END(),_,_) then "-1"; // Part[exp,-1] Returns last element in Mathematica.
195 case DAE.ICONST(integer = i) algorithm
196 ✗ s := intString(i);
197 then s;
198 case DAE.RCONST(real = x) algorithm
199 2903 x2 := intReal(realInt(x));
200
2/2
✓ Branch 0 taken 237 times.
✓ Branch 1 taken 2666 times.
2903 true := realEq(x2,x);
201 2666 s := intString(realInt(x));
202 then s;
203
204 case DAE.RCONST(real = x)
205 algorithm
206 237 s := realString(x);
207 237 s := stringAppendList({"ToExpression[StringReplace[\"",s,"\",\"e\"->\"*1.0*10^\"]]"});
208 then
209 s;
210 case DAE.SCONST(string = s)
211 algorithm
212 ✗ s_1 := stringAppend("\"", s);
213 ✗ s_2 := stringAppend(s_1, "\"");
214 then
215 s_2;
216 case DAE.BCONST(bool = false) then "False";
217 case DAE.BCONST(bool = true) then "True";
218
219 case DAE.CREF(componentRef = cr) algorithm
220 12303 s := printComponentRefMmaStr(cr,vars,knvars);
221 then s;
222
223 case e as DAE.BINARY(exp1 = e1,operator = op,exp2 = e2)
224 algorithm
225 3095 sym := ExpressionDump.binopSymbol(op);
226 3095 s1 := printExp2MmaStr(e1,vars,knvars);
227 3095 s2 := printExp2MmaStr(e2,vars,knvars);
228 3095 p := ExpressionDump.expPriority(e);
229 3095 p1 := ExpressionDump.expPriority(e1);
230 3095 p2 := ExpressionDump.expPriority(e2);
231 3095 s1_1 := ExpressionDump.parenthesize(s1, p1, p,false);
232 3095 s2_1 := ExpressionDump.parenthesize(s2, p2, p,true);
233 3095 s := stringAppend(s1_1, sym);
234 3095 s_1 := stringAppend(s, s2_1);
235 then
236 s_1;
237
238 case e as DAE.UNARY(operator = op,exp = e1)
239 algorithm
240 546 sym := ExpressionDump.unaryopSymbol(op);
241 546 s := printExp2MmaStr(e1, vars,knvars);
242 546 p := ExpressionDump.expPriority(e);
243 546 p1 := ExpressionDump.expPriority(e1);
244 546 s_1 := ExpressionDump.parenthesize(s, p1, p,true);
245 546 s_2 := stringAppend(sym, s_1);
246 then
247 s_2;
248
249 case e as DAE.LBINARY(exp1 = e1,operator = op,exp2 = e2)
250 algorithm
251 ✗ sym := lbinopSymbolMma(op);
252 ✗ s1 := printExp2MmaStr(e1, vars,knvars);
253 ✗ s2 := printExp2MmaStr(e2, vars,knvars);
254 ✗ p := ExpressionDump.expPriority(e);
255 ✗ p1 := ExpressionDump.expPriority(e1);
256 ✗ p2 := ExpressionDump.expPriority(e2);
257 ✗ s1_1 := ExpressionDump.parenthesize(s1, p1, p,false);
258 ✗ s2_1 := ExpressionDump.parenthesize(s2, p2, p,true);
259 ✗ s := stringAppend(s1_1, sym);
260 ✗ s_1 := stringAppend(s, s2_1);
261 then
262 s_1;
263
264 case e as DAE.LUNARY(operator = op,exp = e1)
265 algorithm
266 ✗ sym := lunaryopSymbolMma(op);
267 ✗ s := printExp2MmaStr(e1, vars,knvars);
268 ✗ p := ExpressionDump.expPriority(e);
269 ✗ p1 := ExpressionDump.expPriority(e1);
270 ✗ s_1 := ExpressionDump.parenthesize(s, p1, p,true);
271 ✗ s_2 := stringAppend(sym, s_1);
272 then
273 s_2;
274
275 case e as DAE.RELATION(exp1 = e1,operator = op,exp2 = e2)
276 algorithm
277 1162 sym := relopSymbolMma(op);
278 1162 s1 := printExp2MmaStr(e1,vars,knvars);
279 1162 s2 := printExp2MmaStr(e2,vars,knvars);
280 1162 p := ExpressionDump.expPriority(e);
281 1162 p1 := ExpressionDump.expPriority(e1);
282 1162 s1_1 := ExpressionDump.parenthesize(s1, p1, p,false);
283 1162 s2_1 := ExpressionDump.parenthesize(s2, p1, p,true);
284 1162 s := stringAppend(s1_1, sym);
285 1162 s_1 := stringAppend(s, s2_1);
286 then
287 s_1;
288
289 case DAE.IFEXP(expCond = c,expThen = t,expElse = f)
290
291 algorithm
292 1162 ifstr := printExp2MmaStr(c,vars,knvars);
293 1162 thenstr := printExp2MmaStr(t,vars,knvars);
294 1162 elsestr := printExp2MmaStr(f,vars,knvars);
295 1162 res := stringAppendList({"If[ ",ifstr,", ",thenstr," ,",elsestr,"]"});
296 then
297 res;
298 case DAE.CALL(path = Absyn.IDENT("der"),expLst = {e})
299 algorithm
300 ✗ s_1 :=printExpMmaStr(e,vars,knvars);
301 ✗ s_2 := stringAppendList({"D[",s_1,",\\[FormalT]]"});
302 then s_2;
303
304 // Math functions in Modelica.Math checked against builtin functions
305 case DAE.CALL(Absyn.QUALIFIED("Modelica",Absyn.QUALIFIED("Math",path)),expLst,call_attr) algorithm
306 ✗ s := printExp2MmaStr(DAE.CALL(path,expLst,call_attr),vars,knvars);
307 then s;
308 case DAE.CALL(Absyn.FULLYQUALIFIED(Absyn.QUALIFIED("Modelica",Absyn.QUALIFIED("Math",path))),expLst,call_attr) algorithm
309 ✗ s := printExp2MmaStr(DAE.CALL(path,expLst,call_attr),vars,knvars);
310 then s;
311
312 case DAE.CALL(path = Absyn.IDENT(fname),expLst = expLst)
313 algorithm
314 ✗ s1 := printBuiltinMmaFunc(fname);
315 ✗ s_1 := stringDelimitList(List.map2(expLst,printExpMmaStr,vars,knvars),",");
316 ✗ s_2 := stringAppendList({s1,"[",s_1,"]"});
317 then s_2;
318
319 /* Special case for atan2 */
320 case DAE.CALL(path = Absyn.IDENT("atan2"),expLst = {e1,e2})
321
322 algorithm
323 ✗ s_1 :=printExpMmaStr(e1,vars,knvars);
324 ✗ s_11 :=printExpMmaStr(e2,vars,knvars);
325 ✗ s_2 := stringAppendList({"ArcTan[",s_1,",",s_11,"]"});
326 then s_2;
327
328 /* Special case for log10 */
329 case DAE.CALL(path = Absyn.IDENT("log10"),expLst = {e1})
330 algorithm
331 ✗ s_1 :=printExpMmaStr(e1,vars,knvars);
332 ✗ s_2 := stringAppendList({"Log[",s_1,",10]"});
333 then s_2;
334 case DAE.CALL(path = fcn,expLst = args)
335 algorithm
336 615 fs := AbsynUtil.pathString(fcn);
337 615 fs := translateKnownMmaFuncs(fs); // can fail
338 ✗ argstr := stringDelimitList(List.map2(args, printExpMmaStr,vars,knvars),",");
339 ✗ s := stringAppend(fs, "[");
340 ✗ s_1 := stringAppend(s, argstr);
341 ✗ s_2 := stringAppend(s_1, "]");
342 then
343 s_2;
344
345 case DAE.CALL(path = fcn,expLst = args)
346 algorithm
347 615 fs := AbsynUtil.pathString(fcn);
348 615 argstr := stringDelimitList(List.map2(args, printExpMmaStr,vars,knvars),",");
349 615 s_2 := "FunctionCall[\""+ fs +"\"]["+argstr+"]";
350 then
351 s_2;
352
353 case DAE.RECORD(path = fcn,exps = args)
354 algorithm
355 474 fs := AbsynUtil.pathString(fcn);
356 474 argstr := stringDelimitList(List.map2(args, printExpMmaStr,vars,knvars),",");
357 474 s_2 := "FunctionCall[\""+ fs +"\"]["+argstr+"]";
358 then
359 s_2;
360
361 case DAE.ARRAY(array = es)
362 algorithm
363 ✗ s := stringDelimitList(List.map2(es, printExpMmaStr,vars,knvars),",");
364 ✗ s_1 := stringAppend("{", s);
365 ✗ s_2 := stringAppend(s_1, "}");
366 then
367 s_2;
368 case DAE.TUPLE(PR = es)
369 algorithm
370 22 s := stringDelimitList(List.map2(es, printExpMmaStr,vars,knvars),",");
371 22 s_1 := stringAppend("{", s);
372 22 s_2 := stringAppend(s_1, "}");
373 then
374 s_2;
375 case DAE.MATRIX(matrix = matrix)
376 algorithm
377 ✗ s := stringDelimitList(List.map2(matrix, printRowMmaStr,vars,knvars), "},{");
378 ✗ s_1 := stringAppend("{{", s);
379 ✗ s_2 := stringAppend(s_1, "}}");
380 then
381 s_2;
382 case e as DAE.RANGE(start = start,step = NONE(),stop = stop)
383 algorithm
384 ✗ s1 := printExp2MmaStr(start, vars,knvars);
385 ✗ s3 := printExp2MmaStr(stop, vars,knvars);
386 ✗ p := ExpressionDump.expPriority(e);
387 ✗ pstart := ExpressionDump.expPriority(start);
388 ✗ pstop := ExpressionDump.expPriority(stop);
389 ✗ s1_1 := ExpressionDump.parenthesize(s1, pstart, p,false);
390 ✗ s3_1 := ExpressionDump.parenthesize(s3, pstop, p,false);
391 ✗ s_3 := stringAppendList({"Range[",s1_1,",",s3_1,"]"}); // Range[start,stop]
392 then
393 s_3;
394
395 case DAE.RANGE(start = start,step = SOME(step),stop = stop)
396 algorithm
397 ✗ s2 := printExp2MmaStr(start, vars,knvars);
398 ✗ s3 := printExp2MmaStr(step, vars,knvars);
399 ✗ s4 := printExp2MmaStr(stop, vars,knvars);
400 ✗ s_5 := stringAppendList({"Range[",s2,",",s4,",",s3,"]"}); // Range[start,stop,step]
401 then
402 s_5;
403 /* We prevent casts since we probably do not want numerical values, e.g. Sqrt[2.0] should probably be Sqrt[2] instead*/
404 case DAE.CAST(ty = DAE.T_REAL(),exp = DAE.ICONST(integer = ival))
405 algorithm
406 ✗ res := intString(ival);
407 then
408 res;
409 /* We prevent casts since we probably do not want numerical values, e.g. Sqrt[2.0] should probably be Sqrt[2] instead*/
410 case DAE.CAST(ty = DAE.T_REAL(),exp = DAE.UNARY(operator = DAE.UMINUS(),exp = DAE.ICONST(integer = ival)))
411 algorithm
412 ✗ res := intString(ival);
413 ✗ res2 := stringAppend("-", res);
414 then
415 res2;
416 case DAE.CAST(ty = DAE.T_REAL(),exp = e)
417 algorithm
418 ✗ s := printExpMmaStr(e,vars,knvars);
419 then
420 s;
421 case e as DAE.ASUB(exp = e1,sub = subs)
422 algorithm
423 ✗ ae1 := list(Expression.getSubscriptExp(sub) for sub in subs);
424 ✗ p := ExpressionDump.expPriority(e);
425 ✗ pe1 := ExpressionDump.expPriority(e1);
426 ✗ s1 := printExp2MmaStr(e1,vars,knvars);
427 ✗ s1_1 := ExpressionDump.parenthesize(s1, pe1, p,false);
428 ✗ s4 := stringDelimitList(List.map2(ae1,printExp2MmaStr,vars,knvars),", ");
429 ✗ s_4 :="Index["+ s1_1+",{" +s4 + "}]";
430 then
431 s_4;
432
433 case DAE.SIZE(exp = e,sz = SOME(dim))
434 algorithm
435 ✗ crstr := printExpMmaStr(e,vars,knvars);
436 ✗ dimstr := printExpMmaStr(dim,vars,knvars);
437 ✗ str := stringAppendList({"Dimensions[",crstr,"][[",dimstr,"]]"});
438 then
439 str;
440 case DAE.SIZE(exp = e,sz = NONE())
441 algorithm
442 ✗ crstr := printExpMmaStr(e,vars,knvars);
443 ✗ str := stringAppendList({"Dimensions[",crstr,"]"});
444 then
445 str;
446 case DAE.REDUCTION(DAE.REDUCTIONINFO(path = fcn),exp,(DAE.REDUCTIONITER(id = id,exp = iterexp)::_)) //TODO: need to suport more than one iterator.
447 algorithm
448 ✗ fs := AbsynUtil.pathString(fcn);
449 ✗ expstr := printExpMmaStr(exp,vars,knvars);
450 ✗ iterstr := printExpMmaStr(iterexp,vars,knvars);
451 ✗ str := stringAppendList({"Table[",fs,"[",expstr,"],{",id,", ",iterstr,"}]"});
452 then
453 str;
454
455 case DAE.ENUM_LITERAL(name=path) algorithm
456 ✗ str := AbsynUtil.pathString(path);
457 ✗ str := "Missing[\"ModelicaName\",\""+str+"\"]";
458 then str;
459
460 case e algorithm
461 ✗ str := "Missing[\"UnknownExpression\",\""+ExpressionBasics.printExpStr(e)+"\"]";
462 then str;
463 end matchcontinue;
464 end printExp2MmaStr;
465
466
467 protected function printComponentRefMmaStr "prints a ComponentRef to a string suitable for input to Mathematica"
468 input DAE.ComponentRef cr;
469 input BackendDAE.Variables vars;
470 input BackendDAE.Variables knvars;
471 output String res;
472 algorithm
473 res := matchcontinue cr
474 local
475 String nameStr;
476 Boolean isInput,isOutput;
477 BackendDAE.Var v;
478
479 case DAE.CREF_IDENT("time",_,_) then "\\[FormalT]";
480
481 // Variables
482 case _ algorithm
483 14718 BackendVariable.getVar(cr,vars);
484 12849 nameStr := ComponentReferenceBasics.printComponentRefStr(cr);
485 // If already translated variables.
486 12849 nameStr := System.stringReplace(nameStr,"$p",".");
487 12849 nameStr := System.stringReplace(nameStr,"$lb","[");
488 12849 nameStr := System.stringReplace(nameStr,"$rb","]");
489 12849 nameStr := System.stringReplace(nameStr,"$leftParentesis","[");
490 12849 nameStr := System.stringReplace(nameStr,"$rightParentesis","]");
491
492 12849 nameStr := System.stringReplace(nameStr,"(","[");
493 12849 nameStr := System.stringReplace(nameStr,")","]");
494 // if not translated variables
495 12849 nameStr := System.stringReplace(nameStr,"_","\\[UnderBracket]");
496
497 12849 nameStr := wrapInMember(nameStr);
498 12849 nameStr := addMissingForQuotedNames(nameStr);
499 12849 res := stringAppendList({nameStr,"[\\[FormalT]]"});
500 then res;
501
502 // Input or output variables
503 case _
504
505 algorithm
506
507
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 1869 times.
1869 (v::_,_):=BackendVariable.getVar(cr,knvars);
508 1869 isInput := BackendVariable.isInput(v);
509 1869 isOutput := BackendVariable.isOutputVar(v);
510
1/2
✓ Branch 0 taken 1869 times.
✗ Branch 1 not taken.
1869 true := boolOr(isInput,isOutput);
511 ✗ nameStr := ComponentReferenceBasics.printComponentRefStr(cr);
512
513 // If already translated variables.
514 ✗ nameStr := System.stringReplace(nameStr,"$p",".");
515 ✗ nameStr := System.stringReplace(nameStr,"$lb","[");
516 ✗ nameStr := System.stringReplace(nameStr,"$rb","]");
517 ✗ nameStr := System.stringReplace(nameStr,"$leftParentesis","(");
518 ✗ nameStr := System.stringReplace(nameStr,"$rightParentesis",")");
519 // if not translated variables
520 ✗ nameStr := System.stringReplace(nameStr,"_","\\[UnderBracket]");
521
522 ✗ nameStr := wrapInMember(nameStr);
523 ✗ nameStr := addMissingForQuotedNames(nameStr);
524 ✗ res := stringAppendList({nameStr,"[\\[FormalT]]"});
525 then res;
526
527 // Parameters, etc.
528 case _ algorithm
529
2/2
✓ Branch 0 taken 1869 times.
✓ Branch 1 taken 1869 times.
3738 failure(BackendVariable.getVar(cr,vars));
530 1869 nameStr := ComponentReferenceBasics.printComponentRefStr(cr);
531 // If already translated variables.
532 1869 nameStr := System.stringReplace(nameStr,"$p",".");
533 1869 nameStr := System.stringReplace(nameStr,"$lb","[");
534 1869 nameStr := System.stringReplace(nameStr,"$rb","]");
535 1869 nameStr := System.stringReplace(nameStr,"$leftParentesis","(");
536 1869 nameStr := System.stringReplace(nameStr,"$rightParentesis",")");
537 // if not translated variables
538 1869 nameStr := System.stringReplace(nameStr,"_","\\[UnderBracket]");
539 1869 nameStr := wrapInMember(nameStr);
540 then nameStr;
541 end matchcontinue;
542 end printComponentRefMmaStr;
543
544 protected function wrapInMember "Help function to printComponentRefMmaStr, wraps Member[ ] round
545 dotted names and replaces '.' with ','"
546 input String str;
547 output String outStr;
548 protected
549 String s3;// Boolean b;
550 algorithm
551 //b := Util.stringContainsChar(str,".");
552 //b := true; // always wrap the names
553 //s1 := if_(b,"Member[","");
554 //s2 := if_(b,"]","");
555 14718 s3 := System.stringReplace(str,".","\\[UpPointer]");
556 //outStr := stringAppendList({s1,s3,s2});
557 outStr := s3;
558 end wrapInMember;
559
560 protected function addMissingForQuotedNames " Wraps name in Missing if quoted name, e.g. '1'"
561 input String name;
562 output String res;
563 algorithm
564 res := matchcontinue name
565 case _ algorithm
566
1/2
✓ Branch 1 taken 12849 times.
✗ Branch 2 not taken.
12849 false := -1 == System.stringFind(name,"'");
567 ✗ res := "Missing[\"QuotedName\",\""+System.stringReplace(name,"\\","\\\\")+"\"]";
568 then res;
569 case _ then name;
570 end matchcontinue;
571 end addMissingForQuotedNames;
572
573 protected function lbinopSymbolMma "Return string representation of logical binary operator on Mathematica format
574 "
575 input DAE.Operator inOperator;
576 output String outString;
577 algorithm
578 outString := match inOperator
579 case DAE.AND(_) then " && ";
580 case DAE.OR(_) then " || ";
581 end match;
582 end lbinopSymbolMma;
583
584 protected function lunaryopSymbolMma "
585 Return string representation of logical unary operator for Mathematica
586 "
587 input DAE.Operator inOperator;
588 output String outString;
589 algorithm
590 outString := match inOperator
591 case DAE.NOT(_) then " ! ";
592 end match;
593 end lunaryopSymbolMma;
594
595 protected function relopSymbolMma "
596 Return string representation of function operator for Mathematica.
597 "
598 input DAE.Operator inOperator;
599 output String outString;
600 algorithm
601 outString := match inOperator
602 case DAE.LESS() then " < ";
603 case DAE.LESSEQ() then " <= ";
604 case DAE.GREATER() then " > ";
605 case DAE.GREATEREQ() then " >= ";
606 case DAE.EQUAL() then " == ";
607 case DAE.NEQUAL() then " != "; // differs from Modelica which has '<>'
608 end match;
609 end relopSymbolMma;
610
611 protected function printBuiltinMmaFunc "Translates builtin function to corresponding Mma function"
612 input String modelicaFuncName;
613 output String mathematicaFuncName;
614 algorithm
615 mathematicaFuncName := match modelicaFuncName
616 case "sqrt" then "Sqrt";
617 case "abs" then "Abs";
618 case "sign" then "Sign";
619 case "Integer" then "IntegerPart";
620 case "div" then "Rational";
621 case "max" then "Max";
622 case "min" then "Min";
623 case "mod" then "Quotient";
624 case "rem" then "Mod";
625 case "ceil" then "Cieling";
626 case "floor" then "Floor";
627 case "integer" then "IntegerPart";
628 case "sin" then "Sin";
629 case "cos" then "Cos";
630 case "tan" then "Tan";
631 case "asin" then "ArcSin";
632 case "acos" then "ArcCos";
633 case "atan" then "ArcTan";
634 /* atan2 not possible here. */
635 case "sinh" then "Sinh";
636 case "cosh" then "Cosh";
637 case "tanh" then "Tanh";
638 case "exp" then "Exp";
639 case "log" then "Log";
640 /* log10 not possible here. */
641 end match;
642 end printBuiltinMmaFunc;
643
644 protected function translateKnownMmaFuncs "Translates some internal functions to corresponding Mathematica function"
645 input String func;
646 output String mmaFunc;
647 algorithm
648 mmaFunc := match func
649 case "sin" then "Sin";
650 case "Modelica.Math.sin" then "Sin";
651 case "cos" then "Cos";
652 case "Modelica.Math.cos" then "Cos";
653 case "tan" then "Tan";
654 case "Modelica.Math.tan" then "Tan";
655 case "exp" then "Exp";
656 case "Modelica.Math.exp" then "Exp";
657 end match;
658 end translateKnownMmaFuncs;
659
660 protected function printRowMmaStr "Prints a list of expressions to a string on Mathematica format.
661 "
662 input list<DAE.Exp> es;
663 input BackendDAE.Variables vars;
664 input BackendDAE.Variables knvars;
665 output String s;
666 algorithm
667 ✗ s := stringDelimitList(List.map2(es, printExpMmaStr, vars,knvars),",");
668 end printRowMmaStr;
669
670 protected function escapeMmaString "help function to e.g printMmaEqnStr, escapes characters in strings generated to mathematica"
671 input String str;
672 output String res;
673 algorithm
674 ✗ res := System.stringReplace(str,"\"","\\\"");
675 end escapeMmaString;
676
677
678 protected function dumpSingleAlgorithmStr "Help function to dump, prints algorithms to stdout"
679 input DAE.Algorithm algs;
680 output String outString;
681 algorithm
682 outString := match algs
683 local
684 list<DAE.Statement> stmts;
685 String str;
686 IOStream.IOStream myStream;
687 case DAE.ALGORITHM_STMTS(stmts) algorithm
688 ✗ myStream := IOStream.create("", IOStream.LIST());
689 ✗ myStream := DAEDump.dumpAlgorithmStream(DAE.ALGORITHM(DAE.ALGORITHM_STMTS(stmts),DAE.emptyElementSource), myStream);
690 ✗ str := IOStream.string(myStream);
691 then str;
692 end match;
693 end dumpSingleAlgorithmStr;
694
695 public function printMmaVarsStr "print variables on a form suitable for Mathematica to a string.
696 $p,$lb, $rb, $leftParentesis, $rightParentesis removed.
697 $derivative<varname> replaced by D[<varname>,t]
698 All variables returned as Mma lists on form {{states},{algvars}, e.g. {{Iii},{abc, R1i, R2pi}}
699 "
700 input BackendDAE.Variables vars;
701 output list<String> states;
702 output list<String> algs;
703 output list<String> outputs;
704 output list<String> inputs;
705 algorithm
706 (states,algs,outputs,inputs) := match vars
707 local
708 list<BackendDAE.Var> varLst;
709 case _
710 algorithm
711 28 varLst := BackendVariable.varList(vars);
712 28 varLst := listReverse(varLst); //So the order is the same as for generated c-code.
713 28 states := List.map2(varLst,printMmaVarStr,true,vars);
714 28 algs := List.map2(varLst,printMmaVarStr,false,vars);
715 28 outputs := List.map(varLst,printMmaOutputStr);
716 28 inputs := List.map(varLst,printMmaInputStr);
717 then
718 (states,algs,outputs,inputs);
719 end match;
720 end printMmaVarsStr;
721
722 public function printMmaVarStr "help function to printMmaVarsStr"
723 input BackendDAE.Var v;
724 input Boolean selectKind "true for dumping states, false for algebraic vars";
725 input BackendDAE.Variables allVars;
726 output String str;
727 algorithm
728 str := matchcontinue(v, selectKind)
729 local DAE.ComponentRef name;
730 String nameStr;
731 case (BackendDAE.VAR(varName=DAE.CREF_IDENT("$dummy",DAE.T_UNKNOWN(),{})), _) then "";
732 case (BackendDAE.VAR(varName=name,varKind=BackendDAE.STATE()), true)
733 algorithm
734 ✗ nameStr := printComponentRefMmaStr(name,allVars,BackendVariable.emptyVars());
735 then nameStr;
736 //case (BackendDAE.VAR(varName=name,varKind=BackendDAE.DYN_STATE()),true,allVars)
737 // equation
738 // nameStr = printComponentRefMmaStr(name,allVars,BackendVariable.emptyVars());
739 // then nameStr;
740 case (BackendDAE.VAR(varName=name,varKind=BackendDAE.VARIABLE()), false)
741 algorithm
742 2383 nameStr := printComponentRefMmaStr(name,allVars,BackendVariable.emptyVars());
743 then nameStr;
744 case (BackendDAE.VAR(varName=name,varKind=BackendDAE.DUMMY_DER()), false)
745 algorithm
746 ✗ nameStr := printComponentRefMmaStr(name,allVars,BackendVariable.emptyVars());
747 then nameStr;
748 case (BackendDAE.VAR(varName=name,varKind=BackendDAE.DUMMY_STATE()), false)
749 algorithm
750 ✗ nameStr := printComponentRefMmaStr(name,allVars,BackendVariable.emptyVars());
751 then nameStr;
752 case (BackendDAE.VAR(varName=name,varKind=BackendDAE.DISCRETE()), false)
753 algorithm
754 ✗ nameStr := printComponentRefMmaStr(name,allVars,BackendVariable.emptyVars());
755 then nameStr;
756 case(_, _) then "";
757 end matchcontinue;
758 end printMmaVarStr;
759
760 protected function printMmaOutputStr "
761 print variables that are top level OUTPUT's
762 "
763 input BackendDAE.Var param;
764 output String str;
765 algorithm
766 str := matchcontinue param
767 local
768 BackendDAE.Var v;
769 DAE.ComponentRef name;
770 case v as BackendDAE.VAR(varName=name as (DAE.CREF_IDENT(_,_,{})),varDirection = DAE.OUTPUT())
771 algorithm
772 ✗ true:=BackendVariable.isVarOnTopLevelAndOutput(v);
773 ✗ str := printComponentRefMmaStr(name,BackendVariable.emptyVars(),BackendVariable.emptyVars());
774 then str;
775 case _ then "";
776 end matchcontinue;
777 end printMmaOutputStr;
778
779 protected function printMmaInputStr "
780 print variables that are INPUT's
781 "
782 input BackendDAE.Var param;
783 output String str;
784 algorithm
785 str := matchcontinue param
786 local
787 DAE.ComponentRef name;
788 BackendDAE.Var v;
789 case v as BackendDAE.VAR(varName=name as (DAE.CREF_IDENT(_,_,{})),varDirection = DAE.INPUT())
790 algorithm
791 ✗ true:=BackendVariable.isVarOnTopLevelAndInput(v);
792 ✗ str := printComponentRefMmaStr(name,BackendVariable.emptyVars(),BackendVariable.emptyVars());
793 then str;
794 case _ then "";
795 end matchcontinue;
796 end printMmaInputStr;
797
798 public function printMmaParamsStr "print parameters on a form suitable for Mathematica,
799 $p,$lb, $rb, $leftParentesis, $rightParentesis removed.
800 Returns a list of rules for parameters and their values
801 E.g. {R1R->1.0,R2R->R1R*0.5,I3I->0.1}
802 "
803 input BackendDAE.Variables knvars;
804 output list<String> params;
805 output list<String> inputs;
806 algorithm
807 (params, inputs) := match knvars
808 local
809 list<BackendDAE.Var> varLst;
810 case _ algorithm
811 ✗ varLst := BackendVariable.varList(knvars);
812 ✗ params := List.map(varLst,printMmaParamStr);
813 ✗ inputs := List.map(varLst,printMmaInputStr);
814 then (params, inputs);
815 end match;
816 end printMmaParamsStr;
817
818 protected function printMmaParamStr "help function to prontMmaParamStr"
819 input BackendDAE.Var param;
820 output String str;
821 algorithm
822 str := matchcontinue param
823 local
824 DAE.Exp exp;
825 DAE.ComponentRef name;
826 String expStr,paramStr;
827 Option<DAE.VariableAttributes> val;
828 case BackendDAE.VAR(varName=name,varKind=BackendDAE.PARAM(),bindExp=SOME(exp))
829 algorithm
830 ✗ expStr := printExpMmaStr(exp,BackendVariable.emptyVars(),BackendVariable.emptyVars()); // parameters can not depend on variables. Thus, safe to send empty variables.
831 ✗ paramStr := printComponentRefMmaStr(name,BackendVariable.emptyVars(),BackendVariable.emptyVars());
832 ✗ str := stringAppendList({paramStr,"->",expStr});
833 then str;
834 case BackendDAE.VAR(varName=name,varKind=BackendDAE.PARAM(),bindExp=NONE(),values=val)
835 algorithm
836 ✗ SOME(exp) := getStartAttribute(val);
837 ✗ expStr := printExpMmaStr(exp,BackendVariable.emptyVars(),BackendVariable.emptyVars()); // parameters can not depend on variables. Thus, safe to send empty variables.
838 ✗ paramStr := printComponentRefMmaStr(name,BackendVariable.emptyVars(),BackendVariable.emptyVars());
839 ✗ str := stringAppendList({paramStr,"->",expStr});
840 then str;
841 case BackendDAE.VAR(varName=name,varKind=BackendDAE.PARAM(),bindExp=NONE(),values=val)
842 algorithm
843 ✗ NONE() := getStartAttribute(val);
844 ✗ expStr := printExpMmaStr(DAE.ICONST(0),BackendVariable.emptyVars(),BackendVariable.emptyVars()); // parameters can not depend on variables. Thus, safe to send empty variables.
845 ✗ paramStr := printComponentRefMmaStr(name,BackendVariable.emptyVars(),BackendVariable.emptyVars());
846 ✗ str := stringAppendList({paramStr,"->",expStr});
847 then str;
848 case BackendDAE.VAR(varName=name,varKind=BackendDAE.PARAM())
849 algorithm
850 ✗ paramStr := printComponentRefMmaStr(name,BackendVariable.emptyVars(),BackendVariable.emptyVars());
851 then paramStr;
852 case _ then "";
853 end matchcontinue;
854 end printMmaParamStr;
855
856 protected function getStartAttribute "returns the start attribute of a variable"
857 input Option<DAE.VariableAttributes> inVariableAttributesOption;
858 output Option<DAE.Exp> out;
859 algorithm
860 out:=match inVariableAttributesOption
861 local
862 Option<DAE.Exp> e;
863 case SOME(DAE.VAR_ATTR_REAL(start=e))
864 then e;
865 case SOME(DAE.VAR_ATTR_INT(start=e))
866 then e;
867 case SOME(DAE.VAR_ATTR_BOOL(start=e))
868 then e;
869 case SOME(DAE.VAR_ATTR_STRING(start=e))
870 then e;
871 case _
872 then NONE();
873 end match;
874 end getStartAttribute;
875
876 annotation(__OpenModelica_Interface="backend_tools");
877 end MathematicaDump;
878