<commit_before>/*
 * $File: main.cc
 * $Date: Tue Dec 10 16:43:56 2013 +0800
 * $Author: Xinyu Zhou <zxytim[at]gmail[dot]com>
 */

#include <cstdio>
#include <fstream>

#include "gmm.hh"

#include "datamanip.hh"
#include "common.hh"

#include "tclap/CmdLine.h"

using namespace std;
using namespace TCLAP;

typedef std::vector<std::vector<real_t>> DenseDataset;

static void svm2vec(const std::vector<std::pair<int, real_t>> &input,
		std::vector<real_t> &output, int dim) {
	output = std::vector<real_t>(dim, 0);
	for (auto &item: input) {
		if (item.first > dim) // ignore out bounded values
			continue;
		output[item.first] = item.second;
	}
}

vector<real_t> string_to_double_vector(string line) {
	vector<real_t> x;
	int begin = 0, end = 0;
	int len = line.size();
	while (true) {
		while (end < len && line[end] != ' ' && line[end] != '\n')
			end ++;
		x.push_back(atof(line.substr(begin, end - begin).c_str()));
		if (end == len - 1 || line[end] == '\n' || (end == len - 2 && line[end] == ' ' && line[end] == '\n'))
			break;
		begin = end + 1;
		end = begin;
	}
	return x;
}

void Dataset2DenseDataset(Dataset &X0, DenseDataset &X1) {
	int n, m;
	get_data_metric(X0, n, m);

	X1.resize(X0.size());
	for (size_t i = 0; i < X0.size(); i ++)
		svm2vec(X0[i], X1[i], m);
}

struct Args {
	int concurrency;
	int K;

	string input_file;
	string output_file;
};

Args parse_args(int argc, char *argv[]) {
	Args args;
	try {
		CmdLine cmd("Gaussian Mixture Model (GMM)", ' ', "0.0.1");

		ValueArg<int> arg_concurrency("w", "concurrency", "number of workers", false, 1, "NUMBER");
		ValueArg<int> arg_K("k", "K", "number of gaussians", true, 10, "NUMBER");

		ValueArg<string> arg_input_file("i", "input", "intput file", true, "", "FILE");
		ValueArg<string> arg_output_file("o", "output", "intput file", true, "", "FILE");

		cmd.add(arg_concurrency);
		cmd.add(arg_K);
		cmd.add(arg_input_file);
		cmd.add(arg_output_file);

		cmd.parse(argc, argv);

#define GET_VALUE(name) args.name = arg_##name.getValue();
		GET_VALUE(concurrency);
		GET_VALUE(K);
		GET_VALUE(input_file);
		GET_VALUE(output_file);

	} catch (ArgException &e) {
		cerr << "error: " << e.error() << " for arg " << e.argId() << endl;
	}
	return args;
}

void read_dense_dataset(DenseDataset &X, const char *fname) {
	ifstream fin(fname);
	string line;
	while (getline(fin, line)) {
		X.push_back(string_to_double_vector(line));
	}
}

void write_dense_dataset(DenseDataset &X, const char *fname) {
	ofstream fout(fname);
	for (auto &x: X) {
		for (auto &v: x)
			fout << v << ' ';
		fout << endl;
	}
}

void fill_gaussian(DenseDataset &X, Gaussian *gaussian, int nr_point) {
	for (int i = 0; i < nr_point; i ++)
		X.push_back(gaussian->sample());
}

static vector<real_t> random_vector(int dim, real_t range, Random &random) {
	vector<real_t> vec(dim);
	for (auto &v: vec) v = random.rand_real() * range;
	return vec;
}

void gen_high_dim_gaussian_mixture(DenseDataset &X, int dim, int nr_gaussian, int nr_point_per_gaussian) {
	Random random;
	for (int i = 0; i < nr_gaussian; i ++) {
		Gaussian g(dim);
		g.mean = random_vector(dim, 1, random);
		g.sigma = random_vector(dim, 0.05 + random.rand_real() * 0.1, random);
		fill_gaussian(X, &g, nr_point_per_gaussian);
	}
}

void gen_gaussian_mixture(DenseDataset &X, int nr_point_per_gaussian = 1000) {
	int nr_gaussian = 3;
	Gaussian g0(2);
	g0.mean = {0, 0};
	g0.sigma = {0.1, 0.1};

	Gaussian g1(2);
	g1.mean = {1, 1};
	g1.sigma = {0.1, 0.1};

	Gaussian g2(2);
	g2.mean = {2, 1};
	g2.sigma = {0.2, 0.2};

	fill_gaussian(X, &g0, nr_point_per_gaussian);
	fill_gaussian(X, &g1, nr_point_per_gaussian);
	fill_gaussian(X, &g2, nr_point_per_gaussian);
}

int main(int argc, char *argv[]) {
	srand(42); // Answer to The Ultimate Question of Life, the Universe, and Everything
//    Args args = parse_args(argc, argv);

	DenseDataset X;
//    read_dense_dataset(X, "test.data");
	gen_gaussian_mixture(X, 100);
//    gen_high_dim_gaussian_mixture(X, 13, 10, 68000);

	write_dense_dataset(X, "test.data");

	int concurrency = 4;
	int nr_mixture = 3;

	GMMTrainerBaseline trainer(1, 1e-3, concurrency);
	GMM gmm(nr_mixture, COVTYPE_DIAGONAL, &trainer);
	printf("start training ...\n"); fflush(stdout);
	gmm.fit(X);

	ofstream fout("gmm-test.model");
	gmm.dump(fout);

	return 0;
}

/**
 * vim: syntax=cpp11 foldmethod=marker
 */

<commit_msg>add commandline support<commit_after>/*
 * $File: main.cc
 * $Date: Tue Dec 10 18:20:51 2013 +0800
 * $Author: Xinyu Zhou <zxytim[at]gmail[dot]com>
 */

#include <cstdio>
#include <fstream>

#include "gmm.hh"

#include "datamanip.hh"
#include "common.hh"

#include "tclap/CmdLine.h"

using namespace std;
using namespace TCLAP;

typedef std::vector<std::vector<real_t>> DenseDataset;

vector<real_t> string_to_double_vector(string line) {
	vector<real_t> x;
	int begin = 0, end = 0;
	int len = line.size();
	while (true) {
		while (end < len && line[end] != ' ' && line[end] != '\n')
			end ++;
		x.push_back(atof(line.substr(begin, end - begin).c_str()));
		if (end == len - 1 || line[end] == '\n' || (end == len - 2 && line[end] == ' ' && line[end] == '\n'))
			break;
		begin = end + 1;
		end = begin;
	}
	return x;
}

struct Args {
	int concurrency;
	int K;
	int iteration;
	real_t min_covar = 1e-3;

	string input_file;
	string model_file;
};

Args parse_args(int argc, char *argv[]) {
	Args args;
	try {
		CmdLine cmd("Gaussian Mixture Model (GMM)", ' ', "0.0.1");

		ValueArg<int> arg_concurrency("w", "concurrency", "number of workers", false, 1, "NUMBER");
		ValueArg<int> arg_K("k", "K", "number of gaussians", true, 10, "NUMBER");
		ValueArg<double> arg_min_covar("c", "mincovar", "minimum covariance to avoid overfitting, default 1e-3.", false, 1e-3, "FLOAT");

		ValueArg<string> arg_input_file("i", "input", "intput file", true, "", "FILE");
		ValueArg<string> arg_model_file("m", "model", "model file", true, "", "FILE");
		ValueArg<int> arg_iteration("r", "iteration", "number of iterations",
				false, 200, "NUMBER");

		cmd.add(arg_concurrency);
		cmd.add(arg_K);
		cmd.add(arg_min_covar);
		cmd.add(arg_input_file);
		cmd.add(arg_model_file);
		cmd.add(arg_iteration);

		cmd.parse(argc, argv);

#define GET_VALUE(name) args.name = arg_##name.getValue();
		GET_VALUE(concurrency);
		GET_VALUE(K);
		GET_VALUE(min_covar);
		GET_VALUE(input_file);
		GET_VALUE(model_file);
		GET_VALUE(iteration);

	} catch (ArgException &e) {
		cerr << "error: " << e.error() << " for arg " << e.argId() << endl;
	}
	return args;
}

void read_dense_dataset(DenseDataset &X, const char *fname) {
	ifstream fin(fname);
	string line;
	while (getline(fin, line)) {
		X.push_back(string_to_double_vector(line));
	}
}

void write_dense_dataset(DenseDataset &X, const char *fname) {
	ofstream fout(fname);
	for (auto &x: X) {
		for (auto &v: x)
			fout << v << ' ';
		fout << endl;
	}
}

int main(int argc, char *argv[]) {
//    srand(42); // Answer to The Ultimate Question of Life, the Universe, and Everything
	Args args = parse_args(argc, argv);

	DenseDataset X;
	read_dense_dataset(X, args.input_file.c_str());

	GMMTrainerBaseline trainer(args.iteration, args.min_covar, args.concurrency);
	GMM gmm(args.K, COVTYPE_DIAGONAL, &trainer);
	printf("start training ...\n"); fflush(stdout);
	gmm.fit(X);

	ofstream fout(args.model_file);
	gmm.dump(fout);

	return 0;
}

/**
 * vim: syntax=cpp11 foldmethod=marker
 */

<|endoftext|>


<commit_before>//! \file
/*
**  Copyright (C) - Triton
**
**  This program is under the terms of the Apache License 2.0.
*/

#include <string>

#include <triton/astContext.hpp>
#include <triton/exceptions.hpp>
#include <triton/solverModel.hpp>
#include <triton/symbolicVariable.hpp>
#include <triton/tritonToZ3Ast.hpp>
#include <triton/tritonTypes.hpp>
#include <triton/z3Solver.hpp>
#include <triton/z3ToTritonAst.hpp>

namespace triton {
  namespace engines {
    namespace solver {

      //! Wrapper to handle variadict number of arguments or'd togethers
      z3::expr mk_or(z3::expr_vector args) {
        std::vector<Z3_ast> array;

        for (triton::uint32 i = 0; i < args.size(); i++)
          array.push_back(args[i]);

        return to_expr(args.ctx(), Z3_mk_or(args.ctx(), static_cast<triton::uint32>(array.size()), &(array[0])));
      }

      Z3Solver::Z3Solver() {
        this->timeout = 0;
        this->memoryLimit = 0;
      }

