# R. G. - Type des expressions arithmétiques (`+, -, /, *`) - Fonction pour les évaluer ```ocaml= type bin_op = | Add | Sub | Mul | Div type 'a expr = | Bin_op of bin_op * expr * expr | Value of 'a | Var of string let rec eval var_tbl bin_op_f = function | Value n -> Ok n | Var var -> begin match Hashtbl.find_opt var_tbl var with | Some n -> Ok n | None -> Error (Printf.sprintf "Variable %s not defined" var) end | Bin_op (bin_op, e1, e2) -> let op = bin_op_f bin_op in match eval e1 with | Error _ as err -> err | Ok res1 -> match eval e2 with | Error _ as err -> err | Ok res2 -> match op res1 res2 with | exception Divide_by_zero -> Error "Div zero" | res -> Ok res let rec eval var_tbl bin_op_f = function | Value n -> Value n | Var var -> begin match Hashtbl.find_opt var_tbl var with | Some n -> Value n | None -> Var var end | Bin_op (Mul, e1, e2) -> begin match e1, e2 with | Value n1, Value n2 -> Value (n1 * n2) | Var _ as var, Value _ as value | Value _ as value, Var _ as var -> Bin_op (value, var) | Value _ as value, Bin_op (Add, e1, e2) | Bin_op (Add, e1, e2), Value _ as value -> let e1 = Bin_op (Mul, value, e1) in let e2 = Bin_op (Mul, value, e2) in eval (Bin_op (Add, e1, e2)) end | Bin_op (bin_op, e1, e2) -> let op = bin_op_f bin_op in match eval e1 with | Ok res1 -> match eval e2 with | Error _ as err -> err | Ok res2 -> match op res1 res2 with | exception Divide_by_zero -> Error "Div zero" | res -> Ok res (* n/p => pgcd 6x*x / 2 x = 3x x/(1 + x) t + t + t + t t ~ m * m * m * m 3x + ... + 4x = 7x (3x(y+1))/z *) (* SUM (n * v^k) (string, int * int) Hashtbl.t (expr, int) Hashtbl.t ((expr, int) Hashtbl.t, int) Hashtbl.t (int * (string * int) list) list 3x² + 6x² = 9x² 3x² - 3x² 0x² Sum (n_i * Mul (x_j ^ n_j)) (x, 3, 2) (x, 2, 1) (y, 3, 1) (_, 1, 0) 3x² + 2x + 3y + 1 *) (* 4(x + y) = 4x + 4y *) (* (x + 3) + 4 *) (* val pgcd: int -> int -> int *) type rat = R of int * int let simplify_rat (R (p, q)) = let pgcd = pgcd p q in R (p / pgcd, q / pgcd) let bin_op = function | Add -> fun (R (p1, q1)) (R (p2, q2)) -> let p1 = p1 * q2 in let q1 = q1 * q2 in let p2 = p2 * q1 in R (p1 + p2, q1) | Sub -> ... | Mul -> fun (R (p1, q1)) (R (p2, q2)) -> R (p1 * p2, q1 * q2) let bin_op rat = simplify_rat (bin_op rat) ```