src/HOL/Tools/Predicate_Compile/predicate_compile_aux.ML
changeset 55437 3fd63b92ea3b
parent 54742 7a86358a3c0b
child 55440 721b4561007a
     1.1 --- a/src/HOL/Tools/Predicate_Compile/predicate_compile_aux.ML	Wed Feb 12 13:31:18 2014 +0100
     1.2 +++ b/src/HOL/Tools/Predicate_Compile/predicate_compile_aux.ML	Wed Feb 12 13:33:05 2014 +0100
     1.3 @@ -89,17 +89,17 @@
     1.4    val funT_of : compilation_funs -> mode -> typ -> typ
     1.5    (* Different compilations *)
     1.6    datatype compilation = Pred | Depth_Limited | Random | Depth_Limited_Random | DSeq | Annotated
     1.7 -    | Pos_Random_DSeq | Neg_Random_DSeq | New_Pos_Random_DSeq | New_Neg_Random_DSeq 
     1.8 +    | Pos_Random_DSeq | Neg_Random_DSeq | New_Pos_Random_DSeq | New_Neg_Random_DSeq
     1.9      | Pos_Generator_DSeq | Neg_Generator_DSeq | Pos_Generator_CPS | Neg_Generator_CPS
    1.10    val negative_compilation_of : compilation -> compilation
    1.11    val compilation_for_polarity : bool -> compilation -> compilation
    1.12 -  val is_depth_limited_compilation : compilation -> bool 
    1.13 +  val is_depth_limited_compilation : compilation -> bool
    1.14    val string_of_compilation : compilation -> string
    1.15    val compilation_names : (string * compilation) list
    1.16    val non_random_compilations : compilation list
    1.17    val random_compilations : compilation list
    1.18    (* Different options for compiler *)
    1.19 -  datatype options = Options of {  
    1.20 +  datatype options = Options of {
    1.21      expected_modes : (string * mode list) option,
    1.22      proposed_modes : (string * mode list) list,
    1.23      proposed_names : ((string * mode) * string) list,
    1.24 @@ -161,7 +161,7 @@
    1.25    val unify_consts : theory -> term list -> term list -> (term list * term list)
    1.26    val mk_casesrule : Proof.context -> term -> thm list -> term
    1.27    val preprocess_intro : theory -> thm -> thm
    1.28 -  
    1.29 +
    1.30    val define_quickcheck_predicate :
    1.31      term -> theory -> (((string * typ) * (string * typ) list) * thm) * theory
    1.32  end;
    1.33 @@ -211,7 +211,7 @@
    1.34    | mode_ord (Bool, Bool) = EQUAL
    1.35    | mode_ord (Pair (m1, m2), Pair (m3, m4)) = prod_ord mode_ord mode_ord ((m1, m2), (m3, m4))
    1.36    | mode_ord (Fun (m1, m2), Fun (m3, m4)) = prod_ord mode_ord mode_ord ((m1, m2), (m3, m4))
    1.37 - 
    1.38 +
    1.39  fun list_fun_mode [] = Bool
    1.40    | list_fun_mode (m :: ms) = Fun (m, list_fun_mode ms)
    1.41  
    1.42 @@ -227,7 +227,7 @@
    1.43  fun dest_tuple_mode (Pair (mode, mode')) = mode :: dest_tuple_mode mode'
    1.44    | dest_tuple_mode _ = []
    1.45  
    1.46 -fun all_modes_of_typ' (T as Type ("fun", _)) = 
    1.47 +fun all_modes_of_typ' (T as Type ("fun", _)) =
    1.48    let
    1.49      val (S, U) = strip_type T
    1.50    in
    1.51 @@ -237,7 +237,7 @@
    1.52      else
    1.53        [Input, Output]
    1.54    end
    1.55 -  | all_modes_of_typ' (Type (@{type_name Product_Type.prod}, [T1, T2])) = 
    1.56 +  | all_modes_of_typ' (Type (@{type_name Product_Type.prod}, [T1, T2])) =
    1.57      map_product (curry Pair) (all_modes_of_typ' T1) (all_modes_of_typ' T2)
    1.58    | all_modes_of_typ' _ = [Input, Output]
    1.59  
    1.60 @@ -258,7 +258,7 @@
    1.61  fun all_smodes_of_typ (T as Type ("fun", _)) =
    1.62    let
    1.63      val (S, U) = strip_type T
    1.64 -    fun all_smodes (Type (@{type_name Product_Type.prod}, [T1, T2])) = 
    1.65 +    fun all_smodes (Type (@{type_name Product_Type.prod}, [T1, T2])) =
    1.66        map_product (curry Pair) (all_smodes T1) (all_smodes T2)
    1.67        | all_smodes _ = [Input, Output]
    1.68    in
    1.69 @@ -291,8 +291,9 @@
    1.70  
    1.71  fun ho_args_of_typ T ts =
    1.72    let
    1.73 -    fun ho_arg (T as Type("fun", [_,_])) (SOME t) = if body_type T = @{typ bool} then [t] else []
    1.74 -      | ho_arg (Type("fun", [_,_])) NONE = raise Fail "mode and term do not match"
    1.75 +    fun ho_arg (T as Type ("fun", [_, _])) (SOME t) =
    1.76 +          if body_type T = @{typ bool} then [t] else []
    1.77 +      | ho_arg (Type ("fun", [_, _])) NONE = raise Fail "mode and term do not match"
    1.78        | ho_arg (Type(@{type_name "Product_Type.prod"}, [T1, T2]))
    1.79           (SOME (Const (@{const_name Pair}, _) $ t1 $ t2)) =
    1.80            ho_arg T1 (SOME t1) @ ho_arg T2 (SOME t2)
    1.81 @@ -306,25 +307,25 @@
    1.82  fun ho_argsT_of_typ Ts =
    1.83    let
    1.84      fun ho_arg (T as Type("fun", [_,_])) = if body_type T = @{typ bool} then [T] else []
    1.85 -      | ho_arg (Type(@{type_name "Product_Type.prod"}, [T1, T2])) =
    1.86 +      | ho_arg (Type (@{type_name "Product_Type.prod"}, [T1, T2])) =
    1.87            ho_arg T1 @ ho_arg T2
    1.88        | ho_arg _ = []
    1.89    in
    1.90      maps ho_arg Ts
    1.91    end
    1.92 -  
    1.93 +
    1.94  
    1.95  (* temporary function should be replaced by unsplit_input or so? *)
    1.96  fun replace_ho_args mode hoargs ts =
    1.97    let
    1.98      fun replace (Fun _, _) (arg' :: hoargs') = (arg', hoargs')
    1.99        | replace (Pair (m1, m2), Const (@{const_name Pair}, T) $ t1 $ t2) hoargs =
   1.100 -        let
   1.101 -          val (t1', hoargs') = replace (m1, t1) hoargs
   1.102 -          val (t2', hoargs'') = replace (m2, t2) hoargs'
   1.103 -        in
   1.104 -          (Const (@{const_name Pair}, T) $ t1' $ t2', hoargs'')
   1.105 -        end
   1.106 +          let
   1.107 +            val (t1', hoargs') = replace (m1, t1) hoargs
   1.108 +            val (t2', hoargs'') = replace (m2, t2) hoargs'
   1.109 +          in
   1.110 +            (Const (@{const_name Pair}, T) $ t1' $ t2', hoargs'')
   1.111 +          end
   1.112        | replace (_, t) hoargs = (t, hoargs)
   1.113    in
   1.114      fst (fold_map replace (strip_fun_mode mode ~~ ts) hoargs)
   1.115 @@ -333,7 +334,8 @@
   1.116  fun ho_argsT_of mode Ts =
   1.117    let
   1.118      fun ho_arg (Fun _) T = [T]
   1.119 -      | ho_arg (Pair (m1, m2)) (Type (@{type_name Product_Type.prod}, [T1, T2])) = ho_arg m1 T1 @ ho_arg m2 T2
   1.120 +      | ho_arg (Pair (m1, m2)) (Type (@{type_name Product_Type.prod}, [T1, T2])) =
   1.121 +          ho_arg m1 T1 @ ho_arg m2 T2
   1.122        | ho_arg _ _ = []
   1.123    in
   1.124      flat (map2 ho_arg (strip_fun_mode mode) Ts)
   1.125 @@ -379,28 +381,28 @@
   1.126  fun split_mode mode ts = split_map_mode (fn _ => fn _ => (NONE, NONE)) mode ts
   1.127  
   1.128  fun fold_map_aterms_prodT comb f (Type (@{type_name Product_Type.prod}, [T1, T2])) s =
   1.129 -  let
   1.130 -    val (x1, s') = fold_map_aterms_prodT comb f T1 s
   1.131 -    val (x2, s'') = fold_map_aterms_prodT comb f T2 s'
   1.132 -  in
   1.133 -    (comb x1 x2, s'')
   1.134 -  end
   1.135 -  | fold_map_aterms_prodT comb f T s = f T s
   1.136 +      let
   1.137 +        val (x1, s') = fold_map_aterms_prodT comb f T1 s
   1.138 +        val (x2, s'') = fold_map_aterms_prodT comb f T2 s'
   1.139 +      in
   1.140 +        (comb x1 x2, s'')
   1.141 +      end
   1.142 +  | fold_map_aterms_prodT _ f T s = f T s
   1.143  
   1.144  fun map_filter_prod f (Const (@{const_name Pair}, _) $ t1 $ t2) =
   1.145 -  comb_option HOLogic.mk_prod (map_filter_prod f t1, map_filter_prod f t2)
   1.146 +      comb_option HOLogic.mk_prod (map_filter_prod f t1, map_filter_prod f t2)
   1.147    | map_filter_prod f t = f t
   1.148 -  
   1.149 +
   1.150  fun split_modeT mode Ts =
   1.151    let
   1.152      fun split_arg_mode (Fun _) _ = ([], [])
   1.153        | split_arg_mode (Pair (m1, m2)) (Type (@{type_name Product_Type.prod}, [T1, T2])) =
   1.154 -        let
   1.155 -          val (i1, o1) = split_arg_mode m1 T1
   1.156 -          val (i2, o2) = split_arg_mode m2 T2
   1.157 -        in
   1.158 -          (i1 @ i2, o1 @ o2)
   1.159 -        end
   1.160 +          let
   1.161 +            val (i1, o1) = split_arg_mode m1 T1
   1.162 +            val (i2, o2) = split_arg_mode m2 T2
   1.163 +          in
   1.164 +            (i1 @ i2, o1 @ o2)
   1.165 +          end
   1.166        | split_arg_mode Input T = ([T], [])
   1.167        | split_arg_mode Output T = ([], [T])
   1.168        | split_arg_mode _ _ = raise Fail "split_modeT: mode and type do not match"
   1.169 @@ -427,7 +429,7 @@
   1.170        | ascii_string_of_mode' Bool = "b"
   1.171        | ascii_string_of_mode' (Pair (m1, m2)) =
   1.172            "P" ^ ascii_string_of_mode' m1 ^ ascii_string_of_mode'_Pair m2
   1.173 -      | ascii_string_of_mode' (Fun (m1, m2)) = 
   1.174 +      | ascii_string_of_mode' (Fun (m1, m2)) =
   1.175            "F" ^ ascii_string_of_mode' m1 ^ ascii_string_of_mode'_Fun m2 ^ "B"
   1.176      and ascii_string_of_mode'_Fun (Fun (m1, m2)) =
   1.177            ascii_string_of_mode' m1 ^ (if m2 = Bool then "" else "_" ^ ascii_string_of_mode'_Fun m2)
   1.178 @@ -438,10 +440,11 @@
   1.179        | ascii_string_of_mode'_Pair m = ascii_string_of_mode' m
   1.180    in ascii_string_of_mode'_Fun mode' end
   1.181  
   1.182 +
   1.183  (* premises *)
   1.184  
   1.185 -datatype indprem = Prem of term | Negprem of term | Sidecond of term
   1.186 -  | Generator of (string * typ);
   1.187 +datatype indprem =
   1.188 +  Prem of term | Negprem of term | Sidecond of term | Generator of (string * typ)
   1.189  
   1.190  fun dest_indprem (Prem t) = t
   1.191    | dest_indprem (Negprem t) = t
   1.192 @@ -453,25 +456,28 @@
   1.193    | map_indprem f (Sidecond t) = Sidecond (f t)
   1.194    | map_indprem f (Generator (v, T)) = Generator (dest_Free (f (Free (v, T))))
   1.195  
   1.196 +
   1.197  (* general syntactic functions *)
   1.198  
   1.199  fun is_equationlike_term (Const ("==", _) $ _ $ _) = true
   1.200 -  | is_equationlike_term (Const (@{const_name Trueprop}, _) $ (Const (@{const_name HOL.eq}, _) $ _ $ _)) = true
   1.201 +  | is_equationlike_term
   1.202 +      (Const (@{const_name Trueprop}, _) $ (Const (@{const_name HOL.eq}, _) $ _ $ _)) = true
   1.203    | is_equationlike_term _ = false
   1.204 -  
   1.205 -val is_equationlike = is_equationlike_term o prop_of 
   1.206 +
   1.207 +val is_equationlike = is_equationlike_term o prop_of
   1.208  
   1.209  fun is_pred_equation_term (Const ("==", _) $ u $ v) =
   1.210 -  (fastype_of u = @{typ bool}) andalso (fastype_of v = @{typ bool})
   1.211 +      (fastype_of u = @{typ bool}) andalso (fastype_of v = @{typ bool})
   1.212    | is_pred_equation_term _ = false
   1.213 -  
   1.214 -val is_pred_equation = is_pred_equation_term o prop_of 
   1.215 +
   1.216 +val is_pred_equation = is_pred_equation_term o prop_of
   1.217  
   1.218  fun is_intro_term constname t =
   1.219 -  the_default false (try (fn t => case fst (strip_comb (HOLogic.dest_Trueprop (Logic.strip_imp_concl t))) of
   1.220 -    Const (c, _) => c = constname
   1.221 -  | _ => false) t)
   1.222 -  
   1.223 +  the_default false (try (fn t =>
   1.224 +    case fst (strip_comb (HOLogic.dest_Trueprop (Logic.strip_imp_concl t))) of
   1.225 +      Const (c, _) => c = constname
   1.226 +    | _ => false) t)
   1.227 +
   1.228  fun is_intro constname t = is_intro_term constname (prop_of t)
   1.229  
   1.230  fun is_predT (T as Type("fun", [_, _])) = (body_type T = @{typ bool})
   1.231 @@ -486,14 +492,17 @@
   1.232      val cnstrs = flat (maps
   1.233        (map (fn (_, (Tname, _, cs)) => map (apsnd (rpair Tname o length)) cs) o #descr o snd)
   1.234        (Symtab.dest (Datatype.get_all thy)));
   1.235 -    fun check t = (case strip_comb t of
   1.236 +    fun check t =
   1.237 +      (case strip_comb t of
   1.238          (Var _, []) => true
   1.239        | (Free _, []) => true
   1.240 -      | (Const (s, T), ts) => (case (AList.lookup (op =) cnstrs s, body_type T) of
   1.241 -            (SOME (i, Tname), Type (Tname', _)) => length ts = i andalso Tname = Tname' andalso forall check ts
   1.242 +      | (Const (s, T), ts) =>
   1.243 +          (case (AList.lookup (op =) cnstrs s, body_type T) of
   1.244 +            (SOME (i, Tname), Type (Tname', _)) =>
   1.245 +              length ts = i andalso Tname = Tname' andalso forall check ts
   1.246            | _ => false)
   1.247        | _ => false)
   1.248 -  in check end;
   1.249 +  in check end
   1.250  
   1.251  (* returns true if t is an application of an datatype constructor *)
   1.252  (* which then consequently would be splitted *)
   1.253 @@ -512,35 +521,37 @@
   1.254    else false
   1.255  *)
   1.256  
   1.257 -val is_constr = Code.is_constr o Proof_Context.theory_of;
   1.258 +val is_constr = Code.is_constr o Proof_Context.theory_of
   1.259  
   1.260  fun strip_all t = (Term.strip_all_vars t, Term.strip_all_body t)
   1.261  
   1.262  fun strip_ex (Const (@{const_name Ex}, _) $ Abs (x, T, t)) =
   1.263 -  let
   1.264 -    val (xTs, t') = strip_ex t
   1.265 -  in
   1.266 -    ((x, T) :: xTs, t')
   1.267 -  end
   1.268 +      let
   1.269 +        val (xTs, t') = strip_ex t
   1.270 +      in
   1.271 +        ((x, T) :: xTs, t')
   1.272 +      end
   1.273    | strip_ex t = ([], t)
   1.274  
   1.275  fun focus_ex t nctxt =
   1.276    let
   1.277 -    val ((xs, Ts), t') = apfst split_list (strip_ex t) 
   1.278 +    val ((xs, Ts), t') = apfst split_list (strip_ex t)
   1.279      val (xs', nctxt') = fold_map Name.variant xs nctxt;
   1.280      val ps' = xs' ~~ Ts;
   1.281      val vs = map Free ps';
   1.282      val t'' = Term.subst_bounds (rev vs, t');
   1.283 -  in ((ps', t''), nctxt') end;
   1.284 +  in ((ps', t''), nctxt') end
   1.285  
   1.286 -val strip_intro_concl = (strip_comb o HOLogic.dest_Trueprop o Logic.strip_imp_concl o prop_of)
   1.287 -  
   1.288 +val strip_intro_concl = strip_comb o HOLogic.dest_Trueprop o Logic.strip_imp_concl o prop_of
   1.289 +
   1.290 +
   1.291  (* introduction rule combinators *)
   1.292  
   1.293 -fun map_atoms f intro = 
   1.294 +fun map_atoms f intro =
   1.295    let
   1.296      val (literals, head) = Logic.strip_horn intro
   1.297 -    fun appl t = (case t of
   1.298 +    fun appl t =
   1.299 +      (case t of
   1.300          (@{term Not} $ t') => HOLogic.mk_not (f t')
   1.301        | _ => f t)
   1.302    in
   1.303 @@ -551,16 +562,18 @@
   1.304  fun fold_atoms f intro s =
   1.305    let
   1.306      val (literals, _) = Logic.strip_horn intro
   1.307 -    fun appl t s = (case t of
   1.308 -      (@{term Not} $ t') => f t' s
   1.309 +    fun appl t s =
   1.310 +      (case t of
   1.311 +        (@{term Not} $ t') => f t' s
   1.312        | _ => f t s)
   1.313    in fold appl (map HOLogic.dest_Trueprop literals) s end
   1.314  
   1.315  fun fold_map_atoms f intro s =
   1.316    let
   1.317      val (literals, head) = Logic.strip_horn intro
   1.318 -    fun appl t s = (case t of
   1.319 -      (@{term Not} $ t') => apfst HOLogic.mk_not (f t' s)
   1.320 +    fun appl t s =
   1.321 +      (case t of
   1.322 +        (@{term Not} $ t') => apfst HOLogic.mk_not (f t' s)
   1.323        | _ => f t s)
   1.324      val (literals', s') = fold_map appl (map HOLogic.dest_Trueprop literals) s
   1.325    in
   1.326 @@ -588,12 +601,14 @@
   1.327      Logic.list_implies (premises, f head)
   1.328    end
   1.329  
   1.330 +
   1.331  (* combinators to apply a function to all basic parts of nested products *)
   1.332  
   1.333  fun map_products f (Const (@{const_name Pair}, T) $ t1 $ t2) =
   1.334    Const (@{const_name Pair}, T) $ map_products f t1 $ map_products f t2
   1.335    | map_products f t = f t
   1.336  
   1.337 +
   1.338  (* split theorems of case expressions *)
   1.339  
   1.340  fun prepare_split_thm ctxt split_thm =
   1.341 @@ -602,7 +617,8 @@
   1.342        @{thm atomize_all[symmetric]}, @{thm atomize_imp[symmetric]}]
   1.343  
   1.344  fun find_split_thm thy (Const (name, _)) = Option.map #split (Datatype.info_of_case thy name)
   1.345 -  | find_split_thm thy _ = NONE
   1.346 +  | find_split_thm _ _ = NONE
   1.347 +
   1.348  
   1.349  (* lifting term operations to theorems *)
   1.350  
   1.351 @@ -612,10 +628,11 @@
   1.352  (*
   1.353  fun equals_conv lhs_cv rhs_cv ct =
   1.354    case Thm.term_of ct of
   1.355 -    Const ("==", _) $ _ $ _ => Conv.arg_conv cv ct  
   1.356 -  | _ => error "equals_conv"  
   1.357 +    Const ("==", _) $ _ $ _ => Conv.arg_conv cv ct
   1.358 +  | _ => error "equals_conv"
   1.359  *)
   1.360  
   1.361 +
   1.362  (* Different compilations *)
   1.363  
   1.364  datatype compilation = Pred | Depth_Limited | Random | Depth_Limited_Random | DSeq | Annotated
   1.365 @@ -629,9 +646,9 @@
   1.366    | negative_compilation_of Pos_Generator_DSeq = Neg_Generator_DSeq
   1.367    | negative_compilation_of Neg_Generator_DSeq = Pos_Generator_DSeq
   1.368    | negative_compilation_of Pos_Generator_CPS = Neg_Generator_CPS
   1.369 -  | negative_compilation_of Neg_Generator_CPS = Pos_Generator_CPS  
   1.370 +  | negative_compilation_of Neg_Generator_CPS = Pos_Generator_CPS
   1.371    | negative_compilation_of c = c
   1.372 -  
   1.373 +
   1.374  fun compilation_for_polarity false Pos_Random_DSeq = Neg_Random_DSeq
   1.375    | compilation_for_polarity false New_Pos_Random_DSeq = New_Neg_Random_DSeq
   1.376    | compilation_for_polarity _ c = c
   1.377 @@ -641,7 +658,7 @@
   1.378    (c = Pos_Generator_DSeq) orelse (c = Pos_Generator_DSeq)
   1.379  
   1.380  fun string_of_compilation c =
   1.381 -  case c of
   1.382 +  (case c of
   1.383      Pred => ""
   1.384    | Random => "random"
   1.385    | Depth_Limited => "depth limited"
   1.386 @@ -655,9 +672,10 @@
   1.387    | Pos_Generator_DSeq => "pos_generator_dseq"
   1.388    | Neg_Generator_DSeq => "neg_generator_dseq"
   1.389    | Pos_Generator_CPS => "pos_generator_cps"
   1.390 -  | Neg_Generator_CPS => "neg_generator_cps"
   1.391 -  
   1.392 -val compilation_names = [("pred", Pred),
   1.393 +  | Neg_Generator_CPS => "neg_generator_cps")
   1.394 +
   1.395 +val compilation_names =
   1.396 + [("pred", Pred),
   1.397    ("random", Random),
   1.398    ("depth_limited", Depth_Limited),
   1.399    ("depth_limited_random", Depth_Limited_Random),
   1.400 @@ -675,6 +693,7 @@
   1.401    Pos_Random_DSeq, Neg_Random_DSeq, New_Pos_Random_DSeq, New_Neg_Random_DSeq,
   1.402    Pos_Generator_CPS, Neg_Generator_CPS]
   1.403  
   1.404 +
   1.405  (* datastructures and setup for generic compilation *)
   1.406  
   1.407  datatype compilation_funs = CompilationFuns of {
   1.408 @@ -688,7 +707,7 @@
   1.409    mk_iterate_upto : typ -> term * term * term -> term,
   1.410    mk_not : term -> term,
   1.411    mk_map : typ -> typ -> term -> term -> term
   1.412 -};
   1.413 +}
   1.414  
   1.415  fun mk_monadT (CompilationFuns funs) = #mk_monadT funs
   1.416  fun dest_monadT (CompilationFuns funs) = #dest_monadT funs
   1.417 @@ -701,19 +720,22 @@
   1.418  fun mk_not (CompilationFuns funs) = #mk_not funs
   1.419  fun mk_map (CompilationFuns funs) = #mk_map funs
   1.420  
   1.421 +
   1.422  (** function types and names of different compilations **)
   1.423  
   1.424  fun funT_of compfuns mode T =
   1.425    let
   1.426      val Ts = binder_types T
   1.427 -    val (inTs, outTs) = split_map_modeT (fn m => fn T => (SOME (funT_of compfuns m T), NONE)) mode Ts
   1.428 +    val (inTs, outTs) =
   1.429 +      split_map_modeT (fn m => fn T => (SOME (funT_of compfuns m T), NONE)) mode Ts
   1.430    in
   1.431      inTs ---> (mk_monadT compfuns (HOLogic.mk_tupleT outTs))
   1.432 -  end;
   1.433 +  end
   1.434 +
   1.435  
   1.436  (* Different options for compiler *)
   1.437  
   1.438 -datatype options = Options of {  
   1.439 +datatype options = Options of {
   1.440    expected_modes : (string * mode list) option,
   1.441    proposed_modes : (string * mode list) list,
   1.442    proposed_names : ((string * mode) * string) list,
   1.443 @@ -735,7 +757,7 @@
   1.444    detect_switches : bool,
   1.445    smart_depth_limiting : bool,
   1.446    compilation : compilation
   1.447 -};
   1.448 +}
   1.449  
   1.450  fun expected_modes (Options opt) = #expected_modes opt
   1.451  fun proposed_modes (Options opt) = AList.lookup (op =) (#proposed_modes opt)
   1.452 @@ -798,33 +820,37 @@
   1.453  fun print_step options s =
   1.454    if show_steps options then tracing s else ()
   1.455  
   1.456 +
   1.457  (* simple transformations *)
   1.458  
   1.459  (** tuple processing **)
   1.460  
   1.461  fun rewrite_args [] (pats, intro_t, ctxt) = (pats, intro_t, ctxt)
   1.462 -  | rewrite_args (arg::args) (pats, intro_t, ctxt) = 
   1.463 -    (case HOLogic.strip_tupleT (fastype_of arg) of
   1.464 -      (_ :: _ :: _) =>
   1.465 -      let
   1.466 -        fun rewrite_arg' (Const (@{const_name Pair}, _) $ _ $ t2, Type (@{type_name Product_Type.prod}, [_, T2]))
   1.467 -          (args, (pats, intro_t, ctxt)) = rewrite_arg' (t2, T2) (args, (pats, intro_t, ctxt))
   1.468 -          | rewrite_arg' (t, Type (@{type_name Product_Type.prod}, [T1, T2])) (args, (pats, intro_t, ctxt)) =
   1.469 -            let
   1.470 -              val thy = Proof_Context.theory_of ctxt
   1.471 -              val ([x, y], ctxt') = Variable.variant_fixes ["x", "y"] ctxt
   1.472 -              val pat = (t, HOLogic.mk_prod (Free (x, T1), Free (y, T2)))
   1.473 -              val intro_t' = Pattern.rewrite_term thy [pat] [] intro_t
   1.474 -              val args' = map (Pattern.rewrite_term thy [pat] []) args
   1.475 -            in
   1.476 -              rewrite_arg' (Free (y, T2), T2) (args', (pat::pats, intro_t', ctxt'))
   1.477 -            end
   1.478 -          | rewrite_arg' _ (args, (pats, intro_t, ctxt)) = (args, (pats, intro_t, ctxt))
   1.479 -        val (args', (pats, intro_t', ctxt')) = rewrite_arg' (arg, fastype_of arg)
   1.480 -          (args, (pats, intro_t, ctxt))
   1.481 -      in
   1.482 -        rewrite_args args' (pats, intro_t', ctxt')
   1.483 -      end
   1.484 +  | rewrite_args (arg::args) (pats, intro_t, ctxt) =
   1.485 +      (case HOLogic.strip_tupleT (fastype_of arg) of
   1.486 +        (_ :: _ :: _) =>
   1.487 +        let
   1.488 +          fun rewrite_arg'
   1.489 +                (Const (@{const_name Pair}, _) $ _ $ t2, Type (@{type_name Product_Type.prod}, [_, T2]))
   1.490 +                (args, (pats, intro_t, ctxt)) =
   1.491 +                rewrite_arg' (t2, T2) (args, (pats, intro_t, ctxt))
   1.492 +            | rewrite_arg'
   1.493 +                (t, Type (@{type_name Product_Type.prod}, [T1, T2])) (args, (pats, intro_t, ctxt)) =
   1.494 +                let
   1.495 +                  val thy = Proof_Context.theory_of ctxt
   1.496 +                  val ([x, y], ctxt') = Variable.variant_fixes ["x", "y"] ctxt
   1.497 +                  val pat = (t, HOLogic.mk_prod (Free (x, T1), Free (y, T2)))
   1.498 +                  val intro_t' = Pattern.rewrite_term thy [pat] [] intro_t
   1.499 +                  val args' = map (Pattern.rewrite_term thy [pat] []) args
   1.500 +                in
   1.501 +                  rewrite_arg' (Free (y, T2), T2) (args', (pat::pats, intro_t', ctxt'))
   1.502 +                end
   1.503 +            | rewrite_arg' _ (args, (pats, intro_t, ctxt)) = (args, (pats, intro_t, ctxt))
   1.504 +          val (args', (pats, intro_t', ctxt')) =
   1.505 +            rewrite_arg' (arg, fastype_of arg) (args, (pats, intro_t, ctxt))
   1.506 +        in
   1.507 +          rewrite_args args' (pats, intro_t', ctxt')
   1.508 +        end
   1.509    | _ => rewrite_args args (pats, intro_t, ctxt))
   1.510  
   1.511  fun rewrite_prem atom =
   1.512 @@ -834,23 +860,24 @@
   1.513  
   1.514  fun split_conjuncts_in_assms ctxt th =
   1.515    let
   1.516 -    val ((_, [fixed_th]), ctxt') = Variable.import false [th] ctxt 
   1.517 +    val ((_, [fixed_th]), ctxt') = Variable.import false [th] ctxt
   1.518      fun split_conjs i nprems th =
   1.519        if i > nprems then th
   1.520        else
   1.521 -        case try Drule.RSN (@{thm conjI}, (i, th)) of
   1.522 -          SOME th' => split_conjs i (nprems+1) th'
   1.523 -        | NONE => split_conjs (i+1) nprems th
   1.524 +        (case try Drule.RSN (@{thm conjI}, (i, th)) of
   1.525 +          SOME th' => split_conjs i (nprems + 1) th'
   1.526 +        | NONE => split_conjs (i + 1) nprems th)
   1.527    in
   1.528 -    singleton (Variable.export ctxt' ctxt) (split_conjs 1 (Thm.nprems_of fixed_th) fixed_th)
   1.529 +    singleton (Variable.export ctxt' ctxt)
   1.530 +      (split_conjs 1 (Thm.nprems_of fixed_th) fixed_th)
   1.531    end
   1.532  
   1.533  fun dest_conjunct_prem th =
   1.534 -  case HOLogic.dest_Trueprop (prop_of th) of
   1.535 +  (case HOLogic.dest_Trueprop (prop_of th) of
   1.536      (Const (@{const_name HOL.conj}, _) $ _ $ _) =>
   1.537        dest_conjunct_prem (th RS @{thm conjunct1})
   1.538          @ dest_conjunct_prem (th RS @{thm conjunct2})
   1.539 -    | _ => [th]
   1.540 +   | _ => [th])
   1.541  
   1.542  fun expand_tuples thy intro =
   1.543    let
   1.544 @@ -877,6 +904,7 @@
   1.545      intro'''''
   1.546    end
   1.547  
   1.548 +
   1.549  (** making case distributivity rules **)
   1.550  (*** this should be part of the datatype package ***)
   1.551  
   1.552 @@ -888,7 +916,7 @@
   1.553      val case_combs = Datatype_Prop.make_case_combs case_names descr thy "f";
   1.554      fun make comb =
   1.555        let
   1.556 -        val Type ("fun", [T, T']) = fastype_of comb;
   1.557 +        val Type ("fun", [T, T']) = fastype_of comb
   1.558          val (Const (case_name, _), fs) = strip_comb comb
   1.559          val used = Term.add_tfree_names comb []
   1.560          val U = TFree (singleton (Name.variant_list used) "'t", HOLogic.typeS)
   1.561 @@ -952,12 +980,14 @@
   1.562        (map (fn th => th RS @{thm eq_reflection}) ths) [] t
   1.563    end
   1.564  
   1.565 +
   1.566  (*** conversions ***)
   1.567  
   1.568  fun imp_prems_conv cv ct =
   1.569 -  case Thm.term_of ct of
   1.570 +  (case Thm.term_of ct of
   1.571      Const ("==>", _) $ _ $ _ => Conv.combination_conv (Conv.arg_conv cv) (imp_prems_conv cv) ct
   1.572 -  | _ => Conv.all_conv ct
   1.573 +  | _ => Conv.all_conv ct)
   1.574 +
   1.575  
   1.576  (** eta contract higher-order arguments **)
   1.577  
   1.578 @@ -968,6 +998,7 @@
   1.579      map_term thy (map_concl f o map_atoms f) intro
   1.580    end
   1.581  
   1.582 +
   1.583  (** remove equalities **)
   1.584  
   1.585  fun remove_equalities thy intro =
   1.586 @@ -978,26 +1009,27 @@
   1.587          fun remove_eq (prems, concl) =
   1.588            let
   1.589              fun removable_eq prem =
   1.590 -              case try (HOLogic.dest_eq o HOLogic.dest_Trueprop) prem of
   1.591 -                SOME (lhs, rhs) => (case lhs of
   1.592 -                  Var _ => true
   1.593 +              (case try (HOLogic.dest_eq o HOLogic.dest_Trueprop) prem of
   1.594 +                SOME (lhs, rhs) =>
   1.595 +                  (case lhs of
   1.596 +                    Var _ => true
   1.597                    | _ => (case rhs of Var _ => true | _ => false))
   1.598 -              | NONE => false
   1.599 +              | NONE => false)
   1.600            in
   1.601 -            case find_first removable_eq prems of
   1.602 +            (case find_first removable_eq prems of
   1.603                NONE => (prems, concl)
   1.604              | SOME eq =>
   1.605 -              let
   1.606 -                val (lhs, rhs) = HOLogic.dest_eq (HOLogic.dest_Trueprop eq)
   1.607 -                val prems' = remove (op =) eq prems
   1.608 -                val subst = (case lhs of
   1.609 -                  (v as Var _) =>
   1.610 -                    (fn t => if t = v then rhs else t)
   1.611 -                | _ => (case rhs of
   1.612 -                   (v as Var _) => (fn t => if t = v then lhs else t)))
   1.613 -              in
   1.614 -                remove_eq (map (map_aterms subst) prems', map_aterms subst concl)
   1.615 -              end
   1.616 +                let
   1.617 +                  val (lhs, rhs) = HOLogic.dest_eq (HOLogic.dest_Trueprop eq)
   1.618 +                  val prems' = remove (op =) eq prems
   1.619 +                  val subst =
   1.620 +                    (case lhs of
   1.621 +                      (v as Var _) =>
   1.622 +                        (fn t => if t = v then rhs else t)
   1.623 +                    | _ => (case rhs of (v as Var _) => (fn t => if t = v then lhs else t)))
   1.624 +                in
   1.625 +                  remove_eq (map (map_aterms subst) prems', map_aterms subst concl)
   1.626 +                end)
   1.627            end
   1.628        in
   1.629          Logic.list_implies (remove_eq (prems, concl))
   1.630 @@ -1006,6 +1038,7 @@
   1.631      map_term thy remove_eqs intro
   1.632    end
   1.633  
   1.634 +
   1.635  (* Some last processing *)
   1.636  
   1.637  fun remove_pointless_clauses intro =
   1.638 @@ -1013,6 +1046,7 @@
   1.639      []
   1.640    else [intro]
   1.641  
   1.642 +
   1.643  (* some peephole optimisations *)
   1.644  
   1.645  fun peephole_optimisation thy intro =
   1.646 @@ -1021,7 +1055,8 @@
   1.647      val process =
   1.648        rewrite_rule ctxt (Predicate_Compile_Simps.get ctxt)
   1.649      fun process_False intro_t =
   1.650 -      if member (op =) (Logic.strip_imp_prems intro_t) @{prop "False"} then NONE else SOME intro_t
   1.651 +      if member (op =) (Logic.strip_imp_prems intro_t) @{prop "False"}
   1.652 +      then NONE else SOME intro_t
   1.653      fun process_True intro_t =
   1.654        map_filter_premises (fn p => if p = @{prop True} then NONE else SOME p) intro_t
   1.655    in
   1.656 @@ -1033,60 +1068,65 @@
   1.657  (* importing introduction rules *)
   1.658  
   1.659  fun import_intros inp_pred [] ctxt =
   1.660 -  let
   1.661 -    val ([outp_pred], ctxt') = Variable.import_terms true [inp_pred] ctxt
   1.662 -    val T = fastype_of outp_pred
   1.663 -    val paramTs = ho_argsT_of_typ (binder_types T)
   1.664 -    val (param_names, _) = Variable.variant_fixes
   1.665 -      (map (fn i => "p" ^ (string_of_int i)) (1 upto (length paramTs))) ctxt'
   1.666 -    val params = map2 (curry Free) param_names paramTs
   1.667 -  in
   1.668 -    (((outp_pred, params), []), ctxt')
   1.669 -  end
   1.670 +      let
   1.671 +        val ([outp_pred], ctxt') = Variable.import_terms true [inp_pred] ctxt
   1.672 +        val T = fastype_of outp_pred
   1.673 +        val paramTs = ho_argsT_of_typ (binder_types T)
   1.674 +        val (param_names, _) = Variable.variant_fixes
   1.675 +          (map (fn i => "p" ^ (string_of_int i)) (1 upto (length paramTs))) ctxt'
   1.676 +        val params = map2 (curry Free) param_names paramTs
   1.677 +      in
   1.678 +        (((outp_pred, params), []), ctxt')
   1.679 +      end
   1.680    | import_intros inp_pred (th :: ths) ctxt =
   1.681 -    let
   1.682 -      val ((_, [th']), ctxt') = Variable.import true [th] ctxt
   1.683 -      val thy = Proof_Context.theory_of ctxt'
   1.684 -      val (pred, args) = strip_intro_concl th'
   1.685 -      val T = fastype_of pred
   1.686 -      val ho_args = ho_args_of_typ T args
   1.687 -      fun subst_of (pred', pred) =
   1.688 -        let
   1.689 -          val subst = Sign.typ_match thy (fastype_of pred', fastype_of pred) Vartab.empty
   1.690 -            handle Type.TYPE_MATCH => error ("Type mismatch of predicate " ^ fst (dest_Const pred)
   1.691 -            ^ " (trying to match " ^ Syntax.string_of_typ ctxt (fastype_of pred')
   1.692 -            ^ " and " ^ Syntax.string_of_typ ctxt (fastype_of pred) ^ ")"
   1.693 -            ^ " in " ^ Display.string_of_thm ctxt th)
   1.694 -        in map (fn (indexname, (s, T)) => ((indexname, s), T)) (Vartab.dest subst) end
   1.695 -      fun instantiate_typ th =
   1.696 -        let
   1.697 -          val (pred', _) = strip_intro_concl th
   1.698 -          val _ = if not (fst (dest_Const pred) = fst (dest_Const pred')) then
   1.699 -            raise Fail "Trying to instantiate another predicate" else ()
   1.700 -        in Thm.certify_instantiate (subst_of (pred', pred), []) th end;
   1.701 -      fun instantiate_ho_args th =
   1.702 -        let
   1.703 -          val (_, args') = (strip_comb o HOLogic.dest_Trueprop o Logic.strip_imp_concl o prop_of) th
   1.704 -          val ho_args' = map dest_Var (ho_args_of_typ T args')
   1.705 -        in Thm.certify_instantiate ([], ho_args' ~~ ho_args) th end
   1.706 -      val outp_pred =
   1.707 -        Term_Subst.instantiate (subst_of (inp_pred, pred), []) inp_pred
   1.708 -      val ((_, ths'), ctxt1) =
   1.709 -        Variable.import false (map (instantiate_typ #> instantiate_ho_args) ths) ctxt'
   1.710 -    in
   1.711 -      (((outp_pred, ho_args), th' :: ths'), ctxt1)
   1.712 -    end
   1.713 -  
   1.714 +      let
   1.715 +        val ((_, [th']), ctxt') = Variable.import true [th] ctxt
   1.716 +        val thy = Proof_Context.theory_of ctxt'
   1.717 +        val (pred, args) = strip_intro_concl th'
   1.718 +        val T = fastype_of pred
   1.719 +        val ho_args = ho_args_of_typ T args
   1.720 +        fun subst_of (pred', pred) =
   1.721 +          let
   1.722 +            val subst = Sign.typ_match thy (fastype_of pred', fastype_of pred) Vartab.empty
   1.723 +              handle Type.TYPE_MATCH =>
   1.724 +                error ("Type mismatch of predicate " ^ fst (dest_Const pred) ^
   1.725 +                  " (trying to match " ^ Syntax.string_of_typ ctxt (fastype_of pred') ^
   1.726 +                  " and " ^ Syntax.string_of_typ ctxt (fastype_of pred) ^ ")" ^
   1.727 +                  " in " ^ Display.string_of_thm ctxt th)
   1.728 +          in map (fn (indexname, (s, T)) => ((indexname, s), T)) (Vartab.dest subst) end
   1.729 +        fun instantiate_typ th =
   1.730 +          let
   1.731 +            val (pred', _) = strip_intro_concl th
   1.732 +            val _ =
   1.733 +              if not (fst (dest_Const pred) = fst (dest_Const pred')) then
   1.734 +                raise Fail "Trying to instantiate another predicate"
   1.735 +              else ()
   1.736 +          in Thm.certify_instantiate (subst_of (pred', pred), []) th end
   1.737 +        fun instantiate_ho_args th =
   1.738 +          let
   1.739 +            val (_, args') =
   1.740 +              (strip_comb o HOLogic.dest_Trueprop o Logic.strip_imp_concl o prop_of) th
   1.741 +            val ho_args' = map dest_Var (ho_args_of_typ T args')
   1.742 +          in Thm.certify_instantiate ([], ho_args' ~~ ho_args) th end
   1.743 +        val outp_pred =
   1.744 +          Term_Subst.instantiate (subst_of (inp_pred, pred), []) inp_pred
   1.745 +        val ((_, ths'), ctxt1) =
   1.746 +          Variable.import false (map (instantiate_typ #> instantiate_ho_args) ths) ctxt'
   1.747 +      in
   1.748 +        (((outp_pred, ho_args), th' :: ths'), ctxt1)
   1.749 +      end
   1.750 +
   1.751 +
   1.752  (* generation of case rules from user-given introduction rules *)
   1.753  
   1.754  fun mk_args2 (Type (@{type_name Product_Type.prod}, [T1, T2])) st =
   1.755 -    let
   1.756 -      val (t1, st') = mk_args2 T1 st
   1.757 -      val (t2, st'') = mk_args2 T2 st'
   1.758 -    in
   1.759 -      (HOLogic.mk_prod (t1, t2), st'')
   1.760 -    end
   1.761 -  (*| mk_args2 (T as Type ("fun", _)) (params, ctxt) = 
   1.762 +      let
   1.763 +        val (t1, st') = mk_args2 T1 st
   1.764 +        val (t2, st'') = mk_args2 T2 st'
   1.765 +      in
   1.766 +        (HOLogic.mk_prod (t1, t2), st'')
   1.767 +      end
   1.768 +  (*| mk_args2 (T as Type ("fun", _)) (params, ctxt) =
   1.769      let
   1.770        val (S, U) = strip_type T
   1.771      in
   1.772 @@ -1100,11 +1140,11 @@
   1.773          end
   1.774      end*)
   1.775    | mk_args2 T (params, ctxt) =
   1.776 -    let
   1.777 -      val ([x], ctxt') = Variable.variant_fixes ["x"] ctxt
   1.778 -    in
   1.779 -      (Free (x, T), (params, ctxt'))
   1.780 -    end
   1.781 +      let
   1.782 +        val ([x], ctxt') = Variable.variant_fixes ["x"] ctxt
   1.783 +      in
   1.784 +        (Free (x, T), (params, ctxt'))
   1.785 +      end
   1.786  
   1.787  fun mk_casesrule ctxt pred introrules =
   1.788    let
   1.789 @@ -1129,28 +1169,29 @@
   1.790      val assm = HOLogic.mk_Trueprop (list_comb (pred, argvs))
   1.791      val cases = map mk_case intros
   1.792    in Logic.list_implies (assm :: cases, prop) end;
   1.793 -  
   1.794 +
   1.795  
   1.796  (* unifying constants to have the same type variables *)
   1.797  
   1.798  fun unify_consts thy cs intr_ts =
   1.799 -  (let
   1.800 +  let
   1.801       val add_term_consts_2 = fold_aterms (fn Const c => insert (op =) c | _ => I);
   1.802       fun varify (t, (i, ts)) =
   1.803         let val t' = map_types (Logic.incr_tvar (i + 1)) (#2 (Type.varify_global [] t))
   1.804 -       in (maxidx_of_term t', t'::ts) end;
   1.805 -     val (i, cs') = List.foldr varify (~1, []) cs;
   1.806 -     val (i', intr_ts') = List.foldr varify (i, []) intr_ts;
   1.807 -     val rec_consts = fold add_term_consts_2 cs' [];
   1.808 -     val intr_consts = fold add_term_consts_2 intr_ts' [];
   1.809 +       in (maxidx_of_term t', t' :: ts) end
   1.810 +     val (i, cs') = List.foldr varify (~1, []) cs
   1.811 +     val (i', intr_ts') = List.foldr varify (i, []) intr_ts
   1.812 +     val rec_consts = fold add_term_consts_2 cs' []
   1.813 +     val intr_consts = fold add_term_consts_2 intr_ts' []
   1.814       fun unify (cname, cT) =
   1.815         let val consts = map snd (filter (fn c => fst c = cname) intr_consts)
   1.816 -       in fold (Sign.typ_unify thy) ((replicate (length consts) cT) ~~ consts) end;
   1.817 -     val (env, _) = fold unify rec_consts (Vartab.empty, i');
   1.818 +       in fold (Sign.typ_unify thy) ((replicate (length consts) cT) ~~ consts) end
   1.819 +     val (env, _) = fold unify rec_consts (Vartab.empty, i')
   1.820       val subst = map_types (Envir.norm_type env)
   1.821     in (map subst cs', map subst intr_ts')
   1.822 -   end) handle Type.TUNIFY =>
   1.823 -     (warning "Occurrences of recursive constant have non-unifiable types"; (cs, intr_ts));
   1.824 +   end handle Type.TUNIFY =>
   1.825 +     (warning "Occurrences of recursive constant have non-unifiable types"; (cs, intr_ts))
   1.826 +
   1.827  
   1.828  (* preprocessing rules *)
   1.829  
   1.830 @@ -1163,6 +1204,7 @@
   1.831  
   1.832  fun preprocess_intro thy = expand_tuples thy #> preprocess_equality thy
   1.833  
   1.834 +
   1.835  (* defining a quickcheck predicate *)
   1.836  
   1.837  fun strip_imp_prems (Const(@{const_name HOL.implies}, _) $ A $ B) = A :: strip_imp_prems B
   1.838 @@ -1171,7 +1213,7 @@
   1.839  fun strip_imp_concl (Const(@{const_name HOL.implies}, _) $ _ $ B) = strip_imp_concl B
   1.840    | strip_imp_concl A = A;
   1.841  
   1.842 -fun strip_horn A = (strip_imp_prems A, strip_imp_concl A);
   1.843 +fun strip_horn A = (strip_imp_prems A, strip_imp_concl A)
   1.844  
   1.845  fun define_quickcheck_predicate t thy =
   1.846    let
   1.847 @@ -1184,9 +1226,10 @@
   1.848      val constT = map snd vs' ---> @{typ bool}
   1.849      val thy1 = Sign.add_consts_i [(Binding.name constname, constT, NoSyn)] thy
   1.850      val const = Const (full_constname, constT)
   1.851 -    val t = Logic.list_implies
   1.852 -      (map HOLogic.mk_Trueprop (prems @ [HOLogic.mk_not concl]),
   1.853 -       HOLogic.mk_Trueprop (list_comb (const, map Free vs')))
   1.854 +    val t =
   1.855 +      Logic.list_implies
   1.856 +        (map HOLogic.mk_Trueprop (prems @ [HOLogic.mk_not concl]),
   1.857 +          HOLogic.mk_Trueprop (list_comb (const, map Free vs')))
   1.858      val intro =
   1.859        Goal.prove (Proof_Context.init_global thy1) (map fst vs') [] t
   1.860          (fn _ => ALLGOALS Skip_Proof.cheat_tac)
   1.861 @@ -1194,4 +1237,4 @@
   1.862      ((((full_constname, constT), vs'), intro), thy1)
   1.863    end
   1.864  
   1.865 -end;
   1.866 +end