mirror of
				https://github.com/KevinMidboe/linguist.git
				synced 2025-10-29 17:50:22 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			702 lines
		
	
	
		
			15 KiB
		
	
	
	
		
			Coq
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			702 lines
		
	
	
		
			15 KiB
		
	
	
	
		
			Coq
		
	
	
		
			Executable File
		
	
	
	
	
Require Export Imp.
 | 
						|
Require Export Relations.
 | 
						|
 | 
						|
Inductive tm : Type :=
 | 
						|
   | tm_const : nat -> tm
 | 
						|
   | tm_plus : tm -> tm -> tm.
 | 
						|
 | 
						|
Tactic Notation "tm_cases" tactic(first) ident(c) :=
 | 
						|
   first;
 | 
						|
   [ Case_aux c "tm_const" | Case_aux c "tm_plus" ].
 | 
						|
 | 
						|
Module SimpleArith0.
 | 
						|
 | 
						|
Fixpoint eval (t : tm) : nat :=
 | 
						|
   match t with
 | 
						|
      | tm_const n => n
 | 
						|
      | tm_plus a1 a2 => eval a1 + eval a2
 | 
						|
   end.
 | 
						|
 | 
						|
End SimpleArith0.
 | 
						|
 | 
						|
Module SimpleArith1.
 | 
						|
 | 
						|
Reserved Notation " t '===>' n " (at level 50, left associativity).
 | 
						|
 | 
						|
Inductive eval : tm -> nat -> Prop :=
 | 
						|
   | E_Const : forall n,
 | 
						|
                  tm_const n ===> n
 | 
						|
   | E_Plus : forall t1 t2 n1 n2,
 | 
						|
                  t1 ===> n1 ->
 | 
						|
                  t2 ===> n2 ->
 | 
						|
                  tm_plus t1 t2 ===> plus n1 n2
 | 
						|
 | 
						|
     where " t '===>' n " := (eval t n).
 | 
						|
 | 
						|
End SimpleArith1.
 | 
						|
 | 
						|
Reserved Notation " t '===>' t' " (at level 50, left associativity).
 | 
						|
 | 
						|