      std::vector<std::unordered_map<triton::usize, SolverModel>> Z3Solver::getModels(const triton::ast::SharedAbstractNode& node, triton::uint32 limit, triton::engines::solver::status_e* status, triton::uint32 timeout) const {
        std::vector<std::unordered_map<triton::usize, SolverModel>> ret;
        triton::ast::SharedAbstractNode onode = node;
        triton::ast::TritonToZ3Ast z3Ast{false};

        try {
          if (onode == nullptr)
            throw triton::exceptions::SolverEngine("Z3Solver::getModels(): node cannot be null.");

          /* Z3 does not need an assert() as root node */
          if (node->getType() == triton::ast::ASSERT_NODE)
            onode = node->getChildren()[0];

          if (onode->isLogical() == false)
            throw triton::exceptions::SolverEngine("Z3Solver::getModels(): Must be a logical node.");

          z3::expr      expr = z3Ast.convert(onode);
          z3::context&  ctx  = expr.ctx();
          z3::solver    solver(ctx);

          /* Create a solver and add the expression */
          solver.add(expr);

          z3::params p(ctx);

          /* Define the timeout */
          if (timeout) {
            p.set(":timeout", timeout);
          }
          else if (this->timeout) {
            p.set(":timeout", this->timeout);
          }

          /* Define memory limit */
          if (this->memoryLimit) {
            p.set(":max_memory", this->memoryLimit);
          }

          solver.set(p);

          /* Get first model */
          z3::check_result res = solver.check();

          /* Write back the status code of the first constraint */
          this->writeBackStatus(solver, res, status);

          /* Check if it is sat */
          for (; res == z3::sat && limit >= 1; res = solver.check()) {

            /* Get model */
            z3::model m = solver.get_model();

            /* Traversing the model */
            std::unordered_map<triton::usize, SolverModel> smodel;
            z3::expr_vector args(ctx);
            for (triton::uint32 i = 0; i < m.size(); i++) {

              /* Get the z3 variable */
              z3::func_decl z3Variable = m[i];

              /* Get the name as std::string from a z3 variable */
              std::string varName = z3Variable.name().str();

              /* Get z3 expr */
              z3::expr exp = m.get_const_interp(z3Variable);

              /* Get the size of a z3 expr */
              triton::uint32 bvSize = exp.get_sort().bv_size();

              /* Get the value of a z3 expr */
              std::string svalue = Z3_get_numeral_string(ctx, exp);

              /* Convert a string value to a integer value */
              triton::uint512 value = triton::uint512(svalue);

              /* Create a triton model */
              SolverModel trionModel = SolverModel(z3Ast.variables[varName], value);

              /* Map the result */
              smodel[trionModel.getId()] = trionModel;

              /* Uniq result */
              if (exp.get_sort().is_bv())
                args.push_back(ctx.bv_const(varName.c_str(), bvSize) != ctx.bv_val(svalue.c_str(), bvSize));

            }

            /* Escape last models */
            solver.add(triton::engines::solver::mk_or(args));

            /* If there is model available */
            if (smodel.size() > 0)
              ret.push_back(smodel);

            /* Decrement the limit */
            limit--;
          }
        }
        catch (const z3::exception& e) {
          if (!strcmp(e.msg(), "max. memory exceeded")) {
            if (status) {
              *status = triton::engines::solver::OUTOFMEM;
            }
            return {};
          }
          throw triton::exceptions::SolverEngine(std::string("Z3Solver::getModels(): ") + e.msg());
        }

        return ret;
      }

      bool Z3Solver::isSat(const triton::ast::SharedAbstractNode& node, triton::engines::solver::status_e* status, triton::uint32 timeout) const {
        triton::ast::TritonToZ3Ast z3Ast{false};

        if (node == nullptr)
          throw triton::exceptions::SolverEngine("Z3Solver::isSat(): node cannot be null.");

        if (node->isLogical() == false)
          throw triton::exceptions::SolverEngine("Z3Solver::isSat(): Must be a logical node.");

        try {
          z3::expr      expr = z3Ast.convert(node);
          z3::context&  ctx  = expr.ctx();
          z3::solver    solver(ctx);

          /* Create a solver and add the expression */
          solver.add(expr);

          z3::params p(ctx);

          /* Define the timeout */
          if (timeout) {
            p.set(":timeout", timeout);
          }
          else if (this->timeout) {
            p.set(":timeout", this->timeout);
          }

          /* Define memory limit */
          if (this->memoryLimit) {
            p.set(":max_memory", this->memoryLimit);
          }

          solver.set(p);

          z3::check_result res = solver.check();
          this->writeBackStatus(solver, res, status);
          return res == z3::sat;
        }
        catch (const z3::exception& e) {
          if (!strcmp(e.msg(), "max. memory exceeded")) {
            if (status) {
              *status = triton::engines::solver::OUTOFMEM;
            }
            return {};
          }
          throw triton::exceptions::SolverEngine(std::string("Z3Solver::isSat(): ") + e.msg());
        }
      }

      std::unordered_map<triton::usize, SolverModel> Z3Solver::getModel(const triton::ast::SharedAbstractNode& node, triton::engines::solver::status_e* status, triton::uint32 timeout) const {
        std::unordered_map<triton::usize, SolverModel> ret;
        std::vector<std::unordered_map<triton::usize, SolverModel>> allModels;

        allModels = this->getModels(node, 1, status, timeout);
        if (allModels.size() > 0)
          ret = allModels.front();

        return ret;
      }

      triton::ast::SharedAbstractNode Z3Solver::simplify(const triton::ast::SharedAbstractNode& node) const {
        if (node == nullptr)
          throw triton::exceptions::AstTranslations("Z3Solver::simplify(): node cannot be null.");

        try {
          triton::ast::TritonToZ3Ast z3Ast{false};
          triton::ast::Z3ToTritonAst tritonAst{node->getContext()};

          /* From Triton to Z3 */
          z3::expr expr = z3Ast.convert(node);

          /* Simplify and back to Triton's AST */
          auto snode = tritonAst.convert(expr.simplify());

          return snode;
        }
        catch (const z3::exception& e) {
          throw triton::exceptions::AstTranslations(std::string("Z3Solver::evaluate(): ") + e.msg());
        }
      }

      triton::uint512 Z3Solver::evaluate(const triton::ast::SharedAbstractNode& node) const {
        if (node == nullptr)
          throw triton::exceptions::AstTranslations("Z3Solver::simplify(): node cannot be null.");

        try {
          triton::ast::TritonToZ3Ast z3ast{true};

          /* From Triton to Z3 */
          z3::expr expr = z3ast.convert(node);

          /* Simplify the expression to get a constant */
          expr = expr.simplify();

          triton::uint512 res = 0;
          if (expr.get_sort().is_bool())
            res = Z3_get_bool_value(expr.ctx(), expr) == Z3_L_TRUE ? true : false;
          else
            res = triton::uint512{Z3_get_numeral_string(expr.ctx(), expr)};

          return res;
        }
        catch (const z3::exception& e) {
          throw triton::exceptions::AstTranslations(std::string("Z3Solver::evaluate(): ") + e.msg());
        }
      }

      void Z3Solver::writeBackStatus(z3::solver& solver, z3::check_result res, triton::engines::solver::status_e* status) const {
        if (status != nullptr) {
          switch (res) {
            case z3::sat:
              *status = triton::engines::solver::SAT;
              break;

            case z3::unsat:
              *status = triton::engines::solver::UNSAT;
              break;

            case z3::unknown:
              if (solver.reason_unknown() == "timeout") {
                *status = triton::engines::solver::TIMEOUT;
              }
              else if (solver.reason_unknown() == "max. memory exceeded")
              {
                *status = triton::engines::solver::OUTOFMEM;
              }
              else {
                *status = triton::engines::solver::UNKNOWN;
              }
              break;
          }
        }
      }

      std::string Z3Solver::getName(void) const {
        return "z3";
      }

      void Z3Solver::setTimeout(triton::uint32 ms) {
        this->timeout = ms;
      }

      void Z3Solver::setMemoryLimit(triton::uint32 limit) {
        this->memoryLimit = limit;
      }

    };
  };
};
<commit_msg>Fix double z3 solver check call<commit_after>//! \file
/*
**  Copyright (C) - Triton
**
**  This program is under the terms of the Apache License 2.0.
*/

#include <string>

#include <triton/astContext.hpp>
#include <triton/exceptions.hpp>
#include <triton/solverModel.hpp>
#include <triton/symbolicVariable.hpp>
#include <triton/tritonToZ3Ast.hpp>
#include <triton/tritonTypes.hpp>
#include <triton/z3Solver.hpp>
#include <triton/z3ToTritonAst.hpp>

namespace triton {
  namespace engines {
    namespace solver {

      //! Wrapper to handle variadict number of arguments or'd togethers
      z3::expr mk_or(z3::expr_vector args) {
        std::vector<Z3_ast> array;

        for (triton::uint32 i = 0; i < args.size(); i++)
          array.push_back(args[i]);

        return to_expr(args.ctx(), Z3_mk_or(args.ctx(), static_cast<triton::uint32>(array.size()), &(array[0])));
      }

      Z3Solver::Z3Solver() {
        this->timeout = 0;
        this->memoryLimit = 0;
      }

      std::vector<std::unordered_map<triton::usize, SolverModel>> Z3Solver::getModels(const triton::ast::SharedAbstractNode& node, triton::uint32 limit, triton::engines::solver::status_e* status, triton::uint32 timeout) const {
        std::vector<std::unordered_map<triton::usize, SolverModel>> ret;
        triton::ast::SharedAbstractNode onode = node;
        triton::ast::TritonToZ3Ast z3Ast{false};

        try {
          if (onode == nullptr)
            throw triton::exceptions::SolverEngine("Z3Solver::getModels(): node cannot be null.");

          /* Z3 does not need an assert() as root node */
          if (node->getType() == triton::ast::ASSERT_NODE)
            onode = node->getChildren()[0];

          if (onode->isLogical() == false)
            throw triton::exceptions::SolverEngine("Z3Solver::getModels(): Must be a logical node.");

          z3::expr      expr = z3Ast.convert(onode);
          z3::context&  ctx  = expr.ctx();
          z3::solver    solver(ctx);

          /* Create a solver and add the expression */
          solver.add(expr);

          z3::params p(ctx);

          /* Define the timeout */
          if (timeout) {
            p.set(":timeout", timeout);
          }
          else if (this->timeout) {
            p.set(":timeout", this->timeout);
          }

          /* Define memory limit */
          if (this->memoryLimit) {
            p.set(":max_memory", this->memoryLimit);
          }

          solver.set(p);

          /* Get first model */
          z3::check_result res = solver.check();

          /* Write back the status code of the first constraint */
          this->writeBackStatus(solver, res, status);

          /* Check if it is sat */
          while (res == z3::sat && limit >= 1) {
            /* Get model */
            z3::model m = solver.get_model();

            /* Traversing the model */
            std::unordered_map<triton::usize, SolverModel> smodel;
            z3::expr_vector args(ctx);
            for (triton::uint32 i = 0; i < m.size(); i++) {

              /* Get the z3 variable */
              z3::func_decl z3Variable = m[i];

              /* Get the name as std::string from a z3 variable */
              std::string varName = z3Variable.name().str();

              /* Get z3 expr */
              z3::expr exp = m.get_const_interp(z3Variable);

              /* Get the size of a z3 expr */
              triton::uint32 bvSize = exp.get_sort().bv_size();

              /* Get the value of a z3 expr */
              std::string svalue = Z3_get_numeral_string(ctx, exp);

              /* Convert a string value to a integer value */
              triton::uint512 value = triton::uint512(svalue);

              /* Create a triton model */
              SolverModel trionModel = SolverModel(z3Ast.variables[varName], value);

              /* Map the result */
              smodel[trionModel.getId()] = trionModel;

              /* Uniq result */
              if (exp.get_sort().is_bv())
                args.push_back(ctx.bv_const(varName.c_str(), bvSize) != ctx.bv_val(svalue.c_str(), bvSize));
            }

            /* Check that model is available */
            if (smodel.empty())
              break;

            /* Push model */
            ret.push_back(smodel);

            if (--limit) {
              /* Escape last models */
              solver.add(triton::engines::solver::mk_or(args));

              /* Get next model */
              res = solver.check();
            }
          }
        }
        catch (const z3::exception& e) {
          if (!strcmp(e.msg(), "max. memory exceeded")) {
            if (status) {
              *status = triton::engines::solver::OUTOFMEM;
            }
            return {};
          }
          throw triton::exceptions::SolverEngine(std::string("Z3Solver::getModels(): ") + e.msg());
        }

        return ret;
      }

