Beispiel #1
0
        /// <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;
        }
Beispiel #2
0
 /// <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;
 }
Beispiel #3
0
        /// <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;
        }
Beispiel #4
0
        /// <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();
        }
Beispiel #5
0
        /// <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;
        }
Beispiel #6
0
        /// <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;
        }
Beispiel #7
0
        /// <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");
        }
Beispiel #8
0
        // 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);
            }
        }
Beispiel #9
0
        /// <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;
        }
Beispiel #10
0
        /// <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;
        }
Beispiel #11
0
        /// <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);
        }
Beispiel #12
0
        /// <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, bool infeasible)
        {
            if (sol.NumberOfVariables != vars.Number)
                throw new Exception("Inconsistent number of variables");

            if (sol.NumberOfConstraints != originalIneqs.Count)
                throw new Exception("Inconsistent number of constraints");

            if (infeasible)
            {
                ResortVariables();
            }

            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;

            if (infeasible)
            {
                df = -sum2.lhs;
            }
            else
            {
                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;
        }