src/ZF/Induct/Ntree.thy
author paulson
Thu, 23 May 2002 17:05:21 +0200
changeset 13175 81082cfa5618
parent 12788 6842f90972da
child 16417 9bc16273c2d4
permissions -rw-r--r--
new definition of "apply" and new simprule "beta_if"
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
12229
bfba0eb5124b Ntree and Brouwer converted and moved to ZF/Induct;
wenzelm
parents:
diff changeset
     1
(*  Title:      ZF/Induct/Ntree.thy
bfba0eb5124b Ntree and Brouwer converted and moved to ZF/Induct;
wenzelm
parents:
diff changeset
     2
    ID:         $Id$
bfba0eb5124b Ntree and Brouwer converted and moved to ZF/Induct;
wenzelm
parents:
diff changeset
     3
    Author:     Lawrence C Paulson, Cambridge University Computer Laboratory
bfba0eb5124b Ntree and Brouwer converted and moved to ZF/Induct;
wenzelm
parents:
diff changeset
     4
    Copyright   1994  University of Cambridge
bfba0eb5124b Ntree and Brouwer converted and moved to ZF/Induct;
wenzelm
parents:
diff changeset
     5
*)
bfba0eb5124b Ntree and Brouwer converted and moved to ZF/Induct;
wenzelm
parents:
diff changeset
     6
bfba0eb5124b Ntree and Brouwer converted and moved to ZF/Induct;
wenzelm
parents:
diff changeset
     7
header {* Datatype definition n-ary branching trees *}
bfba0eb5124b Ntree and Brouwer converted and moved to ZF/Induct;
wenzelm
parents:
diff changeset
     8
bfba0eb5124b Ntree and Brouwer converted and moved to ZF/Induct;
wenzelm
parents:
diff changeset
     9
theory Ntree = Main:
bfba0eb5124b Ntree and Brouwer converted and moved to ZF/Induct;
wenzelm
parents:
diff changeset
    10
bfba0eb5124b Ntree and Brouwer converted and moved to ZF/Induct;
wenzelm
parents:
diff changeset
    11
text {*
bfba0eb5124b Ntree and Brouwer converted and moved to ZF/Induct;
wenzelm
parents:
diff changeset
    12
  Demonstrates a simple use of function space in a datatype
bfba0eb5124b Ntree and Brouwer converted and moved to ZF/Induct;
wenzelm
parents:
diff changeset
    13
  definition.  Based upon theory @{text Term}.
bfba0eb5124b Ntree and Brouwer converted and moved to ZF/Induct;
wenzelm
parents:
diff changeset
    14
*}
bfba0eb5124b Ntree and Brouwer converted and moved to ZF/Induct;
wenzelm
parents:
diff changeset
    15
bfba0eb5124b Ntree and Brouwer converted and moved to ZF/Induct;
wenzelm
parents:
diff changeset
    16
consts
bfba0eb5124b Ntree and Brouwer converted and moved to ZF/Induct;
wenzelm
parents:
diff changeset
    17
  ntree :: "i => i"
bfba0eb5124b Ntree and Brouwer converted and moved to ZF/Induct;
wenzelm
parents:
diff changeset
    18
  maptree :: "i => i"
bfba0eb5124b Ntree and Brouwer converted and moved to ZF/Induct;
wenzelm
parents:
diff changeset
    19
  maptree2 :: "[i, i] => i"
bfba0eb5124b Ntree and Brouwer converted and moved to ZF/Induct;
wenzelm
parents:
diff changeset
    20
bfba0eb5124b Ntree and Brouwer converted and moved to ZF/Induct;
wenzelm
parents:
diff changeset
    21
datatype "ntree(A)" = Branch ("a \<in> A", "h \<in> (\<Union>n \<in> nat. n -> ntree(A))")
bfba0eb5124b Ntree and Brouwer converted and moved to ZF/Induct;
wenzelm
parents:
diff changeset
    22
  monos UN_mono [OF subset_refl Pi_mono]  -- {* MUST have this form *}
bfba0eb5124b Ntree and Brouwer converted and moved to ZF/Induct;
wenzelm
parents:
diff changeset
    23
  type_intros nat_fun_univ [THEN subsetD]
