src/HOL/Isar_examples/NestedDatatype.thy
author wenzelm
Sat, 15 Apr 2000 15:00:57 +0200
changeset 8717 20c42415c07d
parent 8676 4bf18b611a75
child 9659 b9cf6801f3da
permissions -rw-r--r--
plain ASCII;
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
8676
4bf18b611a75 added NestedDatatype.thy;
wenzelm
parents:
diff changeset
     1
4bf18b611a75 added NestedDatatype.thy;
wenzelm
parents:
diff changeset
     2
header {* Nested datatypes *};
4bf18b611a75 added NestedDatatype.thy;
wenzelm
parents:
diff changeset
     3
4bf18b611a75 added NestedDatatype.thy;
wenzelm
parents:
diff changeset
     4
theory NestedDatatype = Main:;
4bf18b611a75 added NestedDatatype.thy;
wenzelm
parents:
diff changeset
     5
4bf18b611a75 added NestedDatatype.thy;
wenzelm
parents:
diff changeset
     6
subsection {* Terms and substitution *};
4bf18b611a75 added NestedDatatype.thy;
wenzelm
parents:
diff changeset
     7
4bf18b611a75 added NestedDatatype.thy;
wenzelm
parents:
diff changeset
     8
datatype ('a, 'b) "term" =
4bf18b611a75 added NestedDatatype.thy;
wenzelm
parents:
diff changeset
     9
    Var 'a
4bf18b611a75 added NestedDatatype.thy;
wenzelm
parents:
diff changeset
    10
  | App 'b "('a, 'b) term list";
4bf18b611a75 added NestedDatatype.thy;
wenzelm
parents:
diff changeset
    11
4bf18b611a75 added NestedDatatype.thy;
wenzelm
parents:
diff changeset
    12
consts
8717
20c42415c07d plain ASCII;
wenzelm
parents: 8676
diff changeset
    13
  subst_term :: "('a => ('a, 'b) term) => ('a, 'b) term => ('a, 'b) term"
8676
4bf18b611a75 added NestedDatatype.thy;
wenzelm
parents:
diff changeset
    14
  subst_term_list ::
8717
20c42415c07d plain ASCII;
wenzelm
parents: 8676
diff changeset
    15
    "('a => ('a, 'b) term) => ('a, 'b) term list => ('a, 'b) term list";
8676
4bf18b611a75 added NestedDatatype.thy;
wenzelm
parents:
diff changeset
    16
4bf18b611a75 added NestedDatatype.thy;
wenzelm
parents:
diff changeset
    17
primrec (subst)
4bf18b611a75 added NestedDatatype.thy;
wenzelm
parents:
diff changeset
    18
  "subst_term f (Var a) = f a"
4bf18b611a75 added NestedDatatype.thy;
wenzelm
parents:
diff changeset
    19
  "subst_term f (App b ts) = App b (subst_term_list f ts)"
4bf18b611a75 added NestedDatatype.thy;
wenzelm
parents:
diff changeset
    20
  "subst_term_list f [] = []"
4bf18b611a75 added NestedDatatype.thy;
wenzelm
parents:
diff changeset
    21
  "subst_term_list f (t # ts) = subst_term f t # subst_term_list f ts";
4bf18b611a75 added NestedDatatype.thy;
wenzelm
parents:
diff changeset
    22
4bf18b611a75 added NestedDatatype.thy;
wenzelm
parents:
diff changeset
    23
4bf18b611a75 added NestedDatatype.thy;
wenzelm
parents:
diff changeset
    24
text {*
4bf18b611a75 added NestedDatatype.thy;
wenzelm
parents:
diff changeset
    25
 \medskip A simple lemma about composition of substitutions.
4bf18b611a75 added NestedDatatype.thy;
wenzelm
parents:
diff changeset
    26
*};
4bf18b611a75 added NestedDatatype.thy;
wenzelm
parents:
diff changeset
    27
4bf18b611a75 added NestedDatatype.thy;
wenzelm
parents:
diff changeset
    28
lemma
4bf18b611a75 added NestedDatatype.thy;
wenzelm
parents:
diff changeset
    29
   "subst_term (subst_term f1 o f2) t =
