diff -r bd4794d6e5fb -r 66a9aa769d63 src/HOL/ex/Unification.thy --- a/src/HOL/ex/Unification.thy Wed Jun 29 14:17:12 2022 +0200 +++ b/src/HOL/ex/Unification.thy Wed Jun 29 15:36:19 2022 +0200 @@ -142,6 +142,8 @@ lemma var_same[simp]: "[(v, t)] \ [] \ t = Var v" by (metis assoc.simps(2) subst.simps(1) subst_eq_def var_self) +lemma vars_of_subst_conv_Union: "vars_of (t \ \) = \(vars_of ` (\x. Var x \ \) ` vars_of t)" + by (induction t) simp_all subsection \Unifiers and Most General Unifiers\ @@ -525,6 +527,119 @@ qed (auto intro!: Var_Idem split: option.splits if_splits) +subsection \Unification Returns Substitution With Minimal Range \ + +definition range_vars where + "range_vars \ = \ {vars_of (Var x \ \) |x. Var x \ \ \ Var x}" + +lemma vars_of_subst_subset: "vars_of (N \ \) \ vars_of N \ range_vars \" +proof (rule subsetI) + fix x assume "x \ vars_of (N \ \)" + thus "x \ vars_of N \ range_vars \" + proof (induction N) + case (Var y) + then show ?case + unfolding range_vars_def vars_of.simps + by force + next + case (Const y) + then show ?case by simp + next + case (Comb N1 N2) + then show ?case + by auto + qed +qed + +lemma range_vars_comp_subset: "range_vars (\\<^sub>1 \ \\<^sub>2) \ range_vars \\<^sub>1 \ range_vars \\<^sub>2" +proof (rule subsetI) + fix x assume "x \ range_vars (\\<^sub>1 \ \\<^sub>2)" + then obtain x' where + x'_\\<^sub>1_\\<^sub>2: "Var x' \ \\<^sub>1 \ \\<^sub>2 \ Var x'" and x_in: "x \ vars_of (Var x' \ \\<^sub>1 \ \\<^sub>2)" + unfolding range_vars_def by auto + + show "x \ range_vars \\<^sub>1 \ range_vars \\<^sub>2" + proof (cases "Var x' \ \\<^sub>1 = Var x'") + case True + with x'_\\<^sub>1_\\<^sub>2 x_in show ?thesis + unfolding range_vars_def by auto + next + case x'_\\<^sub>1_neq: False + show ?thesis + proof (cases "Var x' \ \\<^sub>1 \ \\<^sub>2 = Var x' \ \\<^sub>1") + case True + with x'_\\<^sub>1_\\<^sub>2 x_in x'_\\<^sub>1_neq show ?thesis + unfolding range_vars_def by auto + next + case False + with x_in obtain y where "y \ vars_of (Var x' \ \\<^sub>1)" and "x \ vars_of (Var y \ \\<^sub>2)" + by (smt (verit, best) UN_iff image_iff vars_of_subst_conv_Union) + with x'_\\<^sub>1_neq show ?thesis + unfolding range_vars_def by force + qed + qed +qed + +theorem unify_gives_minimal_range: + "unify M N = Some \ \ range_vars \ \ vars_of M \ vars_of N" +proof (induct M N arbitrary: \ rule: unify.induct) + case (1 c M N) + thus ?case by simp +next + case (2 M N c) + thus ?case by simp +next + case (3 c v) + hence "\ = [(v, Const c)]" + by simp + thus ?case + by (simp add: range_vars_def) +next + case (4 M N v) + hence "\ = [(v, M \ N)]" + by (metis option.discI option.sel unify.simps(4)) + thus ?case + by (auto simp: range_vars_def) +next + case (5 v M) + hence "\ = [(v, M)]" + by (metis option.discI option.inject unify.simps(5)) + thus ?case + by (auto simp: range_vars_def) +next + case (6 c d) + hence "\ = []" + by (metis option.distinct(1) option.sel unify.simps(6)) + thus ?case + by (simp add: range_vars_def) +next + case (7 M N M' N') + from "7.prems" obtain \\<^sub>1 \\<^sub>2 where + "unify M M' = Some \\<^sub>1" and "unify (N \ \\<^sub>1) (N' \ \\<^sub>1) = Some \\<^sub>2" and "\ = \\<^sub>1 \ \\<^sub>2" + apply simp + by (metis (no_types, lifting) option.case_eq_if option.collapse option.discI option.sel) + + from "7.hyps"(1) have range_\\<^sub>1: "range_vars \\<^sub>1 \ vars_of M \ vars_of M'" + using \unify M M' = Some \\<^sub>1\ by simp + + from "7.hyps"(2) have "range_vars \\<^sub>2 \ vars_of (N \ \\<^sub>1) \ vars_of (N' \ \\<^sub>1)" + using \unify M M' = Some \\<^sub>1\ \unify (N \ \\<^sub>1) (N' \ \\<^sub>1) = Some \\<^sub>2\ by simp + hence range_\\<^sub>2: "range_vars \\<^sub>2 \ vars_of N \ vars_of N' \ range_vars \\<^sub>1" + using vars_of_subst_subset[of _ \\<^sub>1] by auto + + have "range_vars \ = range_vars (\\<^sub>1 \ \\<^sub>2)" + unfolding \\ = \\<^sub>1 \ \\<^sub>2\ by simp + also have "... \ range_vars \\<^sub>1 \ range_vars \\<^sub>2" + by (rule range_vars_comp_subset) + also have "... \ range_vars \\<^sub>1 \ vars_of N \ vars_of N'" + using range_\\<^sub>2 by auto + also have "... \ vars_of M \ vars_of M' \ vars_of N \ vars_of N'" + using range_\\<^sub>1 by auto + finally show ?case + by auto +qed + + subsection \Idempotent Most General Unifier\ definition IMGU :: "'a subst \ 'a trm \ 'a trm \ bool" where