src/ZF/ex/Ntree.ML
 author lcp Tue Aug 16 18:58:42 1994 +0200 (1994-08-16) changeset 532 851df239ac8b parent 529 f0d16216e394 child 539 01906e4644e0 permissions -rw-r--r--
ZF/Makefile,ROOT.ML, ZF/ex/Integ.thy: updated for EquivClass
```     1 (*  Title: 	ZF/ex/Ntree.ML
```
```     2     ID:         \$Id\$
```
```     3     Author: 	Lawrence C Paulson, Cambridge University Computer Laboratory
```
```     4     Copyright   1994  University of Cambridge
```
```     5
```
```     6 Datatype definition n-ary branching trees
```
```     7 Demonstrates a simple use of function space in a datatype definition
```
```     8
```
```     9 Based upon ex/Term.ML
```
```    10 *)
```
```    11
```
```    12 open Ntree;
```
```    13
```
```    14 goal Ntree.thy "ntree(A) = A * (UN n: nat. n -> ntree(A))";
```
```    15 let open ntree;  val rew = rewrite_rule con_defs in
```
```    16 by (fast_tac (sum_cs addSIs (equalityI :: map rew intrs)
```
```    17                      addEs [rew elim]) 1)
```
```    18 end;
```
```    19 val ntree_unfold = result();
```
```    20
```
```    21 (*A nicer induction rule than the standard one*)
```
```    22 val major::prems = goal Ntree.thy
```
```    23     "[| t: ntree(A);  \
```
```    24 \       !!x n h. [| x: A;  n: nat;  h: n -> ntree(A);  ALL i:n. P(h`i)  \
```
```    25 \                |] ==> P(Branch(x,h))  \
```
```    26 \    |] ==> P(t)";
```
```    27 by (rtac (major RS ntree.induct) 1);
```
```    28 by (etac UN_E 1);
```
```    29 by (REPEAT_SOME (ares_tac prems));
```
```    30 by (fast_tac (ZF_cs addEs [fun_weaken_type]) 1);
```
```    31 by (fast_tac (ZF_cs addDs [apply_type]) 1);
```
```    32 val ntree_induct2 = result();
```
```    33
```
```    34 (*Induction on ntree(A) to prove an equation*)
```
```    35 val major::prems = goal Ntree.thy
```
```    36   "[| t: ntree(A);  f: ntree(A)->B;  g: ntree(A)->B;		\
```
```    37 \     !!x n h. [| x: A;  n: nat;  h: n -> ntree(A);  f O h = g O h |] ==> \
```
```    38 \              f ` Branch(x,h) = g ` Branch(x,h)  		\
```
```    39 \  |] ==> f`t=g`t";
```
```    40 by (rtac (major RS ntree_induct2) 1);
```
```    41 by (REPEAT_SOME (ares_tac prems));
```
```    42 by (cut_facts_tac prems 1);
```
```    43 br fun_extension 1;
```
```    44 by (REPEAT_SOME (ares_tac [comp_fun]));
```
```    45 by (asm_simp_tac (ZF_ss addsimps [comp_fun_apply]) 1);
```
```    46 val ntree_induct_eqn = result();
```
```    47
```
```    48 (**  Lemmas to justify using "Ntree" in other recursive type definitions **)
```
```    49
```
```    50 goalw Ntree.thy ntree.defs "!!A B. A<=B ==> ntree(A) <= ntree(B)";
```
```    51 by (rtac lfp_mono 1);
```
```    52 by (REPEAT (rtac ntree.bnd_mono 1));
```
```    53 by (REPEAT (ares_tac (univ_mono::basic_monos) 1));
```
```    54 val ntree_mono = result();
```
```    55
```
```    56 (*Easily provable by induction also*)
```
```    57 goalw Ntree.thy (ntree.defs@ntree.con_defs) "ntree(univ(A)) <= univ(A)";
```
```    58 by (rtac lfp_lowerbound 1);
```
```    59 by (rtac (A_subset_univ RS univ_mono) 2);
```
```    60 by (safe_tac ZF_cs);
```
```    61 by (REPEAT (ares_tac [Pair_in_univ, nat_fun_univ RS subsetD] 1));
```
```    62 val ntree_univ = result();
```
```    63
```
```    64 val ntree_subset_univ =
```
```    65     [ntree_mono, ntree_univ] MRS subset_trans |> standard;
```
```    66
```
```    67 goal Ntree.thy "!!t A B. [| t: ntree(A);  A <= univ(B) |] ==> t: univ(B)";
```
```    68 by (REPEAT (ares_tac [ntree_subset_univ RS subsetD] 1));
```
```    69 val ntree_into_univ = result();
```