src/HOL/Induct/LList.thy
author wenzelm
Mon, 26 Oct 2009 20:02:37 +0100
changeset 33209 d36ca3960e33
parent 33197 de6285ebcc05
permissions -rw-r--r--
tuned white space;
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
13075
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
     1
(*  Title:      HOL/Induct/LList.thy
3120
c58423c20740 New directory to contain examples of (co)inductive definitions
paulson
parents:
diff changeset
     2
    Author:     Lawrence C Paulson, Cambridge University Computer Laboratory
c58423c20740 New directory to contain examples of (co)inductive definitions
paulson
parents:
diff changeset
     3
c58423c20740 New directory to contain examples of (co)inductive definitions
paulson
parents:
diff changeset
     4
Shares NIL, CONS, List_case with List.thy
c58423c20740 New directory to contain examples of (co)inductive definitions
paulson
parents:
diff changeset
     5
13075
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
     6
Still needs flatten function -- hard because it need
3120
c58423c20740 New directory to contain examples of (co)inductive definitions
paulson
parents:
diff changeset
     7
bounds on the amount of lookahead required.
c58423c20740 New directory to contain examples of (co)inductive definitions
paulson
parents:
diff changeset
     8
c58423c20740 New directory to contain examples of (co)inductive definitions
paulson
parents:
diff changeset
     9
Could try (but would it work for the gfp analogue of term?)
30198
922f944f03b2 name changes
nipkow
parents: 26793
diff changeset
    10
  LListD_Fun_def "LListD_Fun(A) == (%Z. Id_on({Numb(0)}) <++> Id_on(A) <**> Z)"
3120
c58423c20740 New directory to contain examples of (co)inductive definitions
paulson
parents:
diff changeset
    11
c58423c20740 New directory to contain examples of (co)inductive definitions
paulson
parents:
diff changeset
    12
A nice but complex example would be [ML for the Working Programmer, page 176]
c58423c20740 New directory to contain examples of (co)inductive definitions
paulson
parents:
diff changeset
    13
  from(1) = enumerate (Lmap (Lmap(pack), makeqq(from(1),from(1))))
c58423c20740 New directory to contain examples of (co)inductive definitions
paulson
parents:
diff changeset
    14
c58423c20740 New directory to contain examples of (co)inductive definitions
paulson
parents:
diff changeset
    15
Previous definition of llistD_Fun was explicit:
c58423c20740 New directory to contain examples of (co)inductive definitions
paulson
parents:
diff changeset
    16
  llistD_Fun_def
c58423c20740 New directory to contain examples of (co)inductive definitions
paulson
parents:
diff changeset
    17
   "llistD_Fun(r) ==    
c58423c20740 New directory to contain examples of (co)inductive definitions
paulson
parents:
diff changeset
    18
       {(LNil,LNil)}  Un        
10834
a7897aebbffc *** empty log message ***
nipkow
parents: 6382
diff changeset
    19
       (UN x. (split(%l1 l2.(LCons(x,l1),LCons(x,l2))))`r)"
3120
c58423c20740 New directory to contain examples of (co)inductive definitions
paulson
parents:
diff changeset
    20
*)
c58423c20740 New directory to contain examples of (co)inductive definitions
paulson
parents:
diff changeset
    21
13107
8743cc847224 tuned presentation;
wenzelm
parents: 13075
diff changeset
    22
header {*Definition of type llist by a greatest fixed point*}
13075
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
    23
20801
d3616b4abe1b proper import of Main HOL;
wenzelm
parents: 20770
diff changeset
    24
theory LList imports SList begin
3120
c58423c20740 New directory to contain examples of (co)inductive definitions
paulson
parents:
diff changeset
    25
23746
a455e69c31cc Adapted to new inductive definition package.
berghofe
parents: 21404
diff changeset
    26
coinductive_set
13075
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
    27
  llist  :: "'a item set => 'a item set"
23746
a455e69c31cc Adapted to new inductive definition package.
berghofe
parents: 21404
diff changeset
    28
  for A :: "'a item set"
a455e69c31cc Adapted to new inductive definition package.
berghofe
parents: 21404
diff changeset
    29
  where
a455e69c31cc Adapted to new inductive definition package.
berghofe
parents: 21404
diff changeset
    30
    NIL_I:  "NIL \<in> llist(A)"
a455e69c31cc Adapted to new inductive definition package.
berghofe
parents: 21404
diff changeset
    31
  | CONS_I:         "[| a \<in> A;  M \<in> llist(A) |] ==> CONS a M \<in> llist(A)"
3120
c58423c20740 New directory to contain examples of (co)inductive definitions
paulson
parents:
diff changeset
    32
23746
a455e69c31cc Adapted to new inductive definition package.
berghofe
parents: 21404
diff changeset
    33
coinductive_set
a455e69c31cc Adapted to new inductive definition package.
berghofe
parents: 21404
diff changeset
    34
  LListD :: "('a item * 'a item)set => ('a item * 'a item)set"
a455e69c31cc Adapted to new inductive definition package.
berghofe
parents: 21404
diff changeset
    35
  for r :: "('a item * 'a item)set"
a455e69c31cc Adapted to new inductive definition package.
berghofe
parents: 21404
diff changeset
    36
  where
13075
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
    37
    NIL_I:  "(NIL, NIL) \<in> LListD(r)"
23746
a455e69c31cc Adapted to new inductive definition package.
berghofe
parents: 21404
diff changeset
    38
  | CONS_I:         "[| (a,b) \<in> r;  (M,N) \<in> LListD(r) |] 
13075
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
    39
                     ==> (CONS a M, CONS b N) \<in> LListD(r)"
3120
c58423c20740 New directory to contain examples of (co)inductive definitions
paulson
parents:
diff changeset
    40
5977
9f0c8869cf71 tidied up list definitions, using type 'a option instead of
paulson
parents: 3842
diff changeset
    41
9f0c8869cf71 tidied up list definitions, using type 'a option instead of
paulson
parents: 3842
diff changeset
    42
typedef (LList)
13075
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
    43
  'a llist = "llist(range Leaf) :: 'a item set"
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
    44
  by (blast intro: llist.NIL_I)
5977
9f0c8869cf71 tidied up list definitions, using type 'a option instead of
paulson
parents: 3842
diff changeset
    45
19736
wenzelm
parents: 17841
diff changeset
    46
definition
21404
eb85850d3eb7 more robust syntax for definition/abbreviation/notation;
wenzelm
parents: 20801
diff changeset
    47
  list_Fun   :: "['a item set, 'a item set] => 'a item set" where
13075
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
    48
    --{*Now used exclusively for abbreviating the coinduction rule*}
19736
wenzelm
parents: 17841
diff changeset
    49
     "list_Fun A X = {z. z = NIL | (\<exists>M a. z = CONS a M & a \<in> A & M \<in> X)}"
5977
9f0c8869cf71 tidied up list definitions, using type 'a option instead of
paulson
parents: 3842
diff changeset
    50
21404
eb85850d3eb7 more robust syntax for definition/abbreviation/notation;
wenzelm
parents: 20801
diff changeset
    51
definition
5977
9f0c8869cf71 tidied up list definitions, using type 'a option instead of
paulson
parents: 3842
diff changeset
    52
  LListD_Fun :: 
9f0c8869cf71 tidied up list definitions, using type 'a option instead of
paulson
parents: 3842
diff changeset
    53
      "[('a item * 'a item)set, ('a item * 'a item)set] => 
21404
eb85850d3eb7 more robust syntax for definition/abbreviation/notation;
wenzelm
parents: 20801
diff changeset
    54
       ('a item * 'a item)set" where
19736
wenzelm
parents: 17841
diff changeset
    55
    "LListD_Fun r X =   
5977
9f0c8869cf71 tidied up list definitions, using type 'a option instead of
paulson
parents: 3842
diff changeset
    56
       {z. z = (NIL, NIL) |   
13075
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
    57
           (\<exists>M N a b. z = (CONS a M, CONS b N) & (a, b) \<in> r & (M, N) \<in> X)}"
5977
9f0c8869cf71 tidied up list definitions, using type 'a option instead of
paulson
parents: 3842
diff changeset
    58
21404
eb85850d3eb7 more robust syntax for definition/abbreviation/notation;
wenzelm
parents: 20801
diff changeset
    59
definition
eb85850d3eb7 more robust syntax for definition/abbreviation/notation;
wenzelm
parents: 20801
diff changeset
    60
  LNil :: "'a llist" where
13075
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
    61
     --{*abstract constructor*}
19736
wenzelm
parents: 17841
diff changeset
    62
    "LNil = Abs_LList NIL"
5977
9f0c8869cf71 tidied up list definitions, using type 'a option instead of
paulson
parents: 3842
diff changeset
    63
21404
eb85850d3eb7 more robust syntax for definition/abbreviation/notation;
wenzelm
parents: 20801
diff changeset
    64
definition
eb85850d3eb7 more robust syntax for definition/abbreviation/notation;
wenzelm
parents: 20801
diff changeset
    65
  LCons :: "['a, 'a llist] => 'a llist" where
13075
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
    66
     --{*abstract constructor*}
19736
wenzelm
parents: 17841
diff changeset
    67
    "LCons x xs = Abs_LList(CONS (Leaf x) (Rep_LList xs))"
5977
9f0c8869cf71 tidied up list definitions, using type 'a option instead of
paulson
parents: 3842
diff changeset
    68
21404
eb85850d3eb7 more robust syntax for definition/abbreviation/notation;
wenzelm
parents: 20801
diff changeset
    69
definition
eb85850d3eb7 more robust syntax for definition/abbreviation/notation;
wenzelm
parents: 20801
diff changeset
    70
  llist_case :: "['b, ['a, 'a llist]=>'b, 'a llist] => 'b" where
19736
wenzelm
parents: 17841
diff changeset
    71
    "llist_case c d l =
5977
9f0c8869cf71 tidied up list definitions, using type 'a option instead of
paulson
parents: 3842
diff changeset
    72
       List_case c (%x y. d (inv Leaf x) (Abs_LList y)) (Rep_LList l)"
9f0c8869cf71 tidied up list definitions, using type 'a option instead of
paulson
parents: 3842
diff changeset
    73
21404
eb85850d3eb7 more robust syntax for definition/abbreviation/notation;
wenzelm
parents: 20801
diff changeset
    74
definition
eb85850d3eb7 more robust syntax for definition/abbreviation/notation;
wenzelm
parents: 20801
diff changeset
    75
  LList_corec_fun :: "[nat, 'a=> ('b item * 'a) option, 'a] => 'b item" where
19736
wenzelm
parents: 17841
diff changeset
    76
    "LList_corec_fun k f ==
5977
9f0c8869cf71 tidied up list definitions, using type 'a option instead of
paulson
parents: 3842
diff changeset
    77
     nat_rec (%x. {})                         
9f0c8869cf71 tidied up list definitions, using type 'a option instead of
paulson
parents: 3842
diff changeset
    78
             (%j r x. case f x of None    => NIL
9f0c8869cf71 tidied up list definitions, using type 'a option instead of
paulson
parents: 3842
diff changeset
    79
                                | Some(z,w) => CONS z (r w)) 
9f0c8869cf71 tidied up list definitions, using type 'a option instead of
paulson
parents: 3842
diff changeset
    80
             k"
9f0c8869cf71 tidied up list definitions, using type 'a option instead of
paulson
parents: 3842
diff changeset
    81
21404
eb85850d3eb7 more robust syntax for definition/abbreviation/notation;
wenzelm
parents: 20801
diff changeset
    82
definition
eb85850d3eb7 more robust syntax for definition/abbreviation/notation;
wenzelm
parents: 20801
diff changeset
    83
  LList_corec     :: "['a, 'a => ('b item * 'a) option] => 'b item" where
19736
wenzelm
parents: 17841
diff changeset
    84
    "LList_corec a f = (\<Union>k. LList_corec_fun k f a)"
5977
9f0c8869cf71 tidied up list definitions, using type 'a option instead of
paulson
parents: 3842
diff changeset
    85
21404
eb85850d3eb7 more robust syntax for definition/abbreviation/notation;
wenzelm
parents: 20801
diff changeset
    86
definition
eb85850d3eb7 more robust syntax for definition/abbreviation/notation;
wenzelm
parents: 20801
diff changeset
    87
  llist_corec     :: "['a, 'a => ('b * 'a) option] => 'b llist" where
19736
wenzelm
parents: 17841
diff changeset
    88
    "llist_corec a f =
5977
9f0c8869cf71 tidied up list definitions, using type 'a option instead of
paulson
parents: 3842
diff changeset
    89
       Abs_LList(LList_corec a 
9f0c8869cf71 tidied up list definitions, using type 'a option instead of
paulson
parents: 3842
diff changeset
    90
                 (%z. case f z of None      => None
9f0c8869cf71 tidied up list definitions, using type 'a option instead of
paulson
parents: 3842
diff changeset
    91
                                | Some(v,w) => Some(Leaf(v), w)))"
9f0c8869cf71 tidied up list definitions, using type 'a option instead of
paulson
parents: 3842
diff changeset
    92
21404
eb85850d3eb7 more robust syntax for definition/abbreviation/notation;
wenzelm
parents: 20801
diff changeset
    93
definition
eb85850d3eb7 more robust syntax for definition/abbreviation/notation;
wenzelm
parents: 20801
diff changeset
    94
  llistD_Fun :: "('a llist * 'a llist)set => ('a llist * 'a llist)set" where
19736
wenzelm
parents: 17841
diff changeset
    95
    "llistD_Fun(r) =   
10834
a7897aebbffc *** empty log message ***
nipkow
parents: 6382
diff changeset
    96
        prod_fun Abs_LList Abs_LList `         
30198
922f944f03b2 name changes
nipkow
parents: 26793
diff changeset
    97
                LListD_Fun (Id_on(range Leaf))   
10834
a7897aebbffc *** empty log message ***
nipkow
parents: 6382
diff changeset
    98
                            (prod_fun Rep_LList Rep_LList ` r)"
5977
9f0c8869cf71 tidied up list definitions, using type 'a option instead of
paulson
parents: 3842
diff changeset
    99
9f0c8869cf71 tidied up list definitions, using type 'a option instead of
paulson
parents: 3842
diff changeset
   100
9f0c8869cf71 tidied up list definitions, using type 'a option instead of
paulson
parents: 3842
diff changeset
   101
13107
8743cc847224 tuned presentation;
wenzelm
parents: 13075
diff changeset
   102
text{* The case syntax for type @{text "'a llist"} *}
20770
2c583720436e fixed translations: CONST;
wenzelm
parents: 19736
diff changeset
   103
syntax  (* FIXME proper case syntax!? *)
2c583720436e fixed translations: CONST;
wenzelm
parents: 19736
diff changeset
   104
  LNil :: logic
2c583720436e fixed translations: CONST;
wenzelm
parents: 19736
diff changeset
   105
  LCons :: logic
3120
c58423c20740 New directory to contain examples of (co)inductive definitions
paulson
parents:
diff changeset
   106
translations
20770
2c583720436e fixed translations: CONST;
wenzelm
parents: 19736
diff changeset
   107
  "case p of LNil => a | LCons x l => b" == "CONST llist_case a (%x l. b) p"
3120
c58423c20740 New directory to contain examples of (co)inductive definitions
paulson
parents:
diff changeset
   108
c58423c20740 New directory to contain examples of (co)inductive definitions
paulson
parents:
diff changeset
   109
13107
8743cc847224 tuned presentation;
wenzelm
parents: 13075
diff changeset
   110
subsubsection{* Sample function definitions.  Item-based ones start with @{text L} *}
3120
c58423c20740 New directory to contain examples of (co)inductive definitions
paulson
parents:
diff changeset
   111
19736
wenzelm
parents: 17841
diff changeset
   112
definition
21404
eb85850d3eb7 more robust syntax for definition/abbreviation/notation;
wenzelm
parents: 20801
diff changeset
   113
  Lmap       :: "('a item => 'b item) => ('a item => 'b item)" where
19736
wenzelm
parents: 17841
diff changeset
   114
    "Lmap f M = LList_corec M (List_case None (%x M'. Some((f(x), M'))))"
3120
c58423c20740 New directory to contain examples of (co)inductive definitions
paulson
parents:
diff changeset
   115
21404
eb85850d3eb7 more robust syntax for definition/abbreviation/notation;
wenzelm
parents: 20801
diff changeset
   116
definition
eb85850d3eb7 more robust syntax for definition/abbreviation/notation;
wenzelm
parents: 20801
diff changeset
   117
  lmap       :: "('a=>'b) => ('a llist => 'b llist)" where
19736
wenzelm
parents: 17841
diff changeset
   118
    "lmap f l = llist_corec l (%z. case z of LNil => None 
5977
9f0c8869cf71 tidied up list definitions, using type 'a option instead of
paulson
parents: 3842
diff changeset
   119
                                           | LCons y z => Some(f(y), z))"
3120
c58423c20740 New directory to contain examples of (co)inductive definitions
paulson
parents:
diff changeset
   120
21404
eb85850d3eb7 more robust syntax for definition/abbreviation/notation;
wenzelm
parents: 20801
diff changeset
   121
definition
eb85850d3eb7 more robust syntax for definition/abbreviation/notation;
wenzelm
parents: 20801
diff changeset
   122
  iterates   :: "['a => 'a, 'a] => 'a llist" where
19736
wenzelm
parents: 17841
diff changeset
   123
    "iterates f a = llist_corec a (%x. Some((x, f(x))))"     
3120
c58423c20740 New directory to contain examples of (co)inductive definitions
paulson
parents:
diff changeset
   124
21404
eb85850d3eb7 more robust syntax for definition/abbreviation/notation;
wenzelm
parents: 20801
diff changeset
   125
definition
eb85850d3eb7 more robust syntax for definition/abbreviation/notation;
wenzelm
parents: 20801
diff changeset
   126
  Lconst     :: "'a item => 'a item" where
13075
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   127
    "Lconst(M) == lfp(%N. CONS M N)"
3120
c58423c20740 New directory to contain examples of (co)inductive definitions
paulson
parents:
diff changeset
   128
21404
eb85850d3eb7 more robust syntax for definition/abbreviation/notation;
wenzelm
parents: 20801
diff changeset
   129
definition
eb85850d3eb7 more robust syntax for definition/abbreviation/notation;
wenzelm
parents: 20801
diff changeset
   130
  Lappend    :: "['a item, 'a item] => 'a item" where
19736
wenzelm
parents: 17841
diff changeset
   131
   "Lappend M N = LList_corec (M,N)                                         
5977
9f0c8869cf71 tidied up list definitions, using type 'a option instead of
paulson
parents: 3842
diff changeset
   132
     (split(List_case (List_case None (%N1 N2. Some((N1, (NIL,N2))))) 
9f0c8869cf71 tidied up list definitions, using type 'a option instead of
paulson
parents: 3842
diff changeset
   133
                      (%M1 M2 N. Some((M1, (M2,N))))))"
3120
c58423c20740 New directory to contain examples of (co)inductive definitions
paulson
parents:
diff changeset
   134
21404
eb85850d3eb7 more robust syntax for definition/abbreviation/notation;
wenzelm
parents: 20801
diff changeset
   135
definition
eb85850d3eb7 more robust syntax for definition/abbreviation/notation;
wenzelm
parents: 20801
diff changeset
   136
  lappend    :: "['a llist, 'a llist] => 'a llist" where
19736
wenzelm
parents: 17841
diff changeset
   137
    "lappend l n = llist_corec (l,n)                                         
5977
9f0c8869cf71 tidied up list definitions, using type 'a option instead of
paulson
parents: 3842
diff changeset
   138
       (split(llist_case (llist_case None (%n1 n2. Some((n1, (LNil,n2))))) 
9f0c8869cf71 tidied up list definitions, using type 'a option instead of
paulson
parents: 3842
diff changeset
   139
                         (%l1 l2 n. Some((l1, (l2,n))))))"
3120
c58423c20740 New directory to contain examples of (co)inductive definitions
paulson
parents:
diff changeset
   140
13075
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   141
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   142
text{*Append generates its result by applying f, where
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   143
    f((NIL,NIL))          = None
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   144
    f((NIL, CONS N1 N2))  = Some((N1, (NIL,N2))
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   145
    f((CONS M1 M2, N))    = Some((M1, (M2,N))
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   146
*}
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   147
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   148
text{*
13107
8743cc847224 tuned presentation;
wenzelm
parents: 13075
diff changeset
   149
SHOULD @{text LListD_Fun_CONS_I}, etc., be equations (for rewriting)?
13075
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   150
*}
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   151
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   152
lemmas UN1_I = UNIV_I [THEN UN_I, standard]
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   153
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   154
subsubsection{* Simplification *}
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   155
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   156
declare option.split [split]
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   157
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   158
text{*This justifies using llist in other recursive type definitions*}
23746
a455e69c31cc Adapted to new inductive definition package.
berghofe
parents: 21404
diff changeset
   159
lemma llist_mono:
a455e69c31cc Adapted to new inductive definition package.
berghofe
parents: 21404
diff changeset
   160
  assumes subset: "A \<subseteq> B"
a455e69c31cc Adapted to new inductive definition package.
berghofe
parents: 21404
diff changeset
   161
  shows "llist A \<subseteq> llist B"
a455e69c31cc Adapted to new inductive definition package.
berghofe
parents: 21404
diff changeset
   162
proof
a455e69c31cc Adapted to new inductive definition package.
berghofe
parents: 21404
diff changeset
   163
  fix x
a455e69c31cc Adapted to new inductive definition package.
berghofe
parents: 21404
diff changeset
   164
  assume "x \<in> llist A"
a455e69c31cc Adapted to new inductive definition package.
berghofe
parents: 21404
diff changeset
   165
  then show "x \<in> llist B"
a455e69c31cc Adapted to new inductive definition package.
berghofe
parents: 21404
diff changeset
   166
  proof coinduct
a455e69c31cc Adapted to new inductive definition package.
berghofe
parents: 21404
diff changeset
   167
    case llist
a455e69c31cc Adapted to new inductive definition package.
berghofe
parents: 21404
diff changeset
   168
    then show ?case using subset
a455e69c31cc Adapted to new inductive definition package.
berghofe
parents: 21404
diff changeset
   169
      by cases blast+
a455e69c31cc Adapted to new inductive definition package.
berghofe
parents: 21404
diff changeset
   170
  qed
a455e69c31cc Adapted to new inductive definition package.
berghofe
parents: 21404
diff changeset
   171
qed
13075
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   172
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   173
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   174
lemma llist_unfold: "llist(A) = usum {Numb(0)} (uprod A (llist A))"
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   175
  by (fast intro!: llist.intros [unfolded NIL_def CONS_def]
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   176
           elim: llist.cases [unfolded NIL_def CONS_def])
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   177
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   178
13107
8743cc847224 tuned presentation;
wenzelm
parents: 13075
diff changeset
   179
subsection{* Type checking by coinduction *}
8743cc847224 tuned presentation;
wenzelm
parents: 13075
diff changeset
   180
8743cc847224 tuned presentation;
wenzelm
parents: 13075
diff changeset
   181
text {*
8743cc847224 tuned presentation;
wenzelm
parents: 13075
diff changeset
   182
  {\dots} using @{text list_Fun} THE COINDUCTIVE DEFINITION PACKAGE
8743cc847224 tuned presentation;
wenzelm
parents: 13075
diff changeset
   183
  COULD DO THIS!
13075
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   184
*}
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   185
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   186
lemma llist_coinduct: 
17841
b1f10b98430d tidying
paulson
parents: 16417
diff changeset
   187
    "[| M \<in> X;  X \<subseteq> list_Fun A (X Un llist(A)) |] ==>  M \<in> llist(A)"
b1f10b98430d tidying
paulson
parents: 16417
diff changeset
   188
apply (simp add: list_Fun_def)
13075
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   189
apply (erule llist.coinduct)
17841
b1f10b98430d tidying
paulson
parents: 16417
diff changeset
   190
apply (blast intro: elim:); 
13075
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   191
done
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   192
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   193
lemma list_Fun_NIL_I [iff]: "NIL \<in> list_Fun A X"
17841
b1f10b98430d tidying
paulson
parents: 16417
diff changeset
   194
by (simp add: list_Fun_def NIL_def)
13075
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   195
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   196
lemma list_Fun_CONS_I [intro!,simp]: 
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   197
    "[| M \<in> A;  N \<in> X |] ==> CONS M N \<in> list_Fun A X"
17841
b1f10b98430d tidying
paulson
parents: 16417
diff changeset
   198
by (simp add: list_Fun_def CONS_def)
13075
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   199
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   200
13107
8743cc847224 tuned presentation;
wenzelm
parents: 13075
diff changeset
   201
text{*Utilise the ``strong'' part, i.e. @{text "gfp(f)"}*}
13075
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   202
lemma list_Fun_llist_I: "M \<in> llist(A) ==> M \<in> list_Fun A (X Un llist(A))"
23746
a455e69c31cc Adapted to new inductive definition package.
berghofe
parents: 21404
diff changeset
   203
apply (unfold list_Fun_def)
a455e69c31cc Adapted to new inductive definition package.
berghofe
parents: 21404
diff changeset
   204
apply (erule llist.cases)
a455e69c31cc Adapted to new inductive definition package.
berghofe
parents: 21404
diff changeset
   205
apply auto
13075
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   206
done
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   207
13107
8743cc847224 tuned presentation;
wenzelm
parents: 13075
diff changeset
   208
subsection{* @{text LList_corec} satisfies the desired recurion equation *}
13075
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   209
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   210
text{*A continuity result?*}
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   211
lemma CONS_UN1: "CONS M (\<Union>x. f(x)) = (\<Union>x. CONS M (f x))"
17841
b1f10b98430d tidying
paulson
parents: 16417
diff changeset
   212
apply (simp add: CONS_def In1_UN1 Scons_UN1_y)
13075
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   213
done
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   214
17841
b1f10b98430d tidying
paulson
parents: 16417
diff changeset
   215
lemma CONS_mono: "[| M\<subseteq>M';  N\<subseteq>N' |] ==> CONS M N \<subseteq> CONS M' N'"
b1f10b98430d tidying
paulson
parents: 16417
diff changeset
   216
apply (simp add: CONS_def In1_mono Scons_mono)
13075
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   217
done
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   218
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   219
declare LList_corec_fun_def [THEN def_nat_rec_0, simp]
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   220
        LList_corec_fun_def [THEN def_nat_rec_Suc, simp]
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   221
19736
wenzelm
parents: 17841
diff changeset
   222
13075
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   223
subsubsection{* The directions of the equality are proved separately *}
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   224
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   225
lemma LList_corec_subset1: 
17841
b1f10b98430d tidying
paulson
parents: 16417
diff changeset
   226
    "LList_corec a f \<subseteq>  
13075
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   227
     (case f a of None => NIL | Some(z,w) => CONS z (LList_corec w f))"
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   228
apply (unfold LList_corec_def)
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   229
apply (rule UN_least)
17841
b1f10b98430d tidying
paulson
parents: 16417
diff changeset
   230
apply (case_tac k) 
13075
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   231
apply (simp_all (no_asm_simp))
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   232
apply (rule allI impI subset_refl [THEN CONS_mono] UNIV_I [THEN UN_upper])+
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   233
done
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   234
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   235
lemma LList_corec_subset2: 
17841
b1f10b98430d tidying
paulson
parents: 16417
diff changeset
   236
    "(case f a of None => NIL | Some(z,w) => CONS z (LList_corec w f)) \<subseteq>  
13075
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   237
     LList_corec a f"
17841
b1f10b98430d tidying
paulson
parents: 16417
diff changeset
   238
apply (simp add: LList_corec_def)
13075
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   239
apply (simp add: CONS_UN1, safe) 
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   240
apply (rule_tac a="Suc(?k)" in UN_I, simp, simp)+ 
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   241
done
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   242
13107
8743cc847224 tuned presentation;
wenzelm
parents: 13075
diff changeset
   243
text{*the recursion equation for @{text LList_corec} -- NOT SUITABLE FOR REWRITING!*}
13075
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   244
lemma LList_corec:
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   245
     "LList_corec a f =   
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   246
      (case f a of None => NIL | Some(z,w) => CONS z (LList_corec w f))"
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   247
by (rule equalityI LList_corec_subset1 LList_corec_subset2)+
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   248
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   249
text{*definitional version of same*}
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   250
lemma def_LList_corec: 
19736
wenzelm
parents: 17841
diff changeset
   251
     "[| !!x. h(x) = LList_corec x f |]      
13075
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   252
      ==> h(a) = (case f a of None => NIL | Some(z,w) => CONS z (h w))"
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   253
by (simp add: LList_corec)
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   254
13107
8743cc847224 tuned presentation;
wenzelm
parents: 13075
diff changeset
   255
text{*A typical use of co-induction to show membership in the @{text gfp}. 
8743cc847224 tuned presentation;
wenzelm
parents: 13075
diff changeset
   256
  Bisimulation is @{text "range(%x. LList_corec x f)"} *}
13075
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   257
lemma LList_corec_type: "LList_corec a f \<in> llist UNIV"
17841
b1f10b98430d tidying
paulson
parents: 16417
diff changeset
   258
apply (rule_tac X = "range (%x. LList_corec x ?g)" in llist_coinduct)
13075
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   259
apply (rule rangeI, safe)
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   260
apply (subst LList_corec, simp)
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   261
done
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   262
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   263
13107
8743cc847224 tuned presentation;
wenzelm
parents: 13075
diff changeset
   264
subsection{* @{text llist} equality as a @{text gfp}; the bisimulation principle *}
13075
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   265
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   266
text{*This theorem is actually used, unlike the many similar ones in ZF*}
30198
922f944f03b2 name changes
nipkow
parents: 26793
diff changeset
   267
lemma LListD_unfold: "LListD r = dsum (Id_on {Numb 0}) (dprod r (LListD r))"
13075
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   268
  by (fast intro!: LListD.intros [unfolded NIL_def CONS_def]
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   269
           elim: LListD.cases [unfolded NIL_def CONS_def])
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   270
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   271
lemma LListD_implies_ntrunc_equality [rule_format]:
30198
922f944f03b2 name changes
nipkow
parents: 26793
diff changeset
   272
     "\<forall>M N. (M,N) \<in> LListD(Id_on A) --> ntrunc k M = ntrunc k N"
17841
b1f10b98430d tidying
paulson
parents: 16417
diff changeset
   273
apply (induct_tac "k" rule: nat_less_induct) 
13075
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   274
apply (safe del: equalityI)
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   275
apply (erule LListD.cases)
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   276
apply (safe del: equalityI)
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   277
apply (case_tac "n", simp)
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   278
apply (rename_tac "n'")
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   279
apply (case_tac "n'")
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   280
apply (simp_all add: CONS_def less_Suc_eq)
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   281
done
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   282
13107
8743cc847224 tuned presentation;
wenzelm
parents: 13075
diff changeset
   283
text{*The domain of the @{text LListD} relation*}
13075
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   284
lemma Domain_LListD: 
30198
922f944f03b2 name changes
nipkow
parents: 26793
diff changeset
   285
    "Domain (LListD(Id_on A)) \<subseteq> llist(A)"
23746
a455e69c31cc Adapted to new inductive definition package.
berghofe
parents: 21404
diff changeset
   286
apply (rule subsetI)
a455e69c31cc Adapted to new inductive definition package.
berghofe
parents: 21404
diff changeset
   287
apply (erule llist.coinduct)
a455e69c31cc Adapted to new inductive definition package.
berghofe
parents: 21404
diff changeset
   288
apply (simp add: NIL_def CONS_def)
a455e69c31cc Adapted to new inductive definition package.
berghofe
parents: 21404
diff changeset
   289
apply (drule_tac P = "%x. xa \<in> Domain x" in LListD_unfold [THEN subst], auto)
13075
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   290
done
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   291
13107
8743cc847224 tuned presentation;
wenzelm
parents: 13075
diff changeset
   292
text{*This inclusion justifies the use of coinduction to show @{text "M = N"}*}
30198
922f944f03b2 name changes
nipkow
parents: 26793
diff changeset
   293
lemma LListD_subset_Id_on: "LListD(Id_on A) \<subseteq> Id_on(llist(A))"
13075
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   294
apply (rule subsetI)
17841
b1f10b98430d tidying
paulson
parents: 16417
diff changeset
   295
apply (rule_tac p = x in PairE, safe)
30198
922f944f03b2 name changes
nipkow
parents: 26793
diff changeset
   296
apply (rule Id_on_eqI)
17841
b1f10b98430d tidying
paulson
parents: 16417
diff changeset
   297
apply (rule LListD_implies_ntrunc_equality [THEN ntrunc_equality], assumption) 
13075
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   298
apply (erule DomainI [THEN Domain_LListD [THEN subsetD]])
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   299
done
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   300
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   301
13107
8743cc847224 tuned presentation;
wenzelm
parents: 13075
diff changeset
   302
subsubsection{* Coinduction, using @{text LListD_Fun} *}
8743cc847224 tuned presentation;
wenzelm
parents: 13075
diff changeset
   303
8743cc847224 tuned presentation;
wenzelm
parents: 13075
diff changeset
   304
text {* THE COINDUCTIVE DEFINITION PACKAGE COULD DO THIS! *}
13075
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   305
17841
b1f10b98430d tidying
paulson
parents: 16417
diff changeset
   306
lemma LListD_Fun_mono: "A\<subseteq>B ==> LListD_Fun r A \<subseteq> LListD_Fun r B"
b1f10b98430d tidying
paulson
parents: 16417
diff changeset
   307
apply (simp add: LListD_Fun_def)
13075
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   308
apply (assumption | rule basic_monos)+
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   309
done
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   310
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   311
lemma LListD_coinduct: 
17841
b1f10b98430d tidying
paulson
parents: 16417
diff changeset
   312
    "[| M \<in> X;  X \<subseteq> LListD_Fun r (X Un LListD(r)) |] ==>  M \<in> LListD(r)"
23746
a455e69c31cc Adapted to new inductive definition package.
berghofe
parents: 21404
diff changeset
   313
apply (cases M)
17841
b1f10b98430d tidying
paulson
parents: 16417
diff changeset
   314
apply (simp add: LListD_Fun_def)
13075
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   315
apply (erule LListD.coinduct)
17841
b1f10b98430d tidying
paulson
parents: 16417
diff changeset
   316
apply (auto ); 
13075
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   317
done
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   318
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   319
lemma LListD_Fun_NIL_I: "(NIL,NIL) \<in> LListD_Fun r s"
17841
b1f10b98430d tidying
paulson
parents: 16417
diff changeset
   320
by (simp add: LListD_Fun_def NIL_def)
13075
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   321
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   322
lemma LListD_Fun_CONS_I: 
30198
922f944f03b2 name changes
nipkow
parents: 26793
diff changeset
   323
     "[| x\<in>A;  (M,N):s |] ==> (CONS x M, CONS x N) \<in> LListD_Fun (Id_on A) s"
17841
b1f10b98430d tidying
paulson
parents: 16417
diff changeset
   324
by (simp add: LListD_Fun_def CONS_def, blast)
13075
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   325
13107
8743cc847224 tuned presentation;
wenzelm
parents: 13075
diff changeset
   326
text{*Utilise the "strong" part, i.e. @{text "gfp(f)"}*}
13075
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   327
lemma LListD_Fun_LListD_I:
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   328
     "M \<in> LListD(r) ==> M \<in> LListD_Fun r (X Un LListD(r))"
23746
a455e69c31cc Adapted to new inductive definition package.
berghofe
parents: 21404
diff changeset
   329
apply (cases M)
a455e69c31cc Adapted to new inductive definition package.
berghofe
parents: 21404
diff changeset
   330
apply (simp add: LListD_Fun_def)
a455e69c31cc Adapted to new inductive definition package.
berghofe
parents: 21404
diff changeset
   331
apply (erule LListD.cases)
a455e69c31cc Adapted to new inductive definition package.
berghofe
parents: 21404
diff changeset
   332
apply auto
13075
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   333
done
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   334
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   335
13107
8743cc847224 tuned presentation;
wenzelm
parents: 13075
diff changeset
   336
text{*This converse inclusion helps to strengthen @{text LList_equalityI}*}
30198
922f944f03b2 name changes
nipkow
parents: 26793
diff changeset
   337
lemma Id_on_subset_LListD: "Id_on(llist(A)) \<subseteq> LListD(Id_on A)"
13075
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   338
apply (rule subsetI)
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   339
apply (erule LListD_coinduct)
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   340
apply (rule subsetI)
30198
922f944f03b2 name changes
nipkow
parents: 26793
diff changeset
   341
apply (erule Id_onE)
13075
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   342
apply (erule ssubst)
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   343
apply (erule llist.cases)
30198
922f944f03b2 name changes
nipkow
parents: 26793
diff changeset
   344
apply (simp_all add: Id_onI LListD_Fun_NIL_I LListD_Fun_CONS_I)
13075
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   345
done
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   346
30198
922f944f03b2 name changes
nipkow
parents: 26793
diff changeset
   347
lemma LListD_eq_Id_on: "LListD(Id_on A) = Id_on(llist(A))"
922f944f03b2 name changes
nipkow
parents: 26793
diff changeset
   348
apply (rule equalityI LListD_subset_Id_on Id_on_subset_LListD)+
13075
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   349
done
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   350
30198
922f944f03b2 name changes
nipkow
parents: 26793
diff changeset
   351
lemma LListD_Fun_Id_on_I: "M \<in> llist(A) ==> (M,M) \<in> LListD_Fun (Id_on A) (X Un Id_on(llist(A)))"
922f944f03b2 name changes
nipkow
parents: 26793
diff changeset
   352
apply (rule LListD_eq_Id_on [THEN subst])
13075
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   353
apply (rule LListD_Fun_LListD_I)
30198
922f944f03b2 name changes
nipkow
parents: 26793
diff changeset
   354
apply (simp add: LListD_eq_Id_on Id_onI)
13075
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   355
done
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   356
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   357
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   358
subsubsection{* To show two LLists are equal, exhibit a bisimulation! 
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   359
      [also admits true equality]
13107
8743cc847224 tuned presentation;
wenzelm
parents: 13075
diff changeset
   360
   Replace @{text A} by some particular set, like @{text "{x. True}"}??? *}
13075
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   361
lemma LList_equalityI:
30198
922f944f03b2 name changes
nipkow
parents: 26793
diff changeset
   362
     "[| (M,N) \<in> r;  r \<subseteq> LListD_Fun (Id_on A) (r Un Id_on(llist(A))) |] 
13075
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   363
      ==>  M=N"
30198
922f944f03b2 name changes
nipkow
parents: 26793
diff changeset
   364
apply (rule LListD_subset_Id_on [THEN subsetD, THEN Id_onE])
13075
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   365
apply (erule LListD_coinduct)
30198
922f944f03b2 name changes
nipkow
parents: 26793
diff changeset
   366
apply (simp add: LListD_eq_Id_on, safe)
13075
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   367
done
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   368
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   369
13107
8743cc847224 tuned presentation;
wenzelm
parents: 13075
diff changeset
   370
subsection{* Finality of @{text "llist(A)"}: Uniqueness of functions defined by corecursion *}
13075
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   371
13107
8743cc847224 tuned presentation;
wenzelm
parents: 13075
diff changeset
   372
text{*We must remove @{text Pair_eq} because it may turn an instance of reflexivity
8743cc847224 tuned presentation;
wenzelm
parents: 13075
diff changeset
   373
  @{text "(h1 b, h2 b) = (h1 ?x17, h2 ?x17)"} into a conjunction! 
13075
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   374
  (or strengthen the Solver?) 
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   375
*}
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   376
declare Pair_eq [simp del]
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   377
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   378
text{*abstract proof using a bisimulation*}
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   379
lemma LList_corec_unique:
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   380
 "[| !!x. h1(x) = (case f x of None => NIL | Some(z,w) => CONS z (h1 w));   
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   381
     !!x. h2(x) = (case f x of None => NIL | Some(z,w) => CONS z (h2 w)) |] 
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   382
  ==> h1=h2"
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   383
apply (rule ext)
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   384
txt{*next step avoids an unknown (and flexflex pair) in simplification*}
17841
b1f10b98430d tidying
paulson
parents: 16417
diff changeset
   385
apply (rule_tac A = UNIV and r = "range(%u. (h1 u, h2 u))" 
13075
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   386
       in LList_equalityI)
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   387
apply (rule rangeI, safe)
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   388
apply (simp add: LListD_Fun_NIL_I UNIV_I [THEN LListD_Fun_CONS_I])
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   389
done
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   390
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   391
lemma equals_LList_corec:
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   392
 "[| !!x. h(x) = (case f x of None => NIL | Some(z,w) => CONS z (h w)) |]  
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   393
  ==> h = (%x. LList_corec x f)"
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   394
by (simp add: LList_corec_unique LList_corec) 
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   395
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   396
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   397
subsubsection{*Obsolete proof of @{text LList_corec_unique}: 
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   398
               complete induction, not coinduction *}
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   399
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   400
lemma ntrunc_one_CONS [simp]: "ntrunc (Suc 0) (CONS M N) = {}"
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   401
by (simp add: CONS_def ntrunc_one_In1)
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   402
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   403
lemma ntrunc_CONS [simp]: 
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   404
    "ntrunc (Suc(Suc(k))) (CONS M N) = CONS (ntrunc k M) (ntrunc k N)"
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   405
by (simp add: CONS_def)
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   406
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   407
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   408
lemma
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   409
 assumes prem1:
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   410
          "!!x. h1 x = (case f x of None => NIL | Some(z,w) => CONS z (h1 w))"
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   411
     and prem2:
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   412
          "!!x. h2 x = (case f x of None => NIL | Some(z,w) => CONS z (h2 w))"
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   413
 shows "h1=h2"
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   414
apply (rule ntrunc_equality [THEN ext])
17841
b1f10b98430d tidying
paulson
parents: 16417
diff changeset
   415
apply (rule_tac x = x in spec)
13075
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   416
apply (induct_tac "k" rule: nat_less_induct)
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   417
apply (rename_tac "n")
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   418
apply (rule allI)
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   419
apply (subst prem1)
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   420
apply (subst prem2, simp)
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   421
apply (intro strip) 
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   422
apply (case_tac "n") 
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   423
apply (rename_tac [2] "m")
17841
b1f10b98430d tidying
paulson
parents: 16417
diff changeset
   424
apply (case_tac [2] "m", simp_all)
13075
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   425
done
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   426
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   427
13107
8743cc847224 tuned presentation;
wenzelm
parents: 13075
diff changeset
   428
subsection{*Lconst: defined directly by @{text lfp} *}
13075
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   429
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   430
text{*But it could be defined by corecursion.*}
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   431
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   432
lemma Lconst_fun_mono: "mono(CONS(M))"
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   433
apply (rule monoI subset_refl CONS_mono)+
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   434
apply assumption 
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   435
done
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   436
13107
8743cc847224 tuned presentation;
wenzelm
parents: 13075
diff changeset
   437
text{* @{text "Lconst(M) = CONS M (Lconst M)"} *}
13075
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   438
lemmas Lconst = Lconst_fun_mono [THEN Lconst_def [THEN def_lfp_unfold]]
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   439
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   440
text{*A typical use of co-induction to show membership in the gfp.
13107
8743cc847224 tuned presentation;
wenzelm
parents: 13075
diff changeset
   441
  The containing set is simply the singleton @{text "{Lconst(M)}"}. *}
13075
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   442
lemma Lconst_type: "M\<in>A ==> Lconst(M): llist(A)"
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   443
apply (rule singletonI [THEN llist_coinduct], safe)
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   444
apply (rule_tac P = "%u. u \<in> ?A" in Lconst [THEN ssubst])
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   445
apply (assumption | rule list_Fun_CONS_I singletonI UnI1)+
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   446
done
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   447
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   448
lemma Lconst_eq_LList_corec: "Lconst(M) = LList_corec M (%x. Some(x,x))"
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   449
apply (rule equals_LList_corec [THEN fun_cong], simp)
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   450
apply (rule Lconst)
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   451
done
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   452
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   453
text{*Thus we could have used gfp in the definition of Lconst*}
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   454
lemma gfp_Lconst_eq_LList_corec: "gfp(%N. CONS M N) = LList_corec M (%x. Some(x,x))"
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   455
apply (rule equals_LList_corec [THEN fun_cong], simp)
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   456
apply (rule Lconst_fun_mono [THEN gfp_unfold])
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   457
done
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   458
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   459
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   460
subsection{* Isomorphisms *}
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   461
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   462
lemma LListI: "x \<in> llist (range Leaf) ==> x \<in> LList"
17841
b1f10b98430d tidying
paulson
parents: 16417
diff changeset
   463
by (simp add: LList_def)
13075
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   464
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   465
lemma LListD: "x \<in> LList ==> x \<in> llist (range Leaf)"
17841
b1f10b98430d tidying
paulson
parents: 16417
diff changeset
   466
by (simp add: LList_def)
13075
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   467
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   468
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   469
subsubsection{* Distinctness of constructors *}
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   470
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   471
lemma LCons_not_LNil [iff]: "~ LCons x xs = LNil"
17841
b1f10b98430d tidying
paulson
parents: 16417
diff changeset
   472
apply (simp add: LNil_def LCons_def)
13075
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   473
apply (subst Abs_LList_inject)
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   474
apply (rule llist.intros CONS_not_NIL rangeI LListI Rep_LList [THEN LListD])+
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   475
done
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   476
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   477
lemmas LNil_not_LCons [iff] = LCons_not_LNil [THEN not_sym, standard]
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   478
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   479
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   480
subsubsection{* llist constructors *}
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   481
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   482
lemma Rep_LList_LNil: "Rep_LList LNil = NIL"
17841
b1f10b98430d tidying
paulson
parents: 16417
diff changeset
   483
apply (simp add: LNil_def)
13075
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   484
apply (rule llist.NIL_I [THEN LListI, THEN Abs_LList_inverse])
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   485
done
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   486
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   487
lemma Rep_LList_LCons: "Rep_LList(LCons x l) = CONS (Leaf x) (Rep_LList l)"
17841
b1f10b98430d tidying
paulson
parents: 16417
diff changeset
   488
apply (simp add: LCons_def)
13075
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   489
apply (rule llist.CONS_I [THEN LListI, THEN Abs_LList_inverse] 
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   490
            rangeI Rep_LList [THEN LListD])+
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   491
done
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   492
13107
8743cc847224 tuned presentation;
wenzelm
parents: 13075
diff changeset
   493
subsubsection{* Injectiveness of @{text CONS} and @{text LCons} *}
13075
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   494
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   495
lemma CONS_CONS_eq2: "(CONS M N=CONS M' N') = (M=M' & N=N')"
17841
b1f10b98430d tidying
paulson
parents: 16417
diff changeset
   496
apply (simp add: CONS_def)
13075
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   497
done
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   498
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   499
lemmas CONS_inject = CONS_CONS_eq [THEN iffD1, THEN conjE, standard]
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   500
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   501
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   502
text{*For reasoning about abstract llist constructors*}
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   503
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   504
declare Rep_LList [THEN LListD, intro] LListI [intro]
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   505
declare llist.intros [intro]
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   506
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   507
lemma LCons_LCons_eq [iff]: "(LCons x xs=LCons y ys) = (x=y & xs=ys)"
17841
b1f10b98430d tidying
paulson
parents: 16417
diff changeset
   508
apply (simp add: LCons_def)
13075
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   509
apply (subst Abs_LList_inject)
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   510
apply (auto simp add: Rep_LList_inject)
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   511
done
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   512
13524
604d0f3622d6 *** empty log message ***
wenzelm
parents: 13107
diff changeset
   513
lemma CONS_D2: "CONS M N \<in> llist(A) ==> M \<in> A & N \<in> llist(A)"
13075
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   514
apply (erule llist.cases)
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   515
apply (erule CONS_neq_NIL, fast)
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   516
done
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   517
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   518
13107
8743cc847224 tuned presentation;
wenzelm
parents: 13075
diff changeset
   519
subsection{* Reasoning about @{text "llist(A)"} *}
13075
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   520
13107
8743cc847224 tuned presentation;
wenzelm
parents: 13075
diff changeset
   521
text{*A special case of @{text list_equality} for functions over lazy lists*}
13075
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   522
lemma LList_fun_equalityI:
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   523
 "[| M \<in> llist(A); g(NIL): llist(A);                              
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   524
     f(NIL)=g(NIL);                                              
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   525
     !!x l. [| x\<in>A;  l \<in> llist(A) |] ==>                          
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   526
            (f(CONS x l),g(CONS x l)) \<in>                          
30198
922f944f03b2 name changes
nipkow
parents: 26793
diff changeset
   527
                LListD_Fun (Id_on A) ((%u.(f(u),g(u)))`llist(A) Un   
922f944f03b2 name changes
nipkow
parents: 26793
diff changeset
   528
                                    Id_on(llist(A)))              
13075
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   529
  |] ==> f(M) = g(M)"
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   530
apply (rule LList_equalityI)
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   531
apply (erule imageI)
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   532
apply (rule image_subsetI)
23746
a455e69c31cc Adapted to new inductive definition package.
berghofe
parents: 21404
diff changeset
   533
apply (erule_tac a=x in llist.cases)
30198
922f944f03b2 name changes
nipkow
parents: 26793
diff changeset
   534
apply (erule ssubst, erule ssubst, erule LListD_Fun_Id_on_I, blast) 
13075
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   535
done
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   536
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   537
13107
8743cc847224 tuned presentation;
wenzelm
parents: 13075
diff changeset
   538
subsection{* The functional @{text Lmap} *}
13075
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   539
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   540
lemma Lmap_NIL [simp]: "Lmap f NIL = NIL"
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   541
by (rule Lmap_def [THEN def_LList_corec, THEN trans], simp)
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   542
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   543
lemma Lmap_CONS [simp]: "Lmap f (CONS M N) = CONS (f M) (Lmap f N)"
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   544
by (rule Lmap_def [THEN def_LList_corec, THEN trans], simp)
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   545
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   546
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   547
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   548
text{*Another type-checking proof by coinduction*}
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   549
lemma Lmap_type:
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   550
     "[| M \<in> llist(A);  !!x. x\<in>A ==> f(x):B |] ==> Lmap f M \<in> llist(B)"
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   551
apply (erule imageI [THEN llist_coinduct], safe)
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   552
apply (erule llist.cases, simp_all)
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   553
done
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   554
13107
8743cc847224 tuned presentation;
wenzelm
parents: 13075
diff changeset
   555
text{*This type checking rule synthesises a sufficiently large set for @{text f}*}
13075
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   556
lemma Lmap_type2: "M \<in> llist(A) ==> Lmap f M \<in> llist(f`A)"
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   557
apply (erule Lmap_type)
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   558
apply (erule imageI)
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   559
done
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   560
13107
8743cc847224 tuned presentation;
wenzelm
parents: 13075
diff changeset
   561
subsubsection{* Two easy results about @{text Lmap} *}
13075
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   562
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   563
lemma Lmap_compose: "M \<in> llist(A) ==> Lmap (f o g) M = Lmap f (Lmap g M)"
17841
b1f10b98430d tidying
paulson
parents: 16417
diff changeset
   564
apply (simp add: o_def)
13075
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   565
apply (drule imageI)
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   566
apply (erule LList_equalityI, safe)
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   567
apply (erule llist.cases, simp_all)
26793
e36a92ff543e Instantiated some rules to avoid problems with HO unification.
berghofe
parents: 23746
diff changeset
   568
apply (rule LListD_Fun_NIL_I imageI UnI1 rangeI [THEN LListD_Fun_CONS_I, of _ _ _ f])+
13075
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   569
apply assumption  
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   570
done
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   571
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   572
lemma Lmap_ident: "M \<in> llist(A) ==> Lmap (%x. x) M = M"
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   573
apply (drule imageI)
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   574
apply (erule LList_equalityI, safe)
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   575
apply (erule llist.cases, simp_all)
26793
e36a92ff543e Instantiated some rules to avoid problems with HO unification.
berghofe
parents: 23746
diff changeset
   576
apply (rule LListD_Fun_NIL_I imageI UnI1 rangeI [THEN LListD_Fun_CONS_I, of _ _ _ "%x. x"])+
13075
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   577
apply assumption 
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   578
done
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   579
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   580
13107
8743cc847224 tuned presentation;
wenzelm
parents: 13075
diff changeset
   581
subsection{* @{text Lappend} -- its two arguments cause some complications! *}
13075
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   582
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   583
lemma Lappend_NIL_NIL [simp]: "Lappend NIL NIL = NIL"
17841
b1f10b98430d tidying
paulson
parents: 16417
diff changeset
   584
apply (simp add: Lappend_def)
13075
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   585
apply (rule LList_corec [THEN trans], simp)
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   586
done
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   587
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   588
lemma Lappend_NIL_CONS [simp]: 
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   589
    "Lappend NIL (CONS N N') = CONS N (Lappend NIL N')"
17841
b1f10b98430d tidying
paulson
parents: 16417
diff changeset
   590
apply (simp add: Lappend_def)
13075
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   591
apply (rule LList_corec [THEN trans], simp)
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   592
done
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   593
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   594
lemma Lappend_CONS [simp]: 
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   595
    "Lappend (CONS M M') N = CONS M (Lappend M' N)"
17841
b1f10b98430d tidying
paulson
parents: 16417
diff changeset
   596
apply (simp add: Lappend_def)
13075
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   597
apply (rule LList_corec [THEN trans], simp)
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   598
done
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   599
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   600
declare llist.intros [simp] LListD_Fun_CONS_I [simp] 
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   601
        range_eqI [simp] image_eqI [simp]
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   602
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   603
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   604
lemma Lappend_NIL [simp]: "M \<in> llist(A) ==> Lappend NIL M = M"
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   605
by (erule LList_fun_equalityI, simp_all)
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   606
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   607
lemma Lappend_NIL2: "M \<in> llist(A) ==> Lappend M NIL = M"
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   608
by (erule LList_fun_equalityI, simp_all)
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   609
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   610
13107
8743cc847224 tuned presentation;
wenzelm
parents: 13075
diff changeset
   611
subsubsection{* Alternative type-checking proofs for @{text Lappend} *}
13075
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   612
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   613
text{*weak co-induction: bisimulation and case analysis on both variables*}
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   614
lemma Lappend_type: "[| M \<in> llist(A); N \<in> llist(A) |] ==> Lappend M N \<in> llist(A)"
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   615
apply (rule_tac X = "\<Union>u\<in>llist (A) . \<Union>v \<in> llist (A) . {Lappend u v}" in llist_coinduct)
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   616
apply fast
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   617
apply safe
23746
a455e69c31cc Adapted to new inductive definition package.
berghofe
parents: 21404
diff changeset
   618
apply (erule_tac a = u in llist.cases)
a455e69c31cc Adapted to new inductive definition package.
berghofe
parents: 21404
diff changeset
   619
apply (erule_tac a = v in llist.cases, simp_all, blast)
13075
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   620
done
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   621
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   622
text{*strong co-induction: bisimulation and case analysis on one variable*}
13524
604d0f3622d6 *** empty log message ***
wenzelm
parents: 13107
diff changeset
   623
lemma Lappend_type': "[| M \<in> llist(A); N \<in> llist(A) |] ==> Lappend M N \<in> llist(A)"
17841
b1f10b98430d tidying
paulson
parents: 16417
diff changeset
   624
apply (rule_tac X = "(%u. Lappend u N) `llist (A)" in llist_coinduct)
13075
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   625
apply (erule imageI)
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   626
apply (rule image_subsetI)
23746
a455e69c31cc Adapted to new inductive definition package.
berghofe
parents: 21404
diff changeset
   627
apply (erule_tac a = x in llist.cases)
13075
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   628
apply (simp add: list_Fun_llist_I, simp)
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   629
done
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   630
13107
8743cc847224 tuned presentation;
wenzelm
parents: 13075
diff changeset
   631
subsection{* Lazy lists as the type @{text "'a llist"} -- strongly typed versions of above *}
13075
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   632
13107
8743cc847224 tuned presentation;
wenzelm
parents: 13075
diff changeset
   633
subsubsection{* @{text llist_case}: case analysis for @{text "'a llist"} *}
13075
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   634
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   635
declare LListI [THEN Abs_LList_inverse, simp]
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   636
declare Rep_LList_inverse [simp]
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   637
declare Rep_LList [THEN LListD, simp]
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   638
declare rangeI [simp] inj_Leaf [simp] 
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   639
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   640
lemma llist_case_LNil [simp]: "llist_case c d LNil = c"
17841
b1f10b98430d tidying
paulson
parents: 16417
diff changeset
   641
by (simp add: llist_case_def LNil_def)
13075
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   642
17841
b1f10b98430d tidying
paulson
parents: 16417
diff changeset
   643
lemma llist_case_LCons [simp]: "llist_case c d (LCons M N) = d M N"
b1f10b98430d tidying
paulson
parents: 16417
diff changeset
   644
by (simp add: llist_case_def LCons_def)
b1f10b98430d tidying
paulson
parents: 16417
diff changeset
   645
13075
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   646
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   647
text{*Elimination is case analysis, not induction.*}
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   648
lemma llistE: "[| l=LNil ==> P;  !!x l'. l=LCons x l' ==> P |] ==> P"
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   649
apply (rule Rep_LList [THEN LListD, THEN llist.cases])
17841
b1f10b98430d tidying
paulson
parents: 16417
diff changeset
   650
 apply (simp add: Rep_LList_LNil [symmetric] Rep_LList_inject, blast) 
13075
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   651
apply (erule LListI [THEN Rep_LList_cases], clarify)
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   652
apply (simp add: Rep_LList_LCons [symmetric] Rep_LList_inject, blast) 
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   653
done
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   654
13107
8743cc847224 tuned presentation;
wenzelm
parents: 13075
diff changeset
   655
subsubsection{* @{text llist_corec}: corecursion for @{text "'a llist"} *}
13075
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   656
13107
8743cc847224 tuned presentation;
wenzelm
parents: 13075
diff changeset
   657
text{*Lemma for the proof of @{text llist_corec}*}
13075
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   658
lemma LList_corec_type2:
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   659
     "LList_corec a  
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   660
           (%z. case f z of None => None | Some(v,w) => Some(Leaf(v),w)) 
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   661
       \<in> llist(range Leaf)"
17841
b1f10b98430d tidying
paulson
parents: 16417
diff changeset
   662
apply (rule_tac X = "range (%x. LList_corec x ?g)" in llist_coinduct)
13075
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   663
apply (rule rangeI, safe)
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   664
apply (subst LList_corec, force)
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   665
done
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   666
33056
791a4655cae3 renamed "nitpick_const_xxx" attributes to "nitpick_xxx" and "nitpick_ind_intros" to "nitpick_intros"
blanchet
parents: 32655
diff changeset
   667
lemma llist_corec [nitpick_simp]: 
13075
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   668
    "llist_corec a f =   
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   669
     (case f a of None => LNil | Some(z,w) => LCons z (llist_corec w f))"
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   670
apply (unfold llist_corec_def LNil_def LCons_def)
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   671
apply (subst LList_corec)
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   672
apply (case_tac "f a")
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   673
apply (simp add: LList_corec_type2)
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   674
apply (force simp add: LList_corec_type2)
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   675
done
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   676
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   677
text{*definitional version of same*}
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   678
lemma def_llist_corec: 
19736
wenzelm
parents: 17841
diff changeset
   679
     "[| !!x. h(x) = llist_corec x f |] ==>      
13075
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   680
      h(a) = (case f a of None => LNil | Some(z,w) => LCons z (h w))"
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   681
by (simp add: llist_corec)
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   682
13107
8743cc847224 tuned presentation;
wenzelm
parents: 13075
diff changeset
   683
subsection{* Proofs about type @{text "'a llist"} functions *}
13075
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   684
13107
8743cc847224 tuned presentation;
wenzelm
parents: 13075
diff changeset
   685
subsection{* Deriving @{text llist_equalityI} -- @{text llist} equality is a bisimulation *}
13075
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   686
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   687
lemma LListD_Fun_subset_Times_llist: 
17841
b1f10b98430d tidying
paulson
parents: 16417
diff changeset
   688
    "r \<subseteq> (llist A) <*> (llist A) 
30198
922f944f03b2 name changes
nipkow
parents: 26793
diff changeset
   689
     ==> LListD_Fun (Id_on A) r \<subseteq> (llist A) <*> (llist A)"
15481
fc075ae929e4 the new subst tactic, by Lucas Dixon
paulson
parents: 15413
diff changeset
   690
by (auto simp add: LListD_Fun_def)
13075
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   691
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   692
lemma subset_Times_llist:
17841
b1f10b98430d tidying
paulson
parents: 16417
diff changeset
   693
     "prod_fun Rep_LList Rep_LList ` r \<subseteq>  
13075
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   694
     (llist(range Leaf)) <*> (llist(range Leaf))"
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   695
by (blast intro: Rep_LList [THEN LListD])
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   696
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   697
lemma prod_fun_lemma:
17841
b1f10b98430d tidying
paulson
parents: 16417
diff changeset
   698
     "r \<subseteq> (llist(range Leaf)) <*> (llist(range Leaf)) 
b1f10b98430d tidying
paulson
parents: 16417
diff changeset
   699
      ==> prod_fun (Rep_LList o Abs_LList) (Rep_LList o Abs_LList) ` r \<subseteq> r"
13075
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   700
apply safe
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   701
apply (erule subsetD [THEN SigmaE2], assumption)
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   702
apply (simp add: LListI [THEN Abs_LList_inverse])
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   703
done
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   704
30198
922f944f03b2 name changes
nipkow
parents: 26793
diff changeset
   705
lemma prod_fun_range_eq_Id_on:
13075
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   706
     "prod_fun Rep_LList  Rep_LList ` range(%x. (x, x)) =  
30198
922f944f03b2 name changes
nipkow
parents: 26793
diff changeset
   707
      Id_on(llist(range Leaf))"
13075
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   708
apply (rule equalityI, blast) 
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   709
apply (fast elim: LListI [THEN Abs_LList_inverse, THEN subst])
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   710
done
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   711
13107
8743cc847224 tuned presentation;
wenzelm
parents: 13075
diff changeset
   712
text{*Used with @{text lfilter}*}
13075
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   713
lemma llistD_Fun_mono: 
17841
b1f10b98430d tidying
paulson
parents: 16417
diff changeset
   714
    "A\<subseteq>B ==> llistD_Fun A \<subseteq> llistD_Fun B"
b1f10b98430d tidying
paulson
parents: 16417
diff changeset
   715
apply (simp add: llistD_Fun_def prod_fun_def, auto)
13075
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   716
apply (rule image_eqI)
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   717
 prefer 2 apply (blast intro: rev_subsetD [OF _ LListD_Fun_mono], force)
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   718
done
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   719
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   720
subsubsection{* To show two llists are equal, exhibit a bisimulation! 
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   721
      [also admits true equality] *}
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   722
lemma llist_equalityI: 
17841
b1f10b98430d tidying
paulson
parents: 16417
diff changeset
   723
    "[| (l1,l2) \<in> r;  r \<subseteq> llistD_Fun(r Un range(%x.(x,x))) |] ==> l1=l2"
b1f10b98430d tidying
paulson
parents: 16417
diff changeset
   724
apply (simp add: llistD_Fun_def)
13075
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   725
apply (rule Rep_LList_inject [THEN iffD1])
17841
b1f10b98430d tidying
paulson
parents: 16417
diff changeset
   726
apply (rule_tac r = "prod_fun Rep_LList Rep_LList `r" and A = "range (Leaf)" in LList_equalityI)
13075
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   727
apply (erule prod_fun_imageI)
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   728
apply (erule image_mono [THEN subset_trans])
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   729
apply (rule image_compose [THEN subst])
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   730
apply (rule prod_fun_compose [THEN subst])
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   731
apply (subst image_Un)
30198
922f944f03b2 name changes
nipkow
parents: 26793
diff changeset
   732
apply (subst prod_fun_range_eq_Id_on)
13075
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   733
apply (rule LListD_Fun_subset_Times_llist [THEN prod_fun_lemma])
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   734
apply (rule subset_Times_llist [THEN Un_least])
30198
922f944f03b2 name changes
nipkow
parents: 26793
diff changeset
   735
apply (rule Id_on_subset_Times)
13075
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   736
done
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   737
13107
8743cc847224 tuned presentation;
wenzelm
parents: 13075
diff changeset
   738
subsubsection{* Rules to prove the 2nd premise of @{text llist_equalityI} *}
13075
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   739
lemma llistD_Fun_LNil_I [simp]: "(LNil,LNil) \<in> llistD_Fun(r)"
17841
b1f10b98430d tidying
paulson
parents: 16417
diff changeset
   740
apply (simp add: llistD_Fun_def LNil_def)
13075
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   741
apply (rule LListD_Fun_NIL_I [THEN prod_fun_imageI])
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   742
done
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   743
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   744
lemma llistD_Fun_LCons_I [simp]: 
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   745
    "(l1,l2):r ==> (LCons x l1, LCons x l2) \<in> llistD_Fun(r)"
17841
b1f10b98430d tidying
paulson
parents: 16417
diff changeset
   746
apply (simp add: llistD_Fun_def LCons_def)
13075
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   747
apply (rule rangeI [THEN LListD_Fun_CONS_I, THEN prod_fun_imageI])
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   748
apply (erule prod_fun_imageI)
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   749
done
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   750
13107
8743cc847224 tuned presentation;
wenzelm
parents: 13075
diff changeset
   751
text{*Utilise the "strong" part, i.e. @{text "gfp(f)"}*}
13075
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   752
lemma llistD_Fun_range_I: "(l,l) \<in> llistD_Fun(r Un range(%x.(x,x)))"
17841
b1f10b98430d tidying
paulson
parents: 16417
diff changeset
   753
apply (simp add: llistD_Fun_def)
13075
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   754
apply (rule Rep_LList_inverse [THEN subst])
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   755
apply (rule prod_fun_imageI)
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   756
apply (subst image_Un)
30198
922f944f03b2 name changes
nipkow
parents: 26793
diff changeset
   757
apply (subst prod_fun_range_eq_Id_on)
922f944f03b2 name changes
nipkow
parents: 26793
diff changeset
   758
apply (rule Rep_LList [THEN LListD, THEN LListD_Fun_Id_on_I])
13075
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   759
done
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   760
13107
8743cc847224 tuned presentation;
wenzelm
parents: 13075
diff changeset
   761
text{*A special case of @{text list_equality} for functions over lazy lists*}
13075
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   762
lemma llist_fun_equalityI:
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   763
     "[| f(LNil)=g(LNil);                                                 
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   764
         !!x l. (f(LCons x l),g(LCons x l)) 
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   765
                \<in> llistD_Fun(range(%u. (f(u),g(u))) Un range(%v. (v,v)))    
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   766
      |] ==> f(l) = (g(l :: 'a llist) :: 'b llist)"
17841
b1f10b98430d tidying
paulson
parents: 16417
diff changeset
   767
apply (rule_tac r = "range (%u. (f (u),g (u)))" in llist_equalityI)
13075
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   768
apply (rule rangeI, clarify) 
17841
b1f10b98430d tidying
paulson
parents: 16417
diff changeset
   769
apply (rule_tac l = u in llistE)
13075
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   770
apply (simp_all add: llistD_Fun_range_I) 
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   771
done
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   772
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   773
13107
8743cc847224 tuned presentation;
wenzelm
parents: 13075
diff changeset
   774
subsection{* The functional @{text lmap} *}
13075
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   775
33056
791a4655cae3 renamed "nitpick_const_xxx" attributes to "nitpick_xxx" and "nitpick_ind_intros" to "nitpick_intros"
blanchet
parents: 32655
diff changeset
   776
lemma lmap_LNil [simp, nitpick_simp]: "lmap f LNil = LNil"
13075
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   777
by (rule lmap_def [THEN def_llist_corec, THEN trans], simp)
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   778
33056
791a4655cae3 renamed "nitpick_const_xxx" attributes to "nitpick_xxx" and "nitpick_ind_intros" to "nitpick_intros"
blanchet
parents: 32655
diff changeset
   779
lemma lmap_LCons [simp, nitpick_simp]:
32655
dd84779cd191 Added "nitpick_const_simp" tags to lazy list theories.
blanchet
parents: 30198
diff changeset
   780
"lmap f (LCons M N) = LCons (f M) (lmap f N)"
13075
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   781
by (rule lmap_def [THEN def_llist_corec, THEN trans], simp)
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   782
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   783
13107
8743cc847224 tuned presentation;
wenzelm
parents: 13075
diff changeset
   784
subsubsection{* Two easy results about @{text lmap} *}
13075
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   785
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   786
lemma lmap_compose [simp]: "lmap (f o g) l = lmap f (lmap g l)"
17841
b1f10b98430d tidying
paulson
parents: 16417
diff changeset
   787
by (rule_tac l = l in llist_fun_equalityI, simp_all)
13075
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   788
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   789
lemma lmap_ident [simp]: "lmap (%x. x) l = l"
17841
b1f10b98430d tidying
paulson
parents: 16417
diff changeset
   790
by (rule_tac l = l in llist_fun_equalityI, simp_all)
13075
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   791
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   792
13107
8743cc847224 tuned presentation;
wenzelm
parents: 13075
diff changeset
   793
subsection{* iterates -- @{text llist_fun_equalityI} cannot be used! *}
13075
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   794
33056
791a4655cae3 renamed "nitpick_const_xxx" attributes to "nitpick_xxx" and "nitpick_ind_intros" to "nitpick_intros"
blanchet
parents: 32655
diff changeset
   795
lemma iterates [nitpick_simp]: "iterates f x = LCons x (iterates f (f x))"
13075
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   796
by (rule iterates_def [THEN def_llist_corec, THEN trans], simp)
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   797
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   798
lemma lmap_iterates [simp]: "lmap f (iterates f x) = iterates f (f x)"
17841
b1f10b98430d tidying
paulson
parents: 16417
diff changeset
   799
apply (rule_tac r = "range (%u. (lmap f (iterates f u),iterates f (f u)))" in llist_equalityI)
13075
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   800
apply (rule rangeI, safe)
17841
b1f10b98430d tidying
paulson
parents: 16417
diff changeset
   801
apply (rule_tac x1 = "f (u)" in iterates [THEN ssubst])
b1f10b98430d tidying
paulson
parents: 16417
diff changeset
   802
apply (rule_tac x1 = u in iterates [THEN ssubst], simp)
13075
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   803
done
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   804
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   805
lemma iterates_lmap: "iterates f x = LCons x (lmap f (iterates f x))"
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   806
apply (subst lmap_iterates)
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   807
apply (rule iterates)
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   808
done
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   809
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   810
subsection{* A rather complex proof about iterates -- cf Andy Pitts *}
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   811
13107
8743cc847224 tuned presentation;
wenzelm
parents: 13075
diff changeset
   812
subsubsection{* Two lemmas about @{text "natrec n x (%m. g)"}, which is essentially
8743cc847224 tuned presentation;
wenzelm
parents: 13075
diff changeset
   813
  @{text "(g^n)(x)"} *}
13075
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   814
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   815
lemma fun_power_lmap: "nat_rec (LCons b l) (%m. lmap(f)) n =       
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   816
     LCons (nat_rec b (%m. f) n) (nat_rec l (%m. lmap(f)) n)"
17841
b1f10b98430d tidying
paulson
parents: 16417
diff changeset
   817
by (induct_tac "n", simp_all)
13075
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   818
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   819
lemma fun_power_Suc: "nat_rec (g x) (%m. g) n = nat_rec x (%m. g) (Suc n)"
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   820
by (induct_tac "n", simp_all)
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   821
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   822
lemmas Pair_cong = refl [THEN cong, THEN cong, of concl: Pair]
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   823
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   824
13107
8743cc847224 tuned presentation;
wenzelm
parents: 13075
diff changeset
   825
text{*The bisimulation consists of @{text "{(lmap(f)^n (h(u)), lmap(f)^n (iterates(f,u)))}"}
8743cc847224 tuned presentation;
wenzelm
parents: 13075
diff changeset
   826
  for all @{text u} and all @{text "n::nat"}.*}
13075
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   827
lemma iterates_equality:
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   828
     "(!!x. h(x) = LCons x (lmap f (h x))) ==> h = iterates(f)"
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   829
apply (rule ext)
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   830
apply (rule_tac 
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   831
       r = "\<Union>u. range (%n. (nat_rec (h u) (%m y. lmap f y) n, 
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   832
                             nat_rec (iterates f u) (%m y. lmap f y) n))" 
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   833
       in llist_equalityI)
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   834
apply (rule UN1_I range_eqI Pair_cong nat_rec_0 [symmetric])+
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   835
apply clarify
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   836
apply (subst iterates, atomize)
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   837
apply (drule_tac x=u in spec) 
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   838
apply (erule ssubst) 
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   839
apply (subst fun_power_lmap)
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   840
apply (subst fun_power_lmap)
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   841
apply (rule llistD_Fun_LCons_I)
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   842
apply (rule lmap_iterates [THEN subst])
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   843
apply (subst fun_power_Suc)
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   844
apply (subst fun_power_Suc, blast)
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   845
done
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   846
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   847
13107
8743cc847224 tuned presentation;
wenzelm
parents: 13075
diff changeset
   848
