Theory Domain_ex

theory Domain_ex
imports HOLCF
(*  Title:      HOL/HOLCF/Tutorial/Domain_ex.thy
    Author:     Brian Huffman

section ‹Domain package examples›

theory Domain_ex
imports HOLCF

text ‹Domain constructors are strict by default.›

domain d1 = d1a | d1b "d1" "d1"

lemma "d1b⋅⊥⋅y = ⊥" by simp

text ‹Constructors can be made lazy using the ‹lazy› keyword.›

domain d2 = d2a | d2b (lazy "d2")

lemma "d2b⋅x ≠ ⊥" by simp

text ‹Strict and lazy arguments may be mixed arbitrarily.›

domain d3 = d3a | d3b (lazy "d2") "d2"

lemma "P (d3b⋅x⋅y = ⊥) ⟷ P (y = ⊥)" by simp

text ‹Selectors can be used with strict or lazy constructor arguments.›

domain d4 = d4a | d4b (lazy d4b_left :: "d2") (d4b_right :: "d2")

lemma "y ≠ ⊥ ⟹ d4b_left⋅(d4b⋅x⋅y) = x" by simp

text ‹Mixfix declarations can be given for data constructors.›

domain d5 = d5a | d5b (lazy "d5") "d5" (infixl ":#:" 70)

lemma "d5a ≠ x :#: y :#: z" by simp

text ‹Mixfix declarations can also be given for type constructors.›

domain ('a, 'b) lazypair (infixl ":*:" 25) =
  lpair (lazy lfst :: 'a) (lazy lsnd :: 'b) (infixl ":*:" 75)

lemma "∀p::('a :*: 'b). p ⊑ lfst⋅p :*: lsnd⋅p"
by (rule allI, case_tac p, simp_all)

text ‹Non-recursive constructor arguments can have arbitrary types.›

domain ('a, 'b) d6 = d6 "int lift" "'a ⊕ 'b u" (lazy "('a :*: 'b) × ('b → 'a)")

text ‹
  Indirect recusion is allowed for sums, products, lifting, and the
  continuous function space.  However, the domain package does not
  generate an induction rule in terms of the constructors.

domain 'a d7 = d7a "'a d7 ⊕ int lift" | d7b "'a ⊗ 'a d7" | d7c (lazy "'a d7 → 'a")
   "Indirect recursion detected, skipping proofs of (co)induction rules"

text ‹Note that ‹d7.induct› is absent.›

text ‹
  Indirect recursion is also allowed using previously-defined datatypes.

domain 'a slist = SNil | SCons 'a "'a slist"

domain 'a stree = STip | SBranch "'a stree slist"

text ‹Mutually-recursive datatypes can be defined using the ‹and› keyword.›

domain d8 = d8a | d8b "d9" and d9 = d9a | d9b (lazy "d8")

text ‹Non-regular recursion is not allowed.›
domain ('a, 'b) altlist = ANil | ACons 'a "('b, 'a) altlist"
  -- "illegal direct recursion with different arguments"
domain 'a nest = Nest1 'a | Nest2 "'a nest nest"
  -- "illegal direct recursion with different arguments"

text ‹
  Mutually-recursive datatypes must have all the same type arguments,
  not necessarily in the same order.

domain ('a, 'b) list1 = Nil1 | Cons1 'a "('b, 'a) list2"
   and ('b, 'a) list2 = Nil2 | Cons2 'b "('a, 'b) list1"

text ‹Induction rules for flat datatypes have no admissibility side-condition.›

domain 'a flattree = Tip | Branch "'a flattree" "'a flattree"

lemma "⟦P ⊥; P Tip; ⋀x y. ⟦x ≠ ⊥; y ≠ ⊥; P x; P y⟧ ⟹ P (Branch⋅x⋅y)⟧ ⟹ P x"
by (rule flattree.induct)  "no admissibility requirement"

text ‹Trivial datatypes will produce a warning message.›

domain triv = Triv triv triv
   "domain ‹Domain_ex.triv› is empty!"

lemma "(x::triv) = ⊥" by (induct x, simp_all)

text ‹Lazy constructor arguments may have unpointed types.›

domain natlist = nnil | ncons (lazy "nat discr") natlist

text ‹Class constraints may be given for type parameters on the LHS.›

domain ('a::predomain) box = Box (lazy 'a)

domain ('a::countable) stream = snil | scons (lazy "'a discr") "'a stream"

subsection ‹Generated constants and theorems›

domain 'a tree = Leaf (lazy 'a) | Node (left :: "'a tree") (right :: "'a tree")

lemmas tree_abs_bottom_iff =
  iso.abs_bottom_iff [OF iso.intro [OF tree.abs_iso tree.rep_iso]]

text ‹Rules about ismorphism›
term tree_rep
term tree_abs
thm tree.rep_iso
thm tree.abs_iso
thm tree.iso_rews

text ‹Rules about constructors›
term Leaf
term Node
thm Leaf_def Node_def
thm tree.nchotomy
thm tree.exhaust
thm tree.compacts
thm tree.con_rews
thm tree.dist_les
thm tree.dist_eqs
thm tree.inverts
thm tree.injects

text ‹Rules about case combinator›
term tree_case
thm tree.tree_case_def
thm tree.case_rews

text ‹Rules about selectors›
term left
term right
thm tree.sel_rews

text ‹Rules about discriminators›
term is_Leaf
term is_Node
thm tree.dis_rews

text ‹Rules about monadic pattern match combinators›
term match_Leaf
term match_Node
thm tree.match_rews

text ‹Rules about take function›
term tree_take
thm tree.take_def
thm tree.take_0
thm tree.take_Suc
thm tree.take_rews
thm tree.chain_take
thm tree.take_take
thm tree.deflation_take
thm tree.take_below
thm tree.take_lemma
thm tree.lub_take
thm tree.reach
thm tree.finite_induct

text ‹Rules about finiteness predicate›
term tree_finite
thm tree.finite_def
thm tree.finite (* only generated for flat datatypes *)

text ‹Rules about bisimulation predicate›
term tree_bisim
thm tree.bisim_def
thm tree.coinduct

text ‹Induction rule›
thm tree.induct

subsection ‹Known bugs›

text ‹Declaring a mixfix with spaces causes some strange parse errors.›
domain xx = xx ("x y")
  -- "Inner syntax error: unexpected end of input"