Skip to content
Merged
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
Original file line number Diff line number Diff line change
Expand Up @@ -142,11 +142,13 @@ class EpistemicStateNode : public rclcpp_lifecycle::LifecycleNode
/// state without polling a service on every change.
void publish_state();

/// How the tracked model takes an action: repaired on a KD45 task, as it
/// always was, and never refused, since what it records has already happened.
/// How the tracked model takes an action: repaired only when the task asks
/// for repair, as the planner does, and never refused, since what it records
/// has already happened. A model repaired where the planner's was not would
/// refuse an action the policy had every reason to send.
Seriality tracked_seriality() const
{
return task_->kd45 ? Seriality::Repair : Seriality::Ignore;
return task_->repair_seriality() ? Seriality::Repair : Seriality::Ignore;
}

rclcpp::Service<plansys2_epistemic_msgs::srv::LoadTask>::SharedPtr load_task_service_;
Expand Down
28 changes: 28 additions & 0 deletions plansys2_epistemic_executor/test/epistemic_state_node_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -342,6 +342,17 @@ class EpistemicFleetDomainTest : public EpistemicStateNodeTest
///
/// This is where a belief and a sensor reading can disagree in the ordinary
/// way, which is what recovery is for.
/// backdoor-revealed: a KD45 task in which Alice hides the key where Bob cannot
/// see, and then shows it to both of them.
class BackdoorRevealedTest : public EpistemicStateNodeTest
{
protected:
std::string task_for_test() const override
{
return std::string(EPISTEMIC_TASK_DIR) + "/backdoor-revealed.json";
}
};

class StalePriorTest : public EpistemicStateNodeTest
{
protected:
Expand Down Expand Up @@ -492,6 +503,23 @@ TEST_F(EpistemicFleetDomainTest, TheModelItselfIsUnchangedByAskingForAView)
EXPECT_EQ(before->holds, after->holds);
}

TEST_F(BackdoorRevealedTest, AnAnnouncementAgainstABeliefIsTrackedAsThePlannerPredictsIt)
{
// Bob believes the key is not at the back when Alice shows it, and is left
// with no world. The planner does not repair a KD45 task unless asked to,
// and the model that follows execution has to agree with it: repairing here
// deletes the only world there is and refuses the announcement.
for (const std::string action : {"alice-hides-key_alice", "alice-shows-key_alice"}) {
auto request = std::make_shared<plansys2_epistemic_msgs::srv::ApplyAction::Request>();
request->epistemic_action = action;

auto response = call<plansys2_epistemic_msgs::srv::ApplyAction>(
"epistemic_state/apply_action", request);
ASSERT_NE(response, nullptr);
EXPECT_TRUE(response->success) << action << ": " << response->error;
}
}

// Recovery.
//
// The model is a belief about the world, and the world can contradict it. What
Expand Down
8 changes: 8 additions & 0 deletions plansys2_epistemic_planner/test/tasks/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ tests assert).
| `coin-in-the-box-4.json` | del-planner `benchmarks/coin4/problem_4.json` | its shortest plan leaves B believing a contradiction; the `consistent_beliefs` test |
| `active-muddy-child.json` | `Active-Muddy-Child/out/problem_1.json` | 32 initial worlds; the canonical partial-observability case |
| `coin-in-the-box-multipointed.json` | derived, see below | hand-made branching fixture, kept for the parser tests |
| `backdoor-revealed.json` | derived, see below | KD45: an announcement leaves Bob no world; the executor's update test |

The puzzle instances come from the `epddl-workspace/` of
[Epistemic-Robotics](https://github.com/HanielUlises/epistemic-robotics); the
Expand Down Expand Up @@ -46,3 +47,10 @@ path `EpistemicPlanSolver` flattens away when it converts a policy into a
That is the textbook multi-pointed coin-in-the-box, and its solution branches.
If the EPDDL instance is ever written and grounded, replace this file with the
grounder's output.

`backdoor-revealed.json` is del-planner's `benchmarks/backdoor/backdoor-problem.json`
with one action added, `alice-shows-key_alice`, a public announcement that the
key is at the back. After Alice hides the key where Bob cannot see, Bob believes
it is not there, and the announcement leaves him no accessible world. Updating
without repair keeps that one world; seriality repair deletes it and refuses
the update.
185 changes: 185 additions & 0 deletions plansys2_epistemic_planner/test/tasks/backdoor-revealed.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,185 @@
{
"planning-task-info": {
"problem": "backdoor-revealed",
"domain": "backdoor",
"libraries": [
"intermediate"
],
"requirements": [
":KD45-frames",
":disjunctive-list-formulas",
":disjunctive-preconditions",
":equality",
":events-conditions",
":list-comprehensions",
":lists",
":modal-goals",
":multi-pointed-models",
":negative-list-formulas",
":negative-preconditions",
":ontic-actions",
":partial-observability"
],
"agents-number": 2,
"atoms-number": 1,
"facts-number": 0,
"actions-number": 2,
"initial-worlds-number": 1,
"goal-modal-depth": 1,
"goal-size": 5
},
"language": {
"atoms": [
"key-at-back"
],
"agents": [
"alice",
"bob"
]
},
"facts": [],
"initial-state": {
"worlds": [
"w0"
],
"relations": {
"alice": {
"w0": [
"w0"
]
},
"bob": {
"w0": [
"w0"
]
}
},
"labels": {
"w0": []
},
"designated": [
"w0"
]
},
"actions": {
"alice-hides-key_alice": {
"action-type": "private-ontic",
"events": [
"e-hide",
"nil"
],
"relations": {
"Fully": {
"e-hide": [
"e-hide"
],
"nil": [
"nil"
]
},
"Oblivious": {
"e-hide": [
"nil"
],
"nil": [
"nil"
]
}
},
"designated": [
"e-hide"
],
"preconditions": {
"e-hide": {
"formula": {
"connective": "and",
"formulas": [
"true",
{
"connective": "not",
"formula": "key-at-back"
}
]
}
},
"nil": {
"formula": "true"
}
},
"effects": {
"e-hide": {
"key-at-back": {
"formula": "true"
}
},
"nil": null
},
"observability-conditions": {
"alice": {
"Fully": {
"formula": "true"
}
},
"bob": {
"Oblivious": {
"formula": "true"
}
}
}
},
"alice-shows-key_alice": {
"action-type": "public-announcement",
"events": [
"e-show"
],
"relations": {
"Fully": {
"e-show": [
"e-show"
]
}
},
"designated": [
"e-show"
],
"preconditions": {
"e-show": {
"formula": "key-at-back"
}
},
"effects": {
"e-show": null
},
"observability-conditions": {
"alice": {
"Fully": {
"formula": "true"
}
},
"bob": {
"Fully": {
"formula": "true"
}
}
}
}
},
"goal": {
"formula": {
"connective": "and",
"formulas": [
"key-at-back",
{
"modality-name": "box",
"modality-index": [
"bob"
],
"formula": {
"connective": "not",
"formula": "key-at-back"
}
}
]
}
}
}
Loading