[FMFP] Notes for examp prep

This commit is contained in:
2026-07-17 10:59:54 +02:00
parent 6967a1eb4c
commit 452e259792
5 changed files with 53 additions and 4 deletions
@@ -6,6 +6,26 @@
\paragraph{Programming} \paragraph{Programming}
The best tip here is to read the Haskell book, and to solve the exercises during the semester. The best tip here is to read the Haskell book, and to solve the exercises during the semester.
Remember that application is left-associative (i.e. \texttt{func x y} parenthesized is \texttt{(func x) y}, even if \texttt{x} is a function).
A handy to know shortening technique for functions is \texttt{Leaf . f} is equivalent to \texttt{leaf x = Leaf (f x)}.
Thus, the \texttt{.} operator chains functions.
For all functions with recursion, don't forget the base cases. In addition, for guards (i.e. statements with a pipe character (\texttt{|})),
there is no equal sign before the pipe characters.
For the cases notation, there are equal signs. We can use underscores as a ``don't care'' character.
\subparagraph{Lists}
In list comprehensions, to draw from a list, \texttt{<-} is used, to delimit the description of the list contents from the generator part, we use a pipe character
and to separate each statement in the generator part, we use a comma.
Remember that list comprehension does allow duplicates, so it is not entirely equivalent to sets.
We can use the \texttt{nub} function from \texttt{Data.List} to remove duplicates.
We can initialize infinite lists using the \texttt{..} syntax. We define the interval using \texttt{[1, 2..]}, or \texttt{[0, 0..]} to create an infinite lists of zeros.
More advanced types can be ``disassembled'' like this: \texttt{Node x l r} for type \texttt{Node a (Tree x) (Tree x)}
\subparagraph{Fold} \subparagraph{Fold}
One of the most important functions to understand is \texttt{foldr} (and \texttt{foldl}). One of the most important functions to understand is \texttt{foldr} (and \texttt{foldl}).
If you have used \texttt{reduce} functions before, in e.g. JavaScript / TypeScript, If you have used \texttt{reduce} functions before, in e.g. JavaScript / TypeScript,
@@ -22,8 +42,14 @@ In the Haskell prelude, they are defined as follows:
foldl :: (a -> b -> a) -> a -> [b] -> a foldl :: (a -> b -> a) -> a -> [b] -> a
foldl f z [] = z foldl f z [] = z
foldl f z (x:xs) = foldl f (f v x) xs foldl f z (x:xs) = foldl f (f z x) xs
\end{code} \end{code}
When extending them to more complex data structures such as trees, we may need to add one function to the arguments per type of possible element in the data structure.
Ideally, we first write the function, then infer its type.
Remember that in the definition of these two functions, the \texttt{-> b ->} (and \texttt{-> a ->}, respectively) denote the type of the base case.
For more elaborate data structures, the functions for each subtype should be in the same order as in the data type definition, for canonical definition of the fold function.
\subparagraph{zipWith} \subparagraph{zipWith}
To combine a \texttt{map} and a \texttt{zip} function, use \texttt{zipWith}, type: To combine a \texttt{map} and a \texttt{zip} function, use \texttt{zipWith}, type:
@@ -32,4 +58,13 @@ To combine a \texttt{map} and a \texttt{zip} function, use \texttt{zipWith}, typ
\TODO Add more remarks \TODO Add more remarks
\paragraph{Proofs} \paragraph{Proofs}
These proofs use structural induction, see Section~\ref{sec:induction-proofs} for that. These proofs use structural induction, often it is easiest to use strong structural induction, see Section~\ref{sec:induction-proofs} for that.
In many cases, generalizing the statement is what enables the proof. So whenever there is a constant, generalize the constant before doing the proof,
as otherwise the proof will likely be hard to impossible to pull off under the time constraints.
In that case, we set $P(t) \equiv \forall n \in \N_0$ the generalized statement, or equivalent.
Remember:
\begin{itemize}
\item for each case state the fixed variables (which are all free variables in this case)
\item in the base case / simple case, fix $n$
\item in the end state that since it holds for all $n$, it, in particular, holds for $n = 0$ (or equivalent)
\end{itemize}
@@ -5,6 +5,7 @@
The proof trees are again drawn up bottom up, applying rules from the outside in. The proof trees are again drawn up bottom up, applying rules from the outside in.
\begin{enumerate} \begin{enumerate}
\item Create a proof tree using the typing rules. \item Create a proof tree using the typing rules.
An easy way to avoid mistakes is to always write out the structure of each type in the tree.
\item During the proof, keep track of what the applications of rules tell us about types in a list. \item During the proof, keep track of what the applications of rules tell us about types in a list.
\item After reaching leafs in the prooftree, resolve the types by inserting the now known types into the types you kept in the list. \item After reaching leafs in the prooftree, resolve the types by inserting the now known types into the types you kept in the list.
\end{enumerate} \end{enumerate}
@@ -7,5 +7,9 @@ Contrary to those however, we have pre- and postconditions, which we typically n
This typically involves finding a loop invariant that holds before and after each iteration of the loop. This typically involves finding a loop invariant that holds before and after each iteration of the loop.
This invariant should mention every variable used in the loop. This invariant should mention every variable used in the loop.
Any other variable should also be mentioned in it. The loop \textit{variant} may also be added for proving termination. Any other variable should also be mentioned in it. The loop \textit{variant} may also be added for proving termination.
A typical for-loop loop variant would be \texttt{n - x}, as the next value of the loop variant has to be lower than the previous one. A typical for-loop loop variant would be \texttt{n - x = Z}, as the next value of the loop variant has to be lower than the previous one.
Of course, if \texttt{x} is decreasing, it itself can become the variant, as it fulfils the condition. Of course, if \texttt{x} is decreasing, it itself can become the variant, as it fulfils the condition.
Proof outlines work by providing post and pre-condition for each sub-statement in a statement.
If we need to rewrite a statement (e.g. before the first loop body to change to our loop invariant from the overall precondition),
we use the $\models$ symbol.
@@ -12,7 +12,7 @@ As a reminder, these are the operators (details in Section~\ref{sec:ltl-details}
\begin{itemize} \begin{itemize}
\item Now: $p$ states that the proposition is true ``\textit{now}'' \item Now: $p$ states that the proposition is true ``\textit{now}''
\item Holds until: $\Phi U \Psi$ states that $\Phi$ holds (with no other valid proposition holding between) until $\Psi$ holds. \item Holds until: $\Phi U \Psi$ states that $\Phi$ holds (with no other valid proposition holding between) until $\Psi$ holds.
\item Next: $\bigcirc \Phi$ states that $\Phi$ holds for the ``next'' \item Next: $\bigcirc \Phi$ states that $\Phi$ holds for the ``next'' (if nothing else specified from start state)
\item Eventually: $\Diamond \Phi$ states that $\Phi$ holds \textit{eventually}, $\Diamond \Phi \equiv (\texttt{true} U \Phi)$ \item Eventually: $\Diamond \Phi$ states that $\Phi$ holds \textit{eventually}, $\Diamond \Phi \equiv (\texttt{true} U \Phi)$
\item Always (from now on): $\square \Phi$ states that from now on, $\Phi$ will always hold, $\square \Phi \equiv \neg \Diamond \neg \Phi$ \item Always (from now on): $\square \Phi$ states that from now on, $\Phi$ will always hold, $\square \Phi \equiv \neg \Diamond \neg \Phi$
\end{itemize} \end{itemize}
@@ -21,7 +21,16 @@ remember to show the case where the antecedent is true and state that for antece
Another important remark is that you can't just write $\Diamond \neg s_1$, where $s_1$ is a state, you need to specify the propositions. Another important remark is that you can't just write $\Diamond \neg s_1$, where $s_1$ is a state, you need to specify the propositions.
We can also create statements, such as never as $\square \neg \Phi$ (always not $\Phi$), etc.
Overall, be careful with parenthesis!
\subparagraph{Liveness and Safety Properties} \subparagraph{Liveness and Safety Properties}
Proofs here run using the definitions directly, either by showing a counter example (for disproving) or showing that, in fact, the definition holds. Proofs here run using the definitions directly, either by showing a counter example (for disproving) or showing that, in fact, the definition holds.
Indirect proofs may also come in handy, because it is typically easier to show that something is not a safety property (or liveness property) that to show that it is. Indirect proofs may also come in handy, because it is typically easier to show that something is not a safety property (or liveness property) that to show that it is.
These two properties are \textit{mutually exclusive} (with one exception, \texttt{true}), to the extent that an LTL formula can't be both at the same time, but be a conjunct of both.
In fact, every LTL formula is a either one of the two, or a conjunct of both.
Finally, as a reminder, an LTL formula is for example $\square \Diamond a$, with $a$ a property.