1
0
Fork 0
This repository has been archived on 2024-05-03. You can view files and clone it, but cannot push or open issues or pull requests.
unification-pfa/lib/inference.ml

33 lines
1.2 KiB
OCaml
Raw Normal View History

(** Infer the type of a given term and, if exists, returns the type of the term *)
let rec typeof = function
| Term.Var _ -> None
| Term.IntConst _ -> Some Type.Int
| Term.Binop (t1, _, t2) ->
(match typeof t1, typeof t2 with
| ty1, ty2 when ty1 = ty2 -> Some Type.Int
| _ -> None)
| Term.Pair (t1, t2) ->
(* Pair give Products *)
(match typeof t1, typeof t2 with
| Some ty1, Some ty2 -> Some (Type.Product (ty1, ty2))
| _ -> None)
| Term.Proj (proj, t) ->
(* Projections returns type of product based on the projection type *)
(match proj, typeof t with
| Term.First, Some (Type.Product (ty, _)) | Term.Second, Some (Type.Product (_, ty))
-> Some ty
| _, _ -> None)
| Term.Fun (id, t) ->
(match typeof t with
| Some body_type -> Some (Type.Arrow (Type.Int, body_type))
| None -> Some (Type.Var id))
| Term.App (t1, t2) ->
(match typeof t1, typeof t2 with
| Some (Type.Arrow (ty_arg, ty_res)), Some ty_arg' ->
(* Unification for application *)
(match Unification.unify ty_arg ty_arg' with
| Some subst -> Some (TypeSubstitution.apply subst ty_res)
| None -> None)
| _ -> None)
;;