      bool Z3Solver::isSat(const triton::ast::SharedAbstractNode& node, triton::engines::solver::status_e* status, triton::uint32 timeout) const {
        triton::ast::TritonToZ3Ast z3Ast{false};

        if (node == nullptr)
          throw triton::exceptions::SolverEngine("Z3Solver::isSat(): node cannot be null.");

        if (node->isLogical() == false)
          throw triton::exceptions::SolverEngine("Z3Solver::isSat(): Must be a logical node.");

        try {
          z3::expr      expr = z3Ast.convert(node);
          z3::context&  ctx  = expr.ctx();
          z3::solver    solver(ctx);

          /* Create a solver and add the expression */
          solver.add(expr);

          z3::params p(ctx);

          /* Define the timeout */
          if (timeout) {
            p.set(":timeout", timeout);
          }
          else if (this->timeout) {
            p.set(":timeout", this->timeout);
          }

          /* Define memory limit */
          if (this->memoryLimit) {
            p.set(":max_memory", this->memoryLimit);
          }

          solver.set(p);

          z3::check_result res = solver.check();
          this->writeBackStatus(solver, res, status);
          return res == z3::sat;
        }
        catch (const z3::exception& e) {
          if (!strcmp(e.msg(), "max. memory exceeded")) {
            if (status) {
              *status = triton::engines::solver::OUTOFMEM;
            }
            return {};
          }
          throw triton::exceptions::SolverEngine(std::string("Z3Solver::isSat(): ") + e.msg());
        }
      }

      std::unordered_map<triton::usize, SolverModel> Z3Solver::getModel(const triton::ast::SharedAbstractNode& node, triton::engines::solver::status_e* status, triton::uint32 timeout) const {
        std::unordered_map<triton::usize, SolverModel> ret;
        std::vector<std::unordered_map<triton::usize, SolverModel>> allModels;

        allModels = this->getModels(node, 1, status, timeout);
        if (allModels.size() > 0)
          ret = allModels.front();

        return ret;
      }

      triton::ast::SharedAbstractNode Z3Solver::simplify(const triton::ast::SharedAbstractNode& node) const {
        if (node == nullptr)
          throw triton::exceptions::AstTranslations("Z3Solver::simplify(): node cannot be null.");

        try {
          triton::ast::TritonToZ3Ast z3Ast{false};
          triton::ast::Z3ToTritonAst tritonAst{node->getContext()};

          /* From Triton to Z3 */
          z3::expr expr = z3Ast.convert(node);

          /* Simplify and back to Triton's AST */
          auto snode = tritonAst.convert(expr.simplify());

          return snode;
        }
        catch (const z3::exception& e) {
          throw triton::exceptions::AstTranslations(std::string("Z3Solver::evaluate(): ") + e.msg());
        }
      }

      triton::uint512 Z3Solver::evaluate(const triton::ast::SharedAbstractNode& node) const {
        if (node == nullptr)
          throw triton::exceptions::AstTranslations("Z3Solver::simplify(): node cannot be null.");

        try {
          triton::ast::TritonToZ3Ast z3ast{true};

          /* From Triton to Z3 */
          z3::expr expr = z3ast.convert(node);

          /* Simplify the expression to get a constant */
          expr = expr.simplify();

          triton::uint512 res = 0;
          if (expr.get_sort().is_bool())
            res = Z3_get_bool_value(expr.ctx(), expr) == Z3_L_TRUE ? true : false;
          else
            res = triton::uint512{Z3_get_numeral_string(expr.ctx(), expr)};

          return res;
        }
        catch (const z3::exception& e) {
          throw triton::exceptions::AstTranslations(std::string("Z3Solver::evaluate(): ") + e.msg());
        }
      }

      void Z3Solver::writeBackStatus(z3::solver& solver, z3::check_result res, triton::engines::solver::status_e* status) const {
        if (status != nullptr) {
          switch (res) {
            case z3::sat:
              *status = triton::engines::solver::SAT;
              break;

            case z3::unsat:
              *status = triton::engines::solver::UNSAT;
              break;

            case z3::unknown:
              if (solver.reason_unknown() == "timeout") {
                *status = triton::engines::solver::TIMEOUT;
              }
              else if (solver.reason_unknown() == "max. memory exceeded")
              {
                *status = triton::engines::solver::OUTOFMEM;
              }
              else {
                *status = triton::engines::solver::UNKNOWN;
              }
              break;
          }
        }
      }

      std::string Z3Solver::getName(void) const {
        return "z3";
      }

      void Z3Solver::setTimeout(triton::uint32 ms) {
        this->timeout = ms;
      }

      void Z3Solver::setMemoryLimit(triton::uint32 limit) {
        this->memoryLimit = limit;
      }

    };
  };
};
<|endoftext|>


<commit_before>// Copyright (C) 2013 Jérôme Leclercq
// This file is part of the "Nazara Engine - Graphics module"
// For conditions of distribution and use, see copyright notice in Config.hpp

#include <Nazara/Graphics/Loaders/Mesh.hpp>
#include <Nazara/Graphics/Model.hpp>
#include <Nazara/Renderer/Material.hpp>
#include <Nazara/Utility/Mesh.hpp>
#include <memory>
#include <Nazara/Graphics/Debug.hpp>

namespace
{
	nzTernary Check(NzInputStream& stream, const NzModelParameters& parameters)
	{
		NazaraUnused(stream);
		NazaraUnused(parameters);

		return nzTernary_Unknown;
	}

	bool Load(NzModel* model, NzInputStream& stream, const NzModelParameters& parameters)
	{
		NazaraUnused(parameters);

		std::unique_ptr<NzMesh> mesh(new NzMesh);
		mesh->SetPersistent(false);
		if (!mesh->LoadFromStream(stream))
		{
			NazaraError("Failed to load model mesh");
			return false;
		}

		// Nous ne pouvons plus avoir recours au smart pointeur à partir d'ici si nous voulons être exception-safe
		NzMesh* meshPtr = mesh.get();

		model->Reset();
		model->SetMesh(meshPtr);
		mesh.release();

		if (parameters.loadAnimation && meshPtr->IsAnimable())
		{
			NzString animationPath = meshPtr->GetAnimation();
			if (!animationPath.IsEmpty())
			{
				std::unique_ptr<NzAnimation> animation(new NzAnimation);
				animation->SetPersistent(false);
				if (animation->LoadFromFile(animationPath, parameters.animation) && model->SetAnimation(animation.get()))
					animation.release();
				else
					NazaraWarning("Failed to load animation");
			}
		}

		if (parameters.loadMaterials)
		{
			unsigned int matCount = model->GetMaterialCount();

			for (unsigned int i = 0; i < matCount; ++i)
			{
				NzString mat = meshPtr->GetMaterial(i);
				if (!mat.IsEmpty())
				{
					std::unique_ptr<NzMaterial> material(new NzMaterial);
					material->SetPersistent(false);
					if (material->LoadFromFile(mat, parameters.material))
					{
						model->SetMaterial(i, material.get());
						material.release();
					}
					else
						NazaraWarning("Failed to load material #" + NzString::Number(i));
				}
			}
		}

		return true;
	}
}

void NzLoaders_Mesh_Register()
{
	NzModelLoader::RegisterLoader(NzMeshLoader::IsExtensionSupported, Check, Load);
}

void NzLoaders_Mesh_Unregister()
{
	NzModelLoader::UnregisterLoader(NzMeshLoader::IsExtensionSupported, Check, Load);
}
<commit_msg>Fixed Model "Mesh" loader not using mesh parameters<commit_after>// Copyright (C) 2013 Jérôme Leclercq
// This file is part of the "Nazara Engine - Graphics module"
// For conditions of distribution and use, see copyright notice in Config.hpp

#include <Nazara/Graphics/Loaders/Mesh.hpp>
#include <Nazara/Graphics/Model.hpp>
#include <Nazara/Renderer/Material.hpp>
#include <Nazara/Utility/Mesh.hpp>
#include <memory>
#include <Nazara/Graphics/Debug.hpp>

namespace
{
	nzTernary Check(NzInputStream& stream, const NzModelParameters& parameters)
	{
		NazaraUnused(stream);
		NazaraUnused(parameters);

		return nzTernary_Unknown;
	}

	bool Load(NzModel* model, NzInputStream& stream, const NzModelParameters& parameters)
	{
		NazaraUnused(parameters);

		std::unique_ptr<NzMesh> mesh(new NzMesh);
		mesh->SetPersistent(false);
		if (!mesh->LoadFromStream(stream, parameters.mesh))
		{
			NazaraError("Failed to load model mesh");
			return false;
		}

		// Nous ne pouvons plus avoir recours au smart pointeur à partir d'ici si nous voulons être exception-safe
		NzMesh* meshPtr = mesh.get();

		model->Reset();
		model->SetMesh(meshPtr);
		mesh.release();

		if (parameters.loadAnimation && meshPtr->IsAnimable())
		{
			NzString animationPath = meshPtr->GetAnimation();
			if (!animationPath.IsEmpty())
			{
				std::unique_ptr<NzAnimation> animation(new NzAnimation);
				animation->SetPersistent(false);
				if (animation->LoadFromFile(animationPath, parameters.animation) && model->SetAnimation(animation.get()))
					animation.release();
				else
					NazaraWarning("Failed to load animation");
			}
		}

		if (parameters.loadMaterials)
		{
			unsigned int matCount = model->GetMaterialCount();

			for (unsigned int i = 0; i < matCount; ++i)
			{
				NzString mat = meshPtr->GetMaterial(i);
				if (!mat.IsEmpty())
				{
					std::unique_ptr<NzMaterial> material(new NzMaterial);
					material->SetPersistent(false);
					if (material->LoadFromFile(mat, parameters.material))
					{
						model->SetMaterial(i, material.get());
						material.release();
					}
					else
						NazaraWarning("Failed to load material #" + NzString::Number(i));
				}
			}
		}

		return true;
	}
}

void NzLoaders_Mesh_Register()
{
	NzModelLoader::RegisterLoader(NzMeshLoader::IsExtensionSupported, Check, Load);
}

void NzLoaders_Mesh_Unregister()
{
	NzModelLoader::UnregisterLoader(NzMeshLoader::IsExtensionSupported, Check, Load);
}
<|endoftext|>


<commit_before>#include <fstream>
#include <iomanip>
#include <iostream>
#include <memory>
#include <sstream>
#include <tuple>
#include <vector>

#include <openssl/sha.h>

#include <ecdsa/base58.h>
#include <ecdsa/key.h>

#include "args.h"
#include "btcaddr.h"
#include "btcwif.h"

#define BUFF_SIZE 1024

/**
 * Show help document.
 *
 * @param args The argument manager
 */
void ShowHelp(const Args &args) {
  std::cout << "BTCAddr(ess)Gen(erator)" << std::endl
            << "  An easy to use Bitcoin Address offline generator."
            << std::endl
            << std::endl;
  std::cout << "Usage:" << std::endl;
  std::cout << "  ./btcaddrgen [arguments...]" << std::endl << std::endl;
  std::cout << "Arguments:" << std::endl;
  std::cout << args.GetArgsHelpString() << std::endl;
}

std::tuple<std::vector<uint8_t>, bool> HashFile(const std::string &path) {
  std::vector<uint8_t> md;

  std::ifstream input(path, std::ios::binary);
  if (!input.is_open()) {
    std::cerr << "Cannot open file " << path << std::endl;
    return std::make_tuple(md, false);
  }

  // Hash file contents
  SHA512_CTX ctx;
  SHA512_Init(&ctx);

  // Reading...
  char buff[BUFF_SIZE];
  while (!input.eof()) {
    input.read(buff, BUFF_SIZE);
    size_t buff_size = input.gcount();
    SHA512_Update(&ctx, buff, buff_size);
  }

  // Get md buffer.
  md.resize(SHA512_DIGEST_LENGTH);
  SHA512_Final(md.data(), &ctx);

  return std::make_tuple(md, true);
}

