Up to index of Isabelle/HOL
theory FunDef(* Title: HOL/FunDef.thy Author: Alexander Krauss, TU Muenchen *) header {* Function Definitions and Termination Proofs *} theory FunDef imports Wellfounded uses "Tools/prop_logic.ML" "Tools/sat_solver.ML" ("Tools/function_package/fundef_lib.ML") ("Tools/function_package/fundef_common.ML") ("Tools/function_package/inductive_wrap.ML") ("Tools/function_package/context_tree.ML") ("Tools/function_package/fundef_core.ML") ("Tools/function_package/sum_tree.ML") ("Tools/function_package/mutual.ML") ("Tools/function_package/pattern_split.ML") ("Tools/function_package/fundef_package.ML") ("Tools/function_package/auto_term.ML") ("Tools/function_package/measure_functions.ML") ("Tools/function_package/lexicographic_order.ML") ("Tools/function_package/fundef_datatype.ML") ("Tools/function_package/induction_scheme.ML") ("Tools/function_package/termination.ML") ("Tools/function_package/decompose.ML") ("Tools/function_package/descent.ML") ("Tools/function_package/scnp_solve.ML") ("Tools/function_package/scnp_reconstruct.ML") begin subsection {* Definitions with default value. *} definition THE_default :: "'a => ('a => bool) => 'a" where "THE_default d P = (if (∃!x. P x) then (THE x. P x) else d)" lemma THE_defaultI': "∃!x. P x ==> P (THE_default d P)" by (simp add: theI' THE_default_def) lemma THE_default1_equality: "[|∃!x. P x; P a|] ==> THE_default d P = a" by (simp add: the1_equality THE_default_def) lemma THE_default_none: "¬(∃!x. P x) ==> THE_default d P = d" by (simp add:THE_default_def) lemma fundef_ex1_existence: assumes f_def: "f == (λx::'a. THE_default (d x) (λy. G x y))" assumes ex1: "∃!y. G x y" shows "G x (f x)" apply (simp only: f_def) apply (rule THE_defaultI') apply (rule ex1) done lemma fundef_ex1_uniqueness: assumes f_def: "f == (λx::'a. THE_default (d x) (λy. G x y))" assumes ex1: "∃!y. G x y" assumes elm: "G x (h x)" shows "h x = f x" apply (simp only: f_def) apply (rule THE_default1_equality [symmetric]) apply (rule ex1) apply (rule elm) done lemma fundef_ex1_iff: assumes f_def: "f == (λx::'a. THE_default (d x) (λy. G x y))" assumes ex1: "∃!y. G x y" shows "(G x y) = (f x = y)" apply (auto simp:ex1 f_def THE_default1_equality) apply (rule THE_defaultI') apply (rule ex1) done lemma fundef_default_value: assumes f_def: "f == (λx::'a. THE_default (d x) (λy. G x y))" assumes graph: "!!x y. G x y ==> D x" assumes "¬ D x" shows "f x = d x" proof - have "¬(∃y. G x y)" proof assume "∃y. G x y" hence "D x" using graph .. with `¬ D x` show False .. qed hence "¬(∃!y. G x y)" by blast thus ?thesis unfolding f_def by (rule THE_default_none) qed definition in_rel_def[simp]: "in_rel R x y == (x, y) ∈ R" lemma wf_in_rel: "wf R ==> wfP (in_rel R)" by (simp add: wfP_def) use "Tools/function_package/fundef_lib.ML" use "Tools/function_package/fundef_common.ML" use "Tools/function_package/inductive_wrap.ML" use "Tools/function_package/context_tree.ML" use "Tools/function_package/fundef_core.ML" use "Tools/function_package/sum_tree.ML" use "Tools/function_package/mutual.ML" use "Tools/function_package/pattern_split.ML" use "Tools/function_package/auto_term.ML" use "Tools/function_package/fundef_package.ML" use "Tools/function_package/fundef_datatype.ML" use "Tools/function_package/induction_scheme.ML" setup {* FundefPackage.setup #> FundefDatatype.setup #> InductionScheme.setup *} subsection {* Measure Functions *} inductive is_measure :: "('a => nat) => bool" where is_measure_trivial: "is_measure f" use "Tools/function_package/measure_functions.ML" setup MeasureFunctions.setup lemma measure_size[measure_function]: "is_measure size" by (rule is_measure_trivial) lemma measure_fst[measure_function]: "is_measure f ==> is_measure (λp. f (fst p))" by (rule is_measure_trivial) lemma measure_snd[measure_function]: "is_measure f ==> is_measure (λp. f (snd p))" by (rule is_measure_trivial) use "Tools/function_package/lexicographic_order.ML" setup LexicographicOrder.setup subsection {* Congruence Rules *} lemma let_cong [fundef_cong]: "M = N ==> (!!x. x = N ==> f x = g x) ==> Let M f = Let N g" unfolding Let_def by blast lemmas [fundef_cong] = if_cong image_cong INT_cong UN_cong bex_cong ball_cong imp_cong lemma split_cong [fundef_cong]: "(!!x y. (x, y) = q ==> f x y = g x y) ==> p = q ==> split f p = split g q" by (auto simp: split_def) lemma comp_cong [fundef_cong]: "f (g x) = f' (g' x') ==> (f o g) x = (f' o g') x'" unfolding o_apply . subsection {* Simp rules for termination proofs *} lemma termination_basic_simps[termination_simp]: "x < (y::nat) ==> x < y + z" "x < z ==> x < y + z" "x ≤ y ==> x ≤ y + (z::nat)" "x ≤ z ==> x ≤ y + (z::nat)" "x < y ==> x ≤ (y::nat)" by arith+ declare le_imp_less_Suc[termination_simp] lemma prod_size_simp[termination_simp]: "prod_size f g p = f (fst p) + g (snd p) + Suc 0" by (induct p) auto subsection {* Decomposition *} lemma less_by_empty: "A = {} ==> A ⊆ B" and union_comp_emptyL: "[| A O C = {}; B O C = {} |] ==> (A ∪ B) O C = {}" and union_comp_emptyR: "[| A O B = {}; A O C = {} |] ==> A O (B ∪ C) = {}" and wf_no_loop: "R O R = {} ==> wf R" by (auto simp add: wf_comp_self[of R]) subsection {* Reduction Pairs *} definition "reduction_pair P = (wf (fst P) ∧ snd P O fst P ⊆ fst P)" lemma reduction_pairI[intro]: "wf R ==> S O R ⊆ R ==> reduction_pair (R, S)" unfolding reduction_pair_def by auto lemma reduction_pair_lemma: assumes rp: "reduction_pair P" assumes "R ⊆ fst P" assumes "S ⊆ snd P" assumes "wf S" shows "wf (R ∪ S)" proof - from rp `S ⊆ snd P` have "wf (fst P)" "S O fst P ⊆ fst P" unfolding reduction_pair_def by auto with `wf S` have "wf (fst P ∪ S)" by (auto intro: wf_union_compatible) moreover from `R ⊆ fst P` have "R ∪ S ⊆ fst P ∪ S" by auto ultimately show ?thesis by (rule wf_subset) qed definition "rp_inv_image = (λ(R,S) f. (inv_image R f, inv_image S f))" lemma rp_inv_image_rp: "reduction_pair P ==> reduction_pair (rp_inv_image P f)" unfolding reduction_pair_def rp_inv_image_def split_def by force subsection {* Concrete orders for SCNP termination proofs *} definition "pair_less = less_than <*lex*> less_than" definition [code del]: "pair_leq = pair_less^=" definition "max_strict = max_ext pair_less" definition [code del]: "max_weak = max_ext pair_leq ∪ {({}, {})}" definition [code del]: "min_strict = min_ext pair_less" definition [code del]: "min_weak = min_ext pair_leq ∪ {({}, {})}" lemma wf_pair_less[simp]: "wf pair_less" by (auto simp: pair_less_def) text {* Introduction rules for @{text pair_less}/@{text pair_leq} *} lemma pair_leqI1: "a < b ==> ((a, s), (b, t)) ∈ pair_leq" and pair_leqI2: "a ≤ b ==> s ≤ t ==> ((a, s), (b, t)) ∈ pair_leq" and pair_lessI1: "a < b ==> ((a, s), (b, t)) ∈ pair_less" and pair_lessI2: "a ≤ b ==> s < t ==> ((a, s), (b, t)) ∈ pair_less" unfolding pair_leq_def pair_less_def by auto text {* Introduction rules for max *} lemma smax_emptyI: "finite Y ==> Y ≠ {} ==> ({}, Y) ∈ max_strict" and smax_insertI: "[|y ∈ Y; (x, y) ∈ pair_less; (X, Y) ∈ max_strict|] ==> (insert x X, Y) ∈ max_strict" and wmax_emptyI: "finite X ==> ({}, X) ∈ max_weak" and wmax_insertI: "[|y ∈ YS; (x, y) ∈ pair_leq; (XS, YS) ∈ max_weak|] ==> (insert x XS, YS) ∈ max_weak" unfolding max_strict_def max_weak_def by (auto elim!: max_ext.cases) text {* Introduction rules for min *} lemma smin_emptyI: "X ≠ {} ==> (X, {}) ∈ min_strict" and smin_insertI: "[|x ∈ XS; (x, y) ∈ pair_less; (XS, YS) ∈ min_strict|] ==> (XS, insert y YS) ∈ min_strict" and wmin_emptyI: "(X, {}) ∈ min_weak" and wmin_insertI: "[|x ∈ XS; (x, y) ∈ pair_leq; (XS, YS) ∈ min_weak|] ==> (XS, insert y YS) ∈ min_weak" by (auto simp: min_strict_def min_weak_def min_ext_def) text {* Reduction Pairs *} lemma max_ext_compat: assumes "S O R ⊆ R" shows "(max_ext S ∪ {({},{})}) O max_ext R ⊆ max_ext R" using assms apply auto apply (elim max_ext.cases) apply rule apply auto[3] apply (drule_tac x=xa in meta_spec) apply simp apply (erule bexE) apply (drule_tac x=xb in meta_spec) by auto lemma max_rpair_set: "reduction_pair (max_strict, max_weak)" unfolding max_strict_def max_weak_def apply (intro reduction_pairI max_ext_wf) apply simp apply (rule max_ext_compat) by (auto simp: pair_less_def pair_leq_def) lemma min_ext_compat: assumes "S O R ⊆ R" shows "(min_ext S ∪ {({},{})}) O min_ext R ⊆ min_ext R" using assms apply (auto simp: min_ext_def) apply (drule_tac x=ya in bspec, assumption) apply (erule bexE) apply (drule_tac x=xc in bspec) apply assumption by auto lemma min_rpair_set: "reduction_pair (min_strict, min_weak)" unfolding min_strict_def min_weak_def apply (intro reduction_pairI min_ext_wf) apply simp apply (rule min_ext_compat) by (auto simp: pair_less_def pair_leq_def) subsection {* Tool setup *} use "Tools/function_package/termination.ML" use "Tools/function_package/decompose.ML" use "Tools/function_package/descent.ML" use "Tools/function_package/scnp_solve.ML" use "Tools/function_package/scnp_reconstruct.ML" setup {* ScnpReconstruct.setup *} ML_val -- "setup inactive" {* Context.theory_map (FundefCommon.set_termination_prover (ScnpReconstruct.decomp_scnp [ScnpSolve.MAX, ScnpSolve.MIN, ScnpSolve.MS])) *} end