src/HOL/Tools/Predicate_Compile/predicate_compile_fun.ML
changeset 50056 72efd6b4038d
parent 49323 6dff6b1f5417
child 51317 0e70cc4e94e8
equal deleted inserted replaced
50055:94041d602ecb 50056:72efd6b4038d
    38   end
    38   end
    39 
    39 
    40 fun pred_of_function thy name =
    40 fun pred_of_function thy name =
    41   case Item_Net.retrieve (Fun_Pred.get thy) (Const (name, dummyT)) of
    41   case Item_Net.retrieve (Fun_Pred.get thy) (Const (name, dummyT)) of
    42     [] => NONE
    42     [] => NONE
    43   | [(f, p)] => SOME (fst (dest_Const p))
    43   | [(_, p)] => SOME (fst (dest_Const p))
    44   | _ => error ("Multiple matches possible for lookup of constant " ^ name)
    44   | _ => error ("Multiple matches possible for lookup of constant " ^ name)
    45 
    45 
    46 fun defined_const thy name = is_some (pred_of_function thy name)
    46 fun defined_const thy name = is_some (pred_of_function thy name)
    47 
    47 
    48 fun add_function_predicate_translation (f, p) =
    48 fun add_function_predicate_translation (f, p) =
    75 
    75 
    76 fun dest_code_eqn eqn = let
    76 fun dest_code_eqn eqn = let
    77   val (lhs, rhs) = Logic.dest_equals (Logic.unvarify_global (Thm.prop_of eqn))
    77   val (lhs, rhs) = Logic.dest_equals (Logic.unvarify_global (Thm.prop_of eqn))
    78   val (func, args) = strip_comb lhs
    78   val (func, args) = strip_comb lhs
    79 in ((func, args), rhs) end;
    79 in ((func, args), rhs) end;
    80 
       
    81 (* TODO: does not work with higher order functions yet *)
       
    82 fun mk_rewr_eq (func, pred) =
       
    83   let
       
    84     val (argTs, resT) = strip_type (fastype_of func)
       
    85     val nctxt =
       
    86       Name.make_context (Term.fold_aterms (fn Free (x, _) => insert (op =) x | _ => I) (func $ pred) [])
       
    87     val (argnames, nctxt') = fold_map Name.variant (replicate (length argTs) "a") nctxt
       
    88     val (resname, nctxt'') = Name.variant "r" nctxt'
       
    89     val args = map Free (argnames ~~ argTs)
       
    90     val res = Free (resname, resT)
       
    91   in Logic.mk_equals
       
    92       (HOLogic.mk_eq (res, list_comb (func, args)), list_comb (pred, args @ [res]))
       
    93   end;
       
    94 
    80 
    95 fun folds_map f xs y =
    81 fun folds_map f xs y =
    96   let
    82   let
    97     fun folds_map' acc [] y = [(rev acc, y)]
    83     fun folds_map' acc [] y = [(rev acc, y)]
    98       | folds_map' acc (x :: xs) y =
    84       | folds_map' acc (x :: xs) y =
   124             |> map (fn (res, (inner_names, inner_prems)) =>
   110             |> map (fn (res, (inner_names, inner_prems)) =>
   125               let
   111               let
   126                 fun mk_exists (x, T) t = HOLogic.mk_exists (x, T, t)
   112                 fun mk_exists (x, T) t = HOLogic.mk_exists (x, T, t)
   127                 val vTs = 
   113                 val vTs = 
   128                   fold Term.add_frees inner_prems []
   114                   fold Term.add_frees inner_prems []
   129                   |> filter (fn (x, T) => member (op =) inner_names x)
   115                   |> filter (fn (x, _) => member (op =) inner_names x)
   130                 val t = 
   116                 val t = 
   131                   fold mk_exists vTs
   117                   fold mk_exists vTs
   132                   (foldr1 HOLogic.mk_conj (HOLogic.mk_eq (res, resvar) ::
   118                   (foldr1 HOLogic.mk_conj (HOLogic.mk_eq (res, resvar) ::
   133                     map HOLogic.dest_Trueprop inner_prems))
   119                     map HOLogic.dest_Trueprop inner_prems))
   134               in
   120               in
   147         if (pred_type (fastype_of t) = T) then
   133         if (pred_type (fastype_of t) = T) then
   148           lift t (names, prems)
   134           lift t (names, prems)
   149         else
   135         else
   150           error ("unexpected input for flatten or lift" ^ Syntax.string_of_term_global thy t ^
   136           error ("unexpected input for flatten or lift" ^ Syntax.string_of_term_global thy t ^
   151           ", " ^  Syntax.string_of_typ_global thy T)
   137           ", " ^  Syntax.string_of_typ_global thy T)
   152     and flatten' (t as Const (name, T)) (names, prems) = [(t, (names, prems))]
   138     and flatten' (t as Const _) (names, prems) = [(t, (names, prems))]
   153       | flatten' (t as Free (f, T)) (names, prems) = [(t, (names, prems))]
   139       | flatten' (t as Free _) (names, prems) = [(t, (names, prems))]
   154       | flatten' (t as Abs _) (names, prems) = [(t, (names, prems))]
   140       | flatten' (t as Abs _) (names, prems) = [(t, (names, prems))]
   155       | flatten' (t as _ $ _) (names, prems) =
   141       | flatten' (t as _ $ _) (names, prems) =
   156       if Predicate_Compile_Aux.is_constrt thy t orelse keep_functions thy t then
   142       if Predicate_Compile_Aux.is_constrt thy t orelse keep_functions thy t then
   157         [(t, (names, prems))]
   143         [(t, (names, prems))]
   158       else
   144       else
   180             end)
   166             end)
   181         | _ =>
   167         | _ =>
   182         case find_split_thm thy (fst (strip_comb t)) of
   168         case find_split_thm thy (fst (strip_comb t)) of
   183           SOME raw_split_thm =>
   169           SOME raw_split_thm =>
   184           let
   170           let
   185             val (f, args) = strip_comb t
       
   186             val split_thm = prepare_split_thm (Proof_Context.init_global thy) raw_split_thm
   171             val split_thm = prepare_split_thm (Proof_Context.init_global thy) raw_split_thm
   187             val (assms, concl) = Logic.strip_horn (prop_of split_thm)
   172             val (assms, concl) = Logic.strip_horn (prop_of split_thm)
   188             val (P, [split_t]) = strip_comb (HOLogic.dest_Trueprop concl)
   173             val (_, [split_t]) = strip_comb (HOLogic.dest_Trueprop concl)
   189             val t' = case_betapply thy t
   174             val t' = case_betapply thy t
   190             val subst = Pattern.match thy (split_t, t') (Vartab.empty, Vartab.empty)
   175             val subst = Pattern.match thy (split_t, t') (Vartab.empty, Vartab.empty)
   191             fun flatten_of_assm assm =
   176             fun flatten_of_assm assm =
   192               let
   177               let
   193                 val (vTs, assm') = strip_all (Envir.beta_norm (Envir.subst_term subst assm))
   178                 val (vTs, assm') = strip_all (Envir.beta_norm (Envir.subst_term subst assm))
   265 fun define_predicates specs thy =
   250 fun define_predicates specs thy =
   266   if forall (fn (const, _) => defined_const thy const) specs then
   251   if forall (fn (const, _) => defined_const thy const) specs then
   267     ([], thy)
   252     ([], thy)
   268   else
   253   else
   269     let
   254     let
   270       val consts = map fst specs
       
   271       val eqns = maps snd specs
   255       val eqns = maps snd specs
   272       (* create prednames *)
   256       (* create prednames *)
   273       val ((funs, argss), rhss) = map_split dest_code_eqn eqns |>> split_list
   257       val ((funs, argss), rhss) = map_split dest_code_eqn eqns |>> split_list
   274       val dst_funs = distinct (op =) funs
   258       val dst_funs = distinct (op =) funs
   275       val argss' = map (map transform_ho_arg) argss
   259       val argss' = map (map transform_ho_arg) argss
   291           [Logic.list_implies ([HOLogic.mk_Trueprop rhs], HOLogic.mk_Trueprop (list_comb (pred, args)))]
   275           [Logic.list_implies ([HOLogic.mk_Trueprop rhs], HOLogic.mk_Trueprop (list_comb (pred, args)))]
   292         else
   276         else
   293           let
   277           let
   294             val names = Term.add_free_names rhs []
   278             val names = Term.add_free_names rhs []
   295           in flatten thy lookup_pred rhs (names, [])
   279           in flatten thy lookup_pred rhs (names, [])
   296             |> map (fn (resultt, (names', prems)) =>
   280             |> map (fn (resultt, (_, prems)) =>
   297               Logic.list_implies (prems, HOLogic.mk_Trueprop (list_comb (pred, args @ [resultt]))))
   281               Logic.list_implies (prems, HOLogic.mk_Trueprop (list_comb (pred, args @ [resultt]))))
   298           end
   282           end
   299       fun mk_rewr_thm (func, pred) = @{thm refl}
       
   300       val intr_ts = maps mk_intros ((funs ~~ preds) ~~ (argss' ~~ rhss))
   283       val intr_ts = maps mk_intros ((funs ~~ preds) ~~ (argss' ~~ rhss))
   301       val (intrs, thy') = thy
   284       val (intrs, thy') = thy
   302         |> Sign.add_consts_i
   285         |> Sign.add_consts_i
   303           (map (fn Const (name, T) => (Binding.name (Long_Name.base_name name), T, NoSyn))
   286           (map (fn Const (name, T) => (Binding.name (Long_Name.base_name name), T, NoSyn))
   304            dst_preds)
   287            dst_preds)