theory Mgu = Main + Terms + Fresh + Equ + Substs: (* unification problems *) syntax "_equ_prob" :: "trm \ trm \ (trm\trm)" ("_ \? _" [81,81] 81) "_fresh_prob" :: "string \ trm \ (string\trm)" ("_ \? _" [81,81] 81) translations "t1 \? t2" \ "(t1,t2)" " a \? t" \ "(a,t)" (* all solutions for a unification problem *) types problem_type = "((trm\trm)list) \ ((string\trm)list)" unifier_type = "fresh_envs \ substs" consts U :: "problem_type \ (unifier_type set)" defs all_solutions_def : "U P \ {(nabla,s). (\ (t1,t2)\set (fst P). nabla \ subst s t1 \ subst s t2) \ (\ (a,t)\set (snd P). nabla \ a \ subst s t) }" (* set of variables in unification problems *) consts vars_fprobs :: "((string\trm) list) \ (string set)" vars_eprobs :: "((trm\trm)list) \ (string set)" vars_probs :: "problem_type \ nat" primrec "vars_fprobs [] = {}" "vars_fprobs (x#xs) = (vars_trm (snd x))\(vars_fprobs xs)" primrec "vars_eprobs [] = {}" "vars_eprobs (x#xs) = (vars_trm (snd x))\(vars_trm (fst x))\(vars_eprobs xs)" defs vars_probs_def: "vars_probs P \ card((vars_fprobs (snd P))\(vars_eprobs (fst P)))" (* most general unifier *) consts mgu :: "problem_type \ unifier_type \ bool" defs mgu_def: "mgu P unif \ \ (nabla,s1)\ U P. (\ s2. (nabla\(subst s2) (fst unif)) \ (nabla\subst (s2 \(snd unif)) \ subst s1))" (* idempotency of a unifier *) consts idem :: "unifier_type \ bool" defs idem_def: "idem unif \ (fst unif)\ subst ((snd unif)\(snd unif)) \ subst (snd unif)" (* application of a substitution to a problem *) consts apply_subst :: "substs \ problem_type \ problem_type" defs apply_subst_def: "apply_subst s P \ (map (\(t1,t2). (subst s t1 \? subst s t2)) (fst P), map (\(a,t). (a \? (subst s t)) ) (snd P))" (* equality reductions *) consts s_red :: "(problem_type \ substs \ problem_type) set" syntax "_s_red" :: "problem_type \ substs \ problem_type \ bool" ("_ \ _ \ _ " [80,80,80] 80) translations "P1 \sigma\ P2" \ "(P1,sigma,P2)\s_red" inductive s_red intros unit_sred[intro!,dest!]: "((Unit\?Unit)#xs,ys) \[]\ (xs,ys)" paar_sred[intro!,dest!]: "((Paar t1 t2\?Paar s1 s2)#xs,ys) \[]\ ((t1\?s1)#(t2\?s2)#xs,ys)" func_sred[intro!,dest!]: "((Func F t1\?Func F t2)#xs,ys) \[]\ ((t1\?t2)#xs,ys)" abst_aa_sred[intro!,dest!]: "((Abst a t1\?Abst a t2)#xs,ys) \[]\ ((t1\?t2)#xs,ys)" abst_ab_sred[intro!]: "a\b\ ((Abst a t1\?Abst b t2)#xs,ys) \[]\ ((t1\?swap [(a,b)] t2)#xs,(a\?t2)#ys)" atom_sred[intro!,dest!]: "((Atom a\?Atom a)#xs,ys) \[]\ (xs,ys)" susp_sred[intro!,dest!]: "((Susp pi1 X\?Susp pi2 X)#xs,ys) \[]\ (xs,(map (\a. a\? Susp [] X) (ds_list pi1 pi2))@ys)" var_1_sred[intro!]: "\(occurs X t)\((Susp pi X\?t)#xs,ys) \[(X,swap (rev pi) t)]\ apply_subst [(X,swap (rev pi) t)] (xs,ys)" var_2_sred[intro!]: "\(occurs X t)\((t\?Susp pi X)#xs,ys) \[(X,swap (rev pi) t)]\ apply_subst [(X,swap (rev pi) t)] (xs,ys)" (* freshness reductions *) consts c_red :: "(problem_type \ fresh_envs \ problem_type) set" syntax "_c_red" :: "problem_type \ fresh_envs \ problem_type \ bool" ("_ \ _ \ _ " [80,80,80] 80) translations "P1 \nabla\ P2" \ "(P1,nabla,P2)\c_red" inductive c_red intros unit_cred[intro!]: "([],(a \? Unit)#xs) \{}\ ([],xs)" paar_cred[intro!]: "([],(a \? Paar t1 t2)#xs) \{}\ ([],(a\?t1)#(a\?t2)#xs)" func_cred[intro!]: "([],(a \? Func F t)#xs) \{}\ ([],(a\?t)#xs)" abst_aa_cred[intro!]: "([],(a \? Abst a t)#xs) \{}\ ([],xs)" abst_ab_cred[intro!]: "a\b\([],(a \? Abst b t)#xs) \{}\ ([],(a\?t)#xs)" atom_cred[intro!]: "a\b\([],(a \? Atom b)#xs) \{}\ ([],xs)" susp_cred[intro!]: "([],(a \? Susp pi X)#xs) \{((swapas (rev pi) a),X)}\ ([],xs)" (* unification reduction sequence *) consts red_plus :: "(problem_type \ unifier_type \ problem_type) set" syntax red_plus :: "problem_type \ unifier_type \ problem_type \ bool" ("_ \ _ \ _ " [80,80,80] 80) translations "P1 \(nabla,s)\ P2" \ "(P1,(nabla,s),P2)\red_plus" inductive red_plus intros sred_single[intro!]: "\P1\s1\P2\\P1\({},s1)\P2" cred_single[intro!]: "\P1\nabla1\P2\\P1\(nabla1,[])\P2" sred_step[intro!]: "\P1\s1\P2;P2\(nabla2,s2)\P3\\P1\(nabla2,(s2\s1))\P3" cred_step[intro!]: "\P1\nabla1\P2;P2\(nabla2,[])\P3\\P1\(nabla2\nabla1,[])\P3" lemma mgu_idem: "\(nabla1,s1)\U P; \(nabla2,s2)\ U P. nabla2\(subst s2) nabla1 \ nabla2\subst(s2 \ s1)\subst s2 \\ mgu P (nabla1,s1)\idem (nabla1,s1)" apply(rule conjI) apply(simp only: mgu_def) apply(rule ballI) apply(simp) apply(drule_tac x="x" in bspec) apply(assumption) apply(force) apply(drule_tac x="(nabla1,s1)" in bspec) apply(assumption) apply(simp add: idem_def) done lemma problem_subst_comm: "((nabla,s2)\U (apply_subst s1 P)) = ((nabla,(s2\s1))\U P)" apply(simp add: all_solutions_def apply_subst_def) apply(auto) apply(drule_tac x="(a,b)" in bspec, assumption, simp add: subst_comp_expand)+ done lemma P1_to_P2_sred: "\(nabla1,s1)\U P1; P1 \s2\ P2 \\((nabla1,s1)\U P2) \ (nabla1\subst (s1\s2)\subst s1)" apply(ind_cases "P1 \s2\ P2") apply(simp_all) --Unit apply(force intro!: equ_refl simp add: all_solutions_def ext_subst_def subst_equ_def subst_susp) --Paar apply(simp add: all_solutions_def ext_subst_def subst_equ_def subst_susp) apply(force intro!: equ_refl dest!: equ_paar_elim) --Func apply(simp add: all_solutions_def ext_subst_def subst_equ_def subst_susp) apply(force intro!: equ_refl dest!: equ_func_elim) --Abst.aa apply(simp add: all_solutions_def ext_subst_def subst_equ_def subst_susp) apply(force intro!: equ_refl dest!: equ_abst_aa_elim) --Abst.ab apply(simp add: all_solutions_def ext_subst_def subst_equ_def subst_susp) apply(force intro!: equ_refl dest!: equ_abst_ab_elim simp add: subst_swap_comm) --Atom apply(simp add: all_solutions_def ext_subst_def subst_equ_def subst_susp) apply(force intro!: equ_refl) --Susp apply(rule conjI) apply(auto) apply(simp add: all_solutions_def) apply(erule conjE)+ apply(simp add: ds_list_equ_ds) apply(simp only: subst_susp) apply(drule equ_pi1_pi2_dec[THEN mp]) apply(auto) apply(drule_tac x="aa" in bspec) apply(assumption) apply(simp add: subst_susp) apply(simp add: subst_equ_def subst_susp) apply(rule ballI) apply(rule equ_refl) --Var.one apply(drule_tac "t2.1"="swap (rev pi) t" in subst_not_occurs[THEN mp]) apply(simp only: problem_subst_comm) apply(simp add: all_solutions_def ext_subst_def subst_equ_def) apply(rule conjI) apply(rule ballI) apply(erule conjE)+ apply(drule unif_1) apply(clarify) apply(drule_tac x="(a,b)" in bspec) apply(assumption) apply(simp) apply(simp add: unif_2a) apply(erule conjE)+ apply(drule unif_1) apply(rule ballI) apply(clarify) apply(drule_tac x="(a,b)" in bspec) apply(assumption) apply(simp) apply(simp add: unif_2b) apply(rule unif_1) apply(simp add: all_solutions_def) --Var.two apply(drule_tac "t2.1"="swap (rev pi) t" in subst_not_occurs[THEN mp]) apply(simp only: problem_subst_comm) apply(simp add: all_solutions_def ext_subst_def subst_equ_def) apply(auto) apply(drule_tac x="(a,b)" in bspec) apply(assumption) apply(simp) apply(drule equ_sym) apply(drule unif_1) apply(simp add: unif_2a) apply(drule_tac x="(a,b)" in bspec) apply(assumption) apply(simp) apply(drule equ_sym) apply(drule unif_1) apply(simp add: unif_2b) apply(rule unif_1) apply(rule equ_sym) apply(simp add: all_solutions_def) done lemma P1_from_P2_sred: "\(nabla1,s1)\U P2; P1\s2\P2\\(nabla1,s1\s2)\U P1" apply(ind_cases "P1 \s2\ P2") --Susp.Paar.Func.Abst.aa apply(simp add: all_solutions_def, force) apply(simp add: all_solutions_def, force) apply(simp add: all_solutions_def, force) apply(simp add: all_solutions_def, force) --Abst.ab apply(simp only: all_solutions_def) apply(force simp add: subst_swap_comm) --Atom apply(simp only: all_solutions_def, force) --Susp apply(simp) apply(auto) apply(simp add: all_solutions_def) apply(simp add: ds_list_equ_ds) apply(subgoal_tac "nabla1\(swap pi1 (subst s1 (Susp [] X)))\(swap pi2 (subst s1 (Susp [] X)))") apply(simp add: subst_susp subst_swap_comm) apply(simp add: subst_susp subst_swap_comm) apply(rule equ_pi1_pi2_add[THEN mp]) apply(drule conjunct2) apply(auto) apply(drule_tac x="(a,Susp [] X)" in bspec) apply(auto) apply(simp add: subst_susp) --Var.one apply(simp only: problem_subst_comm) apply(simp only: all_solutions_def) apply(simp) apply(simp only: subst_comp_expand) apply(subgoal_tac "subst [(X, swap (rev pi) t)] t = t")--A apply(simp add: subst_susp) apply(simp only: subst_swap_comm) apply(simp only: equ_pi_to_right[THEN sym]) apply(simp only: equ_involutive_right) apply(rule equ_refl) --A apply(rule subst_not_occurs[THEN mp]) apply(assumption) --Var.two apply(simp only: problem_subst_comm) apply(simp only: all_solutions_def) apply(simp) apply(simp only: subst_comp_expand) apply(subgoal_tac "subst [(X, swap (rev pi) t)] t = t")--B apply(simp add: subst_susp) apply(simp only: subst_swap_comm) apply(simp only: equ_pi_to_left[THEN sym]) apply(simp only: equ_involutive_left) apply(rule equ_refl) --B apply(rule subst_not_occurs[THEN mp]) apply(assumption) done lemma P1_to_P2_cred: "\(nabla1,s1)\U P1; P1 \nabla2\ P2 \\((nabla1,s1)\U P2) \ (nabla1\(subst s1) nabla2)" apply(ind_cases " P1\nabla2\P2") apply(simp_all) apply(auto simp add: ext_subst_def all_solutions_def) apply(rule fresh_swap_left[THEN mp]) apply(simp add: subst_swap_comm[THEN sym] subst_susp) done lemma P1_from_P2_cred: "\(nabla1,s1)\U P2; P1 \nabla2\ P2; nabla3\(subst s1) nabla2\\(nabla1\nabla3,s1)\U P1" apply(ind_cases "P1 \nabla2\ P2") apply(simp_all) apply(auto simp add: ext_subst_def all_solutions_def fresh_weak) apply(simp add: subst_susp) apply(rule fresh_swap_right[THEN mp]) apply(drule_tac "nabla2.1"="nabla1" in fresh_weak[THEN mp]) apply(subgoal_tac "nabla3 \ nabla1=nabla1 \ nabla3")--A apply(simp) apply(rule Un_commute) done lemma P1_to_P2_red_plus: "\P1 \(nabla,s)\P2\\ (nabla1,s1)\U P1 \ ((nabla1,s1)\U P2)\(nabla1\subst (s1\s)\subst s1)\(nabla1\(subst s1) nabla)" apply(erule red_plus.induct) -- sred apply(rule impI) apply(drule_tac "P2.0"="P2" and "s2.0"="s1a" in P1_to_P2_sred) apply(force) apply(rule conjI, force)+ apply(force simp add: ext_subst_def) -- cred apply(rule impI) apply(drule_tac "P2.0"="P2" and "nabla2.0"="nabla1a" in P1_to_P2_cred) apply(assumption) apply(force intro!: equ_refl simp add: subst_equ_def) -- sred apply(rule impI) apply(drule_tac "P2.0"="P2" and "s2.0"="s1a" in P1_to_P2_sred) apply(assumption) apply(erule conjE)+ apply(rule conjI) apply(force) apply(rule conjI) apply(drule mp) apply(assumption) apply(erule conjE)+ apply(rule_tac "s2.0"="((s1\s2)\s1a)" in subst_trans) apply(simp only: subst_assoc subst_equ_def) apply(rule ballI) apply(rule equ_refl) apply(rule_tac "s2.0"="(s1\s1a)" in subst_trans) apply(rule subst_cancel_right) apply(assumption) apply(assumption) apply(force) -- cred apply(rule impI) apply(drule_tac "P2.0"="P2" and "nabla2.0"="nabla1a" in P1_to_P2_cred) apply(auto simp add: ext_subst_def) done lemma P1_from_P2_red_plus: "\P1 \(nabla,s)\P2\\(nabla1,s1)\U P2\ nabla3\(subst s1)(nabla)\(nabla1\nabla3,(s1\s))\U P1" apply(erule red_plus.induct) -- sred apply(rule impI)+ apply(drule_tac "P1.0"="P1" and "s2.0"="s1a" in P1_from_P2_sred) apply(assumption) apply(force simp only: all_solutions_def equ_weak fresh_weak) -- cred apply(rule impI)+ apply(drule_tac "P1.0"="P1" and "nabla3.0"="nabla3" and "nabla2.0"="nabla1a" in P1_from_P2_cred) apply(assumption)+ apply(simp add: all_solutions_def) -- sred apply(rule impI)+ apply(simp) apply(drule_tac "P1.0"="P1" and "P2.0"="P2" and "s2.0"="s1a" in P1_from_P2_sred) apply(assumption) apply(simp add: all_solutions_def subst_assoc) -- cred apply(rule impI)+ apply(subgoal_tac "nabla3 \ (subst s1) nabla2")--A apply(simp) apply(drule_tac "P1.0"="P1" and "P2.0"="P2" and "nabla2.0"="nabla1a" and "nabla3.0"="nabla3" in P1_from_P2_cred) apply(assumption) apply(simp) apply(simp add: ext_subst_def) apply(subgoal_tac "nabla1 \ nabla3 \ nabla3=nabla1 \ nabla3")--A apply(simp) --A apply(force) --B apply(simp add: ext_subst_def) done lemma mgu: "\P \(nabla,s)\([],[])\\ mgu P (nabla,s) \ idem (nabla,s)" apply(frule_tac "nabla3.2"="nabla" and "nabla2"="nabla" and "s1.2"="[]" and "nabla1.2"="{}" in P1_from_P2_red_plus[THEN mp,THEN mp]) apply(force simp add: all_solutions_def) apply(force simp add: ext_subst_def) apply(rule mgu_idem) apply(simp add: all_solutions_def) apply(rule ballI) apply(clarify) apply(drule_tac "nabla1.0"="a" and "s1.0"="b"in P1_to_P2_red_plus) apply(simp) done end