std::tuple<std::vector<uint8_t>, bool> Signing(std::shared_ptr<ecdsa::Key> pkey,
                                               const std::string &path) {
  std::vector<uint8_t> signature;

  std::vector<uint8_t> md;
  bool succ;
  std::tie(md, succ) = HashFile(path);
  if (!succ) {
    return std::make_tuple(signature, false);
  }

  std::tie(signature, succ) = pkey->Sign(md);
  if (!succ) {
    std::cerr << "Cannot signing file!" << std::endl;
    return std::make_tuple(signature, false);
  }

  return std::make_tuple(signature, true);
}

bool Verifying(const ecdsa::PubKey &pub_key, const std::string &path,
               const std::vector<uint8_t> &signature) {
  std::vector<uint8_t> md;
  bool succ;
  std::tie(md, succ) = HashFile(path);
  if (succ) {
    return pub_key.Verify(md, signature);
  }
  return false;
}

std::string BinaryToHexString(const unsigned char *bin_data, size_t size) {
  std::stringstream ss_hex;
  for (unsigned int i = 0; i < size; ++i) {
    ss_hex << std::hex << std::setw(2) << std::setfill('0')
           << static_cast<int>(bin_data[i]);
  }
  return ss_hex.str();
}

void ShowKeyInfo(std::shared_ptr<ecdsa::Key> pkey, unsigned char prefix_char) {
  auto pub_key = pkey->CreatePubKey();
  unsigned char hash160[20];
  auto addr = btc::Address::FromPublicKey(pub_key.get_pub_key_data(),
                                          prefix_char, hash160);
  std::cout << "Address: " << addr.ToString() << std::endl;
  std::cout << "Hash160: " << BinaryToHexString(hash160, 20) << std::endl;
  std::cout << "Public key: " << base58::EncodeBase58(pkey->get_pub_key_data())
            << std::endl;
  std::cout << "Private key: "
            << base58::EncodeBase58(pkey->get_priv_key_data()) << std::endl;
  std::cout << "Private key(WIF): "
            << btc::wif::PrivateKeyToWif(pkey->get_priv_key_data())
            << std::endl;
}

/// Main program.
int main(int argc, const char *argv[]) {
  try {
    Args args(argc, argv);
    if (args.is_help()) {
      ShowHelp(args);
      return 0;
    }

    if (args.is_generate_new_key()) {
      ShowKeyInfo(std::make_shared<ecdsa::Key>(), args.get_prefix_char());
      return 0;
    }

    // Import key.
    std::shared_ptr<ecdsa::Key> pkey;
    std::string priv_key_b58 = args.get_import_priv_key();
    if (!priv_key_b58.empty()) {
      std::vector<uint8_t> priv_key;
      // Checking WIF format.
      if (btc::wif::VerifyWifString(priv_key_b58)) {
        // Decoding private key in WIF format.
        priv_key = btc::wif::WifToPrivateKey(priv_key_b58);
      } else {
        // Decoding private key in plain base58 data.
        bool succ = base58::DecodeBase58(priv_key_b58.c_str(), priv_key);
        if (!succ) {
          std::cerr << "Failed to decode base58!" << std::endl;
          return 1;
        }
      }
      pkey = std::make_shared<ecdsa::Key>(priv_key);
      ShowKeyInfo(pkey, args.get_prefix_char());
    }

    // Signing file?
    if (!args.get_signing_file().empty()) {
      if (pkey == nullptr) {
        pkey = std::make_shared<ecdsa::Key>();
        ShowKeyInfo(pkey, args.get_prefix_char());
      }
      std::vector<uint8_t> signature;
      bool succ;
      std::tie(signature, succ) = Signing(pkey, args.get_signing_file());
      if (succ) {
        std::string signature_b58 = base58::EncodeBase58(signature);
        std::cout << "Signature: " << signature_b58 << std::endl;
        return 0;
      }
      return 1;
    }

    // Verifying
    if (!args.get_import_pub_key().empty() &&
        !args.get_verifying_file().empty() && !args.get_signature().empty()) {
      // Verifying
      std::vector<uint8_t> pub_key_data;
      bool succ = base58::DecodeBase58(args.get_import_pub_key(), pub_key_data);
      if (!succ) {
        std::cerr << "Cannot decode public key from base58 string."
                  << std::endl;
        return 1;
      }
      std::vector<uint8_t> signature;
      succ = base58::DecodeBase58(args.get_signature(), signature);
      if (!succ) {
        std::cerr << "Cannot decode signature from base58 string." << std::endl;
        return 1;
      }
      ecdsa::PubKey pub_key(pub_key_data);
      succ = Verifying(pub_key, args.get_verifying_file(), signature);
      if (succ) {
        std::cout << "Verified OK." << std::endl;
        return 0;
      }
      return 1;
    }

    if (priv_key_b58.empty()) {
      std::cerr << "No argument, -h to show help." << std::endl;
    }
    return 1;
  } catch (std::exception &e) {
    std::cerr << e.what() << std::endl;
  }

  return 0;
}
<commit_msg>Little-endian hex encoding.<commit_after>#include <fstream>
#include <iomanip>
#include <iostream>
#include <memory>
#include <sstream>
#include <tuple>
#include <vector>

#include <openssl/sha.h>

#include <ecdsa/base58.h>
#include <ecdsa/key.h>

#include "args.h"
#include "btcaddr.h"
#include "btcwif.h"

#define BUFF_SIZE 1024

/**
 * Show help document.
 *
 * @param args The argument manager
 */
void ShowHelp(const Args &args) {
  std::cout << "BTCAddr(ess)Gen(erator)" << std::endl
            << "  An easy to use Bitcoin Address offline generator."
            << std::endl
            << std::endl;
  std::cout << "Usage:" << std::endl;
  std::cout << "  ./btcaddrgen [arguments...]" << std::endl << std::endl;
  std::cout << "Arguments:" << std::endl;
  std::cout << args.GetArgsHelpString() << std::endl;
}

std::tuple<std::vector<uint8_t>, bool> HashFile(const std::string &path) {
  std::vector<uint8_t> md;

  std::ifstream input(path, std::ios::binary);
  if (!input.is_open()) {
    std::cerr << "Cannot open file " << path << std::endl;
    return std::make_tuple(md, false);
  }

  // Hash file contents
  SHA512_CTX ctx;
  SHA512_Init(&ctx);

  // Reading...
  char buff[BUFF_SIZE];
  while (!input.eof()) {
    input.read(buff, BUFF_SIZE);
    size_t buff_size = input.gcount();
    SHA512_Update(&ctx, buff, buff_size);
  }

  // Get md buffer.
  md.resize(SHA512_DIGEST_LENGTH);
  SHA512_Final(md.data(), &ctx);

  return std::make_tuple(md, true);
}

std::tuple<std::vector<uint8_t>, bool> Signing(std::shared_ptr<ecdsa::Key> pkey,
                                               const std::string &path) {
  std::vector<uint8_t> signature;

  std::vector<uint8_t> md;
  bool succ;
  std::tie(md, succ) = HashFile(path);
  if (!succ) {
    return std::make_tuple(signature, false);
  }

  std::tie(signature, succ) = pkey->Sign(md);
  if (!succ) {
    std::cerr << "Cannot signing file!" << std::endl;
    return std::make_tuple(signature, false);
  }

  return std::make_tuple(signature, true);
}

bool Verifying(const ecdsa::PubKey &pub_key, const std::string &path,
               const std::vector<uint8_t> &signature) {
  std::vector<uint8_t> md;
  bool succ;
  std::tie(md, succ) = HashFile(path);
  if (succ) {
    return pub_key.Verify(md, signature);
  }
  return false;
}

std::string BinaryToHexString(const unsigned char *bin_data, size_t size) {
  std::stringstream ss_hex;
  for (unsigned int i = size - 1; i > 0; --i) {
    ss_hex << std::hex << std::setw(2) << std::setfill('0')
           << static_cast<int>(bin_data[i]);
  }
  return ss_hex.str();
}

void ShowKeyInfo(std::shared_ptr<ecdsa::Key> pkey, unsigned char prefix_char) {
  auto pub_key = pkey->CreatePubKey();
  unsigned char hash160[20];
  auto addr = btc::Address::FromPublicKey(pub_key.get_pub_key_data(),
                                          prefix_char, hash160);
  std::cout << "Address: " << addr.ToString() << std::endl;
  std::cout << "Hash160: " << BinaryToHexString(hash160, 20) << std::endl;
  std::cout << "Public key: " << base58::EncodeBase58(pkey->get_pub_key_data())
            << std::endl;
  std::cout << "Private key: "
            << base58::EncodeBase58(pkey->get_priv_key_data()) << std::endl;
  std::cout << "Private key(WIF): "
            << btc::wif::PrivateKeyToWif(pkey->get_priv_key_data())
            << std::endl;
}

/// Main program.
int main(int argc, const char *argv[]) {
  try {
    Args args(argc, argv);
    if (args.is_help()) {
      ShowHelp(args);
      return 0;
    }

    if (args.is_generate_new_key()) {
      ShowKeyInfo(std::make_shared<ecdsa::Key>(), args.get_prefix_char());
      return 0;
    }

    // Import key.
    std::shared_ptr<ecdsa::Key> pkey;
    std::string priv_key_b58 = args.get_import_priv_key();
    if (!priv_key_b58.empty()) {
      std::vector<uint8_t> priv_key;
      // Checking WIF format.
      if (btc::wif::VerifyWifString(priv_key_b58)) {
        // Decoding private key in WIF format.
        priv_key = btc::wif::WifToPrivateKey(priv_key_b58);
      } else {
        // Decoding private key in plain base58 data.
        bool succ = base58::DecodeBase58(priv_key_b58.c_str(), priv_key);
        if (!succ) {
          std::cerr << "Failed to decode base58!" << std::endl;
          return 1;
        }
      }
      pkey = std::make_shared<ecdsa::Key>(priv_key);
      ShowKeyInfo(pkey, args.get_prefix_char());
    }

    // Signing file?
    if (!args.get_signing_file().empty()) {
      if (pkey == nullptr) {
        pkey = std::make_shared<ecdsa::Key>();
        ShowKeyInfo(pkey, args.get_prefix_char());
      }
      std::vector<uint8_t> signature;
      bool succ;
      std::tie(signature, succ) = Signing(pkey, args.get_signing_file());
      if (succ) {
        std::string signature_b58 = base58::EncodeBase58(signature);
        std::cout << "Signature: " << signature_b58 << std::endl;
        return 0;
      }
      return 1;
    }

    // Verifying
    if (!args.get_import_pub_key().empty() &&
        !args.get_verifying_file().empty() && !args.get_signature().empty()) {
      // Verifying
      std::vector<uint8_t> pub_key_data;
      bool succ = base58::DecodeBase58(args.get_import_pub_key(), pub_key_data);
      if (!succ) {
        std::cerr << "Cannot decode public key from base58 string."
                  << std::endl;
        return 1;
      }
      std::vector<uint8_t> signature;
      succ = base58::DecodeBase58(args.get_signature(), signature);
      if (!succ) {
        std::cerr << "Cannot decode signature from base58 string." << std::endl;
        return 1;
      }
      ecdsa::PubKey pub_key(pub_key_data);
      succ = Verifying(pub_key, args.get_verifying_file(), signature);
      if (succ) {
        std::cout << "Verified OK." << std::endl;
        return 0;
      }
      return 1;
    }

    if (priv_key_b58.empty()) {
      std::cerr << "No argument, -h to show help." << std::endl;
    }
    return 1;
  } catch (std::exception &e) {
    std::cerr << e.what() << std::endl;
  }

  return 0;
}
<|endoftext|>


