1 (* $Id$ *) |
1 (* $Id$ *) |
2 |
2 |
3 (* METHOD FOR ANALYSING EQUATION INVOLVING PERMUTATION *) |
3 (* METHOD FOR ANALYSING EQUATION INVOLVING PERMUTATION *) |
4 |
|
5 (* tries until depth 40 the following (in that order): *) |
|
6 (* *) |
|
7 (* - simplification plus analysing perm_swaps, perm_fresh_fresh, perm_bij *) |
|
8 (* - permutation compositions (on the left hand side of =) *) |
|
9 (* - simplification of permutation on applications and abstractions *) |
|
10 (* - analysing congruences (from Stefan Berghofer's datatype pkg) *) |
|
11 (* - unfolding permutation on functions *) |
|
12 (* - expanding equalities of functions *) |
|
13 (* *) |
|
14 (* for supports - it first unfolds the definitions and strips of intros *) |
|
15 |
4 |
16 local |
5 local |
17 |
6 |
18 (* pulls out dynamically a thm via the simpset *) |
7 (* pulls out dynamically a thm via the simpset *) |
19 fun dynamic_thms ss name = |
8 fun dynamic_thms ss name = |
20 ProofContext.get_thms (Simplifier.the_context ss) (Name name); |
9 ProofContext.get_thms (Simplifier.the_context ss) (Name name); |
|
10 fun dynamic_thm ss name = |
|
11 ProofContext.get_thm (Simplifier.the_context ss) (Name name); |
21 |
12 |
|
13 (* FIXME: make it usable for all atom-types *) |
22 (* initial simplification step in the tactic *) |
14 (* initial simplification step in the tactic *) |
23 fun initial_simp_tac ss i = |
15 fun perm_eval_tac ss i = |
24 let |
16 let |
|
17 val perm_eq_app = thm "nominal.pt_fun_app_eq"; |
|
18 val at_inst = dynamic_thm ss "at_name_inst"; |
|
19 val pt_inst = dynamic_thm ss "pt_name_inst"; |
|
20 |
|
21 fun perm_eval_simproc sg ss redex = |
|
22 (case redex of |
|
23 (* case pi o (f x) == (pi o f) (pi o x) *) |
|
24 (* special treatment in cases of constants *) |
|
25 (Const("nominal.perm",Type("fun",[Type("List.list",[Type("*",[ty,_])]),_])) $ pi $ (f $ x)) |
|
26 => let |
|
27 val _ = warning ("type: "^Sign.string_of_typ (sign_of (the_context())) ty) |
|
28 in |
|
29 |
|
30 (case f of |
|
31 (* nothing to do on constants *) |
|
32 (* FIXME: proper treatment of constants *) |
|
33 Const(_,_) => NONE |
|
34 | (Const(_,_) $ _) => NONE |
|
35 | ((Const(_,_) $ _) $ _) => NONE |
|
36 | (((Const(_,_) $ _) $ _) $ _) => NONE |
|
37 | _ => |
|
38 (* FIXME: analyse type here or at "pty"*) |
|
39 SOME ((at_inst RS (pt_inst RS perm_eq_app)) RS eq_reflection)) |
|
40 end |
|
41 |
|
42 (* case pi o (%x. f x) == (%x. pi o (f ((rev pi)o x))) *) |
|
43 | (Const("nominal.perm",_) $ pi $ (Abs _)) |
|
44 => let |
|
45 val perm_fun_def = thm "nominal.perm_fun_def" |
|
46 in SOME (perm_fun_def) end |
|
47 |
|
48 (* no redex otherwise *) |
|
49 | _ => NONE); |
|
50 |
|
51 val perm_eval = |
|
52 Simplifier.simproc (Theory.sign_of (the_context ())) "perm_eval" |
|
53 ["nominal.perm pi x"] perm_eval_simproc; |
|
54 |
25 (* these lemmas are created dynamically according to the atom types *) |
55 (* these lemmas are created dynamically according to the atom types *) |
26 val perm_swap = dynamic_thms ss "perm_swap"; |
56 val perm_swap = dynamic_thms ss "perm_swap"; |
27 val perm_fresh = dynamic_thms ss "perm_fresh_fresh"; |
57 val perm_fresh = dynamic_thms ss "perm_fresh_fresh"; |
28 val perm_bij = dynamic_thms ss "perm_bij"; |
58 val perm_bij = dynamic_thms ss "perm_bij"; |
29 val ss' = ss addsimps (perm_swap@perm_fresh@perm_bij) |
59 val perm_compose' = dynamic_thms ss "perm_compose'"; |
|
60 val perm_pi_simp = dynamic_thms ss "perm_pi_simp"; |
|
61 val ss' = ss addsimps (perm_swap@perm_fresh@perm_bij@perm_compose'@perm_pi_simp) |
|
62 addsimprocs [perm_eval]; |
|
63 |
30 in |
64 in |
31 ("general simplification step", FIRST [rtac conjI i, asm_full_simp_tac ss' i]) |
65 ("general simplification step", FIRST [rtac conjI i, asm_full_simp_tac ss' i]) |
32 end; |
66 end; |
33 |
67 |
34 (* applies the perm_compose rule - this rule would loop in the simplifier *) |
68 (* applies the perm_compose rule - this rule would loop in the simplifier *) |
35 (* in case there are more atom-types we have to check every possible instance *) |
69 (* in case there are more atom-types we have to check every possible instance *) |
36 (* of perm_compose *) |
70 (* of perm_compose *) |
37 fun apply_perm_compose_tac ss i = |
71 fun apply_perm_compose_tac ss i = |
38 let |
72 let |
39 val perm_compose = dynamic_thms ss "perm_compose"; |
73 val perm_compose = dynamic_thms ss "perm_compose"; |
40 val tacs = map (fn thm => (rtac (thm RS trans) i)) perm_compose |
74 val tacs = map (fn thm => (rtac (thm RS trans) i)) perm_compose |
41 in |
75 in |
42 ("analysing permutation compositions on the lhs",FIRST (tacs)) |
76 ("analysing permutation compositions on the lhs",FIRST (tacs)) |
43 end |
|
44 |
|
45 (* applies the perm_eq_lam and perm_eq_app simplifications *) |
|
46 (* FIXME: it seems the order of perm_app_eq and perm_lam_eq is *) |
|
47 (* significant *) |
|
48 fun apply_app_lam_simp_tac ss i = |
|
49 let |
|
50 val perm_app_eq = dynamic_thms ss "perm_app_eq"; |
|
51 val perm_lam_eq = thm "nominal.perm_eq_lam" |
|
52 in |
|
53 ("simplification of permutations on applications and lambdas", |
|
54 asm_full_simp_tac (HOL_basic_ss addsimps (perm_app_eq@[perm_lam_eq])) i) |
|
55 end |
77 end |
56 |
78 |
57 (* applying Stefan's smart congruence tac *) |
79 (* applying Stefan's smart congruence tac *) |
58 fun apply_cong_tac i = |
80 fun apply_cong_tac i = |
59 ("application of congruence", |
81 ("application of congruence", |
78 EVERY [CHANGED tac, print_tac ("after "^msg)]; |
100 EVERY [CHANGED tac, print_tac ("after "^msg)]; |
79 fun NO_DEBUG_tac (_,tac) = CHANGED tac; |
101 fun NO_DEBUG_tac (_,tac) = CHANGED tac; |
80 |
102 |
81 (* Main Tactic *) |
103 (* Main Tactic *) |
82 |
104 |
83 (* "repeating"-depth is set to 40 - this seems sufficient *) |
|
84 fun perm_simp_tac tactical ss i = |
105 fun perm_simp_tac tactical ss i = |
|
106 DETERM (tactical (perm_eval_tac ss i)); |
|
107 |
|
108 (* perm_simp_tac plus additional tactics to decide *) |
|
109 (* support problems *) |
|
110 (* the "repeating"-depth is set to 40 - this seems sufficient *) |
|
111 fun perm_supports_tac tactical ss i = |
85 DETERM (REPEAT_DETERM_N 40 |
112 DETERM (REPEAT_DETERM_N 40 |
86 (FIRST[tactical (initial_simp_tac ss i), |
113 (FIRST[tactical (perm_eval_tac ss i), |
87 tactical (apply_perm_compose_tac ss i), |
114 tactical (apply_perm_compose_tac ss i), |
88 tactical (apply_app_lam_simp_tac ss i), |
|
89 tactical (apply_cong_tac i), |
115 tactical (apply_cong_tac i), |
90 tactical (unfold_perm_fun_def_tac i), |
116 tactical (unfold_perm_fun_def_tac i), |
91 tactical (expand_fun_eq_tac i)])); |
117 tactical (expand_fun_eq_tac i)])); |
92 |
118 |
93 (* tactic that first unfolds the support definition *) |
119 (* tactic that first unfolds the support definition *) |
94 (* and strips of intros, then applies perm_simp_tac *) |
120 (* and strips off the intros, then applies perm_supports_tac *) |
95 fun supports_tac tactical ss i = |
121 fun supports_tac tactical ss i = |
96 let |
122 let |
97 val supports_def = thm "nominal.op supports_def"; |
123 val supports_def = thm "nominal.op supports_def"; |
98 val fresh_def = thm "nominal.fresh_def"; |
124 val fresh_def = thm "nominal.fresh_def"; |
99 val fresh_prod = thm "nominal.fresh_prod"; |
125 val fresh_prod = thm "nominal.fresh_prod"; |