src/HOL/Tools/function_package/fundef_datatype.ML
changeset 30787 5b7a5a05c7aa
parent 30515 bca05b17b618
child 30790 350bb108406d
equal deleted inserted replaced
30785:15f64e05e703 30787:5b7a5a05c7aa
    13 
    13 
    14     val setup : theory -> theory
    14     val setup : theory -> theory
    15 
    15 
    16     val add_fun : FundefCommon.fundef_config ->
    16     val add_fun : FundefCommon.fundef_config ->
    17       (binding * typ option * mixfix) list -> (Attrib.binding * term) list ->
    17       (binding * typ option * mixfix) list -> (Attrib.binding * term) list ->
    18       bool list -> bool -> local_theory -> Proof.context
    18       bool -> local_theory -> Proof.context
    19     val add_fun_cmd : FundefCommon.fundef_config ->
    19     val add_fun_cmd : FundefCommon.fundef_config ->
    20       (binding * string option * mixfix) list -> (Attrib.binding * string) list ->
    20       (binding * string option * mixfix) list -> (Attrib.binding * string) list ->
    21       bool list -> bool -> local_theory -> Proof.context
    21       bool -> local_theory -> Proof.context
    22 end
    22 end
    23 
    23 
    24 structure FundefDatatype : FUNDEF_DATATYPE =
    24 structure FundefDatatype : FUNDEF_DATATYPE =
    25 struct
    25 struct
    26 
    26 
   233     in
   233     in
   234       map mk_eqn fixes
   234       map mk_eqn fixes
   235     end
   235     end
   236 
   236 
   237 fun add_catchall ctxt fixes spec =
   237 fun add_catchall ctxt fixes spec =
   238     let 
   238     spec @ mk_catchall fixes (mk_arities (map (split_def ctxt) spec))
   239       val catchalls = mk_catchall fixes (mk_arities (map (split_def ctxt) (map snd spec)))
       
   240     in
       
   241       spec @ map (pair true) catchalls
       
   242     end
       
   243 
   239 
   244 fun warn_if_redundant ctxt origs tss =
   240 fun warn_if_redundant ctxt origs tss =
   245     let
   241     let
   246         fun msg t = "Ignoring redundant equation: " ^ quote (Syntax.string_of_term ctxt t)
   242         fun msg t = "Ignoring redundant equation: " ^ quote (Syntax.string_of_term ctxt t)
   247                     
   243                     
   248         val (tss', _) = chop (length origs) tss
   244         val (tss', _) = chop (length origs) tss
   249         fun check ((_, t), []) = (Output.warning (msg t); [])
   245         fun check (t, []) = (Output.warning (msg t); [])
   250           | check ((_, t), s) = s
   246           | check (t, s) = s
   251     in
   247     in
   252         (map check (origs ~~ tss'); tss)
   248         (map check (origs ~~ tss'); tss)
   253     end
   249     end
   254 
   250 
   255 
   251 
   256 fun sequential_preproc (config as FundefConfig {sequential, ...}) flags ctxt fixes spec =
   252 fun sequential_preproc (config as FundefConfig {sequential, ...}) ctxt fixes spec =
   257     let
   253       if sequential then
   258       val enabled = sequential orelse exists I flags
       
   259     in 
       
   260       if enabled then
       
   261         let
   254         let
   262           val flags' = if sequential then map (K true) flags else flags
       
   263 
       
   264           val (nas, eqss) = split_list spec
   255           val (nas, eqss) = split_list spec
   265                             
   256                             
   266           val eqs = map the_single eqss
   257           val eqs = map the_single eqss
   267                     
   258                     
   268           val feqs = eqs
   259           val feqs = eqs
   269                       |> tap (check_defs ctxt fixes) (* Standard checks *)
   260                       |> tap (check_defs ctxt fixes) (* Standard checks *)
   270                       |> tap (map (check_pats ctxt))    (* More checks for sequential mode *)
   261                       |> tap (map (check_pats ctxt))    (* More checks for sequential mode *)
   271                       |> curry op ~~ flags'
       
   272 
   262 
   273           val compleqs = add_catchall ctxt fixes feqs   (* Completion *)
   263           val compleqs = add_catchall ctxt fixes feqs   (* Completion *)
   274 
   264 
   275           val spliteqs = warn_if_redundant ctxt feqs
   265           val spliteqs = warn_if_redundant ctxt feqs
   276                            (FundefSplit.split_some_equations ctxt compleqs)
   266                            (FundefSplit.split_all_equations ctxt compleqs)
   277 
   267 
   278           fun restore_spec thms =
   268           fun restore_spec thms =
   279               nas ~~ Library.take (length nas, Library.unflat spliteqs thms)
   269               nas ~~ Library.take (length nas, Library.unflat spliteqs thms)
   280               
   270               
   281           val spliteqs' = flat (Library.take (length nas, spliteqs))
   271           val spliteqs' = flat (Library.take (length nas, spliteqs))
   294                            |> flat
   284                            |> flat
   295         in
   285         in
   296           (flat spliteqs, restore_spec, sort, case_names)
   286           (flat spliteqs, restore_spec, sort, case_names)
   297         end
   287         end
   298       else
   288       else
   299         FundefCommon.empty_preproc check_defs config flags ctxt fixes spec
   289         FundefCommon.empty_preproc check_defs config ctxt fixes spec
   300     end
       
   301 
   290 
   302 val setup =
   291 val setup =
   303     Method.setup @{binding pat_completeness} (Scan.succeed pat_completeness)
   292     Method.setup @{binding pat_completeness} (Scan.succeed pat_completeness)
   304         "Completeness prover for datatype patterns"
   293         "Completeness prover for datatype patterns"
   305     #> Context.theory_map (FundefCommon.set_preproc sequential_preproc)
   294     #> Context.theory_map (FundefCommon.set_preproc sequential_preproc)
   306 
   295 
   307 
   296 
   308 val fun_config = FundefConfig { sequential=true, default="%x. undefined" (*FIXME dynamic scoping*), 
   297 val fun_config = FundefConfig { sequential=true, default="%x. undefined" (*FIXME dynamic scoping*), 
   309                                 domintros=false, tailrec=false }
   298                                 domintros=false, tailrec=false }
   310 
   299 
   311 fun gen_fun add config fixes statements flags int lthy =
   300 fun gen_fun add config fixes statements int lthy =
   312   let val group = serial_string () in
   301   let val group = serial_string () in
   313     lthy
   302     lthy
   314       |> LocalTheory.set_group group
   303       |> LocalTheory.set_group group
   315       |> add fixes statements config flags
   304       |> add fixes statements config
   316       |> by_pat_completeness_auto int
   305       |> by_pat_completeness_auto int
   317       |> LocalTheory.restore
   306       |> LocalTheory.restore
   318       |> LocalTheory.set_group group
   307       |> LocalTheory.set_group group
   319       |> termination_by (FundefCommon.get_termination_prover lthy) int
   308       |> termination_by (FundefCommon.get_termination_prover lthy) int
   320   end;
   309   end;
   327 local structure P = OuterParse and K = OuterKeyword in
   316 local structure P = OuterParse and K = OuterKeyword in
   328 
   317 
   329 val _ =
   318 val _ =
   330   OuterSyntax.local_theory' "fun" "define general recursive functions (short version)" K.thy_decl
   319   OuterSyntax.local_theory' "fun" "define general recursive functions (short version)" K.thy_decl
   331   (fundef_parser fun_config
   320   (fundef_parser fun_config
   332      >> (fn ((config, fixes), (flags, statements)) => add_fun_cmd config fixes statements flags));
   321      >> (fn ((config, fixes), statements) => add_fun_cmd config fixes statements));
   333 
   322 
   334 end
   323 end
   335 
   324 
   336 end
   325 end