ProgTutorial/Package/Ind_Code.thy
changeset 315 de49d5780f57
parent 305 2ac9dc1a95b4
child 316 74f0a06f751f
equal deleted inserted replaced
314:79202e2eab6a 315:de49d5780f57
    19 
    19 
    20   @{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"}
    21 
    21 
    22   and then ``register'' the definition inside a local theory. 
    22   and then ``register'' the definition inside a local theory. 
    23   To do the latter, we use the following wrapper for the function
    23   To do the latter, we use the following wrapper for the function
    24   @{ML [index] define in LocalTheory}. The wrapper takes a predicate name, a syntax
    24   @{ML_ind [index] define in LocalTheory}. The wrapper takes a predicate name, a syntax
    25   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.
    26 *}
    26 *}
    27 
    27 
    28 ML %linenosgray{*fun make_defn ((predname, mx), trm) lthy =
    28 ML %linenosgray{*fun make_defn ((predname, mx), trm) lthy =
    29 let 
    29 let 
    33   (thm, lthy') 
    33   (thm, lthy') 
    34 end*}
    34 end*}
    35 
    35 
    36 text {*
    36 text {*
    37   It returns the definition (as a theorem) and the local theory in which the
    37   It returns the definition (as a theorem) and the local theory in which the
    38   definition has been made. In Line 4, @{ML [index] internalK in Thm} is a flag
    38   definition has been made. In Line 4, @{ML_ind [index] internalK in Thm} is a flag
    39   attached to the theorem (other possibile flags are @{ML [index] definitionK in Thm}
    39   attached to the theorem (other possibile flags are @{ML_ind [index] definitionK in Thm}
    40   and @{ML [index] axiomK in Thm}). These flags just classify theorems and have no
    40   and @{ML_ind [index] axiomK in Thm}). These flags just classify theorems and have no
    41   significant meaning, except for tools that, for example, find theorems in
    41   significant meaning, except for tools that, for example, find theorems in
    42   the theorem database.\footnote{FIXME: put in the section about theorems.} We
    42   the theorem database.\footnote{FIXME: put in the section about theorems.} We
    43   also use @{ML [index] empty_binding in Attrib} in Line 3, since the definitions for
    43   also use @{ML_ind [index] empty_binding in Attrib} in Line 3, since the definitions for
    44   our inductive predicates are not meant to be seen by the user and therefore
    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
    45   do not need to have any theorem attributes. A testcase for this function is
    46 *}
    46 *}
    47 
    47 
    48 local_setup %gray {* fn lthy =>
    48 local_setup %gray {* fn lthy =>
   171 text {*
   171 text {*
   172   The user will state the introduction rules using meta-implications and
   172   The user will state the introduction rules using meta-implications and
   173   meta-quanti\-fications. In Line 4, we transform these introduction rules
   173   meta-quanti\-fications. In Line 4, we transform these introduction rules
   174   into the object logic (since definitions cannot be stated with
   174   into the object logic (since definitions cannot be stated with
   175   meta-connectives). To do this transformation we have to obtain the theory
   175   meta-connectives). To do this transformation we have to obtain the theory
   176   behind the local theory using the function @{ML [index] theory_of in ProofContext} 
   176   behind the local theory using the function @{ML_ind [index] theory_of in ProofContext} 
   177   (Line 3); with this theory we can use the function
   177   (Line 3); with this theory we can use the function
   178   @{ML [index] atomize_term in ObjectLogic} to make the transformation (Line 4). The call
   178   @{ML_ind [index] atomize_term in ObjectLogic} to make the transformation (Line 4). The call
   179   to @{ML defn_aux} in Line 5 produces all right-hand sides of the
   179   to @{ML defn_aux} in Line 5 produces all right-hand sides of the
   180   definitions. The actual definitions are then made in Line 7.  The result of
   180   definitions. The actual definitions are then made in Line 7.  The result of
   181   the function is a list of theorems and a local theory (the theorems are
   181   the function is a list of theorems and a local theory (the theorems are
   182   registered with the local theory). A testcase for this function is
   182   registered with the local theory). A testcase for this function is
   183 *}
   183 *}
   377   case that no introduction rules are given, the conclusion of this 
   377   case that no introduction rules are given, the conclusion of this 
   378   implication needs to be wrapped inside a @{term Trueprop}, otherwise 
   378   implication needs to be wrapped inside a @{term Trueprop}, otherwise 
   379   the Isabelle's goal mechanism will fail.\footnote{FIXME: check with 
   379   the Isabelle's goal mechanism will fail.\footnote{FIXME: check with 
   380   Stefan...is this so?} 
   380   Stefan...is this so?} 
   381 
   381 
   382   In Line 11 we set up the goal to be proved using the function @{ML [index]
   382   In Line 11 we set up the goal to be proved using the function @{ML_ind [index]
   383   prove in Goal}; in the next line we call the tactic for proving the
   383   prove in Goal}; in the next line we call the tactic for proving the
   384   induction principle. As mentioned before, this tactic expects the
   384   induction principle. As mentioned before, this tactic expects the
   385   definitions, the premise and the (certified) predicates with which the
   385   definitions, the premise and the (certified) predicates with which the
   386   introduction rules have been substituted. The code in these two lines will
   386   introduction rules have been substituted. The code in these two lines will
   387   return a theorem. However, it is a theorem proved inside the local theory
   387   return a theorem. However, it is a theorem proved inside the local theory
   445   the new local theory @{text "lthy'"}. From the local theory we extract
   445   the new local theory @{text "lthy'"}. From the local theory we extract
   446   the ambient theory in Line 6. We need this theory in order to certify 
   446   the ambient theory in Line 6. We need this theory in order to certify 
   447   the new predicates. In Line 8, we construct the types of these new predicates
   447   the new predicates. In Line 8, we construct the types of these new predicates
   448   using the given argument types. Next we turn them into terms and subsequently
   448   using the given argument types. Next we turn them into terms and subsequently
   449   certify them (Line 9 and 10). We can now produce the substituted introduction rules 
   449   certify them (Line 9 and 10). We can now produce the substituted introduction rules 
   450   (Line 11) using the function @{ML [index] subst_free}. Line 14 and 15 just iterate 
   450   (Line 11) using the function @{ML_ind [index] subst_free}. Line 14 and 15 just iterate 
   451   the proofs for all predicates.
   451   the proofs for all predicates.
   452   From this we obtain a list of theorems. Finally we need to export the 
   452   From this we obtain a list of theorems. Finally we need to export the 
   453   fixed variables @{text "Ps"} to obtain the schematic variables @{text "?Ps"} 
   453   fixed variables @{text "Ps"} to obtain the schematic variables @{text "?Ps"} 
   454   (Line 16).
   454   (Line 16).
   455 
   455 
   591   first two) and assumptions from the definition of the predicate (assumption
   591   first two) and assumptions from the definition of the predicate (assumption
   592   three to six). We need to treat these parameters and assumptions
   592   three to six). We need to treat these parameters and assumptions
   593   differently. In the code below we will therefore separate them into @{text
   593   differently. In the code below we will therefore separate them into @{text
   594   "params1"} and @{text params2}, respectively @{text "prems1"} and @{text
   594   "params1"} and @{text params2}, respectively @{text "prems1"} and @{text
   595   "prems2"}. To do this separation, it is best to open a subproof with the
   595   "prems2"}. To do this separation, it is best to open a subproof with the
   596   tactic @{ML [index] SUBPROOF}, since this tactic provides us with the parameters (as
   596   tactic @{ML_ind [index] SUBPROOF}, since this tactic provides us with the parameters (as
   597   list of @{ML_type cterm}s) and the assumptions (as list of @{ML_type thm}s). 
   597   list of @{ML_type cterm}s) and the assumptions (as list of @{ML_type thm}s). 
   598   The problem with @{ML SUBPROOF}, however, is that it always expects us to 
   598   The problem with @{ML SUBPROOF}, however, is that it always expects us to 
   599   completely discharge the goal (see Section~\ref{sec:simpletacs}). This is 
   599   completely discharge the goal (see Section~\ref{sec:simpletacs}). This is 
   600   a bit inconvenient for our gradual explanation of the proof here. Therefore
   600   a bit inconvenient for our gradual explanation of the proof here. Therefore
   601   we use first the function @{ML [index] FOCUS in Subgoal}, which does s
   601   we use first the function @{ML_ind [index] FOCUS in Subgoal}, which does s
   602   ame as @{ML SUBPROOF} 
   602   ame as @{ML SUBPROOF} 
   603   but does not require us to completely discharge the goal. 
   603   but does not require us to completely discharge the goal. 
   604 *}
   604 *}
   605 (*<*)oops(*>*)
   605 (*<*)oops(*>*)
   606 text_raw {*
   606 text_raw {*
   630   First we calculate the values for @{text "params1/2"} and @{text "prems1/2"}
   630   First we calculate the values for @{text "params1/2"} and @{text "prems1/2"}
   631   from @{text "params"} and @{text "prems"}, respectively. To better see what is
   631   from @{text "params"} and @{text "prems"}, respectively. To better see what is
   632   going in our example, we will print out these values using the printing
   632   going in our example, we will print out these values using the printing
   633   function in Figure~\ref{fig:chopprint}. Since @{ML FOCUS in Subgoal} will
   633   function in Figure~\ref{fig:chopprint}. Since @{ML FOCUS in Subgoal} will
   634   supply us the @{text "params"} and @{text "prems"} as lists, we can 
   634   supply us the @{text "params"} and @{text "prems"} as lists, we can 
   635   separate them using the function @{ML [index] chop}. 
   635   separate them using the function @{ML_ind [index] chop}. 
   636 *}
   636 *}
   637 
   637 
   638 ML %linenosgray{*fun chop_test_tac preds rules =
   638 ML %linenosgray{*fun chop_test_tac preds rules =
   639   Subgoal.FOCUS (fn {params, prems, context, ...} =>
   639   Subgoal.FOCUS (fn {params, prems, context, ...} =>
   640   let
   640   let
   697 
   697 
   698   @{term [display] "\<forall>a b t. a \<noteq> b \<longrightarrow> fresh a t \<longrightarrow> fresh a (Lam a t)"}
   698   @{term [display] "\<forall>a b t. a \<noteq> b \<longrightarrow> fresh a t \<longrightarrow> fresh a (Lam a t)"}
   699 
   699 
   700   To use this premise with @{ML rtac}, we need to instantiate its 
   700   To use this premise with @{ML rtac}, we need to instantiate its 
   701   quantifiers (with @{text params1}) and transform it into rule 
   701   quantifiers (with @{text params1}) and transform it into rule 
   702   format (using @{ML [index] rulify in ObjectLogic}). So we can modify the 
   702   format (using @{ML_ind [index] rulify in ObjectLogic}). So we can modify the 
   703   code as follows:
   703   code as follows:
   704 *}
   704 *}
   705 
   705 
   706 ML %linenosgray{*fun apply_prem_tac i preds rules =
   706 ML %linenosgray{*fun apply_prem_tac i preds rules =
   707   Subgoal.FOCUS (fn {params, prems, context, ...} =>
   707   Subgoal.FOCUS (fn {params, prems, context, ...} =>
   861 
   861 
   862 text {*
   862 text {*
   863   In Line 4 we use the @{text prems} from the @{ML SUBPROOF} and resolve 
   863   In Line 4 we use the @{text prems} from the @{ML SUBPROOF} and resolve 
   864   them with @{text prem}. In the simple cases, that is where the @{text prem} 
   864   them with @{text prem}. In the simple cases, that is where the @{text prem} 
   865   comes from a non-recursive premise of the rule, @{text prems} will be 
   865   comes from a non-recursive premise of the rule, @{text prems} will be 
   866   just the empty list and the function @{ML [index] MRS} does nothing. Similarly, in the 
   866   just the empty list and the function @{ML_ind [index] MRS} does nothing. Similarly, in the 
   867   cases where the recursive premises of the rule do not have preconditions. 
   867   cases where the recursive premises of the rule do not have preconditions. 
   868   In case there are preconditions, then Line 4 discharges them. After
   868   In case there are preconditions, then Line 4 discharges them. After
   869   that we can proceed as before, i.e., check whether the outermost
   869   that we can proceed as before, i.e., check whether the outermost
   870   connective is @{text "\<forall>"}.
   870   connective is @{text "\<forall>"}.
   871   
   871   
   940 in
   940 in
   941   map_index intros_aux rules
   941   map_index intros_aux rules
   942 end*}
   942 end*}
   943 
   943 
   944 text {*
   944 text {*
   945   The iteration is done with the function @{ML [index] map_index} since we
   945   The iteration is done with the function @{ML_ind [index] map_index} since we
   946   need the introduction rule together with its number (counted from
   946   need the introduction rule together with its number (counted from
   947   @{text 0}). This completes the code for the functions deriving the
   947   @{text 0}). This completes the code for the functions deriving the
   948   reasoning infrastructure. It remains to implement some administrative
   948   reasoning infrastructure. It remains to implement some administrative
   949   code that strings everything together.
   949   code that strings everything together.
   950 *}
   950 *}
   953 
   953 
   954 text {* 
   954 text {* 
   955   We have produced various theorems (definitions, induction principles and
   955   We have produced various theorems (definitions, induction principles and
   956   introduction rules), but apart from the definitions, we have not yet 
   956   introduction rules), but apart from the definitions, we have not yet 
   957   registered them with the theorem database. This is what the functions 
   957   registered them with the theorem database. This is what the functions 
   958   @{ML [index] note in LocalTheory} does. 
   958   @{ML_ind [index] note in LocalTheory} does. 
   959 
   959 
   960 
   960 
   961   For convenience, we use the following 
   961   For convenience, we use the following 
   962   three wrappers this function:
   962   three wrappers this function:
   963 *}
   963 *}
  1035   @{text "mut_name.inducts"}, respectively (see previous paragraph).
  1035   @{text "mut_name.inducts"}, respectively (see previous paragraph).
  1036   
  1036   
  1037   Line 20 add further every introduction rule under its own name
  1037   Line 20 add further every introduction rule under its own name
  1038   (given by the user).\footnote{FIXME: what happens if the user did not give
  1038   (given by the user).\footnote{FIXME: what happens if the user did not give
  1039   any name.} Line 21 registers the induction principles. For this we have
  1039   any name.} Line 21 registers the induction principles. For this we have
  1040   to use some specific attributes. The first @{ML [index] case_names in RuleCases} 
  1040   to use some specific attributes. The first @{ML_ind [index] case_names in RuleCases} 
  1041   corresponds to the case names that are used by Isar to reference the proof
  1041   corresponds to the case names that are used by Isar to reference the proof
  1042   obligations in the induction. The second @{ML "consumes 1" in RuleCases}
  1042   obligations in the induction. The second @{ML "consumes 1" in RuleCases}
  1043   indicates that the first premise of the induction principle (namely
  1043   indicates that the first premise of the induction principle (namely
  1044   the predicate over which the induction proceeds) is eliminated. 
  1044   the predicate over which the induction proceeds) is eliminated. 
  1045 
  1045