36 CANNOT be a ref, as the setting is used while Isabelle is built.*) |
36 CANNOT be a ref, as the setting is used while Isabelle is built.*) |
37 val abstract_lambdas = true; |
37 val abstract_lambdas = true; |
38 |
38 |
39 val trace_abs = ref false; |
39 val trace_abs = ref false; |
40 |
40 |
|
41 (*FIXME: move some of these functions to Pure/drule.ML *) |
|
42 |
|
43 fun freeze_thm th = #1 (Drule.freeze_thaw th); |
|
44 |
|
45 fun lhs_of th = |
|
46 case prop_of th of (Const("==",_) $ lhs $ _) => lhs |
|
47 | _ => raise THM ("lhs_of", 1, [th]); |
|
48 |
|
49 fun rhs_of th = |
|
50 case prop_of th of (Const("==",_) $ _ $ rhs) => rhs |
|
51 | _ => raise THM ("rhs_of", 1, [th]); |
|
52 |
41 (*Store definitions of abstraction functions, ensuring that identical right-hand |
53 (*Store definitions of abstraction functions, ensuring that identical right-hand |
42 sides are denoted by the same functions and thereby reducing the need for |
54 sides are denoted by the same functions and thereby reducing the need for |
43 extensionality in proofs. |
55 extensionality in proofs. |
44 FIXME! Store in theory data!!*) |
56 FIXME! Store in theory data!!*) |
45 val abstraction_cache = ref Net.empty : thm Net.net ref; |
57 |
|
58 fun seed th net = |
|
59 let val (_,ct) = Thm.dest_abs NONE (Drule.crhs_of th) |
|
60 in Net.insert_term eq_thm (term_of ct, th) net end; |
|
61 |
|
62 val abstraction_cache = ref |
|
63 (seed (thm"COMBI1") (seed (thm"COMBB1") (seed (thm"COMBK1") Net.empty))); |
46 |
64 |
47 (**** Transformation of Elimination Rules into First-Order Formulas****) |
65 (**** Transformation of Elimination Rules into First-Order Formulas****) |
48 |
66 |
49 (* a tactic used to prove an elim-rule. *) |
67 (* a tactic used to prove an elim-rule. *) |
50 fun elimRule_tac th = |
68 fun elimRule_tac th = |
84 let val disjs = foldr1 HOLogic.mk_disj (map (strip_concl [] [] concl) minors) |
102 let val disjs = foldr1 HOLogic.mk_disj (map (strip_concl [] [] concl) minors) |
85 in HOLogic.mk_imp (major, disjs) end; |
103 in HOLogic.mk_imp (major, disjs) end; |
86 |
104 |
87 (* convert an elim rule into an equivalent formula, of type term. *) |
105 (* convert an elim rule into an equivalent formula, of type term. *) |
88 fun elimR2Fol elimR = |
106 fun elimR2Fol elimR = |
89 let val elimR' = #1 (Drule.freeze_thaw elimR) |
107 let val elimR' = freeze_thm elimR |
90 val (prems,concl) = (prems_of elimR', concl_of elimR') |
108 val (prems,concl) = (prems_of elimR', concl_of elimR') |
91 val cv = case concl of (*conclusion variable*) |
109 val cv = case concl of (*conclusion variable*) |
92 Const("Trueprop",_) $ (v as Free(_,Type("bool",[]))) => v |
110 Const("Trueprop",_) $ (v as Free(_,Type("bool",[]))) => v |
93 | v as Free(_, Type("prop",[])) => v |
111 | v as Free(_, Type("prop",[])) => v |
94 | _ => raise ELIMR2FOL |
112 | _ => raise ELIMR2FOL |
205 fun mkvar a = cterm_of thy (Var((a,0),ty)); |
223 fun mkvar a = cterm_of thy (Var((a,0),ty)); |
206 in |
224 in |
207 fun xfun_cong x = Thm.instantiate ([], [(cx, mkvar x)]) fun_cong' |
225 fun xfun_cong x = Thm.instantiate ([], [(cx, mkvar x)]) fun_cong' |
208 end; |
226 end; |
209 |
227 |
210 (*Removes the lambdas from an equation of the form t = (%x. u)*) |
228 (*Removes the lambdas from an equation of the form t = (%x. u). A non-negative n, |
211 fun strip_lambdas th = |
229 serves as an upper bound on how many to remove.*) |
212 case prop_of th of |
230 fun strip_lambdas 0 th = th |
213 _ $ (Const ("op =", _) $ _ $ Abs (x,_,_)) => |
231 | strip_lambdas n th = |
214 strip_lambdas (#1 (Drule.freeze_thaw (th RS xfun_cong x))) |
232 case prop_of th of |
215 | _ => th; |
233 _ $ (Const ("op =", _) $ _ $ Abs (x,_,_)) => |
|
234 strip_lambdas (n-1) (freeze_thm (th RS xfun_cong x)) |
|
235 | _ => th; |
216 |
236 |
217 (*Convert meta- to object-equality. Fails for theorems like split_comp_eq, |
237 (*Convert meta- to object-equality. Fails for theorems like split_comp_eq, |
218 where some types have the empty sort.*) |
238 where some types have the empty sort.*) |
219 fun object_eq th = th RS def_imp_eq |
239 fun mk_object_eq th = th RS def_imp_eq |
220 handle THM _ => error ("Theorem contains empty sort: " ^ string_of_thm th); |
240 handle THM _ => error ("Theorem contains empty sort: " ^ string_of_thm th); |
221 |
|
222 (*Contract all eta-redexes in the theorem, lest they give rise to needless abstractions*) |
|
223 fun eta_conversion_rule th = |
|
224 equal_elim (eta_conversion (cprop_of th)) th; |
|
225 |
|
226 fun crhs_of th = |
|
227 case Drule.strip_comb (cprop_of th) of |
|
228 (f, [_, rhs]) => |
|
229 (case term_of f of Const ("==", _) => rhs |
|
230 | _ => raise THM ("crhs_of", 0, [th])) |
|
231 | _ => raise THM ("crhs_of", 1, [th]); |
|
232 |
|
233 fun lhs_of th = |
|
234 case prop_of th of (Const("==",_) $ lhs $ _) => lhs |
|
235 | _ => raise THM ("lhs_of", 1, [th]); |
|
236 |
|
237 fun rhs_of th = |
|
238 case prop_of th of (Const("==",_) $ _ $ rhs) => rhs |
|
239 | _ => raise THM ("rhs_of", 1, [th]); |
|
240 |
241 |
241 (*Apply a function definition to an argument, beta-reducing the result.*) |
242 (*Apply a function definition to an argument, beta-reducing the result.*) |
242 fun beta_comb cf x = |
243 fun beta_comb cf x = |
243 let val th1 = combination cf (reflexive x) |
244 let val th1 = combination cf (reflexive x) |
244 val th2 = beta_conversion false (crhs_of th1) |
245 val th2 = beta_conversion false (Drule.crhs_of th1) |
245 in transitive th1 th2 end; |
246 in transitive th1 th2 end; |
246 |
247 |
247 (*Apply a function definition to arguments, beta-reducing along the way.*) |
248 (*Apply a function definition to arguments, beta-reducing along the way.*) |
248 fun list_combination cf [] = cf |
249 fun list_combination cf [] = cf |
249 | list_combination cf (x::xs) = list_combination (beta_comb cf x) xs; |
250 | list_combination cf (x::xs) = list_combination (beta_comb cf x) xs; |
278 | lambda_list (v::vs) u = lambda v (lambda_list vs u); |
279 | lambda_list (v::vs) u = lambda v (lambda_list vs u); |
279 |
280 |
280 fun abstract_rule_list [] [] th = th |
281 fun abstract_rule_list [] [] th = th |
281 | abstract_rule_list (v::vs) (ct::cts) th = abstract_rule v ct (abstract_rule_list vs cts th) |
282 | abstract_rule_list (v::vs) (ct::cts) th = abstract_rule v ct (abstract_rule_list vs cts th) |
282 | abstract_rule_list _ _ th = raise THM ("abstract_rule_list", 0, [th]); |
283 | abstract_rule_list _ _ th = raise THM ("abstract_rule_list", 0, [th]); |
|
284 |
|
285 |
|
286 val Envir.Envir {asol = tenv0, iTs = tyenv0, ...} = Envir.empty 0 |
|
287 |
|
288 (*Does an existing abstraction definition have an RHS that matches the one we need now?*) |
|
289 fun match_rhs thy0 t th = |
|
290 let val thy = theory_of_thm th |
|
291 val _ = if !trace_abs then warning ("match_rhs: " ^ string_of_cterm (cterm_of thy t) ^ |
|
292 " against\n" ^ string_of_thm th) else (); |
|
293 val (tyenv,tenv) = if Context.joinable (thy0,thy) then |
|
294 Pattern.first_order_match thy (rhs_of th, t) (tyenv0,tenv0) |
|
295 else raise Pattern.MATCH |
|
296 val term_insts = map Meson.term_pair_of (Vartab.dest tenv) |
|
297 val ct_pairs = if forall lambda_free (map #2 term_insts) then |
|
298 map (pairself (cterm_of thy)) term_insts |
|
299 else raise Pattern.MATCH (*Cannot allow lambdas in the instantiation*) |
|
300 fun ctyp2 (ixn, (S, T)) = (ctyp_of thy (TVar (ixn, S)), ctyp_of thy T) |
|
301 val th' = cterm_instantiate ct_pairs th |
|
302 in SOME (th, instantiate (map ctyp2 (Vartab.dest tyenv), []) th') end |
|
303 handle _ => NONE; |
283 |
304 |
284 (*Traverse a theorem, declaring abstraction function definitions. String s is the suggested |
305 (*Traverse a theorem, declaring abstraction function definitions. String s is the suggested |
285 prefix for the constants. Resulting theory is returned in the first theorem. *) |
306 prefix for the constants. Resulting theory is returned in the first theorem. *) |
286 fun declare_absfuns th = |
307 fun declare_absfuns th = |
287 let fun abstract thy ct = |
308 let fun abstract thy ct = |
291 Abs _ => |
312 Abs _ => |
292 let val cname = Name.internal (gensym "abs_"); |
313 let val cname = Name.internal (gensym "abs_"); |
293 val _ = assert_eta_free ct; |
314 val _ = assert_eta_free ct; |
294 val (cvs,cta) = dest_abs_list ct |
315 val (cvs,cta) = dest_abs_list ct |
295 val (vs,Tvs) = ListPair.unzip (map (dest_Free o term_of) cvs) |
316 val (vs,Tvs) = ListPair.unzip (map (dest_Free o term_of) cvs) |
|
317 val _ = if !trace_abs then warning ("Nested lambda: " ^ string_of_cterm cta) else (); |
296 val (u'_th,defs) = abstract thy cta |
318 val (u'_th,defs) = abstract thy cta |
297 val cu' = crhs_of u'_th |
319 val _ = if !trace_abs then warning ("Returned " ^ string_of_thm u'_th) else (); |
298 val abs_v_u = lambda_list (map term_of cvs) (term_of cu') |
320 val cu' = Drule.crhs_of u'_th |
|
321 val u' = term_of cu' |
|
322 val abs_v_u = lambda_list (map term_of cvs) u' |
299 (*get the formal parameters: ALL variables free in the term*) |
323 (*get the formal parameters: ALL variables free in the term*) |
300 val args = term_frees abs_v_u |
324 val args = term_frees abs_v_u |
|
325 val _ = if !trace_abs then warning (Int.toString (length args) ^ " arguments") else (); |
301 val rhs = list_abs_free (map dest_Free args, abs_v_u) |
326 val rhs = list_abs_free (map dest_Free args, abs_v_u) |
302 (*Forms a lambda-abstraction over the formal parameters*) |
327 (*Forms a lambda-abstraction over the formal parameters*) |
303 val v_rhs = Logic.varify rhs |
328 val v_rhs = Logic.varify rhs |
304 val (ax,thy) = |
329 val _ = if !trace_abs then warning ("Looking up " ^ string_of_cterm cu') else (); |
305 case List.find (fn ax => v_rhs aconv rhs_of ax) |
330 val (ax,ax',thy) = |
306 (Net.match_term (!abstraction_cache) v_rhs) of |
331 case List.mapPartial (match_rhs thy abs_v_u) (Net.match_term (!abstraction_cache) u') |
307 SOME ax => (ax,thy) (*cached axiom, current theory*) |
332 of |
308 | NONE => |
333 (ax,ax')::_ => |
309 let val Ts = map type_of args |
334 (if !trace_abs then warning ("Re-using axiom " ^ string_of_thm ax) else (); |
|
335 (ax,ax',thy)) |
|
336 | [] => |
|
337 let val _ = if !trace_abs then warning "Lookup was empty" else (); |
|
338 val Ts = map type_of args |
310 val cT = Ts ---> (Tvs ---> typ_of (ctyp_of_term cu')) |
339 val cT = Ts ---> (Tvs ---> typ_of (ctyp_of_term cu')) |
311 val thy = theory_of_thm u'_th |
340 val thy = theory_of_thm u'_th |
312 val c = Const (Sign.full_name thy cname, cT) |
341 val c = Const (Sign.full_name thy cname, cT) |
313 val thy = Sign.add_consts_authentic [(cname, cT, NoSyn)] thy |
342 val thy = Sign.add_consts_authentic [(cname, cT, NoSyn)] thy |
314 (*Theory is augmented with the constant, |
343 (*Theory is augmented with the constant, |
315 then its definition*) |
344 then its definition*) |
316 val cdef = cname ^ "_def" |
345 val cdef = cname ^ "_def" |
317 val thy = Theory.add_defs_i false false |
346 val thy = Theory.add_defs_i false false |
318 [(cdef, equals cT $ c $ rhs)] thy |
347 [(cdef, equals cT $ c $ rhs)] thy |
319 val ax = get_axiom thy cdef |
348 val _ = if !trace_abs then (warning ("Definition is " ^ |
320 val _ = abstraction_cache := Net.insert_term eq_absdef (v_rhs,ax) |
349 string_of_thm (get_axiom thy cdef))) |
321 (!abstraction_cache) |
350 else (); |
|
351 val ax = get_axiom thy cdef |> freeze_thm |
|
352 |> mk_object_eq |> strip_lambdas (length args) |
|
353 |> mk_meta_eq |> Meson.generalize |
|
354 val (_,ax') = Option.valOf (match_rhs thy abs_v_u ax) |
|
355 val _ = if !trace_abs then |
|
356 (warning ("Declaring: " ^ string_of_thm ax); |
|
357 warning ("Instance: " ^ string_of_thm ax')) |
|
358 else (); |
|
359 val _ = abstraction_cache := Net.insert_term eq_absdef |
|
360 ((Logic.varify u'), ax) (!abstraction_cache) |
322 handle Net.INSERT => |
361 handle Net.INSERT => |
323 raise THM ("declare_absfuns: INSERT", 0, [th,u'_th,ax]) |
362 raise THM ("declare_absfuns: INSERT", 0, [th,u'_th,ax]) |
324 in (ax,thy) end |
363 in (ax,ax',thy) end |
325 val _ = assert (v_rhs aconv rhs_of ax) "declare_absfuns: rhs mismatch" |
364 in if !trace_abs then warning ("Lookup result: " ^ string_of_thm ax') else (); |
326 val def = #1 (Drule.freeze_thaw ax) |
365 (transitive (abstract_rule_list vs cvs u'_th) (symmetric ax'), ax::defs) end |
327 val def_args = list_combination def (map (cterm_of thy) args) |
|
328 in (transitive (abstract_rule_list vs cvs u'_th) (symmetric def_args), |
|
329 def :: defs) end |
|
330 | (t1$t2) => |
366 | (t1$t2) => |
331 let val (ct1,ct2) = Thm.dest_comb ct |
367 let val (ct1,ct2) = Thm.dest_comb ct |
332 val (th1,defs1) = abstract thy ct1 |
368 val (th1,defs1) = abstract thy ct1 |
333 val (th2,defs2) = abstract (theory_of_thm th1) ct2 |
369 val (th2,defs2) = abstract (theory_of_thm th1) ct2 |
334 in (combination th1 th2, defs1@defs2) end |
370 in (combination th1 th2, defs1@defs2) end |
335 val _ = if !trace_abs then warning (string_of_thm th) else (); |
371 val _ = if !trace_abs then warning ("declare_absfuns, Abstracting: " ^ string_of_thm th) else (); |
336 val (eqth,defs) = abstract (theory_of_thm th) (cprop_of th) |
372 val (eqth,defs) = abstract (theory_of_thm th) (cprop_of th) |
337 val ths = equal_elim eqth th :: |
373 val ths = equal_elim eqth th :: map (strip_lambdas ~1 o mk_object_eq o freeze_thm) defs |
338 map (forall_intr_vars o strip_lambdas o object_eq) defs |
374 val _ = if !trace_abs then warning ("declare_absfuns, Result: " ^ string_of_thm (hd ths)) else (); |
339 in (theory_of_thm eqth, ths) end; |
375 in (theory_of_thm eqth, map Drule.eta_contraction_rule ths) end; |
340 |
376 |
341 fun name_of def = SOME (#1 (dest_Free (lhs_of def))) handle _ => NONE; |
377 fun name_of def = SOME (#1 (dest_Free (lhs_of def))) handle _ => NONE; |
342 |
378 |
343 (*A name is valid provided it isn't the name of a defined abstraction.*) |
379 (*A name is valid provided it isn't the name of a defined abstraction.*) |
344 fun valid_name defs (Free(x,T)) = not (x mem_string (List.mapPartial name_of defs)) |
380 fun valid_name defs (Free(x,T)) = not (x mem_string (List.mapPartial name_of defs)) |
354 Abs (_,T,u) => |
390 Abs (_,T,u) => |
355 let val _ = assert_eta_free ct; |
391 let val _ = assert_eta_free ct; |
356 val (cvs,cta) = dest_abs_list ct |
392 val (cvs,cta) = dest_abs_list ct |
357 val (vs,Tvs) = ListPair.unzip (map (dest_Free o term_of) cvs) |
393 val (vs,Tvs) = ListPair.unzip (map (dest_Free o term_of) cvs) |
358 val (u'_th,defs) = abstract cta |
394 val (u'_th,defs) = abstract cta |
359 val cu' = crhs_of u'_th |
395 val cu' = Drule.crhs_of u'_th |
|
396 val u' = term_of cu' |
360 (*Could use Thm.cabs instead of lambda to work at level of cterms*) |
397 (*Could use Thm.cabs instead of lambda to work at level of cterms*) |
361 val abs_v_u = lambda_list (map term_of cvs) (term_of cu') |
398 val abs_v_u = lambda_list (map term_of cvs) (term_of cu') |
362 (*get the formal parameters: free variables not present in the defs |
399 (*get the formal parameters: free variables not present in the defs |
363 (to avoid taking abstraction function names as parameters) *) |
400 (to avoid taking abstraction function names as parameters) *) |
364 val args = filter (valid_name defs) (term_frees abs_v_u) |
401 val args = filter (valid_name defs) (term_frees abs_v_u) |
365 val crhs = list_cabs (map cterm args, cterm abs_v_u) |
402 val crhs = list_cabs (map cterm args, cterm abs_v_u) |
366 (*Forms a lambda-abstraction over the formal parameters*) |
403 (*Forms a lambda-abstraction over the formal parameters*) |
367 val rhs = term_of crhs |
404 val rhs = term_of crhs |
368 val def = (*FIXME: can we also reuse the const-abstractions?*) |
405 val (ax,ax') = |
369 case List.find (fn ax => rhs aconv rhs_of ax andalso |
406 case List.mapPartial (match_rhs thy abs_v_u) |
370 Context.joinable (thy, theory_of_thm ax)) |
407 (Net.match_term (!abstraction_cache) u') of |
371 (Net.match_term (!abstraction_cache) rhs) of |
408 (ax,ax')::_ => |
372 SOME ax => ax |
409 (if !trace_abs then warning ("Re-using axiom " ^ string_of_thm ax) else (); |
373 | NONE => |
410 (ax,ax')) |
|
411 | [] => |
374 let val Ts = map type_of args |
412 let val Ts = map type_of args |
375 val const_ty = Ts ---> (Tvs ---> typ_of (ctyp_of_term cu')) |
413 val const_ty = Ts ---> (Tvs ---> typ_of (ctyp_of_term cu')) |
376 val c = Free (gensym "abs_", const_ty) |
414 val c = Free (gensym "abs_", const_ty) |
377 val ax = assume (Thm.capply (cterm (equals const_ty $ c)) crhs) |
415 val ax = assume (Thm.capply (cterm (equals const_ty $ c)) crhs) |
|
416 |> mk_object_eq |> strip_lambdas (length args) |
|
417 |> mk_meta_eq |> Meson.generalize |
|
418 val (_,ax') = Option.valOf (match_rhs thy abs_v_u ax) |
378 val _ = abstraction_cache := Net.insert_term eq_absdef (rhs,ax) |
419 val _ = abstraction_cache := Net.insert_term eq_absdef (rhs,ax) |
379 (!abstraction_cache) |
420 (!abstraction_cache) |
380 handle Net.INSERT => |
421 handle Net.INSERT => |
381 raise THM ("assume_absfuns: INSERT", 0, [th,u'_th,ax]) |
422 raise THM ("assume_absfuns: INSERT", 0, [th,u'_th,ax]) |
382 in ax end |
423 in (ax,ax') end |
383 val _ = assert (rhs aconv rhs_of def) "assume_absfuns: rhs mismatch" |
424 in if !trace_abs then warning ("Lookup result: " ^ string_of_thm ax') else (); |
384 val def_args = list_combination def (map cterm args) |
425 (transitive (abstract_rule_list vs cvs u'_th) (symmetric ax'), ax::defs) end |
385 in (transitive (abstract_rule_list vs cvs u'_th) (symmetric def_args), |
|
386 def :: defs) end |
|
387 | (t1$t2) => |
426 | (t1$t2) => |
388 let val (ct1,ct2) = Thm.dest_comb ct |
427 let val (ct1,ct2) = Thm.dest_comb ct |
389 val (t1',defs1) = abstract ct1 |
428 val (t1',defs1) = abstract ct1 |
390 val (t2',defs2) = abstract ct2 |
429 val (t2',defs2) = abstract ct2 |
391 in (combination t1' t2', defs1@defs2) end |
430 in (combination t1' t2', defs1@defs2) end |
|
431 val _ = if !trace_abs then warning ("assume_absfuns, Abstracting: " ^ string_of_thm th) else (); |
392 val (eqth,defs) = abstract (cprop_of th) |
432 val (eqth,defs) = abstract (cprop_of th) |
393 in equal_elim eqth th :: |
433 val ths = equal_elim eqth th :: map (strip_lambdas ~1 o mk_object_eq o freeze_thm) defs |
394 map (forall_intr_vars o strip_lambdas o object_eq) defs |
434 val _ = if !trace_abs then warning ("assume_absfuns, Result: " ^ string_of_thm (hd ths)) else (); |
395 end; |
435 in map Drule.eta_contraction_rule ths end; |
396 |
436 |
397 |
437 |
398 (*cterms are used throughout for efficiency*) |
438 (*cterms are used throughout for efficiency*) |
399 val cTrueprop = Thm.cterm_of HOL.thy HOLogic.Trueprop; |
439 val cTrueprop = Thm.cterm_of HOL.thy HOLogic.Trueprop; |
400 |
440 |
410 |
450 |
411 (*Given the definition of a Skolem function, return a theorem to replace |
451 (*Given the definition of a Skolem function, return a theorem to replace |
412 an existential formula by a use of that function. |
452 an existential formula by a use of that function. |
413 Example: "EX x. x : A & x ~: B ==> sko A B : A & sko A B ~: B" [.] *) |
453 Example: "EX x. x : A & x ~: B ==> sko A B : A & sko A B ~: B" [.] *) |
414 fun skolem_of_def def = |
454 fun skolem_of_def def = |
415 let val (c,rhs) = Drule.dest_equals (cprop_of (#1 (Drule.freeze_thaw def))) |
455 let val (c,rhs) = Drule.dest_equals (cprop_of (freeze_thm def)) |
416 val (ch, frees) = c_variant_abs_multi (rhs, []) |
456 val (ch, frees) = c_variant_abs_multi (rhs, []) |
417 val (chilbert,cabs) = Thm.dest_comb ch |
457 val (chilbert,cabs) = Thm.dest_comb ch |
418 val {sign,t, ...} = rep_cterm chilbert |
458 val {sign,t, ...} = rep_cterm chilbert |
419 val T = case t of Const ("Hilbert_Choice.Eps", Type("fun",[_,T])) => T |
459 val T = case t of Const ("Hilbert_Choice.Eps", Type("fun",[_,T])) => T |
420 | _ => raise THM ("skolem_of_def: expected Eps", 0, [def]) |
460 | _ => raise THM ("skolem_of_def: expected Eps", 0, [def]) |
426 |> forall_intr_list frees |
466 |> forall_intr_list frees |
427 |> forall_elim_vars 0 (*Introduce Vars, but don't discharge defs.*) |
467 |> forall_elim_vars 0 (*Introduce Vars, but don't discharge defs.*) |
428 |> Thm.varifyT |
468 |> Thm.varifyT |
429 end; |
469 end; |
430 |
470 |
431 (*Converts an Isabelle theorem (intro, elim or simp format) into nnf.*) |
471 (*Converts an Isabelle theorem (intro, elim or simp format, even higher-order) into NNF.*) |
432 (*It now works for HOL too. *) |
|
433 fun to_nnf th = |
472 fun to_nnf th = |
434 th |> transfer_to_Reconstruction |
473 th |> transfer_to_Reconstruction |
435 |> transform_elim |> zero_var_indexes |> Drule.freeze_thaw |> #1 |
474 |> transform_elim |> zero_var_indexes |> freeze_thm |
436 |> ObjectLogic.atomize_thm |> make_nnf |> strip_lambdas; |
475 |> ObjectLogic.atomize_thm |> make_nnf |> strip_lambdas ~1; |
437 |
476 |
438 (*The cache prevents repeated clausification of a theorem, |
477 (*The cache prevents repeated clausification of a theorem, |
439 and also repeated declaration of Skolem functions*) |
478 and also repeated declaration of Skolem functions*) |
440 (* FIXME better use Termtab!? No, we MUST use theory data!!*) |
479 (* FIXME better use Termtab!? No, we MUST use theory data!!*) |
441 val clause_cache = ref (Symtab.empty : (thm * thm list) Symtab.table) |
480 val clause_cache = ref (Symtab.empty : (thm * thm list) Symtab.table) |
443 |
482 |
444 (*Generate Skolem functions for a theorem supplied in nnf*) |
483 (*Generate Skolem functions for a theorem supplied in nnf*) |
445 fun skolem_of_nnf th = |
484 fun skolem_of_nnf th = |
446 map (skolem_of_def o assume o (cterm_of (theory_of_thm th))) (assume_skofuns th); |
485 map (skolem_of_def o assume o (cterm_of (theory_of_thm th))) (assume_skofuns th); |
447 |
486 |
448 fun assert_lambda_free ths = assert (forall (lambda_free o prop_of) ths); |
487 fun assert_lambda_free ths msg = |
|
488 case filter (not o lambda_free o prop_of) ths of |
|
489 [] => () |
|
490 | ths' => error (msg ^ "\n" ^ space_implode "\n" (map string_of_thm ths')); |
449 |
491 |
450 fun assume_abstract th = |
492 fun assume_abstract th = |
451 if lambda_free (prop_of th) then [th] |
493 if lambda_free (prop_of th) then [th] |
452 else th |> eta_conversion_rule |> assume_absfuns |
494 else th |> Drule.eta_contraction_rule |> assume_absfuns |
453 |> tap (fn ths => assert_lambda_free ths "assume_abstract: lambdas") |
495 |> tap (fn ths => assert_lambda_free ths "assume_abstract: lambdas") |
454 |
496 |
455 (*Replace lambdas by assumed function definitions in the theorems*) |
497 (*Replace lambdas by assumed function definitions in the theorems*) |
456 fun assume_abstract_list ths = |
498 fun assume_abstract_list ths = |
457 if abstract_lambdas then List.concat (map assume_abstract ths) |
499 if abstract_lambdas then List.concat (map assume_abstract ths) |
458 else map eta_conversion_rule ths; |
500 else map Drule.eta_contraction_rule ths; |
459 |
501 |
460 (*Replace lambdas by declared function definitions in the theorems*) |
502 (*Replace lambdas by declared function definitions in the theorems*) |
461 fun declare_abstract' (thy, []) = (thy, []) |
503 fun declare_abstract' (thy, []) = (thy, []) |
462 | declare_abstract' (thy, th::ths) = |
504 | declare_abstract' (thy, th::ths) = |
463 let val (thy', th_defs) = |
505 let val (thy', th_defs) = |
464 if lambda_free (prop_of th) then (thy, [th]) |
506 if lambda_free (prop_of th) then (thy, [th]) |
465 else |
507 else |
466 th |> zero_var_indexes |> Drule.freeze_thaw |> #1 |
508 th |> zero_var_indexes |> freeze_thm |
467 |> eta_conversion_rule |> transfer thy |> declare_absfuns |
509 |> Drule.eta_contraction_rule |> transfer thy |> declare_absfuns |
468 val _ = assert_lambda_free th_defs "declare_abstract: lambdas" |
510 val _ = assert_lambda_free th_defs "declare_abstract: lambdas" |
469 val (thy'', ths') = declare_abstract' (thy', ths) |
511 val (thy'', ths') = declare_abstract' (thy', ths) |
470 in (thy'', th_defs @ ths') end; |
512 in (thy'', th_defs @ ths') end; |
471 |
513 |
472 (*FIXME DELETE if we decide to switch to abstractions*) |
514 (*FIXME DELETE if we decide to switch to abstractions*) |
473 fun declare_abstract (thy, ths) = |
515 fun declare_abstract (thy, ths) = |
474 if abstract_lambdas then declare_abstract' (thy, ths) |
516 if abstract_lambdas then declare_abstract' (thy, ths) |
475 else (thy, map eta_conversion_rule ths); |
517 else (thy, map Drule.eta_contraction_rule ths); |
476 |
518 |
477 (*Skolemize a named theorem, with Skolem functions as additional premises.*) |
519 (*Skolemize a named theorem, with Skolem functions as additional premises.*) |
478 (*also works for HOL*) |
520 (*also works for HOL*) |
479 fun skolem_thm th = |
521 fun skolem_thm th = |
480 let val nnfth = to_nnf th |
522 let val nnfth = to_nnf th |