mirror of
				https://github.com/KevinMidboe/linguist.git
				synced 2025-10-29 17:50:22 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			733 lines
		
	
	
		
			15 KiB
		
	
	
	
		
			Coq
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			733 lines
		
	
	
		
			15 KiB
		
	
	
	
		
			Coq
		
	
	
		
			Executable File
		
	
	
	
	
| 
 | |
| Require Export SfLib.
 | |
| 
 | |
| Module STLC.
 | |
| 
 | |
| Inductive ty : Type :=
 | |
|    | ty_Bool : ty
 | |
|    | ty_arrow : ty -> ty -> ty.
 | |
| 
 | |
| Inductive tm : Type :=
 | |
|    | tm_var : id -> tm
 | |
|    | tm_app : tm -> tm -> tm
 | |
|    | tm_abs : id -> ty -> tm -> tm
 | |
|    | tm_true : tm
 | |
|    | tm_false : tm
 | |
|    | tm_if : tm -> tm -> tm -> tm.
 | |
| 
 | |
| Tactic Notation "tm_cases" tactic(first) ident(c) :=
 | |
|   first;
 | |
|   [ Case_aux c "tm_var" | Case_aux c "tm_app" 
 | |
|   | Case_aux c "tm_abs" | Case_aux c "tm_true" 
 | |
|   | Case_aux c "tm_false" | Case_aux c "tm_if" ].
 | |
|   
 | |
| Notation a := (Id 0).
 | |
| Notation b := (Id 1).
 | |
| Notation c := (Id 2).
 | |
| 
 | |
| Notation idB :=
 | |
|    (tm_abs a ty_Bool (tm_var a)).
 | |
|    
 | |
| Notation idBB :=
 | |
|    (tm_abs a (ty_arrow ty_Bool ty_Bool) (tm_var a)).
 | |
|    
 | |
| Notation idBBBB :=
 | |
|    (tm_abs a (ty_arrow (ty_arrow ty_Bool ty_Bool) 
 | |
|                          (ty_arrow ty_Bool ty_Bool)) 
 | |
|        (tm_var a)).
 | |
|        
 | |
| Notation k := (tm_abs a ty_Bool (tm_abs b ty_Bool (tm_var a))).
 | |
| 
 | |
| Inductive value : tm -> Prop :=
 | |
|   | v_abs : forall x T t,
 | |
|       value (tm_abs x T t)
 | |
|   | t_true : 
 | |
|       value tm_true
 | |
|   | t_false : 
 | |
|       value tm_false.
 | |
| 
 | |
| Hint Constructors value.
 | |
| 
 | |
| Fixpoint subst (s:tm) (x:id) (t:tm) : tm :=
 | |
|    match t with
 | |
|    | tm_var x' => if beq_id x x' then s else t
 | |
