diff --git a/src/core/algorithms/algorithm_types.h b/src/core/algorithms/algorithm_types.h index 2cbfc8e1d1..85fdeec69e 100644 --- a/src/core/algorithms/algorithm_types.h +++ b/src/core/algorithms/algorithm_types.h @@ -9,7 +9,8 @@ namespace algos { using AlgorithmTypes = std::tuple; + cfd::FDFirstAlgorithm, ACAlgorithm, UCCVerifier, GfdValidation, EGfdValidation, + NaiveGfdValidation>; // clang-format off /* Enumeration of all supported non-pipeline algorithms. If you implement a new @@ -58,7 +59,8 @@ BETTER_ENUM(AlgorithmType, char, /* Graph functional dependency mining algorithms */ gfdvalid, - egfdvalid + egfdvalid, + naivegfdvalid ) // clang-format on diff --git a/src/core/algorithms/algorithms.h b/src/core/algorithms/algorithms.h index 8afaae3383..72f3f7528b 100644 --- a/src/core/algorithms/algorithms.h +++ b/src/core/algorithms/algorithms.h @@ -38,3 +38,4 @@ /* Graph functional dependency mining algorithms */ #include "algorithms/gfd/egfd_validation.h" #include "algorithms/gfd/gfd_validation.h" +#include "algorithms/gfd/naivegfd_validation.h" diff --git a/src/core/algorithms/gfd/naivegfd_validation.cpp b/src/core/algorithms/gfd/naivegfd_validation.cpp new file mode 100644 index 0000000000..d00ff47b75 --- /dev/null +++ b/src/core/algorithms/gfd/naivegfd_validation.cpp @@ -0,0 +1,132 @@ +#include "naivegfd_validation.h" + +#include +#include + +#include + +#include "gfd.h" + +namespace { + +struct CheckCallback { +private: + graph_t const& query; + graph_t const& graph; + const std::vector premises; + const std::vector conclusion; + bool& res; + int& amount; + +public: + CheckCallback(graph_t const& query_, graph_t const& graph_, + std::vector const& premises_, std::vector const& conclusion_, + bool& res_, int& amount_) + : query(query_), + graph(graph_), + premises(premises_), + conclusion(conclusion_), + res(res_), + amount(amount_) {} + + template + bool operator()(CorrespondenceMap1To2 f, CorrespondenceMap2To1) const { + amount++; + auto satisfied = [this, &f](std::vector const& literals) { + for (const Literal& l : literals) { + auto fst_token = l.first; + auto snd_token = l.second; + std::string fst; + std::string snd; + if (fst_token.first == -1) { + fst = fst_token.second; + } else { + vertex_t v; + vertex_t u = boost::vertex(fst_token.first, query); + v = get(f, u); + auto attrs = graph[v].attributes; + if (attrs.find(fst_token.second) == attrs.end()) { + return false; + } + fst = attrs.at(fst_token.second); + } + if (snd_token.first == -1) { + snd = snd_token.second; + } else { + vertex_t v; + vertex_t u = boost::vertex(fst_token.first, query); + v = get(f, u); + auto attrs = graph[v].attributes; + if (attrs.find(snd_token.second) == attrs.end()) { + return false; + } + fst = attrs.at(snd_token.second); + } + if (fst != snd) { + return false; + } + } + return true; + }; + + if (!satisfied(premises)) { + return true; + } + if (!satisfied(conclusion)) { + res = false; + return false; + } + return true; + } +}; + +bool Validate(graph_t const& graph, Gfd const& gfd) { + graph_t pattern = gfd.GetPattern(); + + struct VCompare { + graph_t const& pattern; + graph_t const& graph; + + bool operator()(vertex_t fr, vertex_t to) const { + return pattern[fr].attributes.at("label") == graph[to].attributes.at("label"); + } + } vcompare{pattern, graph}; + + struct ECompare { + graph_t const& pattern; + graph_t const& graph; + + bool operator()(edge_t fr, edge_t to) const { + return pattern[fr].label == graph[to].label; + } + } ecompare{pattern, graph}; + + bool res = true; + int amount = 0; + CheckCallback callback(pattern, graph, gfd.GetPremises(), gfd.GetConclusion(), res, amount); + + bool found = boost::vf2_subgraph_iso( + pattern, graph, callback, get(boost::vertex_index, pattern), + get(boost::vertex_index, graph), vertex_order_by_mult(pattern), ecompare, vcompare); + std::cout << "Checked embeddings: " << amount << std::endl; + if (!found) { + return true; + } + return res; +} + +} // namespace + +namespace algos { + +std::vector NaiveGfdValidation::GenerateSatisfiedGfds(graph_t const& graph, + std::vector const& gfds) { + for (auto& gfd : gfds) { + if (Validate(graph, gfd)) { + result_.push_back(gfd); + } + } + return result_; +} + +} // namespace algos diff --git a/src/core/algorithms/gfd/naivegfd_validation.h b/src/core/algorithms/gfd/naivegfd_validation.h new file mode 100644 index 0000000000..e43af06b61 --- /dev/null +++ b/src/core/algorithms/gfd/naivegfd_validation.h @@ -0,0 +1,19 @@ +#pragma once +#include + +#include "algorithms/algorithm.h" +#include "algorithms/gfd/gfd_handler.h" +#include "gfd.h" + +namespace algos { + +class NaiveGfdValidation : public GfdHandler { +public: + std::vector GenerateSatisfiedGfds(graph_t const& graph, std::vector const& gfds); + + NaiveGfdValidation() : GfdHandler(){}; + + NaiveGfdValidation(graph_t graph_, std::vector gfds_) : GfdHandler(graph_, gfds_) {} +}; + +} // namespace algos