Theory New_Domain
section ‹Definitional domain package›
theory New_Domain
imports HOLCF
begin
text ‹
UPDATE: The definitional back-end is now the default mode of the domain
package. This file should be merged with ‹Domain_ex.thy›.
›
text ‹
Provided that ‹domain› is the default sort, the ‹new_domain›
package should work with any type definition supported by the old
domain package.
›
domain 'a llist = LNil | LCons (lazy 'a) (lazy "'a llist")
text ‹
The difference is that the new domain package is completely
definitional, and does not generate any axioms. The following type
and constant definitions are not produced by the old domain package.
›
thm type_definition_llist
thm llist_abs_def llist_rep_def
text ‹
The new domain package also adds support for indirect recursion with
user-defined datatypes. This definition of a tree datatype uses
indirect recursion through the lazy list type constructor.
›
domain 'a ltree = Leaf (lazy 'a) | Branch (lazy "'a ltree llist")
text ‹
For indirect-recursive definitions, the domain package is not able to
generate a high-level induction rule. (It produces a warning
message instead.) The low-level reach lemma (now proved as a
theorem, no longer generated as an axiom) can be used to derive
other induction rules.
›
thm ltree.reach
text ‹
The definition of the take function uses map functions associated with
each type constructor involved in the definition. A map function
for the lazy list type has been generated by the new domain package.
›
thm ltree.take_rews
thm llist_map_def
lemma ltree_induct:
fixes P :: "'a ltree ⇒ bool"
assumes adm: "adm P"
assumes bot: "P ⊥"
assumes Leaf: "⋀x. P (Leaf⋅x)"
assumes Branch: "⋀f l. ∀x. P (f⋅x) ⟹ P (Branch⋅(llist_map⋅f⋅l))"
shows "P x"
proof -
have "P (⨆i. ltree_take i⋅x)"
using adm
proof (rule admD)
fix i
show "P (ltree_take i⋅x)"
proof (induct i arbitrary: x)
case (0 x)
show "P (ltree_take 0⋅x)" by (simp add: bot)
next
case (Suc n x)
show "P (ltree_take (Suc n)⋅x)"
apply (cases x)
apply (simp add: bot)
apply (simp add: Leaf)
apply (simp add: Branch Suc)
done
qed
qed (simp add: ltree.chain_take)
thus ?thesis
by (simp add: ltree.reach)
qed
end