/// <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> /// 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> /// 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(); }
/// <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); }