COND_REWR_TAC
Cond_rewrite.COND_REWR_TAC :
(term -> term -> ((term * term) list * (type * type) list) list) ->
thm_tactic
A lower level tactic used to implement simple conditional rewriting tactic.
COND_REWR_TAC
is one of the basic building blocks for
the implementation of conditional rewriting in the HOL system. In
particular, the conditional term replacement or rewriting done by all
the built-in conditional rewriting tactics is ultimately done by
applications of COND_REWR_TAC
. The description given here
for COND_REWR_TAC
may therefore be taken as a specification
of the atomic action of replacing equals by equals in the goal under
certain conditions that aare used in all these higher level conditional
rewriting tactics.
The first argument to COND_REWR_TAC
is expected to be a
function which returns a list of matches. Each of these matches is in
the form of the value returned by the built-in function
match
. It is used to search the goal for instances which
may be rewritten.
The second argument to COND_REWR_TAC
is expected to be
an implicative theorem in the following form:
A |- !x1 ... xn. P1 ==> ... Pm ==> (Q[x1,...,xn] = R[x1,...,xn])
where x1
, …, xn
are all the variables that
occur free in the left-hand side of the conclusion of the theorem but do
not occur free in the assumptions.
If fn
is a function and th
is an
implicative theorem of the kind shown above, then
COND_REWR_TAC fn th
will be a tactic which returns a list
of subgoals if evaluating
fn Q[x1,...,xn] gl
returns a non-empty list of matches when applied to a goal
(asm,gl)
.
Let ml
be the match list returned by evaluating
fn Q[x1,...,xn] gl
. Each element in this list is in the
form of
([(e1,x1);...;(ep,xp)], [(ty1,vty1);...;(tyq,vtyq)])
which specifies the term and type instantiations of the input theorem
th
. Either the term pair list or the type pair list may be
empty. In the case that both lists are empty, an exact match is found,
i.e., no instantiation is required. If ml
is an empty list,
no match has been found and the tactic will fail.
For each match in ml
, COND_REWR_TAC
will
perform the following: 1) instantiate the input theorem th
to get
th' = A |- P1' ==> ... ==> Pm' ==> (Q' = R')
where the primed subterms are instances of the corresponding unprimed
subterms obtained by applying INST_TYPE
with
[(ty1,vty1);...;(tyq,vtyq)]
and then INST
with
[(e1,x1);...;(ep,xp)]
; 2) search the assumption list
asm
for occurrences of any antecedents P1'
, …,
Pm'
; 3) if all antecedents appear in asm
, the
goal gl
is reduced to gl'
by substituting
R'
for each free occurrence of Q'
, otherwise,
in addition to the substitution, all antecedents which do not appear in
asm
are added to it and new subgoals corresponding to these
antecedents are created. For example, if Pk'
, …,
Pm'
do not appear in asm
, the following
subgoals are returned:
asm ?- Pk' ... asm ?- Pm' {{asm,Pk',...,Pm'}} ?- gl'
If COND_REWR_TAC
is given a theorem th
:
A |- !x1 ... xn y1 ... yk. P1 ==> ... ==> Pm ==> (Q = R)
where the variables y1
, …, ym
do not occur
free in the left-hand side of the conclusion Q
but they do
occur free in the antecedents, then, when carrying out Step 2 described
above, COND_REWR_TAC
will attempt to find instantiations
for these variables from the assumption asm
. For example,
if x1
and y1
occur free in P1
,
and a match is found in which e1
is an instantiation of
x1
, then P1'
will become
P1[e1/x1, y1]
. If a term
P1'' = P1[e1,e1'/x1,y1]
appears in asm
,
th'
is instantiated with (e1', y1)
to get
th'' = A |- P1'' ==> ... ==> Pm'' ==> (Q' = R'')
then R''
is substituted into gl
for all
free occurrences of Q'
. If no consistent instantiation is
found, then P1'
which contains the uninstantiated variable
y1
will become one of the new subgoals. In such a case, the
user has no control over the choice of the variable yi
.
COND_REWR_TAC fn th
fails if th
is not an
implication of the form described above. If th
is such an
equation, but the function fn
returns a null list of
matches, or the function fn
returns a non-empty list of
matches, but the term or type instantiation fails.
The following example illustrates a straightforward use of
COND_REWR_TAC
. We use the built-in theorem
LESS_MOD
as the input theorem, and the function
search_top_down
as the search function.
#LESS_MOD;;
Theorem LESS_MOD autoloading from theory `arithmetic` ...
LESS_MOD = |- !n k. k < n ==> (k MOD n = k)
|- !n k. k < n ==> (k MOD n = k)
#search_top_down;;
- : (term -> term -> ((term # term) list # (type # type) list) list)
We set up a goal
#g"2 MOD 3 = 2";;
"2 MOD 3 = 2"
() : void
and then apply the tactic
#e(COND_REWR_TAC search_top_down LESS_MOD);;
OK..
2 subgoals
"2 = 2"
[ "2 < 3" ]
"2 < 3"
() : void
Cond_rewrite.COND_REWRITE1_TAC
,
Cond_rewrite.COND_REWRITE1_CONV
,
Cond_rewrite.COND_REWR_CONV
,
Cond_rewrite.COND_REWR_CANON
,
Cond_rewrite.search_top_down