
\section{Opera\coes\ sobre os elementos de uma \sqn}

\subsection{Soma dos elementos de uma \sqn}
Dada uma \sqn\ $S$ de $m$ inteiros, calcule a soma dos elementos de S.

O objetivo consiste em estabelecer:
\[ R = \sum_{\lelt0im}S.i\]

\subsubsection{Solu\cao\ funcional} A solu\cao\ funcional \ee\ dada a partir 
da deriva\cao\ a seguir:
\begin{align*}
	R &= \bndsum{i}{\lelt0im}{S.i}\\
	  &= (S.0+S.1+\cdots+S.m-1)\\
	  &= ((\cdots((S.0+S.1)+S.2)+\cdots)+S.m-1)\\
	  &= ((\cdots((0+S.0)+S.1)+S.2)+\cdots)+S.m-1)\\
\end{align*}

Que \ee\ calculado em Haskell, assumindo que $S$ \'e agora representado por uma 
lista, por

\begin{lstlisting}[language=Haskell]{}

         foldl (+) 0 S 
\end{lstlisting}	 

As defini\coes\ de \emph{foldl} e \emph{foldr} s\ao\ padr\ao:
\begin{lstlisting}[language=Haskell]{}
	foldl op z [] = z
	foldl op a (x:xs) = foldl op (op a x) xs

	foldr op z [] = z
	foldr op a (x:xs) = op x (foldr op a xs)
\end{lstlisting}

Note que a associatividade \`a esquerda da opera\cao\ $(+)$, implementada
atrav\ee s do combinador \emph{foldl},  pode ser 
reescrita como associatividade \`a direita, implementada via \emph{foldr}.

\begin{lstlisting}[language=Haskell]{}

 foldr (+) 0 S 
\end{lstlisting}	 

que, por sua vez, implementa o padr\ao\ recursivo da fun\cao\ \emph{seqsum} a seguir:

\lstinputlisting[language=Haskell]{seqsum.hs}

Nessa fun\cao\ fique mais expl\ii cita a complexidade da soma dos elementos de uma \sqn. Ela demanda:
\begin{itemize}
	\item $m$ opera\coes\ de soma;
	\item $m+1$ testes de fim de \sqn;
	\item $m$ opera\coes\ para recuperar o \emph{tail} da \sqn\ atual.
\end{itemize}

\subsubsection{Solu\cao\ imperativa}

A solu\cao\ imperativa \'e facilmente obtida de uma generaliza\cao\ do output 
desejado
\[ R = \sum_{\lelt0im}S.i\]
a partir da oberva\cao\ da associatividade \`a esquerda do operador $(+)$: 
\begin{itemize}
	\item ao final do loop, $m$ elementos ter\ao\ sido acumulados produzindo
	      o resultado desejado;
	\item em um ciclo $k$, os $k$ primeiros elementos ter\ao\ sido acumulados.
\end{itemize}
Na f\oo rmula de $R$, generaliza-se a constante $M$ para uma vari\aa vel $k$ 
e insere-se a restri\cao\ de que $k$ deve ser maior ou igual a zero elementos
e menor ou igual a $m$ elementos.
\[ P = (\lele0km\land R= \sum_{\lelt0ik}S.i)\]
$P$ ser\aa\ obviamente a invariante do loop. A guarda do loop deve indicar 
quantos elementos ainda devem ser acumulados:
\[ B = (m-k \neq 0) \]

o que d\aa\ a vari\aa vel derivada
\[ T = m-k \]
e a condi\cao\ inicial
\[\text{\bf initially }k = 0 \land R = 0 \]

A deriva\cao\ final do programa consiste apenas em definir o comando guardado do loop que decrescer\aa\ $T$, mantendo a invariante $P$. Fica como exerc\ii cio.

\begin{ex}
	Prove que o programa derivado para c\aa lculo da soma dos elementos de 
	uma \sqn\ est\'a correto.
	\begin{enumerate}
		\item Prove que ele est\aa\ parcialmente correto.
			\begin{enumerate}
				\item Prove que $P$ \ee\ v\aa lido inicialmente.
				\item Prove que $P\land B\ll.\limp\wp{\alpha}{P}$, onde $\alpha$ \ee\ o comando guardado do loop.


				\item Prove que $P\land \neg B\ll.\limp R$
			\end{enumerate}
		\item Prove que o loop termina.
			\begin{enumerate}
				\item Prove que $P \land B\ll.\limp\lr.T>0$
				\item Prove que eventualmente $T=0$ e o loop termina.
			\end{enumerate}
	\end{enumerate}
\end{ex}