<commit_before>// ======================================================================== //
// Copyright 2009-2016 Intel Corporation                                    //
//                                                                          //
// Licensed under the Apache License, Version 2.0 (the "License");          //
// you may not use this file except in compliance with the License.         //
// You may obtain a copy of the License at                                  //
//                                                                          //
//     http://www.apache.org/licenses/LICENSE-2.0                           //
//                                                                          //
// Unless required by applicable law or agreed to in writing, software      //
// distributed under the License is distributed on an "AS IS" BASIS,        //
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. //
// See the License for the specific language governing permissions and      //
// limitations under the License.                                           //
// ======================================================================== //

#include <limits>
// ospray
#include "volume/DataDistributedBlockedVolume.h"
#include "volume/GhostBlockBrickedVolume.h"
#include "common/Core.h"
#include "transferFunction/TransferFunction.h"
#include "volume/GhostBlockBrickedVolume.h"
#if EXP_DATA_PARALLEL
#include "mpi/MPICommon.h"
#endif
// ispc exports:
#include "DataDistributedBlockedVolume_ispc.h"

namespace ospray {

#if EXP_DATA_PARALLEL

  //! Allocate storage and populate the volume, called through the OSPRay API.
  void DataDistributedBlockedVolume::commit()
  {
    // IW: do NOT call parent commit here - this would try to build
    // the parent acceleration strucutre, which doesn't make sense on
    // blocks that do not exist!!!!

    updateEditableParameters();//

    StructuredVolume::commit();

    for (uint32_t i=0;i<numDDBlocks;i++) {
      DDBlock *block = ddBlock+i;
      if (!block->isMine) {
        continue;
      }
      block->cppVolume->commit();
    }
  }

  DataDistributedBlockedVolume::DataDistributedBlockedVolume() :
    numDDBlocks(0),
    ddBlock(NULL)
  {
    PING;
  }

  void DataDistributedBlockedVolume::updateEditableParameters()
  {
    StructuredVolume::updateEditableParameters();
    for (uint32_t i = 0; i < numDDBlocks; i++) {
      DDBlock *block = ddBlock+i;

      if (!block->isMine) {
        continue;
      }

      Ref<TransferFunction> transferFunction
        = (TransferFunction *)getParamObject("transferFunction", NULL);

      auto &cppVolume = block->cppVolume;
      cppVolume->findParam("transferFunction",1)->set(transferFunction.ptr);

      cppVolume->findParam("samplingRate",1)->set(getParam1f("samplingRate",
                                                             1.f));
      cppVolume->findParam("gradientShadingEnabled",
                           1)->set(getParam1i("gradientShadingEnabled", 0));

      cppVolume.ptr->updateEditableParameters();
    }
  }

  bool DataDistributedBlockedVolume::isDataDistributed() const
  {
    return true;
  }

  void DataDistributedBlockedVolume::buildAccelerator()
  {
    std::cout << "intentionally SKIP building an accelerator for data parallel "
              << "volume (this'll be done on the brick level)" << std::endl;
  }

  std::string DataDistributedBlockedVolume::toString() const
  {
    return("ospray::DataDistributedBlockedVolume<" + voxelType + ">");
  }

  //! Copy voxels into the volume at the given index (non-zero return value
  //! indicates success).
  int DataDistributedBlockedVolume::setRegion(
      /* points to the first voxel to be copies. The
         voxels at 'soruce' MUST have dimensions
         'regionSize', must be organized in 3D-array
         order, and must have the same voxel type as the
         volume.*/
      const void *source,
      /*! coordinates of the lower,
        left, front corner of the target
        region.*/
      const vec3i &regionCoords,
      /*! size of the region that we're writing to; MUST
        be the same as the dimensions of source[][][] */
      const vec3i &regionSize)
  {
    // Create the equivalent ISPC volume container and allocate memory for voxel
    // data.
    if (ispcEquivalent == NULL) createEquivalentISPC();

    // The block domains are in terms of the scaled regions so we must check
    // if the data is for the block in the scaled volume
    vec3i finalRegionCoords(vec3f(regionCoords) * scaleFactor);
    vec3i finalRegionSize(vec3f(regionSize) * scaleFactor);
    if (scaleFactor != vec3f(-1.f)) {
      finalRegionCoords = vec3i(vec3f(regionCoords) * scaleFactor);
      finalRegionSize = vec3i(vec3f(regionSize) * scaleFactor);
    } else {
      finalRegionCoords = regionCoords;
      finalRegionSize = regionSize;
    }

    for (uint32_t i = 0; i < numDDBlocks; i++) {
      // that block isn't mine, I shouldn't care ...
      if (!ddBlock[i].isMine) continue;

      // first, do some culling to make sure we only do setrgion
      // calls on blocks that actually map to this block
      if (ddBlock[i].domain.lower.x >= finalRegionCoords.x+finalRegionSize.x) continue;
      if (ddBlock[i].domain.lower.y >= finalRegionCoords.y+finalRegionSize.y) continue;
      if (ddBlock[i].domain.lower.z >= finalRegionCoords.z+finalRegionSize.z) continue;

      if (ddBlock[i].domain.upper.x+finalRegionSize.x < finalRegionCoords.x) continue;
      if (ddBlock[i].domain.upper.y+finalRegionSize.y < finalRegionCoords.y) continue;
      if (ddBlock[i].domain.upper.z+finalRegionSize.z < finalRegionCoords.z) continue;

      vec3i setRegionCoords = finalRegionCoords - ddBlock[i].domain.lower;
      if (scaleFactor != vec3f(-1.f)) {
        setRegionCoords = vec3i(vec3f(setRegionCoords) / scaleFactor);
      }

      ddBlock[i].cppVolume->setRegion(source, setRegionCoords, regionSize);

      ddBlock[i].ispcVolume = ddBlock[i].cppVolume->getIE();

#ifndef OSPRAY_VOLUME_VOXELRANGE_IN_APP
      ManagedObject::Param *param = ddBlock[i].cppVolume->findParam("voxelRange");
      if (param != NULL && param->type == OSP_FLOAT2){
        vec2f blockRange = ((vec2f*)param->f)[0];
        voxelRange.x = std::min(voxelRange.x, blockRange.x);
        voxelRange.y = std::max(voxelRange.y, blockRange.y);
      }
#endif
    }

#ifndef OSPRAY_VOLUME_VOXELRANGE_IN_APP
    // Do a reduction here to worker 0 since it will be queried for the voxel range by the display node
    vec2f globalVoxelRange = voxelRange;
    MPI_CALL(Reduce(&voxelRange.x, &globalVoxelRange.x, 1, MPI_FLOAT, MPI_MIN, 0, mpi::worker.comm));
    MPI_CALL(Reduce(&voxelRange.y, &globalVoxelRange.y, 1, MPI_FLOAT, MPI_MAX, 0, mpi::worker.comm));
    set("voxelRange", globalVoxelRange);
#endif
    return 0;
  }

  void DataDistributedBlockedVolume::createEquivalentISPC()
  {
    if (ispcEquivalent != NULL) return;

    // Get the voxel type.
    voxelType = getParamString("voxelType", "unspecified");
    exitOnCondition(getVoxelType() == OSP_UNKNOWN,
                    "unrecognized voxel type (must be set before calling "
                    "ospSetRegion())");

    // Get the volume dimensions.
    this->dimensions = getParam3i("dimensions", vec3i(0));
    exitOnCondition(reduce_min(this->dimensions) <= 0,
                    "invalid volume dimensions (must be set before calling "
                    "ospSetRegion())");

    ddBlocks    = getParam3i("num_dp_blocks",vec3i(4,4,4));
    blockSize   = divRoundUp(dimensions,ddBlocks);
    std::cout << "#osp:dp: using data parallel volume of " << ddBlocks
              << " blocks, blockSize is " << blockSize << std::endl;

    // Set the grid origin, default to (0,0,0).
    this->gridOrigin = getParam3f("gridOrigin", vec3f(0.f));

    // Get the volume dimensions.
    this->dimensions = getParam3i("dimensions", vec3i(0));
    exitOnCondition(reduce_min(this->dimensions) <= 0,
                    "invalid volume dimensions");

    // Set the grid spacing, default to (1,1,1).
    this->gridSpacing = getParam3f("gridSpacing", vec3f(1.f));

    this->scaleFactor = getParam3f("scaleFactor", vec3f(-1.f));

    numDDBlocks = ospcommon::reduce_mul(ddBlocks);
    ddBlock     = new DDBlock[numDDBlocks];

    printf("=======================================================\n");
    printf("created %ix%ix%i data distributed volume blocks\n",
           ddBlocks.x,ddBlocks.y,ddBlocks.z);
    printf("=======================================================\n");

    if (!ospray::core::isMpiParallel()) {
      throw std::runtime_error("data parallel volume, but not in mpi parallel "
                               "mode...");
    }
    uint64_t numWorkers = ospray::core::getWorkerCount();
    // PRINT(numDDBlocks);
    // PRINT(numWorkers);

    voxelType = getParamString("voxelType", "unspecified");

    // if (numDDBlocks >= numWorkers) {
    // we have more workers than blocks - use one owner per block,
    // meaning we'll end up with multiple blocks per worker
    int blockID = 0;
    for (int iz=0;iz<ddBlocks.z;iz++)
      for (int iy=0;iy<ddBlocks.y;iy++)
        for (int ix=0;ix<ddBlocks.x;ix++, blockID++) {
          DDBlock *block = &ddBlock[blockID];
          if (numDDBlocks >= numWorkers) {
            block->firstOwner = blockID % numWorkers;
            block->numOwners = 1;
          } else {
            block->firstOwner = (blockID * numWorkers) / numDDBlocks;
            int nextBlockFirstOwner = ((blockID+1)*numWorkers) / numDDBlocks;
            block->numOwners = nextBlockFirstOwner - block->firstOwner; // + 1;
          }
          block->isMine
            = (ospray::core::getWorkerRank() >= block->firstOwner)
            && (ospray::core::getWorkerRank() <
                (block->firstOwner + block->numOwners));
          block->domain.lower = vec3i(ix,iy,iz) * blockSize;
          block->domain.upper = min(block->domain.lower+blockSize,dimensions);
          block->bounds.lower = gridOrigin +
            (gridSpacing * vec3f(block->domain.lower));
          block->bounds.upper = gridOrigin +
            (gridSpacing * vec3f(block->domain.upper));

          // iw: add one voxel overlap, so we can properly interpolate
          // even across block boundaries (we need the full *cell* on
          // the right side, not just the last *voxel*!)
          block->domain.upper = min(block->domain.upper+vec3i(1),dimensions);

          if (block->isMine) {
#ifdef EXP_NEW_BB_VOLUME_KERNELS
            Ref<Volume> volume = new GhostBlockBrickedVolume;
#else
            Ref<Volume> volume = new BlockBrickedVolume;
#endif
            vec3i blockDims = block->domain.upper - block->domain.lower;
            volume->findParam("dimensions",1)->set(blockDims);
            volume->findParam("gridOrigin",1)->set(block->bounds.lower);
            volume->findParam("gridSpacing",1)->set(gridSpacing);
            volume->findParam("voxelType",1)->set(voxelType.c_str());
            if (scaleFactor != vec3f(-1.f)) {
              volume->findParam("scaleFactor",1)->set(scaleFactor);
            }

            printf("rank %li owns block %i,%i,%i (ID %i), dims %i %i %i\n",
                   (size_t)core::getWorkerRank(),ix,iy,iz,
                   blockID,blockDims.x,blockDims.y,blockDims.z);
            block->cppVolume = volume;
            block->ispcVolume = NULL; //volume->getIE();
          } else {
            block->ispcVolume = NULL;
            block->cppVolume = NULL;
          }
        }

    // Create an ISPC BlockBrickedVolume object and assign type-specific
    // function pointers.
    ispcEquivalent = ispc::DDBVolume_create(this,
                                            (int)getVoxelType(),
                                            (const ispc::vec3i&)dimensions,
                                            (const ispc::vec3i&)ddBlocks,
                                            (const ispc::vec3i&)blockSize,
                                            ddBlock);
    if (!ispcEquivalent) {
      throw std::runtime_error("could not create create data distributed "
                               "volume");
    }
  }

