Well-Founded Recursion
Overview
This is a proof of the recursion theorem for well-founded recursive definitions. It is modelled on Tobias Nipkow's proof for Isabelle HOL and uses relations modelled with ProofPower HOL's SET type constructor.
A new "wf_rec" theory is created as a child of "wf_rel". Probably
In this section is proved the theorem which justifies well-founded recursive definitions.
In this section I will create a decent proof context for recursive definitions, eventually.
Introduction
A new "wf_rec" theory is created as a child of "wf_rel". Probably
The Theory wf_rec
The new theory is first created, together with a proof context which we will build up as we develop the theory.
xl-sml
open_theory "wf_rel";
force_new_theory "wf_rec";
force_new_pc "wf_rec";
merge_pcs ["xl_cs_exist.gif_conv"] "wf_rec";
set_merge_pcs ["hol", "'bin_rel", "wf_rec"];

Well-Founded Recursion
In this section is proved the theorem which justifies well-founded recursive definitions.
Introduction

The idea here is that a recursive equation is represented by a functional, which is obtained by abstracting the right hand side of the equation on the name of the function. We need to demonstrate that definitions using such a functional have unique solutions.

Is RecFun
is_recfun is the set of 4-tuples <r,a,H,f> such that f solves the recursion equations represented by H for values which are in the left image of a under R. (following Tobias Nipkow)
xl-holconst
is_recfun: (('a cross.gif 'a)SET cross.gif 'a cross.gif (('a cross.gif ('a cross.gif 'a)SET) rarr.gif 'a) cross.gif ('a cross.gif 'a)SET)SET
forall.gif r a H f bull.gif
ftbr (r,a,H,f) isin.gif is_recfun equiv.gif f = {(x,y)|
fttab(x,a) isin.gif r and.gif
fttaby = H(x, {(v,w)| (v,w) isin.gif f and.gif (v,x) isin.gif r})
fttab}
Restriction Intersection
The following lemma states that two restriced recursive functions agree over their intersection.
xl-sml
set_goal([],qqtel.gifforall.gifr H a f b gbull.gif r isin.gif twf
fttaband.gif (r,a,H,f) isin.gif is_recfun
fttaband.gif (r,b,H,g) isin.gif is_recfun
fttabruarr.gif forall.gifxbull.gif (x,a)isin.gifr and.gif (x,b)isin.gifr ruarr.gif forall.gifybull.gif(x,y)isin.giff equiv.gif (x,y)isin.gifgqqter.gif);
a (rewrite_tac(map get_spec [qqtel.giftwfqqter.gif, qqtel.gifwfqqter.gif, qqtel.gifis_recfunqqter.gif]));
a (REPEAT_N 7 strip_tac);
a (spec_nth_asm_tac 4 qqtel.gif{x | (x, a) isin.gif r and.gif (x, b) isin.gif r ruarr.gif forall.gifybull.gif(x,y)isin.giff equiv.gif (x,y)isin.gifg}qqter.gif);
(* *** Goal "1" *** *)
a (SWAP_NTH_ASM_CONCL_T 1 discard_tac);
a (all_asm_ante_tac THEN REPEAT_N 5 strip_tac);
a (once_asm_rewrite_tac[]);
a (rewrite_tac[] THEN REPEAT strip_tac);
a (DROP_NTH_ASM_T 1 rewrite_thm_tac);
a (LEMMA_T qqtel.gif{(v, w)|(v, w) isin.gif f and.gif (v, x) isin.gif r}
ftbr = {(v, w)|(v, w) isin.gif g and.gif (v, x) isin.gif r}qqter.gif
fttabrewrite_thm_tac);
a (rewrite_tac[bin_rel_ext_clauses]);
a (REPEAT strip_tac);
a (spec_nth_asm_tac 5 qqtel.gifx'qqter.gif
ftbr THEN all_asm_fc_tac[]);
a (spec_nth_asm_tac 5 qqtel.gifx'qqter.gif
ftbr THEN all_asm_fc_tac[]);
a (spec_nth_asm_tac 3 qqtel.gifyqqter.gif);
(* *** Goal "2" *** *)
a (SWAP_NTH_ASM_CONCL_T 1 discard_tac);
a (all_asm_ante_tac THEN REPEAT_N 5 strip_tac);
a (once_asm_rewrite_tac[]);
a (rewrite_tac[] THEN REPEAT strip_tac);
a (DROP_NTH_ASM_T 1 rewrite_thm_tac);
a (LEMMA_T qqtel.gif{(v, w)|(v, w) isin.gif g and.gif (v, x) isin.gif r}
ftbr = {(v, w)|(v, w) isin.gif f and.gif (v, x) isin.gif r}qqter.gif
fttabrewrite_thm_tac);
a (rewrite_tac[bin_rel_ext_clauses]);
a (REPEAT strip_tac);
a (spec_nth_asm_tac 5 qqtel.gifx'qqter.gif
ftbr THEN all_asm_fc_tac[]);
a (spec_nth_asm_tac 3 qqtel.gifyqqter.gif);
a (spec_nth_asm_tac 5 qqtel.gifx'qqter.gif
ftbr THEN all_asm_fc_tac[]);
(* *** Goal "3" *** *)
a (strip_tac THEN strip_tac);
a (spec_nth_asm_tac 3 qqtel.gifxqqter.gif);
val ri_lemma = save_pop_thm "ri_lemma";

