Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • programmation-fonctionnelle/lifpf
  • p2208151/lifpf
  • p2402635/lifpf
  • p2103541/lifpf
  • p2105194/lifpf
  • p2210488/lifpf
  • p2212652/lifpf
  • p2019985/lifpf
  • p2208660/lifpf
  • p2102825/lifpf
  • p2002599/lifpf
  • p2106670/lifpf
  • p2103270/lifpf
  • p2210897/lifpf-demo
  • p2110686/lifpf-aysoy
  • p2110638/lifpf
  • p2202556/lifpf
17 results
Show changes
Commits on Source (74)
Showing with 450 additions and 18 deletions
profile = default
margin = 80
\ No newline at end of file
......@@ -10,8 +10,28 @@ export OPAMROOT=/home/tpetu/Enseignants/emmanuel.coquery/opam
test -r /home/tpetu/Enseignants/emmanuel.coquery/opam/opam-init/init.sh && . /home/tpetu/Enseignants/emmanuel.coquery/opam/opam-init/init.sh > /dev/null 2> /dev/null || true
```
On utilisera VSCode en installant le plugin **OCaml Platform**
> Sur une machine personnelle, installer ocaml et opam via les paquets, par exemple sous ubuntu:
>
> ```shell
> sudo apt install ocaml opam
> ```
>
> sous Mac OS X avec Homebrew:
>
> ```shell
> brew install ocaml opam
> ```
>
> Dans un shell, lancer les commandes suivantes:
>
> ```shell
> opam init
> # Suivre s'il faut les instructions de configuration de l'environnement
> opam install ocaml-lsp-server
> ```
On utilisera VSCode en installant le plugin **OCaml Platform**.
Pour supprimer les lignes verticales d'indentation qui peuvent perturber al'affichage avec les `|` des `match`: aller dans le menu File -> Preferences -> Settings, entrer `editor.guide` dans la zone de recherche et décocher la case "Editor > Guides: Indentation". Vérifiez que vous êtes bien dans l'onglet "User" quand vous décochez la case. Voir le screenshot ci-dessous:
![](files/config_lignes_vscode.png)
![config vs code](files/config_lignes_vscode.png)
# UE LIFPF INF2030L Programmation Fonctionnelle
## Semestre 2023 Printemps
[Configuration pour la salle de TP](CONFIGURATION.md)
| jour | heure | type | supports / remarques |
| ----- | ------------- | -------- | ---------------------------------------------------------------------------------- |
| 16/01 | 8h | CM | [Diapositives](cm/lifpf-cm1.pdf) |
| | 9h45 | TD | [Sujet](td/lifpf-td1-enonce.pdf), [corrige](tp/tp1.ml) <br> Groupes B et E à 11h30 |
| 23/01 | 8h | CM | [Diapositives](cm/lifpf-cm2.pdf), [Script démos](cm/cm2-demo.md) |
| | 9h45 ou 11h30 | TP | [Sujet](tp/tp1.md) <br> Groupe de TP, horaire et salle sur [tomuss] |
| 30/01 | 8h | TD + QCM | [Sujet](td/lifpf-td2-enonce.pdf) <br> Groupes A et F en salle Nautibus C1 |
| | 9h45 ou 11h30 | TP | [Sujet](tp/tp2.md) <br> Groupe de TP, horaire et salle sur [tomuss] |
| 20/02 | 8h | CM | [Diapositives](cm/lifpf-cm3.pdf) |
| | 9h45 ou 11h30 | TP | [Sujet](tp/tp3.md) <br> Groupe de TP, horaire et salle sur [tomuss] |
[tomuss]: https://tomuss.univ-lyon1.fr
## Semestre 2025 Printemps
- [Configuration pour la salle de TP](CONFIGURATION.md)
- [Rappels git et gitlab](gitlab.md)
- [Questions sur le cours](https://forge.univ-lyon1.fr/programmation-fonctionnelle/lifpf/-/issues/?sort=updated_desc&state=all&label_name%5B%5D=Question)
(2024) indique qu'il s'agit des supports de l'an dernier qui sont à mettre à jour
| jour | heure | type | sujet | supports / remarques |
| ----- | ------------- | ---------- | --------------------------- | ------------------------------------------------------------------------------------------------- |
| 20/01 | 8h | CM1 | Intro & Lambda-Calcul | [Diapositives Intro](cm/lifpf-cm0.pdf), [Diapositives Cours](cm/lifpf-cm1.pdf) |
| | 9h45 | TD1 sauf B | Lambda-Calcul | [Sujet](td/lifpf-td1-enonce.pdf), [corrigé](td/lifpf-td1-correction.pdf) |
| | 11h30 | TD1 Grp B | | |
| 27/01 | 8h | CM2 | OCaml | [Diapositives](cm/lifpf-cm2.pdf), [Script démos](cm/cm2-demo.md) |
| | 9h45 ou 11h30 | TP1 | Prise en main | [Sujet](tp/tp1.md), [corrigé](tp/tp1.ml) |
| 03/02 | 8h | TD2 | Lambda-Calcul | [Sujet](td/lifpf-td2-enonce.pdf), [corrigé](td/lifpf-td2-correction.pdf) |
| | 9h45 ou 11h30 | TP2 | Listes | [Sujet](tp/tp2.md), [corrigé](tp/tp2.ml) |
| 10/02 | 8h | CM3 | Struct. ind. + types param. | [Diapositives](cm/lifpf-cm3.pdf) [code](cm/cm3-code.ml) |
| | 9h45 ou 11h30 | TP3 | Arbres | [Sujet](tp/tp3.md) [corrigé](tp/tp3.ml) |
| 17/02 | 8h | TD3 | Arbres | [Sujet](td/lifpf-td3-enonce.pdf), [corrigé](td/lifpf-td3-correction.pdf) |
| | 9h45 ou 11h30 | TP4 | Arbres génériques | [Sujet](tp/tp4.md), [corrigé](tp/tp4.ml) |
| 24/02 | 9h45 | Partiel | | Amphi et place communiqués dans tomuss, 1 feuille manuscrite recto/verso autorisée comme document |
| 10/03 | 8h | CM4 | Ordre sup. | [Diapositives](cm/lifpf-cm4.pdf) |
| | 9h45 | TD4 | Ordre sup. | [Sujet](td/lifpf-td4-enonce.pdf), [corrigé](td/lifpf-td4-correction.pdf) |
| 17/03 | 8h | CM5 | Modules | (2024) [Diapositives](cm/lifpf-cm5.pdf) |
| | 9h45 ou 11h30 | TP5 | Struct. gen. | [Sujet](tp/tp5.md) |
| 24/03 | 8h | TD5 | Ordre sup. | (2024) [Sujet](td/lifpf-td5-enonce.pdf) |
| | 9h45 ou 11h30 | TP6 | Transf. struct. | (2024) [Sujet](tp/tp6.md) |
| 31/03 | 9h45 ou 11h15 | TP7 | App. OCaml (à changer ?) | (2024) [Sujet](tp/tp7.md) |
| 07/04 | 8h | CM6 | Foncteurs | (2024) [Diapositives](cm/lifpf-cm6.pdf), [code](cm/cm6-code.ml) |
| | 9h45 | TD6 | Foncteurs | (2024) [Sujet](td/lifpf-td6-enonce.pdf) |
### Annales
- [Printemps 2023, session 1](annales/ccf-2023p-s1.pdf), [corrigé](annales/ccf-2023p-s1-corrige.ml)
### Évaluation
- en TP: 30%
- CC intermédiaire (partiel): 30%
- ECA: 40%
(* Listes et paires *)
(* Questions 1 & 2 *)
let rec map2 (f : 'a -> 'b -> 'c) (l1 : 'a list) (l2 : 'b list) :
'c list =
match (l1, l2) with
| [], _ -> []
| _, [] -> []
| x1 :: l1', x2 :: l2' -> f x1 x2 :: map2 f l1' l2'
(* Questions 3 & 4 *)
let rec zip (l1 : 'a list) (l2 : 'b list) : ('a * 'b) list =
match (l1, l2) with
| [], _ -> []
| _, [] -> []
| x1 :: l1', x2 :: l2' -> (x1, x2) :: zip l1' l2'
(* Questions 5 & 6 *)
let unzip (l : ('a * 'b) list) : 'a list * 'b list =
List.fold_right
(fun p pl -> (fst p :: fst pl, snd p :: snd pl))
l ([], [])
(* Question 7 *)
let map2 (f : 'a -> 'b -> 'c) (l1 : 'a list) (l2 : 'b list) :
'c list =
List.map (fun p -> f (fst p) (snd p)) (zip l1 l2)
(* Expressions booléennes *)
(* Question 8 *)
type boolexpr =
| Var of string
| Vrai
| Non of boolexpr
| Et of boolexpr * boolexpr
(* Questions 9 & 10 *)
let rec eval (env : (string * bool) list) (expr : boolexpr) :
bool option =
match expr with
| Var v -> List.assoc_opt v env
| Vrai -> Some true
| Non expr' -> (
match eval env expr' with
| None -> None
| Some b -> Some (not b))
| Et (expr1, expr2) -> (
match (eval env expr1, eval env expr2) with
| Some b1, Some b2 -> Some (b1 && b2)
| _, _ -> None)
(* Modules et arbres de recherche *)
(* Donné dans l'énoncé *)
module type Cmp = sig
type t
type cmp_t = Lt | Gt | Eq
val cmp : t -> t -> cmp_t
end
(* Question 11 *)
module type ENS_T = sig
type ens
type elt
val appartient : elt -> ens -> bool
val insere : elt -> ens -> ens
end
module ABR_T (M : Cmp) : ENS_T with type elt = M.t = struct
(* Question 12 *)
type ens = Vide | Noeud of (M.t * ens * ens)
type elt = M.t
(* Question 13 *)
let rec appartient v a =
match a with
| Vide -> false
| Noeud (v2, fg, fd) -> (
match M.cmp v v2 with
| Lt -> appartient v fg
| Gt -> appartient v fd
| Eq -> true)
(* Question 14 *)
let rec insere v a =
match a with
| Vide -> Noeud (v, Vide, Vide)
| Noeud (v2, fg, fd) -> (
match M.cmp v v2 with
| Lt -> Noeud (v2, insere v fg, fd)
| Gt -> Noeud (v2, fg, insere v fd)
| Eq -> a)
end
File added
type 'a arbre_bin_g =
| ABGVide
| ABGNoeud of 'a * 'a arbre_bin_g * 'a arbre_bin_g
(** Version naive du contenu d'un arbre binaire *)
let rec contenu_naif (arb : 'a arbre_bin_g) : 'a list =
match arb with
| ABGVide -> []
| ABGNoeud (e, fg, fd) -> contenu_naif fg @ (e :: contenu_naif fd)
let a1 = ABGNoeud (1, ABGVide, ABGVide)
let a2 = ABGNoeud (9, ABGVide, ABGVide)
let a3 = ABGNoeud (3, ABGVide, ABGVide)
let a4 = ABGNoeud (7, ABGVide, ABGVide)
let a5 = ABGNoeud (2, a1, a3)
let a6 = ABGNoeud (8, a4, a2)
let a7 = ABGNoeud (5, a5, a6);;
contenu_naif a7
(** [ajoute_contenu arb l] ajoute les élements de arb en tête des éléments de la
liste l *)
let rec ajoute_contenu (arb : 'a arbre_bin_g) (l : 'a list) : 'a list =
match arb with
| ABGVide -> l
| ABGNoeud (e, fg, fd) ->
let l_fd = ajoute_contenu fd l in
let l_e_fd = e :: l_fd in
ajoute_contenu fg l_e_fd
let contenu (arb : 'a arbre_bin_g) : 'a list = ajoute_contenu arb []
module AssocList = struct
type key = string
type 'a t = (string * 'a) list
let empty : 'a t = []
let put (k : key) (v : 'a) (a : 'a t) : 'a t = (k, v) :: a
let get : key -> 'a t -> 'a option = List.assoc_opt
let keys (a : 'a t) : key list =
List.fold_left
(fun acc (k, v) ->
if List.mem k acc then acc else k :: acc)
[] a
end
module type SAssoc = sig
type key
type 'a t
val empty : 'a t
val put : key -> 'a -> 'a t -> 'a t
val get : key -> 'a t -> 'a option
val keys : 'a t -> key list
end
module AssocTreePb : SAssoc = struct
type key = string
type 'a t = Vide | Noeud of (string * 'a * 'a t * 'a t)
let empty = Vide
let rec put k v a =
match a with
| Vide -> Noeud (k, v, Vide, Vide)
| Noeud (k', v', fg, fd) ->
if k = k' then Noeud (k, v, fg, fd)
else if k < k' then Noeud (k', v', put k v fg, fd)
else Noeud (k', v', fg, put k v fd)
let rec get k a =
match a with
| Vide -> None
| Noeud (k', v', fg, fd) ->
if k = k' then Some v'
else if k < k' then get k fg
else get k fd
let rec keys =
let rec aux a ks =
match a with
| Vide -> ks
| Noeud (k, _, fg, fd) -> k :: aux fg (aux fd ks)
in
fun a -> aux a []
end
let a = AssocTreePb.put "toto" 3 AssocTreePb.empty
module AssocTree : SAssoc with type key = string = struct
type key = string
type 'a t = Vide | Noeud of (string * 'a * 'a t * 'a t)
let empty = Vide
let rec put k v a =
match a with
| Vide -> Noeud (k, v, Vide, Vide)
| Noeud (k', v', fg, fd) ->
if k = k' then Noeud (k, v, fg, fd)
else if k < k' then Noeud (k', v', put k v fg, fd)
else Noeud (k', v', fg, put k v fd)
let rec get k a =
match a with
| Vide -> None
| Noeud (k', v', fg, fd) ->
if k = k' then Some v'
else if k < k' then get k fg
else get k fd
let rec keys =
let rec aux a ks =
match a with
| Vide -> ks
| Noeud (k, _, fg, fd) -> k :: aux fg (aux fd ks)
in
fun a -> aux a []
end
module Assoc : SAssoc with type key = string = AssocList
module Factures = struct
type facture = (int * float) Assoc.t
let ajoute (article : string) (quantite : int) (prix : float)
(f : facture) : facture =
match Assoc.get article f with
| None -> Assoc.put article (quantite, prix) f
| Some (q', _) -> Assoc.put article (quantite + q', prix) f
let string_of_item fact article =
match Assoc.get article fact with
| None -> ""
| Some (qte, px) ->
article ^ "(" ^ string_of_int qte ^ "): "
^ string_of_float px ^ "€"
let string_of_facture (f : facture) : string =
Assoc.keys f
|> List.map (string_of_item f)
|> List.fold_left (fun acc s -> acc ^ "\n" ^ s) ""
end
module Factures (Assoc : SAssoc with type key = string) = struct
type facture = (int * float) Assoc.t
let ajoute (article : string) (quantite : int) (prix : float)
(f : facture) : facture =
match Assoc.get article f with
| None -> Assoc.put article (quantite, prix) f
| Some (q', _) -> Assoc.put article (quantite + q', prix) f
let string_of_item fact article =
match Assoc.get article fact with
| None -> ""
| Some (qte, px) ->
article ^ "(" ^ string_of_int qte ^ "): "
^ string_of_float px ^ "€"
let string_of_facture (f : facture) : string =
Assoc.keys f
|> List.map (string_of_item f)
|> List.fold_left (fun acc s -> acc ^ "\n" ^ s) ""
end
module FacturesTree = Factures (AssocTree)
let _ =
FacturesTree.string_of_facture
(FacturesTree.ajoute "trombones" 100 0.01 AssocTree.empty)
File added
No preview for this file type
No preview for this file type
No preview for this file type
File added
File added
File added
files/gitlab-1-new-project.png

62.4 KiB

files/gitlab-2-blank-project.png

86.2 KiB

files/gitlab-3-cfg-project.png

147 KiB

files/gitlab-4-clone-url.png

127 KiB

files/vscode-1-src-ctl-view.png

29.4 KiB

# Rappels sur l'utilisation de git et Gitlab
## Site forge.univ-lyon1.fr
Le site https://forge.univ-lyon1.fr héberge une forge logicielle (Gitlab) qui permet d'héberger des projets, par exemple les TPs de LIFPF.
Il est possible de donner des droits à d'autres utilisateurs, par exemple pour travailler en binôme (dans un projet depuis le menu "Project information > Members").
## Créer un nouveau projet
Un fois connecté(e), il est possible de créer un nouveau projet (bouton bleu à droite).
![gitlab-1-new-project](files/gitlab-1-new-project.png)
Choisir de créer un projet vierge (blank project).
![gitlab-2-blank-project](files/gitlab-2-blank-project.png)
Donner un nom au projet, choisir un répertoire parent (typiquement votre nom d'utilisateur) et laisser cochée la case du README, puis lancer la création via le bouton "Create project".
![gitlab-3-cfg-project](files/gitlab-3-cfg-project.png)
## Récupérer un projet sur sa machine (clone)
Depuis le projet dans le navigateur, cliquer sur le menu du bouton "Clone" et copier l'URL de clone HTTPS.
![gitlab-4-clone-url](files/gitlab-4-clone-url.png)
Depuis le répertoire où on veut placer le dossier du projet, lancer la commande suivante en remplaçant `<url_du_projet>` par la valeur copiée depuis le navigateur:
```shell
git clone <url_du_projet>
```
Cela créée un répertoire ayant le nom du projet.
Certaines commandes `git`, en particulier `clone`, `pull`, `push` et `fetch`, demanderont probablement un login et un mot de passe. Ce sont ceux de votre compte Lyon 1.
## Synchroniser son travail
Remarque: lors de l'utilisation de VSCode, il est conseillé d'ouvrir le répertoire complet du projet et pas seulement un fichier (via la commande `code nom_du_répertoire` ou via le menu "_File > Open folder_").
Avant de commencer à travailler lancer la commande suivante dans le répertoire du projet:
```shell
git pull
```
Cette commande va répcupérer les dernière mise à jour de votre projet et les appliquer dans le répertoire du projet.
On peut alors commencer à travailler sur les fichiers.
Une fois que le travail stabilisé (par exemple à la fin d'une partie d'un TP), on peut _comiter_ les modifications.
Pour cela, on commence par identifier les fichiers à _comiter_, via la commande `git add`. On peut faire autant de git add que l'on souhaite. La commande git status permet de lister les modifications par rapport à la dernière version _comitée_ par exemple:
```shell
❯ git status
On branch main
Your branch is up to date with 'origin/main'.
Untracked files:
(use "git add <file>..." to include in what will be committed)
titi.ml
toto.ml
tutu.ml
nothing added to commit but untracked files present (use "git add" to track)
❯ git add titi.ml
❯ git add toto.ml tutu.ml
❯ git status
On branch main
Your branch is up to date with 'origin/main'.
Changes to be committed:
(use "git restore --staged <file>..." to unstage)
new file: titi.ml
new file: toto.ml
new file: tutu.ml
```
Une fois les modifications ajoutée, on peut lancer la commande `git commit` en indiquant un message:
```shell
❯ git commit -m "tp7: partie 1.2 terminée"
[main bfec856] tp7: partie 1.2 terminée
3 files changed, 0 insertions(+), 0 deletions(-)
create mode 100644 titi.ml
create mode 100644 toto.ml
create mode 100644 tutu.ml
```
**Attention**, les modification ne sont pas encore répercutées sur forge.univ-lyon1.fr. Pour le faire, il faut utiliser `git push`:
```shell
❯ git push
Enumerating objects: 4, done.
Counting objects: 100% (4/4), done.
Delta compression using up to 10 threads
Compressing objects: 100% (2/2), done.
Writing objects: 100% (3/3), 314 bytes | 314.00 KiB/s, done.
Total 3 (delta 0), reused 0 (delta 0), pack-reused 0
To https://forge.univ-lyon1.fr/EMMANUEL.COQUERY/lifpf-tp7.git
17d2e59..bfec856 main -> main
```
Remarque: VSCode intègre des outils graphiques (vue latérale) pour gérer les opérations `add`, `commit`, `pull` et `push`. Il permet également de voir les modifications apportées au fichiers et facilite la résolution des conflits (cf ci-dessous).
![vscode-1-src-ctl-view](files/vscode-1-src-ctl-view.png)
### Conflits
Lors d'un travail à plusieurs, il est possible que le dépôt ait été édité entre le premier `pull` et le `push`. Dans ce cas `git` refusera de faire le `push`. Il faut alors faire un `pull` pour intégrer les modifications distantes avant de faire le `push`.
Si `git` ne parvient pas à fusionner les modifications, il se peut qu'il génère des conflits, visibles via `git status`et dans VSCode (lettre C à côté du fichier).
Dans ce cas, il faut éditer le fichier et rectifier à la main son contenu.
On peut ouvrir la vue latérale `git` dans VSCode et cliquer sur le fichier pour voir les conflits. Pour chaque conflit, VSCode proposera de prendre une des deux version, voir les deux. Souvent, cela ne dispense pas d'aller éditer le code pour le rectifier.
Une fois les fichiers éditer, on les ajoute comme pour une modification usuelle.
Il suffit ensuite de _comiter_ et pousser (`push`) les modifications.