8717
20c42415c07d plain ASCII;
wenzelm
parents: 8676
diff changeset
    30
      subst_term f1 (subst_term f2 t) &
8676
4bf18b611a75 added NestedDatatype.thy;
wenzelm
parents:
diff changeset
    31
    subst_term_list (subst_term f1 o f2) ts =
4bf18b611a75 added NestedDatatype.thy;
wenzelm
parents:
diff changeset
    32
      subst_term_list f1 (subst_term_list f2 ts)";
4bf18b611a75 added NestedDatatype.thy;
wenzelm
parents:
diff changeset
    33
  by (induct t and ts rule: term.induct) simp_all;
4bf18b611a75 added NestedDatatype.thy;
wenzelm
parents:
diff changeset
    34
4bf18b611a75 added NestedDatatype.thy;
wenzelm
parents:
diff changeset
    35
lemma "subst_term (subst_term f1 o f2) t = subst_term f1 (subst_term f2 t)";
4bf18b611a75 added NestedDatatype.thy;
wenzelm
parents:
diff changeset
    36
proof -;
4bf18b611a75 added NestedDatatype.thy;
wenzelm
parents:
diff changeset
    37
  let "?P t" = ?thesis;
4bf18b611a75 added NestedDatatype.thy;
wenzelm
parents:
diff changeset
    38
  let ?Q = "\\<lambda>ts. subst_term_list (subst_term f1 o f2) ts =
4bf18b611a75 added NestedDatatype.thy;
wenzelm
parents:
diff changeset
    39
    subst_term_list f1 (subst_term_list f2 ts)";
4bf18b611a75 added NestedDatatype.thy;
wenzelm
parents:
diff changeset
    40
  show ?thesis;
4bf18b611a75 added NestedDatatype.thy;
wenzelm
parents:
diff changeset
    41
  proof (induct t);
4bf18b611a75 added NestedDatatype.thy;
wenzelm
parents:
diff changeset
    42
    fix a; show "?P (Var a)"; by simp;
4bf18b611a75 added NestedDatatype.thy;
wenzelm
parents:
diff changeset
    43
  next;
4bf18b611a75 added NestedDatatype.thy;
wenzelm
parents:
diff changeset
    44
    fix b ts; assume "?Q ts";
4bf18b611a75 added NestedDatatype.thy;
wenzelm
parents:
diff changeset
    45
    thus "?P (App b ts)"; by (simp add: o_def);
4bf18b611a75 added NestedDatatype.thy;
wenzelm
parents:
diff changeset
    46
  next;
4bf18b611a75 added NestedDatatype.thy;
wenzelm
parents:
diff changeset
    47
    show "?Q []"; by simp;
4bf18b611a75 added NestedDatatype.thy;
wenzelm
parents:
diff changeset
    48
  next;
4bf18b611a75 added NestedDatatype.thy;
wenzelm
parents:
diff changeset
    49
    fix t ts;
4bf18b611a75 added NestedDatatype.thy;
wenzelm
parents:
diff changeset
    50
    assume "?P t" "?Q ts"; thus "?Q (t # ts)"; by simp;
4bf18b611a75 added NestedDatatype.thy;
wenzelm
parents:
diff changeset
    51
  qed;
4bf18b611a75 added NestedDatatype.thy;
wenzelm
parents:
diff changeset
    52
qed;
4bf18b611a75 added NestedDatatype.thy;
wenzelm
parents:
diff changeset
    53
4bf18b611a75 added NestedDatatype.thy;
wenzelm
parents:
diff changeset
    54
4bf18b611a75 added NestedDatatype.thy;
wenzelm
parents:
diff changeset
    55
subsection {* Alternative induction *};
4bf18b611a75 added NestedDatatype.thy;
wenzelm
parents:
diff changeset
    56
4bf18b611a75 added NestedDatatype.thy;
wenzelm
parents:
diff changeset
    57
theorem term_induct' [case_names Var App]:
8717
20c42415c07d plain ASCII;
wenzelm
parents: 8676
diff changeset
    58
 "(!!a. P (Var a)) ==> (!!b ts. list_all P ts ==> P (App b ts)) ==> P t";
