54 end; |
50 end; |
55 |
51 |
56 |
52 |
57 signature ISTUPLE_SUPPORT = |
53 signature ISTUPLE_SUPPORT = |
58 sig |
54 sig |
59 val add_istuple_type: bstring * string list -> (typ * typ) -> theory -> term * term * theory |
55 val add_istuple_type: bstring * string list -> typ * typ -> theory -> (term * term) * theory |
60 |
|
61 val mk_cons_tuple: term * term -> term |
56 val mk_cons_tuple: term * term -> term |
62 val dest_cons_tuple: term -> term * term |
57 val dest_cons_tuple: term -> term * term |
63 |
58 val istuple_intros_tac: int -> tactic |
64 val istuple_intros_tac: theory -> int -> tactic |
|
65 |
|
66 val named_cterm_instantiate: (string * cterm) list -> thm -> thm |
59 val named_cterm_instantiate: (string * cterm) list -> thm -> thm |
67 end; |
60 end; |
68 |
61 |
69 structure IsTupleSupport: ISTUPLE_SUPPORT = |
62 structure IsTupleSupport: ISTUPLE_SUPPORT = |
70 struct |
63 struct |
71 |
64 |
72 val isomN = "_TupleIsom"; |
65 val isomN = "_TupleIsom"; |
73 val defN = "_def"; |
66 |
74 |
67 val istuple_intro = @{thm isomorphic_tuple_intro}; |
75 val istuple_UNIV_I = @{thm "istuple_UNIV_I"}; |
68 val istuple_intros = Tactic.build_net @{thms isomorphic_tuple.intros}; |
76 val istuple_True_simp = @{thm "istuple_True_simp"}; |
69 |
77 |
70 val tuple_istuple = (@{const_name tuple_istuple}, @{thm tuple_istuple}); |
78 val istuple_intro = @{thm "isomorphic_tuple_intro"}; |
|
79 val istuple_intros = build_net (@{thms "isomorphic_tuple.intros"}); |
|
80 |
|
81 val constname = fst o dest_Const; |
|
82 val tuple_istuple = (constname @{term tuple_istuple}, @{thm tuple_istuple}); |
|
83 |
|
84 val istuple_constN = constname @{term isomorphic_tuple}; |
|
85 val istuple_consN = constname @{term istuple_cons}; |
|
86 |
|
87 val tup_isom_typeN = fst (dest_Type @{typ "('a, 'b, 'c) tuple_isomorphism"}); |
|
88 |
71 |
89 fun named_cterm_instantiate values thm = |
72 fun named_cterm_instantiate values thm = |
90 let |
73 let |
91 fun match name ((name', _), _) = name = name' |
74 fun match name ((name', _), _) = name = name' |
92 | match name _ = false; |
75 | match name _ = false; |
109 |
92 |
110 fun do_typedef name repT alphas thy = |
93 fun do_typedef name repT alphas thy = |
111 let |
94 let |
112 fun get_thms thy name = |
95 fun get_thms thy name = |
113 let |
96 let |
114 val SOME { Rep_inject=rep_inject, Abs_name=absN, abs_type=absT, |
97 val SOME {Rep_inject = rep_inject, Abs_name = absN, abs_type = absT, |
115 Abs_inverse=abs_inverse, ...} = Typedef.get_info thy name; |
98 Abs_inverse = abs_inverse, ...} = Typedef.get_info thy name; |
116 val rewrite_rule = MetaSimplifier.rewrite_rule [istuple_UNIV_I, istuple_True_simp]; |
99 val rewrite_rule = |
117 in (map rewrite_rule [rep_inject, abs_inverse], |
100 MetaSimplifier.rewrite_rule [@{thm istuple_UNIV_I}, @{thm istuple_True_simp}]; |
118 Const (absN, repT --> absT), absT) end; |
101 in |
|
102 (map rewrite_rule [rep_inject, abs_inverse], Const (absN, repT --> absT), absT) |
|
103 end; |
119 in |
104 in |
120 thy |
105 thy |
121 |> Typecopy.typecopy (Binding.name name, alphas) repT NONE |
106 |> Typecopy.typecopy (Binding.name name, alphas) repT NONE |
122 |-> (fn (name, _) => `(fn thy => get_thms thy name)) |
107 |-> (fn (name, _) => `(fn thy => get_thms thy name)) |
123 end; |
108 end; |
124 |
109 |
125 fun mk_cons_tuple (left, right) = |
110 fun mk_cons_tuple (left, right) = |
126 let |
111 let |
127 val (leftT, rightT) = (fastype_of left, fastype_of right); |
112 val (leftT, rightT) = (fastype_of left, fastype_of right); |
128 val prodT = HOLogic.mk_prodT (leftT, rightT); |
113 val prodT = HOLogic.mk_prodT (leftT, rightT); |
129 val isomT = Type (tup_isom_typeN, [prodT, leftT, rightT]); |
114 val isomT = Type (@{type_name tuple_isomorphism}, [prodT, leftT, rightT]); |
130 in |
115 in |
131 Const (istuple_consN, isomT --> leftT --> rightT --> prodT) $ |
116 Const (@{const_name istuple_cons}, isomT --> leftT --> rightT --> prodT) $ |
132 Const (fst tuple_istuple, isomT) $ left $ right |
117 Const (fst tuple_istuple, isomT) $ left $ right |
133 end; |
118 end; |
134 |
119 |
135 fun dest_cons_tuple (v as Const (ic, _) $ Const _ $ left $ right) = |
120 fun dest_cons_tuple (Const (@{const_name istuple_cons}, _) $ Const _ $ t $ u) = (t, u) |
136 if ic = istuple_consN then (left, right) |
121 | dest_cons_tuple t = raise TERM ("dest_cons_tuple", [t]); |
137 else raise TERM ("dest_cons_tuple", [v]) |
|
138 | dest_cons_tuple v = raise TERM ("dest_cons_tuple", [v]); |
|
139 |
122 |
140 fun add_istuple_type (name, alphas) (leftT, rightT) thy = |
123 fun add_istuple_type (name, alphas) (leftT, rightT) thy = |
141 let |
124 let |
142 val repT = HOLogic.mk_prodT (leftT, rightT); |
125 val repT = HOLogic.mk_prodT (leftT, rightT); |
143 |
126 |
151 val intro_inst = |
134 val intro_inst = |
152 rep_inject RS named_cterm_instantiate [("abst", cterm_of typ_thy absC)] istuple_intro; |
135 rep_inject RS named_cterm_instantiate [("abst", cterm_of typ_thy absC)] istuple_intro; |
153 val (_, body) = Logic.dest_equals (List.last (prems_of intro_inst)); |
136 val (_, body) = Logic.dest_equals (List.last (prems_of intro_inst)); |
154 val isomT = fastype_of body; |
137 val isomT = fastype_of body; |
155 val isom_bind = Binding.name (name ^ isomN); |
138 val isom_bind = Binding.name (name ^ isomN); |
156 val isom = Const (Sign.full_name typ_thy isom_bind, isomT); |
139 val isom_name = Sign.full_name typ_thy isom_bind; |
157 val isom_spec = (name ^ isomN ^ defN, Logic.mk_equals (isom, body)); |
140 val isom = Const (isom_name, isomT); |
|
141 val isom_spec = (Thm.def_name (name ^ isomN), Logic.mk_equals (isom, body)); |
158 |
142 |
159 val ([isom_def], cdef_thy) = |
143 val ([isom_def], cdef_thy) = |
160 typ_thy |
144 typ_thy |
161 |> Sign.add_consts_i [Syntax.no_syn (isom_bind, isomT)] |
145 |> Sign.add_consts_i [Syntax.no_syn (isom_bind, isomT)] |
162 |> PureThy.add_defs false [Thm.no_attributes (apfst Binding.name isom_spec)]; |
146 |> PureThy.add_defs false [Thm.no_attributes (apfst Binding.name isom_spec)]; |
163 |
147 |
164 val istuple = isom_def RS (abs_inverse RS (rep_inject RS istuple_intro)); |
148 val istuple = isom_def RS (abs_inverse RS (rep_inject RS istuple_intro)); |
165 val cons = Const (istuple_consN, isomT --> leftT --> rightT --> absT); |
149 val cons = Const (@{const_name istuple_cons}, isomT --> leftT --> rightT --> absT); |
166 |
150 |
167 val thm_thy = |
151 val thm_thy = |
168 cdef_thy |
152 cdef_thy |
169 |> IsTupleThms.map (Symtab.insert Thm.eq_thm_prop (constname isom, istuple)) |
153 |> IsTupleThms.map (Symtab.insert Thm.eq_thm_prop (isom_name, istuple)) |
170 |> Sign.parent_path; |
154 |> Sign.parent_path; |
171 in |
155 in |
172 (isom, cons $ isom, thm_thy) |
156 ((isom, cons $ isom), thm_thy) |
173 end; |
157 end; |
174 |
158 |
175 fun istuple_intros_tac thy = |
159 val istuple_intros_tac = resolve_from_net_tac istuple_intros THEN' |
176 let |
160 CSUBGOAL (fn (cgoal, i) => |
177 val isthms = IsTupleThms.get thy; |
161 let |
178 fun err s t = raise TERM ("istuple_intros_tac: " ^ s, [t]); |
162 val thy = Thm.theory_of_cterm cgoal; |
179 val use_istuple_thm_tac = SUBGOAL (fn (goal, n) => |
163 val goal = Thm.term_of cgoal; |
180 let |
164 |
181 val goal' = Envir.beta_eta_contract goal; |
165 val isthms = IsTupleThms.get thy; |
182 val isom = |
166 fun err s t = raise TERM ("istuple_intros_tac: " ^ s, [t]); |
183 (case goal' of |
167 |
184 Const tp $ (Const pr $ Const is) => |
168 val goal' = Envir.beta_eta_contract goal; |
185 if fst tp = "Trueprop" andalso fst pr = istuple_constN |
169 val is = |
186 then Const is |
170 (case goal' of |
187 else err "unexpected goal predicate" goal' |
171 Const (@{const_name Trueprop}, _) $ |
188 | _ => err "unexpected goal format" goal'); |
172 (Const (@{const_name isomorphic_tuple}, _) $ Const is) => is |
189 val isthm = |
173 | _ => err "unexpected goal format" goal'); |
190 (case Symtab.lookup isthms (constname isom) of |
174 val isthm = |
191 SOME isthm => isthm |
175 (case Symtab.lookup isthms (#1 is) of |
192 | NONE => err "no thm found for constant" isom); |
176 SOME isthm => isthm |
193 in rtac isthm n end); |
177 | NONE => err "no thm found for constant" (Const is)); |
194 in |
178 in rtac isthm i end); |
195 fn n => resolve_from_net_tac istuple_intros n THEN use_istuple_thm_tac n |
|
196 end; |
|
197 |
179 |
198 end; |
180 end; |
199 |
181 |
200 |
182 |
201 structure Record: RECORD = |
183 structure Record: RECORD = |
324 (case try (unsuffix ext_typeN) c_ext_type of |
302 (case try (unsuffix ext_typeN) c_ext_type of |
325 NONE => raise TYPE ("Record.dest_recT", [typ], []) |
303 NONE => raise TYPE ("Record.dest_recT", [typ], []) |
326 | SOME c => ((c, Ts), List.last Ts)) |
304 | SOME c => ((c, Ts), List.last Ts)) |
327 | dest_recT typ = raise TYPE ("Record.dest_recT", [typ], []); |
305 | dest_recT typ = raise TYPE ("Record.dest_recT", [typ], []); |
328 |
306 |
329 fun is_recT T = |
307 val is_recT = can dest_recT; |
330 (case try dest_recT T of NONE => false | SOME _ => true); |
|
331 |
308 |
332 fun dest_recTs T = |
309 fun dest_recTs T = |
333 let val ((c, Ts), U) = dest_recT T |
310 let val ((c, Ts), U) = dest_recT T |
334 in (c, Ts) :: dest_recTs U |
311 in (c, Ts) :: dest_recTs U |
335 end handle TYPE _ => []; |
312 end handle TYPE _ => []; |
1031 |
1008 |
1032 |
1009 |
1033 |
1010 |
1034 (** record simprocs **) |
1011 (** record simprocs **) |
1035 |
1012 |
1036 val record_quick_and_dirty_sensitive = Unsynchronized.ref false; |
|
1037 |
|
1038 |
|
1039 fun quick_and_dirty_prove stndrd thy asms prop tac = |
1013 fun quick_and_dirty_prove stndrd thy asms prop tac = |
1040 if ! record_quick_and_dirty_sensitive andalso ! quick_and_dirty then |
1014 if ! quick_and_dirty then |
1041 Goal.prove (ProofContext.init thy) [] [] |
1015 Goal.prove (ProofContext.init thy) [] [] |
1042 (Logic.list_implies (map Logic.varify asms, Logic.varify prop)) |
1016 (Logic.list_implies (map Logic.varify asms, Logic.varify prop)) |
1043 (K (SkipProof.cheat_tac @{theory HOL})) |
1017 (K (Skip_Proof.cheat_tac @{theory HOL})) |
1044 (*Drule.standard can take quite a while for large records, thats why |
1018 (*Drule.standard can take quite a while for large records, thats why |
1045 we varify the proposition manually here.*) |
1019 we varify the proposition manually here.*) |
1046 else |
1020 else |
1047 let val prf = Goal.prove (ProofContext.init thy) [] asms prop tac |
1021 let val prf = Goal.prove (ProofContext.init thy) [] asms prop tac |
1048 in if stndrd then standard prf else prf end; |
1022 in if stndrd then Drule.standard prf else prf end; |
1049 |
1023 |
1050 fun quick_and_dirty_prf noopt opt () = |
1024 fun quick_and_dirty_prf noopt opt () = |
1051 if ! record_quick_and_dirty_sensitive andalso ! quick_and_dirty |
1025 if ! quick_and_dirty then noopt () else opt (); |
1052 then noopt () |
|
1053 else opt (); |
|
1054 |
1026 |
1055 fun is_sel_upd_pair thy (Const (s, _)) (Const (u, t')) = |
1027 fun is_sel_upd_pair thy (Const (s, _)) (Const (u, t')) = |
1056 (case get_updates thy u of |
1028 (case get_updates thy u of |
1057 SOME u_name => u_name = s |
1029 SOME u_name => u_name = s |
1058 | NONE => raise TERM ("is_sel_upd_pair: not update", [Const (u, t')])); |
1030 | NONE => raise TERM ("is_sel_upd_pair: not update", [Const (u, t')])); |
1059 |
1031 |
1060 fun mk_comp f g = |
1032 fun mk_comp f g = |
1061 let |
1033 let |
1062 val x = fastype_of g; |
1034 val X = fastype_of g; |
1063 val a = domain_type x; |
1035 val A = domain_type X; |
1064 val b = range_type x; |
1036 val B = range_type X; |
1065 val c = range_type (fastype_of f); |
1037 val C = range_type (fastype_of f); |
1066 val T = (b --> c) --> ((a --> b) --> (a --> c)) |
1038 val T = (B --> C) --> (A --> B) --> A --> C; |
1067 in Const ("Fun.comp", T) $ f $ g end; |
1039 in Const ("Fun.comp", T) $ f $ g end; |
1068 |
1040 |
1069 fun mk_comp_id f = |
1041 fun mk_comp_id f = |
1070 let val T = range_type (fastype_of f) |
1042 let val T = range_type (fastype_of f) |
1071 in mk_comp (Const ("Fun.id", T --> T)) f end; |
1043 in mk_comp (Const ("Fun.id", T --> T)) f end; |
1072 |
1044 |
1073 fun get_upd_funs (upd $ _ $ t) = upd :: get_upd_funs t |
1045 fun get_upd_funs (upd $ _ $ t) = upd :: get_upd_funs t |
1074 | get_upd_funs _ = []; |
1046 | get_upd_funs _ = []; |
1075 |
1047 |
1076 fun get_accupd_simps thy term defset intros_tac = |
1048 fun get_accupd_simps thy term defset = |
1077 let |
1049 let |
1078 val (acc, [body]) = strip_comb term; |
1050 val (acc, [body]) = strip_comb term; |
1079 val upd_funs = sort_distinct TermOrd.fast_term_ord (get_upd_funs body); |
1051 val upd_funs = sort_distinct TermOrd.fast_term_ord (get_upd_funs body); |
1080 fun get_simp upd = |
1052 fun get_simp upd = |
1081 let |
1053 let |
1087 else mk_comp_id acc; |
1059 else mk_comp_id acc; |
1088 val prop = lhs === rhs; |
1060 val prop = lhs === rhs; |
1089 val othm = |
1061 val othm = |
1090 Goal.prove (ProofContext.init thy) [] [] prop |
1062 Goal.prove (ProofContext.init thy) [] [] prop |
1091 (fn _ => |
1063 (fn _ => |
1092 EVERY |
1064 simp_tac defset 1 THEN |
1093 [simp_tac defset 1, |
1065 REPEAT_DETERM (IsTupleSupport.istuple_intros_tac 1) THEN |
1094 REPEAT_DETERM (intros_tac 1), |
1066 TRY (simp_tac (HOL_ss addsimps id_o_apps) 1)); |
1095 TRY (simp_tac (HOL_ss addsimps id_o_apps) 1)]); |
|
1096 val dest = |
1067 val dest = |
1097 if is_sel_upd_pair thy acc upd |
1068 if is_sel_upd_pair thy acc upd |
1098 then o_eq_dest |
1069 then o_eq_dest |
1099 else o_eq_id_dest; |
1070 else o_eq_id_dest; |
1100 in standard (othm RS dest) end; |
1071 in Drule.standard (othm RS dest) end; |
1101 in map get_simp upd_funs end; |
1072 in map get_simp upd_funs end; |
1102 |
1073 |
1103 fun get_updupd_simp thy defset intros_tac u u' comp = |
1074 fun get_updupd_simp thy defset u u' comp = |
1104 let |
1075 let |
1105 val f = Free ("f", domain_type (fastype_of u)); |
1076 val f = Free ("f", domain_type (fastype_of u)); |
1106 val f' = Free ("f'", domain_type (fastype_of u')); |
1077 val f' = Free ("f'", domain_type (fastype_of u')); |
1107 val lhs = mk_comp (u $ f) (u' $ f'); |
1078 val lhs = mk_comp (u $ f) (u' $ f'); |
1108 val rhs = |
1079 val rhs = |
1111 else mk_comp (u' $ f') (u $ f); |
1082 else mk_comp (u' $ f') (u $ f); |
1112 val prop = lhs === rhs; |
1083 val prop = lhs === rhs; |
1113 val othm = |
1084 val othm = |
1114 Goal.prove (ProofContext.init thy) [] [] prop |
1085 Goal.prove (ProofContext.init thy) [] [] prop |
1115 (fn _ => |
1086 (fn _ => |
1116 EVERY |
1087 simp_tac defset 1 THEN |
1117 [simp_tac defset 1, |
1088 REPEAT_DETERM (IsTupleSupport.istuple_intros_tac 1) THEN |
1118 REPEAT_DETERM (intros_tac 1), |
1089 TRY (simp_tac (HOL_ss addsimps [id_apply]) 1)); |
1119 TRY (simp_tac (HOL_ss addsimps [id_apply]) 1)]); |
|
1120 val dest = if comp then o_eq_dest_lhs else o_eq_dest; |
1090 val dest = if comp then o_eq_dest_lhs else o_eq_dest; |
1121 in standard (othm RS dest) end; |
1091 in Drule.standard (othm RS dest) end; |
1122 |
1092 |
1123 fun get_updupd_simps thy term defset intros_tac = |
1093 fun get_updupd_simps thy term defset = |
1124 let |
1094 let |
1125 val upd_funs = get_upd_funs term; |
1095 val upd_funs = get_upd_funs term; |
1126 val cname = fst o dest_Const; |
1096 val cname = fst o dest_Const; |
1127 fun getswap u u' = get_updupd_simp thy defset intros_tac u u' (cname u = cname u'); |
1097 fun getswap u u' = get_updupd_simp thy defset u u' (cname u = cname u'); |
1128 fun build_swaps_to_eq _ [] swaps = swaps |
1098 fun build_swaps_to_eq _ [] swaps = swaps |
1129 | build_swaps_to_eq upd (u :: us) swaps = |
1099 | build_swaps_to_eq upd (u :: us) swaps = |
1130 let |
1100 let |
1131 val key = (cname u, cname upd); |
1101 val key = (cname u, cname upd); |
1132 val newswaps = |
1102 val newswaps = |
1146 val named_cterm_instantiate = IsTupleSupport.named_cterm_instantiate; |
1116 val named_cterm_instantiate = IsTupleSupport.named_cterm_instantiate; |
1147 |
1117 |
1148 fun prove_unfold_defs thy ex_simps ex_simprs prop = |
1118 fun prove_unfold_defs thy ex_simps ex_simprs prop = |
1149 let |
1119 let |
1150 val defset = get_sel_upd_defs thy; |
1120 val defset = get_sel_upd_defs thy; |
1151 val in_tac = IsTupleSupport.istuple_intros_tac thy; |
|
1152 val prop' = Envir.beta_eta_contract prop; |
1121 val prop' = Envir.beta_eta_contract prop; |
1153 val (lhs, _) = Logic.dest_equals (Logic.strip_assums_concl prop'); |
1122 val (lhs, _) = Logic.dest_equals (Logic.strip_assums_concl prop'); |
1154 val (_, args) = strip_comb lhs; |
1123 val (_, args) = strip_comb lhs; |
1155 val simps = |
1124 val simps = (if length args = 1 then get_accupd_simps else get_updupd_simps) thy lhs defset; |
1156 if length args = 1 |
|
1157 then get_accupd_simps thy lhs defset in_tac |
|
1158 else get_updupd_simps thy lhs defset in_tac; |
|
1159 in |
1125 in |
1160 Goal.prove (ProofContext.init thy) [] [] prop' |
1126 Goal.prove (ProofContext.init thy) [] [] prop' |
1161 (fn _ => |
1127 (fn _ => |
1162 simp_tac (HOL_basic_ss addsimps (simps @ [K_record_comp])) 1 THEN |
1128 simp_tac (HOL_basic_ss addsimps (simps @ [K_record_comp])) 1 THEN |
1163 TRY (simp_tac (HOL_basic_ss addsimps ex_simps addsimprocs ex_simprs) 1)) |
1129 TRY (simp_tac (HOL_basic_ss addsimps ex_simps addsimprocs ex_simprs) 1)) |
1310 fun get_noop_simps (upd as Const _) (Abs (_, _, (acc as Const _) $ _)) = |
1273 fun get_noop_simps (upd as Const _) (Abs (_, _, (acc as Const _) $ _)) = |
1311 let |
1274 let |
1312 val ss = get_sel_upd_defs thy; |
1275 val ss = get_sel_upd_defs thy; |
1313 val uathm = get_upd_acc_cong_thm upd acc thy ss; |
1276 val uathm = get_upd_acc_cong_thm upd acc thy ss; |
1314 in |
1277 in |
1315 [standard (uathm RS updacc_noopE), standard (uathm RS updacc_noop_compE)] |
1278 [Drule.standard (uathm RS updacc_noopE), |
|
1279 Drule.standard (uathm RS updacc_noop_compE)] |
1316 end; |
1280 end; |
1317 |
1281 |
1318 (*If f is constant then (f o g) = f. we know that K_skeleton |
1282 (*If f is constant then (f o g) = f. We know that K_skeleton |
1319 only returns constant abstractions thus when we see an |
1283 only returns constant abstractions thus when we see an |
1320 abstraction we can discard inner updates.*) |
1284 abstraction we can discard inner updates.*) |
1321 fun add_upd (f as Abs _) fs = [f] |
1285 fun add_upd (f as Abs _) fs = [f] |
1322 | add_upd f fs = (f :: fs); |
1286 | add_upd f fs = (f :: fs); |
1323 |
1287 |
1480 P can peek on the whole subterm (including the quantifier); for free variables P |
1444 P can peek on the whole subterm (including the quantifier); for free variables P |
1481 can only peek on the variable itself. |
1445 can only peek on the variable itself. |
1482 P t = 0: do not split |
1446 P t = 0: do not split |
1483 P t = ~1: completely split |
1447 P t = ~1: completely split |
1484 P t > 0: split up to given bound of record extensions.*) |
1448 P t > 0: split up to given bound of record extensions.*) |
1485 fun record_split_simp_tac thms P i st = |
1449 fun record_split_simp_tac thms P = CSUBGOAL (fn (cgoal, i) => |
1486 let |
1450 let |
1487 val thy = Thm.theory_of_thm st; |
1451 val thy = Thm.theory_of_cterm cgoal; |
|
1452 |
|
1453 val goal = term_of cgoal; |
|
1454 val frees = filter (is_recT o #2) (Term.add_frees goal []); |
1488 |
1455 |
1489 val has_rec = exists_Const |
1456 val has_rec = exists_Const |
1490 (fn (s, Type (_, [Type (_, [T, _]), _])) => |
1457 (fn (s, Type (_, [Type (_, [T, _]), _])) => |
1491 (s = "all" orelse s = "All" orelse s = "Ex") andalso is_recT T |
1458 (s = "all" orelse s = "All" orelse s = "Ex") andalso is_recT T |
1492 | _ => false); |
1459 | _ => false); |
1493 |
|
1494 val goal = nth (Thm.prems_of st) (i - 1); (* FIXME SUBGOAL *) |
|
1495 val frees = filter (is_recT o type_of) (OldTerm.term_frees goal); |
|
1496 |
1460 |
1497 fun mk_split_free_tac free induct_thm i = |
1461 fun mk_split_free_tac free induct_thm i = |
1498 let |
1462 let |
1499 val cfree = cterm_of thy free; |
1463 val cfree = cterm_of thy free; |
1500 val _$ (_ $ r) = concl_of induct_thm; |
1464 val _$ (_ $ r) = concl_of induct_thm; |
1501 val crec = cterm_of thy r; |
1465 val crec = cterm_of thy r; |
1502 val thm = cterm_instantiate [(crec, cfree)] induct_thm; |
1466 val thm = cterm_instantiate [(crec, cfree)] induct_thm; |
1503 in |
1467 in |
1504 EVERY |
1468 simp_tac (HOL_basic_ss addsimps @{thms induct_atomize}) i THEN |
1505 [simp_tac (HOL_basic_ss addsimps @{thms induct_atomize}) i, |
1469 rtac thm i THEN |
1506 rtac thm i, |
1470 simp_tac (HOL_basic_ss addsimps @{thms induct_rulify}) i |
1507 simp_tac (HOL_basic_ss addsimps @{thms induct_rulify}) i] |
|
1508 end; |
1471 end; |
1509 |
1472 |
1510 fun split_free_tac P i (free as Free (_, T)) = |
1473 val split_frees_tacs = |
1511 (case rec_id ~1 T of |
1474 frees |> map_filter (fn (x, T) => |
1512 "" => NONE |
1475 (case rec_id ~1 T of |
1513 | _ => |
1476 "" => NONE |
1514 let val split = P free in |
1477 | _ => |
1515 if split <> 0 then |
1478 let |
1516 (case get_splits thy (rec_id split T) of |
1479 val free = Free (x, T); |
1517 NONE => NONE |
1480 val split = P free; |
1518 | SOME (_, _, _, induct_thm) => |
1481 in |
1519 SOME (mk_split_free_tac free induct_thm i)) |
1482 if split <> 0 then |
1520 else NONE |
1483 (case get_splits thy (rec_id split T) of |
1521 end) |
1484 NONE => NONE |
1522 | split_free_tac _ _ _ = NONE; |
1485 | SOME (_, _, _, induct_thm) => |
1523 |
1486 SOME (mk_split_free_tac free induct_thm i)) |
1524 val split_frees_tacs = map_filter (split_free_tac P i) frees; |
1487 else NONE |
|
1488 end)); |
1525 |
1489 |
1526 val simprocs = if has_rec goal then [record_split_simproc P] else []; |
1490 val simprocs = if has_rec goal then [record_split_simproc P] else []; |
1527 val thms' = K_comp_convs @ thms; |
1491 val thms' = K_comp_convs @ thms; |
1528 in |
1492 in |
1529 st |> |
1493 EVERY split_frees_tacs THEN |
1530 (EVERY split_frees_tacs THEN |
1494 Simplifier.full_simp_tac (get_simpset thy addsimps thms' addsimprocs simprocs) i |
1531 Simplifier.full_simp_tac (get_simpset thy addsimps thms' addsimprocs simprocs) i) |
1495 end); |
1532 end handle Empty => Seq.empty; |
|
1533 |
1496 |
1534 |
1497 |
1535 (* record_split_tac *) |
1498 (* record_split_tac *) |
1536 |
1499 |
1537 (*Split all records in the goal, which are quantified by ! or !!.*) |
1500 (*Split all records in the goal, which are quantified by ! or !!.*) |
1538 fun record_split_tac i st = |
1501 val record_split_tac = CSUBGOAL (fn (cgoal, i) => |
1539 let |
1502 let |
|
1503 val goal = term_of cgoal; |
|
1504 |
1540 val has_rec = exists_Const |
1505 val has_rec = exists_Const |
1541 (fn (s, Type (_, [Type (_, [T, _]), _])) => |
1506 (fn (s, Type (_, [Type (_, [T, _]), _])) => |
1542 (s = "all" orelse s = "All") andalso is_recT T |
1507 (s = "all" orelse s = "All") andalso is_recT T |
1543 | _ => false); |
1508 | _ => false); |
1544 |
|
1545 val goal = nth (Thm.prems_of st) (i - 1); (* FIXME SUBGOAL *) |
|
1546 |
1509 |
1547 fun is_all t = |
1510 fun is_all t = |
1548 (case t of |
1511 (case t of |
1549 Const (quantifier, _) $ _ => |
1512 Const (quantifier, _) $ _ => |
1550 if quantifier = "All" orelse quantifier = "all" then ~1 else 0 |
1513 if quantifier = "All" orelse quantifier = "all" then ~1 else 0 |
1551 | _ => 0); |
1514 | _ => 0); |
1552 |
|
1553 in |
1515 in |
1554 if has_rec goal then |
1516 if has_rec goal then |
1555 Simplifier.full_simp_tac |
1517 Simplifier.full_simp_tac (HOL_basic_ss addsimprocs [record_split_simproc is_all]) i |
1556 (HOL_basic_ss addsimprocs [record_split_simproc is_all]) i st |
1518 else no_tac |
1557 else Seq.empty |
1519 end); |
1558 end handle Subscript => Seq.empty; (* FIXME SUBGOAL *) |
|
1559 |
1520 |
1560 |
1521 |
1561 (* wrapper *) |
1522 (* wrapper *) |
1562 |
1523 |
1563 val record_split_name = "record_split_tac"; |
1524 val record_split_name = "record_split_tac"; |
1603 |
1564 |
1604 (*Do case analysis / induction according to rule on last parameter of ith subgoal |
1565 (*Do case analysis / induction according to rule on last parameter of ith subgoal |
1605 (or on s if there are no parameters). |
1566 (or on s if there are no parameters). |
1606 Instatiation of record variable (and predicate) in rule is calculated to |
1567 Instatiation of record variable (and predicate) in rule is calculated to |
1607 avoid problems with higher order unification.*) |
1568 avoid problems with higher order unification.*) |
1608 fun try_param_tac s rule i st = |
1569 fun try_param_tac s rule = CSUBGOAL (fn (cgoal, i) => |
1609 let |
1570 let |
1610 val cert = cterm_of (Thm.theory_of_thm st); |
1571 val cert = Thm.cterm_of (Thm.theory_of_cterm cgoal); |
1611 val g = nth (prems_of st) (i - 1); (* FIXME SUBGOAL *) |
1572 |
|
1573 val g = Thm.term_of cgoal; |
1612 val params = Logic.strip_params g; |
1574 val params = Logic.strip_params g; |
1613 val concl = HOLogic.dest_Trueprop (Logic.strip_assums_concl g); |
1575 val concl = HOLogic.dest_Trueprop (Logic.strip_assums_concl g); |
1614 val rule' = Thm.lift_rule (Thm.cprem_of st i) rule; |
1576 val rule' = Thm.lift_rule cgoal rule; |
1615 val (P, ys) = strip_comb (HOLogic.dest_Trueprop |
1577 val (P, ys) = strip_comb (HOLogic.dest_Trueprop |
1616 (Logic.strip_assums_concl (prop_of rule'))); |
1578 (Logic.strip_assums_concl (prop_of rule'))); |
1617 (*ca indicates if rule is a case analysis or induction rule*) |
1579 (*ca indicates if rule is a case analysis or induction rule*) |
1618 val (x, ca) = |
1580 val (x, ca) = |
1619 (case rev (Library.drop (length params, ys)) of |
1581 (case rev (Library.drop (length params, ys)) of |
1620 [] => (head_of (fst (HOLogic.dest_eq (HOLogic.dest_Trueprop |
1582 [] => (head_of (fst (HOLogic.dest_eq (HOLogic.dest_Trueprop |
1621 (hd (rev (Logic.strip_assums_hyp (hd (prems_of rule')))))))), true) |
1583 (hd (rev (Logic.strip_assums_hyp (hd (prems_of rule')))))))), true) |
1622 | [x] => (head_of x, false)); |
1584 | [x] => (head_of x, false)); |
1623 val rule'' = cterm_instantiate (map (pairself cert) |
1585 val rule'' = cterm_instantiate (map (pairself cert) |
1624 (case (rev params) of |
1586 (case rev params of |
1625 [] => |
1587 [] => |
1626 (case AList.lookup (op =) (map dest_Free (OldTerm.term_frees (prop_of st))) s of |
1588 (case AList.lookup (op =) (Term.add_frees g []) s of |
1627 NONE => sys_error "try_param_tac: no such variable" |
1589 NONE => sys_error "try_param_tac: no such variable" |
1628 | SOME T => [(P, if ca then concl else lambda (Free (s, T)) concl), (x, Free (s, T))]) |
1590 | SOME T => [(P, if ca then concl else lambda (Free (s, T)) concl), (x, Free (s, T))]) |
1629 | (_, T) :: _ => |
1591 | (_, T) :: _ => |
1630 [(P, list_abs (params, if ca then concl else incr_boundvars 1 (Abs (s, T, concl)))), |
1592 [(P, list_abs (params, if ca then concl else incr_boundvars 1 (Abs (s, T, concl)))), |
1631 (x, list_abs (params, Bound 0))])) rule'; |
1593 (x, list_abs (params, Bound 0))])) rule'; |
1632 in compose_tac (false, rule'', nprems_of rule) i st end; |
1594 in compose_tac (false, rule'', nprems_of rule) i end); |
1633 |
1595 |
1634 |
1596 |
1635 fun extension_definition name fields alphas zeta moreT more vars thy = |
1597 fun extension_definition name fields alphas zeta moreT more vars thy = |
1636 let |
1598 let |
1637 val base = Long_Name.base_name; |
1599 val base = Long_Name.base_name; |
1638 val fieldTs = (map snd fields); |
1600 val fieldTs = map snd fields; |
1639 val alphas_zeta = alphas @ [zeta]; |
1601 val alphas_zeta = alphas @ [zeta]; |
1640 val alphas_zetaTs = map (fn n => TFree (n, HOLogic.typeS)) alphas_zeta; |
1602 val alphas_zetaTs = map (fn a => TFree (a, HOLogic.typeS)) alphas_zeta; |
1641 val extT_name = suffix ext_typeN name |
1603 val extT_name = suffix ext_typeN name |
1642 val extT = Type (extT_name, alphas_zetaTs); |
1604 val extT = Type (extT_name, alphas_zetaTs); |
1643 val fields_moreTs = fieldTs @ [moreT]; |
1605 val fields_moreTs = fieldTs @ [moreT]; |
1644 |
1606 |
1645 |
1607 |
1650 |
1612 |
1651 fun mk_istuple (left, right) (thy, i) = |
1613 fun mk_istuple (left, right) (thy, i) = |
1652 let |
1614 let |
1653 val suff = if i = 0 then ext_typeN else inner_typeN ^ string_of_int i; |
1615 val suff = if i = 0 then ext_typeN else inner_typeN ^ string_of_int i; |
1654 val nm = suffix suff (Long_Name.base_name name); |
1616 val nm = suffix suff (Long_Name.base_name name); |
1655 val (_, cons, thy') = |
1617 val ((_, cons), thy') = |
1656 IsTupleSupport.add_istuple_type |
1618 IsTupleSupport.add_istuple_type |
1657 (nm, alphas_zeta) (fastype_of left, fastype_of right) thy; |
1619 (nm, alphas_zeta) (fastype_of left, fastype_of right) thy; |
1658 in |
1620 in |
1659 (cons $ left $ right, (thy', i + 1)) |
1621 (cons $ left $ right, (thy', i + 1)) |
1660 end; |
1622 end; |
1715 val vars_more = vars @ [more]; |
1677 val vars_more = vars @ [more]; |
1716 val variants = map (fn Free (x, _) => x) vars_more; |
1678 val variants = map (fn Free (x, _) => x) vars_more; |
1717 val ext = mk_ext vars_more; |
1679 val ext = mk_ext vars_more; |
1718 val s = Free (rN, extT); |
1680 val s = Free (rN, extT); |
1719 val P = Free (Name.variant variants "P", extT --> HOLogic.boolT); |
1681 val P = Free (Name.variant variants "P", extT --> HOLogic.boolT); |
1720 val intros_tac = IsTupleSupport.istuple_intros_tac defs_thy; |
|
1721 |
1682 |
1722 val inject_prop = |
1683 val inject_prop = |
1723 let val vars_more' = map (fn (Free (x, T)) => Free (x ^ "'", T)) vars_more in |
1684 let val vars_more' = map (fn (Free (x, T)) => Free (x ^ "'", T)) vars_more in |
1724 HOLogic.mk_conj (HOLogic.eq_const extT $ |
1685 HOLogic.mk_conj (HOLogic.eq_const extT $ |
1725 mk_ext vars_more $ mk_ext vars_more', HOLogic.true_const) |
1686 mk_ext vars_more $ mk_ext vars_more', HOLogic.true_const) |
1741 |
1702 |
1742 fun inject_prf () = |
1703 fun inject_prf () = |
1743 simplify HOL_ss |
1704 simplify HOL_ss |
1744 (prove_standard [] inject_prop |
1705 (prove_standard [] inject_prop |
1745 (fn _ => |
1706 (fn _ => |
1746 EVERY |
1707 simp_tac (HOL_basic_ss addsimps [ext_def]) 1 THEN |
1747 [simp_tac (HOL_basic_ss addsimps [ext_def]) 1, |
1708 REPEAT_DETERM |
1748 REPEAT_DETERM (resolve_tac [refl_conj_eq] 1 ORELSE |
1709 (rtac refl_conj_eq 1 ORELSE |
1749 intros_tac 1 ORELSE |
1710 IsTupleSupport.istuple_intros_tac 1 ORELSE |
1750 resolve_tac [refl] 1)])); |
1711 rtac refl 1))); |
1751 |
1712 |
1752 val inject = timeit_msg "record extension inject proof:" inject_prf; |
1713 val inject = timeit_msg "record extension inject proof:" inject_prf; |
1753 |
1714 |
1754 (*We need a surjection property r = (| f = f r, g = g r ... |) |
1715 (*We need a surjection property r = (| f = f r, g = g r ... |) |
1755 to prove other theorems. We haven't given names to the accessors |
1716 to prove other theorems. We haven't given names to the accessors |
1756 f, g etc yet however, so we generate an ext structure with |
1717 f, g etc yet however, so we generate an ext structure with |
1757 free variables as all arguments and allow the introduction tactic to |
1718 free variables as all arguments and allow the introduction tactic to |
1758 operate on it as far as it can. We then use standard to convert |
1719 operate on it as far as it can. We then use Drule.standard to convert |
1759 the free variables into unifiable variables and unify them with |
1720 the free variables into unifiable variables and unify them with |
1760 (roughly) the definition of the accessor.*) |
1721 (roughly) the definition of the accessor.*) |
1761 fun surject_prf () = |
1722 fun surject_prf () = |
1762 let |
1723 let |
1763 val cterm_ext = cterm_of defs_thy ext; |
1724 val cterm_ext = cterm_of defs_thy ext; |
1764 val start = named_cterm_instantiate [("y", cterm_ext)] surject_assist_idE; |
1725 val start = named_cterm_instantiate [("y", cterm_ext)] surject_assist_idE; |
1765 val tactic1 = |
1726 val tactic1 = |
1766 simp_tac (HOL_basic_ss addsimps [ext_def]) 1 THEN |
1727 simp_tac (HOL_basic_ss addsimps [ext_def]) 1 THEN |
1767 REPEAT_ALL_NEW intros_tac 1; |
1728 REPEAT_ALL_NEW IsTupleSupport.istuple_intros_tac 1; |
1768 val tactic2 = REPEAT (rtac surject_assistI 1 THEN rtac refl 1); |
1729 val tactic2 = REPEAT (rtac surject_assistI 1 THEN rtac refl 1); |
1769 val [halfway] = Seq.list_of (tactic1 start); (* FIXME Seq.lift_of ?? *) |
1730 val [halfway] = Seq.list_of (tactic1 start); |
1770 val [surject] = Seq.list_of (tactic2 (standard halfway)); (* FIXME Seq.lift_of ?? *) |
1731 val [surject] = Seq.list_of (tactic2 (Drule.standard halfway)); |
1771 in |
1732 in |
1772 surject |
1733 surject |
1773 end; |
1734 end; |
1774 val surject = timeit_msg "record extension surjective proof:" surject_prf; |
1735 val surject = timeit_msg "record extension surjective proof:" surject_prf; |
1775 |
1736 |
1776 fun split_meta_prf () = |
1737 fun split_meta_prf () = |
1777 prove_standard [] split_meta_prop |
1738 prove_standard [] split_meta_prop |
1778 (fn _ => |
1739 (fn _ => |
1779 EVERY |
1740 EVERY1 |
1780 [rtac equal_intr_rule 1, Goal.norm_hhf_tac 1, |
1741 [rtac equal_intr_rule, Goal.norm_hhf_tac, |
1781 etac meta_allE 1, atac 1, |
1742 etac meta_allE, atac, |
1782 rtac (prop_subst OF [surject]) 1, |
1743 rtac (prop_subst OF [surject]), |
1783 REPEAT (etac meta_allE 1), atac 1]); |
1744 REPEAT o etac meta_allE, atac]); |
1784 val split_meta = timeit_msg "record extension split_meta proof:" split_meta_prf; |
1745 val split_meta = timeit_msg "record extension split_meta proof:" split_meta_prf; |
1785 |
1746 |
1786 fun induct_prf () = |
1747 fun induct_prf () = |
1787 let val (assm, concl) = induct_prop in |
1748 let val (assm, concl) = induct_prop in |
1788 prove_standard [assm] concl |
1749 prove_standard [assm] concl |
1789 (fn {prems, ...} => |
1750 (fn {prems, ...} => |
1790 EVERY |
1751 cut_rules_tac [split_meta RS Drule.equal_elim_rule2] 1 THEN |
1791 [cut_rules_tac [split_meta RS Drule.equal_elim_rule2] 1, |
1752 resolve_tac prems 2 THEN |
1792 resolve_tac prems 2, |
1753 asm_simp_tac HOL_ss 1) |
1793 asm_simp_tac HOL_ss 1]) |
|
1794 end; |
1754 end; |
1795 val induct = timeit_msg "record extension induct proof:" induct_prf; |
1755 val induct = timeit_msg "record extension induct proof:" induct_prf; |
1796 |
1756 |
1797 val ([inject', induct', surjective', split_meta'], thm_thy) = |
1757 val ([inject', induct', surjective', split_meta'], thm_thy) = |
1798 defs_thy |
1758 defs_thy |
1913 val extension_name = unsuffix ext_typeN (fst extension_scheme); |
1873 val extension_name = unsuffix ext_typeN (fst extension_scheme); |
1914 val extension = let val (n, Ts) = extension_scheme in (n, subst_last HOLogic.unitT Ts) end; |
1874 val extension = let val (n, Ts) = extension_scheme in (n, subst_last HOLogic.unitT Ts) end; |
1915 val extension_names = map (unsuffix ext_typeN o fst o #extension) parents @ [extN]; |
1875 val extension_names = map (unsuffix ext_typeN o fst o #extension) parents @ [extN]; |
1916 val extension_id = implode extension_names; |
1876 val extension_id = implode extension_names; |
1917 |
1877 |
1918 fun rec_schemeT n = mk_recordT (map #extension (prune n parents)) extT; |
1878 fun rec_schemeT n = mk_recordT (map #extension (Library.drop (n, parents))) extT; |
1919 val rec_schemeT0 = rec_schemeT 0; |
1879 val rec_schemeT0 = rec_schemeT 0; |
1920 |
1880 |
1921 fun recT n = |
1881 fun recT n = |
1922 let val (c, Ts) = extension |
1882 let val (c, Ts) = extension in |
1923 in mk_recordT (map #extension (prune n parents)) (Type (c, subst_last HOLogic.unitT Ts)) end; |
1883 mk_recordT (map #extension (Library.drop (n, parents))) |
|
1884 (Type (c, subst_last HOLogic.unitT Ts)) |
|
1885 end; |
1924 val recT0 = recT 0; |
1886 val recT0 = recT 0; |
1925 |
1887 |
1926 fun mk_rec args n = |
1888 fun mk_rec args n = |
1927 let |
1889 let |
1928 val (args', more) = chop_last args; |
1890 val (args', more) = chop_last args; |
1929 fun mk_ext' (((name, T), args), more) = mk_ext (name, T) (args @ [more]); |
1891 fun mk_ext' ((name, T), args) more = mk_ext (name, T) (args @ [more]); |
1930 fun build Ts = |
1892 fun build Ts = |
1931 List.foldr mk_ext' more (prune n (extension_names ~~ Ts ~~ (chunks parent_chunks args'))); |
1893 fold_rev mk_ext' (Library.drop (n, (extension_names ~~ Ts) ~~ chunks parent_chunks args')) |
|
1894 more; |
1932 in |
1895 in |
1933 if more = HOLogic.unit |
1896 if more = HOLogic.unit |
1934 then build (map recT (0 upto parent_len)) |
1897 then build (map recT (0 upto parent_len)) |
1935 else build (map rec_schemeT (0 upto parent_len)) |
1898 else build (map rec_schemeT (0 upto parent_len)) |
1936 end; |
1899 end; |
1982 val recordT_specs = |
1945 val recordT_specs = |
1983 [(Binding.name (suffix schemeN bname), alphas @ [zeta], rec_schemeT0, Syntax.NoSyn), |
1946 [(Binding.name (suffix schemeN bname), alphas @ [zeta], rec_schemeT0, Syntax.NoSyn), |
1984 (Binding.name bname, alphas, recT0, Syntax.NoSyn)]; |
1947 (Binding.name bname, alphas, recT0, Syntax.NoSyn)]; |
1985 |
1948 |
1986 val ext_defs = ext_def :: map #extdef parents; |
1949 val ext_defs = ext_def :: map #extdef parents; |
1987 val intros_tac = IsTupleSupport.istuple_intros_tac extension_thy; |
|
1988 |
1950 |
1989 (*Theorems from the istuple intros. |
1951 (*Theorems from the istuple intros. |
1990 This is complex enough to deserve a full comment. |
1952 This is complex enough to deserve a full comment. |
1991 By unfolding ext_defs from r_rec0 we create a tree of constructor |
1953 By unfolding ext_defs from r_rec0 we create a tree of constructor |
1992 calls (many of them Pair, but others as well). The introduction |
1954 calls (many of them Pair, but others as well). The introduction |
2009 val insts = [("v", cterm_rec), ("v'", cterm_vrs)]; |
1971 val insts = [("v", cterm_rec), ("v'", cterm_vrs)]; |
2010 val init_thm = named_cterm_instantiate insts updacc_eq_triv; |
1972 val init_thm = named_cterm_instantiate insts updacc_eq_triv; |
2011 val terminal = rtac updacc_eq_idI 1 THEN rtac refl 1; |
1973 val terminal = rtac updacc_eq_idI 1 THEN rtac refl 1; |
2012 val tactic = |
1974 val tactic = |
2013 simp_tac (HOL_basic_ss addsimps ext_defs) 1 THEN |
1975 simp_tac (HOL_basic_ss addsimps ext_defs) 1 THEN |
2014 REPEAT (intros_tac 1 ORELSE terminal); |
1976 REPEAT (IsTupleSupport.istuple_intros_tac 1 ORELSE terminal); |
2015 val updaccs = Seq.list_of (tactic init_thm); (* FIXME Seq.lift_of *) |
1977 val updaccs = Seq.list_of (tactic init_thm); |
2016 in |
1978 in |
2017 (updaccs RL [updacc_accessor_eqE], |
1979 (updaccs RL [updacc_accessor_eqE], |
2018 updaccs RL [updacc_updator_eqE], |
1980 updaccs RL [updacc_updator_eqE], |
2019 updaccs RL [updacc_cong_from_eq]) |
1981 updaccs RL [updacc_cong_from_eq]) |
2020 end; |
1982 end; |
2021 val (accessor_thms, updator_thms, upd_acc_cong_assists) = |
1983 val (accessor_thms, updator_thms, upd_acc_cong_assists) = |
2022 timeit_msg "record getting tree access/updates:" get_access_update_thms; |
1984 timeit_msg "record getting tree access/updates:" get_access_update_thms; |
2023 |
1985 |
2024 fun lastN xs = List.drop (xs, parent_fields_len); |
1986 fun lastN xs = Library.drop (parent_fields_len, xs); |
2025 |
1987 |
2026 (*selectors*) |
1988 (*selectors*) |
2027 fun mk_sel_spec ((c, T), thm) = |
1989 fun mk_sel_spec ((c, T), thm) = |
2028 let |
1990 let |
2029 val acc $ arg = |
1991 val acc $ arg = |
2133 let val P = Free (Name.variant all_variants "P", rec_schemeT0-->Term.propT) in |
2095 let val P = Free (Name.variant all_variants "P", rec_schemeT0-->Term.propT) in |
2134 Logic.mk_equals |
2096 Logic.mk_equals |
2135 (All [dest_Free r0] (P $ r0), All (map dest_Free all_vars_more) (P $ r_rec0)) |
2097 (All [dest_Free r0] (P $ r0), All (map dest_Free all_vars_more) (P $ r_rec0)) |
2136 end; |
2098 end; |
2137 |
2099 |
2138 (* FIXME eliminate old List.foldr *) |
|
2139 |
|
2140 val split_object_prop = |
2100 val split_object_prop = |
2141 let fun ALL vs t = List.foldr (fn ((v, T), t) => HOLogic.mk_all (v, T, t)) t vs |
2101 let val ALL = fold_rev (fn (v, T) => fn t => HOLogic.mk_all (v, T, t)) |
2142 in (ALL [dest_Free r0] (P $ r0)) === (ALL (map dest_Free all_vars_more) (P $ r_rec0)) end; |
2102 in ALL [dest_Free r0] (P $ r0) === ALL (map dest_Free all_vars_more) (P $ r_rec0) end; |
2143 |
2103 |
2144 val split_ex_prop = |
2104 val split_ex_prop = |
2145 let fun EX vs t = List.foldr (fn ((v, T), t) => HOLogic.mk_exists (v, T, t)) t vs |
2105 let val EX = fold_rev (fn (v, T) => fn t => HOLogic.mk_exists (v, T, t)) |
2146 in (EX [dest_Free r0] (P $ r0)) === (EX (map dest_Free all_vars_more) (P $ r_rec0)) end; |
2106 in EX [dest_Free r0] (P $ r0) === EX (map dest_Free all_vars_more) (P $ r_rec0) end; |
2147 |
2107 |
2148 (*equality*) |
2108 (*equality*) |
2149 val equality_prop = |
2109 val equality_prop = |
2150 let |
2110 let |
2151 val s' = Free (rN ^ "'", rec_schemeT0); |
2111 val s' = Free (rN ^ "'", rec_schemeT0); |
2166 val ss = get_simpset defs_thy; |
2126 val ss = get_simpset defs_thy; |
2167 |
2127 |
2168 fun sel_convs_prf () = |
2128 fun sel_convs_prf () = |
2169 map (prove_simp false ss (sel_defs @ accessor_thms)) sel_conv_props; |
2129 map (prove_simp false ss (sel_defs @ accessor_thms)) sel_conv_props; |
2170 val sel_convs = timeit_msg "record sel_convs proof:" sel_convs_prf; |
2130 val sel_convs = timeit_msg "record sel_convs proof:" sel_convs_prf; |
2171 fun sel_convs_standard_prf () = map standard sel_convs |
2131 fun sel_convs_standard_prf () = map Drule.standard sel_convs |
2172 val sel_convs_standard = |
2132 val sel_convs_standard = |
2173 timeit_msg "record sel_convs_standard proof:" sel_convs_standard_prf; |
2133 timeit_msg "record sel_convs_standard proof:" sel_convs_standard_prf; |
2174 |
2134 |
2175 fun upd_convs_prf () = |
2135 fun upd_convs_prf () = |
2176 map (prove_simp false ss (upd_defs @ updator_thms)) upd_conv_props; |
2136 map (prove_simp false ss (upd_defs @ updator_thms)) upd_conv_props; |
2177 val upd_convs = timeit_msg "record upd_convs proof:" upd_convs_prf; |
2137 val upd_convs = timeit_msg "record upd_convs proof:" upd_convs_prf; |
2178 fun upd_convs_standard_prf () = map standard upd_convs |
2138 fun upd_convs_standard_prf () = map Drule.standard upd_convs |
2179 val upd_convs_standard = |
2139 val upd_convs_standard = |
2180 timeit_msg "record upd_convs_standard proof:" upd_convs_standard_prf; |
2140 timeit_msg "record upd_convs_standard proof:" upd_convs_standard_prf; |
2181 |
2141 |
2182 fun get_upd_acc_congs () = |
2142 fun get_upd_acc_congs () = |
2183 let |
2143 let |
2184 val symdefs = map symmetric (sel_defs @ upd_defs); |
2144 val symdefs = map symmetric (sel_defs @ upd_defs); |
2185 val fold_ss = HOL_basic_ss addsimps symdefs; |
2145 val fold_ss = HOL_basic_ss addsimps symdefs; |
2186 val ua_congs = map (standard o simplify fold_ss) upd_acc_cong_assists; |
2146 val ua_congs = map (Drule.standard o simplify fold_ss) upd_acc_cong_assists; |
2187 in (ua_congs RL [updacc_foldE], ua_congs RL [updacc_unfoldE]) end; |
2147 in (ua_congs RL [updacc_foldE], ua_congs RL [updacc_unfoldE]) end; |
2188 val (fold_congs, unfold_congs) = |
2148 val (fold_congs, unfold_congs) = |
2189 timeit_msg "record upd fold/unfold congs:" get_upd_acc_congs; |
2149 timeit_msg "record upd fold/unfold congs:" get_upd_acc_congs; |
2190 |
2150 |
2191 val parent_induct = if null parents then [] else [#induct (hd (rev parents))]; |
2151 val parent_induct = if null parents then [] else [#induct (hd (rev parents))]; |
2192 |
2152 |
2193 fun induct_scheme_prf () = |
2153 fun induct_scheme_prf () = |
2194 prove_standard [] induct_scheme_prop |
2154 prove_standard [] induct_scheme_prop |
2195 (fn _ => |
2155 (fn _ => |
2196 EVERY |
2156 EVERY |
2197 [if null parent_induct |
2157 [if null parent_induct then all_tac else try_param_tac rN (hd parent_induct) 1, |
2198 then all_tac else try_param_tac rN (hd parent_induct) 1, |
|
2199 try_param_tac rN ext_induct 1, |
2158 try_param_tac rN ext_induct 1, |
2200 asm_simp_tac HOL_basic_ss 1]); |
2159 asm_simp_tac HOL_basic_ss 1]); |
2201 val induct_scheme = timeit_msg "record induct_scheme proof:" induct_scheme_prf; |
2160 val induct_scheme = timeit_msg "record induct_scheme proof:" induct_scheme_prf; |
2202 |
2161 |
2203 fun induct_prf () = |
2162 fun induct_prf () = |
2215 val ind = |
2174 val ind = |
2216 cterm_instantiate |
2175 cterm_instantiate |
2217 [(cterm_of defs_thy Pvar, cterm_of defs_thy |
2176 [(cterm_of defs_thy Pvar, cterm_of defs_thy |
2218 (lambda w (HOLogic.imp $ HOLogic.mk_eq (r0, w) $ C)))] |
2177 (lambda w (HOLogic.imp $ HOLogic.mk_eq (r0, w) $ C)))] |
2219 induct_scheme; |
2178 induct_scheme; |
2220 in standard (ObjectLogic.rulify (mp OF [ind, refl])) end; |
2179 in Drule.standard (ObjectLogic.rulify (mp OF [ind, refl])) end; |
2221 |
2180 |
2222 fun cases_scheme_prf_noopt () = |
2181 fun cases_scheme_prf_noopt () = |
2223 prove_standard [] cases_scheme_prop |
2182 prove_standard [] cases_scheme_prop |
2224 (fn _ => |
2183 (fn _ => |
2225 EVERY |
2184 EVERY1 |
2226 [asm_full_simp_tac (HOL_basic_ss addsimps [atomize_all, atomize_imp]) 1, |
2185 [asm_full_simp_tac (HOL_basic_ss addsimps [atomize_all, atomize_imp]), |
2227 try_param_tac rN induct_scheme 1, |
2186 try_param_tac rN induct_scheme, |
2228 rtac impI 1, |
2187 rtac impI, |
2229 REPEAT (etac allE 1), |
2188 REPEAT o etac allE, |
2230 etac mp 1, |
2189 etac mp, |
2231 rtac refl 1]); |
2190 rtac refl]); |
2232 val cases_scheme_prf = quick_and_dirty_prf cases_scheme_prf_noopt cases_scheme_prf_opt; |
2191 val cases_scheme_prf = quick_and_dirty_prf cases_scheme_prf_noopt cases_scheme_prf_opt; |
2233 val cases_scheme = timeit_msg "record cases_scheme proof:" cases_scheme_prf; |
2192 val cases_scheme = timeit_msg "record cases_scheme proof:" cases_scheme_prf; |
2234 |
2193 |
2235 fun cases_prf () = |
2194 fun cases_prf () = |
2236 prove_standard [] cases_prop |
2195 prove_standard [] cases_prop |
2247 prove_standard [] surjective_prop |
2206 prove_standard [] surjective_prop |
2248 (fn _ => |
2207 (fn _ => |
2249 EVERY |
2208 EVERY |
2250 [rtac surject_assist_idE 1, |
2209 [rtac surject_assist_idE 1, |
2251 simp_tac init_ss 1, |
2210 simp_tac init_ss 1, |
2252 REPEAT (intros_tac 1 ORELSE (rtac surject_assistI 1 THEN simp_tac leaf_ss 1))]) |
2211 REPEAT |
|
2212 (IsTupleSupport.istuple_intros_tac 1 ORELSE |
|
2213 (rtac surject_assistI 1 THEN simp_tac leaf_ss 1))]) |
2253 end; |
2214 end; |
2254 val surjective = timeit_msg "record surjective proof:" surjective_prf; |
2215 val surjective = timeit_msg "record surjective proof:" surjective_prf; |
2255 |
2216 |
2256 fun split_meta_prf () = |
2217 fun split_meta_prf () = |
2257 prove false [] split_meta_prop |
2218 prove false [] split_meta_prop |
2258 (fn _ => |
2219 (fn _ => |
2259 EVERY |
2220 EVERY1 |
2260 [rtac equal_intr_rule 1, Goal.norm_hhf_tac 1, |
2221 [rtac equal_intr_rule, Goal.norm_hhf_tac, |
2261 etac meta_allE 1, atac 1, |
2222 etac meta_allE, atac, |
2262 rtac (prop_subst OF [surjective]) 1, |
2223 rtac (prop_subst OF [surjective]), |
2263 REPEAT (etac meta_allE 1), atac 1]); |
2224 REPEAT o etac meta_allE, atac]); |
2264 val split_meta = timeit_msg "record split_meta proof:" split_meta_prf; |
2225 val split_meta = timeit_msg "record split_meta proof:" split_meta_prf; |
2265 fun split_meta_standardise () = standard split_meta; |
2226 fun split_meta_standardise () = Drule.standard split_meta; |
2266 val split_meta_standard = |
2227 val split_meta_standard = |
2267 timeit_msg "record split_meta standard:" split_meta_standardise; |
2228 timeit_msg "record split_meta standard:" split_meta_standardise; |
2268 |
2229 |
2269 fun split_object_prf_opt () = |
2230 fun split_object_prf_opt () = |
2270 let |
2231 let |
2285 assume cr (*All n m more. P (ext n m more)*) |
2246 assume cr (*All n m more. P (ext n m more)*) |
2286 |> obj_to_meta_all (*!!n m more. P (ext n m more)*) |
2247 |> obj_to_meta_all (*!!n m more. P (ext n m more)*) |
2287 |> equal_elim (symmetric split_meta') (*!!r. P r*) |
2248 |> equal_elim (symmetric split_meta') (*!!r. P r*) |
2288 |> meta_to_obj_all (*All r. P r*) |
2249 |> meta_to_obj_all (*All r. P r*) |
2289 |> implies_intr cr (* 2 ==> 1 *) |
2250 |> implies_intr cr (* 2 ==> 1 *) |
2290 in standard (thr COMP (thl COMP iffI)) end; |
2251 in Drule.standard (thr COMP (thl COMP iffI)) end; |
2291 |
2252 |
2292 fun split_object_prf_noopt () = |
2253 fun split_object_prf_noopt () = |
2293 prove_standard [] split_object_prop |
2254 prove_standard [] split_object_prop |
2294 (fn _ => |
2255 (fn _ => |
2295 EVERY |
2256 EVERY1 |
2296 [rtac iffI 1, |
2257 [rtac iffI, |
2297 REPEAT (rtac allI 1), etac allE 1, atac 1, |
2258 REPEAT o rtac allI, etac allE, atac, |
2298 rtac allI 1, rtac induct_scheme 1, REPEAT (etac allE 1), atac 1]); |
2259 rtac allI, rtac induct_scheme, REPEAT o etac allE, atac]); |
2299 |
2260 |
2300 val split_object_prf = quick_and_dirty_prf split_object_prf_noopt split_object_prf_opt; |
2261 val split_object_prf = quick_and_dirty_prf split_object_prf_noopt split_object_prf_opt; |
2301 val split_object = timeit_msg "record split_object proof:" split_object_prf; |
2262 val split_object = timeit_msg "record split_object proof:" split_object_prf; |
2302 |
2263 |
2303 |
2264 |