# HG changeset patch # User hoelzl # Date 1430755441 -7200 # Node ID 6a61bb577d5b16e134dca58dd9cd2f85b895fc86 # Parent 423273355b55948397eca64d075d098663bd5427 add rules for least/greatest fixed point calculus diff -r 423273355b55 -r 6a61bb577d5b src/HOL/Inductive.thy --- a/src/HOL/Inductive.thy Mon May 04 17:35:31 2015 +0200 +++ b/src/HOL/Inductive.thy Mon May 04 18:04:01 2015 +0200 @@ -248,6 +248,103 @@ lemma gfp_mono: "(!!Z. f Z \ g Z) ==> gfp f \ gfp g" by (rule gfp_upperbound [THEN gfp_least], blast intro: order_trans) +subsection {* Rules for fixed point calculus *} + + +lemma lfp_rolling: + assumes "mono g" "mono f" + shows "g (lfp (\x. f (g x))) = lfp (\x. g (f x))" +proof (rule antisym) + have *: "mono (\x. f (g x))" + using assms by (auto simp: mono_def) + + show "lfp (\x. g (f x)) \ g (lfp (\x. f (g x)))" + by (rule lfp_lowerbound) (simp add: lfp_unfold[OF *, symmetric]) + + show "g (lfp (\x. f (g x))) \ lfp (\x. g (f x))" + proof (rule lfp_greatest) + fix u assume "g (f u) \ u" + moreover then have "g (lfp (\x. f (g x))) \ g (f u)" + by (intro assms[THEN monoD] lfp_lowerbound) + ultimately show "g (lfp (\x. f (g x))) \ u" + by auto + qed +qed + +lemma lfp_square: + assumes "mono f" shows "lfp f = lfp (\x. f (f x))" +proof (rule antisym) + show "lfp f \ lfp (\x. f (f x))" + by (intro lfp_lowerbound) (simp add: assms lfp_rolling) + show "lfp (\x. f (f x)) \ lfp f" + by (intro lfp_lowerbound) (simp add: lfp_unfold[OF assms, symmetric]) +qed + +lemma lfp_lfp: + assumes f: "\x y w z. x \ y \ w \ z \ f x w \ f y z" + shows "lfp (\x. lfp (f x)) = lfp (\x. f x x)" +proof (rule antisym) + have *: "mono (\x. f x x)" + by (blast intro: monoI f) + show "lfp (\x. lfp (f x)) \ lfp (\x. f x x)" + by (intro lfp_lowerbound) (simp add: lfp_unfold[OF *, symmetric]) + show "lfp (\x. lfp (f x)) \ lfp (\x. f x x)" (is "?F \ _") + proof (intro lfp_lowerbound) + have *: "?F = lfp (f ?F)" + by (rule lfp_unfold) (blast intro: monoI lfp_mono f) + also have "\ = f ?F (lfp (f ?F))" + by (rule lfp_unfold) (blast intro: monoI lfp_mono f) + finally show "f ?F ?F \ ?F" + by (simp add: *[symmetric]) + qed +qed + +lemma gfp_rolling: + assumes "mono g" "mono f" + shows "g (gfp (\x. f (g x))) = gfp (\x. g (f x))" +proof (rule antisym) + have *: "mono (\x. f (g x))" + using assms by (auto simp: mono_def) + show "g (gfp (\x. f (g x))) \ gfp (\x. g (f x))" + by (rule gfp_upperbound) (simp add: gfp_unfold[OF *, symmetric]) + + show "gfp (\x. g (f x)) \ g (gfp (\x. f (g x)))" + proof (rule gfp_least) + fix u assume "u \ g (f u)" + moreover then have "g (f u) \ g (gfp (\x. f (g x)))" + by (intro assms[THEN monoD] gfp_upperbound) + ultimately show "u \ g (gfp (\x. f (g x)))" + by auto + qed +qed + +lemma gfp_square: + assumes "mono f" shows "gfp f = gfp (\x. f (f x))" +proof (rule antisym) + show "gfp (\x. f (f x)) \ gfp f" + by (intro gfp_upperbound) (simp add: assms gfp_rolling) + show "gfp f \ gfp (\x. f (f x))" + by (intro gfp_upperbound) (simp add: gfp_unfold[OF assms, symmetric]) +qed + +lemma gfp_gfp: + assumes f: "\x y w z. x \ y \ w \ z \ f x w \ f y z" + shows "gfp (\x. gfp (f x)) = gfp (\x. f x x)" +proof (rule antisym) + have *: "mono (\x. f x x)" + by (blast intro: monoI f) + show "gfp (\x. f x x) \ gfp (\x. gfp (f x))" + by (intro gfp_upperbound) (simp add: gfp_unfold[OF *, symmetric]) + show "gfp (\x. gfp (f x)) \ gfp (\x. f x x)" (is "?F \ _") + proof (intro gfp_upperbound) + have *: "?F = gfp (f ?F)" + by (rule gfp_unfold) (blast intro: monoI gfp_mono f) + also have "\ = f ?F (gfp (f ?F))" + by (rule gfp_unfold) (blast intro: monoI gfp_mono f) + finally show "?F \ f ?F ?F" + by (simp add: *[symmetric]) + qed +qed subsection {* Inductive predicates and sets *}