subsection{* @{text lappend} -- its two arguments cause some complications! *}
13075
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   849
33056
791a4655cae3 renamed "nitpick_const_xxx" attributes to "nitpick_xxx" and "nitpick_ind_intros" to "nitpick_intros"
blanchet
parents: 32655
diff changeset
   850
lemma lappend_LNil_LNil [simp, nitpick_simp]: "lappend LNil LNil = LNil"
17841
b1f10b98430d tidying
paulson
parents: 16417
diff changeset
   851
apply (simp add: lappend_def)
13075
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   852
apply (rule llist_corec [THEN trans], simp)
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   853
done
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   854
33056
791a4655cae3 renamed "nitpick_const_xxx" attributes to "nitpick_xxx" and "nitpick_ind_intros" to "nitpick_intros"
blanchet
parents: 32655
diff changeset
   855
lemma lappend_LNil_LCons [simp, nitpick_simp]: 
13075
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   856
    "lappend LNil (LCons l l') = LCons l (lappend LNil l')"
17841
b1f10b98430d tidying
paulson
parents: 16417
diff changeset
   857
apply (simp add: lappend_def)
13075
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   858
apply (rule llist_corec [THEN trans], simp)
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   859
done
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   860
33056
791a4655cae3 renamed "nitpick_const_xxx" attributes to "nitpick_xxx" and "nitpick_ind_intros" to "nitpick_intros"
blanchet
parents: 32655
diff changeset
   861
