src/HOL/Tools/Predicate_Compile/predicate_compile_fun.ML
author haftmann
Wed, 26 May 2010 16:05:25 +0200
changeset 37135 636e6d8645d6
parent 36610 bafd82950e24
child 37591 d3daea901123
permissions -rw-r--r--
normalized references to constant "split"
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
33265
01c9c6dbd890 proper headers;
wenzelm
parents: 33250
diff changeset
     1
(*  Title:      HOL/Tools/Predicate_Compile/predicate_compile_fun.ML
01c9c6dbd890 proper headers;
wenzelm
parents: 33250
diff changeset
     2
    Author:     Lukas Bulwahn, TU Muenchen
33250
5c2af18a3237 including the predicate compiler in HOL-Main; added RandomPredicate monad to Quickcheck
bulwahn
parents:
diff changeset
     3
33265
01c9c6dbd890 proper headers;
wenzelm
parents: 33250
diff changeset
     4
Preprocessing functions to predicates.
33250
5c2af18a3237 including the predicate compiler in HOL-Main; added RandomPredicate monad to Quickcheck
bulwahn
parents:
diff changeset
     5
*)
5c2af18a3237 including the predicate compiler in HOL-Main; added RandomPredicate monad to Quickcheck
bulwahn
parents:
diff changeset
     6
5c2af18a3237 including the predicate compiler in HOL-Main; added RandomPredicate monad to Quickcheck
bulwahn
parents:
diff changeset
     7
signature PREDICATE_COMPILE_FUN =
5c2af18a3237 including the predicate compiler in HOL-Main; added RandomPredicate monad to Quickcheck
bulwahn
parents:
diff changeset
     8
sig
33630
68e058d061f5 removed unnecessary oracle in the predicate compiler
bulwahn
parents: 33522
diff changeset
     9
  val define_predicates : (string * thm list) list -> theory -> (string * thm list) list * theory
33250
5c2af18a3237 including the predicate compiler in HOL-Main; added RandomPredicate monad to Quickcheck
bulwahn
parents:
diff changeset
    10
  val rewrite_intro : theory -> thm -> thm list
5c2af18a3237 including the predicate compiler in HOL-Main; added RandomPredicate monad to Quickcheck
bulwahn
parents:
diff changeset
    11
  val pred_of_function : theory -> string -> string option
35324
c9f428269b38 adopting mutabelle and quickcheck to return timing information; exporting make_case_combs in datatype package for predicate compiler; adding Spec_Rules declaration for tail recursive functions; improving the predicate compiler and function flattening
bulwahn
parents: 35021
diff changeset
    12
  val add_function_predicate_translation : (term * term) -> theory -> theory
33250
5c2af18a3237 including the predicate compiler in HOL-Main; added RandomPredicate monad to Quickcheck
bulwahn
parents:
diff changeset
    13
end;
5c2af18a3237 including the predicate compiler in HOL-Main; added RandomPredicate monad to Quickcheck
bulwahn
parents:
diff changeset
    14
5c2af18a3237 including the predicate compiler in HOL-Main; added RandomPredicate monad to Quickcheck
bulwahn
parents:
diff changeset
    15
structure Predicate_Compile_Fun : PREDICATE_COMPILE_FUN =
5c2af18a3237 including the predicate compiler in HOL-Main; added RandomPredicate monad to Quickcheck
bulwahn
parents:
diff changeset
    16
struct
5c2af18a3237 including the predicate compiler in HOL-Main; added RandomPredicate monad to Quickcheck
bulwahn
parents:
diff changeset
    17
34948
2d5f2a9f7601 refactoring the predicate compiler; adding theories for Sequences; adding retrieval to Spec_Rules; adding timing to Quickcheck
bulwahn
parents: 33752
diff changeset
    18
open Predicate_Compile_Aux;
33250
5c2af18a3237 including the predicate compiler in HOL-Main; added RandomPredicate monad to Quickcheck
bulwahn
parents:
diff changeset
    19
35324
c9f428269b38 adopting mutabelle and quickcheck to return timing information; exporting make_case_combs in datatype package for predicate compiler; adding Spec_Rules declaration for tail recursive functions; improving the predicate compiler and function flattening
bulwahn
parents: 35021
diff changeset
    20
(* Table from function to inductive predicate *)
c9f428269b38 adopting mutabelle and quickcheck to return timing information; exporting make_case_combs in datatype package for predicate compiler; adding Spec_Rules declaration for tail recursive functions; improving the predicate compiler and function flattening
bulwahn
parents: 35021
diff changeset
    21
structure Fun_Pred = Theory_Data
33250
5c2af18a3237 including the predicate compiler in HOL-Main; added RandomPredicate monad to Quickcheck
bulwahn
parents:
diff changeset
    22
(
35324
c9f428269b38 adopting mutabelle and quickcheck to return timing information; exporting make_case_combs in datatype package for predicate compiler; adding Spec_Rules declaration for tail recursive functions; improving the predicate compiler and function flattening
bulwahn
parents: 35021
diff changeset
    23
  type T = (term * term) Item_Net.T;
35411
cafb74a131da made smlnj happy
bulwahn
parents: 35324
diff changeset
    24
  val empty = Item_Net.init ((op aconv o pairself fst) : (term * term) * (term * term) -> bool)
cafb74a131da made smlnj happy
bulwahn
parents: 35324
diff changeset
    25
    (single o fst);
33250
5c2af18a3237 including the predicate compiler in HOL-Main; added RandomPredicate monad to Quickcheck
bulwahn
parents:
diff changeset
    26
  val extend = I;
35324
c9f428269b38 adopting mutabelle and quickcheck to return timing information; exporting make_case_combs in datatype package for predicate compiler; adding Spec_Rules declaration for tail recursive functions; improving the predicate compiler and function flattening
bulwahn
parents: 35021
diff changeset
    27
  val merge = Item_Net.merge;
33250
5c2af18a3237 including the predicate compiler in HOL-Main; added RandomPredicate monad to Quickcheck
bulwahn
parents:
diff changeset
    28
)
5c2af18a3237 including the predicate compiler in HOL-Main; added RandomPredicate monad to Quickcheck
bulwahn
parents:
diff changeset
    29
35324
c9f428269b38 adopting mutabelle and quickcheck to return timing information; exporting make_case_combs in datatype package for predicate compiler; adding Spec_Rules declaration for tail recursive functions; improving the predicate compiler and function flattening
bulwahn
parents: 35021
diff changeset
    30
fun lookup thy net t =
36051
810357220388 improving lookup function to handle overloaded constants more correctly in the function flattening of the predicate compiler
bulwahn
parents: 36039
diff changeset
    31
  let
810357220388 improving lookup function to handle overloaded constants more correctly in the function flattening of the predicate compiler
bulwahn
parents: 36039
diff changeset
    32
    val poss_preds = map_filter (fn (f, p) =>
36039
bulwahn
parents: 36035
diff changeset
    33
    SOME (Envir.subst_term (Pattern.match thy (f, t) (Vartab.empty, Vartab.empty)) p)
36051
810357220388 improving lookup function to handle overloaded constants more correctly in the function flattening of the predicate compiler
bulwahn
parents: 36039
diff changeset
    34
    handle Pattern.MATCH => NONE) (Item_Net.retrieve net t)
810357220388 improving lookup function to handle overloaded constants more correctly in the function flattening of the predicate compiler
bulwahn
parents: 36039
diff changeset
    35
  in
810357220388 improving lookup function to handle overloaded constants more correctly in the function flattening of the predicate compiler
bulwahn
parents: 36039
diff changeset
    36
    case poss_preds of
810357220388 improving lookup function to handle overloaded constants more correctly in the function flattening of the predicate compiler
bulwahn
parents: 36039
diff changeset
    37
      [p] => SOME p
810357220388 improving lookup function to handle overloaded constants more correctly in the function flattening of the predicate compiler
bulwahn
parents: 36039
diff changeset
    38
    | _ => NONE
810357220388 improving lookup function to handle overloaded constants more correctly in the function flattening of the predicate compiler
bulwahn
parents: 36039
diff changeset
    39
  end
33250
5c2af18a3237 including the predicate compiler in HOL-Main; added RandomPredicate monad to Quickcheck
bulwahn
parents:
diff changeset
    40
35324
c9f428269b38 adopting mutabelle and quickcheck to return timing information; exporting make_case_combs in datatype package for predicate compiler; adding Spec_Rules declaration for tail recursive functions; improving the predicate compiler and function flattening
bulwahn
parents: 35021
diff changeset
    41
fun pred_of_function thy name =
c9f428269b38 adopting mutabelle and quickcheck to return timing information; exporting make_case_combs in datatype package for predicate compiler; adding Spec_Rules declaration for tail recursive functions; improving the predicate compiler and function flattening
bulwahn
parents: 35021
diff changeset
    42
  case Item_Net.retrieve (Fun_Pred.get thy) (Const (name, Term.dummyT)) of
c9f428269b38 adopting mutabelle and quickcheck to return timing information; exporting make_case_combs in datatype package for predicate compiler; adding Spec_Rules declaration for tail recursive functions; improving the predicate compiler and function flattening
bulwahn
parents: 35021
diff changeset
    43
    [] => NONE