Restrict Unique
An immediate corrolory is that there is only one restricted recursive function at any point. First, however we prove a lemma about the domain of a restricted recursive function.
xl-sml
set_goal([],qqtel.gifforall.gifr a H fbull.gif (r,a,H,f) isin.gif is_recfun
fttabruarr.gif Dom f = {x | (x,a) isin.gif r}qqter.gif);
a (REPEAT strip_tac);
a (strip_asm_tac (list_forall.gif_elim [qqtel.gifrqqter.gif,qqtel.gifaqqter.gif,qqtel.gifHqqter.gif,qqtel.giffqqter.gif] (get_spec qqtel.gifis_recfunqqter.gif)));
a (once_asm_rewrite_tac[] THEN rewrite_tac[sets_ext_clauses, isin.gif_in_clauses]);
a (once_asm_rewrite_tac[]);
a (prove_tac[sets_ext_clauses, isin.gif_in_clauses]);
val recfun_Dom_thm = save_pop_thm "recfun_Dom_thm";


xl-sml
set_goal([],qqtel.gifforall.gifr H a f gbull.gif r isin.gif twf
fttaband.gif (r,a,H,f) isin.gif is_recfun
fttaband.gif (r,a,H,g) isin.gif is_recfun
fttabruarr.gif f = gqqter.gif);
a (REPEAT strip_tac);
a (strip_asm_tac (list_forall.gif_elim [qqtel.gifrqqter.gif,qqtel.gifHqqter.gif,qqtel.gifaqqter.gif,qqtel.giffqqter.gif,qqtel.gifaqqter.gif,qqtel.gifgqqter.gif] ri_lemma));
a (pure_rewrite_tac [rel_ext_Dom_thm]);
a (FC_T rewrite_tac [recfun_Dom_thm]);
a (asm_prove_tac[]);
val recfun_unique_thm = save_pop_thm "recfun_unique_thm";


