18 val operator_names: string list |
18 val operator_names: string list |
19 end; |
19 end; |
20 |
20 |
21 signature COHERENT = |
21 signature COHERENT = |
22 sig |
22 sig |
23 val verbose: bool Unsynchronized.ref |
23 val trace: bool Config.T |
24 val coherent_tac: Proof.context -> thm list -> int -> tactic |
24 val coherent_tac: Proof.context -> thm list -> int -> tactic |
25 val setup: theory -> theory |
|
26 end; |
25 end; |
27 |
26 |
28 functor Coherent(Data: COHERENT_DATA) : COHERENT = |
27 functor Coherent(Data: COHERENT_DATA) : COHERENT = |
29 struct |
28 struct |
30 |
29 |
31 (** misc tools **) |
30 (** misc tools **) |
32 |
31 |
33 val verbose = Unsynchronized.ref false; |
32 val (trace, trace_setup) = Attrib.config_bool @{binding coherent_trace} (K false); |
34 |
33 fun cond_trace ctxt msg = if Config.get ctxt trace then tracing (msg ()) else (); |
35 fun message f = if !verbose then tracing (f ()) else (); |
|
36 |
34 |
37 datatype cl_prf = |
35 datatype cl_prf = |
38 ClPrf of thm * (Type.tyenv * Envir.tenv) * ((indexname * typ) * term) list * |
36 ClPrf of thm * (Type.tyenv * Envir.tenv) * ((indexname * typ) * term) list * |
39 int list * (term list * cl_prf) list; |
37 int list * (term list * cl_prf) list; |
40 |
38 |
145 end |
143 end |
146 |
144 |
147 and valid_cases _ _ _ _ _ _ _ [] = SOME [] |
145 and valid_cases _ _ _ _ _ _ _ [] = SOME [] |
148 | valid_cases ctxt rules goal dom facts nfacts nparams ((Ts, ts) :: ds) = |
146 | valid_cases ctxt rules goal dom facts nfacts nparams ((Ts, ts) :: ds) = |
149 let |
147 let |
150 val _ = message (fn () => "case " ^ commas (map (Syntax.string_of_term ctxt) ts)); |
148 val _ = cond_trace ctxt (fn () => "case " ^ commas (map (Syntax.string_of_term ctxt) ts)); |
151 val params = map_index (fn (i, T) => Free ("par" ^ string_of_int (nparams + i), T)) Ts; |
149 val params = map_index (fn (i, T) => Free ("par" ^ string_of_int (nparams + i), T)) Ts; |
152 val ts' = map_index (fn (i, t) => (subst_bounds (rev params, t), nfacts + i)) ts; |
150 val ts' = map_index (fn (i, t) => (subst_bounds (rev params, t), nfacts + i)) ts; |
153 val dom' = |
151 val dom' = |
154 fold (fn (T, p) => Typtab.map_default (T, []) (fn ps => ps @ [p])) (Ts ~~ params) dom; |
152 fold (fn (T, p) => Typtab.map_default (T, []) (fn ps => ps @ [p])) (Ts ~~ params) dom; |
155 val facts' = fold (fn (t, i) => Net.insert_term op = (t, (t, i))) ts' facts; |
153 val facts' = fold (fn (t, i) => Net.insert_term op = (t, (t, i))) ts' facts; |
163 end; |
161 end; |
164 |
162 |
165 |
163 |
166 (** proof replaying **) |
164 (** proof replaying **) |
167 |
165 |
168 fun thm_of_cl_prf thy goal asms (ClPrf (th, (tye, env), insts, is, prfs)) = |
166 fun thm_of_cl_prf ctxt goal asms (ClPrf (th, (tye, env), insts, is, prfs)) = |
169 let |
167 let |
|
168 val thy = Proof_Context.theory_of ctxt; |
|
169 val cert = Thm.cterm_of thy; |
|
170 val certT = Thm.ctyp_of thy; |
170 val _ = |
171 val _ = |
171 message (fn () => |
172 cond_trace ctxt (fn () => |
172 cat_lines ("asms:" :: map (Display.string_of_thm_global thy) asms) ^ "\n\n"); |
173 cat_lines ("asms:" :: map (Display.string_of_thm ctxt) asms) ^ "\n\n"); |
173 val th' = |
174 val th' = |
174 Drule.implies_elim_list |
175 Drule.implies_elim_list |
175 (Thm.instantiate |
176 (Thm.instantiate |
176 (map (fn (ixn, (S, T)) => |
177 (map (fn (ixn, (S, T)) => (certT (TVar ((ixn, S))), certT T)) (Vartab.dest tye), |
177 (Thm.ctyp_of thy (TVar ((ixn, S))), Thm.ctyp_of thy T)) |
|
178 (Vartab.dest tye), |
|
179 map (fn (ixn, (T, t)) => |
178 map (fn (ixn, (T, t)) => |
180 (Thm.cterm_of thy (Var (ixn, Envir.subst_type tye T)), |
179 (cert (Var (ixn, Envir.subst_type tye T)), cert t)) (Vartab.dest env) @ |
181 Thm.cterm_of thy t)) (Vartab.dest env) @ |
180 map (fn (ixnT, t) => (cert (Var ixnT), cert t)) insts) th) |
182 map (fn (ixnT, t) => |
|
183 (Thm.cterm_of thy (Var ixnT), Thm.cterm_of thy t)) insts) th) |
|
184 (map (nth asms) is); |
181 (map (nth asms) is); |
185 val (_, cases) = dest_elim (prop_of th'); |
182 val (_, cases) = dest_elim (prop_of th'); |
186 in |
183 in |
187 (case (cases, prfs) of |
184 (case (cases, prfs) of |
188 ([([], [_])], []) => th' |
185 ([([], [_])], []) => th' |
189 | ([([], [_])], [([], prf)]) => thm_of_cl_prf thy goal (asms @ [th']) prf |
186 | ([([], [_])], [([], prf)]) => thm_of_cl_prf ctxt goal (asms @ [th']) prf |
190 | _ => |
187 | _ => |
191 Drule.implies_elim_list |
188 Drule.implies_elim_list |
192 (Thm.instantiate (Thm.match |
189 (Thm.instantiate (Thm.match |
193 (Drule.strip_imp_concl (cprop_of th'), goal)) th') |
190 (Drule.strip_imp_concl (cprop_of th'), goal)) th') |
194 (map (thm_of_case_prf thy goal asms) (prfs ~~ cases))) |
191 (map (thm_of_case_prf ctxt goal asms) (prfs ~~ cases))) |
195 end |
192 end |
196 |
193 |
197 and thm_of_case_prf thy goal asms ((params, prf), (_, asms')) = |
194 and thm_of_case_prf ctxt goal asms ((params, prf), (_, asms')) = |
198 let |
195 let |
199 val cparams = map (cterm_of thy) params; |
196 val thy = Proof_Context.theory_of ctxt; |
200 val asms'' = map (cterm_of thy o curry subst_bounds (rev params)) asms'; |
197 val cert = Thm.cterm_of thy; |
|
198 val cparams = map cert params; |
|
199 val asms'' = map (cert o curry subst_bounds (rev params)) asms'; |
201 in |
200 in |
202 Drule.forall_intr_list cparams |
201 Drule.forall_intr_list cparams |
203 (Drule.implies_intr_list asms'' |
202 (Drule.implies_intr_list asms'' |
204 (thm_of_cl_prf thy goal (asms @ map Thm.assume asms'') prf)) |
203 (thm_of_cl_prf ctxt goal (asms @ map Thm.assume asms'') prf)) |
205 end; |
204 end; |
206 |
205 |
207 |
206 |
208 (** external interface **) |
207 (** external interface **) |
209 |
208 |
214 val xs = |
213 val xs = |
215 map (term_of o #2) params @ |
214 map (term_of o #2) params @ |
216 map (fn (_, s) => Free (s, the (Variable.default_type ctxt'' s))) |
215 map (fn (_, s) => Free (s, the (Variable.default_type ctxt'' s))) |
217 (rev (Variable.dest_fixes ctxt'')) (* FIXME !? *) |
216 (rev (Variable.dest_fixes ctxt'')) (* FIXME !? *) |
218 in |
217 in |
219 (case valid ctxt'' (map (mk_rule ctxt'') (prems' @ prems @ rules)) (term_of concl) |
218 (case |
220 (mk_dom xs) Net.empty 0 0 of |
219 valid ctxt'' (map (mk_rule ctxt'') (prems' @ prems @ rules)) (term_of concl) |
|
220 (mk_dom xs) Net.empty 0 0 of |
221 NONE => no_tac |
221 NONE => no_tac |
222 | SOME prf => rtac (thm_of_cl_prf (Proof_Context.theory_of ctxt'') concl [] prf) 1) |
222 | SOME prf => rtac (thm_of_cl_prf ctxt'' concl [] prf) 1) |
223 end) ctxt' 1) ctxt; |
223 end) ctxt' 1) ctxt; |
224 |
224 |
225 val setup = Method.setup @{binding coherent} |
225 val _ = Theory.setup |
226 (Attrib.thms >> (fn rules => fn ctxt => |
226 (trace_setup #> |
227 METHOD (fn facts => HEADGOAL (coherent_tac ctxt (facts @ rules))))) |
227 Method.setup @{binding coherent} |
228 "prove coherent formula"; |
228 (Attrib.thms >> (fn rules => fn ctxt => |
|
229 METHOD (fn facts => HEADGOAL (coherent_tac ctxt (facts @ rules))))) |
|
230 "prove coherent formula"); |
229 |
231 |
230 end; |
232 end; |