src/HOL/Datatype_Examples/TLList.thy
author wenzelm
Sat, 26 Jun 2021 20:55:43 +0200
changeset 73884 0a12ca4f3e8d
parent 71469 d7ef73df3d15
permissions -rw-r--r--
proper Font_Subst.cache for paintScreenLineRange;
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
71263
35a92ce0b94e an extensive example for lift_bnf across quotients
traytel
parents:
diff changeset
     1
section \<open>Terminated Lazy Lists as Quotients of Lazy Lists\<close>
35a92ce0b94e an extensive example for lift_bnf across quotients
traytel
parents:
diff changeset
     2
35a92ce0b94e an extensive example for lift_bnf across quotients
traytel
parents:
diff changeset
     3
text \<open>
35a92ce0b94e an extensive example for lift_bnf across quotients
traytel
parents:
diff changeset
     4
This file demonstrates the lift_bnf utility for quotients on the example of lazy lists.
35a92ce0b94e an extensive example for lift_bnf across quotients
traytel
parents:
diff changeset
     5
35a92ce0b94e an extensive example for lift_bnf across quotients
traytel
parents:
diff changeset
     6
See the Coinductive AFP entry for a much more extensive library
35a92ce0b94e an extensive example for lift_bnf across quotients
traytel
parents:
diff changeset
     7
of (terminated) lazy lists.
35a92ce0b94e an extensive example for lift_bnf across quotients
traytel
parents:
diff changeset
     8
\<close>
35a92ce0b94e an extensive example for lift_bnf across quotients
traytel
parents:
diff changeset
     9
35a92ce0b94e an extensive example for lift_bnf across quotients
traytel
parents:
diff changeset
    10
theory TLList
35a92ce0b94e an extensive example for lift_bnf across quotients
traytel
parents:
diff changeset
    11
imports Main
35a92ce0b94e an extensive example for lift_bnf across quotients
traytel
parents:
diff changeset
    12
begin
35a92ce0b94e an extensive example for lift_bnf across quotients
traytel
parents:
diff changeset
    13
35a92ce0b94e an extensive example for lift_bnf across quotients
traytel
parents:
diff changeset
    14
