Skip to content

Commit

Permalink
Update
Browse files Browse the repository at this point in the history
  • Loading branch information
fortierq committed Sep 28, 2024
1 parent fb16223 commit 7fbd59d
Show file tree
Hide file tree
Showing 9 changed files with 277 additions and 4 deletions.
10 changes: 9 additions & 1 deletion blog/2024-09-11-colle1.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ authors: qfortier
tags: [colle]
---

Voici la liste des compétences à avoir pour votre première colle. La colle est constituée d'un ou plusieurs exercices.
Voici la liste des compétences et connaissances à avoir pour votre première colle. La colle est constituée d'un ou plusieurs exercices.

Langages :
- Définitions et opérations sur les mots et langages
Expand All @@ -26,3 +26,11 @@ Automates :
- Stabilité des langages reconnaissables par complémentaire, intersection, union, différence. Automate produit.
- États accessibles et co-accessibles. Automate émondé. Tout automate est équivalent à un automate émondé.
- Lemme de l'étoile, avec démonstration et application pour montrer qu'un langage n'est pas reconnaissable.

Théorème de Kleene :
- Langage local, expression régulière linéaire.
- Algorithme de Berry-Sethi pour construire un automate (de Glushkov) à partir d'une expression régulière.
- $\epsilon$-transitions. Tout automate avec des $\epsilon$-transitions est équivalent à un automate sans $\epsilon$-transition.
- Automate de Thompson (construit récursivement) à partir d'une expression régulière.
- Méthode d'élimination des états pour obtenir une expression régulière à partir d'un automate.
- Théorème de Kleene et conséquences.
Binary file modified docs/langages/2_automate/td_automate_cor.pdf
Binary file not shown.
11 changes: 11 additions & 0 deletions docs/langages/3_kleene/4_td_kleene.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
---
hide_table_of_contents: true
hide_title: true
title: "TD Automates"
pdf: "td_kleene"
---
import Button from '@site/src/components/Button';

<Button
pdf={require(`./${frontMatter.pdf}.pdf`).default}
/>
10 changes: 10 additions & 0 deletions docs/langages/3_kleene/5_poly_kleene.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
---
hide_table_of_contents: true
hide_title: true
title: "Résumé de cours"
pdf: "poly_kleene"
---

import Pdf from '@site/src/components/Pdf';

<Pdf pdf={require(`./${frontMatter.pdf}.pdf`).default} td={true} />
Binary file added docs/langages/3_kleene/poly_kleene.pdf
Binary file not shown.
Binary file added docs/langages/3_kleene/td_kleene.pdf
Binary file not shown.
7 changes: 4 additions & 3 deletions docs/tp/2_tp2/2_tp2.mdx
Original file line number Diff line number Diff line change
@@ -1,19 +1,20 @@
---
hide_table_of_contents: false
hide_title: false
cor: false
cor: true
title: "TP 2 : Automates"
---
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
import Solution from '@site/src/components/Solution';
import Tp2 from '!!raw-loader!./tp2.ml';

Ce TP est à effectuer en OCaml, sous Visual Code. Vous pouvez utiliser le [Codespace GitHub](../0_codespace.md) ou votre ordinateur personnel.
Si vous avez une boucle infinie (le terminal qui ne répond pas) : Ctrl + C

On pourra créer un fichier `tp2.ml`. Pour exécuter : sélectionner les lignes OCaml et appuyer sur Shift + Entrée. Ceci envoie le code sélectionné dans le terminal (utop). Vous pouvez aussi utiliser utop en mode interactif.
On utilisera `;;` à la fin de chaque fonction pour envoyer correctement le code sur utop.

<Solution file={Tp2} lang='ocaml' show={frontMatter.cor} />

