Recursion Theorem for Well-Founded Relations as Properties
Overview
This document contains the proof of a recursion theorem asserting the existence of a fixed point for any functional which "respects" some well-founded relation.
A new "wf_recp" theory is created as a child of "wf_relp".
The main part of this is the proof that functionals which are well-founded with respect to some well-founded relation have fixed points. This done, the operator "fix" is defined, which yields such a fixed point.
In this section I will create a decent proof context for recursive definitions, eventually.
Introduction
A new "wf_recp" theory is created as a child of "wf_relp".
Introduction

I have already proved a recursion theorem fairly closely following the formulation and proof devised by Tobias Nipkow for Isabelle-HOL. There are two reasons for my wanting a different version of this result. The Nipkow derived version works with relations rather than functions, and in my version the relations are ProofPower sets of pairs (I think in the original they were probably properties of pairs). This is probably all easily modded into one which works directly with functions but I though it should be possible also to do a neater proof (the "proof" of the recursion theorem in Kunen is just a couple of lines).

The end result certainly looks nicer, we'll have to see whether it works out well in practice. In particular the fixpoint operator simply takes a functional as an argument and delivers the fixed point as a result. The functional which you give it as an argument, in the simple cases, is just what you get by abstracting the right hand side of a recursive definition on the name of the function (more complicated of course if a pattern matching definition is used). The relation with respect to which the recursion is well-founded need only be mentioned when attempting to prove that this does yield a fixed point.

Another minor improvement is that I do not require the relation to be transitive.

The proof is shorter than (my version of) the original, but by less than 20 percent. I'm sure there's lots of scope for improvement. (The isabelle version is much shorter than either.)

The Theory wf_recp
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_relp";
force_new_theory "wf_recp";
force_new_pc "wf_recp";
merge_pcs ["xl_cs_exist.gif_conv"] "wf_recp";
set_merge_pcs ["hol", "wf_relp", "wf_recp"];

Defining the Fixed Point Operator
The main part of this is the proof that functionals which are well-founded with respect to some well-founded relation have fixed points. This done, the operator "fix" is defined, which yields such a fixed point.
Definitions

xl-sml
declare_infix (240, "respects");


xl-holconst
$respects: (('a rarr.gif 'b) rarr.gif ('a rarr.gif 'b)) rarr.gif ('a rarr.gif 'a rarr.gif BOOL) rarr.gif BOOL
forall.gif f r bull.gif f respects r equiv.gif forall.gifg h xbull.gif (forall.gifybull.gif (tc r) y x ruarr.gif g y = h y) ruarr.gif f g x = f h x

xl-holconst
fixed_below: (('a rarr.gif 'b) rarr.gif ('a rarr.gif 'b)) rarr.gif ('a rarr.gif 'a rarr.gif BOOL) rarr.gif ('a rarr.gif 'b) rarr.gif 'a rarr.gif BOOL
forall.giff r g xbull.gif fixed_below f r g x equiv.gif forall.gifybull.gif tc r y x ruarr.gif f g y = g y

xl-holconst
fixed_at: (('a rarr.gif 'b) rarr.gif ('a rarr.gif 'b)) rarr.gif ('a rarr.gif 'a rarr.gif BOOL) rarr.gif ('a rarr.gif 'b) rarr.gif 'a rarr.gif BOOL
forall.giff r g xbull.gif fixed_at f r g x equiv.gif fixed_below f r g x and.gif f g x = g x

xl-sml
set_goal ([],qqtel.gifforall.giff rbull.gif well_founded r and.gif f respects r
fttabruarr.gif forall.gifx g ybull.gif fixed_below f r g x and.gif tc r y x ruarr.gif fixed_below f r g yqqter.gif);
a (rewrite_tac [get_spec qqtel.giffixed_belowqqter.gif, get_spec qqtel.gif$respectsqqter.gif]);
a (REPEAT strip_tac);
a (all_asm_fc_tac [tran_tc_thm2]);
a (all_asm_fc_tac []);
val fixed_below_lemma1 = save_pop_thm "fixed_below_lemma1";


