
\section{Permuta\coes\ de uma \sqn}
Esta se\cao\ aborda algoritmos que tratam de variantes de um mesmo problema: calcular alguma permuta\cao\ de uma \sqn.


\subsection{Section swap} 
Dado um vetor \typeof{S.0..m-1}{Int} e dados inteiros $p,q,n$ tais que 
\[ n>0 \land 0\le\lele p{p+n}q\le{q+n}\le m\] 
calcule in-locu uma permuta\cao\ de $S$ que consiste em trocar as se\coes\footnote{
Exemplo retirado de \cite{gries:sp}.}
$S.p..p+n-1$ por $S.q..q+n-1$. 
Assumindo que $B$ 
cont\ee m o valor inicial de $S$, o objetivo consiste em calcular
\footnote{
$B$ \ee\ introduzido
aqui como vari\aa vel auxiliar para facilitar a deriva\cao\ do
programa.}

\begin{align*}
 R \dfn &S(0..p-1)=B(0..p-1)\\
         &\land S(p..p+n-1)=B(q..q+n-1)\\
         &\land S(p+n..q-1)=B(p+n..q-1)\\
         &\land S(q..q+n-1)=B(p..p+n-1)\\
	 &\land S(q+n..m-1)=B(q+n..m-1)
\end{align*}


A invariante $P$ do algoritmo para calcular o swap de se\coes\ do array
\ee\ obtida generalizando $R$, via troca da constante $n$ por
uma vari\aa vel $k$, que deve ser um inteiro entre $0$ e $n$.
\begin{align*}
 P \dfn &\lele 0kn\\
         &\land S(0..p-1)=B(0..p-1)\\
         &\land S(p..p+k-1)=B(q..q+k-1)\\
         &\land S(p+k..q-1)=B(p+k..q-1)\\
         &\land S(q..q+k-1)=B(p..p+k-1)\\
	 &\land S(q+k..m-1)=B(q+k..m-1)
\end{align*}

A vari\aa vel derivada \ee\ \oo bvia:
\[ T \dfn n-k\]

Essa vari\aa vel deve decrescer at\ee\ atingir o valor $0$, o que d\aa\
a guarda do loop:
\[ B_0 \dfn n-k > 0\]

