1#ifndef GUARD_INCLUDE_PROBFD_ABSTRACTIONS_VERIFICATION_H
2#error "This file should only be included from verification.h"
5#include "probfd/pdbs/projection_operator.h"
6#include "probfd/pdbs/projection_state_space.h"
8#include "probfd/evaluator.h"
10#include "downward/lp/lp_solver.h"
17template <
typename State,
typename Action>
20 std::span<const value_t> value_table,
21 lp::LPSolverType type)
23 lp::LPSolver solver(type);
24 const double inf = solver.get_infinity();
26 named_vector::NamedVector<lp::LPVariable> variables;
27 named_vector::NamedVector<lp::LPConstraint> constraints;
29 const std::size_t num_states = value_table.size();
31 for (std::size_t i = 0; i != num_states; ++i) {
36 const auto value = value_table[i];
38 variables.emplace_back(
40 std::min(term_cost, inf),
41 value != INFINITE_VALUE && !std::isnan(value) ? 1_vt : 0_vt);
44 std::vector<Action> aops;
48 for (
const Action& op : aops) {
58 auto& constr = constraints.emplace_back(-inf, cost);
61 for (
const auto& [succ, prob] : successor_dist) {
62 if (succ !=
static_cast<size_t>(i)) {
63 non_loop_prob += prob;
64 constr.insert(succ.id, -prob);
68 constr.insert(i, non_loop_prob);
72 solver.load_problem(lp::LinearProgram(
73 lp::LPObjectiveSense::MAXIMIZE,
75 std::move(constraints),
80 if (!solver.has_optimal_solution()) {
81 if (solver.is_infeasible()) {
82 std::cerr <<
"Critical error: LP was infeasible!" << std::endl;
84 assert(solver.is_unbounded());
85 std::cerr <<
"Critical error: LP was unbounded!" << std::endl;
88 solver.print_failure_analysis();
92 std::vector<double> solution = solver.extract_solution();
94 for (
StateID s = 0; s.id != num_states; ++s.id) {
95 const auto value = value_table[s];
96 if (value != INFINITE_VALUE && !std::isnan(value)) {
virtual value_t get_action_cost(param_type< Action > action)=0
Gets the cost of an action.
virtual TerminationInfo get_termination_info(param_type< State > state)=0
Returns the cost to terminate in a given state and checks whether a state is a goal.
A convenience class that represents a finite probability distribution.
Definition task_state_space.h:27
bool is_dirac(const T &t) const
Checks if the distribution is a Dirac distribution wrt an element.
Definition distribution.h:267
Basic interface for MDPs.
Definition mdp_algorithm.h:14
virtual State get_state(StateID state_id)=0
Get the state mapped to a given state ID.
virtual void generate_applicable_actions(param_type< State > state, std::vector< Action > &result)=0
Generates the applicable actions of the state.
virtual void generate_action_transitions(param_type< State > state, param_type< Action > action, Distribution< StateID > &result)=0
Generates the successor distribution for a given state and action.
value_t get_cost() const
Obtains the cost paid upon termination in the state.
Definition cost_function.h:41
The top-level namespace of probabilistic Fast Downward.
Definition command_line.h:8
double value_t
Typedef for the state value type.
Definition aliases.h:7
void verify(MDP< State, Action > &mdp, std::span< const value_t > value_table, lp::LPSolverType type)
Computes the optimal value function of the abstraction, complete up to forward reachability from the ...
Definition verification_impl.h:18
bool is_approx_equal(value_t v1, value_t v2, value_t epsilon=g_epsilon)
Equivalent to .
A StateID represents a state within a StateIDMap. Just like Fast Downward's StateID type,...
Definition types.h:22