c9f428269b38 adopting mutabelle and quickcheck to return timing information; exporting make_case_combs in datatype package for predicate compiler; adding Spec_Rules declaration for tail recursive functions; improving the predicate compiler and function flattening
bulwahn
parents: 35021
diff changeset
    44
  | [(f, p)] => SOME (fst (dest_Const p))
c9f428269b38 adopting mutabelle and quickcheck to return timing information; exporting make_case_combs in datatype package for predicate compiler; adding Spec_Rules declaration for tail recursive functions; improving the predicate compiler and function flattening
bulwahn
parents: 35021
diff changeset
    45
  | _ => error ("Multiple matches possible for lookup of constant " ^ name)
33250
5c2af18a3237 including the predicate compiler in HOL-Main; added RandomPredicate monad to Quickcheck
bulwahn
parents:
diff changeset
    46
35324
c9f428269b38 adopting mutabelle and quickcheck to return timing information; exporting make_case_combs in datatype package for predicate compiler; adding Spec_Rules declaration for tail recursive functions; improving the predicate compiler and function flattening
bulwahn
parents: 35021
diff changeset
    47
fun defined_const thy name = is_some (pred_of_function thy name)
c9f428269b38 adopting mutabelle and quickcheck to return timing information; exporting make_case_combs in datatype package for predicate compiler; adding Spec_Rules declaration for tail recursive functions; improving the predicate compiler and function flattening
bulwahn
parents: 35021
diff changeset
    48
c9f428269b38 adopting mutabelle and quickcheck to return timing information; exporting make_case_combs in datatype package for predicate compiler; adding Spec_Rules declaration for tail recursive functions; improving the predicate compiler and function flattening
bulwahn
parents: 35021
diff changeset
    49
fun add_function_predicate_translation (f, p) =
c9f428269b38 adopting mutabelle and quickcheck to return timing information; exporting make_case_combs in datatype package for predicate compiler; adding Spec_Rules declaration for tail recursive functions; improving the predicate compiler and function flattening
bulwahn
parents: 35021
diff changeset
    50
  Fun_Pred.map (Item_Net.update (f, p))
33250
5c2af18a3237 including the predicate compiler in HOL-Main; added RandomPredicate monad to Quickcheck
bulwahn
parents:
diff changeset
    51
5c2af18a3237 including the predicate compiler in HOL-Main; added RandomPredicate monad to Quickcheck
bulwahn
parents:
diff changeset
    52
fun transform_ho_typ (T as Type ("fun", _)) =
5c2af18a3237 including the predicate compiler in HOL-Main; added RandomPredicate monad to Quickcheck
bulwahn
parents:
diff changeset
    53
  let
5c2af18a3237 including the predicate compiler in HOL-Main; added RandomPredicate monad to Quickcheck
bulwahn
parents:
diff changeset
    54
    val (Ts, T') = strip_type T
5c2af18a3237 including the predicate compiler in HOL-Main; added RandomPredicate monad to Quickcheck
bulwahn
parents:
diff changeset
    55
  in if T' = @{typ "bool"} then T else (Ts @ [T']) ---> HOLogic.boolT end
5c2af18a3237 including the predicate compiler in HOL-Main; added RandomPredicate monad to Quickcheck
bulwahn
parents:
diff changeset
    56
| transform_ho_typ t = t
5c2af18a3237 including the predicate compiler in HOL-Main; added RandomPredicate monad to Quickcheck
bulwahn
parents:
diff changeset
    57
5c2af18a3237 including the predicate compiler in HOL-Main; added RandomPredicate monad to Quickcheck
bulwahn
parents:
diff changeset
    58
fun transform_ho_arg arg = 
5c2af18a3237 including the predicate compiler in HOL-Main; added RandomPredicate monad to Quickcheck
bulwahn
parents:
diff changeset
    59
  case (fastype_of arg) of
5c2af18a3237 including the predicate compiler in HOL-Main; added RandomPredicate monad to Quickcheck
bulwahn
parents:
diff changeset
    60
    (T as Type ("fun", _)) =>
5c2af18a3237 including the predicate compiler in HOL-Main; added RandomPredicate monad to Quickcheck
bulwahn
parents:
diff changeset
    61
      (case arg of
5c2af18a3237 including the predicate compiler in HOL-Main; added RandomPredicate monad to Quickcheck
bulwahn
parents:
diff changeset
    62
        Free (name, _) => Free (name, transform_ho_typ T)
35878
74a74828d682 cleaning the function flattening
bulwahn
parents: 35877
diff changeset
    63
      | _ => raise Fail "A non-variable term at a higher-order position")
74a74828d682 cleaning the function flattening
bulwahn
parents: 35877
diff changeset
    64
  | _ => arg
33250
5c2af18a3237 including the predicate compiler in HOL-Main; added RandomPredicate monad to Quickcheck
bulwahn
parents:
diff changeset
    65
5c2af18a3237 including the predicate compiler in HOL-Main; added RandomPredicate monad to Quickcheck
bulwahn
parents:
diff changeset
    66
fun pred_type T =
5c2af18a3237 including the predicate compiler in HOL-Main; added RandomPredicate monad to Quickcheck
bulwahn
parents:
diff changeset
    67
  let
5c2af18a3237 including the predicate compiler in HOL-Main; added RandomPredicate monad to Quickcheck
bulwahn
parents:
diff changeset
    68
    val (Ts, T') = strip_type T
5c2af18a3237 including the predicate compiler in HOL-Main; added RandomPredicate monad to Quickcheck
bulwahn
parents:
diff changeset
    69
    val Ts' = map transform_ho_typ Ts
5c2af18a3237 including the predicate compiler in HOL-Main; added RandomPredicate monad to Quickcheck
bulwahn
parents:
diff changeset
    70
  in
5c2af18a3237 including the predicate compiler in HOL-Main; added RandomPredicate monad to Quickcheck
bulwahn
parents:
diff changeset
    71
    (Ts' @ [T']) ---> HOLogic.boolT
5c2af18a3237 including the predicate compiler in HOL-Main; added RandomPredicate monad to Quickcheck
bulwahn
parents:
diff changeset
    72
  end;
5c2af18a3237 including the predicate compiler in HOL-Main; added RandomPredicate monad to Quickcheck
bulwahn
parents:
diff changeset
    73
5c2af18a3237 including the predicate compiler in HOL-Main; added RandomPredicate monad to Quickcheck
bulwahn
parents:
diff changeset
    74
(* creates the list of premises for every intro rule *)
5c2af18a3237 including the predicate compiler in HOL-Main; added RandomPredicate monad to Quickcheck
bulwahn
parents:
diff changeset
    75
(* theory -> term -> (string list, term list list) *)
5c2af18a3237 including the predicate compiler in HOL-Main; added RandomPredicate monad to Quickcheck
bulwahn
parents:
diff changeset
    76
5c2af18a3237 including the predicate compiler in HOL-Main; added RandomPredicate monad to Quickcheck
bulwahn
parents:
diff changeset
    77
fun dest_code_eqn eqn = let
35845
e5980f0ad025 renamed varify/unvarify operations to varify_global/unvarify_global to emphasize that these only work in a global situation;
wenzelm
parents: 35411
diff changeset
    78
  val (lhs, rhs) = Logic.dest_equals (Logic.unvarify_global (Thm.prop_of eqn))
33250
5c2af18a3237 including the predicate compiler in HOL-Main; added RandomPredicate monad to Quickcheck
bulwahn
parents:
diff changeset
    79
  val (func, args) = strip_comb lhs
5c2af18a3237 including the predicate compiler in HOL-Main; added RandomPredicate monad to Quickcheck
bulwahn
parents:
diff changeset
    80
in ((func, args), rhs) end;
5c2af18a3237 including the predicate compiler in HOL-Main; added RandomPredicate monad to Quickcheck
bulwahn
parents:
diff changeset
    81
5c2af18a3237 including the predicate compiler in HOL-Main; added RandomPredicate monad to Quickcheck
bulwahn
parents:
diff changeset
    82
(* TODO: does not work with higher order functions yet *)
5c2af18a3237 including the predicate compiler in HOL-Main; added RandomPredicate monad to Quickcheck
bulwahn
parents:
diff changeset
    83
fun mk_rewr_eq (func, pred) =
5c2af18a3237 including the predicate compiler in HOL-Main; added RandomPredicate monad to Quickcheck
bulwahn
parents:
diff changeset
    84
  let
5c2af18a3237 including the predicate compiler in HOL-Main; added RandomPredicate monad to Quickcheck
bulwahn
parents:
diff changeset
    85
    val (argTs, resT) = (strip_type (fastype_of func))
5c2af18a3237 including the predicate compiler in HOL-Main; added RandomPredicate monad to Quickcheck
bulwahn
parents:
diff changeset
    86
    val nctxt =
5c2af18a3237 including the predicate compiler in HOL-Main; added RandomPredicate monad to Quickcheck
bulwahn
parents:
diff changeset
    87
      Name.make_context (Term.fold_aterms (fn Free (x, _) => insert (op =) x | _ => I) (func $ pred) [])