bfba0eb5124b Ntree and Brouwer converted and moved to ZF/Induct;
wenzelm
parents:
diff changeset
    24
  type_elims UN_E
bfba0eb5124b Ntree and Brouwer converted and moved to ZF/Induct;
wenzelm
parents:
diff changeset
    25
bfba0eb5124b Ntree and Brouwer converted and moved to ZF/Induct;
wenzelm
parents:
diff changeset
    26
datatype "maptree(A)" = Sons ("a \<in> A", "h \<in> maptree(A) -||> maptree(A)")
bfba0eb5124b Ntree and Brouwer converted and moved to ZF/Induct;
wenzelm
parents:
diff changeset
    27
  monos FiniteFun_mono1  -- {* Use monotonicity in BOTH args *}
bfba0eb5124b Ntree and Brouwer converted and moved to ZF/Induct;
wenzelm
parents:
diff changeset
    28
  type_intros FiniteFun_univ1 [THEN subsetD]
bfba0eb5124b Ntree and Brouwer converted and moved to ZF/Induct;
wenzelm
parents:
diff changeset
    29
bfba0eb5124b Ntree and Brouwer converted and moved to ZF/Induct;
wenzelm
parents:
diff changeset
    30
datatype "maptree2(A, B)" = Sons2 ("a \<in> A", "h \<in> B -||> maptree2(A, B)")
bfba0eb5124b Ntree and Brouwer converted and moved to ZF/Induct;
wenzelm
parents:
diff changeset
    31
  monos FiniteFun_mono [OF subset_refl]
bfba0eb5124b Ntree and Brouwer converted and moved to ZF/Induct;
wenzelm
parents:
diff changeset
    32
  type_intros FiniteFun_in_univ'
bfba0eb5124b Ntree and Brouwer converted and moved to ZF/Induct;
wenzelm
parents:
diff changeset
    33
bfba0eb5124b Ntree and Brouwer converted and moved to ZF/Induct;
wenzelm
parents:
diff changeset
    34
constdefs
bfba0eb5124b Ntree and Brouwer converted and moved to ZF/Induct;
wenzelm
parents:
diff changeset
    35
  ntree_rec :: "[[i, i, i] => i, i] => i"
bfba0eb5124b Ntree and Brouwer converted and moved to ZF/Induct;
wenzelm
parents:
diff changeset
    36
  "ntree_rec(b) ==
12610
8b9845807f77 tuned document sources;
wenzelm
parents: 12229
diff changeset
    37
    Vrecursor(\<lambda>pr. ntree_case(\<lambda>x h. b(x, h, \<lambda>i \<in> domain(h). pr`(h`i))))"
12229
bfba0eb5124b Ntree and Brouwer converted and moved to ZF/Induct;
wenzelm
parents:
diff changeset
    38
bfba0eb5124b Ntree and Brouwer converted and moved to ZF/Induct;
wenzelm
parents:
diff changeset
    39
constdefs
bfba0eb5124b Ntree and Brouwer converted and moved to ZF/Induct;
wenzelm
parents:
diff changeset
    40
  ntree_copy :: "i => i"
12610
8b9845807f77 tuned document sources;
wenzelm
parents: 12229
diff changeset
    41
  "ntree_copy(z) == ntree_rec(\<lambda>x h r. Branch(x,r), z)"
12229
bfba0eb5124b Ntree and Brouwer converted and moved to ZF/Induct;
wenzelm
parents:
diff changeset
    42
bfba0eb5124b Ntree and Brouwer converted and moved to ZF/Induct;
wenzelm
parents:
diff changeset
    43
bfba0eb5124b Ntree and Brouwer converted and moved to ZF/Induct;
wenzelm
parents:
diff changeset
    44
text {*
bfba0eb5124b Ntree and Brouwer converted and moved to ZF/Induct;
wenzelm
parents:
diff changeset
    45
  \medskip @{text ntree}
bfba0eb5124b Ntree and Brouwer converted and moved to ZF/Induct;
wenzelm
parents:
diff changeset
    46
*}
bfba0eb5124b Ntree and Brouwer converted and moved to ZF/Induct;
wenzelm
parents:
diff changeset
    47
