Please note that if one would like to use a sliding window, she or he would also have to store data about whether Ri  is element of π for all rules Ri and an executed plan π (i.e., the rows in A) in a FIFO buffer. When we learn data about a new πn, we might not only have to accommodate these new data, but some old πo might fall out of the window so that we have to remove its influence. Via implementing a corresponding FIFO buffer, we could accomplish this easily.
With our definition of a plan's reliability, we obviously search for a plan π with the lowest value r(π).
Consequently, we do not reason about plans of minimal length, but desire plans of minimal costs in terms of r(π) which directly relates to the risk of a plan's failing.
If there are multiple plans with the same "optimal" r(π), we select the one created first. In principle, in such a case also heuristics that choose a plan of minimal length, or one such that the contained rules' maximum reliability value is the lowest could be adopted.
In this context, it is also important to note that our concept is orthogonal to the incorporated planning algorithm/concept - as long as one can use our simple risk-related cost function drawing on results from light-weight diagnostics in that algorithm. So whether a derived plan  π is globally or locally optimal (consider a complete vs. greedy search) depends on the incorporated planning algorithm. Consequently, the planning stage is not in the primary focus of our presentation, but we focus on (a) the exploitation of diagnostic data that describe the reliability of a system's actions as well as on (b) how to exploit such data in the planning stage of a corresponding engine via a specific cost function in the form of a plan's reliability (see Def. 7). While completeness and soundness in terms of finding a plan optimal in the context of the chosen heuristic (the suspiciousness coefficient like Ochiai) thus depends on the planning algorithm, we can easily deduce the complexity of our computations.
Theorem 1 Computing a rule's reliability coefficient is done in constant time, so that computing all of them is linear in the number of rules. Computing a plan π's reliability is linear in the length of its rule sequence.
Proof: Since we keep track of a component's frequency values and only have to update them via simple additions and subtractions (the latter only in case of a sliding window), their computation and that of the chosen suspicious metric like Ochiai is in constant time. We do this for each rule so that we are linear in their number for the entire computation. Computing a plan π's reliability means summing up the contained rules' values (see Def. 7) so that we're linear in the length of π's sequence.
When implementing our concept in practice, there are some aspects that we have to consider in relation to the similarity coefficients, though. For instance, after a cold start, insufficient data would result in a division by zero or a value of zero when computing the coefficients. Since we are using the values directly as reliability measures, and therefore for planning, in our proof-of-concept implementation, we assign small values (0.00001) as a rule's reliability measure in such cases. This follows the idea that after a cold start, we assume that the rules are rather healthy than faulty.
As we stated in the previous section, PDDL is one of the most used planning description languages. To make our approach as universal as possible, we wanted to show that our approach can be used in combination with PDDL, and therefore can be integrated into every system that uses PDDL. However, using PDDL for our approach is not straight forward. We can see from Listing 1, that actions in PDDL are abstract actions still requiring concrete parameters when we want to execute that action. Because our approach uses the feedback from the actual execution of an action, it is a good idea to also reason about concrete actions and the current state of the world. Creating concrete actions from abstract actions is called grounding in different research areas. For our implementation of grounding, we have two important requirements. (1) The calculation of abstract actions to concrete actions has to be dynamic. (2) we have to be able to reuse already discovered concrete actions in the next plan.
To fulfill those two requirements, we implemented a reachability-based algorithm for computing concrete actions. Starting from the initial state, we (1) calculate which concrete actions could be executed from this state. For each such concrete action we (2) calculate how it transforms the state. If the state is a previously encountered state, we (3a) link the state to the already encountered state. If this is a new state, we (3b) continue at (1). The result is a graph where the nodes represent all different states of the world, and the edges represent their transformation through concrete actions. We can now use the reliability score of the concrete actions as edge weights and use traditional pathfinding algorithms to generate a plan. In our implementation, we use Dijkstra's algorithm. Retaining this graph throughout different plans enables us to rediscover already used concrete actions.
It is important to note that with this approach, we reason with the maximum level of information about the concrete execution, i.e., the state of the world before the execution and the concrete action. This, of course, is not the only option. For example, reasoning only about abstract actions would also be possible, e.g., if we know the environment does not influence the result. Nevertheless, using our SFL approach to represent the confidence in an action's success would still be applicable.