mirror of
https://github.com/janishutz/eth-summaries.git
synced 2026-07-27 21:29:09 +02:00
[FMFP] Notes for examp prep
This commit is contained in:
Binary file not shown.
@@ -6,6 +6,26 @@
|
||||
\paragraph{Programming}
|
||||
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}
|
||||
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,
|
||||
@@ -22,8 +42,14 @@ In the Haskell prelude, they are defined as follows:
|
||||
|
||||
foldl :: (a -> b -> a) -> a -> [b] -> a
|
||||
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}
|
||||
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}
|
||||
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
|
||||
|
||||
\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.
|
||||
\begin{enumerate}
|
||||
\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 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}
|
||||
|
||||
@@ -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 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.
|
||||
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.
|
||||
|
||||
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}
|
||||
\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 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 Always (from now on): $\square \Phi$ states that from now on, $\Phi$ will always hold, $\square \Phi \equiv \neg \Diamond \neg \Phi$
|
||||
\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.
|
||||
|
||||
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}
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
Reference in New Issue
Block a user