src/HOL/Tools/Function/function.ML
changeset 53603 59ef06cda7b9
parent 52384 80c00a851de5
child 53604 c1db98d7c66f
equal deleted inserted replaced
53474:077a2758ceb4 53603:59ef06cda7b9
    22 
    22 
    23   val function_cmd: (binding * string option * mixfix) list ->
    23   val function_cmd: (binding * string option * mixfix) list ->
    24     (Attrib.binding * string) list -> Function_Common.function_config ->
    24     (Attrib.binding * string) list -> Function_Common.function_config ->
    25     bool -> local_theory -> Proof.state
    25     bool -> local_theory -> Proof.state
    26 
    26 
    27   val prove_termination: term option -> tactic -> local_theory -> 
    27   val prove_termination: term option -> tactic -> local_theory ->
    28     info * local_theory
    28     info * local_theory
    29   val prove_termination_cmd: string option -> tactic -> local_theory ->
    29   val prove_termination_cmd: string option -> tactic -> local_theory ->
    30     info * local_theory
    30     info * local_theory
    31 
    31 
    32   val termination : term option -> local_theory -> Proof.state
    32   val termination : term option -> local_theory -> Proof.state
    92     val ((goal_state, cont), lthy') =
    92     val ((goal_state, cont), lthy') =
    93       Function_Mutual.prepare_function_mutual config defname fixes eqs lthy
    93       Function_Mutual.prepare_function_mutual config defname fixes eqs lthy
    94 
    94 
    95     fun afterqed [[proof]] lthy =
    95     fun afterqed [[proof]] lthy =
    96       let
    96       let
       
    97         val result = cont (Thm.close_derivation proof)
    97         val FunctionResult {fs, R, dom, psimps, simple_pinducts,
    98         val FunctionResult {fs, R, dom, psimps, simple_pinducts,
    98           termination, domintros, cases, ...} =
    99                 termination, domintros, cases, ...} = result
    99           cont (Thm.close_derivation proof)
   100 
       
   101         val pelims = Function_Elims.mk_partial_elim_rules lthy result
   100 
   102 
   101         val fnames = map (fst o fst) fixes
   103         val fnames = map (fst o fst) fixes
   102         fun qualify n = Binding.name n
   104         fun qualify n = Binding.name n
   103           |> Binding.qualify true defname
   105           |> Binding.qualify true defname
   104         val conceal_partial = if partials then I else Binding.conceal
   106         val conceal_partial = if partials then I else Binding.conceal
   105 
   107 
   106         val addsmps = add_simps fnames post sort_cont
   108         val addsmps = add_simps fnames post sort_cont
   107 
   109 
   108         val ((((psimps', [pinducts']), [termination']), [cases']), lthy) =
   110         (* TODO: case names *)
       
   111         fun addcases lthy =
       
   112           let fun go name thm (thms_acc, lthy) =
       
   113                  case Local_Theory.note ((Binding.name "cases" |> Binding.qualify true name,
       
   114                           [Attrib.internal (K (Rule_Cases.case_names cnames))]), [thm]) lthy
       
   115                  of ((_,thms), lthy') => (thms :: thms_acc, lthy')
       
   116               val (thms, lthy') = fold2 go fnames cases ([], lthy);
       
   117           in
       
   118             (rev thms, lthy')
       
   119           end;
       
   120 
       
   121         fun addpelims lthy =
       
   122           let fun go name thm (thms_acc, lthy) =
       
   123                  case Local_Theory.note ((Binding.name "pelims" |> Binding.qualify true name,
       
   124                           [Attrib.internal (K (Rule_Cases.consumes 1)),
       
   125                            Attrib.internal (K (Rule_Cases.constraints 1))]), thm) lthy
       
   126                  of ((_,thms), lthy') => (thms :: thms_acc, lthy')
       
   127               val (thms, lthy') = fold2 go fnames pelims ([], lthy);
       
   128           in
       
   129             (rev thms, lthy')
       
   130           end;
       
   131 
       
   132           val (((((psimps', [pinducts']), [termination']), cases'), pelims'), lthy) =
   109           lthy
   133           lthy
   110           |> addsmps (conceal_partial o Binding.qualify false "partial")
   134           |> addsmps (conceal_partial o Binding.qualify false "partial")
   111                "psimps" conceal_partial psimp_attribs psimps
   135                "psimps" conceal_partial psimp_attribs psimps
   112           ||>> Local_Theory.notes [((conceal_partial (qualify "pinduct"), []),
   136           ||>> Local_Theory.notes [((conceal_partial (qualify "pinduct"), []),
   113                 simple_pinducts |> map (fn th => ([th],
   137                 simple_pinducts |> map (fn th => ([th],
   114                  [Attrib.internal (K (Rule_Cases.case_names cnames)),
   138                  [Attrib.internal (K (Rule_Cases.case_names cnames)),
   115                   Attrib.internal (K (Rule_Cases.consumes (1 - Thm.nprems_of th))),
   139                   Attrib.internal (K (Rule_Cases.consumes (1 - Thm.nprems_of th))),
   116                   Attrib.internal (K (Induct.induct_pred ""))])))]
   140                   Attrib.internal (K (Induct.induct_pred ""))])))]
   117           ||>> (apfst snd o Local_Theory.note ((Binding.conceal (qualify "termination"), []), [termination]))
   141           ||>> (apfst snd o Local_Theory.note ((Binding.conceal (qualify "termination"), []), [termination]))
   118           ||>> (apfst snd o Local_Theory.note ((qualify "cases",
   142           ||>> addcases
   119                  [Attrib.internal (K (Rule_Cases.case_names cnames))]), [cases]))
   143           ||>> addpelims
   120           ||> (case domintros of NONE => I | SOME thms => 
   144           ||> (case domintros of NONE => I | SOME thms =>
   121                    Local_Theory.note ((qualify "domintros", []), thms) #> snd)
   145                    Local_Theory.note ((qualify "domintros", []), thms) #> snd)
   122 
   146 
   123         val info = { add_simps=addsmps, case_names=cnames, psimps=psimps',
   147         val info = { add_simps=addsmps, fnames=fnames, case_names=cnames, psimps=psimps',
   124           pinducts=snd pinducts', simps=NONE, inducts=NONE, termination=termination',
   148           pinducts=snd pinducts', simps=NONE, inducts=NONE, termination=termination',
   125           fs=fs, R=R, dom=dom, defname=defname, is_partial=true, cases=cases'}
   149           fs=fs, R=R, dom=dom, defname=defname, is_partial=true, cases=flat cases',
       
   150           pelims=pelims',elims=NONE}
   126 
   151 
   127         val _ = Proof_Display.print_consts do_print lthy (K false) (map fst fixes)
   152         val _ = Proof_Display.print_consts do_print lthy (K false) (map fst fixes)
   128       in
   153       in
   129         (info,
   154         (info,
   130          lthy |> Local_Theory.declaration {syntax = false, pervasive = false}
   155          lthy |> Local_Theory.declaration {syntax = false, pervasive = false}
   178           (case import_last_function lthy of
   203           (case import_last_function lthy of
   179             SOME info => info
   204             SOME info => info
   180           | NONE => error "Not a function"))
   205           | NONE => error "Not a function"))
   181 
   206 
   182     val { termination, fs, R, add_simps, case_names, psimps,
   207     val { termination, fs, R, add_simps, case_names, psimps,
   183       pinducts, defname, cases, dom, ...} = info
   208       pinducts, defname, fnames, cases, dom, pelims, ...} = info
   184     val domT = domain_type (fastype_of R)
   209     val domT = domain_type (fastype_of R)
   185     val goal = HOLogic.mk_Trueprop (HOLogic.mk_all ("x", domT, mk_acc domT R $ Free ("x", domT)))
   210     val goal = HOLogic.mk_Trueprop (HOLogic.mk_all ("x", domT, mk_acc domT R $ Free ("x", domT)))
   186     fun afterqed [[totality]] lthy =
   211     fun afterqed [[totality]] lthy =
   187       let
   212       let
   188         val totality = Thm.close_derivation totality
   213         val totality = Thm.close_derivation totality
   189         val remove_domain_condition =
   214         val remove_domain_condition =
   190           full_simplify (put_simpset HOL_basic_ss lthy
   215           full_simplify (put_simpset HOL_basic_ss lthy
   191             addsimps [totality, @{thm True_implies_equals}])
   216             addsimps [totality, @{thm True_implies_equals}])
   192         val tsimps = map remove_domain_condition psimps
   217         val tsimps = map remove_domain_condition psimps
   193         val tinduct = map remove_domain_condition pinducts
   218         val tinduct = map remove_domain_condition pinducts
       
   219         val telims = map (map remove_domain_condition) pelims
   194 
   220 
   195         fun qualify n = Binding.name n
   221         fun qualify n = Binding.name n
   196           |> Binding.qualify true defname
   222           |> Binding.qualify true defname
       
   223 
       
   224         fun addtelims lthy =
       
   225           let fun go name thm (thms_acc, lthy) =
       
   226                  case Local_Theory.note ((Binding.name "elims" |> Binding.qualify true name,
       
   227                           [Attrib.internal (K (Rule_Cases.consumes 1)),
       
   228                            Attrib.internal (K (Rule_Cases.constraints 1)),
       
   229                            Attrib.internal (K (Induct.cases_pred defname))]), thm) lthy
       
   230                  of ((_,thms), lthy') => (thms :: thms_acc, lthy')
       
   231               val (thms, lthy') = fold2 go fnames telims ([], lthy);
       
   232           in
       
   233             (rev thms, lthy')
       
   234           end;
       
   235 
   197       in
   236       in
   198         lthy
   237         lthy
   199         |> add_simps I "simps" I simp_attribs tsimps
   238         |> add_simps I "simps" I simp_attribs tsimps
   200         ||>> Local_Theory.note
   239         ||>> Local_Theory.note
   201            ((qualify "induct",
   240            ((qualify "induct",
   202              [Attrib.internal (K (Rule_Cases.case_names case_names))]),
   241              [Attrib.internal (K (Rule_Cases.case_names case_names))]),
   203             tinduct)
   242             tinduct)
   204         |-> (fn (simps, (_, inducts)) => fn lthy =>
   243         ||>> addtelims
   205           let val info' = { is_partial=false, defname=defname, add_simps=add_simps,
   244         |-> (fn ((simps,(_,inducts)), elims) => fn lthy =>
       
   245           let val info' = { is_partial=false, defname=defname, fnames=fnames, add_simps=add_simps,
   206             case_names=case_names, fs=fs, R=R, dom=dom, psimps=psimps, pinducts=pinducts,
   246             case_names=case_names, fs=fs, R=R, dom=dom, psimps=psimps, pinducts=pinducts,
   207             simps=SOME simps, inducts=SOME inducts, termination=termination, cases=cases }
   247             simps=SOME simps, inducts=SOME inducts, termination=termination, cases=cases, pelims=pelims, elims=SOME elims}
   208           in
   248           in
   209             (info',
   249             (info',
   210              lthy 
   250              lthy
   211              |> Local_Theory.declaration {syntax = false, pervasive = false}
   251              |> Local_Theory.declaration {syntax = false, pervasive = false}
   212                (add_function_data o transform_function_data info')
   252                (add_function_data o transform_function_data info')
   213              |> Spec_Rules.add Spec_Rules.Equational (fs, tsimps))
   253              |> Spec_Rules.add Spec_Rules.Equational (fs, tsimps))
   214           end)
   254           end)
   215       end
   255       end