codatatype (lset: 'a) llist = LNil | LCons 'a "'a llist"
35a92ce0b94e an extensive example for lift_bnf across quotients
traytel
parents:
diff changeset
    15
  for map: lmap rel: lrel
35a92ce0b94e an extensive example for lift_bnf across quotients
traytel
parents:
diff changeset
    16
35a92ce0b94e an extensive example for lift_bnf across quotients
traytel
parents:
diff changeset
    17
inductive lfinite where
35a92ce0b94e an extensive example for lift_bnf across quotients
traytel
parents:
diff changeset
    18
  LNil: "lfinite LNil"
35a92ce0b94e an extensive example for lift_bnf across quotients
traytel
parents:
diff changeset
    19
| LCons: "\<And>x xs. lfinite xs \<Longrightarrow> lfinite (LCons x xs)"
35a92ce0b94e an extensive example for lift_bnf across quotients
traytel
parents:
diff changeset
    20
35a92ce0b94e an extensive example for lift_bnf across quotients
traytel
parents:
diff changeset
    21
lemma lfinite_lmapI: "lfinite xs \<Longrightarrow> lfinite (lmap f xs)"
35a92ce0b94e an extensive example for lift_bnf across quotients
traytel
parents:
diff changeset
    22
  by (induct xs rule: lfinite.induct) (auto intro: lfinite.intros)
35a92ce0b94e an extensive example for lift_bnf across quotients
traytel
parents:
diff changeset
    23
35a92ce0b94e an extensive example for lift_bnf across quotients
traytel
parents:
diff changeset
    24
lemma lfinite_lmapD: "lfinite (lmap f xs) \<Longrightarrow> lfinite xs"
35a92ce0b94e an extensive example for lift_bnf across quotients
traytel
parents:
diff changeset
    25
proof (induct "lmap f xs" arbitrary: xs rule: lfinite.induct)
35a92ce0b94e an extensive example for lift_bnf across quotients
traytel
parents:
diff changeset
    26
  case LNil
35a92ce0b94e an extensive example for lift_bnf across quotients
traytel
parents:
diff changeset
    27
  then show ?case
35a92ce0b94e an extensive example for lift_bnf across quotients
traytel
parents:
diff changeset
    28
    by (cases xs) (auto intro: lfinite.intros)
35a92ce0b94e an extensive example for lift_bnf across quotients
traytel
parents:
diff changeset
    29
next
35a92ce0b94e an extensive example for lift_bnf across quotients
traytel
parents:
diff changeset
    30
  case (LCons y ys)
35a92ce0b94e an extensive example for lift_bnf across quotients
traytel
parents:
diff changeset
    31
  then show ?case
35a92ce0b94e an extensive example for lift_bnf across quotients
traytel
parents:
diff changeset
    32
    by (cases xs) (auto intro: lfinite.intros)
35a92ce0b94e an extensive example for lift_bnf across quotients
traytel
parents:
diff changeset
    33
qed
35a92ce0b94e an extensive example for lift_bnf across quotients
traytel
parents:
diff changeset
    34
35a92ce0b94e an extensive example for lift_bnf across quotients
traytel
parents:
diff changeset
    35
lemma lfinite_lmap[simp]: "lfinite (lmap f xs) = lfinite xs"
35a92ce0b94e an extensive example for lift_bnf across quotients
traytel
parents:
diff changeset
    36
  by (metis lfinite_lmapI lfinite_lmapD)
35a92ce0b94e an extensive example for lift_bnf across quotients
traytel
parents:
diff changeset
    37
35a92ce0b94e an extensive example for lift_bnf across quotients
traytel
parents:
diff changeset
    38
lemma lfinite_lrel: "lfinite xs \<Longrightarrow> lrel R xs ys \<Longrightarrow> lfinite ys"
35a92ce0b94e an extensive example for lift_bnf across quotients
traytel
parents:
diff changeset
    39
proof (induct xs arbitrary: ys rule: lfinite.induct)
35a92ce0b94e an extensive example for lift_bnf across quotients
traytel
parents:
diff changeset
    40
  case LNil
35a92ce0b94e an extensive example for lift_bnf across quotients
traytel
parents:
diff changeset
    41
  then show ?case
35a92ce0b94e an extensive example for lift_bnf across quotients
traytel
parents:
diff changeset
    42
    by (cases ys) (auto intro: lfinite.intros)
35a92ce0b94e an extensive example for lift_bnf across quotients
traytel
parents:
diff changeset
    43
next
35a92ce0b94e an extensive example for lift_bnf across quotients
traytel
parents:
diff changeset
    44
  case (LCons x xs)
35a92ce0b94e an extensive example for lift_bnf across quotients
traytel
parents:
diff changeset
    45
  then show ?case
35a92ce0b94e an extensive example for lift_bnf across quotients
traytel
parents:
diff changeset
    46
    by (cases ys) (auto intro: lfinite.intros)
35a92ce0b94e an extensive example for lift_bnf across quotients
traytel
parents:
diff changeset
    47
      qed
35a92ce0b94e an extensive example for lift_bnf across quotients
traytel
parents:
diff changeset
    48
35a92ce0b94e an extensive example for lift_bnf across quotients
traytel
parents:
diff changeset
    49
lemma lfinite_lrel': "lfinite ys \<Longrightarrow> lrel R xs ys \<Longrightarrow> lfinite xs"
35a92ce0b94e an extensive example for lift_bnf across quotients
traytel
parents:
diff changeset
    50
  using lfinite_lrel llist.rel_flip by blast
35a92ce0b94e an extensive example for lift_bnf across quotients
traytel
parents:
diff changeset
    51
35a92ce0b94e an extensive example for lift_bnf across quotients
traytel
parents:
diff changeset
    52
lemma lfinite_lrel_eq:
35a92ce0b94e an extensive example for lift_bnf across quotients
traytel
parents:
diff changeset
    53
   "lrel R xs ys \<Longrightarrow> lfinite xs = lfinite ys"
35a92ce0b94e an extensive example for lift_bnf across quotients
traytel
parents:
diff changeset
    54
  using lfinite_lrel lfinite_lrel' by blast+
35a92ce0b94e an extensive example for lift_bnf across quotients
traytel
parents:
diff changeset
    55
35a92ce0b94e an extensive example for lift_bnf across quotients
traytel
parents:
diff changeset
    56
definition eq_tllist where
35a92ce0b94e an extensive example for lift_bnf across quotients
traytel
parents:
diff changeset
    57
  "eq_tllist p q = (fst p = fst q \<and> (if lfinite (fst p) then snd p = snd q else True))"
35a92ce0b94e an extensive example for lift_bnf across quotients
traytel
parents:
diff changeset
    58
35a92ce0b94e an extensive example for lift_bnf across quotients
traytel
parents:
diff changeset
    59
quotient_type ('a, 'b) tllist = "'a llist \<times> 'b" / eq_tllist
35a92ce0b94e an extensive example for lift_bnf across quotients
traytel
parents:
diff changeset
    60
  apply (rule equivpI)
35a92ce0b94e an extensive example for lift_bnf across quotients
traytel
parents:
diff changeset
    61
    apply (rule reflpI; auto simp: eq_tllist_def)
35a92ce0b94e an extensive example for lift_bnf across quotients
traytel
parents:
diff changeset
    62
   apply (rule sympI; auto simp: eq_tllist_def)
35a92ce0b94e an extensive example for lift_bnf across quotients
traytel
parents:
diff changeset
    63
  apply (rule transpI; auto simp: eq_tllist_def)
35a92ce0b94e an extensive example for lift_bnf across quotients
traytel
parents:
diff changeset
    64
  done
35a92ce0b94e an extensive example for lift_bnf across quotients
traytel
parents:
diff changeset
    65
35a92ce0b94e an extensive example for lift_bnf across quotients
traytel
parents:
diff changeset
    66
primcorec lconst where
35a92ce0b94e an extensive example for lift_bnf across quotients
traytel
parents:
diff changeset
    67
  "lconst a = LCons a (lconst a)"
35a92ce0b94e an extensive example for lift_bnf across quotients
traytel
parents:
diff changeset
    68
35a92ce0b94e an extensive example for lift_bnf across quotients
traytel
parents:
diff changeset
    69
lemma lfinite_lconst[simp]: "\<not> lfinite (lconst a)"
35a92ce0b94e an extensive example for lift_bnf across quotients
traytel
parents:
diff changeset
    70
proof
35a92ce0b94e an extensive example for lift_bnf across quotients
traytel
parents:
diff changeset
    71
  assume "lfinite (lconst a)"
35a92ce0b94e an extensive example for lift_bnf across quotients
traytel
parents:
diff changeset
    72
  then show "False"
35a92ce0b94e an extensive example for lift_bnf across quotients
traytel
parents:
diff changeset
    73
  apply (induct "lconst a" rule: lfinite.induct)
35a92ce0b94e an extensive example for lift_bnf across quotients
traytel
parents:
diff changeset
    74
  subgoal by (subst (asm) lconst.code) auto
35a92ce0b94e an extensive example for lift_bnf across quotients
traytel
parents:
diff changeset
    75
  subgoal by (subst (asm) (2) lconst.code) auto
35a92ce0b94e an extensive example for lift_bnf across quotients
traytel
parents:
diff changeset
    76
  done
35a92ce0b94e an extensive example for lift_bnf across quotients
traytel
parents:
diff changeset
    77
qed
35a92ce0b94e an extensive example for lift_bnf across quotients
traytel
parents:
diff changeset
    78
35a92ce0b94e an extensive example for lift_bnf across quotients
traytel
parents:
diff changeset
    79
lemma lset_lconst: "x \<in> lset (lconst b) \<Longrightarrow> x = b"
35a92ce0b94e an extensive example for lift_bnf across quotients
traytel
parents:
diff changeset
    80
  apply (induct x "lconst b" arbitrary: b rule: llist.set_induct)
35a92ce0b94e an extensive example for lift_bnf across quotients
traytel
parents:
diff changeset
    81
  subgoal by (subst (asm) lconst.code) auto
35a92ce0b94e an extensive example for lift_bnf across quotients
traytel
parents:
diff changeset
    82
  subgoal by (subst (asm) (2) lconst.code) auto
35a92ce0b94e an extensive example for lift_bnf across quotients
traytel
parents:
diff changeset
    83
  done
35a92ce0b94e an extensive example for lift_bnf across quotients
traytel
parents:
diff changeset
    84
35a92ce0b94e an extensive example for lift_bnf across quotients
traytel
parents:
diff changeset
    85
lift_bnf (tlset1: 'a, tlset2: 'b) tllist
71469
d7ef73df3d15 lift BNF witnesses for quotients (unless better ones are specified by the user)
traytel
parents: 71354
diff changeset
    86
  [wits: "\<lambda>a. (lconst a, undefined)" ]
71263
35a92ce0b94e an extensive example for lift_bnf across quotients
traytel
parents:
diff changeset
    87
  for map: tlmap rel: tlrel
35a92ce0b94e an extensive example for lift_bnf across quotients
traytel
parents:
diff changeset
    88
  subgoal for P Q P' Q'
35a92ce0b94e an extensive example for lift_bnf across quotients
traytel
parents:
diff changeset
    89
    by (force simp: eq_tllist_def relcompp_apply llist.rel_compp lfinite_lrel_eq split: if_splits)
35a92ce0b94e an extensive example for lift_bnf across quotients
traytel
parents:
diff changeset
    90
  subgoal for Ss
35a92ce0b94e an extensive example for lift_bnf across quotients
traytel
parents:
diff changeset
    91
    by (auto simp: eq_tllist_def)
35a92ce0b94e an extensive example for lift_bnf across quotients
traytel
parents:
diff changeset
    92
  subgoal for Ss
35a92ce0b94e an extensive example for lift_bnf across quotients
traytel
parents:
diff changeset
    93
    apply (auto 0 0 simp: eq_tllist_def)
35a92ce0b94e an extensive example for lift_bnf across quotients
traytel
parents:
diff changeset
    94
    by metis
35a92ce0b94e an extensive example for lift_bnf across quotients
traytel
parents:
diff changeset
    95
  subgoal for x b
35a92ce0b94e an extensive example for lift_bnf across quotients
traytel
parents:
diff changeset
    96
    by (auto simp: eq_tllist_def llist.set_map dest: lset_lconst split: if_splits)
35a92ce0b94e an extensive example for lift_bnf across quotients
traytel
parents:
diff changeset
    97
  subgoal for x b
35a92ce0b94e an extensive example for lift_bnf across quotients
traytel
parents:
diff changeset
    98
    by (auto simp: eq_tllist_def sum_set_defs split: if_splits sum.splits)
35a92ce0b94e an extensive example for lift_bnf across quotients
traytel
parents:
diff changeset
    99
  done
35a92ce0b94e an extensive example for lift_bnf across quotients
traytel
parents:
diff changeset
   100
35a92ce0b94e an extensive example for lift_bnf across quotients
traytel
parents:
diff changeset
   101
lift_definition TLNil :: "'b \<Rightarrow> ('a, 'b) tllist" is "\<lambda>b. (LNil, b)" .
35a92ce0b94e an extensive example for lift_bnf across quotients
traytel
parents:
diff changeset
   102
lift_definition TLCons :: "'a \<Rightarrow> ('a, 'b) tllist \<Rightarrow> ('a, 'b) tllist" is "\<lambda>x (xs, b). (LCons x xs, b)"
35a92ce0b94e an extensive example for lift_bnf across quotients
traytel
parents:
diff changeset
   103
  by (auto simp: eq_tllist_def split: if_splits elim: lfinite.cases)
35a92ce0b94e an extensive example for lift_bnf across quotients
traytel
parents:
diff changeset
   104
35a92ce0b94e an extensive example for lift_bnf across quotients
traytel
parents:
diff changeset
   105
lemma lfinite_LCons: "lfinite (LCons x xs) = lfinite xs"
35a92ce0b94e an extensive example for lift_bnf across quotients
traytel
parents:
diff changeset
   106
  using lfinite.simps by auto
35a92ce0b94e an extensive example for lift_bnf across quotients
traytel
parents:
diff changeset
   107
35a92ce0b94e an extensive example for lift_bnf across quotients
traytel
parents:
diff changeset
   108
lemmas lfinite_simps[simp] = lfinite.LNil lfinite_LCons
35a92ce0b94e an extensive example for lift_bnf across quotients
traytel
parents:
diff changeset
   109
35a92ce0b94e an extensive example for lift_bnf across quotients
traytel
parents:
diff changeset
   110
lemma tlset_TLNil: "tlset1 (TLNil b) = {}" "tlset2 (TLNil b) = {b}"
35a92ce0b94e an extensive example for lift_bnf across quotients
traytel
parents:
diff changeset
   111
  by (transfer; auto simp: eq_tllist_def split: if_splits)+
35a92ce0b94e an extensive example for lift_bnf across quotients
traytel
parents:
diff changeset
   112
35a92ce0b94e an extensive example for lift_bnf across quotients
traytel
parents:
diff changeset
   113
lemma tlset_TLCons: "tlset1 (TLCons x xs) = {x} \<union> tlset1 xs" "tlset2 (TLCons x xs) = tlset2 xs"
35a92ce0b94e an extensive example for lift_bnf across quotients
traytel
parents:
diff changeset
   114
  by (transfer; auto simp: eq_tllist_def split: if_splits)+
35a92ce0b94e an extensive example for lift_bnf across quotients
traytel
parents:
diff changeset
   115
35a92ce0b94e an extensive example for lift_bnf across quotients
traytel
parents:
diff changeset
   116
lift_definition tlfinite :: "('a, 'b) tllist \<Rightarrow> bool" is "\<lambda>(xs, _). lfinite xs"
35a92ce0b94e an extensive example for lift_bnf across quotients
traytel
parents:
diff changeset
   117
  by (auto simp: eq_tllist_def)
35a92ce0b94e an extensive example for lift_bnf across quotients
traytel
parents:
diff changeset
   118
35a92ce0b94e an extensive example for lift_bnf across quotients
traytel
parents:
diff changeset
   119
lemma tlfinite_tlset2: "tlfinite xs \<Longrightarrow> tlset2 xs \<noteq> {}"
35a92ce0b94e an extensive example for lift_bnf across quotients
traytel
parents:
diff changeset
   120
  apply (transfer, safe)
35a92ce0b94e an extensive example for lift_bnf across quotients
traytel
parents:
diff changeset
   121
  subgoal for xs b
35a92ce0b94e an extensive example for lift_bnf across quotients
traytel
parents:
diff changeset
   122
    by (induct xs rule: lfinite.induct) (auto simp: eq_tllist_def setr.simps)
35a92ce0b94e an extensive example for lift_bnf across quotients
traytel
parents:
diff changeset
   123
  done
35a92ce0b94e an extensive example for lift_bnf across quotients
traytel
parents:
diff changeset
   124
35a92ce0b94e an extensive example for lift_bnf across quotients
traytel
parents:
diff changeset
   125
lemma tlfinite_tlset2': "b \<in> tlset2 xs \<Longrightarrow> tlfinite xs"
35a92ce0b94e an extensive example for lift_bnf across quotients
traytel
parents:
diff changeset
   126
  by (transfer fixing: b, auto simp: eq_tllist_def setr.simps split: if_splits)
35a92ce0b94e an extensive example for lift_bnf across quotients
traytel
parents:
diff changeset
   127
35a92ce0b94e an extensive example for lift_bnf across quotients
traytel
parents:
diff changeset
   128
lemma "\<not> tlfinite xs \<Longrightarrow> tlset2 xs = {}"
35a92ce0b94e an extensive example for lift_bnf across quotients
traytel
parents:
diff changeset
   129
  by (meson equals0I tlfinite_tlset2')
35a92ce0b94e an extensive example for lift_bnf across quotients
traytel
parents:
diff changeset
   130
35a92ce0b94e an extensive example for lift_bnf across quotients
traytel
parents:
diff changeset
   131
end