20 |
20 |
21 structure FundefPrep : FUNDEF_PREP = |
21 structure FundefPrep : FUNDEF_PREP = |
22 struct |
22 struct |
23 |
23 |
24 |
24 |
|
25 open FundefLib |
25 open FundefCommon |
26 open FundefCommon |
26 open FundefAbbrev |
27 open FundefAbbrev |
27 |
28 |
28 (* Theory dependencies. *) |
29 (* Theory dependencies. *) |
29 val Pair_inject = thm "Product_Type.Pair_inject"; |
30 val Pair_inject = thm "Product_Type.Pair_inject"; |
30 |
31 |
31 val acc_induct_rule = thm "Accessible_Part.acc_induct_rule" |
32 val acc_induct_rule = thm "FunDef.accP_induct_rule" |
32 |
33 |
33 val ex1_implies_ex = thm "FunDef.fundef_ex1_existence" |
34 val ex1_implies_ex = thm "FunDef.fundef_ex1_existence" |
34 val ex1_implies_un = thm "FunDef.fundef_ex1_uniqueness" |
35 val ex1_implies_un = thm "FunDef.fundef_ex1_uniqueness" |
35 val ex1_implies_iff = thm "FunDef.fundef_ex1_iff" |
36 val ex1_implies_iff = thm "FunDef.fundef_ex1_iff" |
36 |
37 |
141 |> fold (forall_elim o cert o Free) rcfix |
142 |> fold (forall_elim o cert o Free) rcfix |
142 |> fold implies_elim_swp ags |
143 |> fold implies_elim_swp ags |
143 |> fold implies_elim_swp rcassm |
144 |> fold implies_elim_swp rcassm |
144 |
145 |
145 val h_assum = |
146 val h_assum = |
146 mk_relmem (rcarg, h $ rcarg) G |
147 Trueprop (G $ rcarg $ (h $ rcarg)) |
147 |> fold_rev (curry Logic.mk_implies o prop_of) rcassm |
148 |> fold_rev (curry Logic.mk_implies o prop_of) rcassm |
148 |> fold_rev (mk_forall o Free) rcfix |
149 |> fold_rev (mk_forall o Free) rcfix |
149 |> Pattern.rewrite_term (ProofContext.theory_of ctxt) [(f, h)] [] |
150 |> Pattern.rewrite_term (ProofContext.theory_of ctxt) [(f, h)] [] |
150 |> abstract_over_list (rev qs) |
151 |> abstract_over_list (rev qs) |
151 in |
152 in |
270 |> fold implies_elim_swp agsj' |
271 |> fold implies_elim_swp agsj' |
271 |> fold implies_elim_swp Ghsj' |
272 |> fold implies_elim_swp Ghsj' |
272 |
273 |
273 val y_eq_rhsj'h = assume (cterm_of thy (Trueprop (mk_eq (y, rhsj'h)))) |
274 val y_eq_rhsj'h = assume (cterm_of thy (Trueprop (mk_eq (y, rhsj'h)))) |
274 val lhsi_eq_lhsj' = assume (cterm_of thy (Trueprop (mk_eq (lhsi, lhsj')))) (* lhs_i = lhs_j' |-- lhs_i = lhs_j' *) |
275 val lhsi_eq_lhsj' = assume (cterm_of thy (Trueprop (mk_eq (lhsi, lhsj')))) (* lhs_i = lhs_j' |-- lhs_i = lhs_j' *) |
275 |
|
276 val eq_pairs = assume (cterm_of thy (Trueprop (mk_eq (mk_prod (lhsi, y), mk_prod (lhsj',rhsj'h))))) |
|
277 in |
276 in |
278 (trans OF [case_hyp, lhsi_eq_lhsj']) (* lhs_i = lhs_j' |-- x = lhs_j' *) |
277 (trans OF [case_hyp, lhsi_eq_lhsj']) (* lhs_i = lhs_j' |-- x = lhs_j' *) |
279 |> implies_elim RLj_import (* Rj1' ... Rjk', lhs_i = lhs_j' |-- rhs_j'_h = rhs_j'_f *) |
278 |> implies_elim RLj_import (* Rj1' ... Rjk', lhs_i = lhs_j' |-- rhs_j'_h = rhs_j'_f *) |
280 |> (fn it => trans OF [it, compat]) (* lhs_i = lhs_j', Gj', Rj1' ... Rjk' |-- rhs_j'_h = rhs_i_f *) |
279 |> (fn it => trans OF [it, compat]) (* lhs_i = lhs_j', Gj', Rj1' ... Rjk' |-- rhs_j'_h = rhs_i_f *) |
281 |> (fn it => trans OF [y_eq_rhsj'h, it]) (* lhs_i = lhs_j', Gj', Rj1' ... Rjk', y = rhs_j_h' |-- y = rhs_i_f *) |
280 |> (fn it => trans OF [y_eq_rhsj'h, it]) (* lhs_i = lhs_j', Gj', Rj1' ... Rjk', y = rhs_j_h' |-- y = rhs_i_f *) |
|
281 |> fold_rev (implies_intr o cprop_of) Ghsj' |
|
282 |> fold_rev (implies_intr o cprop_of) agsj' (* lhs_i = lhs_j' , y = rhs_j_h' |-- Gj', Rj1'...Rjk' ==> y = rhs_i_f *) |
282 |> implies_intr (cprop_of y_eq_rhsj'h) |
283 |> implies_intr (cprop_of y_eq_rhsj'h) |
283 |> implies_intr (cprop_of lhsi_eq_lhsj') (* Gj', Rj1' ... Rjk' |-- [| lhs_i = lhs_j', y = rhs_j_h' |] ==> y = rhs_i_f *) |
284 |> implies_intr (cprop_of lhsi_eq_lhsj') |
284 |> (fn it => Drule.compose_single(it, 2, Pair_inject)) (* Gj', Rj1' ... Rjk' |-- (lhs_i, y) = (lhs_j', rhs_j_h') ==> y = rhs_i_f *) |
|
285 |> implies_elim_swp eq_pairs |
|
286 |> fold_rev (implies_intr o cprop_of) Ghsj' |
|
287 |> fold_rev (implies_intr o cprop_of) agsj' (* Gj', Rj1', ..., Rjk' ==> (lhs_i, y) = (lhs_j', rhs_j_h') ==> y = rhs_i_f *) |
|
288 |> implies_intr (cprop_of eq_pairs) |
|
289 |> fold_rev forall_intr (cterm_of thy h :: cqsj') |
285 |> fold_rev forall_intr (cterm_of thy h :: cqsj') |
290 end |
286 end |
291 |
287 |
292 |
288 |
293 |
289 |
303 |> fold_rev (implies_intr o cprop_of) CCas |
299 |> fold_rev (implies_intr o cprop_of) CCas |
304 |> fold_rev (forall_intr o cterm_of thy o Free) RIvs |
300 |> fold_rev (forall_intr o cterm_of thy o Free) RIvs |
305 |
301 |
306 val existence = fold (curry op COMP o prep_RC) RCs lGI |
302 val existence = fold (curry op COMP o prep_RC) RCs lGI |
307 |
303 |
308 val a = cterm_of thy (mk_prod (lhs, y)) |
|
309 val P = cterm_of thy (mk_eq (y, rhsC)) |
304 val P = cterm_of thy (mk_eq (y, rhsC)) |
310 val a_in_G = assume (cterm_of thy (Trueprop (mk_mem (term_of a, G)))) |
305 val G_lhs_y = assume (cterm_of thy (Trueprop (G $ lhs $ y))) |
311 |
306 |
312 val unique_clauses = map2 (mk_uniqueness_clause thy globals f compat_store clausei) clauses rep_lemmas |
307 val unique_clauses = map2 (mk_uniqueness_clause thy globals f compat_store clausei) clauses rep_lemmas |
313 |
308 |
314 val uniqueness = G_cases |
309 val uniqueness = G_cases |
315 |> forall_elim a |
310 |> forall_elim (cterm_of thy lhs) |
|
311 |> forall_elim (cterm_of thy y) |
316 |> forall_elim P |
312 |> forall_elim P |
317 |> implies_elim_swp a_in_G |
313 |> implies_elim_swp G_lhs_y |
318 |> fold implies_elim_swp unique_clauses |
314 |> fold implies_elim_swp unique_clauses |
319 |> implies_intr (cprop_of a_in_G) |
315 |> implies_intr (cprop_of G_lhs_y) |
320 |> forall_intr (cterm_of thy y) |
316 |> forall_intr (cterm_of thy y) |
321 |
317 |
322 val P2 = cterm_of thy (lambda y (mk_mem (mk_prod (lhs, y), G))) (* P2 y := (lhs, y): G *) |
318 val P2 = cterm_of thy (lambda y (G $ lhs $ y)) (* P2 y := (lhs, y): G *) |
323 |
319 |
324 val exactly_one = |
320 val exactly_one = |
325 ex1I |> instantiate' [SOME (ctyp_of thy ranT)] [SOME P2, SOME (cterm_of thy rhsC)] |
321 ex1I |> instantiate' [SOME (ctyp_of thy ranT)] [SOME P2, SOME (cterm_of thy rhsC)] |
326 |> curry (op COMP) existence |
322 |> curry (op COMP) existence |
327 |> curry (op COMP) uniqueness |
323 |> curry (op COMP) uniqueness |
330 |> fold_rev (implies_intr o cprop_of) ags |
326 |> fold_rev (implies_intr o cprop_of) ags |
331 |> fold_rev forall_intr cqs |
327 |> fold_rev forall_intr cqs |
332 |
328 |
333 val function_value = |
329 val function_value = |
334 existence |
330 existence |
335 |> implies_intr ihyp |
331 |> implies_intr ihyp |
336 |> implies_intr (cprop_of case_hyp) |
332 |> implies_intr (cprop_of case_hyp) |
337 |> forall_intr (cterm_of thy x) |
333 |> forall_intr (cterm_of thy x) |
338 |> forall_elim (cterm_of thy lhs) |
334 |> forall_elim (cterm_of thy lhs) |
339 |> curry (op RS) refl |
335 |> curry (op RS) refl |
340 in |
336 in |
341 (exactly_one, function_value) |
337 (exactly_one, function_value) |
342 end |
338 end |
343 |
339 |
344 |
340 |
346 |
342 |
347 fun prove_stuff thy congs globals G f R clauses complete compat compat_store G_elim f_def = |
343 fun prove_stuff thy congs globals G f R clauses complete compat compat_store G_elim f_def = |
348 let |
344 let |
349 val Globals {h, domT, ranT, x, ...} = globals |
345 val Globals {h, domT, ranT, x, ...} = globals |
350 |
346 |
351 val inst_ex1_ex = f_def RS ex1_implies_ex |
347 val inst_ex1_ex = f_def RS ex1_implies_ex |
352 val inst_ex1_un = f_def RS ex1_implies_un |
348 val inst_ex1_un = f_def RS ex1_implies_un |
353 val inst_ex1_iff = f_def RS ex1_implies_iff |
349 val inst_ex1_iff = f_def RS ex1_implies_iff |
354 |
350 |
355 (* Inductive Hypothesis: !!z. (z,x):R ==> EX!y. (z,y):G *) |
351 (* Inductive Hypothesis: !!z. (z,x):R ==> EX!y. (z,y):G *) |
356 val ihyp = all domT $ Abs ("z", domT, |
352 val ihyp = all domT $ Abs ("z", domT, |
357 implies $ Trueprop (mk_relmemT domT domT (Bound 0, x) R) |
353 implies $ Trueprop (R $ Bound 0 $ x) |
358 $ Trueprop (Const ("Ex1", (ranT --> boolT) --> boolT) $ |
354 $ Trueprop (Const ("Ex1", (ranT --> boolT) --> boolT) $ |
359 Abs ("y", ranT, mk_relmemT domT ranT (Bound 1, Bound 0) G))) |
355 Abs ("y", ranT, G $ Bound 1 $ Bound 0))) |
360 |> cterm_of thy |
356 |> cterm_of thy |
361 |
357 |
362 val ihyp_thm = assume ihyp |> forall_elim_vars 0 |
358 val ihyp_thm = assume ihyp |> forall_elim_vars 0 |
363 val ih_intro = ihyp_thm RS inst_ex1_ex |
359 val ih_intro = ihyp_thm RS inst_ex1_ex |
364 val ih_elim = ihyp_thm RS inst_ex1_un |
360 val ih_elim = ihyp_thm RS inst_ex1_un |
373 val _ = Output.debug "Proving: Graph is a function" (* FIXME: Rewrite this proof. *) |
369 val _ = Output.debug "Proving: Graph is a function" (* FIXME: Rewrite this proof. *) |
374 val graph_is_function = complete |
370 val graph_is_function = complete |
375 |> forall_elim_vars 0 |
371 |> forall_elim_vars 0 |
376 |> fold (curry op COMP) ex1s |
372 |> fold (curry op COMP) ex1s |
377 |> implies_intr (ihyp) |
373 |> implies_intr (ihyp) |
378 |> implies_intr (cterm_of thy (Trueprop (mk_mem (x, mk_acc domT R)))) |
374 |> implies_intr (cterm_of thy (Trueprop (mk_acc domT R $ x))) |
379 |> forall_intr (cterm_of thy x) |
375 |> forall_intr (cterm_of thy x) |
380 |> (fn it => Drule.compose_single (it, 2, acc_induct_rule)) (* "EX! y. (?x,y):G" *) |
376 |> (fn it => Drule.compose_single (it, 2, acc_induct_rule)) (* "EX! y. (?x,y):G" *) |
381 |> (fn it => fold (forall_intr o cterm_of thy) (term_vars (prop_of it)) it) |
377 |> (fn it => fold (forall_intr o cterm_of thy) (term_vars (prop_of it)) it) |
382 |> Drule.close_derivation |
378 |> Drule.close_derivation |
383 |
379 |
392 end |
388 end |
393 |
389 |
394 |
390 |
395 fun define_graph Gname fvar domT ranT clauses RCss lthy = |
391 fun define_graph Gname fvar domT ranT clauses RCss lthy = |
396 let |
392 let |
397 val GT = mk_relT (domT, ranT) |
393 val GT = domT --> ranT --> boolT |
398 val Gvar = Free (the_single (Variable.variant_frees lthy [] [(Gname, GT)])) |
394 val Gvar = Free (the_single (Variable.variant_frees lthy [] [(Gname, GT)])) |
399 |
395 |
400 fun mk_GIntro (ClauseContext {qs, gs, lhs, rhs, ...}) RCs = |
396 fun mk_GIntro (ClauseContext {qs, gs, lhs, rhs, ...}) RCs = |
401 let |
397 let |
402 fun mk_h_assm (rcfix, rcassm, rcarg) = |
398 fun mk_h_assm (rcfix, rcassm, rcarg) = |
403 mk_relmem (rcarg, fvar $ rcarg) Gvar |
399 Trueprop (Gvar $ rcarg $ (fvar $ rcarg)) |
404 |> fold_rev (curry Logic.mk_implies o prop_of) rcassm |
400 |> fold_rev (curry Logic.mk_implies o prop_of) rcassm |
405 |> fold_rev (mk_forall o Free) rcfix |
401 |> fold_rev (mk_forall o Free) rcfix |
406 in |
402 in |
407 mk_relmem (lhs, rhs) Gvar |
403 Trueprop (Gvar $ lhs $ rhs) |
408 |> fold_rev (curry Logic.mk_implies o mk_h_assm) RCs |
404 |> fold_rev (curry Logic.mk_implies o mk_h_assm) RCs |
409 |> fold_rev (curry Logic.mk_implies) gs |
405 |> fold_rev (curry Logic.mk_implies) gs |
410 |> fold_rev mk_forall (fvar :: qs) |
406 |> fold_rev mk_forall (fvar :: qs) |
411 end |
407 end |
412 |
408 |
422 |
418 |
423 fun define_function fdefname (fname, mixfix) domT ranT G default lthy = |
419 fun define_function fdefname (fname, mixfix) domT ranT G default lthy = |
424 let |
420 let |
425 val f_def = |
421 val f_def = |
426 Abs ("x", domT, Const ("FunDef.THE_default", ranT --> (ranT --> boolT) --> ranT) $ (default $ Bound 0) $ |
422 Abs ("x", domT, Const ("FunDef.THE_default", ranT --> (ranT --> boolT) --> ranT) $ (default $ Bound 0) $ |
427 Abs ("y", ranT, mk_relmemT domT ranT (Bound 1, Bound 0) G)) |
423 Abs ("y", ranT, G $ Bound 1 $ Bound 0)) |
|
424 |> Envir.beta_norm (* Fixme: LocalTheory.def does not work if not beta-normal *) |
428 |
425 |
429 val ((f, (_, f_defthm)), lthy) = LocalTheory.def ((fname ^ "C", mixfix), ((fdefname, []), f_def)) lthy |
426 val ((f, (_, f_defthm)), lthy) = LocalTheory.def ((fname ^ "C", mixfix), ((fdefname, []), f_def)) lthy |
430 in |
427 in |
431 ((f, f_defthm), lthy) |
428 ((f, f_defthm), lthy) |
432 end |
429 end |
433 |
430 |
434 |
431 |
435 fun define_recursion_relation Rname domT ranT fvar f qglrs clauses RCss lthy = |
432 fun define_recursion_relation Rname domT ranT fvar f qglrs clauses RCss lthy = |
436 let |
433 let |
437 |
434 |
438 val RT = mk_relT (domT, domT) |
435 val RT = domT --> domT --> boolT |
439 val Rvar = Free (the_single (Variable.variant_frees lthy [] [(Rname, RT)])) |
436 val Rvar = Free (the_single (Variable.variant_frees lthy [] [(Rname, RT)])) |
440 |
437 |
441 fun mk_RIntro (ClauseContext {qs, gs, lhs, ...}, (oqs, _, _, _)) (rcfix, rcassm, rcarg) = |
438 fun mk_RIntro (ClauseContext {qs, gs, lhs, ...}, (oqs, _, _, _)) (rcfix, rcassm, rcarg) = |
442 mk_relmem (rcarg, lhs) Rvar |
439 Trueprop (Rvar $ rcarg $ lhs) |
443 |> fold_rev (curry Logic.mk_implies o prop_of) rcassm |
440 |> fold_rev (curry Logic.mk_implies o prop_of) rcassm |
444 |> fold_rev (curry Logic.mk_implies) gs |
441 |> fold_rev (curry Logic.mk_implies) gs |
445 |> fold_rev (mk_forall o Free) rcfix |
442 |> fold_rev (mk_forall o Free) rcfix |
446 |> fold_rev mk_forall_rename (map fst oqs ~~ qs) |
443 |> fold_rev mk_forall_rename (map fst oqs ~~ qs) |
447 (* "!!qs xs. CS ==> G => (r, lhs) : R" *) |
444 (* "!!qs xs. CS ==> G => (r, lhs) : R" *) |
463 (Globals {h = Free (h, domT --> ranT), |
460 (Globals {h = Free (h, domT --> ranT), |
464 y = Free (y, ranT), |
461 y = Free (y, ranT), |
465 x = Free (x, domT), |
462 x = Free (x, domT), |
466 z = Free (z, domT), |
463 z = Free (z, domT), |
467 a = Free (a, domT), |
464 a = Free (a, domT), |
468 D = Free (D, HOLogic.mk_setT domT), |
465 D = Free (D, domT --> boolT), |
469 P = Free (P, domT --> boolT), |
466 P = Free (P, domT --> boolT), |
470 Pbool = Free (Pbool, boolT), |
467 Pbool = Free (Pbool, boolT), |
471 fvar = fvar, |
468 fvar = fvar, |
472 domT = domT, |
469 domT = domT, |
473 ranT = ranT |
470 ranT = ranT |
519 val trees = map (FundefCtxTree.inst_tree (ProofContext.theory_of lthy) fvar f) trees |
516 val trees = map (FundefCtxTree.inst_tree (ProofContext.theory_of lthy) fvar f) trees |
520 |
517 |
521 val ((R, RIntro_thmss, R_elim), lthy) = |
518 val ((R, RIntro_thmss, R_elim), lthy) = |
522 define_recursion_relation (defname ^ "_rel") domT ranT fvar f abstract_qglrs clauses RCss lthy |
519 define_recursion_relation (defname ^ "_rel") domT ranT fvar f abstract_qglrs clauses RCss lthy |
523 |
520 |
524 val dom_abbrev = Logic.mk_equals (Free (defname ^ "_dom", fastype_of (mk_acc domT R)), mk_acc domT R) |
521 val dom_abbrev = Logic.mk_equals (Free (defname ^ "_dom", domT --> boolT), mk_acc domT R) |
525 val lthy = Specification.abbreviation_i ("", false) [(NONE, dom_abbrev)] lthy |
522 val lthy = Specification.abbreviation_i ("", false) [(NONE, dom_abbrev)] lthy |
526 |
523 |
527 val newthy = ProofContext.theory_of lthy |
524 val newthy = ProofContext.theory_of lthy |
528 val clauses = map (transfer_clause_ctx newthy) clauses |
525 val clauses = map (transfer_clause_ctx newthy) clauses |
529 |
526 |