chap9: init
This commit is contained in:
+353
@@ -0,0 +1,353 @@
|
||||
From Stdlib Require Import
|
||||
Strings.String
|
||||
FSets.FMapInterface
|
||||
FSets.FMapList
|
||||
FSets.FMapFacts
|
||||
Structures.OrderedTypeEx.
|
||||
|
||||
Module Chap9.
|
||||
(*
|
||||
NOTE: a lot of the definitions of stlc done here were
|
||||
taken from https://softwarefoundations.cis.upenn.edu/plf-current/Stlc.html
|
||||
and adapted to fit the contents from the book.
|
||||
*)
|
||||
|
||||
Inductive type : Type :=
|
||||
| type_Bool : type
|
||||
| type_Arrow : type -> type -> type.
|
||||
|
||||
Scheme Equality for type.
|
||||
|
||||
Inductive term : Type :=
|
||||
| term_var : string -> term
|
||||
| term_app : term -> term -> term
|
||||
| term_abs : string -> type -> term -> term
|
||||
| term_true : term
|
||||
| term_false : term
|
||||
| term_if : term -> term -> term -> term.
|
||||
|
||||
Scheme Equality for term.
|
||||
|
||||
Declare Scope stlc_scope.
|
||||
Delimit Scope stlc_scope with stlc.
|
||||
Open Scope stlc_scope.
|
||||
|
||||
Declare Custom Entry stlc_type.
|
||||
Declare Custom Entry stlc_term.
|
||||
|
||||
Notation "x" := x (in custom stlc_type at level 0, x global) : stlc_scope.
|
||||
Notation "<{{ x }}>" := x (x custom stlc_type).
|
||||
Notation "( t )" := t (in custom stlc_type at level 0, t custom stlc_type) : stlc_scope.
|
||||
Notation "S -> T" := (type_Arrow S T) (in custom stlc_type at level 99, right associativity) : stlc_scope.
|
||||
Notation "$( t )" := t (in custom stlc_type at level 0, t constr) : stlc_scope.
|
||||
Notation "'Bool'" := type_Bool (in custom stlc_type at level 0) : stlc_scope.
|
||||
Notation "'if' x 'then' y 'else' z" :=
|
||||
(term_if x y z) (in custom stlc_term at level 200,
|
||||
x custom stlc_term,
|
||||
y custom stlc_term,
|
||||
z custom stlc_term at level 200,
|
||||
left associativity).
|
||||
Notation "'true'" := true (at level 1).
|
||||
Notation "'true'" := term_true (in custom stlc_term at level 0).
|
||||
Notation "'false'" := false (at level 1).
|
||||
Notation "'false'" := term_false (in custom stlc_term at level 0).
|
||||
|
||||
Notation "$( x )" := x (in custom stlc_term at level 0, x constr, only parsing) : stlc_scope.
|
||||
Notation "x" := x (in custom stlc_term at level 0, x constr at level 0) : stlc_scope.
|
||||
Notation "<{ e }>" := e (e custom stlc_term at level 200) : stlc_scope.
|
||||
Notation "( x )" := x (in custom stlc_term at level 0, x custom stlc_term) : stlc_scope.
|
||||
Notation "x y" := (term_app x y) (in custom stlc_term at level 10, left associativity) : stlc_scope.
|
||||
Notation "\ x : t , y" :=
|
||||
(term_abs x t y) (in custom stlc_term at level 200, x global,
|
||||
t custom stlc_type,
|
||||
y custom stlc_term at level 200,
|
||||
left associativity).
|
||||
|
||||
Coercion term_var : string >-> term.
|
||||
Arguments term_var _%_string.
|
||||
|
||||
Definition f : string := "f".
|
||||
Definition x : string := "x".
|
||||
Definition y : string := "y".
|
||||
Definition z : string := "z".
|
||||
Hint Unfold f : core.
|
||||
Hint Unfold x : core.
|
||||
Hint Unfold y : core.
|
||||
Hint Unfold z : core.
|
||||
|
||||
Inductive value : term -> Prop :=
|
||||
| v_abs : forall (x : string) (T2 : type) (t1 : term),
|
||||
value <{\x:T2, t1}>
|
||||
| v_true :
|
||||
value <{true}>
|
||||
| v_false :
|
||||
value <{false}>.
|
||||
|
||||
Hint Constructors value : core.
|
||||
|
||||
Reserved Notation "'[' x ':=' s ']' t" (in custom stlc_term at level 5, x global, s custom stlc_term,
|
||||
t custom stlc_term at next level, right associativity).
|
||||
Fixpoint subst (x : string) (s : term) (t : term) : term :=
|
||||
match t with
|
||||
| term_var y =>
|
||||
if String.eqb x y then s else t
|
||||
| <{\y:T, t1}> =>
|
||||
if String.eqb x y then t else <{\y:T, [x:=s] t1}>
|
||||
| <{t1 t2}> =>
|
||||
<{[x:=s] t1 [x:=s] t2}>
|
||||
| <{true}> =>
|
||||
<{true}>
|
||||
| <{false}> =>
|
||||
<{false}>
|
||||
| <{if t1 then t2 else t3}> =>
|
||||
<{if [x:=s] t1 then [x:=s] t2 else [x:=s] t3}>
|
||||
end
|
||||
where "'[' x ':=' s ']' t" := (subst x s t) (in custom stlc_term).
|
||||
|
||||
Reserved Notation "t '--->' t'" (at level 40).
|
||||
Inductive step : term -> term -> Prop :=
|
||||
| E_App1 : forall t1 t1' t2,
|
||||
t1 ---> t1' ->
|
||||
<{t1 t2}> ---> <{t1' t2}>
|
||||
| E_App2 : forall v1 t2 t2',
|
||||
value v1 ->
|
||||
t2 ---> t2' ->
|
||||
<{v1 t2}> ---> <{v1 t2'}>
|
||||
| E_AppAbs : forall x T t v,
|
||||
value v ->
|
||||
<{(\x:T, t) v}> ---> <{ [x:=v]t }>
|
||||
| E_IfTrue : forall t1 t2,
|
||||
<{if true then t1 else t2}> ---> t1
|
||||
| E_IfFalse : forall t1 t2,
|
||||
<{if false then t1 else t2}> ---> t2
|
||||
| E_If : forall t1 t1' t2 t3,
|
||||
t1 ---> t1' ->
|
||||
<{if t1 then t2 else t3}> ---> <{if t1' then t2 else t3}>
|
||||
where "t '--->' t'" := (step t t').
|
||||
|
||||
Hint Constructors step : core.
|
||||
|
||||
Module M := FMapList.Make(String_as_OT).
|
||||
Definition context := M.t type.
|
||||
Definition empty_ctx : context := @M.empty type.
|
||||
|
||||
Notation "x ')>' v ';' m " := (M.add x v m)
|
||||
(in custom stlc_term at level 0, x constr at level 0, v custom stlc_type, right associativity) : stlc_scope.
|
||||
Notation "x ')>' v " := (M.add x v empty_ctx)
|
||||
(in custom stlc_term at level 0, x constr at level 0, v custom stlc_type) : stlc_scope.
|
||||
Notation "'empty'" := empty_ctx (in custom stlc_term) : stlc_scope.
|
||||
|
||||
Reserved Notation "<{ Γ '|-' t '∈' T }>"
|
||||
(at level 0, Γ custom stlc_term at level 200, t custom stlc_term, T custom stlc_type).
|
||||
Inductive has_type : context -> term -> type -> Prop :=
|
||||
| T_Var : forall (Γ : context) (x : string) (T1 : type),
|
||||
M.find x Γ = Some T1 ->
|
||||
<{ Γ |- x ∈ T1 }>
|
||||
| T_Abs : forall (Γ : context) (x : string) (T1 T2 : type) (t1 : term),
|
||||
<{ x )> T1; Γ |- t1 ∈ T2 }> ->
|
||||
<{ Γ |- \x:T1, t1 ∈ T1 -> T2 }>
|
||||
| T_App : forall (Γ : context) (t1 t2 : term) (T1 T2 : type),
|
||||
<{ Γ |- t1 ∈ T2 -> T1 }> ->
|
||||
<{ Γ |- t2 ∈ T2 }> ->
|
||||
<{ Γ |- t1 t2 ∈ T1 }>
|
||||
| T_True : forall Γ,
|
||||
<{ Γ |- true ∈ Bool }>
|
||||
| T_False : forall Γ,
|
||||
<{ Γ |- false ∈ Bool }>
|
||||
| T_If : forall t1 t2 t3 T1 Γ,
|
||||
<{ Γ |- t1 ∈ Bool }> ->
|
||||
<{ Γ |- t2 ∈ T1 }> ->
|
||||
<{ Γ |- t3 ∈ T1 }> ->
|
||||
<{ Γ |- if t1 then t2 else t3 ∈ T1 }>
|
||||
where "<{ Γ '|-' t '∈' T }>" := (has_type Γ t T) : stlc_scope.
|
||||
|
||||
Hint Constructors has_type : core.
|
||||
|
||||
(* Notation multistep := (multi step).
|
||||
Notation "t1 '-->*' t2" := (multistep t1 t2) (at level 40). *)
|
||||
|
||||
Example typing_example_1' :
|
||||
<{ empty |- \x:Bool, x ∈ Bool -> Bool }>.
|
||||
Proof. eauto. Qed.
|
||||
|
||||
(* End of definitions Software Foundations definitions of STLC *)
|
||||
|
||||
(* 9.2.2 *)
|
||||
|
||||
Example typing_example_1 :
|
||||
<{ f )> Bool -> Bool |- f (if false then true else false) ∈ Bool }>.
|
||||
Proof.
|
||||
Admitted.
|
||||
|
||||
Example typing_example_2 :
|
||||
<{ f )> Bool -> Bool |- \x:Bool, f (true) ∈ Bool -> Bool }>.
|
||||
Proof.
|
||||
Admitted.
|
||||
|
||||
(* 9.2.3 *)
|
||||
Lemma fxy_bool_iff :
|
||||
forall Γ,
|
||||
<{ Γ |- f x y ∈ Bool }> <->
|
||||
exists T1 T2,
|
||||
M.find f Γ = Some <{{ T1 -> T2 -> Bool }}>
|
||||
/\ M.find x Γ = Some T1
|
||||
/\ M.find y Γ = Some T2.
|
||||
Proof.
|
||||
split.
|
||||
- intros H.
|
||||
inversion H.
|
||||
Admitted.
|
||||
|
||||
(* 9.3.1 *)
|
||||
Lemma type_inv_var :
|
||||
forall (Γ : context) (x : string) (R : type),
|
||||
<{ Γ |- x ∈ R }> ->
|
||||
exists T', M.find x Γ = Some T'.
|
||||
Proof.
|
||||
intros Γ x R H.
|
||||
inversion H.
|
||||
exists R.
|
||||
assumption.
|
||||
Qed.
|
||||
|
||||
Lemma type_inv_abs :
|
||||
forall (Γ : context) (x : string) (T1 R : type) (t2 : term),
|
||||
<{ Γ |- \x:T1, t2 ∈ R }> ->
|
||||
exists R2,
|
||||
R = <{{ T1 -> R2 }}> /\
|
||||
<{ x )> T1; Γ |- t2 ∈ R2 }>.
|
||||
Proof.
|
||||
intros Γ x T1 R t2 H.
|
||||
inversion H.
|
||||
exists T2.
|
||||
split.
|
||||
- reflexivity.
|
||||
- assumption.
|
||||
Qed.
|
||||
|
||||
Lemma type_inv_app :
|
||||
forall (Γ : context) (t1 t2 : term) (T11 R : type),
|
||||
<{ Γ |- t1 t2 ∈ R }> ->
|
||||
exists T12,
|
||||
<{ Γ |- t1 ∈ T12 -> R }> /\
|
||||
<{ Γ |- t2 ∈ T12 }>.
|
||||
Proof.
|
||||
intros Γ t1 t2 T11 R H.
|
||||
inversion H.
|
||||
exists T2.
|
||||
split.
|
||||
- assumption.
|
||||
- assumption.
|
||||
Qed.
|
||||
|
||||
Lemma type_inv_true :
|
||||
forall (Γ : context) (R : type),
|
||||
<{ Γ |- true ∈ R }> ->
|
||||
R = type_Bool.
|
||||
Proof.
|
||||
intros Γ R H.
|
||||
inversion H.
|
||||
reflexivity.
|
||||
Qed.
|
||||
|
||||
Lemma type_inv_false :
|
||||
forall (Γ : context) (R : type),
|
||||
<{ Γ |- false ∈ R }> ->
|
||||
R = type_Bool.
|
||||
Proof.
|
||||
intros Γ R H.
|
||||
inversion H.
|
||||
reflexivity.
|
||||
Qed.
|
||||
|
||||
Lemma type_inv_if :
|
||||
forall (Γ : context) (t1 t2 t3 : term) (R : type),
|
||||
<{ Γ |- if t1 then t2 else t3 ∈ R }> ->
|
||||
<{ Γ |- t1 ∈ Bool }> /\
|
||||
<{ Γ |- t2 ∈ R }> /\
|
||||
<{ Γ |- t3 ∈ R }>.
|
||||
Proof.
|
||||
intros Γ t1 t2 t3 R H.
|
||||
inversion H.
|
||||
split.
|
||||
- assumption.
|
||||
- split.
|
||||
+ assumption.
|
||||
+ assumption.
|
||||
Qed.
|
||||
|
||||
(* 9.3.2 *)
|
||||
|
||||
Lemma unique_context_content :
|
||||
forall (Γ : context) (x : string) (T1 T2 : type),
|
||||
<{ Γ |- x ∈ T1 }> ->
|
||||
<{ Γ |- x ∈ T2 }> ->
|
||||
T1 = T2.
|
||||
Proof.
|
||||
intros Γ x T1 T2 H1 H2.
|
||||
inversion H1.
|
||||
inversion H2.
|
||||
subst.
|
||||
rewrite H3 in H7.
|
||||
inversion H7.
|
||||
reflexivity.
|
||||
Qed.
|
||||
|
||||
Lemma no_self_arrow :
|
||||
forall T U,
|
||||
type_Arrow T U <> T.
|
||||
Proof.
|
||||
induction T; intros U H.
|
||||
- discriminate H.
|
||||
- inversion H.
|
||||
apply IHT1 in H1.
|
||||
contradiction.
|
||||
Qed.
|
||||
|
||||
Lemma no_x_x_T :
|
||||
forall (Γ : context) (x : string) (T : type),
|
||||
~(exists Γ T, <{ Γ |- x x ∈ T }>).
|
||||
Proof.
|
||||
intros Γ x T H.
|
||||
destruct H as [Γ' [T' H']].
|
||||
inversion H'.
|
||||
apply unique_context_content with
|
||||
(Γ := Γ') (x := x) (T1 := T2) (T2 := <{{ T2 -> T' }}>) in H2.
|
||||
- symmetry in H2.
|
||||
apply no_self_arrow in H2.
|
||||
contradiction.
|
||||
- assumption.
|
||||
Qed.
|
||||
|
||||
(* 9.3.3 *)
|
||||
Lemma unique_bag_content :
|
||||
forall (Γ : context) (x : string) (T1 T2 : type),
|
||||
M.find x Γ = Some T1 ->
|
||||
M.find x Γ = Some T2 ->
|
||||
T1 = T2.
|
||||
Proof.
|
||||
intros Γ x T1 T2 H1 H2.
|
||||
rewrite H1 in H2.
|
||||
inversion H2.
|
||||
reflexivity.
|
||||
Qed.
|
||||
|
||||
Lemma uniqueness_of_types :
|
||||
forall (Γ : context) (t : term) (T1 T2 : type),
|
||||
<{ Γ |- t ∈ T1 }> ->
|
||||
<{ Γ |- t ∈ T2 }> ->
|
||||
T1 = T2.
|
||||
Proof.
|
||||
intros Γ t T1 T2 H1 H2.
|
||||
generalize dependent T2.
|
||||
induction H1.
|
||||
- intros T2 H2.
|
||||
inversion H2.
|
||||
apply unique_bag_content with
|
||||
(Γ := Γ) (x := x0) (T1 := T1) (T2 := T2) in H.
|
||||
+ assumption.
|
||||
+ assumption.
|
||||
- intros R.
|
||||
Admitted.
|
||||
|
||||
End Chap9.
|
||||
Reference in New Issue
Block a user