summaryrefslogtreecommitdiff
path: root/src/core/model
diff options
context:
space:
mode:
authorBenjamin Paassen <bpaassen@techfak.uni-bielefeld.de>2015-02-12 19:31:18 +0100
committerBenjamin Paassen <bpaassen@techfak.uni-bielefeld.de>2015-02-12 19:31:18 +0100
commit110fb7da850377e39b2879da44339dc936c266dc (patch)
treec421ed2ddf1d1371975fc8afd2745234fe859f75 /src/core/model
parentf0934f5484c58e7533f804735c8b31f7bcbc81e8 (diff)
further revised pathTo. Now only the TREE field is used in further exploration.
Diffstat (limited to 'src/core/model')
-rw-r--r--src/core/model/Domain.cpp50
-rw-r--r--src/core/model/Domain.hpp18
2 files changed, 44 insertions, 24 deletions
diff --git a/src/core/model/Domain.cpp b/src/core/model/Domain.cpp
index 25b2528..619454c 100644
--- a/src/core/model/Domain.cpp
+++ b/src/core/model/Domain.cpp
@@ -212,7 +212,7 @@ bool Descriptor::doValidate(Logger &logger) const
struct PathState {
std::shared_ptr<PathState> pred;
Node *node;
- int length;
+ size_t length;
PathState(std::shared_ptr<PathState> pred, Node *node)
: pred(pred), node(node)
@@ -234,10 +234,12 @@ static void constructPath(std::shared_ptr<PathState> state,
vec.push_back(state->node);
}
-template <typename F>
static NodeVector<Node> pathTo(const Descriptor *start, Logger &logger,
- F finished)
+ Handle<Node> target, bool &success)
{
+ success = false;
+ // shortest path.
+ NodeVector<Node> shortest;
// state queue for breadth-first search.
std::queue<std::shared_ptr<PathState>> states;
{
@@ -245,11 +247,16 @@ static NodeVector<Node> pathTo(const Descriptor *start, Logger &logger,
NodeVector<FieldDescriptor> fields = start->getFieldDescriptors();
for (auto fd : fields) {
- states.push(std::make_shared<PathState>(nullptr, fd.get()));
+ if (fd == target) {
+ // if we have found the target directly, return without search.
+ success = true;
+ return shortest;
+ }
+ if (fd->getFieldType() == FieldDescriptor::FieldType::TREE) {
+ states.push(std::make_shared<PathState>(nullptr, fd.get()));
+ }
}
}
- // shortest path.
- NodeVector<Node> shortest;
// set of visited nodes.
std::unordered_set<const Node *> visited;
while (!states.empty()) {
@@ -270,15 +277,18 @@ static NodeVector<Node> pathTo(const Descriptor *start, Logger &logger,
const StructuredClass *strct =
static_cast<const StructuredClass *>(current->node);
- // continue the search path via all fields.
+ // look through all fields.
NodeVector<FieldDescriptor> fields = strct->getFieldDescriptors();
for (auto fd : fields) {
// if we found our target, break off the search in this branch.
- if (finished(fd)) {
+ if (fd == target) {
fin = true;
continue;
}
- states.push(std::make_shared<PathState>(current, fd.get()));
+ // only continue in the TREE field.
+ if (fd->getFieldType() == FieldDescriptor::FieldType::TREE) {
+ states.push(std::make_shared<PathState>(current, fd.get()));
+ }
}
/*
@@ -290,7 +300,7 @@ static NodeVector<Node> pathTo(const Descriptor *start, Logger &logger,
NodeVector<StructuredClass> subs = strct->getSubclasses();
for (auto sub : subs) {
// if we found our target, break off the search in this branch.
- if (finished(sub)) {
+ if (sub == target) {
fin = true;
current = current->pred;
continue;
@@ -308,7 +318,7 @@ static NodeVector<Node> pathTo(const Descriptor *start, Logger &logger,
// and we proceed by visiting all permitted children.
for (auto c : field->getChildren()) {
// if we found our target, break off the search in this branch.
- if (finished(c)) {
+ if (c == target) {
fin = true;
continue;
}
@@ -320,6 +330,7 @@ static NodeVector<Node> pathTo(const Descriptor *start, Logger &logger,
}
// check if we are finished.
if (fin) {
+ success = true;
// if so we look if we found a shorter path than the current minimum
if (shortest.empty() || current->length < shortest.size()) {
NodeVector<Node> newPath;
@@ -332,7 +343,7 @@ static NodeVector<Node> pathTo(const Descriptor *start, Logger &logger,
constructPath(current, newPath);
logger.error(
std::string("Can not unambigously create a path from \"") +
- start->getName() + "\".");
+ start->getName() + "\" to \"" + target->getName() + "\".");
logger.note("Dismissed the path:", SourceLocation{},
MessageMode::NO_CONTEXT);
for (auto n : newPath) {
@@ -347,15 +358,18 @@ static NodeVector<Node> pathTo(const Descriptor *start, Logger &logger,
NodeVector<Node> Descriptor::pathTo(Handle<StructuredClass> target,
Logger &logger) const
{
- return ousia::pathTo(this, logger,
- [target](Handle<Node> n) { return n == target; });
+ bool success = false;
+ return ousia::pathTo(this, logger, target, success);
}
-NodeVector<Node> Descriptor::pathTo(Handle<FieldDescriptor> field,
- Logger &logger) const
+std::pair<NodeVector<Node>, bool> Descriptor::pathTo(
+ Handle<FieldDescriptor> field, Logger &logger) const
+{
+ bool success = false;
+ NodeVector<Node> path = ousia::pathTo(this, logger, field, success);
+ return std::make_pair(path, success);
+}
{
- return ousia::pathTo(this, logger,
- [field](Handle<Node> n) { return n == field; });
}
static ssize_t getFieldDescriptorIndex(const NodeVector<FieldDescriptor> &fds,
diff --git a/src/core/model/Domain.hpp b/src/core/model/Domain.hpp
index abe7a52..91d635e 100644
--- a/src/core/model/Domain.hpp
+++ b/src/core/model/Domain.hpp
@@ -593,19 +593,25 @@ public:
Logger &logger) const;
/**
* This tries to construct the shortest possible path of this Descriptor
- * to the given FieldDescriptor.
+ * to the given FieldDescriptor. Note that this method has the problem that
+ * an empty return path does NOT strictly imply that no such path could
+ * be constructed: We also return an empty vector if the given
+ * FieldDescriptor is a direct child. Therefore we also return a bool value
+ * indicating that the path is valid or not.
+ *
*
* Implicitly this does a breadth-first search on the graph of
* StructuredClasses that are transparent. It also takes care of cycles.
*
* @param field is a FieldDescriptor that may be allowed as child of this
* Descriptor.
- * @return either a path of FieldDescriptors and StructuredClasses
- * between this Descriptor and the input FieldDescriptor or an
- * empty vector if no such path can be constructed.
+ * @return returns a tuple containing a path of FieldDescriptors and
+ * StructuredClasses between this Descriptor and the input
+ * FieldDescriptor and a bool value indicating if the
+ * construction was successful.
*/
- NodeVector<Node> pathTo(Handle<FieldDescriptor> field,
- Logger &logger) const;
+ std::pair<NodeVector<Node>, bool> pathTo(Handle<FieldDescriptor> field,
+ Logger &logger) const;
};
/*
* TODO: We should discuss Cardinalities one more time. Is it smart to define