File: INDUCT_THEN.doc

package info (click to toggle)
hol88 2.02.19940316-33
  • links: PTS
  • area: main
  • in suites: stretch
  • size: 65,988 kB
  • ctags: 21,623
  • sloc: ml: 199,939; ansic: 9,666; sh: 7,118; makefile: 6,095; lisp: 2,747; yacc: 894; sed: 201; cpp: 87; awk: 5
file content (101 lines) | stat: -rw-r--r-- 4,100 bytes parent folder | download | duplicates (11)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
\DOC INDUCT_THEN

\TYPE {INDUCT_THEN : (thm -> thm_tactic -> tactic)}

\SYNOPSIS
Structural induction tactic for automatically-defined concrete types.

\KEYWORDS
theorem-tactic, induction.

\DESCRIBE
The function {INDUCT_THEN} implements structural induction tactics for
arbitrary concrete recursive types of the kind definable by {define_type}.  The
first argument to {INDUCT_THEN} is a structural induction theorem for the
concrete type in question. This theorem must have the form of an induction
theorem of the kind returned by {prove_induction_thm}. When applied to such a
theorem, the function {INDUCT_THEN} constructs specialized tactic for
doing structural induction on the concrete type in question.

The second argument to {INDUCT_THEN} is a function that determines what is be
done with the induction hypotheses in the goal-directed proof by structural
induction.  Suppose that {th} is a structural induction theorem for a concrete
data type {ty}, and that {A ?- !x.P} is a universally-quantified goal in which
the variable {x} ranges over values of type {ty}. If the type {ty} has {n}
constructors {C1}, ..., {Cn} and `{Ci(vs)}' represents a (curried) application
of the {i}th constructor to a sequence of variables, then if {ttac} is a
function that maps the induction hypotheses {hypi} of the {i}th subgoal
to the tactic:
{
      A  ?- P[Ci(vs)/x]
   ======================  MAP_EVERY ttac hypi
         A1 ?- Gi
}
\noindent then {INDUCT_THEN th ttac} is an induction tactic that decomposes
the goal {A ?- !x.P} into a set of {n} subgoals, one for each constructor,
as follows:
{
            A ?- !x.P
  ================================  INDUCT_THEN th ttac
     A1 ?- G1  ...   An ?- Gn
}
\noindent The resulting subgoals correspond to the cases in a structural
induction on the variable {x} of type {ty}, with induction hypotheses treated
as determined by {ttac}.

\FAILURE
{INDUCT_THEN th ttac g} fails if {th} is not a structural induction theorem of
the form returned by {prove_induction_thm}, or if the goal does not have the
form {A ?- !x:ty.P} where {ty} is the type for which {th} is the induction
theorem, or if {ttac} fails for any subgoal in the induction.

\EXAMPLE
The built-in structural induction theorem for lists is:
{
   |- !P. P[] /\ (!t. P t ==> (!h. P(CONS h t))) ==> (!l. P l)
}
\noindent When {INDUCT_THEN} is applied to this theorem, it constructs
and returns a specialized induction tactic (parameterized by a theorem-tactic)
for doing induction on lists:
{
   #let LIST_INDUCT_THEN = INDUCT_THEN list_INDUCT;;
   LIST_INDUCT_THEN = - : (thm_tactic -> tactic)
}
\noindent The resulting function, when supplied with the thm-tactic
{ASSUME_TAC}, returns a tactic that decomposes a goal {?- !l.P[l]} into the
base case {?- P[NIL]} and a step case {P[l] ?- !h. P[CONS h l]}, where the
induction hypothesis {P[l]} in the step case has been put on the assumption
list.  That is, the tactic:
{
   LIST_INDUCT_THEN ASSUME_TAC
}
\noindent does structural induction on lists, putting any induction hypotheses
that arise onto the assumption list:
{
                      A ?- !l. P
   =======================================================
    A |- P[NIL/l]   A u {{P[l'/l]}} ?- !h. P[(CONS h l')/l]
}
\noindent Likewise {LIST_INDUCT_THEN STRIP_ASSUME_TAC} will also do induction
on lists, but will strip induction hypotheses apart before adding them to the
assumptions (this may be useful if P is a conjunction or a disjunction, or is
existentially quantified).  By contrast, the tactic:
{
   LIST_INDUCT_THEN MP_TAC
}
\noindent will decompose the goal as follows:
{
                      A ?- !l. P
   =====================================================
    A |- P[NIL/l]   A ?- P[l'/l] ==> !h. P[CONS h l'/l]
}
\noindent That is, the induction hypothesis becomes the antecedent of an
implication expressing the step case in the induction, rather than an
assumption of the step-case subgoal.

\SEEALSO
define_type, new_recursive_definition, prove_cases_thm,
prove_constructors_distinct, prove_constructors_one_one, prove_induction_thm,
prove_rec_fn_exists.

\ENDDOC