src/HOL/Library/Coinductive_List.thy
changeset 30240 5b25fee0362c
parent 28856 5e009a80fe6d
child 30663 0b6aff7451b2
equal deleted inserted replaced
30239:179ff9cb160b 30240:5b25fee0362c
   296 where EqNIL: "(NIL, NIL) \<in> EqLList r"
   296 where EqNIL: "(NIL, NIL) \<in> EqLList r"
   297   | EqCONS: "(a, b) \<in> r \<Longrightarrow> (M, N) \<in> EqLList r \<Longrightarrow>
   297   | EqCONS: "(a, b) \<in> r \<Longrightarrow> (M, N) \<in> EqLList r \<Longrightarrow>
   298       (CONS a M, CONS b N) \<in> EqLList r"
   298       (CONS a M, CONS b N) \<in> EqLList r"
   299 
   299 
   300 lemma EqLList_unfold:
   300 lemma EqLList_unfold:
   301     "EqLList r = dsum (diag {Datatype.Numb 0}) (dprod r (EqLList r))"
   301     "EqLList r = dsum (Id_on {Datatype.Numb 0}) (dprod r (EqLList r))"
   302   by (fast intro!: EqLList.intros [unfolded NIL_def CONS_def]
   302   by (fast intro!: EqLList.intros [unfolded NIL_def CONS_def]
   303            elim: EqLList.cases [unfolded NIL_def CONS_def])
   303            elim: EqLList.cases [unfolded NIL_def CONS_def])
   304 
   304 
   305 lemma EqLList_implies_ntrunc_equality:
   305 lemma EqLList_implies_ntrunc_equality:
   306     "(M, N) \<in> EqLList (diag A) \<Longrightarrow> ntrunc k M = ntrunc k N"
   306     "(M, N) \<in> EqLList (Id_on A) \<Longrightarrow> ntrunc k M = ntrunc k N"
   307   apply (induct k arbitrary: M N rule: nat_less_induct)
   307   apply (induct k arbitrary: M N rule: nat_less_induct)
   308   apply (erule EqLList.cases)
   308   apply (erule EqLList.cases)
   309    apply (safe del: equalityI)
   309    apply (safe del: equalityI)
   310   apply (case_tac n)
   310   apply (case_tac n)
   311    apply simp
   311    apply simp
   312   apply (rename_tac n')
   312   apply (rename_tac n')
   313   apply (case_tac n')
   313   apply (case_tac n')
   314    apply (simp_all add: CONS_def less_Suc_eq)
   314    apply (simp_all add: CONS_def less_Suc_eq)
   315   done
   315   done
   316 
   316 
   317 lemma Domain_EqLList: "Domain (EqLList (diag A)) \<subseteq> LList A"
   317 lemma Domain_EqLList: "Domain (EqLList (Id_on A)) \<subseteq> LList A"
   318   apply (rule subsetI)
   318   apply (rule subsetI)
   319   apply (erule LList.coinduct)
   319   apply (erule LList.coinduct)
   320   apply (subst (asm) EqLList_unfold)
   320   apply (subst (asm) EqLList_unfold)
   321   apply (auto simp add: NIL_def CONS_def)
   321   apply (auto simp add: NIL_def CONS_def)
   322   done
   322   done
   323 
   323 
   324 lemma EqLList_diag: "EqLList (diag A) = diag (LList A)"
   324 lemma EqLList_Id_on: "EqLList (Id_on A) = Id_on (LList A)"
   325   (is "?lhs = ?rhs")
   325   (is "?lhs = ?rhs")
   326 proof
   326 proof
   327   show "?lhs \<subseteq> ?rhs"
   327   show "?lhs \<subseteq> ?rhs"
   328     apply (rule subsetI)
   328     apply (rule subsetI)
   329     apply (rule_tac p = x in PairE)
   329     apply (rule_tac p = x in PairE)
   330     apply clarify
   330     apply clarify
   331     apply (rule diag_eqI)
   331     apply (rule Id_on_eqI)
   332      apply (rule EqLList_implies_ntrunc_equality [THEN ntrunc_equality],
   332      apply (rule EqLList_implies_ntrunc_equality [THEN ntrunc_equality],
   333        assumption)
   333        assumption)
   334     apply (erule DomainI [THEN Domain_EqLList [THEN subsetD]])
   334     apply (erule DomainI [THEN Domain_EqLList [THEN subsetD]])
   335     done
   335     done
   336   {
   336   {
   337     fix M N assume "(M, N) \<in> diag (LList A)"
   337     fix M N assume "(M, N) \<in> Id_on (LList A)"
   338     then have "(M, N) \<in> EqLList (diag A)"
   338     then have "(M, N) \<in> EqLList (Id_on A)"
   339     proof coinduct
   339     proof coinduct
   340       case (EqLList M N)
   340       case (EqLList M N)
   341       then obtain L where L: "L \<in> LList A" and MN: "M = L" "N = L" by blast
   341       then obtain L where L: "L \<in> LList A" and MN: "M = L" "N = L" by blast
   342       from L show ?case
   342       from L show ?case
   343       proof cases
   343       proof cases
   344         case NIL with MN have ?EqNIL by simp
   344         case NIL with MN have ?EqNIL by simp
   345         then show ?thesis ..
   345         then show ?thesis ..
   346       next
   346       next
   347         case CONS with MN have ?EqCONS by (simp add: diagI)
   347         case CONS with MN have ?EqCONS by (simp add: Id_onI)
   348         then show ?thesis ..
   348         then show ?thesis ..
   349       qed
   349       qed
   350     qed
   350     qed
   351   }
   351   }
   352   then show "?rhs \<subseteq> ?lhs" by auto
   352   then show "?rhs \<subseteq> ?lhs" by auto
   353 qed
   353 qed
   354 
   354 
   355 lemma EqLList_diag_iff [iff]: "(p \<in> EqLList (diag A)) = (p \<in> diag (LList A))"
   355 lemma EqLList_Id_on_iff [iff]: "(p \<in> EqLList (Id_on A)) = (p \<in> Id_on (LList A))"
   356   by (simp only: EqLList_diag)
   356   by (simp only: EqLList_Id_on)
   357 
   357 
   358 
   358 
   359 text {*
   359 text {*
   360   To show two LLists are equal, exhibit a bisimulation!  (Also admits
   360   To show two LLists are equal, exhibit a bisimulation!  (Also admits
   361   true equality.)
   361   true equality.)
   365   [consumes 1, case_names EqLList, case_conclusion EqLList EqNIL EqCONS]:
   365   [consumes 1, case_names EqLList, case_conclusion EqLList EqNIL EqCONS]:
   366   assumes r: "(M, N) \<in> r"
   366   assumes r: "(M, N) \<in> r"
   367     and step: "\<And>M N. (M, N) \<in> r \<Longrightarrow>
   367     and step: "\<And>M N. (M, N) \<in> r \<Longrightarrow>
   368       M = NIL \<and> N = NIL \<or>
   368       M = NIL \<and> N = NIL \<or>
   369         (\<exists>a b M' N'.
   369         (\<exists>a b M' N'.
   370           M = CONS a M' \<and> N = CONS b N' \<and> (a, b) \<in> diag A \<and>
   370           M = CONS a M' \<and> N = CONS b N' \<and> (a, b) \<in> Id_on A \<and>
   371             ((M', N') \<in> r \<or> (M', N') \<in> EqLList (diag A)))"
   371             ((M', N') \<in> r \<or> (M', N') \<in> EqLList (Id_on A)))"
   372   shows "M = N"
   372   shows "M = N"
   373 proof -
   373 proof -
   374   from r have "(M, N) \<in> EqLList (diag A)"
   374   from r have "(M, N) \<in> EqLList (Id_on A)"
   375   proof coinduct
   375   proof coinduct
   376     case EqLList
   376     case EqLList
   377     then show ?case by (rule step)
   377     then show ?case by (rule step)
   378   qed
   378   qed
   379   then show ?thesis by auto
   379   then show ?thesis by auto
   385     and fun_NIL: "g NIL \<in> LList A"  "f NIL = g NIL"
   385     and fun_NIL: "g NIL \<in> LList A"  "f NIL = g NIL"
   386     and fun_CONS: "\<And>x l. x \<in> A \<Longrightarrow> l \<in> LList A \<Longrightarrow>
   386     and fun_CONS: "\<And>x l. x \<in> A \<Longrightarrow> l \<in> LList A \<Longrightarrow>
   387             (f (CONS x l), g (CONS x l)) = (NIL, NIL) \<or>
   387             (f (CONS x l), g (CONS x l)) = (NIL, NIL) \<or>
   388             (\<exists>M N a b.
   388             (\<exists>M N a b.
   389               (f (CONS x l), g (CONS x l)) = (CONS a M, CONS b N) \<and>
   389               (f (CONS x l), g (CONS x l)) = (CONS a M, CONS b N) \<and>
   390                 (a, b) \<in> diag A \<and>
   390                 (a, b) \<in> Id_on A \<and>
   391                 (M, N) \<in> {(f u, g u) | u. u \<in> LList A} \<union> diag (LList A))"
   391                 (M, N) \<in> {(f u, g u) | u. u \<in> LList A} \<union> Id_on (LList A))"
   392       (is "\<And>x l. _ \<Longrightarrow> _ \<Longrightarrow> ?fun_CONS x l")
   392       (is "\<And>x l. _ \<Longrightarrow> _ \<Longrightarrow> ?fun_CONS x l")
   393   shows "f M = g M"
   393   shows "f M = g M"
   394 proof -
   394 proof -
   395   let ?bisim = "{(f L, g L) | L. L \<in> LList A}"
   395   let ?bisim = "{(f L, g L) | L. L \<in> LList A}"
   396   have "(f M, g M) \<in> ?bisim" using M by blast
   396   have "(f M, g M) \<in> ?bisim" using M by blast
   399     case (EqLList M N)
   399     case (EqLList M N)
   400     then obtain L where MN: "M = f L" "N = g L" and L: "L \<in> LList A" by blast
   400     then obtain L where MN: "M = f L" "N = g L" and L: "L \<in> LList A" by blast
   401     from L show ?case
   401     from L show ?case
   402     proof (cases L)
   402     proof (cases L)
   403       case NIL
   403       case NIL
   404       with fun_NIL and MN have "(M, N) \<in> diag (LList A)" by auto
   404       with fun_NIL and MN have "(M, N) \<in> Id_on (LList A)" by auto
   405       then have "(M, N) \<in> EqLList (diag A)" ..
   405       then have "(M, N) \<in> EqLList (Id_on A)" ..
   406       then show ?thesis by cases simp_all
   406       then show ?thesis by cases simp_all
   407     next
   407     next
   408       case (CONS a K)
   408       case (CONS a K)
   409       from fun_CONS and `a \<in> A` `K \<in> LList A`
   409       from fun_CONS and `a \<in> A` `K \<in> LList A`
   410       have "?fun_CONS a K" (is "?NIL \<or> ?CONS") .
   410       have "?fun_CONS a K" (is "?NIL \<or> ?CONS") .
   411       then show ?thesis
   411       then show ?thesis
   412       proof
   412       proof
   413         assume ?NIL
   413         assume ?NIL
   414         with MN CONS have "(M, N) \<in> diag (LList A)" by auto
   414         with MN CONS have "(M, N) \<in> Id_on (LList A)" by auto
   415         then have "(M, N) \<in> EqLList (diag A)" ..
   415         then have "(M, N) \<in> EqLList (Id_on A)" ..
   416         then show ?thesis by cases simp_all
   416         then show ?thesis by cases simp_all
   417       next
   417       next
   418         assume ?CONS
   418         assume ?CONS
   419         with CONS obtain a b M' N' where
   419         with CONS obtain a b M' N' where
   420             fg: "(f L, g L) = (CONS a M', CONS b N')"
   420             fg: "(f L, g L) = (CONS a M', CONS b N')"
   421           and ab: "(a, b) \<in> diag A"
   421           and ab: "(a, b) \<in> Id_on A"
   422           and M'N': "(M', N') \<in> ?bisim \<union> diag (LList A)"
   422           and M'N': "(M', N') \<in> ?bisim \<union> Id_on (LList A)"
   423           by blast
   423           by blast
   424         from M'N' show ?thesis
   424         from M'N' show ?thesis
   425         proof
   425         proof
   426           assume "(M', N') \<in> ?bisim"
   426           assume "(M', N') \<in> ?bisim"
   427           with MN fg ab show ?thesis by simp
   427           with MN fg ab show ?thesis by simp
   428         next
   428         next
   429           assume "(M', N') \<in> diag (LList A)"
   429           assume "(M', N') \<in> Id_on (LList A)"
   430           then have "(M', N') \<in> EqLList (diag A)" ..
   430           then have "(M', N') \<in> EqLList (Id_on A)" ..
   431           with MN fg ab show ?thesis by simp
   431           with MN fg ab show ?thesis by simp
   432         qed
   432         qed
   433       qed
   433       qed
   434     qed
   434     qed
   435   qed
   435   qed
   461     next
   461     next
   462       case (Some p)
   462       case (Some p)
   463       with h h' MN have "M = CONS (fst p) (h (snd p))"
   463       with h h' MN have "M = CONS (fst p) (h (snd p))"
   464 	and "N = CONS (fst p) (h' (snd p))"
   464 	and "N = CONS (fst p) (h' (snd p))"
   465         by (simp_all split: prod.split)
   465         by (simp_all split: prod.split)
   466       then have ?EqCONS by (auto iff: diag_iff)
   466       then have ?EqCONS by (auto iff: Id_on_iff)
   467       then show ?thesis ..
   467       then show ?thesis ..
   468     qed
   468     qed
   469   qed
   469   qed
   470 qed
   470 qed
   471 
   471 
   496       with MN have ?EqNIL by (simp add: Rep_llist_LNil)
   496       with MN have ?EqNIL by (simp add: Rep_llist_LNil)
   497       then show ?thesis ..
   497       then show ?thesis ..
   498     next
   498     next
   499       assume "?EqLCons (l1, l2)"
   499       assume "?EqLCons (l1, l2)"
   500       with MN have ?EqCONS
   500       with MN have ?EqCONS
   501         by (force simp add: Rep_llist_LCons EqLList_diag intro: Rep_llist_UNIV)
   501         by (force simp add: Rep_llist_LCons EqLList_Id_on intro: Rep_llist_UNIV)
   502       then show ?thesis ..
   502       then show ?thesis ..
   503     qed
   503     qed
   504   qed
   504   qed
   505   then show ?thesis by (simp add: M_def N_def Rep_llist_inject)
   505   then show ?thesis by (simp add: M_def N_def Rep_llist_inject)
   506 qed
   506 qed