/// <summary> /// Converts to a HOL term /// </summary> /// <param name="precision"></param> /// <returns></returns> public string ToHOLExplicit(int precision, VariableCollection vars) { StringBuilder str = new StringBuilder(); switch (type) { case IneqType.Eq: // Eq becomes Le str.Append("mk_le_ineq "); break; case IneqType.Le: str.Append("mk_le_ineq "); break; case IneqType.Ge: str.Append("mk_ge_ineq "); break; } str.Append(lhs.ToHOLExplicit(precision, vars)); str.Append(rhs.ToHOLExplicit(precision)); return(str.ToString()); }
/// <summary> /// Converts to a HOL term /// </summary> /// <param name="precision"></param> /// <returns></returns> public string ToHOLExplicit(int precision, VariableCollection vars) { StringBuilder str = new StringBuilder(); if (c.value == 0) { return(""); } str.Append("(mk_term "); str.Append(c.ToHOLExplicit(precision)); str.Append('"' + vars[varName].ToString() + '"'); str.Append(')'); return(str.ToString()); }
/// <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> /// 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(); }