537 |
537 |
538 (* conversion *) |
538 (* conversion *) |
539 |
539 |
540 fun all_exists_conv cv ctxt ct = |
540 fun all_exists_conv cv ctxt ct = |
541 (case Thm.term_of ct of |
541 (case Thm.term_of ct of |
542 Const (@{const_name HOL.Ex}, _) $ Abs _ => |
542 Const (@{const_name Ex}, _) $ Abs _ => |
543 Conv.arg_conv (Conv.abs_conv (all_exists_conv cv o #2) ctxt) ct |
543 Conv.arg_conv (Conv.abs_conv (all_exists_conv cv o #2) ctxt) ct |
544 | _ => cv ctxt ct) |
544 | _ => cv ctxt ct) |
545 |
545 |
546 fun all_but_last_exists_conv cv ctxt ct = |
546 fun all_but_last_exists_conv cv ctxt ct = |
547 (case Thm.term_of ct of |
547 (case Thm.term_of ct of |
548 Const (@{const_name HOL.Ex}, _) $ Abs (_, _, Const (@{const_name HOL.Ex}, _) $ _) => |
548 Const (@{const_name Ex}, _) $ Abs (_, _, Const (@{const_name Ex}, _) $ _) => |
549 Conv.arg_conv (Conv.abs_conv (all_but_last_exists_conv cv o #2) ctxt) ct |
549 Conv.arg_conv (Conv.abs_conv (all_but_last_exists_conv cv o #2) ctxt) ct |
550 | _ => cv ctxt ct) |
550 | _ => cv ctxt ct) |
551 |
551 |
552 fun Collect_conv cv ctxt ct = |
552 fun Collect_conv cv ctxt ct = |
553 (case Thm.term_of ct of |
553 (case Thm.term_of ct of |
554 Const (@{const_name Set.Collect}, _) $ Abs _ => Conv.arg_conv (Conv.abs_conv cv ctxt) ct |
554 Const (@{const_name Collect}, _) $ Abs _ => Conv.arg_conv (Conv.abs_conv cv ctxt) ct |
555 | _ => raise CTERM ("Collect_conv", [ct])) |
555 | _ => raise CTERM ("Collect_conv", [ct])) |
556 |
556 |
557 fun rewr_conv' th = Conv.rewr_conv (mk_meta_eq th) |
557 fun rewr_conv' th = Conv.rewr_conv (mk_meta_eq th) |
558 |
558 |
559 fun conjunct_assoc_conv ct = |
559 fun conjunct_assoc_conv ct = |
565 (Collect_conv (all_exists_conv conv o #2) ctxt)) |
565 (Collect_conv (all_exists_conv conv o #2) ctxt)) |
566 |
566 |
567 |
567 |
568 (* term abstraction of list comprehension patterns *) |
568 (* term abstraction of list comprehension patterns *) |
569 |
569 |
570 datatype termlets = If | Case of (typ * int) |
570 datatype termlets = If | Case of typ * int |
571 |
571 |
572 fun simproc ctxt redex = |
572 fun simproc ctxt redex = |
573 let |
573 let |
574 val set_Nil_I = @{thm trans} OF [@{thm list.set(1)}, @{thm empty_def}] |
574 val set_Nil_I = @{lemma "set [] = {x. False}" by (simp add: empty_def [symmetric])} |
575 val set_singleton = @{lemma "set [a] = {x. x = a}" by simp} |
575 val set_singleton = @{lemma "set [a] = {x. x = a}" by simp} |
576 val inst_Collect_mem_eq = @{lemma "set A = {x. x : set A}" by simp} |
576 val inst_Collect_mem_eq = @{lemma "set A = {x. x : set A}" by simp} |
577 val del_refl_eq = @{lemma "(t = t & P) == P" by simp} |
577 val del_refl_eq = @{lemma "(t = t \<and> P) \<equiv> P" by simp} |
578 fun mk_set T = Const (@{const_name List.set}, HOLogic.listT T --> HOLogic.mk_setT T) |
578 fun mk_set T = Const (@{const_name set}, HOLogic.listT T --> HOLogic.mk_setT T) |
579 fun dest_set (Const (@{const_name List.set}, _) $ xs) = xs |
579 fun dest_set (Const (@{const_name set}, _) $ xs) = xs |
580 fun dest_singleton_list (Const (@{const_name List.Cons}, _) |
580 fun dest_singleton_list (Const (@{const_name Cons}, _) $ t $ (Const (@{const_name Nil}, _))) = t |
581 $ t $ (Const (@{const_name List.Nil}, _))) = t |
|
582 | dest_singleton_list t = raise TERM ("dest_singleton_list", [t]) |
581 | dest_singleton_list t = raise TERM ("dest_singleton_list", [t]) |
583 (* We check that one case returns a singleton list and all other cases |
582 (* We check that one case returns a singleton list and all other cases |
584 return [], and return the index of the one singleton list case *) |
583 return [], and return the index of the one singleton list case *) |
585 fun possible_index_of_singleton_case cases = |
584 fun possible_index_of_singleton_case cases = |
586 let |
585 let |
587 fun check (i, case_t) s = |
586 fun check (i, case_t) s = |
588 (case strip_abs_body case_t of |
587 (case strip_abs_body case_t of |
589 (Const (@{const_name List.Nil}, _)) => s |
588 (Const (@{const_name Nil}, _)) => s |
590 | _ => (case s of SOME NONE => SOME (SOME i) | _ => NONE)) |
589 | _ => (case s of SOME NONE => SOME (SOME i) | _ => NONE)) |
591 in |
590 in |
592 fold_index check cases (SOME NONE) |> the_default NONE |
591 fold_index check cases (SOME NONE) |> the_default NONE |
593 end |
592 end |
594 (* returns (case_expr type index chosen_case constr_name) option *) |
593 (* returns (case_expr type index chosen_case constr_name) option *) |
622 THEN rtac @{thm impI} 1 |
621 THEN rtac @{thm impI} 1 |
623 THEN Subgoal.FOCUS (fn {prems, context, ...} => |
622 THEN Subgoal.FOCUS (fn {prems, context, ...} => |
624 CONVERSION (right_hand_set_comprehension_conv (K |
623 CONVERSION (right_hand_set_comprehension_conv (K |
625 (HOLogic.conj_conv (Conv.rewr_conv (List.last prems RS @{thm Eq_TrueI})) Conv.all_conv |
624 (HOLogic.conj_conv (Conv.rewr_conv (List.last prems RS @{thm Eq_TrueI})) Conv.all_conv |
626 then_conv |
625 then_conv |
627 rewr_conv' @{lemma "(True & P) = P" by simp})) context) 1) ctxt 1 |
626 rewr_conv' @{lemma "(True \<and> P) = P" by simp})) context) 1) ctxt 1 |
628 THEN tac ctxt cont |
627 THEN tac ctxt cont |
629 THEN rtac @{thm impI} 1 |
628 THEN rtac @{thm impI} 1 |
630 THEN Subgoal.FOCUS (fn {prems, context, ...} => |
629 THEN Subgoal.FOCUS (fn {prems, context, ...} => |
631 CONVERSION (right_hand_set_comprehension_conv (K |
630 CONVERSION (right_hand_set_comprehension_conv (K |
632 (HOLogic.conj_conv (Conv.rewr_conv (List.last prems RS @{thm Eq_FalseI})) Conv.all_conv |
631 (HOLogic.conj_conv (Conv.rewr_conv (List.last prems RS @{thm Eq_FalseI})) Conv.all_conv |
633 then_conv rewr_conv' @{lemma "(False & P) = False" by simp})) context) 1) ctxt 1 |
632 then_conv rewr_conv' @{lemma "(False \<and> P) = False" by simp})) context) 1) ctxt 1 |
634 THEN rtac set_Nil_I 1 |
633 THEN rtac set_Nil_I 1 |
635 | tac ctxt (Case (T, i) :: cont) = |
634 | tac ctxt (Case (T, i) :: cont) = |
636 let |
635 let |
637 val SOME {injects, distincts, case_thms, split, ...} = |
636 val SOME {injects, distincts, case_thms, split, ...} = |
638 Ctr_Sugar.ctr_sugar_of ctxt (fst (dest_Type T)) |
637 Ctr_Sugar.ctr_sugar_of ctxt (fst (dest_Type T)) |
655 then_conv conjunct_assoc_conv)) context |
654 then_conv conjunct_assoc_conv)) context |
656 then_conv (HOLogic.Trueprop_conv (HOLogic.eq_conv Conv.all_conv (Collect_conv (fn (_, ctxt) => |
655 then_conv (HOLogic.Trueprop_conv (HOLogic.eq_conv Conv.all_conv (Collect_conv (fn (_, ctxt) => |
657 Conv.repeat_conv |
656 Conv.repeat_conv |
658 (all_but_last_exists_conv |
657 (all_but_last_exists_conv |
659 (K (rewr_conv' |
658 (K (rewr_conv' |
660 @{lemma "(EX x. x = t & P x) = P t" by simp})) ctxt)) context)))) 1) ctxt 1 |
659 @{lemma "(\<exists>x. x = t \<and> P x) = P t" by simp})) ctxt)) context)))) 1) ctxt 1 |
661 THEN tac ctxt cont |
660 THEN tac ctxt cont |
662 else |
661 else |
663 Subgoal.FOCUS (fn {prems, context, ...} => |
662 Subgoal.FOCUS (fn {prems, context, ...} => |
664 CONVERSION |
663 CONVERSION |
665 (right_hand_set_comprehension_conv (K |
664 (right_hand_set_comprehension_conv (K |
666 (HOLogic.conj_conv |
665 (HOLogic.conj_conv |
667 ((HOLogic.eq_conv Conv.all_conv |
666 ((HOLogic.eq_conv Conv.all_conv |
668 (rewr_conv' (List.last prems))) then_conv |
667 (rewr_conv' (List.last prems))) then_conv |
669 (Conv.rewrs_conv (map (fn th => th RS @{thm Eq_FalseI}) distincts))) |
668 (Conv.rewrs_conv (map (fn th => th RS @{thm Eq_FalseI}) distincts))) |
670 Conv.all_conv then_conv |
669 Conv.all_conv then_conv |
671 (rewr_conv' @{lemma "(False & P) = False" by simp}))) context then_conv |
670 (rewr_conv' @{lemma "(False \<and> P) = False" by simp}))) context then_conv |
672 HOLogic.Trueprop_conv |
671 HOLogic.Trueprop_conv |
673 (HOLogic.eq_conv Conv.all_conv |
672 (HOLogic.eq_conv Conv.all_conv |
674 (Collect_conv (fn (_, ctxt) => |
673 (Collect_conv (fn (_, ctxt) => |
675 Conv.repeat_conv |
674 Conv.repeat_conv |
676 (Conv.bottom_conv |
675 (Conv.bottom_conv |
677 (K (rewr_conv' |
676 (K (rewr_conv' |
678 @{lemma "(EX x. P) = P" by simp})) ctxt)) context))) 1) ctxt 1 |
677 @{lemma "(\<exists>x. P) = P" by simp})) ctxt)) context))) 1) ctxt 1 |
679 THEN rtac set_Nil_I 1)) case_thms) |
678 THEN rtac set_Nil_I 1)) case_thms) |
680 end |
679 end |
681 fun make_inner_eqs bound_vs Tis eqs t = |
680 fun make_inner_eqs bound_vs Tis eqs t = |
682 (case dest_case t of |
681 (case dest_case t of |
683 SOME (x, T, i, cont, constr_name) => |
682 SOME (x, T, i, cont, constr_name) => |
697 SOME (condition, cont) => make_inner_eqs bound_vs (If :: Tis) (condition :: eqs) cont |
696 SOME (condition, cont) => make_inner_eqs bound_vs (If :: Tis) (condition :: eqs) cont |
698 | NONE => |
697 | NONE => |
699 if eqs = [] then NONE (* no rewriting, nothing to be done *) |
698 if eqs = [] then NONE (* no rewriting, nothing to be done *) |
700 else |
699 else |
701 let |
700 let |
702 val Type (@{type_name List.list}, [rT]) = fastype_of1 (map snd bound_vs, t) |
701 val Type (@{type_name list}, [rT]) = fastype_of1 (map snd bound_vs, t) |
703 val pat_eq = |
702 val pat_eq = |
704 (case try dest_singleton_list t of |
703 (case try dest_singleton_list t of |
705 SOME t' => |
704 SOME t' => |
706 Const (@{const_name HOL.eq}, rT --> rT --> @{typ bool}) $ |
705 Const (@{const_name HOL.eq}, rT --> rT --> @{typ bool}) $ |
707 Bound (length bound_vs) $ t' |
706 Bound (length bound_vs) $ t' |