bfba0eb5124b Ntree and Brouwer converted and moved to ZF/Induct;
wenzelm
parents:
diff changeset
    48
lemma ntree_unfold: "ntree(A) = A \<times> (\<Union>n \<in> nat. n -> ntree(A))"
12788
6842f90972da made proofs more robust
paulson
parents: 12610
diff changeset
    49
  by (blast intro: ntree.intros [unfolded ntree.con_defs]
12229
bfba0eb5124b Ntree and Brouwer converted and moved to ZF/Induct;
wenzelm
parents:
diff changeset
    50
    elim: ntree.cases [unfolded ntree.con_defs])
bfba0eb5124b Ntree and Brouwer converted and moved to ZF/Induct;
wenzelm
parents:
diff changeset
    51
bfba0eb5124b Ntree and Brouwer converted and moved to ZF/Induct;
wenzelm
parents:
diff changeset
    52
lemma ntree_induct [induct set: ntree]:
bfba0eb5124b Ntree and Brouwer converted and moved to ZF/Induct;
wenzelm
parents:
diff changeset
    53
  "[| t \<in> ntree(A);
bfba0eb5124b Ntree and Brouwer converted and moved to ZF/Induct;
wenzelm
parents:
diff changeset
    54
      !!x n h. [| x \<in> A;  n \<in> nat;  h \<in> n -> ntree(A);  \<forall>i \<in> n. P(h`i)
bfba0eb5124b Ntree and Brouwer converted and moved to ZF/Induct;
wenzelm
parents:
diff changeset
    55
               |] ==> P(Branch(x,h))
bfba0eb5124b Ntree and Brouwer converted and moved to ZF/Induct;
wenzelm
parents:
diff changeset
    56
   |] ==> P(t)"
bfba0eb5124b Ntree and Brouwer converted and moved to ZF/Induct;
wenzelm
parents:
diff changeset
    57
  -- {* A nicer induction rule than the standard one. *}
bfba0eb5124b Ntree and Brouwer converted and moved to ZF/Induct;
wenzelm
parents:
diff changeset
    58
proof -
bfba0eb5124b Ntree and Brouwer converted and moved to ZF/Induct;
wenzelm
parents:
diff changeset
    59
  case rule_context
bfba0eb5124b Ntree and Brouwer converted and moved to ZF/Induct;
wenzelm
parents:
diff changeset
    60
  assume "t \<in> ntree(A)"
bfba0eb5124b Ntree and Brouwer converted and moved to ZF/Induct;
wenzelm
parents:
diff changeset
    61
  thus ?thesis
bfba0eb5124b Ntree and Brouwer converted and moved to ZF/Induct;
wenzelm
parents:
diff changeset
    62
    apply induct
bfba0eb5124b Ntree and Brouwer converted and moved to ZF/Induct;
wenzelm
parents:
diff changeset
    63
    apply (erule UN_E)
bfba0eb5124b Ntree and Brouwer converted and moved to ZF/Induct;
wenzelm
parents:
diff changeset
    64
    apply (assumption | rule rule_context)+
bfba0eb5124b Ntree and Brouwer converted and moved to ZF/Induct;
wenzelm
parents:
diff changeset
    65
     apply (fast elim: fun_weaken_type)
bfba0eb5124b Ntree and Brouwer converted and moved to ZF/Induct;
wenzelm
parents:
diff changeset
    66
    apply (fast dest: apply_type)
bfba0eb5124b Ntree and Brouwer converted and moved to ZF/Induct;
wenzelm
parents:
diff changeset
    67
    done
bfba0eb5124b Ntree and Brouwer converted and moved to ZF/Induct;
wenzelm
parents:
diff changeset
    68
qed
bfba0eb5124b Ntree and Brouwer converted and moved to ZF/Induct;
wenzelm
parents:
diff changeset
    69
bfba0eb5124b Ntree and Brouwer converted and moved to ZF/Induct;
wenzelm
parents:
diff changeset
    70
lemma ntree_induct_eqn:
bfba0eb5124b Ntree and Brouwer converted and moved to ZF/Induct;
wenzelm
parents:
diff changeset
    71
  "[| t \<in> ntree(A);  f \<in> ntree(A)->B;  g \<in> ntree(A)->B;
bfba0eb5124b Ntree and Brouwer converted and moved to ZF/Induct;
wenzelm
parents:
diff changeset
    72
      !!x n h. [| x \<in> A;  n \<in> nat;  h \<in> n -> ntree(A);  f O h = g O h |] ==>
bfba0eb5124b Ntree and Brouwer converted and moved to ZF/Induct;
wenzelm
parents:
diff changeset
    73
               f ` Branch(x,h) = g ` Branch(x,h)
bfba0eb5124b Ntree and Brouwer converted and moved to ZF/Induct;
wenzelm
parents:
diff changeset
    74
   |] ==> f`t=g`t"
bfba0eb5124b Ntree and Brouwer converted and moved to ZF/Induct;
wenzelm
parents:
diff changeset
    75
  -- {* Induction on @{term "ntree(A)"} to prove an equation *}
bfba0eb5124b Ntree and Brouwer converted and moved to ZF/Induct;
wenzelm
parents:
diff changeset
    76
proof -
bfba0eb5124b Ntree and Brouwer converted and moved to ZF/Induct;
wenzelm
parents:
diff changeset
    77
  case rule_context
bfba0eb5124b Ntree and Brouwer converted and moved to ZF/Induct;
wenzelm
parents:
diff changeset
    78
  assume "t \<in> ntree(A)"
bfba0eb5124b Ntree and Brouwer converted and moved to ZF/Induct;
wenzelm
parents:
diff changeset
    79
  thus ?thesis
bfba0eb5124b Ntree and Brouwer converted and moved to ZF/Induct;
wenzelm
parents:
diff changeset
    80
    apply induct
bfba0eb5124b Ntree and Brouwer converted and moved to ZF/Induct;
wenzelm
parents:
diff changeset
    81
    apply (assumption | rule rule_context)+
bfba0eb5124b Ntree and Brouwer converted and moved to ZF/Induct;
wenzelm
parents:
diff changeset
    82
    apply (insert rule_context)
bfba0eb5124b Ntree and Brouwer converted and moved to ZF/Induct;
wenzelm
parents:
diff changeset
    83
    apply (rule fun_extension)
bfba0eb5124b Ntree and Brouwer converted and moved to ZF/Induct;
wenzelm
parents:
diff changeset
    84
      apply (assumption | rule comp_fun)+
bfba0eb5124b Ntree and Brouwer converted and moved to ZF/Induct;
wenzelm
parents:
diff changeset
    85
    apply (simp add: comp_fun_apply)
bfba0eb5124b Ntree and Brouwer converted and moved to ZF/Induct;
wenzelm
parents:
diff changeset
    86
  done
bfba0eb5124b Ntree and Brouwer converted and moved to ZF/Induct;
wenzelm
parents:
diff changeset
    87
qed
bfba0eb5124b Ntree and Brouwer converted and moved to ZF/Induct;
wenzelm
parents:
diff changeset
    88
bfba0eb5124b Ntree and Brouwer converted and moved to ZF/Induct;
wenzelm
parents:
diff changeset
    89
text {*
bfba0eb5124b Ntree and Brouwer converted and moved to ZF/Induct;
wenzelm
parents:
diff changeset
    90
  \medskip Lemmas to justify using @{text Ntree} in other recursive
bfba0eb5124b Ntree and Brouwer converted and moved to ZF/Induct;
wenzelm
parents:
diff changeset
    91
  type definitions.
bfba0eb5124b Ntree and Brouwer converted and moved to ZF/Induct;
wenzelm
parents:
diff changeset
    92
*}
bfba0eb5124b Ntree and Brouwer converted and moved to ZF/Induct;
wenzelm
parents:
diff changeset
    93
bfba0eb5124b Ntree and Brouwer converted and moved to ZF/Induct;
wenzelm
parents:
diff changeset
    94
lemma ntree_mono: "A \<subseteq> B ==> ntree(A) \<subseteq> ntree(B)"
bfba0eb5124b Ntree and Brouwer converted and moved to ZF/Induct;
wenzelm
parents:
diff changeset
    95
  apply (unfold ntree.defs)
bfba0eb5124b Ntree and Brouwer converted and moved to ZF/Induct;
wenzelm
parents:
diff changeset
    96
  apply (rule lfp_mono)
bfba0eb5124b Ntree and Brouwer converted and moved to ZF/Induct;
wenzelm
parents:
diff changeset
    97
    apply (rule ntree.bnd_mono)+
bfba0eb5124b Ntree and Brouwer converted and moved to ZF/Induct;
wenzelm
parents:
diff changeset
    98
  apply (assumption | rule univ_mono basic_monos)+
bfba0eb5124b Ntree and Brouwer converted and moved to ZF/Induct;
wenzelm
parents:
diff changeset
    99
  done
bfba0eb5124b Ntree and Brouwer converted and moved to ZF/Induct;
wenzelm
parents:
diff changeset
   100
bfba0eb5124b Ntree and Brouwer converted and moved to ZF/Induct;
wenzelm
parents:
diff changeset
   101
lemma ntree_univ: "ntree(univ(A)) \<subseteq> univ(A)"
bfba0eb5124b Ntree and Brouwer converted and moved to ZF/Induct;
wenzelm
parents:
diff changeset
   102
  -- {* Easily provable by induction also *}
bfba0eb5124b Ntree and Brouwer converted and moved to ZF/Induct;
wenzelm
parents:
diff changeset
   103
  apply (unfold ntree.defs ntree.con_defs)
bfba0eb5124b Ntree and Brouwer converted and moved to ZF/Induct;
wenzelm
parents:
diff changeset
   104
  apply (rule lfp_lowerbound)
bfba0eb5124b Ntree and Brouwer converted and moved to ZF/Induct;
wenzelm
parents:
diff changeset
   105
   apply (rule_tac [2] A_subset_univ [THEN univ_mono])
bfba0eb5124b Ntree and Brouwer converted and moved to ZF/Induct;
wenzelm
parents:
diff changeset
   106
  apply (blast intro: Pair_in_univ nat_fun_univ [THEN subsetD])
bfba0eb5124b Ntree and Brouwer converted and moved to ZF/Induct;
wenzelm
parents:
diff changeset
   107
  done
bfba0eb5124b Ntree and Brouwer converted and moved to ZF/Induct;
wenzelm
parents:
diff changeset
   108
bfba0eb5124b Ntree and Brouwer converted and moved to ZF/Induct;
wenzelm
parents:
diff changeset
   109
lemma ntree_subset_univ: "A \<subseteq> univ(B) ==> ntree(A) \<subseteq> univ(B)"
bfba0eb5124b Ntree and Brouwer converted and moved to ZF/Induct;
wenzelm
parents:
diff changeset
   110
  by (rule subset_trans [OF ntree_mono ntree_univ])
bfba0eb5124b Ntree and Brouwer converted and moved to ZF/Induct;
wenzelm
parents:
diff changeset
   111
bfba0eb5124b Ntree and Brouwer converted and moved to ZF/Induct;
wenzelm
parents:
diff changeset
   112
bfba0eb5124b Ntree and Brouwer converted and moved to ZF/Induct;
wenzelm
parents:
diff changeset
   113
text {*
bfba0eb5124b Ntree and Brouwer converted and moved to ZF/Induct;
wenzelm
parents:
diff changeset
   114
  \medskip @{text ntree} recursion.
bfba0eb5124b Ntree and Brouwer converted and moved to ZF/Induct;
wenzelm
parents:
diff changeset
   115
*}
bfba0eb5124b Ntree and Brouwer converted and moved to ZF/Induct;
wenzelm
parents:
diff changeset
   116
13175
81082cfa5618 new definition of "apply" and new simprule "beta_if"
paulson
parents: 12788
diff changeset
   117
lemma ntree_rec_Branch:
81082cfa5618 new definition of "apply" and new simprule "beta_if"
paulson
parents: 12788
diff changeset
   118
    "function(h) ==>
81082cfa5618 new definition of "apply" and new simprule "beta_if"
paulson
parents: 12788
diff changeset
   119
     ntree_rec(b, Branch(x,h)) = b(x, h, \<lambda>i \<in> domain(h). ntree_rec(b, h`i))"
