AI 24/25 Project Software
Documentation for the AI 24/25 course programming project software
Loading...
Searching...
No Matches
verification_impl.h
1#ifndef GUARD_INCLUDE_PROBFD_ABSTRACTIONS_VERIFICATION_H
2#error "This file should only be included from verification.h"
3#endif
4
5#include "probfd/pdbs/projection_operator.h"
6#include "probfd/pdbs/projection_state_space.h"
7
8#include "probfd/evaluator.h"
9
10#include "downward/lp/lp_solver.h"
11
12#include <cmath>
13#include <ranges>
14
15namespace probfd {
16
17template <typename State, typename Action>
18void verify(
20 std::span<const value_t> value_table,
21 lp::LPSolverType type)
22{
23 lp::LPSolver solver(type);
24 const double inf = solver.get_infinity();
25
26 named_vector::NamedVector<lp::LPVariable> variables;
27 named_vector::NamedVector<lp::LPConstraint> constraints;
28
29 const std::size_t num_states = value_table.size();
30
31 for (std::size_t i = 0; i != num_states; ++i) {
32 const State state = mdp.get_state(i);
33 const auto term_info = mdp.get_termination_info(state);
34 const value_t term_cost = term_info.get_cost();
35
36 const auto value = value_table[i];
37
38 variables.emplace_back(
39 -inf,
40 std::min(term_cost, inf),
41 value != INFINITE_VALUE && !std::isnan(value) ? 1_vt : 0_vt);
42
43 // Generate operators...
44 std::vector<Action> aops;
45 mdp.generate_applicable_actions(i, aops);
46
47 // Push successors
48 for (const Action& op : aops) {
49 const value_t cost = mdp.get_action_cost(op);
50
51 Distribution<StateID> successor_dist;
52 mdp.generate_action_transitions(i, op, successor_dist);
53
54 if (successor_dist.is_dirac(i)) {
55 continue;
56 }
57
58 auto& constr = constraints.emplace_back(-inf, cost);
59
60 value_t non_loop_prob = 0_vt;
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);
65 }
66 }
67
68 constr.insert(i, non_loop_prob);
69 }
70 }
71
72 solver.load_problem(lp::LinearProgram(
73 lp::LPObjectiveSense::MAXIMIZE,
74 std::move(variables),
75 std::move(constraints),
76 inf));
77
78 solver.solve();
79
80 if (!solver.has_optimal_solution()) {
81 if (solver.is_infeasible()) {
82 std::cerr << "Critical error: LP was infeasible!" << std::endl;
83 } else {
84 assert(solver.is_unbounded());
85 std::cerr << "Critical error: LP was unbounded!" << std::endl;
86 }
87
88 solver.print_failure_analysis();
89 abort();
90 }
91
92 std::vector<double> solution = solver.extract_solution();
93
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)) {
97 assert(is_approx_equal(value, solution[s], 0.001));
98 }
99 }
100}
101
102} // namespace probfd
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