src/HOL/Induct/Com.thy
changeset 23746 a455e69c31cc
parent 19736 d8d0f8f51d69
child 24178 4ff1dc2aa18d
equal deleted inserted replaced
23745:28df61d931e2 23746:a455e69c31cc
    12 
    12 
    13 typedecl loc
    13 typedecl loc
    14 
    14 
    15 types  state = "loc => nat"
    15 types  state = "loc => nat"
    16        n2n2n = "nat => nat => nat"
    16        n2n2n = "nat => nat => nat"
    17 
       
    18 arities loc :: type
       
    19 
    17 
    20 datatype
    18 datatype
    21   exp = N nat
    19   exp = N nat
    22       | X loc
    20       | X loc
    23       | Op n2n2n exp exp
    21       | Op n2n2n exp exp
    31 
    29 
    32 
    30 
    33 subsection {* Commands *}
    31 subsection {* Commands *}
    34 
    32 
    35 text{* Execution of commands *}
    33 text{* Execution of commands *}
    36 consts  exec    :: "((exp*state) * (nat*state)) set => ((com*state)*state)set"
       
    37 
       
    38 abbreviation
       
    39   exec_rel  ("_/ -[_]-> _" [50,0,50] 50)
       
    40   "csig -[eval]-> s == (csig,s) \<in> exec eval"
       
    41 
    34 
    42 abbreviation (input)
    35 abbreviation (input)
    43   generic_rel  ("_/ -|[_]-> _" [50,0,50] 50)
    36   generic_rel  ("_/ -|[_]-> _" [50,0,50] 50)  where
    44   "esig -|[eval]-> ns == (esig,ns) \<in> eval"
    37   "esig -|[eval]-> ns == (esig,ns) \<in> eval"
    45 
    38 
    46 text{*Command execution.  Natural numbers represent Booleans: 0=True, 1=False*}
    39 text{*Command execution.  Natural numbers represent Booleans: 0=True, 1=False*}
    47 inductive "exec eval"
    40 
    48   intros
    41 inductive_set
    49     Skip:    "(SKIP,s) -[eval]-> s"
    42   exec :: "((exp*state) * (nat*state)) set => ((com*state)*state)set"
    50 
    43   and exec_rel :: "com * state => ((exp*state) * (nat*state)) set => state => bool"
    51     Assign:  "(e,s) -|[eval]-> (v,s') ==> (x := e, s) -[eval]-> s'(x:=v)"
    44     ("_/ -[_]-> _" [50,0,50] 50)
    52 
    45   for eval :: "((exp*state) * (nat*state)) set"
    53     Semi:    "[| (c0,s) -[eval]-> s2; (c1,s2) -[eval]-> s1 |]
    46   where
       
    47     "csig -[eval]-> s == (csig,s) \<in> exec eval"
       
    48 
       
    49   | Skip:    "(SKIP,s) -[eval]-> s"
       
    50 
       
    51   | Assign:  "(e,s) -|[eval]-> (v,s') ==> (x := e, s) -[eval]-> s'(x:=v)"
       
    52 
       
    53   | Semi:    "[| (c0,s) -[eval]-> s2; (c1,s2) -[eval]-> s1 |]
    54              ==> (c0 ;; c1, s) -[eval]-> s1"
    54              ==> (c0 ;; c1, s) -[eval]-> s1"
    55 
    55 
    56     IfTrue: "[| (e,s) -|[eval]-> (0,s');  (c0,s') -[eval]-> s1 |]
    56   | IfTrue: "[| (e,s) -|[eval]-> (0,s');  (c0,s') -[eval]-> s1 |]
    57              ==> (IF e THEN c0 ELSE c1, s) -[eval]-> s1"
    57              ==> (IF e THEN c0 ELSE c1, s) -[eval]-> s1"
    58 
    58 
    59     IfFalse: "[| (e,s) -|[eval]->  (Suc 0, s');  (c1,s') -[eval]-> s1 |]
    59   | IfFalse: "[| (e,s) -|[eval]->  (Suc 0, s');  (c1,s') -[eval]-> s1 |]
    60               ==> (IF e THEN c0 ELSE c1, s) -[eval]-> s1"
    60               ==> (IF e THEN c0 ELSE c1, s) -[eval]-> s1"
    61 
    61 
    62     WhileFalse: "(e,s) -|[eval]-> (Suc 0, s1)
    62   | WhileFalse: "(e,s) -|[eval]-> (Suc 0, s1)
    63                  ==> (WHILE e DO c, s) -[eval]-> s1"
    63                  ==> (WHILE e DO c, s) -[eval]-> s1"
    64 
    64 
    65     WhileTrue:  "[| (e,s) -|[eval]-> (0,s1);
    65   | WhileTrue:  "[| (e,s) -|[eval]-> (0,s1);
    66                     (c,s1) -[eval]-> s2;  (WHILE e DO c, s2) -[eval]-> s3 |]
    66                     (c,s1) -[eval]-> s2;  (WHILE e DO c, s2) -[eval]-> s3 |]
    67                  ==> (WHILE e DO c, s) -[eval]-> s3"
    67                  ==> (WHILE e DO c, s) -[eval]-> s3"
    68 
    68 
    69 declare exec.intros [intro]
    69 declare exec.intros [intro]
    70 
    70 
    77     and exec_WHILE_case: "(WHILE b DO c,s) -[eval]-> t"
    77     and exec_WHILE_case: "(WHILE b DO c,s) -[eval]-> t"
    78 
    78 
    79 
    79 
    80 text{*Justifies using "exec" in the inductive definition of "eval"*}
    80 text{*Justifies using "exec" in the inductive definition of "eval"*}
    81 lemma exec_mono: "A<=B ==> exec(A) <= exec(B)"
    81 lemma exec_mono: "A<=B ==> exec(A) <= exec(B)"
    82 apply (unfold exec.defs )
    82 apply (rule subsetI)
    83 apply (rule lfp_mono)
    83 apply (simp add: split_paired_all)
    84 apply (assumption | rule basic_monos)+
    84 apply (erule exec.induct)
    85 done
    85 apply blast+
       
    86 done
       
    87 
       
    88 lemma [pred_set_conv]:
       
    89   "((\<lambda>x x' y y'. ((x, x'), (y, y')) \<in> R) <= (\<lambda>x x' y y'. ((x, x'), (y, y')) \<in> S)) = (R <= S)"
       
    90   by (auto simp add: le_fun_def le_bool_def)
       
    91 
       
    92 lemma [pred_set_conv]:
       
    93   "((\<lambda>x x' y. ((x, x'), y) \<in> R) <= (\<lambda>x x' y. ((x, x'), y) \<in> S)) = (R <= S)"
       
    94   by (auto simp add: le_fun_def le_bool_def)
    86 
    95 
    87 ML {*
    96 ML {*
    88 Unify.trace_bound := 30;
    97 Unify.trace_bound := 30;
    89 Unify.search_bound := 60;
    98 Unify.search_bound := 60;
    90 *}
    99 *}
   100 
   109 
   101 
   110 
   102 subsection {* Expressions *}
   111 subsection {* Expressions *}
   103 
   112 
   104 text{* Evaluation of arithmetic expressions *}
   113 text{* Evaluation of arithmetic expressions *}
   105 consts
   114 
       
   115 inductive_set
   106   eval    :: "((exp*state) * (nat*state)) set"
   116   eval    :: "((exp*state) * (nat*state)) set"
   107 
   117   and eval_rel :: "[exp*state,nat*state] => bool"  (infixl "-|->" 50)
   108 abbreviation
   118   where
   109   eval_rel :: "[exp*state,nat*state] => bool"         (infixl "-|->" 50)
   119     "esig -|-> ns == (esig, ns) \<in> eval"
   110   "esig -|-> ns == (esig, ns) \<in> eval"
   120 
   111 
   121   | N [intro!]: "(N(n),s) -|-> (n,s)"
   112 inductive eval
   122 
   113   intros
   123   | X [intro!]: "(X(x),s) -|-> (s(x),s)"
   114     N [intro!]: "(N(n),s) -|-> (n,s)"
   124 
   115 
   125   | Op [intro]: "[| (e0,s) -|-> (n0,s0);  (e1,s0)  -|-> (n1,s1) |]
   116     X [intro!]: "(X(x),s) -|-> (s(x),s)"
       
   117 
       
   118     Op [intro]: "[| (e0,s) -|-> (n0,s0);  (e1,s0)  -|-> (n1,s1) |]
       
   119                  ==> (Op f e0 e1, s) -|-> (f n0 n1, s1)"
   126                  ==> (Op f e0 e1, s) -|-> (f n0 n1, s1)"
   120 
   127 
   121     valOf [intro]: "[| (c,s) -[eval]-> s0;  (e,s0)  -|-> (n,s1) |]
   128   | valOf [intro]: "[| (c,s) -[eval]-> s0;  (e,s0)  -|-> (n,s1) |]
   122                     ==> (VALOF c RESULTIS e, s) -|-> (n, s1)"
   129                     ==> (VALOF c RESULTIS e, s) -|-> (n, s1)"
   123 
   130 
   124   monos exec_mono
   131   monos exec_mono
   125 
   132 
   126 
   133 
   133 
   140 
   134 lemma var_assign_eval [intro!]: "(X x, s(x:=n)) -|-> (n, s(x:=n))"
   141 lemma var_assign_eval [intro!]: "(X x, s(x:=n)) -|-> (n, s(x:=n))"
   135 by (rule fun_upd_same [THEN subst], fast)
   142 by (rule fun_upd_same [THEN subst], fast)
   136 
   143 
   137 
   144 
   138 text{* Make the induction rule look nicer -- though eta_contract makes the new
   145 text{* Make the induction rule look nicer -- though @{text eta_contract} makes the new
   139     version look worse than it is...*}
   146     version look worse than it is...*}
   140 
   147 
   141 lemma split_lemma:
   148 lemma split_lemma:
   142      "{((e,s),(n,s')). P e s n s'} = Collect (split (%v. split (split P v)))"
   149      "{((e,s),(n,s')). P e s n s'} = Collect (split (%v. split (split P v)))"
   143 by auto
   150 by auto
   165 apply (frule Int_lower1 [THEN exec_mono, THEN subsetD])
   172 apply (frule Int_lower1 [THEN exec_mono, THEN subsetD])
   166 apply (auto simp add: split_lemma)
   173 apply (auto simp add: split_lemma)
   167 done
   174 done
   168 
   175 
   169 
   176 
   170 text{*Lemma for Function_eval.  The major premise is that (c,s) executes to s1
   177 text{*Lemma for @{text Function_eval}.  The major premise is that @{text "(c,s)"} executes to @{text "s1"}
   171   using eval restricted to its functional part.  Note that the execution
   178   using eval restricted to its functional part.  Note that the execution
   172   (c,s) -[eval]-> s2 can use unrestricted eval!  The reason is that
   179   @{text "(c,s) -[eval]-> s2"} can use unrestricted @{text eval}!  The reason is that
   173   the execution (c,s) -[eval Int {...}]-> s1 assures us that execution is
   180   the execution @{text "(c,s) -[eval Int {...}]-> s1"} assures us that execution is
   174   functional on the argument (c,s).
   181   functional on the argument @{text "(c,s)"}.
   175 *}
   182 *}
   176 lemma com_Unique:
   183 lemma com_Unique:
   177  "(c,s) -[eval Int {((e,s),(n,t)). \<forall>nt'. (e,s) -|-> nt' --> (n,t)=nt'}]-> s1
   184  "(c,s) -[eval Int {((e,s),(n,t)). \<forall>nt'. (e,s) -|-> nt' --> (n,t)=nt'}]-> s1
   178   ==> \<forall>s2. (c,s) -[eval]-> s2 --> s2=s1"
   185   ==> \<forall>s2. (c,s) -[eval]-> s2 --> s2=s1"
   179 apply (induct set: exec)
   186 apply (induct set: exec)