12229
bfba0eb5124b Ntree and Brouwer converted and moved to ZF/Induct;
wenzelm
parents:
diff changeset
   120
  apply (rule ntree_rec_def [THEN def_Vrecursor, THEN trans])
bfba0eb5124b Ntree and Brouwer converted and moved to ZF/Induct;
wenzelm
parents:
diff changeset
   121
  apply (simp add: ntree.con_defs rank_pair2 [THEN [2] lt_trans] rank_apply)
bfba0eb5124b Ntree and Brouwer converted and moved to ZF/Induct;
wenzelm
parents:
diff changeset
   122
  done
bfba0eb5124b Ntree and Brouwer converted and moved to ZF/Induct;
wenzelm
parents:
diff changeset
   123
bfba0eb5124b Ntree and Brouwer converted and moved to ZF/Induct;
wenzelm
parents:
diff changeset
   124
lemma ntree_copy_Branch [simp]:
13175
81082cfa5618 new definition of "apply" and new simprule "beta_if"
paulson
parents: 12788
diff changeset
   125
    "function(h) ==>
81082cfa5618 new definition of "apply" and new simprule "beta_if"
paulson
parents: 12788
diff changeset
   126
     ntree_copy (Branch(x, h)) = Branch(x, \<lambda>i \<in> domain(h). ntree_copy (h`i))"
81082cfa5618 new definition of "apply" and new simprule "beta_if"
paulson
parents: 12788
diff changeset
   127
  by (simp add: ntree_copy_def ntree_rec_Branch)
12229
bfba0eb5124b Ntree and Brouwer converted and moved to ZF/Induct;
wenzelm
parents:
diff changeset
   128
bfba0eb5124b Ntree and Brouwer converted and moved to ZF/Induct;
wenzelm
parents:
diff changeset
   129
lemma ntree_copy_is_ident: "z \<in> ntree(A) ==> ntree_copy(z) = z"
bfba0eb5124b Ntree and Brouwer converted and moved to ZF/Induct;
wenzelm
parents:
diff changeset
   130
  apply (induct_tac z)
13175
81082cfa5618 new definition of "apply" and new simprule "beta_if"
paulson
parents: 12788
diff changeset
   131
  apply (auto simp add: domain_of_fun Pi_Collect_iff fun_is_function)
12229
bfba0eb5124b Ntree and Brouwer converted and moved to ZF/Induct;
wenzelm
parents:
diff changeset
   132
  done
bfba0eb5124b Ntree and Brouwer converted and moved to ZF/Induct;
wenzelm
parents:
diff changeset
   133
bfba0eb5124b Ntree and Brouwer converted and moved to ZF/Induct;
wenzelm
parents:
diff changeset
   134
bfba0eb5124b Ntree and Brouwer converted and moved to ZF/Induct;
wenzelm
parents:
diff changeset
   135
text {*
bfba0eb5124b Ntree and Brouwer converted and moved to ZF/Induct;
wenzelm
parents:
diff changeset
   136
  \medskip @{text maptree}
bfba0eb5124b Ntree and Brouwer converted and moved to ZF/Induct;
wenzelm
parents:
diff changeset
   137
*}
bfba0eb5124b Ntree and Brouwer converted and moved to ZF/Induct;
wenzelm
parents:
diff changeset
   138
bfba0eb5124b Ntree and Brouwer converted and moved to ZF/Induct;
wenzelm
parents:
diff changeset
   139
lemma maptree_unfold: "maptree(A) = A \<times> (maptree(A) -||> maptree(A))"
bfba0eb5124b Ntree and Brouwer converted and moved to ZF/Induct;
wenzelm
parents:
diff changeset
   140
  by (fast intro!: maptree.intros [unfolded maptree.con_defs]
bfba0eb5124b Ntree and Brouwer converted and moved to ZF/Induct;
wenzelm
parents:
diff changeset
   141
    elim: maptree.cases [unfolded maptree.con_defs])
bfba0eb5124b Ntree and Brouwer converted and moved to ZF/Induct;
wenzelm
parents:
diff changeset
   142
bfba0eb5124b Ntree and Brouwer converted and moved to ZF/Induct;
wenzelm
parents:
diff changeset
   143
lemma maptree_induct [induct set: maptree]:
bfba0eb5124b Ntree and Brouwer converted and moved to ZF/Induct;
wenzelm
parents:
diff changeset
   144
  "[| t \<in> maptree(A);
bfba0eb5124b Ntree and Brouwer converted and moved to ZF/Induct;
wenzelm
parents:
diff changeset
   145
      !!x n h. [| x \<in> A;  h \<in> maptree(A) -||> maptree(A);
bfba0eb5124b Ntree and Brouwer converted and moved to ZF/Induct;
wenzelm
parents:
diff changeset
   146
                  \<forall>y \<in> field(h). P(y)
bfba0eb5124b Ntree and Brouwer converted and moved to ZF/Induct;
wenzelm
parents:
diff changeset
   147
               |] ==> P(Sons(x,h))
bfba0eb5124b Ntree and Brouwer converted and moved to ZF/Induct;
wenzelm
parents:
diff changeset
   148
   |] ==> P(t)"
bfba0eb5124b Ntree and Brouwer converted and moved to ZF/Induct;
wenzelm
parents:
diff changeset
   149
  -- {* A nicer induction rule than the standard one. *}
bfba0eb5124b Ntree and Brouwer converted and moved to ZF/Induct;
wenzelm
parents:
diff changeset
   150
proof -
bfba0eb5124b Ntree and Brouwer converted and moved to ZF/Induct;
wenzelm
parents:
diff changeset
   151
  case rule_context
bfba0eb5124b Ntree and Brouwer converted and moved to ZF/Induct;
wenzelm
parents:
diff changeset
   152
  assume "t \<in> maptree(A)"
bfba0eb5124b Ntree and Brouwer converted and moved to ZF/Induct;
wenzelm
parents:
diff changeset
   153
  thus ?thesis
bfba0eb5124b Ntree and Brouwer converted and moved to ZF/Induct;
wenzelm
parents:
diff changeset
   154
    apply induct
bfba0eb5124b Ntree and Brouwer converted and moved to ZF/Induct;
wenzelm
parents:
diff changeset
   155
    apply (assumption | rule rule_context)+
bfba0eb5124b Ntree and Brouwer converted and moved to ZF/Induct;
wenzelm
parents:
diff changeset
   156
     apply (erule Collect_subset [THEN FiniteFun_mono1, THEN subsetD])
bfba0eb5124b Ntree and Brouwer converted and moved to ZF/Induct;
wenzelm
parents:
diff changeset
   157
    apply (drule FiniteFun.dom_subset [THEN subsetD])
bfba0eb5124b Ntree and Brouwer converted and moved to ZF/Induct;
wenzelm
parents:
diff changeset
   158
    apply (drule Fin.dom_subset [THEN subsetD])
bfba0eb5124b Ntree and Brouwer converted and moved to ZF/Induct;
wenzelm
parents:
diff changeset
   159
    apply fast
bfba0eb5124b Ntree and Brouwer converted and moved to ZF/Induct;
wenzelm
parents:
diff changeset
   160
    done
bfba0eb5124b Ntree and Brouwer converted and moved to ZF/Induct;
wenzelm
parents:
diff changeset
   161
qed
bfba0eb5124b Ntree and Brouwer converted and moved to ZF/Induct;
wenzelm
parents:
diff changeset
   162
bfba0eb5124b Ntree and Brouwer converted and moved to ZF/Induct;
wenzelm
parents:
diff changeset
   163
bfba0eb5124b Ntree and Brouwer converted and moved to ZF/Induct;
wenzelm
parents:
diff changeset
   164
text {*
bfba0eb5124b Ntree and Brouwer converted and moved to ZF/Induct;
wenzelm
parents:
diff changeset
   165
  \medskip @{text maptree2}
bfba0eb5124b Ntree and Brouwer converted and moved to ZF/Induct;
wenzelm
parents:
diff changeset
   166
*}
bfba0eb5124b Ntree and Brouwer converted and moved to ZF/Induct;
wenzelm
parents:
diff changeset
   167
bfba0eb5124b Ntree and Brouwer converted and moved to ZF/Induct;
wenzelm
parents:
diff changeset
   168
lemma maptree2_unfold: "maptree2(A, B) = A \<times> (B -||> maptree2(A, B))"
bfba0eb5124b Ntree and Brouwer converted and moved to ZF/Induct;
wenzelm
parents:
diff changeset
   169
  by (fast intro!: maptree2.intros [unfolded maptree2.con_defs]
bfba0eb5124b Ntree and Brouwer converted and moved to ZF/Induct;
wenzelm
parents:
diff changeset
   170
    elim: maptree2.cases [unfolded maptree2.con_defs])
bfba0eb5124b Ntree and Brouwer converted and moved to ZF/Induct;
wenzelm
parents:
diff changeset
   171
bfba0eb5124b Ntree and Brouwer converted and moved to ZF/Induct;
wenzelm
parents:
diff changeset
   172
lemma maptree2_induct [induct set: maptree2]:
bfba0eb5124b Ntree and Brouwer converted and moved to ZF/Induct;
wenzelm
parents:
diff changeset
   173
  "[| t \<in> maptree2(A, B);
bfba0eb5124b Ntree and Brouwer converted and moved to ZF/Induct;
wenzelm
parents:
diff changeset
   174
      !!x n h. [| x \<in> A;  h \<in> B -||> maptree2(A,B);  \<forall>y \<in> range(h). P(y)
bfba0eb5124b Ntree and Brouwer converted and moved to ZF/Induct;
wenzelm
parents:
diff changeset
   175
               |] ==> P(Sons2(x,h))
bfba0eb5124b Ntree and Brouwer converted and moved to ZF/Induct;
wenzelm
parents:
diff changeset
   176
   |] ==> P(t)"
bfba0eb5124b Ntree and Brouwer converted and moved to ZF/Induct;
wenzelm
parents:
diff changeset
   177
proof -
bfba0eb5124b Ntree and Brouwer converted and moved to ZF/Induct;
wenzelm
parents:
diff changeset
   178
  case rule_context
bfba0eb5124b Ntree and Brouwer converted and moved to ZF/Induct;
wenzelm
parents:
diff changeset
   179
  assume "t \<in> maptree2(A, B)"
bfba0eb5124b Ntree and Brouwer converted and moved to ZF/Induct;
wenzelm
parents:
diff changeset
   180
  thus ?thesis
bfba0eb5124b Ntree and Brouwer converted and moved to ZF/Induct;
wenzelm
parents:
diff changeset
   181
    apply induct
bfba0eb5124b Ntree and Brouwer converted and moved to ZF/Induct;
wenzelm
parents:
diff changeset
   182
    apply (assumption | rule rule_context)+
bfba0eb5124b Ntree and Brouwer converted and moved to ZF/Induct;
wenzelm
parents:
diff changeset
   183
     apply (erule FiniteFun_mono [OF subset_refl Collect_subset, THEN subsetD])
bfba0eb5124b Ntree and Brouwer converted and moved to ZF/Induct;
wenzelm
parents:
diff changeset
   184
    apply (drule FiniteFun.dom_subset [THEN subsetD])
bfba0eb5124b Ntree and Brouwer converted and moved to ZF/Induct;
wenzelm
parents:
diff changeset
   185
    apply (drule Fin.dom_subset [THEN subsetD])
bfba0eb5124b Ntree and Brouwer converted and moved to ZF/Induct;
wenzelm
parents:
diff changeset
   186
    apply fast
bfba0eb5124b Ntree and Brouwer converted and moved to ZF/Induct;
wenzelm
parents:
diff changeset
   187
    done
bfba0eb5124b Ntree and Brouwer converted and moved to ZF/Induct;
wenzelm
parents:
diff changeset
   188
qed
bfba0eb5124b Ntree and Brouwer converted and moved to ZF/Induct;
wenzelm
parents:
diff changeset
   189
bfba0eb5124b Ntree and Brouwer converted and moved to ZF/Induct;
wenzelm
parents:
diff changeset
   190
end