/// <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> /// Creates files for producing a formal proof for the given linear program /// </summary> static bool ProcessLP(string fname, LpNumber upperBound, int precision, ListHyp hypermap, bool infeasible, bool holTerms) { if (precision > 7) { 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, infeasible); } if (!infeasible && sol.Optimal.value > upperBound.value) { throw new Exception("Optimal value is greater than " + upperBound.value + ": " + fname); } if (!lp.SetSolution(sol, precision, infeasible)) { 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); FileStream main_bin = new FileStream(fname + "_out.bin", FileMode.Create); lp.PrintCertificate(new StreamWriter(main), new BinaryWriter(main_bin), precision, hypermap, log, infeasible, holTerms); main_bin.Close(); main.Close(); // Debug file with text inequalities // FileStream text = new FileStream(fname + "_text.hl", FileMode.Create); // lp.PrintAllText(new StreamWriter(text), precision, hypermap); // text.Close(); return(true); }
/// <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, false); } if (!lp.SetSolution(sol, precision, false)) { 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> /// 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 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; }