/// <summary> /// Creates files for producing a formal proof for the given linear program. /// The precision is selected automatically /// </summary> static void ProcessLP(string fname, LpNumber upperBound, ListHyp hypermap) { Console.WriteLine("Processing {0}...", fname); try { for (int precision = 3; ; precision++) { Console.WriteLine("Precision = {0}", precision); if (hypermap != null) { if (ProcessLP(fname, upperBound, precision, hypermap)) { break; } } else { if (processLPGeneral(fname, precision, upperBound)) { break; } } } } catch (Exception e) { Console.Error.WriteLine("ERROR: {0}", e.Message); } Console.WriteLine("done\n"); }
/// <summary> /// Creates files for producing a formal proof for the given linear program. /// The precision is selected automatically /// </summary> static void ProcessLP(string fname, LpNumber upperBound, ListHyp hypermap, bool infeasible, bool holTerms) { Console.WriteLine("Processing {0}...", fname); for (int precision = 3; ; precision++) { Console.WriteLine("Precision = {0}", precision); if (hypermap != null) { if (ProcessLP(fname, upperBound, precision, hypermap, infeasible, holTerms)) { break; } } else { if (processLPGeneral(fname, precision, upperBound)) { break; } } } Console.WriteLine("done\n"); }
// Main static void Main(string[] args) { FileStream flog = new FileStream("log.txt", FileMode.Create); log = new StreamWriter(flog); using (log) { // GenerateArithTest(); // return; // Flyspeck if (args.Length == 0) { Console.WriteLine("Processing Flyspeck linear programs"); Console.WriteLine(); ProcessFlyspeckLP(); return; } // Incorrect number of arguments if (args.Length != 2) { Console.WriteLine("Usage: LP-HL lp_name upper_bound"); Console.WriteLine("Files {lp_name}.lp and {lp_name}.txt must be in the current directory."); Console.WriteLine("{upper_bound} is a decimal number"); return; } // Specific LP string name = args[0]; LpNumber upperBound = new LpNumber(decimal.Parse(args[1])); ProcessLP(name, upperBound, null); } }
// Adds an indexed inequality to a dictionary private void AddIndexedIneq(Inequality ineq, LpNumber marginal, ListHyp hypermap) { IndexedInequality newIneq = new IndexedInequality(ineq, marginal, hypermap); string name = ineq.Id.name; // Ad hoc treatment of sums over faces if (name == "sol_sum" || name == "tau_sum") { DartList face = hypermap.Manager.TranslateIneq(hypermap, ineq.Id) as DartList; if (face == null) { throw new Exception("A face is expected for the constraint " + name); } name += face.list.Count.ToString(); } if (ineq.type == Inequality.IneqType.Eq && ineq.NegFlag) { name += "_neg"; } if (dict.ContainsKey(name)) { dict[name].Add(newIneq); } else { var list = new List <IndexedInequality>(); list.Add(newIneq); dict.Add(name, list); ineqNames.Add(name); } }
/// <summary> /// Private constructor /// </summary> private Inequality(Label id, IneqType type, LinearFunction lhs, LpNumber rhs, bool negFlag) { this.Id = id; this.type = type; this.lhs = lhs; this.rhs = rhs; this.NegFlag = negFlag; }
/// <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> /// Returns the equality 0 = 0 /// </summary> public static Inequality Zero() { Label id = new Label("ZERO", ""); LinearFunction lhs = new LinearFunction(new List <decimal>(), new List <string>()); LpNumber rhs = new LpNumber(0); Inequality ineq = new Inequality(id, IneqType.Eq, lhs, rhs, false); return(ineq); }
// Main static int Main(string[] args) { try { FileStream flog = new FileStream("log.txt", FileMode.Create); log = new StreamWriter(flog); using (log) { // GenerateArithTest(); // return; // Flyspeck if (args.Length == 0 || args.Length == 1) { ListHypManager hypermaps = InitializeHypermaps(); Console.WriteLine("Processing Flyspeck linear program(s)"); Console.WriteLine(); if (args.Length == 1) { ProcessFlyspeckLP(args[0], hypermaps); } else { ProcessFlyspeckLPs(hypermaps); } return(0); } // Incorrect number of arguments if (args.Length != 2) { Console.WriteLine("Usage: LP-HL lp_name upper_bound"); Console.WriteLine("Files {lp_name}.lp and {lp_name}.txt must be in the current directory."); Console.WriteLine("{upper_bound} is a decimal number"); return(1); } // Specific LP string name = args[0]; LpNumber upperBound = new LpNumber(decimal.Parse(args[1])); ProcessLP(name, upperBound, null, false, true); } } catch (Exception e) { Console.Error.WriteLine("ERROR: {0}", e.Message); return(2); } return(0); }
/// <summary> /// Addition /// </summary> /// <param name="f1"></param> /// <param name="f2"></param> /// <returns></returns> public static LinearFunction operator +(LinearFunction f1, LinearFunction f2) { f1.terms.Sort(); f2.terms.Sort(); LinearFunction f = new LinearFunction(); int n1 = f1.terms.Count; int n2 = f2.terms.Count; int index1 = 0, index2 = 0; while (index1 < n1 && index2 < n2) { Term t1 = f1.terms[index1]; Term t2 = f2.terms[index2]; int r = t1.CompareTo(t2); if (r == 0) { LpNumber n = t1.c + t2.c; if (n.value != 0) { f.terms.Add(new Term(n, t1.varName)); } index1++; index2++; } else if (r > 0) { f.terms.Add(t2); index2++; } else { f.terms.Add(t1); index1++; } } for (int i = index1; i < n1; i++) { f.terms.Add(f1.terms[i]); } for (int i = index2; i < n2; i++) { f.terms.Add(f2.terms[i]); } return(f); }
/// <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> /// Computes the index automatically /// </summary> public IndexedInequality(Inequality ineq, LpNumber marginal, ListHyp hypermap) { this.ineq = ineq; this.marginal = marginal; if (ineq.Id.index == null || ineq.Id.index == "") { this.index = 0; } else { this.index = hypermap.Manager.FindIneqIndex(hypermap, ineq.Id); } }
/// <summary> /// Generates a test for arithmetic /// </summary> static void GenerateArithTest() { FileStream fs = new FileStream("arith_test_data.hl", FileMode.Create); StreamWriter w = new StreamWriter(fs); Random rnd = new Random(0); w.WriteLine("let data = ["); for (int i = 0; i < 1000; i++) { decimal n1 = rnd.Next(1000000000, 2000000000); decimal n2 = rnd.Next(1000000000, 2000000000); // n1 *= rnd.Next(1000000000, 2000000000); // n2 *= rnd.Next(1000000000, 2000000000); n1 *= rnd.Next(100000, 500000); n2 *= rnd.Next(100000, 500000); int x1 = (int)Math.Log10((double)n1); int x2 = (int)Math.Log10((double)n2); LpNumber m1 = new LpNumber(n1); LpNumber m2 = new LpNumber(n2); w.Write(m1.ToHOLExplicit(0)); w.Write(","); w.Write(m2.ToHOLExplicit(0)); if (i < 999) { w.Write(";"); } w.Write("(* {0}, {1} *)", x1, x2); w.WriteLine(); } w.WriteLine("];;"); w.Flush(); fs.Close(); }
/// <summary> /// Prints the given inequality into a stream /// </summary> private void WriteIneqText(Inequality ineq, LpNumber marginal, int precision, StreamWriter writer, ListHyp hypermap) { // Relabel HypermapElement element = hypermap.Manager.TranslateIneq(hypermap, ineq.Id); int index = hypermap.Manager.FindIneqIndex(hypermap, ineq.Id); // Write out if (ineq.NegFlag && ineq.type == Inequality.IneqType.Eq) { writer.Write("-"); } writer.Write(ineq.Id + " & "); writer.Write(index + " & "); writer.Write(element + ": "); writer.Write(ineq.ToHOLString(precision, vars)); writer.Write("\t ("); writer.Write(marginal.ToHOLString(precision)); writer.WriteLine(")"); }
/// <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)); }
/// <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); }
// Adds an indexed inequality to a dictionary private void AddIndexedIneq(Inequality ineq, LpNumber marginal, ListHyp hypermap) { IndexedInequality newIneq = new IndexedInequality(ineq, marginal, hypermap); string name = ineq.Id.name; if (ineq.type == Inequality.IneqType.Eq && ineq.NegFlag) { name += "_neg"; } if (dict.ContainsKey(name)) { dict[name].Add(newIneq); } else { var list = new List <IndexedInequality>(); list.Add(newIneq); dict.Add(name, list); ineqNames.Add(name); } }
/// <summary> /// Loads solutions from a stream (a file) /// </summary> /// <param name="r"></param> /// <returns></returns> public static LPSolution LoadSolution(StreamReader r, int precision, LpNumber upperBound) { LPSolution sol = new LPSolution(); sol.UpperBound = upperBound; string str = r.ReadLine(); if (str == null) { throw new Exception("Two numbers are expected on the first line"); } string[] els = str.Split(' '); if (els.Length != 2) { throw new Exception("Two numbers are expected on the first line"); } // Subtract one since we don't count the objective function sol.NumberOfConstraints = int.Parse(els[0]) - 1; sol.NumberOfVariables = int.Parse(els[1]); // Optimal var vals = ReadThirdValue(r, 1, precision); sol.Optimal = vals[0]; // Skip one line (the objective function) ReadThirdValue(r, 1, precision); // Constraints sol.ConstraintMarginals = ReadThirdValue(r, sol.NumberOfConstraints, precision); // Bounds sol.VariableMarginals = ReadThirdValue(r, sol.NumberOfVariables, precision); return(sol); }
/// <summary> /// Reads k third values from the input stream /// </summary> /// <param name="k"></param> /// <returns></returns> private static List <LpNumber> ReadThirdValue(StreamReader r, int k, int precision) { List <LpNumber> result = new List <LpNumber>(); for (int i = 0; i < k; i++) { string str = r.ReadLine(); if (str == null) { throw new Exception("Unexpected end of file"); } string[] els = str.Split(' '); if (els.Length != 3) { throw new Exception("Triples are expected: " + str); } LpNumber val = new LpNumber(double.Parse(els[2]), precision); result.Add(val); } return(result); }
/// <summary> /// Processes all inequalities based on the given solution /// </summary> /// <param name="sol"></param> /// <param name="precision"></param> /// <returns></returns> public bool SetSolution(LPSolution sol, int precision) { if (sol.NumberOfVariables != vars.Number) { throw new Exception("Inconsistent number of variables"); } if (sol.NumberOfConstraints != originalIneqs.Count) { throw new Exception("Inconsistent number of constraints"); } ineqs = new List <Inequality>(); // ineqMarginals = new List<LpNumber>(); // Constraints for (int i = 0; i < sol.NumberOfConstraints; i++) { LpNumber m = sol.ConstraintMarginals[i]; if (m.IsZero(precision)) { continue; } Inequality ineq = originalIneqs[i]; if (m.value < 0) { ineq = -ineq; m = -m; } ineq = ineq.Round(precision); ineq.Marginal = m; ineqs.Add(ineq); // ineqMarginals.Add(m); } // Variables List <Inequality> tmpIneqs = new List <Inequality>(); for (int i = 0; i < sol.NumberOfVariables; i++) { Variable var = vars[i]; LpNumber m = sol.VariableMarginals[i]; if (m.IsZero(precision)) { continue; } Inequality ineq; if (m.value < 0) { var.LMarginal = -m; ineq = -Inequality.FromLowerBound(var); ineq = ineq.Round(precision) * (-m.value); } else { var.UMarginal = m; ineq = Inequality.FromUpperBound(var); ineq = ineq.Round(precision) * m.value; } tmpIneqs.Add(ineq); } // Compute additional inequality // Inequality sum1 = ineqs[0] * ineqs[0].Marginal.value; //ineqMarginals[0].value; Inequality sum1 = Inequality.Zero(); for (int i = 0; i < ineqs.Count; i++) { sum1 += ineqs[i] * ineqs[i].Marginal.value; //ineqMarginals[i].value; } Inequality sum2 = sum1; for (int i = 0; i < tmpIneqs.Count; i++) { sum2 += tmpIneqs[i]; } // df LinearFunction df = objective - sum2.lhs; // Compute corrections for marginals foreach (var term in df.Terms) { LpNumber c = term.c; if (c.value < 0) { vars[term.varName].LMarginal -= c; } else { vars[term.varName].UMarginal += c; } } // Verification LpNumber sum = sum1.rhs; for (int i = 0; i < vars.Number; i++) { Variable var = vars[i]; if (!var.LMarginal.IsZero(precision)) { sum -= var.LMarginal * LpNumber.RoundDown(var.LBound, precision); } if (!var.UMarginal.IsZero(precision)) { sum += var.UMarginal * LpNumber.RoundUp(var.UBound, precision); } } LpNumber eps = sol.UpperBound - sum; Console.WriteLine("eps = {0}", eps); if (eps.value < 0) { return(false); } // Set the upper bound upperBound = sol.UpperBound; // Generate inequalities for variables Console.Write("Generating inequalities for variables..."); varIneqs = new List <Inequality>(); // varIneqMarginals = new List<LpNumber>(); for (int i = 0; i < vars.Number; i++) { Variable var = vars[i]; Inequality ineq; if (!var.LMarginal.IsZero(precision)) { ineq = -Inequality.FromLowerBound(var); ineq = ineq.Round(precision); ineq.Marginal = var.LMarginal; varIneqs.Add(ineq); // varIneqMarginals.Add(var.LMarginal); } if (!var.UMarginal.IsZero(precision)) { ineq = Inequality.FromUpperBound(var); ineq = ineq.Round(precision); ineq.Marginal = var.UMarginal; varIneqs.Add(ineq); // varIneqMarginals.Add(var.UMarginal); } } Console.WriteLine("done"); return(true); }
/// <summary> /// Loads solutions from a stream (a file) /// </summary> /// <param name="r"></param> /// <returns></returns> public static LPSolution LoadSolution(StreamReader r, int precision, LpNumber upperBound, bool infeasible) { LPSolution sol = new LPSolution(); sol.UpperBound = upperBound; if (infeasible) { sol.UpperBound = new LpNumber(0); } string str = r.ReadLine(); if (str == null) { throw new Exception("Two numbers are expected on the first line"); } string[] els = str.Split(' '); if (els.Length != 2) { throw new Exception("Two numbers are expected on the first line"); } int nc = int.Parse(els[0]); int nv = int.Parse(els[1]); if (infeasible) { sol.NumberOfConstraints = nc; // Do not count slack variables sol.NumberOfVariables = nv - nc; } else { // Subtract one since we don't count the objective function for a feasible solution sol.NumberOfConstraints = nc - 1; sol.NumberOfVariables = nv; } // Optimal var vals = ReadThirdValue(r, 1, precision); sol.Optimal = vals[0]; if (!infeasible) { // Skip one line (the objective function) ReadThirdValue(r, 1, precision); } // Constraints sol.ConstraintMarginals = ReadThirdValue(r, sol.NumberOfConstraints, precision); if (infeasible) { // Skip slack variables ReadThirdValue(r, nc, precision); } // Bounds sol.VariableMarginals = ReadThirdValue(r, sol.NumberOfVariables, precision); return(sol); }
/// <summary> /// Default constructor /// </summary> /// <param name="c"></param> /// <param name="varName"></param> public Term(LpNumber c, Label varName) { this.c = c; this.varName = varName; }
/// <summary> /// Copy constructor /// </summary> /// <param name="t"></param> public Term(Term t) { this.c = t.c; this.varName = t.varName; }
/// <summary> /// Creates a HOL certificate /// </summary> public void PrintCertificate(StreamWriter writer, int precision, ListHyp hypermap, StreamWriter log) { // Find target variables foreach (var term in objective.Terms) { vars[term.varName].TargetVariable = true; } // Compute the precision constant decimal mul = 1; for (int i = 0; i < precision; i++) { mul *= 10; } // Head writer.WriteLine("needs \"nobranching_lp.hl\";;\n"); writer.WriteLine("module Test_case = struct"); // Parameters writer.WriteLine("let hypermap_string = \"" + hypermap.rawString + "\";;"); writer.WriteLine("let precision = " + precision + ";;"); dict.Clear(); ineqNames.Clear(); // Constraints int counter = 0; vars.RelabelAllVariables(hypermap); writer.WriteLine("(***************)"); writer.WriteLine("(* Constraints *)"); writer.WriteLine("(***************)"); for (int i = 0; i < ineqs.Count; i++) { Inequality ineq = ineqs[i]; LpNumber m = ineq.Marginal; if (ineq.Id.name == "lnsum_def") { throw new Exception("lnsum_def cannot be active"); } // Ignore zero values if (m.IsZero(precision)) { continue; } ineq *= mul; m *= mul; AddIndexedIneq(ineq, m, hypermap); } writer.WriteLine("let constraints = ["); SaveIndexedIneqs(writer, precision); writer.WriteLine("];;"); // Variables writer.WriteLine(); writer.WriteLine("(***************)"); writer.WriteLine("(* Variables *)"); writer.WriteLine("(***************)"); // Sort variables varIneqs.Sort(new VarsComparer(vars)); // Target variables first dict.Clear(); ineqNames.Clear(); counter = 0; for (; counter < varIneqs.Count; counter++) { Inequality ineq = varIneqs[counter]; if (!vars[ineq.lhs.Terms.First().varName].TargetVariable) { break; } LpNumber m = ineq.Marginal; m *= mul * mul; ineq = ineq * mul; AddIndexedIneq(ineq, m, hypermap); } writer.WriteLine("let target_variables = ["); SaveIndexedIneqs(writer, precision); writer.WriteLine("];;"); writer.WriteLine(); writer.WriteLine("(*************************)"); writer.WriteLine(); // All other variables dict.Clear(); ineqNames.Clear(); for (int i = counter; i < varIneqs.Count; i++) { Inequality ineq = varIneqs[i]; LpNumber m = ineq.Marginal; m *= mul * mul; ineq = ineq * mul; AddIndexedIneq(ineq, m, hypermap); } writer.WriteLine("let variable_bounds = ["); SaveIndexedIneqs(writer, precision); writer.WriteLine("];;"); // Tail writer.WriteLine("let result = prove_hypermap_lp hypermap_string precision constraints target_variables variable_bounds;;"); writer.WriteLine("end;;"); writer.WriteLine(); writer.WriteLine("concl (Test_case.result)"); writer.Flush(); log.WriteLine("{0}\t{1}\t{2}", hypermap.Id, ineqs.Count + varIneqs.Count, vars.Number); }
/// <summary> /// Prints all inequalities in a text file using HOL syntax /// </summary> /// <param name="writer"></param> /// <param name="precision"></param> public void PrintAllText(StreamWriter writer, int precision, ListHyp hypermap) { // Find target variables foreach (var term in objective.Terms) { vars[term.varName].TargetVariable = true; } // Compute the precision constant decimal mul = 1; for (int i = 0; i < precision; i++) { mul *= 10; } // Target writer.WriteLine("target: " + objective.ToHOLString(precision, vars)); // Precision writer.WriteLine("precision_constant: " + mul); // Constraints int counter = 0; vars.RelabelAllVariables(hypermap); for (int i = 0; i < ineqs.Count; i++) { Inequality ineq = ineqs[i]; LpNumber m = ineq.Marginal; if (ineq.Id.name == "lnsum_def") { throw new Exception("lnsum_def cannot be active"); } // Ignore zero values if (m.IsZero(precision)) { continue; } WriteIneqText(ineq * mul, m * mul, precision, writer, hypermap); counter++; } writer.WriteLine(); writer.WriteLine("Inequalities for constraints: {0}", counter); writer.WriteLine("-------------------------------------------------------"); writer.WriteLine(); // Variables // Sort variables varIneqs.Sort(new VarsComparer(vars)); // Target variables first writer.WriteLine("Target variables:"); counter = 0; for (; counter < varIneqs.Count; counter++) { Inequality ineq = varIneqs[counter]; if (!vars[ineq.lhs.Terms.First().varName].TargetVariable) { break; } LpNumber m = ineq.Marginal; //varIneqMarginals[i]; m *= mul * mul; ineq = ineq * mul; WriteIneqText(ineq, m, precision, writer, hypermap); } writer.WriteLine("-------------------------------------------------------"); writer.WriteLine(); // All other variables writer.WriteLine("Variables:"); for (int i = counter; i < varIneqs.Count; i++) { Inequality ineq = varIneqs[i]; LpNumber m = ineq.Marginal; //varIneqMarginals[i]; if (m.IsZero(precision)) { throw new Exception("Unexpected zero"); } /* if (i < varIneqs.Count - 1) * { * Inequality ineq2 = varIneqs[i + 1]; * LpNumber m2 = ineq2.Marginal; * * if (m2.IsZero(precision)) * throw new Exception("Unexpected zero"); * * if (ineq.lhs.Terms.First().varName == ineq2.lhs.Terms.First().varName) * { * m *= mul * mul; * m2 *= mul * mul; * ineq = ineq * mul; * ineq2 = ineq2 * mul; * * writer.Write("var2_le_transform ("); * writer.Write(ineq.ToHOLExplicit(precision, vars)); * writer.Write(", "); * writer.Write(m.ToHOLExplicit(precision)); * writer.Write(") "); * * writer.Write("("); * writer.Write(ineq2.ToHOLExplicit(precision, vars)); * writer.Write(", "); * writer.Write(m2.ToHOLExplicit(precision)); * writer.WriteLine(");"); * * i++; * continue; * } * } */ m *= mul * mul; ineq = ineq * mul; WriteIneqText(ineq, m, precision, writer, hypermap); } writer.WriteLine("Inequalities for variables: {0}", varIneqs.Count); writer.Flush(); }
/// <summary> /// Computes the index automatically /// </summary> public IndexedInequality(Inequality ineq, LpNumber marginal, ListHyp hypermap) { this.ineq = ineq; this.marginal = marginal; this.index = hypermap.Manager.FindIneqIndex(hypermap, ineq.Id); }
/// <summary> /// Converts the LP into HOL data /// </summary> /// <param name="writer"></param> public void ConvertToHOL(StreamWriter writer, int precision) { // Find target variables foreach (var term in objective.Terms) { vars[term.varName].TargetVariable = true; } // Compute the precision constant decimal mul = 1; for (int i = 0; i < precision; i++) { mul *= 10; } // Dependencies writer.WriteLine("module Lp = struct"); // writer.WriteLine("needs \"arith/prove_lp.hl\";;"); // writer.WriteLine("open Prove_lp;;"); // Target writer.WriteLine("let target = `" + objective.ToHOLString(precision, vars) + "`;;"); // Target bound writer.WriteLine("let target_bound = `" + upperBound.ToHOLString(100) + "`;;"); // Precision // LpNumber precision_constant = new LpNumber(mul * mul * mul); writer.Write("let precision_constant = "); writer.Write("Int " + mul); // writer.Write(precision_constant.ToHOLExplicit(0)); writer.WriteLine(";;"); // Constraints int counter = 0; writer.WriteLine("let ineqs = ["); vars.MakeSimpleNames(); for (int i = 0; i < ineqs.Count; i++) { Inequality ineq = ineqs[i]; LpNumber m = ineq.Marginal; //ineqMarginals[i]; if (ineq.Id.name == "lnsum_def") { throw new Exception("lnsum_def cannot be active"); } // Ignore zero values if (m.IsZero(precision)) { continue; } // m *= mul * mul; m *= mul; ineq = ineq * mul; writer.Write("ASSUME ("); writer.Write(ineq.ToHOLExplicit(precision, vars)); writer.Write("), "); writer.Write(m.ToHOLExplicit(precision)); writer.WriteLine(";"); counter++; } writer.WriteLine("];;"); int constraintIneqs = counter; // Variables // Sort variables varIneqs.Sort(new VarsComparer(vars)); // Save target variables first writer.WriteLine("let target_vars = ["); counter = 0; for (; counter < varIneqs.Count; counter++) { Inequality ineq = varIneqs[counter]; if (!vars[ineq.lhs.Terms.First().varName].TargetVariable) { break; } LpNumber m = ineq.Marginal; //varIneqMarginals[i]; m *= mul * mul; ineq = ineq * mul; writer.Write("ASSUME ("); writer.Write(ineq.ToHOLExplicit(precision, vars)); writer.Write("), "); writer.Write(m.ToHOLExplicit(precision)); writer.WriteLine(";"); } writer.WriteLine("];;\n\n"); writer.WriteLine("let var_ineqs = ["); // writer.WriteLine("let vars = ["); // counter = 0; for (int i = counter; i < varIneqs.Count; i++) { Inequality ineq = varIneqs[i]; LpNumber m = ineq.Marginal; //varIneqMarginals[i]; if (m.IsZero(precision)) { throw new Exception("Unexpected zero"); } if (i < varIneqs.Count - 1) { Inequality ineq2 = varIneqs[i + 1]; LpNumber m2 = ineq2.Marginal; if (m2.IsZero(precision)) { throw new Exception("Unexpected zero"); } if (ineq.lhs.Terms.First().varName == ineq2.lhs.Terms.First().varName) { m *= mul * mul; m2 *= mul * mul; ineq = ineq * mul; ineq2 = ineq2 * mul; writer.Write("var2_le_transform ("); writer.Write(ineq.ToHOLExplicit(precision, vars)); writer.Write(", "); writer.Write(m.ToHOLExplicit(precision)); writer.Write(") "); writer.Write("("); writer.Write(ineq2.ToHOLExplicit(precision, vars)); writer.Write(", "); writer.Write(m2.ToHOLExplicit(precision)); writer.WriteLine(");"); i++; continue; } } m *= mul * mul; ineq = ineq * mul; writer.Write("var1_le_transform ("); writer.Write(ineq.ToHOLExplicit(precision, vars)); writer.Write(", "); writer.Write(m.ToHOLExplicit(precision)); writer.WriteLine(");"); // writer.WriteLine(";"); } writer.WriteLine("];;"); Console.WriteLine("Inequalities for constraints: {0}", constraintIneqs); Console.WriteLine("Inequalities for variables: {0}", varIneqs.Count); Console.WriteLine("Number of variables: {0}", vars.Number); Console.WriteLine("Total constraints: {0}", constraintIneqs + varIneqs.Count); writer.WriteLine("let start = Sys.time();;"); writer.WriteLine("let result = prove_lp ineqs var_ineqs target_vars target_bound precision_constant;;"); // writer.WriteLine("let result = Prove_lp.prove_lp ineqs vars target_bound precision_constant;;"); writer.WriteLine("end;;"); writer.WriteLine("Sys.time() -. Lp.start;;"); // writer.WriteLine("let done_message = \"{0} done\";;", fname); writer.WriteLine("concl (Lp.result);;"); writer.Flush(); }