OMCompiler/Compiler/NFFrontEnd/NFOperator.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 uniontype NFOperator | ||
| 37 | protected | ||
| 38 | import Operator = NFOperator; | ||
| 39 | import Util; | ||
| 40 | |||
| 41 | public | ||
| 42 | import Type = NFType; | ||
| 43 | import Absyn; | ||
| 44 | import AbsynUtil; | ||
| 45 | import DAE; | ||
| 46 | import JSON; | ||
| 47 | |||
| 48 | type Op = enumeration( | ||
| 49 | // Basic arithmetic operators. | ||
| 50 | ADD, // 1: + | ||
| 51 | SUB, // 2: - | ||
| 52 | MUL, // 3: * | ||
| 53 | DIV, // 4: / | ||
| 54 | POW, // 5: ^ | ||
| 55 | // Element-wise arithmetic operators. These are only used until the type | ||
| 56 | // checking, then replaced with a more specific operator. | ||
| 57 | ADD_EW, // 6: .+ | ||
| 58 | SUB_EW, // 7: .- | ||
| 59 | MUL_EW, // 8: .* | ||
| 60 | DIV_EW, // 9: ./ | ||
| 61 | POW_EW, // 10: .^ | ||
| 62 | // Scalar-Array and Array-Scalar arithmetic operators. | ||
| 63 | ADD_SCALAR_ARRAY, // 11: scalar + array | ||
| 64 | ADD_ARRAY_SCALAR, // 12: array + scalar | ||
| 65 | SUB_SCALAR_ARRAY, // 13: scalar - array | ||
| 66 | SUB_ARRAY_SCALAR, // 14: array - scalar | ||
| 67 | MUL_SCALAR_ARRAY, // 15: scalar * array | ||
| 68 | MUL_ARRAY_SCALAR, // 16: array * scalar | ||
| 69 | MUL_VECTOR_MATRIX, // 17: vector * matrix | ||
| 70 | MUL_MATRIX_VECTOR, // 18: matrix * vector | ||
| 71 | SCALAR_PRODUCT, // 19: vector * vector | ||
| 72 | MATRIX_PRODUCT, // 20: matrix * matrix | ||
| 73 | DIV_SCALAR_ARRAY, // 21: scalar / array | ||
| 74 | DIV_ARRAY_SCALAR, // 22: array / scalar | ||
| 75 | POW_SCALAR_ARRAY, // 23: scalar ^ array | ||
| 76 | POW_ARRAY_SCALAR, // 24: array ^ scalar | ||
| 77 | POW_MATRIX, // 25: matrix ^ Integer | ||
| 78 | // Unary arithmetic operators. | ||
| 79 | UMINUS, // 26: - | ||
| 80 | // Logic operators. | ||
| 81 | AND, // 27: and | ||
| 82 | OR, // 28: or | ||
| 83 | NOT, // 29: not | ||
| 84 | // Relational operators. | ||
| 85 | LESS, // 30: < | ||
| 86 | LESSEQ, // 31: <= | ||
| 87 | GREATER, // 32: > | ||
| 88 | GREATEREQ, // 33: >= | ||
| 89 | EQUAL, // 34: == | ||
| 90 | NEQUAL, // 35: <> | ||
| 91 | USERDEFINED // 36: Overloaded operator. | ||
| 92 | ); | ||
| 93 | |||
| 94 | record OPERATOR | ||
| 95 | Type ty; | ||
| 96 | Op op; | ||
| 97 | end OPERATOR; | ||
| 98 | |||
| 99 | function compare | ||
| 100 | input Operator op1; | ||
| 101 | input Operator op2; | ||
| 102 | output Integer comp; | ||
| 103 | protected | ||
| 104 | Op o1 = op1.op, o2 = op2.op; | ||
| 105 | algorithm | ||
| 106 | // TODO: Compare the types instead if both operators are USERDEFINED. | ||
| 107 | 55564 | comp := Util.intCompare(Integer(o1), Integer(o2)); | |
| 108 | end compare; | ||
| 109 | |||
| 110 | function invert | ||
| 111 | input output Operator operator; | ||
| 112 | algorithm | ||
| 113 | operator.op := match operator.op | ||
| 114 | case Op.ADD then Op.SUB; | ||
| 115 | case Op.SUB then Op.ADD; | ||
| 116 | case Op.MUL then Op.DIV; | ||
| 117 | case Op.DIV then Op.MUL; | ||
| 118 | case Op.ADD_EW then Op.SUB_EW; | ||
| 119 | case Op.SUB_EW then Op.ADD_EW; | ||
| 120 | case Op.MUL_EW then Op.DIV_EW; | ||
| 121 | case Op.DIV_EW then Op.MUL_EW; | ||
| 122 | case Op.ADD_SCALAR_ARRAY then Op.SUB_SCALAR_ARRAY; | ||
| 123 | case Op.ADD_ARRAY_SCALAR then Op.SUB_ARRAY_SCALAR; | ||
| 124 | case Op.SUB_SCALAR_ARRAY then Op.ADD_SCALAR_ARRAY; | ||
| 125 | case Op.SUB_ARRAY_SCALAR then Op.ADD_ARRAY_SCALAR; | ||
| 126 | case Op.MUL_SCALAR_ARRAY then Op.DIV_SCALAR_ARRAY; | ||
| 127 | case Op.MUL_ARRAY_SCALAR then Op.DIV_ARRAY_SCALAR; | ||
| 128 | case Op.DIV_SCALAR_ARRAY then Op.MUL_SCALAR_ARRAY; | ||
| 129 | case Op.DIV_ARRAY_SCALAR then Op.MUL_ARRAY_SCALAR; | ||
| 130 | case Op.LESS then Op.GREATEREQ; | ||
| 131 | case Op.LESSEQ then Op.GREATER; | ||
| 132 | case Op.GREATER then Op.LESSEQ; | ||
| 133 | case Op.GREATEREQ then Op.LESS; | ||
| 134 | case Op.EQUAL then Op.EQUAL; | ||
| 135 | case Op.NEQUAL then Op.NEQUAL; | ||
| 136 | // ToDo: should POW return POW? exponent should be negated | ||
| 137 | else algorithm | ||
| 138 | ✗ | Error.addMessage(Error.INTERNAL_ERROR,{getInstanceName() + "Failed! Don't know how to invert: " + symbol(operator)}); | |
| 139 | ✗ | then fail(); | |
| 140 | end match; | ||
| 141 | end invert; | ||
| 142 | |||
| 143 | function negate | ||
| 144 | "the logical negation of a relational operator, e.g. < to >= and == to <>" | ||
| 145 | input output Operator operator; | ||
| 146 | algorithm | ||
| 147 | operator.op := match operator.op | ||
| 148 | case Op.LESS then Op.GREATEREQ; | ||
| 149 | case Op.LESSEQ then Op.GREATER; | ||
| 150 | case Op.GREATER then Op.LESSEQ; | ||
| 151 | case Op.GREATEREQ then Op.LESS; | ||
| 152 | case Op.EQUAL then Op.NEQUAL; | ||
| 153 | case Op.NEQUAL then Op.EQUAL; | ||
| 154 | else algorithm | ||
| 155 | ✗ | Error.addMessage(Error.INTERNAL_ERROR,{getInstanceName() + " failed! Don't know how to negate: " + symbol(operator)}); | |
| 156 | ✗ | then fail(); | |
| 157 | end match; | ||
| 158 | end negate; | ||
| 159 | |||
| 160 | type TypeRestriction = enumeration(SCALAR, VECTOR, MATRIX, ARRAY, OTHER); | ||
| 161 | |||
| 162 | function typeRestriction | ||
| 163 | input Type ty; | ||
| 164 | output TypeRestriction restriction; | ||
| 165 | algorithm | ||
| 166 |
2/2✓ Branch 1 taken 743 times.
✓ Branch 2 taken 106436 times.
|
107179 | if Type.isScalar(ty) then |
| 167 | restriction := TypeRestriction.SCALAR; | ||
| 168 | elseif Type.isVector(ty) then | ||
| 169 | restriction := TypeRestriction.VECTOR; | ||
| 170 | elseif Type.isMatrix(ty) then | ||
| 171 | restriction := TypeRestriction.MATRIX; | ||
| 172 | elseif Type.isArray(ty) then | ||
| 173 | restriction := TypeRestriction.ARRAY; | ||
| 174 | else | ||
| 175 | restriction := TypeRestriction.OTHER; | ||
| 176 | end if; | ||
| 177 | end typeRestriction; | ||
| 178 | |||
| 179 | function repairMultary | ||
| 180 | input output Operator operator; | ||
| 181 | input list<Type> types; | ||
| 182 | protected | ||
| 183 | MathClassification mc = getMathClassification(operator); | ||
| 184 | SizeClassification sc; | ||
| 185 | list<tuple<TypeRestriction, Type>> lst; | ||
| 186 | tuple<TypeRestriction, Type> min_, max_; | ||
| 187 | Type ty; | ||
| 188 | function tplLt | ||
| 189 | input tuple<TypeRestriction, Type> tpl1; | ||
| 190 | input tuple<TypeRestriction, Type> tpl2; | ||
| 191 | output Boolean b = Util.tuple21(tpl1) < Util.tuple21(tpl2); | ||
| 192 | end tplLt; | ||
| 193 | algorithm | ||
| 194 |
4/4✓ Branch 0 taken 425 times.
✓ Branch 1 taken 211 times.
✓ Branch 2 taken 425 times.
✓ Branch 3 taken 211 times.
|
636 | lst := list((typeRestriction(t), t) for t in types); |
| 195 | 211 | min_ := List.minElement(lst, tplLt); | |
| 196 | 211 | max_ := List.maxElement(lst, tplLt); | |
| 197 | (sc, ty) := match (min_, max_) | ||
| 198 | case ((TypeRestriction.SCALAR, _), (TypeRestriction.SCALAR, ty)) then (SizeClassification.SCALAR, ty); | ||
| 199 | case ((TypeRestriction.SCALAR, _), (_ ,ty)) then (SizeClassification.SCALAR_ARRAY, ty); | ||
| 200 | case ((TypeRestriction.VECTOR, _), (TypeRestriction.VECTOR, ty)) then (SizeClassification.ELEMENT_WISE, ty); | ||
| 201 | case ((TypeRestriction.VECTOR, _), (TypeRestriction.MATRIX, ty)) then (SizeClassification.VECTOR_MATRIX, ty); | ||
| 202 | case ((TypeRestriction.MATRIX, _), (TypeRestriction.MATRIX, ty)) then (SizeClassification.ELEMENT_WISE, ty); | ||
| 203 | case ((TypeRestriction.ARRAY, _), (TypeRestriction.ARRAY, ty)) then (SizeClassification.ELEMENT_WISE, ty); | ||
| 204 | else algorithm | ||
| 205 | ✗ | Error.terminate(getInstanceName() + " failed because the multary arguments have incompatible sizes: " | |
| 206 | + List.toString(types, Type.toString), sourceInfo()); | ||
| 207 | ✗ | then fail(); | |
| 208 | end match; | ||
| 209 | 211 | operator := fromClassification((mc, sc), ty); | |
| 210 | end repairMultary; | ||
| 211 | |||
| 212 | function repairBinary | ||
| 213 | input output Operator operator; | ||
| 214 | input Type ty1; | ||
| 215 | input Type ty2; | ||
| 216 | protected | ||
| 217 | MathClassification mc = getMathClassification(operator); | ||
| 218 | SizeClassification sc; | ||
| 219 | Type ty; | ||
| 220 | algorithm | ||
| 221 | (sc, ty) := match (typeRestriction(ty1), typeRestriction(ty2)) | ||
| 222 | local | ||
| 223 | TypeRestriction r1, r2; | ||
| 224 | case (TypeRestriction.SCALAR, TypeRestriction.SCALAR) then (SizeClassification.SCALAR, ty1); | ||
| 225 | case (TypeRestriction.SCALAR, r2) guard(r2>TypeRestriction.SCALAR) then (SizeClassification.SCALAR_ARRAY, ty2); | ||
| 226 | case (r1, TypeRestriction.SCALAR) guard(r1>TypeRestriction.SCALAR) then (SizeClassification.ARRAY_SCALAR, ty1); | ||
| 227 | case (TypeRestriction.VECTOR, TypeRestriction.MATRIX) then (SizeClassification.VECTOR_MATRIX, ty1); | ||
| 228 | case (TypeRestriction.MATRIX, TypeRestriction.VECTOR) then (SizeClassification.MATRIX_VECTOR, ty2); | ||
| 229 | 222 | case (r1, r2) guard(r1 == r2) then (getSizeClassification(operator), ty1); | |
| 230 | else algorithm | ||
| 231 | ✗ | Error.terminate(getInstanceName() + " failed because the binary arguments have incompatible sizes: " | |
| 232 | + Type.toString(ty1) + ", " + Type.toString(ty2), sourceInfo()); | ||
| 233 | ✗ | then fail(); | |
| 234 | end match; | ||
| 235 | 53377 | operator := fromClassification((mc, sc), ty); | |
| 236 | end repairBinary; | ||
| 237 | |||
| 238 | function isLogical | ||
| 239 | input Operator operator; | ||
| 240 | output Boolean b; | ||
| 241 | algorithm | ||
| 242 | b := match operator.op | ||
| 243 | case Op.AND then true; | ||
| 244 | case Op.OR then true; | ||
| 245 | case Op.NOT then true; | ||
| 246 | else false; | ||
| 247 | end match; | ||
| 248 | end isLogical; | ||
| 249 | |||
| 250 | function isRelational | ||
| 251 | input Operator operator; | ||
| 252 | output Boolean b; | ||
| 253 | algorithm | ||
| 254 | b := match operator.op | ||
| 255 | case Op.LESS then true; | ||
| 256 | case Op.LESSEQ then true; | ||
| 257 | case Op.GREATER then true; | ||
| 258 | case Op.GREATEREQ then true; | ||
| 259 | case Op.EQUAL then true; | ||
| 260 | case Op.NEQUAL then true; | ||
| 261 | else false; | ||
| 262 | end match; | ||
| 263 | end isRelational; | ||
| 264 | |||
| 265 | function isScalarProduct | ||
| 266 | input Operator operator; | ||
| 267 | output Boolean b; | ||
| 268 | algorithm | ||
| 269 | b := match operator.op | ||
| 270 | case Op.SCALAR_PRODUCT then true; | ||
| 271 | else false; | ||
| 272 | end match; | ||
| 273 | end isScalarProduct; | ||
| 274 | |||
| 275 | function fromAbsyn | ||
| 276 | input Absyn.Operator inOperator; | ||
| 277 | output Operator outOperator; | ||
| 278 | protected | ||
| 279 | Op op; | ||
| 280 | algorithm | ||
| 281 | op := match inOperator | ||
| 282 | case Absyn.ADD() then Op.ADD; | ||
| 283 | case Absyn.SUB() then Op.SUB; | ||
| 284 | case Absyn.MUL() then Op.MUL; | ||
| 285 | case Absyn.DIV() then Op.DIV; | ||
| 286 | case Absyn.POW() then Op.POW; | ||
| 287 | case Absyn.ADD_EW() then Op.ADD_EW; | ||
| 288 | case Absyn.SUB_EW() then Op.SUB_EW; | ||
| 289 | case Absyn.MUL_EW() then Op.MUL_EW; | ||
| 290 | case Absyn.DIV_EW() then Op.DIV_EW; | ||
| 291 | case Absyn.POW_EW() then Op.POW_EW; | ||
| 292 | case Absyn.UPLUS() then Op.ADD; | ||
| 293 | case Absyn.UPLUS_EW() then Op.ADD; | ||
| 294 | case Absyn.UMINUS() then Op.UMINUS; | ||
| 295 | case Absyn.UMINUS_EW() then Op.UMINUS; | ||
| 296 | case Absyn.AND() then Op.AND; | ||
| 297 | case Absyn.OR() then Op.OR; | ||
| 298 | case Absyn.NOT() then Op.NOT; | ||
| 299 | case Absyn.LESS() then Op.LESS; | ||
| 300 | case Absyn.LESSEQ() then Op.LESSEQ; | ||
| 301 | case Absyn.GREATER() then Op.GREATER; | ||
| 302 | case Absyn.GREATEREQ() then Op.GREATEREQ; | ||
| 303 | case Absyn.EQUAL() then Op.EQUAL; | ||
| 304 | case Absyn.NEQUAL() then Op.NEQUAL; | ||
| 305 | end match; | ||
| 306 | |||
| 307 | 1101057 | outOperator := OPERATOR(Type.UNKNOWN(), op); | |
| 308 | end fromAbsyn; | ||
| 309 | |||
| 310 | function toAbsyn | ||
| 311 | input Operator op; | ||
| 312 | output Absyn.Operator aop; | ||
| 313 | algorithm | ||
| 314 | aop := match op.op | ||
| 315 | ✗ | case Op.ADD then if Type.isArray(op.ty) then Absyn.Operator.ADD_EW() else Absyn.Operator.ADD(); | |
| 316 | ✗ | case Op.SUB then if Type.isArray(op.ty) then Absyn.Operator.SUB_EW() else Absyn.Operator.SUB(); | |
| 317 | ✗ | case Op.MUL then if Type.isArray(op.ty) then Absyn.Operator.MUL_EW() else Absyn.Operator.MUL(); | |
| 318 | ✗ | case Op.DIV then if Type.isArray(op.ty) then Absyn.Operator.DIV_EW() else Absyn.Operator.DIV(); | |
| 319 | ✗ | case Op.POW then if Type.isArray(op.ty) then Absyn.Operator.POW_EW() else Absyn.Operator.POW(); | |
| 320 | case Op.ADD_EW then Absyn.Operator.ADD_EW(); | ||
| 321 | case Op.SUB_EW then Absyn.Operator.SUB_EW(); | ||
| 322 | case Op.MUL_EW then Absyn.Operator.MUL_EW(); | ||
| 323 | case Op.DIV_EW then Absyn.Operator.DIV_EW(); | ||
| 324 | case Op.POW_EW then Absyn.Operator.POW_EW(); | ||
| 325 | case Op.ADD_SCALAR_ARRAY then Absyn.Operator.ADD(); | ||
| 326 | case Op.ADD_ARRAY_SCALAR then Absyn.Operator.ADD(); | ||
| 327 | case Op.SUB_SCALAR_ARRAY then Absyn.Operator.SUB(); | ||
| 328 | case Op.SUB_ARRAY_SCALAR then Absyn.Operator.SUB(); | ||
| 329 | case Op.MUL_SCALAR_ARRAY then Absyn.Operator.MUL(); | ||
| 330 | case Op.MUL_ARRAY_SCALAR then Absyn.Operator.MUL(); | ||
| 331 | case Op.MUL_VECTOR_MATRIX then Absyn.Operator.MUL(); | ||
| 332 | case Op.MUL_MATRIX_VECTOR then Absyn.Operator.MUL(); | ||
| 333 | case Op.SCALAR_PRODUCT then Absyn.Operator.MUL(); | ||
| 334 | case Op.MATRIX_PRODUCT then Absyn.Operator.MUL(); | ||
| 335 | case Op.DIV_SCALAR_ARRAY then Absyn.Operator.DIV(); | ||
| 336 | case Op.DIV_ARRAY_SCALAR then Absyn.Operator.DIV(); | ||
| 337 | case Op.POW_SCALAR_ARRAY then Absyn.Operator.POW(); | ||
| 338 | case Op.POW_ARRAY_SCALAR then Absyn.Operator.POW(); | ||
| 339 | case Op.POW_MATRIX then Absyn.Operator.POW(); | ||
| 340 | ✗ | case Op.UMINUS then if Type.isArray(op.ty) then Absyn.Operator.UMINUS_EW() else Absyn.Operator.UMINUS(); | |
| 341 | case Op.AND then Absyn.Operator.AND(); | ||
| 342 | case Op.OR then Absyn.Operator.OR(); | ||
| 343 | case Op.NOT then Absyn.Operator.NOT(); | ||
| 344 | case Op.LESS then Absyn.Operator.LESS(); | ||
| 345 | case Op.LESSEQ then Absyn.Operator.LESSEQ(); | ||
| 346 | case Op.GREATER then Absyn.Operator.GREATER(); | ||
| 347 | case Op.EQUAL then Absyn.Operator.EQUAL(); | ||
| 348 | case Op.NEQUAL then Absyn.Operator.NEQUAL(); | ||
| 349 | else | ||
| 350 | algorithm | ||
| 351 | ✗ | Error.terminate(getInstanceName() + " got unknown type.", sourceInfo()); | |
| 352 | ✗ | then | |
| 353 | fail(); | ||
| 354 | end match; | ||
| 355 | end toAbsyn; | ||
| 356 | |||
| 357 | function toDAE | ||
| 358 | input Operator op; | ||
| 359 | output DAE.Operator daeOp; | ||
| 360 | output Boolean swapArguments = false "The DAE structure only has array*scalar, not scalar*array, etc"; | ||
| 361 | output Boolean negate = false "The second argument should be negated."; | ||
| 362 | protected | ||
| 363 | DAE.Type ty; | ||
| 364 | algorithm | ||
| 365 | 761477 | ty := Type.toDAE(op.ty); | |
| 366 | daeOp := match op.op | ||
| 367 |
2/2✓ Branch 1 taken 1956 times.
✓ Branch 2 taken 161506 times.
|
163462 | case Op.ADD then if Type.isArray(op.ty) then DAE.ADD_ARR(ty) else DAE.ADD(ty); |
| 368 |
2/2✓ Branch 1 taken 395 times.
✓ Branch 2 taken 116671 times.
|
117066 | case Op.SUB then if Type.isArray(op.ty) then DAE.SUB_ARR(ty) else DAE.SUB(ty); |
| 369 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 359465 times.
|
359465 | case Op.MUL then if Type.isArray(op.ty) then DAE.MUL_ARR(ty) else DAE.MUL(ty); |
| 370 |
2/2✓ Branch 1 taken 1 time.
✓ Branch 2 taken 45167 times.
|
45168 | case Op.DIV then if Type.isArray(op.ty) then DAE.DIV_ARR(ty) else DAE.DIV(ty); |
| 371 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 23120 times.
|
23120 | case Op.POW then if Type.isArray(op.ty) then DAE.POW_ARR2(ty) else DAE.POW(ty); |
| 372 | ✗ | case Op.ADD_SCALAR_ARRAY algorithm swapArguments := true; then DAE.ADD_ARRAY_SCALAR(ty); | |
| 373 | 3 | case Op.ADD_ARRAY_SCALAR then DAE.ADD_ARRAY_SCALAR(ty); | |
| 374 | 1 | case Op.SUB_SCALAR_ARRAY then DAE.SUB_SCALAR_ARRAY(ty); | |
| 375 | // array .- scalar is handled as array .+ (-scalar) | ||
| 376 | 1 | case Op.SUB_ARRAY_SCALAR algorithm negate := true; then DAE.ADD_ARRAY_SCALAR(ty); | |
| 377 | 346 | case Op.MUL_SCALAR_ARRAY algorithm swapArguments := true; then DAE.MUL_ARRAY_SCALAR(ty); | |
| 378 | 159 | case Op.MUL_ARRAY_SCALAR then DAE.MUL_ARRAY_SCALAR(ty); | |
| 379 | ✗ | case Op.MUL_VECTOR_MATRIX then DAE.MUL_MATRIX_PRODUCT(ty); | |
| 380 | 68 | case Op.MUL_MATRIX_VECTOR then DAE.MUL_MATRIX_PRODUCT(ty); | |
| 381 | 405 | case Op.SCALAR_PRODUCT then DAE.MUL_SCALAR_PRODUCT(ty); | |
| 382 | 8 | case Op.ADD_EW then DAE.ADD_ARR(ty); | |
| 383 | 44 | case Op.SUB_EW then DAE.SUB_ARR(ty); | |
| 384 | 38 | case Op.MUL_EW then DAE.MUL_ARR(ty); | |
| 385 | ✗ | case Op.DIV_EW then DAE.DIV_ARR(ty); | |
| 386 | 156 | case Op.MATRIX_PRODUCT then DAE.MUL_MATRIX_PRODUCT(ty); | |
| 387 | ✗ | case Op.DIV_SCALAR_ARRAY then DAE.DIV_SCALAR_ARRAY(ty); | |
| 388 | 215 | case Op.DIV_ARRAY_SCALAR then DAE.DIV_ARRAY_SCALAR(ty); | |
| 389 | ✗ | case Op.POW_SCALAR_ARRAY then DAE.POW_SCALAR_ARRAY(ty); | |
| 390 | 18 | case Op.POW_ARRAY_SCALAR then DAE.POW_ARRAY_SCALAR(ty); | |
| 391 | 4 | case Op.POW_MATRIX then DAE.POW_ARR(ty); | |
| 392 |
2/2✓ Branch 1 taken 328 times.
✓ Branch 2 taken 27115 times.
|
27443 | case Op.UMINUS then if Type.isArray(op.ty) then DAE.UMINUS_ARR(ty) else DAE.UMINUS(ty); |
| 393 | 2669 | case Op.AND then DAE.AND(ty); | |
| 394 | 1133 | case Op.OR then DAE.OR(ty); | |
| 395 | 920 | case Op.NOT then DAE.NOT(ty); | |
| 396 | 4657 | case Op.LESS then DAE.LESS(ty); | |
| 397 | 2324 | case Op.LESSEQ then DAE.LESSEQ(ty); | |
| 398 | 5411 | case Op.GREATER then DAE.GREATER(ty); | |
| 399 | 3458 | case Op.GREATEREQ then DAE.GREATEREQ(ty); | |
| 400 | 3028 | case Op.EQUAL then DAE.EQUAL(ty); | |
| 401 | 687 | case Op.NEQUAL then DAE.NEQUAL(ty); | |
| 402 | else | ||
| 403 | algorithm | ||
| 404 | ✗ | Error.terminate(getInstanceName() + " got unknown type: " + opToString(op.op), sourceInfo()); | |
| 405 | ✗ | then | |
| 406 | fail(); | ||
| 407 | end match; | ||
| 408 | end toDAE; | ||
| 409 | |||
| 410 | function typeOf | ||
| 411 | input Operator op; | ||
| 412 | output Type ty = op.ty; | ||
| 413 | end typeOf; | ||
| 414 | |||
| 415 | function setType | ||
| 416 | input Type ty; | ||
| 417 | input output Operator op; | ||
| 418 | algorithm | ||
| 419 | 122733 | op.ty := ty; | |
| 420 | end setType; | ||
| 421 | |||
| 422 | function scalarize | ||
| 423 | input output Operator op; | ||
| 424 | algorithm | ||
| 425 | 51364 | op.ty := Type.arrayElementType(op.ty); | |
| 426 | end scalarize; | ||
| 427 | |||
| 428 | function unlift | ||
| 429 | input output Operator op; | ||
| 430 | algorithm | ||
| 431 | 995 | op.ty := Type.unliftArray(op.ty); | |
| 432 | end unlift; | ||
| 433 | |||
| 434 | function symbol | ||
| 435 | input Operator op; | ||
| 436 | input String spacing = " "; | ||
| 437 | output String symbol; | ||
| 438 | algorithm | ||
| 439 | symbol := match op.op | ||
| 440 | case Op.ADD then "+"; | ||
| 441 | case Op.SUB then "-"; | ||
| 442 | case Op.MUL then "*"; | ||
| 443 | case Op.DIV then "/"; | ||
| 444 | case Op.POW then "^"; | ||
| 445 | case Op.ADD_EW then ".+"; | ||
| 446 | case Op.SUB_EW then ".-"; | ||
| 447 | case Op.MUL_EW then ".*"; | ||
| 448 | case Op.DIV_EW then "./"; | ||
| 449 | case Op.POW_EW then ".^"; | ||
| 450 | case Op.ADD_SCALAR_ARRAY then ".+"; | ||
| 451 | case Op.ADD_ARRAY_SCALAR then ".+"; | ||
| 452 | case Op.SUB_SCALAR_ARRAY then ".-"; | ||
| 453 | case Op.SUB_ARRAY_SCALAR then ".-"; | ||
| 454 | case Op.MUL_SCALAR_ARRAY then "*"; | ||
| 455 | case Op.MUL_ARRAY_SCALAR then ".*"; | ||
| 456 | case Op.MUL_VECTOR_MATRIX then "*"; | ||
| 457 | case Op.MUL_MATRIX_VECTOR then "*"; | ||
| 458 | case Op.SCALAR_PRODUCT then "*"; | ||
| 459 | case Op.MATRIX_PRODUCT then "*"; | ||
| 460 | case Op.DIV_SCALAR_ARRAY then "./"; | ||
| 461 | case Op.DIV_ARRAY_SCALAR then "/"; | ||
| 462 | case Op.POW_SCALAR_ARRAY then ".^"; | ||
| 463 | case Op.POW_ARRAY_SCALAR then ".^"; | ||
| 464 | case Op.POW_MATRIX then "^"; | ||
| 465 | case Op.UMINUS then "-"; | ||
| 466 | case Op.AND then "and"; | ||
| 467 | case Op.OR then "or"; | ||
| 468 | case Op.NOT then "not"; | ||
| 469 | case Op.LESS then "<"; | ||
| 470 | case Op.LESSEQ then "<="; | ||
| 471 | case Op.GREATER then ">"; | ||
| 472 | case Op.GREATEREQ then ">="; | ||
| 473 | case Op.EQUAL then "=="; | ||
| 474 | case Op.NEQUAL then "<>"; | ||
| 475 | //case Op.USERDEFINED then "Userdefined:" + AbsynUtil.pathString(op.fqName); | ||
| 476 | else | ||
| 477 | algorithm | ||
| 478 | ✗ | Error.terminate(getInstanceName() + " got unknown type.", sourceInfo()); | |
| 479 | ✗ | then | |
| 480 | fail(); | ||
| 481 | end match; | ||
| 482 | |||
| 483 | 72920 | symbol := spacing + symbol + spacing; | |
| 484 | end symbol; | ||
| 485 | |||
| 486 | function toJSON | ||
| 487 | input Operator operator; | ||
| 488 | output JSON json; | ||
| 489 | protected | ||
| 490 | constant array<JSON> symbols = MetaModelica.Dangerous.listArrayLiteral({ | ||
| 491 | JSON.STRING("+"), | ||
| 492 | JSON.STRING("-"), | ||
| 493 | JSON.STRING("*"), | ||
| 494 | JSON.STRING("/"), | ||
| 495 | JSON.STRING("^"), | ||
| 496 | JSON.STRING(".+"), | ||
| 497 | JSON.STRING(".-"), | ||
| 498 | JSON.STRING(".*"), | ||
| 499 | JSON.STRING("./"), | ||
| 500 | JSON.STRING(".^"), | ||
| 501 | JSON.STRING(".+"), | ||
| 502 | JSON.STRING(".+"), | ||
| 503 | JSON.STRING(".-"), | ||
| 504 | JSON.STRING(".-"), | ||
| 505 | JSON.STRING("*"), | ||
| 506 | JSON.STRING(".*"), | ||
| 507 | JSON.STRING("*"), | ||
| 508 | JSON.STRING("*"), | ||
| 509 | JSON.STRING("*"), | ||
| 510 | JSON.STRING("*"), | ||
| 511 | JSON.STRING("./"), | ||
| 512 | JSON.STRING("/"), | ||
| 513 | JSON.STRING(".^"), | ||
| 514 | JSON.STRING(".^"), | ||
| 515 | JSON.STRING("^"), | ||
| 516 | JSON.STRING("-"), | ||
| 517 | JSON.STRING("and"), | ||
| 518 | JSON.STRING("or"), | ||
| 519 | JSON.STRING("not"), | ||
| 520 | JSON.STRING("<"), | ||
| 521 | JSON.STRING("<="), | ||
| 522 | JSON.STRING(">"), | ||
| 523 | JSON.STRING(">="), | ||
| 524 | JSON.STRING("=="), | ||
| 525 | JSON.STRING("<>") | ||
| 526 | }); | ||
| 527 | |||
| 528 | Op op = operator.op; | ||
| 529 | algorithm | ||
| 530 | 3 | json := symbols[Integer(op)]; | |
| 531 | end toJSON; | ||
| 532 | |||
| 533 | function priority | ||
| 534 | input Operator op; | ||
| 535 | input Boolean lhs; | ||
| 536 | output Integer priority; | ||
| 537 | algorithm | ||
| 538 | priority := match op.op | ||
| 539 |
2/2✓ Branch 0 taken 17547 times.
✓ Branch 1 taken 3573 times.
|
21120 | case Op.ADD then if lhs then 5 else 6; |
| 540 | case Op.SUB then 5; | ||
| 541 | case Op.MUL then 2; | ||
| 542 | case Op.DIV then 2; | ||
| 543 | case Op.POW then 1; | ||
| 544 |
1/2✓ Branch 0 taken 5 times.
✗ Branch 1 not taken.
|
5 | case Op.ADD_EW then if lhs then 5 else 6; |
| 545 | case Op.SUB_EW then 5; | ||
| 546 |
1/2✓ Branch 0 taken 50 times.
✗ Branch 1 not taken.
|
50 | case Op.MUL_EW then if lhs then 2 else 3; |
| 547 | case Op.DIV_EW then 2; | ||
| 548 | case Op.POW_EW then 1; | ||
| 549 | ✗ | case Op.ADD_SCALAR_ARRAY then if lhs then 5 else 6; | |
| 550 | ✗ | case Op.ADD_ARRAY_SCALAR then if lhs then 5 else 6; | |
| 551 | case Op.SUB_SCALAR_ARRAY then 5; | ||
| 552 | case Op.SUB_ARRAY_SCALAR then 5; | ||
| 553 |
1/2✓ Branch 0 taken 64 times.
✗ Branch 1 not taken.
|
64 | case Op.MUL_SCALAR_ARRAY then if lhs then 2 else 3; |
| 554 |
1/2✓ Branch 0 taken 8 times.
✗ Branch 1 not taken.
|
8 | case Op.MUL_ARRAY_SCALAR then if lhs then 2 else 3; |
| 555 | ✗ | case Op.MUL_VECTOR_MATRIX then if lhs then 2 else 3; | |
| 556 |
2/2✓ Branch 0 taken 4 times.
✓ Branch 1 taken 3 times.
|
7 | case Op.MUL_MATRIX_VECTOR then if lhs then 2 else 3; |
| 557 |
2/2✓ Branch 0 taken 66 times.
✓ Branch 1 taken 54 times.
|
120 | case Op.SCALAR_PRODUCT then if lhs then 2 else 3; |
| 558 |
2/2✓ Branch 0 taken 8 times.
✓ Branch 1 taken 9 times.
|
17 | case Op.MATRIX_PRODUCT then if lhs then 2 else 3; |
| 559 | case Op.DIV_SCALAR_ARRAY then 2; | ||
| 560 | case Op.DIV_ARRAY_SCALAR then 2; | ||
| 561 | case Op.POW_SCALAR_ARRAY then 1; | ||
| 562 | case Op.POW_ARRAY_SCALAR then 1; | ||
| 563 | case Op.POW_MATRIX then 1; | ||
| 564 | case Op.AND then 8; | ||
| 565 | case Op.OR then 9; | ||
| 566 | else 0; | ||
| 567 | end match; | ||
| 568 | end priority; | ||
| 569 | |||
| 570 | function isAssociative | ||
| 571 | input Operator op; | ||
| 572 | output Boolean isAssociative; | ||
| 573 | algorithm | ||
| 574 | isAssociative := match op.op | ||
| 575 | case Op.ADD then true; | ||
| 576 | case Op.ADD_EW then true; | ||
| 577 | //case ADD_ARRAY_SCALAR() then true; | ||
| 578 | case Op.MUL_EW then true; | ||
| 579 | //case MUL_ARRAY_SCALAR() then true; | ||
| 580 | else false; | ||
| 581 | end match; | ||
| 582 | end isAssociative; | ||
| 583 | |||
| 584 | function isNonAssociative | ||
| 585 | input Operator op; | ||
| 586 | output Boolean isNonAssociative; | ||
| 587 | algorithm | ||
| 588 | isNonAssociative := match op.op | ||
| 589 | case Op.POW then true; | ||
| 590 | case Op.POW_EW then true; | ||
| 591 | case Op.POW_SCALAR_ARRAY then true; | ||
| 592 | case Op.POW_ARRAY_SCALAR then true; | ||
| 593 | case Op.POW_MATRIX then true; | ||
| 594 | else false; | ||
| 595 | end match; | ||
| 596 | end isNonAssociative; | ||
| 597 | |||
| 598 | function makeAdd | ||
| 599 | input Type ty; | ||
| 600 | output Operator op = OPERATOR(ty, Op.ADD); | ||
| 601 | end makeAdd; | ||
| 602 | |||
| 603 | function makeSub | ||
| 604 | input Type ty; | ||
| 605 | output Operator op = OPERATOR(ty, Op.SUB); | ||
| 606 | end makeSub; | ||
| 607 | |||
| 608 | function makeMul | ||
| 609 | input Type ty; | ||
| 610 | output Operator op = OPERATOR(ty, Op.MUL); | ||
| 611 | end makeMul; | ||
| 612 | |||
| 613 | function makeScalarProduct | ||
| 614 | input Type ty; | ||
| 615 | output Operator op = OPERATOR(ty, Op.SCALAR_PRODUCT); | ||
| 616 | end makeScalarProduct; | ||
| 617 | |||
| 618 | function makeDiv | ||
| 619 | input Type ty; | ||
| 620 | output Operator op = OPERATOR(ty, Op.DIV); | ||
| 621 | end makeDiv; | ||
| 622 | |||
| 623 | function makePow | ||
| 624 | input Type ty; | ||
| 625 | output Operator op = OPERATOR(ty, Op.POW); | ||
| 626 | end makePow; | ||
| 627 | |||
| 628 | function makeAddEW | ||
| 629 | input Type ty; | ||
| 630 | output Operator op = OPERATOR(ty, Op.ADD_EW); | ||
| 631 | end makeAddEW; | ||
| 632 | |||
| 633 | function makeSubEW | ||
| 634 | input Type ty; | ||
| 635 | output Operator op = OPERATOR(ty, Op.SUB_EW); | ||
| 636 | end makeSubEW; | ||
| 637 | |||
| 638 | function makeMulEW | ||
| 639 | input Type ty; | ||
| 640 | output Operator op = OPERATOR(ty, Op.MUL_EW); | ||
| 641 | end makeMulEW; | ||
| 642 | |||
| 643 | function makeDivEW | ||
| 644 | input Type ty; | ||
| 645 | output Operator op = OPERATOR(ty, Op.DIV_EW); | ||
| 646 | end makeDivEW; | ||
| 647 | |||
| 648 | function makeUMinus | ||
| 649 | input Type ty; | ||
| 650 | output Operator op = OPERATOR(ty, Op.UMINUS); | ||
| 651 | end makeUMinus; | ||
| 652 | |||
| 653 | function makeAnd | ||
| 654 | input Type ty; | ||
| 655 | output Operator op = OPERATOR(ty, Op.AND); | ||
| 656 | end makeAnd; | ||
| 657 | |||
| 658 | function makeOr | ||
| 659 | input Type ty; | ||
| 660 | output Operator op = OPERATOR(ty, Op.OR); | ||
| 661 | end makeOr; | ||
| 662 | |||
| 663 | function makeNot | ||
| 664 | input Type ty; | ||
| 665 | output Operator op = OPERATOR(ty, Op.NOT); | ||
| 666 | end makeNot; | ||
| 667 | |||
| 668 | function makeLess | ||
| 669 | input Type ty; | ||
| 670 | output Operator op = OPERATOR(ty, Op.LESS); | ||
| 671 | end makeLess; | ||
| 672 | |||
| 673 | function makeLessEq | ||
| 674 | input Type ty; | ||
| 675 | output Operator op = OPERATOR(ty, Op.LESSEQ); | ||
| 676 | end makeLessEq; | ||
| 677 | |||
| 678 | function makeGreater | ||
| 679 | input Type ty; | ||
| 680 | output Operator op = OPERATOR(ty, Op.GREATER); | ||
| 681 | end makeGreater; | ||
| 682 | |||
| 683 | function makeGreaterEq | ||
| 684 | input Type ty; | ||
| 685 | output Operator op = OPERATOR(ty, Op.GREATEREQ); | ||
| 686 | end makeGreaterEq; | ||
| 687 | |||
| 688 | function makeEqual | ||
| 689 | input Type ty; | ||
| 690 | output Operator op = OPERATOR(ty, Op.EQUAL); | ||
| 691 | end makeEqual; | ||
| 692 | |||
| 693 | function makeNotEqual | ||
| 694 | input Type ty; | ||
| 695 | output Operator op = OPERATOR(ty, Op.NEQUAL); | ||
| 696 | end makeNotEqual; | ||
| 697 | |||
| 698 | function makeScalarArray | ||
| 699 | input Type ty; | ||
| 700 | input Op op; | ||
| 701 | output Operator outOp; | ||
| 702 | protected | ||
| 703 | Op o; | ||
| 704 | algorithm | ||
| 705 | o := match op | ||
| 706 | case Op.ADD then Op.ADD_SCALAR_ARRAY; | ||
| 707 | case Op.SUB then Op.SUB_SCALAR_ARRAY; | ||
| 708 | case Op.MUL then Op.MUL_SCALAR_ARRAY; | ||
| 709 | case Op.DIV then Op.DIV_SCALAR_ARRAY; | ||
| 710 | case Op.POW then Op.POW_SCALAR_ARRAY; | ||
| 711 | end match; | ||
| 712 | |||
| 713 | 13 | outOp := OPERATOR(ty, o); | |
| 714 | end makeScalarArray; | ||
| 715 | |||
| 716 | function makeArrayScalar | ||
| 717 | input Type ty; | ||
| 718 | input Op op; | ||
| 719 | output Operator outOp; | ||
| 720 | protected | ||
| 721 | Op o; | ||
| 722 | algorithm | ||
| 723 | o := match op | ||
| 724 | case Op.ADD then Op.ADD_ARRAY_SCALAR; | ||
| 725 | case Op.SUB then Op.SUB_ARRAY_SCALAR; | ||
| 726 | case Op.MUL then Op.MUL_ARRAY_SCALAR; | ||
| 727 | case Op.DIV then Op.DIV_ARRAY_SCALAR; | ||
| 728 | case Op.POW then Op.POW_ARRAY_SCALAR; | ||
| 729 | end match; | ||
| 730 | |||
| 731 | 12 | outOp := OPERATOR(ty, o); | |
| 732 | end makeArrayScalar; | ||
| 733 | |||
| 734 | function makeEW | ||
| 735 | input output Operator op; | ||
| 736 | algorithm | ||
| 737 | () := match op.op | ||
| 738 | ✗ | case Op.ADD algorithm op.op := Op.ADD_EW; then (); | |
| 739 | ✗ | case Op.SUB algorithm op.op := Op.SUB_EW; then (); | |
| 740 | 111 | case Op.MUL algorithm op.op := Op.MUL_EW; then (); | |
| 741 | ✗ | case Op.DIV algorithm op.op := Op.DIV_EW; then (); | |
| 742 | ✗ | case Op.POW algorithm op.op := Op.POW_EW; then (); | |
| 743 | else (); | ||
| 744 | end match; | ||
| 745 | end makeEW; | ||
| 746 | |||
| 747 | function stripEW | ||
| 748 | input output Operator op; | ||
| 749 | algorithm | ||
| 750 | () := match op.op | ||
| 751 | ✗ | case Op.ADD_EW algorithm op.op := Op.ADD; then (); | |
| 752 | ✗ | case Op.SUB_EW algorithm op.op := Op.SUB; then (); | |
| 753 | 8 | case Op.MUL_EW algorithm op.op := Op.MUL; then (); | |
| 754 | ✗ | case Op.DIV_EW algorithm op.op := Op.DIV; then (); | |
| 755 | ✗ | case Op.POW_EW algorithm op.op := Op.POW; then (); | |
| 756 | else (); | ||
| 757 | end match; | ||
| 758 | end stripEW; | ||
| 759 | |||
| 760 | function isElementWise | ||
| 761 | input Operator op; | ||
| 762 | output Boolean ew; | ||
| 763 | algorithm | ||
| 764 | ew := match op.op | ||
| 765 | case Op.ADD_EW then true; | ||
| 766 | case Op.SUB_EW then true; | ||
| 767 | case Op.MUL_EW then true; | ||
| 768 | case Op.DIV_EW then true; | ||
| 769 | case Op.POW_EW then true; | ||
| 770 | else false; | ||
| 771 | end match; | ||
| 772 | end isElementWise; | ||
| 773 | |||
| 774 | type MathClassification = enumeration(ADDITION, SUBTRACTION, MULTIPLICATION, DIVISION, POWER, LOGICAL, RELATION); | ||
| 775 | type SizeClassification = enumeration(SCALAR, ELEMENT_WISE, ARRAY_SCALAR, SCALAR_ARRAY, MATRIX, VECTOR_MATRIX, MATRIX_VECTOR, LOGICAL, RELATION); | ||
| 776 | type Classification = tuple<MathClassification, SizeClassification>; | ||
| 777 | |||
| 778 | function mathSymbol | ||
| 779 | input MathClassification mcl; | ||
| 780 | output String str; | ||
| 781 | algorithm | ||
| 782 | str := match mcl | ||
| 783 | case MathClassification.ADDITION then "+"; | ||
| 784 | case MathClassification.SUBTRACTION then "-"; | ||
| 785 | case MathClassification.MULTIPLICATION then "*"; | ||
| 786 | case MathClassification.DIVISION then "/"; | ||
| 787 | case MathClassification.POWER then "^"; | ||
| 788 | case MathClassification.LOGICAL then "L"; | ||
| 789 | case MathClassification.RELATION then "R"; | ||
| 790 | else fail(); | ||
| 791 | end match; | ||
| 792 | end mathSymbol; | ||
| 793 | |||
| 794 | function classificationString | ||
| 795 | input Classification cla; | ||
| 796 | output String str; | ||
| 797 | protected | ||
| 798 | MathClassification mcl; | ||
| 799 | SizeClassification scl; | ||
| 800 | algorithm | ||
| 801 | ✗ | (mcl, scl) := cla; | |
| 802 | ✗ | str := mathClassificationString(mcl) + sizeClassificationString(scl); | |
| 803 | end classificationString; | ||
| 804 | |||
| 805 | function mathClassificationString | ||
| 806 | input MathClassification mcl; | ||
| 807 | output String str; | ||
| 808 | algorithm | ||
| 809 | str := match mcl | ||
| 810 | case MathClassification.ADDITION then "[ADD]"; | ||
| 811 | case MathClassification.SUBTRACTION then "[SUB]"; | ||
| 812 | case MathClassification.MULTIPLICATION then "[MUL]"; | ||
| 813 | case MathClassification.DIVISION then "[DIV]"; | ||
| 814 | case MathClassification.POWER then "[POW]"; | ||
| 815 | case MathClassification.LOGICAL then "[LOG]"; | ||
| 816 | case MathClassification.RELATION then "[REL]"; | ||
| 817 | else fail(); | ||
| 818 | end match; | ||
| 819 | end mathClassificationString; | ||
| 820 | |||
| 821 | function sizeClassificationString | ||
| 822 | input SizeClassification scl; | ||
| 823 | output String str; | ||
| 824 | algorithm | ||
| 825 | str := match scl | ||
| 826 | case SizeClassification.SCALAR then "[SCALAR]"; | ||
| 827 | case SizeClassification.ELEMENT_WISE then "[ELMWIS]"; | ||
| 828 | case SizeClassification.ARRAY_SCALAR then "[ARR-SC]"; | ||
| 829 | case SizeClassification.SCALAR_ARRAY then "[SC-ARR]"; | ||
| 830 | case SizeClassification.MATRIX then "[MATRIX]"; | ||
| 831 | case SizeClassification.VECTOR_MATRIX then "[VEC-MA]"; | ||
| 832 | case SizeClassification.MATRIX_VECTOR then "[MA-VEC]"; | ||
| 833 | case SizeClassification.LOGICAL then "[LOGICL]"; | ||
| 834 | case SizeClassification.RELATION then "[RELATN]"; | ||
| 835 | else fail(); | ||
| 836 | end match; | ||
| 837 | end sizeClassificationString; | ||
| 838 | |||
| 839 | function classify | ||
| 840 | input Operator op; | ||
| 841 | output Classification cl; | ||
| 842 | algorithm | ||
| 843 | cl := match op.op | ||
| 844 | case Op.ADD then (MathClassification.ADDITION, SizeClassification.SCALAR); | ||
| 845 | case Op.SUB then (MathClassification.SUBTRACTION, SizeClassification.SCALAR); | ||
| 846 | case Op.MUL then (MathClassification.MULTIPLICATION, SizeClassification.SCALAR); | ||
| 847 | case Op.DIV then (MathClassification.DIVISION, SizeClassification.SCALAR); | ||
| 848 | case Op.POW then (MathClassification.POWER, SizeClassification.SCALAR); | ||
| 849 | case Op.ADD_EW then (MathClassification.ADDITION, SizeClassification.ELEMENT_WISE); | ||
| 850 | case Op.SUB_EW then (MathClassification.SUBTRACTION, SizeClassification.ELEMENT_WISE); | ||
| 851 | case Op.MUL_EW then (MathClassification.MULTIPLICATION, SizeClassification.ELEMENT_WISE); | ||
| 852 | case Op.DIV_EW then (MathClassification.DIVISION, SizeClassification.ELEMENT_WISE); | ||
| 853 | case Op.POW_EW then (MathClassification.POWER, SizeClassification.ELEMENT_WISE); | ||
| 854 | case Op.MUL_ARRAY_SCALAR then (MathClassification.MULTIPLICATION, SizeClassification.ARRAY_SCALAR); | ||
| 855 | case Op.MUL_SCALAR_ARRAY then (MathClassification.MULTIPLICATION, SizeClassification.SCALAR_ARRAY); | ||
| 856 | case Op.ADD_ARRAY_SCALAR then (MathClassification.ADDITION, SizeClassification.ARRAY_SCALAR); | ||
| 857 | case Op.ADD_SCALAR_ARRAY then (MathClassification.ADDITION, SizeClassification.SCALAR_ARRAY); | ||
| 858 | case Op.SUB_ARRAY_SCALAR then (MathClassification.SUBTRACTION, SizeClassification.ARRAY_SCALAR); | ||
| 859 | case Op.SUB_SCALAR_ARRAY then (MathClassification.SUBTRACTION, SizeClassification.SCALAR_ARRAY); | ||
| 860 | case Op.SCALAR_PRODUCT then (MathClassification.MULTIPLICATION, SizeClassification.SCALAR); | ||
| 861 | case Op.MATRIX_PRODUCT then (MathClassification.MULTIPLICATION, SizeClassification.MATRIX); | ||
| 862 | case Op.MUL_VECTOR_MATRIX then (MathClassification.MULTIPLICATION, SizeClassification.VECTOR_MATRIX); | ||
| 863 | case Op.MUL_MATRIX_VECTOR then (MathClassification.MULTIPLICATION, SizeClassification.MATRIX_VECTOR); | ||
| 864 | case Op.DIV_ARRAY_SCALAR then (MathClassification.DIVISION, SizeClassification.ARRAY_SCALAR); | ||
| 865 | case Op.DIV_SCALAR_ARRAY then (MathClassification.DIVISION, SizeClassification.SCALAR_ARRAY); | ||
| 866 | case Op.POW_ARRAY_SCALAR then (MathClassification.POWER, SizeClassification.ARRAY_SCALAR); | ||
| 867 | case Op.POW_SCALAR_ARRAY then (MathClassification.POWER, SizeClassification.SCALAR_ARRAY); | ||
| 868 | case Op.POW_MATRIX then (MathClassification.POWER, SizeClassification.MATRIX); | ||
| 869 | case Op.AND then (MathClassification.LOGICAL, SizeClassification.LOGICAL); | ||
| 870 | case Op.OR then (MathClassification.LOGICAL, SizeClassification.LOGICAL); | ||
| 871 | case Op.NOT then (MathClassification.LOGICAL, SizeClassification.LOGICAL); | ||
| 872 | case Op.LESS then (MathClassification.RELATION, SizeClassification.RELATION); | ||
| 873 | case Op.LESSEQ then (MathClassification.RELATION, SizeClassification.RELATION); | ||
| 874 | case Op.GREATER then (MathClassification.RELATION, SizeClassification.RELATION); | ||
| 875 | case Op.GREATEREQ then (MathClassification.RELATION, SizeClassification.RELATION); | ||
| 876 | case Op.EQUAL then (MathClassification.RELATION, SizeClassification.RELATION); | ||
| 877 | case Op.NEQUAL then (MathClassification.RELATION, SizeClassification.RELATION); | ||
| 878 | else algorithm | ||
| 879 | ✗ | Error.addInternalError(getInstanceName() + ": Don't know how to handle " + String(op.op), sourceInfo()); | |
| 880 | ✗ | then fail(); | |
| 881 | end match; | ||
| 882 | end classify; | ||
| 883 | |||
| 884 | function classifyAddition | ||
| 885 | "used to create an addition of the resulting type. | ||
| 886 | Note: not to be used for logical or relations" | ||
| 887 | input Operator op; | ||
| 888 | output SizeClassification sz = if Type.isScalar(op.ty) then SizeClassification.SCALAR else SizeClassification.ELEMENT_WISE; | ||
| 889 | end classifyAddition; | ||
| 890 | |||
| 891 | function fromClassification | ||
| 892 | "Only works for non-logical operators!" | ||
| 893 | input Classification cl "mathematical and size classification"; | ||
| 894 | input Type ty "Type information"; | ||
| 895 | output Operator result "Resulting operator"; | ||
| 896 | protected | ||
| 897 | Op op; | ||
| 898 | algorithm | ||
| 899 | op := match cl | ||
| 900 | case (MathClassification.ADDITION, SizeClassification.SCALAR) then Op.ADD; | ||
| 901 | case (MathClassification.SUBTRACTION, SizeClassification.SCALAR) then Op.SUB; | ||
| 902 | case (MathClassification.MULTIPLICATION, SizeClassification.SCALAR) then Op.MUL; | ||
| 903 | // this has to be done correctly. use type of the expressions? | ||
| 904 | //case (MathClassification.MULTIPLICATION, SizeClassification.SCALAR) then Op.SCALAR_PRODUCT; | ||
| 905 | case (MathClassification.DIVISION, SizeClassification.SCALAR) then Op.DIV; | ||
| 906 | case (MathClassification.POWER, SizeClassification.SCALAR) then Op.POW; | ||
| 907 | |||
| 908 | case (MathClassification.ADDITION, SizeClassification.ELEMENT_WISE) then Op.ADD_EW; | ||
| 909 | case (MathClassification.SUBTRACTION, SizeClassification.ELEMENT_WISE) then Op.SUB_EW; | ||
| 910 | case (MathClassification.MULTIPLICATION, SizeClassification.ELEMENT_WISE) then Op.MUL_EW; | ||
| 911 | case (MathClassification.DIVISION, SizeClassification.ELEMENT_WISE) then Op.DIV_EW; | ||
| 912 | case (MathClassification.POWER, SizeClassification.ELEMENT_WISE) then Op.POW_EW; | ||
| 913 | |||
| 914 | case (MathClassification.ADDITION, SizeClassification.ARRAY_SCALAR) then Op.ADD_ARRAY_SCALAR; | ||
| 915 | case (MathClassification.SUBTRACTION, SizeClassification.ARRAY_SCALAR) then Op.SUB_ARRAY_SCALAR; | ||
| 916 | case (MathClassification.MULTIPLICATION, SizeClassification.ARRAY_SCALAR) then Op.MUL_ARRAY_SCALAR; | ||
| 917 | case (MathClassification.DIVISION, SizeClassification.ARRAY_SCALAR) then Op.DIV_ARRAY_SCALAR; | ||
| 918 | case (MathClassification.POWER, SizeClassification.ARRAY_SCALAR) then Op.POW_ARRAY_SCALAR; | ||
| 919 | |||
| 920 | case (MathClassification.ADDITION, SizeClassification.SCALAR_ARRAY) then Op.ADD_SCALAR_ARRAY; | ||
| 921 | case (MathClassification.SUBTRACTION, SizeClassification.SCALAR_ARRAY) then Op.SUB_SCALAR_ARRAY; | ||
| 922 | case (MathClassification.MULTIPLICATION, SizeClassification.SCALAR_ARRAY) then Op.MUL_SCALAR_ARRAY; | ||
| 923 | case (MathClassification.DIVISION, SizeClassification.SCALAR_ARRAY) then Op.DIV_SCALAR_ARRAY; | ||
| 924 | case (MathClassification.POWER, SizeClassification.SCALAR_ARRAY) then Op.POW_SCALAR_ARRAY; | ||
| 925 | |||
| 926 | case (MathClassification.ADDITION, SizeClassification.MATRIX) then Op.ADD_EW; | ||
| 927 | case (MathClassification.SUBTRACTION, SizeClassification.MATRIX) then Op.SUB_EW; | ||
| 928 | case (MathClassification.POWER, SizeClassification.MATRIX) then Op.POW_MATRIX; | ||
| 929 | case (MathClassification.MULTIPLICATION, SizeClassification.MATRIX) then Op.MATRIX_PRODUCT; | ||
| 930 | case (MathClassification.MULTIPLICATION, SizeClassification.VECTOR_MATRIX) then Op.MUL_VECTOR_MATRIX; | ||
| 931 | case (MathClassification.MULTIPLICATION, SizeClassification.MATRIX_VECTOR) then Op.MUL_MATRIX_VECTOR; | ||
| 932 | else algorithm | ||
| 933 | ✗ | Error.addInternalError(getInstanceName() + ": Don't know how to handle math class and size class combination: " + classificationString(cl), sourceInfo()); | |
| 934 | ✗ | then fail(); | |
| 935 | end match; | ||
| 936 | 62288 | result := OPERATOR(ty, op); | |
| 937 | end fromClassification; | ||
| 938 | |||
| 939 | function getMathClassification | ||
| 940 | input Operator op; | ||
| 941 | output MathClassification mcl; | ||
| 942 | algorithm | ||
| 943 | 189395 | (mcl, _) := classify(op); | |
| 944 | end getMathClassification; | ||
| 945 | |||
| 946 | function getSizeClassification | ||
| 947 | input Operator op; | ||
| 948 | output SizeClassification scl; | ||
| 949 | algorithm | ||
| 950 | 681 | (_, scl) := classify(op); | |
| 951 | end getSizeClassification; | ||
| 952 | |||
| 953 | function combineSizeClassification | ||
| 954 | input SizeClassification scl1; | ||
| 955 | input SizeClassification scl2; | ||
| 956 | output SizeClassification scl; | ||
| 957 | algorithm | ||
| 958 | scl := match (scl1, scl2) | ||
| 959 | // Todo: more cases? | ||
| 960 | case (SizeClassification.ELEMENT_WISE, SizeClassification.SCALAR) then SizeClassification.ARRAY_SCALAR; | ||
| 961 | case (SizeClassification.SCALAR, SizeClassification.ELEMENT_WISE) then SizeClassification.SCALAR_ARRAY; | ||
| 962 | else scl1; | ||
| 963 | end match; | ||
| 964 | end combineSizeClassification; | ||
| 965 | |||
| 966 | function isDashClassification | ||
| 967 | input MathClassification mcl; | ||
| 968 | output Boolean b; | ||
| 969 | algorithm | ||
| 970 | b := match mcl | ||
| 971 | case MathClassification.ADDITION then true; | ||
| 972 | case MathClassification.SUBTRACTION then true; | ||
| 973 | else false; | ||
| 974 | end match; | ||
| 975 | end isDashClassification; | ||
| 976 | |||
| 977 | function isCommutative | ||
| 978 | "returns true for operators that are commutative" | ||
| 979 | input Operator operator; | ||
| 980 | output Boolean b; | ||
| 981 | algorithm | ||
| 982 | b := match Type.arrayElementType(operator.ty) | ||
| 983 | case Type.INTEGER() then true; | ||
| 984 | case Type.REAL() then true; | ||
| 985 | case Type.BOOLEAN() then true; | ||
| 986 | else false; | ||
| 987 | end match; | ||
| 988 | 56 | if not b then return; end if; | |
| 989 | |||
| 990 | b := match operator.op | ||
| 991 | case Op.ADD then true; | ||
| 992 | case Op.MUL then true; | ||
| 993 | case Op.ADD_EW then true; | ||
| 994 | case Op.MUL_EW then true; | ||
| 995 | // the following might need adaption since they depend on argument ordering | ||
| 996 | // furthermore weird regarding more than two arguments in Expression.MULTARY() | ||
| 997 | case Op.ADD_SCALAR_ARRAY then true; | ||
| 998 | case Op.ADD_ARRAY_SCALAR then true; | ||
| 999 | case Op.MUL_SCALAR_ARRAY then true; | ||
| 1000 | case Op.MUL_ARRAY_SCALAR then true; | ||
| 1001 | else false; | ||
| 1002 | end match; | ||
| 1003 | end isCommutative; | ||
| 1004 | |||
| 1005 | function isSoftCommutative | ||
| 1006 | "returns true for operators that are not commutative but have an easy rule for swapping arguments" | ||
| 1007 | input Operator operator; | ||
| 1008 | output Boolean b; | ||
| 1009 | algorithm | ||
| 1010 | b := match operator.op | ||
| 1011 | case Op.SUB then true; | ||
| 1012 | case Op.DIV then true; | ||
| 1013 | case Op.SUB_EW then true; | ||
| 1014 | case Op.DIV_EW then true; | ||
| 1015 | // the following might need adaption since they depend on argument ordering | ||
| 1016 | // furthermore weird regarding more than two arguments in Expression.MULTARY() | ||
| 1017 | case Op.SUB_SCALAR_ARRAY then true; | ||
| 1018 | case Op.SUB_ARRAY_SCALAR then true; | ||
| 1019 | case Op.DIV_SCALAR_ARRAY then true; | ||
| 1020 | case Op.DIV_ARRAY_SCALAR then true; | ||
| 1021 | else false; | ||
| 1022 | end match; | ||
| 1023 | end isSoftCommutative; | ||
| 1024 | |||
| 1025 | function repetition | ||
| 1026 | input Operator operator; | ||
| 1027 | output tuple<Boolean, Boolean> b; | ||
| 1028 | algorithm | ||
| 1029 | b := match operator.op | ||
| 1030 | case Op.ADD_SCALAR_ARRAY then (true, false); | ||
| 1031 | case Op.ADD_ARRAY_SCALAR then (false, true); | ||
| 1032 | case Op.MUL_SCALAR_ARRAY then (true, false); | ||
| 1033 | case Op.MUL_ARRAY_SCALAR then (false, true); | ||
| 1034 | case Op.MUL_VECTOR_MATRIX then (true, true); | ||
| 1035 | case Op.MUL_MATRIX_VECTOR then (true, true); | ||
| 1036 | case Op.MATRIX_PRODUCT then (true, true); | ||
| 1037 | else (false, false); | ||
| 1038 | end match; | ||
| 1039 | end repetition; | ||
| 1040 | |||
| 1041 | function reduction | ||
| 1042 | input Operator operator; | ||
| 1043 | output Boolean b; | ||
| 1044 | algorithm | ||
| 1045 | b := match operator.op | ||
| 1046 | case Op.MUL_MATRIX_VECTOR then true; | ||
| 1047 | case Op.MUL_VECTOR_MATRIX then true; | ||
| 1048 | case Op.MATRIX_PRODUCT then true; | ||
| 1049 | case Op.SCALAR_PRODUCT then true; | ||
| 1050 | else false; | ||
| 1051 | end match; | ||
| 1052 | end reduction; | ||
| 1053 | |||
| 1054 | function isCombineable | ||
| 1055 | input Operator op1; | ||
| 1056 | input Operator op2; | ||
| 1057 | output Boolean b; | ||
| 1058 | protected | ||
| 1059 | MathClassification mcl1, mcl2; | ||
| 1060 | SizeClassification scl1, scl2; | ||
| 1061 | algorithm | ||
| 1062 | 3466 | (mcl1, scl1) := classify(op1); | |
| 1063 | 3466 | (mcl2, scl2) := classify(op2); | |
| 1064 |
4/4✓ Branch 1 taken 41 times.
✓ Branch 2 taken 3425 times.
✓ Branch 4 taken 38 times.
✓ Branch 5 taken 3 times.
|
3466 | b := isCombineableMath(mcl1, mcl2) and isCombineableSize(scl1, scl2); |
| 1065 | if b then | ||
| 1066 |
3/4✓ Branch 1 taken 38 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 14 times.
✓ Branch 5 taken 24 times.
|
38 | b := not (isScalarProduct(op1) or isScalarProduct(op2)); |
| 1067 | end if; | ||
| 1068 | end isCombineable; | ||
| 1069 | |||
| 1070 | function isCombineableMath | ||
| 1071 | input MathClassification mcl1; | ||
| 1072 | input MathClassification mcl2; | ||
| 1073 | output Boolean b; | ||
| 1074 | algorithm | ||
| 1075 |
6/6✓ Branch 0 taken 3449 times.
✓ Branch 1 taken 17 times.
✓ Branch 3 taken 1861 times.
✓ Branch 4 taken 1588 times.
✓ Branch 6 taken 24 times.
✓ Branch 7 taken 1837 times.
|
3466 | b := mcl1 == mcl2 or (isDashClassification(mcl1) and isDashClassification(mcl2)); |
| 1076 | end isCombineableMath; | ||
| 1077 | |||
| 1078 | function isCombineableSize | ||
| 1079 | input SizeClassification scl1; | ||
| 1080 | input SizeClassification scl2; | ||
| 1081 | output Boolean b; | ||
| 1082 | algorithm | ||
| 1083 | 41 | b := scl1 == scl2; | |
| 1084 | end isCombineableSize; | ||
| 1085 | |||
| 1086 | function toDebugString | ||
| 1087 | input Operator op; | ||
| 1088 | output String str; | ||
| 1089 | algorithm | ||
| 1090 | ✗ | str := "OPERATOR(" + Type.toString(op.ty) + ", " + opToString(op.op) + ")"; | |
| 1091 | end toDebugString; | ||
| 1092 | |||
| 1093 | function opToString | ||
| 1094 | input Op op; | ||
| 1095 | output String str; | ||
| 1096 | algorithm | ||
| 1097 | str := match op | ||
| 1098 | case Op.ADD then "ADD"; | ||
| 1099 | case Op.SUB then "SUB"; | ||
| 1100 | case Op.MUL then "MUL"; | ||
| 1101 | case Op.DIV then "DIV"; | ||
| 1102 | case Op.POW then "POW"; | ||
| 1103 | case Op.ADD_EW then "ADD_EW"; | ||
| 1104 | case Op.SUB_EW then "SUB_EW"; | ||
| 1105 | case Op.MUL_EW then "MUL_EW"; | ||
| 1106 | case Op.DIV_EW then "DIV_EW"; | ||
| 1107 | case Op.POW_EW then "POW_EW"; | ||
| 1108 | case Op.ADD_SCALAR_ARRAY then "ADD_SCALAR_ARRAY"; | ||
| 1109 | case Op.ADD_ARRAY_SCALAR then "ADD_ARRAY_SCALAR"; | ||
| 1110 | case Op.SUB_SCALAR_ARRAY then "SUB_SCALAR_ARRAY"; | ||
| 1111 | case Op.SUB_ARRAY_SCALAR then "SUB_ARRAY_SCALAR"; | ||
| 1112 | case Op.MUL_SCALAR_ARRAY then "MUL_SCALAR_ARRAY"; | ||
| 1113 | case Op.MUL_ARRAY_SCALAR then "MUL_ARRAY_SCALAR"; | ||
| 1114 | case Op.MUL_VECTOR_MATRIX then "MUL_VECTOR_MATRIX"; | ||
| 1115 | case Op.MUL_MATRIX_VECTOR then "MUL_MATRIX_VECTOR"; | ||
| 1116 | case Op.SCALAR_PRODUCT then "SCALAR_PRODUCT"; | ||
| 1117 | case Op.MATRIX_PRODUCT then "MATRIX_PRODUCT"; | ||
| 1118 | case Op.DIV_SCALAR_ARRAY then "DIV_SCALAR_ARRAY"; | ||
| 1119 | case Op.DIV_ARRAY_SCALAR then "DIV_ARRAY_SCALAR"; | ||
| 1120 | case Op.POW_SCALAR_ARRAY then "POW_SCALAR_ARRAY"; | ||
| 1121 | case Op.POW_ARRAY_SCALAR then "POW_ARRAY_SCALAR"; | ||
| 1122 | case Op.POW_MATRIX then "POW_MATRIX"; | ||
| 1123 | case Op.UMINUS then "UMINUS"; | ||
| 1124 | case Op.AND then "AND"; | ||
| 1125 | case Op.OR then "OR"; | ||
| 1126 | case Op.NOT then "NOT"; | ||
| 1127 | case Op.LESS then "LESS"; | ||
| 1128 | case Op.LESSEQ then "LESSEQ"; | ||
| 1129 | case Op.GREATER then "GREATER"; | ||
| 1130 | case Op.GREATEREQ then "GREATEREQ"; | ||
| 1131 | case Op.EQUAL then "EQUAL"; | ||
| 1132 | case Op.NEQUAL then "NEQUAL"; | ||
| 1133 | case Op.USERDEFINED then "USERDEFINED"; | ||
| 1134 | else algorithm | ||
| 1135 | ✗ | Error.addMessage(Error.INTERNAL_ERROR,{getInstanceName() + "failed. Unhanded enumeration."}); | |
| 1136 | ✗ | then fail(); | |
| 1137 | end match; | ||
| 1138 | end opToString; | ||
| 1139 | |||
| 1140 | annotation(__OpenModelica_Interface="nf_frontend"); | ||
| 1141 | end NFOperator; | ||
| 1142 |