Progresso no loop demanda reduzir $T$, via incremento de $k$, mantendo
a validade de $P$. A a\cao\ associada \`a transi\cao\ do loop, facilmente
derivada a partir de $P$ e do incremento de $k$, fica:

\[ S_0 \dfn S(p+k),S(q+k),k:=S(q+k),S(p+k),k+1\]


O algoritmo est\aa\ na \rffig{swapsec}. 

\begin{figure}
\lstset{language=Pascal,keywordstyle=\bfseries,escapechar=\@,
        keywords={do,od,if,fi,Seq,Int,cand,initially,Var,let,in,tel}}
\lstinputlisting{swapsec.tex}
\caption{Array swap}\label{swapsec}
\end{figure}	 


\begin{ex}
	Prove que:
	\begin{enumerate}
		\item $P\land \limp T>0$
		\item O programa da \rffig{swapsec} termina.
		\item $P\land B_0 \limp \wp{S_0}{P}$
		\item $P$ \ee\ uma invariante do loop do programa da 
			\rffig{swapsec}.
		\item $P\land \neg B_0 \limp R$
	\end{enumerate}
\end{ex}

O primeiro objetivo consiste em provar que a execu\cao\ de $S_0$ n\ao\
altera a validade de $P$. Antes, por\ee m,
observe que, ap\oo s $S_0$, um novo $S$, que chamaremos de $S'$, \ee\ produzido. 
\[ S'\dfn (S;p+k:S(q+k);q+k:S(p+k))\]

Note que $S'$ define os novos valores de $S$ e que as igualdades abaixo
de verificam e elas mostram que se\coes\ de $S$ n\ao\ foram alteradas.
\begin{gather*}
 S'(0..p+k-1)= S(0..p+k-1)\\
 S'(p+k+1..q+k-1)=S(p+k+1..q+k-1)\\
 S'(q+k+1..m-1)=S(q+k+1..m-1)
\end{gather*}

As igualdades a seguir mostram as posi\coes\ de $S$ que foram alteradas:
\begin{gather*}
	S'(p+k) = S(q+k)\\
	S'(q+k) = S(p+k) \\
\end{gather*}

Al\ee m disso, observe que
\begin{gather*}
	S(q+k) = B(q+k)\\
	S(p+k) = B(p+k)
\end{gather*}

Esses dois conjutnos de igualdades s\ao\ usadas na prova do teorema a seguir.
\begin{theo}
	$P\land B_0 \limp \wp{S_0}{P}$

\proofbeg
\begin{align*}
	&\wp{S_0}{P}\\
	=&\lele {-1}k{n-1}\\
         &\land S'(0..p-1)=B(0..p-1)\\
         &\land S'(p..p+k)=B(q..q+k)\\
         &\land S'(p+k+1..q-1)=B(p+k+1..q-1)\\
         &\land S'(q..q+k)=B(p..p+k)\\
	 &\land S'(q+k+1..m-1)=B(q+k+1..m-1)\\
        =&\lele {-1}k{n}\land k\neq n\\
         &\land S'(0..p-1)=B(0..p-1)\\
         &\land S'(p..p+k-1)=B(q..q+k-1)\\
	 &\land S'(p+k)=B(q+k) \\
         &\land S'(p+k..q-1)=B(p+k..q-1)\\
         &\land S'(q..q+k-1)=B(p..p+k-1)\\
	 &\land S'(q+k)=B(p+k)\\
	 &\land S'(q+k..m-1)=B(q+k..m-1)\\
	 =&\jstop{\text{subsituindo }S'}\\
	 &\lele {-1}k{n}\land k\neq n\\
         &\land S(0..p-1)=B(0..p-1)\\
         &\land S(p..p+k-1)=B(q..q+k-1)\\
	 &\land B(q+k)=B(q+k) \\
         &\land S(p+k..q-1)=B(p+k..q-1)\\
         &\land S(q..q+k-1)=B(p..p+k-1)\\
	 &\land B(p+k)=B(p+k)\\
	 &\land S(q+k..m-1)=B(q+k..m-1)\\
         =&\jstop{\text{simplificando }\land}\\
          &\lele {-1}k{n}\land k\neq n\\
          &\land S(0..p-1)=B(0..p-1)\\
          &\land S(p..p+k-1)=B(q..q+k-1)\\
         &\land S(p+k..q-1)=B(p+k..q-1)\\
         &\land S(q..q+k-1)=B(p..p+k-1)\\
	 &\land S(q+k..m-1)=B(q+k..m-1)\\
        \lif&\jstop{\lrintro\lor}\\
          &\lele {0}k{n}\land k\neq n\\
          &\land S(0..p-1)=B(0..p-1)\\
          &\land S(p..p+k-1)=B(q..q+k-1)\\
         &\land S(p+k..q-1)=B(p+k..q-1)\\
         &\land S(q..q+k-1)=B(p..p+k-1)\\
	 &\land S(q+k..m-1)=B(q+k..m-1)\\
         =& P\land B_0
\end{align*}
\proofend

\end{theo}

\subsection{Reverso de uma \sqn} Dada uma \sqn, c\'alcule seu reverso. 

\subsubsection{A l\oo gica}

Gries e Schneider, em \cite{gries:sp}, apresentam o seguinte conjunto de
axiomas para definir o reverso de um \sqn.
\begin{align}
	\label{nullrev}& rev.\xnil = \xnil \\
	\label{consrev}& rev.\xcons cx = \xcat{(rev.x)}{\xsqn c}\\
	\text{onde}\nonumber&\\
	\label{nullcat}& \xcat\xnil y=y\\
	\label{conscat}& \xcat{(\xcons cx)}y = \xcons c{(\xcat xy)}
\end{align}

A solu\cao\ funcional, em Haskell, para o problema do reverso de uma
\sqn\ \ee\ retirada diretamente dos axiomas \ref{nullrev} e \ref{consrev}.

Talvez seja mais intuitivo ler $y$ como reverso de $x$ quando:
o \uu ltimo elemento de
$x$ \ee\ o primeiro de $y$, o primeiro de $x$ \ee\ \uu ltimo em $y$ e a sub\sqn\
que vai do segundo ao pen\uu ltimo elemento de $y$ \ee\ o reverso da sub\sqn\ que
vai do segundo ao pen\uu ltimo elemento de $x$.

\begin{align}
	& reverse.\xsqn{}= \xsqn{}\\
	& reverse.\xsqn{a} = \xsqn{a}\\
 	& reverse (\xsnoc{\xcons ax}b) = \xsnoc{\xcons{b}{(reverse.x)}}a\\
	\text{onde} &\\
	& \xsnoc xa = \xcat x\xsqn a
\end{align}

\begin{ex} \label{rev:ex}
	Prove que:
	\begin{enumerate}
		\item $rev.\xcat{\xsqn a}{x}=\xcat{(rev.x)}{\xsqn a}$
		\item $rev.\xcat{x}{\xsqn a}=\xcat{\xsqn a}{rev.x}$
		\item $rev.\xcat{\xsqn a}{\xcat{x}{\xsqn b}}=\xcat{\xsqn b}{\xcat{(rev.x)}{\xsqn a}}$
	\end{enumerate}
\end{ex}

A \uu ltima prova do \rfex{rev:ex} fornece a base a defini\cao\
da invariante do algoritmo imperativo para c\aa lculo do reverso de uma 
\sqn.


\subsubsection{Solu\cao\ imperativa}
A invariante do algoritmo para c\aa lculo do reverso de uma \sqn\ surge 
da generaliza\cao\ do teorema provado no \rfex{rev:ex}.
\begin{ex}
	\label{gen:rev:ex}
	Prove que
	\begin{enumerate}
	  \item $rev.\xcat xy = \xcat{(rev.y)}{(rev.x)}$
	  \item $rev.\xcat{x}{\xcat{w}{\xcat{y}{z}}}=\xcat{(rev.z)}{\xcat{(rev.\xcat wy)}{(rev.x)}}$
        \end{enumerate}
\end{ex}

Uma defini\cao\ alternativa para o reverso de uma \sqn, mais adequada ao
tratamento de \sqn\ como array.

\begin{definition}
	\begin{align*}
	S.i..j &= rev(B.h..k)\dfn \\
	   &j-i=k-h \\
	   &\land\lr. j-i<0\\
	   &\quad\lor (S.i=B.k \land S(i+1..j)= rev(B.h..k-1))
        \end{align*}
\end{definition}
\begin{ex}
	\label{rev:inv:ex}
	Apresente uma defini\cao\ formal de se\cao\ de uma \sqn\ $S$ e
	prove que para qualquer inteiro $i$ n\ao\ negativo, menor do que zero:
	\begin{align*}
		rev.S(0..m-1)= &{(rev.S(m-1-i..m-1))}\\
		\xcatftor&{(rev.S(i..m-1-i))}\\
		\xcatftor&{(rev.S(0..i))}
	\end{align*}
\end{ex}

\begin{ex}
	Apresente uma algoritmo para c\aa lculo do reverso de uma \sqn e
	prove sua corre\cao.
	\begin{enumerate}
		\item Use teorema provado no \rfex{rev:inv:ex} para definir
			a invariante $P$ do loop do algoritmo.
		\item Use a vari\aa vel derivada
			\[ T = m-2i \]
		\item Define a guarda $B$ do loop e prove que
			\[ P\land B\ll.\limp\lr. \wp\alpha P\]
			onde $\alpha$ \ee\ 
			\[ S.i,S(m-1-i),i := S(m-1-i),S.i,i+1\]
	\end{enumerate}
\end{ex}



\subsection{Parti\cao\ de uma \sqn\ por um \pivot}
Dada uma \sqn\ $S$ e um elemento indicado como \pivot, o objetivo consiste em
particionar a \sqn\ original em
duas \sqn s: de elementos menores do que o \pivot e de elementos maiores
do que o \pivot. Acrescentada a restri\cao\ de que a \sqn\ seja representada 
em um vetor e de que as trocas devem ser realizadas no pr\oo prio vetor,
evitando a gera\cao\ de \sqn s adicionais, o objetivo consiste em 
encontrar uma permuta\cao\ de $S$ e um valor $p$ tal que
\[ R\dfn \lelt 0pm \land S(0..p-1) < S.p \land S(p+1..m-1) \ge S.p \]

Dado que a posi\cao\ inicial do \pivot\ n\ao\ foi especificada, \ee\ 
razo\aa vel arbitrar que ele se encontrar inicialmente na posi\cao\ $0$
e que o objetivo consiste em estabelecer para algum $i$ que

\[  S(0..i-1) < S.0 \land S(i..m-1) > S.0 \]
para, ent\ao, computar $R$.

Note que se 
\[ \beta \dfn S.0,S(i-1),p:=S(i-1),S.0,i-1\]

ent\ao
\begin{align*}
	&\wp{\beta}{R}\\
  =& \lelt 0{i-1}m\\
   \land &S'(0..i-1-1)<S'(i-1)\\
   \land &S'(i-1+1..m-1)\ge S'(i-1)\\
   \land & {i-1=i-1}\\
   =&\jstop{\text{aritm\ee tica}}\\
   \land &\lele 1im\\
   \land &S'(0..i-1-1)<S'(i-1)\\
   \land &S'(i-1+1..m-1)\ge S'(i-1)\\
   = &\lele 1im\\
   \land &S'(0)<S'(i-1)\land S'(1..i-2)<S'(i-1)\\
   \land &S'(i..m-1)\ge S'(i-1)\\
   =&\jstop{S'=(S;0:S(i-1);i-1:S.0)}\\
    &\lele 1im\\
   \land & S(i-1) < S(0) \land S(1..i-2)<S(0)\\
   \land & S(i..m-1)\ge S(0)\\
   =&\lele 1im\\
   \land & S(1..i-1)<S(0)\\
   \land & S(i..m-1)\ge S(0)
\end{align*}

A precondi\cao\ derivada define o estado final do loop que construir\aa\ a 
permuta\cao\ de $S$:
   \[\lele 1im \land  S(1..i-1)<S(0) \land  S(i..m-1)\ge S(0)\]

Uma generaliza\cao\ dessa condi\cao, substituindo $m$ por $j$, define
parte da invariante:
    \[\lele 1im \land S(1..i-1)<S(0) \land  S(i..j-1)\ge S(0)\]
 A invariante \ee\ obtida fortalecendo essa condi\cao\ pela observa\cao\
 de que:
 \begin{itemize}
	 \item os elementos menores do que $S(0)$ est\ao\ compreendidos entre 
		 as posi\coes\ $1$ e $i-1$;
	 \item os elementos restantes est\ao\ compreendidos entre 
		 as posi\coes\ $i$ e $j-1$, o que imp\~oem $i\le j$, devendo
		 $j$ ficar limitado a $m$.
 \end{itemize}

 \[ P\dfn 1<\lele ijm \land S(1..i-1)<S(0) \land S(i..j-1)\ge S(0)\]

 O loop analisar\aa\ cada elemento da \sqn\ da esquerda para direita, 
incorporando a cada transi\cao\ um elemento
uma das parti\coes\ e reduzindo a sec\ao\ n\ao\
particionada do vetor, que \ee\ $S(j..m-1)$. Sua vari\aa vel derivada

\[ T \dfn (m-j) \]

A guarda do loop

\[ B\dfn m-j\neq 0\]

O progresso do loop em dire\cao\ ao ponto-fixo demanda decrementar $T$, que
s\oo\ pode ocorrer incrementando $j$, j\aa\ que $m$ \ee\ constante.
Por outro lado, o incremento de $j$ pode ocorrer sem perturbar invariante
em duas condi\coes:

\begin{itemize}
	\item quando $B_0$ \ee\ v\aa lido
		\[ B_0 \dfn S.j \ge S.0\];
	\item quando $B_1$ \ee\ v\aa lido
		\[ B_1 \dfn S.j<S.0\] 
		que demanda incorporar $S.j$ \`a parti\cao\
		dos elementos menores do que $S.0$.
\end{itemize}

A \rffig{lomutpartition} apresenta o algoritmo, que Bentley em 
\cite{bentley:pearls} atribui a Lomut. Note que cada comando apresenta
suas precondi\coes\ e poscondi\coes\ detalhadas.
As a\coes\ $S_0$ e $S_1$ s\ao\ facilmente derivadas:

\begin{gather*}
	S_0 \dfn j:=j+1\\
	S_1 \dfn S.i,S.j,i,j:=S.j,S.i,i+1,j+1
\end{gather*}

\begin{figure}
\lstset{language=Pascal,keywordstyle=\bfseries,escapechar=\@,
        keywords={do,od,if,fi,Seq,Int,cand,initially,Var,let,in,tel}}
\lstinputlisting{partition.outline.tex}
\caption{Parti\cao\ de Lomut}\label{lomutpartition}
\end{figure}

O pr\oo ximo passo consiste em provar a corre\cao\ do algoritmo da 
\rffig{lomutpartition}.


\begin{theo}
	Prove que  $P$ \ee\ v\aa lida inicialmente.
	\proofbeg
	Exerc\ii cio.
	\proofend
\end{theo}

O teorema a seguir estabelece que quando a invariante $P$ e a guarda do
loop s\ao\ v\aa lidas, ao menos uma das guardas do comando \textbf{if}
ser\aa\ v\aa lida.

\begin{theo}
	Prove que
	\[ P\land B \limp (B_0\lor B_1)\] 
	\proofbeg
	$B_0$ e $B_1$ s\ao\ complementares.
	\proofend
\end{theo}

O pr\oo ximo teorema estabelece que a a\cao\ associada \`a primeira guarda do
\textbf{if}, a\cao\ $S_0$ da guarda $B_0$, preserva a invariante do loop.
Sua prova fica como exerc\ii cio.

\begin{theo}
	Provar que 
	\[ P\land B \land B_0 \limp \wp S_0 P)\]
        \proofbeg
	Exerc\ii cio: veja prova a seguir.
	\proofend
\end{theo}

O teorema a seguir estabelece que a a\cao\ $S_1$, associada \`a guarda $B_1$
preserva a invariante $P$.


\begin{theo}
	Provar que 
	\[ P\land B \land B_1\limp \wp S_1 P)\]
	\proofbeg

\begin{align*}
	&\wp{S_1}{P}\\ 
=&\\
& 1<\lele {i+1}{j+1}m \\
&\land S'(1..i+1-1)<S'(0) \land S'(i+1..j+1-1)\ge S'(0)\\
=&\\
&-1<\lele ij{m-1} \\
&\land S'(1..i)<S'(0) \land S'(i+1..j)\ge S'(0)\\
=&\\
&0\le\lele ij{m} \\
&\land (m\neq j \land S'(1..i)<S'(0) \land S'(i+1..j)\ge S'(0))\\
=&\\
&(0=i\lor 0<\lele ij{m})\\
&\land (m\neq j \land S'(1..i)<S(0) \land S'(i+1..j)\ge S'(0))\\
=&\\
&(0=i\land m\neq j \land S'(1..i)<S'(0) \land S'(i+1..j)\ge S'(0))\\
&\lor (0<\lele ij{m} \land m\neq j \\
&\quad \land 
S'(1..i)<S'(0) \land S'(i+1..j)\ge S'(0))\\
\lif&\jstop{\lrintro{lor}}\\
&(0<\lele ij{m}) \land m\neq j \\
&\land S'(1..i)<S'(0) \land S'(i+1..j)\ge S'(0)\\
=&\jstop{\text{trocando }S'\text{ por seus valores em }S}\\
&(0<\lele ij{m}) \land m\neq j \\
&\land S(1..i-1)<S(0) \land S(i)\ge S(0) \\
&\land S(i+1..j-1)\ge S(0)\land S(j)<S(0)\\
=&\\
&P\land B \land B_1
\end{align*}

	\proofend
\end{theo}



   




