/* * * Copyright (C) 2015 Jason Gowan * All rights reserved. * * This software may be modified and distributed under the terms * of the BSD license. See the LICENSE file for details. */ #ifndef IPOG_H_ #define IPOG_H_ #include #include #include #include #include #include #include "combinations.h" #include "dither_types.h" #include "base_constraint_handler.h" #include "simple_constraint_handler.h" namespace dither { class Ipog { std::size_t t_; std::vector> input_params_; std::vector> param_cache_; std::forward_list bound_; std::forward_list unbound_; std::unordered_map> int_params_; std::unordered_map> str_params_; std::unordered_map> bool_params_; std::vector ordered_param_names_; std::vector ordered_param_index_; std::vector reverse_ordered_param_index_; std::unordered_map param_index_; std::unordered_map reverse_param_index_; dtest_case merge_scratch_; BaseConstraintHandler* constraint_handler; std::vector> constraints; std::vector ranges; std::size_t solution_size; std::vector> original_previously_tested_; std::vector> previously_tested_; inline void transform(std::vector& scratch, std::vector& test_case) { for(std::size_t i = 0; i < test_case.size(); i++) { scratch[ordered_param_index_[i]] = test_case[i]; } std::copy(scratch.cbegin(), scratch.cend(), test_case.begin()); } inline bool has_previously_tested(std::vector& test_case); inline bool has_previously_tested(dtest_case& test_case); inline bool has_previously_tested(const int, dtest_case& test_case); public: Ipog(); ~Ipog(); Ipog(const unsigned int); void set_t(const unsigned int t) { t_ = t; } void add_parameter(const std::string, const int[], const unsigned int); void add_parameter(const std::string, const std::string[], const unsigned int); void add_parameter(const std::string); void init_bound(); void init_param_cache(); void run(); int size(); std::string *header(); void ground_solutions(); inline bool is_valid() { return t_ <= param_cache_.size(); } std::forward_list> cover(int); const int maximize_coverage(const int, dtest_case &, std::forward_list> &); void add_constraint(const int[], const unsigned int); void add_previously_tested(const int[], const std::size_t); inline bool is_covered(const dtest_case &test_case, const std::vector ¶ms); inline bool is_covered(const std::vector ¶ms); inline const int merge(const int, dtest_case &, const std::vector &); void display_raw_solution(); void fill(int[]); inline void display_header() { for (std::size_t i = 0; i < param_cache_.size();) { std::cout << reverse_param_index_[i]; if (++i < param_cache_.size()) { std::cout << ','; } } std::cout << std::endl; } inline void display_test_case(const dtest_case &test_case) { for (std::size_t i = 0; i < test_case.size();) { const dval value = test_case[i]; if (value == -1) { std::cout << '-'; if (++i < test_case.size()) { std::cout << ','; } continue; } const param my_param = param_cache_[reverse_ordered_param_index_[i]][value]; switch (my_param.type) { case DITHER_INT_T: std::cout << int_params_[my_param.name][my_param.second]; break; case DITHER_BOOL_T: std::cout << std::boolalpha << bool_params_[my_param.name][my_param.second]; break; case DITHER_STRING_T: std::cout << str_params_[my_param.name][my_param.second]; break; } if (++i < test_case.size()) { std::cout << ','; } } std::cout << std::endl; } }; } #endif