Theory Wellfounded_Recursion
subsection ‹Well-Founded Recursion›
theory Wellfounded_Recursion
imports
Binary_Relations_Transitive_Closure
Wellfounded_Transitive_Recursion
begin
paragraph ‹Summary›
text ‹We use @{term wft_rec} to define well-founded recursion on non-transitive, well-founded
relations. The fact that the transitive closure of a well-founded relation is itself well-founded
can be used to remove the transitivity assumption of @{thm wft_rec_eq_wf_rec_stepI}.›
lemma wellfounded_trans_closure_if_wellfounded:
assumes "wellfounded R"
shows "wellfounded (trans_closure R)"
proof (rule ccontr)
assume "¬(wellfounded (trans_closure R))"
then obtain P X where "P X" and no_minimal: "⋀Y. P Y ⟹ (∃y. trans_closure R y Y ∧ P y)"
unfolding wellfounded_eq_wellfounded_on wellfounded_on_pred_def by auto
from assms have "¬(P Y) ∧ (∀y. trans_closure R y Y ⟶ ¬(P y))" for Y
proof (induction Y rule: wellfounded_induct)
case (step Y)
show ?case
proof (rule ccontr)
assume "¬(¬(P Y) ∧ (∀y. trans_closure R y Y ⟶ ¬(P y)))"
then consider "P Y" | y where "trans_closure R y Y" "P y" by blast
then show "False"
proof cases
case 1
then obtain y where "trans_closure R y Y" "P y" using no_minimal by blast
then show "False" using step.IH trans_closure_cases by force
next
case 2
then show "False" using step.IH trans_closure_cases by force
qed
qed
qed
then show "False" using ‹P X› by blast
qed
consts wf_rec :: "'a ⇒ 'b ⇒ 'c"
definition "wf_rec_rel R step = wft_rec (trans_closure R) (λf. wf_rec_step R step (λ_. f))"
adhoc_overloading wf_rec wf_rec_rel
theorem wf_rec_eq_wf_rec_stepI:
assumes "wellfounded R"
shows "wf_rec R step X = wf_rec_step R step (λ_. wf_rec R step) X"
proof -
have fun_rel_restrict_eq:
"fun_rel_restrict (fun_rel_restrict f (trans_closure R) X) R X x = fun_rel_restrict f R X x"
for f x by (cases "R x X") (auto dest: trans_closure_if_rel)
have "wf_rec R step X = wf_rec_step R step (fun_rel_restrict (wf_rec R step) (trans_closure R)) X"
using wellfounded_trans_closure_if_wellfounded[OF assms] transitive_trans_closure[of R]
wft_rec_eq_wf_rec_stepI[where ?step="λf. wf_rec_step R step (λ_. f)"]
by (simp add: wf_rec_step_eq wf_rec_rel_def)
then show ?thesis unfolding wf_rec_step_eq fun_rel_restrict_eq by simp
qed
consts wf_rec_on :: "'a ⇒ 'b ⇒ 'c ⇒ 'd"
definition wf_rec_on_pred :: "('a ⇒ bool) ⇒ ('a ⇒ 'a ⇒ bool) ⇒ (('a ⇒ 'b) ⇒ 'a ⇒ 'b) ⇒ 'a ⇒ 'b" where
"wf_rec_on_pred P R ≡ wf_rec R↑⇘P⇙"
adhoc_overloading wf_rec_on wf_rec_on_pred
lemma wf_rec_on_eq_wf_rec_restrict: "wf_rec_on P R = wf_rec R↑⇘P⇙"
unfolding wf_rec_on_pred_def by simp
theorem wf_rec_on_eq_wf_rec_step_restrictI:
assumes "wellfounded_on P R"
shows "wf_rec_on P R step X = wf_rec_step R↑⇘P⇙ step (λ_. wf_rec_on P R step) X"
proof -
from assms have "wellfounded R↑⇘P⇙" using wellfounded_rel_restrict_if_wellfounded_on by blast
with wf_rec_eq_wf_rec_stepI show ?thesis unfolding wf_rec_on_eq_wf_rec_restrict by fastforce
qed
lemma wf_rec_on_eq_app_fun_restrict_fun_rel_restrictI:
fixes step
assumes wf: "wellfounded_on P R"
and "P x"
defines "f ≡ wf_rec_on P R step"
shows "f x = step (fun_restrict (fun_rel_restrict f R x) P) x"
proof -
from wf have "f x = step (fun_rel_restrict f R↑⇘P⇙ x) x"
unfolding f_def by (simp only: wf_rec_step_eq wf_rec_on_eq_wf_rec_step_restrictI)
moreover have "fun_rel_restrict f R↑⇘P⇙ x = fun_restrict (fun_rel_restrict f R x) P"
using ‹P x› fun_rel_restrict_rel_restrict_eq_fun_restrict_fun_rel_restrictI by simp
ultimately show ?thesis by simp
qed
end