5c2af18a3237 including the predicate compiler in HOL-Main; added RandomPredicate monad to Quickcheck
bulwahn
parents:
diff changeset
    88
    val (argnames, nctxt') = Name.variants (replicate (length argTs) "a") nctxt
5c2af18a3237 including the predicate compiler in HOL-Main; added RandomPredicate monad to Quickcheck
bulwahn
parents:
diff changeset
    89
    val ([resname], nctxt'') = Name.variants ["r"] nctxt'
5c2af18a3237 including the predicate compiler in HOL-Main; added RandomPredicate monad to Quickcheck
bulwahn
parents:
diff changeset
    90
    val args = map Free (argnames ~~ argTs)
5c2af18a3237 including the predicate compiler in HOL-Main; added RandomPredicate monad to Quickcheck
bulwahn
parents:
diff changeset
    91
    val res = Free (resname, resT)
5c2af18a3237 including the predicate compiler in HOL-Main; added RandomPredicate monad to Quickcheck
bulwahn
parents:
diff changeset
    92
  in Logic.mk_equals
5c2af18a3237 including the predicate compiler in HOL-Main; added RandomPredicate monad to Quickcheck
bulwahn
parents:
diff changeset
    93
      (HOLogic.mk_eq (res, list_comb (func, args)), list_comb (pred, args @ [res]))
5c2af18a3237 including the predicate compiler in HOL-Main; added RandomPredicate monad to Quickcheck
bulwahn
parents:
diff changeset
    94
  end;
5c2af18a3237 including the predicate compiler in HOL-Main; added RandomPredicate monad to Quickcheck
bulwahn
parents:
diff changeset
    95
5c2af18a3237 including the predicate compiler in HOL-Main; added RandomPredicate monad to Quickcheck
bulwahn
parents:
diff changeset
    96
fun folds_map f xs y =
5c2af18a3237 including the predicate compiler in HOL-Main; added RandomPredicate monad to Quickcheck
bulwahn
parents:
diff changeset
    97
  let
5c2af18a3237 including the predicate compiler in HOL-Main; added RandomPredicate monad to Quickcheck
bulwahn
parents:
diff changeset
    98
    fun folds_map' acc [] y = [(rev acc, y)]
5c2af18a3237 including the predicate compiler in HOL-Main; added RandomPredicate monad to Quickcheck
bulwahn
parents:
diff changeset
    99
      | folds_map' acc (x :: xs) y =
5c2af18a3237 including the predicate compiler in HOL-Main; added RandomPredicate monad to Quickcheck
bulwahn
parents:
diff changeset
   100
        maps (fn (x, y) => folds_map' (x :: acc) xs y) (f x y)
5c2af18a3237 including the predicate compiler in HOL-Main; added RandomPredicate monad to Quickcheck
bulwahn
parents:
diff changeset
   101
    in
5c2af18a3237 including the predicate compiler in HOL-Main; added RandomPredicate monad to Quickcheck
bulwahn
parents:
diff changeset
   102
      folds_map' [] xs y
5c2af18a3237 including the predicate compiler in HOL-Main; added RandomPredicate monad to Quickcheck
bulwahn
parents:
diff changeset
   103
    end;
5c2af18a3237 including the predicate compiler in HOL-Main; added RandomPredicate monad to Quickcheck
bulwahn
parents:
diff changeset
   104
35324
c9f428269b38 adopting mutabelle and quickcheck to return timing information; exporting make_case_combs in datatype package for predicate compiler; adding Spec_Rules declaration for tail recursive functions; improving the predicate compiler and function flattening
bulwahn
parents: 35021
diff changeset
   105
fun keep_functions thy t =
c9f428269b38 adopting mutabelle and quickcheck to return timing information; exporting make_case_combs in datatype package for predicate compiler; adding Spec_Rules declaration for tail recursive functions; improving the predicate compiler and function flattening
bulwahn
parents: 35021
diff changeset
   106
  case try dest_Const (fst (strip_comb t)) of
c9f428269b38 adopting mutabelle and quickcheck to return timing information; exporting make_case_combs in datatype package for predicate compiler; adding Spec_Rules declaration for tail recursive functions; improving the predicate compiler and function flattening
bulwahn
parents: 35021
diff changeset
   107
    SOME (c, _) => Predicate_Compile_Data.keep_function thy c
c9f428269b38 adopting mutabelle and quickcheck to return timing information; exporting make_case_combs in datatype package for predicate compiler; adding Spec_Rules declaration for tail recursive functions; improving the predicate compiler and function flattening
bulwahn
parents: 35021
diff changeset
   108
  | _ => false
c9f428269b38 adopting mutabelle and quickcheck to return timing information; exporting make_case_combs in datatype package for predicate compiler; adding Spec_Rules declaration for tail recursive functions; improving the predicate compiler and function flattening
bulwahn
parents: 35021
diff changeset
   109
35875
b0d24a74b06b restructuring function flattening
bulwahn
parents: 35874
diff changeset
   110
fun flatten thy lookup_pred t (names, prems) =
b0d24a74b06b restructuring function flattening
bulwahn
parents: 35874
diff changeset
   111
  let
b0d24a74b06b restructuring function flattening
bulwahn
parents: 35874
diff changeset
   112
    fun lift t (names, prems) =
b0d24a74b06b restructuring function flattening
bulwahn
parents: 35874
diff changeset
   113
      case lookup_pred (Envir.eta_contract t) of
b0d24a74b06b restructuring function flattening
bulwahn
parents: 35874
diff changeset
   114
        SOME pred => [(pred, (names, prems))]
b0d24a74b06b restructuring function flattening
bulwahn
parents: 35874
diff changeset
   115
      | NONE =>
b0d24a74b06b restructuring function flattening
bulwahn
parents: 35874
diff changeset
   116
        let
b0d24a74b06b restructuring function flattening
bulwahn
parents: 35874
diff changeset
   117
          val (vars, body) = strip_abs t
b0d24a74b06b restructuring function flattening
bulwahn
parents: 35874
diff changeset
   118
          val _ = assert (fastype_of body = body_type (fastype_of body))
b0d24a74b06b restructuring function flattening
bulwahn
parents: 35874
diff changeset
   119
          val absnames = Name.variant_list names (map fst vars)
b0d24a74b06b restructuring function flattening
bulwahn
parents: 35874
diff changeset
   120
          val frees = map2 (curry Free) absnames (map snd vars)
b0d24a74b06b restructuring function flattening
bulwahn
parents: 35874
diff changeset
   121
          val body' = subst_bounds (rev frees, body)
b0d24a74b06b restructuring function flattening
bulwahn
parents: 35874
diff changeset
   122
          val resname = Name.variant (absnames @ names) "res"
b0d24a74b06b restructuring function flattening
bulwahn
parents: 35874
diff changeset
   123
          val resvar = Free (resname, fastype_of body)
b0d24a74b06b restructuring function flattening
bulwahn
parents: 35874
diff changeset
   124
          val t = flatten' body' ([], [])
b0d24a74b06b restructuring function flattening
bulwahn
parents: 35874
diff changeset
   125
            |> map (fn (res, (inner_names, inner_prems)) =>
b0d24a74b06b restructuring function flattening
bulwahn
parents: 35874
diff changeset
   126
              let
b0d24a74b06b restructuring function flattening
bulwahn
parents: 35874
diff changeset
   127
                fun mk_exists (x, T) t = HOLogic.mk_exists (x, T, t)
b0d24a74b06b restructuring function flattening
bulwahn
parents: 35874
diff changeset
   128
                val vTs = 
b0d24a74b06b restructuring function flattening
bulwahn
parents: 35874
diff changeset
   129
                  fold Term.add_frees inner_prems []
b0d24a74b06b restructuring function flattening
bulwahn
parents: 35874
diff changeset
   130
                  |> filter (fn (x, T) => member (op =) inner_names x)
b0d24a74b06b restructuring function flattening
bulwahn
parents: 35874
diff changeset
   131
                val t = 
b0d24a74b06b restructuring function flattening
bulwahn
parents: 35874
diff changeset
   132
                  fold mk_exists vTs
b0d24a74b06b restructuring function flattening
bulwahn
parents: 35874
diff changeset
   133
                  (foldr1 HOLogic.mk_conj (HOLogic.mk_eq (res, resvar) ::
b0d24a74b06b restructuring function flattening
bulwahn
parents: 35874
diff changeset
   134
                    map HOLogic.dest_Trueprop inner_prems))
b0d24a74b06b restructuring function flattening
bulwahn
parents: 35874
diff changeset
   135
              in
b0d24a74b06b restructuring function flattening
bulwahn
parents: 35874
diff changeset
   136
                t
b0d24a74b06b restructuring function flattening
bulwahn
parents: 35874
diff changeset
   137
              end)
b0d24a74b06b restructuring function flattening
bulwahn
parents: 35874
diff changeset
   138
              |> foldr1 HOLogic.mk_disj
b0d24a74b06b restructuring function flattening
bulwahn
parents: 35874
diff changeset
   139
              |> fold lambda (resvar :: rev frees)
b0d24a74b06b restructuring function flattening
bulwahn
parents: 35874
diff changeset
   140
        in
b0d24a74b06b restructuring function flattening
bulwahn
parents: 35874
diff changeset
   141
          [(t, (names, prems))]
b0d24a74b06b restructuring function flattening
bulwahn
parents: 35874
diff changeset
   142
        end
b0d24a74b06b restructuring function flattening
bulwahn
parents: 35874
diff changeset
   143
    and flatten_or_lift (t, T) (names, prems) =
b0d24a74b06b restructuring function flattening
bulwahn
parents: 35874
diff changeset
   144
      if fastype_of t = T then
b0d24a74b06b restructuring function flattening
bulwahn
parents: 35874
diff changeset
   145
        flatten' t (names, prems)
b0d24a74b06b restructuring function flattening
bulwahn
parents: 35874
diff changeset
   146
      else
b0d24a74b06b restructuring function flattening
bulwahn
parents: 35874
diff changeset
   147
        (* note pred_type might be to general! *)
b0d24a74b06b restructuring function flattening
bulwahn
parents: 35874
diff changeset
   148
        if (pred_type (fastype_of t) = T) then
b0d24a74b06b restructuring function flattening
bulwahn
parents: 35874
diff changeset
   149
          lift t (names, prems)
b0d24a74b06b restructuring function flattening
bulwahn
parents: 35874
diff changeset
   150
        else
b0d24a74b06b restructuring function flattening
bulwahn
parents: 35874
diff changeset
   151
          error ("unexpected input for flatten or lift" ^ Syntax.string_of_term_global thy t ^
b0d24a74b06b restructuring function flattening
bulwahn
parents: 35874
diff changeset
   152
          ", " ^  Syntax.string_of_typ_global thy T)
b0d24a74b06b restructuring function flattening
bulwahn
parents: 35874
diff changeset
   153
    and flatten' (t as Const (name, T)) (names, prems) = [(t, (names, prems))]
b0d24a74b06b restructuring function flattening
bulwahn
parents: 35874
diff changeset
   154
      | flatten' (t as Free (f, T)) (names, prems) = [(t, (names, prems))]
b0d24a74b06b restructuring function flattening
bulwahn
parents: 35874
diff changeset
   155
      | flatten' (t as Abs _) (names, prems) = [(t, (names, prems))]
b0d24a74b06b restructuring function flattening
bulwahn
parents: 35874
diff changeset
   156
      | flatten' (t as _ $ _) (names, prems) =
35324
c9f428269b38 adopting mutabelle and quickcheck to return timing information; exporting make_case_combs in datatype package for predicate compiler; adding Spec_Rules declaration for tail recursive functions; improving the predicate compiler and function flattening
bulwahn
parents: 35021
diff changeset
   157
      if Predicate_Compile_Aux.is_constrt thy t orelse keep_functions thy t then
33250
5c2af18a3237 including the predicate compiler in HOL-Main; added RandomPredicate monad to Quickcheck
bulwahn
parents:
diff changeset
   158
        [(t, (names, prems))]
5c2af18a3237 including the predicate compiler in HOL-Main; added RandomPredicate monad to Quickcheck
bulwahn
parents:
diff changeset
   159
      else
35324
c9f428269b38 adopting mutabelle and quickcheck to return timing information; exporting make_case_combs in datatype package for predicate compiler; adding Spec_Rules declaration for tail recursive functions; improving the predicate compiler and function flattening
bulwahn
parents: 35021
diff changeset
   160
        case (fst (strip_comb t)) of
c9f428269b38 adopting mutabelle and quickcheck to return timing information; exporting make_case_combs in datatype package for predicate compiler; adding Spec_Rules declaration for tail recursive functions; improving the predicate compiler and function flattening
bulwahn
parents: 35021
diff changeset
   161
          Const (@{const_name "If"}, _) =>
c9f428269b38 adopting mutabelle and quickcheck to return timing information; exporting make_case_combs in datatype package for predicate compiler; adding Spec_Rules declaration for tail recursive functions; improving the predicate compiler and function flattening
bulwahn
parents: 35021
diff changeset
   162
            (let
c9f428269b38 adopting mutabelle and quickcheck to return timing information; exporting make_case_combs in datatype package for predicate compiler; adding Spec_Rules declaration for tail recursive functions; improving the predicate compiler and function flattening
bulwahn
parents: 35021
diff changeset
   163
              val (_, [B, x, y]) = strip_comb t
c9f428269b38 adopting mutabelle and quickcheck to return timing information; exporting make_case_combs in datatype package for predicate compiler; adding Spec_Rules declaration for tail recursive functions; improving the predicate compiler and function flattening
bulwahn
parents: 35021
diff changeset
   164
            in
35875
b0d24a74b06b restructuring function flattening
bulwahn
parents: 35874
diff changeset
   165
              flatten' B (names, prems)
b0d24a74b06b restructuring function flattening
bulwahn
parents: 35874
diff changeset
   166
              |> maps (fn (B', (names, prems)) =>
b0d24a74b06b restructuring function flattening
bulwahn
parents: 35874
diff changeset
   167
                (flatten' x (names, prems)
b0d24a74b06b restructuring function flattening
bulwahn
parents: 35874
diff changeset
   168
                |> map (fn (res, (names, prems)) => (res, (names, (HOLogic.mk_Trueprop B') :: prems))))
b0d24a74b06b restructuring function flattening
bulwahn
parents: 35874
diff changeset
   169
                @ (flatten' y (names, prems)
b0d24a74b06b restructuring function flattening
bulwahn
parents: 35874
diff changeset
   170
                |> map (fn (res, (names, prems)) =>
b0d24a74b06b restructuring function flattening
bulwahn
parents: 35874
diff changeset
   171
                  (* in general unsound! *)
b0d24a74b06b restructuring function flattening
bulwahn
parents: 35874
diff changeset
   172
                  (res, (names, (HOLogic.mk_Trueprop (HOLogic.mk_not B')) :: prems)))))
35324
c9f428269b38 adopting mutabelle and quickcheck to return timing information; exporting make_case_combs in datatype package for predicate compiler; adding Spec_Rules declaration for tail recursive functions; improving the predicate compiler and function flattening
bulwahn
parents: 35021
diff changeset
   173
            end)
c9f428269b38 adopting mutabelle and quickcheck to return timing information; exporting make_case_combs in datatype package for predicate compiler; adding Spec_Rules declaration for tail recursive functions; improving the predicate compiler and function flattening
bulwahn
parents: 35021
diff changeset
   174
        | Const (@{const_name "Let"}, _) => 
c9f428269b38 adopting mutabelle and quickcheck to return timing information; exporting make_case_combs in datatype package for predicate compiler; adding Spec_Rules declaration for tail recursive functions; improving the predicate compiler and function flattening
bulwahn
parents: 35021
diff changeset
   175
            (let
c9f428269b38 adopting mutabelle and quickcheck to return timing information; exporting make_case_combs in datatype package for predicate compiler; adding Spec_Rules declaration for tail recursive functions; improving the predicate compiler and function flattening
bulwahn
parents: 35021
diff changeset
   176
              val (_, [f, g]) = strip_comb t
c9f428269b38 adopting mutabelle and quickcheck to return timing information; exporting make_case_combs in datatype package for predicate compiler; adding Spec_Rules declaration for tail recursive functions; improving the predicate compiler and function flattening
bulwahn
parents: 35021
diff changeset
   177
            in
35874
bcfa6b4b21c6 renaming mk_prems to flatten in the function flattening
bulwahn
parents: 35873
diff changeset
   178
              flatten' f (names, prems)
35324
c9f428269b38 adopting mutabelle and quickcheck to return timing information; exporting make_case_combs in datatype package for predicate compiler; adding Spec_Rules declaration for tail recursive functions; improving the predicate compiler and function flattening
bulwahn
parents: 35021
diff changeset
   179
              |> maps (fn (res, (names, prems)) =>
35874
bcfa6b4b21c6 renaming mk_prems to flatten in the function flattening
bulwahn
parents: 35873
diff changeset
   180
                flatten' (betapply (g, res)) (names, prems))
35324
c9f428269b38 adopting mutabelle and quickcheck to return timing information; exporting make_case_combs in datatype package for predicate compiler; adding Spec_Rules declaration for tail recursive functions; improving the predicate compiler and function flattening
bulwahn
parents: 35021
diff changeset
   181
            end)
37135
636e6d8645d6 normalized references to constant "split"
haftmann
parents: 36610
diff changeset
   182
        | Const (@{const_name split}, _) => 
35324
c9f428269b38 adopting mutabelle and quickcheck to return timing information; exporting make_case_combs in datatype package for predicate compiler; adding Spec_Rules declaration for tail recursive functions; improving the predicate compiler and function flattening
bulwahn
parents: 35021
diff changeset
   183
            (let
35877
295e1af6c8dc generalized split transformation in the function flattening
bulwahn
parents: 35876
diff changeset
   184
              val (_, g :: res :: args) = strip_comb t
35324
c9f428269b38 adopting mutabelle and quickcheck to return timing information; exporting make_case_combs in datatype package for predicate compiler; adding Spec_Rules declaration for tail recursive functions; improving the predicate compiler and function flattening
bulwahn
parents: 35021
diff changeset
   185
              val [res1, res2] = Name.variant_list names ["res1", "res2"]
c9f428269b38 adopting mutabelle and quickcheck to return timing information; exporting make_case_combs in datatype package for predicate compiler; adding Spec_Rules declaration for tail recursive functions; improving the predicate compiler and function flattening
bulwahn
parents: 35021
diff changeset
   186
              val (T1, T2) = HOLogic.dest_prodT (fastype_of res)
c9f428269b38 adopting mutabelle and quickcheck to return timing information; exporting make_case_combs in datatype package for predicate compiler; adding Spec_Rules declaration for tail recursive functions; improving the predicate compiler and function flattening
bulwahn
parents: 35021
diff changeset
   187
              val (resv1, resv2) = (Free (res1, T1), Free (res2, T2))
c9f428269b38 adopting mutabelle and quickcheck to return timing information; exporting make_case_combs in datatype package for predicate compiler; adding Spec_Rules declaration for tail recursive functions; improving the predicate compiler and function flattening
bulwahn
parents: 35021
diff changeset
   188
            in
35877
295e1af6c8dc generalized split transformation in the function flattening
bulwahn
parents: 35876
diff changeset
   189
              flatten' (betapplys (g, (resv1 :: resv2 :: args)))
35324
c9f428269b38 adopting mutabelle and quickcheck to return timing information; exporting make_case_combs in datatype package for predicate compiler; adding Spec_Rules declaration for tail recursive functions; improving the predicate compiler and function flattening
bulwahn
parents: 35021
diff changeset
   190
              (res1 :: res2 :: names,
c9f428269b38 adopting mutabelle and quickcheck to return timing information; exporting make_case_combs in datatype package for predicate compiler; adding Spec_Rules declaration for tail recursive functions; improving the predicate compiler and function flattening
bulwahn
parents: 35021
diff changeset
   191
              HOLogic.mk_Trueprop (HOLogic.mk_eq (res, HOLogic.mk_prod (resv1, resv2))) :: prems)
c9f428269b38 adopting mutabelle and quickcheck to return timing information; exporting make_case_combs in datatype package for predicate compiler; adding Spec_Rules declaration for tail recursive functions; improving the predicate compiler and function flattening
bulwahn
parents: 35021
diff changeset
   192
            end)
c9f428269b38 adopting mutabelle and quickcheck to return timing information; exporting make_case_combs in datatype package for predicate compiler; adding Spec_Rules declaration for tail recursive functions; improving the predicate compiler and function flattening
bulwahn
parents: 35021
diff changeset
   193
        | _ =>
36029
a790b94e090c removing fishing for split thm in the predicate compiler
bulwahn
parents: 35878
diff changeset
   194
        case find_split_thm thy (fst (strip_comb t)) of
a790b94e090c removing fishing for split thm in the predicate compiler
bulwahn
parents: 35878
diff changeset
   195
          SOME raw_split_thm =>
33250
5c2af18a3237 including the predicate compiler in HOL-Main; added RandomPredicate monad to Quickcheck
bulwahn
parents:
diff changeset
   196
          let
5c2af18a3237 including the predicate compiler in HOL-Main; added RandomPredicate monad to Quickcheck
bulwahn
parents:
diff changeset
   197
            val (f, args) = strip_comb t
36610
bafd82950e24 renamed ProofContext.init to ProofContext.init_global to emphasize that this is not the real thing;
wenzelm
parents: 36249
diff changeset
   198
            val split_thm = prepare_split_thm (ProofContext.init_global thy) raw_split_thm
36029
a790b94e090c removing fishing for split thm in the predicate compiler
bulwahn
parents: 35878
diff changeset
   199
            val (assms, concl) = Logic.strip_horn (prop_of split_thm)
33250
5c2af18a3237 including the predicate compiler in HOL-Main; added RandomPredicate monad to Quickcheck
bulwahn
parents:
diff changeset
   200
            val (P, [split_t]) = strip_comb (HOLogic.dest_Trueprop concl) 
5c2af18a3237 including the predicate compiler in HOL-Main; added RandomPredicate monad to Quickcheck
bulwahn
parents:
diff changeset
   201
            val subst = Pattern.match thy (split_t, t) (Vartab.empty, Vartab.empty)
5c2af18a3237 including the predicate compiler in HOL-Main; added RandomPredicate monad to Quickcheck
bulwahn
parents:
diff changeset
   202
            val (_, split_args) = strip_comb split_t
5c2af18a3237 including the predicate compiler in HOL-Main; added RandomPredicate monad to Quickcheck
bulwahn
parents:
diff changeset
   203
            val match = split_args ~~ args
35874
bcfa6b4b21c6 renaming mk_prems to flatten in the function flattening
bulwahn
parents: 35873
diff changeset
   204
            fun flatten_of_assm assm =
33250
5c2af18a3237 including the predicate compiler in HOL-Main; added RandomPredicate monad to Quickcheck
bulwahn
parents:
diff changeset
   205
              let
5c2af18a3237 including the predicate compiler in HOL-Main; added RandomPredicate monad to Quickcheck
bulwahn
parents:
diff changeset
   206
                val (vTs, assm') = strip_all (Envir.beta_norm (Envir.subst_term subst assm))
5c2af18a3237 including the predicate compiler in HOL-Main; added RandomPredicate monad to Quickcheck
bulwahn
parents:
diff changeset
   207
                val var_names = Name.variant_list names (map fst vTs)
5c2af18a3237 including the predicate compiler in HOL-Main; added RandomPredicate monad to Quickcheck
bulwahn
parents:
diff changeset
   208
                val vars = map Free (var_names ~~ (map snd vTs))
5c2af18a3237 including the predicate compiler in HOL-Main; added RandomPredicate monad to Quickcheck
bulwahn
parents:
diff changeset
   209
                val (prems', pre_res) = Logic.strip_horn (subst_bounds (rev vars, assm'))
5c2af18a3237 including the predicate compiler in HOL-Main; added RandomPredicate monad to Quickcheck
bulwahn
parents:
diff changeset
   210
                val (_, [inner_t]) = strip_comb (HOLogic.dest_Trueprop pre_res)
35324
c9f428269b38 adopting mutabelle and quickcheck to return timing information; exporting make_case_combs in datatype package for predicate compiler; adding Spec_Rules declaration for tail recursive functions; improving the predicate compiler and function flattening
bulwahn
parents: 35021
diff changeset
   211
                val (lhss : term list, rhss) =
c9f428269b38 adopting mutabelle and quickcheck to return timing information; exporting make_case_combs in datatype package for predicate compiler; adding Spec_Rules declaration for tail recursive functions; improving the predicate compiler and function flattening
bulwahn
parents: 35021
diff changeset
   212
                  split_list (map (HOLogic.dest_eq o HOLogic.dest_Trueprop) prems')
33250
5c2af18a3237 including the predicate compiler in HOL-Main; added RandomPredicate monad to Quickcheck
bulwahn
parents:
diff changeset
   213
              in
35874
bcfa6b4b21c6 renaming mk_prems to flatten in the function flattening
bulwahn
parents: 35873
diff changeset
   214
                folds_map flatten' lhss (var_names @ names, prems)
35324
c9f428269b38 adopting mutabelle and quickcheck to return timing information; exporting make_case_combs in datatype package for predicate compiler; adding Spec_Rules declaration for tail recursive functions; improving the predicate compiler and function flattening
bulwahn
parents: 35021
diff changeset
   215
                |> map (fn (ress, (names, prems)) =>
c9f428269b38 adopting mutabelle and quickcheck to return timing information; exporting make_case_combs in datatype package for predicate compiler; adding Spec_Rules declaration for tail recursive functions; improving the predicate compiler and function flattening
bulwahn
parents: 35021
diff changeset
   216
                  let
c9f428269b38 adopting mutabelle and quickcheck to return timing information; exporting make_case_combs in datatype package for predicate compiler; adding Spec_Rules declaration for tail recursive functions; improving the predicate compiler and function flattening
bulwahn
parents: 35021
diff changeset
   217
                    val prems' = map (HOLogic.mk_Trueprop o HOLogic.mk_eq) (ress ~~ rhss)
c9f428269b38 adopting mutabelle and quickcheck to return timing information; exporting make_case_combs in datatype package for predicate compiler; adding Spec_Rules declaration for tail recursive functions; improving the predicate compiler and function flattening
bulwahn
parents: 35021
diff changeset
   218
                  in (names, prems' @ prems) end)
35874
bcfa6b4b21c6 renaming mk_prems to flatten in the function flattening
bulwahn
parents: 35873
diff changeset
   219
                |> maps (flatten' inner_t)
33250
5c2af18a3237 including the predicate compiler in HOL-Main; added RandomPredicate monad to Quickcheck
bulwahn
parents:
diff changeset
   220
              end
5c2af18a3237 including the predicate compiler in HOL-Main; added RandomPredicate monad to Quickcheck
bulwahn
parents:
diff changeset
   221
          in
35874
bcfa6b4b21c6 renaming mk_prems to flatten in the function flattening
bulwahn
parents: 35873
diff changeset
   222
            maps flatten_of_assm assms
33250
5c2af18a3237 including the predicate compiler in HOL-Main; added RandomPredicate monad to Quickcheck
bulwahn
parents:
diff changeset
   223
          end
36029
a790b94e090c removing fishing for split thm in the predicate compiler
bulwahn
parents: 35878
diff changeset
   224
      | NONE =>
33250
5c2af18a3237 including the predicate compiler in HOL-Main; added RandomPredicate monad to Quickcheck
bulwahn
parents:
diff changeset
   225
          let
5c2af18a3237 including the predicate compiler in HOL-Main; added RandomPredicate monad to Quickcheck
bulwahn
parents:
diff changeset
   226
            val (f, args) = strip_comb t
35324
c9f428269b38 adopting mutabelle and quickcheck to return timing information; exporting make_case_combs in datatype package for predicate compiler; adding Spec_Rules declaration for tail recursive functions; improving the predicate compiler and function flattening
bulwahn
parents: 35021
diff changeset
   227
            val args = map (Pattern.eta_long []) args
c9f428269b38 adopting mutabelle and quickcheck to return timing information; exporting make_case_combs in datatype package for predicate compiler; adding Spec_Rules declaration for tail recursive functions; improving the predicate compiler and function flattening
bulwahn
parents: 35021
diff changeset
   228
            val _ = assert (fastype_of t = body_type (fastype_of t))
35875
b0d24a74b06b restructuring function flattening
bulwahn
parents: 35874
diff changeset
   229
            val f' = lookup_pred f
b0d24a74b06b restructuring function flattening
bulwahn
parents: 35874
diff changeset
   230
            val Ts = case f' of
35873
d09a58c890e3 simplifying function flattening
bulwahn
parents: 35845
diff changeset
   231
              SOME pred => (fst (split_last (binder_types (fastype_of pred))))
35875
b0d24a74b06b restructuring function flattening
bulwahn
parents: 35874
diff changeset
   232
            | NONE => binder_types (fastype_of f)
33250
5c2af18a3237 including the predicate compiler in HOL-Main; added RandomPredicate monad to Quickcheck
bulwahn
parents:
diff changeset
   233
          in
35875
b0d24a74b06b restructuring function flattening
bulwahn
parents: 35874
diff changeset
   234
            folds_map flatten_or_lift (args ~~ Ts) (names, prems) |>
b0d24a74b06b restructuring function flattening
bulwahn
parents: 35874
diff changeset
   235
            (case f' of
b0d24a74b06b restructuring function flattening
bulwahn
parents: 35874
diff changeset
   236
              NONE =>
b0d24a74b06b restructuring function flattening
bulwahn
parents: 35874
diff changeset
   237
                map (fn (argvs, (names', prems')) => (list_comb (f, argvs), (names', prems')))
b0d24a74b06b restructuring function flattening
bulwahn
parents: 35874
diff changeset
   238
            | SOME pred =>
b0d24a74b06b restructuring function flattening
bulwahn
parents: 35874
diff changeset
   239
                map (fn (argvs, (names', prems')) =>
b0d24a74b06b restructuring function flattening
bulwahn
parents: 35874
diff changeset
   240
                  let
b0d24a74b06b restructuring function flattening
bulwahn
parents: 35874
diff changeset
   241
                    fun lift_arg T t =
b0d24a74b06b restructuring function flattening
bulwahn
parents: 35874
diff changeset
   242
                      if (fastype_of t) = T then t
b0d24a74b06b restructuring function flattening
bulwahn
parents: 35874
diff changeset
   243
                      else
b0d24a74b06b restructuring function flattening
bulwahn
parents: 35874
diff changeset
   244
                        let
b0d24a74b06b restructuring function flattening
bulwahn
parents: 35874
diff changeset
   245
                          val _ = assert (T =
b0d24a74b06b restructuring function flattening
bulwahn
parents: 35874
diff changeset
   246
                            (binder_types (fastype_of t) @ [@{typ bool}] ---> @{typ bool}))
b0d24a74b06b restructuring function flattening
bulwahn
parents: 35874
diff changeset
   247
                          fun mk_if T (b, t, e) =
b0d24a74b06b restructuring function flattening
bulwahn
parents: 35874
diff changeset
   248
                            Const (@{const_name If}, @{typ bool} --> T --> T --> T) $ b $ t $ e
b0d24a74b06b restructuring function flattening
bulwahn
parents: 35874
diff changeset
   249
                          val Ts = binder_types (fastype_of t)
35878
74a74828d682 cleaning the function flattening
bulwahn
parents: 35877
diff changeset
   250
                        in
35875
b0d24a74b06b restructuring function flattening
bulwahn
parents: 35874
diff changeset
   251
                          list_abs (map (pair "x") Ts @ [("b", @{typ bool})],
b0d24a74b06b restructuring function flattening
bulwahn
parents: 35874
diff changeset
   252
                            mk_if @{typ bool} (list_comb (t, map Bound (length Ts downto 1)),
b0d24a74b06b restructuring function flattening
bulwahn
parents: 35874
diff changeset
   253
                            HOLogic.mk_eq (@{term True}, Bound 0),
b0d24a74b06b restructuring function flattening
bulwahn
parents: 35874
diff changeset
   254
                            HOLogic.mk_eq (@{term False}, Bound 0)))
b0d24a74b06b restructuring function flattening
bulwahn
parents: 35874
diff changeset
   255
                        end
b0d24a74b06b restructuring function flattening
bulwahn
parents: 35874
diff changeset
   256
                    val argvs' = map2 lift_arg Ts argvs
b0d24a74b06b restructuring function flattening
bulwahn
parents: 35874
diff changeset
   257
                    val resname = Name.variant names' "res"
b0d24a74b06b restructuring function flattening
bulwahn
parents: 35874
diff changeset
   258
                    val resvar = Free (resname, body_type (fastype_of t))
b0d24a74b06b restructuring function flattening
bulwahn
parents: 35874
diff changeset
   259
                    val prem = HOLogic.mk_Trueprop (list_comb (pred, argvs' @ [resvar]))
b0d24a74b06b restructuring function flattening
bulwahn
parents: 35874
diff changeset
   260
                  in (resvar, (resname :: names', prem :: prems')) end))
33250
5c2af18a3237 including the predicate compiler in HOL-Main; added RandomPredicate monad to Quickcheck
bulwahn
parents:
diff changeset
   261
          end
5c2af18a3237 including the predicate compiler in HOL-Main; added RandomPredicate monad to Quickcheck
bulwahn
parents:
diff changeset
   262
  in
35875
b0d24a74b06b restructuring function flattening
bulwahn
parents: 35874
diff changeset
   263
    map (apfst Envir.eta_contract) (flatten' (Pattern.eta_long [] t) (names, prems))
33250
5c2af18a3237 including the predicate compiler in HOL-Main; added RandomPredicate monad to Quickcheck
bulwahn
parents:
diff changeset
   264
  end;
5c2af18a3237 including the predicate compiler in HOL-Main; added RandomPredicate monad to Quickcheck
bulwahn
parents:
diff changeset
   265
36249
24f2ab79b506 replaced call to inductive package by axiomatization in the function flattening of the predicate compiler
bulwahn
parents: 36051
diff changeset
   266
(* FIXME: create new predicate name -- does not avoid nameclashing *)
24f2ab79b506 replaced call to inductive package by axiomatization in the function flattening of the predicate compiler
bulwahn
parents: 36051
diff changeset
   267
fun pred_of thy f =
24f2ab79b506 replaced call to inductive package by axiomatization in the function flattening of the predicate compiler
bulwahn
parents: 36051
diff changeset
   268
  let
24f2ab79b506 replaced call to inductive package by axiomatization in the function flattening of the predicate compiler
bulwahn
parents: 36051
diff changeset
   269
    val (name, T) = dest_Const f
24f2ab79b506 replaced call to inductive package by axiomatization in the function flattening of the predicate compiler
bulwahn
parents: 36051
diff changeset
   270
    val base_name' = (Long_Name.base_name name ^ "P")
24f2ab79b506 replaced call to inductive package by axiomatization in the function flattening of the predicate compiler
bulwahn
parents: 36051
diff changeset
   271
    val name' = Sign.full_bname thy base_name'
24f2ab79b506 replaced call to inductive package by axiomatization in the function flattening of the predicate compiler
bulwahn
parents: 36051
diff changeset
   272
    val T' = if (body_type T = @{typ bool}) then T else pred_type T
24f2ab79b506 replaced call to inductive package by axiomatization in the function flattening of the predicate compiler
bulwahn
parents: 36051
diff changeset
   273
  in
24f2ab79b506 replaced call to inductive package by axiomatization in the function flattening of the predicate compiler
bulwahn
parents: 36051
diff changeset
   274
    (name', Const (name', T'))
24f2ab79b506 replaced call to inductive package by axiomatization in the function flattening of the predicate compiler
bulwahn
parents: 36051
diff changeset
   275
  end
24f2ab79b506 replaced call to inductive package by axiomatization in the function flattening of the predicate compiler
bulwahn
parents: 36051
diff changeset
   276
35878
74a74828d682 cleaning the function flattening
bulwahn
parents: 35877
diff changeset
   277
(* assumption: mutual recursive predicates all have the same parameters. *)
33250
5c2af18a3237 including the predicate compiler in HOL-Main; added RandomPredicate monad to Quickcheck
bulwahn
parents:
diff changeset
   278
fun define_predicates specs thy =
35324
c9f428269b38 adopting mutabelle and quickcheck to return timing information; exporting make_case_combs in datatype package for predicate compiler; adding Spec_Rules declaration for tail recursive functions; improving the predicate compiler and function flattening
bulwahn
parents: 35021
diff changeset
   279
  if forall (fn (const, _) => defined_const thy const) specs then
33250
5c2af18a3237 including the predicate compiler in HOL-Main; added RandomPredicate monad to Quickcheck
bulwahn
parents:
diff changeset
   280
    ([], thy)
5c2af18a3237 including the predicate compiler in HOL-Main; added RandomPredicate monad to Quickcheck
bulwahn
parents:
diff changeset
   281
  else
35876
ac44e2312f0a only adding lifted arguments to item net in the function flattening; correcting indentation; removing dead code
bulwahn
parents: 35875
diff changeset
   282
    let
ac44e2312f0a only adding lifted arguments to item net in the function flattening; correcting indentation; removing dead code
bulwahn
parents: 35875
diff changeset
   283
      val consts = map fst specs
ac44e2312f0a only adding lifted arguments to item net in the function flattening; correcting indentation; removing dead code
bulwahn
parents: 35875
diff changeset
   284
      val eqns = maps snd specs
35878
74a74828d682 cleaning the function flattening
bulwahn
parents: 35877
diff changeset
   285
      (* create prednames *)
35876
ac44e2312f0a only adding lifted arguments to item net in the function flattening; correcting indentation; removing dead code
bulwahn
parents: 35875
diff changeset
   286
      val ((funs, argss), rhss) = map_split dest_code_eqn eqns |>> split_list
36249
24f2ab79b506 replaced call to inductive package by axiomatization in the function flattening of the predicate compiler
bulwahn
parents: 36051
diff changeset
   287
      val dst_funs = distinct (op =) funs
35876
ac44e2312f0a only adding lifted arguments to item net in the function flattening; correcting indentation; removing dead code
bulwahn
parents: 35875
diff changeset
   288
      val argss' = map (map transform_ho_arg) argss
ac44e2312f0a only adding lifted arguments to item net in the function flattening; correcting indentation; removing dead code
bulwahn
parents: 35875
diff changeset
   289
      fun is_lifted (t1, t2) = (fastype_of t2 = pred_type (fastype_of t1))
36249
24f2ab79b506 replaced call to inductive package by axiomatization in the function flattening of the predicate compiler
bulwahn
parents: 36051
diff changeset
   290
      (* FIXME: higher order arguments also occur in tuples! *)
35876
ac44e2312f0a only adding lifted arguments to item net in the function flattening; correcting indentation; removing dead code
bulwahn
parents: 35875
diff changeset
   291
      val lifted_args = distinct (op =) (filter is_lifted (flat argss ~~ flat argss'))
36249
24f2ab79b506 replaced call to inductive package by axiomatization in the function flattening of the predicate compiler
bulwahn
parents: 36051
diff changeset
   292
      val (prednames, preds) = split_list (map (pred_of thy) funs)
24f2ab79b506 replaced call to inductive package by axiomatization in the function flattening of the predicate compiler
bulwahn
parents: 36051
diff changeset
   293
      val dst_preds = distinct (op =) preds
24f2ab79b506 replaced call to inductive package by axiomatization in the function flattening of the predicate compiler
bulwahn
parents: 36051
diff changeset
   294
      val dst_prednames = distinct (op =) prednames
35878
74a74828d682 cleaning the function flattening
bulwahn
parents: 35877
diff changeset
   295
      (* mapping from term (Free or Const) to term *)
35876
ac44e2312f0a only adding lifted arguments to item net in the function flattening; correcting indentation; removing dead code
bulwahn
parents: 35875
diff changeset
   296
      val net = fold Item_Net.update
36249
24f2ab79b506 replaced call to inductive package by axiomatization in the function flattening of the predicate compiler
bulwahn
parents: 36051
diff changeset
   297
        ((dst_funs ~~ dst_preds) @ lifted_args)
35876
ac44e2312f0a only adding lifted arguments to item net in the function flattening; correcting indentation; removing dead code
bulwahn
parents: 35875
diff changeset
   298
          (Fun_Pred.get thy)
ac44e2312f0a only adding lifted arguments to item net in the function flattening; correcting indentation; removing dead code
bulwahn
parents: 35875
diff changeset
   299
      fun lookup_pred t = lookup thy net t
ac44e2312f0a only adding lifted arguments to item net in the function flattening; correcting indentation; removing dead code
bulwahn
parents: 35875
diff changeset
   300
      (* create intro rules *)
ac44e2312f0a only adding lifted arguments to item net in the function flattening; correcting indentation; removing dead code
bulwahn
parents: 35875
diff changeset
   301
      fun mk_intros ((func, pred), (args, rhs)) =
ac44e2312f0a only adding lifted arguments to item net in the function flattening; correcting indentation; removing dead code
bulwahn
parents: 35875
diff changeset
   302
        if (body_type (fastype_of func) = @{typ bool}) then
35878
74a74828d682 cleaning the function flattening
bulwahn
parents: 35877
diff changeset
   303
         (* TODO: preprocess predicate definition of rhs *)
35876
ac44e2312f0a only adding lifted arguments to item net in the function flattening; correcting indentation; removing dead code
bulwahn
parents: 35875
diff changeset
   304
          [Logic.list_implies ([HOLogic.mk_Trueprop rhs], HOLogic.mk_Trueprop (list_comb (pred, args)))]
33250
5c2af18a3237 including the predicate compiler in HOL-Main; added RandomPredicate monad to Quickcheck
bulwahn
parents:
diff changeset
   305
        else
5c2af18a3237 including the predicate compiler in HOL-Main; added RandomPredicate monad to Quickcheck
bulwahn
parents:
diff changeset
   306
          let
35876
ac44e2312f0a only adding lifted arguments to item net in the function flattening; correcting indentation; removing dead code
bulwahn
parents: 35875
diff changeset
   307
            val names = Term.add_free_names rhs []
ac44e2312f0a only adding lifted arguments to item net in the function flattening; correcting indentation; removing dead code
bulwahn
parents: 35875
diff changeset
   308
          in flatten thy lookup_pred rhs (names, [])
ac44e2312f0a only adding lifted arguments to item net in the function flattening; correcting indentation; removing dead code
bulwahn
parents: 35875
diff changeset
   309
            |> map (fn (resultt, (names', prems)) =>
ac44e2312f0a only adding lifted arguments to item net in the function flattening; correcting indentation; removing dead code
bulwahn
parents: 35875
diff changeset
   310
              Logic.list_implies (prems, HOLogic.mk_Trueprop (list_comb (pred, args @ [resultt]))))
ac44e2312f0a only adding lifted arguments to item net in the function flattening; correcting indentation; removing dead code
bulwahn
parents: 35875
diff changeset
   311
          end
ac44e2312f0a only adding lifted arguments to item net in the function flattening; correcting indentation; removing dead code
bulwahn
parents: 35875
diff changeset
   312
      fun mk_rewr_thm (func, pred) = @{thm refl}
35878
74a74828d682 cleaning the function flattening
bulwahn
parents: 35877
diff changeset
   313
      val intr_ts = maps mk_intros ((funs ~~ preds) ~~ (argss' ~~ rhss))
36249
24f2ab79b506 replaced call to inductive package by axiomatization in the function flattening of the predicate compiler
bulwahn
parents: 36051
diff changeset
   314
      val (intrs, thy') = thy
24f2ab79b506 replaced call to inductive package by axiomatization in the function flattening of the predicate compiler
bulwahn
parents: 36051
diff changeset
   315
        |> Sign.add_consts_i
24f2ab79b506 replaced call to inductive package by axiomatization in the function flattening of the predicate compiler
bulwahn
parents: 36051
diff changeset
   316
          (map (fn Const (name, T) => (Binding.name (Long_Name.base_name name), T, NoSyn))
24f2ab79b506 replaced call to inductive package by axiomatization in the function flattening of the predicate compiler
bulwahn
parents: 36051
diff changeset
   317
           dst_preds)
24f2ab79b506 replaced call to inductive package by axiomatization in the function flattening of the predicate compiler
bulwahn
parents: 36051
diff changeset
   318
        |> fold_map Specification.axiom (map (pair (Binding.empty, [])) intr_ts)
24f2ab79b506 replaced call to inductive package by axiomatization in the function flattening of the predicate compiler
bulwahn
parents: 36051
diff changeset
   319
      val specs = map (fn predname => (predname,
24f2ab79b506 replaced call to inductive package by axiomatization in the function flattening of the predicate compiler
bulwahn
parents: 36051
diff changeset
   320
          map Drule.export_without_context (filter (Predicate_Compile_Aux.is_intro predname) intrs)))
24f2ab79b506 replaced call to inductive package by axiomatization in the function flattening of the predicate compiler
bulwahn
parents: 36051
diff changeset
   321
        dst_prednames
35878
74a74828d682 cleaning the function flattening
bulwahn
parents: 35877
diff changeset
   322
      val thy'' = Fun_Pred.map
36249
24f2ab79b506 replaced call to inductive package by axiomatization in the function flattening of the predicate compiler
bulwahn
parents: 36051
diff changeset
   323
        (fold Item_Net.update (map (pairself Logic.varify_global)
24f2ab79b506 replaced call to inductive package by axiomatization in the function flattening of the predicate compiler
bulwahn
parents: 36051
diff changeset
   324
          (dst_funs ~~ dst_preds))) thy'
36035
d82682936c52 adding registration of functions in the function flattening
bulwahn
parents: 36029
diff changeset
   325
      fun functional_mode_of T =
d82682936c52 adding registration of functions in the function flattening
bulwahn
parents: 36029
diff changeset
   326
        list_fun_mode (replicate (length (binder_types T)) Input @ [Output])
d82682936c52 adding registration of functions in the function flattening
bulwahn
parents: 36029
diff changeset
   327
      val thy''' = fold
d82682936c52 adding registration of functions in the function flattening
bulwahn
parents: 36029
diff changeset
   328
        (fn (predname, Const (name, T)) => Predicate_Compile_Core.register_alternative_function
d82682936c52 adding registration of functions in the function flattening
bulwahn
parents: 36029
diff changeset
   329
          predname (functional_mode_of T) name)
36249
24f2ab79b506 replaced call to inductive package by axiomatization in the function flattening of the predicate compiler
bulwahn
parents: 36051
diff changeset
   330
      (dst_prednames ~~ dst_funs) thy''
35876
ac44e2312f0a only adding lifted arguments to item net in the function flattening; correcting indentation; removing dead code
bulwahn
parents: 35875
diff changeset
   331
    in
36035
d82682936c52 adding registration of functions in the function flattening
bulwahn
parents: 36029
diff changeset
   332
      (specs, thy''')
35876
ac44e2312f0a only adding lifted arguments to item net in the function flattening; correcting indentation; removing dead code
bulwahn
parents: 35875
diff changeset
   333
    end
33250
5c2af18a3237 including the predicate compiler in HOL-Main; added RandomPredicate monad to Quickcheck
bulwahn
parents:
diff changeset
   334
5c2af18a3237 including the predicate compiler in HOL-Main; added RandomPredicate monad to Quickcheck
bulwahn
parents:
diff changeset
   335
fun rewrite_intro thy intro =
5c2af18a3237 including the predicate compiler in HOL-Main; added RandomPredicate monad to Quickcheck
bulwahn
parents:
diff changeset
   336
  let
35324
c9f428269b38 adopting mutabelle and quickcheck to return timing information; exporting make_case_combs in datatype package for predicate compiler; adding Spec_Rules declaration for tail recursive functions; improving the predicate compiler and function flattening
bulwahn
parents: 35021
diff changeset
   337
    fun lookup_pred t = lookup thy (Fun_Pred.get thy) t
36249
24f2ab79b506 replaced call to inductive package by axiomatization in the function flattening of the predicate compiler
bulwahn
parents: 36051
diff changeset
   338
    (*val _ = tracing ("Rewriting intro " ^ Display.string_of_thm_global thy intro)*)
35845
e5980f0ad025 renamed varify/unvarify operations to varify_global/unvarify_global to emphasize that these only work in a global situation;
wenzelm
parents: 35411
diff changeset
   339
    val intro_t = Logic.unvarify_global (prop_of intro)
33250
5c2af18a3237 including the predicate compiler in HOL-Main; added RandomPredicate monad to Quickcheck
bulwahn
parents:
diff changeset
   340
    val (prems, concl) = Logic.strip_horn intro_t
5c2af18a3237 including the predicate compiler in HOL-Main; added RandomPredicate monad to Quickcheck
bulwahn
parents:
diff changeset
   341
    val frees = map fst (Term.add_frees intro_t [])
5c2af18a3237 including the predicate compiler in HOL-Main; added RandomPredicate monad to Quickcheck
bulwahn
parents:
diff changeset
   342
    fun rewrite prem names =
5c2af18a3237 including the predicate compiler in HOL-Main; added RandomPredicate monad to Quickcheck
bulwahn
parents:
diff changeset
   343
      let
35324
c9f428269b38 adopting mutabelle and quickcheck to return timing information; exporting make_case_combs in datatype package for predicate compiler; adding Spec_Rules declaration for tail recursive functions; improving the predicate compiler and function flattening
bulwahn
parents: 35021
diff changeset
   344
        (*val _ = tracing ("Rewriting premise " ^ Syntax.string_of_term_global thy prem ^ "...")*)
36249
24f2ab79b506 replaced call to inductive package by axiomatization in the function flattening of the predicate compiler
bulwahn
parents: 36051
diff changeset
   345
        val t = HOLogic.dest_Trueprop prem
33250
5c2af18a3237 including the predicate compiler in HOL-Main; added RandomPredicate monad to Quickcheck
bulwahn
parents:
diff changeset
   346
        val (lit, mk_lit) = case try HOLogic.dest_not t of
5c2af18a3237 including the predicate compiler in HOL-Main; added RandomPredicate monad to Quickcheck
bulwahn
parents:
diff changeset
   347
            SOME t => (t, HOLogic.mk_not)
5c2af18a3237 including the predicate compiler in HOL-Main; added RandomPredicate monad to Quickcheck
bulwahn
parents:
diff changeset
   348
          | NONE => (t, I)
36249
24f2ab79b506 replaced call to inductive package by axiomatization in the function flattening of the predicate compiler
bulwahn
parents: 36051
diff changeset
   349
        val (P, args) = strip_comb lit
33250
5c2af18a3237 including the predicate compiler in HOL-Main; added RandomPredicate monad to Quickcheck
bulwahn
parents:
diff changeset
   350
      in
35874
bcfa6b4b21c6 renaming mk_prems to flatten in the function flattening
bulwahn
parents: 35873
diff changeset
   351
        folds_map (flatten thy lookup_pred) args (names, [])
33250
5c2af18a3237 including the predicate compiler in HOL-Main; added RandomPredicate monad to Quickcheck
bulwahn
parents:
diff changeset
   352
        |> map (fn (resargs, (names', prems')) =>
5c2af18a3237 including the predicate compiler in HOL-Main; added RandomPredicate monad to Quickcheck
bulwahn
parents:
diff changeset
   353
          let
5c2af18a3237 including the predicate compiler in HOL-Main; added RandomPredicate monad to Quickcheck
bulwahn
parents:
diff changeset
   354
            val prem' = HOLogic.mk_Trueprop (mk_lit (list_comb (P, resargs)))
5c2af18a3237 including the predicate compiler in HOL-Main; added RandomPredicate monad to Quickcheck
bulwahn
parents:
diff changeset
   355
          in (prem'::prems', names') end)
5c2af18a3237 including the predicate compiler in HOL-Main; added RandomPredicate monad to Quickcheck
bulwahn
parents:
diff changeset
   356
      end
5c2af18a3237 including the predicate compiler in HOL-Main; added RandomPredicate monad to Quickcheck
bulwahn
parents:
diff changeset
   357
    val intro_ts' = folds_map rewrite prems frees
5c2af18a3237 including the predicate compiler in HOL-Main; added RandomPredicate monad to Quickcheck
bulwahn
parents:
diff changeset
   358
      |> maps (fn (prems', frees') =>
5c2af18a3237 including the predicate compiler in HOL-Main; added RandomPredicate monad to Quickcheck
bulwahn
parents:
diff changeset
   359
        rewrite concl frees'
5c2af18a3237 including the predicate compiler in HOL-Main; added RandomPredicate monad to Quickcheck
bulwahn
parents:
diff changeset
   360
        |> map (fn (concl'::conclprems, _) =>
5c2af18a3237 including the predicate compiler in HOL-Main; added RandomPredicate monad to Quickcheck
bulwahn
parents:
diff changeset
   361
          Logic.list_implies ((flat prems') @ conclprems, concl')))
36249
24f2ab79b506 replaced call to inductive package by axiomatization in the function flattening of the predicate compiler
bulwahn
parents: 36051
diff changeset
   362
    (*val _ = tracing ("Rewritten intro to " ^
24f2ab79b506 replaced call to inductive package by axiomatization in the function flattening of the predicate compiler
bulwahn
parents: 36051
diff changeset
   363
      commas (map (Syntax.string_of_term_global thy) intro_ts'))*)
33250
5c2af18a3237 including the predicate compiler in HOL-Main; added RandomPredicate monad to Quickcheck
bulwahn
parents:
diff changeset
   364
  in
35021
c839a4c670c6 renamed old-style Drule.standard to Drule.export_without_context, to emphasize that this is in no way a standard operation;
wenzelm
parents: 34954
diff changeset
   365
    map (Drule.export_without_context o Skip_Proof.make_thm thy) intro_ts'
33630
68e058d061f5 removed unnecessary oracle in the predicate compiler
bulwahn
parents: 33522
diff changeset
   366
  end
33250
5c2af18a3237 including the predicate compiler in HOL-Main; added RandomPredicate monad to Quickcheck
bulwahn
parents:
diff changeset
   367
5c2af18a3237 including the predicate compiler in HOL-Main; added RandomPredicate monad to Quickcheck
bulwahn
parents:
diff changeset
   368
end;