# HG changeset patch # User desharna # Date 1671180922 -3600 # Node ID f8826fc8c4191cafa8cc8100596bddba7bafc62e # Parent 878ed0fcb5105309ff72f8cf6234732683397749 added lemmas IMGU_subst_domain_subset and IMGU_range_vars_subset diff -r 878ed0fcb510 -r f8826fc8c419 src/HOL/ex/Unification.thy --- a/src/HOL/ex/Unification.thy Thu Dec 15 13:18:25 2022 +0100 +++ b/src/HOL/ex/Unification.thy Fri Dec 16 09:55:22 2022 +0100 @@ -59,6 +59,14 @@ lemma occs_vars_subset: "M \ N \ vars_of M \ vars_of N" by (induct N) auto +lemma size_less_size_if_occs: "t \ u \ size t < size u" +proof (induction u arbitrary: t) + case (Comb u1 u2) + thus ?case by fastforce +qed simp_all + +corollary neq_if_occs: "t \ u \ t \ u" + using size_less_size_if_occs by auto subsection \Substitutions\ @@ -151,7 +159,17 @@ subsection \Unifiers and Most General Unifiers\ definition Unifier :: "'a subst \ 'a trm \ 'a trm \ bool" -where "Unifier \ t u \ (t \ \ = u \ \)" + where "Unifier \ t u \ (t \ \ = u \ \)" + +lemma not_occs_if_Unifier: + assumes "Unifier \ t u" + shows "\ (t \ u) \ \ (u \ t)" +proof - + from assms have "t \ \ = u \ \" + unfolding Unifier_def by simp + thus ?thesis + using neq_if_occs subst_mono by metis +qed definition MGU :: "'a subst \ 'a trm \ 'a trm \ bool" where "MGU \ t u \ @@ -719,4 +737,175 @@ "unify M N = Some \ \ IMGU \ M N" by (simp add: IMGU_iff_Idem_and_MGU unify_computes_MGU unify_gives_Idem) + +subsection \Unification is complete\ + +lemma unify_eq_Some_if_Unifier: + assumes "Unifier \ t u" + shows "\\. unify t u = Some \" + using assms +proof (induction t u rule: unify.induct) + case (1 c M N) + thus ?case + by (simp add: Unifier_def) +next + case (2 M N c) + thus ?case + by (simp add: Unifier_def) +next + case (3 c v) + thus ?case + by simp +next + case (4 M N v) + hence "\ (Var v \ M \ N)" + by (auto dest: not_occs_if_Unifier) + thus ?case + by simp +next + case (5 v M) + thus ?case + by (auto dest: not_occs_if_Unifier) +next + case (6 c d) + thus ?case + by (simp add: Unifier_def) +next + case (7 M N M' N') + from "7.prems" have "Unifier \ M M'" + by (simp add: Unifier_def) + with "7.IH"(1) obtain \ where "unify M M' = Some \" + by auto + moreover have "Unifier \ (N \ \) (N' \ \)" + by (smt (verit, ccfv_threshold) "7.prems" IMGU_def Unifier_def calculation subst.simps(3) + subst_comp subst_eq_def trm.inject(3) unify_computes_IMGU) + ultimately show ?case + using "7.IH"(2) by auto +qed + +definition subst_domain where + "subst_domain \ = {x. Var x \ \ \ Var x}" + +lemma subst_domain_subset_list_domain: "subst_domain \ \ fst ` set \" +proof (rule Set.subsetI) + fix x assume "x \ subst_domain \" + hence "Var x \ \ \ Var x" + by (simp add: subst_domain_def) + then show "x \ fst ` set \" + proof (induction \) + case Nil + thus ?case + by simp + next + case (Cons p \) + show ?case + proof (cases "x = fst p") + case True + thus ?thesis + by simp + next + case False + with Cons.IH Cons.prems show ?thesis + by (cases p) simp + qed + qed +qed + +lemma subst_apply_eq_Var: + assumes "s \ \ = Var x" + obtains y where "s = Var y" and "Var y \ \ = Var x" + using assms by (induct s) auto + +lemma mem_range_varsI: + assumes "Var x \ \ = Var y" and "x \ y" + shows "y \ range_vars \" + using assms unfolding range_vars_def + by (metis (mono_tags, lifting) UnionI mem_Collect_eq trm.inject(1) vars_iff_occseq) + +lemma IMGU_subst_domain_subset: + assumes "IMGU \ t u" + shows "subst_domain \ \ vars_of t \ vars_of u" +proof (rule Set.subsetI) + from assms have "Unifier \ t u" + by (simp add: IMGU_def) + then obtain \ where "unify t u = Some \" + using unify_eq_Some_if_Unifier by metis + hence "Unifier \ t u" + using MGU_def unify_computes_MGU by blast + with assms have "\ \ \ \ \" + by (simp add: IMGU_def) + + fix x assume "x \ subst_domain \" + hence "Var x \ \ \ Var x" + by (simp add: subst_domain_def) + + show "x \ vars_of t \ vars_of u" + proof (cases "x \ subst_domain \") + case True + hence "x \ fst ` set \" + using subst_domain_subset_list_domain by fast + thus ?thesis + using unify_gives_minimal_domain[OF \unify t u = Some \\] by auto + next + case False + hence "Var x \ \ = Var x" + by (simp add: subst_domain_def) + hence "Var x \ \ \ \ = Var x" + using \\ \ \ \ \\ + by (metis subst_comp subst_eq_dest) + then show ?thesis + apply (rule subst_apply_eq_Var) + using \Var x \ \ \ Var x\ + using unify_gives_minimal_range[OF \unify t u = Some \\] + using mem_range_varsI + by force + qed +qed + +lemma IMGU_range_vars_subset: + assumes "IMGU \ t u" + shows "range_vars \ \ vars_of t \ vars_of u" +proof (rule Set.subsetI) + from assms have "Unifier \ t u" + by (simp add: IMGU_def) + then obtain \ where "unify t u = Some \" + using unify_eq_Some_if_Unifier by metis + hence "Unifier \ t u" + using MGU_def unify_computes_MGU by blast + with assms have "\ \ \ \ \" + by (simp add: IMGU_def) + + have ball_subst_dom: "\x \ subst_domain \. vars_of (Var x \ \) \ vars_of t \ vars_of u" + using unify_gives_minimal_range[OF \unify t u = Some \\] + using range_vars_def subst_domain_def by fastforce + + fix x assume "x \ range_vars \" + then obtain y where "x \ vars_of (Var y \ \)" and "Var y \ \ \ Var y" + by (auto simp: range_vars_def) + + have vars_of_y_\: "vars_of (Var y \ \) \ vars_of t \ vars_of u" + using ball_subst_dom + by (metis (mono_tags, lifting) IMGU_subst_domain_subset \Var y \ \ \ Var y\ assms empty_iff + insert_iff mem_Collect_eq subset_eq subst_domain_def vars_of.simps(1)) + + show "x \ vars_of t \ vars_of u" + proof (rule ccontr) + assume "x \ vars_of t \ vars_of u" + hence "x \ vars_of (Var y \ \)" + using vars_of_y_\ by blast + moreover have "x \ vars_of (Var y \ \ \ \)" + proof - + have "Var x \ \ = Var x" + using \x \ vars_of t \ vars_of u\ + using IMGU_subst_domain_subset \unify t u = Some \\ subst_domain_def unify_computes_IMGU + by fastforce + thus ?thesis + by (metis \x \ vars_of (Var y \ \)\ subst_mono vars_iff_occseq) + qed + ultimately show False + using \\ \ \ \ \\ + by (metis subst_comp subst_eq_dest) + qed +qed + end