163 |
163 |
164 (* strip_bn_fun takes a rhs of a bn function: this can only contain unions or |
164 (* strip_bn_fun takes a rhs of a bn function: this can only contain unions or |
165 appends of elements; in case of recursive calls it retruns also the applied |
165 appends of elements; in case of recursive calls it retruns also the applied |
166 bn function *) |
166 bn function *) |
167 ML {* |
167 ML {* |
168 fun strip_bn_fun t = |
168 fun strip_bn_fun lthy args t = |
169 case t of |
169 let |
170 Const (@{const_name sup}, _) $ l $ r => strip_bn_fun l @ strip_bn_fun r |
170 fun aux t = |
171 | Const (@{const_name append}, _) $ l $ r => strip_bn_fun l @ strip_bn_fun r |
171 case t of |
172 | Const (@{const_name insert}, _) $ (Const (@{const_name atom}, _) $ Bound i) $ y => |
172 Const (@{const_name sup}, _) $ l $ r => aux l @ aux r |
173 (i, NONE) :: strip_bn_fun y |
173 | Const (@{const_name append}, _) $ l $ r => aux l @ aux r |
174 | Const (@{const_name Cons}, _) $ (Const (@{const_name atom}, _) $ Bound i) $ y => |
174 | Const (@{const_name insert}, _) $ (Const (@{const_name atom}, _) $ (x as Var _)) $ y => |
175 (i, NONE) :: strip_bn_fun y |
175 (find_index (equal x) args, NONE) :: aux y |
176 | Const (@{const_name bot}, _) => [] |
176 | Const (@{const_name Cons}, _) $ (Const (@{const_name atom}, _) $ (x as Var _)) $ y => |
177 | Const (@{const_name Nil}, _) => [] |
177 (find_index (equal x) args, NONE) :: aux y |
178 | (f as Free _) $ Bound i => [(i, SOME f)] |
178 | Const (@{const_name bot}, _) => [] |
179 | _ => error ("Unsupported binding function: " ^ (PolyML.makestring t)) |
179 | Const (@{const_name Nil}, _) => [] |
|
180 | (f as Const _) $ (x as Var _) => [(find_index (equal x) args, SOME f)] |
|
181 | _ => error ("Unsupported binding function: " ^ (Syntax.string_of_term lthy t)) |
|
182 in |
|
183 aux t |
|
184 end |
180 *} |
185 *} |
181 |
186 |
182 ML {* |
187 ML {* |
183 fun find [] _ = error ("cannot find element") |
188 fun find [] _ = error ("cannot find element") |
184 | find ((x, z)::xs) y = if (Long_Name.base_name x) = y then z else find xs y |
189 | find ((x, z)::xs) y = if (Long_Name.base_name x) = y then z else find xs y |
188 fun prep_bn_descr lthy dt_names dts eqs = |
193 fun prep_bn_descr lthy dt_names dts eqs = |
189 let |
194 let |
190 fun aux eq = |
195 fun aux eq = |
191 let |
196 let |
192 val (lhs, rhs) = eq |
197 val (lhs, rhs) = eq |
193 |> strip_qnt_body "all" |
|
194 |> HOLogic.dest_Trueprop |
198 |> HOLogic.dest_Trueprop |
195 |> HOLogic.dest_eq |
199 |> HOLogic.dest_eq |
196 val (bn_fun, [cnstr]) = strip_comb lhs |
200 val (bn_fun, [cnstr]) = strip_comb lhs |
197 val (_, ty) = dest_Free bn_fun |
201 val (_, ty) = dest_Const bn_fun |
198 val (ty_name, _) = dest_Type (domain_type ty) |
202 val (ty_name, _) = dest_Type (domain_type ty) |
199 val dt_index = find_index (fn x => x = ty_name) dt_names |
203 val dt_index = find_index (fn x => x = ty_name) dt_names |
200 val (cnstr_head, cnstr_args) = strip_comb cnstr |
204 val (cnstr_head, cnstr_args) = strip_comb cnstr |
201 val rhs_elements = strip_bn_fun rhs |
205 val rhs_elements = strip_bn_fun lthy cnstr_args rhs |
202 val included = map (apfst (fn i => length (cnstr_args) - i - 1)) rhs_elements |
206 val included = map (apfst (fn i => length (cnstr_args) - i - 1)) rhs_elements |
203 in |
207 in |
204 (dt_index, (bn_fun, (cnstr_head, included))) |
208 (dt_index, (bn_fun, (cnstr_head, included))) |
205 end |
209 end |
206 fun order dts i ts = |
210 fun order dts i ts = |
248 val bn_fun_env = bn_fun_strs ~~ bn_fun_strs' |
252 val bn_fun_env = bn_fun_strs ~~ bn_fun_strs' |
249 val bn_fun_full_env = map (pairself (Long_Name.qualify thy_name)) |
253 val bn_fun_full_env = map (pairself (Long_Name.qualify thy_name)) |
250 (bn_fun_strs ~~ bn_fun_strs') |
254 (bn_fun_strs ~~ bn_fun_strs') |
251 |
255 |
252 val (raw_dt_names, raw_dts) = rawify_dts dt_names dts dts_env |
256 val (raw_dt_names, raw_dts) = rawify_dts dt_names dts dts_env |
|
257 val raw_dt_names' = map (Long_Name.qualify thy_name) raw_dt_names |
253 val (raw_bn_funs, raw_bn_eqs) = rawify_bn_funs dts_env cnstrs_env bn_fun_env bn_funs bn_eqs |
258 val (raw_bn_funs, raw_bn_eqs) = rawify_bn_funs dts_env cnstrs_env bn_fun_env bn_funs bn_eqs |
254 val raw_bclauses = rawify_bclauses dts_env cnstrs_env bn_fun_env binds |
259 val raw_bclauses = rawify_bclauses dts_env cnstrs_env bn_fun_full_env binds |
255 val raw_bn_descr = prep_bn_descr lthy dt_full_names' raw_dts (map snd raw_bn_eqs) |
260 (*val raw_bn_descr = prep_bn_descr lthy dt_full_names' raw_dts (map snd raw_bn_eqs)*) |
256 |
261 |
257 val (raw_dt_names, lthy1) = add_datatype_wrapper raw_dt_names raw_dts lthy |
262 val (raw_dt_full_names, lthy1) = add_datatype_wrapper raw_dt_names raw_dts lthy |
258 val (raw_bn_funs2, raw_bn_eqs2, lthy2) = add_primrec_wrapper raw_bn_funs raw_bn_eqs lthy1 |
263 val (raw_bn_funs2, raw_bn_eqs2, lthy2) = add_primrec_wrapper raw_bn_funs raw_bn_eqs lthy1 |
259 |
264 |
260 val morphism_2_0 = ProofContext.export_morphism lthy2 lthy |
265 val raw_bn_descr = |
261 fun export_fun f (t, n , l) = (f t, n, map (map (apsnd (Option.map f))) l); |
266 prep_bn_descr lthy dt_full_names' raw_dts (map prop_of raw_bn_eqs2) |
262 val raw_bn_descr_exp = map (export_fun (Morphism.term morphism_2_0)) raw_bn_descr; |
267 in |
263 in |
268 (raw_dt_full_names, raw_bclauses, raw_bn_funs2, raw_bn_eqs2, raw_bn_descr, lthy2) |
264 (raw_dt_names, raw_bclauses, raw_bn_funs, raw_bn_eqs, raw_bn_funs2, raw_bn_eqs2, raw_bn_descr_exp, raw_bn_descr, lthy1) |
|
265 end |
269 end |
266 *} |
270 *} |
267 |
271 |
268 lemma equivp_hack: "equivp x" |
272 lemma equivp_hack: "equivp x" |
269 sorry |
273 sorry |
303 setup STEPS_setup |
307 setup STEPS_setup |
304 |
308 |
305 ML {* |
309 ML {* |
306 fun nominal_datatype2 dts bn_funs bn_eqs bclauses lthy = |
310 fun nominal_datatype2 dts bn_funs bn_eqs bclauses lthy = |
307 let |
311 let |
308 (* definition of the raw datatypes and raw bn-functions *) |
312 (* definition of the raw datatypes *) |
309 val (raw_dt_names, raw_bclauses, raw_bn_funs2, raw_bn_eqs2, raw_bn_funs, raw_bn_eqs, raw_bn_descr, raw_bn_descr2, lthy1) = |
313 val (raw_dt_names, raw_bclauses, raw_bn_funs, raw_bn_eqs, raw_bn_descr, lthy1) = |
310 if get_STEPS lthy > 1 then raw_nominal_decls dts bn_funs bn_eqs bclauses lthy |
314 if get_STEPS lthy > 1 then raw_nominal_decls dts bn_funs bn_eqs bclauses lthy |
311 else raise TEST lthy |
315 else raise TEST lthy |
312 |
|
313 val _ = tracing ("raw_bn_descr " ^ @{make_string} raw_bn_descr) |
|
314 val _ = tracing ("raw_bn_descr2 " ^ @{make_string} raw_bn_descr2) |
|
315 val _ = tracing ("raw_bclauses " ^ @{make_string} raw_bclauses) |
|
316 val _ = tracing ("raw_bn_fund " ^ @{make_string} raw_bn_funs) |
|
317 val _ = tracing ("raw_bn_eqs " ^ @{make_string} raw_bn_eqs) |
|
318 val _ = tracing ("raw_bn_fund2 " ^ @{make_string} raw_bn_funs2) |
|
319 val _ = tracing ("raw_bn_eqs2 " ^ cat_lines (map (Syntax.string_of_term lthy o snd) raw_bn_eqs2)) |
|
320 |
316 |
321 val dtinfo = Datatype.the_info (ProofContext.theory_of lthy1) (hd raw_dt_names) |
317 val dtinfo = Datatype.the_info (ProofContext.theory_of lthy1) (hd raw_dt_names) |
322 val {descr, sorts, ...} = dtinfo |
318 val {descr, sorts, ...} = dtinfo |
323 val all_tys = map (fn (i, _) => nth_dtyp descr sorts i) descr |
319 val all_tys = map (fn (i, _) => nth_dtyp descr sorts i) descr |
324 val all_full_tnames = map (fn (_, (n, _, _)) => n) descr |
320 val all_full_tnames = map (fn (_, (n, _, _)) => n) descr |
347 (* definition of raw fv_functions *) |
343 (* definition of raw fv_functions *) |
348 val lthy3 = Theory_Target.init NONE thy; |
344 val lthy3 = Theory_Target.init NONE thy; |
349 |
345 |
350 val (fv, fvbn, fv_def, lthy3a) = |
346 val (fv, fvbn, fv_def, lthy3a) = |
351 if get_STEPS lthy2 > 3 |
347 if get_STEPS lthy2 > 3 |
352 then define_raw_fvs (map (fn (x, _, _) => Binding.name_of x) raw_bn_funs2) (map snd raw_bn_eqs2) descr sorts raw_bn_descr2 raw_bn_descr2 raw_bclauses lthy3 |
348 then define_raw_fvs descr sorts raw_bn_funs raw_bn_descr raw_bclauses lthy3 |
353 else raise TEST lthy3 |
349 else raise TEST lthy3 |
354 |
350 |
355 |
351 |
356 (* definition of raw alphas *) |
352 (* definition of raw alphas *) |
357 val (((alpha_ts, alpha_intros), (alpha_cases, alpha_induct)), lthy4) = |
353 val (((alpha_ts, alpha_intros), (alpha_cases, alpha_induct)), lthy4) = |
360 else raise TEST lthy3a |
356 else raise TEST lthy3a |
361 |
357 |
362 val (alpha_ts_nobn, alpha_ts_bn) = chop (length fv) alpha_ts |
358 val (alpha_ts_nobn, alpha_ts_bn) = chop (length fv) alpha_ts |
363 |
359 |
364 val dts_names = map (fn (i, (s, _, _)) => (s, i)) descr; |
360 val dts_names = map (fn (i, (s, _, _)) => (s, i)) descr; |
365 val bn_tys = map (domain_type o fastype_of) raw_bn_funs; |
361 val bn_tys = map (domain_type o fastype_of) [] (*raw_bn_funs;*) |
366 val bn_nos = map (dtyp_no_of_typ dts_names) bn_tys; |
362 val bn_nos = map (dtyp_no_of_typ dts_names) bn_tys; |
367 val bns = raw_bn_funs ~~ bn_nos; |
363 val bns = [] (*raw_bn_funs*) ~~ bn_nos; |
368 val rel_dists = flat (map (distinct_rel lthy4 alpha_cases) |
364 val rel_dists = flat (map (distinct_rel lthy4 alpha_cases) |
369 (rel_distinct ~~ alpha_ts_nobn)); |
365 (rel_distinct ~~ alpha_ts_nobn)); |
370 val rel_dists_bn = flat (map (distinct_rel lthy4 alpha_cases) |
366 val rel_dists_bn = flat (map (distinct_rel lthy4 alpha_cases) |
371 ((map (fn i => nth rel_distinct i) bn_nos) ~~ alpha_ts_bn)) |
367 ((map (fn i => nth rel_distinct i) bn_nos) ~~ alpha_ts_bn)) |
372 |
368 |
374 val alpha_eq_iff = build_rel_inj alpha_intros (inject_thms @ distinct_thms) alpha_cases lthy4 |
370 val alpha_eq_iff = build_rel_inj alpha_intros (inject_thms @ distinct_thms) alpha_cases lthy4 |
375 val alpha_eq_iff_simp = map remove_loop alpha_eq_iff; |
371 val alpha_eq_iff_simp = map remove_loop alpha_eq_iff; |
376 |
372 |
377 (* proving equivariance lemmas *) |
373 (* proving equivariance lemmas *) |
378 val _ = warning "Proving equivariance"; |
374 val _ = warning "Proving equivariance"; |
379 val (bv_eqvt, lthy5) = prove_eqvt all_tys induct_thm (raw_bn_eqs @ raw_perm_defs) (map fst bns) lthy4 |
375 val (bv_eqvt, lthy5) = prove_eqvt all_tys induct_thm ((*raw_bn_eqs @*) raw_perm_defs) (map fst bns) lthy4 |
380 val (fv_eqvt, lthy6) = prove_eqvt all_tys induct_thm (fv_def @ raw_perm_defs) (fv @ fvbn) lthy5 |
376 val (fv_eqvt, lthy6) = prove_eqvt all_tys induct_thm (fv_def @ raw_perm_defs) (fv @ fvbn) lthy5 |
381 val (alpha_eqvt, lthy6a) = Nominal_Eqvt.equivariance alpha_ts alpha_induct alpha_intros lthy6; |
377 val (alpha_eqvt, lthy6a) = Nominal_Eqvt.equivariance alpha_ts alpha_induct alpha_intros lthy6; |
382 |
378 |
383 (* proving alpha equivalence *) |
379 (* proving alpha equivalence *) |
384 val _ = warning "Proving equivalence"; |
380 val _ = warning "Proving equivalence"; |
398 map (fn (cname, dts) => |
394 map (fn (cname, dts) => |
399 Const (cname, map (Datatype_Aux.typ_of_dtyp descr sorts) dts ---> |
395 Const (cname, map (Datatype_Aux.typ_of_dtyp descr sorts) dts ---> |
400 Datatype_Aux.typ_of_dtyp descr sorts (Datatype_Aux.DtRec i))) l) descr); |
396 Datatype_Aux.typ_of_dtyp descr sorts (Datatype_Aux.DtRec i))) l) descr); |
401 val (consts, const_defs, lthy8) = quotient_lift_consts_export qtys (const_names ~~ raw_consts) lthy7; |
397 val (consts, const_defs, lthy8) = quotient_lift_consts_export qtys (const_names ~~ raw_consts) lthy7; |
402 val _ = warning "Proving respects"; |
398 val _ = warning "Proving respects"; |
403 val bns_rsp_pre' = build_fvbv_rsps alpha_ts alpha_induct raw_bn_eqs (map fst bns) lthy8; |
399 val bns_rsp_pre' = build_fvbv_rsps alpha_ts alpha_induct [] (*raw_bn_eqs*) (map fst bns) lthy8; |
404 val (bns_rsp_pre, lthy9) = fold_map ( |
400 val (bns_rsp_pre, lthy9) = fold_map ( |
405 fn (bn_t, _) => prove_const_rsp qtys Binding.empty [bn_t] (fn _ => |
401 fn (bn_t, _) => prove_const_rsp qtys Binding.empty [bn_t] (fn _ => |
406 resolve_tac bns_rsp_pre' 1)) bns lthy8; |
402 resolve_tac bns_rsp_pre' 1)) bns lthy8; |
407 val bns_rsp = flat (map snd bns_rsp_pre); |
403 val bns_rsp = flat (map snd bns_rsp_pre); |
408 |
404 |
427 const_rsp_tac) raw_consts lthy11a |
423 const_rsp_tac) raw_consts lthy11a |
428 val qfv_names = map (unsuffix "_raw" o Long_Name.base_name o fst o dest_Const) (fv @ fvbn) |
424 val qfv_names = map (unsuffix "_raw" o Long_Name.base_name o fst o dest_Const) (fv @ fvbn) |
429 val (qfv_ts, qfv_defs, lthy12a) = quotient_lift_consts_export qtys (qfv_names ~~ (fv @ fvbn)) lthy12; |
425 val (qfv_ts, qfv_defs, lthy12a) = quotient_lift_consts_export qtys (qfv_names ~~ (fv @ fvbn)) lthy12; |
430 val (qfv_ts_nobn, qfv_ts_bn) = chop (length raw_perm_funs) qfv_ts; |
426 val (qfv_ts_nobn, qfv_ts_bn) = chop (length raw_perm_funs) qfv_ts; |
431 val qbn_names = map (fn (b, _ , _) => Name.of_binding b) bn_funs |
427 val qbn_names = map (fn (b, _ , _) => Name.of_binding b) bn_funs |
432 val (qbn_ts, qbn_defs, lthy12b) = quotient_lift_consts_export qtys (qbn_names ~~ raw_bn_funs) lthy12a; |
428 val (qbn_ts, qbn_defs, lthy12b) = quotient_lift_consts_export qtys (qbn_names ~~ [] (*raw_bn_funs*)) lthy12a; |
433 val qalpha_bn_names = map (unsuffix "_raw" o Long_Name.base_name o fst o dest_Const) alpha_ts_bn |
429 val qalpha_bn_names = map (unsuffix "_raw" o Long_Name.base_name o fst o dest_Const) alpha_ts_bn |
434 val (qalpha_ts_bn, qalphabn_defs, lthy12c) = |
430 val (qalpha_ts_bn, qalphabn_defs, lthy12c) = |
435 quotient_lift_consts_export qtys (qalpha_bn_names ~~ alpha_ts_bn) lthy12b; |
431 quotient_lift_consts_export qtys (qalpha_bn_names ~~ alpha_ts_bn) lthy12b; |
436 val _ = warning "Lifting permutations"; |
432 val _ = warning "Lifting permutations"; |
437 val thy = Local_Theory.exit_global lthy12c; |
433 val thy = Local_Theory.exit_global lthy12c; |
454 val (_, lthy14a) = Local_Theory.note ((suffix_bind "inducts", []), q_inducts) lthy14; |
450 val (_, lthy14a) = Local_Theory.note ((suffix_bind "inducts", []), q_inducts) lthy14; |
455 val q_perm = map (lift_thm qtys lthy14) raw_perm_defs; |
451 val q_perm = map (lift_thm qtys lthy14) raw_perm_defs; |
456 val lthy15 = note_simp_suffix "perm" q_perm lthy14a; |
452 val lthy15 = note_simp_suffix "perm" q_perm lthy14a; |
457 val q_fv = map (lift_thm qtys lthy15) fv_def; |
453 val q_fv = map (lift_thm qtys lthy15) fv_def; |
458 val lthy16 = note_simp_suffix "fv" q_fv lthy15; |
454 val lthy16 = note_simp_suffix "fv" q_fv lthy15; |
459 val q_bn = map (lift_thm qtys lthy16) raw_bn_eqs; |
455 val q_bn = map (lift_thm qtys lthy16) [] (*raw_bn_eqs;*) |
460 val lthy17 = note_simp_suffix "bn" q_bn lthy16; |
456 val lthy17 = note_simp_suffix "bn" q_bn lthy16; |
461 val _ = warning "Lifting eq-iff"; |
457 val _ = warning "Lifting eq-iff"; |
462 (*val _ = map tracing (map PolyML.makestring alpha_eq_iff);*) |
458 (*val _ = map tracing (map PolyML.makestring alpha_eq_iff);*) |
463 val eq_iff_unfolded0 = map (Local_Defs.unfold lthy17 @{thms alphas}) alpha_eq_iff_simp |
459 val eq_iff_unfolded0 = map (Local_Defs.unfold lthy17 @{thms alphas}) alpha_eq_iff_simp |
464 val eq_iff_unfolded1 = map (Local_Defs.unfold lthy17 @{thms Pair_eqvt}) eq_iff_unfolded0 |
460 val eq_iff_unfolded1 = map (Local_Defs.unfold lthy17 @{thms Pair_eqvt}) eq_iff_unfolded0 |
573 |> map (map (fn (_, antys, _, bns) => (map fst antys, bns))) |
569 |> map (map (fn (_, antys, _, bns) => (map fst antys, bns))) |
574 |
570 |
575 fun prep_binder env bn_str = |
571 fun prep_binder env bn_str = |
576 case (Syntax.read_term lthy bn_str) of |
572 case (Syntax.read_term lthy bn_str) of |
577 Free (x, _) => (NONE, index_lookup env x) |
573 Free (x, _) => (NONE, index_lookup env x) |
578 | Const (a, T) $ Free (x, _) => (SOME (Free (Long_Name.base_name a, T)), index_lookup env x) |
574 | Const (a, T) $ Free (x, _) => (SOME (Const (a, T)), index_lookup env x) |
579 | _ => error ("The term " ^ bn_str ^ " is not allowed as binding function.") |
575 | _ => error ("The term " ^ bn_str ^ " is not allowed as binding function.") |
580 |
576 |
581 fun prep_body env bn_str = index_lookup env bn_str |
577 fun prep_body env bn_str = index_lookup env bn_str |
582 |
578 |
583 fun prep_mode "bind" = Lst |
579 fun prep_mode "bind" = Lst |