xl-sml
set_goal ([],qqtel.gifforall.giff rbull.gif well_founded r and.gif f respects r
fttabruarr.gif forall.gifx gbull.gif fixed_below f r g x ruarr.gif fixed_at f r (f g) xqqter.gif);
a (rewrite_tac [get_spec qqtel.giffixed_belowqqter.gif, get_spec qqtel.giffixed_atqqter.gif, get_spec qqtel.gif$respectsqqter.gif]);
a (REPEAT strip_tac);
(* *** Goal "1" *** *)
a (list_spec_nth_asm_tac 3 [qqtel.giff gqqter.gif, qqtel.gifgqqter.gif]);
a (spec_nth_asm_tac 1 qqtel.gifyqqter.gif);
a (all_asm_fc_tac [tran_tc_thm2]);
a (all_asm_fc_tac []);
(* *** Goal "2" *** *)
a (list_spec_nth_asm_tac 2 [qqtel.giff gqqter.gif, qqtel.gifgqqter.gif]);
a (all_asm_fc_tac []);
val fixed_at_lemma1 = save_pop_thm "fixed_at_lemma1";


xl-sml
set_goal ([],qqtel.gifforall.giff rbull.gif well_founded r and.gif f respects r
fttabruarr.gif forall.gifx gbull.gif fixed_below f r g x ruarr.gif forall.gifybull.gif tc r y x ruarr.gif fixed_at f r g yqqter.gif);
a (rewrite_tac [get_spec qqtel.giffixed_belowqqter.gif, get_spec qqtel.giffixed_atqqter.gif, get_spec qqtel.gif$respectsqqter.gif]);
a (REPEAT strip_tac);
(* *** Goal "1" *** *)
a (all_asm_fc_tac [tran_tc_thm2]);
a (all_asm_fc_tac []);
(* *** Goal "2" *** *)
a (all_asm_fc_tac []);
val fixed_at_lemma2 = save_pop_thm "fixed_at_lemma2";


xl-sml
set_goal ([],qqtel.gifforall.giff rbull.gif well_founded r and.gif f respects r
fttabruarr.gif forall.gifx gbull.gif (forall.gifybull.gif tc r y x ruarr.gif fixed_at f r g y) ruarr.gif fixed_below f r g xqqter.gif);
a (REPEAT_N 4 strip_tac);
a (rewrite_tac [get_spec qqtel.giffixed_atqqter.gif, get_spec qqtel.giffixed_belowqqter.gif]);
a (REPEAT strip_tac);
a (all_asm_fc_tac []);
val fixed_at_lemma3 = save_pop_thm "fixed_at_lemma3";


xl-sml
set_goal ([],qqtel.gifforall.giff rbull.gif well_founded r and.gif f respects r
fttabruarr.gif forall.gifx g hbull.gif fixed_below f r g x and.gif fixed_below f r h x ruarr.gif forall.gifzbull.gif tc r z x ruarr.gif h z = g zqqter.gif);
a (REPEAT_N 4 strip_tac);
a (wf_induction_tac (asm_rule qqtel.gifwell_founded rqqter.gif) qqtel.gifxqqter.gif);
a (REPEAT strip_tac);
a (spec_nth_asm_tac 4 qqtel.gifzqqter.gif);
a (all_asm_fc_tac [fixed_below_lemma1]);
a (list_spec_nth_asm_tac 3 [qqtel.gifgqqter.gif, qqtel.gifhqqter.gif]);
a (all_asm_fc_tac [fixed_at_lemma2]);
a (all_asm_fc_tac [get_spec qqtel.giffixed_atqqter.gif]);
a (all_asm_fc_tac [fixed_at_lemma1]);
a (all_asm_fc_tac [get_spec qqtel.gif$respectsqqter.gif]);
a (GET_ASM_T qqtel.giff h z = h zqqter.gif (rewrite_thm_tac o eq_sym_rule));
a (GET_ASM_T qqtel.giff h z = f g zqqter.gif rewrite_thm_tac);
a strip_tac;
val fixed_below_lemma2 = save_pop_thm "fixed_below_lemma2";


xl-sml
set_goal ([],qqtel.gifforall.giff rbull.gif well_founded r and.gif f respects r
fttabruarr.gif forall.gifg xbull.gif fixed_at f r g x ruarr.gif forall.gifybull.gif tc r y x ruarr.gif fixed_at f r g yqqter.gif);
a (REPEAT strip_tac);
a (all_fc_tac [get_spec qqtel.giffixed_atqqter.gif]);
a (all_fc_tac[fixed_at_lemma2]);
val fixed_at_lemma4 = save_pop_thm "fixed_at_lemma4";


