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