33 done |
33 done |
34 |
34 |
35 lemma fundef_ex1_eqvt: |
35 lemma fundef_ex1_eqvt: |
36 fixes x::"'a::pt" |
36 fixes x::"'a::pt" |
37 assumes f_def: "f == (\<lambda>x::'a. THE_default d (G x))" |
37 assumes f_def: "f == (\<lambda>x::'a. THE_default d (G x))" |
|
38 assumes eqvt: "eqvt G" |
38 assumes ex1: "\<exists>!y. G x y" |
39 assumes ex1: "\<exists>!y. G x y" |
39 assumes eqvt: "eqvt G" |
|
40 shows "(p \<bullet> (f x)) = f (p \<bullet> x)" |
40 shows "(p \<bullet> (f x)) = f (p \<bullet> x)" |
41 apply (simp only: f_def) |
41 apply (simp only: f_def) |
42 apply(subst the_default_eqvt) |
42 apply(subst the_default_eqvt) |
43 apply (rule ex1) |
43 apply (rule ex1) |
44 apply(perm_simp) |
44 apply(perm_simp) |
45 using eqvt |
45 using eqvt |
46 apply(simp add: eqvt_def) |
46 apply(simp add: eqvt_def) |
47 done |
47 done |
48 |
48 |
49 |
49 lemma fundef_ex1_eqvt_at: |
|
50 fixes x::"'a::pt" |
|
51 assumes f_def: "f == (\<lambda>x::'a. THE_default d (G x))" |
|
52 assumes eqvt: "eqvt G" |
|
53 assumes ex1: "\<exists>!y. G x y" |
|
54 shows "eqvt_at f x" |
|
55 unfolding eqvt_at_def |
|
56 using assms |
|
57 apply(auto intro: fundef_ex1_eqvt) |
|
58 done |
50 |
59 |
51 ML {* |
60 ML {* |
52 |
61 |
53 val trace = Unsynchronized.ref false |
62 val trace = Unsynchronized.ref false |
54 fun trace_msg msg = if ! trace then tracing (msg ()) else () |
63 fun trace_msg msg = if ! trace then tracing (msg ()) else () |
159 ML {* |
168 ML {* |
160 (** building proof obligations *) |
169 (** building proof obligations *) |
161 |
170 |
162 fun mk_compat_proof_obligations domT ranT fvar f glrs = |
171 fun mk_compat_proof_obligations domT ranT fvar f glrs = |
163 let |
172 let |
|
173 (* |
164 val _ = tracing ("domT: " ^ @{make_string} domT) |
174 val _ = tracing ("domT: " ^ @{make_string} domT) |
165 val _ = tracing ("ranT: " ^ @{make_string} ranT) |
175 val _ = tracing ("ranT: " ^ @{make_string} ranT) |
166 val _ = tracing ("fvar: " ^ @{make_string} fvar) |
176 val _ = tracing ("fvar: " ^ @{make_string} fvar) |
167 val _ = tracing ("f: " ^ @{make_string} f) |
177 val _ = tracing ("f: " ^ @{make_string} f) |
168 |
178 *) |
|
179 |
169 fun mk_impl ((qs, gs, lhs, rhs), (qs', gs', lhs', rhs')) = |
180 fun mk_impl ((qs, gs, lhs, rhs), (qs', gs', lhs', rhs')) = |
170 let |
181 let |
171 val shift = incr_boundvars (length qs') |
182 val shift = incr_boundvars (length qs') |
172 |
183 |
173 val RCs_rhs = find_calls2 fvar rhs |
184 val RCs_rhs = find_calls2 fvar rhs |
328 let |
336 let |
329 val compat = lookup_compat_thm j i cts |
337 val compat = lookup_compat_thm j i cts |
330 in |
338 in |
331 compat (* "!!qj qi. Gsj => Gsi => lhsj = lhsi ==> rhsj = rhsi" *) |
339 compat (* "!!qj qi. Gsj => Gsi => lhsj = lhsi ==> rhsj = rhsi" *) |
332 |> fold Thm.forall_elim (cqsj @ cqsi) (* "Gsj => Gsi => lhsj = lhsi ==> rhsj = rhsi" *) |
340 |> fold Thm.forall_elim (cqsj @ cqsi) (* "Gsj => Gsi => lhsj = lhsi ==> rhsj = rhsi" *) |
333 |> tap (fn th => tracing ("NEED TO PROVE " ^ @{make_string} th)) |
341 (*|> tap (fn th => tracing ("NEED TO PROVE " ^ @{make_string} th))*) |
334 (*|> Thm.elim_implies @{thm TrueI}*) (* THERE *) |
342 (*|> Thm.elim_implies @{thm TrueI}*) (* THERE *) |
335 |> eqvt_at_elim |
343 |> eqvt_at_elim |
336 |> tap (fn th => tracing ("AFTER " ^ @{make_string} th)) |
344 (*|> tap (fn th => tracing ("AFTER " ^ @{make_string} th))*) |
337 |> fold Thm.elim_implies agsj |
345 |> fold Thm.elim_implies agsj |
338 |> fold Thm.elim_implies agsi |
346 |> fold Thm.elim_implies agsi |
339 |> Thm.elim_implies ((Thm.assume lhsi_eq_lhsj) RS sym) (* "Gsj, Gsi, lhsi = lhsj |-- rhsj = rhsi" *) |
347 |> Thm.elim_implies ((Thm.assume lhsi_eq_lhsj) RS sym) (* "Gsj, Gsi, lhsi = lhsj |-- rhsj = rhsi" *) |
340 end |
348 end |
341 else |
349 else |
342 let |
350 let |
343 val compat = lookup_compat_thm i j cts |
351 val compat = lookup_compat_thm i j cts |
344 in |
352 in |
345 compat (* "!!qi qj. Gsi => Gsj => lhsi = lhsj ==> rhsi = rhsj" *) |
353 compat (* "!!qi qj. Gsi => Gsj => lhsi = lhsj ==> rhsi = rhsj" *) |
346 |> fold Thm.forall_elim (cqsi @ cqsj) (* "Gsi => Gsj => lhsi = lhsj ==> rhsi = rhsj" *) |
354 |> fold Thm.forall_elim (cqsi @ cqsj) (* "Gsi => Gsj => lhsi = lhsj ==> rhsi = rhsj" *) |
347 |> tap (fn th => tracing ("NEED TO PROVE " ^ @{make_string} th)) |
355 (*|> tap (fn th => tracing ("NEED TO PROVE " ^ @{make_string} th))*) |
348 (*|> Thm.elim_implies @{thm TrueI}*) |
356 (*|> Thm.elim_implies @{thm TrueI}*) |
349 |> eqvt_at_elim |
357 |> eqvt_at_elim |
350 |> tap (fn th => tracing ("AFTER " ^ @{make_string} th)) |
358 (*|> tap (fn th => tracing ("AFTER " ^ @{make_string} th))*) |
351 |> fold Thm.elim_implies agsi |
359 |> fold Thm.elim_implies agsi |
352 |> fold Thm.elim_implies agsj |
360 |> fold Thm.elim_implies agsj |
353 |> Thm.elim_implies (Thm.assume lhsi_eq_lhsj) |
361 |> Thm.elim_implies (Thm.assume lhsi_eq_lhsj) |
354 |> (fn thm => thm RS sym) (* "Gsi, Gsj, lhsi = lhsj |-- rhsj = rhsi" *) |
362 |> (fn thm => thm RS sym) (* "Gsi, Gsj, lhsi = lhsj |-- rhsj = rhsi" *) |
355 end |
363 end |
489 in |
497 in |
490 (exactly_one, function_value) |
498 (exactly_one, function_value) |
491 end |
499 end |
492 *} |
500 *} |
493 |
501 |
494 (* AAA *) |
502 ML Thm.forall_elim_vars |
495 |
503 |
496 ML {* |
504 ML {* (ex1_implies_ex, ex1_implies_un) *} |
497 fun prove_stuff ctxt globals G f R clauses complete compat compat_store G_elim f_def = |
505 thm fundef_ex1_eqvt_at |
|
506 |
|
507 ML {* |
|
508 fun prove_stuff ctxt globals G f R clauses complete compat compat_store G_elim G_eqvt f_def = |
498 let |
509 let |
499 val Globals {h, domT, ranT, x, ...} = globals |
510 val Globals {h, domT, ranT, x, ...} = globals |
500 val thy = ProofContext.theory_of ctxt |
511 val thy = ProofContext.theory_of ctxt |
501 |
512 |
502 (* Inductive Hypothesis: !!z. (z,x):R ==> EX!y. (z,y):G *) |
513 (* Inductive Hypothesis: !!z. (z,x):R ==> EX!y. (z,y):G *) |
508 |
519 |
509 val ihyp_thm = Thm.assume ihyp |> Thm.forall_elim_vars 0 |
520 val ihyp_thm = Thm.assume ihyp |> Thm.forall_elim_vars 0 |
510 val ih_intro = ihyp_thm RS (f_def RS ex1_implies_ex) |
521 val ih_intro = ihyp_thm RS (f_def RS ex1_implies_ex) |
511 val ih_elim = ihyp_thm RS (f_def RS ex1_implies_un) |
522 val ih_elim = ihyp_thm RS (f_def RS ex1_implies_un) |
512 |> instantiate' [] [NONE, SOME (cterm_of thy h)] |
523 |> instantiate' [] [NONE, SOME (cterm_of thy h)] |
513 |
524 val ih_eqvt = ihyp_thm RS (G_eqvt RS (f_def RS @{thm fundef_ex1_eqvt_at})) |
514 (* |
525 |
515 val _ = tracing ("ihyp\n" ^ @{make_string} ihyp) |
526 |
516 val _ = tracing ("ihyp_thm\n" ^ @{make_string} ihyp_thm) |
527 val _ = tracing ("ihyp_thm\n" ^ @{make_string} ihyp_thm) |
517 val _ = tracing ("ih_intro\n" ^ @{make_string} ih_intro) |
528 val _ = tracing ("ih_intro\n" ^ @{make_string} ih_intro) |
518 val _ = tracing ("ih_elim\n" ^ @{make_string} ih_elim) |
529 val _ = tracing ("ih_elim\n" ^ @{make_string} ih_elim) |
519 *) |
530 val _ = tracing ("ih_eqvt\n" ^ @{make_string} ih_eqvt) |
520 |
531 |
521 val _ = trace_msg (K "Proving Replacement lemmas...") |
532 val _ = trace_msg (K "Proving Replacement lemmas...") |
522 val repLemmas = map (mk_replacement_lemma thy h ih_elim) clauses |
533 val repLemmas = map (mk_replacement_lemma thy h ih_elim) clauses |
523 |
534 |
524 (* |
|
525 val _ = tracing (cat_lines (map @{make_string} repLemmas)) |
535 val _ = tracing (cat_lines (map @{make_string} repLemmas)) |
526 *) |
|
527 |
536 |
528 val _ = trace_msg (K "Proving cases for unique existence...") |
537 val _ = trace_msg (K "Proving cases for unique existence...") |
529 val (ex1s, values) = |
538 val (ex1s, values) = |
530 split_list (map (mk_uniqueness_case thy globals G f |
539 split_list (map (mk_uniqueness_case thy globals G f |
531 ihyp ih_intro G_elim compat_store clauses repLemmas) clauses) |
540 ihyp ih_intro G_elim compat_store clauses repLemmas) clauses) |
532 |
541 |
533 (* |
|
534 val _ = tracing ("ex1s\n" ^ cat_lines (map @{make_string} ex1s)) |
542 val _ = tracing ("ex1s\n" ^ cat_lines (map @{make_string} ex1s)) |
535 val _ = tracing ("values\n" ^ cat_lines (map @{make_string} values)) |
543 val _ = tracing ("values\n" ^ cat_lines (map @{make_string} values)) |
536 *) |
|
537 |
544 |
538 val _ = trace_msg (K "Proving: Graph is a function") |
545 val _ = trace_msg (K "Proving: Graph is a function") |
539 val graph_is_function = complete |
546 val graph_is_function = complete |
|
547 |> tap (fn th => tracing ("A\n" ^ @{make_string} th)) |
540 |> Thm.forall_elim_vars 0 |
548 |> Thm.forall_elim_vars 0 |
|
549 |> tap (fn th => tracing ("B\n" ^ @{make_string} th)) |
541 |> fold (curry op COMP) ex1s |
550 |> fold (curry op COMP) ex1s |
|
551 |> tap (fn th => tracing ("C\n" ^ @{make_string} th)) |
542 |> Thm.implies_intr (ihyp) |
552 |> Thm.implies_intr (ihyp) |
|
553 |> tap (fn th => tracing ("D\n" ^ @{make_string} th)) |
543 |> Thm.implies_intr (cterm_of thy (HOLogic.mk_Trueprop (mk_acc domT R $ x))) |
554 |> Thm.implies_intr (cterm_of thy (HOLogic.mk_Trueprop (mk_acc domT R $ x))) |
|
555 |> tap (fn th => tracing ("E\n" ^ @{make_string} th)) |
544 |> Thm.forall_intr (cterm_of thy x) |
556 |> Thm.forall_intr (cterm_of thy x) |
|
557 |> tap (fn th => tracing ("F\n" ^ @{make_string} th)) |
545 |> (fn it => Drule.compose_single (it, 2, acc_induct_rule)) (* "EX! y. (?x,y):G" *) |
558 |> (fn it => Drule.compose_single (it, 2, acc_induct_rule)) (* "EX! y. (?x,y):G" *) |
|
559 |> tap (fn th => tracing ("G\n" ^ @{make_string} th)) |
546 |> (fn it => fold (Thm.forall_intr o cterm_of thy o Var) (Term.add_vars (prop_of it) []) it) |
560 |> (fn it => fold (Thm.forall_intr o cterm_of thy o Var) (Term.add_vars (prop_of it) []) it) |
|
561 |> tap (fn th => tracing ("H\n" ^ @{make_string} th)) |
|
562 |
547 |
563 |
548 val goalstate = Conjunction.intr graph_is_function complete |
564 val goalstate = Conjunction.intr graph_is_function complete |
549 |> Thm.close_derivation |
565 |> Thm.close_derivation |
550 |> Goal.protect |
566 |> Goal.protect |
551 |> fold_rev (Thm.implies_intr o cprop_of) compat |
567 |> fold_rev (Thm.implies_intr o cprop_of) compat |
1094 val _ = tracing ("compat_store:\n" ^ @{make_string} compat_store) |
1112 val _ = tracing ("compat_store:\n" ^ @{make_string} compat_store) |
1095 *) |
1113 *) |
1096 |
1114 |
1097 val (goalstate, values) = PROFILE "prove_stuff" |
1115 val (goalstate, values) = PROFILE "prove_stuff" |
1098 (prove_stuff lthy globals G f R xclauses complete compat |
1116 (prove_stuff lthy globals G f R xclauses complete compat |
1099 compat_store G_elim) f_defthm |
1117 compat_store G_elim G_eqvt) f_defthm |
1100 |
1118 |
1101 val _ = tracing ("goalstate prove_stuff thm:\n" ^ @{make_string} goalstate) |
1119 val _ = tracing ("goalstate prove_stuff thm:\n" ^ @{make_string} goalstate) |
|
1120 val _ = tracing ("values prove_stuff thms:\n" ^ cat_lines (map @{make_string} values)) |
1102 |
1121 |
1103 val mk_trsimps = |
1122 val mk_trsimps = |
1104 mk_trsimps lthy globals f G R f_defthm R_elim G_induct xclauses |
1123 mk_trsimps lthy globals f G R f_defthm R_elim G_induct xclauses |
1105 |
1124 |
1106 fun mk_partial_rules provedgoal = |
1125 fun mk_partial_rules provedgoal = |