typage du exfalso, etc
This commit is contained in:
parent
0b67d9a5eb
commit
bd6dedc074
2
Makefile
2
Makefile
@ -1,4 +1,4 @@
|
|||||||
pieuvre: main.ml expr.ml affichage.ml lexer.mll parser.mly
|
pieuvre: main.ml lam.ml affichage.ml lexer.mll parser.mly
|
||||||
dune build
|
dune build
|
||||||
cp _build/default/main.exe pieuvre
|
cp _build/default/main.exe pieuvre
|
||||||
chmod +w pieuvre
|
chmod +w pieuvre
|
||||||
|
19
affichage.ml
19
affichage.ml
@ -1,4 +1,4 @@
|
|||||||
open Expr
|
open Lam
|
||||||
open Types
|
open Types
|
||||||
|
|
||||||
(* fonction d'affichage *)
|
(* fonction d'affichage *)
|
||||||
@ -7,8 +7,8 @@ let rec string_of_ty = function
|
|||||||
| Arr(t1, t2) ->
|
| Arr(t1, t2) ->
|
||||||
let s1 = string_of_ty t1 in
|
let s1 = string_of_ty t1 in
|
||||||
let s2 = string_of_ty t2 in
|
let s2 = string_of_ty t2 in
|
||||||
s1 ^ " => (" ^ s2 ^ ")"
|
"(" ^ s1 ^ " -> " ^ s2 ^ ")"
|
||||||
| Bot -> "#"
|
| Bot -> "False"
|
||||||
|
|
||||||
let rec string_of_expr = function
|
let rec string_of_expr = function
|
||||||
Fun ((s, t), e) ->
|
Fun ((s, t), e) ->
|
||||||
@ -16,12 +16,19 @@ let rec string_of_expr = function
|
|||||||
let s_e = string_of_expr e in
|
let s_e = string_of_expr e in
|
||||||
"fun (" ^ s ^ " : " ^ s_ty ^ ") => (" ^ s_e ^ ")"
|
"fun (" ^ s ^ " : " ^ s_ty ^ ") => (" ^ s_e ^ ")"
|
||||||
| App (e1, e2) ->
|
| App (e1, e2) ->
|
||||||
"("^(string_of_expr e1)^") "^(string_of_expr e2)
|
"("^(string_of_expr e1)^" "^(string_of_expr e2)^")"
|
||||||
| Var (s) -> s
|
| Var (s) -> s
|
||||||
| Exf (e, s) -> "exf("^(string_of_expr e)^":"^s^")"
|
| Exf (e, t) ->
|
||||||
|
let s_e = string_of_expr e in
|
||||||
|
let s_ty = string_of_ty t in
|
||||||
|
"exf (" ^ s_e ^ " : " ^ s_ty ^ ")"
|
||||||
|
|
||||||
|
|
||||||
|
let print_ty t =
|
||||||
|
print_string (string_of_ty t)
|
||||||
|
|
||||||
let print_expr e =
|
let print_expr e =
|
||||||
print_string (string_of_expr e)
|
print_string (string_of_expr e)
|
||||||
|
|
||||||
let affiche_val v = print_string "TODO"
|
|
||||||
|
let affiche_val _ = print_string "TODO"
|
||||||
|
9
expr.ml
9
expr.ml
@ -1,9 +0,0 @@
|
|||||||
type id = string
|
|
||||||
|
|
||||||
type ty_annot = id * Types.ty
|
|
||||||
|
|
||||||
type expr =
|
|
||||||
Fun of ty_annot * expr
|
|
||||||
| App of expr * expr
|
|
||||||
| Var of id
|
|
||||||
| Exf of expr * string
|
|
9
lam.ml
Normal file
9
lam.ml
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
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
|
@ -9,20 +9,22 @@ let digit = ['0'-'9']
|
|||||||
let word = (lowercase | uppercase)*
|
let word = (lowercase | uppercase)*
|
||||||
|
|
||||||
let var_id = lowercase lowercase* digit*
|
let var_id = lowercase lowercase* digit*
|
||||||
let ty_id = uppercase word digit*
|
let ty_id = uppercase uppercase* digit*
|
||||||
|
|
||||||
rule token = parse
|
rule token = parse
|
||||||
| [' ' '\t'] { token lexbuf }
|
| [' ' '\t'] { token lexbuf }
|
||||||
| '\n' { EOL }
|
| '\n' { EOL }
|
||||||
| '+' { PLUS }
|
| '+' { PLUS }
|
||||||
| '*' { TIMES }
|
| '*' { TIMES }
|
||||||
| '1' { TOP }
|
| "True" { TOP }
|
||||||
| '0' { BOTTOM }
|
| "False" { BOT }
|
||||||
| '(' { LPAREN }
|
| '(' { LPAREN }
|
||||||
| ')' { RPAREN }
|
| ')' { RPAREN }
|
||||||
| "fun" { FUN }
|
| "fun" { FUN }
|
||||||
| ':' { COLON }
|
| ':' { COLON }
|
||||||
| "=>" { ARR }
|
| "=>" { ARR }
|
||||||
|
| "->" { TARR }
|
||||||
|
| '~' { TILDE }
|
||||||
| "exf" { EXFALSO }
|
| "exf" { EXFALSO }
|
||||||
| var_id as s { VARID(s) }
|
| var_id as s { VARID(s) }
|
||||||
| ty_id as s { TYID(s) }
|
| ty_id as s { TYID(s) }
|
||||||
|
4
main.ml
4
main.ml
@ -1,11 +1,11 @@
|
|||||||
open Expr
|
|
||||||
open Affichage
|
open Affichage
|
||||||
|
open Typing
|
||||||
|
|
||||||
let interpret e =
|
let interpret e =
|
||||||
begin
|
begin
|
||||||
print_expr e;
|
print_expr e;
|
||||||
print_newline();
|
print_newline();
|
||||||
(*print_int (eval e);*)
|
print_ty (typeinfer [] e);
|
||||||
print_newline()
|
print_newline()
|
||||||
end
|
end
|
||||||
|
|
||||||
|
17
parser.mly
17
parser.mly
@ -1,21 +1,22 @@
|
|||||||
%{
|
%{
|
||||||
open Expr
|
open Lam
|
||||||
open Types
|
open Types
|
||||||
%}
|
%}
|
||||||
|
|
||||||
%token PLUS TIMES
|
%token PLUS TIMES
|
||||||
%token TOP BOTTOM EXFALSO
|
%token TOP BOT EXFALSO TILDE
|
||||||
%token LPAREN RPAREN
|
%token LPAREN RPAREN
|
||||||
%token FUN ARR COLON
|
%token FUN ARR COLON TARR
|
||||||
%token <string> VARID
|
%token <string> VARID
|
||||||
%token <string> TYID
|
%token <string> TYID
|
||||||
|
|
||||||
%token EOL
|
%token EOL
|
||||||
|
|
||||||
%right ARR
|
%right TARR
|
||||||
|
%right TILDE
|
||||||
|
|
||||||
%start main
|
%start main
|
||||||
%type <Expr.expr> main
|
%type <Lam.lam> main
|
||||||
|
|
||||||
%%
|
%%
|
||||||
main:
|
main:
|
||||||
@ -26,12 +27,16 @@ ty_annot:
|
|||||||
|
|
||||||
ty:
|
ty:
|
||||||
| id=TYID { TVar(id) }
|
| id=TYID { TVar(id) }
|
||||||
|
| BOT { Bot }
|
||||||
| LPAREN t=ty RPAREN { t }
|
| LPAREN t=ty RPAREN { t }
|
||||||
| t1=ty ARR t2=ty { Arr(t1, t2) }
|
| TILDE t=ty { Arr(t, Bot) }
|
||||||
|
| t1=ty TARR t2=ty { Arr(t1, t2) }
|
||||||
|
|
||||||
expression:
|
expression:
|
||||||
| FUN LPAREN annot=ty_annot RPAREN ARR e=expression
|
| FUN LPAREN annot=ty_annot RPAREN ARR e=expression
|
||||||
{ Fun (annot, e) }
|
{ Fun (annot, e) }
|
||||||
|
| EXFALSO LPAREN e=expression COLON t=ty RPAREN
|
||||||
|
{ Exf (e, t) }
|
||||||
| e=app_expr { e }
|
| e=app_expr { e }
|
||||||
|
|
||||||
app_expr:
|
app_expr:
|
||||||
|
@ -1 +1 @@
|
|||||||
fun (f : A => B) => f
|
fun (f : A -> B) => f
|
||||||
|
1
tests/exfalso1.lam
Normal file
1
tests/exfalso1.lam
Normal file
@ -0,0 +1 @@
|
|||||||
|
fun (x : A) => exf (x : A)
|
1
tests/exfalso2.lam
Normal file
1
tests/exfalso2.lam
Normal file
@ -0,0 +1 @@
|
|||||||
|
exf(fun (f : ~A) => fun (x : A) => f x : (A -> False) -> A -> False)
|
1
tests/exfalso3.lam
Normal file
1
tests/exfalso3.lam
Normal file
@ -0,0 +1 @@
|
|||||||
|
fun (f : ~A) => fun (x : A) => exf (x : A)
|
1
tests/neg.lam
Normal file
1
tests/neg.lam
Normal file
@ -0,0 +1 @@
|
|||||||
|
fun (x : ~A -> B) => x
|
1
tests/nested_arrow.lam
Normal file
1
tests/nested_arrow.lam
Normal file
@ -0,0 +1 @@
|
|||||||
|
fun (x : A -> B -> C -> ~A) => x
|
@ -1 +1 @@
|
|||||||
fun (f : A => B) => fun (x : A) => f x
|
fun (f : A -> B) => fun (x : A) => f x
|
||||||
|
1
tests/one.lam
Normal file
1
tests/one.lam
Normal file
@ -0,0 +1 @@
|
|||||||
|
fun (z : A) => fun (f : A -> A) => f z
|
1
tests/three.lam
Normal file
1
tests/three.lam
Normal file
@ -0,0 +1 @@
|
|||||||
|
fun (z : A) => fun (f : A -> A) => f (f (f z))
|
1
tests/zero.lam
Normal file
1
tests/zero.lam
Normal file
@ -0,0 +1 @@
|
|||||||
|
fun (z : A) => fun (f : A -> A) => z
|
2
types.ml
2
types.ml
@ -5,4 +5,4 @@ type ty =
|
|||||||
| Arr of ty * ty
|
| Arr of ty * ty
|
||||||
| Bot
|
| Bot
|
||||||
|
|
||||||
type gam = ty_id * ty list
|
type gam = (ty_id * ty) list
|
||||||
|
41
typing.ml
Normal file
41
typing.ml
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
open Types
|
||||||
|
open Lam
|
||||||
|
|
||||||
|
let rec typecheck (g : gam) (e : lam) (expected_t : ty) =
|
||||||
|
match e with
|
||||||
|
Var x -> (List.assoc x g) = expected_t
|
||||||
|
| Fun ((x, actual_t1), e) ->
|
||||||
|
begin match expected_t with
|
||||||
|
Arr (expected_t1, expected_t2) ->
|
||||||
|
let g' = (x, expected_t1)::g in
|
||||||
|
(actual_t1 = expected_t1) && (typecheck g' e expected_t2)
|
||||||
|
| _ -> false
|
||||||
|
end
|
||||||
|
| App (e1, e2) ->
|
||||||
|
begin match typeinfer g e1 with
|
||||||
|
Arr (expected_t2, actual_t) ->
|
||||||
|
(actual_t = expected_t) && (typecheck g e2 expected_t2)
|
||||||
|
| _ -> false
|
||||||
|
end
|
||||||
|
| Exf (e, t) ->
|
||||||
|
(expected_t = Bot) && (typecheck g e t)
|
||||||
|
|
||||||
|
and typeinfer (g : gam) (e : lam) : ty =
|
||||||
|
match e with
|
||||||
|
Var x -> List.assoc x g
|
||||||
|
| Fun ((x, t1), e) ->
|
||||||
|
let g' = (x, t1)::g in
|
||||||
|
let t2 = typeinfer g' e in
|
||||||
|
Arr (t1, t2)
|
||||||
|
| App (e1, e2) ->
|
||||||
|
begin match typeinfer g e1 with
|
||||||
|
Arr (t1, t2) ->
|
||||||
|
if typecheck g e2 t1
|
||||||
|
then t2
|
||||||
|
else failwith "couldn't infer"
|
||||||
|
| _ -> failwith "couldn't infer"
|
||||||
|
end
|
||||||
|
| Exf (e, t) ->
|
||||||
|
if typecheck g e t
|
||||||
|
then Bot
|
||||||
|
else failwith "couldn't infer"
|
Loading…
Reference in New Issue
Block a user