src/HOL/Library/Coinductive_List.thy
changeset 19086 1b3780be6cc2
parent 18730 843da46f89ac
child 20503 503ac4c5ef91
equal deleted inserted replaced
19085:a1a251b297dd 19086:1b3780be6cc2
     9 imports Main
     9 imports Main
    10 begin
    10 begin
    11 
    11 
    12 subsection {* List constructors over the datatype universe *}
    12 subsection {* List constructors over the datatype universe *}
    13 
    13 
    14 constdefs
    14 definition
    15   NIL :: "'a Datatype_Universe.item"
    15   "NIL = Datatype_Universe.In0 (Datatype_Universe.Numb 0)"
    16   "NIL \<equiv> Datatype_Universe.In0 (Datatype_Universe.Numb 0)"
    16   "CONS M N = Datatype_Universe.In1 (Datatype_Universe.Scons M N)"
    17   CONS :: "'a Datatype_Universe.item \<Rightarrow> 'a Datatype_Universe.item
       
    18     \<Rightarrow> 'a Datatype_Universe.item"
       
    19   "CONS M N \<equiv> Datatype_Universe.In1 (Datatype_Universe.Scons M N)"
       
    20 
    17 
    21 lemma CONS_not_NIL [iff]: "CONS M N \<noteq> NIL"
    18 lemma CONS_not_NIL [iff]: "CONS M N \<noteq> NIL"
    22   and NIL_not_CONS [iff]: "NIL \<noteq> CONS M N"
    19   and NIL_not_CONS [iff]: "NIL \<noteq> CONS M N"
    23   and CONS_inject [iff]: "(CONS K M) = (CONS L N) = (K = L \<and> M = N)"
    20   and CONS_inject [iff]: "(CONS K M) = (CONS L N) = (K = L \<and> M = N)"
    24   by (simp_all add: NIL_def CONS_def)
    21   by (simp_all add: NIL_def CONS_def)
    28 
    25 
    29 lemma CONS_UN1: "CONS M (\<Union>x. f x) = (\<Union>x. CONS M (f x))"
    26 lemma CONS_UN1: "CONS M (\<Union>x. f x) = (\<Union>x. CONS M (f x))"
    30     -- {* A continuity result? *}
    27     -- {* A continuity result? *}
    31   by (simp add: CONS_def In1_UN1 Scons_UN1_y)
    28   by (simp add: CONS_def In1_UN1 Scons_UN1_y)
    32 
    29 
    33 constdefs
    30 definition
    34   List_case where
    31   "List_case c h = Datatype_Universe.Case (\<lambda>_. c) (Datatype_Universe.Split h)"
    35   "List_case c h \<equiv> Datatype_Universe.Case (\<lambda>_. c) (Datatype_Universe.Split h)"
       
    36 
    32 
    37 lemma List_case_NIL [simp]: "List_case c h NIL = c"
    33 lemma List_case_NIL [simp]: "List_case c h NIL = c"
    38   and List_case_CONS [simp]: "List_case c h (CONS M N) = h M N"
    34   and List_case_CONS [simp]: "List_case c h (CONS M N) = h M N"
    39   by (simp_all add: List_case_def NIL_def CONS_def)
    35   by (simp_all add: List_case_def NIL_def CONS_def)
    40 
    36 
    61   "LList_corec_aux (Suc k) f x =
    57   "LList_corec_aux (Suc k) f x =
    62     (case f x of
    58     (case f x of
    63       None \<Rightarrow> NIL
    59       None \<Rightarrow> NIL
    64     | Some (z, w) \<Rightarrow> CONS z (LList_corec_aux k f w))"
    60     | Some (z, w) \<Rightarrow> CONS z (LList_corec_aux k f w))"
    65 
    61 
    66 constdefs
    62 definition
    67   LList_corec :: "'a \<Rightarrow> ('a \<Rightarrow> ('b Datatype_Universe.item \<times> 'a) option) \<Rightarrow>
    63   "LList_corec a f = (\<Union>k. LList_corec_aux k f a)"
    68     'b Datatype_Universe.item"
       
    69   "LList_corec a f \<equiv> \<Union>k. LList_corec_aux k f a"
       
    70 
    64 
    71 text {*
    65 text {*
    72   Note: the subsequent recursion equation for @{text LList_corec} may
    66   Note: the subsequent recursion equation for @{text LList_corec} may
    73   be used with the Simplifier, provided it operates in a non-strict
    67   be used with the Simplifier, provided it operates in a non-strict
    74   fashion for case expressions (i.e.\ the usual @{text case}
    68   fashion for case expressions (i.e.\ the usual @{text case}
   148     by (simp add: llist_def)
   142     by (simp add: llist_def)
   149   also have "\<dots> \<subseteq> LList UNIV" by (rule LList_mono) simp
   143   also have "\<dots> \<subseteq> LList UNIV" by (rule LList_mono) simp
   150   finally show ?thesis .
   144   finally show ?thesis .
   151 qed
   145 qed
   152 
   146 
   153 constdefs
   147 definition
   154   LNil :: "'a llist"
   148   "LNil = Abs_llist NIL"
   155   "LNil \<equiv> Abs_llist NIL"
   149   "LCons x xs = Abs_llist (CONS (Datatype_Universe.Leaf x) (Rep_llist xs))"
   156 
       
   157   LCons :: "'a \<Rightarrow> 'a llist \<Rightarrow> 'a llist"
       
   158   "LCons x xs \<equiv> Abs_llist (CONS (Datatype_Universe.Leaf x) (Rep_llist xs))"
       
   159 
   150 
   160 lemma LCons_not_LNil [iff]: "LCons x xs \<noteq> LNil"
   151 lemma LCons_not_LNil [iff]: "LCons x xs \<noteq> LNil"
   161   apply (simp add: LNil_def LCons_def)
   152   apply (simp add: LNil_def LCons_def)
   162   apply (subst Abs_llist_inject)
   153   apply (subst Abs_llist_inject)
   163     apply (auto intro: NIL_type CONS_type Rep_llist)
   154     apply (auto intro: NIL_type CONS_type Rep_llist)
   200     with LCons show ?thesis .
   191     with LCons show ?thesis .
   201   qed
   192   qed
   202 qed
   193 qed
   203 
   194 
   204 
   195 
   205 constdefs
   196 definition
   206   llist_case :: "'b \<Rightarrow> ('a \<Rightarrow> 'a llist \<Rightarrow> 'b) \<Rightarrow> 'a llist \<Rightarrow> 'b"
   197   "llist_case c d l =
   207   "llist_case c d l \<equiv>
       
   208     List_case c (\<lambda>x y. d (inv Datatype_Universe.Leaf x) (Abs_llist y)) (Rep_llist l)"
   198     List_case c (\<lambda>x y. d (inv Datatype_Universe.Leaf x) (Abs_llist y)) (Rep_llist l)"
   209 
       
   210 translations
   199 translations
   211   "case p of LNil \<Rightarrow> a | LCons x l \<Rightarrow> b" \<rightleftharpoons> "llist_case a (\<lambda>x l. b) p"
   200   "case p of LNil \<Rightarrow> a | LCons x l \<Rightarrow> b" \<rightleftharpoons> "llist_case a (\<lambda>x l. b) p"
   212 
   201 
   213 lemma llist_case_LNil [simp]: "llist_case c d LNil = c"
   202 lemma llist_case_LNil [simp]: "llist_case c d LNil = c"
   214   by (simp add: llist_case_def LNil_def
   203   by (simp add: llist_case_def LNil_def
   217 lemma llist_case_LCons [simp]: "llist_case c d (LCons M N) = d M N"
   206 lemma llist_case_LCons [simp]: "llist_case c d (LCons M N) = d M N"
   218   by (simp add: llist_case_def LCons_def
   207   by (simp add: llist_case_def LCons_def
   219     CONS_type Abs_llist_inverse Rep_llist Rep_llist_inverse inj_Leaf)
   208     CONS_type Abs_llist_inverse Rep_llist Rep_llist_inverse inj_Leaf)
   220 
   209 
   221 
   210 
   222 constdefs
   211 definition
   223   llist_corec :: "'a \<Rightarrow> ('a \<Rightarrow> ('b \<times> 'a) option) \<Rightarrow> 'b llist"
   212   "llist_corec a f =
   224   "llist_corec a f \<equiv>
       
   225     Abs_llist (LList_corec a
   213     Abs_llist (LList_corec a
   226       (\<lambda>z.
   214       (\<lambda>z.
   227         case f z of None \<Rightarrow> None
   215         case f z of None \<Rightarrow> None
   228         | Some (v, w) \<Rightarrow> Some (Datatype_Universe.Leaf v, w)))"
   216         | Some (v, w) \<Rightarrow> Some (Datatype_Universe.Leaf v, w)))"
   229 
   217 
   537 
   525 
   538 subsection {* Derived operations -- both on the set and abstract type *}
   526 subsection {* Derived operations -- both on the set and abstract type *}
   539 
   527 
   540 subsubsection {* @{text Lconst} *}
   528 subsubsection {* @{text Lconst} *}
   541 
   529 
   542 constdefs
   530 definition
   543   Lconst where
       
   544   "Lconst M \<equiv> lfp (\<lambda>N. CONS M N)"
   531   "Lconst M \<equiv> lfp (\<lambda>N. CONS M N)"
   545 
   532 
   546 lemma Lconst_fun_mono: "mono (CONS M)"
   533 lemma Lconst_fun_mono: "mono (CONS M)"
   547   by (simp add: monoI CONS_mono)
   534   by (simp add: monoI CONS_mono)
   548 
   535 
   578   done
   565   done
   579 
   566 
   580 
   567 
   581 subsubsection {* @{text Lmap} and @{text lmap} *}
   568 subsubsection {* @{text Lmap} and @{text lmap} *}
   582 
   569 
   583 constdefs
   570 definition
   584   Lmap where
   571   "Lmap f M = LList_corec M (List_case None (\<lambda>x M'. Some (f x, M')))"
   585   "Lmap f M \<equiv> LList_corec M (List_case None (\<lambda>x M'. Some (f x, M')))"
   572   "lmap f l = llist_corec l
   586 
       
   587   lmap :: "('a \<Rightarrow> 'b) \<Rightarrow> 'a llist \<Rightarrow> 'b llist"
       
   588   "lmap f l \<equiv> llist_corec l
       
   589     (\<lambda>z.
   573     (\<lambda>z.
   590       case z of LNil \<Rightarrow> None
   574       case z of LNil \<Rightarrow> None
   591       | LCons y z \<Rightarrow> Some (f y, z))"
   575       | LCons y z \<Rightarrow> Some (f y, z))"
   592 
   576 
   593 lemma Lmap_NIL [simp]: "Lmap f NIL = NIL"
   577 lemma Lmap_NIL [simp]: "Lmap f NIL = NIL"
   676 
   660 
   677 
   661 
   678 
   662 
   679 subsubsection {* @{text Lappend} *}
   663 subsubsection {* @{text Lappend} *}
   680 
   664 
   681 constdefs
   665 definition
   682   Lappend where
   666   "Lappend M N = LList_corec (M, N)
   683   "Lappend M N \<equiv> LList_corec (M, N)
       
   684     (split (List_case
   667     (split (List_case
   685         (List_case None (\<lambda>N1 N2. Some (N1, (NIL, N2))))
   668         (List_case None (\<lambda>N1 N2. Some (N1, (NIL, N2))))
   686         (\<lambda>M1 M2 N. Some (M1, (M2, N)))))"
   669         (\<lambda>M1 M2 N. Some (M1, (M2, N)))))"
   687 
   670   "lappend l n = llist_corec (l, n)
   688   lappend :: "'a llist \<Rightarrow> 'a llist \<Rightarrow> 'a llist"
       
   689   "lappend l n \<equiv> llist_corec (l, n)
       
   690     (split (llist_case
   671     (split (llist_case
   691         (llist_case None (\<lambda>n1 n2. Some (n1, (LNil, n2))))
   672         (llist_case None (\<lambda>n1 n2. Some (n1, (LNil, n2))))
   692         (\<lambda>l1 l2 n. Some (l1, (l2, n)))))"
   673         (\<lambda>l1 l2 n. Some (l1, (l2, n)))))"
   693 
   674 
   694 lemma Lappend_NIL_NIL [simp]:
   675 lemma Lappend_NIL_NIL [simp]:
   758 
   739 
   759 subsection{* iterates *}
   740 subsection{* iterates *}
   760 
   741 
   761 text {* @{text llist_fun_equalityI} cannot be used here! *}
   742 text {* @{text llist_fun_equalityI} cannot be used here! *}
   762 
   743 
   763 constdefs
   744 definition
   764   iterates :: "('a \<Rightarrow> 'a) \<Rightarrow> 'a \<Rightarrow> 'a llist"
   745   iterates :: "('a \<Rightarrow> 'a) \<Rightarrow> 'a \<Rightarrow> 'a llist"
   765   "iterates f a \<equiv> llist_corec a (\<lambda>x. Some (x, f x))"
   746   "iterates f a = llist_corec a (\<lambda>x. Some (x, f x))"
   766 
   747 
   767 lemma iterates: "iterates f x = LCons x (iterates f (f x))"
   748 lemma iterates: "iterates f x = LCons x (iterates f (f x))"
   768   apply (unfold iterates_def)
   749   apply (unfold iterates_def)
   769   apply (subst llist_corec)
   750   apply (subst llist_corec)
   770   apply simp
   751   apply simp