/// <summary> /// Parses a bound of a variable /// </summary> /// <param name="scanner"></param> /// <param name="lp"></param> private static void ParseBound(Scanner scanner, LP lp) { Label varName; // TODO: wrong way of dealing with free variables // because the name of a variable could be more complicated // than just one identifier Token t = scanner.peekToken(1); if (t.Type == TokenType.Identifier && t.StringValue == "free") { // name varName = Label.ParseLabel(scanner); lp.vars.AddVariable(varName); // free t = scanner.nextToken(); return; } // Lower bound t = scanner.nextToken(); if (t.Type != TokenType.Integer && t.Type != TokenType.Double) { throw new Exception("A number is expected: " + t); } decimal low = decimal.Parse(t.StringValue); // <= t = scanner.nextToken(); if (t.Type != TokenType.Le) { throw new Exception("<= expected: " + t); } // Variable varName = Label.ParseLabel(scanner); // <= t = scanner.nextToken(); if (t.Type != TokenType.Le) { throw new Exception("<= expected: " + t); } // Upper bound t = scanner.nextToken(); if (t.Type != TokenType.Integer && t.Type != TokenType.Double) { throw new Exception("A number is expected: " + t); } decimal high = decimal.Parse(t.StringValue); lp.vars.AddVariable(varName); lp.vars[varName].LBound = low; lp.vars[varName].UBound = high; }
/// <summary> /// Parses a label /// </summary> public static Label ParseLabel(Scanner scanner) { Token t = scanner.nextToken(); if (t.Type != TokenType.Identifier) { throw new Exception("Identifier expected: " + t); } String name = t.StringValue; StringBuilder str = new StringBuilder(); t = scanner.peekToken(); if (t.Type == TokenType.LParen) { // ( scanner.nextToken(); t = scanner.peekToken(); if (t.Type != TokenType.RParen) { while (true) { t = scanner.nextToken(); if (t.Type != TokenType.Identifier && t.Type != TokenType.Integer) { throw new Exception("Identifier or integer expected: " + t); } str.Append(t.StringValue); // ) or , t = scanner.nextToken(); if (t.Type == TokenType.RParen) { break; } if (t.Type != TokenType.Comma) { throw new Exception(", expected: " + t); } str.Append(','); } } else { // ) scanner.nextToken(); } } return(new Label(name, str.ToString())); }
/// <summary> /// Parses an inequality /// </summary> /// <param name="scanner"></param> /// <returns></returns> public static Inequality ParseInequality(Scanner scanner) { Token t; // Identifier Label id = Label.ParseLabel(scanner); // : t = scanner.nextToken(); if (t.Type != TokenType.Colon) { throw new Exception(": expected: " + t); } // lhs LinearFunction lhs = LinearFunction.ParseFunction(scanner); // type t = scanner.nextToken(); IneqType type; switch (t.Type) { case TokenType.Le: type = IneqType.Le; break; case TokenType.Ge: type = IneqType.Ge; break; case TokenType.Eq: type = IneqType.Eq; break; default: throw new Exception("<=, =>, or = expected: " + t); } // rhs t = scanner.nextToken(); if (t.Type != TokenType.Integer && t.Type != TokenType.Double) { throw new Exception("A number is expected: " + t); } LpNumber rhs = new LpNumber(decimal.Parse(t.StringValue)); return(new Inequality(id, type, lhs, rhs, false)); }
// Loads definitions for variables private void LoadVariables(Scanner s) { variables = new Dictionary <string, Definition>(); while (true) { Token t = s.peekToken(); if (t.Type == TokenType.EOF) { break; } if (t.Type == TokenType.Identifier && t.StringValue == "end") { // end s.nextToken(); break; } Definition def = ReadDefinition(s); if (def.set == null) { def.set = defaultSets[def.domain]; } variables.Add(def.name, def); } }
private Definition ReadDefinition(Scanner s) { // name Token t = s.nextToken(); if (t.Type != TokenType.Identifier) { throw new Exception("Identifier expected: " + t); } string name = t.StringValue; // : t = s.nextToken(); if (t.Type != TokenType.Colon) { throw new Exception(": expected: " + t); } // domain t = s.nextToken(); if (t.Type != TokenType.Identifier) { throw new Exception("Identifier expected: " + t); } string domain = t.StringValue; string set = null; t = s.peekToken(); if (t.Type == TokenType.Comma) { // , t = s.nextToken(); // set t = s.nextToken(); if (t.Type != TokenType.Identifier) { throw new Exception("Identifier expected: " + t); } set = t.StringValue; } return(new Definition(name, domain, set)); }
/// <summary> /// Parses a term /// </summary> /// <param name="scanner"></param> /// <returns></returns> public static Term ParseTerm(Scanner scanner) { Token t = scanner.nextToken(); bool negative = false; decimal c; Label varName; // Sign if (t.Type == TokenType.Minus) { negative = true; } else if (t.Type != TokenType.Plus) { throw new Exception("+ or - expected: " + t); } t = scanner.peekToken(); // Coefficient if (t.Type == TokenType.Integer || t.Type == TokenType.Double) { // number scanner.nextToken(); c = decimal.Parse(t.StringValue); } else { c = 1; } if (negative) { c = -c; } // Variable varName = Label.ParseLabel(scanner); return(new Term(new LpNumber(c), varName)); }
// Loads default sets private void LoadDefaultSets(Scanner s) { defaultSets = new Dictionary <string, string>(); while (true) { Token t = s.peekToken(); if (t.Type == TokenType.EOF) { break; } if (t.Type == TokenType.Identifier && t.StringValue == "end") { // end s.nextToken(); break; } Definition def = ReadDefinition(s); defaultSets.Add(def.name, def.domain); } }
/// <summary> /// Parses a LP /// </summary> /// <param name="scanner"></param> /// <returns></returns> public static LP ParseLP(Scanner scanner) { LP lp = new LP(); // Maximize Token t = scanner.nextToken(); if (t.Type != TokenType.Identifier && t.StringValue != "Maximize") { throw new Exception("Maximize expected: " + t); } // objective t = scanner.nextToken(); if (t.Type != TokenType.Identifier) { throw new Exception("Identifier expected: " + t); } // : t = scanner.nextToken(); if (t.Type != TokenType.Colon) { throw new Exception(": expected: " + t); } // objective function lp.objective = LinearFunction.ParseFunction(scanner); // Subject To t = scanner.nextToken(); if (t.Type != TokenType.Identifier && t.StringValue != "Subject") { throw new Exception("Subject To expected: " + t); } t = scanner.nextToken(); if (t.Type != TokenType.Identifier && t.StringValue != "To") { throw new Exception("Subject To expected: " + t); } // Constraints while (true) { t = scanner.peekToken(); if (t.Type == TokenType.Identifier && t.StringValue == "Bounds") { break; } if (t.Type == TokenType.EOF) { break; } Inequality ineq = Inequality.ParseInequality(scanner); lp.originalIneqs.Add(ineq); } // Bounds t = scanner.nextToken(); if (t.Type != TokenType.Identifier && t.StringValue != "Bounds") { throw new Exception("Bounds expected: " + t); } // Bounds while (true) { t = scanner.peekToken(); if (t.Type == TokenType.Identifier && t.StringValue == "End") { break; } if (t.Type == TokenType.EOF) { break; } ParseBound(scanner, lp); } return(lp); }
// Reads one definition private Definition ReadDefinition(Scanner s) { // name Token t = s.nextToken(); if (t.Type != TokenType.Identifier) throw new Exception("Identifier expected: " + t); string name = t.StringValue; // : t = s.nextToken(); if (t.Type != TokenType.Colon) throw new Exception(": expected: " + t); // domain t = s.nextToken(); if (t.Type != TokenType.Identifier) throw new Exception("Identifier expected: " + t); string domain = t.StringValue; string set = null; t = s.peekToken(); if (t.Type == TokenType.Comma) { // , t = s.nextToken(); // set t = s.nextToken(); if (t.Type != TokenType.Identifier) throw new Exception("Identifier expected: " + t); set = t.StringValue; } return new Definition(name, domain, set); }
// Loads definitions for variables private void LoadVariables(Scanner s) { variables = new Dictionary<string, Definition>(); while (true) { Token t = s.peekToken(); if (t.Type == TokenType.EOF) break; if (t.Type == TokenType.Identifier && t.StringValue == "end") { // end s.nextToken(); break; } Definition def = ReadDefinition(s); if (def.set == null) def.set = defaultSets[def.domain]; variables.Add(def.name, def); } }
// Loads default sets private void LoadDefaultSets(Scanner s) { defaultSets = new Dictionary<string, string>(); while (true) { Token t = s.peekToken(); if (t.Type == TokenType.EOF) break; if (t.Type == TokenType.Identifier && t.StringValue == "end") { // end s.nextToken(); break; } Definition def = ReadDefinition(s); defaultSets.Add(def.name, def.domain); } }
/// <summary> /// Reads all hypermaps from a file /// </summary> public ListHypManager(TextReader tame_archive, TextReader definitions) { // Load all hypermaps data = new Dictionary<string, ListHyp>(); while (tame_archive != null) { string str = tame_archive.ReadLine(); if (str == null) break; if (str.Length < 2) continue; if (str[0] != '"') continue; str = str.Substring(1, str.Length - 3); ListHyp hyp = new ListHyp(str, this); data.Add(hyp.Id, hyp); } // Load definitions Scanner s = new Scanner(definitions); Token t; // DefaultSets t = s.nextToken(); if (t.StringValue != "DefaultSets") throw new Exception("DefaultSets expected: " + t); LoadDefaultSets(s); // Variable t = s.nextToken(); if (t.StringValue != "Variables") throw new Exception("Variables expected: " + t); LoadVariables(s); // Constraints t = s.nextToken(); if (t.StringValue != "Constraints") throw new Exception("Constraints expected: " + t); LoadConstraints(s); GenerateVariableInequalities(); }
/// <summary> /// Parses an inequality /// </summary> /// <param name="scanner"></param> /// <returns></returns> public static Inequality ParseInequality(Scanner scanner) { Token t; // Identifier Label id = Label.ParseLabel(scanner); // : t = scanner.nextToken(); if (t.Type != TokenType.Colon) throw new Exception(": expected: " + t); // lhs LinearFunction lhs = LinearFunction.ParseFunction(scanner); // type t = scanner.nextToken(); IneqType type; switch (t.Type) { case TokenType.Le: type = IneqType.Le; break; case TokenType.Ge: type = IneqType.Ge; break; case TokenType.Eq: type = IneqType.Eq; break; default: throw new Exception("<=, =>, or = expected: " + t); } // rhs t = scanner.nextToken(); if (t.Type != TokenType.Integer && t.Type != TokenType.Double) throw new Exception("A number is expected: " + t); LpNumber rhs = new LpNumber(decimal.Parse(t.StringValue)); return new Inequality(id, type, lhs, rhs, false); }
/// <summary> /// Reads all hypermaps from a file /// </summary> public ListHypManager(TextReader tame_archive, TextReader definitions) { // Load all hypermaps data = new Dictionary <string, ListHyp>(); while (true) { string str = tame_archive.ReadLine(); if (str == null) { break; } if (str.Length < 2) { continue; } if (str[0] != '"') { continue; } str = str.Substring(1, str.Length - 3); ListHyp hyp = new ListHyp(str, this); data.Add(hyp.Id, hyp); } // Load definitions Scanner s = new Scanner(definitions); Token t; // DefaultSets t = s.nextToken(); if (t.StringValue != "DefaultSets") { throw new Exception("DefaultSets expected: " + t); } LoadDefaultSets(s); // Variable t = s.nextToken(); if (t.StringValue != "Variables") { throw new Exception("Variables expected: " + t); } LoadVariables(s); // Constraints t = s.nextToken(); if (t.StringValue != "Constraints") { throw new Exception("Constraints expected: " + t); } LoadConstraints(s); GenerateVariableInequalities(); }
/// <summary> /// Parses a LP /// </summary> /// <param name="scanner"></param> /// <returns></returns> public static LP ParseLP(Scanner scanner) { LP lp = new LP(); // Maximize Token t = scanner.nextToken(); if (t.Type != TokenType.Identifier && t.StringValue != "Maximize") throw new Exception("Maximize expected: " + t); // objective t = scanner.nextToken(); if (t.Type != TokenType.Identifier) throw new Exception("Identifier expected: " + t); // : t = scanner.nextToken(); if (t.Type != TokenType.Colon) throw new Exception(": expected: " + t); // objective function lp.objective = LinearFunction.ParseFunction(scanner); // Subject To t = scanner.nextToken(); if (t.Type != TokenType.Identifier && t.StringValue != "Subject") throw new Exception("Subject To expected: " + t); t = scanner.nextToken(); if (t.Type != TokenType.Identifier && t.StringValue != "To") throw new Exception("Subject To expected: " + t); // Constraints while (true) { t = scanner.peekToken(); if (t.Type == TokenType.Identifier && t.StringValue == "Bounds") break; if (t.Type == TokenType.EOF) break; Inequality ineq = Inequality.ParseInequality(scanner); lp.originalIneqs.Add(ineq); } // Bounds t = scanner.nextToken(); if (t.Type != TokenType.Identifier && t.StringValue != "Bounds") throw new Exception("Bounds expected: " + t); // Bounds while (true) { t = scanner.peekToken(); if (t.Type == TokenType.Identifier && t.StringValue == "End") break; if (t.Type == TokenType.EOF) break; ParseBound(scanner, lp); } return lp; }
/// <summary> /// Parses a bound of a variable /// </summary> /// <param name="scanner"></param> /// <param name="lp"></param> private static void ParseBound(Scanner scanner, LP lp) { Label varName; // TODO: wrong way of dealing with free variables // because the name of a variable could be more complicated // than just one identifier Token t = scanner.peekToken(1); if (t.Type == TokenType.Identifier && t.StringValue == "free") { // name varName = Label.ParseLabel(scanner); lp.vars.AddVariable(varName); // free t = scanner.nextToken(); return; } // Lower bound t = scanner.nextToken(); if (t.Type != TokenType.Integer && t.Type != TokenType.Double) throw new Exception("A number is expected: " + t); decimal low = decimal.Parse(t.StringValue); // <= t = scanner.nextToken(); if (t.Type != TokenType.Le) throw new Exception("<= expected: " + t); // Variable varName = Label.ParseLabel(scanner); // <= t = scanner.nextToken(); if (t.Type != TokenType.Le) throw new Exception("<= expected: " + t); // Upper bound t = scanner.nextToken(); if (t.Type != TokenType.Integer && t.Type != TokenType.Double) throw new Exception("A number is expected: " + t); decimal high = decimal.Parse(t.StringValue); lp.vars.AddVariable(varName); lp.vars[varName].LBound = low; lp.vars[varName].UBound = high; }