src/HOL/Hoare/hoare_syntax.ML
changeset 74503 403ce50e6a2a
parent 72998 7ea253f93606
child 74561 8e6c973003c8
equal deleted inserted replaced
74500:40f03761f77f 74503:403ce50e6a2a
     1 (*  Title:      HOL/Hoare/hoare_syntax.ML
     1 (*  Title:      HOL/Hoare/hoare_syntax.ML
     2     Author:     Leonor Prensa Nieto & Tobias Nipkow
     2     Author:     Leonor Prensa Nieto & Tobias Nipkow
     3     Author:     Walter Guttmann (extension to total-correctness proofs)
     3     Author:     Walter Guttmann (initial extension to total-correctness proofs)
       
     4     Author:     Tobias Nipkow (complete version of total correctness with separate anno type)
     4 
     5 
     5 Syntax translations for Hoare logic.
     6 Syntax translations for Hoare logic.
     6 *)
     7 *)
     7 
     8 
     8 signature HOARE_SYNTAX =
     9 signature HOARE_SYNTAX =
    82 (* com_tr *)
    83 (* com_tr *)
    83 
    84 
    84 fun com_tr ctxt =
    85 fun com_tr ctxt =
    85   let
    86   let
    86     fun tr (Const (\<^syntax_const>\<open>_assign\<close>, _) $ x $ e) xs =
    87     fun tr (Const (\<^syntax_const>\<open>_assign\<close>, _) $ x $ e) xs =
    87           syntax_const ctxt #Basic $ mk_fexp x e xs
    88           (syntax_const ctxt #Basic $ mk_fexp x e xs, Syntax.const \<^const_syntax>\<open>Abasic\<close>)
    88       | tr (Const (\<^syntax_const>\<open>_Seq\<close>,_) $ c1 $ c2) xs =
    89       | tr (Const (\<^syntax_const>\<open>_Seq\<close>,_) $ c1 $ c2) xs =
    89           syntax_const ctxt #Seq $ tr c1 xs $ tr c2 xs
    90           let val (c1',a1) = tr c1 xs;
       
    91               val (c2',a2) = tr c2 xs
       
    92           in (syntax_const ctxt #Seq $ c1' $ c2', Syntax.const \<^const_syntax>\<open>Aseq\<close> $ a1 $ a2) end
    90       | tr (Const (\<^syntax_const>\<open>_Cond\<close>,_) $ b $ c1 $ c2) xs =
    93       | tr (Const (\<^syntax_const>\<open>_Cond\<close>,_) $ b $ c1 $ c2) xs =
    91           syntax_const ctxt #Cond $ bexp_tr b xs $ tr c1 xs $ tr c2 xs
    94           let val (c1',a1) = tr c1 xs;
    92       | tr (Const (\<^syntax_const>\<open>_While\<close>,_) $ b $ I $ V $ c) xs =
    95               val (c2',a2) = tr c2 xs
    93           syntax_const ctxt #While $ bexp_tr b xs $ assn_tr I xs $ var_tr V xs $ tr c xs
    96           in (syntax_const ctxt #Cond $ bexp_tr b xs $ c1' $ c2',
    94       | tr t _ = t;
    97               Syntax.const \<^const_syntax>\<open>Acond\<close> $ a1 $ a2)
       
    98           end
       
    99       | tr (Const (\<^syntax_const>\<open>_While\<close>,_) $ b $ i $ v $ c) xs =
       
   100           let val (c',a) = tr c xs
       
   101               val (v',A) = case v of
       
   102                 Const (\<^const_syntax>\<open>HOL.eq\<close>, _) $ z $ t => (t, Syntax_Trans.abs_tr [z, a]) |
       
   103                 t => (t, absdummy dummyT a)
       
   104           in (syntax_const ctxt #While $ bexp_tr b xs $ c',
       
   105               Syntax.const \<^const_syntax>\<open>Awhile\<close>
       
   106                 $ assn_tr i xs $ var_tr v' xs $ A)
       
   107           end
       
   108       | tr (Const (\<^syntax_const>\<open>_While0\<close>,_) $ b $ I $ c) xs =
       
   109           let val (c',a) = tr c xs
       
   110           in (syntax_const ctxt #While $ bexp_tr b xs $ c',
       
   111               Syntax.const \<^const_syntax>\<open>Awhile\<close>
       
   112                 $ assn_tr I xs $ var_tr (Syntax.const \<^const_syntax>\<open>zero_class.zero\<close>) xs
       
   113                 $ absdummy dummyT a)
       
   114           end
       
   115       | tr t _ = (t, Syntax.const \<^const_syntax>\<open>Abasic\<close>)
    95   in tr end;
   116   in tr end;
    96 
   117 
    97 fun vars_tr (Const (\<^syntax_const>\<open>_idts\<close>, _) $ idt $ vars) = idt :: vars_tr vars
   118 fun vars_tr (Const (\<^syntax_const>\<open>_idts\<close>, _) $ idt $ vars) = idt :: vars_tr vars
    98   | vars_tr t = [t];
   119   | vars_tr t = [t];
    99 
   120 
   100 in
   121 in
   101 
   122 
   102 fun hoare_vars_tr ctxt [vars, pre, prg, post] =
   123 fun hoare_vars_tr ctxt [vars, pre, prg, post] =
   103       let val xs = vars_tr vars
   124       let val xs = vars_tr vars
   104       in syntax_const ctxt #Valid $ assn_tr pre xs $ com_tr ctxt prg xs $ assn_tr post xs end
   125           val (c',a) = com_tr ctxt prg xs
       
   126       in syntax_const ctxt #Valid $ assn_tr pre xs $ c' $ a $ assn_tr post xs end
   105   | hoare_vars_tr _ ts = raise TERM ("hoare_vars_tr", ts);
   127   | hoare_vars_tr _ ts = raise TERM ("hoare_vars_tr", ts);
   106 
   128 
   107 fun hoare_tc_vars_tr ctxt [vars, pre, prg, post] =
   129 fun hoare_tc_vars_tr ctxt [vars, pre, prg, post] =
   108       let val xs = vars_tr vars
   130       let val xs = vars_tr vars
   109       in syntax_const ctxt #ValidTC $ assn_tr pre xs $ com_tr ctxt prg xs $ assn_tr post xs end
   131           val (c',a) = com_tr ctxt prg xs
       
   132       in syntax_const ctxt #ValidTC $ assn_tr pre xs $ c' $ a $ assn_tr post xs end
   110   | hoare_tc_vars_tr _ ts = raise TERM ("hoare_tc_vars_tr", ts);
   133   | hoare_tc_vars_tr _ ts = raise TERM ("hoare_tc_vars_tr", ts);
   111 
   134 
   112 end;
   135 end;
   113 
   136 
   114 
   137 
   156   | assn_tr' t = t;
   179   | assn_tr' t = t;
   157 
   180 
   158 fun bexp_tr' (Const (\<^const_syntax>\<open>Collect\<close>, _) $ T) = dest_abstuple T
   181 fun bexp_tr' (Const (\<^const_syntax>\<open>Collect\<close>, _) $ T) = dest_abstuple T
   159   | bexp_tr' t = t;
   182   | bexp_tr' t = t;
   160 
   183 
   161 fun var_tr' (Const (\<^const_syntax>\<open>Collect\<close>, _) $ T) = dest_abstuple T
   184 fun var_tr' xo T =
   162   | var_tr' t = t;
   185   let val n = dest_abstuple T
       
   186   in case xo of NONE => n | SOME x => Syntax.const \<^const_syntax>\<open>HOL.eq\<close> $ Syntax.free x $ n end
   163 
   187 
   164 
   188 
   165 (* com_tr' *)
   189 (* com_tr' *)
   166 
   190 
   167 fun mk_assign ctxt f =
   191 fun mk_assign ctxt f =
   172     if ch
   196     if ch
   173     then Syntax.const \<^syntax_const>\<open>_assign\<close> $ a $ b
   197     then Syntax.const \<^syntax_const>\<open>_assign\<close> $ a $ b
   174     else syntax_const ctxt #Skip
   198     else syntax_const ctxt #Skip
   175   end;
   199   end;
   176 
   200 
   177 fun com_tr' ctxt t =
   201 fun com_tr' ctxt (t,a) =
   178   let
   202   let
   179     val (head, args) = apfst (try (#1 o Term.dest_Const)) (Term.strip_comb t);
   203     val (head, args) = apfst (try (#1 o Term.dest_Const)) (Term.strip_comb t);
   180     fun arg k = nth args (k - 1);
   204     fun arg k = nth args (k - 1);
   181     val n = length args;
   205     val n = length args;
       
   206     val (_, args_a) = apfst (try (#1 o Term.dest_Const)) (Term.strip_comb a);
       
   207     fun arg_a k = nth args_a (k - 1)
   182   in
   208   in
   183     (case head of
   209     case head of
   184       NONE => t
   210       NONE => t
   185     | SOME c =>
   211     | SOME c =>
   186         if c = const_syntax ctxt #Basic andalso n = 1 andalso is_f (arg 1) then
   212         if c = const_syntax ctxt #Basic andalso n = 1 andalso is_f (arg 1) then
   187           mk_assign ctxt (arg 1)
   213           mk_assign ctxt (arg 1)
   188         else if c = const_syntax ctxt #Seq andalso n = 2 then
   214         else if c = const_syntax ctxt #Seq andalso n = 2 then
   189           Syntax.const \<^syntax_const>\<open>_Seq\<close> $ com_tr' ctxt (arg 1) $ com_tr' ctxt (arg 2)
   215           Syntax.const \<^syntax_const>\<open>_Seq\<close>
       
   216             $ com_tr' ctxt (arg 1, arg_a 1) $ com_tr' ctxt (arg 2, arg_a 2)
   190         else if c = const_syntax ctxt #Cond andalso n = 3 then
   217         else if c = const_syntax ctxt #Cond andalso n = 3 then
   191           Syntax.const \<^syntax_const>\<open>_Cond\<close> $
   218           Syntax.const \<^syntax_const>\<open>_Cond\<close> $
   192             bexp_tr' (arg 1) $ com_tr' ctxt (arg 2) $ com_tr' ctxt (arg 3)
   219             bexp_tr' (arg 1) $ com_tr' ctxt (arg 2, arg_a 1) $ com_tr' ctxt (arg 3, arg_a 2)
   193         else if c = const_syntax ctxt #While andalso n = 4 then
   220         else if c = const_syntax ctxt #While andalso n = 2 then
   194           Syntax.const \<^syntax_const>\<open>_While\<close> $
   221                let val (xo,a') = case arg_a 3 of
   195             bexp_tr' (arg 1) $ assn_tr' (arg 2) $ var_tr' (arg 3) $ com_tr' ctxt (arg 4)
   222                      Abs(x,_,a) => (if loose_bvar1(a,0) then SOME x else NONE,
   196         else t)
   223                                     subst_bound (Syntax.free x, a)) |
       
   224                      t => (NONE,t)
       
   225                in Syntax.const \<^syntax_const>\<open>_While\<close>
       
   226                  $ bexp_tr' (arg 1) $ assn_tr' (arg_a 1) $ var_tr' xo (arg_a 2) $ com_tr' ctxt (arg 2, a')
       
   227                end
       
   228         else t
   197   end;
   229   end;
   198 
   230 
   199 in
   231 in
   200 
   232 
   201 fun spec_tr' syn ctxt [p, c, q] =
   233 fun spec_tr' syn ctxt [p, c, a, q] =
   202   Syntax.const syn $ assn_tr' p $ com_tr' ctxt c $ assn_tr' q;
   234   Syntax.const syn $ assn_tr' p $ com_tr' ctxt (c,a) $ assn_tr' q;
   203 
   235 
   204 end;
   236 end;
   205 
   237 
   206 
   238 
   207 (** setup **)
   239 (** setup **)