int main(int argc, char** argv) { pomagma::Log::Context log_context(argc, argv); if (argc != 4) { std::cout << "Usage: " << boost::filesystem::basename(argv[0]) << " structure language address" << "\n" << "Environment Variables:\n" << " POMAGMA_LOG_FILE = " << pomagma::DEFAULT_LOG_FILE << "\n" << " POMAGMA_LOG_LEVEL = " << pomagma::DEFAULT_LOG_LEVEL << "\n"; POMAGMA_WARN("incorrect program args"); exit(1); } const char* structure_file = argv[1]; const char* language_file = argv[2]; const char* address = argv[3]; pomagma::Server server(structure_file, language_file); server.serve(address); return 0; }
void Server::trim(const std::vector<TrimTask>& tasks) { compact(m_structure); const size_t item_count = m_structure.carrier().item_count(); std::vector<TrimTask> sorted_tasks = tasks; std::sort(sorted_tasks.begin(), sorted_tasks.end(), [](const TrimTask& lhs, const TrimTask& rhs) { return lhs.size > rhs.size; }); const size_t task_count = sorted_tasks.size(); #pragma omp parallel for schedule(dynamic, 1) for (size_t iter = 0; iter < task_count; ++iter) { const TrimTask& task = sorted_tasks[iter]; if (task.size >= item_count) { if (task.size > item_count) { POMAGMA_WARN("trimming only " << item_count << " of " << task.size << " obs"); } m_structure.dump(task.filename); } else { Structure region; region.init_carrier(task.size); extend(region.signature(), m_structure.signature()); pomagma::trim(m_structure, region, m_theory_file, m_language_file, task.temperature); if (POMAGMA_DEBUG_LEVEL > 1) { region.validate(); } region.dump(task.filename); } } }
size_t Approximator::test_less() { POMAGMA_INFO("Testing LESS closure"); size_t fail_count = 0; const size_t item_dim = m_item_dim; #pragma omp parallel { Approximation actual(item_dim, m_top, m_bot); DenseSet temp_set(m_item_dim); #pragma omp for schedule(dynamic, 1) for (Ob x = 1; x <= item_dim; ++x) { Approximation expected(x, m_less); actual = expected; close(actual, temp_set); if (actual != expected) { #pragma omp atomic fail_count += 1; } } } if (fail_count) { POMAGMA_WARN("LESS failed " << fail_count << " cases"); } return fail_count; }
size_t Server::infer (size_t priority) { size_t theorem_count = 0; switch (priority) { case 0: theorem_count = infer_pos(m_structure); break; case 1: theorem_count = infer_neg(m_structure); break; default: POMAGMA_WARN("unknown priority: " << priority); break; } if (POMAGMA_DEBUG_LEVEL > 1) { m_structure.validate(); } return theorem_count; }
size_t Approximator::test() { POMAGMA_INFO("Testing approximator"); size_t fail_count = 0; fail_count += test_less(); for (auto pair : m_structure.signature().binary_functions()) { fail_count += test_function(pair.first, *pair.second); } for (auto pair : m_structure.signature().symmetric_functions()) { fail_count += test_function(pair.first, *pair.second); } if (fail_count) { POMAGMA_WARN("Failed approximator test"); } else { POMAGMA_INFO("Passed approximator test"); } return fail_count; }
size_t Approximator::test_function(const std::string& name, const Function& fun) { POMAGMA_INFO("Testing " << name << " approximation"); size_t ob_fail_count = 0; size_t upper_fail_count = 0; size_t upper_extra_count = 0; size_t upper_missing_count = 0; size_t lower_fail_count = 0; size_t lower_extra_count = 0; size_t lower_missing_count = 0; const size_t item_dim = m_item_dim; #pragma omp parallel { DenseSet temp_set(item_dim); #pragma omp for schedule(dynamic, 1) for (Ob x = 1; x <= item_dim; ++x) { Approximation approx_x(x, m_less); approx_x.ob = 0; for (auto iter = fun.iter_lhs(x); iter.ok(); iter.next()) { Ob y = *iter; Approximation approx_y(y, m_less); approx_y.ob = 0; Ob xy = fun.find(x, y); Approximation expected(xy, m_less); Approximation actual = find(fun, approx_x, approx_y); if (actual.ob != expected.ob) { #pragma omp atomic ob_fail_count += 1; } if (actual.upper != expected.upper) { #pragma omp atomic upper_fail_count += 1; temp_set.set_diff(actual.upper, expected.upper); if (size_t count = temp_set.count_items()) { #pragma omp atomic upper_extra_count += count; } temp_set.set_diff(expected.upper, actual.upper); if (size_t count = temp_set.count_items()) { #pragma omp atomic upper_missing_count += count; } } if (actual.lower != expected.lower) { #pragma omp atomic lower_fail_count += 1; temp_set.set_diff(actual.lower, expected.lower); if (size_t count = temp_set.count_items()) { #pragma omp atomic lower_extra_count += count; } temp_set.set_diff(expected.lower, actual.lower); if (size_t count = temp_set.count_items()) { #pragma omp atomic lower_missing_count += count; } } } } } if (ob_fail_count) { POMAGMA_WARN(name << " ob failed " << ob_fail_count << " cases"); } if (upper_missing_count or upper_extra_count) { POMAGMA_WARN(name << " upper has " << upper_missing_count << " missing and " << upper_extra_count << " extra obs in " << upper_fail_count << " cases"); } if (lower_missing_count or lower_extra_count) { POMAGMA_WARN(name << " lower has " << lower_missing_count << " missing and " << lower_extra_count << " extra obs in " << lower_fail_count << " cases"); } return ob_fail_count + upper_fail_count + lower_fail_count; }
Server::~Server() { for (const std::string& message : m_error_log) { POMAGMA_WARN(message); } }