| author | haftmann | 
| Fri, 19 Jun 2009 19:45:00 +0200 | |
| changeset 31725 | f08507464b9d | 
| parent 30136 | 6a874aedb964 | 
| child 32843 | c8f5a7c8353f | 
| permissions | -rw-r--r-- | 
| 22905 
dab6a898b47c
Conversions: primitive equality reasoning (from drule.ML);
 wenzelm parents: diff
changeset | 1 | (* Title: Pure/conv.ML | 
| 
dab6a898b47c
Conversions: primitive equality reasoning (from drule.ML);
 wenzelm parents: diff
changeset | 2 | Author: Amine Chaieb and Makarius | 
| 
dab6a898b47c
Conversions: primitive equality reasoning (from drule.ML);
 wenzelm parents: diff
changeset | 3 | |
| 
dab6a898b47c
Conversions: primitive equality reasoning (from drule.ML);
 wenzelm parents: diff
changeset | 4 | Conversions: primitive equality reasoning. | 
| 
dab6a898b47c
Conversions: primitive equality reasoning (from drule.ML);
 wenzelm parents: diff
changeset | 5 | *) | 
| 
dab6a898b47c
Conversions: primitive equality reasoning (from drule.ML);
 wenzelm parents: diff
changeset | 6 | |
| 22937 | 7 | infix 1 then_conv; | 
| 8 | infix 0 else_conv; | |
| 23169 | 9 | |
| 30136 
6a874aedb964
Made then_conv and else_conv available as infix operations.
 boehmes parents: 
29606diff
changeset | 10 | signature BASIC_CONV = | 
| 
6a874aedb964
Made then_conv and else_conv available as infix operations.
 boehmes parents: 
29606diff
changeset | 11 | sig | 
| 
6a874aedb964
Made then_conv and else_conv available as infix operations.
 boehmes parents: 
29606diff
changeset | 12 | val then_conv: conv * conv -> conv | 
| 
6a874aedb964
Made then_conv and else_conv available as infix operations.
 boehmes parents: 
29606diff
changeset | 13 | val else_conv: conv * conv -> conv | 
| 
6a874aedb964
Made then_conv and else_conv available as infix operations.
 boehmes parents: 
29606diff
changeset | 14 | end; | 
| 
6a874aedb964
Made then_conv and else_conv available as infix operations.
 boehmes parents: 
29606diff
changeset | 15 | |
| 22905 
dab6a898b47c
Conversions: primitive equality reasoning (from drule.ML);
 wenzelm parents: diff
changeset | 16 | signature CONV = | 
| 
dab6a898b47c
Conversions: primitive equality reasoning (from drule.ML);
 wenzelm parents: diff
changeset | 17 | sig | 
| 30136 
6a874aedb964
Made then_conv and else_conv available as infix operations.
 boehmes parents: 
29606diff
changeset | 18 | include BASIC_CONV | 
| 22905 
dab6a898b47c
Conversions: primitive equality reasoning (from drule.ML);
 wenzelm parents: diff
changeset | 19 | val no_conv: conv | 
| 
dab6a898b47c
Conversions: primitive equality reasoning (from drule.ML);
 wenzelm parents: diff
changeset | 20 | val all_conv: conv | 
| 22926 | 21 | val first_conv: conv list -> conv | 
| 22 | val every_conv: conv list -> conv | |
| 22937 | 23 | val try_conv: conv -> conv | 
| 24 | val repeat_conv: conv -> conv | |
| 26571 | 25 | val abs_conv: (cterm * Proof.context -> conv) -> Proof.context -> conv | 
| 22926 | 26 | val combination_conv: conv -> conv -> conv | 
| 27 | val comb_conv: conv -> conv | |
| 28 | val arg_conv: conv -> conv | |
| 29 | val fun_conv: conv -> conv | |
| 30 | val arg1_conv: conv -> conv | |
| 31 | val fun2_conv: conv -> conv | |
| 23034 | 32 | val binop_conv: conv -> conv | 
| 26571 | 33 | val forall_conv: (cterm * Proof.context -> conv) -> Proof.context -> conv | 
| 34 | val implies_conv: conv -> conv -> conv | |
| 35 | val implies_concl_conv: conv -> conv | |
| 36 | val rewr_conv: thm -> conv | |
| 37 | val params_conv: int -> (Proof.context -> conv) -> Proof.context -> conv | |
| 38 | val prems_conv: int -> conv -> conv | |
| 22905 
dab6a898b47c
Conversions: primitive equality reasoning (from drule.ML);
 wenzelm parents: diff
