460 by (cases p) simp |
460 by (cases p) simp |
461 |
461 |
462 lemma The_split: "The (split P) = (THE xy. P (fst xy) (snd xy))" |
462 lemma The_split: "The (split P) = (THE xy. P (fst xy) (snd xy))" |
463 by (simp add: case_prod_unfold) |
463 by (simp add: case_prod_unfold) |
464 |
464 |
465 lemma split_weak_cong: "p = q \<Longrightarrow> split c p = split c q" |
465 lemmas split_weak_cong = prod.case_cong_weak |
466 -- {* Prevents simplification of @{term c}: much faster *} |
466 -- {* Prevents simplification of @{term c}: much faster *} |
467 by (fact prod.case_cong_weak) |
|
468 |
467 |
469 lemma cond_split_eta: "(!!x y. f x y = g (x, y)) ==> (%(x, y). f x y) = g" |
468 lemma cond_split_eta: "(!!x y. f x y = g (x, y)) ==> (%(x, y). f x y) = g" |
470 by (simp add: split_eta) |
469 by (simp add: split_eta) |
471 |
470 |
472 lemma split_paired_all [no_atp]: "(!!x. PROP P x) == (!!a b. PROP P (a, b))" |
471 lemma split_paired_all [no_atp]: "(!!x. PROP P x) == (!!a b. PROP P (a, b))" |
575 SOME (i, f) => SOME (metaeq ctxt s (subst arg 0 i f)) |
574 SOME (i, f) => SOME (metaeq ctxt s (subst arg 0 i f)) |
576 | NONE => NONE) |
575 | NONE => NONE) |
577 | beta_proc _ _ = NONE; |
576 | beta_proc _ _ = NONE; |
578 fun eta_proc ctxt (s as Const (@{const_name case_prod}, _) $ Abs (_, _, t)) = |
577 fun eta_proc ctxt (s as Const (@{const_name case_prod}, _) $ Abs (_, _, t)) = |
579 (case split_pat eta_term_pat 1 t of |
578 (case split_pat eta_term_pat 1 t of |
580 SOME (_, ft) => SOME (metaeq ctxt s (let val (f $ arg) = ft in f end)) |
579 SOME (_, ft) => SOME (metaeq ctxt s (let val f $ _ = ft in f end)) |
581 | NONE => NONE) |
580 | NONE => NONE) |
582 | eta_proc _ _ = NONE; |
581 | eta_proc _ _ = NONE; |
583 end; |
582 end; |
584 *} |
583 *} |
585 simproc_setup split_beta ("split f z") = {* fn _ => fn ctxt => fn ct => beta_proc ctxt (term_of ct) *} |
584 simproc_setup split_beta ("split f z") = {* fn _ => fn ctxt => fn ct => beta_proc ctxt (term_of ct) *} |
586 simproc_setup split_eta ("split f") = {* fn _ => fn ctxt => fn ct => eta_proc ctxt (term_of ct) *} |
585 simproc_setup split_eta ("split f") = {* fn _ => fn ctxt => fn ct => eta_proc ctxt (term_of ct) *} |
587 |
586 |
588 lemma split_beta [mono]: "(%(x, y). P x y) z = P (fst z) (snd z)" |
587 lemmas split_beta [mono] = prod.case_eq_if |
589 by (subst surjective_pairing, rule split_conv) |
|
590 |
588 |
591 lemma split_beta': "(\<lambda>(x,y). f x y) = (\<lambda>x. f (fst x) (snd x))" |
589 lemma split_beta': "(\<lambda>(x,y). f x y) = (\<lambda>x. f (fst x) (snd x))" |
592 by (auto simp: fun_eq_iff) |
590 by (auto simp: fun_eq_iff) |
593 |
591 |
594 |
592 lemmas split_split [no_atp] = prod.split |
595 lemma split_split [no_atp]: "R(split c p) = (ALL x y. p = (x, y) --> R(c x y))" |
|
596 -- {* For use with @{text split} and the Simplifier. *} |
593 -- {* For use with @{text split} and the Simplifier. *} |
597 by (insert surj_pair [of p], clarify, simp) |
|
598 |
594 |
599 text {* |
595 text {* |
600 @{thm [source] split_split} could be declared as @{text "[split]"} |
596 @{thm [source] split_split} could be declared as @{text "[split]"} |
601 done after the Splitter has been speeded up significantly; |
597 done after the Splitter has been speeded up significantly; |
602 precompute the constants involved and don't do anything unless the |
598 precompute the constants involved and don't do anything unless the |
603 current goal contains one of those constants. |
599 current goal contains one of those constants. |
604 *} |
600 *} |
605 |
601 |
606 lemma split_split_asm [no_atp]: "R (split c p) = (~(EX x y. p = (x, y) & (~R (c x y))))" |
602 lemmas split_split_asm [no_atp] = prod.split_asm |
607 by (subst split_split, simp) |
|
608 |
603 |
609 text {* |
604 text {* |
610 \medskip @{term split} used as a logical connective or set former. |
605 \medskip @{term split} used as a logical connective or set former. |
611 |
606 |
612 \medskip These rules are for use with @{text blast}; could instead |
607 \medskip These rules are for use with @{text blast}; could instead |
647 |
642 |
648 lemma mem_splitI2: "!!p. [| !!a b. p = (a, b) ==> z: c a b |] ==> z: split c p" |
643 lemma mem_splitI2: "!!p. [| !!a b. p = (a, b) ==> z: c a b |] ==> z: split c p" |
649 by (simp only: split_tupled_all, simp) |
644 by (simp only: split_tupled_all, simp) |
650 |
645 |
651 lemma mem_splitE: |
646 lemma mem_splitE: |
652 assumes major: "z \<in> split c p" |
647 assumes "z \<in> split c p" |
653 and cases: "\<And>x y. p = (x, y) \<Longrightarrow> z \<in> c x y \<Longrightarrow> Q" |
648 obtains x y where "p = (x, y)" and "z \<in> c x y" |
654 shows Q |
649 using assms by (rule splitE2) |
655 by (rule major [unfolded case_prod_unfold] cases surjective_pairing)+ |
|
656 |
650 |
657 declare mem_splitI2 [intro!] mem_splitI [intro!] splitI2' [intro!] splitI2 [intro!] splitI [intro!] |
651 declare mem_splitI2 [intro!] mem_splitI [intro!] splitI2' [intro!] splitI2 [intro!] splitI [intro!] |
658 declare mem_splitE [elim!] splitE' [elim!] splitE [elim!] |
652 declare mem_splitE [elim!] splitE' [elim!] splitE [elim!] |
659 |
653 |
660 ML {* |
654 ML {* |