|    | tm_abs x' T t1 => tm_abs x' T (if beq_id x x' then t1 else (subst s x t1))
 | |
|    | tm_app t1 t2 => tm_app (subst s x t1) (subst s x t2)
 | |
|    | tm_true => tm_true
 | |
|    | tm_false => tm_false
 | |
|    | tm_if t1 t2 t3 => tm_if (subst s x t1) (subst s x t2) (subst s x t3)
 | |
| end.
 | |
| 
 | |
| Reserved Notation "t1 '==>' t2" (at level 40).
 | |
| 
 | |
| Inductive step : tm -> tm -> Prop :=
 | |
|  | ST_AppAbs : forall x T t12 v2,
 | |
|         value v2 ->
 | |
|         (tm_app (tm_abs x T t12) v2) ==> (subst v2 x t12)
 | |
|  | ST_App1 : forall t1 t1' t2,
 | |
|         t1 ==> t1' ->
 | |
|         tm_app t1 t2 ==> tm_app t1' t2
 | |
|  | ST_App2 : forall v1 t2 t2',
 | |
|         value v1 ->
 | |
|         t2 ==> t2' ->
 | |
|         tm_app v1 t2 ==> tm_app v1 t2'
 | |
|  | ST_IfTrue : forall t1 t2,
 | |
|      (tm_if tm_true t1 t2) ==> t1
 | |
|  | ST_IfFalse : forall t1 t2,
 | |
|      (tm_if tm_false t1 t2) ==> t2
 | |
|  | ST_If : forall t1 t1' t2 t3,
 | |
|      t1 ==> t1' ->
 | |
|      (tm_if t1 t2 t3) ==> (tm_if t1' t2 t3)
 | |
| 
 | |
| where "t1 '==>' t2" := (step t1 t2).
 | |
| 
 | |
| Tactic Notation "step_cases" tactic(first) ident(c) :=
 | |
|  first;
 | |
|  [ Case_aux c "ST_AppAbs" | Case_aux c "ST_App1" 
 | |
|  | Case_aux c "ST_App2" | Case_aux c "ST_IfTrue" 
 | |
|  | Case_aux c "ST_IfFalse" | Case_aux c "ST_If" ].
 | |
| 
 | |
| Notation stepmany := (refl_step_closure step).
 | |
| Notation "t1 '==>*' t2" := (stepmany t1 t2) (at level 40).
 | |
| 
 | |
| Hint Constructors step.
 | |
| 
 | |
| Lemma step_example3 :
 | |
|        (tm_app (tm_app idBBBB idBB) idB)
 | |
|   ==>* idB.
 | |
| Proof.
 | |
|  eapply rsc_step.
 | |
|  apply ST_App1.
 | |
|  apply ST_AppAbs.
 | |
|  apply v_abs.
 | |
|  
 | |
|  simpl.
 | |
|  eapply rsc_step.
 | |
|   apply ST_AppAbs.
 | |
|   apply v_abs.
 | |
|   
 | |
|   simpl.
 | |
|   apply rsc_refl.
 | |
| Qed.
 | |
| 
 | |
| Definition context := partial_map ty.
 | |
| Module Context.
 | |
| 
 | |
| Definition partial_map (A:Type) := id -> option A.
 | |
| Definition empty {A:Type} : partial_map A := (fun _ => None).
 | |
| Definition extend {A:Type} (Gamma : partial_map A) (x:id) (T : A) :=
 | |
|    fun x' => if beq_id x x' then Some T else Gamma x'.
 | |
|    
 | |
| Lemma extend_eq : forall A (ctxt: partial_map A) x T,
 | |
|    (extend ctxt x T) x = Some T.
 | |
| Proof.
 | |
|    intros. unfold extend. rewrite <- beq_id_refl. auto.
 | |
| Qed.
 | |
| 
 | |
| Lemma extend_neq : forall A (ctxt: partial_map A) x1 T x2,
 | |
|    beq_id x2 x1 = false ->
 | |
|       (extend ctxt x2 T) x1 = ctxt x1.
 | |
| Proof.
 | |
| intros. unfold extend. rewrite H. auto.
 | |
| Qed.
 | |
| 
 | |
| End Context.
 | |
| 
 | |
| Inductive has_type : context -> tm -> ty -> Prop :=
 | |
|    | T_Var : forall Gamma x T,
 | |
|       Gamma x = Some T ->
 | |
|          has_type Gamma (tm_var x) T
 | |
|    | T_Abs : forall Gamma x T11 T12 t12,
 | |
|       has_type (extend Gamma x T11) t12 T12 ->
 | |
|          has_type Gamma (tm_abs x T11 t12) (ty_arrow T11 T12)
 | |
|    | T_App : forall T11 T12 Gamma t1 t2,
 | |
|       has_type Gamma t1 (ty_arrow T11 T12) ->
 | |
|          has_type Gamma t2 T11 ->
 | |
|             has_type Gamma (tm_app t1 t2) T12
 | |
|    | T_True : forall Gamma,
 | |
|       has_type Gamma tm_true ty_Bool
 | |
|    | T_False : forall Gamma,
 | |
|       has_type Gamma tm_false ty_Bool
 | |
|    | T_If : forall t1 t2 t3 T Gamma,
 | |
|       has_type Gamma t1 ty_Bool ->
 | |
|       has_type Gamma t2 T ->
 | |
|       has_type Gamma t3 T ->
 | |
|       has_type Gamma (tm_if t1 t2 t3) T.
 | |
|       
 | |
| Tactic Notation "has_type_cases" tactic(first) ident(c) :=
 | |
|   first;
 | |
|   [ Case_aux c "T_Var" | Case_aux c "T_Abs" 
 | |
|   | Case_aux c "T_App" | Case_aux c "T_True" 
 | |
|   | Case_aux c "T_False" | Case_aux c "T_If" ].
 | |
| 
 | |
| Hint Constructors has_type.
 | |
| 
 | |
| Hint Unfold beq_id beq_nat extend.
 | |
| 
 | |
| Example typing_example_2_full :
 | |
|   has_type empty
 | |
|     (tm_abs a ty_Bool
 | |
|        (tm_abs b (ty_arrow ty_Bool ty_Bool)
 | |
|           (tm_app (tm_var b) (tm_app (tm_var b) (tm_var a)))))
 | |
|     (ty_arrow ty_Bool (ty_arrow (ty_arrow ty_Bool ty_Bool) ty_Bool)).
 | |
| Proof.
 | |
| apply T_Abs.
 | |
| apply T_Abs.
 | |
| apply T_App with (T11 := ty_Bool).
 | |
|  apply T_Var.
 | |
|  unfold extend.
 | |
|  simpl.
 | |
|  reflexivity.
 | |
|  
 | |
|  apply T_App with (T11 := ty_Bool).
 | |
|   apply T_Var.
 | |
|   unfold extend.
 | |
|   simpl.
 | |
|   reflexivity.
 | |
|   
 | |
|   apply T_Var.
 | |
|   unfold extend.
 | |
|   simpl.
 | |
|   reflexivity.
 | |
| Qed.
 | |
| 
 | |
| Example typing_example_3 :
 | |
|   exists T, 
 | |
|     has_type empty
 | |
|       (tm_abs a (ty_arrow ty_Bool ty_Bool)
 | |
|          (tm_abs b (ty_arrow ty_Bool ty_Bool)
 | |
|             (tm_abs c ty_Bool
 | |
|                (tm_app (tm_var b) (tm_app (tm_var a) (tm_var c))))))
 | |
|       T.
 | |
| 
 | |
| Proof with auto.
 | |
| exists
 | |
|  (ty_arrow (ty_arrow ty_Bool ty_Bool)
 | |
|     (ty_arrow (ty_arrow ty_Bool ty_Bool) (ty_arrow ty_Bool ty_Bool))).
 | |
| apply T_Abs.
 | |
| apply T_Abs.
 | |
| apply T_Abs.
 | |
| apply T_App with (T11 := ty_Bool).
 | |
|  apply T_Var.
 | |
|  unfold extend.
 | |
|  simpl.
 | |
|  reflexivity.
 | |
|  
 | |
|  apply T_App with (T11 := ty_Bool).
 | |
|   auto.
 | |
|   
 | |
|   auto.
 | |
| Qed.
 | |
| 
 | |
| 
 | |
| Theorem coiso : forall a b e,
 | |
|    a ==>* b ->
 | |
|       tm_app a e ==>* tm_app b e.
 | |
| Proof.
 | |
| intros.
 | |
| induction H.
 | |
|  apply rsc_refl.
 | |
|  
 | |
|  apply rsc_step with (tm_app y e).
 | |
|   apply ST_App1.
 | |
|   assumption.
 | |
|   
 | |
|   assumption.
 | |
| Qed.
 | |
| 
 | |
| Theorem reptrans : forall a b c,
 | |
|    a ==>* b ->
 | |
|       b ==>* c ->
 | |
|          a ==>* c.
 | |
| Proof.
 | |
| 
 | |
| intros a b c H.
 | |
| induction H.
 | |
|  intros.
 | |
|  assumption.
 | |
|  
 | |
|  intros H1.
 | |
|  apply IHrefl_step_closure in H1.
 | |
|  apply rsc_step with y.
 | |
|   assumption.
 | |
|   
 | |
|   assumption.
 | |
| Qed.
 | |
| 
 | |
| (* TODO
 | |
| Example typing_nonexample_3 :
 | |
|   ~ (exists S, exists T,
 | |
|         has_type empty 
 | |
|           (tm_abs a S
 | |
|              (tm_app (tm_var a) (tm_var a)))
 | |
|           T).
 | |
| Proof.
 | |
| *)
 | |
| 
 | |
| Inductive appears_free_in : id -> tm -> Prop :=
 | |
|   | afi_var : forall x,
 | |
|       appears_free_in x (tm_var x)
 | |
|   | afi_app1 : forall x t1 t2,
 | |
|       appears_free_in x t1 -> appears_free_in x (tm_app t1 t2)
 | |
|   | afi_app2 : forall x t1 t2,
 | |
|       appears_free_in x t2 -> appears_free_in x (tm_app t1 t2)
 | |
|   | afi_abs : forall x y T11 t12,
 | |
|       y <> x ->
 | |
|       appears_free_in x t12 ->
 | |
|       appears_free_in x (tm_abs y T11 t12)
 | |
|   | afi_if1 : forall x t1 t2 t3,
 | |
|       appears_free_in x t1 ->
 | |
|       appears_free_in x (tm_if t1 t2 t3)
 | |
|   | afi_if2 : forall x t1 t2 t3,
 | |
|       appears_free_in x t2 ->
 | |
|       appears_free_in x (tm_if t1 t2 t3)
 | |
|   | afi_if3 : forall x t1 t2 t3,
 | |
|       appears_free_in x t3 ->
 | |
|       appears_free_in x (tm_if t1 t2 t3).
 | |
|       
 | |
| Tactic Notation "afi_cases" tactic(first) ident(c) :=
 | |
|   first;
 | |
|   [ Case_aux c "afi_var"
 | |
|   | Case_aux c "afi_app1" | Case_aux c "afi_app2" 
 | |
|   | Case_aux c "afi_abs" 
 | |
|   | Case_aux c "afi_if1" | Case_aux c "afi_if2" 
 | |
|   | Case_aux c "afi_if3" ].
 | |
| 
 | |
| Hint Constructors appears_free_in.
 | |
| 
 | |
| Definition closed (t:tm) :=
 | |
|   forall x, ~ appears_free_in x t.
 | |
|   
 | |
| Lemma free_in_context : forall x t T Gamma,
 | |
|   appears_free_in x t ->
 | |
|   has_type Gamma t T ->
 | |
|   exists T', Gamma x = Some T'.
 | |
| Proof.
 | |
|   intros. generalize dependent Gamma. generalize dependent T.
 | |
|   afi_cases (induction H) Case; 
 | |
|          intros; try solve [inversion H0; eauto].
 | |
|   Case "afi_abs".
 | |
|     inversion H1; subst.
 | |
|     apply IHappears_free_in in H7.
 | |
|     apply not_eq_beq_id_false in H.
 | |
|     rewrite extend_neq in H7; assumption.
 | |
| Qed.
 | |
| 
 | |
| Corollary typable_empty__closed : forall t T, 
 | |
|     has_type empty t T ->
 | |
|     closed t.
 | |
| Proof.
 | |
| intros t T H x H1.
 | |
| remember (@empty ty) as Gamma.
 | |
| assert (exists t' : _, Gamma x = Some t').
 | |
|  apply free_in_context with (t := t) (T := T).
 | |
|   assumption.
 | |
|   
 | |
|   assumption.
 | |
|   
 | |
|  inversion H0.
 | |
|  rewrite HeqGamma in H2.
 | |
|  inversion H2.
 | |
| Qed.
 | |
| 
 | |
| Lemma context_invariance : forall Gamma Gamma' t S,
 | |
|      has_type Gamma t S ->
 | |
|      (forall x, appears_free_in x t -> Gamma x = Gamma' x) ->
 | |
|      has_type Gamma' t S.
 | |
| Proof with auto.
 | |
| intros.
 | |
| generalize dependent Gamma'.
 | |
| has_type_cases (induction H) Case; intros; auto.
 | |
|  apply T_Var.
 | |
|  rewrite <- H0...
 | |
|  
 | |
|  apply T_Abs.
 | |
|  apply IHhas_type.
 | |
|  intros x0 Hafi.
 | |
|  unfold extend.
 | |
|  remember (beq_id x x0) as e.
 | |
|  destruct e.
 | |
|   reflexivity.
 | |
|   
 | |
|   auto.
 | |
|   apply H0.
 | |
|   apply afi_abs.
 | |
|    auto.
 | |
|    eauto   .
 | |
|    apply beq_id_false_not_eq.
 | |
|    rewrite Heqe.
 | |
|    reflexivity.
 | |
|    
 | |
|    assumption.
 | |
|    
 | |
|  apply T_App with T11.
 | |
|   auto.
 | |
|   
 | |
|   auto.
 | |
| Qed.
 | |
| 
 | |
| Lemma substitution_preserves_typing : forall Gamma x U v t T,
 | |
|    has_type (extend Gamma x U) t T ->
 | |
|       has_type empty v U ->
 | |
|          has_type Gamma (subst v x t) T.
 | |
| Proof with eauto.
 | |
|    intros Gamma x U v t T Ht Hv.
 | |
|    generalize dependent Gamma.
 | |
|    generalize dependent T.
 | |
|    tm_cases (induction t) Case; intros T Gamma H; inversion H; subst; simpl...
 | |
|    Case "tm_var".
 | |
|        rename i into y. remember (beq_id x y) as e. destruct e.
 | |
|        SCase "x=y".
 | |
|          apply beq_id_eq in Heqe. subst.
 | |
|          rewrite extend_eq in H2.
 | |
|          inversion H2; subst.
 | |
|          clear H2.
 | |
|            eapply context_invariance...
 | |
|            intros x Hcontra.
 | |
|            destruct (free_in_context _ _ T empty Hcontra) as (T', HT')...
 | |
|            inversion HT'.
 | |
| 
 | |
|            apply T_Var.
 | |
|            rewrite extend_neq in H2.
 | |
|             assumption.
 | |
| 
 | |
|             rewrite Heqe.
 | |
|             reflexivity.
 | |
| 
 | |
|           rename i into y.
 | |
|           apply T_Abs.
 | |
|           remember (beq_id x y) as e.
 | |
|           destruct e.
 | |
|            eapply context_invariance...
 | |
|            apply beq_id_eq in Heqe.
 | |
|            subst.
 | |
|            intros x Hafi.
 | |
|            unfold extend.
 | |
|            destruct (beq_id y x).
 | |
|             reflexivity.
 | |
| 
 | |
|             reflexivity.
 | |
| 
 | |
|            apply IHt.
 | |
|            eapply context_invariance...
 | |
|            intros x0 Hafi.
 | |
|            unfold extend.
 | |
|            remember (beq_id y x0) as Coiso1.
 | |
|            remember (beq_id x x0) as Coiso2.
 | |
|            destruct Coiso1.
 | |
|             auto.
 | |
|             eauto   .
 | |
|             destruct Coiso2.
 | |
|              eauto   .
 | |
|              auto.
 | |
|              apply beq_id_eq in HeqCoiso1.
 | |
|              apply beq_id_eq in HeqCoiso2.
 | |
|              subst.
 | |
|              assert (x0 <> x0).
 | |
|               apply beq_id_false_not_eq.
 | |
|               rewrite Heqe.
 | |
|               auto.
 | |
| 
 | |
|               apply ex_falso_quodlibet.
 | |
|               apply H0.
 | |
|               reflexivity.
 | |
| 
 | |
|              reflexivity.
 | |
| 
 | |
|             destruct Coiso2.
 | |
|              auto.
 | |
| 
 | |
|              auto.
 | |
| Qed.
 | |
| 
 | |
| Theorem preservation : forall t t' T,
 | |
|      has_type empty t T ->
 | |
|      t ==> t' ->
 | |
|      has_type empty t' T.
 | |
| Proof.
 | |
| remember (@empty ty) as Gamma.
 | |
| intros t t' T HT.
 | |
| generalize dependent t'.
 | |
| induction HT.
 | |
|  intros t' H1.
 | |
|  inversion H1.
 | |
|  
 | |
|  intros t' H1.
 | |
|  inversion H1.
 | |
|  
 | |
|  intros t' H1.
 | |
|  inversion H1.
 | |
|   apply substitution_preserves_typing with T11.
 | |
|    subst.
 | |
|    inversion HT1.
 | |
|    subst.
 | |
|    apply H2.
 | |
|    
 | |
|    subst.
 | |
|    assumption.
 | |
|    
 | |
|   subst.
 | |
|   apply T_App with T11.
 | |
|    apply IHHT1.
 | |
|     reflexivity.
 | |
|     
 | |
|     assumption.
 | |
|     
 | |
|    assumption.
 | |
|    
 | |
|   subst.
 | |
|   apply T_App with T11.
 | |
|    assumption.
 | |
|    
 | |
|    apply IHHT2.
 | |
|     reflexivity.
 | |
|     
 | |
|     assumption.
 | |
|     
 | |
|  intros t' H.
 | |
|  inversion H.
 | |
|  
 | |
|  intros t' H.
 | |
|  inversion H.
 | |
|  
 | |
|  intros t' H.
 | |
|  inversion H.
 | |
|   subst.
 | |
|   assumption.
 | |
|   
 | |
|   subst.
 | |
|   assumption.
 | |
|   
 | |
|   subst.
 | |
|   apply T_If.
 | |
|    apply IHHT1.
 | |
|     reflexivity.
 | |
|     
 | |
|     assumption.
 | |
|     
 | |
|    assumption.
 | |
|    
 | |
|    assumption.
 | |
| Qed.
 | |
| 
 | |
| Theorem progress : forall t T,
 | |
|      has_type empty t T ->
 | |
|      value t \/ exists t', t ==> t'.
 | |
| Proof.
 | |
| intros t T.
 | |
| intros H.
 | |
| remember (@empty ty) as Gamma.
 | |
| induction H.
 | |
|  rewrite HeqGamma in H.
 | |
|  unfold empty in H.
 | |
|  inversion H.
 | |
|  
 | |
|  left.
 | |
|  apply v_abs.
 | |
|  
 | |
|  right.
 | |
|  assert (value t1 \/ (exists t' : tm, t1 ==> t')).
 | |
|   apply IHhas_type1.
 | |
|   assumption.
 | |
|   
 | |
|   assert (value t2 \/ (exists t' : tm, t2 ==> t')).
 | |
|    apply IHhas_type2.
 | |
|    assumption.
 | |
|    
 | |
|    inversion H1.
 | |
|     inversion H2.
 | |
|      inversion H3.
 | |
|       subst.
 | |
|       exists (subst t2 x t).
 | |
|       apply ST_AppAbs.
 | |
|       assumption.
 | |
|       
 | |
|       subst.
 | |
|       inversion H.
 | |
|       
 | |
|       subst.
 | |
|       inversion H.
 | |
|       
 | |
|      inversion H4.
 | |
|      exists (tm_app t1 x).
 | |
|      apply ST_App2.
 | |
|       assumption.
 | |
|       
 | |
|       assumption.
 | |
|       
 | |
|     inversion H3.
 | |
|     exists (tm_app x t2).
 | |
|     apply ST_App1.
 | |
|     assumption.
 | |
|     
 | |
|  left.
 | |
|  auto.
 | |
|  
 | |
|  left.
 | |
|  auto.
 | |
|  
 | |
|  right.
 | |
|  assert (value t1 \/ (exists t' : tm, t1 ==> t')).
 | |
|   apply IHhas_type1.
 | |
|   assumption.
 | |
|   
 | |
|   inversion H2.
 | |
|    inversion H3.
 | |
|     subst.
 | |
|     inversion H.
 | |
|     
 | |
|     subst.
 | |
|     exists t2.
 | |
|     apply ST_IfTrue.
 | |
|     
 | |
|     subst.
 | |
|     exists t3.
 | |
|     apply ST_IfFalse.
 | |
|     
 | |
|    inversion H3.
 | |
|    exists (tm_if x t2 t3).
 | |
|    apply ST_If.
 | |
|    assumption.
 | |
| Qed.
 | |
| 
 | |
| Theorem progress' : forall t T,
 | |
|      has_type empty t T ->
 | |
|      value t \/ exists t', t ==> t'.
 | |
| Proof.
 | |
| intros t.
 | |
| tm_cases (induction t) Case; intros T Ht; auto.
 | |
|  inversion Ht.
 | |
|  inversion H1.
 | |
|  
 | |
|  right.
 | |
|  inversion Ht.
 | |
|  subst.
 | |
|  assert (value t1 \/ (exists t' : tm, t1 ==> t')).
 | |
|   apply IHt1 with (T := ty_arrow T11 T).
 | |
|   assumption.
 | |
|   
 | |
|   assert (value t2 \/ (exists t' : tm, t2 ==> t')).
 | |
|    apply IHt2 with T11.
 | |
|    assumption.
 | |
|    
 | |
|    inversion H.
 | |
|     inversion H1.
 | |
|      subst.
 | |
|      inversion H0.
 | |
|       exists (subst t2 x t).
 | |
|       apply ST_AppAbs.
 | |
|       assumption.
 | |
|       
 | |
|       inversion H3.
 | |
|       exists (tm_app (tm_abs x T0 t) x0).
 | |
|       apply ST_App2.
 | |
|        assumption.
 | |
|        
 | |
|        assumption.
 | |
|        
 | |
|      subst.
 | |
|      inversion H2.
 | |
|      
 | |
|      subst.
 | |
|      inversion H2.
 | |
|      
 | |
|     inversion H1.
 | |
|     exists (tm_app x t2).
 | |
|     apply ST_App1.
 | |
|     assumption.
 | |
|     
 | |
|  right.
 | |
|  inversion Ht.
 | |
|  subst.
 | |
|  assert (value t1 \/ (exists t' : tm, t1 ==> t')).
 | |
|   apply IHt1 with ty_Bool.
 | |
|   assumption.
 | |
|   
 | |
|   assert (value t2 \/ (exists t' : tm, t2 ==> t')).
 | |
|    apply IHt2 with T.
 | |
|    assumption.
 | |
|    
 | |
|    assert (value t3 \/ (exists t' : tm, t3 ==> t')).
 | |
|     apply IHt3 with T.
 | |
|     assumption.
 | |
|     
 | |
|     inversion H.
 | |
|      inversion H2.
 | |
|       subst.
 | |
|       inversion H3.
 | |
|       
 | |
|       subst.
 | |
|       subst.
 | |
|       exists t2.
 | |
|       apply ST_IfTrue.
 | |
|       
 | |
|       exists t3.
 | |
|       apply ST_IfFalse.
 | |
|       
 | |
|      inversion H2.
 | |
|      exists (tm_if x t2 t3).
 | |
|      apply ST_If.
 | |
|      assumption.
 | |
| Qed.
 | |
| 
 | |
| Theorem types_unique : forall t T Gamma,
 | |
|    has_type Gamma t T ->
 | |
|       (forall T', has_type Gamma t T' -> T' = T).
 | |
| Proof.
 | |
| intros t T Gamma H.
 | |
| induction H.
 | |
|  intros T'.
 | |
|  intros H1.
 | |
|  inversion H1.
 | |
|  subst.
 | |
|  subst.
 | |
|  auto.
 | |
|  eauto   .
 | |
|  inversion H1.
 | |
|  subst.
 | |
|  assert (Some T = Some T').
 | |
|   rewrite <- H3.
 | |
|   rewrite <- H.
 | |
|   reflexivity.
 | |
|   
 | |
|   inversion H0.
 | |
|   reflexivity.
 | |
|   
 | |
|  intros T'.
 | |
|  intros H1.
 | |
|  inversion H1.
 | |
|  subst.
 | |
|  assert (T1 = T12).
 | |
|   apply IHhas_type.
 | |
|   assumption.
 | |
|   
 | |
|   rewrite H0.
 | |
|   reflexivity.
 | |
|   
 | |
|  intros T' H1.
 | |
|  subst.
 | |
|  inversion H1.
 | |
|  subst.
 | |
|  assert (ty_arrow T0 T' = ty_arrow T11 T12).
 | |
|   apply IHhas_type1.
 | |
|   assumption.
 | |
|   
 | |
|   inversion H2.
 | |
|   reflexivity.
 | |
|   
 | |
|  intros T'.
 | |
|  intros H.
 | |
|  inversion H.
 | |
|  reflexivity.
 | |
|  
 | |
|  intros.
 | |
|  inversion H.
 | |
|  reflexivity.
 | |
|  
 | |
|  intros T'.
 | |
|  intros H2.
 | |
|  inversion H2.
 | |
|  subst.
 | |
|  apply IHhas_type2.
 | |
|  assumption.
 | |
| Qed. |