Skip to content

Commit

Permalink
Adjust error handling.
Browse files Browse the repository at this point in the history
* Replace naked throw statements with POTASSCO-error macros were
  possible and add fail{Option,Value} functions for throwing
  option related errors.
  • Loading branch information
BenKaufmann committed Mar 25, 2024
1 parent eb0b28d commit e7973f1
Show file tree
Hide file tree
Showing 15 changed files with 108 additions and 102 deletions.
4 changes: 2 additions & 2 deletions clasp/dependency_graph.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
//
// Copyright (c) 2010-2017 Benjamin Kaufmann
// Copyright (c) 2010-present Benjamin Kaufmann
//
// This file is part of Clasp. See http://www.cs.uni-potsdam.de/clasp/
//
Expand Down Expand Up @@ -197,7 +197,7 @@ class PrgDepGraph {
//! Heads (i.e. successors): atoms from same SCC precede those from other SCCs.
/*!
* \note Disjunctive heads are stored in flattened atom-lists, where the
* lists are terminated on both ends with the special sentinal atom 0.
* lists are terminated on both ends with the special sentinel atom 0.
* E.g. given
* x :- B.
* y :- B.
Expand Down
15 changes: 4 additions & 11 deletions clasp/logic_program.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
//
// Copyright (c) 2013-2017 Benjamin Kaufmann
// Copyright (c) 2013-present Benjamin Kaufmann
//
// This file is part of Clasp. See http://www.cs.uni-potsdam.de/clasp/
//
Expand Down Expand Up @@ -118,22 +118,15 @@ class LpStats {
private:
uint32 eqs_[3];
};
//! Exception type for signaling an invalid incremental program update.
class RedefinitionError : public std::logic_error {
public:
explicit RedefinitionError(unsigned atomId, const char* atomName = "");
unsigned atom() const { return atomId_; }
private:
unsigned atomId_;
};

using Potassco::TheoryData;
struct MapLit_t {
POTASSCO_ENUM_CONSTANTS(MapLit_t, Raw = 0, Refined = 1);
};

//! A class for defining a logic program.
/*!
* Use this class to specify a logic program. Once the program is completly defined,
* Use this class to specify a logic program. Once the program is completely defined,
* call endProgram() to load the logic program into a SharedContext object.
*/
class LogicProgram : public ProgramBuilder {
Expand Down Expand Up @@ -328,7 +321,7 @@ class LogicProgram : public ProgramBuilder {
* is neither tautological (e.g. a :- a) nor contradictory (e.g. a :- b, not b).
* Atoms in the simplified rule that are not yet known are implicitly created.
*
* \throws RedefinitionError if the precondition is violated.
* \throws std::logic_error if the precondition is violated.
* \note If the head of the simplified rule mentions an atom from a previous step,
* that atom shall either be frozen or false. In the former case,
* unfreeze() is implicitly called. In the latter case, the rule is interpreted
Expand Down
51 changes: 24 additions & 27 deletions clasp/mt/parallel_solve.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
//
// Copyright (c) 2010-2017 Benjamin Kaufmann
// Copyright (c) 2010-present Benjamin Kaufmann
//
// This file is part of Clasp. See http://www.cs.uni-potsdam.de/clasp/
//
Expand Down Expand Up @@ -142,39 +142,37 @@ class ParallelSolve : public SolveAlgorithm {
ParallelSolve(const ParallelSolve&);
ParallelSolve& operator=(const ParallelSolve&);
typedef SingleOwnerPtr<const LitVec> PathPtr;
enum ErrorCode { LogicError = 1, RuntimeError = 2, OutOfMemory = 3, UnknownError = 4 };
enum { masterId = 0 };
enum { masterId = 0 };
// -------------------------------------------------------------------------------------------
// Thread setup
struct EntryPoint;
void destroyThread(uint32 id);
void allocThread(uint32 id, Solver& s);
int joinThreads();
void destroyThread(uint32 id);
void allocThread(uint32 id, Solver& s);
int joinThreads();
// -------------------------------------------------------------------------------------------
// Algorithm steps
void setIntegrate(uint32 grace, uint8 filter);
void setRestarts(uint32 maxR, const ScheduleStrategy& rs);
bool beginSolve(SharedContext& ctx, const LitVec& assume);
bool doSolve(SharedContext& ctx, const LitVec& assume);
void doStart(SharedContext& ctx, const LitVec& assume);
int doNext(int last);
void doStop();
void doDetach();
bool doInterrupt();
void solveParallel(uint32 id);
void initQueue();
bool requestWork(Solver& s, PathPtr& out);
void terminate(Solver& s, bool complete);
bool waitOnSync(Solver& s);
void exception(uint32 id, PathPtr& path, ErrorCode e, const char* what);
void reportProgress(const Event& ev) const;
void reportProgress(const Solver& s, const char* msg) const;
void setIntegrate(uint32 grace, uint8 filter);
void setRestarts(uint32 maxR, const ScheduleStrategy& rs);
bool beginSolve(SharedContext& ctx, const LitVec& assume);
bool doSolve(SharedContext& ctx, const LitVec& assume);
void doStart(SharedContext& ctx, const LitVec& assume);
int doNext(int last);
void doStop();
void doDetach();
bool doInterrupt();
void solveParallel(uint32 id);
void initQueue();
bool requestWork(Solver& s, PathPtr& out);
void terminate(Solver& s, bool complete);
bool waitOnSync(Solver& s);
void exception(uint32 id, PathPtr& path, int err, const char* what);
void reportProgress(const Event& ev) const;
void reportProgress(const Solver& s, const char* msg) const;
// -------------------------------------------------------------------------------------------
typedef ParallelSolveOptions::Distribution Distribution;
struct SharedData;
// SHARED DATA
SharedData* shared_; // Shared control data
ParallelHandler** thread_; // Thread-locl control data
ParallelHandler** thread_; // Thread-local control data
// READ ONLY
Distribution distribution_; // distribution options
uint32 maxRestarts_; // disable global restarts once reached
Expand Down Expand Up @@ -355,13 +353,12 @@ class LocalDistribution : public Distributor {
private:
typedef Detail::RawStack RawStack;
typedef MPSCPtrQueue::Node QNode;
enum { BLOCK_CAP = 128 };
QNode* allocNode(uint32 tId, SharedLiterals* clause);
void freeNode(uint32 tId, QNode* n) const;
struct ThreadData {
MPSCPtrQueue received; // queue holding received clauses
uint64 peers; // set of peers from which this thread receives clauses
QNode sentinal; // sentinal node for simplifying queue impl
QNode sentinel; // sentinel node for simplifying queue impl
QNode* free; // local free list - only accessed by this thread
}** thread_; // one entry for each thread
RawStack blocks_; // allocated node blocks
Expand Down
2 changes: 1 addition & 1 deletion libpotassco
18 changes: 9 additions & 9 deletions src/clasp_facade.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
//
// Copyright (c) 2006-2017 Benjamin Kaufmann
// Copyright (c) 2006-present Benjamin Kaufmann
//
// This file is part of Clasp. See http://www.cs.uni-potsdam.de/clasp/
//
Expand Down Expand Up @@ -229,7 +229,7 @@ struct ClaspFacade::SolveStrategy {
}
Result result() {
wait(-1.0);
if (error()) { throw std::runtime_error(error_.c_str()); }
POTASSCO_EXPECT(!error(), error_.c_str());
return result_;
}
const Model* model() {
Expand Down Expand Up @@ -346,9 +346,9 @@ void ClaspFacade::SolveStrategy::detachAlgo(bool more, int nException, int state
try {
if (nException == 1) { throw; }
switch (state) {
case 0: ++state; PROTECT(nException, algo_->stop()); // FALLTHRU
case 1: ++state; PROTECT(nException, facade_->stopStep(signal_, !more)); // FALLTHRU
case 2: ++state; if (handler_) { PROTECT(nException, handler_->onEvent(StepReady(facade_->summary()))); } // FALLTHRU
case 0: ++state; PROTECT(nException, algo_->stop()); // FALLTHROUGH
case 1: ++state; PROTECT(nException, facade_->stopStep(signal_, !more)); // FALLTHROUGH
case 2: ++state; if (handler_) { PROTECT(nException, handler_->onEvent(StepReady(facade_->summary()))); } // FALLTHROUGH
case 3: state = -1;
result_ = facade_->result();
facade_->assume_.resize(aTop_);
Expand Down Expand Up @@ -426,7 +426,7 @@ ClaspFacade::SolveStrategy* ClaspFacade::SolveStrategy::create(SolveMode_t m, Cl
#if CLASP_HAS_THREADS
return new SolveStrategy::Async(m, f, &algo);
#else
throw std::logic_error("Solve mode not supported!");
POTASSCO_REQUIRE(CLASP_HAS_THREADS, "Solve mode not supported!");
#endif
}
/////////////////////////////////////////////////////////////////////////////////////////
Expand Down Expand Up @@ -577,12 +577,12 @@ struct SummaryStats {
range_ = r;
}
uint32 size() const { return range_.hi - range_.lo; }
const char* key(uint32 i) const { return i < size() ? sumKeys_s[i + range_.lo].key : throw std::out_of_range(POTASSCO_FUNC_NAME); }
const char* key(uint32 i) const { POTASSCO_CHECK(i < size(), ERANGE); return sumKeys_s[i + range_.lo].key; }
StatisticObject at(const char* key) const {
for (const KV* x = sumKeys_s + range_.lo, *end = sumKeys_s + range_.hi; x != end; ++x) {
if (std::strcmp(x->key, key) == 0) { return x->get(stats_); }
}
throw std::out_of_range(POTASSCO_FUNC_NAME);
POTASSCO_CHECK(false, ERANGE);
}
StatisticObject toStats() const { return StatisticObject::map(this); }
const ClaspFacade::Summary* stats_;
Expand Down Expand Up @@ -833,7 +833,7 @@ ProgramBuilder& ClaspFacade::start(ClaspConfig& config, ProblemType t) {
if (t == Problem_t::Sat) { return startSat(config); }
else if (t == Problem_t::Pb) { return startPB(config); }
else if (t == Problem_t::Asp) { return startAsp(config); }
else { throw std::domain_error("Unknown problem type!"); }
else { POTASSCO_CHECK(false, EDOM, "Unknown problem type!"); }
}

ProgramBuilder& ClaspFacade::start(ClaspConfig& config, std::istream& str) {
Expand Down
34 changes: 27 additions & 7 deletions src/clasp_options.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
//
// Copyright (c) 2006-2017 Benjamin Kaufmann
// Copyright (c) 2006-present Benjamin Kaufmann
//
// This file is part of Clasp. See http://www.cs.uni-potsdam.de/clasp/
//
Expand Down Expand Up @@ -185,6 +185,26 @@ static std::string& xconvert(std::string& out, const Set<ET>& x) {
}
namespace Clasp {
/////////////////////////////////////////////////////////////////////////////////////////
// Errors
/////////////////////////////////////////////////////////////////////////////////////////
typedef Potassco::ProgramOptions::ContextError OptionError;
typedef Potassco::ProgramOptions::ValueError ValueError;
POTASSCO_ATTR_NORETURN void failOption(OptionError::Type type, const std::string& ctx, const std::string& opt,
const std::string& desc = "") {
using namespace Potassco::ProgramOptions;
switch (type) {
case OptionError::unknown_option: throw UnknownOption(ctx, opt);
case OptionError::ambiguous_option: throw AmbiguousOption(ctx, opt, desc);
default: throw ContextError(ctx, type, opt, desc);
}
}

POTASSCO_ATTR_NORETURN void failValue(ValueError::Type type, const std::string& ctx, const std::string& opt,
const std::string& value) {
using namespace Potassco::ProgramOptions;
throw ValueError(ctx, type, opt, value);
}
/////////////////////////////////////////////////////////////////////////////////////////
// Enum mappings for clasp types
/////////////////////////////////////////////////////////////////////////////////////////
#define MAP(x, y) {static_cast<const char*>(x), static_cast<int>(y)}
Expand Down Expand Up @@ -531,7 +551,7 @@ class ClaspCliConfig::ProgOption : public Potassco::ProgramOptions::Value {
ProgOption(ClaspCliConfig& c, int o) : Potassco::ProgramOptions::Value(0), config_(&c), option_(o) {}
bool doParse(const std::string& opt, const std::string& value) {
int ret = isOption(option_) ? config_->setActive(option_, value.c_str()) : config_->setAppOpt(option_, value.c_str());
if (ret == -1) { throw Potassco::ProgramOptions::UnknownOption(config_->isGenerator() ? "<clasp>" : "<tester>", opt); }
if (ret == -1) { failOption(OptionError::unknown_option, config_->isGenerator() ? "<clasp>" : "<tester>", opt); }
return ret > 0;
}
int option() const { return option_; }
Expand All @@ -546,7 +566,7 @@ struct ClaspCliConfig::ParseContext : public Potassco::ProgramOptions::ParseCont
ParseContext(ClaspCliConfig& x, const char* c, const ParsedOpts* ex, bool allowMeta, ParsedOpts* o)
: self(&x), config(c), exclude(ex), out(o), meta(allowMeta) { seen[0] = seen[1] = 0; }
OptPtr getOption(const char* name, FindType ft);
OptPtr getOption(int, const char* key) { throw Potassco::ProgramOptions::UnknownOption(config, key); }
OptPtr getOption(int, const char* key) { failOption(OptionError::unknown_option, config, key); }
void addValue(const OptPtr& key, const std::string& value);
uint64 seen[2];
std::string temp;
Expand All @@ -564,8 +584,8 @@ void ClaspCliConfig::ParseContext::addValue(const OptPtr& key, const std::string
int id = v->option();
uint64& xs = seen[id/64];
uint64 m = static_cast<uint64>(1u) << (id & 63);
if ((xs & m) != 0 && !v->isComposing()){ throw ValueError(config, ValueError::multiple_occurrences, key->name(), value); }
if (!v->parse(key->name(), value, s)) { throw ValueError(config, ValueError::invalid_value, key->name(), value); }
if ((xs & m) != 0 && !v->isComposing()){ failValue(ValueError::multiple_occurrences, config, key->name(), value); }
if (!v->parse(key->name(), value, s)) { failValue(ValueError::invalid_value, config, key->name(), value); }
if (out) { out->add(key->name()); }
xs |= m;
}
Expand All @@ -588,7 +608,7 @@ Potassco::ProgramOptions::SharedOptPtr ClaspCliConfig::ParseContext::getOption(c
Name2Id* next = pos + 1;
cmp = next != self->index_g.end ? std::strncmp(key.name, next->name, len) : -1;
found = cmp != 0;
if (!found) { throw Potassco::ProgramOptions::AmbiguousOption(config, cmdName, ""); }
if (!found) { failOption(OptionError::ambiguous_option, config, cmdName); }
}
if (found) { it = self->opts_->begin() + pos->key; }
}
Expand All @@ -597,7 +617,7 @@ Potassco::ProgramOptions::SharedOptPtr ClaspCliConfig::ParseContext::getOption(c
if (it != end && (meta || isOption(static_cast<const ProgOption*>(it->get()->value())->option()))) {
return *it;
}
throw Potassco::ProgramOptions::UnknownOption(config, cmdName);
failOption(OptionError::unknown_option, config, cmdName);
}
/////////////////////////////////////////////////////////////////////////////////////////
// Default Configs
Expand Down
4 changes: 2 additions & 2 deletions src/dependency_graph.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
//
// Copyright (c) 2010-2017 Benjamin Kaufmann
// Copyright (c) 2010-present Benjamin Kaufmann
//
// This file is part of Clasp. See http://www.cs.uni-potsdam.de/clasp/
//
Expand Down Expand Up @@ -45,7 +45,7 @@ namespace Asp {
// class PrgDepGraph
/////////////////////////////////////////////////////////////////////////////////////////
PrgDepGraph::PrgDepGraph(NonHcfMapType m) {
// add sentinal atom needed for disjunctions
// add sentinel atom needed for disjunctions
createAtom(lit_false(), PrgNode::noScc);
VarVec adj; adj.push_back(idMax);
initAtom(sentinel_atom, 0, adj, 0);
Expand Down
14 changes: 8 additions & 6 deletions src/logic_program.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
//
// Copyright (c) 2013-2017 Benjamin Kaufmann
// Copyright (c) 2013-present Benjamin Kaufmann
//
// This file is part of Clasp. See http://www.cs.uni-potsdam.de/clasp/
//
Expand Down Expand Up @@ -147,7 +147,8 @@ uint32 LpStats::size() {
return (sizeof(lpStats_s)/sizeof(const char*))-1;
}
const char* LpStats::key(uint32 i) {
return i < size() ? lpStats_s[i] : throw std::out_of_range(POTASSCO_FUNC_NAME);
POTASSCO_CHECK(i < size(), ERANGE);
return lpStats_s[i];
}
StatisticObject LpStats::at(const char* k) const {
#define MAP_IF(x, A) if (std::strcmp(k, x) == 0) return A;
Expand All @@ -157,7 +158,7 @@ StatisticObject LpStats::at(const char* k) const {
#undef VALUE
#undef FUNC
#undef MAP_IF
throw std::out_of_range(POTASSCO_FUNC_NAME);
POTASSCO_CHECK(false, ERANGE);
}
#undef LP_STATS
/////////////////////////////////////////////////////////////////////////////////////////
Expand Down Expand Up @@ -570,10 +571,11 @@ void LogicProgram::accept(Potassco::AbstractProgram& out) {
// Program mutating functions
/////////////////////////////////////////////////////////////////////////////////////////
#define check_not_frozen() POTASSCO_REQUIRE(!frozen(), "Can't update frozen program!")
#define check_modular(x, atomId) (void)( (!!(x)) || (throw RedefinitionError((atomId), this->findName((atomId))), 0))
RedefinitionError::RedefinitionError(unsigned atomId, const char* name)
: std::logic_error(POTASSCO_FORMAT("redefinition of atom <'%s',%u>", name && *name ? name : "_", atomId)) {
static inline const char* getAtomName(const LogicProgram& prg, Atom_t a) {
const char* ret = prg.findName(a);
return ret && *ret ? ret : "_";
}
#define check_modular(x, atomId) POTASSCO_REQUIRE(x, "redefinition of atom <'%s',%u>", getAtomName(*this, (atomId)), (atomId))

Atom_t LogicProgram::newAtom() {
check_not_frozen();
Expand Down
Loading

0 comments on commit e7973f1

Please sign in to comment.