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(argumentsChar,
276 [
this](
const Clingo::WarningCode code,
char const *msg) {
279 case Clingo::WarningCode::AtomUndefined:
280 case Clingo::WarningCode::OperationUndefined:
281 case Clingo::WarningCode::RuntimeError:
284 case Clingo::WarningCode::Other:
285 case Clingo::WarningCode::VariableUnbounded:
288 case Clingo::WarningCode::FileIncluded:
289 case Clingo::WarningCode::GlobalVariable:
293 logger_->
log(level, log_comp_.c_str(), msg);
306 log_comp_(log_component.empty() ?
"Clingo" : log_component),
307 debug_level_(ASP_DBG_NONE),
309 thread_mode_splitting_(false),
310 control_is_locked_(false),
312 model_mutex_(
Mutex::RECURSIVE),
333 model_callbacks_.emplace_back(callback);
344 model_callbacks_.erase(std::find(model_callbacks_.begin(), model_callbacks_.end(), callback));
353 std::shared_ptr<std::function<
void(Clingo::SolveResult)>> callback)
356 finish_callbacks_.emplace_back(callback);
365 std::shared_ptr<std::function<
void(Clingo::SolveResult)>> callback)
368 finish_callbacks_.erase(std::find(finish_callbacks_.begin(), finish_callbacks_.end(), callback));
379 ground_callback_ = std::move(callback);
403 logger_->
log_info(log_comp_.c_str(),
"Start async solving.");
410 async_handle_ = control_->solve(Clingo::SymbolicLiteralSpan{},
this,
true,
true);
428 logger_->
log_info(log_comp_.c_str(),
"Start sync solving.");
435 control_->solve(Clingo::SymbolicLiteralSpan{},
this,
false,
true);
451 logger_->
log_info(log_comp_.c_str(),
"Cancel solving.");
454 control_->interrupt();
466 logger_->
log_warn(log_comp_.c_str(),
467 "Could not reset while solving. " 468 "Please try again when the solving is stopped.");
472 logger_->
log_warn(log_comp_.c_str(),
"Resetting Clingo");
490 throw Exception(
"Tried to set the number of threads while Clingo was solving.");
493 throw Exception(
"Tried to set thread count to %d, only values >= 1 are valid.", threads);
495 logger_->
log_info(log_comp_.c_str(),
496 "Change # of threads for solving from %d to %d " 497 "and splitting from %s to %s.",
500 thread_mode_splitting_ ?
"true" :
"false",
501 thread_mode_splitting ?
"true" :
"false");
502 num_threads_ = threads;
503 thread_mode_splitting_ = thread_mode_splitting;
524 return debug_level_.load();
533 return debug_level_.store(log_level);
543 return model_symbols_;
558 logger_->
log_info(log_comp_.c_str(),
"Loading file program file %s.", path.c_str());
559 control_->load(path.c_str());
579 logger_->
log_info(log_comp_.c_str(),
"Grounding %zu parts:", parts.size());
582 for (
const Clingo::Part &part : parts) {
585 for (
const auto ¶m : part.params()) {
591 params += param.to_string();
593 logger_->
log_info(log_comp_.c_str(),
"Part #%d: %s [%s]", ++i, part.name(), params.c_str());
598 control_->ground(parts, ground_callback_);
601 logger_->
log_info(log_comp_.c_str(),
"Grounding done.");
620 logger_->
log_info(log_comp_.c_str(),
621 "Assigning %s to %s.",
623 const char *ret =
"Unknown Value";
625 case Clingo::TruthValue::Free: ret =
"Free";
break;
626 case Clingo::TruthValue::True: ret =
"True";
break;
627 case Clingo::TruthValue::False: ret =
"False";
break;
631 atom.to_string().c_str());
633 control_->assign_external(atom, value);
650 logger_->
log_info(log_comp_.c_str(),
"Releasing %s.", atom.to_string().c_str());
652 control_->release_external(atom);
bool start_solving(void)
Starts the solving process, if it isn't already running.
informational output about normal procedures
virtual void log_info(const char *component, const char *format,...)=0
Log informational message.
int num_threads(void) const noexcept
Returns how many threads Clingo should use.
bool load_file(const std::string &path)
Loads a file in the solver.
void relock(void)
Relock mutex after unlock.
Fawkes library namespace.
void unlock()
Unlock the mutex.
void unlock(void)
Unlock mutex.
Print which programs are grounded.
warning, should be investigated but software still functions, an example is that something was reques...
bool start_solving_blocking(void)
Starts the solving process.
Print assignments and releases of externals.
void set_debug_level(DebugLevel_t log_level)
Set debug level.
bool reset(void)
Tries to reset Clingo.
void set_ground_callback(Clingo::GroundCallback &&callback)
Sets the ground callback, to implement custom functions.
void unregister_model_callback(std::shared_ptr< std::function< bool(void)>> callback)
Unregisters a callback for the event of a new model.
bool release_external(const Clingo::Symbol &atom)
Releases an external value.
error, may be recoverable (software still running) or not (software has to terminate).
DebugLevel_t debug_level() const
Get current debug level.
Base class for exceptions in Fawkes.
Clingo::SymbolVector model_symbols(void) const
Returns a copy of the last symbols found.
void register_finish_callback(std::shared_ptr< std::function< void(Clingo::SolveResult)>> callback)
Registers a callback for the event of finishing the solving process.
~BoolMutexLocker(void)
Destructor.
DebugLevel_t
Debug levels, higher levels include the lower values.
void register_model_callback(std::shared_ptr< std::function< bool(void)>> callback)
Registers a callback for the event of a new model.
Print when starting/finishing grounding/solving for analysis.
virtual void log_warn(const char *component, const char *format,...)=0
Log warning message.
Ignore '#show' statements and print all symbols of a model.
void unregister_finish_callback(std::shared_ptr< std::function< void(Clingo::SolveResult)>> callback)
Unregisters a callback for the event of finishing the solving process.
bool solving(void) const noexcept
Returns whether the solving process is running.
bool ground(const Clingo::PartSpan &parts)
Grounds a program part.
BoolMutexLocker(Mutex *mutex, bool &associated_bool)
Constructor.
void set_num_threads(const int threads, const bool use_splitting=false)
Sets the number of threads Clingo should use.
void lock()
Lock this mutex.
ClingoAccess(Logger *logger, const std::string &log_component)
Constructor.
Mutex mutual exclusion lock.
virtual void log(LogLevel level, const char *component, const char *format,...)
Log message of given log level.
Helper class to incorporate bool into mutex locker with RAII.
~ClingoAccess(void)
Destructor.
use this to disable log output
bool assign_external(const Clingo::Symbol &atom, const bool value)
Assign external value.
bool cancel_solving(void)
Stops the solving process, if it is running.
Activates the –output-debug=text option for clingo.