1046 in |
1054 in |
1047 Option.map (Skip_Proof.make_thm thy) |
1055 Option.map (Skip_Proof.make_thm thy) |
1048 (process_False (process_True (prop_of (process intro)))) |
1056 (process_False (process_True (prop_of (process intro)))) |
1049 end |
1057 end |
1050 |
1058 |
|
1059 |
|
1060 (* importing introduction rules *) |
|
1061 |
|
1062 fun import_intros inp_pred [] ctxt = |
|
1063 let |
|
1064 val ([outp_pred], ctxt') = Variable.import_terms true [inp_pred] ctxt |
|
1065 val T = fastype_of outp_pred |
|
1066 val paramTs = ho_argsT_of_typ (binder_types T) |
|
1067 val (param_names, ctxt'') = Variable.variant_fixes |
|
1068 (map (fn i => "p" ^ (string_of_int i)) (1 upto (length paramTs))) ctxt' |
|
1069 val params = map2 (curry Free) param_names paramTs |
|
1070 in |
|
1071 (((outp_pred, params), []), ctxt') |
|
1072 end |
|
1073 | import_intros inp_pred (th :: ths) ctxt = |
|
1074 let |
|
1075 val ((_, [th']), ctxt') = Variable.import true [th] ctxt |
|
1076 val thy = ProofContext.theory_of ctxt' |
|
1077 val (pred, args) = strip_intro_concl th' |
|
1078 val T = fastype_of pred |
|
1079 val ho_args = ho_args_of_typ T args |
|
1080 fun subst_of (pred', pred) = |
|
1081 let |
|
1082 val subst = Sign.typ_match thy (fastype_of pred', fastype_of pred) Vartab.empty |
|
1083 handle Type.TYPE_MATCH => error ("Type mismatch of predicate " ^ fst (dest_Const pred) |
|
1084 ^ " (trying to match " ^ Syntax.string_of_typ ctxt (fastype_of pred') |
|
1085 ^ " and " ^ Syntax.string_of_typ ctxt (fastype_of pred) ^ ")" |
|
1086 ^ " in " ^ Display.string_of_thm ctxt th) |
|
1087 in map (fn (indexname, (s, T)) => ((indexname, s), T)) (Vartab.dest subst) end |
|
1088 fun instantiate_typ th = |
|
1089 let |
|
1090 val (pred', _) = strip_intro_concl th |
|
1091 val _ = if not (fst (dest_Const pred) = fst (dest_Const pred')) then |
|
1092 raise Fail "Trying to instantiate another predicate" else () |
|
1093 in Thm.certify_instantiate (subst_of (pred', pred), []) th end; |
|
1094 fun instantiate_ho_args th = |
|
1095 let |
|
1096 val (_, args') = (strip_comb o HOLogic.dest_Trueprop o Logic.strip_imp_concl o prop_of) th |
|
1097 val ho_args' = map dest_Var (ho_args_of_typ T args') |
|
1098 in Thm.certify_instantiate ([], ho_args' ~~ ho_args) th end |
|
1099 val outp_pred = |
|
1100 Term_Subst.instantiate (subst_of (inp_pred, pred), []) inp_pred |
|
1101 val ((_, ths'), ctxt1) = |
|
1102 Variable.import false (map (instantiate_typ #> instantiate_ho_args) ths) ctxt' |
|
1103 in |
|
1104 (((outp_pred, ho_args), th' :: ths'), ctxt1) |
|
1105 end |
|
1106 |
|
1107 (* generation of case rules from user-given introduction rules *) |
|
1108 |
|
1109 fun mk_args2 (Type (@{type_name Product_Type.prod}, [T1, T2])) st = |
|
1110 let |
|
1111 val (t1, st') = mk_args2 T1 st |
|
1112 val (t2, st'') = mk_args2 T2 st' |
|
1113 in |
|
1114 (HOLogic.mk_prod (t1, t2), st'') |
|
1115 end |
|
1116 (*| mk_args2 (T as Type ("fun", _)) (params, ctxt) = |
|
1117 let |
|
1118 val (S, U) = strip_type T |
|
1119 in |
|
1120 if U = HOLogic.boolT then |
|
1121 (hd params, (tl params, ctxt)) |
|
1122 else |
|
1123 let |
|
1124 val ([x], ctxt') = Variable.variant_fixes ["x"] ctxt |
|
1125 in |
|
1126 (Free (x, T), (params, ctxt')) |
|
1127 end |
|
1128 end*) |
|
1129 | mk_args2 T (params, ctxt) = |
|
1130 let |
|
1131 val ([x], ctxt') = Variable.variant_fixes ["x"] ctxt |
|
1132 in |
|
1133 (Free (x, T), (params, ctxt')) |
|
1134 end |
|
1135 |
|
1136 fun mk_casesrule ctxt pred introrules = |
|
1137 let |
|
1138 (* TODO: can be simplified if parameters are not treated specially ? *) |
|
1139 val (((pred, params), intros_th), ctxt1) = import_intros pred introrules ctxt |
|
1140 (* TODO: distinct required ? -- test case with more than one parameter! *) |
|
1141 val params = distinct (op aconv) params |
|
1142 val intros = map prop_of intros_th |
|
1143 val ([propname], ctxt2) = Variable.variant_fixes ["thesis"] ctxt1 |
|
1144 val prop = HOLogic.mk_Trueprop (Free (propname, HOLogic.boolT)) |
|
1145 val argsT = binder_types (fastype_of pred) |
|
1146 (* TODO: can be simplified if parameters are not treated specially ? <-- see uncommented code! *) |
|
1147 val (argvs, _) = fold_map mk_args2 argsT (params, ctxt2) |
|
1148 fun mk_case intro = |
|
1149 let |
|
1150 val (_, args) = (strip_comb o HOLogic.dest_Trueprop o Logic.strip_imp_concl) intro |
|
1151 val prems = Logic.strip_imp_prems intro |
|
1152 val eqprems = |
|
1153 map2 (HOLogic.mk_Trueprop oo (curry HOLogic.mk_eq)) argvs args |
|
1154 val frees = map Free (fold Term.add_frees (args @ prems) []) |
|
1155 in fold Logic.all frees (Logic.list_implies (eqprems @ prems, prop)) end |
|
1156 val assm = HOLogic.mk_Trueprop (list_comb (pred, argvs)) |
|
1157 val cases = map mk_case intros |
|
1158 in Logic.list_implies (assm :: cases, prop) end; |
|
1159 |
|
1160 |
|
1161 (* unifying constants to have the same type variables *) |
|
1162 |
|
1163 fun unify_consts thy cs intr_ts = |
|
1164 (let |
|
1165 val add_term_consts_2 = fold_aterms (fn Const c => insert (op =) c | _ => I); |
|
1166 fun varify (t, (i, ts)) = |
|
1167 let val t' = map_types (Logic.incr_tvar (i + 1)) (#2 (Type.varify_global [] t)) |
|
1168 in (maxidx_of_term t', t'::ts) end; |
|
1169 val (i, cs') = List.foldr varify (~1, []) cs; |
|
1170 val (i', intr_ts') = List.foldr varify (i, []) intr_ts; |
|
1171 val rec_consts = fold add_term_consts_2 cs' []; |
|
1172 val intr_consts = fold add_term_consts_2 intr_ts' []; |
|
1173 fun unify (cname, cT) = |
|
1174 let val consts = map snd (filter (fn c => fst c = cname) intr_consts) |
|
1175 in fold (Sign.typ_unify thy) ((replicate (length consts) cT) ~~ consts) end; |
|
1176 val (env, _) = fold unify rec_consts (Vartab.empty, i'); |
|
1177 val subst = map_types (Envir.norm_type env) |
|
1178 in (map subst cs', map subst intr_ts') |
|
1179 end) handle Type.TUNIFY => |
|
1180 (warning "Occurrences of recursive constant have non-unifiable types"; (cs, intr_ts)); |
|
1181 |
|
1182 (* preprocessing rules *) |
|
1183 |
|
1184 fun Trueprop_conv cv ct = |
|
1185 case Thm.term_of ct of |
|
1186 Const (@{const_name Trueprop}, _) $ _ => Conv.arg_conv cv ct |
|
1187 | _ => raise Fail "Trueprop_conv" |
|
1188 |
|
1189 fun preprocess_equality thy rule = |
|
1190 Conv.fconv_rule |
|
1191 (imp_prems_conv |
|
1192 (Trueprop_conv (Conv.try_conv (Conv.rewr_conv (Thm.symmetric @{thm Predicate.eq_is_eq}))))) |
|
1193 (Thm.transfer thy rule) |
|
1194 |
|
1195 fun preprocess_intro thy = expand_tuples thy #> preprocess_equality thy |
|
1196 |
1051 (* defining a quickcheck predicate *) |
1197 (* defining a quickcheck predicate *) |
1052 |
1198 |
1053 fun strip_imp_prems (Const(@{const_name HOL.implies}, _) $ A $ B) = A :: strip_imp_prems B |
1199 fun strip_imp_prems (Const(@{const_name HOL.implies}, _) $ A $ B) = A :: strip_imp_prems B |
1054 | strip_imp_prems _ = []; |
1200 | strip_imp_prems _ = []; |
1055 |
1201 |