lemma lappend_LCons [simp, nitpick_simp]: 
13075
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   862
    "lappend (LCons l l') N = LCons l (lappend l' N)"
17841
b1f10b98430d tidying
paulson
parents: 16417
diff changeset
   863
apply (simp add: lappend_def)
13075
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   864
apply (rule llist_corec [THEN trans], simp)
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   865
done
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   866
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   867
lemma lappend_LNil [simp]: "lappend LNil l = l"
17841
b1f10b98430d tidying
paulson
parents: 16417
diff changeset
   868
by (rule_tac l = l in llist_fun_equalityI, simp_all)
13075
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   869
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   870
lemma lappend_LNil2 [simp]: "lappend l LNil = l"
17841
b1f10b98430d tidying
paulson
parents: 16417
diff changeset
   871
by (rule_tac l = l in llist_fun_equalityI, simp_all)
13075
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   872
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   873
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   874
text{*The infinite first argument blocks the second*}
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   875
lemma lappend_iterates [simp]: "lappend (iterates f x) N = iterates f x"
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   876
apply (rule_tac r = "range (%u. (lappend (iterates f u) N,iterates f u))" 
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   877
       in llist_equalityI)
17841
b1f10b98430d tidying
paulson
parents: 16417
diff changeset
   878
 apply (rule rangeI, safe)
