From 869030639aede7c9c432db4c4549265e872ef45d Mon Sep 17 00:00:00 2001 From: NotXia <35894453+NotXia@users.noreply.github.com> Date: Fri, 24 Nov 2023 15:17:17 +0100 Subject: [PATCH] Add FAIKR1 hierarchical and reactive planners --- .../module1/img/_conditional_planning.pdf | Bin 0 -> 29769 bytes .../module1/img/conditional_planning.drawio | 91 +++ .../module1/main.tex | 1 - .../module1/sections/_generative_planning.tex | 566 -------------- .../module1/sections/_planning.tex | 730 +++++++++++++++++- 5 files changed, 820 insertions(+), 568 deletions(-) create mode 100644 src/fundamentals-of-ai-and-kr/module1/img/_conditional_planning.pdf create mode 100644 src/fundamentals-of-ai-and-kr/module1/img/conditional_planning.drawio delete mode 100644 src/fundamentals-of-ai-and-kr/module1/sections/_generative_planning.tex diff --git a/src/fundamentals-of-ai-and-kr/module1/img/_conditional_planning.pdf b/src/fundamentals-of-ai-and-kr/module1/img/_conditional_planning.pdf new file mode 100644 index 0000000000000000000000000000000000000000..3bc7eb00b8fbf3dce6d74d46e6c8b28afe84ed55 GIT binary patch literal 29769 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 l$-)E##Lo_?_aBbt;%emV>goLVvsk# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/fundamentals-of-ai-and-kr/module1/main.tex b/src/fundamentals-of-ai-and-kr/module1/main.tex index 99160d2..2b61075 100644 --- a/src/fundamentals-of-ai-and-kr/module1/main.tex +++ b/src/fundamentals-of-ai-and-kr/module1/main.tex @@ -13,6 +13,5 @@ \input{sections/_swarm_intelligence.tex} \input{sections/_games.tex} \input{sections/_planning.tex} - \input{sections/_generative_planning.tex} \end{document} \ No newline at end of file diff --git a/src/fundamentals-of-ai-and-kr/module1/sections/_generative_planning.tex b/src/fundamentals-of-ai-and-kr/module1/sections/_generative_planning.tex deleted file mode 100644 index 1fe9879..0000000 --- a/src/fundamentals-of-ai-and-kr/module1/sections/_generative_planning.tex +++ /dev/null @@ -1,566 +0,0 @@ -\chapter{Generative planning} - -\begin{description} - \item[Generative planning] \marginnote{Generative planning} - Offline planning that creates the entire plan before execution based on - a snapshot of the current state of the world. - It relies on the following assumptions: - \begin{descriptionlist} - \item[Atomic time] - Actions cannot be interrupted. - \item[Determinism] - Actions are deterministic. - \item[Closed world] - The initial state is fully known, - what is not in the initial state is considered false (which is different from unknown). - \item[No interference] Only the execution of the plan changes the state of the world. - \end{descriptionlist} -\end{description} - - - -\section{Linear planning} -\marginnote{Linear planning} -Formulates the planning problem as a search problem where: -\begin{itemize} - \item Nodes contain the state of the world. - \item Edges represent possible actions. -\end{itemize} -Produces a totally ordered list of actions. - -The direction of the search can be: -\begin{descriptionlist} - \item[Forward] \marginnote{Forward search} - Starting from the initial state, the search terminates when a state containing a superset of the goal is reached. - \item[Backward] \marginnote{Backward search} - Starting from the goal, the search terminates when a state containing a subset of the initial state is reached. - - Goal regression is used to reduce the goal into sub-goals. - Given a (sub-)goal $G$ and a rule (action) $R$ with delete-list (states that are false after the action) \texttt{d\_list} - and add-list (states that are true after the action) \texttt{a\_list}, regression of $G$ through $R$ is define as: - \[ - \begin{split} - \texttt{regr[$G$, $R$]} &= \texttt{true} \text{ if } G \in \texttt{a\_list} \text{ (i.e. regression possible)} \\ - \texttt{regr[$G$, $R$]} &= \texttt{false} \text{ if } G \in \texttt{d\_list} \text{ (i.e. regression not possible)} \\ - \texttt{regr[$G$, $R$]} &= G \text{ otherwise} \text{ (i.e. $R$ does not influence $G$)} \\ - \end{split} - \] - - \begin{example}[Moving blocks] - Given the action \texttt{unstack(X, Y)} with: - \[ - \begin{split} - \texttt{d\_list} &= \{ \texttt{handempty}, \texttt{on(X, Y)}, \texttt{clear(X)} \} \\ - \texttt{a\_list} &= \{ \texttt{holding(X)}, \texttt{clear(Y)} \} - \end{split} - \] - We have that: - \[ - \begin{split} - \texttt{regr[holding(b), unstack(b, Y)]} &= \texttt{true} \\ - \texttt{regr[handempty, unstack(X, Y)]} &= \texttt{false} \\ - \texttt{regr[ontable(c), unstack(X, Y)]} &= \texttt{ontable(c)} \\ - \texttt{regr[clear(c), unstack(X, Y)]} &= \begin{cases} - \texttt{true} & \text{if \texttt{Y}=\texttt{c}} \\ - \texttt{clear(c)} & \text{otherwise} - \end{cases} - \end{split} - \] - \end{example} -\end{descriptionlist} - - -\subsection{Deductive planning} -\marginnote{Deductive planning} -Formulates the planning problem using first order logic to represent states, goals and actions. -Plans are generated as theorem proofs. - -\subsubsection{Green's formulation} -\marginnote{Green's formulation} -Green's formulation is based on \textbf{situation calculus}. -To find a plan, the goal is negated and it is proven that it leads to an inconsistency. - -The main concepts are: -\begin{descriptionlist} - \item[Situation] - Properties (fluents) that hold in a given state \texttt{s}. - \begin{example}[Moving blocks] - To denote that \texttt{ontable(c)} holds in a state \texttt{s}, we use the axiom: - \[ \texttt{ontable(c, s)} \] - \end{example} - The operator \texttt{do} allows to evolve the state such that: - \[ \texttt{do(A, S)} = \texttt{S'} \] - \texttt{S'} is the new state obtained by applying the action \texttt{A} in the state \texttt{S}. - - \item[Actions] - Define the pre-condition and post-condition fluents of an action in the form: - \[ \texttt{pre-conditions} \rightarrow \texttt{post-conditions} \] - Applying the equivalence $A \rightarrow B \equiv \lnot A \vee B$, actions can be described by means of disjunctions. - \begin{example}[Moving blocks] - The action \texttt{stack(X, Y)} has pre-conditions \texttt{holding(X)} and \texttt{clear(Y)}, and - post-conditions \texttt{on(X, Y)}, \texttt{clear(X)} and \texttt{handfree}. - Its representation in Green's formulation is: - \[ - \begin{split} - \texttt{holding(X, S)} \land \texttt{clear(Y, S)} &\rightarrow \\ - &\texttt{on(X, Y, do(stack(X, Y), s))} \land \\ - &\texttt{clear(X, do(stack(X, Y), s))} \land \\ - &\texttt{handfree(do(stack(X, Y), s))} \\ - \end{split} - \] - \end{example} - - \item[Frame axioms] - Besides the effects of actions, each state also have to define for all non-changing fluents their frame axioms. - If the problem is complex, the number of frame axioms becomes unreasonable. - \begin{example}[Moving blocks] - \[ \texttt{on(U, V, S)}, \texttt{diff(U, X)} \rightarrow \texttt{on(U, V, do(move(X, Y, Z), S))} \] - \end{example} -\end{descriptionlist} - - -\begin{example}[Moving blocks] - The initial state is described by the following axioms:\\[0.5em] - \begin{minipage}{.3\linewidth} - \centering - \texttt{on(a, d, s0)} \\ - \texttt{on(b, e, s0)} \\ - \texttt{on(c, f, s0)} \\ - \texttt{clear(a, s0)} \\ - \texttt{clear(b, s0)} \\ - \end{minipage} - \begin{minipage}{.3\linewidth} - \centering - \texttt{clear(c, s0)} \\ - \texttt{clear(g, s0)} \\ - \texttt{diff(a, b)} \\ - \texttt{diff(a, c)} \\ - \texttt{diff(a, d)} \dots \\ - \end{minipage} - \begin{minipage}{.3\linewidth} - \centering - \includegraphics[width=\linewidth]{img/_moving_block_example_green.pdf} - \end{minipage}\\[0.5em] - - For simplicity, we only consider the action \texttt{move(X, Y, Z)} that moves \texttt{X} from \texttt{Y} to \texttt{Z}. - It is defined as: - \[ - \begin{split} - \texttt{clear(X, S)}&, \texttt{clear(Z, S)}, \texttt{on(X, Y, S)}, \texttt{diff(X, Z)} \rightarrow \\ - &\texttt{clear(Y, do(move(X, Y, Z), S))}, \texttt{on(X, Z, do(move(X, Y, Z), S))} - \end{split} - \] - This action can be translated into the following effect axioms: - \[ - \begin{split} - \lnot\texttt{clear(X, S)} &\vee \lnot\texttt{clear(Z, S)} \vee \lnot\texttt{on(X, Y, S)} \vee \lnot\texttt{diff(X, Z)} \vee \\ - &\texttt{clear(Y, do(move(X, Y, Z), S))} - \end{split} - \] - \[ - \begin{split} - \lnot\texttt{clear(X, S)} &\vee \lnot\texttt{clear(Z, S)} \vee \lnot\texttt{on(X, Y, S)} \vee \lnot\texttt{diff(X, Z)} \vee \\ - &\texttt{on(X, Z, do(move(X, Y, Z), S))} - \end{split} - \] -\end{example} - -Given the goal \texttt{on(a, b, s1)}, we prove that $\lnot\texttt{on(a, b, s1)}$ leads to an inconsistency. -We decide to make the following substitutions: -\[ \{ \texttt{X}/\texttt{a}, \texttt{Z}/\texttt{b}, \texttt{s1}/\texttt{do(move(a, Y, b), S)} \} \] -The premise of \texttt{move} leads to an inconsistency (when applying \texttt{move} its premise is false): -\begin{center} - \begin{tabular}{c|c|c|c} - $\lnot\texttt{clear(a, S)}$ & $\lnot\texttt{clear(b, S)}$ & $\lnot\texttt{on(a, Y, S)}$ & $\lnot\texttt{diff(a, b)}$ \\ - False with $\{ \texttt{S}/\texttt{s0} \}$ & False with $\{ \texttt{S}/\texttt{s0} \}$ - & False with $\{ \texttt{S}/\texttt{s0}, \texttt{Y}/\texttt{d} \}$ & False - \end{tabular} -\end{center} -Therefore, the substitution $\{ \texttt{s1}/\texttt{do(move(a, Y, b), S)} \}$ defines the plan to reach the goal \texttt{on(a, b, s1)}. - - -\subsubsection{Kowalsky's formulation} -\marginnote{Kowalsky's formulation} -Kowalsky's formulation avoids the frame axioms problem by using a set of fixed predicates: -\begin{descriptionlist} - \item[\texttt{holds(rel, s/a)}] - Describes the relations \texttt{rel} that are true in a state \texttt{s} or after the execution of an action \texttt{a}. - \item[\texttt{poss(s)}] - Indicates if a state \texttt{s} is possible. - \item[\texttt{pact(a, s)}] - Indicates if an action \texttt{a} can be executed in a state \texttt{s}. -\end{descriptionlist} -Actions can be described as: -\[ \texttt{poss(S)} \land \texttt{pact(A, S)} \rightarrow \texttt{poss(do(A, S))} \] - -In the Kowalsky's formulation, each action requires a frame assertion (in Green's formulation, each state requires frame axioms). - -\begin{example}[Moving blocks] - An initial state can be described by the following axioms:\\[0.5em] - \begin{minipage}{.35\linewidth} - \centering - \texttt{holds(on(a, b), s0)} \\ - \texttt{holds(ontable(b), s0)} \\ - \texttt{holds(ontable(c), s0)} \\ - \end{minipage} - \begin{minipage}{.35\linewidth} - \centering - \texttt{holds(clear(a), s0)} \\ - \texttt{holds(clear(c), s0)} \\ - \texttt{holds(handempty, s0)} \\ - \texttt{poss(s0)} \\ - \end{minipage} - \begin{minipage}{.2\linewidth} - \centering - \includegraphics[width=0.6\linewidth]{img/_moving_block_example_kowalsky.pdf} - \end{minipage}\\[0.5em] -\end{example} - -\begin{example}[Moving blocks] - The action \texttt{unstack(X, Y)} has: - \begin{descriptionlist} - \item[Pre-conditions] \texttt{on(X, Y)}, \texttt{clear(X)} and \texttt{handempty} - \item[Effects] \phantom{} - \begin{description} - \item[Add-list] \texttt{holding(X)} and \texttt{clear(Y)} - \item[Delete-list] \texttt{on(X, Y)}, \texttt{clear(X)} and \texttt{handempty} - \end{description} - \end{descriptionlist} - - Its description in Kowalsky's formulation is: - \begin{descriptionlist} - \item[Pre-conditions] - \[ - \begin{split} - \texttt{holds(on(X, Y), S)}&, \texttt{holds(clear(X), S)}, \texttt{holds(handempty, S)} \rightarrow \\ - &\texttt{pact(unstack(X, Y), S)} - \end{split} - \] - - \item[Effects] (use add-list) - \[ \texttt{holds(holding(X), do(unstack(X, Y), S))} \] - \[ \texttt{holds(clear(Y), do(unstack(X, Y), S))} \] - - \item[Frame condition] (uses delete-list) - \[ - \begin{split} - \texttt{holds(V, S)}&, \texttt{V} \neq \texttt{on(X, Y)}, \texttt{V} \neq \texttt{clear(X)}, \texttt{V} \neq \texttt{handempty} - \rightarrow \\ - & \texttt{holds(V, do(unstack(X, Y), S))} - \end{split} - \] - \end{descriptionlist} -\end{example} - - -\subsection{STRIPS} -\marginnote{STRIPS} -STRIPS (Stanford Research Institute Problem Solver) is an ad-hoc algorithm -for linear planning resolution. -The elements of the problem are represented as: -\begin{descriptionlist} - \item[State] represented with its true fluents. - \item[Goal] represented with its true fluents. - \item[Action] represented using three lists: - \begin{descriptionlist} - \item[Preconditions] Fluents that are required to be true in order to apply the action. - \item[Delete-list] Fluents that become false after the action. - \item[Add-list] Fluents that become true after the action. - \end{descriptionlist} - Add-list and delete-list can be combined in an effect list with positive (add-list) and negative (delete-list) axioms. - - \begin{description} - \item[STRIPS assumption] Everything that is not in the add-list or delete-list is unchanged in the next state. - \end{description} -\end{descriptionlist} - -STRIPS uses two data structures: -\begin{descriptionlist} - \item[Goal stack] Does a backward search to reach the initial state. - \item[Current state] Represents the forward application of the actions found using the goal stack. -\end{descriptionlist} - -\begin{algorithm} -\caption{STRIPS} -\begin{lstlisting}[mathescape=true] -def strips(problem): - goal_stack = Stack() - current_state = State(problem.initial_state) - goal_stack.push(problem.goal) - plan = [] - while not goal_stack.empty(): - if (goal_stack.top() is a single/conjunction of goals and - there is a substitution $\theta$ that makes it $\subseteq$ current_state): - A = goal_stack.pop() - $\theta$ = find_substitution(A, current_state) - goal_stack.apply_substitution($\theta$) - elif goal_stack.top() is a single goal: - R = rule with a $\in$ R.add_list - _ = goal_stack.pop() # Pop goal - goal_stack.push(R) - goal_stack.push(R.preconditions) - elif goal_stack.top() is a conjunction of goals: - for g in permutation(goal_stack.top()): - goal_stack.push(g) - # Note that there is no pop - elif goal_stack.top() is an action: - action = goal_stack.pop() - current_state.apply(action) - plan.append(action) - return plan -\end{lstlisting} -\end{algorithm} - -\begin{example}[Moving blocks] - \begin{center} - \includegraphics[trim={0 32.2cm 0 0}, clip, width=0.85\textwidth]{img/_strips_example.pdf} - \end{center} - \begin{center} - \includegraphics[trim={0 0 0 17.5cm}, clip, width=0.85\textwidth]{img/_strips_example.pdf} - \end{center} -\end{example} - -Since there are non-deterministic choices, the search space may become very large. -Heuristics may be used to avoid this. - -Conjunction of goals are solved separately, but this could lead to the \marginnote{Sussman anomaly} \textbf{Sussman anomaly} -where a sub-goal destroys what another sub-goal has done. -For this reason, when a conjunction is encountered, it is not immediately popped from the goal stack -and is left as a final check. - - - -\section{Non-linear planning} -\marginnote{Non-linear planning} -Non-linear planning finds a plan as a search problem in the space of plans (instead of states as in linear planning). -Each node of the search tree is a partial plan. Edges represent plan refinement operations. - -A non-linear plan is represented by: -\begin{descriptionlist} - \item[Actions{\normalfont.}] \marginnote{Actions set} - \item[Orderings] \marginnote{Orderings set} - between actions. - \item[Causal links] \marginnote{Causal links} - triplet $\langle S_i, S_j, c \rangle$ where $S_i$ and $S_j$ are actions and $c$ is a sub-goal. - $c$ should be the effect of $S_i$ and precondition of $S_j$. - - Causal links represent causal relations between actions (i.e. interaction between sub-goals): - to execute $S_j$, the effect $c$ of $S_i$ is required first. -\end{descriptionlist} - -The initial plan is an empty plan with two fake actions \texttt{start} and \texttt{stop} -with ordering $\texttt{start} < \texttt{stop}$: -\begin{descriptionlist} - \item[\texttt{start}] has no preconditions and the effects match the initial state. - \item[\texttt{stop}] has no effects and the preconditions match the goal. -\end{descriptionlist} -At each step, one of the following refinement operations can be applied until the goal is reached: -\begin{itemize} - \item Add an action to the set of actions. - \item Add an ordering to the set of orderings. - \item Add a causal link to the set of causal links. -\end{itemize} - -\begin{figure}[h] - \centering - \includegraphics[width=0.45\textwidth]{img/_nonlinear_plan_example.pdf} - \caption{Example of search tree in non-linear planning} -\end{figure} - - -\begin{description} - \item[Least commitment planning] \marginnote{Least commitment planning} - Only strictly necessary restrictions (e.g. ordering) are imposed. - Non-linear planning is a least commitment planning. - - \item[Linearization] \marginnote{Linearization} - At the end, the partially ordered actions should be linearized, - respecting the ordering constraints, to obtain the final plan. -\end{description} - - -\begin{description} - \item[Threat] \marginnote{Threat} - An action $S_k$ is a threat to a causal link $\langle S_i, S_j, c \rangle$ - if its effects cancel $c$. - $S_k$ should not be executed in between $S_i$ and $S_j$. - - \begin{figure}[H] - \centering - \includegraphics[width=0.3\textwidth]{img/_threat_example.pdf} - \caption{Example of threat. Causal links are represented using thick arrows.} - \end{figure} - - Possible solutions to a threat $S_k$ to $\langle S_i, S_j, c \rangle$ are: - \begin{descriptionlist} - \item[Demotion] \marginnote{Demotion} - Add the ordering constraint $S_k < S_i$ (i.e. threat executed before). - \item[Promotion] \marginnote{Promotion} - Add the ordering constraint $S_k > S_i$ (i.e. threat executed after). - \end{descriptionlist} -\end{description} - -\begin{algorithm} -\caption{Partial order planning (POP)} -\begin{lstlisting}[mathescape=true] -def pop(initial_state, goal, actions): - plan = init_empty_plan(initial_state, goal) - while not plan.isSolution(): - try: - sn, c = selectSubgoal(plan) - chooseOperator(plan, actions, sn, c) - resolveThreats(plan) - except PlanFailError: - plan.backtrack() - return plan - -def selectSubgoal(plan): - sn, c = random([sn, c in plan.steps if c in sn.unsolved_preconditions]) - return sn, c - -def chooseOperator(plan, actions, sn, c): - s = random([s in (actions + plan.steps) if c in s.effects]) - if s is None: raise(PlanFailError) - plan.addCausalLink($\langle$s, sn, c$\rangle$) - plan.addOrdering(s < sn) - if s not in plan.steps: - plan.addAction(s) - plan.addOrdering(start < s < stop) - -def resolveThreats(plan): - for s_k, s_i, s_j in plan.threats(): - resolution = random([ DEMOTION, PROMOTION ]) - if resolution == DEMOTION: - plan.addOrdering(s_k < s_i) - elif resolution == PROMOTION: - plan.addOrdering(s_k > s_j) - if plan.isNotConsistent(): raise(PlanFailError) -\end{lstlisting} -\end{algorithm} - -\begin{example}[Purchasing schedule] - The initial state is: - \[ \texttt{at(home)}, \texttt{sells(hws, drill)}, \texttt{sells(sm, milk)}, \texttt{sells(sm, banana)} \] - where $\texttt{hws}$ means "hardware store" and $\texttt{sm}$ means "supermarket". - - The goal is: - \[ \texttt{at(home)}, \texttt{have(drill)}, \texttt{have(milk)}, \texttt{have(banana)} \] - - The possible actions are:\\[0.5em] - \begin{minipage}{.5\linewidth} - \begin{descriptionlist} - \item[\texttt{GO(X, Y)}] \phantom{} - \begin{description} - \item[Preconditions] $\texttt{at(X)}$ - \item[Effects] $\texttt{at(Y)}$, $\lnot \texttt{at(X)}$ - \end{description} - \end{descriptionlist} - \end{minipage} - \begin{minipage}{.5\linewidth} - \begin{descriptionlist} - \item[\texttt{BUY(S, Y)}] \phantom{} - \begin{description} - \item[Preconditions] $\texttt{at(S)}$, $\texttt{sells(S, Y)}$ - \item[Effects] $\texttt{have(Y)}$ - \end{description} - \end{descriptionlist} - \end{minipage}\\[0.5em] - - Partial order planning steps are: - \begin{enumerate} - \item Define the initial plan: - \begin{center} - \includegraphics[width=0.7\textwidth]{img/_pop_example1.pdf} - \end{center} - - \item The loop of POP is: - \begin{itemize} - \item Choose an action $a_i$ and one of its unsolved preconditions $c$. - \item Select an action $a_j$ with the precondition $c$ in its effects. - \item Add the ordering constraint $\texttt{start} < a_j < \texttt{stop}$. - \item Add the causal link $\langle a_j, a_i, c \rangle$ (and ordering $a_j < a_i$). - \item Solve threats. - \end{itemize} - - We choose the action $a_i = \texttt{stop}$ and the precondition $c = \texttt{have(drill)}$. - We choose as action with $c$ in its effects $a_j = \texttt{BUY(X, drill)}$. - We therefore add to the plan the ordering $\texttt{start} < \texttt{BUY(X, drill)} < \texttt{stop}$ and - the causal link $\langle \texttt{BUY(X, drill)}, \texttt{stop}, \texttt{have(drill)} \rangle$: - \begin{center} - \includegraphics[width=0.7\textwidth]{img/_pop_example2.pdf} - \end{center} - - \item Repeat the previous point for the preconditions $\texttt{have(milk)}$ and $\texttt{have(banana)}$: - \begin{center} - \includegraphics[width=0.7\textwidth]{img/_pop_example3.pdf} - \end{center} - - \item Now, we choose as action $\texttt{BUY(X, drill)}$ and as unsolved precondition $\texttt{sells(X, drill)}$. - This can be solved from the action $\texttt{start}$ with effect $\texttt{sells(hws, drill)}$. - We make the substitution $\texttt{X}/\texttt{drill}$ and - add $\langle \texttt{start}, \texttt{BUY(hws, drill)}, \texttt{sells(hws, drill)} \rangle$ to the causal links. - The same process can be repeated for $\texttt{BUY(X, milk)}$ and $\texttt{BUY(X, banana)}$: - \begin{center} - \includegraphics[width=0.7\textwidth]{img/_pop_example4.pdf} - \end{center} - - \item Now, we choose as action $\texttt{BUY(hws, drill)}$ and as unsolved precondition $\texttt{at(hws)}$. - This can be solved using the action $\texttt{GO(X, hws)}$. - We add $\langle \texttt{GO(X, hws)}, \texttt{BUY(hws, drill)}, \texttt{at(hws)} \rangle$ to the causal links. - - We continue by choosing as action $\texttt{GO(X, hws)}$ and as unsolved precondition $\texttt{at(X)}$. - This can be solved from $\texttt{start}$ with effect $\texttt{at(home)}$. - We therefore make the substitution $\texttt{X}/\texttt{home}$ and - add $\langle \texttt{start}, \texttt{GO(home, hws)}, \texttt{at(home)} \rangle$ to the causal links. - - The same process can be repeated for the $\texttt{milk}$ and $\texttt{banana}$ branch: - \begin{center} - \includegraphics[width=0.7\textwidth]{img/_pop_example5.pdf} - \end{center} - - \item We have a threat between $\texttt{GO(home, hws)}$ and $\texttt{GO(home, sm)}$ as they both - require the precondition $\texttt{at(home)}$ and both have as effect $\lnot\texttt{at(home)}$. - It can be easily seen that neither promotion nor demotion solves the conflict. - We are therefore forced to backtrack. - - We backtrack at the previous point, where we chose as action $\texttt{GO(X, sm)}$ and as precondition $\texttt{at(X)}$ - (this step has been implicitly done in the previous point). - \begin{itemize} - \item Instead of choosing the action $\texttt{start}$, we choose $\texttt{GO(home, hws)}$ with the effect $\texttt{at(hws)}$. - We therefore make the substitution $\texttt{X}/\texttt{hws}$ and update the causal links. - \item We also resolve the threat $\texttt{GO(hws, sm)}$ to $\texttt{BUY(hws, drill)}$ - (it removes the precondition $\texttt{at(hws)}$) - by promoting $\texttt{GO(hws, sm)}$ - and adding the ordering constraint $\texttt{BUY(hws, drill)} < \texttt{GO(hws, sm)}$: - \end{itemize} - \begin{center} - \includegraphics[width=0.7\textwidth]{img/_pop_example6.pdf} - \end{center} - - \item Now, we choose as action $\texttt{stop}$ and as precondition $\texttt{at(home)}$. - We choose as action $\texttt{GO(sm, home)}$ and update the causal links. - - Finally, we solve the threat $\texttt{GO(sm, home)}$ to - both $\texttt{BUY(sm, milk)}$ and $\texttt{BUY(sm, banana)}$ (it removes the required precondition $\texttt{at(sm)}$) - by promoting $\texttt{GO(sm, home)}$. - The newly added ordering constraints are - $\texttt{BUY(sm, milk)} < \texttt{GO(sm, home)}$ and - $\texttt{BUY(sm, banana)} < \texttt{GO(sm, home)}$. - - The final plan is: - \begin{center} - \includegraphics[width=0.7\textwidth]{img/_pop_example7.pdf} - \end{center} - By considering the ordering constraints, a linearization could be: - \[ - \begin{split} - \texttt{GO(home, hws)} &\rightarrow - \texttt{BUY(hws, drill)} \rightarrow - \texttt{GO(hws, sm)} \rightarrow\\ - &\texttt{BUY(sm, milk)} \rightarrow - \texttt{BUY(sm, banana)} \rightarrow - \texttt{GO(sm, home)} - \end{split} - \] - \end{enumerate} -\end{example} \ No newline at end of file diff --git a/src/fundamentals-of-ai-and-kr/module1/sections/_planning.tex b/src/fundamentals-of-ai-and-kr/module1/sections/_planning.tex index 4e1a57b..751b937 100644 --- a/src/fundamentals-of-ai-and-kr/module1/sections/_planning.tex +++ b/src/fundamentals-of-ai-and-kr/module1/sections/_planning.tex @@ -1,4 +1,7 @@ -\chapter{Automated planning definitions} +\chapter{Automated planning} + + +\section{Definitions} \begin{description} \item[Automated planning] \marginnote{Automated planning} @@ -49,4 +52,729 @@ \item[Non deterministic] An action applied to the real world may have unexpected effects due to uncertainty. \end{descriptionlist} + + \item[Generative planning] \marginnote{Generative planning} + Offline planning that creates the entire plan before execution based on + a snapshot of the current state of the world. + It relies on the following assumptions: + \begin{descriptionlist} + \item[Atomic time] + Actions cannot be interrupted. + \item[Determinism] + Actions are deterministic. + \item[Closed world] + The initial state is fully known, + what is not in the initial state is considered false (which is different from unknown). + \item[No interference] Only the execution of the plan changes the state of the world. + \end{descriptionlist} \end{description} + + + +\section{Linear planning} +\marginnote{Linear planning} +Formulates the planning problem as a search problem where: +\begin{itemize} + \item Nodes contain the state of the world. + \item Edges represent possible actions. +\end{itemize} +Produces a totally ordered list of actions. + +The direction of the search can be: +\begin{descriptionlist} + \item[Forward] \marginnote{Forward search} + Starting from the initial state, the search terminates when a state containing a superset of the goal is reached. + \item[Backward] \marginnote{Backward search} + Starting from the goal, the search terminates when a state containing a subset of the initial state is reached. + + Goal regression is used to reduce the goal into sub-goals. + Given a (sub-)goal $G$ and a rule (action) $R$ with delete-list (states that are false after the action) \texttt{d\_list} + and add-list (states that are true after the action) \texttt{a\_list}, regression of $G$ through $R$ is define as: + \[ + \begin{split} + \texttt{regr[$G$, $R$]} &= \texttt{true} \text{ if } G \in \texttt{a\_list} \text{ (i.e. regression possible)} \\ + \texttt{regr[$G$, $R$]} &= \texttt{false} \text{ if } G \in \texttt{d\_list} \text{ (i.e. regression not possible)} \\ + \texttt{regr[$G$, $R$]} &= G \text{ otherwise} \text{ (i.e. $R$ does not influence $G$)} \\ + \end{split} + \] + + \begin{example}[Moving blocks] + Given the action \texttt{unstack(X, Y)} with: + \[ + \begin{split} + \texttt{d\_list} &= \{ \texttt{handempty}, \texttt{on(X, Y)}, \texttt{clear(X)} \} \\ + \texttt{a\_list} &= \{ \texttt{holding(X)}, \texttt{clear(Y)} \} + \end{split} + \] + We have that: + \[ + \begin{split} + \texttt{regr[holding(b), unstack(b, Y)]} &= \texttt{true} \\ + \texttt{regr[handempty, unstack(X, Y)]} &= \texttt{false} \\ + \texttt{regr[ontable(c), unstack(X, Y)]} &= \texttt{ontable(c)} \\ + \texttt{regr[clear(c), unstack(X, Y)]} &= \begin{cases} + \texttt{true} & \text{if \texttt{Y}=\texttt{c}} \\ + \texttt{clear(c)} & \text{otherwise} + \end{cases} + \end{split} + \] + \end{example} +\end{descriptionlist} + + +\subsection{Deductive planning} +\marginnote{Deductive planning} +Formulates the planning problem using first order logic to represent states, goals and actions. +Plans are generated as theorem proofs. + +\subsubsection{Green's formulation} +\marginnote{Green's formulation} +Green's formulation is based on \textbf{situation calculus}. +To find a plan, the goal is negated and it is proven that it leads to an inconsistency. + +The main concepts are: +\begin{descriptionlist} + \item[Situation] + Properties (fluents) that hold in a given state \texttt{s}. + \begin{example}[Moving blocks] + To denote that \texttt{ontable(c)} holds in a state \texttt{s}, we use the axiom: + \[ \texttt{ontable(c, s)} \] + \end{example} + The operator \texttt{do} allows to evolve the state such that: + \[ \texttt{do(A, S)} = \texttt{S'} \] + \texttt{S'} is the new state obtained by applying the action \texttt{A} in the state \texttt{S}. + + \item[Actions] + Define the pre-condition and post-condition fluents of an action in the form: + \[ \texttt{pre-conditions} \rightarrow \texttt{post-conditions} \] + Applying the equivalence $A \rightarrow B \equiv \lnot A \vee B$, actions can be described by means of disjunctions. + \begin{example}[Moving blocks] + The action \texttt{stack(X, Y)} has pre-conditions \texttt{holding(X)} and \texttt{clear(Y)}, and + post-conditions \texttt{on(X, Y)}, \texttt{clear(X)} and \texttt{handfree}. + Its representation in Green's formulation is: + \[ + \begin{split} + \texttt{holding(X, S)} \land \texttt{clear(Y, S)} &\rightarrow \\ + &\texttt{on(X, Y, do(stack(X, Y), s))} \land \\ + &\texttt{clear(X, do(stack(X, Y), s))} \land \\ + &\texttt{handfree(do(stack(X, Y), s))} \\ + \end{split} + \] + \end{example} + + \item[Frame axioms] + Besides the effects of actions, each state also have to define for all non-changing fluents their frame axioms. + If the problem is complex, the number of frame axioms becomes unreasonable. + \begin{example}[Moving blocks] + \[ \texttt{on(U, V, S)}, \texttt{diff(U, X)} \rightarrow \texttt{on(U, V, do(move(X, Y, Z), S))} \] + \end{example} +\end{descriptionlist} + + +\begin{example}[Moving blocks] + The initial state is described by the following axioms:\\[0.5em] + \begin{minipage}{.3\linewidth} + \centering + \texttt{on(a, d, s0)} \\ + \texttt{on(b, e, s0)} \\ + \texttt{on(c, f, s0)} \\ + \texttt{clear(a, s0)} \\ + \texttt{clear(b, s0)} \\ + \end{minipage} + \begin{minipage}{.3\linewidth} + \centering + \texttt{clear(c, s0)} \\ + \texttt{clear(g, s0)} \\ + \texttt{diff(a, b)} \\ + \texttt{diff(a, c)} \\ + \texttt{diff(a, d)} \dots \\ + \end{minipage} + \begin{minipage}{.3\linewidth} + \centering + \includegraphics[width=\linewidth]{img/_moving_block_example_green.pdf} + \end{minipage}\\[0.5em] + + For simplicity, we only consider the action \texttt{move(X, Y, Z)} that moves \texttt{X} from \texttt{Y} to \texttt{Z}. + It is defined as: + \[ + \begin{split} + \texttt{clear(X, S)}&, \texttt{clear(Z, S)}, \texttt{on(X, Y, S)}, \texttt{diff(X, Z)} \rightarrow \\ + &\texttt{clear(Y, do(move(X, Y, Z), S))}, \texttt{on(X, Z, do(move(X, Y, Z), S))} + \end{split} + \] + This action can be translated into the following effect axioms: + \[ + \begin{split} + \lnot\texttt{clear(X, S)} &\vee \lnot\texttt{clear(Z, S)} \vee \lnot\texttt{on(X, Y, S)} \vee \lnot\texttt{diff(X, Z)} \vee \\ + &\texttt{clear(Y, do(move(X, Y, Z), S))} + \end{split} + \] + \[ + \begin{split} + \lnot\texttt{clear(X, S)} &\vee \lnot\texttt{clear(Z, S)} \vee \lnot\texttt{on(X, Y, S)} \vee \lnot\texttt{diff(X, Z)} \vee \\ + &\texttt{on(X, Z, do(move(X, Y, Z), S))} + \end{split} + \] +\end{example} + +Given the goal \texttt{on(a, b, s1)}, we prove that $\lnot\texttt{on(a, b, s1)}$ leads to an inconsistency. +We decide to make the following substitutions: +\[ \{ \texttt{X}/\texttt{a}, \texttt{Z}/\texttt{b}, \texttt{s1}/\texttt{do(move(a, Y, b), S)} \} \] +The premise of \texttt{move} leads to an inconsistency (when applying \texttt{move} its premise is false): +\begin{center} + \begin{tabular}{c|c|c|c} + $\lnot\texttt{clear(a, S)}$ & $\lnot\texttt{clear(b, S)}$ & $\lnot\texttt{on(a, Y, S)}$ & $\lnot\texttt{diff(a, b)}$ \\ + False with $\{ \texttt{S}/\texttt{s0} \}$ & False with $\{ \texttt{S}/\texttt{s0} \}$ + & False with $\{ \texttt{S}/\texttt{s0}, \texttt{Y}/\texttt{d} \}$ & False + \end{tabular} +\end{center} +Therefore, the substitution $\{ \texttt{s1}/\texttt{do(move(a, Y, b), S)} \}$ defines the plan to reach the goal \texttt{on(a, b, s1)}. + + +\subsubsection{Kowalsky's formulation} +\marginnote{Kowalsky's formulation} +Kowalsky's formulation avoids the frame axioms problem by using a set of fixed predicates: +\begin{descriptionlist} + \item[\texttt{holds(rel, s/a)}] + Describes the relations \texttt{rel} that are true in a state \texttt{s} or after the execution of an action \texttt{a}. + \item[\texttt{poss(s)}] + Indicates if a state \texttt{s} is possible. + \item[\texttt{pact(a, s)}] + Indicates if an action \texttt{a} can be executed in a state \texttt{s}. +\end{descriptionlist} +Actions can be described as: +\[ \texttt{poss(S)} \land \texttt{pact(A, S)} \rightarrow \texttt{poss(do(A, S))} \] + +In the Kowalsky's formulation, each action requires a frame assertion (in Green's formulation, each state requires frame axioms). + +\begin{example}[Moving blocks] + An initial state can be described by the following axioms:\\[0.5em] + \begin{minipage}{.35\linewidth} + \centering + \texttt{holds(on(a, b), s0)} \\ + \texttt{holds(ontable(b), s0)} \\ + \texttt{holds(ontable(c), s0)} \\ + \end{minipage} + \begin{minipage}{.35\linewidth} + \centering + \texttt{holds(clear(a), s0)} \\ + \texttt{holds(clear(c), s0)} \\ + \texttt{holds(handempty, s0)} \\ + \texttt{poss(s0)} \\ + \end{minipage} + \begin{minipage}{.2\linewidth} + \centering + \includegraphics[width=0.6\linewidth]{img/_moving_block_example_kowalsky.pdf} + \end{minipage}\\[0.5em] +\end{example} + +\begin{example}[Moving blocks] + The action \texttt{unstack(X, Y)} has: + \begin{descriptionlist} + \item[Pre-conditions] \texttt{on(X, Y)}, \texttt{clear(X)} and \texttt{handempty} + \item[Effects] \phantom{} + \begin{description} + \item[Add-list] \texttt{holding(X)} and \texttt{clear(Y)} + \item[Delete-list] \texttt{on(X, Y)}, \texttt{clear(X)} and \texttt{handempty} + \end{description} + \end{descriptionlist} + + Its description in Kowalsky's formulation is: + \begin{descriptionlist} + \item[Pre-conditions] + \[ + \begin{split} + \texttt{holds(on(X, Y), S)}&, \texttt{holds(clear(X), S)}, \texttt{holds(handempty, S)} \rightarrow \\ + &\texttt{pact(unstack(X, Y), S)} + \end{split} + \] + + \item[Effects] (use add-list) + \[ \texttt{holds(holding(X), do(unstack(X, Y), S))} \] + \[ \texttt{holds(clear(Y), do(unstack(X, Y), S))} \] + + \item[Frame condition] (uses delete-list) + \[ + \begin{split} + \texttt{holds(V, S)}&, \texttt{V} \neq \texttt{on(X, Y)}, \texttt{V} \neq \texttt{clear(X)}, \texttt{V} \neq \texttt{handempty} + \rightarrow \\ + & \texttt{holds(V, do(unstack(X, Y), S))} + \end{split} + \] + \end{descriptionlist} +\end{example} + + +\subsection{STRIPS} +\marginnote{STRIPS} +STRIPS (Stanford Research Institute Problem Solver) is an ad-hoc algorithm +for linear planning resolution. +The elements of the problem are represented as: +\begin{descriptionlist} + \item[State] represented with its true fluents. + \item[Goal] represented with its true fluents. + \item[Action] represented using three lists: + \begin{descriptionlist} + \item[Preconditions] Fluents that are required to be true in order to apply the action. + \item[Delete-list] Fluents that become false after the action. + \item[Add-list] Fluents that become true after the action. + \end{descriptionlist} + Add-list and delete-list can be combined in an effect list with positive (add-list) and negative (delete-list) axioms. + + \begin{description} + \item[STRIPS assumption] Everything that is not in the add-list or delete-list is unchanged in the next state. + \end{description} +\end{descriptionlist} + +STRIPS uses two data structures: +\begin{descriptionlist} + \item[Goal stack] Does a backward search to reach the initial state. + \item[Current state] Represents the forward application of the actions found using the goal stack. +\end{descriptionlist} + +\begin{algorithm} +\caption{STRIPS} +\begin{lstlisting}[mathescape=true] +def strips(problem): + goal_stack = Stack() + current_state = State(problem.initial_state) + goal_stack.push(problem.goal) + plan = [] + while not goal_stack.empty(): + if (goal_stack.top() is a single/conjunction of goals and + there is a substitution $\theta$ that makes it $\subseteq$ current_state): + A = goal_stack.pop() + $\theta$ = find_substitution(A, current_state) + goal_stack.apply_substitution($\theta$) + elif goal_stack.top() is a single goal: + R = rule with a $\in$ R.add_list + _ = goal_stack.pop() # Pop goal + goal_stack.push(R) + goal_stack.push(R.preconditions) + elif goal_stack.top() is a conjunction of goals: + for g in permutation(goal_stack.top()): + goal_stack.push(g) + # Note that there is no pop + elif goal_stack.top() is an action: + action = goal_stack.pop() + current_state.apply(action) + plan.append(action) + return plan +\end{lstlisting} +\end{algorithm} + +\begin{example}[Moving blocks] + \begin{center} + \includegraphics[trim={0 16cm 0 0}, clip, width=0.85\textwidth]{img/_strips_example.pdf} + \end{center} + \begin{center} + \includegraphics[trim={0 0 0 33.8cm}, clip, width=0.85\textwidth]{img/_strips_example.pdf} + \end{center} +\end{example} + +Since there are non-deterministic choices, the search space may become very large. +Heuristics may be used to avoid this. + +Conjunction of goals are solved separately, but this could lead to the \marginnote{Sussman anomaly} \textbf{Sussman anomaly} +where a sub-goal destroys what another sub-goal has done. +For this reason, when a conjunction is encountered, it is not immediately popped from the goal stack +and is left as a final check. + + + +\section{Non-linear planning} +\marginnote{Non-linear planning} + + +\subsection{Partial order planning} + +Non-linear planning finds a plan as a search problem in the space of plans (instead of states as in linear planning). +Each node of the search tree is a partial plan. Edges represent plan refinement operations. + +A non-linear plan is represented by: +\begin{descriptionlist} + \item[Actions{\normalfont.}] \marginnote{Actions set} + \item[Orderings] \marginnote{Orderings set} + between actions. + \item[Causal links] \marginnote{Causal links} + triplet $\langle S_i, S_j, c \rangle$ where $S_i$ and $S_j$ are actions and $c$ is a sub-goal. + $c$ should be the effect of $S_i$ and precondition of $S_j$. + + Causal links represent causal relations between actions (i.e. interaction between sub-goals): + to execute $S_j$, the effect $c$ of $S_i$ is required first. +\end{descriptionlist} + +The initial plan is an empty plan with two fake actions \texttt{start} and \texttt{stop} +with ordering $\texttt{start} < \texttt{stop}$: +\begin{descriptionlist} + \item[\texttt{start}] has no preconditions and the effects match the initial state. + \item[\texttt{stop}] has no effects and the preconditions match the goal. +\end{descriptionlist} +At each step, one of the following refinement operations can be applied until the goal is reached: +\begin{itemize} + \item Add an action to the set of actions. + \item Add an ordering to the set of orderings. + \item Add a causal link to the set of causal links. +\end{itemize} + +\begin{figure}[h] + \centering + \includegraphics[width=0.45\textwidth]{img/_nonlinear_plan_example.pdf} + \caption{Example of search tree in non-linear planning} +\end{figure} + + +\begin{description} + \item[Least commitment planning] \marginnote{Least commitment planning} + Only strictly necessary restrictions (e.g. ordering) are imposed. + Non-linear planning is a least commitment planning. + + \item[Linearization] \marginnote{Linearization} + At the end, the partially ordered actions should be linearized, + respecting the ordering constraints, to obtain the final plan. +\end{description} + + +\begin{description} + \item[Threat] \marginnote{Threat} + An action $S_k$ is a threat to a causal link $\langle S_i, S_j, c \rangle$ + if its effects cancel $c$. + $S_k$ should not be executed in between $S_i$ and $S_j$. + + \begin{figure}[H] + \centering + \includegraphics[width=0.3\textwidth]{img/_threat_example.pdf} + \caption{Example of threat. Causal links are represented using thick arrows.} + \end{figure} + + Possible solutions to a threat $S_k$ to $\langle S_i, S_j, c \rangle$ are: + \begin{descriptionlist} + \item[Demotion] \marginnote{Demotion} + Add the ordering constraint $S_k < S_i$ (i.e. threat executed before). + \item[Promotion] \marginnote{Promotion} + Add the ordering constraint $S_k > S_j$ (i.e. threat executed after). + \end{descriptionlist} +\end{description} + +\begin{algorithm}[H] +\caption{Partial order planning (POP)} +\begin{lstlisting}[mathescape=true] +def pop(initial_state, goal, actions): + plan = init_empty_plan(initial_state, goal) + while not plan.isSolution(): + try: + sn, c = selectSubgoal(plan) + chooseOperator(plan, actions, sn, c) + resolveThreats(plan) + except PlanFailError: + plan.backtrack() + return plan + +def selectSubgoal(plan): + sn, c = random([sn, c in plan.steps if c in sn.unsolved_preconditions]) + return sn, c + +def chooseOperator(plan, actions, sn, c): + s = random([s in (actions + plan.steps) if c in s.effects]) + if s is None: raise(PlanFailError) + plan.addCausalLink($\langle$s, sn, c$\rangle$) + plan.addOrdering(s < sn) + if s not in plan.steps: + plan.addAction(s) + plan.addOrdering(start < s < stop) + +def resolveThreats(plan): + for s_k, s_i, s_j in plan.threats(): + resolution = random([ DEMOTION, PROMOTION ]) + if resolution == DEMOTION: + plan.addOrdering(s_k < s_i) + elif resolution == PROMOTION: + plan.addOrdering(s_k > s_j) + if plan.isNotConsistent(): raise(PlanFailError) +\end{lstlisting} +\end{algorithm} + +\begin{example}[Purchasing schedule] + The initial state is: + \[ \texttt{at(home)}, \texttt{sells(hws, drill)}, \texttt{sells(sm, milk)}, \texttt{sells(sm, banana)} \] + where $\texttt{hws}$ means "hardware store" and $\texttt{sm}$ means "supermarket". + + The goal is: + \[ \texttt{at(home)}, \texttt{have(drill)}, \texttt{have(milk)}, \texttt{have(banana)} \] + + The possible actions are:\\[0.5em] + \begin{minipage}{.5\linewidth} + \begin{descriptionlist} + \item[\texttt{GO(X, Y)}] \phantom{} + \begin{description} + \item[Preconditions] $\texttt{at(X)}$ + \item[Effects] $\texttt{at(Y)}$, $\lnot \texttt{at(X)}$ + \end{description} + \end{descriptionlist} + \end{minipage} + \begin{minipage}{.5\linewidth} + \begin{descriptionlist} + \item[\texttt{BUY(S, Y)}] \phantom{} + \begin{description} + \item[Preconditions] $\texttt{at(S)}$, $\texttt{sells(S, Y)}$ + \item[Effects] $\texttt{have(Y)}$ + \end{description} + \end{descriptionlist} + \end{minipage}\\[0.5em] + + Partial order planning steps are: + \begin{enumerate} + \item Define the initial plan: + \begin{center} + \includegraphics[width=0.7\textwidth]{img/_pop_example1.pdf} + \end{center} + + \item The loop of POP is: + \begin{itemize} + \item Choose an action $a_i$ and one of its unsolved preconditions $c$. + \item Select an action $a_j$ with the precondition $c$ in its effects. + \item Add the ordering constraint $\texttt{start} < a_j < \texttt{stop}$. + \item Add the causal link $\langle a_j, a_i, c \rangle$ (and ordering $a_j < a_i$). + \item Solve threats. + \end{itemize} + + We choose the action $a_i = \texttt{stop}$ and the precondition $c = \texttt{have(drill)}$. + We choose as action with $c$ in its effects $a_j = \texttt{BUY(X, drill)}$. + We therefore add to the plan the ordering $\texttt{start} < \texttt{BUY(X, drill)} < \texttt{stop}$ and + the causal link $\langle \texttt{BUY(X, drill)}, \texttt{stop}, \texttt{have(drill)} \rangle$: + \begin{center} + \includegraphics[width=0.7\textwidth]{img/_pop_example2.pdf} + \end{center} + + \item Repeat the previous point for the preconditions $\texttt{have(milk)}$ and $\texttt{have(banana)}$: + \begin{center} + \includegraphics[width=0.7\textwidth]{img/_pop_example3.pdf} + \end{center} + + \item Now, we choose as action $\texttt{BUY(X, drill)}$ and as unsolved precondition $\texttt{sells(X, drill)}$. + This can be solved from the action $\texttt{start}$ with effect $\texttt{sells(hws, drill)}$. + We make the substitution $\texttt{X}/\texttt{drill}$ and + add $\langle \texttt{start}, \texttt{BUY(hws, drill)}, \texttt{sells(hws, drill)} \rangle$ to the causal links. + The same process can be repeated for $\texttt{BUY(X, milk)}$ and $\texttt{BUY(X, banana)}$: + \begin{center} + \includegraphics[width=0.7\textwidth]{img/_pop_example4.pdf} + \end{center} + + \item Now, we choose as action $\texttt{BUY(hws, drill)}$ and as unsolved precondition $\texttt{at(hws)}$. + This can be solved using the action $\texttt{GO(X, hws)}$. + We add $\langle \texttt{GO(X, hws)}, \texttt{BUY(hws, drill)}, \texttt{at(hws)} \rangle$ to the causal links. + + We continue by choosing as action $\texttt{GO(X, hws)}$ and as unsolved precondition $\texttt{at(X)}$. + This can be solved from $\texttt{start}$ with effect $\texttt{at(home)}$. + We therefore make the substitution $\texttt{X}/\texttt{home}$ and + add $\langle \texttt{start}, \texttt{GO(home, hws)}, \texttt{at(home)} \rangle$ to the causal links. + + The same process can be repeated for the $\texttt{milk}$ and $\texttt{banana}$ branch: + \begin{center} + \includegraphics[width=0.7\textwidth]{img/_pop_example5.pdf} + \end{center} + + \item We have a threat between $\texttt{GO(home, hws)}$ and $\texttt{GO(home, sm)}$ as they both + require the precondition $\texttt{at(home)}$ and both have as effect $\lnot\texttt{at(home)}$. + It can be easily seen that neither promotion nor demotion solves the conflict. + We are therefore forced to backtrack. + + We backtrack at the previous point, where we chose as action $\texttt{GO(X, sm)}$ and as precondition $\texttt{at(X)}$ + (this step has been implicitly done in the previous point). + \begin{itemize} + \item Instead of choosing the action $\texttt{start}$, we choose $\texttt{GO(home, hws)}$ with the effect $\texttt{at(hws)}$. + We therefore make the substitution $\texttt{X}/\texttt{hws}$ and update the causal links. + \item We also resolve the threat $\texttt{GO(hws, sm)}$ to $\texttt{BUY(hws, drill)}$ + (it removes the precondition $\texttt{at(hws)}$) + by promoting $\texttt{GO(hws, sm)}$ + and adding the ordering constraint $\texttt{BUY(hws, drill)} < \texttt{GO(hws, sm)}$: + \end{itemize} + \begin{center} + \includegraphics[width=0.7\textwidth]{img/_pop_example6.pdf} + \end{center} + + \item Now, we choose as action $\texttt{stop}$ and as precondition $\texttt{at(home)}$. + We choose as action $\texttt{GO(sm, home)}$ and update the causal links. + + Finally, we solve the threat $\texttt{GO(sm, home)}$ to + both $\texttt{BUY(sm, milk)}$ and $\texttt{BUY(sm, banana)}$ (it removes the required precondition $\texttt{at(sm)}$) + by promoting $\texttt{GO(sm, home)}$. + The newly added ordering constraints are + $\texttt{BUY(sm, milk)} < \texttt{GO(sm, home)}$ and + $\texttt{BUY(sm, banana)} < \texttt{GO(sm, home)}$. + + The final plan is: + \begin{center} + \includegraphics[width=0.7\textwidth]{img/_pop_example7.pdf} + \end{center} + By considering the ordering constraints, a linearization could be: + \[ + \begin{split} + \texttt{GO(home, hws)} &\rightarrow + \texttt{BUY(hws, drill)} \rightarrow + \texttt{GO(hws, sm)} \rightarrow\\ + &\texttt{BUY(sm, milk)} \rightarrow + \texttt{BUY(sm, banana)} \rightarrow + \texttt{GO(sm, home)} + \end{split} + \] + \end{enumerate} +\end{example} + + +\subsection{Modal truth criterion} +\marginnote{Modal truth criterion} + +Modal truth criterion uses five plan refinement methods that +ensures the completeness of the planner (POP is not complete). + +MTC refinement methods are: +\begin{descriptionlist} + \item[Establishment] \marginnote{Establishment} + The same standard operations of POP: + \begin{enumerate} + \item Insert a new action in the plan. + \item Add an ordering constraint. + \item Do a variable assignement. + \end{enumerate} + + \item[Promotion] \marginnote{Promotion} + As in POP. + + \item[Demotion] \marginnote{Demotion} + As in POP. + + \item[White knight] \marginnote{White knight} + Insert an operator $S_n$ between $S_k$ and $S_j$, where $S_k$ threatens $S_j$, + in such way that $S_n$ re-establishes the preconditions of $S_j$. + + \item[Separation] \marginnote{Separation} + Add a constraint to a variable to avoid that it unifies with an unwanted value. +\end{descriptionlist} + + + +\section{Hierarchical planning} +\marginnote{Hierarchical planning} +Hierarchical planning allows to create a complex plan at different levels of abstraction. +Different meta-level searches are executed to generate meta-level plans that are progressively refined. + + +\subsection{ABSTRIPS} +\marginnote{ABSTRIPS} +In ABSTRIPS, a criticality value is assigned to each precondition based on the complexity of its achievement. + +At each level, a plan is found assuming that the preconditions corresponding to lower levels of criticality are true. +At the next level, the previously found plan and its preconditions are used as starting point in the goal stack. + +\begin{algorithm} +\caption{ABSTRIPS} +\begin{lstlisting}[mathescape=true] + def abstrips(problem, start_threshold, threshold_step): + threshold = start_threshold + plan = None + while $\text{there is a precondition still not considered}$: + true_preconds = problem.preconds[criticality < threshold] + plan = strips(problem, true_preconds, starting_plan=plan) + threshold -= threshold_step + return plan +\end{lstlisting} +\end{algorithm} + + + +\subsection{Macro-operators} +\marginnote{Macro-operators} +In macro-operators, two types of operators are defined: +\begin{descriptionlist} + \item[Atomic] Elementary operations that can be executed by an agent. + \item[Macro] Set of atomic operators. Before execution, this type of operator has to be decomposed. + \begin{description} + \item[Precompiled decomposition] + The decomposition is known and described along side the preconditions and effects of the operator. + \item[Planned decomposition] + The planner has to synthesize the atomic operators that compose a macro operator. + \end{description} + + Constraints are needed for a safe decomposition. + Let $A$ be a macro with effect $X$ and $P$ its decomposition: + \begin{itemize} + \item $X$ must be the effect of at least an atomic action in $P$ and should be protected until the end of $P$. + \item Each precondition of the actions in $P$ must be guaranteed by previous actions or be a precondition of $A$. + \item $P$ must not threat any causal link. + \end{itemize} + + Moreover, when a macro action $A$ is replaced with its decomposition $P$: + \begin{itemize} + \item For each $B$ such that $B < A$, impose the ordering $B < \texttt{First($P$)}$. + \item For each $B$ such that $A < B$, impose the ordering $\texttt{Last($P$)} < B$. + \item Each causal link $\langle S, A, c \rangle$ is replaced with $\langle S, S_i, c \rangle$, + where $S_i$ are actions in $P$ with precondition $c$ and do not have other atomic operators of the macro before. + \item Each causal link $\langle A, S, c \rangle$ is replaced with $\langle S_i, A, c \rangle$, + where $S_i$ are actions in $P$ with effect $c$ and do not have other atomic operators of the macro after. + \end{itemize} + +\end{descriptionlist} + +\begin{algorithm} +\caption{Hierarchical decomposition POP} +\begin{lstlisting}[mathescape=true] +def hdpop(initial_state, goal, actions, decomposition_methods): + plan = init_empty_plan(initial_state, goal) + while not plan.isSolution(): + try: + if choice() == ESTABLISHMENT: + sn, c = selectSubgoal(plan) + chooseOperator(plan, actions, sn, c) + else: + macro = selectMacroStep(plan) + chooseDecomposition(macro, decomposition_methods, plan) + resolveThreats(plan) + except PlanFailError: + plan.backtrack() + return plan +\end{lstlisting} +\end{algorithm} + + + +\section{Conditional planning} +\marginnote{Conditional planning} +Conditional planning is based on the open world assumption where what is not in the initial state is unknown. +It generates a different plan for each source of uncertainty and therefore has exponential complexity. + +\begin{description} + \item[Sensing action] + Action with pre-conditions and post-conditions that allows to obtain unknown information. +\end{description} + + +\begin{example}[Inflate tire] + \phantom{}\\ + \begin{center} + \includegraphics[width=0.65\textwidth]{img/_conditional_planning.pdf} + \end{center} + + When executing a sensing action, a copy of the goal is generated for each possible scenario. +\end{example} + + + +\section{Reactive planning} +Reactive planners are on-line algorithms able to interact with the dynamicity the world. + +\subsection{Pure reactive systems} +\marginnote{Pure reactive systems} +Pure reactive planners have a knowledge base that describes the conditions for which an action has to be executed. +The choice of the action is predictable. Therefore, this approach is not suited for domains that require reasoning. + +\subsection{Hybrid systems} +\marginnote{Hybrid systems} +Hybrid planners integrate the generative and reactive approach. +The steps the algorithm does are: +\begin{itemize} + \item Generates a plan to achieve the goal. + \item Checks the pre-conditions and post-conditions of the action it is going to execute. + \item Backtracks the effects of an action in case of a failure. + \item Corrects the plan if external events occur. +\end{itemize} \ No newline at end of file