evalue_range_propagation: fix substitution for negative variables
[barvinok.git] / barvinok_ehrhart.cc
blobb36194fdf7b71695cf61a4119e6747306927c84c
1 #include <unistd.h>
2 #include <stdlib.h>
3 #include <strings.h>
4 #include <barvinok/util.h>
5 #include <barvinok/barvinok.h>
6 #include "argp.h"
7 #include "progname.h"
8 #include "evalue_convert.h"
10 /* The input of this example program is a polytope in PolyLib notation,
11 * i.e., an n by d+2 matrix of the n constraints A x + b >= 0 defining
12 * the polytope * sitting in a d-dimensional space. The first column
13 * is 1 for an inequality and 0 for an equality. b is placed in the
14 * final column.
15 * Alternatively, if the matrix is preceded by the word "vertices"
16 * on a line by itself, it will be interpreted as a list of vertices
17 * in PolyLib notation, i.e., an n by (d+2) matrix, where n is
18 * the number of vertices/rays and d the dimension. The first column is
19 * 0 for lines and 1 for vertices/rays. The final column is the denominator
20 * or 0 for rays. Note that for barvinok_ehrhart, the first column
21 * should always be 1.
24 struct argp_option argp_options[] = {
25 { "series", 's', 0, 0, "compute rational generating function" },
26 { 0 }
29 struct arguments {
30 int series;
31 struct barvinok_options *barvinok;
32 struct convert_options convert;
35 static error_t parse_opt(int key, char *arg, struct argp_state *state)
37 struct arguments *options = (struct arguments*) state->input;
39 switch (key) {
40 case ARGP_KEY_INIT:
41 state->child_inputs[0] = options->barvinok;
42 state->child_inputs[1] = &options->convert;
43 options->series = 0;
44 break;
45 case 's':
46 options->series = 1;
47 break;
48 default:
49 return ARGP_ERR_UNKNOWN;
51 return 0;
54 int main(int argc, char **argv)
56 Polyhedron *A, *C, *U;
57 const char **param_name;
58 int print_solution = 1;
59 struct arguments options;
60 static struct argp_child argp_children[] = {
61 { &barvinok_argp, 0, 0, 0 },
62 { &convert_argp, 0, "output conversion", BV_GRP_LAST+1 },
63 { 0 }
65 static struct argp argp = { argp_options, parse_opt, 0, 0, argp_children };
66 barvinok_options *bv_options = barvinok_options_new_with_defaults();
68 options.barvinok = bv_options;
69 set_program_name(argv[0]);
70 argp_parse(&argp, argc, argv, 0, 0, &options);
72 A = Polyhedron_Read(bv_options->MaxRays);
73 param_name = Read_ParamNames(stdin, 1);
74 Polyhedron_Print(stdout, P_VALUE_FMT, A);
75 C = Cone_over_Polyhedron(A);
76 U = Universe_Polyhedron(1);
77 if (options.series) {
78 gen_fun *gf;
79 gf = barvinok_series_with_options(C, U, bv_options);
80 gf->print(std::cout, U->Dimension, param_name);
81 puts("");
82 delete gf;
83 } else {
84 evalue *EP;
85 /* A (conceptually) obvious optimization would be to pass in
86 * the parametric vertices, which are just n times the original
87 * vertices, rather than letting barvinok_enumerate_ev (re)compute
88 * them through Polyhedron2Param_SimplifiedDomain.
90 EP = barvinok_enumerate_with_options(C, U, bv_options);
91 assert(EP);
92 if (evalue_convert(EP, &options.convert, bv_options->verbose,
93 C->Dimension, param_name))
94 print_solution = 0;
95 if (print_solution)
96 print_evalue(stdout, EP, param_name);
97 evalue_free(EP);
99 Free_ParamNames(param_name, 1);
100 Polyhedron_Free(A);
101 Polyhedron_Free(C);
102 Polyhedron_Free(U);
103 barvinok_options_free(bv_options);
104 return 0;