src/HOL/Tools/Predicate_Compile/predicate_compile_fun.ML
changeset 69593 3dda49e08b9d
parent 64583 2edac4e13918
child 74561 8e6c973003c8
equal deleted inserted replaced
69592:a80d8ec6c998 69593:3dda49e08b9d
    99       (case lookup_pred (Envir.eta_contract t) of
    99       (case lookup_pred (Envir.eta_contract t) of
   100         SOME pred => [(pred, (names, prems))]
   100         SOME pred => [(pred, (names, prems))]
   101       | NONE =>
   101       | NONE =>
   102           let
   102           let
   103             val (vars, body) = strip_abs t
   103             val (vars, body) = strip_abs t
   104             val _ = @{assert} (fastype_of body = body_type (fastype_of body))
   104             val _ = \<^assert> (fastype_of body = body_type (fastype_of body))
   105             val absnames = Name.variant_list names (map fst vars)
   105             val absnames = Name.variant_list names (map fst vars)
   106             val frees = map2 (curry Free) absnames (map snd vars)
   106             val frees = map2 (curry Free) absnames (map snd vars)
   107             val body' = subst_bounds (rev frees, body)
   107             val body' = subst_bounds (rev frees, body)
   108             val resname = singleton (Name.variant_list (absnames @ names)) "res"
   108             val resname = singleton (Name.variant_list (absnames @ names)) "res"
   109             val resvar = Free (resname, fastype_of body)
   109             val resvar = Free (resname, fastype_of body)
   142       | flatten' (t as _ $ _) (names, prems) =
   142       | flatten' (t as _ $ _) (names, prems) =
   143       if is_constrt ctxt t orelse keep_functions thy t then
   143       if is_constrt ctxt t orelse keep_functions thy t then
   144         [(t, (names, prems))]
   144         [(t, (names, prems))]
   145       else
   145       else
   146         case (fst (strip_comb t)) of
   146         case (fst (strip_comb t)) of
   147           Const (@{const_name "If"}, _) =>
   147           Const (\<^const_name>\<open>If\<close>, _) =>
   148             (let
   148             (let
   149               val (_, [B, x, y]) = strip_comb t
   149               val (_, [B, x, y]) = strip_comb t
   150             in
   150             in
   151               flatten' B (names, prems)
   151               flatten' B (names, prems)
   152               |> maps (fn (B', (names, prems)) =>
   152               |> maps (fn (B', (names, prems)) =>
   155                 @ (flatten' y (names, prems)
   155                 @ (flatten' y (names, prems)
   156                 |> map (fn (res, (names, prems)) =>
   156                 |> map (fn (res, (names, prems)) =>
   157                   (* in general unsound! *)
   157                   (* in general unsound! *)
   158                   (res, (names, (HOLogic.mk_Trueprop (HOLogic.mk_not B')) :: prems)))))
   158                   (res, (names, (HOLogic.mk_Trueprop (HOLogic.mk_not B')) :: prems)))))
   159             end)
   159             end)
   160         | Const (@{const_name "Let"}, _) =>
   160         | Const (\<^const_name>\<open>Let\<close>, _) =>
   161             (let
   161             (let
   162               val (_, [f, g]) = strip_comb t
   162               val (_, [f, g]) = strip_comb t
   163             in
   163             in
   164               flatten' f (names, prems)
   164               flatten' f (names, prems)
   165               |> maps (fn (res, (names, prems)) =>
   165               |> maps (fn (res, (names, prems)) =>
   196           end
   196           end
   197       | NONE =>
   197       | NONE =>
   198           let
   198           let
   199             val (f, args) = strip_comb t
   199             val (f, args) = strip_comb t
   200             val args = map (Envir.eta_long []) args
   200             val args = map (Envir.eta_long []) args
   201             val _ = @{assert} (fastype_of t = body_type (fastype_of t))
   201             val _ = \<^assert> (fastype_of t = body_type (fastype_of t))
   202             val f' = lookup_pred f
   202             val f' = lookup_pred f
   203             val Ts =
   203             val Ts =
   204               (case f' of
   204               (case f' of
   205                 SOME pred => (fst (split_last (binder_types (fastype_of pred))))
   205                 SOME pred => (fst (split_last (binder_types (fastype_of pred))))
   206               | NONE => binder_types (fastype_of f))
   206               | NONE => binder_types (fastype_of f))
   214                   let
   214                   let
   215                     fun lift_arg T t =
   215                     fun lift_arg T t =
   216                       if (fastype_of t) = T then t
   216                       if (fastype_of t) = T then t
   217                       else
   217                       else
   218                         let
   218                         let
   219                           val _ = @{assert} (T =
   219                           val _ = \<^assert> (T =
   220                             (binder_types (fastype_of t) @ [@{typ bool}] ---> @{typ bool}))
   220                             (binder_types (fastype_of t) @ [\<^typ>\<open>bool\<close>] ---> \<^typ>\<open>bool\<close>))
   221                           fun mk_if T (b, t, e) =
   221                           fun mk_if T (b, t, e) =
   222                             Const (@{const_name If}, @{typ bool} --> T --> T --> T) $ b $ t $ e
   222                             Const (\<^const_name>\<open>If\<close>, \<^typ>\<open>bool\<close> --> T --> T --> T) $ b $ t $ e
   223                           val Ts = binder_types (fastype_of t)
   223                           val Ts = binder_types (fastype_of t)
   224                         in
   224                         in
   225                           fold_rev Term.abs (map (pair "x") Ts @ [("b", @{typ bool})])
   225                           fold_rev Term.abs (map (pair "x") Ts @ [("b", \<^typ>\<open>bool\<close>)])
   226                             (mk_if @{typ bool} (list_comb (t, map Bound (length Ts downto 1)),
   226                             (mk_if \<^typ>\<open>bool\<close> (list_comb (t, map Bound (length Ts downto 1)),
   227                               HOLogic.mk_eq (@{term True}, Bound 0),
   227                               HOLogic.mk_eq (\<^term>\<open>True\<close>, Bound 0),
   228                               HOLogic.mk_eq (@{term False}, Bound 0)))
   228                               HOLogic.mk_eq (\<^term>\<open>False\<close>, Bound 0)))
   229                         end
   229                         end
   230                     val argvs' = map2 lift_arg Ts argvs
   230                     val argvs' = map2 lift_arg Ts argvs
   231                     val resname = singleton (Name.variant_list names') "res"
   231                     val resname = singleton (Name.variant_list names') "res"
   232                     val resvar = Free (resname, body_type (fastype_of t))
   232                     val resvar = Free (resname, body_type (fastype_of t))
   233                     val prem = HOLogic.mk_Trueprop (list_comb (pred, argvs' @ [resvar]))
   233                     val prem = HOLogic.mk_Trueprop (list_comb (pred, argvs' @ [resvar]))
   241 fun pred_of thy f =
   241 fun pred_of thy f =
   242   let
   242   let
   243     val (name, T) = dest_Const f
   243     val (name, T) = dest_Const f
   244     val base_name' = (Long_Name.base_name name ^ "P")
   244     val base_name' = (Long_Name.base_name name ^ "P")
   245     val name' = Sign.full_bname thy base_name'
   245     val name' = Sign.full_bname thy base_name'
   246     val T' = if (body_type T = @{typ bool}) then T else pred_type T
   246     val T' = if (body_type T = \<^typ>\<open>bool\<close>) then T else pred_type T
   247   in
   247   in
   248     (name', Const (name', T'))
   248     (name', Const (name', T'))
   249   end
   249   end
   250 
   250 
   251 (* assumption: mutual recursive predicates all have the same parameters. *)
   251 (* assumption: mutual recursive predicates all have the same parameters. *)
   270         ((dst_funs ~~ dst_preds) @ lifted_args)
   270         ((dst_funs ~~ dst_preds) @ lifted_args)
   271           (Fun_Pred.get thy)
   271           (Fun_Pred.get thy)
   272       fun lookup_pred t = lookup thy net t
   272       fun lookup_pred t = lookup thy net t
   273       (* create intro rules *)
   273       (* create intro rules *)
   274       fun mk_intros ((func, pred), (args, rhs)) =
   274       fun mk_intros ((func, pred), (args, rhs)) =
   275         if (body_type (fastype_of func) = @{typ bool}) then
   275         if (body_type (fastype_of func) = \<^typ>\<open>bool\<close>) then
   276          (* TODO: preprocess predicate definition of rhs *)
   276          (* TODO: preprocess predicate definition of rhs *)
   277           [Logic.list_implies
   277           [Logic.list_implies
   278             ([HOLogic.mk_Trueprop rhs], HOLogic.mk_Trueprop (list_comb (pred, args)))]
   278             ([HOLogic.mk_Trueprop rhs], HOLogic.mk_Trueprop (list_comb (pred, args)))]
   279         else
   279         else
   280           let
   280           let