changeset | 39 | val concl_conv: int -> conv -> conv | 
| 
dab6a898b47c
Conversions: primitive equality reasoning (from drule.ML);
 wenzelm parents: diff
changeset | 40 | val fconv_rule: conv -> thm -> thm | 
| 23583 
00751df1f98c
else_conv: only handle THM | CTERM | TERM | TYPE;
 wenzelm parents: 
23534diff
changeset | 41 | val gconv_rule: conv -> int -> thm -> thm | 
| 22905 
dab6a898b47c
Conversions: primitive equality reasoning (from drule.ML);
 wenzelm parents: diff
changeset | 42 | end; | 
| 
dab6a898b47c
Conversions: primitive equality reasoning (from drule.ML);
 wenzelm parents: diff
changeset | 43 | |
| 
dab6a898b47c
Conversions: primitive equality reasoning (from drule.ML);
 wenzelm parents: diff
changeset | 44 | structure Conv: CONV = | 
| 
dab6a898b47c
Conversions: primitive equality reasoning (from drule.ML);
 wenzelm parents: diff
changeset | 45 | struct | 
| 
dab6a898b47c
Conversions: primitive equality reasoning (from drule.ML);
 wenzelm parents: diff
changeset | 46 | |
| 
dab6a898b47c
Conversions: primitive equality reasoning (from drule.ML);
 wenzelm parents: diff
changeset | 47 | (* conversionals *) | 
| 
dab6a898b47c
Conversions: primitive equality reasoning (from drule.ML);
 wenzelm parents: diff
changeset | 48 | |
| 
dab6a898b47c
Conversions: primitive equality reasoning (from drule.ML);
 wenzelm parents: diff
changeset | 49 | fun no_conv _ = raise CTERM ("no conversion", []);
 | 
| 
dab6a898b47c
Conversions: primitive equality reasoning (from drule.ML);
 wenzelm parents: diff
changeset | 50 | val all_conv = Thm.reflexive; | 
| 
dab6a898b47c
Conversions: primitive equality reasoning (from drule.ML);
 wenzelm parents: diff
changeset | 51 | |
| 22937 | 52 | fun (cv1 then_conv cv2) ct = | 
| 22905 
dab6a898b47c
Conversions: primitive equality reasoning (from drule.ML);
 wenzelm parents: diff
changeset | 53 | let | 
| 22926 | 54 | val eq1 = cv1 ct; | 
| 55 | val eq2 = cv2 (Thm.rhs_of eq1); | |
| 22905 
dab6a898b47c
Conversions: primitive equality reasoning (from drule.ML);
 wenzelm parents: diff
changeset | 56 | in | 
| 23596 | 57 | if Thm.is_reflexive eq1 then eq2 | 
| 58 | else if Thm.is_reflexive eq2 then eq1 | |
| 22905 
dab6a898b47c
Conversions: primitive equality reasoning (from drule.ML);
 wenzelm parents: diff
changeset | 59 | else Thm.transitive eq1 eq2 | 
| 
dab6a898b47c
Conversions: primitive equality reasoning (from drule.ML);
 wenzelm parents: diff
changeset | 60 | end; | 
| 
dab6a898b47c
Conversions: primitive equality reasoning (from drule.ML);
 wenzelm parents: diff
changeset | 61 | |
| 22937 | 62 | fun (cv1 else_conv cv2) ct = | 
| 23583 
00751df1f98c
else_conv: only handle THM | CTERM | TERM | TYPE;
 wenzelm parents: 
23534diff
changeset | 63 | (cv1 ct | 
| 
00751df1f98c
else_conv: only handle THM | CTERM | TERM | TYPE;
 wenzelm parents: 
23534diff
changeset | 64 | handle THM _ => cv2 ct | 
| 
00751df1f98c
else_conv: only handle THM | CTERM | TERM | TYPE;
 wenzelm parents: 
23534diff
changeset | 65 | | CTERM _ => cv2 ct | 
| 
00751df1f98c
else_conv: only handle THM | CTERM | TERM | TYPE;
 wenzelm parents: 
23534diff
changeset | 66 | | TERM _ => cv2 ct | 
| 
00751df1f98c
else_conv: only handle THM | CTERM | TERM | TYPE;
 wenzelm parents: 
23534diff
changeset | 67 | | TYPE _ => cv2 ct); | 
| 22926 | 68 | |
| 22937 | 69 | fun first_conv cvs = fold_rev (curry op else_conv) cvs no_conv; | 
| 70 | fun every_conv cvs = fold_rev (curry op then_conv) cvs all_conv; | |
| 22926 | 71 | |
| 22937 | 72 | fun try_conv cv = cv else_conv all_conv; | 
| 73 | fun repeat_conv cv ct = try_conv (cv then_conv repeat_conv cv) ct; | |
| 22926 | 74 | |
| 22905 
dab6a898b47c
Conversions: primitive equality reasoning (from drule.ML);
 wenzelm parents: diff
