Skip to content

Commit 5003b97

Browse files
author
Jens Frenkel
committed
- add information to store how often a state are differentiated
- bugfix BackendVariable.hasContinousVar git-svn-id: https://openmodelica.org/svn/OpenModelica/trunk@14672 f25d12d1-65f4-0310-ae8a-bbce733d8d8e
1 parent b011ca9 commit 5003b97

18 files changed

+236
-85
lines changed

Compiler/BackEnd/BackendDAE.mo

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,9 @@ end BackendDAEType;
8686
public
8787
uniontype VarKind "- Variabile kind"
8888
record VARIABLE end VARIABLE;
89-
record STATE end STATE; // we should also save information if it is a state with used derivative and the how often this states was differentiated
89+
record STATE
90+
Integer index "how often this states was differentiated";
91+
end STATE;
9092
record STATE_DER end STATE_DER;
9193
record DUMMY_DER end DUMMY_DER;
9294
record DUMMY_STATE end DUMMY_STATE;

Compiler/BackEnd/BackendDAECreate.mo

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -768,10 +768,10 @@ algorithm
768768
(outVarKind) := matchcontinue (inVarKind,inType,inComponentRef,inVarDirection,inConnectorType,daeAttr)
769769
// variable -> state if have stateSelect=StateSelect.always
770770
case (DAE.VARIABLE(),_,_,_,_,SOME(DAE.VAR_ATTR_REAL(stateSelectOption = SOME(DAE.ALWAYS()))))
771-
then (BackendDAE.STATE());
771+
then (BackendDAE.STATE(1));
772772
// variable -> state if have stateSelect=StateSelect.prefer
773773
case (DAE.VARIABLE(),_,_,_,_,SOME(DAE.VAR_ATTR_REAL(stateSelectOption = SOME(DAE.PREFER()))))
774-
then (BackendDAE.STATE());
774+
then (BackendDAE.STATE(1));
775775

776776
case (DAE.VARIABLE(),DAE.T_BOOL(varLst = _),_,_,_,_)
777777
equation
@@ -2485,7 +2485,7 @@ algorithm
24852485
Boolean b,b1,b2;
24862486
DAE.Exp e,ae;
24872487
// state variable
2488-
case (BackendDAE.VAR(varKind=BackendDAE.STATE()),_,1,_,
2488+
case (BackendDAE.VAR(varKind=BackendDAE.STATE(_)),_,1,_,
24892489
BackendDAE.VAR(varName=cr2),_,1,_,_,_,_,_,_,_)
24902490
equation
24912491
// check if replacable
@@ -2510,7 +2510,7 @@ algorithm
25102510
(vars,iKnVars,iExtVars,avars,repl);
25112511
// state variable
25122512
case (BackendDAE.VAR(varName=cr1),_,1,_,
2513-
BackendDAE.VAR(varKind=BackendDAE.STATE()),_,1,_,_,_,_,_,_,_)
2513+
BackendDAE.VAR(varKind=BackendDAE.STATE(_)),_,1,_,_,_,_,_,_,_)
25142514
equation
25152515
// check if replacable
25162516
false = BackendVariable.isStateVar(v1);
@@ -3207,7 +3207,7 @@ algorithm
32073207
equation
32083208
false = BackendVariable.isVarDiscrete(var) "do not change discrete vars to states, because they have no derivative" ;
32093209
false = BackendVariable.isStateVar(var);
3210-
var1 = BackendVariable.setVarKind(var,BackendDAE.STATE());
3210+
var1 = BackendVariable.setVarKind(var,BackendDAE.STATE(1));
32113211
vars = BackendVariable.addVar(var1, inVars);
32123212
then (vars,iExp);
32133213
case(_,_,_)
@@ -3240,7 +3240,7 @@ algorithm
32403240
equation
32413241
false = BackendVariable.isVarDiscrete(var) "do not change discrete vars to states, because they have no derivative" ;
32423242
false = BackendVariable.isStateVar(var);
3243-
var = BackendVariable.setVarKind(var,BackendDAE.STATE());
3243+
var = BackendVariable.setVarKind(var,BackendDAE.STATE(1));
32443244
vars = BackendVariable.addVar(var, inVars);
32453245
vars = updateStatesVars(vars,newStates,true);
32463246
then vars;

