src/HOL/HOLCF/Tutorial/Domain_ex.thy
author kuncar
Fri Dec 09 18:07:04 2011 +0100 (2011-12-09)
changeset 45802 b16f976db515
parent 42151 4da4fc77664b
child 58880 0baae4311a9f
permissions -rw-r--r--
Quotient_Info stores only relation maps
wenzelm@42151
     1
(*  Title:      HOL/HOLCF/Tutorial/Domain_ex.thy
huffman@30920
     2
    Author:     Brian Huffman
huffman@30920
     3
*)
huffman@30920
     4
huffman@30920
     5
header {* Domain package examples *}
huffman@30920
     6
huffman@30920
     7
theory Domain_ex
huffman@30920
     8
imports HOLCF
huffman@30920
     9
begin
huffman@30920
    10
huffman@30920
    11
text {* Domain constructors are strict by default. *}
huffman@30920
    12
huffman@30920
    13
domain d1 = d1a | d1b "d1" "d1"
huffman@30920
    14
huffman@30920
    15
lemma "d1b\<cdot>\<bottom>\<cdot>y = \<bottom>" by simp
huffman@30920
    16
huffman@30920
    17
text {* Constructors can be made lazy using the @{text "lazy"} keyword. *}
huffman@30920
    18
huffman@30920
    19
domain d2 = d2a | d2b (lazy "d2")
huffman@30920
    20
huffman@30920
    21
lemma "d2b\<cdot>x \<noteq> \<bottom>" by simp
huffman@30920
    22
huffman@30920
    23
text {* Strict and lazy arguments may be mixed arbitrarily. *}
huffman@30920
    24
huffman@30920
    25
domain d3 = d3a | d3b (lazy "d2") "d2"
huffman@30920
    26
huffman@30920
    27
lemma "P (d3b\<cdot>x\<cdot>y = \<bottom>) \<longleftrightarrow> P (y = \<bottom>)" by simp
huffman@30920
    28
huffman@30920
    29
text {* Selectors can be used with strict or lazy constructor arguments. *}
huffman@30920
    30
huffman@30920
    31
domain d4 = d4a | d4b (lazy d4b_left :: "d2") (d4b_right :: "d2")
huffman@30920
    32
huffman@30920
    33
lemma "y \<noteq> \<bottom> \<Longrightarrow> d4b_left\<cdot>(d4b\<cdot>x\<cdot>y) = x" by simp
huffman@30920
    34
huffman@30920
    35
text {* Mixfix declarations can be given for data constructors. *}
huffman@30920
    36
huffman@30920
    37
domain d5 = d5a | d5b (lazy "d5") "d5" (infixl ":#:" 70)
huffman@30920
    38
huffman@30920
    39
lemma "d5a \<noteq> x :#: y :#: z" by simp
huffman@30920
    40
huffman@30920
    41
text {* Mixfix declarations can also be given for type constructors. *}
huffman@30920
    42
huffman@30920
    43
domain ('a, 'b) lazypair (infixl ":*:" 25) =
huffman@30920
    44
  lpair (lazy lfst :: 'a) (lazy lsnd :: 'b) (infixl ":*:" 75)
huffman@30920
    45
huffman@30920
    46
lemma "\<forall>p::('a :*: 'b). p \<sqsubseteq> lfst\<cdot>p :*: lsnd\<cdot>p"
huffman@30920
    47
by (rule allI, case_tac p, simp_all)
huffman@30920
    48
huffman@30920
    49
text {* Non-recursive constructor arguments can have arbitrary types. *}
huffman@30920
    50
huffman@30920
    51
domain ('a, 'b) d6 = d6 "int lift" "'a \<oplus> 'b u" (lazy "('a :*: 'b) \<times> ('b \<rightarrow> 'a)")
huffman@30920
    52
huffman@30920
    53
text {*
huffman@30920
    54
  Indirect recusion is allowed for sums, products, lifting, and the
huffman@35585
    55
  continuous function space.  However, the domain package does not
huffman@35585
    56
  generate an induction rule in terms of the constructors.
huffman@30920
    57
*}
huffman@30920
    58
