\documentclass[a4paper]{article}
\usepackage{amsmath, amssymb, amsfonts}
\usepackage[italian]{babel}
\usepackage[utf8]{inputenc}
\usepackage{graphicx}
\usepackage{hyperref}
\usepackage[a4paper, total={6in, 8in}]{geometry}
\usepackage{minted}
\usepackage{mathpazo}
\usepackage{fancyhdr}
\usepackage{amsthm}
\usepackage{tikz}
\usetikzlibrary{automata,positioning,shapes.geometric}

% Definizione degli ambienti
\newtheorem{theorem}{Teorema}
\newtheorem{definition}{Definizione}
\newtheorem{example}{Esempio}
\newtheorem{lemma}{Lemma}
\newtheorem{proposition}{Proposizione}

\hypersetup{
    pdftitle={Lezione di Informatica Teorica: Oracoli e Gerarchia Polinomiale},
    pdfauthor={Appunti da Trascrizione AI}
}

\pagestyle{fancy}
\fancyhf{}
\fancyhead[L]{\textit{Lezione di Informatica Teorica}}
\fancyfoot[C]{\thepage}

\title{Lezione di Informatica Teorica: Oracoli e Gerarchia Polinomiale}
\author{Appunti da Trascrizione Automatica}
\date{\today}

\begin{document}
\maketitle
\tableofcontents
\newpage

\section{Introduzione: Ripasso e Problemi Difficili}

Ricapitoliamo il problema del \textbf{Vertex Cover (VC)}.
\begin{definition}[Vertex Cover]
Dato un grafo $G=(V,E)$, un Vertex Cover $VC$ è un sottoinsieme di vertici $V' \subseteq V$ tale che per ogni arco $(u,v) \in E$, almeno uno tra $u$ e $v$ appartiene a $V'$.
\end{definition}

Il problema decisionale associato, che denotiamo $VC$, è:
\begin{definition}[Problema Decisionale VC]
$VC = \{ \langle G, k \rangle \mid G \text{ è un grafo e ammette un Vertex Cover di taglia al più } k \}$.
\end{definition}
Il problema $VC$ è \textbf{NP-completo}. Questo significa che un'istanza $\langle G,k \rangle$ appartiene a $VC$ se e solo se esiste un certificato conciso (un $V'$ di taglia $\le k$) verificabile in tempo polinomiale.

\subsection{Richiamo sulle Classi NP e Co-NP}
\begin{definition}[NP]
La classe NP (Non-deterministic Polynomial time) contiene i linguaggi per cui le istanze "sì" hanno un certificato conciso e verificabile in tempo polinomiale.
\end{definition}
\begin{definition}[Co-NP]
La classe Co-NP contiene i linguaggi $L$ tali che il loro complemento $\overline{L}$ appartiene a NP. Intuitivamente, per i problemi in Co-NP, le istanze "no" hanno un certificato conciso e verificabile in tempo polinomiale.
\end{definition}

\subsection{Il Problema Min-Cover}
Introduciamo un problema decisionale leggermente diverso: \textbf{Min-Cover}.
\begin{definition}[Min-Cover]
$Min-Cover = \{ \langle G, k \rangle \mid G \text{ è un grafo e il Vertex Cover di taglia minima ha taglia esattamente } k \}$.
\end{definition}
A differenza di $VC$, $Min-Cover$ richiede che la taglia sia \emph{esattamente} $k$ e che sia la taglia \emph{minima}.

\subsubsection{Complessità di Min-Cover}
*   \textbf{Sta in NP?} Se abbiamo un certificato $V'$ di taglia $k$, possiamo verificare che sia un Vertex Cover. Ma come verifichiamo che sia \emph{minimo}? Non possiamo, a meno di testare tutte le possibilità più piccole, che porterebbe a un tempo esponenziale. Sembra non essere in NP.
*   \textbf{Sta in Co-NP?} Per dimostrare che un'istanza $\langle G,k \rangle$ è un "no" (ovvero che la taglia minima non è $k$), dovremmo fornire un certificato conciso. Se la taglia minima fosse $< k$, potremmo fornire un $V'$ di taglia inferiore. Ma se la taglia minima fosse $> k$, non avremmo un modo semplice per certificarlo in Co-NP. Sembra non essere in Co-NP.
*   \textbf{Sta in PSPACE?} Sì. Possiamo generare tutti i possibili sottoinsiemi di $V$, verificare per ciascuno se è un Vertex Cover e calcolarne la taglia. Teniamo traccia della taglia minima trovata. Poiché i sottoinsiemi possono essere generati e testati uno alla volta riutilizzando lo stesso spazio, questo può essere fatto in spazio polinomiale.