Inductive eval : tm -> tm -> Prop :=
 | 
						|
   | E_Const : forall n1,
 | 
						|
      tm_const n1 ===> tm_const n1
 | 
						|
   | E_Plus : forall t1 n1 t2 n2,
 | 
						|
      t1 ===> tm_const n1 ->
 | 
						|
      t2 ===> tm_const n2 ->
 | 
						|
         tm_plus t1 t2 ===> tm_const (plus n1 n2)
 | 
						|
   where " t '===>' t' " := (eval t t').
 | 
						|
 | 
						|
Tactic Notation "eval_cases" tactic(first) ident(c) :=
 | 
						|
   first;
 | 
						|
   [ Case_aux c "E_Const" | Case_aux c "E_Plus" ].
 | 
						|
 | 
						|
Module SimpleArith2.
 | 
						|
 | 
						|
Reserved Notation " t '=>' t' " (at level 40).
 | 
						|
 | 
						|
Inductive step : tm -> tm -> Prop :=
 | 
						|
   | ST_PlusConstConst : forall n1 n2,
 | 
						|
      tm_plus (tm_const n1) (tm_const n2) => tm_const (plus n1 n2)
 | 
						|
   | ST_Plus1 : forall t1 t1' t2,
 | 
						|
      t1 => t1' ->
 | 
						|
         tm_plus t1 t2 => tm_plus t1' t2
 | 
						|
   | ST_Plus2 : forall n1 t2 t2',
 | 
						|
      t2 => t2' ->
 | 
						|
      tm_plus (tm_const n1) t2 => tm_plus (tm_const n1) t2'
 | 
						|
 | 
						|
   where " t '=>' t' " := (step t t').
 | 
						|
 | 
						|
Tactic Notation "step_cases" tactic(first) ident(c) :=
 | 
						|
   first;
 | 
						|
   [ Case_aux c "ST_PlusConstConst"
 | 
						|
   | Case_aux c "ST_Plus1" | Case_aux c "ST_Plus2" ].
 | 
						|
 | 
						|
Example test_step_1 : 
 | 
						|
      tm_plus 
 | 
						|
        (tm_plus (tm_const 0) (tm_const 3))
 | 
						|
        (tm_plus (tm_const 2) (tm_const 4))
 | 
						|
      =>
 | 
						|
      tm_plus 
 | 
						|
        (tm_const (plus 0 3))
 | 
						|
        (tm_plus (tm_const 2) (tm_const 4)).
 | 
						|
Proof.
 | 
						|
  apply ST_Plus1. apply ST_PlusConstConst. Qed.
 | 
						|
 | 
						|
Example test_step_2 : 
 | 
						|
      tm_plus 
 | 
						|
        (tm_const 0)
 | 
						|
        (tm_plus 
 | 
						|
          (tm_const 2) 
 | 
						|
          (tm_plus (tm_const 0) (tm_const 3)))
 | 
						|
      =>
 | 
						|
      tm_plus 
 | 
						|
        (tm_const 0)
 | 
						|
        (tm_plus 
 | 
						|
          (tm_const 2) 
 | 
						|
          (tm_const (plus 0 3))).
 | 
						|
Proof.
 | 
						|
apply ST_Plus2.
 | 
						|
simpl.
 | 
						|
apply ST_Plus2.
 | 
						|
apply ST_PlusConstConst.
 | 
						|
Qed.
 | 
						|
 | 
						|
Theorem step_deterministic:
 | 
						|
  partial_function step.
 | 
						|
Proof.
 | 
						|
  unfold partial_function. intros x y1 y2 Hy1 Hy2.
 | 
						|
  generalize dependent y2.
 | 
						|
  step_cases (induction Hy1) Case; intros y2 Hy2.
 | 
						|
    Case "ST_PlusConstConst". step_cases (inversion Hy2) SCase.
 | 
						|
      SCase "ST_PlusConstConst". reflexivity.
 | 
						|
      SCase "ST_Plus1". inversion H2.
 | 
						|
      SCase "ST_Plus2". inversion H2.
 | 
						|
    Case "ST_Plus1". step_cases (inversion Hy2) SCase.
 | 
						|
      SCase "ST_PlusConstConst". rewrite <- H0 in Hy1. inversion Hy1.
 | 
						|
      SCase "ST_Plus1".
 | 
						|
        rewrite <- (IHHy1 t1'0).
 | 
						|
        reflexivity. assumption.
 | 
						|
      SCase "ST_Plus2". rewrite <- H in Hy1. inversion Hy1.
 | 
						|
    Case "ST_Plus2". step_cases (inversion Hy2) SCase.
 | 
						|
      SCase "ST_PlusConstConst". rewrite <- H1 in Hy1. inversion Hy1.
 | 
						|
      SCase "ST_Plus1". inversion H2.
 | 
						|
      SCase "ST_Plus2".
 | 
						|
        rewrite <- (IHHy1 t2'0).
 | 
						|
        reflexivity. assumption. Qed.
 | 
						|
 | 
						|
End SimpleArith2.
 | 
						|
 | 
						|
Inductive value : tm -> Prop :=
 | 
						|
   v_const: forall n, value (tm_const n).
 | 
						|
 | 
						|
Reserved Notation " t '=>' t' " (at level 40).
 | 
						|
 | 
						|
Inductive step : tm -> tm -> Prop :=
 | 
						|
   | ST_PlusConstConst : forall n1 n2,
 | 
						|
      tm_plus (tm_const n1) (tm_const n2)
 | 
						|
         => tm_const (plus n1 n2)
 | 
						|
   | ST_Plus1 : forall t1 t1' t2,
 | 
						|
      t1 => t1' ->
 | 
						|
         tm_plus t1 t2 => tm_plus t1' t2
 | 
						|
   | ST_Plus2 : forall v1 t2 t2',
 | 
						|
      value v1 ->
 | 
						|
         t2 => t2' ->
 | 
						|
            tm_plus v1 t2 => tm_plus v1 t2'
 | 
						|
 | 
						|
   where " t '=>' t' " := (step t t').
 | 
						|
 | 
						|
Tactic Notation "step_cases" tactic(first) ident(c) :=
 | 
						|
   first;
 | 
						|
   [ Case_aux c "ST_PlusConstConst"
 | 
						|
      | Case_aux c "ST_Plus1" | Case_aux c "ST_Plus2" ].
 | 
						|
 | 
						|
Theorem step_deterministic :
 | 
						|
   partial_function step.
 | 
						|
Proof.
 | 
						|
unfold partial_function.
 | 
						|
intros x y1 y2 Hy1 Hy2.
 | 
						|
generalize dependent y2.
 | 
						|
step_cases (induction Hy1) Case; intros y2 Hy2.
 | 
						|
 step_cases (inversion Hy2) SCase.
 | 
						|
  reflexivity.
 | 
						|
  
 | 
						|
  inversion H2.
 | 
						|
  
 | 
						|
  inversion Hy2.
 | 
						|
   subst.
 | 
						|
   assumption.
 | 
						|
   
 | 
						|
   subst.
 | 
						|
   inversion H3.
 | 
						|
   
 | 
						|
   subst.
 | 
						|
   inversion H3.
 | 
						|
   
 | 
						|
 step_cases (inversion Hy2) SCase.
 | 
						|
  rewrite <- H0 in Hy1.
 | 
						|
  inversion Hy1.
 | 
						|
  
 | 
						|
  rewrite <- (IHHy1 t1'0).
 | 
						|
   reflexivity.
 | 
						|
   
 | 
						|
   assumption.
 | 
						|
   
 | 
						|
  rewrite <- H in Hy1.
 | 
						|
  rewrite <- H in H1.
 | 
						|
  subst.
 | 
						|
  inversion H1.
 | 
						|
  subst.
 | 
						|
  inversion Hy1.
 | 
						|
  
 | 
						|
 step_cases (inversion Hy2) SCase.
 | 
						|
  subst.
 | 
						|
  inversion Hy1.
 | 
						|
  
 | 
						|
  subst.
 | 
						|
  inversion H.
 | 
						|
  subst.
 | 
						|
  inversion H3.
 | 
						|
  
 | 
						|
  subst.
 | 
						|
  inversion H2.
 | 
						|
  subst.
 | 
						|
  rewrite <- (IHHy1 t2'0).
 | 
						|
   reflexivity.
 | 
						|
   
 | 
						|
   assumption.
 | 
						|
Qed.
 | 
						|
 | 
						|
Theorem strong_progress : forall t,
 | 
						|
        value t \/ (exists t', t => t').
 | 
						|
Proof.
 | 
						|
   tm_cases (induction t) Case.
 | 
						|
      Case "tm_const". left. apply v_const.
 | 
						|
      Case "tm_plus". right. inversion IHt1.
 | 
						|
         SCase "l". inversion IHt2.
 | 
						|
            SSCase "l". inversion H. inversion H0.
 | 
						|
               exists (tm_const (plus n n0)).
 | 
						|
               apply ST_PlusConstConst.
 | 
						|
            SSCase "r". inversion H0 as [t' H1].
 | 
						|
               exists (tm_plus t1 t').
 | 
						|
               apply ST_Plus2. apply H. apply H1.
 | 
						|
         SCase "r". inversion H as [t' H0].
 | 
						|
            exists (tm_plus t' t2).
 | 
						|
            apply ST_Plus1. apply H0. Qed.
 | 
						|
 | 
						|
Definition normal_form {X:Type} (R: relation X) (t: X) : Prop :=
 | 
						|
    ~ (exists t', R t t'). 
 | 
						|
 | 
						|
Lemma value_is_nf: forall t,
 | 
						|
      value t -> normal_form step t.
 | 
						|
Proof.
 | 
						|
   unfold normal_form. intros t H. inversion H.
 | 
						|
   intros contra. inversion contra. inversion H1.
 | 
						|
   Qed.
 | 
						|
 | 
						|
Lemma nf_is_value: forall t,
 | 
						|
      normal_form step t -> value t.
 | 
						|
Proof.
 | 
						|
   unfold normal_form. intros t H.
 | 
						|
   assert (G: value t \/ (exists t', t => t')).
 | 
						|
      SCase "Proof of assertion". apply strong_progress.
 | 
						|
   inversion G.
 | 
						|
      SCase "l". assumption.
 | 
						|
      SCase "r". apply ex_falso_quodlibet. apply H. assumption. Qed.
 | 
						|
 | 
						|
Corollary nf_same_as_value : forall t,
 | 
						|
            normal_form step t <-> value t.
 | 
						|
Proof.
 | 
						|
   split. apply nf_is_value. apply value_is_nf.
 | 
						|
Qed.
 | 
						|
 | 
						|
Module Temp1.
 | 
						|
 | 
						|
Inductive value : tm -> Prop :=
 | 
						|
| v_const : forall n, value (tm_const n)
 | 
						|
| v_funny : forall t1 n2, (* <---- *)
 | 
						|
              value (tm_plus t1 (tm_const n2)).
 | 
						|
 | 
						|
Reserved Notation " t '=>' t' " (at level 40).
 | 
						|
 | 
						|
Inductive step : tm -> tm -> Prop :=
 | 
						|
  | ST_PlusConstConst : forall n1 n2,
 | 
						|
      tm_plus (tm_const n1) (tm_const n2) => tm_const (plus n1 n2)
 | 
						|
  | ST_Plus1 : forall t1 t1' t2,
 | 
						|
      t1 => t1' ->
 | 
						|
      tm_plus t1 t2 => tm_plus t1' t2
 | 
						|
  | ST_Plus2 : forall v1 t2 t2',
 | 
						|
      value v1 ->
 | 
						|
      t2 => t2' ->
 | 
						|
      tm_plus v1 t2 => tm_plus v1 t2'
 | 
						|
 | 
						|
  where " t '=>' t' " := (step t t').
 | 
						|
 | 
						|
Lemma value_not_same_as_normal_form:
 | 
						|
   exists t, value t /\ ~ normal_form step t.
 | 
						|
Proof.
 | 
						|
intros.
 | 
						|
unfold normal_form.
 | 
						|
exists (tm_plus (tm_plus (tm_const 1) (tm_const 2)) (tm_const 2)).
 | 
						|
split.
 | 
						|
 apply v_funny.
 | 
						|
 
 | 
						|
 unfold not.
 | 
						|
 intros.
 | 
						|
 apply H.
 | 
						|
 exists (tm_plus (tm_const (1 + 2)) (tm_const 2)).
 | 
						|
 apply ST_Plus1.
 | 
						|
 apply ST_PlusConstConst.
 | 
						|
Qed.
 | 
						|
 | 
						|
End Temp1.
 | 
						|
 | 
						|
Module Temp2.
 | 
						|
 | 
						|
Inductive value : tm -> Prop :=
 | 
						|
   | v_const : forall n, value (tm_const n).
 | 
						|
 | 
						|
(*Reserved Notation " t '===>' t' " (at level 40).*)
 | 
						|
 | 
						|
Inductive step : tm -> tm -> Prop :=
 | 
						|
  | ST_Funny : forall n, (* <---- *)
 | 
						|
      tm_const n ===> tm_plus (tm_const n) (tm_const 0)
 | 
						|
  | ST_PlusConstConst : forall n1 n2,
 | 
						|
      tm_plus (tm_const n1) (tm_const n2) ===> tm_const (plus n1 n2)
 | 
						|
  | ST_Plus1 : forall t1 t1' t2,
 | 
						|
      t1 ===> t1' ->
 | 
						|
      tm_plus t1 t2 ===> tm_plus t1' t2
 | 
						|
  | ST_Plus2 : forall v1 t2 t2',
 | 
						|
      value v1 ->
 | 
						|
      t2 ===> t2' ->
 | 
						|
      tm_plus v1 t2 ===> tm_plus v1 t2'
 | 
						|
 | 
						|
  where " t '===>' t' " := (step t t').
 | 
						|
 | 
						|
Lemma value_not_same_as_normal_form :
 | 
						|
  exists t, value t /\ ~ normal_form step t.
 | 
						|
Proof.
 | 
						|
exists (tm_const 0).
 | 
						|
split.
 | 
						|
 apply v_const.
 | 
						|
 
 | 
						|
 unfold normal_form.
 | 
						|
 unfold not.
 | 
						|
 intro H.
 | 
						|
 apply H.
 | 
						|
 exists (tm_plus (tm_const 0) (tm_const 0)).
 | 
						|
 apply ST_Funny.
 | 
						|
Qed.
 | 
						|
 | 
						|
End Temp2.
 | 
						|
 | 
						|
Module Temp3.
 | 
						|
 | 
						|
Inductive value : tm -> Prop :=
 | 
						|
  | v_const : forall n, value (tm_const n).
 | 
						|
 | 
						|
(*Reserved Notation " t '===>' t' " (at level 40).*)
 | 
						|
 | 
						|
Inductive step : tm -> tm -> Prop :=
 | 
						|
  | ST_PlusConstConst : forall n1 n2,
 | 
						|
      tm_plus (tm_const n1) (tm_const n2) ===> tm_const (plus n1 n2)
 | 
						|
  | ST_Plus1 : forall t1 t1' t2,
 | 
						|
      t1 ===> t1' ->
 | 
						|
      tm_plus t1 t2 ===> tm_plus t1' t2
 | 
						|
 | 
						|
  where " t '===>' t' " := (step t t').
 | 
						|
 | 
						|
Lemma value_not_same_as_normal_form:
 | 
						|
   exists t, ~ value t /\ normal_form step t.
 | 
						|
Proof.
 | 
						|
exists (tm_plus (tm_const 1) (tm_plus (tm_const 0) (tm_const 0))).
 | 
						|
split.
 | 
						|
 intros H.
 | 
						|
 inversion H.
 | 
						|
 
 | 
						|
 unfold normal_form.
 | 
						|
 intros H.
 | 
						|
 inversion H.
 | 
						|
 inversion H0.
 | 
						|
 inversion H4.
 | 
						|
Qed.
 | 
						|
 | 
						|
End Temp3.
 | 
						|
 | 
						|
Module Temp4.
 | 
						|
Inductive tm : Type :=
 | 
						|
   | tm_true : tm
 | 
						|
   | tm_false : tm
 | 
						|
   | tm_if : tm -> tm -> tm -> tm.
 | 
						|
 | 
						|
Inductive value : tm -> Prop :=
 | 
						|
   | v_true : value tm_true
 | 
						|
   | v_false : value tm_false.
 | 
						|
 | 
						|
Inductive step : tm -> tm -> Prop :=
 | 
						|
   | 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 " t '===>' t' " := (step t t').
 | 
						|
 | 
						|
Example bool_step_prop3 :
 | 
						|
     tm_if
 | 
						|
       (tm_if tm_true tm_true tm_true)
 | 
						|
       (tm_if tm_true tm_true tm_true)
 | 
						|
       tm_false
 | 
						|
   ===>
 | 
						|
     tm_if
 | 
						|
       tm_true
 | 
						|
       (tm_if tm_true tm_true tm_true)
 | 
						|
       tm_false.
 | 
						|
Proof.
 | 
						|
apply ST_If.
 | 
						|
apply ST_IfTrue.
 | 
						|
Qed.
 | 
						|
 | 
						|
Theorem strong_progress: forall t,
 | 
						|
        value t \/ (exists t', t ===> t').
 | 
						|
Proof.
 | 
						|
induction t.
 | 
						|
 left.
 | 
						|
 constructor.
 | 
						|
 
 | 
						|
 left.
 | 
						|
 constructor.
 | 
						|
 
 | 
						|
 right.
 | 
						|
 inversion IHt1.
 | 
						|
  inversion H.
 | 
						|
   exists t2.
 | 
						|
   apply ST_IfTrue.
 | 
						|
   
 | 
						|
   exists t3.
 | 
						|
   apply ST_IfFalse.
 | 
						|
   
 | 
						|
  inversion H.
 | 
						|
  exists (tm_if x t2 t3).
 | 
						|
  apply ST_If.
 | 
						|
  assumption.
 | 
						|
Qed.
 | 
						|
 | 
						|
Theorem step_deterministic :
 | 
						|
  partial_function step.
 | 
						|
Proof.
 | 
						|
unfold partial_function.
 | 
						|
intros x y1 y2 Hy1 Hy2.
 | 
						|
generalize dependent y2.
 | 
						|
induction Hy1.
 | 
						|
 intros.
 | 
						|
 inversion Hy2.
 | 
						|
  reflexivity.
 | 
						|
  
 | 
						|
  subst.
 | 
						|
  inversion H3.
 | 
						|
  
 | 
						|
 intros.
 | 
						|
 inversion Hy2.
 | 
						|
  reflexivity.
 | 
						|
  
 | 
						|
  inversion H3.
 | 
						|
  
 | 
						|
 intros.
 | 
						|
 inversion Hy2.
 | 
						|
  subst.
 | 
						|
  inversion Hy1.
 | 
						|
  
 | 
						|
  subst.
 | 
						|
  inversion Hy1.
 | 
						|
  
 | 
						|
  subst.
 | 
						|
  apply IHHy1 in H3.
 | 
						|
  subst.
 | 
						|
  reflexivity.
 | 
						|
Qed.
 | 
						|
 | 
						|
Module Temp5.
 | 
						|
 | 
						|
 | 
						|
Inductive step : tm -> tm -> Prop :=
 | 
						|
   | 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
 | 
						|
   | ST_ShortCut : forall v t,
 | 
						|
      value v ->
 | 
						|
         tm_if t v v ===> v
 | 
						|
 | 
						|
   where " t '===>' t' " := (step t t').
 | 
						|
 | 
						|
Definition bool_step_prop4 :=
 | 
						|
         tm_if
 | 
						|
            (tm_if tm_true tm_true tm_true)
 | 
						|
            tm_false
 | 
						|
            tm_false
 | 
						|
     ===>
 | 
						|
         tm_false.
 | 
						|
 | 
						|
Example bool_step_prop4_holds : 
 | 
						|
  bool_step_prop4.
 | 
						|
Proof.
 | 
						|
   unfold bool_step_prop4.
 | 
						|
   apply ST_ShortCut.
 | 
						|
   constructor.
 | 
						|
Qed.
 | 
						|
 | 
						|
Theorem strong_progress: forall t,
 | 
						|
        value t \/ (exists t', t ===> t').
 | 
						|
Proof.
 | 
						|
   induction t.
 | 
						|
 left.
 | 
						|
 constructor.
 | 
						|
 
 | 
						|
 left.
 | 
						|
 constructor.
 | 
						|
 
 | 
						|
 inversion IHt1.
 | 
						|
  right.
 | 
						|
  inversion H.
 | 
						|
   exists t2.
 | 
						|
   constructor.
 | 
						|
   
 | 
						|
   exists t3.
 | 
						|
   constructor.
 | 
						|
   
 | 
						|
  right.
 | 
						|
  inversion H.
 | 
						|
  exists (tm_if x t2 t3).
 | 
						|
  apply ST_If.
 | 
						|
  assumption.
 | 
						|
Qed.
 | 
						|
 | 
						|
End Temp5.
 | 
						|
End Temp4.
 | 
						|
 | 
						|
Definition stepmany := refl_step_closure step.
 | 
						|
 | 
						|
Notation " t '===>*' t' " := (stepmany t t') (at level 40).
 | 
						|
 | 
						|
Lemma test_stepmany_1:
 | 
						|
   tm_plus
 | 
						|
      (tm_plus (tm_const 0) (tm_const 3))
 | 
						|
      (tm_plus (tm_const 2) (tm_const 4))
 | 
						|
      ===>*
 | 
						|
         tm_const (plus (plus 0 3) (plus 2 4)).
 | 
						|
Proof.
 | 
						|
   eapply rsc_step. apply ST_Plus1. apply ST_PlusConstConst.
 | 
						|
  eapply rsc_step. apply ST_Plus2. apply v_const.
 | 
						|
  apply ST_PlusConstConst.
 | 
						|
  eapply rsc_step. apply ST_PlusConstConst.
 | 
						|
  apply rsc_refl. Qed.
 | 
						|
 | 
						|
Lemma test_stepmany_2:
 | 
						|
   tm_const 3 ===>* tm_const 3.
 | 
						|
Proof.
 | 
						|
   eapply rsc_refl.
 | 
						|
Qed.
 | 
						|
 | 
						|
Lemma test_stepmany_3:
 | 
						|
   tm_plus (tm_const 0) (tm_const 3)
 | 
						|
      ===>*
 | 
						|
   tm_plus (tm_const 0) (tm_const 3).
 | 
						|
Proof.
 | 
						|
   eapply rsc_refl.
 | 
						|
Qed.
 | 
						|
 | 
						|
Lemma test_stepmany_4:
 | 
						|
   tm_plus
 | 
						|
      (tm_const 0)
 | 
						|
      (tm_plus
 | 
						|
         (tm_const 2)
 | 
						|
         (tm_plus (tm_const 0) (tm_const 3)))
 | 
						|
   ===>*
 | 
						|
      tm_plus
 | 
						|
         (tm_const 0)
 | 
						|
         (tm_const (plus 2 (plus 0 3))).
 | 
						|
Proof.
 | 
						|
eapply rsc_step.
 | 
						|
 apply ST_Plus2.
 | 
						|
  apply v_const.
 | 
						|
  
 | 
						|
  apply ST_Plus2.
 | 
						|
   apply v_const.
 | 
						|
   
 | 
						|
   apply ST_PlusConstConst.
 | 
						|
   
 | 
						|
 eapply rsc_step.
 | 
						|
  apply ST_Plus2.
 | 
						|
   apply v_const.
 | 
						|
   
 | 
						|
   apply ST_PlusConstConst.
 | 
						|
   
 | 
						|
  eapply rsc_refl.
 | 
						|
Qed.
 | 
						|
 | 
						|
Definition step_normal_form := normal_form step.
 | 
						|
 | 
						|
Definition normal_form_of (t t' : tm) :=
 | 
						|
  (t ===>* t' /\ step_normal_form t').
 | 
						|
 | 
						|
   (*
 | 
						|
Theorem normal_forms_unique:
 | 
						|
   partial_function normal_form_of.
 | 
						|
Proof.
 | 
						|
   unfold partial_function. unfold normal_form_of. intros x y1 y2 P1 P2.
 | 
						|
   destruct P1 as [P11 P12]. destruct P2 as [P21 P22].
 | 
						|
   generalize dependent y2.
 | 
						|
 | 
						|
   unfold step_normal_form in P12.
 | 
						|
   unfold step_normal_form.
 | 
						|
   unfold normal_form.
 | 
						|
   unfold normal_form in P12.
 | 
						|
   induction x.
 | 
						|
   intros.
 | 
						|
   unfold stepmany.
 | 
						|
   inversion P11.
 | 
						|
   subst.
 | 
						|
   inversion P21.
 | 
						|
   subst.
 | 
						|
   reflexivity.
 | 
						|
 | 
						|
   subst.
 | 
						|
   inversion P21.
 | 
						|
   reflexivity.
 | 
						|
 | 
						|
   subst.
 | 
						|
   inversion H1.
 | 
						|
 | 
						|
   inversion H.
 | 
						|
   *)
 | 
						|
 | 
						|
Definition normalizing {X:Type} (R:relation X) :=
 | 
						|
     forall t, exists t',
 | 
						|
         (refl_step_closure R) t t' /\ normal_form R t'.
 | 
						|
 | 
						|
Lemma stepmany_congr_1 : forall t1 t1' t2,
 | 
						|
      t1 ===>* t1' ->
 | 
						|
         tm_plus t1 t2 ===>* tm_plus t1' t2.
 | 
						|
Proof.
 | 
						|
intros t1 t1' t2 H.
 | 
						|
rsc_cases (induction H) Case.
 | 
						|
 apply rsc_refl.
 | 
						|
  
 | 
						|
  apply rsc_step with (tm_plus y t2).
 | 
						|
    apply ST_Plus1.
 | 
						|
      apply H.
 | 
						|
        
 | 
						|
        apply IHrefl_step_closure.
 | 
						|
Qed.
 | 
						|
 | 
						|
Lemma stepmany_congr2 : forall t1 t2 t2',
 | 
						|
      value t1 ->
 | 
						|
         t2 ===>* t2' ->
 | 
						|
            tm_plus t1 t2 ===>* tm_plus t1 t2'.
 | 
						|
Proof.
 | 
						|
intros t1 t2 t2'.
 | 
						|
intros H1.
 | 
						|
intros H2.
 | 
						|
induction H2.
 | 
						|
 apply rsc_refl.
 | 
						|
  
 | 
						|
  apply rsc_step with (tm_plus t1 y).
 | 
						|
    apply ST_Plus2.
 | 
						|
       assumption.
 | 
						|
          
 | 
						|
          assumption.
 | 
						|
             
 | 
						|
            assumption.
 | 
						|
Qed.
 | 
						|
 | 
						|
Theorem step_normalizing :
 | 
						|
  normalizing step.
 | 
						|
Proof.
 | 
						|
  unfold normalizing.
 | 
						|
  tm_cases (induction t) Case.
 | 
						|
    Case "tm_const".
 | 
						|
      exists (tm_const n).
 | 
						|
      split.
 | 
						|
      SCase "l". apply rsc_refl.
 | 
						|
      SCase "r".
 | 
						|
        (* We can use rewrite with "iff" statements, not
 | 
						|
           just equalities: *)
 | 
						|
        rewrite nf_same_as_value. apply v_const.
 | 
						|
    Case "tm_plus".
 | 
						|
      destruct IHt1 as [t1' H1]. destruct IHt2 as [t2' H2].
 | 
						|
      destruct H1 as [H11 H12]. destruct H2 as [H21 H22].
 | 
						|
      rewrite nf_same_as_value in H12. rewrite nf_same_as_value in H22.
 | 
						|
      inversion H12 as [n1]. inversion H22 as [n2].
 | 
						|
      rewrite <- H in H11.
 | 
						|
      rewrite <- H0 in H21.
 | 
						|
      exists (tm_const (plus n1 n2)).
 | 
						|
      split.
 | 
						|
        SCase "l".
 | 
						|
          apply rsc_trans with (tm_plus (tm_const n1) t2).
 | 
						|
          apply stepmany_congr_1. apply H11.
 | 
						|
          apply rsc_trans with 
 | 
						|
             (tm_plus (tm_const n1) (tm_const n2)).
 | 
						|
          apply stepmany_congr2. apply v_const. apply H21.
 | 
						|
          apply rsc_R. apply ST_PlusConstConst.
 | 
						|
        SCase "r".
 | 
						|
          rewrite nf_same_as_value. apply v_const. Qed.
 | 
						|
          
 | 
						|
 Lemma eval__value : forall t1 t2,
 | 
						|
      eval t1 t2 ->
 | 
						|
      value t2.
 | 
						|
 Proof.
 | 
						|
   intros t1 t2 HE.
 | 
						|
   eval_cases (inversion HE) Case; apply v_const. Qed.
 | 
						|
   
 | 
						|
 | 
						|
   (*
 | 
						|
Theorem eval__stepmany: forall t v,
 | 
						|
  eval t v -> t ===>* v.
 | 
						|
Proof.   
 | 
						|
*)
 |