17 val mk_alpha_eq_iff: Proof.context -> thm list -> thm list -> thm list -> thm list -> thm list |
17 val mk_alpha_eq_iff: Proof.context -> thm list -> thm list -> thm list -> thm list -> thm list |
18 |
18 |
19 val raw_prove_refl: term list -> term list -> thm list -> thm -> Proof.context -> thm list |
19 val raw_prove_refl: term list -> term list -> thm list -> thm -> Proof.context -> thm list |
20 val raw_prove_sym: term list -> thm list -> thm -> Proof.context -> thm list |
20 val raw_prove_sym: term list -> thm list -> thm -> Proof.context -> thm list |
21 val raw_prove_trans: term list -> thm list -> thm list -> thm -> thm list -> Proof.context -> thm list |
21 val raw_prove_trans: term list -> thm list -> thm list -> thm -> thm list -> Proof.context -> thm list |
|
22 val raw_prove_bn_imp: term list -> term list -> thm list -> thm -> Proof.context -> thm list |
22 end |
23 end |
23 |
24 |
24 structure Nominal_Dt_Alpha: NOMINAL_DT_ALPHA = |
25 structure Nominal_Dt_Alpha: NOMINAL_DT_ALPHA = |
25 struct |
26 struct |
|
27 |
|
28 fun lookup xs x = the (AList.lookup (op=) xs x) |
|
29 fun group xs = AList.group (op=) xs |
26 |
30 |
27 (** definition of the inductive rules for alpha and alpha_bn **) |
31 (** definition of the inductive rules for alpha and alpha_bn **) |
28 |
32 |
29 (* construct the compound terms for prod_fv and prod_alpha *) |
33 (* construct the compound terms for prod_fv and prod_alpha *) |
30 fun mk_prod_fv (t1, t2) = |
34 fun mk_prod_fv (t1, t2) = |
87 fun mk_alpha_bn_prem alpha_bn_map args args' bodies binder = |
91 fun mk_alpha_bn_prem alpha_bn_map args args' bodies binder = |
88 case binder of |
92 case binder of |
89 (NONE, _) => [] |
93 (NONE, _) => [] |
90 | (SOME bn, i) => |
94 | (SOME bn, i) => |
91 if member (op=) bodies i then [] |
95 if member (op=) bodies i then [] |
92 else [the (AList.lookup (op=) alpha_bn_map bn) $ (nth args i) $ (nth args' i)] |
96 else [lookup alpha_bn_map bn $ nth args i $ nth args' i] |
93 |
97 |
94 (* generat the premises for an alpha rule; mk_frees is used |
98 (* generat the premises for an alpha rule; mk_frees is used |
95 if no binders are present *) |
99 if no binders are present *) |
96 fun mk_alpha_prems lthy alpha_map alpha_bn_map is_rec (args, args') bclause = |
100 fun mk_alpha_prems lthy alpha_map alpha_bn_map is_rec (args, args') bclause = |
97 let |
101 let |
139 let |
143 let |
140 val arg_names = Datatype_Prop.make_tnames arg_tys |
144 val arg_names = Datatype_Prop.make_tnames arg_tys |
141 val arg_names' = Name.variant_list arg_names arg_names |
145 val arg_names' = Name.variant_list arg_names arg_names |
142 val args = map Free (arg_names ~~ arg_tys) |
146 val args = map Free (arg_names ~~ arg_tys) |
143 val args' = map Free (arg_names' ~~ arg_tys) |
147 val args' = map Free (arg_names' ~~ arg_tys) |
144 val alpha = fst (the (AList.lookup (op=) alpha_map ty)) |
148 val alpha = fst (lookup alpha_map ty) |
145 val concl = HOLogic.mk_Trueprop (alpha $ list_comb (constr, args) $ list_comb (constr, args')) |
149 val concl = HOLogic.mk_Trueprop (alpha $ list_comb (constr, args) $ list_comb (constr, args')) |
146 val prems = map (mk_alpha_prems lthy alpha_map alpha_bn_map is_rec (args, args')) bclauses |
150 val prems = map (mk_alpha_prems lthy alpha_map alpha_bn_map is_rec (args, args')) bclauses |
147 in |
151 in |
148 Library.foldr Logic.mk_implies (flat prems, concl) |
152 Library.foldr Logic.mk_implies (flat prems, concl) |
149 end |
153 end |
167 case AList.lookup (op=) bn_args i of |
171 case AList.lookup (op=) bn_args i of |
168 NONE => (case (AList.lookup (op=) alpha_map ty) of |
172 NONE => (case (AList.lookup (op=) alpha_map ty) of |
169 NONE => [HOLogic.mk_eq (arg, arg')] |
173 NONE => [HOLogic.mk_eq (arg, arg')] |
170 | SOME (alpha, _) => [alpha $ arg $ arg']) |
174 | SOME (alpha, _) => [alpha $ arg $ arg']) |
171 | SOME (NONE) => [] |
175 | SOME (NONE) => [] |
172 | SOME (SOME bn) => [the (AList.lookup (op=) alpha_bn_map bn) $ arg $ arg'] |
176 | SOME (SOME bn) => [lookup alpha_bn_map bn $ arg $ arg'] |
173 end |
177 end |
174 in |
178 in |
175 case bclause of |
179 case bclause of |
176 BC (_, [], bodies) => |
180 BC (_, [], bodies) => |
177 map HOLogic.mk_Trueprop |
181 map HOLogic.mk_Trueprop |
183 let |
187 let |
184 val arg_names = Datatype_Prop.make_tnames arg_tys |
188 val arg_names = Datatype_Prop.make_tnames arg_tys |
185 val arg_names' = Name.variant_list arg_names arg_names |
189 val arg_names' = Name.variant_list arg_names arg_names |
186 val args = map Free (arg_names ~~ arg_tys) |
190 val args = map Free (arg_names ~~ arg_tys) |
187 val args' = map Free (arg_names' ~~ arg_tys) |
191 val args' = map Free (arg_names' ~~ arg_tys) |
188 val alpha_bn = the (AList.lookup (op=) alpha_bn_map bn_trm) |
192 val alpha_bn = lookup alpha_bn_map bn_trm |
189 val concl = HOLogic.mk_Trueprop (alpha_bn $ list_comb (constr, args) $ list_comb (constr, args')) |
193 val concl = HOLogic.mk_Trueprop (alpha_bn $ list_comb (constr, args) $ list_comb (constr, args')) |
190 val prems = map (mk_alpha_bn lthy alpha_map alpha_bn_map bn_args is_rec (args, args')) bclauses |
194 val prems = map (mk_alpha_bn lthy alpha_map alpha_bn_map bn_args is_rec (args, args')) bclauses |
191 in |
195 in |
192 Library.foldr Logic.mk_implies (flat prems, concl) |
196 Library.foldr Logic.mk_implies (flat prems, concl) |
193 end |
197 end |
359 val arg_bn_tys = |
363 val arg_bn_tys = |
360 alpha_bns |
364 alpha_bns |
361 |> map fastype_of |
365 |> map fastype_of |
362 |> map domain_type |
366 |> map domain_type |
363 val arg_names = Datatype_Prop.make_tnames arg_tys |
367 val arg_names = Datatype_Prop.make_tnames arg_tys |
364 val arg_bn_names = map (fn ty => the (AList.lookup (op=) (arg_tys ~~ arg_names) ty)) arg_bn_tys |
368 val arg_bn_names = map (lookup (arg_tys ~~ arg_names)) arg_bn_tys |
365 val args = map Free (arg_names ~~ arg_tys) |
369 val args = map Free (arg_names ~~ arg_tys) |
366 val arg_bns = map Free (arg_bn_names ~~ arg_bn_tys) |
370 val arg_bns = map Free (arg_bn_names ~~ arg_bn_tys) |
367 val goal = |
371 val goal = |
368 AList.group (op=) ((arg_bns ~~ alpha_bns) @ (args ~~ alpha_trms)) |
372 group ((arg_bns ~~ alpha_bns) @ (args ~~ alpha_trms)) |
369 |> map (fn (ar, cnsts) => map (fn c => c $ ar $ ar) cnsts) |
373 |> map (fn (ar, cnsts) => map (fn c => c $ ar $ ar) cnsts) |
370 |> map (foldr1 HOLogic.mk_conj) |
374 |> map (foldr1 HOLogic.mk_conj) |
371 |> foldr1 HOLogic.mk_conj |
375 |> foldr1 HOLogic.mk_conj |
372 |> HOLogic.mk_Trueprop |
376 |> HOLogic.mk_Trueprop |
373 in |
377 in |
536 |> singleton (ProofContext.export ctxt' ctxt) |
540 |> singleton (ProofContext.export ctxt' ctxt) |
537 |> Datatype_Aux.split_conj_thm |
541 |> Datatype_Aux.split_conj_thm |
538 |> map (fn th => zero_var_indexes (th RS norm)) |
542 |> map (fn th => zero_var_indexes (th RS norm)) |
539 end |
543 end |
540 |
544 |
|
545 |
|
546 (* proves that alpha_raw implies alpha_bn *) |
|
547 |
|
548 fun is_true @{term "Trueprop True"} = true |
|
549 | is_true _ = false |
|
550 |
|
551 fun raw_prove_bn_imp_tac pred_names alpha_intros ctxt = |
|
552 Subgoal.FOCUS (fn {prems, context, ...} => |
|
553 let |
|
554 val prems' = flat (map Datatype_Aux.split_conj_thm prems) |
|
555 val prems'' = map (transform_prem1 context pred_names) prems' |
|
556 in |
|
557 HEADGOAL (REPEAT o |
|
558 FIRST' [ rtac @{thm TrueI}, |
|
559 rtac @{thm conjI}, |
|
560 resolve_tac prems', |
|
561 resolve_tac prems'', |
|
562 resolve_tac alpha_intros ]) |
|
563 end) ctxt |
|
564 |
|
565 fun raw_prove_bn_imp alpha_trms alpha_bns alpha_intros alpha_induct ctxt = |
|
566 let |
|
567 val alpha_names = map (fst o dest_Const) alpha_trms |
|
568 |
|
569 val arg_tys = |
|
570 alpha_trms |
|
571 |> map fastype_of |
|
572 |> map domain_type |
|
573 val arg_bn_tys = |
|
574 alpha_bns |
|
575 |> map fastype_of |
|
576 |> map domain_type |
|
577 val (arg_names1, (arg_names2, ctxt')) = |
|
578 ctxt |
|
579 |> Variable.variant_fixes (replicate (length arg_tys) "x") |
|
580 ||> Variable.variant_fixes (replicate (length arg_tys) "y") |
|
581 val arg_bn_names1 = map (lookup (arg_tys ~~ arg_names1)) arg_bn_tys |
|
582 val arg_bn_names2 = map (lookup (arg_tys ~~ arg_names2)) arg_bn_tys |
|
583 val args1 = map Free (arg_names1 ~~ arg_tys) |
|
584 val args2 = map Free (arg_names2 ~~ arg_tys) |
|
585 val arg_bns1 = map Free (arg_bn_names1 ~~ arg_bn_tys) |
|
586 val arg_bns2 = map Free (arg_bn_names2 ~~ arg_bn_tys) |
|
587 |
|
588 val alpha_bn_trms = map2 (fn t => fn (ar1, ar2) => t $ ar1 $ ar2) alpha_bns (arg_bns1 ~~ arg_bns2) |
|
589 val true_trms = map (K @{term True}) arg_tys |
|
590 |
|
591 val goal_rhs = |
|
592 group ((arg_bn_tys ~~ alpha_bn_trms) @ (arg_tys ~~ true_trms)) |
|
593 |> map snd |
|
594 |> map (foldr1 HOLogic.mk_conj) |
|
595 |
|
596 val goal_lhs = map2 (fn t => fn (ar1, ar2) => t $ ar1 $ ar2) alpha_trms (args1 ~~ args2) |
|
597 val goal_rest = map (fn t => HOLogic.mk_imp (t, @{term "True"})) alpha_bn_trms |
|
598 |
|
599 val goal = |
|
600 (map2 (curry HOLogic.mk_imp) goal_lhs goal_rhs) @ goal_rest |
|
601 |> foldr1 HOLogic.mk_conj |
|
602 |> HOLogic.mk_Trueprop |
|
603 in |
|
604 Goal.prove ctxt' [] [] goal |
|
605 (fn {context, ...} => |
|
606 HEADGOAL (DETERM o (rtac alpha_induct) |
|
607 THEN_ALL_NEW raw_prove_bn_imp_tac alpha_names alpha_intros context)) |
|
608 |> singleton (ProofContext.export ctxt' ctxt) |
|
609 |> Datatype_Aux.split_conj_thm |
|
610 |> map (fn th => zero_var_indexes (th RS mp)) |
|
611 |> map Datatype_Aux.split_conj_thm |
|
612 |> flat |
|
613 |> filter_out (is_true o concl_of) |
|
614 end |
|
615 |
|
616 |
541 end (* structure *) |
617 end (* structure *) |
542 |
618 |