Compiler/BackEnd/BackendDAEOptimize.mo

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6168,7 +6168,7 @@ algorithm
61686168
(r2,res) = generateJacobianVars2(var, restVar, inMatrixName);
61696169
then (r2,res);
61706170

6171-
case(var as BackendDAE.VAR(varName=cref,varKind=BackendDAE.STATE()), currVar::restVar, _) equation
6171+
case(var as BackendDAE.VAR(varName=cref,varKind=BackendDAE.STATE(_)), currVar::restVar, _) equation
61726172
cref = ComponentReference.crefPrefixDer(cref);
61736173
derivedCref = differentiateVarWithRespectToX(cref, currVar, inMatrixName);
61746174
r1 = BackendDAE.VAR(derivedCref, BackendDAE.STATE_DER(), DAE.BIDIR(), DAE.NON_PARALLEL(), DAE.T_REAL_DEFAULT, NONE(), NONE(), {}, DAE.emptyElementSource, NONE(), NONE(), DAE.NON_CONNECTOR());
@@ -6216,7 +6216,7 @@ algorithm
62166216
then
62176217
creatallDiffedVars(restVar,cref,inAllVars,inIndex, inMatrixName,iVars);
62186218

6219-
case(BackendDAE.VAR(varName=currVar,varKind=BackendDAE.STATE())::restVar,cref,_,_, _, _) equation
6219+
case(BackendDAE.VAR(varName=currVar,varKind=BackendDAE.STATE(_))::restVar,cref,_,_, _, _) equation
62206220
({v1}, _) = BackendVariable.getVar(currVar, inAllVars);
62216221
currVar = ComponentReference.crefPrefixDer(currVar);
62226222
derivedCref = differentiateVarWithRespectToX(currVar, cref, inMatrixName);
@@ -6231,7 +6231,7 @@ algorithm
62316231
then
62326232
creatallDiffedVars(restVar, cref, inAllVars, inIndex+1, inMatrixName,r1::iVars);
62336233

6234-
case(BackendDAE.VAR(varName=currVar,varKind=BackendDAE.STATE())::restVar,cref,_,_, _, _) equation
6234+
case(BackendDAE.VAR(varName=currVar,varKind=BackendDAE.STATE(_))::restVar,cref,_,_, _, _) equation
62356235
currVar = ComponentReference.crefPrefixDer(currVar);
62366236
derivedCref = differentiateVarWithRespectToX(currVar, cref, inMatrixName);
62376237
r1 = BackendDAE.VAR(derivedCref, BackendDAE.VARIABLE(), DAE.BIDIR(), DAE.NON_PARALLEL(), DAE.T_REAL_DEFAULT, NONE(), NONE(), {}, DAE.emptyElementSource, NONE(), NONE(), DAE.NON_CONNECTOR());

Compiler/BackEnd/BackendDAETransform.mo

Lines changed: 8 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1178,7 +1178,7 @@ algorithm
11781178
DAE.ElementSource source;
11791179

