/// <summary> /// Called by ParseMetric(String str). Strips the assign()s until it find the value /// </summary> /// <param name="name">name of the metric (e.g., "default" or "euclidean")</param> /// <returns>The value for X . Y metric</returns> private static double ParseMetric(Specification S, string name, Object O, string str) { // first check if 'O' could be the final value of the metric specification G25.rsep.FunctionApplication FA = O as G25.rsep.FunctionApplication; if ((FA == null) || (FA.FunctionName == "negate") || (FA.FunctionName == "nop")) { return ParseMetricValue(S, O, str); } // This FA should be of the form X.Y=value // First argument must be a XdotY function application, and the function name should be "assign" G25.rsep.FunctionApplication XdotY = FA.Arguments[0] as G25.rsep.FunctionApplication; if ((FA.NbArguments != 2) || (FA.FunctionName != "assign") || (XdotY == null) || (XdotY.NbArguments != 2) || (XdotY.FunctionName != "ip")) throw new G25.UserException("Invalid metric specification '" + str + "'"); // get value by recursing double value = ParseMetric(S, name, FA.Arguments[1], str); // get, check names of basis vectors string basisVectorName1 = XdotY.Arguments[0] as String; string basisVectorName2 = XdotY.Arguments[1] as String; if ((basisVectorName1 == null) || (basisVectorName2 == null)) throw new G25.UserException("Invalid basis vector names in metric specification '" + str + "'"); int basisVectorIdx1 = S.BasisVectorNameToIndex(basisVectorName1); int basisVectorIdx2 = S.BasisVectorNameToIndex(basisVectorName2); S.SetMetric(name, basisVectorIdx1, basisVectorIdx2, value); return value; }