|
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)
|
|
Restriction Intersection
The following lemma states that two restriced recursive functions agree over their intersection.
|
xl-sml
set_goal([], r H a f b g r twf  (r,a,H,f) is_recfun  (r,b,H,g) is_recfun  x (x,a) r (x,b) r y (x,y) f (x,y) g );
a (rewrite_tac(map get_spec [ twf , wf , is_recfun ]));
a (REPEAT_N 7 strip_tac);
a (spec_nth_asm_tac 4 {x | (x, a) r (x, b) r y (x,y) f (x,y) g} );
(* *** 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 {(v, w)|(v, w) f (v, x) r}
= {(v, w)|(v, w) g (v, x) r} rewrite_thm_tac);
a (rewrite_tac[bin_rel_ext_clauses]);
a (REPEAT strip_tac);
a (spec_nth_asm_tac 5 x'
THEN all_asm_fc_tac[]);
a (spec_nth_asm_tac 5 x'
THEN all_asm_fc_tac[]);
a (spec_nth_asm_tac 3 y );
(* *** 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 {(v, w)|(v, w) g (v, x) r}
= {(v, w)|(v, w) f (v, x) r} rewrite_thm_tac);
a (rewrite_tac[bin_rel_ext_clauses]);
a (REPEAT strip_tac);
a (spec_nth_asm_tac 5 x'
THEN all_asm_fc_tac[]);
a (spec_nth_asm_tac 3 y );
a (spec_nth_asm_tac 5 x'
THEN all_asm_fc_tac[]);
(* *** Goal "3" *** *)
a (strip_tac THEN strip_tac);
a (spec_nth_asm_tac 3 x );
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([], r a H f (r,a,H,f) is_recfun  Dom f = {x | (x,a) r} );
a (REPEAT strip_tac);
a (strip_asm_tac (list_ _elim [ r , a , H , f ] (get_spec is_recfun )));
a (once_asm_rewrite_tac[] THEN rewrite_tac[sets_ext_clauses, _in_clauses]);
a (once_asm_rewrite_tac[]);
a (prove_tac[sets_ext_clauses, _in_clauses]);
val recfun_Dom_thm = save_pop_thm "recfun_Dom_thm";
|
|
xl-sml
set_goal([], r H a f g r twf  (r,a,H,f) is_recfun  (r,a,H,g) is_recfun  f = g );
a (REPEAT strip_tac);
a (strip_asm_tac (list_ _elim [ r , H , a , f , a , g ] 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([], r H a f b g r twf  (r,a,H,f) is_recfun  (r,b,H,g) is_recfun  (a,b) r  f = (Dom f) g );
a (REPEAT strip_tac);
a (strip_asm_tac (list_ _elim [ r , H , a , f , b , g ] ri_lemma));
a (fc_tac [recfun_Dom_thm, get_spec twf ]);
a (pure_asm_rewrite_tac [rel_ext_Dom_thm, Dom_rest_thm]);
a (rewrite_tac [rel_ext_Dom_thm, sets_ext_clauses, _in_clauses]);
a (REPEAT strip_tac THEN_TRY all_asm_fc_tac[]);
a (spec_asm_tac   x (x, a) r (x, b) r ( y (x, y) f (x, y) g)  x );
a (asm_rewrite_tac[]);
val recfun_restr_lemma = save_pop_thm "recfun_restr_lemma";
|
|
xl-sml
set_goal([], r H a f b r twf  (r,a,H,f) is_recfun  (b,a) r  (r,b,H,{(v,w) | (v,w) f (v,b) r}) is_recfun );
a (REPEAT strip_tac);
a (rewrite_tac [get_spec is_recfun , bin_rel_ext_clauses, _in_clauses]);
a (fc_tac [get_spec is_recfun ]);
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 {(v, w)|((v, w) f (v, b) r) (v, x) r} = {(v, w)|(v, w) f (v, x) r} THEN1 (rewrite_tac [bin_rel_ext_clauses, _in_clauses]));
(* *** Goal "1.1" *** *)
a (REPEAT strip_tac);
a (fc_tac [get_spec twf ,get_spec Transitive ]);
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_spec twf ,get_spec Transitive ]);
a (all_asm_fc_tac[]);
(* *** Goal "2.2" *** *)
a (lemma_tac {(v, w)|((v, w) f (v, b) r) (v, x) r} = {(v, w)|(v, w) f (v, x) r} THEN1 (rewrite_tac [bin_rel_ext_clauses, _in_clauses]));
(* *** Goal "2.2.1" *** *)
a (REPEAT strip_tac);
a (fc_tac [get_spec twf ,get_spec Transitive ]);
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([], H R a R twf f (R, a, H, f) is_recfun );
a (REPEAT strip_tac);
a (fc_tac[get_spec twf ]);
a (strip_asm_tac ( _elim R (get_spec wf )) THEN1 REPEAT (all_asm_fc_tac[]));
a (spec_nth_asm_tac 1 {z| f (R, z, H, f) is_recfun} );
(* *** Goal "1" *** *)
a (SWAP_NTH_ASM_CONCL_T 1 discard_tac THEN strip_tac);
a (lemma_tac  g g = { (v,w) | (v,x) R  h (R,v,H,h) is_recfun w = H(v,h)} THEN1 prove_ _tac);
a ( _tac g );
a (rewrite_tac[get_spec is_recfun , bin_rel_ext_clauses, _in_clauses]);
a (REPEAT strip_tac);
(* *** Goal "1.1" *** *)
a (asm_ante_tac (x', y) g );
a (asm_rewrite_tac[] THEN REPEAT strip_tac);
(* *** Goal "1.2" *** *)
a (swap_asm_concl_tac (x', y) g );
a (asm_rewrite_tac[] THEN swap_nth_asm_concl_tac 1);
a (spec_nth_asm_tac 5 x' );
a (lemma_tac h={(v, w)|(v, w) g (v, x') R} );
(* *** Goal "1.2.1" *** *)
a (asm_rewrite_tac[bin_rel_ext_clauses, _in_clauses]);
a (strip_tac THEN strip_tac THEN asm_rewrite_tac[]);
a (FC_T once_rewrite_tac [get_spec is_recfun ]);
a (rewrite_tac[]);
a (REPEAT strip_tac);
(* *** Goal "1.2.1.1" *** *)
a (all_asm_fc_tac[]);
(* *** Goal "1.2.1.2" *** *)
a ( _tac {(v, w)|(v, w) h (v, x'') R} THEN asm_rewrite_tac[]);
a (strip_asm_tac (list_ _elim [ R , H , x' , h , x'' ] restr_is_recfun_lemma));
(* *** Goal "1.2.1.3" *** *)
a (lemma_tac (R,x'',H,{(v, w)|(v, w) h (v, x'') R}) is_recfun THEN1 (strip_asm_tac (list_ _elim [ R , H , x' , h , x'' ] restr_is_recfun_lemma)));
a (strip_asm_tac (list_ _elim [ R , H , x'' , {(v, w)|(v, w) h (v, x'') R} , h' ] recfun_unique_thm));
a (asm_rewrite_tac[]);
(* *** Goal "1.2.2" *** *)
a (asm_ante_tac y = H (x', h) );
a (GET_ASM_T h = {(v, w)|(v, w) g (v, x') R} rewrite_thm_tac);
(* *** Goal "1.3" *** *)
a (asm_rewrite_tac[]);
a (spec_asm_tac  y (y, x) R y {z| f (R, z, H, f) is_recfun}  x' );
a ( _tac f THEN asm_rewrite_tac[]);
a (lemma_tac {(v, w)
|((v, x) R
( h (R, v, H, h) is_recfun w = H (v, h)))
(v, x') R} = f );
(* *** 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 is_recfun ]);
a (once_asm_rewrite_tac[]);
a (rewrite_tac[ _in_clauses]);
(*a (once_asm_rewrite_tac[]);*)
a (lemma_tac {(v, w)|(v, w) f (v, x'') R} = h );
a ((POP_ASM_T discard_tac) THEN (POP_ASM_T discard_tac) THEN once_asm_rewrite_tac[]);
a (GET_ASM_T Dom h = {x|(x, x'') R} 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  x ( y (x, y) f) (x, x') R  x'' );
(* *** 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 ( _tac {(x,y)| (x,y) f (x,x'') R} THEN REPEAT strip_tac);
(* *** Goal "1.3.1.3.1" *** *)
a (ALL_FC_T (MAP_EVERY(asm_tac o (rewrite_rule[sets_ext_clauses]))) [recfun_Dom_thm]);
a (spec_asm_tac  x ( y (x, y) f) (x, x') R x'' );
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 is_recfun ]);
a (POP_ASM_T (fn a=> STRIP_T (fn h=> ante_tac (once_rewrite_rule[h]a))));
a (rewrite_tac [ _in_clauses]);
a (strip_tac);
(* *** Goal "1.3.1.4" *** *)
a (ALL_FC_T (MAP_EVERY(asm_tac o (rewrite_rule[sets_ext_clauses]))) [recfun_Dom_thm]);
a (spec_asm_tac  x ( y (x, y) f) (x, x') R x'' );
a (asm_fc_tac[]);
a (asm_fc_tac[]);
(* *** Goal "1.3.2" *** *)
a (asm_rewrite_tac[]);
(* *** Goal "2" *** *)
a (spec_asm_tac  x x {z| f (R, z, H, f) is_recfun} a );
a ( _tac f THEN strip_tac);
val exists_recfun_thm = save_pop_thm "exists_recfun_thm";
|
|
xl-sml
set_goal([], the_recfun
r a H r twf (r, a, H, the_recfun (r, a, H)) is_recfun );
a (PC_T "hol" prove_ _tac THEN strip_tac);
a ( _tac  recfun Fst x twf
(Fst x, Fst (Snd x), Snd (Snd x), recfun) is_recfun );
a strip_tac;
a (fc_tac[list_ _elim [ Snd(Snd x) , Fst x , Fst (Snd x) ] exists_recfun_thm]);
a (all_ _tac);
a ( _tac f THEN asm_rewrite_tac[]);
val recfun_consistent = top_thm();
xl_set_cs_ _thm (pop_thm());
|
We now define the function wftrec which delivers a solution to a recursion functional.
The following theorem shows that this is indeed a fixed-point.
|
|