xl-sml
set_goal([],qqtel.gifforall.gifr H a f b gbull.gif r isin.gif twf
fttaband.gif (r,a,H,f) isin.gif is_recfun
fttaband.gif (r,b,H,g) isin.gif is_recfun
fttaband.gif (a,b) isin.gif r
fttabruarr.gif f = (Dom f) dr.gif gqqter.gif);
a (REPEAT strip_tac);
a (strip_asm_tac (list_forall.gif_elim [qqtel.gifrqqter.gif,qqtel.gifHqqter.gif,qqtel.gifaqqter.gif,qqtel.giffqqter.gif,qqtel.gifbqqter.gif,qqtel.gifgqqter.gif] ri_lemma));
a (fc_tac [recfun_Dom_thm, get_spec qqtel.giftwfqqter.gif]);
a (pure_asm_rewrite_tac [rel_ext_Dom_thm, Dom_rest_thm]);
a (rewrite_tac [rel_ext_Dom_thm, sets_ext_clauses, isin.gif_in_clauses]);
a (REPEAT strip_tac THEN_TRY all_asm_fc_tac[]);
a (spec_asm_tac
fttabqqtel.gifforall.gif xbull.gif (x, a) isin.gif r and.gif (x, b) isin.gif r ruarr.gif (forall.gif ybull.gif (x, y) isin.gif f equiv.gif (x, y) isin.gif g)qqter.gif
fttabqqtel.gifxqqter.gif);
a (asm_rewrite_tac[]);
val recfun_restr_lemma = save_pop_thm "recfun_restr_lemma";


xl-sml
set_goal([],qqtel.gifforall.gifr H a f bbull.gif r isin.gif twf
fttaband.gif (r,a,H,f) isin.gif is_recfun
fttaband.gif (b,a) isin.gif r
fttabruarr.gif (r,b,H,{(v,w) | (v,w) isin.gif f and.gif (v,b) isin.gif r}) isin.gif is_recfunqqter.gif);
a (REPEAT strip_tac);
a (rewrite_tac [get_specqqtel.gifis_recfunqqter.gif, bin_rel_ext_clauses, isin.gif_in_clauses]);
a (fc_tac [get_specqqtel.gifis_recfunqqter.gif]);
a (REPEAT_N 4 strip_tac);
(* *** Goal "1" *** *)
a (GET_NTH_ASM_T 1 (fn asm=>STRIP_T (fn x => strip_asm_tac(once_rewrite_rule[asm]x))));
a (REPEAT strip_tac);
a (lemma_tac qqtel.gif{(v, w)|((v, w) isin.gif f and.gif (v, b) isin.gif r) and.gif (v, x) isin.gif r} = {(v, w)|(v, w) isin.gif f and.gif (v, x) isin.gif r}qqter.gif
fttabTHEN1 (rewrite_tac [bin_rel_ext_clauses,isin.gif_in_clauses]));
(* *** Goal "1.1" *** *)
a (REPEAT strip_tac);
a (fc_tac [get_specqqtel.giftwfqqter.gif,get_specqqtel.gifTransitiveqqter.gif]);
a (all_asm_fc_tac[]);
(* *** Goal "1.2" *** *)
a (pure_once_asm_rewrite_tac[]);
a (rewrite_tac[]);
(* *** Goal "2" *** *)
a (REPEAT strip_tac);
a (once_asm_rewrite_tac[]);
a (rewrite_tac[]);
a (REPEAT strip_tac);
(* *** Goal "2.1" *** *)
a (fc_tac [get_specqqtel.giftwfqqter.gif,get_specqqtel.gifTransitiveqqter.gif]);
a (all_asm_fc_tac[]);
(* *** Goal "2.2" *** *)
a (lemma_tac qqtel.gif{(v, w)|((v, w) isin.gif f and.gif (v, b) isin.gif r) and.gif (v, x) isin.gif r} = {(v, w)|(v, w) isin.gif f and.gif (v, x) isin.gif r}qqter.gif
fttabTHEN1 (rewrite_tac [bin_rel_ext_clauses,isin.gif_in_clauses]));
(* *** Goal "2.2.1" *** *)
a (REPEAT strip_tac);
a (fc_tac [get_specqqtel.giftwfqqter.gif,get_specqqtel.gifTransitiveqqter.gif]);
a (all_asm_fc_tac[]);
(* *** Goal "2.2.2" *** *)
a (GET_NTH_ASM_T 1 (fn x=> pure_once_rewrite_tac[x]));
a (rewrite_tac[]);
val restr_is_recfun_lemma = save_pop_thm "restr_is_recfun_lemma";

