src/HOL/List.thy
changeset 60156 76853162a87e
parent 59728 0bb88aa34768
child 60158 6696fc3f3347
equal deleted inserted replaced
60155:91477b3a2d6b 60156:76853162a87e
   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'