Theory Domain_ex
section ‹Domain package examples›
theory Domain_ex
imports HOLCF
begin
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")
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.›