  // A volume type with internal data-distribution. needs a renderer
  // that is capable of data-parallel rendering!
  OSP_REGISTER_VOLUME(DataDistributedBlockedVolume, data_distributed_volume);

#endif

} // ::ospray
<commit_msg>Datadistrib volume would return 0 to indicate success which is wrong<commit_after>// ======================================================================== //
// Copyright 2009-2016 Intel Corporation                                    //
//                                                                          //
// Licensed under the Apache License, Version 2.0 (the "License");          //
// you may not use this file except in compliance with the License.         //
// You may obtain a copy of the License at                                  //
//                                                                          //
//     http://www.apache.org/licenses/LICENSE-2.0                           //
//                                                                          //
// Unless required by applicable law or agreed to in writing, software      //
// distributed under the License is distributed on an "AS IS" BASIS,        //
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. //
// See the License for the specific language governing permissions and      //
// limitations under the License.                                           //
// ======================================================================== //

#include <limits>
// ospray
#include "volume/DataDistributedBlockedVolume.h"
#include "volume/GhostBlockBrickedVolume.h"
#include "common/Core.h"
#include "transferFunction/TransferFunction.h"
#include "volume/GhostBlockBrickedVolume.h"
#if EXP_DATA_PARALLEL
#include "mpi/MPICommon.h"
#endif
// ispc exports:
#include "DataDistributedBlockedVolume_ispc.h"

namespace ospray {

#if EXP_DATA_PARALLEL

  //! Allocate storage and populate the volume, called through the OSPRay API.
  void DataDistributedBlockedVolume::commit()
  {
    // IW: do NOT call parent commit here - this would try to build
    // the parent acceleration strucutre, which doesn't make sense on
    // blocks that do not exist!!!!

    updateEditableParameters();//

    StructuredVolume::commit();

    for (uint32_t i=0;i<numDDBlocks;i++) {
      DDBlock *block = ddBlock+i;
      if (!block->isMine) {
        continue;
      }
      block->cppVolume->commit();
    }
  }

  DataDistributedBlockedVolume::DataDistributedBlockedVolume() :
    numDDBlocks(0),
    ddBlock(NULL)
  {
    PING;
  }

  void DataDistributedBlockedVolume::updateEditableParameters()
  {
    StructuredVolume::updateEditableParameters();
    for (uint32_t i = 0; i < numDDBlocks; i++) {
      DDBlock *block = ddBlock+i;

      if (!block->isMine) {
        continue;
      }

      Ref<TransferFunction> transferFunction
        = (TransferFunction *)getParamObject("transferFunction", NULL);

      auto &cppVolume = block->cppVolume;
      cppVolume->findParam("transferFunction",1)->set(transferFunction.ptr);

      cppVolume->findParam("samplingRate",1)->set(getParam1f("samplingRate",
                                                             1.f));
      cppVolume->findParam("gradientShadingEnabled",
                           1)->set(getParam1i("gradientShadingEnabled", 0));

      cppVolume.ptr->updateEditableParameters();
    }
  }

  bool DataDistributedBlockedVolume::isDataDistributed() const
  {
    return true;
  }

  void DataDistributedBlockedVolume::buildAccelerator()
  {
    std::cout << "intentionally SKIP building an accelerator for data parallel "
              << "volume (this'll be done on the brick level)" << std::endl;
  }

  std::string DataDistributedBlockedVolume::toString() const
  {
    return("ospray::DataDistributedBlockedVolume<" + voxelType + ">");
  }

  //! Copy voxels into the volume at the given index (non-zero return value
  //! indicates success).
  int DataDistributedBlockedVolume::setRegion(
      /* points to the first voxel to be copies. The
         voxels at 'soruce' MUST have dimensions
         'regionSize', must be organized in 3D-array
         order, and must have the same voxel type as the
         volume.*/
      const void *source,
      /*! coordinates of the lower,
        left, front corner of the target
        region.*/
      const vec3i &regionCoords,
      /*! size of the region that we're writing to; MUST
        be the same as the dimensions of source[][][] */
      const vec3i &regionSize)
  {
    // Create the equivalent ISPC volume container and allocate memory for voxel
    // data.
    if (ispcEquivalent == NULL) createEquivalentISPC();

    // The block domains are in terms of the scaled regions so we must check
    // if the data is for the block in the scaled volume
    vec3i finalRegionCoords(vec3f(regionCoords) * scaleFactor);
    vec3i finalRegionSize(vec3f(regionSize) * scaleFactor);
    if (scaleFactor != vec3f(-1.f)) {
      finalRegionCoords = vec3i(vec3f(regionCoords) * scaleFactor);
      finalRegionSize = vec3i(vec3f(regionSize) * scaleFactor);
    } else {
      finalRegionCoords = regionCoords;
      finalRegionSize = regionSize;
    }

    for (uint32_t i = 0; i < numDDBlocks; i++) {
      // that block isn't mine, I shouldn't care ...
      if (!ddBlock[i].isMine) continue;

      // first, do some culling to make sure we only do setrgion
      // calls on blocks that actually map to this block
      if (ddBlock[i].domain.lower.x >= finalRegionCoords.x+finalRegionSize.x) continue;
      if (ddBlock[i].domain.lower.y >= finalRegionCoords.y+finalRegionSize.y) continue;
      if (ddBlock[i].domain.lower.z >= finalRegionCoords.z+finalRegionSize.z) continue;

      if (ddBlock[i].domain.upper.x+finalRegionSize.x < finalRegionCoords.x) continue;
      if (ddBlock[i].domain.upper.y+finalRegionSize.y < finalRegionCoords.y) continue;
      if (ddBlock[i].domain.upper.z+finalRegionSize.z < finalRegionCoords.z) continue;

      vec3i setRegionCoords = finalRegionCoords - ddBlock[i].domain.lower;
      if (scaleFactor != vec3f(-1.f)) {
        setRegionCoords = vec3i(vec3f(setRegionCoords) / scaleFactor);
      }

      ddBlock[i].cppVolume->setRegion(source, setRegionCoords, regionSize);

      ddBlock[i].ispcVolume = ddBlock[i].cppVolume->getIE();

#ifndef OSPRAY_VOLUME_VOXELRANGE_IN_APP
      ManagedObject::Param *param = ddBlock[i].cppVolume->findParam("voxelRange");
      if (param != NULL && param->type == OSP_FLOAT2){
        vec2f blockRange = ((vec2f*)param->f)[0];
        voxelRange.x = std::min(voxelRange.x, blockRange.x);
        voxelRange.y = std::max(voxelRange.y, blockRange.y);
      }
#endif
    }

#ifndef OSPRAY_VOLUME_VOXELRANGE_IN_APP
    // Do a reduction here to worker 0 since it will be queried for the voxel range by the display node
    vec2f globalVoxelRange = voxelRange;
    MPI_CALL(Reduce(&voxelRange.x, &globalVoxelRange.x, 1, MPI_FLOAT, MPI_MIN, 0, mpi::worker.comm));
    MPI_CALL(Reduce(&voxelRange.y, &globalVoxelRange.y, 1, MPI_FLOAT, MPI_MAX, 0, mpi::worker.comm));
    set("voxelRange", globalVoxelRange);
#endif
    return true;
  }

  void DataDistributedBlockedVolume::createEquivalentISPC()
  {
    if (ispcEquivalent != NULL) return;

    // Get the voxel type.
    voxelType = getParamString("voxelType", "unspecified");
    exitOnCondition(getVoxelType() == OSP_UNKNOWN,
                    "unrecognized voxel type (must be set before calling "
                    "ospSetRegion())");

    // Get the volume dimensions.
    this->dimensions = getParam3i("dimensions", vec3i(0));
    exitOnCondition(reduce_min(this->dimensions) <= 0,
                    "invalid volume dimensions (must be set before calling "
                    "ospSetRegion())");

    ddBlocks    = getParam3i("num_dp_blocks",vec3i(4,4,4));
    blockSize   = divRoundUp(dimensions,ddBlocks);
    std::cout << "#osp:dp: using data parallel volume of " << ddBlocks
              << " blocks, blockSize is " << blockSize << std::endl;

    // Set the grid origin, default to (0,0,0).
    this->gridOrigin = getParam3f("gridOrigin", vec3f(0.f));

    // Get the volume dimensions.
    this->dimensions = getParam3i("dimensions", vec3i(0));
    exitOnCondition(reduce_min(this->dimensions) <= 0,
                    "invalid volume dimensions");

    // Set the grid spacing, default to (1,1,1).
    this->gridSpacing = getParam3f("gridSpacing", vec3f(1.f));

    this->scaleFactor = getParam3f("scaleFactor", vec3f(-1.f));

    numDDBlocks = ospcommon::reduce_mul(ddBlocks);
    ddBlock     = new DDBlock[numDDBlocks];

    printf("=======================================================\n");
    printf("created %ix%ix%i data distributed volume blocks\n",
           ddBlocks.x,ddBlocks.y,ddBlocks.z);
    printf("=======================================================\n");

    if (!ospray::core::isMpiParallel()) {
      throw std::runtime_error("data parallel volume, but not in mpi parallel "
                               "mode...");
    }
    uint64_t numWorkers = ospray::core::getWorkerCount();
    // PRINT(numDDBlocks);
    // PRINT(numWorkers);

    voxelType = getParamString("voxelType", "unspecified");

    // if (numDDBlocks >= numWorkers) {
    // we have more workers than blocks - use one owner per block,
    // meaning we'll end up with multiple blocks per worker
    int blockID = 0;
    for (int iz=0;iz<ddBlocks.z;iz++)
      for (int iy=0;iy<ddBlocks.y;iy++)
        for (int ix=0;ix<ddBlocks.x;ix++, blockID++) {
          DDBlock *block = &ddBlock[blockID];
          if (numDDBlocks >= numWorkers) {
            block->firstOwner = blockID % numWorkers;
            block->numOwners = 1;
          } else {
            block->firstOwner = (blockID * numWorkers) / numDDBlocks;
            int nextBlockFirstOwner = ((blockID+1)*numWorkers) / numDDBlocks;
            block->numOwners = nextBlockFirstOwner - block->firstOwner; // + 1;
          }
          block->isMine
            = (ospray::core::getWorkerRank() >= block->firstOwner)
            && (ospray::core::getWorkerRank() <
                (block->firstOwner + block->numOwners));
          block->domain.lower = vec3i(ix,iy,iz) * blockSize;
          block->domain.upper = min(block->domain.lower+blockSize,dimensions);
          block->bounds.lower = gridOrigin +
            (gridSpacing * vec3f(block->domain.lower));
          block->bounds.upper = gridOrigin +
            (gridSpacing * vec3f(block->domain.upper));

          // iw: add one voxel overlap, so we can properly interpolate
          // even across block boundaries (we need the full *cell* on
          // the right side, not just the last *voxel*!)
          block->domain.upper = min(block->domain.upper+vec3i(1),dimensions);

          if (block->isMine) {
#ifdef EXP_NEW_BB_VOLUME_KERNELS
            Ref<Volume> volume = new GhostBlockBrickedVolume;
#else
            Ref<Volume> volume = new BlockBrickedVolume;
#endif
            vec3i blockDims = block->domain.upper - block->domain.lower;
            volume->findParam("dimensions",1)->set(blockDims);
            volume->findParam("gridOrigin",1)->set(block->bounds.lower);
            volume->findParam("gridSpacing",1)->set(gridSpacing);
            volume->findParam("voxelType",1)->set(voxelType.c_str());
            if (scaleFactor != vec3f(-1.f)) {
              volume->findParam("scaleFactor",1)->set(scaleFactor);
            }

            printf("worker rank %li owns block %i,%i,%i (ID %i), dims %i %i %i\n",
                   (size_t)core::getWorkerRank(),ix,iy,iz,
                   blockID,blockDims.x,blockDims.y,blockDims.z);
            block->cppVolume = volume;
            block->ispcVolume = NULL; //volume->getIE();
          } else {
            block->ispcVolume = NULL;
            block->cppVolume = NULL;
          }
        }

    // Create an ISPC BlockBrickedVolume object and assign type-specific
    // function pointers.
    ispcEquivalent = ispc::DDBVolume_create(this,
                                            (int)getVoxelType(),
                                            (const ispc::vec3i&)dimensions,
                                            (const ispc::vec3i&)ddBlocks,
                                            (const ispc::vec3i&)blockSize,
                                            ddBlock);
    if (!ispcEquivalent) {
      throw std::runtime_error("could not create create data distributed "
                               "volume");
    }
  }

