TP-programmation-fonctionnelle/BE/assocmem.ml
2023-06-21 20:13:54 +02:00

112 lines
3.2 KiB
OCaml
Executable file
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

open Util
open Mem
(*
get_assoc:
int -> (int * char) list -> char -> char
Description:
Retourne la valeur associée à la clef e dans la liste l,
ou la valeur fournie def si la clef nexiste pas.
Paramètres:
- e : la clé dont on cherche la valeur associée
- l : la liste que l'on va chercher
- def : élement par défaut si l'on ne trouve rien
Renvoie:
la valeur associée à la clé, ou def
Préconditions:
- True
Postconditions:
- True
Exceptions:
- None
*)
let rec get_assoc e l def =
match l with
| [] -> def
| (k,v)::q -> if k=e then v else (get_assoc e q def)
(* Tests unitaires *)
let liste_test = [ (0, 'a'); (1, 'b'); (2, 'c') ]
let%test _ = get_assoc 0 liste_test '0' = 'a'
let%test _ = get_assoc 1 liste_test '0' = 'b'
let%test _ = get_assoc 2 liste_test '0' = 'c'
let%test _ = get_assoc 3 liste_test '0' = '0'
(*
set_assoc:
int -> (int * char) list -> char -> (int * char) list
Description:
Remplace la valeur associée à la clef e dans la liste l par x,
ou ajoute le couple (e, x) si la clef nexiste pas déjà.
Paramètres:
- e : la clé dont on veut remplacer la valeur associée
- l : la liste que l'on va modifier
- x : nouvelle valeur associée à e
Renvoie:
La nouvelle liste modifiée
Préconditions:
- True
Postconditions:
- True
Exceptions:
- None
*)
let rec set_assoc e l x =
match l with
| [] -> l@[(e,x)]
| (k,v)::q -> if k=e then (k,x)::q else (k,v)::(set_assoc e q x)
(* Tests unitaires *)
let liste_test = [ (0, 'a'); (1, 'b'); (2, 'c') ]
let%test _ = set_assoc 0 liste_test 'd' = [ (0, 'd'); (1, 'b'); (2, 'c') ]
let%test _ = set_assoc 1 liste_test 'e' = [ (0, 'a'); (1, 'e'); (2, 'c') ]
let%test _ = set_assoc 2 liste_test 'f' = [ (0, 'a'); (1, 'b'); (2, 'f') ]
let%test _ = set_assoc 3 liste_test 'g' = [ (0, 'a'); (1, 'b'); (2, 'c'); (3, 'g') ]
module AssocMemory : Memory =
struct
(* Type = liste qui associe des adresses (entiers) à des valeurs (caractères) *)
type mem_type = (int * char) list
(* Un type qui contient la mémoire + la taille de son bus d'adressage *)
type mem = int * mem_type
(* Nom de l'implémentation *)
let name = "assoc"
(* Taille du bus d'adressage *)
let bussize (bs, _) = bs
(* Taille maximale de la mémoire *)
let size (bs, _) = pow2 bs
(* Taille de la mémoire en mémoire *)
let allocsize (_, m) =
List.fold_right (fun _ res_q -> 1 + res_q) m 0
(* Nombre de cases utilisées *)
let busyness (_, m) =
List.fold_right (
fun (_,v) res_q -> if v != _0 then 1 + res_q else res_q
) m 0
(* Construire une mémoire vide *)
let clear bs = (bs, [])
(* Lire une valeur *)
let read (bs, m) addr =
if addr > (size (bs, m)) then
raise OutOfBound
else
match (get_assoc addr m _0) with
| v -> v
(* Écrire une valeur *)
let write (bs, m) addr x =
if addr > (size (bs, m)) then
raise OutOfBound
else
(bs, (set_assoc addr m x))
end