43 |
43 |
44 (** definition of the inductive rules for alpha and alpha_bn **) |
44 (** definition of the inductive rules for alpha and alpha_bn **) |
45 |
45 |
46 (* construct the compound terms for prod_fv and prod_alpha *) |
46 (* construct the compound terms for prod_fv and prod_alpha *) |
47 fun mk_prod_fv (t1, t2) = |
47 fun mk_prod_fv (t1, t2) = |
48 let |
48 let |
49 val ty1 = fastype_of t1 |
49 val ty1 = fastype_of t1 |
50 val ty2 = fastype_of t2 |
50 val ty2 = fastype_of t2 |
51 val resT = HOLogic.mk_prodT (domain_type ty1, domain_type ty2) --> @{typ "atom set"} |
51 val resT = HOLogic.mk_prodT (domain_type ty1, domain_type ty2) --> @{typ "atom set"} |
52 in |
52 in |
53 Const (@{const_name "prod_fv"}, [ty1, ty2] ---> resT) $ t1 $ t2 |
53 Const (@{const_name "prod_fv"}, [ty1, ty2] ---> resT) $ t1 $ t2 |
54 end |
54 end |
55 |
55 |
56 fun mk_prod_alpha (t1, t2) = |
56 fun mk_prod_alpha (t1, t2) = |
57 let |
57 let |
58 val ty1 = fastype_of t1 |
58 val ty1 = fastype_of t1 |
59 val ty2 = fastype_of t2 |
59 val ty2 = fastype_of t2 |
60 val prodT = HOLogic.mk_prodT (domain_type ty1, domain_type ty2) |
60 val prodT = HOLogic.mk_prodT (domain_type ty1, domain_type ty2) |
61 val resT = [prodT, prodT] ---> @{typ "bool"} |
61 val resT = [prodT, prodT] ---> @{typ "bool"} |
62 in |
62 in |
63 Const (@{const_name "prod_alpha"}, [ty1, ty2] ---> resT) $ t1 $ t2 |
63 Const (@{const_name "prod_alpha"}, [ty1, ty2] ---> resT) $ t1 $ t2 |
64 end |
64 end |
65 |
65 |
66 (* generates the compound binder terms *) |
66 (* generates the compound binder terms *) |
67 fun mk_binders lthy bmode args binders = |
67 fun mk_binders lthy bmode args binders = |
68 let |
68 let |
69 fun bind_set lthy args (NONE, i) = setify lthy (nth args i) |
69 fun bind_set lthy args (NONE, i) = setify lthy (nth args i) |
70 | bind_set _ args (SOME bn, i) = bn $ (nth args i) |
70 | bind_set _ args (SOME bn, i) = bn $ (nth args i) |
71 fun bind_lst lthy args (NONE, i) = listify lthy (nth args i) |
71 fun bind_lst lthy args (NONE, i) = listify lthy (nth args i) |
72 | bind_lst _ args (SOME bn, i) = bn $ (nth args i) |
72 | bind_lst _ args (SOME bn, i) = bn $ (nth args i) |
73 |
73 |
74 val (combine_fn, bind_fn) = |
74 val (combine_fn, bind_fn) = |
75 case bmode of |
75 case bmode of |
76 Lst => (mk_append, bind_lst) |
76 Lst => (mk_append, bind_lst) |
77 | Set => (mk_union, bind_set) |
77 | Set => (mk_union, bind_set) |
78 | Res => (mk_union, bind_set) |
78 | Res => (mk_union, bind_set) |
79 in |
79 in |
80 binders |
80 binders |
81 |> map (bind_fn lthy args) |
81 |> map (bind_fn lthy args) |
82 |> foldl1 combine_fn |
82 |> foldl1 combine_fn |
83 end |
83 end |
84 |
84 |
85 (* produces the term for an alpha with abstraction *) |
85 (* produces the term for an alpha with abstraction *) |
86 fun mk_alpha_term bmode fv alpha args args' binders binders' = |
86 fun mk_alpha_term bmode fv alpha args args' binders binders' = |
87 let |
87 let |
88 val (alpha_name, binder_ty) = |
88 val (alpha_name, binder_ty) = |
89 case bmode of |
89 case bmode of |
90 Lst => (@{const_name "alpha_lst"}, @{typ "atom list"}) |
90 Lst => (@{const_name "alpha_lst"}, @{typ "atom list"}) |
91 | Set => (@{const_name "alpha_set"}, @{typ "atom set"}) |
91 | Set => (@{const_name "alpha_set"}, @{typ "atom set"}) |
92 | Res => (@{const_name "alpha_res"}, @{typ "atom set"}) |
92 | Res => (@{const_name "alpha_res"}, @{typ "atom set"}) |
93 val ty = fastype_of args |
93 val ty = fastype_of args |
94 val pair_ty = HOLogic.mk_prodT (binder_ty, ty) |
94 val pair_ty = HOLogic.mk_prodT (binder_ty, ty) |
95 val alpha_ty = [ty, ty] ---> @{typ "bool"} |
95 val alpha_ty = [ty, ty] ---> @{typ "bool"} |
96 val fv_ty = ty --> @{typ "atom set"} |
96 val fv_ty = ty --> @{typ "atom set"} |
97 val pair_lhs = HOLogic.mk_prod (binders, args) |
97 val pair_lhs = HOLogic.mk_prod (binders, args) |
98 val pair_rhs = HOLogic.mk_prod (binders', args') |
98 val pair_rhs = HOLogic.mk_prod (binders', args') |
99 in |
99 in |
100 HOLogic.exists_const @{typ perm} $ Abs ("p", @{typ perm}, |
100 HOLogic.exists_const @{typ perm} $ Abs ("p", @{typ perm}, |
101 Const (alpha_name, [pair_ty, alpha_ty, fv_ty, @{typ "perm"}, pair_ty] ---> @{typ bool}) |
101 Const (alpha_name, [pair_ty, alpha_ty, fv_ty, @{typ "perm"}, pair_ty] ---> @{typ bool}) |
102 $ pair_lhs $ alpha $ fv $ (Bound 0) $ pair_rhs) |
102 $ pair_lhs $ alpha $ fv $ (Bound 0) $ pair_rhs) |
103 end |
103 end |
104 |
104 |
105 (* for non-recursive binders we have to produce alpha_bn premises *) |
105 (* for non-recursive binders we have to produce alpha_bn premises *) |
106 fun mk_alpha_bn_prem alpha_bn_map args args' bodies binder = |
106 fun mk_alpha_bn_prem alpha_bn_map args args' bodies binder = |
107 case binder of |
107 case binder of |
108 (NONE, _) => [] |
108 (NONE, _) => [] |
111 else [lookup alpha_bn_map bn $ nth args i $ nth args' i] |
111 else [lookup alpha_bn_map bn $ nth args i $ nth args' i] |
112 |
112 |
113 (* generate the premises for an alpha rule; mk_frees is used |
113 (* generate the premises for an alpha rule; mk_frees is used |
114 if no binders are present *) |
114 if no binders are present *) |
115 fun mk_alpha_prems lthy alpha_map alpha_bn_map is_rec (args, args') bclause = |
115 fun mk_alpha_prems lthy alpha_map alpha_bn_map is_rec (args, args') bclause = |
116 let |
116 let |
117 fun mk_frees i = |
117 fun mk_frees i = |
118 let |
118 let |
119 val arg = nth args i |
119 val arg = nth args i |
120 val arg' = nth args' i |
120 val arg' = nth args' i |
121 val ty = fastype_of arg |
121 val ty = fastype_of arg |
122 in |
122 in |
123 if nth is_rec i |
123 if nth is_rec i |
124 then fst (lookup alpha_map ty) $ arg $ arg' |
124 then fst (lookup alpha_map ty) $ arg $ arg' |
125 else HOLogic.mk_eq (arg, arg') |
125 else HOLogic.mk_eq (arg, arg') |
126 end |
126 end |
127 |
127 |
128 fun mk_alpha_fv i = |
128 fun mk_alpha_fv i = |
129 let |
129 let |
130 val ty = fastype_of (nth args i) |
130 val ty = fastype_of (nth args i) |
131 in |
131 in |
132 case AList.lookup (op=) alpha_map ty of |
132 case AList.lookup (op=) alpha_map ty of |
133 NONE => (HOLogic.eq_const ty, supp_const ty) |
133 NONE => (HOLogic.eq_const ty, supp_const ty) |
134 | SOME (alpha, fv) => (alpha, fv) |
134 | SOME (alpha, fv) => (alpha, fv) |
135 end |
135 end |
136 in |
136 in |
137 case bclause of |
137 case bclause of |
138 BC (_, [], bodies) => map (HOLogic.mk_Trueprop o mk_frees) bodies |
138 BC (_, [], bodies) => map (HOLogic.mk_Trueprop o mk_frees) bodies |
139 | BC (bmode, binders, bodies) => |
139 | BC (bmode, binders, bodies) => |
140 let |
140 let |
141 val (alphas, fvs) = split_list (map mk_alpha_fv bodies) |
141 val (alphas, fvs) = split_list (map mk_alpha_fv bodies) |
142 val comp_fv = foldl1 mk_prod_fv fvs |
142 val comp_fv = foldl1 mk_prod_fv fvs |
143 val comp_alpha = foldl1 mk_prod_alpha alphas |
143 val comp_alpha = foldl1 mk_prod_alpha alphas |
144 val comp_args = foldl1 HOLogic.mk_prod (map (nth args) bodies) |
144 val comp_args = foldl1 HOLogic.mk_prod (map (nth args) bodies) |
145 val comp_args' = foldl1 HOLogic.mk_prod (map (nth args') bodies) |
145 val comp_args' = foldl1 HOLogic.mk_prod (map (nth args') bodies) |
146 val comp_binders = mk_binders lthy bmode args binders |
146 val comp_binders = mk_binders lthy bmode args binders |
147 val comp_binders' = mk_binders lthy bmode args' binders |
147 val comp_binders' = mk_binders lthy bmode args' binders |
148 val alpha_prem = |
148 val alpha_prem = |
149 mk_alpha_term bmode comp_fv comp_alpha comp_args comp_args' comp_binders comp_binders' |
149 mk_alpha_term bmode comp_fv comp_alpha comp_args comp_args' comp_binders comp_binders' |
150 val alpha_bn_prems = flat (map (mk_alpha_bn_prem alpha_bn_map args args' bodies) binders) |
150 val alpha_bn_prems = flat (map (mk_alpha_bn_prem alpha_bn_map args args' bodies) binders) |
151 in |
151 in |
152 map HOLogic.mk_Trueprop (alpha_prem::alpha_bn_prems) |
152 map HOLogic.mk_Trueprop (alpha_prem::alpha_bn_prems) |
153 end |
153 end |
154 end |
154 end |
155 |
155 |
156 (* produces the introduction rule for an alpha rule *) |
156 (* produces the introduction rule for an alpha rule *) |
157 fun mk_alpha_intros lthy alpha_map alpha_bn_map (constr, ty, arg_tys, is_rec) bclauses = |
157 fun mk_alpha_intros lthy alpha_map alpha_bn_map (constr, ty, arg_tys, is_rec) bclauses = |
158 let |
158 let |
159 val arg_names = Datatype_Prop.make_tnames arg_tys |
159 val arg_names = Datatype_Prop.make_tnames arg_tys |
160 val arg_names' = Name.variant_list arg_names arg_names |
160 val arg_names' = Name.variant_list arg_names arg_names |
161 val args = map Free (arg_names ~~ arg_tys) |
161 val args = map Free (arg_names ~~ arg_tys) |
162 val args' = map Free (arg_names' ~~ arg_tys) |
162 val args' = map Free (arg_names' ~~ arg_tys) |
163 val alpha = fst (lookup alpha_map ty) |
163 val alpha = fst (lookup alpha_map ty) |
164 val concl = HOLogic.mk_Trueprop (alpha $ list_comb (constr, args) $ list_comb (constr, args')) |
164 val concl = HOLogic.mk_Trueprop (alpha $ list_comb (constr, args) $ list_comb (constr, args')) |
165 val prems = map (mk_alpha_prems lthy alpha_map alpha_bn_map is_rec (args, args')) bclauses |
165 val prems = map (mk_alpha_prems lthy alpha_map alpha_bn_map is_rec (args, args')) bclauses |
166 in |
166 in |
167 Library.foldr Logic.mk_implies (flat prems, concl) |
167 Library.foldr Logic.mk_implies (flat prems, concl) |
168 end |
168 end |
169 |
169 |
170 (* produces the premise of an alpha-bn rule; we only need to |
170 (* produces the premise of an alpha-bn rule; we only need to |
171 treat the case special where the binding clause is empty; |
171 treat the case special where the binding clause is empty; |
172 |
172 |
173 - if the body is not included in the bn_info, then we either |
173 - if the body is not included in the bn_info, then we either |
174 produce an equation or an alpha-premise |
174 produce an equation or an alpha-premise |
175 |
175 |
176 - if the body is included in the bn_info, then we create |
176 - if the body is included in the bn_info, then we create |
177 either a recursive call to alpha-bn, or no premise *) |
177 either a recursive call to alpha-bn, or no premise *) |
178 fun mk_alpha_bn lthy alpha_map alpha_bn_map bn_args is_rec (args, args') bclause = |
178 fun mk_alpha_bn lthy alpha_map alpha_bn_map bn_args is_rec (args, args') bclause = |
179 let |
179 let |
180 fun mk_alpha_bn_prem alpha_map alpha_bn_map bn_args (args, args') i = |
180 fun mk_alpha_bn_prem i = |
181 let |
181 let |
182 val arg = nth args i |
182 val arg = nth args i |
183 val arg' = nth args' i |
183 val arg' = nth args' i |
184 val ty = fastype_of arg |
184 val ty = fastype_of arg |
185 in |
185 in |
186 case AList.lookup (op=) bn_args i of |
186 case AList.lookup (op=) bn_args i of |
187 NONE => (case (AList.lookup (op=) alpha_map ty) of |
187 NONE => (case (AList.lookup (op=) alpha_map ty) of |
188 NONE => [HOLogic.mk_eq (arg, arg')] |
188 NONE => [HOLogic.mk_eq (arg, arg')] |
189 | SOME (alpha, _) => [alpha $ arg $ arg']) |
189 | SOME (alpha, _) => [alpha $ arg $ arg']) |
190 | SOME (NONE) => [] |
190 | SOME (NONE) => [] |
191 | SOME (SOME bn) => [lookup alpha_bn_map bn $ arg $ arg'] |
191 | SOME (SOME bn) => [lookup alpha_bn_map bn $ arg $ arg'] |
192 end |
192 end |
193 in |
193 in |
194 case bclause of |
194 case bclause of |
195 BC (_, [], bodies) => |
195 BC (_, [], bodies) => |
196 map HOLogic.mk_Trueprop |
196 map HOLogic.mk_Trueprop (flat (map mk_alpha_bn_prem bodies)) |
197 (flat (map (mk_alpha_bn_prem alpha_map alpha_bn_map bn_args (args, args')) bodies)) |
197 | _ => mk_alpha_prems lthy alpha_map alpha_bn_map is_rec (args, args') bclause |
198 | _ => mk_alpha_prems lthy alpha_map alpha_bn_map is_rec (args, args') bclause |
198 end |
199 end |
|
200 |
199 |
201 fun mk_alpha_bn_intro lthy bn_trm alpha_map alpha_bn_map (bn_args, (constr, _, arg_tys, is_rec)) bclauses = |
200 fun mk_alpha_bn_intro lthy bn_trm alpha_map alpha_bn_map (bn_args, (constr, _, arg_tys, is_rec)) bclauses = |
202 let |
201 let |
203 val arg_names = Datatype_Prop.make_tnames arg_tys |
202 val arg_names = Datatype_Prop.make_tnames arg_tys |
204 val arg_names' = Name.variant_list arg_names arg_names |
203 val arg_names' = Name.variant_list arg_names arg_names |
205 val args = map Free (arg_names ~~ arg_tys) |
204 val args = map Free (arg_names ~~ arg_tys) |
206 val args' = map Free (arg_names' ~~ arg_tys) |
205 val args' = map Free (arg_names' ~~ arg_tys) |
207 val alpha_bn = lookup alpha_bn_map bn_trm |
206 val alpha_bn = lookup alpha_bn_map bn_trm |
208 val concl = HOLogic.mk_Trueprop (alpha_bn $ list_comb (constr, args) $ list_comb (constr, args')) |
207 val concl = HOLogic.mk_Trueprop (alpha_bn $ list_comb (constr, args) $ list_comb (constr, args')) |
209 val prems = map (mk_alpha_bn lthy alpha_map alpha_bn_map bn_args is_rec (args, args')) bclauses |
208 val prems = map (mk_alpha_bn lthy alpha_map alpha_bn_map bn_args is_rec (args, args')) bclauses |
210 in |
209 in |
211 Library.foldr Logic.mk_implies (flat prems, concl) |
210 Library.foldr Logic.mk_implies (flat prems, concl) |
212 end |
211 end |
213 |
212 |
214 fun mk_alpha_bn_intros lthy alpha_map alpha_bn_map constrs_info bclausesss (bn_trm, bn_n, bn_argss) = |
213 fun mk_alpha_bn_intros lthy alpha_map alpha_bn_map constrs_info bclausesss (bn_trm, bn_n, bn_argss) = |
215 let |
214 let |
216 val nth_constrs_info = nth constrs_info bn_n |
215 val nth_constrs_info = nth constrs_info bn_n |
217 val nth_bclausess = nth bclausesss bn_n |
216 val nth_bclausess = nth bclausesss bn_n |
218 in |
217 in |
219 map2 (mk_alpha_bn_intro lthy bn_trm alpha_map alpha_bn_map) (bn_argss ~~ nth_constrs_info) nth_bclausess |
218 map2 (mk_alpha_bn_intro lthy bn_trm alpha_map alpha_bn_map) (bn_argss ~~ nth_constrs_info) nth_bclausess |
220 end |
219 end |
221 |
220 |
222 fun define_raw_alpha raw_full_ty_names raw_tys cns_info bn_info bclausesss fvs lthy = |
221 fun define_raw_alpha raw_full_ty_names raw_tys cns_info bn_info bclausesss fvs lthy = |
223 let |
222 let |
224 val alpha_names = map (prefix "alpha_" o Long_Name.base_name) raw_full_ty_names |
223 val alpha_names = map (prefix "alpha_" o Long_Name.base_name) raw_full_ty_names |
225 val alpha_tys = map (fn ty => [ty, ty] ---> @{typ bool}) raw_tys |
224 val alpha_tys = map (fn ty => [ty, ty] ---> @{typ bool}) raw_tys |
226 val alpha_frees = map Free (alpha_names ~~ alpha_tys) |
225 val alpha_frees = map Free (alpha_names ~~ alpha_tys) |
227 val alpha_map = raw_tys ~~ (alpha_frees ~~ fvs) |
226 val alpha_map = raw_tys ~~ (alpha_frees ~~ fvs) |
228 |
227 |
229 val (bns, bn_tys) = split_list (map (fn (bn, i, _) => (bn, i)) bn_info) |
228 val (bns, bn_tys) = split_list (map (fn (bn, i, _) => (bn, i)) bn_info) |
230 val bn_names = map (fn bn => Long_Name.base_name (fst (dest_Const bn))) bns |
229 val bn_names = map (fn bn => Long_Name.base_name (fst (dest_Const bn))) bns |
231 val alpha_bn_names = map (prefix "alpha_") bn_names |
230 val alpha_bn_names = map (prefix "alpha_") bn_names |
232 val alpha_bn_arg_tys = map (nth raw_tys) bn_tys |
231 val alpha_bn_arg_tys = map (nth raw_tys) bn_tys |
233 val alpha_bn_tys = map (fn ty => [ty, ty] ---> @{typ "bool"}) alpha_bn_arg_tys |
232 val alpha_bn_tys = map (fn ty => [ty, ty] ---> @{typ "bool"}) alpha_bn_arg_tys |
234 val alpha_bn_frees = map Free (alpha_bn_names ~~ alpha_bn_tys) |
233 val alpha_bn_frees = map Free (alpha_bn_names ~~ alpha_bn_tys) |
235 val alpha_bn_map = bns ~~ alpha_bn_frees |
234 val alpha_bn_map = bns ~~ alpha_bn_frees |
236 |
235 |
237 val alpha_intros = map2 (map2 (mk_alpha_intros lthy alpha_map alpha_bn_map)) cns_info bclausesss |
236 val alpha_intros = map2 (map2 (mk_alpha_intros lthy alpha_map alpha_bn_map)) cns_info bclausesss |
238 val alpha_bn_intros = map (mk_alpha_bn_intros lthy alpha_map alpha_bn_map cns_info bclausesss) bn_info |
237 val alpha_bn_intros = map (mk_alpha_bn_intros lthy alpha_map alpha_bn_map cns_info bclausesss) bn_info |
239 |
238 |
240 val all_alpha_names = map (fn (a, ty) => ((Binding.name a, ty), NoSyn)) |
239 val all_alpha_names = map (fn (a, ty) => ((Binding.name a, ty), NoSyn)) |
241 (alpha_names @ alpha_bn_names ~~ alpha_tys @ alpha_bn_tys) |
240 (alpha_names @ alpha_bn_names ~~ alpha_tys @ alpha_bn_tys) |
242 val all_alpha_intros = map (pair Attrib.empty_binding) (flat alpha_intros @ flat alpha_bn_intros) |
241 val all_alpha_intros = map (pair Attrib.empty_binding) (flat alpha_intros @ flat alpha_bn_intros) |
243 |
242 |
244 val (alphas, lthy') = Inductive.add_inductive_i |
243 val (alphas, lthy') = Inductive.add_inductive_i |
245 {quiet_mode = true, verbose = false, alt_name = Binding.empty, |
244 {quiet_mode = true, verbose = false, alt_name = Binding.empty, |
246 coind = false, no_elim = false, no_ind = false, skip_mono = false, fork_mono = false} |
245 coind = false, no_elim = false, no_ind = false, skip_mono = false, fork_mono = false} |
247 all_alpha_names [] all_alpha_intros [] lthy |
246 all_alpha_names [] all_alpha_intros [] lthy |
248 |
247 |
249 val all_alpha_trms_loc = #preds alphas; |
248 val all_alpha_trms_loc = #preds alphas; |
250 val alpha_induct_loc = #raw_induct alphas; |
249 val alpha_induct_loc = #raw_induct alphas; |
251 val alpha_intros_loc = #intrs alphas; |
250 val alpha_intros_loc = #intrs alphas; |
252 val alpha_cases_loc = #elims alphas; |
251 val alpha_cases_loc = #elims alphas; |
253 val phi = ProofContext.export_morphism lthy' lthy; |
252 val phi = ProofContext.export_morphism lthy' lthy; |
254 |
253 |
255 val all_alpha_trms = map (Morphism.term phi) all_alpha_trms_loc |
254 val all_alpha_trms = map (Morphism.term phi) all_alpha_trms_loc |
256 val (all_alpha_trms', _) = Variable.importT_terms all_alpha_trms lthy |
255 val (all_alpha_trms', _) = Variable.importT_terms all_alpha_trms lthy |
257 val alpha_induct = Morphism.thm phi alpha_induct_loc; |
256 val alpha_induct = Morphism.thm phi alpha_induct_loc; |
258 val alpha_intros = map (Morphism.thm phi) alpha_intros_loc |
257 val alpha_intros = map (Morphism.thm phi) alpha_intros_loc |
259 val alpha_cases = map (Morphism.thm phi) alpha_cases_loc |
258 val alpha_cases = map (Morphism.thm phi) alpha_cases_loc |
260 |
259 |
261 val (alpha_trms, alpha_bn_trms) = chop (length fvs) all_alpha_trms' |
260 val (alpha_trms, alpha_bn_trms) = chop (length fvs) all_alpha_trms' |
262 in |
261 in |
263 (alpha_trms, alpha_bn_trms, alpha_intros, alpha_cases, alpha_induct, lthy') |
262 (alpha_trms, alpha_bn_trms, alpha_intros, alpha_cases, alpha_induct, lthy') |
264 end |
263 end |
265 |
264 |
266 |
265 |
267 |
266 |
268 (** produces the distinctness theorems **) |
267 (** produces the distinctness theorems **) |
269 |
268 |
270 (* transforms the distinctness theorems of the constructors |
269 (* transforms the distinctness theorems of the constructors |
271 to "not-alphas" of the constructors *) |
270 to "not-alphas" of the constructors *) |
272 fun mk_distinct_goal ty_trm_assoc neq = |
271 fun mk_distinct_goal ty_trm_assoc neq = |
273 let |
272 let |
274 val (lhs, rhs) = |
273 val (lhs, rhs) = |
275 neq |
274 neq |
276 |> HOLogic.dest_Trueprop |
275 |> HOLogic.dest_Trueprop |
277 |> HOLogic.dest_not |
276 |> HOLogic.dest_not |
278 |> HOLogic.dest_eq |
277 |> HOLogic.dest_eq |
279 val ty = fastype_of lhs |
278 val ty = fastype_of lhs |
280 in |
279 in |
281 (lookup ty_trm_assoc ty) $ lhs $ rhs |
280 (lookup ty_trm_assoc ty) $ lhs $ rhs |
282 |> HOLogic.mk_not |
281 |> HOLogic.mk_not |
283 |> HOLogic.mk_Trueprop |
282 |> HOLogic.mk_Trueprop |
284 end |
283 end |
285 |
284 |
286 fun distinct_tac cases_thms distinct_thms = |
285 fun distinct_tac cases_thms distinct_thms = |
287 rtac notI THEN' eresolve_tac cases_thms |
286 rtac notI THEN' eresolve_tac cases_thms |
288 THEN_ALL_NEW asm_full_simp_tac (HOL_ss addsimps distinct_thms) |
287 THEN_ALL_NEW asm_full_simp_tac (HOL_ss addsimps distinct_thms) |
289 |
288 |
290 |
289 |
291 fun mk_alpha_distincts ctxt cases_thms distinct_thms alpha_trms alpha_tys = |
290 fun mk_alpha_distincts ctxt cases_thms distinct_thms alpha_trms alpha_tys = |
292 let |
291 let |
293 (* proper import of type-variables does not work, |
292 (* proper import of type-variables does not work, |
294 since then they are replaced by new variables, messing |
293 since then they are replaced by new variables, messing |
295 up the ty_term assoc list *) |
294 up the ty_trm assoc list *) |
296 val distinct_thms' = map Thm.legacy_freezeT distinct_thms |
295 val distinct_thms' = map Thm.legacy_freezeT distinct_thms |
297 val ty_trm_assoc = alpha_tys ~~ alpha_trms |
296 val ty_trm_assoc = alpha_tys ~~ alpha_trms |
298 |
297 |
299 fun mk_alpha_distinct distinct_trm = |
298 fun mk_alpha_distinct distinct_trm = |
300 let |
299 let |
301 val ([trm'], ctxt') = Variable.import_terms true [distinct_trm] ctxt |
300 val ([trm'], ctxt') = Variable.import_terms true [distinct_trm] ctxt |
302 val goal = mk_distinct_goal ty_trm_assoc distinct_trm |
301 val goal = mk_distinct_goal ty_trm_assoc distinct_trm |
303 in |
302 in |
304 Goal.prove ctxt' [] [] goal |
303 Goal.prove ctxt' [] [] goal |
305 (K (distinct_tac cases_thms distinct_thms 1)) |
304 (K (distinct_tac cases_thms distinct_thms 1)) |
306 |> singleton (Variable.export ctxt' ctxt) |
305 |> singleton (Variable.export ctxt' ctxt) |
307 end |
306 end |
308 |
307 |
309 in |
308 in |
310 map (mk_alpha_distinct o prop_of) distinct_thms' |
309 map (mk_alpha_distinct o prop_of) distinct_thms' |
311 |> map Thm.varifyT_global |
310 |> map Thm.varifyT_global |
312 end |
311 end |
313 |
312 |
314 |
313 |
315 |
314 |
316 (** produces the alpha_eq_iff simplification rules **) |
315 (** produces the alpha_eq_iff simplification rules **) |
317 |
316 |
339 if hyps = [] then HOLogic.mk_Trueprop concl |
338 if hyps = [] then HOLogic.mk_Trueprop concl |
340 else HOLogic.mk_Trueprop (HOLogic.mk_eq (concl, list_conj hyps)) |
339 else HOLogic.mk_Trueprop (HOLogic.mk_eq (concl, list_conj hyps)) |
341 end; |
340 end; |
342 |
341 |
343 fun mk_alpha_eq_iff ctxt alpha_intros distinct_thms inject_thms alpha_elims = |
342 fun mk_alpha_eq_iff ctxt alpha_intros distinct_thms inject_thms alpha_elims = |
344 let |
343 let |
345 val ((_, thms_imp), ctxt') = Variable.import false alpha_intros ctxt; |
344 val ((_, thms_imp), ctxt') = Variable.import false alpha_intros ctxt; |
346 val goals = map mk_alpha_eq_iff_goal thms_imp; |
345 val goals = map mk_alpha_eq_iff_goal thms_imp; |
347 val tac = alpha_eq_iff_tac (distinct_thms @ inject_thms) alpha_intros alpha_elims 1; |
346 val tac = alpha_eq_iff_tac (distinct_thms @ inject_thms) alpha_intros alpha_elims 1; |
348 val thms = map (fn goal => Goal.prove ctxt' [] [] goal (K tac)) goals; |
347 val thms = map (fn goal => Goal.prove ctxt' [] [] goal (K tac)) goals; |
349 in |
348 in |
350 Variable.export ctxt' ctxt thms |
349 Variable.export ctxt' ctxt thms |
351 |> map mk_simp_rule |
350 |> map mk_simp_rule |
352 end |
351 end |
353 |
352 |
354 |
353 |
355 (** proof by induction over the alpha-definitions **) |
354 (** proof by induction over the alpha-definitions **) |
356 |
355 |
357 fun is_true @{term "Trueprop True"} = true |
356 fun is_true @{term "Trueprop True"} = true |
358 | is_true _ = false |
357 | is_true _ = false |
359 |
358 |
360 fun alpha_prove alphas props alpha_induct_thm cases_tac ctxt = |
359 fun alpha_prove alphas props alpha_induct_thm cases_tac ctxt = |
361 let |
360 let |
362 val arg_tys = map (domain_type o fastype_of) alphas |
361 val arg_tys = map (domain_type o fastype_of) alphas |
363 |
362 |
364 val ((arg_names1, arg_names2), ctxt') = |
363 val ((arg_names1, arg_names2), ctxt') = |
365 ctxt |
364 ctxt |
366 |> Variable.variant_fixes (replicate (length alphas) "x") |
365 |> Variable.variant_fixes (replicate (length alphas) "x") |
367 ||>> Variable.variant_fixes (replicate (length alphas) "y") |
366 ||>> Variable.variant_fixes (replicate (length alphas) "y") |
368 |
367 |
369 val args1 = map2 (curry Free) arg_names1 arg_tys |
368 val args1 = map2 (curry Free) arg_names1 arg_tys |
370 val args2 = map2 (curry Free) arg_names2 arg_tys |
369 val args2 = map2 (curry Free) arg_names2 arg_tys |
371 |
370 |
372 val true_trms = replicate (length alphas) (K @{term True}) |
371 val true_trms = replicate (length alphas) (K @{term True}) |
373 |
372 |
374 fun apply_all x fs = map (fn f => f x) fs |
373 fun apply_all x fs = map (fn f => f x) fs |
375 val goals_rhs = |
374 val goals_rhs = |
376 group (props @ (alphas ~~ true_trms)) |
375 group (props @ (alphas ~~ true_trms)) |
377 |> map snd |
376 |> map snd |
378 |> map2 apply_all (args1 ~~ args2) |
377 |> map2 apply_all (args1 ~~ args2) |
379 |> map fold_conj |
378 |> map fold_conj |
380 |
379 |
381 fun apply_trm_pair t (ar1, ar2) = t $ ar1 $ ar2 |
380 fun apply_trm_pair t (ar1, ar2) = t $ ar1 $ ar2 |
382 val goals_lhs = map2 apply_trm_pair alphas (args1 ~~ args2) |
381 val goals_lhs = map2 apply_trm_pair alphas (args1 ~~ args2) |
383 |
382 |
384 val goals = |
383 val goals = |
385 (map2 (curry HOLogic.mk_imp) goals_lhs goals_rhs) |
384 (map2 (curry HOLogic.mk_imp) goals_lhs goals_rhs) |
386 |> foldr1 HOLogic.mk_conj |
385 |> foldr1 HOLogic.mk_conj |
387 |> HOLogic.mk_Trueprop |
386 |> HOLogic.mk_Trueprop |
388 |
387 |
389 fun tac ctxt = |
388 fun tac ctxt = |
390 HEADGOAL |
389 HEADGOAL |
391 (DETERM o (rtac alpha_induct_thm) |
390 (DETERM o (rtac alpha_induct_thm) |
392 THEN_ALL_NEW FIRST' [rtac @{thm TrueI}, cases_tac ctxt]) |
391 THEN_ALL_NEW FIRST' [rtac @{thm TrueI}, cases_tac ctxt]) |
393 in |
392 in |
394 Goal.prove ctxt' [] [] goals (fn {context, ...} => tac context) |
393 Goal.prove ctxt' [] [] goals (fn {context, ...} => tac context) |
395 |> singleton (ProofContext.export ctxt' ctxt) |
394 |> singleton (ProofContext.export ctxt' ctxt) |
396 |> Datatype_Aux.split_conj_thm |
395 |> Datatype_Aux.split_conj_thm |
397 |> map (fn th => th RS mp) |
396 |> map (fn th => th RS mp) |
398 |> map Datatype_Aux.split_conj_thm |
397 |> map Datatype_Aux.split_conj_thm |
399 |> flat |
398 |> flat |
400 |> map zero_var_indexes |
399 |> map zero_var_indexes |
401 |> filter_out (is_true o concl_of) |
400 |> filter_out (is_true o concl_of) |
402 end |
401 end |
403 |
402 |
404 |
403 |
405 (** reflexivity proof for the alphas **) |
404 (** reflexivity proof for the alphas **) |
406 |
405 |
407 val exi_zero = @{lemma "P (0::perm) ==> (? x. P x)" by auto} |
406 val exi_zero = @{lemma "P (0::perm) ==> (? x. P x)" by auto} |
408 |
407 |
409 fun cases_tac intros = |
408 fun cases_tac intros = |
410 let |
409 let |
411 val prod_simps = @{thms split_conv prod_alpha_def prod_rel.simps} |
410 val prod_simps = @{thms split_conv prod_alpha_def prod_rel.simps} |
412 |
411 |
413 val unbound_tac = REPEAT o (etac @{thm conjE}) THEN' atac |
412 val unbound_tac = REPEAT o (etac @{thm conjE}) THEN' atac |
414 |
413 |
415 val bound_tac = |
414 val bound_tac = |
416 EVERY' [ rtac exi_zero, |
415 EVERY' [ rtac exi_zero, |
417 resolve_tac @{thms alpha_refl}, |
416 resolve_tac @{thms alpha_refl}, |
418 asm_full_simp_tac (HOL_ss addsimps prod_simps) ] |
417 asm_full_simp_tac (HOL_ss addsimps prod_simps) ] |
419 in |
418 in |
420 REPEAT o FIRST' [rtac @{thm conjI}, |
419 REPEAT o FIRST' [rtac @{thm conjI}, |
421 resolve_tac intros THEN_ALL_NEW FIRST' [rtac @{thm refl}, unbound_tac, bound_tac]] |
420 resolve_tac intros THEN_ALL_NEW FIRST' [rtac @{thm refl}, unbound_tac, bound_tac]] |
422 end |
421 end |
423 |
422 |
424 fun raw_prove_refl alpha_trms alpha_bns alpha_intros raw_dt_induct ctxt = |
423 fun raw_prove_refl alpha_trms alpha_bns alpha_intros raw_dt_induct ctxt = |
425 let |
424 let |
426 val arg_tys = |
425 val arg_tys = |
427 alpha_trms |
426 alpha_trms |
428 |> map fastype_of |
427 |> map fastype_of |
429 |> map domain_type |
428 |> map domain_type |
430 val arg_bn_tys = |
429 val arg_bn_tys = |
431 alpha_bns |
430 alpha_bns |
432 |> map fastype_of |
431 |> map fastype_of |
433 |> map domain_type |
432 |> map domain_type |
434 val arg_names = Datatype_Prop.make_tnames arg_tys |
433 val arg_names = Datatype_Prop.make_tnames arg_tys |
435 val arg_bn_names = map (lookup (arg_tys ~~ arg_names)) arg_bn_tys |
434 val arg_bn_names = map (lookup (arg_tys ~~ arg_names)) arg_bn_tys |
436 val args = map Free (arg_names ~~ arg_tys) |
435 val args = map Free (arg_names ~~ arg_tys) |
437 val arg_bns = map Free (arg_bn_names ~~ arg_bn_tys) |
436 val arg_bns = map Free (arg_bn_names ~~ arg_bn_tys) |
438 val goal = |
437 val goal = |
439 group ((arg_bns ~~ alpha_bns) @ (args ~~ alpha_trms)) |
438 group ((arg_bns ~~ alpha_bns) @ (args ~~ alpha_trms)) |
440 |> map (fn (ar, cnsts) => map (fn c => c $ ar $ ar) cnsts) |
439 |> map (fn (ar, cnsts) => map (fn c => c $ ar $ ar) cnsts) |
441 |> map (foldr1 HOLogic.mk_conj) |
440 |> map (foldr1 HOLogic.mk_conj) |
442 |> foldr1 HOLogic.mk_conj |
441 |> foldr1 HOLogic.mk_conj |
443 |> HOLogic.mk_Trueprop |
442 |> HOLogic.mk_Trueprop |
444 in |
443 in |
445 Goal.prove ctxt arg_names [] goal |
444 Goal.prove ctxt arg_names [] goal |
446 (fn {context, ...} => |
445 (fn {context, ...} => |
447 HEADGOAL (DETERM o (rtac raw_dt_induct) THEN_ALL_NEW cases_tac alpha_intros)) |
446 HEADGOAL (DETERM o (rtac raw_dt_induct) THEN_ALL_NEW cases_tac alpha_intros)) |
448 |> Datatype_Aux.split_conj_thm |
447 |> Datatype_Aux.split_conj_thm |
449 |> map Datatype_Aux.split_conj_thm |
448 |> map Datatype_Aux.split_conj_thm |
450 |> flat |
449 |> flat |
451 end |
450 end |
452 |
451 |
453 |
452 |
454 |
453 |
455 (** symmetry proof for the alphas **) |
454 (** symmetry proof for the alphas **) |
456 |
455 |
457 val exi_neg = @{lemma "(EX (p::perm). P p) ==> (!!q. P q ==> Q (- q)) ==> EX p. Q p" |
456 val exi_neg = @{lemma "(EX (p::perm). P p) ==> (!!q. P q ==> Q (- q)) ==> EX p. Q p" |
458 by (erule exE, rule_tac x="-p" in exI, auto)} |
457 by (erule exE, rule_tac x="-p" in exI, auto)} |
459 |
458 |
460 (* for premises that contain binders *) |
459 (* for premises that contain binders *) |
461 fun prem_bound_tac pred_names ctxt = |
460 fun prem_bound_tac pred_names ctxt = |
462 let |
461 let |
463 fun trans_prem_tac pred_names ctxt = |
462 fun trans_prem_tac pred_names ctxt = |
464 SUBPROOF (fn {prems, context, ...} => |
463 SUBPROOF (fn {prems, context, ...} => |
465 let |
464 let |
466 val prems' = map (transform_prem1 context pred_names) prems |
465 val prems' = map (transform_prem1 context pred_names) prems |
467 in |
466 in |
468 resolve_tac prems' 1 |
467 resolve_tac prems' 1 |
469 end) ctxt |
468 end) ctxt |
470 val prod_simps = @{thms split_conv permute_prod.simps prod_alpha_def prod_rel.simps alphas} |
469 val prod_simps = @{thms split_conv permute_prod.simps prod_alpha_def prod_rel.simps alphas} |
471 in |
470 in |
472 EVERY' |
471 EVERY' |
473 [ etac exi_neg, |
472 [ etac exi_neg, |
474 resolve_tac @{thms alpha_sym_eqvt}, |
473 resolve_tac @{thms alpha_sym_eqvt}, |
475 asm_full_simp_tac (HOL_ss addsimps prod_simps), |
474 asm_full_simp_tac (HOL_ss addsimps prod_simps), |
476 Nominal_Permeq.eqvt_tac ctxt [] [] THEN' rtac @{thm refl}, |
475 Nominal_Permeq.eqvt_tac ctxt [] [] THEN' rtac @{thm refl}, |
477 trans_prem_tac pred_names ctxt ] |
476 trans_prem_tac pred_names ctxt ] |
478 end |
477 end |
479 |
478 |
480 fun raw_prove_sym alpha_trms alpha_intros alpha_induct ctxt = |
479 fun raw_prove_sym alpha_trms alpha_intros alpha_induct ctxt = |
481 let |
480 let |
482 val props = map (fn t => fn (x, y) => t $ y $ x) alpha_trms |
481 val props = map (fn t => fn (x, y) => t $ y $ x) alpha_trms |
483 |
482 |
484 fun tac ctxt = |
483 fun tac ctxt = |
485 let |
484 let |
486 val alpha_names = map (fst o dest_Const) alpha_trms |
485 val alpha_names = map (fst o dest_Const) alpha_trms |
487 in |
486 in |
488 resolve_tac alpha_intros THEN_ALL_NEW |
487 resolve_tac alpha_intros THEN_ALL_NEW |
489 FIRST' [atac, rtac @{thm sym} THEN' atac, prem_bound_tac alpha_names ctxt] |
488 FIRST' [atac, rtac @{thm sym} THEN' atac, prem_bound_tac alpha_names ctxt] |
490 end |
489 end |
491 in |
490 in |
492 alpha_prove alpha_trms (alpha_trms ~~ props) alpha_induct tac ctxt |
491 alpha_prove alpha_trms (alpha_trms ~~ props) alpha_induct tac ctxt |
493 end |
492 end |
494 |
493 |
495 |
494 |
496 (** transitivity proof for alphas **) |
495 (** transitivity proof for alphas **) |
497 |
496 |
498 (* applies cases rules and resolves them with the last premise *) |
497 (* applies cases rules and resolves them with the last premise *) |
514 in |
513 in |
515 HEADGOAL (rtac exi_inst) |
514 HEADGOAL (rtac exi_inst) |
516 end) |
515 end) |
517 |
516 |
518 fun non_trivial_cases_tac pred_names intros ctxt = |
517 fun non_trivial_cases_tac pred_names intros ctxt = |
519 let |
518 let |
520 val prod_simps = @{thms split_conv alphas permute_prod.simps prod_alpha_def prod_rel.simps} |
519 val prod_simps = @{thms split_conv alphas permute_prod.simps prod_alpha_def prod_rel.simps} |
521 in |
520 in |
522 resolve_tac intros |
521 resolve_tac intros |
523 THEN_ALL_NEW (asm_simp_tac HOL_basic_ss THEN' |
522 THEN_ALL_NEW (asm_simp_tac HOL_basic_ss THEN' |
524 TRY o EVERY' (* if binders are present *) |
523 TRY o EVERY' (* if binders are present *) |
525 [ etac @{thm exE}, |
524 [ etac @{thm exE}, |
526 etac @{thm exE}, |
525 etac @{thm exE}, |
527 perm_inst_tac ctxt, |
526 perm_inst_tac ctxt, |
528 resolve_tac @{thms alpha_trans_eqvt}, |
527 resolve_tac @{thms alpha_trans_eqvt}, |
529 atac, |
528 atac, |
530 aatac pred_names ctxt, |
529 aatac pred_names ctxt, |
531 Nominal_Permeq.eqvt_tac ctxt [] [] THEN' rtac @{thm refl}, |
530 Nominal_Permeq.eqvt_tac ctxt [] [] THEN' rtac @{thm refl}, |
532 asm_full_simp_tac (HOL_ss addsimps prod_simps) ]) |
531 asm_full_simp_tac (HOL_ss addsimps prod_simps) ]) |
533 end |
532 end |
534 |
533 |
535 fun prove_trans_tac pred_names raw_dt_thms intros cases ctxt = |
534 fun prove_trans_tac pred_names raw_dt_thms intros cases ctxt = |
536 let |
535 let |
537 fun all_cases ctxt = |
536 fun all_cases ctxt = |
538 asm_full_simp_tac (HOL_basic_ss addsimps raw_dt_thms) |
537 asm_full_simp_tac (HOL_basic_ss addsimps raw_dt_thms) |
539 THEN' TRY o non_trivial_cases_tac pred_names intros ctxt |
538 THEN' TRY o non_trivial_cases_tac pred_names intros ctxt |
540 in |
539 in |
541 EVERY' [ rtac @{thm allI}, rtac @{thm impI}, |
540 EVERY' [ rtac @{thm allI}, rtac @{thm impI}, |
542 ecases_tac cases ctxt THEN_ALL_NEW all_cases ctxt ] |
541 ecases_tac cases ctxt THEN_ALL_NEW all_cases ctxt ] |
543 end |
542 end |
544 |
543 |
545 fun prep_trans_goal alpha_trm (arg1, arg2) = |
544 fun prep_trans_goal alpha_trm (arg1, arg2) = |
546 let |
545 let |
547 val arg_ty = fastype_of arg1 |
546 val arg_ty = fastype_of arg1 |
548 val mid = alpha_trm $ arg2 $ (Bound 0) |
547 val mid = alpha_trm $ arg2 $ (Bound 0) |
549 val rhs = alpha_trm $ arg1 $ (Bound 0) |
548 val rhs = alpha_trm $ arg1 $ (Bound 0) |
550 in |
549 in |
551 HOLogic.all_const arg_ty $ Abs ("z", arg_ty, HOLogic.mk_imp (mid, rhs)) |
550 HOLogic.all_const arg_ty $ Abs ("z", arg_ty, HOLogic.mk_imp (mid, rhs)) |
552 end |
551 end |
553 |
552 |
554 fun raw_prove_trans alpha_trms raw_dt_thms alpha_intros alpha_induct alpha_cases ctxt = |
553 fun raw_prove_trans alpha_trms raw_dt_thms alpha_intros alpha_induct alpha_cases ctxt = |
555 let |
554 let |
556 val alpha_names = map (fst o dest_Const) alpha_trms |
555 val alpha_names = map (fst o dest_Const) alpha_trms |
557 val props = map prep_trans_goal alpha_trms |
556 val props = map prep_trans_goal alpha_trms |
558 val norm = @{lemma "A ==> (!x. B x --> C x) ==> (!!x. [|A; B x|] ==> C x)" by simp} |
557 val norm = @{lemma "A ==> (!x. B x --> C x) ==> (!!x. [|A; B x|] ==> C x)" by simp} |
559 in |
558 in |
560 alpha_prove alpha_trms (alpha_trms ~~ props) alpha_induct |
559 alpha_prove alpha_trms (alpha_trms ~~ props) alpha_induct |
561 (prove_trans_tac alpha_names raw_dt_thms alpha_intros alpha_cases) ctxt |
560 (prove_trans_tac alpha_names raw_dt_thms alpha_intros alpha_cases) ctxt |
562 end |
561 end |
563 |
562 |
564 |
563 |
565 (** proves the equivp predicate for all alphas **) |
564 (** proves the equivp predicate for all alphas **) |
566 |
565 |
567 val transp_def' = |
566 val transp_def' = |
568 @{lemma "transp R == !x y. R x y --> (!z. R y z --> R x z)" |
567 @{lemma "transp R == !x y. R x y --> (!z. R y z --> R x z)" |
569 by (rule eq_reflection, auto simp add: transp_def)} |
568 by (rule eq_reflection, auto simp add: transp_def)} |
570 |
569 |
571 fun raw_prove_equivp alphas alpha_bns refl symm trans ctxt = |
570 fun raw_prove_equivp alphas alpha_bns refl symm trans ctxt = |
572 let |
571 let |
573 val refl' = map (fold_rule @{thms reflp_def} o atomize) refl |
572 val refl' = map (fold_rule @{thms reflp_def} o atomize) refl |
574 val symm' = map (fold_rule @{thms symp_def} o atomize) symm |
573 val symm' = map (fold_rule @{thms symp_def} o atomize) symm |
575 val trans' = map (fold_rule [transp_def'] o atomize) trans |
574 val trans' = map (fold_rule [transp_def'] o atomize) trans |
576 |
575 |
577 fun prep_goal t = |
576 fun prep_goal t = |
578 HOLogic.mk_Trueprop (Const (@{const_name "equivp"}, fastype_of t --> @{typ bool}) $ t) |
577 HOLogic.mk_Trueprop (Const (@{const_name "equivp"}, fastype_of t --> @{typ bool}) $ t) |
579 in |
578 in |
580 Goal.prove_multi ctxt [] [] (map prep_goal (alphas @ alpha_bns)) |
579 Goal.prove_multi ctxt [] [] (map prep_goal (alphas @ alpha_bns)) |
581 (K (HEADGOAL (Goal.conjunction_tac THEN_ALL_NEW (rtac @{thm equivpI} THEN' |
580 (K (HEADGOAL (Goal.conjunction_tac THEN_ALL_NEW (rtac @{thm equivpI} THEN' |
582 RANGE [resolve_tac refl', resolve_tac symm', resolve_tac trans'])))) |
581 RANGE [resolve_tac refl', resolve_tac symm', resolve_tac trans'])))) |
583 |> chop (length alphas) |
582 |> chop (length alphas) |
584 end |
583 end |
585 |
584 |
586 |
585 |
587 (* proves that alpha_raw implies alpha_bn *) |
586 (* proves that alpha_raw implies alpha_bn *) |
588 |
587 |
589 fun raw_prove_bn_imp_tac pred_names alpha_intros ctxt = |
588 fun raw_prove_bn_imp_tac pred_names alpha_intros ctxt = |
600 resolve_tac prems'', |
599 resolve_tac prems'', |
601 resolve_tac alpha_intros ])) |
600 resolve_tac alpha_intros ])) |
602 end) ctxt |
601 end) ctxt |
603 |
602 |
604 fun raw_prove_bn_imp alpha_trms alpha_bn_trms alpha_intros alpha_induct ctxt = |
603 fun raw_prove_bn_imp alpha_trms alpha_bn_trms alpha_intros alpha_induct ctxt = |
605 let |
604 let |
606 val arg_ty = domain_type o fastype_of |
605 val arg_ty = domain_type o fastype_of |
607 val alpha_names = map (fst o dest_Const) alpha_trms |
606 val alpha_names = map (fst o dest_Const) alpha_trms |
608 val ty_assoc = map (fn t => (arg_ty t, t)) alpha_trms |
607 val ty_assoc = map (fn t => (arg_ty t, t)) alpha_trms |
609 val props = map (fn t => (lookup ty_assoc (arg_ty t), fn (x, y) => t $ x $ y)) alpha_bn_trms |
608 val props = map (fn t => (lookup ty_assoc (arg_ty t), fn (x, y) => t $ x $ y)) alpha_bn_trms |
610 in |
609 in |
611 alpha_prove (alpha_trms @ alpha_bn_trms) props alpha_induct |
610 alpha_prove (alpha_trms @ alpha_bn_trms) props alpha_induct |
612 (raw_prove_bn_imp_tac alpha_names alpha_intros) ctxt |
611 (raw_prove_bn_imp_tac alpha_names alpha_intros) ctxt |
613 end |
612 end |
614 |
613 |
615 |
614 |
616 (* respectfulness for fv_raw / bn_raw *) |
615 (* respectfulness for fv_raw / bn_raw *) |
617 |
616 |
618 fun raw_fv_bn_rsp_aux alpha_trms alpha_bn_trms fvs bns fv_bns alpha_induct simps ctxt = |
617 fun raw_fv_bn_rsp_aux alpha_trms alpha_bn_trms fvs bns fv_bns alpha_induct simps ctxt = |
619 let |
618 let |
620 val arg_ty = domain_type o fastype_of |
619 val arg_ty = domain_type o fastype_of |
621 val ty_assoc = map (fn t => (arg_ty t, t)) alpha_trms |
620 val ty_assoc = map (fn t => (arg_ty t, t)) alpha_trms |
622 fun mk_eq' t x y = HOLogic.mk_eq (t $ x, t $ y) |
621 fun mk_eq' t x y = HOLogic.mk_eq (t $ x, t $ y) |
623 |
622 |
624 val prop1 = map (fn t => (lookup ty_assoc (arg_ty t), fn (x, y) => mk_eq' t x y)) fvs |
623 val prop1 = map (fn t => (lookup ty_assoc (arg_ty t), fn (x, y) => mk_eq' t x y)) fvs |
625 val prop2 = map (fn t => (lookup ty_assoc (arg_ty t), fn (x, y) => mk_eq' t x y)) (bns @ fv_bns) |
624 val prop2 = map (fn t => (lookup ty_assoc (arg_ty t), fn (x, y) => mk_eq' t x y)) (bns @ fv_bns) |
626 val prop3 = map2 (fn t1 => fn t2 => (t1, fn (x, y) => mk_eq' t2 x y)) alpha_bn_trms fv_bns |
625 val prop3 = map2 (fn t1 => fn t2 => (t1, fn (x, y) => mk_eq' t2 x y)) alpha_bn_trms fv_bns |
627 |
626 |
628 val ss = HOL_ss addsimps (simps @ @{thms alphas prod_fv.simps set.simps append.simps} |
627 val ss = HOL_ss addsimps (simps @ @{thms alphas prod_fv.simps set.simps append.simps} |
629 @ @{thms Un_assoc Un_insert_left Un_empty_right Un_empty_left}) |
628 @ @{thms Un_assoc Un_insert_left Un_empty_right Un_empty_left}) |
630 |
629 |
631 in |
630 in |
632 alpha_prove (alpha_trms @ alpha_bn_trms) (prop1 @ prop2 @ prop3) alpha_induct |
631 alpha_prove (alpha_trms @ alpha_bn_trms) (prop1 @ prop2 @ prop3) alpha_induct |
633 (K (asm_full_simp_tac ss)) ctxt |
632 (K (asm_full_simp_tac ss)) ctxt |
634 end |
633 end |
635 |
634 |
636 |
635 |
637 (* respectfulness for size *) |
636 (* respectfulness for size *) |
638 |
637 |
639 fun raw_size_rsp_aux all_alpha_trms alpha_induct simps ctxt = |
638 fun raw_size_rsp_aux all_alpha_trms alpha_induct simps ctxt = |
640 let |
639 let |
641 val arg_tys = map (domain_type o fastype_of) all_alpha_trms |
640 val arg_tys = map (domain_type o fastype_of) all_alpha_trms |
642 |
641 |
643 fun mk_prop ty (x, y) = HOLogic.mk_eq |
642 fun mk_prop ty (x, y) = HOLogic.mk_eq |
644 (HOLogic.size_const ty $ x, HOLogic.size_const ty $ y) |
643 (HOLogic.size_const ty $ x, HOLogic.size_const ty $ y) |
645 |
644 |
646 val props = map2 (fn trm => fn ty => (trm, mk_prop ty)) all_alpha_trms arg_tys |
645 val props = map2 (fn trm => fn ty => (trm, mk_prop ty)) all_alpha_trms arg_tys |
647 |
646 |
648 val ss = HOL_ss addsimps (simps @ @{thms alphas prod_alpha_def prod_rel.simps |
647 val ss = HOL_ss addsimps (simps @ @{thms alphas prod_alpha_def prod_rel.simps |
649 permute_prod_def prod.cases prod.recs}) |
648 permute_prod_def prod.cases prod.recs}) |
650 |
649 |
651 val tac = (TRY o REPEAT o etac @{thm exE}) THEN' asm_full_simp_tac ss |
650 val tac = (TRY o REPEAT o etac @{thm exE}) THEN' asm_full_simp_tac ss |
652 in |
651 in |
653 alpha_prove all_alpha_trms props alpha_induct (K tac) ctxt |
652 alpha_prove all_alpha_trms props alpha_induct (K tac) ctxt |
654 end |
653 end |
655 |
654 |
656 |
655 |
657 (* respectfulness for constructors *) |
656 (* respectfulness for constructors *) |
658 |
657 |
659 fun raw_constr_rsp_tac alpha_intros simps = |
658 fun raw_constr_rsp_tac alpha_intros simps = |
660 let |
659 let |
661 val pre_ss = HOL_ss addsimps @{thms fun_rel_def} |
660 val pre_ss = HOL_ss addsimps @{thms fun_rel_def} |
662 val post_ss = HOL_ss addsimps @{thms alphas prod_alpha_def prod_rel.simps |
661 val post_ss = HOL_ss addsimps @{thms alphas prod_alpha_def prod_rel.simps |
663 prod_fv.simps fresh_star_zero permute_zero prod.cases} @ simps |
662 prod_fv.simps fresh_star_zero permute_zero prod.cases} @ simps |
664 (* funs_rsp alpha_bn_simps *) |
663 in |
665 in |
664 asm_full_simp_tac pre_ss |
666 asm_full_simp_tac pre_ss |
665 THEN' REPEAT o (resolve_tac @{thms allI impI}) |
667 THEN' REPEAT o (resolve_tac @{thms allI impI}) |
666 THEN' resolve_tac alpha_intros |
668 THEN' resolve_tac alpha_intros |
667 THEN_ALL_NEW (TRY o (rtac exi_zero) THEN' asm_full_simp_tac post_ss) |
669 THEN_ALL_NEW (TRY o (rtac exi_zero) THEN' asm_full_simp_tac post_ss) |
668 end |
670 end |
|
671 |
669 |
672 |
670 |
673 fun raw_constrs_rsp constrs alpha_trms alpha_intros simps ctxt = |
671 fun raw_constrs_rsp constrs alpha_trms alpha_intros simps ctxt = |
674 let |
672 let |
675 val alpha_arg_tys = map (domain_type o fastype_of) alpha_trms |
673 val alpha_arg_tys = map (domain_type o fastype_of) alpha_trms |
676 |
674 |
677 fun lookup ty = |
675 fun lookup ty = |
678 case AList.lookup (op=) (alpha_arg_tys ~~ alpha_trms) ty of |
676 case AList.lookup (op=) (alpha_arg_tys ~~ alpha_trms) ty of |
679 NONE => HOLogic.eq_const ty |
677 NONE => HOLogic.eq_const ty |
680 | SOME alpha => alpha |
678 | SOME alpha => alpha |
681 |
679 |
682 fun fun_rel_app t1 t2 = |
680 fun fun_rel_app t1 t2 = |
683 Const (@{const_name "fun_rel"}, dummyT) $ t1 $ t2 |
681 Const (@{const_name "fun_rel"}, dummyT) $ t1 $ t2 |
684 |
682 |
685 fun prep_goal trm = |
683 fun prep_goal trm = |
686 trm |
684 trm |
687 |> strip_type o fastype_of |
685 |> strip_type o fastype_of |
688 |>> map lookup |
686 |>> map lookup |
689 ||> lookup |
687 ||> lookup |
690 |> uncurry (fold_rev fun_rel_app) |
688 |> uncurry (fold_rev fun_rel_app) |
691 |> (fn t => t $ trm $ trm) |
689 |> (fn t => t $ trm $ trm) |
692 |> Syntax.check_term ctxt |
690 |> Syntax.check_term ctxt |
693 |> HOLogic.mk_Trueprop |
691 |> HOLogic.mk_Trueprop |
694 in |
692 in |
695 Goal.prove_multi ctxt [] [] (map prep_goal constrs) |
693 Goal.prove_multi ctxt [] [] (map prep_goal constrs) |
696 (K (HEADGOAL |
694 (K (HEADGOAL |
697 (Goal.conjunction_tac THEN_ALL_NEW raw_constr_rsp_tac alpha_intros simps))) |
695 (Goal.conjunction_tac THEN_ALL_NEW raw_constr_rsp_tac alpha_intros simps))) |
698 end |
696 end |
699 |
697 |
700 |
698 |
701 (* rsp lemmas for alpha_bn relations *) |
699 (* rsp lemmas for alpha_bn relations *) |
702 |
700 |
703 val rsp_equivp = |
701 val rsp_equivp = |