theory Unification = Main + Terms + Fresh + Equ + Substs + Mgu: (* problems to which no reduction applies *) consts stuck :: "problem_type set" defs stuck_def: "stuck \ { P1. \(\P2 nabla s. P1 \(nabla,s)\P2)}" (* all problems which are stuck and have no unifier *) consts fail :: "problem_type set" inductive fail intros [intro!]: "\occurs X t\\(Susp pi X\?Abst a t#xs,ys)\fail" [intro!]: "\occurs X t\\(Susp pi X\?Func F t#xs,ys)\fail" [intro!]: "\occurs X t1\occurs X t2\\(Susp pi X\?Paar t1 t2#xs,ys)\fail" [intro!]: "\occurs X t\\(Abst a t\?Susp pi X#xs,ys)\fail" [intro!]: "\occurs X t\\(Func F t\?Susp pi X#xs,ys)\fail" [intro!]: "\occurs X t1\occurs X t2\\(Paar t1 t2\?Susp pi X#xs,ys)\fail" [intro!,dest!]: "([],a\? Atom a#ys)\fail" [intro!]: "a\b\(Atom a\? Atom b#xs,ys)\fail" [intro!,dest!]: "(Abst a t\?Unit#xs,ys)\fail" [intro!,dest!]: "(Unit\?Abst a t#xs,ys)\fail" [intro!,dest!]: "(Abst a t\?Atom b#xs,ys)\fail" [intro!,dest!]: "(Atom b\?Abst a t#xs,ys)\fail" [intro!,dest!]: "(Abst a t\?Paar t1 t2#xs,ys)\fail" [intro!,dest!]: "(Paar t1 t2\?Abst a t#xs,ys)\fail" [intro!,dest!]: "(Abst a t\?Func F t1#xs,ys)\fail" [intro!,dest!]: "(Func F t1\?Abst a t#xs,ys)\fail" [intro!,dest!]: "(Unit\?Atom b#xs,ys)\fail" [intro!,dest!]: "(Atom b\?Unit#xs,ys)\fail" [intro!,dest!]: "(Unit\?Paar t1 t2#xs,ys)\fail" [intro!,dest!]: "(Paar t1 t2\?Unit#xs,ys)\fail" [intro!,dest!]: "(Unit\?Func F t1#xs,ys)\fail" [intro!,dest!]: "(Func F t1\?Unit#xs,ys)\fail" [intro!,dest!]: "(Atom a\?Paar t1 t2#xs,ys)\fail" [intro!,dest!]: "(Paar t1 t2\?Atom a#xs,ys)\fail" [intro!,dest!]: "(Atom a\?Func F t1#xs,ys)\fail" [intro!,dest!]: "(Func F t1\?Atom a#xs,ys)\fail" [intro!,dest!]: "(Func F t\?Paar t1 t2#xs,ys)\fail" [intro!,dest!]: "(Paar t1 t2\?Func F t#xs,ys)\fail" [intro!]: "\F1\F2\\(Func F1 t1\?Func F2 t2#xs,ys)\fail" (* the results that are interesting are the stuck ones *) consts results :: "problem_type \ problem_type set" defs results_def: "results P1 \ if P1\stuck then {P1} else {P2. \nabla s. P1\(nabla,s)\P2 \ P2\stuck}" (* a "failed" problem has no unifier *) lemma fail_then_empty: "(P1\fail) \ (U P1={})" apply(erule fail.cases) apply(simp add: all_solutions_def) apply(rule allI)+ apply(rule impI) apply(drule_tac nabla1="aa" and s1="b" and "pi1.1"="pi" in occurs_sub_trm_equ[THEN mp]) apply(subgoal_tac "\t1\psub_trms (Abst a (subst b t)).\(\pi2. aa\Abst a (subst b t)\swap pi2 t1)") apply(simp) apply(drule equ_sym) apply(clarify) apply(drule_tac "t1.0"="Abst a (subst b t)" and "t2.0"="subst b (Susp pi X)" and "t3.0"="swap pia t2" in equ_trans) apply(simp) apply(best) apply(rule psub_trm_not_equ) apply(simp add: all_solutions_def) apply(rule allI)+ apply(rule impI) apply(drule_tac nabla1="a" and s1="b" and "pi1.1"="pi" in occurs_sub_trm_equ[THEN mp]) apply(subgoal_tac "\t1\psub_trms (Func F (subst b t)).\(\pi2. a\Func F (subst b t)\swap pi2 t1)") apply(simp) apply(drule equ_sym) apply(clarify) apply(drule_tac "t1.0"="Func F (subst b t)" and "t2.0"="subst b (Susp pi X)" and "t3.0"="swap pia t2" in equ_trans) apply(simp) apply(best) apply(rule psub_trm_not_equ) apply(simp add: all_solutions_def) apply(rule allI)+ apply(rule impI) apply(erule disjE) apply(drule_tac nabla1="a" and s1="b" and "pi1.1"="pi" in occurs_sub_trm_equ[THEN mp]) apply(subgoal_tac "\t3\psub_trms (Paar (subst b t1) (subst b t2)). \(\pi2. a\Paar (subst b t1) (subst b t2)\swap pi2 t3)") apply(simp) apply(drule equ_sym) apply(clarify) apply(drule_tac "t1.0"="Paar (subst b t1) (subst b t2)" and "t2.0"="subst b (Susp pi X)" and "t3.0"="swap pia t2a" in equ_trans) apply(simp) apply(best) apply(rule psub_trm_not_equ) apply(drule_tac nabla1="a" and s1="b" and "pi1.1"="pi" in occurs_sub_trm_equ[THEN mp]) apply(subgoal_tac "\t3\psub_trms (Paar (subst b t1) (subst b t2)). \(\pi2. a\Paar (subst b t1) (subst b t2)\swap pi2 t3)") apply(simp) apply(drule equ_sym) apply(clarify) apply(drule_tac "t1.0"="Paar (subst b t1) (subst b t2)" and "t2.0"="subst b (Susp pi X)" and "t3.0"="swap pia t2a" in equ_trans) apply(simp) apply(best) apply(rule psub_trm_not_equ) apply(simp add: all_solutions_def) apply(rule allI)+ apply(rule impI) apply(drule_tac nabla1="aa" and s1="b" and "pi1.1"="pi" in occurs_sub_trm_equ[THEN mp]) apply(subgoal_tac "\t3\psub_trms (Abst a (subst b t)). \(\pi2. aa\Abst a (subst b t)\swap pi2 t3)") apply(simp) apply(clarify) apply(drule_tac "t1.0"="Abst a (subst b t)" and "t2.0"="subst b (Susp pi X)" and "t3.0"="swap pia t2" in equ_trans) apply(simp) apply(best) apply(rule psub_trm_not_equ) apply(simp add: all_solutions_def) apply(rule allI)+ apply(rule impI) apply(drule_tac nabla1="a" and s1="b" and "pi1.1"="pi" in occurs_sub_trm_equ[THEN mp]) apply(subgoal_tac "\t1\psub_trms (Func F (subst b t)).\(\pi2. a\Func F (subst b t)\swap pi2 t1)") apply(simp) apply(clarify) apply(drule_tac "t1.0"="Func F (subst b t)" and "t2.0"="subst b (Susp pi X)" and "t3.0"="swap pia t2" in equ_trans) apply(simp) apply(best) apply(rule psub_trm_not_equ) apply(simp add: all_solutions_def) apply(rule allI)+ apply(rule impI) apply(erule disjE) apply(drule_tac nabla1="a" and s1="b" and "pi1.1"="pi" in occurs_sub_trm_equ[THEN mp]) apply(subgoal_tac "\t3\psub_trms (Paar (subst b t1) (subst b t2)). \(\pi2. a\Paar (subst b t1) (subst b t2)\swap pi2 t3)") apply(simp) apply(clarify) apply(drule_tac "t1.0"="Paar (subst b t1) (subst b t2)" and "t2.0"="subst b (Susp pi X)" and "t3.0"="swap pia t2a" in equ_trans) apply(simp) apply(best) apply(rule psub_trm_not_equ) apply(drule_tac nabla1="a" and s1="b" and "pi1.1"="pi" in occurs_sub_trm_equ[THEN mp]) apply(subgoal_tac "\t3\psub_trms (Paar (subst b t1) (subst b t2)). \(\pi2. a\Paar (subst b t1) (subst b t2)\swap pi2 t3)") apply(simp) apply(clarify) apply(drule_tac "t1.0"="Paar (subst b t1) (subst b t2)" and "t2.0"="subst b (Susp pi X)" and "t3.0"="swap pia t2a" in equ_trans) apply(simp) apply(best) apply(rule psub_trm_not_equ) apply(simp add: all_solutions_def, fast dest!: fresh.cases) apply(simp add: all_solutions_def, fast dest!: equ.cases)+ done (* the only stuck problems are the "failed" problems and the empty problem *) lemma stuck_equiv: "stuck = {([],[])}\fail" apply(subgoal_tac "([],[])\stuck") apply(subgoal_tac "\P\fail. P\stuck") apply(subgoal_tac "\P\stuck. P=([],[]) \ P\fail") apply(force) apply(rule ballI) apply(thin_tac "([], []) \ stuck") apply(thin_tac "\P\fail. P \ stuck") apply(simp add: stuck_def) apply(clarify) apply(case_tac a) apply(simp) apply(case_tac b) apply(simp) apply(simp) apply(case_tac aa) apply(simp) apply(case_tac ba) apply(simp_all) apply(case_tac "ab=lista") apply(force) apply(force) apply(force) apply(force) apply(force) apply(force) apply(force) apply(case_tac aa) apply(simp) apply(case_tac ab) apply(simp_all) apply(case_tac ba) apply(simp_all) apply(case_tac "lista=listb") apply(force) apply(force) apply(case_tac "occurs list2 (Abst lista trm)") apply(force) apply(drule_tac x="fst (apply_subst [(list2,swap (rev list1) (Abst lista trm))] (list,b))" in spec) apply(drule_tac x="snd (apply_subst [(list2,swap (rev list1) (Abst lista trm))] (list,b))" in spec) apply(drule_tac x="{}" in spec) apply(drule_tac x="[(list2, swap (rev list1) (Abst lista trm))]" in spec) apply(simp only: surjective_pairing[THEN sym]) apply(force) apply(force) apply(force) apply(force) apply(force) apply(case_tac ba) apply(simp_all) apply(case_tac "occurs list2 (Abst lista trm)") apply(force) apply(drule_tac x="fst (apply_subst [(list2,swap (rev list1) (Abst lista trm))] (list,b))" in spec) apply(drule_tac x="snd (apply_subst [(list2,swap (rev list1) (Abst lista trm))] (list,b))" in spec) apply(drule_tac x="{}" in spec) apply(drule_tac x="[(list2, swap (rev list1) (Abst lista trm))]" in spec) apply(simp only: surjective_pairing[THEN sym]) apply(force) apply(case_tac "list2=list2a") apply(force) apply(case_tac "occurs list2 (Susp list1a list2a)") apply(simp) apply(drule_tac x="fst (apply_subst [(list2,swap (rev list1) (Susp list1a list2a))] (list,b))" in spec) apply(drule_tac x="snd (apply_subst [(list2,swap (rev list1) (Susp list1a list2a))] (list,b))" in spec) apply(drule_tac x="{}" in spec) apply(drule_tac x="[(list2, swap (rev list1) (Susp list1a list2a))]" in spec) apply(simp only: surjective_pairing[THEN sym]) apply(force) apply(case_tac "occurs list2 Unit") apply(simp) apply(drule_tac x="fst (apply_subst [(list2,swap (rev list1) Unit)] (list,b))" in spec) apply(drule_tac x="snd (apply_subst [(list2,swap (rev list1) Unit)] (list,b))" in spec) apply(drule_tac x="{}" in spec) apply(drule_tac x="[(list2, swap (rev list1) Unit)]" in spec) apply(simp only: surjective_pairing[THEN sym]) apply(force) apply(case_tac "occurs list2 (Atom lista)") apply(simp) apply(drule_tac x="fst (apply_subst [(list2,swap (rev list1) (Atom lista))] (list,b))" in spec) apply(drule_tac x="snd (apply_subst [(list2,swap (rev list1) (Atom lista))] (list,b))" in spec) apply(drule_tac x="{}" in spec) apply(drule_tac x="[(list2, swap (rev list1) (Atom lista))]" in spec) apply(simp only: surjective_pairing[THEN sym]) apply(force) apply(case_tac "occurs list2 (Paar trm1 trm2)") apply(force) apply(drule_tac x="fst (apply_subst [(list2,swap (rev list1) (Paar trm1 trm2))] (list,b))" in spec) apply(drule_tac x="snd (apply_subst [(list2,swap (rev list1) (Paar trm1 trm2))] (list,b))" in spec) apply(drule_tac x="{}" in spec) apply(drule_tac x="[(list2, swap (rev list1) (Paar trm1 trm2))]" in spec) apply(simp only: surjective_pairing[THEN sym]) apply(force) apply(case_tac "occurs list2 (Func lista trm)") apply(force) apply(drule_tac x="fst (apply_subst [(list2,swap (rev list1) (Func lista trm))] (list,b))" in spec) apply(drule_tac x="snd (apply_subst [(list2,swap (rev list1) (Func lista trm))] (list,b))" in spec) apply(drule_tac x="{}" in spec) apply(drule_tac x="[(list2, swap (rev list1) (Func lista trm))]" in spec) apply(simp only: surjective_pairing[THEN sym]) apply(force) apply(case_tac ba) apply(simp_all) apply(force) apply(case_tac "occurs list2 Unit") apply(simp) apply(drule_tac x="fst (apply_subst [(list2,swap (rev list1) Unit)] (list,b))" in spec) apply(drule_tac x="snd (apply_subst [(list2,swap (rev list1) Unit)] (list,b))" in spec) apply(drule_tac x="{}" in spec) apply(drule_tac x="[(list2, swap (rev list1) Unit)]" in spec) apply(simp only: surjective_pairing[THEN sym]) apply(force) apply(force) apply(force) apply(force) apply(force) apply(case_tac ba) apply(simp_all) apply(force) apply(case_tac "occurs list2 (Atom lista)") apply(simp) apply(drule_tac x="fst (apply_subst [(list2,swap (rev list1) (Atom lista))] (list,b))" in spec) apply(drule_tac x="snd (apply_subst [(list2,swap (rev list1) (Atom lista))] (list,b))" in spec) apply(drule_tac x="{}" in spec) apply(drule_tac x="[(list2, swap (rev list1) (Atom lista))]" in spec) apply(simp only: surjective_pairing[THEN sym]) apply(force) apply(force) apply(force) apply(force) apply(force) apply(case_tac ba) apply(simp_all) apply(force) apply(case_tac "occurs list2 (Paar trm1 trm2)") apply(force) apply(drule_tac x="fst (apply_subst [(list2,swap (rev list1) (Paar trm1 trm2))] (list,b))" in spec) apply(drule_tac x="snd (apply_subst [(list2,swap (rev list1) (Paar trm1 trm2))] (list,b))" in spec) apply(drule_tac x="{}" in spec) apply(drule_tac x="[(list2, swap (rev list1) (Paar trm1 trm2))]" in spec) apply(simp only: surjective_pairing[THEN sym]) apply(force) apply(force) apply(force) apply(force) apply(force) apply(case_tac ba) apply(simp_all) apply(force) apply(case_tac "occurs list2 (Func lista trm)") apply(force) apply(drule_tac x="fst (apply_subst [(list2,swap (rev list1) (Func lista trm))] (list,b))" in spec) apply(drule_tac x="snd (apply_subst [(list2,swap (rev list1) (Func lista trm))] (list,b))" in spec) apply(drule_tac x="{}" in spec) apply(drule_tac x="[(list2, swap (rev list1) (Func lista trm))]" in spec) apply(simp only: surjective_pairing[THEN sym]) apply(force) apply(force) apply(force) apply(force) apply(force) apply(rule ballI) apply(thin_tac "([], []) \ stuck") apply(simp add: stuck_def) apply(clarify) apply(ind_cases "((a, b), (nabla, s), aa, ba) \ red_plus") apply(ind_cases "((a, b), s, aa, ba) \ s_red") apply(simp_all) apply(ind_cases "((Unit, Unit) # aa, b) \ fail") apply(ind_cases "((Paar t1 t2, Paar s1 s2) # xs, b) \ fail") apply(ind_cases "((Func F t1, Func F t2) # xs, b) \ fail") apply(simp) apply(ind_cases "((Abst ab t1, Abst ab t2) # xs, b) \ fail") apply(ind_cases "((Abst ab t1, Abst bb t2) # xs, b) \ fail") apply(ind_cases "((Atom ab, Atom ab) # aa, b) \ fail") apply(simp) apply(ind_cases "((Susp pi1 X, Susp pi2 X) # aa, b) \ fail") apply(ind_cases "((Susp pi X, t) # xs, b) \ fail") apply(simp add: apply_subst_def)+ apply(case_tac "occurs X t1") apply(simp) apply(simp) apply(ind_cases "((t, Susp pi X) # xs, b) \ fail") apply(simp add: apply_subst_def) apply(case_tac "occurs X t1") apply(simp) apply(simp) apply(case_tac "occurs X t1") apply(simp) apply(simp) apply(ind_cases "((a, b), nabla, aa, ba) \ c_red") apply(simp_all) apply(ind_cases "([], (ab, Unit) # ba) \ fail") apply(ind_cases "([], (ab, Paar t1 t2) # xs) \ fail") apply(ind_cases "([], (ab, Func F t) # xs) \ fail") apply(ind_cases "([], (ab, Abst ab t) # ba) \ fail") apply(ind_cases "([], (ab, Abst bb t) # xs) \ fail") apply(ind_cases "([], (ab, Atom bb) # ba) \ fail") apply(simp) apply(ind_cases "([], (ab, Susp pi X) # ba) \ fail") apply(ind_cases "(a, b) \ s1 \ P2") apply(simp_all) apply(ind_cases "((Unit, Unit) # xs, b) \ fail") apply(ind_cases "((Paar t1 t2, Paar s1 s2) # xs, b) \ fail") apply(ind_cases "((Func F t1, Func F t2) # xs, b) \ fail") apply(simp) apply(ind_cases "((Abst ab t1, Abst ab t2) # xs, b) \ fail") apply(ind_cases "((Abst ab t1, Abst bb t2) # xs, b) \ fail") apply(ind_cases "((Atom ab, Atom ab) # aa, b) \ fail") apply(simp) apply(ind_cases "((Susp pi1 X, Susp pi2 X) # aa, b) \ fail") apply(ind_cases "((Susp pi X, t) # xs, b) \ fail") apply(simp add: apply_subst_def)+ apply(case_tac "occurs X t1") apply(simp) apply(simp) apply(ind_cases "((t, Susp pi X) # xs, b) \ fail") apply(simp add: apply_subst_def) apply(case_tac "occurs X t1") apply(simp) apply(simp) apply(case_tac "occurs X t1") apply(simp) apply(simp) apply(ind_cases "(a, b) \ nabla1 \ P2") apply(simp_all) apply(ind_cases "([], (ab, Unit) # ba) \ fail") apply(ind_cases "([], (ab, Paar t1 t2) # xs) \ fail") apply(ind_cases "([], (ab, Func F t) # xs) \ fail") apply(ind_cases "([], (ab, Abst ab t) # ba) \ fail") apply(ind_cases "([], (ab, Abst bb t) # xs) \ fail") apply(ind_cases "([], (ab, Atom bb) # ba) \ fail") apply(simp) apply(ind_cases "([], (ab, Susp pi X) # ba) \ fail") apply(simp add: stuck_def) apply(rule allI)+ apply(clarify) apply(ind_cases "(([], []), (nabla, s), a, b) \ red_plus") apply(ind_cases "(([], []), s, a, b) \ s_red") apply(ind_cases "(([], []), nabla, a, b) \ c_red") apply(ind_cases "([], []) \ s1 \ P2") apply(ind_cases "([], []) \ nabla1 \ P2") done lemma u_empty_sred: "P1\s\P2 \ U P2 ={} \ U P1={}" apply(rule impI) apply(ind_cases "P1 \ s \ P2") apply(rule impI, simp add: all_solutions_def) apply(rule impI, simp add: all_solutions_def) apply(fast dest!: equ_paar_elim) apply(rule impI, simp add: all_solutions_def) apply(fast dest!: equ_func_elim) apply(rule impI, simp add: all_solutions_def) apply(fast dest!: equ_abst_aa_elim) apply(rule impI, simp add: all_solutions_def) apply(force dest!: equ_abst_ab_elim simp add: subst_swap_comm[THEN sym]) apply(rule impI, simp add: all_solutions_def) apply(rule impI, simp add: all_solutions_def) apply(simp add: ds_list_equ_ds) apply(rule allI)+ apply(rule impI) apply(drule_tac x="a" in spec) apply(drule_tac x="b" in spec) apply(erule disjE) apply(force) apply(simp add: subst_susp) apply(drule equ_pi1_pi2_dec[THEN mp]) apply(force simp add: subst_susp) apply(auto) apply(simp add: all_solutions_def) apply(simp_all add: apply_subst_def) apply(auto) apply(drule_tac x="a" in spec) apply(drule_tac x="b" in spec) apply(drule unif_1) apply(auto) apply(drule_tac x="(aa,ba)" in bspec) apply(assumption) apply(simp) apply(drule_tac "t1.0"="aa" and "t2.0"="ba" in unif_2a) apply(simp add: subst_comp_expand) apply(drule_tac x="(aa,ba)" in bspec) apply(assumption) apply(simp) apply(drule_tac a="aa" and "t"="ba" in unif_2b) apply(simp add: subst_comp_expand) apply(simp add: all_solutions_def) apply(auto) apply(drule_tac x="a" in spec) apply(drule_tac x="b" in spec) apply(drule equ_sym) apply(drule unif_1) apply(auto) apply(drule_tac x="(aa,ba)" in bspec) apply(assumption) apply(simp) apply(drule_tac "t1.0"="aa" and "t2.0"="ba" in unif_2a) apply(simp add: subst_comp_expand) apply(drule_tac x="(aa,ba)" in bspec) apply(assumption) apply(simp) apply(drule_tac a="aa" and "t"="ba" in unif_2b) apply(simp add: subst_comp_expand) done lemma u_empty_cred: "P1\nabla\P2 \ U P2 ={} \ U P1={}" apply(rule impI) apply(ind_cases "P1 \nabla\P2") apply(rule impI, simp add: all_solutions_def) apply(rule impI, simp add: all_solutions_def) apply(fast dest!: fresh_paar_elim) apply(rule impI, simp add: all_solutions_def) apply(fast dest!: fresh_func_elim) apply(rule impI, simp add: all_solutions_def) apply(rule impI, simp add: all_solutions_def) apply(force dest!: fresh_abst_ab_elim) apply(rule impI, simp add: all_solutions_def) apply(rule impI, simp add: all_solutions_def) done lemma u_empty_red_plus: "P1\(nabla,s)\P2 \ U P2 ={} \ U P1={}" apply(rule impI) apply(erule red_plus.induct) apply(drule u_empty_sred[THEN mp], assumption) apply(drule u_empty_cred[THEN mp], assumption) apply(drule u_empty_sred[THEN mp], force) apply(drule u_empty_cred[THEN mp], force) done (* all problems that cannot be solved produce "failed" problems only *) lemma empty_then_fail: "U P1={} \ (\P\results P1. P\fail)" apply(simp add: results_def) apply(rule conjI) apply(rule impI) apply(rule impI) apply(simp add: stuck_equiv) apply(erule disjE) apply(subgoal_tac "({},[])\U ([],[])") apply(simp) apply(simp add: all_solutions_def) apply(assumption) apply(rule impI)+ apply(rule allI)+ apply(rule impI) apply(erule conjE) apply(simp add: stuck_equiv) apply(auto) apply(subgoal_tac "({},[])\U ([],[])") apply(drule_tac "nabla3.0"="nabla" and "nabla1.0"="{}" and "s1.0"="[]" in P1_from_P2_red_plus) apply(simp add: ext_subst_def) apply(auto) apply(simp add: all_solutions_def) done (* if a problem can be solved then no "failed" problem is produced *) lemma not_empty_then_not_fail: "U P1\{} \ \(\P\results P1. P\fail)" apply(rule impI) apply(simp) apply(rule ballI) apply(clarify) apply(simp add: results_def) apply(case_tac "P1\stuck") apply(simp_all) apply(drule fail_then_empty) apply(simp) apply(drule fail_then_empty) apply(erule conjE) apply(clarify) apply(drule u_empty_red_plus[THEN mp]) apply(simp) done end