\subsubsection{Un Algoritmo per Min-Cover}
Osserviamo che $Min-Cover$ può essere riformulato in termini di $VC$:
$\langle G, k \rangle \in Min-Cover \iff \langle G, k \rangle \in VC \text{ AND } \langle G, k-1 \rangle \notin VC$.

Questo significa che per decidere $Min-Cover$, possiamo fare due domande a un decisore per $VC$.
Consideriamo il seguente pseudocodice:
\begin{minted}[mathescape, linenos, escapeinside=||]{python}
# `check_VC` è una subroutine che decide il problema VC
def solve_MinCover(G, k):
    # Domanda 1: Esiste un VC di taglia <= k?
    result1 = check_VC(G, k)

    # Domanda 2: Esiste un VC di taglia <= k-1?
    result2 = check_VC(G, k - 1)

    # La taglia minima è esattamente k se result1 è vero E result2 è falso
    return result1 and (not result2)
\end{minted}
Questo algoritmo deterministico in tempo polinomiale necessita di un "aiuto" esterno da una procedura capace di risolvere $VC$.

\section{Macchine ad Oracolo}
Per formalizzare il concetto di "aiuto" o "subroutine esterna", introduciamo il modello delle \textbf{macchine ad oracolo}.

\begin{definition}[Macchina ad Oracolo]
Una macchina ad oracolo $M^L$ è una Macchina di Turing deterministica o non deterministica estesa con i seguenti componenti:
\begin{itemize}
    \item \textbf{Oracle Tape (Nastro dell'Oracolo):} Un nastro di sola scrittura utilizzato per formulare le query all'oracolo.
    \item \textbf{Query State ($q_?$):} Uno stato speciale in cui la macchina può entrare dopo aver scritto una query sull'Oracle Tape.
    \item \textbf{Answer States ($q_{yes}$, $q_{no}$):} Due stati speciali in cui la macchina transita in un singolo passo dopo essere entrata in $q_?$. La transizione dipende dalla risposta dell'oracolo: a $q_{yes}$ se la stringa sulla query tape è un'istanza "sì" del linguaggio $L$, a $q_{no}$ se è un'istanza "no".
\end{itemize}
L'oracolo $L$ è un linguaggio (un problema decisionale). Quando la macchina entra in $q_?$, la stringa sul nastro dell'oracolo viene valutata istantaneamente dall'oracolo $L$. Dopo la transizione a $q_{yes}$ o $q_{no}$, il contenuto dell'Oracle Tape viene automaticamente cancellato. Ogni query all'oracolo conta come un singolo passo di computazione per la macchina chiamante.
\end{definition}
La notazione $M^L$ indica che la macchina $M$ ha accesso a un oracolo per il linguaggio $L$.

\section{Classi di Complessità con Oracolo}
Le macchine ad oracolo permettono di definire nuove classi di complessità.
\begin{definition}[$P^C$]
$P^C = \{ L \mid L \text{ può essere deciso in tempo polinomiale da una macchina ad oracolo deterministica } M^{\text{L'}} \text{ dove } L' \in C \}$.
\end{definition}
\begin{definition}[$NP^C$]
$NP^C = \{ L \mid L \text{ può essere deciso in tempo polinomiale da una macchina ad oracolo non deterministica } M^{\text{L'}} \text{ dove } L' \in C \}$.
\end{definition}

\subsection{Min-Cover in $P^{NP}$}
Basandoci sull'algoritmo precedente per $Min-Cover$:
Il problema $VC$ è in NP. L'algoritmo \texttt{solve\_MinCover} è deterministico e fa un numero costante (2) di query a un oracolo per $VC$ (che è un linguaggio in NP).
Quindi, $Min-Cover \in P^{NP}$.

\subsection{Relazioni tra le Classi con Oracolo}
\begin{proposition}[$NP \subseteq P^{NP}$]
Sia $L \in NP$. Per dimostrare che $L \in P^{NP}$, costruiamo una macchina $M$ che utilizza un oracolo per $L$. $M$ prende l'input $x$, lo scrive sul nastro dell'oracolo, effettua una query. Se l'oracolo risponde "sì", $M$ accetta; altrimenti, $M$ rifiuta. Questa macchina è deterministica e opera in tempo polinomiale (solo 1 query + tempo per copiare input). Quindi, $L \in P^{NP}$.
\end{proposition}

\begin{proposition}[$CoNP \subseteq P^{NP}$]
Sia $L \in CoNP$. Ciò implica che $\overline{L} \in NP$. Costruiamo una macchina $M$ che utilizza un oracolo per $\overline{L}$. $M$ prende l'input $x$, lo scrive sul nastro dell'oracolo, effettua una query. Se l'oracolo per $\overline{L}$ risponde "sì" (cioè $x \in \overline{L}$), $M$ rifiuta; altrimenti (cioè $x \notin \overline{L}$, quindi $x \in L$), $M$ accetta. Questa macchina è deterministica e opera in tempo polinomiale. Quindi, $L \in P^{NP}$.
\end{proposition}

\begin{figure}[h]
    \centering
    \begin{tikzpicture}[node distance=1.5cm, auto, thick, scale=0.8, every node/.style={transformお待ち},
        set/.style = {ellipse, draw, minimum width=2.5cm, minimum height=1.5cm}]

        % P
        \node (P) [set, label=below:$P$] at (0,0) {};
        
        % NP and CoNP
        \node (NP) [set, above right=0.8cm and 0.8cm of P, label=below:$NP$] {};
        \node (CoNP) [set, above left=0.8cm and 0.8cm of P, label=below:$CoNP$] {};
        
        % PNP
        \node (PNP) [set, minimum width=5cm, minimum height=3.5cm, draw, fit=(NP) (CoNP), label=above:$P^{NP}$] at (0,1.5) {};

        % Inclusions
        \draw[->] (P) -- (NP);
        \draw[->] (P) -- (CoNP);
        \draw[->] (NP) -- (PNP);
        \draw[->] (CoNP) -- (PNP);
    \end{tikzpicture}
    \caption{Relazioni iniziali tra $P$, $NP$, $CoNP$ e $P^{NP}$}
\end{figure}

\section{Gerarchia Polinomiale}
La nozione di classi ad oracolo può essere generalizzata, definendo livelli ricorsivamente. Questo porta alla \textbf{Gerarchia Polinomiale}.
La gerarchia polinomiale è un insieme di classi di complessità denotate da $\Sigma_i^P$, $\Pi_i^P$, e $\Delta_i^P$ per $i \ge 0$.

\begin{definition}[Gerarchia Polinomiale]
Le classi della Gerarchia Polinomiale sono definite come segue:
\begin{itemize}
    \item \textbf{Livello 0:}
    $\Sigma_0^P = P$
    $\Pi_0^P = P$
    $\Delta_0^P = P$
    \item \textbf{Livello $i+1$ (per $i \ge 0$):}
    $\Sigma_{i+1}^P = NP^{\Sigma_i^P}$
    $\Pi_{i+1}^P = co\Sigma_{i+1}^P$
    $\Delta_{i+1}^P = P^{\Sigma_i^P}$
\end{itemize}
\end{definition}

\subsubsection{Esempi dei Primi Livelli:}
\begin{itemize}
    \item $\Sigma_1^P = NP^{\Sigma_0^P} = NP^P = NP$ (poiché un oracolo in P non aggiunge potere computazionale a una macchina NP, che già può simulare P).
    \item $\Pi_1^P = co\Sigma_1^P = coNP$.
    \item $\Delta_1^P = P^{\Sigma_0^P} = P^P = P$.
    \item $\Delta_2^P = P^{\Sigma_1^P} = P^{NP}$. (Il problema $Min-Cover$ visto prima si colloca precisamente in $\Delta_2^P$).
    \item $\Sigma_2^P = NP^{\Sigma_1^P} = NP^{NP}$.
    \item $\Pi_2^P = co\Sigma_2^P = coNP^{NP}$.
\end{itemize}

\subsection{Relazioni di Inclusione nella Gerarchia Polinomiale}
\begin{proposition}[Inclusioni Fondamentali]
Per ogni $i \ge 0$:
\begin{enumerate}
    \item $\Sigma_i^P \subseteq \Delta_{i+1}^P$: Ogni linguaggio in $\Sigma_i^P$ può essere deciso da una macchina deterministica in tempo polinomiale che fa una sola query a un oracolo per un linguaggio in $\Sigma_i^P$ (la query è l'input stesso).
    \item $\Pi_i^P \subseteq \Delta_{i+1}^P$: Similmente, ogni linguaggio in $\Pi_i^P$ (il cui complemento è in $\Sigma_i^P$) può essere deciso da una macchina deterministica in tempo polinomiale con un oracolo in $\Sigma_i^P$ (query il complemento dell'input e inverte la risposta).
    \item $\Delta_i^P \subseteq \Sigma_i^P$: Una macchina deterministica in tempo polinomiale con oracolo $\Sigma_{i-1}^P$ è meno potente di una macchina non deterministica in tempo polinomiale con lo stesso oracolo.
    \item $\Delta_i^P \subseteq \Pi_i^P$: Simile al punto 3, una macchina deterministica è meno potente di una macchina non deterministica che accetta se il complemento rifiuta.
\end{enumerate}
\end{proposition}

\begin{figure}[h]
    \centering
    \begin{tikzpicture}[node distance=1.5cm, auto, thick, scale=0.8, every node/.style={transformお待ち}]

        % Layer 0 (P)
        \node (P) [ellipse, draw, minimum width=2.5cm, minimum height=1.5cm, label=below:$P (\Sigma_0^P, \Pi_0^P, \Delta_0^P)$] at (0,0) {};

        % Layer 1 (NP, CoNP)
        \node (NP) [ellipse, draw, minimum width=2.5cm, minimum height=1.5cm, above right=1.2cm and 1.2cm of P, label=below:$NP (\Sigma_1^P)$] {};
        \node (CoNP) [ellipse, draw, minimum width=2.5cm, minimum height=1.5cm, above left=1.2cm and 1.2cm of P, label=below:$CoNP (\Pi_1^P)$] {};
        
        % Layer 2 (Delta_2^P)
        \node (Delta2) [ellipse, draw, minimum width=5cm, minimum height=2cm, fit=(NP) (CoNP), label=above:$\Delta_2^P (P^{NP})$] at (0, 3) {};

        % Layer 2 (Sigma_2^P, Pi_2^P)
        \node (Sigma2) [ellipse, draw, minimum width=2.5cm, minimum height=1.5cm, above right=1.2cm and 1.2cm of Delta2, label=below:$\Sigma_2^P (NP^{NP})$] {};
        \node (Pi2) [ellipse, draw, minimum width=2.5cm, minimum height=1.5cm, above left=1.2cm and 1.2cm of Delta2, label=below:$\Pi_2^P (CoNP^{NP})$] {};

        % Layer 3 (Delta_3^P)
        \node (Delta3) [ellipse, draw, minimum width=5cm, minimum height=2cm, fit=(Sigma2) (Pi2), label=above:$\Delta_3^P (P^{NP^{NP}})$] at (0, 6) {};

        % Layer 3 (Sigma_3^P, Pi_3^P)
        \node (Sigma3) [ellipse, draw, minimum width=2.5cm, minimum height=1.5cm, above right=1.2cm and 1.2cm of Delta3, label=below:$\Sigma_3^P$] {};
        \node (Pi3) [ellipse, draw, minimum width=2.5cm, minimum height=1.5cm, above left=1.2cm and 1.2cm of Delta3, label=below:$\Pi_3^P$] {};

        % Inclusions
        \draw[->] (P) -- (NP);
        \draw[->] (P) -- (CoNP);
        \draw[->] (NP) -- (Delta2);
        \draw[->] (CoNP) -- (Delta2);
        \draw[->] (Delta2) -- (Sigma2);
        \draw[->] (Delta2) -- (Pi2);
        \draw[->] (Sigma2) -- (Delta3);
        \draw[->] (Pi2) -- (Delta3);
        \draw[->] (Delta3) -- (Sigma3);
        \draw[->] (Delta3) -- (Pi3);
        
        % Vertical Ellipses for higher levels
        \node (dots1) at (0, 7.5) {$\vdots$};
        \node (dots2) at (0, 8) {$\vdots$};
        
        % PSPACE encompassing
        \node (PSPACE) [ellipse, draw, minimum width=10cm, minimum height=9cm, dashed, fit=(Delta3) (Sigma3) (Pi3), label=above right:$PSPACE$] at (0, 4.5) {};

        % EXPTIME encompassing
        \node (EXPTIME) [ellipse, draw, minimum width=12cm, minimum height=11cm, dashed, fit=(PSPACE), label=above right:$EXPTIME$] at (0, 5) {};
        
        % NEXPTIME encompassing
        \node (NEXPTIME) [ellipse, draw, minimum width=14cm, minimum height=13cm, dashed, fit=(EXPTIME), label=above right:$NEXPTIME$] at (0, 6) {};

        % R encompassing
        \node (R) [ellipse, draw, minimum width=16cm, minimum height=15cm, dashed, fit=(NEXPTIME), label=above right:$R$] at (0, 7) {};

    \end{tikzpicture}
    \caption{Struttura della Gerarchia Polinomiale e relazioni con altre classi.}
    \label{fig:polynomial_hierarchy}
\end{figure}

La gerarchia polinomiale contiene infiniti livelli, e la questione se questa gerarchia collassi (cioè se ci sia un livello $k$ tale che $\Sigma_k^P = PSPACE$) o se sia infinita è un problema aperto. Si ritiene che sia infinita. L'intera gerarchia polinomiale è contenuta in $PSPACE$. Al di sopra di $PSPACE$ troviamo $EXPTIME$, $NEXPTIME$, e infine la classe $R$ (Ricorsivamente enumerabile o Decidibile).

\subsection{Problemi Completi nella Gerarchia Polinomiale}
Le formule booleane quantificate (QBF) sono problemi naturali che si collocano ai vari livelli della gerarchia.

\begin{definition}[SAT Quantificato]
\begin{itemize}
    \item \textbf{Existential SAT ($SAT_{\exists}$):}
    $\{ \langle \Phi \rangle \mid \exists X_1, \dots, X_n \text{ tale che } \Phi(X_1, \dots, X_n) \text{ è vera} \}$
    Questo è il problema $SAT$ standard ed è NP-completo ($\Sigma_1^P$-completo).
    \item \textbf{Alternating SAT ($\Sigma_2^P$-complete):}
    $\{ \langle \Phi \rangle \mid \exists X_1, \dots, X_n \forall Y_1, \dots, Y_m \text{ tale che } \Phi(X, Y) \text{ è vera} \}$
    Questo problema è $\Sigma_2^P$-completo. Significa: "Esiste un'assegnazione per $X$ tale che per ogni assegnazione di $Y$, la formula $\Phi$ è vera".
    \item \textbf{Alternating SAT ($\Sigma_3^P$-complete):}
    $\{ \langle \Phi \rangle \mid \exists X \forall Y \exists Z \text{ tale che } \Phi(X, Y, Z) \text{ è vera} \}$
    Questo problema è $\Sigma_3^P$-completo. Significa: "Esiste un $X$ tale che per ogni $Y$, esiste un $Z$ tale che $\Phi$ è vera".
\end{itemize}
\end{definition}

L'alternanza dei quantificatori ("esiste", "per ogni", "esiste", ...) cattura la complessità dei giochi strategici (come gli scacchi): "Esiste una mossa che posso fare, tale che, qualunque mossa faccia il mio avversario, esiste una mossa che posso fare io, tale che... e alla fine vinco."

\section{Problemi Funzionali e Classi Funzionali}
Finora abbiamo parlato di problemi decisionali (risposta sì/no). Ora introduciamo i problemi funzionali, che richiedono il calcolo di un valore.

\begin{definition}[Functional Min-Cover (FMin-Cover)]
$FMin-Cover(G) = \min \{ |V'| \mid V' \subseteq V \text{ è un Vertex Cover di } G \}$.
\end{definition}
Questo problema richiede di calcolare la taglia del Vertex Cover minimo, non solo di decidere se esiste un VC di una certa taglia.

\subsection{La Classe FP}
\begin{definition}[FP (Functional Polynomial Time)]
FP è la classe delle funzioni che possono essere calcolate da trasduttori deterministici in tempo polinomiale. Un trasduttore è una Macchina di Turing con un nastro di output aggiuntivo.
\end{definition}
Le riduzioni polinomiali che usiamo spesso sono funzioni che appartengono a FP.

\subsection{FMin-Cover e le Classi con Oracolo}
Consideriamo nuovamente il problema $FMin-Cover$. Vogliamo calcolare la taglia del VC minimo. Abbiamo a disposizione un oracolo per $VC$ (il problema decisionale, che è NP-completo).

\subsubsection{Algoritmo per FMin-Cover usando un Oracolo VC:}
\textbf{1. Ricerca Lineare:}
\begin{enumerate}
    \item Si inizia con $k=1$.
    \item Si chiede all'oracolo $VC$: "Il grafo $G$ ha un Vertex Cover di taglia $\le k$?" (query $\langle G, k \rangle$).
    \item Se l'oracolo risponde "no", si incrementa $k$ e si ripete.
    \item Se l'oracolo risponde "sì", allora $k$ è la taglia minima. Si restituisce $k$.
\end{enumerate}
Il valore massimo di $k$ da testare è $|V|$ (poiché l'insieme di tutti i vertici $V$ è sempre un Vertex Cover). Quindi, si effettuano al più $|V|$ query all'oracolo. Poiché $|V|$ è polinomiale nella dimensione dell'input, questa procedura è in tempo polinomiale.
Quindi, $FMin-Cover \in FP^{NP}$.

\textbf{2. Ricerca Binaria (più efficiente):}
\begin{enumerate}
    \item Si stabilisce un intervallo di ricerca per la taglia minima, ad esempio $[0, |V|]$.
    \item Si seleziona il punto medio $m$ dell'intervallo.
    \item Si chiede all'oracolo $VC$: "Il grafo $G$ ha un Vertex Cover di taglia $\le m$?" (query $\langle G, m \rangle$).
    \item Se l'oracolo risponde "sì", significa che la taglia minima è $\le m$. Si restringe l'intervallo a $[0, m]$.
    \item Se l'oracolo risponde "no", significa che la taglia minima è $> m$. Si restringe l'intervallo a $[m+1, |V|]$.
    \item Si ripete fino a quando l'intervallo si riduce a un singolo valore.
\end{enumerate}
Con la ricerca binaria, il numero di query all'oracolo è $O(\log |V|)$.
Questa osservazione porta a una notazione più specifica per la classe di complessità:
$FMin-Cover \in FP^{NP[O(\log n)]}$. Questa notazione indica che la macchina deterministica in tempo polinomiale effettua solo un numero logaritmico di query all'oracolo in NP.

\subsection{Perché FMin-Cover non è in FP (se P $\neq$ NP)?}
La domanda finale è: $FMin-Cover \in FP$?
Se $FMin-Cover$ fosse in $FP$, significherebbe che esisterebbe un algoritmo deterministico in tempo polinomiale capace di \textbf{calcolare} la taglia del Vertex Cover minimo.
Se avessimo tale algoritmo, potremmo risolvere il problema decisionale $VC$ (che è NP-completo) in tempo polinomiale:
\begin{itemize}
    \item Input: $\langle G, k \rangle$.
    \item Calcola $size = FMin-Cover(G)$ usando l'algoritmo FP ipotizzato.
    \item Se $size \le k$, rispondi "sì"; altrimenti, rispondi "no".
\item Questo significherebbe che $VC \in P$. Ma poiché $VC$ è NP-completo, questo implicherebbe $P=NP$.
\end{itemize}
Poiché la maggior parte dei ricercatori ritiene che $P \neq NP$, si conclude che $FMin-Cover$ (e la maggior parte dei problemi di ottimizzazione NP-difficili) non è in FP.

Questo mostra la relazione fondamentale tra i problemi decisionali e i loro equivalenti funzionali/di ottimizzazione: la difficoltà di calcolare la soluzione ottimale è direttamente legata alla difficoltà di decidere una proprietà della soluzione.

\end{document}