TP-programmation-fonctionnelle/BE/assocmem.ml

112 lines
3.2 KiB
OCaml
Raw Normal View History

2023-06-21 18:13:54 +00:00
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