Implementación O`Caml del Sistema de Tipos para el

Anuncio
Implementación O’Caml del Sistema de Tipos
para el λ-Cálculo con booleanos
Programación Funcional
1.
Representación de Tipos y Expresiones
type variable = string;;
type booleano = F | V;;
type tipo = Bool
| Flecha of tipo * tipo;;
type term =
|
|
|
|
2.
Cons
Var
Abs
App
Cnd
of
of
of
of
of
booleano
variable
variable * tipo * term
term * term
term * term * term;;
Pretty-printer de Tipos y Expresiones
let rec pretty_tipo = function
Bool
-> "Bool"
| Flecha (m,n) -> "(" ^ pretty_tipo m ^ " -> " ^ pretty_tipo n ^ ")";;
let rec pretty_term = function
Cons V
-> "true"
| Cons F
-> "false"
| Var x
-> x
| Abs (x,t,m) -> "(\\" ^ x ^ ":" ^ pretty_tipo t ^ "." ^ pretty_term m ^ ")"
| App (m,n)
-> "(" ^ pretty_term m ^ " " ^ pretty_term n ^ ")"
| Cnd (g,t,e) -> "(if " ^ pretty_term g ^ " then " ^ pretty_term t
^ " else " ^ pretty_term e ^ ")";;
1
3.
Representación de Contextos
type contexto = (variable * tipo) list;;
let contexto_vacio = [];;
let aniade (v,t) contexto = (v,t) :: contexto;;
4.
Tipo de una Variable en un Contexto
exception No_ligada of string;;
let rec tipo_de_variable contexto x =
match contexto with
(y,t)::_ when x=y -> t
| _ :: contexto’
-> tipo_de_variable contexto’ x
| _
-> raise (No_ligada x);;
5.
Algoritmo de Tipado
exception Type_error of string;;
let rec tipar contexto = function
Cons _
-> Bool
| Var x
-> tipo_de_variable contexto x
| App (f,x) ->
let t1 = tipar contexto f
and t2 = tipar contexto x
in (match t1 with
Flecha(t,s) when t=t2 -> s
| Flecha(t,s)
->
raise (Type_error ("El tipo de " ^ pretty_term x ^ " es " ^
pretty_tipo t2 ^ " y no concuerda con " ^
pretty_tipo t))
| _
-> raise (Type_error (pretty_term f ^ ": " ^
pretty_tipo t1 ^
" no es una función")))
| Abs (x,t,m) -> Flecha (t, tipar (aniade (x,t) contexto) m)
| Cnd (g,t,e) ->
match (tipar contexto g) with
Bool -> let t1 = tipar contexto t
2
and t2 = tipar contexto e
in if t1 = t2
then t1
else raise (Type_error ("La rama then tiene tipo " ^
pretty_tipo t1 ^
" mientras que la rama else es " ^
pretty_tipo t2 ^
" en " ^ pretty_term (Cnd(g,t,e))))
| nobool -> raise (Type_error ("La guardia de " ^
pretty_term (Cnd(g,t,e)) ^
" no es booleana, sino de tipo " ^
pretty_tipo nobool));;
6.
Ejemplos de Expresiones
let e1 = Abs ("x", Bool, Cnd (Var "x", Cons F, Cons V));;
let e2 = Abs ("x", Bool,
Abs ("y", Bool,
Cnd (Var "x", Var "y", Cons F)));;
let e3 = Abs ("f", Flecha(Bool,Bool),
Abs("x", Bool,
App(Var "f", App(Var "f", Var "x"))));;
let e4 = App (Var "f", Cons V);;
let e5 = App( Abs( "f", Flecha(Bool,Bool),
App (Var "f", Cons F)), Cons V);;
let e6 = App (Cons V, Cons F);;
let e7 = Cnd (Abs ("x",Bool,Var "x"), Cons V, Cons F);;
let e8 = Cnd (Cons V, Cons F, Abs("x", Bool, Var "x"));;
7.
Tipado de los Ejemplos
# pretty_tipo (tipar contexto_vacio e1);;
- : string = "(Bool -> Bool)"
3
# pretty_tipo (tipar contexto_vacio e2);;
- : string = "(Bool -> (Bool -> Bool))"
# pretty_tipo (tipar contexto_vacio e3);;
- : string = "((Bool -> Bool) -> (Bool -> Bool))"
# pretty_tipo (tipar contexto_vacio e4);;
Uncaught exception: No_ligada("f")
# pretty_tipo (tipar contexto_vacio e5);;
Uncaught exception: Type_error("El tipo de true es Bool y no concuerda
con (Bool -> Bool)")
# pretty_tipo (tipar contexto_vacio e6);;
Uncaught exception: Type_error("true: Bool no es una función")
# pretty_tipo (tipar contexto_vacio e7);;
Uncaught exception: Type_error("La guardia de (if (\\x:Bool.x) then true
else false) no es booleana, sino de tipo (Bool -> Bool)")
# pretty_tipo (tipar contexto_vacio e8);;
Uncaught exception: Type_error("La rama then tiene tipo Bool mientras que
la rama else es (Bool -> Bool) en (if true then false else (\\x:Bool.x))")
4
Descargar