8676
4bf18b611a75 added NestedDatatype.thy;
wenzelm
parents:
diff changeset
    59
proof -;
8717
20c42415c07d plain ASCII;
wenzelm
parents: 8676
diff changeset
    60
  assume var: "!!a. P (Var a)";
20c42415c07d plain ASCII;
wenzelm
parents: 8676
diff changeset
    61
  assume app: "!!b ts. list_all P ts ==> P (App b ts)";
8676
4bf18b611a75 added NestedDatatype.thy;
wenzelm
parents:
diff changeset
    62
  show ?thesis;
4bf18b611a75 added NestedDatatype.thy;
wenzelm
parents:
diff changeset
    63
  proof (induct P t);
4bf18b611a75 added NestedDatatype.thy;
wenzelm
parents:
diff changeset
    64
    fix a; show "P (Var a)"; by (rule var);
4bf18b611a75 added NestedDatatype.thy;
wenzelm
parents:
diff changeset
    65
  next;
4bf18b611a75 added NestedDatatype.thy;
wenzelm
parents:
diff changeset
    66
    fix b t ts; assume "list_all P ts";
4bf18b611a75 added NestedDatatype.thy;
wenzelm
parents:
diff changeset
    67
    thus "P (App b ts)"; by (rule app);
4bf18b611a75 added NestedDatatype.thy;
wenzelm
parents:
diff changeset
    68
  next;
4bf18b611a75 added NestedDatatype.thy;
wenzelm
parents:
diff changeset
    69
    show "list_all P []"; by simp;
4bf18b611a75 added NestedDatatype.thy;
wenzelm
parents:
diff changeset
    70
  next;
4bf18b611a75 added NestedDatatype.thy;
wenzelm
parents:
diff changeset
    71
    fix t ts; assume "P t" "list_all P ts";
4bf18b611a75 added NestedDatatype.thy;
wenzelm
parents:
diff changeset
    72
    thus "list_all P (t # ts)"; by simp;
4bf18b611a75 added NestedDatatype.thy;
wenzelm
parents:
diff changeset
    73
  qed;
4bf18b611a75 added NestedDatatype.thy;
wenzelm
parents:
diff changeset
    74
qed;
4bf18b611a75 added NestedDatatype.thy;
wenzelm
parents:
diff changeset
    75
8717
20c42415c07d plain ASCII;
wenzelm
parents: 8676
diff changeset
    76
lemma
20c42415c07d plain ASCII;
wenzelm
parents: 8676
diff changeset
    77
  "subst_term (subst_term f1 o f2) t = subst_term f1 (subst_term f2 t)"
8676
4bf18b611a75 added NestedDatatype.thy;
wenzelm
parents:
diff changeset
    78
  (is "?P t");
4bf18b611a75 added NestedDatatype.thy;
wenzelm
parents:
diff changeset
    79
proof (induct ?P t rule: term_induct');
4bf18b611a75 added NestedDatatype.thy;
wenzelm
parents:
diff changeset
    80
  case Var;
4bf18b611a75 added NestedDatatype.thy;
wenzelm
parents:
diff changeset
    81
  show "?P (Var a)"; by (simp add: o_def);
4bf18b611a75 added NestedDatatype.thy;
wenzelm
parents:
diff changeset
    82
next;
4bf18b611a75 added NestedDatatype.thy;
wenzelm
parents:
diff changeset
    83
  case App;
8717
20c42415c07d plain ASCII;
wenzelm
parents: 8676
diff changeset
    84
  have "?this --> ?P (App b ts)";
8676
4bf18b611a75 added NestedDatatype.thy;
wenzelm
parents:
diff changeset
    85
    by (induct ts) simp_all;
4bf18b611a75 added NestedDatatype.thy;
wenzelm
parents:
diff changeset
    86
  thus "..."; ..;
4bf18b611a75 added NestedDatatype.thy;
wenzelm
parents:
diff changeset
    87
qed;
4bf18b611a75 added NestedDatatype.thy;
wenzelm
parents:
diff changeset
    88
4bf18b611a75 added NestedDatatype.thy;
wenzelm
parents:
diff changeset
    89
end;