-
Notifications
You must be signed in to change notification settings - Fork 0
/
SysF.v
92 lines (79 loc) · 3.25 KB
/
SysF.v
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
(*
Problem(s):
System F Type Checking (SysF_TC)
System F Typability (SysF_TYP)
System F Inhabitation (SysF_INH)
*)
(*
Literature:
[1] Andrej Dudenhefner and Jakob Rehof.
"A Simpler Undecidability Proof for System F Inhabitation."
24th International Conference on Types for Proofs and Programs (TYPES 2018).
Schloss Dagstuhl-Leibniz-Zentrum fuer Informatik, 2019.
[2] Joe B. Wells.
"Typability and type checking in the second-order lambda-calculus are equivalent and undecidable."
Proceedings Ninth Annual IEEE Symposium on Logic In Computer Science.
IEEE, 1994.
*)
Require Import List.
(* pure lambda-terms M, N, .. *)
Inductive pure_term : Type :=
| pure_var : nat -> pure_term
| pure_app : pure_term -> pure_term -> pure_term
| pure_abs : pure_term -> pure_term.
(* polymorphic types s, t, ..*)
Inductive poly_type : Type :=
| poly_var : nat -> poly_type
| poly_arr : poly_type -> poly_type -> poly_type
| poly_abs : poly_type -> poly_type.
(* system F type environments *)
Definition environment := list poly_type.
(* function composition *)
Definition funcomp {X Y Z} (g : Y -> Z) (f : X -> Y) :=
fun x => g (f x).
(* stream cons *)
Definition scons {X: Type} (x : X) (xi : nat -> X) :=
fun n => match n with | 0 => x | S n => xi n end.
(* polymorphic type variable renaming *)
Fixpoint ren_poly_type (xi : nat -> nat) (s : poly_type) : poly_type :=
match s return poly_type with
| poly_var x => poly_var (xi x)
| poly_arr s t => poly_arr (ren_poly_type xi s) (ren_poly_type xi t)
| poly_abs s => poly_abs (ren_poly_type (scons 0 (funcomp S xi)) s)
end.
(* polymorphic type variable substitution *)
Fixpoint subst_poly_type (sigma : nat -> poly_type) (s : poly_type) : poly_type :=
match s return poly_type with
| poly_var s => sigma s
| poly_arr s t => poly_arr (subst_poly_type sigma s) (subst_poly_type sigma t)
| poly_abs s => poly_abs (subst_poly_type (scons (poly_var 0) (funcomp (ren_poly_type S) sigma)) s)
end.
(*
Curry-style System F Type Assignment predicate
Γ ⊢ M : τ is (type_assignment Γ M τ)
*)
Inductive type_assignment : environment -> pure_term -> poly_type -> Prop :=
| type_assignment_var {Gamma x t} :
nth_error Gamma x = Some t ->
type_assignment Gamma (pure_var x) t
| type_assignment_app {Gamma M N s t} :
type_assignment Gamma M (poly_arr s t) -> type_assignment Gamma N s ->
type_assignment Gamma (pure_app M N) t
| type_assignment_abs {Gamma M s t} :
type_assignment (s :: Gamma) M t ->
type_assignment Gamma (pure_abs M) (poly_arr s t)
| type_assignment_inst {Gamma M s t} :
type_assignment Gamma M (poly_abs s) ->
type_assignment Gamma M (subst_poly_type (scons t poly_var) s)
| type_assignment_gen {Gamma M s} :
type_assignment (map (ren_poly_type S) Gamma) M s ->
type_assignment Gamma M (poly_abs s).
(* System F Type Checking *)
Definition SysF_TC : environment * pure_term * poly_type -> Prop :=
fun '(Gamma, M, t) => type_assignment Gamma M t.
(* System F Typability *)
Definition SysF_TYP : pure_term -> Prop :=
fun M => exists Gamma t, type_assignment Gamma M t.
(* System F Inhabitation *)
Definition SysF_INH : environment * poly_type -> Prop :=
fun '(Gamma, t) => exists M, type_assignment Gamma M t.