15944
9b00875e21f7 from simplesubst to new subst
paulson
parents: 15481
diff changeset
   879
apply (subst (1 2) iterates)
9b00875e21f7 from simplesubst to new subst
paulson
parents: 15481
diff changeset
   880
apply simp 
13075
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   881
done
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   882
13107
8743cc847224 tuned presentation;
wenzelm
parents: 13075
diff changeset
   883
subsubsection{* Two proofs that @{text lmap} distributes over lappend *}
13075
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   884
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   885
text{*Long proof requiring case analysis on both both arguments*}
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   886
lemma lmap_lappend_distrib:
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   887
     "lmap f (lappend l n) = lappend (lmap f l) (lmap f n)"
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   888
apply (rule_tac r = "\<Union>n. range (%l. (lmap f (lappend l n),
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   889
                                      lappend (lmap f l) (lmap f n)))" 
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   890
       in llist_equalityI)
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   891
apply (rule UN1_I)
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   892
apply (rule rangeI, safe)
17841
b1f10b98430d tidying
paulson
parents: 16417
diff changeset
   893
apply (rule_tac l = l in llistE)
b1f10b98430d tidying
paulson
parents: 16417
diff changeset
   894
apply (rule_tac l = n in llistE, simp_all)
13075
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   895
apply (blast intro: llistD_Fun_LCons_I) 
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   896
done
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   897
13107
8743cc847224 tuned presentation;
wenzelm
parents: 13075
diff changeset
   898