huffman@31232
    59
domain 'a d7 = d7a "'a d7 \<oplus> int lift" | d7b "'a \<otimes> 'a d7" | d7c (lazy "'a d7 \<rightarrow> 'a")
huffman@36120
    60
  -- "Indirect recursion detected, skipping proofs of (co)induction rules"
huffman@37000
    61
huffman@37000
    62
text {* Note that @{text d7.induct} is absent. *}
huffman@30920
    63
huffman@30920
    64
text {*
huffman@36120
    65
  Indirect recursion is also allowed using previously-defined datatypes.
huffman@30920
    66
*}
huffman@36120
    67
huffman@30920
    68
domain 'a slist = SNil | SCons 'a "'a slist"
huffman@36120
    69
huffman@36120
    70
domain 'a stree = STip | SBranch "'a stree slist"
huffman@30920
    71
huffman@30920
    72
text {* Mutually-recursive datatypes can be defined using the @{text "and"} keyword. *}
huffman@30920
    73
huffman@30920
    74
domain d8 = d8a | d8b "d9" and d9 = d9a | d9b (lazy "d8")
huffman@30920
    75
huffman@30920
    76
text {* Non-regular recursion is not allowed. *}
huffman@30920
    77
(*
huffman@30920
    78
domain ('a, 'b) altlist = ANil | ACons 'a "('b, 'a) altlist"
huffman@30920
    79
  -- "illegal direct recursion with different arguments"
huffman@30920
    80
domain 'a nest = Nest1 'a | Nest2 "'a nest nest"
huffman@30920
    81
  -- "illegal direct recursion with different arguments"
huffman@30920
    82
*)
huffman@30920
    83
huffman@30920
    84
text {*
huffman@30920
    85
  Mutually-recursive datatypes must have all the same type arguments,
huffman@30920
    86
  not necessarily in the same order.
huffman@30920
    87
*}
huffman@30920
    88
huffman@30920
    89
domain ('a, 'b) list1 = Nil1 | Cons1 'a "('b, 'a) list2"
huffman@30920
    90
   and ('b, 'a) list2 = Nil2 | Cons2 'b "('a, 'b) list1"
huffman@30920
    91
huffman@30920
    92
text {* Induction rules for flat datatypes have no admissibility side-condition. *}
huffman@30920
    93
huffman@30920
    94
domain 'a flattree = Tip | Branch "'a flattree" "'a flattree"
huffman@30920
    95
huffman@30920
    96
lemma "\<lbrakk>P \<bottom>; P Tip; \<And>x y. \<lbrakk>x \<noteq> \<bottom>; y \<noteq> \<bottom>; P x; P y\<rbrakk> \<Longrightarrow> P (Branch\<cdot>x\<cdot>y)\<rbrakk> \<Longrightarrow> P x"
huffman@35781
    97
by (rule flattree.induct) -- "no admissibility requirement"
huffman@30920
    98
huffman@30920
    99
text {* Trivial datatypes will produce a warning message. *}
huffman@30920
   100
huffman@35443
   101
domain triv = Triv triv triv
huffman@37000
   102
  -- "domain @{text Domain_ex.triv} is empty!"
huffman@30920
   103
huffman@30920
   104
lemma "(x::triv) = \<bottom>" by (induct x, simp_all)
huffman@30920
   105
huffman@36120
   106
text {* Lazy constructor arguments may have unpointed types. *}
huffman@36120
   107
huffman@40501
   108
domain natlist = nnil | ncons (lazy "nat discr") natlist
huffman@36120
   109
huffman@36120
   110
text {* Class constraints may be given for type parameters on the LHS. *}
huffman@36120
   111
huffman@40501
   112
domain ('a::predomain) box = Box (lazy 'a)
huffman@40329
   113
huffman@40501
   114
domain ('a::countable) stream = snil | scons (lazy "'a discr") "'a stream"
huffman@36120
   115
huffman@30920
   116
huffman@30920
   117
subsection {* Generated constants and theorems *}
huffman@30920
   118
huffman@35661
   119
domain 'a tree = Leaf (lazy 'a) | Node (left :: "'a tree") (right :: "'a tree")
huffman@30920
   120