changeset | 75 | |
| 
dab6a898b47c
Conversions: primitive equality reasoning (from drule.ML);
 wenzelm parents: diff
changeset | 76 | |
| 22926 | 77 | (** Pure conversions **) | 
| 78 | ||
| 79 | (* lambda terms *) | |
| 80 | ||
| 24834 
5684cbf8c895
abs_conv/forall_conv: proper context (avoid gensym);
 wenzelm parents: 
23656diff
changeset | 81 | fun abs_conv cv ctxt ct = | 
| 23587 | 82 | (case Thm.term_of ct of | 
| 22926 | 83 | Abs (x, _, _) => | 
| 23596 | 84 | let | 
| 24834 
5684cbf8c895
abs_conv/forall_conv: proper context (avoid gensym);
 wenzelm parents: 
23656diff
changeset | 85 | val ([u], ctxt') = Variable.variant_fixes ["u"] ctxt; | 
| 
5684cbf8c895
abs_conv/forall_conv: proper context (avoid gensym);
 wenzelm parents: 
23656diff
changeset | 86 | val (v, ct') = Thm.dest_abs (SOME u) ct; | 
| 26571 | 87 | val eq = cv (v, ctxt') ct'; | 
| 23596 | 88 | in if Thm.is_reflexive eq then all_conv ct else Thm.abstract_rule x v eq end | 
| 22926 | 89 |   | _ => raise CTERM ("abs_conv", [ct]));
 | 
| 90 | ||
| 91 | fun combination_conv cv1 cv2 ct = | |
| 92 | let val (ct1, ct2) = Thm.dest_comb ct | |
| 93 | in Thm.combination (cv1 ct1) (cv2 ct2) end; | |
| 94 | ||
| 95 | fun comb_conv cv = combination_conv cv cv; | |
| 96 | fun arg_conv cv = combination_conv all_conv cv; | |
| 97 | fun fun_conv cv = combination_conv cv all_conv; | |
| 98 | ||
| 99 | val arg1_conv = fun_conv o arg_conv; | |
| 100 | val fun2_conv = fun_conv o fun_conv; | |
| 101 | ||
| 23034 | 102 | fun binop_conv cv = combination_conv (arg_conv cv) cv; | 
| 22926 | 103 | |
| 23169 | 104 | |
| 26571 | 105 | (* primitive logic *) | 
| 106 | ||
| 107 | fun forall_conv cv ctxt ct = | |
| 108 | (case Thm.term_of ct of | |
| 109 |     Const ("all", _) $ Abs _ => arg_conv (abs_conv cv ctxt) ct
 | |
| 110 |   | _ => raise CTERM ("forall_conv", [ct]));
 | |
| 111 | ||
| 112 | fun implies_conv cv1 cv2 ct = | |
| 113 | (case Thm.term_of ct of | |
| 114 |     Const ("==>", _) $ _ $ _ => combination_conv (arg_conv cv1) cv2 ct
 | |
| 115 |   | _ => raise CTERM ("implies_conv", [ct]));
 | |
| 116 | ||
| 117 | fun implies_concl_conv cv ct = | |
| 118 | (case Thm.term_of ct of | |
| 119 |     Const ("==>", _) $ _ $ _ => arg_conv cv ct
 | |
| 120 |   | _ => raise CTERM ("implies_concl_conv", [ct]));
 | |
| 121 | ||
| 122 | ||
| 123 | (* single rewrite step, cf. REWR_CONV in HOL *) | |
| 124 | ||
| 125 | fun rewr_conv rule ct = | |
| 126 | let | |
| 127 | val rule1 = Thm.incr_indexes (#maxidx (Thm.rep_cterm ct) + 1) rule; | |
| 128 | val lhs = Thm.lhs_of rule1; | |
| 129 | val rule2 = Thm.rename_boundvars (Thm.term_of lhs) (Thm.term_of ct) rule1; | |
| 130 | in | |
| 131 | Drule.instantiate (Thm.match (lhs, ct)) rule2 | |
| 132 |       handle Pattern.MATCH => raise CTERM ("rewr_conv", [lhs, ct])
 | |
| 133 | end; | |
| 134 | ||
| 135 | ||
| 136 | (* conversions on HHF rules *) | |
| 22905 
dab6a898b47c
Conversions: primitive equality reasoning (from drule.ML);
 wenzelm parents: diff
changeset | 137 | |
| 
dab6a898b47c
Conversions: primitive equality reasoning (from drule.ML);
 wenzelm parents: diff
changeset | 138 | (*rewrite B in !!x1 ... xn. B*) | 
| 26571 | 139 | fun params_conv n cv ctxt ct = | 
| 27332 | 140 | if n <> 0 andalso Logic.is_all (Thm.term_of ct) | 
| 26571 | 141 | then arg_conv (abs_conv (params_conv (n - 1) cv o #2) ctxt) ct | 
| 24834 
5684cbf8c895
abs_conv/forall_conv: proper context (avoid gensym);
 wenzelm parents: 
23656diff
changeset | 142 | else cv ctxt ct; | 
| 22905 
dab6a898b47c
Conversions: primitive equality reasoning (from drule.ML);
 wenzelm parents: diff
changeset | 143 | |
| 26571 | 144 | (*rewrite the A's in A1 ==> ... ==> An ==> B*) | 
| 145 | fun prems_conv 0 _ ct = all_conv ct | |
| 146 | | prems_conv n cv ct = | |
| 147 | (case try Thm.dest_implies ct of | |
| 148 | NONE => all_conv ct | |
| 149 | | SOME (A, B) => Drule.imp_cong_rule (cv A) (prems_conv (n - 1) cv B)); | |
| 150 | ||
| 22905 
dab6a898b47c
Conversions: primitive equality reasoning (from drule.ML);
 wenzelm parents: diff
changeset | 151 | (*rewrite B in A1 ==> ... ==> An ==> B*) | 
| 
dab6a898b47c
Conversions: primitive equality reasoning (from drule.ML);
 wenzelm parents: diff
changeset | 152 | fun concl_conv 0 cv ct = cv ct | 
| 
dab6a898b47c
Conversions: primitive equality reasoning (from drule.ML);
 wenzelm parents: diff
changeset | 153 | | concl_conv n cv ct = | 
| 
dab6a898b47c
Conversions: primitive equality reasoning (from drule.ML);
 wenzelm parents: diff
changeset | 154 | (case try Thm.dest_implies ct of | 
| 
dab6a898b47c
Conversions: primitive equality reasoning (from drule.ML);
 wenzelm parents: diff
changeset | 155 | NONE => cv ct | 
| 22926 | 156 | | SOME (A, B) => Drule.imp_cong_rule (all_conv A) (concl_conv (n - 1) cv B)); | 
| 22905 
dab6a898b47c
Conversions: primitive equality reasoning (from drule.ML);
 wenzelm parents: diff
changeset | 157 | |
| 23596 | 158 | |
| 26571 | 159 | (* conversions as inference rules *) | 
| 22905 
dab6a898b47c
Conversions: primitive equality reasoning (from drule.ML);
 wenzelm parents: diff
changeset | 160 | |
| 23596 | 161 | (*forward conversion, cf. FCONV_RULE in LCF*) | 
| 162 | fun fconv_rule cv th = | |
| 163 | let val eq = cv (Thm.cprop_of th) in | |
| 164 | if Thm.is_reflexive eq then th | |
| 165 | else Thm.equal_elim eq th | |
| 166 | end; | |
| 22905 
dab6a898b47c
Conversions: primitive equality reasoning (from drule.ML);
 wenzelm parents: diff
changeset | 167 | |
| 23596 | 168 | (*goal conversion*) | 
| 169 | fun gconv_rule cv i th = | |
| 170 | (case try (Thm.cprem_of th) i of | |
| 171 | SOME ct => | |
| 172 | let val eq = cv ct in | |
| 173 | if Thm.is_reflexive eq then th | |
| 174 | else Drule.with_subgoal i (fconv_rule (arg1_conv (K eq))) th | |
| 175 | end | |
| 176 |   | NONE => raise THM ("gconv_rule", i, [th]));
 | |
| 23411 
c524900454f3
Added eta_conv and eta-expansion conversion: waiting for it to be in thm.ML; exported is_refl
 chaieb parents: 
23169diff
changeset | 177 | |
| 22905 
dab6a898b47c
Conversions: primitive equality reasoning (from drule.ML);
 wenzelm parents: diff
changeset | 178 | end; | 
| 30136 
6a874aedb964
Made then_conv and else_conv available as infix operations.
 boehmes parents: 
29606diff
changeset | 179 | |
| 
6a874aedb964
Made then_conv and else_conv available as infix operations.
 boehmes parents: 
29606diff
changeset | 180 | structure BasicConv: BASIC_CONV = Conv; | 
| 
6a874aedb964
Made then_conv and else_conv available as infix operations.
 boehmes parents: 
29606diff
changeset | 181 | open BasicConv; |