text{*Shorter proof of theorem above using @{text llist_equalityI} as strong coinduction*}
13524
604d0f3622d6 *** empty log message ***
wenzelm
parents: 13107
diff changeset
   899
lemma lmap_lappend_distrib':
13075
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   900
     "lmap f (lappend l n) = lappend (lmap f l) (lmap f n)"
17841
b1f10b98430d tidying
paulson
parents: 16417
diff changeset
   901
by (rule_tac l = l in llist_fun_equalityI, auto)
13075
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   902
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   903
text{*Without strong coinduction, three case analyses might be needed*}
13524
604d0f3622d6 *** empty log message ***
wenzelm
parents: 13107
diff changeset
   904
lemma lappend_assoc': "lappend (lappend l1 l2) l3 = lappend l1 (lappend l2 l3)"
17841
b1f10b98430d tidying
paulson
parents: 16417
diff changeset
   905
by (rule_tac l = l1 in llist_fun_equalityI, auto)
13075
d3e1d554cd6d conversion of some HOL/Induct proof scripts to Isar
paulson
parents: 10834
diff changeset
   906
33197
de6285ebcc05 continuation of Nitpick's integration into Isabelle;
blanchet
parents: 33056
diff changeset
   907
setup {*
33209
d36ca3960e33 tuned white space;
wenzelm
parents: 33197
diff changeset
   908
  Nitpick.register_codatatype @{typ "'a llist"} @{const_name llist_case}
d36ca3960e33 tuned white space;
wenzelm
parents: 33197
diff changeset
   909
    (map dest_Const [@{term LNil}, @{term LCons}])
33197
de6285ebcc05 continuation of Nitpick's integration into Isabelle;
blanchet
parents: 33056
diff changeset
   910
*}
de6285ebcc05 continuation of Nitpick's integration into Isabelle;
blanchet
parents: 33056
diff changeset
   911
3120
c58423c20740 New directory to contain examples of (co)inductive definitions
paulson
parents:
diff changeset
   912
end