check.cpp

Go to the documentation of this file.
00001 /*
00002  * Copyright (C) 2009 Kamil Dudka <xdudka00@stud.fit.vutbr.cz>
00003  *
00004  * This file is part of nucad (Non-Uniform CA Designer).
00005  *
00006  * nucad is free software: you can redistribute it and/or modify
00007  * it under the terms of the GNU General Public License as published by
00008  * the Free Software Foundation, either version 3 of the License, or
00009  * any later version.
00010  *
00011  * nucad is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014  * GNU General Public License for more details.
00015  *
00016  * You should have received a copy of the GNU General Public License
00017  * along with nucad.  If not, see <http://www.gnu.org/licenses/>.
00018  */
00019 
00026 #include "CaDesigner.h"
00027 #include "CaFactory.h"
00028 #include "Color.h"
00029 
00030 #ifndef BUILDING_DOX
00031 #   include <iostream>
00032 #   include <string>
00033 #endif
00034 
00035 #include <getopt.h>
00036 
00037 using std::string;
00038 
00039 // cmd-line option list
00040 static struct option const long_opts[] = {
00041     { "echo",       no_argument,        0, 'e' },
00042     { "input",      required_argument,  0, 'i' },
00043     { "list",       no_argument,        0, 'l' },
00044     { "quiet",      no_argument,        0, 'q' },
00045     { "rules",      no_argument,        0, 'r' },
00046     { "simulate",   no_argument,        0, 's' },
00047     { "help",       no_argument,        0, 'h' },
00048 
00049     // this line avoids SIGSEGV if an invalid long option is given
00050     { NULL, 0, NULL, 0}
00051 };
00052 
00053 namespace {
00059     void usage(const char *name, int status)
00060     {
00061         if (status != EXIT_SUCCESS)
00062             std::cerr << "Try `" << name
00063                 << " --help' for more information." << std::endl;
00064         else
00065             std::cout << "Usage: " << name << " [OPTIONS] CIRCUIT_NAME\n\
00066   -e, --echo                   diagnostic echo for rules\n\
00067   -i, --input=INPUT            simulation for given input\n\
00068   -l, --list                   print circuit list\n\
00069   -q, --quiet                  suppress statistics\n\
00070   -r, --rules                  dump rules in human readable form\n\
00071   -s, --simulate               simulation for all inputs\n\
00072       --help                   print this help to stdout"
00073                 << std::endl;
00074     }
00075 
00081     void writeRules(GaCaRules *rules, size_t caSize, std::ostream &str)
00082     {
00083         for (unsigned row = 0; row < caSize; ++row) {
00084             for (unsigned col = 0; col < caSize; ++col) {
00085                 str << Color(C_LIGHT_PURPLE) << "--- cell ["
00086                     << row << "," << col << "]"
00087                     << Color(C_NO_COLOR) << std::endl;
00088                 TRule5N rule;
00089                 rules->getRuleAtPos(Pos(row, col), rule);
00090                 writeRule(str, rule);
00091             }
00092         }
00093     }
00094 
00095 }
00096 
00097 int main(int argc, char *argv[]) {
00098     // name of executable which is printed on user interaction
00099     static const char *szAppName = argv[0];
00100 
00101     // enable colorized output only if stdout/stderr are connected to terminal
00102     Color::enable(isatty(STDOUT_FILENO) && isatty(STDERR_FILENO));
00103 
00104     // state variables necessary to always delete an existing (if any) evaluator
00105     int ec = 0;
00106     CaEvaluator *evaluator = 0;
00107 
00108     try {
00109         // parameters to be read from cmd-line by getopt_long
00110         bool echo = false;
00111         bool printList = false;
00112         bool quiet = false;
00113         bool dumpRules = false;
00114         bool simOne = false;
00115         bool simAll = false;
00116         TBus in = 0;
00117 
00118         // parse cmd-line arguments
00119         int c;
00120         while ((c = getopt_long (argc, argv, "ei:lqrs", long_opts, 0)) != -1) {
00121             switch (c) {
00122                 case 'e':
00123                     echo = true;
00124                     break;
00125 
00126                 case 'i':
00127                     simOne = true;
00128                     // FIXME: check if the string is really a number
00129                     if (!optarg)
00130                         throw std::runtime_error(
00131                                 "invalid --input (-i) argument");
00132                     // FIXME: avoid using atoi()
00133                     in = atoi(optarg);
00134                     break;
00135 
00136                 case 'l':
00137                     printList = true;
00138                     break;
00139 
00140                 case 'q':
00141                     quiet = true;
00142                     break;
00143 
00144                 case 'r':
00145                     dumpRules = true;
00146                     break;
00147 
00148                 case 's':
00149                     simAll = true;
00150                     break;
00151 
00152                 case 'h':
00153                     // print usage and exit successfully
00154                     usage(argv[0], EXIT_SUCCESS);
00155                     return EXIT_SUCCESS;
00156             }
00157         }
00158 
00159         // check for possible cmd-line arguments conflicts
00160         if (simOne && simAll)
00161             throw std::runtime_error(
00162                     "options -i and -s are mutually exclusive");
00163 
00164         // create factory on stack (to avoid possible memory leak)
00165         CaEvaluatorFactory factory;
00166 
00167         if (printList) {
00168             // print circuit list and exit
00169             factory.printList(std::cout);
00170             return 0;
00171         }
00172 
00173         // read circuit name from cmd-line
00174         argc -= optind;
00175         argv += optind;
00176         if (argc != 1)
00177             throw std::runtime_error("invalid count of arguments");
00178 
00179         // try to create evaluator for desired circuit
00180         // this might fail if circuit name is not valid
00181         evaluator = factory.create(argv[0]);
00182 
00183         // parse data from stdin line after line
00184         string line;
00185         while (getline(std::cin, line)) {
00186             // deserialize non-uniform CA's rules
00187             GaCaRules rules(line);
00188 
00189             // check size of the deserialized CA's
00190             if (rules.size() !=
00191                     evaluator->caSize() * evaluator->caSize() * RULE_WIDTH)
00192                 throw std::runtime_error(
00193                         "GaCaRules size mismatch (not implemented)");
00194 
00195             if (echo)
00196                 // print echo if requested by cmd-line parameter
00197                 std::cout << rules << std::endl;
00198 
00199             if (!quiet) {
00200                 // simulate given CA's rules and print statistics
00201                 unsigned min, max;
00202                 if (evaluator->cntSteps(&rules, min, max)) {
00203                     std::cout << "--- nSteps: <" << min << ", " << max << ">"
00204                         << std::endl;
00205                 } else {
00206                     std::cout << "--- fitness = " << evaluator->eval(&rules)
00207                         << std::endl;
00208                 }
00209             }
00210 
00211             if (dumpRules)
00212                 // write CA's rules in human-readable format
00213                 writeRules(&rules, evaluator->caSize(), std::cout);
00214 
00215             if (simOne)
00216                 // simulate CA for given input value
00217                 evaluator->simulate(&rules, std::cout, in);
00218 
00219             if (simAll)
00220                 // simulate CA for all possible input values
00221                 evaluator->simulate(&rules, std::cout);
00222         }
00223     }
00224     catch (std::runtime_error &e) {
00225         std::cerr << szAppName << ": "
00226             << Color(C_LIGHT_RED) << "error: " << Color(C_NO_COLOR)
00227             << e.what() << std::endl;
00228         ec = 1;
00229     }
00230 
00231     delete evaluator;
00232 
00233     return ec;
00234 }

Generated on Sat May 2 16:39:31 2009 for nucad by  doxygen 1.5.4