11801180
case (BackendDAE.VAR(varName = cr,
1181-
varKind = BackendDAE.STATE(),
1181+
varKind = BackendDAE.STATE(_),
11821182
varDirection = dir,
11831183
varParallelism = prl,
11841184
varType = tp,
@@ -2937,31 +2937,25 @@ protected function findState
29372937
"function: findState
29382938
author: PA
29392939
Returns the first state from a list of component references."
2940-
input BackendDAE.Variables inVariables;
2940+
input BackendDAE.Variables vars;
29412941
input list<DAE.ComponentRef> inExpComponentRefLst;
29422942
output DAE.ComponentRef outComponentRef;
29432943
algorithm
29442944
outComponentRef:=
2945-
matchcontinue (inVariables,inExpComponentRefLst)
2945+
matchcontinue (vars,inExpComponentRefLst)
29462946
local
29472947
BackendDAE.Var v;
2948-
BackendDAE.Variables vars;
29492948
DAE.ComponentRef cr;
29502949
list<DAE.ComponentRef> crs;
2951-
2952-
case (vars,(cr :: crs))
2950+
case (_,(cr :: crs))
29532951
equation
29542952
((v :: _),_) = BackendVariable.getVar(cr, vars);
2955-
BackendDAE.STATE() = BackendVariable.varKind(v);
2953+
BackendDAE.STATE(_) = BackendVariable.varKind(v);
29562954
then
29572955
cr;
2958-
2959-
case (vars,(cr :: crs))
2960-
equation
2961-
cr = findState(vars, crs);
2956+
case (_,(cr :: crs))
29622957
then
2963-
cr;
2964-
2958+
findState(vars, crs);
29652959
end matchcontinue;
29662960
end findState;
29672961

@@ -3523,7 +3517,7 @@ algorithm
35233517

35243518
case ((DAE.CALL(path = Absyn.IDENT(name = "der"),expLst = {DAE.CALL(path = Absyn.IDENT(name = "der"),expLst = {DAE.CREF(componentRef = cr)})}),(vars,i)))
35253519
equation
3526-
((BackendDAE.VAR(cr,BackendDAE.STATE(),a,prl,b,c,d,lstSubs,source,dae_var_attr,comment,ct) :: _),_) = BackendVariable.getVar(cr, vars) "der(der(s)) s is state => der_der_s" ;
3520+
((BackendDAE.VAR(cr,BackendDAE.STATE(_),a,prl,b,c,d,lstSubs,source,dae_var_attr,comment,ct) :: _),_) = BackendVariable.getVar(cr, vars) "der(der(s)) s is state => der_der_s" ;
35273521
dummyder = ComponentReference.crefPrefixDer(cr);
35283522
dummyder = ComponentReference.crefPrefixDer(dummyder);
35293523
vars_1 = BackendVariable.addVar(BackendDAE.VAR(dummyder, BackendDAE.DUMMY_DER(), a, prl, b, NONE(), NONE(), lstSubs, source, NONE(), comment, ct), vars);

Compiler/BackEnd/BackendDAEUtil.mo

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -907,7 +907,7 @@ algorithm
907907
local
908908
BackendDAE.Var v;
909909
Boolean b;
910-
case ((v as BackendDAE.VAR(varKind=BackendDAE.STATE()),_))
910+
case ((v as BackendDAE.VAR(varKind=BackendDAE.STATE(_)),_))
911911
then ((v,false,false));
912912
case ((v,b)) then ((v,b,b));
913913
end match;
@@ -1131,7 +1131,7 @@ algorithm
11311131
then
11321132
((var,(nx,ny+1,ny_string, ny_int,ny_bool)));
11331133

1134-
case ((var as BackendDAE.VAR(varKind = BackendDAE.STATE()),(nx,ny,ny_string, ny_int, ny_bool)))
1134+
case ((var as BackendDAE.VAR(varKind = BackendDAE.STATE(_)),(nx,ny,ny_string, ny_int, ny_bool)))
11351135
then
11361136
((var,(nx+1,ny,ny_string, ny_int,ny_bool)));
11371137

@@ -1641,7 +1641,7 @@ algorithm
16411641
((e,false,(vars,e::expl)));
16421642
case (((e as DAE.CALL(path = Absyn.IDENT(name = "der"),expLst = {DAE.CREF(componentRef = cr)})),(vars,expl)))
16431643
equation
1644-
((BackendDAE.VAR(varKind = BackendDAE.STATE()) :: _),_) = BackendVariable.getVar(cr, vars);
1644+
((BackendDAE.VAR(varKind = BackendDAE.STATE(_)) :: _),_) = BackendVariable.getVar(cr, vars);
16451645
then
16461646
((e,false,(vars,e::expl)));
16471647
// is this case right?
@@ -3798,7 +3798,7 @@ algorithm
37983798
/*If variable x is a state, der(x) is a variable in incidence matrix,
37993799
x is inserted as negative value, since it is needed by debugging and
38003800
index reduction using dummy derivatives */
3801-
case (BackendDAE.VAR(varKind = BackendDAE.STATE()) :: rest,i::irest,vars,b)
3801+
case (BackendDAE.VAR(varKind = BackendDAE.STATE(_)) :: rest,i::irest,vars,b)
38023802
equation
38033803
i1 = Util.if_(b,-i,i);
38043804
failure(_ = List.getMemberOnTrue(i1, vars, intEq));
@@ -3909,7 +3909,7 @@ algorithm
39093909
failure(_ = List.getMemberOnTrue(i, vars, intEq));
39103910
res = incidenceRowExp1(rest,irest,i::vars,b);
39113911
then res;
3912-
case (BackendDAE.VAR(varKind = BackendDAE.STATE()) :: rest,i::irest,vars,b)
3912+
case (BackendDAE.VAR(varKind = BackendDAE.STATE(_)) :: rest,i::irest,vars,b)
39133913
equation
39143914
failure( true = b);
39153915
failure(_ = List.getMemberOnTrue(i, vars, intEq));
@@ -5341,7 +5341,7 @@ algorithm
53415341
// if not negatet rowmark then
53425342
false = intEq(rowmark[r],-mark);
53435343
// solved?
5344-
BackendDAE.VAR(varName=cr1,varKind=BackendDAE.STATE()) = BackendVariable.getVarAt(vars, r);
5344+
BackendDAE.VAR(varName=cr1,varKind=BackendDAE.STATE(_)) = BackendVariable.getVarAt(vars, r);
53455345
true = ComponentReference.crefEqualNoStringCompare(cr, cr1);
53465346
false = Expression.expHasDerCref(e2,cr);
53475347
then
@@ -5351,7 +5351,7 @@ algorithm
53515351
// if not negatet rowmark then
53525352
false = intEq(rowmark[r],-mark);
53535353
// solved?
5354-
BackendDAE.VAR(varName=cr1,varKind=BackendDAE.STATE()) = BackendVariable.getVarAt(vars, r);
5354+
BackendDAE.VAR(varName=cr1,varKind=BackendDAE.STATE(_)) = BackendVariable.getVarAt(vars, r);
53555355
true = ComponentReference.crefEqualNoStringCompare(cr, cr1);
53565356
false = Expression.expHasDerCref(e1,cr);
53575357
then
@@ -5443,7 +5443,7 @@ algorithm
54435443
// if not negatet rowmark then linear or nonlinear
54445444
false = intEq(rowmark[r],-mark);
54455445
// de/dvar
5446-
BackendDAE.VAR(varName=cr,varKind=BackendDAE.STATE()) = BackendVariable.getVarAt(vars, r);
5446+
BackendDAE.VAR(varName=cr,varKind=BackendDAE.STATE(_)) = BackendVariable.getVarAt(vars, r);
54475447
cr1 = ComponentReference.crefPrefixDer(cr);
54485448
de = Expression.crefExp(cr);
54495449
((de,_)) = Expression.replaceExp(Expression.expSub(e1,e2), DAE.CALL(Absyn.IDENT("der"),{de},DAE.callAttrBuiltinReal), Expression.crefExp(cr1));
@@ -5868,13 +5868,13 @@ algorithm
58685868
/*If variable x is a state, der(x) is a variable in incidence matrix,
58695869
x is inserted as negative value, since it is needed by debugging and
58705870
index reduction using dummy derivatives */
5871-
case (BackendDAE.VAR(varKind = BackendDAE.STATE()) :: rest,i::irest,_,false,_,_,_)
5871+
case (BackendDAE.VAR(varKind = BackendDAE.STATE(_)) :: rest,i::irest,_,false,_,_,_)
58725872
equation
58735873
false = intEq(intAbs(rowmark[i]),mark);
58745874
_ = arrayUpdate(rowmark,i,Util.if_(unsolvable,-mark,mark));
58755875
res = adjacencyRowExpEnhanced1(rest,irest,i::vars,notinder,mark,rowmark,unsolvable);
58765876
then res;
5877-
case (BackendDAE.VAR(varKind = BackendDAE.STATE()) :: rest,i::irest,_,true,_,_,_)
5877+
case (BackendDAE.VAR(varKind = BackendDAE.STATE(_)) :: rest,i::irest,_,true,_,_,_)
58785878
equation
58795879
i1 = -i;
58805880
failure(_ = List.getMemberOnTrue(i1, vars, intEq));

Compiler/BackEnd/BackendDump.mo

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2358,9 +2358,11 @@ public function kindString
23582358
algorithm
23592359
kindStr:=
23602360
match (inVarKind)
2361-
local Absyn.Path path;
2361+
local
2362+
Absyn.Path path;
2363+
Integer i;
23622364
case BackendDAE.VARIABLE() then "VARIABLE";
2363-
case BackendDAE.STATE() then "STATE";
2365+
case BackendDAE.STATE(i) then "STATE(" +& intString(i) +& ")";
23642366
case BackendDAE.STATE_DER() then "STATE_DER";
23652367
case BackendDAE.DUMMY_DER() then "DUMMY_DER";
23662368
case BackendDAE.DUMMY_STATE() then "DUMMY_STATE";

Compiler/BackEnd/BackendVariable.mo

Lines changed: 10 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -175,7 +175,7 @@ algorithm
175175
fixed is by default false. For all variables declared as constant it is an error to have "fixed = false".
176176
case (v) // states are by default fixed.
177177
equation
178-
BackendDAE.STATE() = varKind(v);
178+
BackendDAE.STATE(_) = varKind(v);
179179
fixes = Flags.isSet(Flags.INIT_DLOW_DUMP);
180180
then
181181
not fixed;
@@ -889,7 +889,7 @@ public function isStateVar
889889
algorithm
890890
outBoolean:=
891891
matchcontinue (inVar)
892-
case (BackendDAE.VAR(varKind = BackendDAE.STATE())) then true;
892+
case (BackendDAE.VAR(varKind = BackendDAE.STATE(_))) then true;
893893
case (_) then false;
894894
end matchcontinue;
895895
end isStateVar;
@@ -906,7 +906,7 @@ algorithm
906906
BackendDAE.Variables vars;
907907
case(cr,vars)
908908
equation
909-
((BackendDAE.VAR(varKind = BackendDAE.STATE()) :: _),_) = getVar(cr, vars);
909+
((BackendDAE.VAR(varKind = BackendDAE.STATE(_)) :: _),_) = getVar(cr, vars);
910910
then
911911
true;
912912
case(_,_) then false;
@@ -1077,7 +1077,7 @@ public function isStateorStateDerVar
10771077
algorithm
10781078
outBoolean:=
10791079
match (inVar)
1080-
case (BackendDAE.VAR(varKind = BackendDAE.STATE())) then true;
1080+
case (BackendDAE.VAR(varKind = BackendDAE.STATE(_))) then true;
10811081
case (BackendDAE.VAR(varKind = BackendDAE.STATE_DER())) then true;
10821082
else
10831083
then false;
@@ -1135,19 +1135,13 @@ algorithm
11351135
Boolean res;
11361136
BackendDAE.Var v;
11371137
list<BackendDAE.Var> vs;
1138-
case ((BackendDAE.VAR(varKind=BackendDAE.VARIABLE(),varType = DAE.T_INTEGER(source = _)) :: _)) then false;
1139-
case ((BackendDAE.VAR(varKind=BackendDAE.VARIABLE(),varType = DAE.T_BOOL(source = _)) :: _)) then false;
1140-
case ((BackendDAE.VAR(varKind=BackendDAE.VARIABLE(),varType = DAE.T_ENUMERATION(source = _)) :: _)) then false;
1141-
case ((BackendDAE.VAR(varKind=BackendDAE.VARIABLE()) :: _)) then true;
1142-
case ((BackendDAE.VAR(varKind=BackendDAE.STATE()) :: _)) then true;
1138+
case ((BackendDAE.VAR(varKind=BackendDAE.VARIABLE(),varType = DAE.T_REAL(source = _)) :: _)) then true;
1139+
case ((BackendDAE.VAR(varKind=BackendDAE.VARIABLE(),varType = DAE.T_ARRAY(ty=DAE.T_REAL(source = _))) :: _)) then true;
1140+
case ((BackendDAE.VAR(varKind=BackendDAE.STATE(_)) :: _)) then true;
11431141
case ((BackendDAE.VAR(varKind=BackendDAE.STATE_DER()) :: _)) then true;
11441142
case ((BackendDAE.VAR(varKind=BackendDAE.DUMMY_DER()) :: _)) then true;
11451143
case ((BackendDAE.VAR(varKind=BackendDAE.DUMMY_STATE()) :: _)) then true;
1146-
case ((v :: vs))
1147-
equation
1148-
res = hasContinousVar(vs);
1149-
then
1150-
res;
1144+
case ((v :: vs)) then hasContinousVar(vs);
11511145
case ({}) then false;
11521146
end match;
11531147
end hasContinousVar;
@@ -1610,7 +1604,7 @@ public function createDummyVar "function createDummyVar
16101604
output DAE.ComponentRef outCr;
16111605
algorithm
16121606
outCr := ComponentReference.makeCrefIdent("$dummy",DAE.T_REAL_DEFAULT,{});
1613-
outVar := BackendDAE.VAR(outCr, BackendDAE.STATE(),DAE.BIDIR(),DAE.NON_PARALLEL(),DAE.T_REAL_DEFAULT,NONE(),NONE(),{},
1607+
outVar := BackendDAE.VAR(outCr, BackendDAE.STATE(1),DAE.BIDIR(),DAE.NON_PARALLEL(),DAE.T_REAL_DEFAULT,NONE(),NONE(),{},
16141608
DAE.emptyElementSource,
16151609
SOME(DAE.VAR_ATTR_REAL(NONE(),NONE(),NONE(),(NONE(),NONE()),NONE(),SOME(DAE.BCONST(true)),NONE(),NONE(),NONE(),NONE(),NONE(),NONE(),NONE(),NONE())),
16161610
NONE(),DAE.NON_CONNECTOR());
@@ -2547,7 +2541,7 @@ algorithm
25472541
_:=
25482542
match (inVarKind)
25492543
case (BackendDAE.VARIABLE()) then ();
2550-
case (BackendDAE.STATE()) then ();
2544+
case (BackendDAE.STATE(_)) then ();
25512545
case (BackendDAE.DUMMY_STATE()) then ();
25522546
case (BackendDAE.DUMMY_DER()) then ();
25532547
case (BackendDAE.DISCRETE()) then ();

Compiler/BackEnd/DAEQuery.mo

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -658,7 +658,7 @@ algorithm
658658

659659
case (DAE.CREF(componentRef = cr),vars)
660660
equation
661-
((BackendDAE.VAR(varKind = BackendDAE.STATE()) :: _),p) =
661+
((BackendDAE.VAR(varKind = BackendDAE.STATE(_)) :: _),p) =
662662
BackendVariable.getVar(cr, vars) "If variable x is a state, der(x) is a variable in incidence matrix,
663663
x is inserted as negative value, since it is needed by debugging and index
664664
reduction using dummy derivatives" ;
@@ -818,7 +818,7 @@ algorithm
818818

819819
case (DAE.CALL(path = Absyn.IDENT(name = "der"),expLst = {DAE.CREF(componentRef = cr)}),vars)
820820
equation
821-
((BackendDAE.VAR(varKind = BackendDAE.STATE()) :: _),p) = BackendVariable.getVar(cr, vars);
821+
((BackendDAE.VAR(varKind = BackendDAE.STATE(_)) :: _),p) = BackendVariable.getVar(cr, vars);
822822
pStr = List.map(p, intString);
823823
then
824824
pStr;

Compiler/BackEnd/Derive.mo

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -370,7 +370,7 @@ algorithm
370370
// Continuous-time variables (and for shared eq-systems, also unknown variables: keep them as-is)
371371
case ((e as DAE.CREF(componentRef = cr,ty = tp)),(timevars,_))
372372
equation
373-
// ({BackendDAE.VAR(varKind = BackendDAE.STATE())},_) = BackendVariable.getVar(cr, timevars);
373+
// ({BackendDAE.VAR(varKind = BackendDAE.STATE(_))},_) = BackendVariable.getVar(cr, timevars);
374374
then DAE.CALL(Absyn.IDENT("der"),{e},DAE.CALL_ATTR(tp,false,true,DAE.NO_INLINE(),DAE.NO_TAIL()));
375375

376376
// der(sign(x)) -> 0

0 commit comments

Comments
 (0)