{/*## Automate
1. Créer un fichier `tp2.ml` avec le type suivant d'automate non-déterministe.
Expand Down
140 changes: 140 additions & 0 deletions docs/tp/2_tp2/tp2.ml
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
(* type automate = {
initiaux : int list;
finaux : int list;
transitions : (int * char * int) list
}
(* 2 *)
let a1 = {
initiaux = [0];
finaux = [1];
transitions = [(0, 'b', 0); (0, 'a', 1); (1, 'a', 0); (1, 'b', 1)]
}
let a2 = {
initiaux = [0];
finaux = [2];
transitions = [(0, 'a', 0); (0, 'b', 1); (1, 'a', 0); (1, 'a', 2); (2, 'b', 2)]
}
(* 3 *)
let miroir a =
let rec aux = function
| [] -> []
| (e, l, e2)::q -> (e2, l, e)::aux q
in {initiaux = a.finaux; finaux = a.initiaux; transitions = aux a.transitions};;
miroir a1
(* 4 *)
let est_deterministe a =
let rec aux = function
| [] -> true
| (q1, a, q2)::t ->
let rec aux2 = function
| [] -> aux q
| (q1', a', q2')::t' -> if q1 = q1' && a = a' then false else aux2 t'
in aux2 q
in List.length a.initiaux = 1 && aux a.transitions;;
est_deterministe a1;;
est_deterministe a2;; *)

(* 1 *)
type afdc = {
initial : int;
finaux : int list;
delta : int array array
}
let a1 = {
initial = 0;
finaux = [1];
delta = [|[|1; 0|]; [|0; 1|]|]
}
let a2 = {
initial = 0;
finaux = [2];
delta = [|[|0; 1|]; [|1; 2|]; [|2; 0|]|]
}

(* 2 *)
let rec delta_etoile a q u = match u with
| [] -> q
| t::q2 -> delta_etoile a (a.delta.(q).(t)) q2;;

delta_etoile a1 a1.initial [0; 1];;

(* 3 *)
let accepte a u =
List.mem (delta_etoile a a.initial u) a.finaux;;

accepte a1 [0; 1];;
accepte a1 [1; 0; 0];;

(* 4 *)
let complementaire a =
let rec aux n =
if n = -1 then []
else if List.mem n a.finaux then aux (n - 1)
else n::aux (n - 1) in
{initial = a.initial; finaux = aux (Array.length a.delta - 1); delta = a.delta};;
complementaire a1;;

(* 5 *)
let accessibles a =
let vus = Array.make (Array.length a.delta) false in
let rec aux q =
vus.(q) <- true;
for i = 0 to Array.length a.delta.(q) - 1 do
if not vus.(a.delta.(q).(i)) then aux a.delta.(q).(i)
done in
aux a.initial;
let rec aux2 n =
if n = -1 then []
else if vus.(n) then n::aux2 (n - 1)
else aux2 (n - 1) in
aux2 (Array.length a.delta - 1);;
accessibles a1;;

let a3 = {
initial = 0;
finaux = [2];
delta = [|[|1; 0; 0|]; [|0; 1; 0|]; [|1; 0; 2|]|]
};;
accessibles a3;; (* 3 n'est pas accessible *)

(* 6 *)
let vide a =
List.exists (fun q -> List.mem q a.finaux) (accessibles a);;

(* 7 *)
let inter a b =
let n = Array.length a.delta in
let p = Array.length b.delta in
let s = Array.length a.delta.(0) in
let d = Array.make_matrix (n*p) s (-1) in
for i = 0 to n - 1 do
for j = 0 to p - 1 do
for k = 0 to s - 1 do
d.(i*p + j).(k) <- a.delta.(i).(k)*p + b.delta.(j).(k)
done
done
done;
let rec finaux l1 l2 = match l1, l2 with
| [], _ -> []
| _, [] -> []
| i::q, j::q' -> (i*p + j)::(finaux q l2)@(finaux [i] q') in
{initial = a.initial*p + b.initial; finaux = finaux a.finaux b.finaux; delta = d};;

let a3 = inter a1 a2;;
accepte a3 [0; 1; 0; 0; 1];;
accepte a3 [0; 1; 1; 0; 0; 1];;
accepte a3 [1; 0; 0; 1];;

(* 8 *)
(* A est inclus dans B ssi A inter (complémentaire de B) est vide *)
let inclus a b =
vide (inter a (complementaire b));;

(* 9 *)
let equivalent a b =
inclus a b && inclus b a;;
103 changes: 103 additions & 0 deletions docs/tp/3_tp3/3_tp3.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
{/* % \section{Calcul des ensembles $P(L)$, $S(L)$, $F(L)$}
% Soit $L$ un langage. On rappelle les définitions du cours :
% \begin{itemize}
% \item $P(L)$ = $\s{a \in \Sigma \tq a\Sigma^*\cap L \neq \emptyset}$ (premières lettres des mots de L)
% \item $S(L) = \s{a \in \Sigma \tq \Sigma^* a \cap L \neq \emptyset}$ (dernières lettres des mots de L)
% \item $F(L) = \s{u \in \Sigma^2 \tq \Sigma^* u \Sigma^* \cap L \neq \emptyset}$ (fs de longueur 2 des mots de L)
% % \item $N(L) = \Sigma^2 \backslash F(L)$ %(les mots de longueur 2 qui ne sont pas f d'un mot de $L$).
% \end{itemize}
% Dans la suite, on utilise le type suivant d'expression régulière : \begin{center}
% \begin{code}{ocaml}
% type 'a regexp =
% | Vide | Epsilon | L of 'a
% | Union of 'a regexp * 'a regexp
% | Concat of 'a regexp * 'a regexp
% | Etoile of 'a regexp
% \end{code}
% \end{center}
% \begin{enumerate}
% \item Écrire une fonction \ocaml{has_eps : 'a regexp -> bool} déterminant si le langage d'une expression régulière contient $\epsilon$.
% \if\cor1\\
% \begin{emphase}
% \underline{Solution} : \begin{center}
% \begin{code}{ocaml}
% let rec has_eps = function
% | Vide | L _ -> false
% | Epsilon | Etoile _ -> true
% | Union (e1, e2) -> has_eps e1 || has_eps e2
% | Concat (e1, e2) -> has_eps e1 && has_eps e2
% \end{code}
% \end{center}
% \end{emphase}
% \fi
% \item Écrire une fonction \ocaml{union : 'a list -> 'a list -> 'a list} telle que, si \ocaml{l1} et \ocaml{l2} sont des listes sans doublon (ce qu'on suppose être le cas...), \ocaml{union l1 l2} renvoie une liste sans doublon contenant les éléments des deux listes. Par exemple, \ocaml{union [1; 2] [3; 1]} peut renvoyer \ocaml{[1; 2; 3]} (l'ordre des éléments de la liste de retour n'importe pas).
% \if\cor1\\
% \begin{emphase}
% \underline{Solution} : \begin{center}
% \begin{code}{ocaml}
% let rec union l1 l2 = match l1 with
% | [] -> l2
% | a::q1 -> if List.mem a l2 then union q1 l2 else a::(union q1 l2)
% \end{code}
% \end{center}
% \end{emphase}
% \fi
% \item Écrire une fonction \ocaml{p} de type \ocaml{'a regexp -> 'a list} telle que \ocaml{p e} renvoie $P(L($\ocaml{e}$))$.
% \if\cor1\\
% \begin{emphase}
% \underline{Solution} : \begin{center}
% \begin{code}{ocaml}
% let rec p = function
% | Vide | Epsilon -> []
% | L a -> [a]
% | Union (e1, e2) -> union (p e1) (p e2)
% | Concat (e1, e2) -> if has_eps e1 then union (p e1) (p e2) else p e1
% | Etoile e -> p e
% \end{code}
% \end{center}
% \end{emphase}
% \fi
% \item Que faudrait-il modifier à \ocaml{p} pour obtenir une fonction \ocaml{s} renvoyant $S(L)$?
% \if\cor1\\
% \begin{emphase}
% \underline{Solution} : Échanger \ocaml{e1} et \ocaml{e2} dans \ocaml{Concat(e1, e2) -> ...}
% \end{emphase}
% \fi
% \item Écrire une fonction \ocaml{produit : 'a list -> 'b list -> ('a * 'b) list} effectuant le produit cartésien de 2 listes : si \ocaml{l1} et \ocaml{l2} sont des listes, \ocaml{produit l1 l2} renvoie une liste de tous les couples distincts composés d'un élément de \ocaml{l1} et un élément de \ocaml{l2}. Par exemple, \ocaml{produit [1; 2] [3; 1]} peut renvoyer \\
% \ocaml{[(1, 3); (1, 1); (2, 3); (2; 1)]} (l'ordre des éléments de la liste de retour n'importe pas).
% \if\cor1\\
% \begin{emphase}
% \underline{Solution} : Avec \ocaml{List.map} :\begin{center}
% \begin{code}{ocaml}
% let rec produit l1 l2 = match l1 with
% | [] -> []
% | a::q1 -> List.map (fun b -> (a, b)) l2 @ produit q1 l2
% \end{code}
% \end{center}
% Sans \ocaml{List.map} :\begin{center}
% \begin{code}{ocaml}
% let rec produit l1 l2 = match l1 with
% | [] -> []
% | a::q1 -> let rec aux l2 = match l2 with
% | [] -> []
% | b::q2 -> (a, b)::aux q2
% in aux l2 @ produit q1 l2
% \end{code}
% \end{center}
% \end{emphase}
% \fi
% \item En déduire une fonction \ocaml{f} de type \ocaml{'a regexp -> ('a * 'a) list} telle que \ocaml{f e} renvoie $F(L($\ocaml{e}$))$.
% \if\cor1\\
% \begin{emphase}
% \underline{Solution} : \begin{center}
% \begin{code}{ocaml}
% let rec f = function
% | Vide | Epsilon | L _ -> []
% | Union (e1, e2) -> union (f e1) (f e2)
% | Concat (e1, e2) -> union (f e1) (union (produit (s e1) (p e2)) (f e2))
% | Etoile e -> union (f e) (produit (s e) (p e))
% \end{code}
% \end{center}
% \end{emphase}
% \fi
% \end{enumerate} */}

0 comments on commit 7fbd59d

Please sign in to comment.