diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml
new file mode 100644
index 000000000..4f9fc8f58
--- /dev/null
+++ b/.github/workflows/main.yml
@@ -0,0 +1,65 @@
+name: Compiling & Checking
+run-name: Compiling all files
+on:
+ push:
+ branches:
+ - master
+ - master_clean
+jobs:
+ compiling:
+ runs-on: ubuntu-latest
+
+ steps:
+ - name: Checkout
+ uses: actions/checkout@v1
+ - name: Setting Up
+# Install textlive
+ run: |
+ sudo apt-get install texlive-latex-base
+ sudo apt-get install texlive-fonts-recommended
+ sudo apt-get install texlive-fonts-extra
+ sudo apt-get install texlive-latex-extra
+ sudo apt install texlive-lang-french
+ - name: File Diff Check
+ shell: bash
+ id: check_file_changed
+ run: |
+ Diff=$(git diff --name-only HEAD^ HEAD)
+ Pattern=".tex"
+ # We can change the pattern easily
+
+ echo $Diff
+
+ for arg in $Diff; do
+ echo $arg
+ # If the file is a .tex
+ if echo "$arg" | grep -q "$Pattern"; then
+ echo -e "\e[32m___START COMPILE___\e[0m"
+
+ IFS="/"
+ read -ra parts <<< "$arg"
+ IFS=" "
+
+ # Going to the right directory
+ Done=false
+
+ Back=""
+ for part in "${parts[@]}"; do
+ if echo "$part" | grep -q "$Pattern"; then
+ # Compile the document
+ ls
+ pdflatex "$part"
+ Done=true
+ fi
+
+ if !($Done); then
+ ls
+ cd "$part"
+ Back=$Back"../"
+ fi
+ done
+
+ cd $Back
+ echo -e "\e[32m___FINISH COMPILE___\e[0m"
+ fi
+ done
\ No newline at end of file
diff --git a/README.md b/README.md
index 19c96292e..2afa40b61 100644
--- a/README.md
+++ b/README.md
@@ -1,15 +1,15 @@
# Synthèses de l'EPL
-| **Documentation** | **PDF** | **Chat** | **Forum** | **Git** |
-|:------------------:|:-------:|:--------:|:---------:|:-------:|
-| [][doc-url] | [][pdf-url] | [![Join the chat at https://gitter.im/Gp2mv3/Syntheses](https://badges.gitter.im/Gp2mv3/Syntheses.svg)][chat-url] | [][forum-url] | [][git-url]
+| **Documentation** | **PDF** | **Chat** |**Git** | **Build** | **Discord**|
+|:------------------:|:-------:|:--------:|:------:|:---------:|:----------:|
+| [][doc-url] | [][pdf-url] | [![Join the chat at https://gitter.im/Gp2mv3/Syntheses](https://badges.gitter.im/Gp2mv3/Syntheses.svg)][chat-url] | [][git-url] | [][build-url] | [][discord-url]
Les documents présents sur ce repository sont des documents
mis à disposition pour les étudiants de l'EPL.
-| | Current maintainers |
-|:-------:|:------------------- |
-| :star: | Pour le moment :bangbang: **aucun** :bangbang:, voir [Historique](#historique). |
+| | Current maintainers |
+| :-----: | :------------------------------------------------------------------------------------- |
+| :star: | Pour le moment :bangbang: **aucun** :bangbang:, voir [Historique](#historique). |
| :beers: | Ne manquez pas de remercier gracieusement ces étudiants qui tiennent ce projet à flot! |
## Visualisation des synthèses et correctifs
@@ -86,3 +86,5 @@ Si cette license vous pose problème, venez en discuter en ouvrant une [issue](h
[chat-url]: https://gitter.im/Gp2mv3/Syntheses?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge
[forum-url]: http://forum-epl.be
[git-url]: https://try.github.io
+[build-url]: https://github.com/Tfloow/Syntheses/actions
+[discord-url]: https://discord.gg/WUuu38vtET
diff --git a/logo_ucl.pdf b/logo_ucl.pdf
index f40fc3143..d5d39544b 100644
Binary files a/logo_ucl.pdf and b/logo_ucl.pdf differ
diff --git a/src/config.yml b/src/config.yml
index 7b415a2e5..b4925b25d 100644
--- a/src/config.yml
+++ b/src/config.yml
@@ -148,3 +148,5 @@ name:
vehicle: Vehicle System Dynamics
mads: Modelling and analysis of dynamical systems
maths-discretes: Mathématiques discrètes et probabilité
+ info: Concepts des langages de programmation
+ projet: Projet P3
diff --git a/src/q4/info-INFO1104/exam/2020/2020.mk b/src/q4/info-INFO1104/exam/2020/2020.mk
new file mode 100644
index 000000000..d209b81a7
--- /dev/null
+++ b/src/q4/info-INFO1104/exam/2020/2020.mk
@@ -0,0 +1,2 @@
+YEAR=2020
+include ../../../exam.mk
diff --git a/src/q4/info-INFO1104/exam/2020/Juin/All/Makefile b/src/q4/info-INFO1104/exam/2020/Juin/All/Makefile
new file mode 100644
index 000000000..a519d4a83
--- /dev/null
+++ b/src/q4/info-INFO1104/exam/2020/Juin/All/Makefile
@@ -0,0 +1,2 @@
+MINMAJ=All
+include ../Juin.mk
diff --git a/src/q4/info-INFO1104/exam/2020/Juin/All/info-INFO1104-exam-2020-Juin-All.tex b/src/q4/info-INFO1104/exam/2020/Juin/All/info-INFO1104-exam-2020-Juin-All.tex
new file mode 100644
index 000000000..236a74310
--- /dev/null
+++ b/src/q4/info-INFO1104/exam/2020/Juin/All/info-INFO1104-exam-2020-Juin-All.tex
@@ -0,0 +1,392 @@
+\documentclass[fr]{../../../../../../eplexam}
+\usepackage{listings}
+\definecolor{codegreen}{rgb}{0,0.6,0}
+\definecolor{codegray}{rgb}{0.5,0.5,0.5}
+\definecolor{codepurple}{rgb}{0.58,0,0.82}
+\definecolor{backcolour}{rgb}{1.0,1.0,1.0}
+\definecolor{codeblue}{rgb}{0,0,0.8}
+
+\lstdefinestyle{mystyle}{
+ backgroundcolor=\color{backcolour},
+ commentstyle=\color{codegray},
+ keywordstyle=\color{codeblue},
+ numberstyle=\tiny\color{codegray},
+ stringstyle=\color{codeblue},
+ basicstyle=\ttfamily\footnotesize,
+ breakatwhitespace=false,
+ breaklines=true,
+ captionpos=b,
+ keepspaces=true,
+ numbers=left,
+ numbersep=5pt,
+ showspaces=false,
+ showstringspaces=false,
+ showtabs=false,
+ tabsize=2,
+ frame=shadowbox
+}
+\lstset{style=mystyle}
+\lstset{language=Oz}
+
+\hypertitle{Concepts des langages de programmation}{4}{LINFO}{1104}{2020}{Juin}{All}
+{Norah Habets \and Thomas Debelle}
+{P. Van Roy}
+
+\section{Programming paradigms}
+This question concerns the programming paradigms we have seen in the
+course. Which of the following programming paradigms are deterministic (no observable
+nondeterminism)? Select all that apply, multiple responses are possible
+% Insérer ci-dessous la solution à la question
+
+\begin{solution}
+ \begin{itemize}
+ \item Functional programming: Oui car pas de concurrence.
+ \item Object-oriented programming: Non car permet un état mutable.
+ \item Functional dataflow: Oui car concurrent mais le résultat est toujours le même quelqu'en soit l'ordre d'exéctuion.
+ \item Actor dataflow: Non car ports.
+ \item active object: Non car ports.
+ \end{itemize}
+\end{solution}
+
+\section{Free identifiers}
+This question concerns free identifiers in a program. Given the following program fragment
+What are the free identifiers in this fragment ? Select all that applyn multiple responses are possible.
+
+\begin{lstlisting}
+local Z in
+ fun {F X} Z+X end
+ fun {G X} fun {$ Y} X+Y end end
+end
+\end{lstlisting}
+
+
+\begin{solution}
+ Identificateur libre correspond à un élément déclaré en dehors d'une fonction/procédure mais utilisé dedans. Dans notre cas \textbf{X} et \textbf{Z}.
+\end{solution}
+
+\section{List data structure}
+This question concerns the list, a recursive data structure we have defined in the
+course. Which of the following terms are lists? Select all that apply, multiple responses are possible.
+
+\begin{solution}
+ \begin{tabular}{c c}
+ nil & (a|nil)|b\\
+ null & a|(nil|b)\\
+ leaf & a|b\\
+ (a|nil)|(b|nil) & nil|a|b\\
+ a|(b|nil) & nil|nil
+ \end{tabular}
+\end{solution}
+
+\begin{lstlisting}
+ abc
+\end{lstlisting}
+
+\section{Ordered binary trees}
+This question concerns ordered binary trees. Given the three tree operations defined in the course
+to operate on ordered binary trees, namely \{Lookup K T\}, \{Insert K V T\}, and \{Delete K T\}. Assume they are defined correctly
+in the same way we defined them in the course, where the trees have the following syntactic definition:
+ ::= leaf | tree(key:V value:V )
+Execute the following code on paper (not on a computer):
+A=\{Delete dog \{Insert mouse souris \{Insert cat chat \{Insert dog chien leaf\}\}\}\}
+
+\begin{solution}
+\begin{lstlisting}[escapechar=µ]
+A=tree(key:mouse value:souris tree(key:cat value:chat leaf leaf) leaf)
+A=tree(key:cat value:chat leaf tree(key:mouse value:souris leaf leaf))
+\end{lstlisting}
+\end{solution}
+
+\section{Abstract machine semantics}
+The following two questions concern the abstract machine semantics we have seen in the course.
+We will investigate the following program's semantics.
+
+\begin{lstlisting}
+local F G A B C in
+ A=5
+ fun {G X} A*X end
+ fun {F X}
+ local A in
+ A={G X}
+ {G A}
+ end
+ end
+ B=10
+ C={F B}
+ {Browse C}
+end
+\end{lstlisting}
+Assume the program executes until just before the call C=\{F B\}. At this point, the execution state is the following:
+\begin{lstlisting}
+([(C={F B},E1), ({Browse C},E1)],
+ {f=(proc {$ X R} local A in A={G X} R={G A} end end,{G->g)),
+ g=(proc {$ X R} R=A*X end,{A->a}), a=5, b=10, c}
+\end{lstlisting}
+Here E1 has a particular value that we do not specify further, and variables f and g are bound to procedure values. Now do one
+execution step according to the abstract machine semantics. This starts the execution of procedure F.\\
+
+Which of the following choices best describes the execution state after this one step? Select only one
+choice.
+
+\begin{solution}
+ On met le corps de F en haute de la pile. Réponse E ou F. Ce n'est pas encore calculé à ce moment là. E2=\{X $\rightarrow$ b; R $\rightarrow$ c; G $\rightarrow$ g\}
+\end{solution}
+
+\section{Lambda Calculus}
+Reduce the expression FIRST (PAIR 1 NIL) to its final form. Show all reductions. Make sure to keep the
+abbreviations for 1 and NIL during these reductions, since they will not be reduced. Please put one
+reduction on each line of your answer (use a bullet list)
+
+\begin{solution}
+ $(FIRST (PAIR \wedge NIL)) \longrightarrow (\lambda p ( p TRUE)(PAIR \wedge NIL)) \longrightarrow ((PAIR \wedge NIL) TRUE) \longrightarrow ((\lambda x.\lambda y . \lambda f.$(f x y) 1 NIL) TRUE) $\longrightarrow (TRUE 1 NIL) \longrightarrow (\lambda x. \lambda y . x \wedge NIL) \longrightarrow 1$
+\end{solution}
+
+\section{Partial values}
+This question is about using unbound variables when building data structures. Consider this program fragment
+
+\begin{solution}
+ true $\longrightarrow$ quand Oz rencontre une variable non liée, il met l'instruction en pause et continue jusqu'à ce que la variable soit liée.
+\end{solution}
+
+\section{Data abstraction}
+The following two questions are about a data abstraction that is defined as follows.
+We define a counter with five operations:
+\begin{enumerate}
+ \item Create a new counter instance with initial count equal to integer 0.
+ \item Increment the counter (value N becomes N+1)
+ \item Decrement the counter (value N becomes N-1)
+ \item Test if the counter is zero (return true if the value is zero and false if it is nonzero).
+ \item Get the counter's value (return the value N).
+\end{enumerate}
+We will implement this counter in two different ways.\\
+Give the implementation of the counter abstraction as an abstract data type (Oz code). You can assume
+that any useful helper operation defined in the course exists. Try to make the code look nice (use a
+numbered bullet list)
+
+\begin{solution}
+\begin{lstlisting}[escapechar=µ]
+local Wrap Unwrap in
+ {NewWrapper Wrap Unwrap}
+ fun {Newcounter} {Wrap 0} end
+ fun {Inc C} {Wrap {Unwrap C}+1} end
+ fun {Dec C} {Wrap {Unwrap C}-1} end
+ fun {IsZero C} {Unwrap C}==0 end
+ fun {Get C} {Unwrap C} end
+end
+\end{lstlisting}
+\end{solution}
+
+Give the implementation for the counter abstraction as an object (Oz code). You should group the object
+operations in a record (do not use class syntax). Try to make the code look nice (use a numbered bullet
+list).
+
+\begin{solution}
+\begin{lstlisting}[escapechar=µ]
+fun {NewConter}
+ C={NewCell 0}
+ proc {Inc} C:=@C+1 end
+ proc {Dec} C:=@C-1 end
+ fun {IsZero} @C==0 end
+ fun {Get} @C end
+in
+ counter(inc:Inc dec:Dec isZero:IsZero get:Get)
+end
+\end{lstlisting}
+\end{solution}
+
+\section{Limits of deterministic dataflow}
+This question is about client/servers and the limits of deterministic dataflow. Given a
+client/server application with two clients and one server. Each client puts its messages on a stream. The server reads both streams
+and services both clients. Whenever a client sends a message to the server, the server must respond to the message and send a
+reply back to the client in a reasonable time that depends only on the message travel time between client and server, and the
+server's computation time. Assume the client/server is written in deterministic dataflow, and the server code is as follows. In this
+code, S1 is a stream of requests from client 1 and S2 is a stream of requests from client 2.
+\begin{lstlisting}
+proc {Server S1 S2}
+ case (S1|S2) of (M1|T1)|(M2|T2) then
+ ... (handle M1)
+ ... (handle M2)
+ {Server T1 T2}
+ end
+end
+\end{lstlisting}
+
+Explain in detail why this server code does not satisfy the specification of the client/server, as it is given
+above. Give a precise sequence of operations (client requests and server actions) to show what can go
+wrong.
+
+\begin{solution}
+ Si un utilisateur envoie un message au serveur et pas l'autre, alors le case ne sera pas satsifait et le message ne sera pas traité tant que l'autre utilisateur n'envoie pas de message.
+ Dans ce cas, le temps de réponse ne dépend pas du temps de voyage et du temps de calcul, ce qui ne répond pas aux \textbf{spécifications}.
+\end{solution}
+
+\section{Message protocols}
+The following two questions are about message protocols. We will do an RMI with callback between a client
+object and a server object. We will use the following implementation. You can assume that NewPortObject2 is defined in the same
+way as in the course, namely to create port objects with no internal state.
+
+\begin{center}
+\begin{minipage}{0.45\linewidth}
+\begin{lstlisting}
+declare
+proc {ServerProc Msg}
+ case Msg of calc(X Y Client)
+ then D in
+ {Send Client delta(D)}
+ Y=X*X+2.0*D*X+D*D+23.0
+ end
+end
+
+Server={NewPortObject2 ServerProc}
+\end{lstlisting}
+\end{minipage}
+%
+\begin{minipage}{0.45\linewidth}
+\begin{lstlisting}
+declare
+proc {ClientProc Msg}
+ case Msg of work(Z) then Y in
+ {Send Server calc(10.0 Y Client)}
+ Z=Y+10.0
+ [] delta(D) then
+ D=0.1
+ end
+end
+Client={NewPortObject2 ClientProc}
+\end{lstlisting}
+\end{minipage}
+\end{center}
+
+Explain what an "RMI with callback" is supposed to do: what is the precise sequence of messages that
+should be exchanged between the client and server.
+\begin{solution}
+ Un RMI avec callback est un protocole de message dans lequel le client va demander au serveur de faire une action. Mais pour pouvoir compléter celle-ci, le serveur a besoin
+ d'une info de la part du client, donc il va envoyer un message au client en demandant cette info. Une fois que le client a répondu, le serveur peut terminer
+ ses calculs et renvoyer le résultat de l'action au client. Donc, ici, le client demande au serveur de lier $Y$ avec \{Send Server calc(10.0 Y Client)\} mais le serveur a besoin de $D$ pour calculer $Y$.
+ Le serveur envoie donc un message au client pour demander de lier $D$ avec \{Send Client delta($D$)\}. Le client va donc lier $D$ et le serveur pourra donc terminer son calcul et lier $Y$.
+\end{solution}
+
+Explain why the code given above is incorrect. Give a precise execution scenario to show the problem.
+Explain how to fix the problem (explain in words what is going on and how to correct it), and explain how
+to fix the code (you can give a code fragment in your answer).
+
+\begin{solution}
+ La ligne $Z = Y + 10.0$ devrait être dans le thread. Quand cette ligne est exécutée, $Y$ n'est pas lié. Donc, le programme reste bloquée sur cette ligne. Mettre cette
+ instruction dans un thread permet au programe de continuer même si $Y$ n'est pas lié.
+\end{solution}
+
+\section{Memory management}
+
+\begin{center}
+\begin{minipage}{0.45\linewidth}
+\begin{lstlisting}
+%Program 1:
+declare S P Loop in
+P={NewPort S}
+proc {Loop N}
+ {Send P N} {Loop N+1}
+end
+{Loop 1}
+\end{lstlisting}
+\end{minipage}
+%
+\begin{minipage}{0.45\linewidth}
+\begin{lstlisting}
+%Program 2:
+declare P Loop in
+local S in
+P={NewPort S}
+end
+proc {Loop N} {Send P N} {Loop N+1} end
+{Loop 1}
+\end{lstlisting}
+\end{minipage}
+\end{center}
+
+One of these programs has constant active memory size and the other has a memory leak where the active memory size grows
+without bounds (which may crash the computer eventually if the process is not terminated)\\
+
+For both programs, explain what happens to its active memory during its execution and why. Your
+explanation must justify how the behavior is a consequence of the port semantics and of the difference
+between the declare and local statements.
+
+\begin{solution}
+ C'est le programme 1 qui a une faute de mémoire. \\
+ La sémantique des ports est la suivante: pour la création d'un port: P=\{NewPort S\} donne l'environnement \{P $\rightarrow$ p, S $\rightarrow$ s\} et dnas la mémoire
+ des ports, la paire $p:s$ est créée avec, $s$, une variable non liée. Quand on effectue l'opération \{Send P X\}, on crée
+ une nouvelle variable non liée $s'$, on lie $s$ à $x|s'$ et on met à jour la paire $p:s'$. \\
+
+ Quand le port est dans un \textit{declare}, la variable $s$ sera toujours atteignable et ne sera donc pas éliminé par le garbage
+ collector. Tandis que si le stream du port est dans un local, les variables $s$ de ce stream ne seront accessibles que depuis ce local. Donc une fois que le local est exécuté
+ , chaque fois qu'un message est envoyé au port, la variable $s$ du stream devient \textit{inatteignable}, et est donc éliminée, gardant ainsi la consommation
+ de mémoire active constante.
+\end{solution}
+
+\section{Deterministic dataflow with ports}
+This question is about concurrent programming with deterministic dataflow and ports. Given
+the following program which does dynamic concurrent composition. It defines a thread creation abstraction in which threads can create threads recursively, and the top level call to NewThread terminates when all subthreads have terminated.
+
+\begin{lstlisting}
+proc {NewThread P SubThread}
+ proc {ZeroExit N S}
+ case S of X|S2 then
+ if N+X\=0 then
+ {ZeroExit N+X S2}
+ end
+ end
+ end
+ S Pt={NewPort S}
+in
+ proc {SubThread P}
+ thread
+ {Send Pt 1} % This should be done before the thread creation
+ {P}
+ {Send Pt ~1}
+ end
+ end
+ {SubThread P}
+ {ZeroExit 0 S}
+end
+\end{lstlisting}
+
+This program deliberately has a bug: the {Send Pt 1} call is done inside the new thread (to avoid a bug, it should be done before the
+thread creation).\\
+
+Explain this buggy behavior. You should give a precise scenario of multiple thread creations that shows
+the buggy behavior, such that the NewThread call exits despite that there is still at least one active thread.
+In your explanation, you should make explicit all the scheduler decisions that result in the buggy behavior.
+
+\begin{solution}
+ Le problème avec ce programme, c'est qu'il peut s'arrêter avant que tous les threads soient finis. En effet, le programme s'arrête quand le compteur de threads est égal à $0$.
+ À chaque fois qu'un thread se termine, sa dernière instruction est de décrémenter le compteur de thread. Quand on crée un thread il faut incrémenter le compteur. Le problème avec
+ le code proposé est le suivant: le scheduler décide quel thread s'exécute quand et pour combien de temps. En incrémentant le compteur de threads à l'intérieur d'un thread,
+ la situation suivante peut se produire.\\
+ Imaginons le compteur est à 1 et le thread en cours d'exécution est presque terminé. Le scheduler commence un nouveau thread et crée donc une nouvelle stack avec son environnement,
+ mais n'exécute encore aucune instruction sur cette stack, il a juste démarré ce nouveau thread. Puis, le scheduler change de thread et termine l'exécution du thread qui se terminait.
+ Le compteur de threads passe donc à 0 avant que le nouveau thread n'ait eu l'occasion d'incrémenter ce compteur. Ce derneier étant à 0, l'exécution du programme se termine, malgré
+ le fait qu'il n'y ait toujours un thread en cours d'exécution.\\
+
+ En mettant l'incrémentation du compteur avant le thread éviterait ce problème.
+\end{solution}
+
+\section{Erlang/OTP}
+ This question is about building resilient distributed applications with Erlang/OTP. The
+Erlang/OTP platform has many abstractions to construct resilient distributed applications. Assume you are
+building a resilient distributed collaborative graphic editor, in which many users can work simultaneously
+on the same document. This editor should always maintain a consistent document view for all users, it
+should be completely robust against any kind of failure, and it should have high performance with low
+perceived latency. Explain as best you can how you would structure this editor using the Erlang/OTP
+abstractions we have seen in the course. Try to explain the role of as many Erlang/OTP abstractions as
+possible in your answer. You will be graded on the completeness of your answer (mentioning as many as
+possible the relevant Erlang abstractions among the ones we have seen in the course) and on the
+coherence of your answer (how clearly you can explain the overall architecture of your editor, how all the
+Erlang abstractions work together to achieve the overall goals, and what is the role of each abstraction in
+achieving the overall goals). To achieve coherence, think about your answer before writing it down and
+reread it before submitting the final version.
+\nosolution
+
+% Ajouter \nosolution s'il n'y a pas de solution disponible pour cette question
+
+% \nosolution
+
+\end{document}
diff --git a/src/q4/info-INFO1104/exam/2020/Juin/Juin.mk b/src/q4/info-INFO1104/exam/2020/Juin/Juin.mk
new file mode 100644
index 000000000..6584a9746
--- /dev/null
+++ b/src/q4/info-INFO1104/exam/2020/Juin/Juin.mk
@@ -0,0 +1,2 @@
+MONTH=Juin
+include ../../2020.mk
diff --git a/src/q4/info-INFO1104/exam/2020/Septembre/All/Makefile b/src/q4/info-INFO1104/exam/2020/Septembre/All/Makefile
new file mode 100644
index 000000000..ca0c513cb
--- /dev/null
+++ b/src/q4/info-INFO1104/exam/2020/Septembre/All/Makefile
@@ -0,0 +1,2 @@
+MINMAJ=All
+include ../Septembre.mk
diff --git a/src/q4/info-INFO1104/exam/2020/Septembre/All/info-INFO1104-exam-2020-Septembre-All.tex b/src/q4/info-INFO1104/exam/2020/Septembre/All/info-INFO1104-exam-2020-Septembre-All.tex
new file mode 100644
index 000000000..4b047a8d3
--- /dev/null
+++ b/src/q4/info-INFO1104/exam/2020/Septembre/All/info-INFO1104-exam-2020-Septembre-All.tex
@@ -0,0 +1,303 @@
+\documentclass[fr]{../../../../../../eplexam}
+\usepackage{listings}
+\definecolor{codegreen}{rgb}{0,0.6,0}
+\definecolor{codegray}{rgb}{0.5,0.5,0.5}
+\definecolor{codepurple}{rgb}{0.58,0,0.82}
+\definecolor{backcolour}{rgb}{1.0,1.0,1.0}
+\definecolor{codeblue}{rgb}{0,0,0.8}
+
+\lstdefinestyle{mystyle}{
+ backgroundcolor=\color{backcolour},
+ commentstyle=\color{codegray},
+ keywordstyle=\color{codeblue},
+ numberstyle=\tiny\color{codegray},
+ stringstyle=\color{codeblue},
+ basicstyle=\ttfamily\footnotesize,
+ breakatwhitespace=false,
+ breaklines=true,
+ captionpos=b,
+ keepspaces=true,
+ numbers=left,
+ numbersep=5pt,
+ showspaces=false,
+ showstringspaces=false,
+ showtabs=false,
+ tabsize=2,
+ frame=shadowbox
+}
+\lstset{style=mystyle}
+\lstset{language=Oz}
+
+\hypertitle{Concepts des langages de programmation}{4}{INFO}{1104}{2020}{Septembre}{All}
+{Norah Habets \and Thomas Debelle}
+{P. Van Roy}
+
+\section{List data structure}
+This question is about the list, an important recursive data structure that we have seen
+in the course. Which of the following terms are lists? Select all that apply, multiple responses are possible.
+
+\begin{solution}
+\begin{tabular}{c c}
+nil|nil|nil & a|b|nil\\
+0|nil & a|b\\
+nil|b|a & (a|nil)|(b|nil)\\
+nil|nil & b|(a|nil)\\
+(a|nil)|b & 0 \\
+ & nil|0
+\end{tabular}
+\end{solution}
+
+\section{Functional programming}
+Define the function \{SumOdd L A\} that calculates the sum of all elements of L
+in odd positions starting from the first. If L=[a1 a2 ... am] then \{SumOdd L A\} returns A+a1+a3+... (up to
+the end of L). Your definition must be declarative and tail-recursive and it must use pattern matching. You
+will be judged on the precise correctness of your answer: any error (including syntax errors) will be penalized.
+\begin{lstlisting}
+declare
+fun {SumOdd L A}
+ case L
+ of nil then A
+ [] H|nil then A+H
+ [] H|T then {SumOdd T.2 A+H}
+ end
+end
+\end{lstlisting}
+
+\section{Contextual environment}
+\begin{lstlisting}
+fun {F X}
+ fun {$ Y}
+ fun {$ Z}
+ X+Y+Z
+ end
+ end
+end
+\end{lstlisting}
+What is the contextual environment of the outermost anonymous function in this definition, i.e., the function with header fun \{\$ Y\}?
+
+\begin{solution}
+ L'environnement contextuel d'une fonction (ou d'une procédure) contient tous les identificateurs qui sont utilisés à l'intérieur de la fonction mais déclarés en dehors
+ \begin{lstlisting}[escapechar=µ]
+ Ec = {X µ$\rightarrow$µ x} de {$ Y}
+ \end{lstlisting}
+\end{solution}
+
+\section{Lambda calculus}
+Here we use the capital letter L to represent the lambda symbol, and =DEF to represent a definition. For this question,
+reduce the expression AND TRUE (NOT FALSE) to its final form. Show all intermediate reductions. For readability, keep the
+abbreviations TRUE and FALSE in your reductions when they are not applied as functions (write them in full when they are
+used as functions). Please put one reduction on each line of your answer.
+
+\begin{solution}
+ (AND TRUE (NOT FALSE)) $\longrightarrow$ ($\lambda p. \lambda q. p qp$ TRUE (NOT FALSE))$\longrightarrow$ (TRUE (NOT FALSE) TRUE) $\longrightarrow$ ($\lambda x.\lambda y.x$(NOT FALSE) TRUE) $\longrightarrow$ (NOT FALSE) $\longrightarrow$ ($\lambda p.p$ FALSE TRUE FALSE) $\longrightarrow$ (FALSE FALSE TRUE) $\longrightarrow$ ($\lambda x.\lambda y.y$ FALSE TRUE) $\longrightarrow$ TRUE
+\end{solution}
+
+For this question, reduce the same expression as in the previous
+question, but do the reduction in a different order. The result should be the same as before. This illustrates the Church-Rosser theorem?
+
+\begin{solution}
+ (AND TRUE (NOT FALSE)) $\longrightarrow$ (AND TRUE ($\lambda p.p$ FALSE TRUE FALSE)) $\longrightarrow$ (AND TRUE (FALSE FALSE TRUE)) $\longrightarrow$ (AND TRUE ($\lambda x. \lambda y.y$ FALSE TRUE)) $\longrightarrow$ (AND TRUE TRUE) $\longrightarrow$ ($\lambda p. \lambda q.pqp$ TRUE TRUE) $\longrightarrow$ (TRUE TRUE TRUE) $\longrightarrow$ ($\lambda x. \lambda y.x$ TRUE TRUE) $\longrightarrow$ TRUE
+\end{solution}
+
+
+\section{Abstract machine semantics}
+\begin{lstlisting}[escapechar=µ]
+([({P A B},{Pµ$\rightarrow$µp,Aµ$\rightarrow$µa,Bµ$\rightarrow$µb})], {a=5,n=10,b,p=(proc {$ X Y} Y=X+N end,{Nµ$\rightarrow$µn})}
+\end{lstlisting}
+Which of the following choices best describes the execution state after doing exactly one step in the abstract machine?
+Select only one choice.\par
+
+In case the above answer was A or B, which of the following choices best describes the value of E1?
+Select only one possibility.
+
+\begin{solution}
+ \begin{lstlisting}[escapechar=µ]
+ ([({P A B}, {P µ$\rightarrow$µ p, A µ$\rightarrow$µ a, B µ$\rightarrow$µ b})],{a=5,n=10,b,p=(proc {$ X Y} Y=X+N end, {N µ$\rightarrow$µ n})})
+ µ$\longrightarrow$µ ([(Y=X+N, µ$E_1$µ)], {a=5, n=10, b, p=proc {$ X Y} Y=X+N end, {N µ$\rightarrow$µ n}})
+ µ$\longrightarrow$µ µ$E_1$µ={X µ$\rightarrow$µ a, Y µ$\rightarrow$µ b, N µ$\rightarrow$µ n}
+ \end{lstlisting}
+\end{solution}
+
+\section{List data structures}
+Given the following instruction:
+
+\begin{lstlisting}
+{Browse [nil]==nil|nil}
+\end{lstlisting}
+What does this display?
+
+\begin{solution}
+ \begin{lstlisting}[escapechar=µ]
+ {Browse [nil] == nil|nil} µ$\longrightarrow$µ true
+ \end{lstlisting}
+\end{solution}
+
+\section{Limitation of deterministic dataflow}
+The deterministic dataflow paradigm is very useful when writing concurrent programs
+because it has no race conditions. However, it has a strong limitation which means that in some cases it cannot be used. Consider
+a client/server application with two clients and one server. Each client puts its requests on a stream. The server reads both
+streams and handles the requests. There is an important fairness requirement: whenever a client sends a message to the server,
+the server must respond in a reasonable time that depends only on the message travel time between client and server, and its own
+computations. There must be no other dependency. Assume the client/server is written in deterministic dataflow, and the server
+code is as follows. In this code, S1 is a stream of requests from client 1 and S2 is a stream of requests from client 2.
+
+\begin{lstlisting}
+proc {Server S1 S2}
+ case (S1|S2) of (M1|T1)|S2 then
+ ... (handle M1)
+ {Server T1 S2}
+ [] S1|(M2|T2) then
+ ... (handle M2)
+ {Server S1 T2}
+ end
+end
+\end{lstlisting}
+
+Explain precisely why the server code given above does not satisfy the fairness requirement. Give a
+concrete scenario of client and server operations to show what can go wrong.
+
+\begin{solution}
+Cela ne fonctionne pas si le client 2 envoie un message et que le client 1 n'envoie rien. C'est la sémantique du case qui fait que ça ne fonctionne pas. Le deuxième pattern est pris quand on ne peut pas faire réussir le premier. Cette procédure va donc toujours attendre le premier pattern (que le client 1 envoie un message) et ne va jamais passer au deuxième. Si on échangeait les patterns, ça sera l'inverse. De plus, le terme de "\textit{fairness}" est dit d'un scheduler, si chaque runnable thread sera exécuté dans un temps fini, ce qui n'est donc pas le cas ici.
+\end{solution}
+
+One might think that writing the server in a different way (but still in deterministic dataflow) would solve the
+problem. But this is not possible. For this question, give the general reason why it is not possible to
+satisfy the fairness requirement in deterministic dataflow.
+
+\begin{solution}
+En dataflow déterministe, on ne peut écrire que des programmes sans non déterminisme \textit{observable}. Or, dans le cas de l'application \textbf{serveur|client}, le non déterminisme est inséparable de l'application. En effet, il n'est pas possible de prévoir quand un client va appeler le serveur. Il faut donc être capable d'écrire un programme qui puisse attendre sur plusieurs pattern, ce qui n'est pas possible en dataflow déterministe.
+\end{solution}
+
+
+Explain how to write a client/server that does satisfy the fairness requirement. You first need to introduce
+a new concept, since pure deterministic dataflow cannot solve the problem. Give a simple code
+implementation of a server and a simple code implementation of a client. Your code can be extremely
+simple, as long as it shows how to satisfy the fairness requirement.
+
+\begin{solution}
+Pour pouvoir écrire une application du style client serveur, il faut introduire le concept de \textbf{port}, c'est à dire un stream \textit{nommé}.
+\begin{lstlisting}[escapechar=µ]
+P={NewPort S}
+proc {Server S}
+ case S
+ of M|T then
+ (handle M)
+ {Server T}
+ end
+end
+\end{lstlisting}
+On envoie un message au serveur via \{Send P M\} où M est le message et P notre port/stream nommé.
+\end{solution}
+
+\section{Nondeterminism}
+Is the following program nondeterministic ?
+\begin{lstlisting}
+declare X={NewCell 1}
+thread X:=2 end
+thread X:=2 end
+\end{lstlisting}
+
+\begin{solution}
+Oui et est donc dangereux. On ne sait pas quel X:=2 sera exécuté en premier et X:= n'est pas une opération \textbf{atomique} donc il est possible qu'un thread "sélectionné" X puis soit arrêté par le scheduler qui va donner du temps de calcul à l'autre thread. Donc cela va modifier X et le X "tenu" par le premier thread ne sera plus le bon.
+\end{solution}
+
+\section{Port objects}
+In the course we have seen stateful port objects. It is remarkable that they can be defined as follows with the
+FoldL operation:
+
+\begin{lstlisting}
+fun {NewPortObject Init F}
+P Out in
+ thread S in
+ P={NewPort S} Out={FoldL S F Init}
+ end
+ P
+end
+\end{lstlisting}
+
+Instead of using a local function Loop to read the message stream and update the state, we use FoldL. For this question,
+explain how this definition works. Your answer should start with a specification of the FoldL operation and show how this
+specification can be used to do the work of the port object's state transition function.
+
+\begin{solution}
+La fonction FoldL permet d'appliquer une fonction sur tous les éléments d'une liste. Ici, pour passer d'un état à un autre, il faut appliquer une fonction sur les éléments du stream de l'objet. Puisqu'un stream est une liste avec la dernière variable \textit{non liée}, la fonction FoldL est parfaite.
+\end{solution}
+
+\section{Mutable state}
+In the course, we introduced mutable state in the form of cells, which are a form of
+variable that can be updated multiple times. This is no longer compatible with functional programming,
+but it enables new abilities that are not possible in functional programming. For this question, give and
+explain an example of a new ability that becomes available with mutable state that was not available
+without mutable state.
+
+\begin{solution}
+L'ajout de cellules est nécessaire pour ajouter de la modularité dans un programme c'est à dire changer des fonctions sans pour autant changer leur interface. Si, par exemple, on veut ajouter un compteur dans une fonction pour garder une trace de combien de fois elle est appelée lors de l'exécution d'un programme, en programmation fonctionnelle, il faudrait rajouter un argument à cette fonction et donc modifier le code partout où cette fonction est appelée. Avec les cellules ce n'est pas nécessaire. En programmation fonctionnelle, il n'y a pas d'état, le programme ne se souvient pas de ce qui s'est passé avant. Avec les cellules, il est possible de créer des programmes avec l'état, qui ont donc une mémoire interne. Un programme peut changer son comportement en fonction de ses états passés.
+\end{solution}
+
+\section{Memory management}
+This question is about memory management. You are given the following two programs.
+\begin{center}
+\begin{minipage}{0.45\linewidth}
+\begin{lstlisting}
+%Program 1:
+declare S P Loop in
+P={NewPort S}
+proc {Loop N}
+ {Send P N} {Loop N+1}
+ end
+{Loop 1}
+\end{lstlisting}
+\end{minipage}
+%
+\begin{minipage}{0.45\linewidth}
+\begin{lstlisting}
+%Program 2:
+declare P Loop in
+local S in
+ P={NewPort S}
+end
+proc [Loop N} {Send P N} {Loop N+1} end
+{Loop 1
+\end{lstlisting}
+\end{minipage}
+\end{center}
+One of these programs has constant active memory size and the other has a memory leak where the active memory size grows
+without bounds (which may crash the computer eventually if the process is not terminated).\\
+To understand the behavior of these programs, it is essential to understand the port semantics. Given the
+port semantics, explain for both program what happens to its active memory during its execution and
+why. Your answer must show how the behavior is a consequence of port semantics and of the difference
+between the declare and local statements.
+
+\begin{solution}
+ C'est le programme 1 qui a une faute de mémoire. \\
+ La sémantique des ports est la suivante: pour la création d'un port: P=\{NewPort S\} donne l'environnement \{P $\rightarrow$ p, S $\rightarrow$ s\} et dnas la mémoire
+ des ports, la paire $p:s$ est créée avec, $s$, une variable non liée. Quand on effectue l'opération \{Send P X\}, on crée
+ une nouvelle variable non liée $s'$, on lie $s$ à $x|s'$ et on met à jour la paire $p:s'$. \\
+
+ Quand le port est dans un \textit{declare}, la variable $s$ sera toujours atteignable et ne sera donc pas éliminé par le garbage
+ collector. Tandis que si le stream du port est dans un local, les variables $s$ de ce stream ne seront accessibles que depuis ce local. Donc une fois que le local est exécuté
+ , chaque fois qu'un message est envoyé au port, la variable $s$ du stream devient \textit{inatteignable}, et est donc éliminée, gardant ainsi la consommation
+ de mémoire active constante.
+\end{solution}
+
+\section{Erlang/OTP}
+This question is about building robust distributed applications using the Erlang/OTP
+platform. One of the key concepts in Erlang/OTP is the supervisor tree, where one process is able to
+observe and manage a set of other processes\par
+
+Explain the one\_for\_one and one\_for\_all restart strategies, and give for each strategy a simple application
+scenario where it would be useful.
+
+\begin{solution}
+ces stratégies sont utilisées quand un superviseur supervise plusieurs processus:
+\begin{itemize}
+\item One\_for\_one: quand un des enfants crash, il est simplement redémarré par le superviseur sans que ça n'impacte les autres processus (\textit{ex}: client serveur: pour pas impacter les autres clients si il y a un crash)
+\item One\_for\_all: si un des enfants crash, tous les processus liés par le même superviseur sont arrêtés et relancés, même s'ils n'ont aucun problème (\textit{ex}: processus synchronisé: nécessaire quand les processus sont dépendants, pour qu'ils restent synchronisés)
+\end{itemize}
+\end{solution}
+
+% Ajouter \nosolution s'il n'y a pas de solution disponible pour cette question
+
+% \nosolution
+
+\end{document}
diff --git a/src/q4/info-INFO1104/exam/2020/Septembre/Septembre.mk b/src/q4/info-INFO1104/exam/2020/Septembre/Septembre.mk
new file mode 100644
index 000000000..f670bdce6
--- /dev/null
+++ b/src/q4/info-INFO1104/exam/2020/Septembre/Septembre.mk
@@ -0,0 +1,2 @@
+MONTH=Septembre
+include ../../2020.mk
diff --git a/src/q4/info-INFO1104/exam/2021/2021.mk b/src/q4/info-INFO1104/exam/2021/2021.mk
new file mode 100644
index 000000000..53bb573dd
--- /dev/null
+++ b/src/q4/info-INFO1104/exam/2021/2021.mk
@@ -0,0 +1,2 @@
+YEAR=2021
+include ../../../exam.mk
diff --git a/src/q4/info-INFO1104/exam/2021/Juin/All/Makefile b/src/q4/info-INFO1104/exam/2021/Juin/All/Makefile
new file mode 100644
index 000000000..a519d4a83
--- /dev/null
+++ b/src/q4/info-INFO1104/exam/2021/Juin/All/Makefile
@@ -0,0 +1,2 @@
+MINMAJ=All
+include ../Juin.mk
diff --git a/src/q4/info-INFO1104/exam/2021/Juin/All/info-INFO1104-exam-2021-Juin-All.tex b/src/q4/info-INFO1104/exam/2021/Juin/All/info-INFO1104-exam-2021-Juin-All.tex
new file mode 100644
index 000000000..9dd1bff8b
--- /dev/null
+++ b/src/q4/info-INFO1104/exam/2021/Juin/All/info-INFO1104-exam-2021-Juin-All.tex
@@ -0,0 +1,239 @@
+\documentclass[fr]{../../../../../../eplexam}
+\usepackage{listings}
+\definecolor{codegreen}{rgb}{0,0.6,0}
+\definecolor{codegray}{rgb}{0.5,0.5,0.5}
+\definecolor{codepurple}{rgb}{0.58,0,0.82}
+\definecolor{backcolour}{rgb}{1.0,1.0,1.0}
+\definecolor{codeblue}{rgb}{0,0,0.8}
+
+
+
+\lstdefinestyle{mystyle}{
+ backgroundcolor=\color{backcolour},
+ commentstyle=\color{codegray},
+ keywordstyle=\color{codeblue},
+ numberstyle=\tiny\color{codegray},
+ stringstyle=\color{codeblue},
+ basicstyle=\ttfamily\footnotesize,
+ breakatwhitespace=false,
+ breaklines=true,
+ captionpos=b,
+ keepspaces=true,
+ numbers=left,
+ numbersep=5pt,
+ showspaces=false,
+ showstringspaces=false,
+ showtabs=false,
+ tabsize=2,
+ frame=shadowbox
+}
+\lstset{style=mystyle}
+\lstset{language=Oz}
+
+\hypertitle{}{4}{INFO}{1104}{2021}{Juin}{All}
+{Norah Habets \and Thomas Debelle}
+{P. Van Roy}
+
+\section{Kernel language}
+Translate the following program:
+\begin{lstlisting}[escapechar=µ]
+local F C in
+ C={NewCell 0)
+ fun {F A}
+ fun {$ B}
+ C:=@C+1
+ A+B
+ end
+ end
+ {Browse {{F 1} 2}}
+end
+\end{lstlisting}
+into kernel language. Be careful to do a complete translation that uses only kernel language instructions!
+
+\begin{solution}
+\begin{lstlisting}[escapechar=µ]
+local F C Zero One in
+ Zero=0
+ One=1
+ {NewCell Zero C}
+ F=proc{$ A ?R1}
+ R1=proc{$ B ?R2}
+ local C1 C2 C3 in
+ {Exchange C C1 Zero}
+ C2=C1+One
+ {Exchange C C3 C2}
+ R2=A+B
+ end
+ end
+ end
+ local F1 F2 Two in
+ Two=2
+ {F One F1}
+ {F1 Two F2}
+ {Browse F2}
+ end
+end
+\end{lstlisting}
+\end{solution}
+
+\section{Function composition}
+Define a function {Compose F G) that takes two one-argument functions F and G and returns their function composition. Give the contextual environment of the function returned by Compose.
+
+\begin{solution}
+\begin{lstlisting}[escapechar=µ]
+declare
+fun {Compose F G}
+ fun {$ X}{F {G X}} end
+end
+\end{lstlisting}
+Où E = \{F $\rightarrow$ f, G $\rightarrow$ g\}
+\end{solution}
+
+\section{Lambda calculus reduction}
+Reduce the expression (SUCC (SUCC 0)) and show itis equivalent to 2. To make your answer easier to understand, only replace a function by its definition When you need it for a reduction step.
+
+\begin{solution}
+(SUCC (SUCC 0)) $\longrightarrow$ (SUCC ($\lambda n. \lambda f. \lambda x.f((n f)x) \lambda f( \lambda x.x$)) $\longrightarrow$ (SUCC ($\lambda f. \lambda x.f ((\lambda f (\lambda x.x)f)x)$)) $\longrightarrow$ (SUCC ($\lambda f.(\lambda x.(f.x)$)) $\longrightarrow$ ($\lambda n . \lambda f. \lambda x.f ((n f)x) \lambda f(\lambda x (f x))$) $\longrightarrow$ ($\lambda f. \lambda x.f ((\lambda f (\lambda x(f x))f)x$) $\longrightarrow$ ($\lambda f. \lambda x.f(\lambda x(f x)x)$) $\longrightarrow$ ($\lambda f. \lambda x.f(f x)$) $\longrightarrow$ 2
+\end{solution}
+
+\section{Functional programming}
+Define the declarative function {Prod F Xs Ys} that has three arguments, a tvvo-argument function F and two lists Xs=[$x_1$ $x_2$ ... $x_n$] and Ys=[$y_1$ $y_2$ ... $y_n$] and returns the list:\\
+$[f(x_1, y_1) f(x_1,y_2) ... f(x_1, y_m) f(x_2, y_1) f(x_2, y_2) ... f(x_2, y_m) ... f(x_n, y_1) f(x_n, y_2) ... f(x_n, y_m)]$\\
+The number of elements in the returned list is mxn. For example, if Xs=[1 2 3] and Ys=[10 100 1000] and F is multiplication, then the result is [10 100 1000 20 200 2000 30 300 3000). You can define auxiliary functions to simplify your answer. Each recursive function should implement one loop. All functions
+should be declarative. Don't worty too much about efficiency, slight inefficiencies will not be penalized.
+
+\begin{solution}
+\begin{lstlisting}[escapechar=µ]
+declare
+fun {Prod F Xs Ys}
+ fun {SubProd F X Ys}
+ case Ys
+ of Y|nil then {F X Y}|nil
+ [] Y|Yr then {F X Y}|{SubProd F X Yr}
+ end
+ end
+in
+ case Xs
+ of X|nil then {SubProd F X Ys}
+ [] X|Xr then {Append {SubProd F X Ys} {Prod F Xr Ys}}
+ end
+end
+\end{lstlisting}
+\end{solution}
+
+\section{Objects and abstract data types}
+In the course we saw two fundamentally different forms of data abstraction, namely objects and abstract data types ADTs and give an example of each.
+
+\begin{solution}
+\begin{center}
+\begin{minipage}{0.45\linewidth}
+Objet: représente à la fois une valeur et un ensemble d'opérations (liés)
+\begin{lstlisting}
+fun {NewStack}
+ C={NewCell nil}
+ proc {Push X} C:=X|@C end
+ proc {Pop X} S=@C in C:=S.2 X=S.1 end
+ proc {IsEmtpy B} B=(@C==nil) end
+in
+ proc {$ M}
+ case M of push(x) then {Push X}
+ [] pop(X) then {Pop X}
+ [] isEmpty(B) then {IsEmpty B} end
+ end
+end
+\end{lstlisting}
+\end{minipage}
+%
+\begin{minipage}{0.45\linewidth}
+Adt: représente un ensemble de valeurs et un ensemble d'opérations (séparés)
+\begin{lstlisting}
+local Wrap Unwrap in
+ {NewWrapper Wrap Unwrap}
+ fun {NewStack}
+ {Wrap nil}
+ end
+ fun {Push S X}
+ {Wrap X|{Unwrap S}}
+ end
+ fun {Pop W X} {Unwrap W} in X=S.1 {Wrap S.2} end
+ fun {IsEmpty S} {Unwrap S}==nil end
+end
+\end{lstlisting}
+\end{minipage}
+\end{center}
+\end{solution}
+
+\section{Exception}
+To handle exceptional situations in a program. we add a new concept called exceptions. We introduce two new instructions for exceptions, namely try $_1$ catch $$ then $_2$ end and raise $$ end. For this question, give the semantics Of try and raise by showing their effects on the semantic stack.
+
+\begin{solution}
+\includegraphics[scale=0.55]{stackException.png}
+\end{solution}
+
+\section{The importance of nondeterminism}
+
+
+\subsection{Definition of nondeterminism}
+Define the of nondeterminism in a programming language. Give an example of a program that shows non determinism.
+
+\begin{solution}
+Non-déterminisme correspond à la capacité d'un système à faire des décisions indépendamment du développeur.
+\begin{lstlisting}
+declare X1 X2
+X1=1 X2=2
+thread {Browse X1} end
+thread {Browse X2} end
+\end{lstlisting}
+On ne sait pas si X1 va être affiché en premier ou non.
+\end{solution}
+
+\subsection{Limitations of deterministic dataflow}
+Deterministic dataflow has the strong property that ithas no observable nondeterminism, For this question. give a specification of a client/server application and use this specification to explain Whythe
+client/server cannot be written as a deterministic dataflow program. Then define the concept of a port and show in a few lines Of code how to write a client/server by using a port.
+
+\begin{solution}
+Sans non-déterminisme observable, le résultat est toujours le même et le choix est pas fait par le scheduler mais par le programmeur.\par
+Or, dans une application client serveur, le résultat dépend de quand on reçoit le message. On reçoit un message, on compile, on répond. Il y a donc d'office du non déterminisme. Le résultat doit être choisi par le scheduler si 2 clients.\par
+Un port est un stream nommé.
+\begin{lstlisting}
+proc {Server S1 S2}
+ case (S1|S2) of (M1|T1)|S2 then
+ ... (handle M1)
+ {Server T1 S2}
+ [] S1|(M2|T2) then
+ ... (handle M2)
+ {Server S1 T2}
+ end
+end
+\end{lstlisting}
+\end{solution}
+
+
+\section{Erlang support for fault tolerance}
+
+\subsection{Process linking}
+An Erlang process is similarto a port Object An important primitive operation to support fault tolerance in Erlang is linking where processes are linked together. For this question. define linking and explain what it does. How does it work when there are more than two processes?
+
+\begin{solution}
+Link crée un lien entre 2 processus qui est bidirectionnel dans les 2 sens. Lorsqu'un process s'arrête il envoie le signal "normal" à tous les processus auxquels il est lié, sinon il envoie la cause de son arrêt \textit{anormal}. Les processus qui reçoivent un message "anormal" crash aussi et renvoient le message causant le crash.\par
+Un process peut être configuré pour piéger les signaux de sorte en appelant \textit{process\_flag}(trap\_exit, true)\par
+Un superviseur peut recevoir dans sa mailbox le message sans s'arrêter et prendre des mesures pour restaurer le système. \par
+Ainsi, tous les processus liés au crash en suivant la chaine jusqu'à arriver au superviseur. Si aucun process ne démarre, le programme s'arrête. On peut outrepasser un superviseur avec \textbf{exit(kill, Pid)}.
+\end{solution}
+
+\subsection{Supervisor trees}
+One of the key concepts in Erlang/OTP to support fault tolerance ts the supervisor tree. Explain what is a supervisor tree. As part of your answer, give two restart strategies and explain how they work. Justify each Strategy with a simple execution scenario.
+
+\begin{solution}
+Un arbre de supervision peut redémarrer, modifier ou arrêter un processus qu'il observe (auquel il est lié). Un superviseur, est lui-même supervisé par un autre superviseur, au cas où il échoue. 2 stratégies:
+\begin{enumerate}
+\item One\_for\_one: quand un des enfants crash, il est simplement redémarré par le superviseur sans que ça n'impacte les autres processus (\textit{ex}: client serveur: pour pas impacter les autres clients si il y a un crash)
+\item One\_for\_all: si un des enfants crash, tous les processus liés par le même superviseur sont arrêtés et relancés, même s'ils n'ont aucun problème (\textit{ex}: processus synchronisé: nécessaire quand les processus sont dépendants, pour qu'ils restent synchronisés)
+\end{enumerate}
+\end{solution}
+
+% Ajouter \nosolution s'il n'y a pas de solution disponible pour cette question
+
+% \nosolution
+
+\end{document}
diff --git a/src/q4/info-INFO1104/exam/2021/Juin/All/stackException.png b/src/q4/info-INFO1104/exam/2021/Juin/All/stackException.png
new file mode 100644
index 000000000..0d30b6e0c
Binary files /dev/null and b/src/q4/info-INFO1104/exam/2021/Juin/All/stackException.png differ
diff --git a/src/q4/info-INFO1104/exam/2021/Juin/Juin.mk b/src/q4/info-INFO1104/exam/2021/Juin/Juin.mk
new file mode 100644
index 000000000..25aee0790
--- /dev/null
+++ b/src/q4/info-INFO1104/exam/2021/Juin/Juin.mk
@@ -0,0 +1,2 @@
+MONTH=Juin
+include ../../2021.mk
diff --git a/src/q4/info-INFO1104/exam/2021/Septembre/All/Makefile b/src/q4/info-INFO1104/exam/2021/Septembre/All/Makefile
new file mode 100644
index 000000000..ca0c513cb
--- /dev/null
+++ b/src/q4/info-INFO1104/exam/2021/Septembre/All/Makefile
@@ -0,0 +1,2 @@
+MINMAJ=All
+include ../Septembre.mk
diff --git a/src/q4/info-INFO1104/exam/2021/Septembre/All/info-INFO1104-exam-2021-Septembre-All.tex b/src/q4/info-INFO1104/exam/2021/Septembre/All/info-INFO1104-exam-2021-Septembre-All.tex
new file mode 100644
index 000000000..615a7c126
--- /dev/null
+++ b/src/q4/info-INFO1104/exam/2021/Septembre/All/info-INFO1104-exam-2021-Septembre-All.tex
@@ -0,0 +1,229 @@
+\documentclass[fr]{../../../../../../eplexam}
+\usepackage{listings}
+\definecolor{codegreen}{rgb}{0,0.6,0}
+\definecolor{codegray}{rgb}{0.5,0.5,0.5}
+\definecolor{codepurple}{rgb}{0.58,0,0.82}
+\definecolor{backcolour}{rgb}{1.0,1.0,1.0}
+\definecolor{codeblue}{rgb}{0,0,0.8}
+
+\lstdefinestyle{mystyle}{
+ backgroundcolor=\color{backcolour},
+ commentstyle=\color{codegray},
+ keywordstyle=\color{codeblue},
+ numberstyle=\tiny\color{codegray},
+ stringstyle=\color{codeblue},
+ basicstyle=\ttfamily\footnotesize,
+ breakatwhitespace=false,
+ breaklines=true,
+ captionpos=b,
+ keepspaces=true,
+ numbers=left,
+ numbersep=5pt,
+ showspaces=false,
+ showstringspaces=false,
+ showtabs=false,
+ tabsize=2,
+ frame=shadowbox
+}
+\lstset{style=mystyle}
+\lstset{language=Oz}
+\hypertitle{}{4}{INFO}{1104}{2021}{Septembre}{All}
+{Norah Habets \and Thomas Debelle}
+{P. Van Roy}
+
+
+\section{Scope}
+Define the scope of an identifier occurrence. Give a code example where the same identifier occurs more than once and where these occurrences represent more than one variable.
+
+\begin{solution}
+La portée d'un identificateur est la partie où l'occurrence se réfère à la même déclaration de variable
+\begin{lstlisting}[escapechar=µ]
+local
+ X
+in
+ X=42 {Browse X} %Affiche 42
+ local
+ X
+ in
+ X=11 {Browse X} %Affiche 11
+ end
+ {Browse X} %Affiche 42
+end
+\end{lstlisting}
+\end{solution}
+
+\section{Ordered binary tree}
+Define an ordered binarytree type. Give first the EBNF grammar definition Ofa binary tree and then define the condition of bein ordered.
+
+\begin{solution}
+EBNF = Extended Backus-Naur form
+\begin{lstlisting}[escapechar=µ]
+ ::= leaf|t(T ... )
+ ::= leaf|t(key:T value:T left: right:
+\end{lstlisting}
+\begin{itemize}
+\item \underline{Binary:} chaque élément hormis les feuilles ont 2 sous-arbres
+\item \underline{Ordered:} pour chaque arbre (inclus les sous-arbres) toutes les clés à gauche dans le sous-arbres sont inférieurs à la clé de la racine. Les clés à droite sont toutes supérieures à celles de la clé de la racine.
+\end{itemize}
+\end{solution}
+
+\section{Deleting a node from an ordered binary tree}
+Given an ordered binary tree where each node has a key and a value. Define the function \{Delete K T\} that removes the node with key K from the tree (if the node exists) and returns a new ordered binary tree that contains all the nodes of T without the node with key K. To implementthe Delete function, you will need to define one auxiliary function, \{RemoveSmaIlest T\} which returns the smallest element of T and a new ordered tree without the smallest element. Both functions should be written in Oz in the declarative paradigm and using pattern matching to keep them simple. To make sure you define Delete and RemoveSmaIIest correctly, it can be a good idea to draw diagrams of what these functions do in different cases (such as when a tree is empty or when a tree has an empty subtree).
+
+\begin{solution}
+\begin{center}
+\begin{lstlisting}
+fun {RemoveSmallest T}
+ case T
+ of leaf then none
+ [] tree(key:X value:V left:T1 right:T2) then
+ case {RemoveSmallest T1}
+ of none then triple(T2 X V)
+ [] triple(Tp Xp Vp) then
+ triple(tree(key:X value:V left:Tp right:T2) Xp Vp)
+ end
+ end
+end
+\end{lstlisting}
+\begin{lstlisting}
+fun {Delete K T}
+ case T
+ of leaf then leaf
+ [] tree(key:X value:V left:T1 right:T2) andthen K==X then
+ case {RemoveSmallest T2}
+ of none then T1
+ [] triple(Tp Yp Vp) then
+ tree(key:Yp value:Vp left:T1 right:Tp)
+ end
+ [] tree(key:X value:V left:T1 right:T2) andthen KX then
+ tree(key:K value:V left:T1 right:{Delete K T2})
+ end
+end
+\end{lstlisting}
+\end{center}
+\end{solution}
+
+\section{Lambda calculus}
+Reduce the expression (SECOND (PAIR I (PAIR 2 NIL)))) to its simplest form. To make your answer easy to read, it is highly recommended to keep the abbreviations wheneveryou can! Only replace an abbreviation by its definition when you intend to applyit There Will be a penalty if your answer is overly complex.
+
+\begin{solution}
+(SECOND (PAIR 1 (PAIR 2 NIL))) $\longrightarrow$ ($\lambda p.$(p FALSE)(PAIR 1 (PAIR 2 NIL))) $\longrightarrow$ (PAIR 1 (PAIR 2 NIL) FALSE) $\longrightarrow$ ($\lambda x. \lambda y. \lambda f$(f x y) 1 (PAIR 2 NIL) FALSE) $\longrightarrow$ (FALSE 1 (PAIR 2 NIL)) $\longrightarrow$ ($\lambda x. \lambda y.y$ 1 (PAIR 2 NIL)) $\longrightarrow$ (PAIR 2 NIL) $\longrightarrow$ ($\lambda x. \lambda y. \lambda f$(f x y) 2 NIL) $\longrightarrow$ ($\lambda f.$(f 2 NIL))
+\end{solution}
+
+\section{Data abstraction}
+In the course we saw two fundamentally different forms of data abstraction, namely objects and abstract data types ADTs). For this question, define objects and ADTs and give an example of each (either a code example or an example from the real world). Explain Why your example is an Object or an ADT.
+
+\begin{solution}
+\begin{center}
+\begin{minipage}{0.45\linewidth}
+Objet: représente à la fois une valeur et un ensemble d'opérations (liés)
+\begin{lstlisting}
+fun {NewStack}
+ C={NewCell nil}
+ proc {Push X} C:=X|@C end
+ proc {Pop X} S=@C in C:=S.2 X=S.1 end
+ proc {IsEmtpy B} B=(@C==nil) end
+in
+ proc {$ M}
+ case M of push(x) then {Push X}
+ [] pop(X) then {Pop X}
+ [] isEmpty(B) then {IsEmpty B} end
+ end
+end
+\end{lstlisting}
+\end{minipage}
+%
+\begin{minipage}{0.45\linewidth}
+Adt: représente un ensemble de valeurs et un ensemble d'opérations (séparés)
+\begin{lstlisting}
+local Wrap Unwrap in
+ {NewWrapper Wrap Unwrap}
+ fun {NewStack}
+ {Wrap nil}
+ end
+ fun {Push S X}
+ {Wrap X|{Unwrap S}}
+ end
+ fun {Pop W X} {Unwrap W} in X=S.1 {Wrap S.2} end
+ fun {IsEmpty S} {Unwrap S}==nil end
+end
+\end{lstlisting}
+\end{minipage}
+\end{center}
+\end{solution}
+
+\section{Functional object}
+Give a code example of a functional Object. Calling a functional object returns another object with a new value inside. For example, Cl=\{NewCounter\} creates the counter Object CI with initial count 0. Then returns a new counter Object C2 with count l, and returns a new counter Object C3 with count 2. Hint: you need to define an auxiliary function \{CounterObject I\} that returns a counter object with count I. A counter Object is a record with an "inc" field that contains an increment function.
+
+\begin{solution}
+\begin{lstlisting}[escapechar=µ]
+declare
+fun {NewCounter}
+ fun {CounterObject I}
+ fun {Inc} {CounterObject I+1} end
+ fun {Get} I end %Optionnel
+ in
+ counter(inc:Inc get:Get)
+ end
+in
+ {CounterObject 0}
+end
+\end{lstlisting}
+\end{solution}
+
+\section{Exceptions}
+To handle exceptional situations in a program, we add a new concept called exceptions. We introducenew instructions for exceptions, namely try $_1$ catch $$ then $_2$ end and raise end. For this question, give the semantics of both try and raise by showing their effects on the semantic stack. Be careful to show exactly what is on the stack, including and and also the other instructions (such as the instructions below the try). Your answer should show the connection between and by giving the environments of the instructions. Your answer should also show what happens in the case that no exception is raised and also what happens in the case that a raise is executed.
+
+\begin{solution}
+\includegraphics[scale=0.55]{stackException.png}
+\end{solution}
+
+\section{The scheduler and its friends}
+Define the concept of a scheduler in a concurrent system. Explain precisely what the scheduler does. As part of your explanation, define the six concepts of nondeterminism, time slice, runnable, suspended, fairness, and statvation. Be sure to give a clear definition for each of these six concepts!
+
+\begin{solution}
+\begin{itemize}
+\item \underline{Scheduler:} partie du système qui décide à tout moment quel thread exécuter (donc exemple non déterminisme)
+ \begin{lstlisting}[escapechar=µ]
+ declare
+ thread X=1 end
+ thread X=2 end
+ {Browse X} %On ne sait pas si 1 ou 2 sera affichµ\textcolor{gray}{é}µ
+ \end{lstlisting}
+% oui on doit faire "µ\textcolor{gray}{é}µ" pour afficher un accent mdr
+\item \underline{Non déterminisme:} Capacité du système à faire des décisions indépendantes du développeur.
+\item \underline{Time slice:} courte période (souvent 10 ms) pendant laquelle s'exécute un thread.
+\item \underline{Runnable:} dit d'un thread si l'instruction située au sommet de sa stack n'est pas en attente d'une variable dataflow.
+\item \underline{Suspended:} dit d'un thread si il est bloqué sur une variable.
+\item \underline{Fairness:} dit d'un scheduler, si chaque runnable thread sera exécuté dans un temps fini (les threads sont classés en fonction de leur priorité et des garanties supplémentes sont données sur le pourcentage du temps accordé aux threads de même priorité)
+\item \underline{Starvation:} si le scheduler n'est pas \textit{fair}. Certains threads peuvent "\textit{starve}" donc recevoir 0\% du temps du processeur et ne s'exécutent donc jamais et le programme s'arrête.
+\end{itemize}
+\end{solution}
+
+\section{Erlang support for fault tolerance}
+
+\subsection{Process linking}
+An Erlang process is similar to a port Object. An important primitive operation to support fault tolerance in Erlang is linking, where processes are linked together. For this question, define linking and explain what it does. How does it work when there are more than processes?
+
+\begin{solution}
+Link crée un lien entre 2 processus qui est bidirectionnel dans les 2 sens. Lorsqu'un process s'arrête il envoie le signal "normal" à tous les processus auxquels il est lié, sinon il envoie la cause de son arrêt \textit{anormal}. Les processus qui reçoivent un message "anormal" crash aussi et renvoient le message causant le crash.\par
+Un process peut être configuré pour piéger les signaux de sorte en appelant \textit{process\_flag}(trap\_exit, true)\par
+Un superviseur peut recevoir dans sa mailbox le message sans s'arrêter et prendre des mesures pour restaurer le système. \par
+Ainsi, tous les processus liés au crash en suivant la chaine jusqu'à arriver au superviseur. Si aucun process ne démarre, le programme s'arrête. On peut outrepasser un superviseur avec \textbf{exit(kill, Pid)}.
+\end{solution}
+
+\subsection{Supervisor trees}
+One of the key concepts in Erlang/OTP to support fault tolerance is the supervisor tree. Explain what is a supervisor tree. As part of your answer, give two restart strategies and explain how they work. Justify each strategy with a simple execution scenario.
+
+\begin{solution}
+Un arbre de supervision peut redémarrer, modifier ou arrêter un processus qu'il observe (auquel il est lié). Un superviseur, est lui-même supervisé par un autre superviseur, au cas où il échoue. 2 stratégies:
+\begin{enumerate}
+\item One\_for\_one: quand un des enfants crash, il est simplement redémarré par le superviseur sans que ça n'impacte les autres processus (\textit{ex}: client serveur: pour pas impacter les autres clients si il y a un crash)
+\item One\_for\_all: si un des enfants crash, tous les processus liés par le même superviseur sont arrêtés et relancés, même s'ils n'ont aucun problème (\textit{ex}: processus synchronisé: nécessaire quand les processus sont dépendants, pour qu'ils restent synchronisés)
+\end{enumerate}
+\end{solution}
+
+
+\end{document}
diff --git a/src/q4/info-INFO1104/exam/2021/Septembre/All/stackException.png b/src/q4/info-INFO1104/exam/2021/Septembre/All/stackException.png
new file mode 100644
index 000000000..0d30b6e0c
Binary files /dev/null and b/src/q4/info-INFO1104/exam/2021/Septembre/All/stackException.png differ
diff --git a/src/q4/info-INFO1104/exam/2021/Septembre/Septembre.mk b/src/q4/info-INFO1104/exam/2021/Septembre/Septembre.mk
new file mode 100644
index 000000000..2cdf73d47
--- /dev/null
+++ b/src/q4/info-INFO1104/exam/2021/Septembre/Septembre.mk
@@ -0,0 +1,2 @@
+MONTH=Septembre
+include ../../2021.mk
diff --git a/src/q4/info-INFO1104/exam/2022/2022.mk b/src/q4/info-INFO1104/exam/2022/2022.mk
new file mode 100644
index 000000000..3f2bc1c33
--- /dev/null
+++ b/src/q4/info-INFO1104/exam/2022/2022.mk
@@ -0,0 +1,2 @@
+YEAR=2022
+include ../../../exam.mk
diff --git a/src/q4/info-INFO1104/exam/2022/Juin/All/Diagramme2.drawio b/src/q4/info-INFO1104/exam/2022/Juin/All/Diagramme2.drawio
new file mode 100644
index 000000000..1c41fe3c0
--- /dev/null
+++ b/src/q4/info-INFO1104/exam/2022/Juin/All/Diagramme2.drawio
@@ -0,0 +1,103 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/q4/info-INFO1104/exam/2022/Juin/All/Diagramme2.png b/src/q4/info-INFO1104/exam/2022/Juin/All/Diagramme2.png
new file mode 100644
index 000000000..6667e6d91
Binary files /dev/null and b/src/q4/info-INFO1104/exam/2022/Juin/All/Diagramme2.png differ
diff --git a/src/q4/info-INFO1104/exam/2022/Juin/All/Makefile b/src/q4/info-INFO1104/exam/2022/Juin/All/Makefile
new file mode 100644
index 000000000..a519d4a83
--- /dev/null
+++ b/src/q4/info-INFO1104/exam/2022/Juin/All/Makefile
@@ -0,0 +1,2 @@
+MINMAJ=All
+include ../Juin.mk
diff --git a/src/q4/info-INFO1104/exam/2022/Juin/All/info-INFO1104-exam-2022-Juin-All.tex b/src/q4/info-INFO1104/exam/2022/Juin/All/info-INFO1104-exam-2022-Juin-All.tex
new file mode 100644
index 000000000..f826e6ae6
--- /dev/null
+++ b/src/q4/info-INFO1104/exam/2022/Juin/All/info-INFO1104-exam-2022-Juin-All.tex
@@ -0,0 +1,174 @@
+\documentclass[fr]{../../../../../../eplexam}
+\usepackage{listings}
+\definecolor{codegreen}{rgb}{0,0.6,0}
+\definecolor{codegray}{rgb}{0.5,0.5,0.5}
+\definecolor{codepurple}{rgb}{0.58,0,0.82}
+\definecolor{backcolour}{rgb}{1.0,1.0,1.0}
+\definecolor{codeblue}{rgb}{0,0,0.8}
+
+\lstdefinestyle{mystyle}{
+ backgroundcolor=\color{backcolour},
+ commentstyle=\color{codegray},
+ keywordstyle=\color{codeblue},
+ numberstyle=\tiny\color{codegray},
+ stringstyle=\color{codeblue},
+ basicstyle=\ttfamily\footnotesize,
+ breakatwhitespace=false,
+ breaklines=true,
+ captionpos=b,
+ keepspaces=true,
+ numbers=left,
+ numbersep=5pt,
+ showspaces=false,
+ showstringspaces=false,
+ showtabs=false,
+ tabsize=2,
+ frame=shadowbox
+}
+\lstset{style=mystyle}
+\lstset{language=Oz}
+\hypertitle{}{4}{INFO}{1104}{2022}{Juin}{All}
+{Norah Habets \and Thomas Debelle}
+{P. Van Roy}
+
+\section{kernel language}
+\begin{center}
+\begin{minipage}{0.45\linewidth}
+Translate the following program into kernel language. Be careful to do a complete translation that uses only kernel language instructions !
+\end{minipage}
+%
+\begin{minipage}{0.45\linewidth}
+\begin{lstlisting}
+local F in
+ fun {F A B}
+ fun {$ C}
+ fun {$ D} (A+B)*(C+D) end
+ end
+ end
+ {Browse {{{F 5 6} 4} 3}}
+end
+\end{lstlisting}
+\end{minipage}
+\end{center}
+
+\begin{solution}
+\begin{lstlisting}[escapechar=µ]
+local F in
+ proc {F A B R1}
+ R1=proc {$ C R2}
+ R2=proc {$ D R3} local V1 V2 in V1=A+B V2=C+D
+ R3=V1*V2 end
+ end
+ end
+ end
+local Three Four Five Six X Y Z in Three=3 Four=4 Five=5 Six=6
+ {F Five Six X} {X Four Y} {Y Three Z} {Browse Z} end
+end
+\end{lstlisting}
+\end{solution}
+
+\section{Give the semantic rule for the instruction "thread end"}
+Show the execution state before and after the execution of this instruction. Your answer can continue on the nextpage.
+
+\begin{solution}
+\begin{center}
+\includegraphics[scale=0.6]{Diagramme2.png}
+\end{center}
+Séquence d'états d'exécution: $(MST_1, \sigma_1) \rightarrow (MST_2, \sigma_2) \rightarrow ...$. MST = multiset of semantic stacks. Une étape par thread (choix du thread par le scheduler). On utilise l'interleaving semantics.\\
+On crée une nouvelle pile sémantique contenant et qui accède à la même mémoire que la pile sémantique de base. La mémoire est partagée.
+\end{solution}
+
+\section{Lambda calculus reduction}
+Reduce the expression (SUCC (SUCC I)) and show itis equivalent to 3. Show all reduction steps. To make your answer easier to understand, you must only replace a function by its definition when you need it for a reduction step.
+
+\begin{solution}
+(SUCC (SUCC 1)) $\longrightarrow$ (SUCC ($\lambda n. \lambda f. \lambda x.f$((n f) x) 1)) $\longrightarrow$ (SUCC ($\lambda f. \lambda x.f$((1 f) x))) $\longrightarrow$ (SUCC ($\lambda f. \lambda x.f$(($\lambda f. \lambda x.fxf$)x))) $\longrightarrow$ (SUCC ($\lambda f. \lambda x.f$ (($\lambda x.fx$)x))) $\longrightarrow$ (SUCC ($\lambda f. \lambda x.f$(f x))) $\longrightarrow$ (SUCC 2) $\longrightarrow$ ($\lambda f. \lambda x.f$((2 f) x)) $\longrightarrow$ ($\lambda f. \lambda x.f(f(f$ x))) $\longrightarrow$ $3$
+\end{solution}
+
+\section{Exceptions}
+To handle exceptional situations in a program, we add a new concept called exceptions. We introducenew instructions for exceptions, namely try $_1$ catch $$ then $_2$ end and raise end. For this question, give the semantics of both try and raise by showing their effects on the semantic stack. Be careful to show exactly what is on the stack, including and and also the other instructions (such as the instructions below the try). Your answer should show the connection between and by giving the environments of the instructions. Your answer should also show what happens in the case that no exception is raised and also what happens in the case that a raise is executed.
+
+\begin{solution}
+\includegraphics[scale=0.55]{stackException.png}
+\end{solution}
+
+\section{Ports and port objects}
+\subsection{Give the semantics of the port send operation}
+For the operation \{Send P X\}, give the execution state before and after the operation's execution. You may assume that P is correctly bound to a port before the execution (the port is already created).
+
+\begin{solution}
+En supposant que le port a été créé par P=\{NewPort S\}:
+\begin{lstlisting}[escapechar=µ]
+([({Send P X}, {P µ$\rightarrow$µ p, X µ$\rightarrow$µ x, S µ$\rightarrow$µ s}), ...], µ$\sigma$µ={p=µ$\xi$µ,s,x}µ$\bigcup$µ{p:s})
+([(...)], µ$\sigma$µ={p=µ$\xi$µ,s=x|s',s',x}µ$\bigcup$µ{p:s'})
+\end{lstlisting}
+\begin{center}
+\includegraphics[scale=0.5]{semantiquePort.png}
+\end{center}
+\end{solution}
+
+\subsection{Stateful port objects}
+Define a function that takes an initial state and a state transition function so that it creates a stateful port Object when it is called.
+
+\begin{solution}
+\begin{lstlisting}[escapechar=µ]
+fun {NewPortObject Behaviour Init}
+ local S
+ thread P={NewPort S} Out={FoldL S Behaviour Init} end
+ in
+ proc {$ M} {Send P M} end
+ end
+end
+declare
+fun {FoldL S F U}
+ case S of nil then U
+ [] H|T then {FoldL T F {F U H}}
+ end
+end
+\end{lstlisting}
+\end{solution}
+
+\section{Erlang mechanisms for long-lived programs}
+
+\subsection{Process linking}
+An Erlang process is similar to a port Object. An important primitive operation to support fault tolerance in Erlang is linking, where processes are linked together. For this question, define linking and explain what it does. How does it work when there are more than processes?
+
+\begin{solution}
+Link crée un lien entre 2 processus qui est bidirectionnel dans les 2 sens. Lorsqu'un process s'arrête il envoie le signal "normal" à tous les processus auxquels il est lié, sinon il envoie la cause de son arrêt \textit{anormal}. Les processus qui reçoivent un message "anormal" crash aussi et renvoient le message causant le crash.\par
+Un process peut être configuré pour piéger les signaux de sorte en appelant \textit{process\_flag}(trap\_exit, true)\par
+Un superviseur peut recevoir dans sa mailbox le message sans s'arrêter et prendre des mesures pour restaurer le système. \par
+Ainsi, tous les processus liés au crash en suivant la chaine jusqu'à arriver au superviseur. Si aucun process ne démarre, le programme s'arrête. On peut outrepasser un superviseur avec \textbf{exit(kill, Pid)}.
+\end{solution}
+
+\subsection{Dynamic code change}
+In Erlangitis possible to update the code without stopping the system. Erlang has two basic mechanisms to allow this. For this question, explain the two mechanisms and give small code fragments in Erlang to illustrate them (as we did in the course). Hint: one of the mechanisms needs to be supported by the implementation, whereas the other mechanism is a consequence of functional programming.
+
+\begin{solution}
+\begin{minipage}[t]{0.45\linewidth}
+\begin{lstlisting}[language=erlang, caption={use new version}]
+-module(m).
+
+loop(Data, F) ->
+ receive
+ (From,Q} ->
+ {Reply,Data1}=F(Q,Data),
+ m:loop(Data1, F)
+end.
+\end{lstlisting}
+\end{minipage}
+%
+\begin{minipage}[t]{0.45\linewidth}
+\begin{lstlisting}[language=erlang, caption={use old version}]
+-module(m).
+
+loop(Data, F) ->
+ receive
+ {From,Q} ->
+ {Reply,Data1}=F(Q,Data),
+ loop(Data1, F)
+end.
+\end{lstlisting}
+\end{minipage}
+\end{solution}
+
+\end{document}
diff --git a/src/q4/info-INFO1104/exam/2022/Juin/All/semantiquePort.png b/src/q4/info-INFO1104/exam/2022/Juin/All/semantiquePort.png
new file mode 100644
index 000000000..ed3ae1dd8
Binary files /dev/null and b/src/q4/info-INFO1104/exam/2022/Juin/All/semantiquePort.png differ
diff --git a/src/q4/info-INFO1104/exam/2022/Juin/All/stackException.png b/src/q4/info-INFO1104/exam/2022/Juin/All/stackException.png
new file mode 100644
index 000000000..0d30b6e0c
Binary files /dev/null and b/src/q4/info-INFO1104/exam/2022/Juin/All/stackException.png differ
diff --git a/src/q4/info-INFO1104/exam/2022/Juin/Juin.mk b/src/q4/info-INFO1104/exam/2022/Juin/Juin.mk
new file mode 100644
index 000000000..35bb47f16
--- /dev/null
+++ b/src/q4/info-INFO1104/exam/2022/Juin/Juin.mk
@@ -0,0 +1,2 @@
+MONTH=Juin
+include ../../2022.mk
diff --git a/src/q4/info-INFO1104/exam/2022/Septembre/All/Makefile b/src/q4/info-INFO1104/exam/2022/Septembre/All/Makefile
new file mode 100644
index 000000000..ca0c513cb
--- /dev/null
+++ b/src/q4/info-INFO1104/exam/2022/Septembre/All/Makefile
@@ -0,0 +1,2 @@
+MINMAJ=All
+include ../Septembre.mk
diff --git a/src/q4/info-INFO1104/exam/2022/Septembre/All/info-INFO1104-exam-2022-Septembre-All.tex b/src/q4/info-INFO1104/exam/2022/Septembre/All/info-INFO1104-exam-2022-Septembre-All.tex
new file mode 100644
index 000000000..53473c829
--- /dev/null
+++ b/src/q4/info-INFO1104/exam/2022/Septembre/All/info-INFO1104-exam-2022-Septembre-All.tex
@@ -0,0 +1,206 @@
+\documentclass[fr]{../../../../../../eplexam}
+\usepackage{listings}
+\definecolor{codegreen}{rgb}{0,0.6,0}
+\definecolor{codegray}{rgb}{0.5,0.5,0.5}
+\definecolor{codepurple}{rgb}{0.58,0,0.82}
+\definecolor{backcolour}{rgb}{1.0,1.0,1.0}
+\definecolor{codeblue}{rgb}{0,0,0.8}
+
+
+\lstdefinestyle{mystyle}{
+ backgroundcolor=\color{backcolour},
+ commentstyle=\color{codegray},
+ keywordstyle=\color{codeblue},
+ numberstyle=\tiny\color{codegray},
+ stringstyle=\color{codeblue},
+ basicstyle=\ttfamily\footnotesize,
+ breakatwhitespace=false,
+ breaklines=true,
+ captionpos=b,
+ keepspaces=true,
+ numbers=left,
+ numbersep=5pt,
+ showspaces=false,
+ showstringspaces=false,
+ showtabs=false,
+ tabsize=2,
+ frame=shadowbox
+}
+\lstset{style=mystyle}
+\lstset{language=Oz}
+\hypertitle{}{4}{INFO}{1104}{2022}{Septembre}{All}
+{Norah Habets \and Thomas Debelle}
+{P. Van Roy}
+
+\section{Kernel Language}
+\begin{center}
+\begin{minipage}{0.45\linewidth}
+Translate the following program into kernel language. Be careful to do a complete translation that uses only kernel language instructions !
+\end{minipage}
+%
+\begin{minipage}{0.45\linewidth}
+\begin{lstlisting}
+local F C in
+ C={NewCell 1}
+ fun {F A}
+ @A
+ end
+ C:={F C}+1
+end
+\end{lstlisting}
+\end{minipage}
+\end{center}
+
+\begin{solution}
+\begin{lstlisting}[escapechar=µ]
+local F C One C1 in One=1
+ {NewCell One C}
+ F=proc {$ A ?R1}
+ R1=@A
+ end
+ {F C ?R2}
+ C1=R2+One
+ C:=C1
+end
+\end{lstlisting}
+\end{solution}
+
+\section{Basic concepts}
+\subsection{Scope}
+Define "scope" in a programming language. Give an example.
+
+\begin{solution}
+La portée d'un identificateur est la partie où l'occurrence se réfère à la même déclaration de variable
+\begin{lstlisting}[escapechar=µ]
+local
+ X
+in
+ X=42 {Browse X} %Affiche 42
+ local
+ X
+ in
+ X=11 {Browse X} %Affiche 11
+ end
+ {Browse X} %Affiche 42
+end
+\end{lstlisting}
+\end{solution}
+
+\subsection{Contextual environment}
+Define "contextual environment" of a procedure. Give an example
+
+\begin{solution}
+L'environnement contextuel une fonction (ou procédure) contient tous les identificateurs qui sont utilisés dans la fonction mais déclarés en dehors.
+\begin{lstlisting}[escapechar=µ]
+declare
+fun {Compose F G}
+ fun {$ X}{F {G X}} end
+end
+\end{lstlisting}
+Où E = \{F $\rightarrow$ f, G $\rightarrow$ g\}
+\end{solution}
+
+\section{Lambda calculus}
+Reduce the expression (PLUS 1 (IFTHENELSE (ISZERO 1) O I)) to its simplest form. Show all reduction steps. To make your answer easier to understand, you must only replace a function by its definition when you need it for a reduction step. If you do not do this, there wüll be a penalty.
+
+\begin{solution}
+\begin{itemize}
+\item (ISZERO 1) $\longrightarrow$ ($\lambda n.(n(\lambda x.$FALSE) TRUE 1) $\longrightarrow$ (1 ($\lambda x.$FALSE) TRUE) $\longrightarrow$ ($\lambda f.(\lambda x$(f x))($\lambda x.$FALSE) TRUE) $\longrightarrow$ (($\lambda x.$ FALSE) TRUE) $\longrightarrow$ (($\lambda x. \lambda x. \lambda y.y$) TRUE) $\longrightarrow$ $\lambda x. \lambda y.y$ $\longrightarrow$ FALSE
+\item (IFTHENELSE (ISZERO 1) 0 1) $\longrightarrow$ (IFTHENELSE FALSE 0 1) $\longrightarrow$ ($\lambda p. \lambda a. \lambda b.$(p a b) FALSE 0 1) $\longrightarrow$ (FALSE 0 1) $\longrightarrow$ ($\lambda x. \lambda y.y$ 0 1) $\longrightarrow$ 1
+\item (PLUS 1 (IFTHENELSE (ISZERO 1) 0 1)) $\longrightarrow$ (PLUS 1 1) $\longrightarrow$ ($\lambda m. \lambda n. \lambda f. \lambda x.$(m f)((n f) x) 1 1) $\longrightarrow$ ($\lambda f. \lambda x.$(1 f)((1 f) x)) $\longrightarrow$ ($\lambda f. \lambda x.$(f (f x))) $\longrightarrow$ 2
+\end{itemize}
+\end{solution}
+
+\section{Functional object}
+Give a code example of a functional Object. Calling a functional Object returns another Object with a new value inside. For example, creates the counter object Cl with initial count 0. Then returns a new counter Object C2 with count 1, and returns a new counter Object C3 with count 2. Hints: A functional Object is purely declarative; cells are not allowed. You need to define an auxiliary function \{CounterObject I\} that returns a counter Object with count I. A counter Object is a record with an 'inc' field that contains an increment function.
+
+\begin{solution}
+\begin{lstlisting}[escapechar=µ]
+declare
+fun {NewCounter}
+ fun {CounterObject I}
+ fun {Inc} {CounterObject I+1} end
+ fun {Get} I end %Optionnel
+ in
+ counter(inc:Inc get:Get)
+ end
+in
+ {CounterObject 0}
+end
+\end{lstlisting}
+\end{solution}
+
+
+\section{Nondeterminism}
+\subsection{Definition of nondeterminism}
+Define the concept of nondeterminism in a programming language. Be careful to give a precise definition! It is a bit subtle. Give an example of a program that shows nondeterminism.
+
+\begin{solution}
+Non-déterminisme correspond à la capacité d'un système à faire des décisions indépendamment du développeur.
+\begin{lstlisting}
+declare X1 X2
+X1=1 X2=2
+thread {Browse X1} end
+thread {Browse X2} end
+\end{lstlisting}
+On ne sait pas si X1 va être affiché en premier ou non.
+\end{solution}
+
+
+\subsection{Overcoming the limitation of deterministic dataflow}
+Deterministic dataflow has the strong property that it has no observable nondeterminism. For this question, first give a specification of a client/server application, second use this specification to explain Why the client/server be written as a deterministic dataflow program. Third, briefly define the concept of a port and fourth show in a few lines of code how to write a client/server with a port.
+
+\begin{solution}
+Sans non-déterminisme observable, le résultat est toujours le même. Or, dans une application Client|Serveur, le résultat dépend de quand on reçoit le message. On reçoit un message, on compile et on répond. Il y a donc d'office du non-déterminisme. Le résultat est choisi par le scheduler et non par le développeur.\par
+Un port est un stream:
+\begin{lstlisting}[escapechar=µ]
+P={NewPort S} %Crµ\textcolor{gray}{é}µe un port avec un stream
+{Send P N} %Ajoute N au stream
+\end{lstlisting}
+Client Serveur avec un port. Les clients envoient et reçoivent des message. Les clients sont des agents concurrents. Le serveur reçoit un message, fait un calcul en local et envoie une réponse immédiate.
+\end{solution}
+
+\section{Erlang mechanisms for long-lived programs}
+
+\subsection{Process linking}
+An Erlang process is similar to a port Object. An important primitive operation to support fault tolerance in Erlang is linking, where processes are linked together. For this question, define linking and explain what it does. How does it work when there are more than processes?
+
+\begin{solution}
+Link crée un lien entre 2 processus qui est bidirectionnel dans les 2 sens. Lorsqu'un process s'arrête il envoie le signal "normal" à tous les processus auxquels il est lié, sinon il envoie la cause de son arrêt \textit{anormal}. Les processus qui reçoivent un message "anormal" crash aussi et renvoient le message causant le crash.\par
+Un process peut être configuré pour piéger les signaux de sorte en appelant \textit{process\_flag}(trap\_exit, true)\par
+Un superviseur peut recevoir dans sa mailbox le message sans s'arrêter et prendre des mesures pour restaurer le système. \par
+Ainsi, tous les processus liés au crash en suivant la chaine jusqu'à arriver au superviseur. Si aucun process ne démarre, le programme s'arrête. On peut outrepasser un superviseur avec \textbf{exit(kill, Pid)}.
+\end{solution}
+
+\subsection{Dynamic code change}
+In Erlangitis possible to update the code without stopping the system. Erlang has two basic mechanisms to allow this. For this question, explain the two mechanisms and give small code fragments in Erlang to illustrate them (as we did in the course). Hint: one of the mechanisms needs to be supported by the implementation, whereas the other mechanism is a consequence of functional programming.
+
+\begin{solution}
+\begin{minipage}[t]{0.45\linewidth}
+\begin{lstlisting}[language=erlang, caption={use new version}]
+-module(m).
+
+loop(Data, F) ->
+ receive
+ (From,Q} ->
+ {Reply,Data1}=F(Q,Data),
+ m:loop(Data1, F)
+end.
+\end{lstlisting}
+\end{minipage}
+%
+\begin{minipage}[t]{0.45\linewidth}
+\begin{lstlisting}[language=erlang, caption={use old version}]
+-module(m).
+
+loop(Data, F) ->
+ receive
+ {From,Q} ->
+ {Reply,Data1}=F(Q,Data),
+ loop(Data1, F)
+end.
+\end{lstlisting}
+\end{minipage}
+\end{solution}
+
+\end{document}
diff --git a/src/q4/info-INFO1104/exam/2022/Septembre/Septembre.mk b/src/q4/info-INFO1104/exam/2022/Septembre/Septembre.mk
new file mode 100644
index 000000000..0569908d9
--- /dev/null
+++ b/src/q4/info-INFO1104/exam/2022/Septembre/Septembre.mk
@@ -0,0 +1,2 @@
+MONTH=Septembre
+include ../../2022.mk
diff --git a/src/q4/info-INFO1104/exam/exam.mk b/src/q4/info-INFO1104/exam/exam.mk
new file mode 100644
index 000000000..b4ea52ded
--- /dev/null
+++ b/src/q4/info-INFO1104/exam/exam.mk
@@ -0,0 +1,3 @@
+TYPE=exam
+BASE_DIR=../../../
+include $(BASE_DIR)../info-INFO1104.mk
diff --git a/src/q4/info-INFO1104/info-INFO1104.mk b/src/q4/info-INFO1104/info-INFO1104.mk
new file mode 100644
index 000000000..8c9d08bfb
--- /dev/null
+++ b/src/q4/info-INFO1104/info-INFO1104.mk
@@ -0,0 +1,4 @@
+NAME=info
+OPTION=INFO
+CODE=1104
+include $(BASE_DIR)../../q4.mk
diff --git a/src/q4/projet-EPL1503/exam/2023/2023.mk b/src/q4/projet-EPL1503/exam/2023/2023.mk
new file mode 100644
index 000000000..3be9f03b6
--- /dev/null
+++ b/src/q4/projet-EPL1503/exam/2023/2023.mk
@@ -0,0 +1,2 @@
+YEAR=2023
+include ../../../exam.mk
diff --git a/src/q4/projet-EPL1503/exam/2023/Juin/All/Makefile b/src/q4/projet-EPL1503/exam/2023/Juin/All/Makefile
new file mode 100644
index 000000000..a519d4a83
--- /dev/null
+++ b/src/q4/projet-EPL1503/exam/2023/Juin/All/Makefile
@@ -0,0 +1,2 @@
+MINMAJ=All
+include ../Juin.mk
diff --git a/src/q4/projet-EPL1503/exam/2023/Juin/All/projet-EPL1503-exam-2023-Juin-All.tex b/src/q4/projet-EPL1503/exam/2023/Juin/All/projet-EPL1503-exam-2023-Juin-All.tex
new file mode 100644
index 000000000..c264e0cb4
--- /dev/null
+++ b/src/q4/projet-EPL1503/exam/2023/Juin/All/projet-EPL1503-exam-2023-Juin-All.tex
@@ -0,0 +1,412 @@
+\documentclass[fr]{../../../../../../eplexam}
+\usepackage{listings}
+
+\definecolor{codegreen}{rgb}{0,0.6,0}
+\definecolor{codegray}{rgb}{0.5,0.5,0.5}
+\definecolor{codepurple}{rgb}{0.58,0,0.82}
+\definecolor{backcolour}{rgb}{0.95,0.95,0.92}
+
+\lstdefinestyle{mystyle}{
+ backgroundcolor=\color{backcolour},
+ commentstyle=\color{codegreen},
+ keywordstyle=\color{magenta},
+ numberstyle=\tiny\color{codegray},
+ stringstyle=\color{codepurple},
+ basicstyle=\ttfamily\footnotesize,
+ breakatwhitespace=false,
+ breaklines=true,
+ captionpos=b,
+ keepspaces=true,
+ numbers=left,
+ numbersep=5pt,
+ showspaces=false,
+ showstringspaces=false,
+ showtabs=false,
+ tabsize=2
+}
+\lstset{style=mystyle}
+\lstset{language=C}
+
+\hypertitle{Projet P3}{4}{EPL}{1503}{2023}{Juin}{All}
+{Thomas Debelle}
+{Olivier Bonaventure \& Axel Legay}
+
+\section{Étudiants en échec}
+L'EPL a développé un petit logiciel en C qui stocke les points de tous les étudiants dans un tableau contenant des structures record définies comme suit :
+\begin{lstlisting}[escapechar=µ]
+struct record { char *student; // nom de l'µ\textcolor{gray}{é}µtudiant (toujours diffµ\textcolor{gray}{é}µrent de NULL)
+ int n; // nombre de cours suivis (strictement positif)
+ int *points; // points obtenus pour chaque cours (les points sont toujours en 0 et 20)
+};
+\end{lstlisting}
+% µ\textcolor{gray}{é}µ
+
+Ecrivez le corps de la fonction \textbf{echecs} dont la spécification est la suivante :
+
+\begin{lstlisting}[escapechar=µ]
+/*
+* @pre n>0 correspond au nombre d'µ\textcolor{gray}{é}µtudiants dans la classe, *classe!=NULL
+* @post retourne le nombre de cours en µ\textcolor{gray}{é}µchecs pour l'ensemble des µ\textcolor{gray}{é}µtudiants de la classe
+*/
+int echecs(int n, struct record *classe) {
+\end{lstlisting}
+A titre d'exemple, considérons la classe contenant trois étudiants : - Marie qui a suivi 3 cours et obtenu 18, 10 et 11 - Jean qui a suivi 5 cours et obtenu 9, 7, 13, 20 et 10 - Luc qui a suivi 4 cours et obtenu 10, 11, 6 et 0\\
+
+Lorsque l'on applique la fonction échecs à un tableau contenant les 3 records de ces étudiants, elle retourne la valeur 4.
+
+\begin{solution}
+\begin{lstlisting}[escapechar=µ]
+if(classe == NULL){
+ return 0;
+}
+
+int count = 0;
+for(int i = 0; i < n; i++){
+ for(int j = 0; j < classe[i].n; j++){
+ if(classe[i].points[j] < 10){
+ count++;
+ }
+ }
+}
+
+return count;
+\end{lstlisting}
+\end{solution}
+
+\section{Nombre de caractères différents}
+Un chaîne de caractères contient différents caractères. Vous devez écrire le corps de la fonction ndiff qui retourne le nombre de caractères différents dans la chaîne passée en argument.\\
+
+Complétez le corps de la fonction ndiff sur base de la spécification ci-dessous:
+
+\begin{lstlisting}[escapechar=µ]
+#include
+#include
+#include
+
+/*
+ * @pre -
+ * @post retourne le nombre de caractµ\textcolor{gray}{è}µres diffµ\textcolor{gray}{é}µrents dans la chaµ\textcolor{gray}{î}µne pointµ\textcolor{gray}{é}µe par str
+ * Exemples:
+ * - ndiff("ABA") retourne 2
+ * - ndiff("") retourne 0
+ * - ndiff(NULL) retourne 0
+ * - ndiff("AabBAb") retourne 4
+ */
+int ndiff(char *str) {
+\end{lstlisting}
+
+\begin{solution}
+\begin{lstlisting}[escapechar=µ]
+if(str == NULL){
+ return 0;
+}
+if(strlen(str) == 0){
+ return 0;
+}
+
+char* found = (char*) malloc(sizeof(char)*(strlen(str) + 1)); // create a string with all the different character of str
+int size = 0; int flag = 0; // the size of the found array and a flag to check if we found something
+
+for(int i = 0; i < strlen(str); i++){
+ if(size == 0){
+ found[size] = str[i];
+ size++;
+ }else{
+ flag = 1;
+ for(int j = 0; j < size; j++){
+ if(found[j] == str[i]){
+ flag = 0;
+ break;
+ }
+ }
+ if(flag){
+ found[size] = str[i];
+ size++;
+ }
+ }
+}
+
+return size;
+\end{lstlisting}
+\end{solution}
+
+\section{Liste doublement chaînée}
+
+Une liste doublement chaînée est implémentée comme suit. Cette structure de données permet d'enregistrer un ensemble d'éléments, en liant pour chacun une clé à une valeur. On va faire l'hypothèse dans cette question qu'il n'y a qu'un seul exemplaire de chaque clé dans la liste.
+
+\begin{lstlisting}[escapechar=µ]
+typedef struct node {
+ int key;
+ double value;
+ struct node* next;
+ struct node* prev;
+} node_t;
+
+typedef struct list {
+ node_t* head;
+ node_t* tail;
+} list_t;
+
+list_t* create_list() {
+ list_t* list = (list_t*) malloc(sizeof(list_t));
+ if (list == NULL) {
+ return NULL;
+ }
+
+ list->head = NULL;
+ list->tail = NULL
+
+ return list;
+}
+
+int insert(list_t* list, int key, double value) {
+ node_t* node = (node_t*) malloc(sizeof(node_t));
+ if (node == NULL) {
+ return -1;
+ }
+
+ node->key = key;
+ node->value = value;
+ node->next = NULL;
+
+ if (list->tail == NULL) {
+ list->head = node;
+ node->prev = NULL;
+ } else {
+ list->tail->next = node;
+ node->prev = list->tail;
+ }
+
+ list->tail = node
+ return 0;
+}
+
+void free_list(list_t* list) {
+ node_t* current = list->tail;
+
+ if (current == NULL) {
+ free(list);
+ return;
+ }
+
+ while (current->prev != NULL) {
+ current = current->prev;
+ free(current->next);
+ }
+
+ free(current);
+ free(list);
+}
+\end{lstlisting}
+Vous devez implémenter la fonction delete dont les spécifications vous sont fournies.\\
+Insérez ici le corps de la fonction delete dont les spécifications vous sont données ci-dessous :
+
+\begin{solution}
+\begin{lstlisting}[escapechar=µ]
+if(list == NULL){
+ return 0;
+}
+
+if(list->tail == NULL && list->head == NULL){
+ return 0;
+}
+
+node_t* current = list->head; node_t* prev = current;
+
+// Check if the list is made of 1 element
+if(current->next == NULL){
+ if(current->key == key){
+ free_list(list); // Free the whole list
+ return key;
+ }else{
+ return 0;
+ }
+}
+
+while(current != NULL){
+ if(current->key == key){
+ if(current->prev == NULL){ // If we remove the head of the list
+ printf("We are removing a head\n");
+ list->head = current->next;
+ current->next->prev = NULL;
+ free(current); // Because we used malloc to create a node
+ return key;
+ }
+ if(current->next == NULL){ // If we remove the tail of the list
+ list->tail = current->prev;
+ current->prev->next = NULL;
+ free(current);
+ return key;
+ }
+
+ prev->next = current->next;
+ current->next->prev = prev;
+
+ free(current);
+
+ return key;
+ }
+
+ prev = current;
+ current = current->next;
+}
+
+return 0;
+\end{lstlisting}
+\end{solution}
+
+\section{Copie de fichier}
+Ecrivez une fonction permettant de copier un fichier quelconque. Votre fonction ne peut bien entendu pas modifier le fichier source.\\
+
+Vous pouvez uniquement utiliser les fonctions open(2), mmap(2), munmap(2), msync(2), ftruncate(3), fstat(2), memcpy(3) and close(2). Vous ne pouvez appeler memcpy(3) qu'une seule fois.\\
+
+Astuce : msync(2) est une fonction qui vous permet de garantir que les modifications faites en mémoire (notamment celles à une adresse pointée par mmap) seront aussi sauvées sur disque. Lisez la documentation pour voir comment l'utiliser correctement.\\
+
+Astuce : La fonction ftruncate(3) est une fonction que l'on utilise assez rarement, mais elle est nécessaire pour cette question.
+
+\begin{lstlisting}[escapechar=µ]
+/*
+ * @pre file_name != NULL, nom du fichier source
+ * new_file_name != NULL, nom du fichier destination (la copie)
+ *
+ * @post copie le contenu de {file_name} vers {new_file_name}.
+ * return 0 si la fonction se termine avec succµ\textcolor{gray}{è}µs, -1 en cas d'erreur.
+ */
+int copy(char *file_name, char *new_file_name) {
+\end{lstlisting}
+
+\begin{solution}
+J'ai eu 90.91\% mais une version un peu différente existe dans le syllabus de théorie à la partie gestion des utilisateurs et des systèmes de fichiers. Mon erreur serait une erreur avec les fichiers vide.
+\begin{lstlisting}[escapechar=µ]
+if(file_name == NULL || new_file_name == NULL){
+ return -1;
+}
+
+int fdOld = open(file_name, O_RDONLY);
+if(fdOld == -1){
+ return -1;
+}
+
+struct stat* buffStatOld = (struct stat*) malloc(sizeof(struct stat));
+if(buffStatOld == NULL){
+ close(fdOld);
+ return -1;
+}
+
+if(fstat(fdOld, buffStatOld)){
+ free(buffStatOld); close(fdOld);
+ return -1;
+}
+
+if(buffStatOld->st_size == 0){ // If the file is empty
+ return 0;
+}
+
+int fdNew = open(new_file_name, buffStatOld->st_mode | O_CREAT | O_RDWR);
+// we have all the permission from the other files + we can create a new file if needed and we can write
+if(fdNew == -1){
+ free(buffStatOld); close(fdOld);
+ return -1;
+}
+
+void* oldMap = mmap(NULL, buffStatOld->st_size, PROT_READ, MAP_SHARED, fdOld, 0);
+if(oldMap == MAP_FAILED){
+ free(buffStatOld); close(fdOld); close(fdNew);
+ return -1;
+}
+
+if(ftruncate(fdNew, buffStatOld->st_size)){
+ free(buffStatOld); close(fdOld); close(fdNew);
+ return -1;
+}
+
+void* newMap = mmap(NULL, buffStatOld->st_size, PROT_READ | PROT_WRITE, MAP_SHARED, fdNew, 0);
+if(newMap == MAP_FAILED){
+ free(buffStatOld); close(fdOld); close(fdNew);
+ munmap(oldMap, buffStatOld->st_size);
+ return -1;
+}
+
+// The actual interesting code
+if(memcpy(newMap, oldMap, buffStatOld->st_size) == NULL){ // We copy the file in memory from the old to the new and check if it fails
+ free(buffStatOld); close(fdOld); close(fdNew);
+ munmap(oldMap, buffStatOld->st_size); munmap(newMap, buffStatOld->st_size);
+ return -1;
+}
+
+if(msync(newMap, buffStatOld->st_size, MS_SYNC)){ // MS_SYNC can slow down the program but it's a small trade off and we check if the syncing fails
+ free(buffStatOld); close(fdOld); close(fdNew);
+ munmap(oldMap, buffStatOld->st_size); munmap(newMap, buffStatOld->st_size);
+ return -1;
+}
+// The end of it TT
+
+if(munmap(oldMap, buffStatOld->st_size)){
+ free(buffStatOld); close(fdOld); close(fdNew);
+ munmap(newMap, buffStatOld->st_size);
+ return -1;
+}
+
+
+if(munmap(newMap, buffStatOld->st_size)){
+ free(buffStatOld); close(fdOld); close(fdNew);
+ return -1;
+}
+
+if(close(fdNew)){
+ free(buffStatOld); close(fdOld);
+ return -1;
+}
+
+if(close(fdOld)){
+ free(buffStatOld);
+ return -1;
+}
+
+free(buffStatOld);
+return 0;
+\end{lstlisting}
+\end{solution}
+
+\section{Comparaison de fonctions}
+Parfois il est intéressant de comparer le résultat de fonctions sans nécessairement savoir quel est le code de ces fonctions. Dans cet exercice, vous devez écrire une fonction compare qui reçoit comme arguments un intervalle fermé et deux pointeurs vers des fonctions qui retournent chacune un entier.\\
+
+Pour illustrer cette fonction compare, considérons les fonctions identite et abs:
+
+\begin{lstlisting}[escapechar=µ]
+int identite(int x) { return x; }
+int abs(int x) {
+ if (x>=0)
+ return x;
+ else
+ return -x;
+}
+\end{lstlisting}
+
+Dans l'intervalle $[0,2]$ $(min=0, max=2)$, compare retourne la valeur 3 lorsque elle est appliquée aux fonctions identité et abs. Dans l'intervalle $[-1,1]$ $(min=-1, max=1)$, elle retourne $2$ lorsqu'elle est appliquée aux mêmes fonctions.\\
+
+Proposez le corps de la fonction compare dont la spécification est reprise ci-dessous:
+\begin{lstlisting}[escapechar=µ]
+/*
+ * @pre min