huffman@40321
   121
lemmas tree_abs_bottom_iff =
huffman@40321
   122
  iso.abs_bottom_iff [OF iso.intro [OF tree.abs_iso tree.rep_iso]]
huffman@30920
   123
huffman@30920
   124
text {* Rules about ismorphism *}
huffman@30920
   125
term tree_rep
huffman@30920
   126
term tree_abs
huffman@30920
   127
thm tree.rep_iso
huffman@30920
   128
thm tree.abs_iso
huffman@30920
   129
thm tree.iso_rews
huffman@30920
   130
huffman@30920
   131
text {* Rules about constructors *}
huffman@30920
   132
term Leaf
huffman@30920
   133
term Node
huffman@35444
   134
thm Leaf_def Node_def
huffman@35781
   135
thm tree.nchotomy
huffman@30920
   136
thm tree.exhaust
huffman@30920
   137
thm tree.compacts
huffman@30920
   138
thm tree.con_rews
huffman@30920
   139
thm tree.dist_les
huffman@30920
   140
thm tree.dist_eqs
huffman@30920
   141
thm tree.inverts
huffman@30920
   142
thm tree.injects
huffman@30920
   143
huffman@30920
   144
text {* Rules about case combinator *}
huffman@40213
   145
term tree_case
huffman@40213
   146
thm tree.tree_case_def
huffman@40213
   147
thm tree.case_rews
huffman@30920
   148
huffman@30920
   149
text {* Rules about selectors *}
huffman@30920
   150
term left
huffman@30920
   151
term right
huffman@30920
   152
thm tree.sel_rews
huffman@30920
   153
huffman@30920
   154
text {* Rules about discriminators *}
huffman@30920
   155
term is_Leaf
huffman@30920
   156
term is_Node
huffman@30920
   157
thm tree.dis_rews
huffman@30920
   158
huffman@30920
   159
text {* Rules about monadic pattern match combinators *}
huffman@30920
   160
term match_Leaf
huffman@30920
   161
term match_Node
huffman@30920
   162
thm tree.match_rews
huffman@30920
   163
huffman@30920
   164
text {* Rules about take function *}
huffman@30920
   165
term tree_take
huffman@30920
   166
thm tree.take_def
huffman@35494
   167
thm tree.take_0
huffman@35494
   168
thm tree.take_Suc
huffman@30920
   169
thm tree.take_rews
huffman@35494
   170
thm tree.chain_take
huffman@35494
   171
thm tree.take_take
huffman@35494
   172
thm tree.deflation_take
huffman@35781
   173
thm tree.take_below
huffman@35642
   174
thm tree.take_lemma
huffman@35585
   175
thm tree.lub_take
huffman@35494
   176
thm tree.reach
huffman@35781
   177
thm tree.finite_induct
huffman@30920
   178
huffman@30920
   179
text {* Rules about finiteness predicate *}
huffman@30920
   180
term tree_finite
huffman@30920
   181
thm tree.finite_def
huffman@35661
   182
thm tree.finite (* only generated for flat datatypes *)
huffman@30920
   183
huffman@30920
   184
text {* Rules about bisimulation predicate *}
huffman@30920
   185
term tree_bisim
huffman@30920
   186
thm tree.bisim_def
huffman@35781
   187
thm tree.coinduct
huffman@30920
   188
huffman@30920
   189
text {* Induction rule *}
huffman@35781
   190
thm tree.induct
huffman@30920
   191
huffman@30920
   192
huffman@30920
   193
subsection {* Known bugs *}
huffman@30920
   194
huffman@30920
   195
text {* Declaring a mixfix with spaces causes some strange parse errors. *}
huffman@30920
   196
(*
huffman@30920
   197
domain xx = xx ("x y")
huffman@30920
   198
  -- "Inner syntax error: unexpected end of input"
huffman@30922
   199
*)
huffman@30922
   200
huffman@30920
   201
end