Now the big one:
xl-sml
set_goal([],qqtel.gifforall.gifH R abull.gif R isin.gif twf ruarr.gif exist.giffbull.gif (R, a, H, f) isin.gif is_recfunqqter.gif);
a (REPEAT strip_tac);
a (fc_tac[get_specqqtel.giftwfqqter.gif]);
a (strip_asm_tac (forall.gif_elim qqtel.gifRqqter.gif (get_specqqtel.gifwfqqter.gif))
fttabTHEN1 REPEAT (all_asm_fc_tac[]));
a (spec_nth_asm_tac 1 qqtel.gif{z|exist.gif fbull.gif (R, z, H, f) isin.gif is_recfun}qqter.gif);
(* *** Goal "1" *** *)
a (SWAP_NTH_ASM_CONCL_T 1 discard_tac THEN strip_tac);
a (lemma_tac qqtel.gifexist.gifgbull.gif g = { (v,w) | (v,x) isin.gif R and.gif
fttabexist.gifhbull.gif (R,v,H,h) isin.gif is_recfun and.gif w = H(v,h)}qqter.gif
fttabTHEN1 prove_exist.gif_tac);
a (exist.gif_tac qqtel.gifgqqter.gif);
a (rewrite_tac[get_spec qqtel.gifis_recfunqqter.gif, bin_rel_ext_clauses, isin.gif_in_clauses]);
a (REPEAT strip_tac);
(* *** Goal "1.1" *** *)
a (asm_ante_tac qqtel.gif(x', y) isin.gif gqqter.gif);
a (asm_rewrite_tac[] THEN REPEAT strip_tac);
(* *** Goal "1.2" *** *)
a (swap_asm_concl_tac qqtel.gif(x', y) isin.gif gqqter.gif);
a (asm_rewrite_tac[] THEN swap_nth_asm_concl_tac 1);
a (spec_nth_asm_tac 5 qqtel.gifx'qqter.gif);
a (lemma_tac qqtel.gifh={(v, w)|(v, w) isin.gif g and.gif (v, x') isin.gif R}qqter.gif);
(* *** Goal "1.2.1" *** *)
a (asm_rewrite_tac[bin_rel_ext_clauses, isin.gif_in_clauses]);
a (strip_tac THEN strip_tac THEN asm_rewrite_tac[]);
a (FC_T once_rewrite_tac [get_specqqtel.gifis_recfunqqter.gif]);
a (rewrite_tac[]);
a (REPEAT strip_tac);
(* *** Goal "1.2.1.1" *** *)
a (all_asm_fc_tac[]);
(* *** Goal "1.2.1.2" *** *)
a (exist.gif_tac qqtel.gif{(v, w)|(v, w) isin.gif h and.gif (v, x'') isin.gif R}qqter.gif
fttabTHEN asm_rewrite_tac[]);
a (strip_asm_tac (list_forall.gif_elim [qqtel.gifRqqter.gif,qqtel.gifHqqter.gif,qqtel.gifx'qqter.gif,qqtel.gifhqqter.gif,qqtel.gifx''qqter.gif] restr_is_recfun_lemma));
(* *** Goal "1.2.1.3" *** *)
a (lemma_tac qqtel.gif(R,x'',H,{(v, w)|(v, w) isin.gif h and.gif (v, x'') isin.gif R}) isin.gif is_recfunqqter.gif
fttabTHEN1 (strip_asm_tac (list_forall.gif_elim [qqtel.gifRqqter.gif,qqtel.gifHqqter.gif,qqtel.gifx'qqter.gif,qqtel.gifhqqter.gif,qqtel.gifx''qqter.gif] restr_is_recfun_lemma)));
a (strip_asm_tac (list_forall.gif_elim
fttab[qqtel.gifRqqter.gif,qqtel.gifHqqter.gif,qqtel.gifx''qqter.gif,qqtel.gif{(v, w)|(v, w) isin.gif h and.gif (v, x'') isin.gif R}qqter.gif,qqtel.gifh'qqter.gif]
fttabrecfun_unique_thm));
a (asm_rewrite_tac[]);
(* *** Goal "1.2.2" *** *)
a (asm_ante_tac qqtel.gify = H (x', h)qqter.gif);
a (GET_ASM_T qqtel.gifh = {(v, w)|(v, w) isin.gif g and.gif (v, x') isin.gif R}qqter.gif
fttabrewrite_thm_tac);
(* *** Goal "1.3" *** *)
a (asm_rewrite_tac[]);
a (spec_asm_tac qqtel.gifforall.gif ybull.gif (y, x) isin.gif R ruarr.gif y isin.gif {z|exist.gif fbull.gif (R, z, H, f) isin.gif is_recfun}qqter.gif
fttabqqtel.gifx'qqter.gif);
a (exist.gif_tac qqtel.giffqqter.gif THEN asm_rewrite_tac[]);
a (lemma_tac qqtel.gif{(v, w)
ftbr |((v, x) isin.gif R
ftbr and.gif (exist.gif hbull.gif (R, v, H, h) isin.gif is_recfun and.gif w = H (v, h)))
ftbr and.gif (v, x') isin.gif R} = fqqter.gif);
(* *** Goal "1.3.1" *** *)
a (rewrite_tac[bin_rel_ext_clauses]);
a (REPEAT strip_tac);
(* *** Goal "1.3.1.1" *** *)
a (all_fc_tac [recfun_restr_lemma]);
a (all_fc_tac [recfun_Dom_thm]);
a (all_fc_tac [get_spec qqtel.gifis_recfunqqter.gif]);
a (once_asm_rewrite_tac[]);
a (rewrite_tac[isin.gif_in_clauses]);
(*a (once_asm_rewrite_tac[]);*)
a (lemma_tac qqtel.gif{(v, w)|(v, w) isin.gif f and.gif (v, x'') isin.gif R} = hqqter.gif);
a ((POP_ASM_T discard_tac) THEN (POP_ASM_T discard_tac)
fttabTHEN once_asm_rewrite_tac[]);
a (GET_ASM_T qqtel.gifDom h = {x|(x, x'') isin.gif R}qqter.gif pure_rewrite_thm_tac);
a (prove_tac[bin_rel_ext_clauses]);
a (POP_ASM_T rewrite_thm_tac THEN strip_tac);
(* *** Goal "1.3.1.2" *** *)
a (POP_ASM_T ante_tac);
a (ALL_FC_T (MAP_EVERY ante_tac) [recfun_Dom_thm]);
a (rewrite_tac[sets_ext_clauses]);
a (REPEAT strip_tac);
a (spec_asm_tac qqtel.gifforall.gif xbull.gif (exist.gif ybull.gif (x, y) isin.gif f) equiv.gif (x, x') isin.gif Rqqter.gif
fttabqqtel.gifx''qqter.gif);
(* *** Goal "1.3.1.2.1" *** *)
a (REPEAT (asm_fc_tac[]));
a (REPEAT (asm_fc_tac[]));
a (REPEAT (asm_fc_tac[]));
(* *** Goal "1.3.1.3" *** *)
a (exist.gif_tac qqtel.gif{(x,y)| (x,y) isin.gif f and.gif (x,x'') isin.gif R}qqter.gif THEN REPEAT strip_tac);
(* *** Goal "1.3.1.3.1" *** *)
a (ALL_FC_T
fttab(MAP_EVERY(asm_tac o (rewrite_rule[sets_ext_clauses])))
fttab[recfun_Dom_thm]);
a (spec_asm_tac qqtel.gifforall.gif xbull.gif (exist.gif ybull.gif (x, y) isin.gif f) equiv.gif (x, x') isin.gif Rqqter.gif qqtel.gifx''qqter.gif);
a (asm_fc_tac[]);
a (asm_fc_tac[]);
a (all_fc_tac [restr_is_recfun_lemma]);
(* *** Goal "1.3.1.3.2" *** *)
a (ALL_FC_T (MAP_EVERY ante_tac) [get_spec qqtel.gifis_recfunqqter.gif]);
a (POP_ASM_T (fn a=> STRIP_T (fn h=> ante_tac (once_rewrite_rule[h]a))));
a (rewrite_tac [isin.gif_in_clauses]);
a (strip_tac);
(* *** Goal "1.3.1.4" *** *)
a (ALL_FC_T
fttab(MAP_EVERY(asm_tac o (rewrite_rule[sets_ext_clauses])))
fttab[recfun_Dom_thm]);
a (spec_asm_tac qqtel.gifforall.gif xbull.gif (exist.gif ybull.gif (x, y) isin.gif f) equiv.gif (x, x') isin.gif Rqqter.gif qqtel.gifx''qqter.gif);
a (asm_fc_tac[]);
a (asm_fc_tac[]);
(* *** Goal "1.3.2" *** *)
a (asm_rewrite_tac[]);
(* *** Goal "2" *** *)
a (spec_asm_tac qqtel.gifforall.gif xbull.gif x isin.gif {z|exist.gif fbull.gif (R, z, H, f) isin.gif is_recfun}qqter.gif qqtel.gifaqqter.gif);
a (exist.gif_tac qqtel.giffqqter.gif THEN strip_tac);
val exists_recfun_thm = save_pop_thm "exists_recfun_thm";


xl-sml
set_goal([],qqtel.gifexist.gif the_recfun
ftbr bull.gif forall.gif r a Hbull.gif r isin.gif twf ruarr.gif (r, a, H, the_recfun (r, a, H)) isin.gif is_recfunqqter.gif);
a (PC_T "hol" prove_exist.gif_tac THEN strip_tac);
a (exist.gif_tac qqtel.gifepsilon.gifrecfunbull.gif Fst x isin.gif twf
ftbr ruarr.gif (Fst x, Fst (Snd x), Snd (Snd x), recfun) isin.gif is_recfunqqter.gif);
a strip_tac;
a (fc_tac[list_forall.gif_elim [qqtel.gifSnd(Snd x)qqter.gif,qqtel.gifFst xqqter.gif,qqtel.gifFst (Snd x)qqter.gif] exists_recfun_thm]);
a (all_epsilon.gif_tac);
a (exist.gif_tac qqtel.giffqqter.gif THEN asm_rewrite_tac[]);
val recfun_consistent = top_thm();
xl_set_cs_exist.gif_thm (pop_thm());


xl-holconst
the_recfun: (('a cross.gif 'a)SET cross.gif 'a cross.gif (('a cross.gif ('a cross.gif 'a)SET) rarr.gif 'a)) rarr.gif ('a cross.gif 'a)SET
forall.gif r a Hbull.gif r isin.gif twf ruarr.gif (r,a,H,the_recfun(r,a,H)) isin.gif is_recfun
We now define the function wftrec which delivers a solution to a recursion functional.
xl-holconst
wftrecfun: (('a cross.gif 'a)SET cross.gif (('a cross.gif ('a cross.gif 'a)SET) rarr.gif 'a)) rarr.gif ('a cross.gif 'a)SET
forall.gif r Hbull.gif wftrecfun (r,H) = {(a,v) | v = H(a,the_recfun(r,a,H))}
The following theorem shows that this is indeed a fixed-point.
xl-holconst
wftrec: (('a cross.gif 'a)SET cross.gif 'a cross.gif (('a cross.gif ('a cross.gif 'a)SET) rarr.gif 'a)) rarr.gif 'a
forall.gif r a Hbull.gif wftrec (r,a,H) = H(a,the_recfun(r,a,H))
Recursion Theorem
Proof Context
In this section I will create a decent proof context for recursive definitions, eventually.
Proof Context

xl-sml
(* commit_pc "wf_rec"; *)


up quick index © RBJ

$Id: WfRec.xml,v 1.3 2008/04/06 13:07:17 rbj01 Exp $

V