src/HOL/Hoare/hoare_syntax.ML
changeset 72987 b1be35908165
parent 72806 4fa08e083865
child 72998 7ea253f93606
equal deleted inserted replaced
72986:d231d71d27b4 72987:b1be35908165
     5 Syntax translations for Hoare logic.
     5 Syntax translations for Hoare logic.
     6 *)
     6 *)
     7 
     7 
     8 signature HOARE_SYNTAX =
     8 signature HOARE_SYNTAX =
     9 sig
     9 sig
    10   val hoare_vars_tr: term list -> term
    10   val hoare_vars_tr: Proof.context -> term list -> term
    11   val hoare_tc_vars_tr: term list -> term
    11   val hoare_tc_vars_tr: Proof.context -> term list -> term
    12   val spec_tr': string -> term list -> term
    12   val spec_tr': string -> Proof.context -> term list -> term
       
    13   val setup:
       
    14     {Basic: string, Skip: string, Seq: string, Cond: string, While: string,
       
    15       Valid: string, ValidTC: string} -> theory -> theory
    13 end;
    16 end;
    14 
    17 
    15 structure Hoare_Syntax: HOARE_SYNTAX =
    18 structure Hoare_Syntax: HOARE_SYNTAX =
    16 struct
    19 struct
       
    20 
       
    21 (** theory data **)
       
    22 
       
    23 structure Data = Theory_Data
       
    24 (
       
    25   type T =
       
    26     {Basic: string, Skip: string, Seq: string, Cond: string, While: string,
       
    27       Valid: string, ValidTC: string} option;
       
    28   val empty: T = NONE;
       
    29   val extend = I;
       
    30   fun merge (data1, data2) =
       
    31     if is_some data1 andalso is_some data2 andalso data1 <> data2 then
       
    32       error "Cannot merge syntax from different Hoare Logics"
       
    33     else merge_options (data1, data2);
       
    34 );
       
    35 
       
    36 fun const_syntax ctxt which =
       
    37   (case Data.get (Proof_Context.theory_of ctxt) of
       
    38     SOME consts => which consts
       
    39   | NONE => error "Undefined Hoare syntax consts");
       
    40 
       
    41 val syntax_const = Syntax.const oo const_syntax;
       
    42 
       
    43 
    17 
    44 
    18 (** parse translation **)
    45 (** parse translation **)
    19 
    46 
    20 local
    47 local
    21 
    48 
    52 fun var_tr v xs = mk_abstuple xs v;
    79 fun var_tr v xs = mk_abstuple xs v;
    53 
    80 
    54 
    81 
    55 (* com_tr *)
    82 (* com_tr *)
    56 
    83 
    57 fun com_tr (Const (\<^syntax_const>\<open>_assign\<close>, _) $ x $ e) xs =
    84 fun com_tr ctxt =
    58       Syntax.const \<^const_syntax>\<open>Basic\<close> $ mk_fexp x e xs
    85   let
    59   | com_tr (Const (\<^const_syntax>\<open>Basic\<close>,_) $ f) _ = Syntax.const \<^const_syntax>\<open>Basic\<close> $ f
    86     fun tr (Const (\<^syntax_const>\<open>_assign\<close>, _) $ x $ e) xs =
    60   | com_tr (Const (\<^const_syntax>\<open>Seq\<close>,_) $ c1 $ c2) xs =
    87           syntax_const ctxt #Basic $ mk_fexp x e xs
    61       Syntax.const \<^const_syntax>\<open>Seq\<close> $ com_tr c1 xs $ com_tr c2 xs
    88       | tr (Const (\<^syntax_const>\<open>_Seq\<close>,_) $ c1 $ c2) xs =
    62   | com_tr (Const (\<^const_syntax>\<open>Cond\<close>,_) $ b $ c1 $ c2) xs =
    89           syntax_const ctxt #Seq $ tr c1 xs $ tr c2 xs
    63       Syntax.const \<^const_syntax>\<open>Cond\<close> $ bexp_tr b xs $ com_tr c1 xs $ com_tr c2 xs
    90       | tr (Const (\<^syntax_const>\<open>_Cond\<close>,_) $ b $ c1 $ c2) xs =
    64   | com_tr (Const (\<^const_syntax>\<open>While\<close>,_) $ b $ I $ V $ c) xs =
    91           syntax_const ctxt #Cond $ bexp_tr b xs $ tr c1 xs $ tr c2 xs
    65       Syntax.const \<^const_syntax>\<open>While\<close> $ bexp_tr b xs $ assn_tr I xs $ var_tr V xs $ com_tr c xs
    92       | tr (Const (\<^syntax_const>\<open>_While\<close>,_) $ b $ I $ V $ c) xs =
    66   | com_tr t _ = t;
    93           syntax_const ctxt #While $ bexp_tr b xs $ assn_tr I xs $ var_tr V xs $ tr c xs
       
    94       | tr t _ = t;
       
    95   in tr end;
    67 
    96 
    68 fun vars_tr (Const (\<^syntax_const>\<open>_idts\<close>, _) $ idt $ vars) = idt :: vars_tr vars
    97 fun vars_tr (Const (\<^syntax_const>\<open>_idts\<close>, _) $ idt $ vars) = idt :: vars_tr vars
    69   | vars_tr t = [t];
    98   | vars_tr t = [t];
    70 
    99 
    71 in
   100 in
    72 
   101 
    73 fun hoare_vars_tr [vars, pre, prg, post] =
   102 fun hoare_vars_tr ctxt [vars, pre, prg, post] =
    74       let val xs = vars_tr vars
   103       let val xs = vars_tr vars
    75       in Syntax.const \<^const_syntax>\<open>Valid\<close> $
   104       in syntax_const ctxt #Valid $ assn_tr pre xs $ com_tr ctxt prg xs $ assn_tr post xs end
    76          assn_tr pre xs $ com_tr prg xs $ assn_tr post xs
   105   | hoare_vars_tr _ ts = raise TERM ("hoare_vars_tr", ts);
    77       end
   106 
    78   | hoare_vars_tr ts = raise TERM ("hoare_vars_tr", ts);
   107 fun hoare_tc_vars_tr ctxt [vars, pre, prg, post] =
    79 
       
    80 fun hoare_tc_vars_tr [vars, pre, prg, post] =
       
    81       let val xs = vars_tr vars
   108       let val xs = vars_tr vars
    82       in Syntax.const \<^const_syntax>\<open>ValidTC\<close> $
   109       in syntax_const ctxt #ValidTC $ assn_tr pre xs $ com_tr ctxt prg xs $ assn_tr post xs end
    83          assn_tr pre xs $ com_tr prg xs $ assn_tr post xs
   110   | hoare_tc_vars_tr _ ts = raise TERM ("hoare_tc_vars_tr", ts);
    84       end
       
    85   | hoare_tc_vars_tr ts = raise TERM ("hoare_tc_vars_tr", ts);
       
    86 
   111 
    87 end;
   112 end;
    88 
   113 
    89 
   114 
    90 
   115 
   137   | var_tr' t = t;
   162   | var_tr' t = t;
   138 
   163 
   139 
   164 
   140 (* com_tr' *)
   165 (* com_tr' *)
   141 
   166 
   142 fun mk_assign f =
   167 fun mk_assign ctxt f =
   143   let
   168   let
   144     val (vs, ts) = mk_vts f;
   169     val (vs, ts) = mk_vts f;
   145     val (ch, which) = find_ch (vs ~~ ts) (length vs - 1) (rev vs);
   170     val (ch, (a, b)) = find_ch (vs ~~ ts) (length vs - 1) (rev vs);
   146   in
   171   in
   147     if ch
   172     if ch
   148     then Syntax.const \<^syntax_const>\<open>_assign\<close> $ fst which $ snd which
   173     then Syntax.const \<^syntax_const>\<open>_assign\<close> $ a $ b
   149     else Syntax.const \<^const_syntax>\<open>annskip\<close>
   174     else syntax_const ctxt #Skip
   150   end;
   175   end;
   151 
   176 
   152 fun com_tr' (Const (\<^const_syntax>\<open>Basic\<close>, _) $ f) =
   177 fun com_tr' ctxt t =
   153       if is_f f then mk_assign f
   178   let
   154       else Syntax.const \<^const_syntax>\<open>Basic\<close> $ f
   179     val (head, args) = apfst (try (#1 o Term.dest_Const)) (Term.strip_comb t);
   155   | com_tr' (Const (\<^const_syntax>\<open>Seq\<close>,_) $ c1 $ c2) =
   180     fun arg k = nth args (k - 1);
   156       Syntax.const \<^const_syntax>\<open>Seq\<close> $ com_tr' c1 $ com_tr' c2
   181     val n = length args;
   157   | com_tr' (Const (\<^const_syntax>\<open>Cond\<close>, _) $ b $ c1 $ c2) =
   182   in
   158       Syntax.const \<^const_syntax>\<open>Cond\<close> $ bexp_tr' b $ com_tr' c1 $ com_tr' c2
   183     (case head of
   159   | com_tr' (Const (\<^const_syntax>\<open>While\<close>, _) $ b $ I $ V $ c) =
   184       NONE => t
   160       Syntax.const \<^const_syntax>\<open>While\<close> $ bexp_tr' b $ assn_tr' I $ var_tr' V $ com_tr' c
   185     | SOME c =>
   161   | com_tr' t = t;
   186         if c = const_syntax ctxt #Basic andalso n = 1 andalso is_f (arg 1) then
       
   187           mk_assign ctxt (arg 1)
       
   188         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)
       
   190         else if c = const_syntax ctxt #Cond andalso n = 3 then
       
   191           Syntax.const \<^syntax_const>\<open>_Cond\<close> $
       
   192             bexp_tr' (arg 1) $ com_tr' ctxt (arg 2) $ com_tr' ctxt (arg 3)
       
   193         else if c = const_syntax ctxt #While andalso n = 4 then
       
   194           Syntax.const \<^syntax_const>\<open>_While\<close> $
       
   195             bexp_tr' (arg 1) $ assn_tr' (arg 2) $ var_tr' (arg 3) $ com_tr' ctxt (arg 4)
       
   196         else t)
       
   197   end;
   162 
   198 
   163 in
   199 in
   164 
   200 
   165 fun spec_tr' syn [p, c, q] = Syntax.const syn $ assn_tr' p $ com_tr' c $ assn_tr' q;
   201 fun spec_tr' syn ctxt [p, c, q] =
   166 
   202   Syntax.const syn $ assn_tr' p $ com_tr' ctxt c $ assn_tr' q;
   167 end;
   203 
   168 
   204 end;
   169 end;
   205 
   170 
   206 
       
   207 (** setup **)
       
   208 
       
   209 fun setup consts =
       
   210   Data.put (SOME consts) #>
       
   211   Sign.parse_translation
       
   212    [(\<^syntax_const>\<open>_hoare_vars\<close>, hoare_vars_tr),
       
   213     (\<^syntax_const>\<open>_hoare_vars_tc\<close>, hoare_tc_vars_tr)] #>
       
   214   Sign.print_translation
       
   215    [(#Valid consts, spec_tr' \<^syntax_const>\<open>_hoare\<close>),
       
   216     (#ValidTC consts, spec_tr' \<^syntax_const>\<open>_hoare_tc\<close>)];
       
   217 
       
   218 end;