diff --git a/Compiler/BackEnd/Derive.mo b/Compiler/BackEnd/Derive.mo index 7a3475b6ba4..992520e6cad 100644 --- a/Compiler/BackEnd/Derive.mo +++ b/Compiler/BackEnd/Derive.mo @@ -373,21 +373,28 @@ algorithm // ({BackendDAE.VAR(varKind = BackendDAE.STATE())},_) = BackendVariable.getVar(cr, timevars); then DAE.CALL(Absyn.IDENT("der"),{e},DAE.callAttrBuiltinReal); + // der(sign(x)) -> 0 + case (DAE.CALL(path = Absyn.IDENT("sign"),expLst = {e}),_) + then + DAE.RCONST(0.0); + + // der(sin(x)) = der(x)cos(x) case (DAE.CALL(path = Absyn.IDENT("sin"),expLst = {e}),_) equation - e_1 = differentiateExpTime(e, inVariables) "der(sin(x)) = der(x)cos(x)" ; + e_1 = differentiateExpTime(e, inVariables); then DAE.BINARY(e_1,DAE.MUL(DAE.T_REAL_DEFAULT), DAE.CALL(Absyn.IDENT("cos"),{e},DAE.callAttrBuiltinReal)); + // der(cos(x)) = -der(x)sin(x) case (DAE.CALL(path = Absyn.IDENT("cos"),expLst = {e}),_) equation - e_1 = differentiateExpTime(e, inVariables) "der(cos(x)) = -der(x)sin(x)" ; + e_1 = differentiateExpTime(e, inVariables); then DAE.UNARY(DAE.UMINUS(DAE.T_REAL_DEFAULT),DAE.BINARY(e_1,DAE.MUL(DAE.T_REAL_DEFAULT), DAE.CALL(Absyn.IDENT("sin"),{e},DAE.callAttrBuiltinReal))); - // der(arccos(x)) = -der(x)/sqrt(1-x^2) + // der(arccos(x)) = -der(x)/sqrt(1-x^2) case (DAE.CALL(path = Absyn.IDENT("acos"),expLst = {e}),_) equation e_1 = differentiateExpTime(e, inVariables); @@ -396,59 +403,63 @@ algorithm DAE.CALL(Absyn.IDENT("sqrt"),{DAE.BINARY(DAE.RCONST(1.0),DAE.SUB(DAE.T_REAL_DEFAULT),DAE.BINARY(e,DAE.MUL(DAE.T_REAL_DEFAULT),e))}, DAE.callAttrBuiltinReal))); - // der(arcsin(x)) = der(x)/sqrt(1-x^2) - case (DAE.CALL(path = Absyn.IDENT("asin"),expLst = {e}),_) - equation - e_1 = differentiateExpTime(e, inVariables) ; - then - DAE.BINARY(e_1,DAE.DIV(DAE.T_REAL_DEFAULT), - DAE.CALL(Absyn.IDENT("sqrt"),{DAE.BINARY(DAE.RCONST(1.0),DAE.SUB(DAE.T_REAL_DEFAULT),DAE.BINARY(e,DAE.MUL(DAE.T_REAL_DEFAULT),e))}, - DAE.callAttrBuiltinReal)); - - // der(arctan(x)) = der(x)/1+x^2 - case (DAE.CALL(path = Absyn.IDENT("atan"),expLst = {e}),_) - equation - e_1 = differentiateExpTime(e, inVariables) ; - then - DAE.BINARY(e_1,DAE.DIV(DAE.T_REAL_DEFAULT),DAE.BINARY(DAE.RCONST(1.0),DAE.ADD(DAE.T_REAL_DEFAULT),DAE.BINARY(e,DAE.MUL(DAE.T_REAL_DEFAULT),e))); - - // der(arctan2(y,0)) = der(sign(y)*pi/2) = 0 - case (DAE.CALL(path = Absyn.IDENT("atan2"),expLst = {e,e1}),_) - equation - true = Expression.isZero(e1); - (exp,_) = Expression.makeZeroExpression({}); - then - exp; - - // der(arctan2(y,x)) = der(y/x)/1+(y/x)^2 - case (DAE.CALL(path = Absyn.IDENT("atan2"),expLst = {e,e1}),_) - equation - false = Expression.isZero(e1); - exp = Expression.makeDiv(e,e1); - e_1 = differentiateExpTime(exp, inVariables); - then - DAE.BINARY(e_1,DAE.DIV(DAE.T_REAL_DEFAULT),DAE.BINARY(DAE.RCONST(1.0),DAE.ADD(DAE.T_REAL_DEFAULT),DAE.BINARY(e,DAE.MUL(DAE.T_REAL_DEFAULT),e))); + // der(arcsin(x)) = der(x)/sqrt(1-x^2) + case (DAE.CALL(path = Absyn.IDENT("asin"),expLst = {e}),_) + equation + e_1 = differentiateExpTime(e, inVariables) ; + then + DAE.BINARY(e_1,DAE.DIV(DAE.T_REAL_DEFAULT), + DAE.CALL(Absyn.IDENT("sqrt"),{DAE.BINARY(DAE.RCONST(1.0),DAE.SUB(DAE.T_REAL_DEFAULT),DAE.BINARY(e,DAE.MUL(DAE.T_REAL_DEFAULT),e))}, + DAE.callAttrBuiltinReal)); + + // der(arctan(x)) = der(x)/1+x^2 + case (DAE.CALL(path = Absyn.IDENT("atan"),expLst = {e}),_) + equation + e_1 = differentiateExpTime(e, inVariables) ; + then + DAE.BINARY(e_1,DAE.DIV(DAE.T_REAL_DEFAULT),DAE.BINARY(DAE.RCONST(1.0),DAE.ADD(DAE.T_REAL_DEFAULT),DAE.BINARY(e,DAE.MUL(DAE.T_REAL_DEFAULT),e))); + // der(arctan2(y,0)) = der(sign(y)*pi/2) = 0 + case (DAE.CALL(path = Absyn.IDENT("atan2"),expLst = {e,e1}),_) + equation + true = Expression.isZero(e1); + (exp,_) = Expression.makeZeroExpression({}); + then + exp; + + // der(arctan2(y,x)) = der(y/x)/1+(y/x)^2 + case (DAE.CALL(path = Absyn.IDENT("atan2"),expLst = {e,e1}),_) + equation + false = Expression.isZero(e1); + exp = Expression.makeDiv(e,e1); + e_1 = differentiateExpTime(exp, inVariables); + then + DAE.BINARY(e_1,DAE.DIV(DAE.T_REAL_DEFAULT),DAE.BINARY(DAE.RCONST(1.0),DAE.ADD(DAE.T_REAL_DEFAULT),DAE.BINARY(e,DAE.MUL(DAE.T_REAL_DEFAULT),e))); + + // der(exp(x)) = der(x)exp(x) case (DAE.CALL(path = fname as Absyn.IDENT("exp"),expLst = {e}),_) equation - e_1 = differentiateExpTime(e, inVariables) "der(exp(x)) = der(x)exp(x)" ; + e_1 = differentiateExpTime(e, inVariables); then DAE.BINARY(e_1,DAE.MUL(DAE.T_REAL_DEFAULT), DAE.CALL(fname,{e},DAE.callAttrBuiltinReal)); + // der(log(x)) = der(x)/x case (DAE.CALL(path = Absyn.IDENT("log"),expLst = {e}),_) equation - e_1 = differentiateExpTime(e, inVariables) "der(log(x)) = der(x)/x"; + e_1 = differentiateExpTime(e, inVariables); then DAE.BINARY(e_1,DAE.DIV(DAE.T_REAL_DEFAULT),e); + // der(log10(x)) = der(x)/(ln(10)*x) case (DAE.CALL(path = Absyn.IDENT("log10"),expLst = {e}),_) equation - e_1 = differentiateExpTime(e, inVariables) "der(log10(x)) = der(x)/(ln(10)*x)"; + e_1 = differentiateExpTime(e, inVariables); r = realLn(10.0); then DAE.BINARY(e_1,DAE.DIV(DAE.T_REAL_DEFAULT),DAE.BINARY(DAE.RCONST(r),DAE.MUL(DAE.T_REAL_DEFAULT),e)); + case (DAE.CALL(path = fname as Absyn.IDENT("max"),expLst = {e1,e2},attr=DAE.CALL_ATTR(ty=tp)),_) equation e1_1 = differentiateExpTime(e1, inVariables); diff --git a/Compiler/FrontEnd/Ceval.mo b/Compiler/FrontEnd/Ceval.mo index 64185266df5..6ce99b7f94e 100644 --- a/Compiler/FrontEnd/Ceval.mo +++ b/Compiler/FrontEnd/Ceval.mo @@ -972,7 +972,7 @@ algorithm equation id = Absyn.pathString(path); handler = cevalBuiltinHandler(id); - (cache,v,st) = handler(cache,env, args, impl, st, msg); + (cache,v,st) = handler(cache, env, args, impl, st, msg); then (cache,v,st); case (cache,env,(e as DAE.CALL(path = funcpath,expLst = expl,attr = DAE.CALL_ATTR(builtin = true))),impl,(st as NONE()),msg) @@ -1743,12 +1743,54 @@ algorithm Absyn.Ident currentPrefixIdent; list expl; list vals; + Env.CSetsType clst; case (DAE.CREF(componentRef = cr), env) equation - (env as (Env.FRAME(connectionSet = (crs,prefix))::_)) = Env.stripForLoopScope(env); + env = Env.stripForLoopScope(env); + Env.FRAME(connectionSet = clst)::_ = env; + res = cevalCardinality2(cr, clst, env, 0); + then + Values.INTEGER(res); + + case (DAE.ARRAY(array = expl), _) + equation + vals = List.map1(expl, cevalCardinality, inEnv); + dim = listLength(vals); + then + Values.ARRAY(vals, {dim}); + + end match; +end cevalCardinality; + +protected function cevalCardinality2 + input DAE.ComponentRef inCref; + input Env.CSetsType inCSets; + input Env.Env inEnv; + input Integer inStartValue; + output Integer outValue; +algorithm + outValue := match(inCref, inCSets, inEnv, inStartValue) + local + Env.Env env; + list cr_lst,cr_lst2,cr_totlst,crs; + Integer res, dim; + DAE.ComponentRef cr; + DAE.ComponentRef prefix,currentPrefix; + Absyn.Ident currentPrefixIdent; + list expl; + list vals; + Env.CSetsType rest; + + case (cr, {}, env, _) then inStartValue; + + case (cr, (crs,prefix)::rest, env, _) + equation + // strip the subs from the cref! + cr = ComponentReference.crefStripSubs(cr); + cr_lst = List.select1(crs, ComponentReference.crefContainedIn, cr); - currentPrefixIdent= ComponentReference.crefLastIdent(prefix); + currentPrefixIdent = ComponentReference.crefLastIdent(prefix); currentPrefix = ComponentReference.makeCrefIdent(currentPrefixIdent,DAE.T_UNKNOWN_DEFAULT,{}); // Select connect references that has cr as suffix and correct Prefix. cr_lst = List.select1r(cr_lst, ComponentReference.crefPrefixOf, currentPrefix); @@ -1759,7 +1801,6 @@ algorithm cr_totlst = List.unionOnTrue(listAppend(cr_lst,cr_lst2),{},ComponentReference.crefEqual); res = listLength(cr_totlst); - /*print("inFrame :");print(Env.printEnvPathStr(env));print("\n"); print("cardinality(");print(ComponentReference.printComponentRefStr(cr));print(")=");print(intString(res)); print("\nicrefs =");print(stringDelimitList(List.map(crs,ComponentReference.printComponentRefStr),",")); @@ -1767,18 +1808,12 @@ algorithm print("\n"); print("prefix =");print(ComponentReference.printComponentRefStr(prefix));print("\n");*/ // print("env:");print(Env.printEnvStr(env)); + res = cevalCardinality2(cr, rest, inEnv, res + inStartValue); then - Values.INTEGER(res); - - case (DAE.ARRAY(array = expl), _) - equation - vals = List.map1(expl, cevalCardinality, inEnv); - dim = listLength(vals); - then - Values.ARRAY(vals, {dim}); + res; end match; -end cevalCardinality; +end cevalCardinality2; protected function cevalBuiltinCat "function: cevalBuiltinCat author: PA diff --git a/Compiler/FrontEnd/Env.mo b/Compiler/FrontEnd/Env.mo index 83ef5169ff0..5ef2dae85c9 100644 --- a/Compiler/FrontEnd/Env.mo +++ b/Compiler/FrontEnd/Env.mo @@ -102,6 +102,7 @@ protected import Util; protected import Types; protected import SCodeDump; protected import Mod; +protected import Lookup; public type Ident = String " An identifier is just a string " ; public type Env = list "an environment is a list of frames"; @@ -133,10 +134,11 @@ public uniontype CacheTree end CACHETREE; end CacheTree; -type CSetsType = tuple,DAE.ComponentRef>; +type CSetsType = list,DAE.ComponentRef>>; public uniontype ScopeType record FUNCTION_SCOPE end FUNCTION_SCOPE; + record CLASS_SCOPE end CLASS_SCOPE; record PARALLEL_SCOPE end PARALLEL_SCOPE; @@ -247,7 +249,7 @@ algorithm ht := avlTreeNew(); httypes := avlTreeNew(); cref_ := ComponentReference.makeCrefIdent("",DAE.T_UNKNOWN_DEFAULT,{}); - outFrame := FRAME(inName,inType,ht,httypes,{},({},cref_),encapsulatedPrefix,{}); + outFrame := FRAME(inName,inType,ht,httypes,{},{({},cref_)},encapsulatedPrefix,{}); end newFrame; public function isTyped " @@ -380,7 +382,7 @@ algorithm AvlTree clsAndVars, types ; list imports; list fs; - tuple,DAE.ComponentRef> crefs; + CSetsType crefs; SCode.Encapsulated enc; list defineUnits; @@ -463,7 +465,7 @@ algorithm Option id; Option st; list imps; - tuple,DAE.ComponentRef> crs; + CSetsType crs; SCode.Encapsulated encflag; SCode.Element c; Ident n; @@ -501,7 +503,7 @@ algorithm Option st; list imps; Env fs, env, frames, classEnv, oldCE; - tuple,DAE.ComponentRef> crs; + CSetsType crs; SCode.Element e, oldE; Ident n; list defineUnits; @@ -576,7 +578,7 @@ algorithm Option st; list imps; Env fs; - tuple,DAE.ComponentRef> crs; + CSetsType crs; SCode.Encapsulated encflag; list defineUnits; @@ -606,7 +608,7 @@ algorithm Option st; list imps; Env fs,env,remember; - tuple,DAE.ComponentRef> crs; + CSetsType crs; SCode.Encapsulated encflag; InstStatus i; DAE.Var v; @@ -653,7 +655,7 @@ algorithm Option st; list imps; Env fs,env,frames; - tuple,DAE.ComponentRef> crs; + CSetsType crs; DAE.Var v; Ident n,id; list defineUnits; @@ -707,7 +709,7 @@ algorithm Option st; list imps; Env fs; - tuple,DAE.ComponentRef> crs; + CSetsType crs; SCode.Encapsulated encflag; Ident n; DAE.Type t; @@ -741,7 +743,7 @@ algorithm AvlTree httypes; AvlTree ht; list imps; - tuple,DAE.ComponentRef> crs; + CSetsType crs; SCode.Encapsulated encflag; Absyn.Import imp; Env fs,env; @@ -769,7 +771,7 @@ algorithm AvlTree httypes; AvlTree ht; list imps; - tuple,DAE.ComponentRef> crs; + CSetsType crs; SCode.Encapsulated encflag; Env fs; list defineUnits; @@ -849,7 +851,7 @@ algorithm AvlTree cls; list imps; Env bc,fs; - tuple,DAE.ComponentRef> crefs; + CSetsType crefs; Boolean enc; Frame f; list defineUnits; @@ -1011,6 +1013,63 @@ algorithm end matchcontinue; end joinEnvPath; +public function getEnvNameStr + "Returns the FQ name of the environment, see also getEnvPath" + input Env inEnv; + output String outString; +algorithm + outString := matchcontinue(inEnv) + case (_) + then + Absyn.pathString(getEnvName(inEnv)); + else "."; + end matchcontinue; +end getEnvNameStr; + +public function mergeEnvConnectionSet +"@author: adrpo + adds the connectionSet from the FromEnv to the ToEnv" + input Env inFromEnv; + input Env inToEnv; + output Env outEnv; +algorithm + outEnv := matchcontinue(inFromEnv, inToEnv) + local + Env env, forloopenv; + CSetsType clst, clst1, clst2; + Option on; + Option ot; + AvlTree cv; + AvlTree tys; + list i; + SCode.Encapsulated ep; + list du; + + case (_, _) + equation + false = isTopScope(inFromEnv); + false = isTopScope(inToEnv); + FRAME(connectionSet = clst1)::_ = stripForLoopScope(inFromEnv); + (FRAME(on,ot,cv,tys,i,clst2,ep,du)::env, forloopenv) = Lookup.splitEnv(inToEnv); + clst = listAppend(clst2, clst1); + env = listAppend(forloopenv, FRAME(on,ot,cv,tys,i,clst,ep,du)::env); + then + env; + + case (_, _) + equation + true = Flags.isSet(Flags.FAILTRACE); + print("Env.mergeEnvConnectionSet failed on:" +& + "\n\tinFromEnv: " +& getEnvNameStr(inFromEnv) +& + "\n\tinToEnv: " +& getEnvNameStr(inToEnv) +& "\n"); + then + fail(); + + // never fail, return the ToEnv + else inToEnv; + end matchcontinue; +end mergeEnvConnectionSet; + public function printEnvPathStr "function: printEnvPathStr Retrive the environment path as a string, see getEnvPath." input Env inEnv; @@ -1092,11 +1151,16 @@ algorithm _ := matchcontinue(env) local list crs; - case(env as (FRAME(connectionSet = (crs,_))::_)) equation - print(printEnvPathStr(env));print(" : "); - print(stringDelimitList(List.map(crs,ComponentReference.printComponentRefStr),", ")); - print("\n"); - then (); + CSetsType clst; + + case(env as (FRAME(connectionSet = clst)::_)) + equation + crs = List.flatten(List.map(clst, Util.tuple21)); + print(printEnvPathStr(env));print(" : "); + print(stringDelimitList(List.map(crs,ComponentReference.printComponentRefStr),", ")); + print("\n"); + then + (); end matchcontinue; end printEnvConnectionCrefs; @@ -1112,8 +1176,9 @@ algorithm AvlTree httypes; AvlTree ht; list imps; - tuple,DAE.ComponentRef> crs; + CSetsType crs; SCode.Encapsulated encflag; + case FRAME(optName = optName,clsAndVars = ht,types = httypes,imports = imps,connectionSet = crs,encapsulatedPrefix = encflag) equation sid = Util.getOptionOrDefault(optName, "unnamed"); @@ -1140,7 +1205,7 @@ algorithm AvlTree httypes; AvlTree ht; list imps; - tuple,DAE.ComponentRef> crs; + CSetsType crs; SCode.Encapsulated encflag; case FRAME(optName = SOME(sid),clsAndVars = ht,types = httypes,imports = imps,connectionSet = crs,encapsulatedPrefix = encflag) diff --git a/Compiler/FrontEnd/Inst.mo b/Compiler/FrontEnd/Inst.mo index 326ba7129f6..838b7000b14 100644 --- a/Compiler/FrontEnd/Inst.mo +++ b/Compiler/FrontEnd/Inst.mo @@ -160,8 +160,6 @@ protected import ValuesUtil; protected import System; protected import SCodeFlatten; protected import SCodeDump; -protected import SCodeMod; -//protected import Database; public function newIdent "function: newIdent @@ -4658,18 +4656,23 @@ algorithm SCode.Encapsulated enc; InstanceHierarchy ih; list defineUnits; + Env.CSetsType clst; case (Connect.SETS(connectionCrefs = crs),_, - (Env.FRAME( n,st,bt1,bt2,imp,_,enc,defineUnits) :: fs),ih) + (Env.FRAME( n,st,bt1,bt2,imp,clst,enc,defineUnits) :: fs),ih) equation prefix_cr = PrefixUtil.prefixToCref(prefix); - then (Env.FRAME(n,st,bt1,bt2,imp,(crs,prefix_cr),enc,defineUnits) :: fs,ih); + // strip the subs! + prefix_cr = ComponentReference.crefStripSubs(prefix_cr); + then + (Env.FRAME(n,st,bt1,bt2,imp,(crs,prefix_cr)::clst,enc,defineUnits) :: fs,ih); case (Connect.SETS(connectionCrefs = crs),_, - (Env.FRAME(n,st,bt1,bt2,imp,_,enc,defineUnits) :: fs),ih) + (Env.FRAME(n,st,bt1,bt2,imp,clst,enc,defineUnits) :: fs),ih) equation cref_ = ComponentReference.makeCrefIdent("",DAE.T_UNKNOWN_DEFAULT,{}); - then (Env.FRAME(n,st,bt1,bt2,imp,(crs,cref_),enc,defineUnits) :: fs,ih); + then + (Env.FRAME(n,st,bt1,bt2,imp,(crs,cref_)::clst,enc,defineUnits) :: fs,ih); end matchcontinue; end addConnectionSetToEnv; @@ -4685,7 +4688,9 @@ algorithm local Absyn.ComponentRef acr1, acr2; DAE.ComponentRef ecr1, ecr2; - list es; + list es, eqs; + list eeqlst; + list acc; case ({}, _) then inAccumCrefs; @@ -4694,9 +4699,20 @@ algorithm equation ecr1 = ComponentReference.toExpCref(acr1); ecr2 = ComponentReference.toExpCref(acr2); + // strip the subs as we don't care! + ecr1 = ComponentReference.crefStripSubs(ecr1); + ecr2 = ComponentReference.crefStripSubs(ecr2); then extractConnectionCrefs(es, ecr1 :: ecr2 :: inAccumCrefs); + case (SCode.EQUATION(eEquation = + SCode.EQ_FOR(eEquationLst = eeqlst)) :: es, _) + equation + eqs = List.map(eeqlst, SCode.makeEquation); + acc = extractConnectionCrefs(eqs, inAccumCrefs); + then + extractConnectionCrefs(es, acc); + case (_ :: es, _) then extractConnectionCrefs(es, inAccumCrefs); @@ -4723,6 +4739,10 @@ algorithm equation first_pre = PrefixUtil.prefixFirst(pre); cr = PrefixUtil.prefixToCref(first_pre); + + // strip the subs! + cr = ComponentReference.crefStripSubs(cr); + crs = List.select1r(crs, ComponentReference.crefPrefixOf, cr); s = ConnectUtil.setConnectionCrefs(inSets, crs); then @@ -6880,7 +6900,7 @@ algorithm Absyn.TPATH(t, _), m, comment, cond, _), mod_1) = redeclareType(cache, env2, ih, mod, comp, pre, ci_state, impl, DAE.NOMOD()); - (cache, cls, cenv) = Lookup.lookupClass(cache, env, t, true); + (cache, cls, cenv) = Lookup.lookupClass(cache, env2 /* env */, t, true); attr = SCode.mergeAttributesFromClass(attr, cls); // If the element is protected, and an external modification @@ -6911,7 +6931,8 @@ algorithm // adrpo: 2010-09-28: check if the IDX mod doesn't overlap! Mod.checkIdxModsForNoOverlap(mod_1, PrefixUtil.prefixAdd(name, {}, pre, vt, ci_state), info); - // replace classes + // merge cardinality sets from env2 to cenv! + cenv = Env.mergeEnvConnectionSet(env2, cenv); (cache, comp_env, ih, store, dae, csets, ty, graph_new) = instVar(cache, cenv, ih, store, ci_state, mod_1, pre, name, cls, attr, diff --git a/Compiler/FrontEnd/SCode.mo b/Compiler/FrontEnd/SCode.mo index 17dacd8ff9e..a302f6e4c9d 100644 --- a/Compiler/FrontEnd/SCode.mo +++ b/Compiler/FrontEnd/SCode.mo @@ -4486,5 +4486,12 @@ algorithm end matchcontinue; end setClassPrefixes; +public function makeEquation + input EEquation inEEq; + output Equation outEq; +algorithm + outEq := EQUATION(inEEq); +end makeEquation; + end SCode;