23 #include "clingo_access.h"
25 #include <core/threading/mutex_locker.h>
26 #include <logging/logger.h>
43 : mutex_(mutex), bool_(associated_bool), initial_locked_(associated_bool)
45 if (!initial_locked_) {
54 if (initial_locked_ != bool_) {
55 if (initial_locked_) {
82 const bool initial_locked_;
174 ClingoAccess::on_model(Clingo::Model &model)
176 MutexLocker locker1(&model_mutex_);
177 model_symbols_ = model.symbols(
181 logger_->
log_info(log_comp_.c_str(),
182 "New %smodel found: #%d",
183 model.optimality_proven() ?
"optimal " :
"",
191 auto begin = old_symbols_.begin(), end = old_symbols_.end();
193 for (
const Clingo::Symbol &symbol : model_symbols_) {
194 auto iter = std::find(begin, end, symbol);
196 logger_->
log_info(log_comp_.c_str(),
"New Symbol: %s", symbol.to_string().c_str());
198 std::swap(*iter, *--end);
202 for (; begin != end; ++begin) {
203 logger_->
log_info(log_comp_.c_str(),
"Symbol removed: %s", begin->to_string().c_str());
208 old_symbols_ = model_symbols_;
212 MutexLocker locker2(&callback_mutex_);
213 for (
const auto &cb : model_callbacks_) {
225 ClingoAccess::on_finish(Clingo::SolveResult result)
228 logger_->
log_info(log_comp_.c_str(),
"Solving nearly done.");
231 BoolMutexLocker locker1(&control_mutex_, control_is_locked_);
232 MutexLocker locker2(&callback_mutex_);
233 for (
const auto &cb : finish_callbacks_) {
237 std::thread blocking_thread([
this](
void) {
238 async_handle_.wait();
240 logger_->
log_info(log_comp_.c_str(),
"Solving done.");
245 blocking_thread.detach();
253 ClingoAccess::alloc_control()
261 std::vector<std::string> argumentsString;
262 std::vector<const char *> argumentsChar;
265 argumentsChar.push_back(
"--output-debug=text");
268 if (num_threads_ != 1) {
269 std::stringstream s(
"-t ", std::ios_base::ate | std::ios_base::out);
270 s << num_threads_ <<
"," << (thread_mode_splitting_ ?
"split" :
"compete");
271 argumentsString.push_back(s.str());
272 argumentsChar.push_back(argumentsString.back().c_str());
275 control_ =
new Clingo::Control(
277 [
this](
const Clingo::WarningCode code,
char const *msg) {
280 case Clingo::WarningCode::AtomUndefined:
281 case Clingo::WarningCode::OperationUndefined:
283 case Clingo::WarningCode::Other:
285 case Clingo::WarningCode::FileIncluded:
288 logger_->
log(level, log_comp_.c_str(), msg);
301 log_comp_(log_component.empty() ?
"Clingo" : log_component),
302 debug_level_(ASP_DBG_NONE),
304 thread_mode_splitting_(false),
305 control_is_locked_(false),
307 model_mutex_(
Mutex::RECURSIVE),
328 model_callbacks_.emplace_back(callback);
339 model_callbacks_.erase(std::find(model_callbacks_.begin(), model_callbacks_.end(), callback));
348 std::shared_ptr<std::function<
void(Clingo::SolveResult)>> callback)
351 finish_callbacks_.emplace_back(callback);
360 std::shared_ptr<std::function<
void(Clingo::SolveResult)>> callback)
363 finish_callbacks_.erase(std::find(finish_callbacks_.begin(), finish_callbacks_.end(), callback));
374 ground_callback_ = std::move(callback);
398 logger_->
log_info(log_comp_.c_str(),
"Start async solving.");
405 async_handle_ = control_->solve(Clingo::SymbolicLiteralSpan{},
this,
true,
true);
423 logger_->
log_info(log_comp_.c_str(),
"Start sync solving.");
430 control_->solve(Clingo::SymbolicLiteralSpan{},
this,
false,
true);
446 logger_->
log_info(log_comp_.c_str(),
"Cancel solving.");
449 control_->interrupt();
461 logger_->
log_warn(log_comp_.c_str(),
462 "Could not reset while solving. "
463 "Please try again when the solving is stopped.");
467 logger_->
log_warn(log_comp_.c_str(),
"Resetting Clingo");
485 throw Exception(
"Tried to set the number of threads while Clingo was solving.");
488 throw Exception(
"Tried to set thread count to %d, only values >= 1 are valid.", threads);
490 logger_->
log_info(log_comp_.c_str(),
491 "Change # of threads for solving from %d to %d "
492 "and splitting from %s to %s.",
495 thread_mode_splitting_ ?
"true" :
"false",
496 thread_mode_splitting ?
"true" :
"false");
497 num_threads_ = threads;
498 thread_mode_splitting_ = thread_mode_splitting;
519 return debug_level_.load();
528 return debug_level_.store(log_level);
538 return model_symbols_;
553 logger_->
log_info(log_comp_.c_str(),
"Loading file program file %s.", path.c_str());
554 control_->load(path.c_str());
574 logger_->
log_info(log_comp_.c_str(),
"Grounding %zu parts:", parts.size());
577 for (
const Clingo::Part &part : parts) {
580 for (
const auto ¶m : part.params()) {
586 params += param.to_string();
588 logger_->
log_info(log_comp_.c_str(),
"Part #%d: %s [%s]", ++i, part.name(), params.c_str());
593 control_->ground(parts, ground_callback_);
596 logger_->
log_info(log_comp_.c_str(),
"Grounding done.");
617 "Assigning %s to %s.",
619 const char *ret =
"Unknown Value";
621 case Clingo::TruthValue::Free: ret =
"Free"; break;
622 case Clingo::TruthValue::True: ret =
"True"; break;
623 case Clingo::TruthValue::False: ret =
"False"; break;
627 atom.to_string().c_str());
629 control_->assign_external(atom, value);
638 ClingoAccess::release_external(
const Clingo::Symbol &atom)
645 if (debug_level_ >= ASP_DBG_EXTERNALS) {
646 logger_->log_info(log_comp_.c_str(),
"Releasing %s.", atom.to_string().c_str());
648 control_->release_external(atom);