(* Source check.ml *)
open T
open Type
open Ast
exception Error of string
(* L'écriture du code est relativement mécanique, à partir des règles du cours *)
let rec check env t =
match t with
|
Num _ ->
Nat
|
Var x ->
begin
try List.
assoc x env with
|
Not_found ->
raise (
Error (
"Variable inconnue: "^
x))
(* Bonne idée de changer Not_found en une exception plus spécifique *)
end
|
Op (
_,
t1,
t2) ->
check_nat env t1 ;
(* Voir ci-après *)
check_nat env t2 ;
Nat
|
Ifz (
t1,
t2,
t3) ->
check_nat env t1 ;
let tt2 =
check env t2
and tt3 =
check env t3 in
if tt2 <>
tt3 then raise (
Error "Same") ;
tt3
|
Let (
x,
t1,
t2) ->
let ty1 =
check env t1 in
check ((
x,
ty1)::
env)
t2
|
App (
t1,
t2) ->
let ty1,
ty2 =
check_fun env t1
and ty3 =
check env t2 in
if ty1 <>
ty3 then raise (
Error "App") ;
ty2
|
Fun (
x,
tx,
t) ->
let ty =
check ((
x,
tx)::
env)
t in
Arrow (
tx,
ty)
|
Fix (
x,
tx,
t) ->
let ty =
check ((
x,
tx)::
env)
t in
if tx <>
ty then raise (
Error "Fix") ;
tx
(* Noter l'usage de fonctions auxiliaires pour traiter
les cas qui surviennent plusieurs fois *)
and check_nat env t =
match check env t with
|
Nat -> ()
|
_ ->
raise (
Error "Nat")
and check_fun env t =
match check env t with
|
Arrow (
ty1,
ty2) ->
ty1,
ty2
|
_ ->
raise (
Error "Arrow")
This document was translated from LATEX by
HEVEA.