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