示例#1
0
        /// <summary>
        /// Creates an upper bound inequality for a variable
        /// </summary>
        /// <param name="var"></param>
        /// <returns></returns>
        public static Inequality FromUpperBound(Variable var)
        {
            Inequality ineq = new Inequality(new Label(var.Name, var.Name.name + "_hi"),
                                             IneqType.Le, new LinearFunction(var), new LpNumber(var.UBound), false);

            return(ineq);
        }
示例#2
0
        // 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);
            }
        }
示例#3
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);
        }
示例#4
0
            /// <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);
                }
            }
示例#5
0
        /// <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(")");
        }
示例#6
0
        // 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);
            }
        }
示例#7
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)
        {
            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);
        }
示例#8
0
        /// <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);
        }
示例#9
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;
        }
示例#10
0
        /// <summary>
        /// Creates an upper bound inequality for a variable
        /// </summary>
        /// <param name="var"></param>
        /// <returns></returns>
        public static Inequality FromUpperBound(Variable var)
        {
            Inequality ineq = new Inequality(new Label(var.Name, var.Name.name + "_hi"),
                    IneqType.Le, new LinearFunction(var), new LpNumber(var.UBound), false);

            return ineq;
        }
示例#11
0
 /// <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);
 }
示例#12
0
        /// <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();
        }
示例#13
0
        /// <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();
        }
示例#14
0
        /// <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);
        }