  // A volume type with internal data-distribution. needs a renderer
  // that is capable of data-parallel rendering!
  OSP_REGISTER_VOLUME(DataDistributedBlockedVolume, data_distributed_volume);

#endif

} // ::ospray
<|endoftext|>


<commit_before>#include "agent.h"
#include "environment.h"
#include "errors.h"

#include <string>
#include <vector>
#include <fstream>
#include <stdexcept>
#include <cassert>

Strategy ConvertToStrategy(const std::string& identifier) {
    if(identifier.size() == 1) {
        switch(identifier[0]) {
            case 'L': return BreadthFirstStrategy;
            case 'P': return LimitedDepthFirstStrategy;
            case 'A': throw input_error("Strategy not yet implemented.");
            default:
                /* Nothing */;
        }
    }
    throw input_error("Unknown strategy: '" + identifier + "'");
    return Strategy();
}

void openFile(const std::string& filename, MapMatrix& matrix, std::set<Position>& gold_locations) {
    std::ifstream input(filename);
    if(!input.is_open())
        throw input_error("Unable to open file '" + filename + "'.");

    matrix.clear();
    gold_locations.clear();

    std::string line;
    getline(input, line);
    int size;
    try {
        size = stoi(line);
    } catch(const std::invalid_argument&) {
        throw input_error("'" + line + "' is not an int.");
    } catch(const std::out_of_range&) {
        throw input_error("'" + line + "' is out of range, doesn't fit in an int.");
    }
    if(size < 1 || size > 50)
        throw input_error("Invalid size, size must be in range [1, 50].");

    matrix.resize(size);

    for (int j = 0; j < matrix.size(); ++j) {
        auto& matrix_line = matrix[j];

        getline(input, line);
        if(line.size() != matrix_line.size())
            throw input_error("'" + line + "' size doesn't match declared size.");

        for (std::string::size_type i = 0; i < line.size(); ++i) {
            switch (line[i]) {
                case '*':
                    gold_locations.insert(Position(static_cast<int>(i),
                                                   static_cast<int>(j)));
                    // No break on purpose.
                case '0':
                    matrix_line[i] = false; break;
                case '1':
                    matrix_line[i] = true; break;
                default:
                    throw input_error(std::string("Unknown character '") + line[i] + "' on line ");
            }
        }
    }
    if (static_cast<int>(gold_locations.size()) != matrix.size() / 2)
        throw input_error("Wrong ammount of gold locations. Expected "
                    + std::to_string(matrix.size() / 2)
                    + " got " + std::to_string(gold_locations.size()));

    assert(matrix.size() == size);

}

int main(int argc, char* argv[])
try {
    if(argc != 3) {
        fprintf(stderr, "Usage: %s <map-file-path> <search-type>\n", argv[0]);
        return EXIT_SUCCESS;
    }

    Environment env;
    openFile(argv[1], env.data().matrix_, env.data().gold_locations_);

    env.set_agent(std::unique_ptr<Agent>(new Agent(ConvertToStrategy(argv[2]))));

    auto result = env.Run();

    printf("%d pontos\n", env.data().CalculateScore(*result));

    return 0;

} catch(const input_error& err) {
    fprintf(stderr, "Input error: %s\n", err.what());
    return EXIT_FAILURE;
}
<commit_msg>Print the result path.<commit_after>#include "agent.h"
#include "environment.h"
#include "errors.h"

#include <string>
#include <vector>
#include <fstream>
#include <stdexcept>
#include <cassert>

char ActionToChar(Action a) {
    switch (a) {
        case Action::MOVE_LEFT: return 'E';
        case Action::MOVE_UP: return 'C';
        case Action::MOVE_RIGHT: return 'D';
        case Action::MOVE_DOWN: return 'B';
        case Action::PICK_GOLD: return 'P';
        default: break;
    }
    throw input_error("Converting Action with no textual representation.");
    return '\0';
}

Strategy ConvertToStrategy(const std::string& identifier) {
    if(identifier.size() == 1) {
        switch(identifier[0]) {
            case 'L': return BreadthFirstStrategy;
            case 'P': return LimitedDepthFirstStrategy;
            case 'A': throw input_error("Strategy not yet implemented.");
            default:
                /* Nothing */;
        }
    }
    throw input_error("Unknown strategy: '" + identifier + "'");
    return Strategy();
}

void openFile(const std::string& filename, MapMatrix& matrix, std::set<Position>& gold_locations) {
    std::ifstream input(filename);
    if(!input.is_open())
        throw input_error("Unable to open file '" + filename + "'.");

    matrix.clear();
    gold_locations.clear();

    std::string line;
    getline(input, line);
    int size;
    try {
        size = stoi(line);
    } catch(const std::invalid_argument&) {
        throw input_error("'" + line + "' is not an int.");
    } catch(const std::out_of_range&) {
        throw input_error("'" + line + "' is out of range, doesn't fit in an int.");
    }
    if(size < 1 || size > 50)
        throw input_error("Invalid size, size must be in range [1, 50].");

    matrix.resize(size);

    for (int j = 0; j < matrix.size(); ++j) {
        auto& matrix_line = matrix[j];

        getline(input, line);
        if(line.size() != matrix_line.size())
            throw input_error("'" + line + "' size doesn't match declared size.");

        for (std::string::size_type i = 0; i < line.size(); ++i) {
            switch (line[i]) {
                case '*':
                    gold_locations.insert(Position(static_cast<int>(i),
                                                   static_cast<int>(j)));
                    // No break on purpose.
                case '0':
                    matrix_line[i] = false; break;
                case '1':
                    matrix_line[i] = true; break;
                default:
                    throw input_error(std::string("Unknown character '") + line[i] + "' on line ");
            }
        }
    }
    if (static_cast<int>(gold_locations.size()) != matrix.size() / 2)
        throw input_error("Wrong ammount of gold locations. Expected "
                    + std::to_string(matrix.size() / 2)
                    + " got " + std::to_string(gold_locations.size()));

    assert(matrix.size() == size);

}

int main(int argc, char* argv[])
try {
    if(argc != 3) {
        fprintf(stderr, "Usage: %s <map-file-path> <search-type>\n", argv[0]);
        return EXIT_SUCCESS;
    }

    Environment env;
    openFile(argv[1], env.data().matrix_, env.data().gold_locations_);

    env.set_agent(std::unique_ptr<Agent>(new Agent(ConvertToStrategy(argv[2]))));

    auto result = env.Run();

    printf("%d pontos\n", env.data().CalculateScore(*result));
    for (Action a : result->CreateActionList())
        printf("%c ", ActionToChar(a));
    puts("");
    return 0;

} catch(const input_error& err) {
    fprintf(stderr, "Input error: %s\n", err.what());
    return EXIT_FAILURE;
}
<|endoftext|>


<commit_before>/**
 *  Copyright (c) 2014-present, Facebook, Inc.
 *  All rights reserved.
 *
 *  This source code is licensed under both the Apache 2.0 license (found in the
 *  LICENSE file in the root directory of this source tree) and the GPLv2 (found
 *  in the COPYING file in the root directory of this source tree).
 *  You may select, at your option, one of the above-listed licenses.
 */

#include <boost/algorithm/string.hpp>

#include <osquery/flags.h>
#include <osquery/logger.h>

#include "osquery/core/conversions.h"
#include "osquery/events/linux/auditeventpublisher.h"
#include "osquery/tables/events/linux/selinux_events.h"

