src/HOL/Tools/Predicate_Compile/predicate_compile_fun.ML
changeset 35876 ac44e2312f0a
parent 35875 b0d24a74b06b
child 35877 295e1af6c8dc
equal deleted inserted replaced
35875:b0d24a74b06b 35876:ac44e2312f0a
   329 (* assumption: mutual recursive predicates all have the same parameters. *)  
   329 (* assumption: mutual recursive predicates all have the same parameters. *)  
   330 fun define_predicates specs thy =
   330 fun define_predicates specs thy =
   331   if forall (fn (const, _) => defined_const thy const) specs then
   331   if forall (fn (const, _) => defined_const thy const) specs then
   332     ([], thy)
   332     ([], thy)
   333   else
   333   else
   334   let
   334     let
   335     val consts = map fst specs
   335       val consts = map fst specs
   336     val eqns = maps snd specs
   336       val eqns = maps snd specs
   337     (*val eqns = maps (Predicate_Compile_Preproc_Data.get_specification thy) consts*)
   337       (*val eqns = maps (Predicate_Compile_Preproc_Data.get_specification thy) consts*)
   338       (* create prednames *)
   338         (* create prednames *)
   339     val ((funs, argss), rhss) = map_split dest_code_eqn eqns |>> split_list
   339       val ((funs, argss), rhss) = map_split dest_code_eqn eqns |>> split_list
   340     val argss' = map (map transform_ho_arg) argss
   340       val argss' = map (map transform_ho_arg) argss
   341     (* TODO: higher order arguments also occur in tuples! *)
   341       (* TODO: higher order arguments also occur in tuples! *)
   342     val ho_argss = distinct (op =) (maps (filter (is_funtype o fastype_of)) argss)
   342       fun is_lifted (t1, t2) = (fastype_of t2 = pred_type (fastype_of t1))
   343     val params = distinct (op =) (maps (filter (is_funtype o fastype_of)) argss')
   343       val lifted_args = distinct (op =) (filter is_lifted (flat argss ~~ flat argss'))
   344     val pnames = map dest_Free params
   344       val preds = map pred_of funs
   345     val preds = map pred_of funs
   345         (* mapping from term (Free or Const) to term *)
   346     val prednames = map (fst o dest_Free) preds
   346       val net = fold Item_Net.update
   347     val funnames = map (fst o dest_Const) funs
   347         ((funs ~~ preds) @ lifted_args)
   348     val fun_pred_names = (funnames ~~ prednames)  
   348           (Fun_Pred.get thy)
   349       (* mapping from term (Free or Const) to term *)
   349       fun lookup_pred t = lookup thy net t
   350     fun map_Free f = Free o f o dest_Free
   350       (* create intro rules *)
   351     val net = fold Item_Net.update
   351     
   352       ((funs ~~ preds) @ (ho_argss ~~ params))
   352       fun mk_intros ((func, pred), (args, rhs)) =
   353         (Fun_Pred.get thy)
   353         if (body_type (fastype_of func) = @{typ bool}) then
   354     fun lookup_pred t = lookup thy net t
   354          (*TODO: preprocess predicate definition of rhs *)
   355     (* create intro rules *)
   355           [Logic.list_implies ([HOLogic.mk_Trueprop rhs], HOLogic.mk_Trueprop (list_comb (pred, args)))]
   356   
       
   357     fun mk_intros ((func, pred), (args, rhs)) =
       
   358       if (body_type (fastype_of func) = @{typ bool}) then
       
   359        (*TODO: preprocess predicate definition of rhs *)
       
   360         [Logic.list_implies ([HOLogic.mk_Trueprop rhs], HOLogic.mk_Trueprop (list_comb (pred, args)))]
       
   361       else
       
   362         let
       
   363           val names = Term.add_free_names rhs []
       
   364         in flatten thy lookup_pred rhs (names, [])
       
   365           |> map (fn (resultt, (names', prems)) =>
       
   366             Logic.list_implies (prems, HOLogic.mk_Trueprop (list_comb (pred, args @ [resultt]))))
       
   367         end
       
   368     fun mk_rewr_thm (func, pred) = @{thm refl}
       
   369   in
       
   370     case (*try *)SOME (maps mk_intros ((funs ~~ preds) ~~ (argss' ~~ rhss))) of
       
   371       NONE =>
       
   372         let val _ = tracing "error occured!" in ([], thy) end
       
   373     | SOME intr_ts =>
       
   374         if is_some (try (map (cterm_of thy)) intr_ts) then
       
   375           let
       
   376             val (ind_result, thy') =
       
   377               thy
       
   378               |> Sign.map_naming Name_Space.conceal
       
   379               |> Inductive.add_inductive_global
       
   380                 {quiet_mode = false, verbose = false, alt_name = Binding.empty, coind = false,
       
   381                   no_elim = false, no_ind = false, skip_mono = false, fork_mono = false}
       
   382                 (map (fn (s, T) =>
       
   383                   ((Binding.name s, T), NoSyn)) (distinct (op =) (map dest_Free preds)))
       
   384                 []
       
   385                 (map (fn x => (Attrib.empty_binding, x)) intr_ts)
       
   386                 []
       
   387               ||> Sign.restore_naming thy
       
   388             val prednames = map (fst o dest_Const) (#preds ind_result)
       
   389             (* val rewr_thms = map mk_rewr_eq ((distinct (op =) funs) ~~ (#preds ind_result)) *)
       
   390             (* add constants to my table *)
       
   391             
       
   392             val specs = map (fn predname => (predname, filter (Predicate_Compile_Aux.is_intro predname)
       
   393               (#intrs ind_result))) prednames
       
   394             (*
       
   395             val thy'' = Pred_Compile_Preproc.map (fold Symtab.update_new (consts ~~ prednames)) thy'
       
   396             *)
       
   397             
       
   398             val thy'' = Fun_Pred.map
       
   399               (fold Item_Net.update (map (apfst Logic.varify_global)
       
   400                 (distinct (op =) funs ~~ (#preds ind_result)))) thy'
       
   401             (*val _ = print_specs thy'' specs*)
       
   402           in
       
   403             (specs, thy'')
       
   404           end
       
   405         else
   356         else
   406           let
   357           let
   407             val _ = Output.tracing (
   358             val names = Term.add_free_names rhs []
   408             "Introduction rules of function_predicate are not welltyped: " ^
   359           in flatten thy lookup_pred rhs (names, [])
   409               commas (map (Syntax.string_of_term_global thy) intr_ts))
   360             |> map (fn (resultt, (names', prems)) =>
   410           in ([], thy) end
   361               Logic.list_implies (prems, HOLogic.mk_Trueprop (list_comb (pred, args @ [resultt]))))
   411   end
   362           end
       
   363       fun mk_rewr_thm (func, pred) = @{thm refl}
       
   364     in
       
   365       case (*try *)SOME (maps mk_intros ((funs ~~ preds) ~~ (argss' ~~ rhss))) of
       
   366         NONE =>
       
   367           let val _ = tracing "error occured!" in ([], thy) end
       
   368       | SOME intr_ts =>
       
   369           if is_some (try (map (cterm_of thy)) intr_ts) then
       
   370             let
       
   371               val (ind_result, thy') =
       
   372                 thy
       
   373                 |> Sign.map_naming Name_Space.conceal
       
   374                 |> Inductive.add_inductive_global
       
   375                   {quiet_mode = false, verbose = false, alt_name = Binding.empty, coind = false,
       
   376                     no_elim = false, no_ind = false, skip_mono = false, fork_mono = false}
       
   377                   (map (fn (s, T) =>
       
   378                     ((Binding.name s, T), NoSyn)) (distinct (op =) (map dest_Free preds)))
       
   379                   []
       
   380                   (map (fn x => (Attrib.empty_binding, x)) intr_ts)
       
   381                   []
       
   382                 ||> Sign.restore_naming thy
       
   383               val prednames = map (fst o dest_Const) (#preds ind_result)
       
   384               (* val rewr_thms = map mk_rewr_eq ((distinct (op =) funs) ~~ (#preds ind_result)) *)
       
   385               (* add constants to my table *)
       
   386               
       
   387               val specs = map (fn predname => (predname, filter (Predicate_Compile_Aux.is_intro predname)
       
   388                 (#intrs ind_result))) prednames
       
   389               val thy'' = Fun_Pred.map
       
   390                 (fold Item_Net.update (map (apfst Logic.varify_global)
       
   391                   (distinct (op =) funs ~~ (#preds ind_result)))) thy'
       
   392               (*val _ = print_specs thy'' specs*)
       
   393             in
       
   394               (specs, thy'')
       
   395             end
       
   396           else
       
   397             let
       
   398               val _ = Output.tracing (
       
   399               "Introduction rules of function_predicate are not welltyped: " ^
       
   400                 commas (map (Syntax.string_of_term_global thy) intr_ts))
       
   401             in ([], thy) end
       
   402     end
   412 
   403 
   413 fun rewrite_intro thy intro =
   404 fun rewrite_intro thy intro =
   414   let
   405   let
   415     (*val _ = tracing ("Rewriting intro with registered mapping for: " ^
   406     (*val _ = tracing ("Rewriting intro with registered mapping for: " ^
   416       commas (Symtab.keys (Pred_Compile_Preproc.get thy)))*)
   407       commas (Symtab.keys (Pred_Compile_Preproc.get thy)))*)