1 /*
2 4ti2 -- A software package for algebraic, geometric and combinatorial
3 problems on linear spaces.
4 
5 Copyright (C) 2006 4ti2 team.
6 Main author(s): Peter Malkin.
7 
8 This program is free software; you can redistribute it and/or
9 modify it under the terms of the GNU General Public License
10 as published by the Free Software Foundation; either version 2
11 of the License, or (at your option) any later version.
12 
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
17 
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
21 */
22 
23 #include "WalkOptions.h"
24 #include "Globals.h"
25 #include <iostream>
26 #include <fstream>
27 #include <unistd.h>
28 #include <cstdlib>
29 
30 #if 1  /// we use gnulib, so don't need to test for _GNU_SOURCE
31 #include <getopt.h>
32 #endif
33 
34 using namespace _4ti2_;
35 
36 WalkOptions* WalkOptions::o = new WalkOptions;
37 
WalkOptions()38 WalkOptions::WalkOptions()
39 {
40     output = VERBOSE;
41 }
42 
43 WalkOptions*
instance()44 WalkOptions::instance()
45 {
46     return o;
47 }
48 
49 void
process_options(int argc,char ** argv)50 WalkOptions::process_options(int argc, char** argv)
51 {
52     int c;
53     optind = 1;
54     while (1) {
55 #if 1  /// we use gnulib, so don't need to test for _GNU_SOURCE
56         int option_index = 0;
57         static struct option long_options[] = {
58             {"precision",        1, 0,'p'},
59             {"truncation",       1, 0,'t'},
60             {"output-freq",      1, 0,'f'},
61             {"quiet",            0, 0,'q'},
62 	    {"version",          0, 0,'V'},
63             {"help",             0, 0,'h'},
64             {0, 0, 0, 0}
65         };
66 
67         c = getopt_long (argc, argv, "f:t:p:qh",
68                  long_options, &option_index);
69 #else
70         c = getopt(argc, argv, "f:t:p:qh");
71 #endif
72         if (c == -1)
73             break;
74 
75         switch (c) {
76         case 'f':
77             if (sscanf(optarg, "%d", &Globals::output_freq) != 1)
78             {  unrecognised_option_argument("-f, --output_freq"); }
79             break;
80         case 'q':
81             output = SILENT;
82             out = new std::ofstream;
83             err = new std::ofstream;
84             break;
85         case 't':
86             if (std::string("ip").find(optarg) == 0)
87             { Globals::truncation = Globals::IP; }
88             else if (std::string("lp").find(optarg) == 0)
89             { Globals::truncation = Globals::LP; }
90             else if (std::string("weight").find(optarg) == 0)
91             { Globals::truncation = Globals::WEIGHT; }
92             else if (std::string("none").find(optarg) == 0)
93             { Globals::truncation = Globals::NONE; }
94             else { unrecognised_option_argument("-t, --truncation"); }
95             break;
96         case 'p': // The precision (i.e. int32, int64, or arbitrary)
97             if (std::string("32").find(optarg) == 0) { }
98             else if (std::string("64").find(optarg) == 0) { }
99             else if (std::string("arbitrary").find(optarg) == 0) { }
100             else { unrecognised_option_argument("-p, --precision"); }
101             break;
102 	case 'V':
103 	    print_banner(false);
104 	    exit(0);
105 	    break;
106         case 'h':
107         case '?':
108         case ':':
109             print_usage();
110             exit(0);
111             break;
112 
113         default:
114             std::cerr << "Error: getopt returned unknown character code\n";
115             print_usage();
116             exit(1);
117         }
118     }
119 
120     if (optind == argc-1)
121     {
122         filename = argv[optind];
123     }
124     else
125     {
126         std::cerr << "Command Line Error: Incorrect number of arguments.\n";
127         print_usage();
128         exit(1);
129     }
130 }
131 
132 void
print_usage()133 WalkOptions::print_usage()
134 {
135     std::cout << "Usage: walk [options] PROJECT\n\n";
136     std::cout << "Computes the minimal solution of an integer linear program\n";
137     std::cout << "or, more general, a lattice program using a Groebner basis.\n\n";
138     std::cout << "\
139 Input Files:\n\
140   PROJECT.mat         A matrix (optional only if lattice basis is given).\n\
141   PROJECT.lat         A lattice basis (optional only if matrix is given).\n\
142   PROJECT.gro.start   The starting Groebner basis (needed).\n\
143   PROJECT.gro.cost    The starting cost vector (optional, default is degrevlex).\n\
144                       Ties are broken with degrevlex.\n\
145   PROJECT.cost        The target cost vector (optional, default is degrevlex).\n\
146                       Ties are broken with degrevlex.\n\
147   PROJECT.zsol        An integer solution to specify a fiber (needed).\n\
148   PROJECT.sign        The sign constraints of the variables ('1' means\n\
149                       non-negative and '0' means a free variable).\n\
150                       It is optional, and the default is all non-negative.\n\
151 Output Files:\n\
152   PROJECT.gro         The Groebner basis of the lattice.\n\n";
153     std::cout << "\
154 Options:\n\
155   -p, --precision=PREC       Select PREC as the integer arithmetic precision.\n\
156                              PREC is one of the following: `64' (default),\n\
157                              `32', and `arbitrary' (only `arb` is needed).\n\
158   -t, --truncation=TRUNC     Set TRUNC as the truncation method.  TRUNC is\n\
159                              of the following: `ip', `lp', `weight' (default),\n\
160                              or `none'. Only relevant if `zsol' is given.\n\
161   -f, --output-freq=n        Set the frequency of output (default is 1000).\n\
162   -q, --quiet                Do not output anything to the screen.\n\
163   -h, --help                 Display this help and exit.\n\
164 \n";
165 }
166 
167 void
unrecognised_option_argument(const char * option)168 WalkOptions::unrecognised_option_argument(const char* option)
169 {
170    std::cerr << "4ti2: ";
171    std::cerr << "Unrecognised argument \"" << optarg << "\" ";
172    std::cerr << "for the option " << option << ".\n\n";
173    print_usage();
174    exit(1);
175 }
176