namespace osquery {
FLAG(bool,
     audit_allow_selinux_events,
     false,
     "Allow the audit publisher to process audit events");

REGISTER(SELinuxEventSubscriber, "event_subscriber", "selinux_events");

// Depend on the external getUptime table method.
namespace tables {
extern long getUptime();
}

Status SELinuxEventSubscriber::init() {
  if (!FLAGS_audit_allow_selinux_events) {
    return Status(1, "Subscriber disabled via configuration");
  }

  auto sc = createSubscriptionContext();
  subscribe(&SELinuxEventSubscriber::Callback, sc);

  return Status(0, "OK");
}

Status SELinuxEventSubscriber::Callback(const ECRef& ec, const SCRef& sc) {
  std::vector<Row> emitted_row_list;
  auto status = ProcessEvents(emitted_row_list, ec->audit_events);
  if (!status.ok()) {
    return status;
  }

  for (auto& row : emitted_row_list) {
    add(row);
  }

  return Status(0, "Ok");
}

Status SELinuxEventSubscriber::ProcessEvents(
    std::vector<Row>& emitted_row_list,
    const std::vector<AuditEvent>& event_list) noexcept {
  emitted_row_list.clear();

  for (const auto& event : event_list) {
    if (event.type != AuditEvent::Type::SELinux) {
      continue;
    }

    for (const auto& record : event.record_list) {
      Row r;

      auto record_pretty_name_it = kSELinuxRecordLabels.find(record.type);
      if (record_pretty_name_it == kSELinuxRecordLabels.end()) {
        r["type"] = std::to_string(record.type);
      } else {
        r["type"] = record_pretty_name_it->second;
      }

      r["message"] = record.raw_data;
      r["uptime"] = std::to_string(tables::getUptime());
      emitted_row_list.push_back(r);
    }
  }

  return Status(0, "Ok");
}

const std::set<int>& SELinuxEventSubscriber::GetEventSet() noexcept {
  return kSELinuxEventList;
}
} // namespace osquery
<commit_msg>bug: Fix SELinux events rebase (#4684)<commit_after>/**
 *  Copyright (c) 2014-present, Facebook, Inc.
 *  All rights reserved.
 *
 *  This source code is licensed under both the Apache 2.0 license (found in the
 *  LICENSE file in the root directory of this source tree) and the GPLv2 (found
 *  in the COPYING file in the root directory of this source tree).
 *  You may select, at your option, one of the above-listed licenses.
 */

#include <boost/algorithm/string.hpp>

#include <osquery/flags.h>
#include <osquery/logger.h>
#include <osquery/registry_factory.h>

#include "osquery/core/conversions.h"
#include "osquery/events/linux/auditeventpublisher.h"
#include "osquery/tables/events/linux/selinux_events.h"

namespace osquery {
FLAG(bool,
     audit_allow_selinux_events,
     false,
     "Allow the audit publisher to process audit events");

REGISTER(SELinuxEventSubscriber, "event_subscriber", "selinux_events");

// Depend on the external getUptime table method.
namespace tables {
extern long getUptime();
}

Status SELinuxEventSubscriber::init() {
  if (!FLAGS_audit_allow_selinux_events) {
    return Status(1, "Subscriber disabled via configuration");
  }

  auto sc = createSubscriptionContext();
  subscribe(&SELinuxEventSubscriber::Callback, sc);

  return Status(0, "OK");
}

Status SELinuxEventSubscriber::Callback(const ECRef& ec, const SCRef& sc) {
  std::vector<Row> emitted_row_list;
  auto status = ProcessEvents(emitted_row_list, ec->audit_events);
  if (!status.ok()) {
    return status;
  }

  for (auto& row : emitted_row_list) {
    add(row);
  }

  return Status(0, "Ok");
}

Status SELinuxEventSubscriber::ProcessEvents(
    std::vector<Row>& emitted_row_list,
    const std::vector<AuditEvent>& event_list) noexcept {
  emitted_row_list.clear();

  for (const auto& event : event_list) {
    if (event.type != AuditEvent::Type::SELinux) {
      continue;
    }

    for (const auto& record : event.record_list) {
      Row r;

      auto record_pretty_name_it = kSELinuxRecordLabels.find(record.type);
      if (record_pretty_name_it == kSELinuxRecordLabels.end()) {
        r["type"] = std::to_string(record.type);
      } else {
        r["type"] = record_pretty_name_it->second;
      }

      r["message"] = record.raw_data;
      r["uptime"] = std::to_string(tables::getUptime());
      emitted_row_list.push_back(r);
    }
  }

  return Status(0, "Ok");
}

const std::set<int>& SELinuxEventSubscriber::GetEventSet() noexcept {
  return kSELinuxEventList;
}
} // namespace osquery
<|endoftext|>


<commit_before>/**
 *  Copyright (c) 2014-present, Facebook, Inc.
 *  All rights reserved.
 *
 *  This source code is licensed under both the Apache 2.0 license (found in the
 *  LICENSE file in the root directory of this source tree) and the GPLv2 (found
 *  in the COPYING file in the root directory of this source tree).
 *  You may select, at your option, one of the above-listed licenses.
 */

#include <boost/algorithm/string/predicate.hpp>
#include <boost/algorithm/string/replace.hpp>
#include <boost/algorithm/string/trim.hpp>
#include <boost/regex.hpp>

#include <osquery/tables/system/system_utils.h>
#include <osquery/filesystem/filesystem.h>
#include <osquery/tables.h>
#include <osquery/utils/conversions/split.h>

namespace fs = boost::filesystem;
namespace alg = boost::algorithm;

namespace osquery {
namespace tables {

/// Location of the kernel panic crash logs in OS X
const std::string kDiagnosticReportsPath = "/Library/Logs/DiagnosticReports";

/// List of all register values we wish to catch
const std::set<std::string> kKernelRegisters = {
    "CR0",
    "RAX",
    "RSP",
    "R8",
    "R12",
    "RFL",
};

/// List of the days of the Week, used to grab our timestamp.
const std::set<std::string> kDays = {"Mon", "Tue", "Wed", "Thu", "Fri"};

/// Map of the values we currently parse out of the log file
const std::map<std::string, std::string> kKernelPanicKeys = {
    {"dependency", "dependencies"},
    {"BSD process name corresponding to current thread", "name"},
    {"System model name", "system_model"},
    {"System uptime in nanoseconds", "uptime"},
};

void readKernelPanic(const std::string& appLog, QueryData& results) {
  Row r;
  r["path"] = appLog;
  std::string content;

  if (!readFile(appLog, content).ok()) {
    return;
  }

  boost::regex rxSpaces("\\s+");
  auto lines = osquery::split(content, "\n");
  for (auto it = lines.begin(); it != lines.end(); it++) {
    auto line = *it;
    boost::trim(line);

    auto toks = osquery::split(line, ":");
    if (toks.size() == 0) {
      continue;
    }

    auto timeTokens = osquery::split(toks[0], " ");
    if (timeTokens.size() >= 1 && kDays.count(timeTokens[0]) > 0) {
      r["time"] = line;
    }

    if (kKernelRegisters.count(toks[0]) > 0) {
      auto registerTokens = osquery::split(line, ",");
      if (registerTokens.size() == 0) {
        continue;
      }

      for (auto& tok_ : registerTokens) {
        auto regHolder = osquery::split(tok_, ":");
        if (regHolder.size() != 2) {
          continue;
        }
        auto reg = std::move(regHolder[0]);
        auto val = std::move(regHolder[1]);
        if (reg.size() > 0 && val.size() > 0) {
          std::string regLine = reg + ":" + val;
          r["registers"] += (r["registers"].empty()) ? std::move(regLine)
                                                     : " " + std::move(regLine);
        }
      }
    } else if (boost::starts_with(toks[0], "last loaded kext at") &&
               toks.size() == 2) {
      r["last_loaded"] = boost::regex_replace(toks[1], rxSpaces, " ");
    } else if (boost::starts_with(toks[0], "last unloaded kext at") &&
               toks.size() == 2) {
      r["last_unloaded"] = boost::regex_replace(toks[1], rxSpaces, " ");
    } else if (boost::starts_with(toks[0], "Backtrace") &&
               std::next(it) != lines.end()) {
      r["frame_backtrace"] = *(std::next(it));
    } else if (boost::starts_with(toks[0], "Kernel Extensions in backtrace") &&
               std::next(it) != lines.end()) {
      r["module_backtrace"] = *(std::next(it));
    } else if (boost::starts_with(toks[0], "Mac OS version") &&
               std::next(it) != lines.end()) {
      r["os_version"] = *(std::next(it));
    } else if (boost::starts_with(toks[0], "Kernel version") &&
               std::next(it) != lines.end()) {
      r["kernel_version"] = *(std::next(it));
    } else if (kKernelPanicKeys.count(toks[0]) != 0 && toks.size() == 2) {
      r[kKernelPanicKeys.at(toks[0])] = toks[1];
    }
  }
  results.push_back(r);
}

QueryData genKernelPanics(QueryContext& context) {
  QueryData results;

  if (context.constraints["uid"].notExistsOrMatches("0")) {
    std::vector<std::string> files;
    if (listFilesInDirectory(kDiagnosticReportsPath, files)) {
      for (const auto& lf : files) {
        if (alg::ends_with(lf, ".panic")) {
          readKernelPanic(lf, results);
        }
      }
    }
  }

  return results;
}
}
}
<commit_msg>Include weekends on the kernel_panics table (#5298)<commit_after>/**
 *  Copyright (c) 2014-present, Facebook, Inc.
 *  All rights reserved.
 *
 *  This source code is licensed under both the Apache 2.0 license (found in the
 *  LICENSE file in the root directory of this source tree) and the GPLv2 (found
 *  in the COPYING file in the root directory of this source tree).
 *  You may select, at your option, one of the above-listed licenses.
 */

#include <boost/algorithm/string/predicate.hpp>
#include <boost/algorithm/string/replace.hpp>
#include <boost/algorithm/string/trim.hpp>
#include <boost/regex.hpp>

#include <osquery/tables/system/system_utils.h>
#include <osquery/filesystem/filesystem.h>
#include <osquery/tables.h>
#include <osquery/utils/conversions/split.h>

namespace fs = boost::filesystem;
namespace alg = boost::algorithm;

namespace osquery {
namespace tables {

/// Location of the kernel panic crash logs in OS X
const std::string kDiagnosticReportsPath = "/Library/Logs/DiagnosticReports";

/// List of all register values we wish to catch
const std::set<std::string> kKernelRegisters = {
    "CR0",
    "RAX",
    "RSP",
    "R8",
    "R12",
    "RFL",
};

/// List of the days of the Week, used to grab our timestamp.
const std::set<std::string> kDays = {
    "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"};

/// Map of the values we currently parse out of the log file
const std::map<std::string, std::string> kKernelPanicKeys = {
    {"dependency", "dependencies"},
    {"BSD process name corresponding to current thread", "name"},
    {"System model name", "system_model"},
    {"System uptime in nanoseconds", "uptime"},
};

void readKernelPanic(const std::string& appLog, QueryData& results) {
  Row r;
  r["path"] = appLog;
  std::string content;

  if (!readFile(appLog, content).ok()) {
    return;
  }

  boost::regex rxSpaces("\\s+");
  auto lines = osquery::split(content, "\n");
  for (auto it = lines.begin(); it != lines.end(); it++) {
    auto line = *it;
    boost::trim(line);

    auto toks = osquery::split(line, ":");
    if (toks.size() == 0) {
      continue;
    }

    auto timeTokens = osquery::split(toks[0], " ");
    if (timeTokens.size() >= 1 && kDays.count(timeTokens[0]) > 0) {
      r["time"] = line;
    }

    if (kKernelRegisters.count(toks[0]) > 0) {
      auto registerTokens = osquery::split(line, ",");
      if (registerTokens.size() == 0) {
        continue;
      }

      for (auto& tok_ : registerTokens) {
        auto regHolder = osquery::split(tok_, ":");
        if (regHolder.size() != 2) {
          continue;
        }
        auto reg = std::move(regHolder[0]);
        auto val = std::move(regHolder[1]);
        if (reg.size() > 0 && val.size() > 0) {
          std::string regLine = reg + ":" + val;
          r["registers"] += (r["registers"].empty()) ? std::move(regLine)
                                                     : " " + std::move(regLine);
        }
      }
    } else if (boost::starts_with(toks[0], "last loaded kext at") &&
               toks.size() == 2) {
      r["last_loaded"] = boost::regex_replace(toks[1], rxSpaces, " ");
    } else if (boost::starts_with(toks[0], "last unloaded kext at") &&
               toks.size() == 2) {
      r["last_unloaded"] = boost::regex_replace(toks[1], rxSpaces, " ");
    } else if (boost::starts_with(toks[0], "Backtrace") &&
               std::next(it) != lines.end()) {
      r["frame_backtrace"] = *(std::next(it));
    } else if (boost::starts_with(toks[0], "Kernel Extensions in backtrace") &&
               std::next(it) != lines.end()) {
      r["module_backtrace"] = *(std::next(it));
    } else if (boost::starts_with(toks[0], "Mac OS version") &&
               std::next(it) != lines.end()) {
      r["os_version"] = *(std::next(it));
    } else if (boost::starts_with(toks[0], "Kernel version") &&
               std::next(it) != lines.end()) {
      r["kernel_version"] = *(std::next(it));
    } else if (kKernelPanicKeys.count(toks[0]) != 0 && toks.size() == 2) {
      r[kKernelPanicKeys.at(toks[0])] = toks[1];
    }
  }
  results.push_back(r);
}

QueryData genKernelPanics(QueryContext& context) {
  QueryData results;

  if (context.constraints["uid"].notExistsOrMatches("0")) {
    std::vector<std::string> files;
    if (listFilesInDirectory(kDiagnosticReportsPath, files)) {
      for (const auto& lf : files) {
        if (alg::ends_with(lf, ".panic")) {
          readKernelPanic(lf, results);
        }
      }
    }
  }

  return results;
}
}
}
<|endoftext|>