ProgTutorial/Package/Ind_Code.thy
changeset 237 0a8981f52045
parent 224 647cab4a72c2
child 239 b63c72776f03
equal deleted inserted replaced
236:7b6d81ff9d9a 237:0a8981f52045
     3 begin
     3 begin
     4 
     4 
     5 section {* The Gory Details\label{sec:code} *} 
     5 section {* The Gory Details\label{sec:code} *} 
     6 
     6 
     7 text {*
     7 text {*
     8   As mentioned before the code falls roughly into three parts: code that deals
     8   As mentioned before the code falls roughly into three parts: the code that deals
     9   with the definitions, withe the induction principles and the introduction
     9   with the definitions, with the induction principles and with the introduction
    10   rules, respectively. In addition there are some administrative functions
    10   rules. In addition there are some administrative functions that string everything 
    11   that string everything together.
    11   together.
    12 *}
    12 *}
    13 
    13 
    14 subsection {* Definitions *}
    14 subsection {* Definitions *}
    15 
    15 
    16 text {*
    16 text {*
    17   We first have to produce for each predicate the definition, whose general form is
    17   We first have to produce for each predicate the user specifies an appropriate
       
    18   definition, whose general form is
    18 
    19 
    19   @{text [display] "pred \<equiv> \<lambda>zs. \<forall>preds. orules \<longrightarrow> pred zs"}
    20   @{text [display] "pred \<equiv> \<lambda>zs. \<forall>preds. orules \<longrightarrow> pred zs"}
    20 
    21 
    21   and then ``register'' the definition inside a local theory. 
    22   and then ``register'' the definition inside a local theory. 
    22   To do the latter, we use the following wrapper for 
    23   To do the latter, we use the following wrapper for the function
    23   @{ML LocalTheory.define}. The wrapper takes a predicate name, a syntax
    24   @{ML LocalTheory.define}. The wrapper takes a predicate name, a syntax
    24   annotation and a term representing the right-hand side of the definition.
    25   annotation and a term representing the right-hand side of the definition.
    25 *}
    26 *}
    26 
    27 
    27 ML %linenosgray{*fun make_defn ((predname, syn), trm) lthy =
    28 ML %linenosgray{*fun make_defn ((predname, mx), trm) lthy =
    28 let 
    29 let 
    29   val arg = ((predname, syn), (Attrib.empty_binding, trm))
    30   val arg = ((predname, mx), (Attrib.empty_binding, trm))
    30   val ((_, (_ , thm)), lthy') = LocalTheory.define Thm.internalK arg lthy
    31   val ((_, (_ , thm)), lthy') = LocalTheory.define Thm.internalK arg lthy
    31 in 
    32 in 
    32   (thm, lthy') 
    33   (thm, lthy') 
    33 end*}
    34 end*}
    34 
    35 
    35 text {*
    36 text {*
    36   It returns the definition (as a theorem) and the local theory in which this definition has 
    37   It returns the definition (as a theorem) and the local theory in which the
    37   been made. In Line 4, @{ML internalK in Thm} is a flag attached to the 
    38   definition has been made. In Line 4, @{ML internalK in Thm} is a flag
    38   theorem (others possibile flags are @{ML definitionK in Thm} and @{ML axiomK in Thm}). 
    39   attached to the theorem (others possibile flags are @{ML definitionK in Thm}
    39   These flags just classify theorems and have no significant meaning, except 
    40   and @{ML axiomK in Thm}). These flags just classify theorems and have no
    40   for tools that, for example, find theorems in the theorem database. We also
    41   significant meaning, except for tools that, for example, find theorems in
    41   use @{ML empty_binding in Attrib} in Line 3, since for our inductive predicates 
    42   the theorem database.\footnote{FIXME: put in the section about theorems.} We
    42   the definitions do not need to have any theorem attributes. A testcase for this 
    43   also use @{ML empty_binding in Attrib} in Line 3, since the definitions for
    43   function is
    44   our inductive predicates are not meant to be seen by the user and therefore
       
    45   do not need to have any theorem attributes. A testcase for this function is
    44 *}
    46 *}
    45 
    47 
    46 local_setup %gray {* fn lthy =>
    48 local_setup %gray {* fn lthy =>
    47 let
    49 let
    48   val arg = ((@{binding "MyTrue"}, NoSyn), @{term True})
    50   val arg = ((@{binding "My_True"}, NoSyn), @{term True})
    49   val (def, lthy') = make_defn arg lthy 
    51   val (def, lthy') = make_defn arg lthy 
    50 in
    52 in
    51   warning (str_of_thm_no_vars lthy' def); lthy'
    53   warning (str_of_thm_no_vars lthy' def); lthy'
    52 end *}
    54 end *}
    53 
    55 
    54 text {*
    56 text {*
    55   which introduces the definition @{prop "MyTrue \<equiv> True"} and then prints it out. 
    57   which introduces the definition @{thm My_True_def} and then prints it out. 
    56   Since we are testing the function inside \isacommand{local\_setup}, i.e., make
    58   Since we are testing the function inside \isacommand{local\_setup}, i.e., make
    57   actual changes to the ambient theory, we can query the definition with the usual
    59   actual changes to the ambient theory, we can query the definition with the usual
    58   command \isacommand{thm}:
    60   command \isacommand{thm}:
    59 
    61 
    60   \begin{isabelle}
    62   \begin{isabelle}
    61   \isacommand{thm}~@{text "MyTrue_def"}\\
    63   \isacommand{thm}~@{thm [source] "My_True_def"}\\
    62   @{text "> MyTrue \<equiv> True"}
    64   @{text ">"}~@{thm "My_True_def"}
    63   \end{isabelle}
    65   \end{isabelle}
    64 
    66 
    65   The next two functions construct the right-hand sides of the definitions, 
    67   The next two functions construct the right-hand sides of the definitions, 
    66   which are terms of the form
    68   which are terms whose general form is:
    67 
    69 
    68   @{text [display] "\<lambda>zs. \<forall>preds. orules \<longrightarrow> pred zs"}
    70   @{text [display] "\<lambda>zs. \<forall>preds. orules \<longrightarrow> pred zs"}
    69 
    71 
    70   When constructing them, the variables @{text "zs"} need to be chosen so that
    72   When constructing these terms, the variables @{text "zs"} need to be chosen so 
    71   they do not occur in the @{text orules} and also be distinct from the @{text
    73   that they do not occur in the @{text orules} and also be distinct from the 
    72   "preds"}.
    74   @{text "preds"}.
    73 
    75 
    74 
    76 
    75   The first function, named @{text defn_aux}, constructs the term for one
    77   The first function, named @{text defn_aux}, constructs the term for one
    76   particular predicate (the argument @{text "pred"} in the code below). The
    78   particular predicate (the argument @{text "pred"} in the code below). The
    77   number of arguments of this predicate is determined by the number of
    79   number of arguments of this predicate is determined by the number of
   143                (\<forall>a s t. fresh a t \<longrightarrow> fresh a s \<longrightarrow> fresh a (App t s)) \<longrightarrow>
   145                (\<forall>a s t. fresh a t \<longrightarrow> fresh a s \<longrightarrow> fresh a (App t s)) \<longrightarrow>
   144                 (\<forall>a t. fresh a (Lam a t)) \<longrightarrow>
   146                 (\<forall>a t. fresh a (Lam a t)) \<longrightarrow>
   145                 (\<forall>a b t. \<not> a = b \<longrightarrow> fresh a t \<longrightarrow> fresh a (Lam b t)) \<longrightarrow> fresh z za"}
   147                 (\<forall>a b t. \<not> a = b \<longrightarrow> fresh a t \<longrightarrow> fresh a (Lam b t)) \<longrightarrow> fresh z za"}
   146 
   148 
   147 
   149 
   148   The second function, named @{text defns}, has to just iterate the function
   150   The second function, named @{text defns}, has to iterate the function
   149   @{ML defn_aux} over all predicates. The argument @{text "preds"} is again
   151   @{ML defn_aux} over all predicates. The argument @{text "preds"} is again
   150   the the list of predicates as @{ML_type term}s; the argument @{text
   152   the list of predicates as @{ML_type term}s; the argument @{text
   151   "prednames"} is the list of binding names of the predicates; @{text syns} 
   153   "prednames"} is the list of binding names of the predicates; @{text mxs} 
   152   are the list of syntax annotations for the predicates; @{text "arg_tyss"} is
   154   are the list of syntax, or mixfix, annotations for the predicates; 
   153   the list of argument-type-lists.
   155   @{text "arg_tyss"} is the list of argument-type-lists.
   154 *}
   156 *}
   155 
   157 
   156 ML %linenosgray{*fun defns rules preds prednames syns arg_typss lthy =
   158 ML %linenosgray{*fun defns rules preds prednames mxs arg_typss lthy =
   157 let
   159 let
   158   val thy = ProofContext.theory_of lthy
   160   val thy = ProofContext.theory_of lthy
   159   val orules = map (ObjectLogic.atomize_term thy) rules
   161   val orules = map (ObjectLogic.atomize_term thy) rules
   160   val defs = map (defn_aux lthy orules preds) (preds ~~ arg_typss) 
   162   val defs = map (defn_aux lthy orules preds) (preds ~~ arg_typss) 
   161 in
   163 in
   162   fold_map make_defn (prednames ~~ syns ~~ defs) lthy
   164   fold_map make_defn (prednames ~~ mxs ~~ defs) lthy
   163 end*}
   165 end*}
   164 
   166 
   165 text {*
   167 text {*
   166   The user will state the introduction rules using meta-implications and
   168   The user will state the introduction rules using meta-implications and
   167   meta-quanti\-fications. In Line 4, we transform these introduction rules into
   169   meta-quanti\-fications. In Line 4, we transform these introduction rules
   168   the object logic (since definitions cannot be stated with
   170   into the object logic (since definitions cannot be stated with
   169   meta-connectives). To do this transformation we have to obtain the theory
   171   meta-connectives). To do this transformation we have to obtain the theory
   170   behind the local theory (Line 3); with this theory we can use the function
   172   behind the local theory (Line 3); with this theory we can use the function
   171   @{ML ObjectLogic.atomize_term} to make the transformation (Line 4). The call
   173   @{ML ObjectLogic.atomize_term} to make the transformation (Line 4). The call
   172   to @{ML defn_aux} in Line 5 produces all right-hand sides of the
   174   to @{ML defn_aux} in Line 5 produces all right-hand sides of the
   173   definitions. The actual definitions are then made in Line 7.  The result
   175   definitions. The actual definitions are then made in Line 7.  The result of
   174   of the function is a list of theorems and a local theory. A testcase for 
   176   the function is a list of theorems and a local theory (the theorems are
   175   this function is 
   177   registered with the local theory). A testcase for this function is
   176 *}
   178 *}
   177 
   179 
   178 local_setup %gray {* fn lthy =>
   180 local_setup %gray {* fn lthy =>
   179 let
   181 let
   180   val (defs, lthy') = 
   182   val (defs, lthy') = 
   181     defns eo_rules eo_preds eo_prednames eo_syns eo_arg_tyss lthy
   183     defns eo_rules eo_preds eo_prednames eo_mxs eo_arg_tyss lthy
   182 in
   184 in
   183   warning (str_of_thms_no_vars lthy' defs); lthy
   185   warning (str_of_thms_no_vars lthy' defs); lthy
   184 end *}
   186 end *}
   185 
   187 
   186 text {*
   188 text {*
   299                           [@{cterm "P::string\<Rightarrow>trm\<Rightarrow>bool"}] *})
   301                           [@{cterm "P::string\<Rightarrow>trm\<Rightarrow>bool"}] *})
   300 
   302 
   301 
   303 
   302 text {*
   304 text {*
   303   While the tactic for proving the induction principles is relatively simple,
   305   While the tactic for proving the induction principles is relatively simple,
   304   it will be a bit of work to construct the goals from the introduction rules
   306   it will be a bit more work to construct the goals from the introduction rules
   305   the user provides.  Therefore let us have a closer look at the first 
   307   the user provides.  Therefore let us have a closer look at the first 
   306   proved theorem:
   308   proved theorem:
   307 
   309 
   308   \begin{isabelle}
   310   \begin{isabelle}
   309   \isacommand{thm}~@{thm [source] automatic_ind_prin_even}\\
   311   \isacommand{thm}~@{thm [source] automatic_ind_prin_even}\\
   966   and the introduction rules @{text "rule_spec"}.   
   968   and the introduction rules @{text "rule_spec"}.   
   967 *}
   969 *}
   968 
   970 
   969 ML %linenosgray{*fun add_inductive pred_specs rule_specs lthy =
   971 ML %linenosgray{*fun add_inductive pred_specs rule_specs lthy =
   970 let
   972 let
   971   val syns = map snd pred_specs
   973   val mxs = map snd pred_specs
   972   val pred_specs' = map fst pred_specs
   974   val pred_specs' = map fst pred_specs
   973   val prednames = map fst pred_specs'
   975   val prednames = map fst pred_specs'
   974   val preds = map (fn (p, ty) => Free (Binding.name_of p, ty)) pred_specs'
   976   val preds = map (fn (p, ty) => Free (Binding.name_of p, ty)) pred_specs'
   975   val tyss = map (binder_types o fastype_of) preds   
   977   val tyss = map (binder_types o fastype_of) preds   
   976 
   978 
   977   val (namesattrs, rules) = split_list rule_specs    
   979   val (namesattrs, rules) = split_list rule_specs    
   978 
   980 
   979   val (defs, lthy') = defns rules preds prednames syns tyss lthy      
   981   val (defs, lthy') = defns rules preds prednames mxs tyss lthy      
   980   val ind_prin = inds rules defs preds tyss lthy' 	
   982   val ind_prins = inds rules defs preds tyss lthy' 	
   981   val intro_rules = intros rules preds defs lthy'
   983   val intro_rules = intros rules preds defs lthy'
   982 
   984 
   983   val mut_name = space_implode "_" (map Binding.name_of prednames)
   985   val mut_name = space_implode "_" (map Binding.name_of prednames)
   984   val case_names = map (Binding.name_of o fst) namesattrs
   986   val case_names = map (Binding.name_of o fst) namesattrs
   985 in
   987 in
   986   lthy' |> reg_many mut_name ((@{binding "intros"}, []), intro_rules) 
   988   lthy' |> reg_many mut_name ((@{binding "intros"}, []), intro_rules) 
       
   989         ||>> reg_many mut_name ((@{binding "inducts"}, []), ind_prins)
   987         ||>> fold_map (reg_single1 mut_name) (namesattrs ~~ intro_rules)  
   990         ||>> fold_map (reg_single1 mut_name) (namesattrs ~~ intro_rules)  
   988         ||>> fold_map (reg_single2 @{binding "induct"} 
   991         ||>> fold_map (reg_single2 @{binding "induct"} 
   989               [Attrib.internal (K (RuleCases.case_names case_names)),
   992               [Attrib.internal (K (RuleCases.case_names case_names)),
   990                Attrib.internal (K (RuleCases.consumes 1)),
   993                Attrib.internal (K (RuleCases.consumes 1)),
   991                Attrib.internal (K (Induct.induct_pred ""))]) 
   994                Attrib.internal (K (Induct.induct_pred ""))]) 
   992              (prednames ~~ ind_prin) 
   995              (prednames ~~ ind_prins) 
   993         |> snd
   996         |> snd
   994 end*}
   997 end*}
   995 
   998 
   996 text {*
   999 text {*
   997   In Line 3 the function extracts the syntax annotations from the predicates. 
  1000   In Line 3 the function extracts the syntax annotations from the predicates. 
  1015   @{text [quotes] "_"}-separated list of predicate names (for example
  1018   @{text [quotes] "_"}-separated list of predicate names (for example
  1016   @{text "even_odd"}. Also by custom, the case names in intuction 
  1019   @{text "even_odd"}. Also by custom, the case names in intuction 
  1017   proofs correspond to the names of the introduction rules. These
  1020   proofs correspond to the names of the introduction rules. These
  1018   are generated in Line 16.
  1021   are generated in Line 16.
  1019 
  1022 
  1020   Line 18 now adds to @{text "lthy'"} all the introduction rules 
  1023   Lines 18 and 19 now add to @{text "lthy'"} all the introduction rules 
  1021   under the name @{text "mut_name.intros"} (see previous paragraph).
  1024   und induction principles under the name @{text "mut_name.intros"} and
  1022   Line 19 add further every introduction rule under its own name
  1025   @{text "mut_name.inducts"}, respectively (see previous paragraph).
       
  1026   
       
  1027   Line 20 add further every introduction rule under its own name
  1023   (given by the user).\footnote{FIXME: what happens if the user did not give
  1028   (given by the user).\footnote{FIXME: what happens if the user did not give
  1024   any name.} Line 20 registers the induction principles. For this we have
  1029   any name.} Line 21 registers the induction principles. For this we have
  1025   to use some specific attributes. The first @{ML "case_names" in RuleCases} 
  1030   to use some specific attributes. The first @{ML "case_names" in RuleCases} 
  1026   corresponds to the case names that are used by Isar to reference the proof
  1031   corresponds to the case names that are used by Isar to reference the proof
  1027   obligations in the induction. The second @{ML "consumes 1" in RuleCases}
  1032   obligations in the induction. The second @{ML "consumes 1" in RuleCases}
  1028   indicates that the first premise of the induction principle (namely
  1033   indicates that the first premise of the induction principle (namely
  1029   the predicate over which the induction proceeds) is eliminated. 
  1034   the predicate over which the induction proceeds) is eliminated. 
  1030 
  1035 
  1031   This completes all the code and fits in with the ``front end'' described
  1036   This completes all the code and fits in with the ``front end'' described
  1032   in Section~\ref{sec:interface}.\footnote{FIXME: Describe @{ML Induct.induct_pred}. Why the mut-name? 
  1037   in Section~\ref{sec:interface}.\footnote{FIXME: Describe @{ML Induct.induct_pred}. 
       
  1038   Why the mut-name? 
  1033   What does @{ML Binding.qualify} do?}
  1039   What does @{ML Binding.qualify} do?}
  1034 *}
  1040 *}
  1035 (*<*)end(*>*)
  1041 (*<*)end(*>*)