Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions src/search/landmarks/landmark_graph.cc
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,11 @@ LandmarkNode &LandmarkGraph::get_disjunctive_landmark(const FactPair &fact) cons
return *(disjunctive_landmarks_to_nodes.find(fact)->second);
}

const vector<LandmarkNode *> &LandmarkGraph::get_conjunctive_landmarks(
const FactPair &fact) const {
assert(contains_conjunctive_landmark(fact));
return conjunctive_landmarks_to_nodes.find(fact)->second;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

return conjunctive_landmarks_to_nodes[fact];
?

}

bool LandmarkGraph::contains_simple_landmark(const FactPair &lm) const {
return simple_landmarks_to_nodes.count(lm) != 0;
Expand All @@ -66,6 +71,10 @@ bool LandmarkGraph::contains_disjunctive_landmark(const FactPair &lm) const {
return disjunctive_landmarks_to_nodes.count(lm) != 0;
}

bool LandmarkGraph::contains_conjunctive_landmark(const FactPair &lm) const {
return conjunctive_landmarks_to_nodes.count(lm) != 0;
}

bool LandmarkGraph::contains_overlapping_disjunctive_landmark(
const set<FactPair> &lm) const {
// Test whether ONE of the facts is present in some disjunctive landmark.
Expand Down Expand Up @@ -118,6 +127,9 @@ LandmarkNode &LandmarkGraph::add_landmark(Landmark &&landmark) {
}
++num_disjunctive_landmarks;
} else if (lm.conjunctive) {
for (const FactPair &lm_fact : lm.facts) {
conjunctive_landmarks_to_nodes[lm_fact].emplace_back(new_node_p);
}
++num_conjunctive_landmarks;
} else {
simple_landmarks_to_nodes.emplace(lm.facts.front(), new_node_p);
Expand All @@ -144,6 +156,14 @@ void LandmarkGraph::remove_node_occurrences(LandmarkNode *node) {
}
} else if (landmark.conjunctive) {
--num_conjunctive_landmarks;
for (const FactPair &lm_fact : landmark.facts) {
vector<LandmarkNode *> *conjunctive_landmarks_vector =
&(conjunctive_landmarks_to_nodes.find(lm_fact)->second);
auto it = find(conjunctive_landmarks_vector->begin(),
conjunctive_landmarks_vector->end(), node);
assert(it != conjunctive_landmarks_vector->end());
conjunctive_landmarks_vector->erase(it);
}
} else {
simple_landmarks_to_nodes.erase(landmark.facts[0]);
}
Expand Down
6 changes: 6 additions & 0 deletions src/search/landmarks/landmark_graph.h
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ class LandmarkGraph {

utils::HashMap<FactPair, LandmarkNode *> simple_landmarks_to_nodes;
utils::HashMap<FactPair, LandmarkNode *> disjunctive_landmarks_to_nodes;
utils::HashMap<FactPair, std::vector<LandmarkNode *>> conjunctive_landmarks_to_nodes;
Nodes nodes;

void remove_node_occurrences(LandmarkNode *node);
Expand Down Expand Up @@ -118,13 +119,18 @@ class LandmarkGraph {
/* This is needed only by landmark graph factories and will disappear
when moving landmark graph creation there. */
LandmarkNode &get_disjunctive_landmark(const FactPair &fact) const;
// TODO: comment?
const std::vector<LandmarkNode *> &get_conjunctive_landmarks(
const FactPair &fact) const;

/* This is needed only by landmark graph factories and will disappear
when moving landmark graph creation there. It is not needed by
HMLandmarkFactory*/
bool contains_simple_landmark(const FactPair &lm) const;
/* Only used internally. */
bool contains_disjunctive_landmark(const FactPair &lm) const;
// TODO: comment?
bool contains_conjunctive_landmark(const FactPair &lm) const;
/* This is needed only by landmark graph factories and will disappear
when moving landmark graph creation there. It is not needed by
HMLandmarkFactory*/
Expand Down
33 changes: 24 additions & 9 deletions src/search/landmarks/landmark_heuristic.cc
Original file line number Diff line number Diff line change
Expand Up @@ -118,12 +118,7 @@ void LandmarkHeuristic::compute_landmark_graph(

void LandmarkHeuristic::generate_preferred_operators(
const State &state, ConstBitsetView &future) {
/*
Find operators that achieve future landmarks.
TODO: Conjunctive landmarks are ignored in *lm_graph->get_node(...)*, so
they are ignored when computing preferred operators. We consider this
a bug and want to fix it in issue1072.
*/
// Find operators that achieve future landmarks.
assert(successor_generator);
vector<OperatorID> applicable_operators;
successor_generator->generate_applicable_ops(state, applicable_operators);
Expand All @@ -132,12 +127,32 @@ void LandmarkHeuristic::generate_preferred_operators(
OperatorProxy op = task_proxy.get_operators()[op_id];
EffectsProxy effects = op.get_effects();
for (EffectProxy effect : effects) {
if (!does_fire(effect, state))
if (!does_fire(effect, state)) {
continue;
}
FactPair fact = effect.get_fact().get_pair();
if (state[fact.var].get_value() == fact.value) {
continue;
FactProxy fact_proxy = effect.get_fact();
LandmarkNode *lm_node = lm_graph->get_node(fact_proxy.get_pair());
}
LandmarkNode *lm_node = lm_graph->get_node(fact);
if (lm_node && future.test(lm_node->get_id())) {
set_preferred(op);
break;
}
bool pref = false;
if (lm_graph->contains_conjunctive_landmark(fact)) {
vector<LandmarkNode *> conjunctive_landmarks =
lm_graph->get_conjunctive_landmarks(fact);
for (auto conj_lm : conjunctive_landmarks) {
if (future.test(conj_lm->get_id())) {
set_preferred(op);
pref = true;
break;
}
}
}
if (pref) {
break;
}
}
}
Expand Down