Skip to content

Commit

Permalink
[hax] add config.dg.doRuleIsomorphismDuringBinding
Browse files Browse the repository at this point in the history
  • Loading branch information
jakobandersen committed Jun 12, 2024
1 parent c0f3e85 commit 7bd0455
Show file tree
Hide file tree
Showing 5 changed files with 46 additions and 31 deletions.
3 changes: 2 additions & 1 deletion libs/libmod/src/mod/Config.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -341,6 +341,7 @@ struct Config {
((bool, disableRepeatFixedPointCheck, false)) \
((bool, applyAssumeConfluence, false)) \
((int, applyLimit, -1)) \
((bool, doRuleIsomorphismDuringBinding, true)) \
)) \
((Graph, graph, \
((bool, smilesCheckAST, false)) \
Expand Down Expand Up @@ -399,7 +400,7 @@ struct Config {
#define MOD_toString(s) MOD_toString1(s)
#define MOD_toString1(s) #s

BOOST_PP_SEQ_FOR_EACH(MOD_CONFIG_nsIter, ~, MOD_CONFIG_DATA())
BOOST_PP_SEQ_FOR_EACH(MOD_CONFIG_nsIter, ~, MOD_CONFIG_DATA())

#undef MOD_CONFIG_settingIterCons
#undef MOD_CONFIG_settingIter
Expand Down
31 changes: 20 additions & 11 deletions libs/libmod/src/mod/lib/DG/NonHyperBuilder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ void ExecuteResult::list(bool withUniverse) const {
// -----------------------------------------------------------------------------

Builder::Builder(NonHyperBuilder *dg,
std::shared_ptr<Function<void(dg::DG::Vertex)>> onNewVertex,
std::shared_ptr<Function<void(dg::DG::Vertex)>> onNewVertex,
std::shared_ptr<Function<void(dg::DG::HyperEdge)>> onNewHyperEdge) : dg(dg) {
if(dg->getHasCalculated()) {
this->dg = nullptr;
Expand Down Expand Up @@ -103,8 +103,9 @@ std::pair<NonHyper::Edge, bool> Builder::addDerivation(const Derivations &d, Iso
}

struct NonHyperBuilder::ExecutionEnv final : public Strategies::ExecutionEnv {
ExecutionEnv(NonHyperBuilder &owner, LabelSettings labelSettings, Rules::GraphAsRuleCache &graphAsRuleCache)
: Strategies::ExecutionEnv(labelSettings, graphAsRuleCache), owner(owner) {}
ExecutionEnv(NonHyperBuilder &owner, LabelSettings labelSettings, bool doRuleIsomorphism,
Rules::GraphAsRuleCache &graphAsRuleCache)
: Strategies::ExecutionEnv(labelSettings, doRuleIsomorphism, graphAsRuleCache), owner(owner) {}

void tryAddGraph(std::shared_ptr<graph::Graph> gCand) override {
owner.tryAddGraph(gCand);
Expand Down Expand Up @@ -184,8 +185,10 @@ struct NonHyperBuilder::ExecutionEnv final : public Strategies::ExecutionEnv {

ExecuteResult
Builder::execute(std::unique_ptr<Strategies::Strategy> strategy_, int verbosity, bool ignoreRuleLabelTypes) {
const bool doRuleIsomorphism = getConfig().dg.doRuleIsomorphismDuringBinding.get();
NonHyperBuilder::StrategyExecution exec{
std::make_unique<NonHyperBuilder::ExecutionEnv>(*dg, dg->getLabelSettings(), dg->graphAsRuleCache),
std::make_unique<NonHyperBuilder::ExecutionEnv>(*dg, dg->getLabelSettings(), doRuleIsomorphism,
dg->graphAsRuleCache),
std::make_unique<Strategies::GraphState>(),
std::move(strategy_)
};
Expand All @@ -196,8 +199,9 @@ Builder::execute(std::unique_ptr<Strategies::Strategy> strategy_, int verbosity,
if(dg->getLabelSettings().type == LabelType::Term) {
const auto &term = get_term(gCand->getGraph().getLabelledGraph());
if(!isValid(term)) {
std::string msg = "Parsing failed for graph '" + gCand->getName() + "' in static add strategy. " +
term.getParsingError();
std::string msg =
"Parsing failed for graph '" + gCand->getName() + "' in static add strategy. " +
term.getParsingError();
throw TermParsingError(std::move(msg));
}
}
Expand Down Expand Up @@ -232,6 +236,7 @@ std::vector<std::pair<NonHyper::Edge, bool>>
Builder::apply(const std::vector<std::shared_ptr<graph::Graph>> &graphs,
std::shared_ptr<rule::Rule> rOrig,
int verbosity, IsomorphismPolicy graphPolicy) {
const bool doRuleIsomorphism = getConfig().dg.doRuleIsomorphismDuringBinding.get();
IO::Logger logger(std::cout);
dg->rules.insert(rOrig);
switch(graphPolicy) {
Expand Down Expand Up @@ -288,7 +293,7 @@ Builder::apply(const std::vector<std::shared_ptr<graph::Graph>> &graphs,
verbosity, logger,
round,
firstGraph, firstGraph + round + 1, inputRules,
dg->graphAsRuleCache, ls,
dg->graphAsRuleCache, ls, doRuleIsomorphism,
onOutput);
for(BoundRule &br: outputRules) {
// always go to the next graph
Expand Down Expand Up @@ -353,6 +358,7 @@ std::vector<std::pair<NonHyper::Edge, bool>>
Builder::applyRelaxed(const std::vector<std::shared_ptr<graph::Graph>> &graphs,
std::shared_ptr<rule::Rule> rOrig,
int verbosity, IsomorphismPolicy graphPolicy) {
const bool doRuleIsomorphism = getConfig().dg.doRuleIsomorphismDuringBinding.get();
IO::Logger logger(std::cout);
dg->rules.insert(rOrig);
switch(graphPolicy) {
Expand Down Expand Up @@ -439,7 +445,7 @@ Builder::applyRelaxed(const std::vector<std::shared_ptr<graph::Graph>> &graphs,
(verbosity, logger,
round,
firstGraph, lastGraph, inputRules,
dg->graphAsRuleCache, ls,
dg->graphAsRuleCache, ls, doRuleIsomorphism,
onOutput);
for(BoundRule &br: outputRules) {
// always go to the next graph
Expand Down Expand Up @@ -656,15 +662,17 @@ bool Builder::trustLoadDump(nlohmann::json &&j,
for(int src: e[1]) {
auto gIter = graphFromId.find(src);
if(gIter == end(graphFromId)) {
err << "Corrupt data for edge " << e[0].get<int>() << ". Source " << src << " is not a yet a vertex.";
err << "Corrupt data for edge " << e[0].get<int>() << ". Source " << src
<< " is not a yet a vertex.";
return false;
}
srcGraphs.push_back(gIter->second);
}
for(int tar: e[2]) {
auto gIter = graphFromId.find(tar);
if(gIter == end(graphFromId)) {
err << "Corrupt data for edge " << e[0].get<int>() << ". Target " << tar << " is not a yet a vertex.";
err << "Corrupt data for edge " << e[0].get<int>() << ". Target " << tar
<< " is not a yet a vertex.";
return false;
}
tarGraphs.push_back(gIter->second);
Expand All @@ -676,7 +684,8 @@ bool Builder::trustLoadDump(nlohmann::json &&j,
} else {
for(const int rId: ruleIds) {
if(rId < 0 || rId >= rules.size()) {
err << "Corrupt data for edge " << e[0].get<int>() << ". Rule offset " << rId << " is not in range.";
err << "Corrupt data for edge " << e[0].get<int>() << ". Rule offset " << rId
<< " is not in range.";
return false;
}
const auto r = rules[rId];
Expand Down
37 changes: 20 additions & 17 deletions libs/libmod/src/mod/lib/DG/RuleApplicationUtils.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ struct BoundRule {
friend std::ostream &operator<<(std::ostream &s, const BoundRule &br) {
s << "{rule=" << br.rule->getName() << ", boundGraphs=[";
bool first = true;
for(const auto *g : br.boundGraphs) {
for(const auto *g: br.boundGraphs) {
if(!first) s << ", ";
else first = false;
s << g->getName();
Expand Down Expand Up @@ -67,6 +67,7 @@ template<typename Iter, typename OnOutput>
const std::vector<BoundRule> &inputRules,
Rules::GraphAsRuleCache &graphAsRuleCache,
const LabelSettings labelSettings,
const bool doRuleIsomorphism,
OnOutput onOutput) {
if(verbosity >= V_RuleApplication) {
logger.indent() << "Bind round " << (bindRound + 1) << " with "
Expand All @@ -77,7 +78,7 @@ template<typename Iter, typename OnOutput>
int numDup = 0;
int numUnique = 0;
std::vector<BoundRule> outputRules;
for(const BoundRule &brInput : inputRules) {
for(const BoundRule &brInput: inputRules) {
if(verbosity >= V_RuleApplication_Binding) {
logger.indent() << "Processing input rule " << brInput << std::endl;
++logger.indentLevel;
Expand All @@ -92,19 +93,21 @@ template<typename Iter, typename OnOutput>
++logger.indentLevel;
}
const auto reporter =
[labelSettings, &logger, &brInput, &outputRules, firstGraph, iterGraph, onOutput, &numUnique, &numDup]
[labelSettings, doRuleIsomorphism, &logger, &brInput, &outputRules, firstGraph, iterGraph, onOutput, &numUnique, &numDup]
(std::unique_ptr<lib::Rules::Real> r) -> bool {
BoundRule brOutput{r.release(), brInput.boundGraphs,
static_cast<int>(iterGraph - firstGraph)};
brOutput.boundGraphs.push_back(*iterGraph);
if(!brOutput.rule->isOnlyRightSide()) {
// check if we have it already
brOutput.makeCanonical();
for(const BoundRule &brStored : outputRules) {
if(brStored.isomorphicTo(brOutput, labelSettings)) {
delete brOutput.rule;
++numDup;
return true;
if(doRuleIsomorphism) {
for(const BoundRule &brStored: outputRules) {
if(brStored.isomorphicTo(brOutput, labelSettings)) {
delete brOutput.rule;
++numDup;
return true;
}
}
}
// we store a copy of the bound info so the user can mess with their copy
Expand Down Expand Up @@ -155,7 +158,7 @@ struct BoundRuleStorage {
return g1->getId() < g2->getId();
});

for(BoundRule &rp : ruleStore) {
for(BoundRule &rp: ruleStore) {
if(rThis.size() != rp.boundGraphs.size()) continue;
std::vector<const lib::Graph::Single *> &rOther = rp.boundGraphs;

Expand Down Expand Up @@ -183,7 +186,7 @@ struct BoundRuleStorage {
ruleStore.push_back(p);
if(verbose) {
logger.indent() << "BoundRules: added <" << r->getName() << ", {";
for(const auto *g : p.boundGraphs)
for(const auto *g: p.boundGraphs)
logger.s << " " << g->getName();
logger.s << " }> onlyRight: " << std::boolalpha << r->isOnlySide(lib::Rules::Membership::R)
<< std::endl;
Expand Down Expand Up @@ -235,14 +238,14 @@ std::vector<std::shared_ptr<graph::Graph>> splitRule(const lib::Rules::LabelledR
auto rpString = get_string(get_labelled_right(rDPO));
assert(num_vertices(gRight) == num_vertices(get_graph(rDPO)));
std::vector<Vertex> vertexMap(num_vertices(gRight));
for(const auto vSide : asRange(vertices(gRight))) {
for(const auto vSide: asRange(vertices(gRight))) {
const auto comp = compMap[get(boost::vertex_index_t(), gRight, vSide)];
auto &p = products[comp];
const auto v = add_vertex(*p.gPtr);
vertexMap[get(boost::vertex_index_t(), gRight, vSide)] = v;
p.pStringPtr->addVertex(v, rpString[vSide]);
}
for(const auto eSide : asRange(edges(gRight))) {
for(const auto eSide: asRange(edges(gRight))) {
const auto vSideSrc = source(eSide, gRight);
const auto vSideTar = target(eSide, gRight);
const auto comp = compMap[get(boost::vertex_index_t(), gRight, vSideSrc)];
Expand All @@ -256,16 +259,16 @@ std::vector<std::shared_ptr<graph::Graph>> splitRule(const lib::Rules::LabelledR

if(withStereo && has_stereo(rDPO)) {
// make the inverse vertex maps
for(auto &p : products)
for(auto &p: products)
p.vertexMap.resize(num_vertices(*p.gPtr));
for(const auto vSide : asRange(vertices(gRight))) {
for(const auto vSide: asRange(vertices(gRight))) {
const auto comp = compMap[get(boost::vertex_index_t(), gRight, vSide)];
auto &p = products[comp];
const auto v = vertexMap[get(boost::vertex_index_t(), gRight, vSide)];
p.vertexMap[get(boost::vertex_index_t(), *p.gPtr, v)] = vSide;
}

for(auto &p : products) {
for(auto &p: products) {
const auto &lgRight = get_labelled_right(rDPO);
assert(has_stereo(lgRight));
const auto vertexMap = [&p](const auto &vProduct) {
Expand All @@ -288,13 +291,13 @@ std::vector<std::shared_ptr<graph::Graph>> splitRule(const lib::Rules::LabelledR
} // end of stereo prop
// wrap them
std::vector<std::shared_ptr<graph::Graph>> right;
for(auto &g : products) {
for(auto &g: products) {
// check against the database
auto gCand = std::make_unique<lib::Graph::Single>(std::move(g.gPtr), std::move(g.pStringPtr),
std::move(g.pStereoPtr));
std::shared_ptr<graph::Graph> gWrapped = checkIfNew(std::move(gCand));
// checkIfNew does not add the graph, so we must check against the previous products as well
for(auto gPrev : right) {
for(auto gPrev: right) {
const auto ls = mod::LabelSettings(labelType, LabelRelation::Isomorphism, withStereo,
LabelRelation::Isomorphism);
const bool iso = lib::Graph::Single::isomorphic(gPrev->getGraph(), gWrapped->getGraph(), ls);
Expand Down
1 change: 1 addition & 0 deletions libs/libmod/src/mod/lib/DG/Strategies/Rule.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -263,6 +263,7 @@ void Rule::executeImpl(PrintSettings settings, const GraphState &input) {
firstGraph, lastGraph, inputRules,
getExecutionEnv().graphAsRuleCache,
getExecutionEnv().labelSettings,
getExecutionEnv().doRuleIsomorphism,
onOutput);
if(round != 0) {
// in round 0 the inputRules is the actual original input rule, so don't delete it
Expand Down
5 changes: 3 additions & 2 deletions libs/libmod/src/mod/lib/DG/Strategies/Strategy.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ namespace mod::lib::DG::Strategies {
class GraphState;

struct ExecutionEnv {
ExecutionEnv(LabelSettings labelSettings, Rules::GraphAsRuleCache &graphAsRuleCache)
: labelSettings(labelSettings), graphAsRuleCache(graphAsRuleCache) {}
ExecutionEnv(LabelSettings labelSettings, bool doRuleIsomorphism, Rules::GraphAsRuleCache &graphAsRuleCache)
: labelSettings(labelSettings), doRuleIsomorphism(doRuleIsomorphism), graphAsRuleCache(graphAsRuleCache) {}
virtual ~ExecutionEnv() {};
// May throw LogicError if exists.
virtual void tryAddGraph(std::shared_ptr<graph::Graph> g) = 0;
Expand All @@ -37,6 +37,7 @@ struct ExecutionEnv {
virtual void popRightPredicate() = 0;
public:
const LabelSettings labelSettings;
const bool doRuleIsomorphism;
Rules::GraphAsRuleCache &graphAsRuleCache;
};

Expand Down

0 comments on commit 7bd0455

Please sign in to comment.