// 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); } }
// 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); }
/// <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(); }
// 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> /// Creates files for a formal proof for a general linear program /// </summary> static bool processLPGeneral(string fname, int precision, LpNumber upperBound) { if (precision > 10) throw new Exception("Cannot solve the problem (precision > 10): " + fname); LP lp; LPSolution sol; // Load an LP FileStream fs = new FileStream(fname + ".lp", FileMode.Open); using (fs) { StreamReader r = new StreamReader(fs); Scanner scanner = new Scanner(r, fname + ".lp"); lp = LP.ParseLP(scanner); } // Load solutions fs = new FileStream(fname + ".txt", FileMode.Open); using (fs) { sol = LPSolution.LoadSolution(new StreamReader(fs), precision, upperBound); } if (!lp.SetSolution(sol, precision)) return false; // Create a test file containing all inequalities explicitly FileStream test = new FileStream(fname + "_test.hl", FileMode.Create); lp.ConvertToHOL(new StreamWriter(test), precision); test.Close(); return true; }
/// <summary> /// Creates files for producing a formal proof for the given linear program /// </summary> static bool ProcessLP(string fname, LpNumber upperBound, int precision, ListHyp hypermap) { if (precision > 5) throw new Exception("Cannot solve the problem: " + fname); LP lp; LPSolution sol; // Load an LP FileStream fs = new FileStream(fname + ".lp", FileMode.Open); using (fs) { StreamReader r = new StreamReader(fs); Scanner scanner = new Scanner(r, fname + ".lp"); lp = LP.ParseLP(scanner); } // Load solutions fs = new FileStream(fname + ".txt", FileMode.Open); using (fs) { sol = LPSolution.LoadSolution(new StreamReader(fs), precision, upperBound); } if (sol.Optimal.value > upperBound.value) throw new Exception("Optimal value is greater than " + upperBound.value + ": " + fname); if (!lp.SetSolution(sol, precision)) return false; // Create a test file containing all inequalities explicitly FileStream test = new FileStream(fname + "_test.hl", FileMode.Create); lp.ConvertToHOL(new StreamWriter(test), precision); test.Close(); // Create a certificate file FileStream main = new FileStream(fname + "_out.hl", FileMode.Create); lp.PrintCertificate(new StreamWriter(main), precision, hypermap, log); main.Close(); return true; }
/// <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> /// 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; }