xl-sml
set_goal ([],qqtel.gifforall.giff rbull.gif well_founded r and.gif f respects r
fttabruarr.gif forall.gifg h xbull.gif fixed_at f r g x and.gif fixed_at f r h x ruarr.gif g x = h xqqter.gif);
a (REPEAT strip_tac);
a (fc_tac[get_spec qqtel.gif$respectsqqter.gif]);
a (all_fc_tac[get_spec qqtel.giffixed_atqqter.gif]);
a (all_asm_fc_tac[get_spec qqtel.gif$respectsqqter.gif]);
a (fc_tac[get_spec qqtel.giffixed_belowqqter.gif]);
a (fc_tac[fixed_below_lemma2]);
a (asm_fc_tac[]);
a (asm_fc_tac[]);
a (asm_fc_tac[]);
a (asm_fc_tac[]);
a (eq_sym_nth_asm_tac 14);
a (eq_sym_nth_asm_tac 13);
a (asm_rewrite_tac[]);
val fixed_at_lemma5 = save_pop_thm "fixed_at_lemma5";


xl-sml
set_goal ([],qqtel.gifforall.giff rbull.gif well_founded r and.gif f respects r
fttabruarr.gif forall.gifxbull.gif (forall.gifybull.gif tc r y x ruarr.gif exist.gifgbull.gif fixed_at f r g y) ruarr.gif exist.gifgbull.gif fixed_below f r g xqqter.gif);
a (REPEAT strip_tac);
a (exist.gif_tac qqtel.giflambda.gifzbull.gif (epsilon.gifhbull.gif fixed_at f r h z) zqqter.gif);
a (rewrite_tac [get_spec qqtel.giffixed_belowqqter.gif]
fttabTHEN REPEAT strip_tac);
a (GET_ASM_T qqtel.giff respects rqqter.gif ante_tac
fttabTHEN rewrite_tac [list_forall.gif_elim [qqtel.giffqqter.gif, qqtel.gifrqqter.gif] (get_spec qqtel.gif$respectsqqter.gif)]
fttabTHEN strip_tac);
a (list_spec_nth_asm_tac 1 [qqtel.giflambda.gif zbull.gif (epsilon.gif hbull.gif fixed_at f r h z) zqqter.gif, qqtel.gifepsilon.gif hbull.gif fixed_at f r h yqqter.gif]);
a (spec_nth_asm_tac 1 qqtel.gifyqqter.gif);
(* *** Goal "1" *** *)
a (swap_nth_asm_concl_tac 1 THEN rewrite_tac[]);
a (asm_fc_tac[fixed_at_lemma4]);
a (list_spec_nth_asm_tac 2 [qqtel.giffqqter.gif, qqtel.gifgqqter.gif, qqtel.gifyqqter.gif, qqtel.gify'qqter.gif]);
a (asm_fc_tac[]);
a (all_epsilon.gif_tac);
(* *** Goal "1.1" *** *)
a (exist.gif_tac qqtel.gifgqqter.gif THEN asm_rewrite_tac[]);
(* *** Goal "1.2" *** *)
a (exist.gif_tac qqtel.gifgqqter.gif THEN asm_rewrite_tac[]);
(* *** Goal "1.3" *** *)
a (exist.gif_tac qqtel.gifgqqter.gif THEN asm_rewrite_tac[]);
(* *** Goal "1.4" *** *)
a (asm_tac fixed_at_lemma4);
a (list_spec_nth_asm_tac 1 [qqtel.giffqqter.gif, qqtel.gifrqqter.gif]);
a (list_spec_nth_asm_tac 1 [qqtel.gifepsilon.gif hbull.gif fixed_at f r h yqqter.gif, qqtel.gifyqqter.gif]);
a (list_spec_nth_asm_tac 1 [qqtel.gify'qqter.gif]);
a (all_asm_fc_tac[fixed_at_lemma5]);
(* *** Goal "2" *** *)
a (asm_rewrite_tac[]);
a (all_asm_fc_tac[]);
a (all_epsilon.gif_tac);
(* *** Goal "2.1" *** *)
a (exist.gif_tac qqtel.gifgqqter.gif THEN asm_rewrite_tac[]);
(* *** Goal "2.2" *** *)
a (all_fc_tac[get_spec qqtel.giffixed_atqqter.gif]);
val fixed_below_lemma3 = save_pop_thm "fixed_below_lemma3";


xl-sml
set_goal ([],qqtel.gifforall.gifr fbull.gif well_founded r and.gif f respects r
fttabruarr.gif forall.gifxbull.gif exist.gifgbull.gif fixed_below f r g x qqter.gif);
a (REPEAT_N 4 strip_tac);
a (wf_induction_tac (asm_rule qqtel.gifwell_founded rqqter.gif) qqtel.gifxqqter.gif);
a (lemma_tac qqtel.gifforall.gif ubull.gif tc r u t ruarr.gif (exist.gif gbull.gif fixed_at f r g u)qqter.gif
fttabTHEN1 (REPEAT strip_tac
fttabTHEN all_asm_fc_tac[]
fttabTHEN all_fc_tac[fixed_at_lemma1]
fttabTHEN exist.gif_tac qqtel.giff gqqter.gif
fttabTHEN asm_rewrite_tac[]));
a (all_fc_tac[fixed_below_lemma3]);
a (exist.gif_tac qqtel.gifgqqter.gif THEN strip_tac);
val fixed_below_lemma4 = save_pop_thm "fixed_below_lemma4";


xl-sml
set_goal ([],qqtel.gifforall.giff rbull.gif well_founded r and.gif f respects r
fttabruarr.gif forall.gifxbull.gif exist.gifgbull.gif fixed_at f r g x qqter.gif);
a (REPEAT_N 4 strip_tac);
a (all_fc_tac[fixed_below_lemma4]);
a (spec_nth_asm_tac 1 qqtel.gifxqqter.gif);
a (exist.gif_tac qqtel.giff gqqter.gif);
a (all_fc_tac[fixed_at_lemma1]);
val fixed_at_lemma6 = save_pop_thm "fixed_at_lemma6";


xl-sml
set_goal ([],qqtel.gifforall.giff rbull.gif well_founded r and.gif f respects r ruarr.gif
fttabforall.gifxbull.gif fixed_at f r (lambda.gif xbull.gif (epsilon.gif hbull.gif fixed_at f r h x) x) xqqter.gif);
a (REPEAT strip_tac);
a (lemma_tac qqtel.gifexist.gifgbull.gif (lambda.gif xbull.gif (epsilon.gif hbull.gif fixed_at f r h x) x) = gqqter.gif THEN1 prove_exist.gif_tac);
a (asm_rewrite_tac[]);
a (wf_induction_tac (asm_rule qqtel.gifwell_founded rqqter.gif) qqtel.gifxqqter.gif);
a (rewrite_tac[get_spec qqtel.giffixed_atqqter.gif] THEN strip_tac);
(* *** Goal "1" *** *)
a (asm_fc_tac [list_forall.gif_elim [qqtel.giffqqter.gif, qqtel.gifrqqter.gif] fixed_at_lemma3]);
a (asm_fc_tac []);
a (list_spec_nth_asm_tac 1 [qqtel.giftqqter.gif, qqtel.gifgqqter.gif]);
a (asm_fc_tac []);
(* *** Goal "2" *** *)
a (fc_tac [list_forall.gif_elim [qqtel.giffqqter.gif, qqtel.gifrqqter.gif] fixed_at_lemma6]);
a (list_spec_nth_asm_tac 1 [qqtel.giffqqter.gif, qqtel.giftqqter.gif]);
a (fc_tac [get_spec qqtel.giffixed_atqqter.gif]);
a (lemma_tac qqtel.gifg t = g' tqqter.gif THEN1 (GET_NTH_ASM_T 6 (rewrite_thm_tac o eq_sym_rule)));
(* *** Goal "2.1" *** *)
a (epsilon.gif_tac qqtel.gifepsilon.gif hbull.gif fixed_at f r h tqqter.gif);
(* *** Goal "2.1.1" *** *)
a (exist.gif_tac qqtel.gifg'qqter.gif THEN asm_rewrite_tac[]);
(* *** Goal "2.1.2" *** *)
a (fc_tac [get_spec qqtel.giffixed_atqqter.gif]);
a (fc_tac [fixed_at_lemma5]);
a (list_spec_nth_asm_tac 1 [qqtel.giffqqter.gif, qqtel.gifepsilon.gif hbull.gif fixed_at f r h tqqter.gif, qqtel.giftqqter.gif, qqtel.gifg'qqter.gif]);
(* *** Goal "2.2" *** *)
a (fc_tac [get_spec qqtel.gif$respectsqqter.gif]);
a (list_spec_nth_asm_tac 1 [qqtel.giftqqter.gif, qqtel.gifgqqter.gif, qqtel.gifg'qqter.gif]);
(* *** Goal "2.2.1" *** *)
a (asm_fc_tac []);
a (asm_fc_tac [fixed_at_lemma4]);
a (list_spec_nth_asm_tac 1 [qqtel.giffqqter.gif, qqtel.gifg'qqter.gif, qqtel.giftqqter.gif, qqtel.gifyqqter.gif]);
a (asm_fc_tac [fixed_at_lemma5]);
a (REPEAT (asm_fc_tac[]));
(* *** Goal "2.2.2" *** *)
a (asm_rewrite_tac[]);
val fixed_lemma1 = save_pop_thm "fixed_lemma1";


xl-sml
set_goal ([],qqtel.gifforall.giff rbull.gif well_founded r and.gif f respects r ruarr.gif exist.gifgbull.gif f g = gqqter.gif);
a (REPEAT strip_tac);
a (exist.gif_tac qqtel.giflambda.gifxbull.gif (epsilon.gifhbull.gif fixed_at f r h x) xqqter.gif
fttabTHEN rewrite_tac [ext_thm]
fttabTHEN REPEAT strip_tac);
a (all_fc_tac [list_forall.gif_elim [qqtel.giffqqter.gif, qqtel.gifrqqter.gif] fixed_lemma1]);
a (spec_nth_asm_tac 1 qqtel.gifxqqter.gif);
a (all_fc_tac [get_spec qqtel.giffixed_atqqter.gif]);
a (asm_rewrite_tac[]);
val fixp_thm1 = save_pop_thm "fixp_thm1";


xl-sml
set_goal ([],qqtel.gifexist.giffixbull.gif forall.giff rbull.giffttabwell_founded r and.gif f respects r
fttabruarr.gif f (fix f) = (fix f)qqter.gif);
a (exist.gif_tac qqtel.giflambda.giffbull.gif epsilon.gifgbull.gif f g = gqqter.gif);
a (REPEAT strip_tac THEN rewrite_tac[]);
a (all_epsilon.gif_tac);
a (all_fc_tac [fixp_thm1]);
a (exist.gif_tac qqtel.gifgqqter.gif THEN strip_tac);
val _ = xl_set_cs_exist.gif_thm (pop_thm ());


xl-holconst
fix: (('a rarr.gif 'b) rarr.gif ('a rarr.gif 'b)) rarr.gif 'a rarr.gif 'b
forall.giff rbull.gif well_founded r and.gif f respects r ruarr.gif f (fix f) = fix f
Respect Theorems
Some theorems which help to prove that functions respect relations.
Introduction

My first applications of the recursion theorem are in set theory, typically involving recursion which respects membership or its transitive closure.

The Inverse of a Relation
The following function takes a relation and a function and returns a function which maps each element in the domain of the relation to the relation which holds between a predecessor of that element and its value under the function. i.e. it maps the function over the predecessors of the element and returns the result as a relation. It may therefore be used to rephrase primitive recursive definitions, and so the result which follows may be used to establish the existence of functions defined by primitive recursion.
xl-holconst
relmap : ('a rarr.gif 'a rarr.gif BOOL) rarr.gif ('a rarr.gif 'b) rarr.gif ('a rarr.gif ('a rarr.gif 'b rarr.gif BOOL))
forall.gifr fbull.gif relmap r f = lambda.gifx y zbull.gif r y x and.gif z = f y

xl-sml
set_goal ([],qqtel.gifforall.gifr gbull.gif (lambda.giffbull.gif g o (relmap r f)) respects rqqter.gif);
a (rewrite_tac[get_spec qqtel.gif$respectsqqter.gif, get_spec qqtel.gifrelmapqqter.gif, get_spec qqtel.gif$oqqter.gif]
fttabTHEN REPEAT strip_tac);
a (lemma_tac qqtel.gif(lambda.gif y zbull.gif r y x and.gif z = g' y) = (lambda.gif y zbull.gif r y x and.gif z = h y)qqter.gif
fttabTHEN1 rewrite_tac[ext_thm]);
(* *** Goal "1" *** *)
a (REPEAT strip_tac);
(* *** Goal "1.2" *** *)
a (asm_fc_tac[tc_incr_thm]);
a (asm_fc_tac[]);
a (asm_rewrite_tac []);
(* *** Goal "1.2" *** *)
a (asm_fc_tac[tc_incr_thm]);
a (asm_fc_tac[]);
a (asm_rewrite_tac []);
(* *** Goal "2" *** *)
a (asm_rewrite_tac []);
val relmap_respect_thm = save_pop_thm "relmap_respect_thm";

Proof Context
In this section I will create a decent proof context for recursive definitions, eventually.
Proof Context

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


up quick index © RBJ

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

V