pieuvre/lam.ml
2024-04-16 10:40:50 +02:00

41 lines
1.2 KiB
OCaml

type id = string
type ty_annot = id * Types.ty
type lam =
Fun of ty_annot * lam
| App of lam * lam
| Var of id
| Exf of lam * Types.ty
(** alpha renaming in a deterministic way *)
let alpha_convert (e : lam) : lam =
let cpt_var = ref 0 in (* id cpt for variables *)
let generator (cpt : int ref) : id = (* id generator *)
let v = "__"^(string_of_int !cpt)
in incr cpt; v
in let renamed = ref []
in let new_ren_var (cpt : int ref) (var : id) : id = (* checks if a variable already has a new id, or generates one *)
let var' = generator cpt in (
renamed := (var, var')::!renamed;
var'
)
in let get_ren_var (var : id) : id = (* returns var if not found *)
match List.assoc_opt var !renamed with
| Some var' -> var'
| None -> var
in let rec alpha_aux (e : lam) : lam = match e with (* actual renaming *)
Fun ((v, t), e) -> Fun ((new_ren_var cpt_var v, t), alpha_aux e)
| App (e1, e2) -> App (alpha_aux e1, alpha_aux e2)
| Var v -> Var (get_ren_var v)
| Exf (e, t) -> Exf (alpha_aux e, t)
in alpha_aux e
(** alpha equivalence *)
let (=~) (e1 : lam) (e2 : lam) : bool =
alpha_convert e1 = alpha_convert e2