4 heavily based on the code of Alexander Krauss |
4 heavily based on the code of Alexander Krauss |
5 (code forked on 14 January 2011) |
5 (code forked on 14 January 2011) |
6 |
6 |
7 Core of the nominal function package. |
7 Core of the nominal function package. |
8 *) |
8 *) |
|
9 |
|
10 |
|
11 structure Nominal_Function_Common = |
|
12 struct |
|
13 |
|
14 |
|
15 (* Configuration management *) |
|
16 datatype nominal_function_opt |
|
17 = Sequential |
|
18 | Default of string |
|
19 | DomIntros |
|
20 | No_Partials |
|
21 | Invariant of string |
|
22 |
|
23 datatype nominal_function_config = NominalFunctionConfig of |
|
24 {sequential: bool, |
|
25 default: string option, |
|
26 domintros: bool, |
|
27 partials: bool, |
|
28 inv: string option} |
|
29 |
|
30 fun apply_opt Sequential (NominalFunctionConfig {sequential, default, domintros, partials, inv}) = |
|
31 NominalFunctionConfig |
|
32 {sequential=true, default=default, domintros=domintros, partials=partials, inv=inv} |
|
33 | apply_opt (Default d) (NominalFunctionConfig {sequential, default, domintros, partials, inv}) = |
|
34 NominalFunctionConfig |
|
35 {sequential=sequential, default=SOME d, domintros=domintros, partials=partials, inv=inv} |
|
36 | apply_opt DomIntros (NominalFunctionConfig {sequential, default, domintros, partials, inv}) = |
|
37 NominalFunctionConfig |
|
38 {sequential=sequential, default=default, domintros=true, partials=partials, inv=inv} |
|
39 | apply_opt No_Partials (NominalFunctionConfig {sequential, default, domintros, partials, inv}) = |
|
40 NominalFunctionConfig |
|
41 {sequential=sequential, default=default, domintros=domintros, partials=false, inv=inv} |
|
42 | apply_opt (Invariant s) (NominalFunctionConfig {sequential, default, domintros, partials, inv}) = |
|
43 NominalFunctionConfig |
|
44 {sequential=sequential, default=default, domintros=domintros, partials=partials, inv = SOME s} |
|
45 |
|
46 val nominal_default_config = |
|
47 NominalFunctionConfig { sequential=false, default=NONE, |
|
48 domintros=false, partials=true, inv=NONE} |
|
49 |
|
50 end |
|
51 |
9 |
52 |
10 signature NOMINAL_FUNCTION_CORE = |
53 signature NOMINAL_FUNCTION_CORE = |
11 sig |
54 sig |
12 val trace: bool Unsynchronized.ref |
55 val trace: bool Unsynchronized.ref |
13 |
56 |
121 in |
165 in |
122 Const (@{const_name eqvt}, ty --> @{typ bool}) $ trm |
166 Const (@{const_name eqvt}, ty --> @{typ bool}) $ trm |
123 |> HOLogic.mk_Trueprop |
167 |> HOLogic.mk_Trueprop |
124 end |
168 end |
125 |
169 |
|
170 fun mk_inv inv (f_trm, arg_trm) = |
|
171 betapplys (inv, [arg_trm, (f_trm $ arg_trm)]) |
|
172 |> HOLogic.mk_Trueprop |
|
173 |
|
174 fun mk_invariant (Globals {x, y, ...}) G invariant = |
|
175 let |
|
176 val prem = HOLogic.mk_Trueprop (G $ x $ y) |
|
177 val concl = HOLogic.mk_Trueprop (betapplys (invariant, [x, y])) |
|
178 in |
|
179 Logic.mk_implies (prem, concl) |
|
180 |> mk_forall_rename ("y", y) |
|
181 |> mk_forall_rename ("x", x) |
|
182 end |
|
183 |
126 (** building proof obligations *) |
184 (** building proof obligations *) |
127 fun mk_eqvt_proof_obligation qs fvar (vs, assms, arg) = |
185 fun mk_eqvt_proof_obligation qs fvar (vs, assms, arg) = |
128 mk_eqvt_at (fvar, arg) |
186 mk_eqvt_at (fvar, arg) |
129 |> curry Logic.list_implies (map prop_of assms) |
187 |> curry Logic.list_implies (map prop_of assms) |
130 |> curry Term.list_all_free vs |
188 |> curry Term.list_all_free vs |
131 |> curry Term.list_abs_free qs |
189 |> curry Term.list_abs_free qs |
132 |> strip_abs_body |
190 |> strip_abs_body |
133 |
191 |
|
192 fun mk_inv_proof_obligation inv qs fvar (vs, assms, arg) = |
|
193 mk_inv inv (fvar, arg) |
|
194 |> curry Logic.list_implies (map prop_of assms) |
|
195 |> curry Term.list_all_free vs |
|
196 |> curry Term.list_abs_free qs |
|
197 |> strip_abs_body |
|
198 |
134 (** building proof obligations *) |
199 (** building proof obligations *) |
135 fun mk_compat_proof_obligations domT ranT fvar f RCss glrs = |
200 fun mk_compat_proof_obligations domT ranT fvar f RCss inv glrs = |
136 let |
201 let |
137 fun mk_impl (((qs, gs, lhs, rhs), RCs), ((qs', gs', lhs', rhs'), _)) = |
202 fun mk_impl (((qs, gs, lhs, rhs), RCs), ((qs', gs', lhs', rhs'), _)) = |
138 let |
203 let |
139 val shift = incr_boundvars (length qs') |
204 val shift = incr_boundvars (length qs') |
140 val eqvts_proof_obligations = map (shift o mk_eqvt_proof_obligation qs fvar) RCs |
205 val eqvts_proof_obligations = map (shift o mk_eqvt_proof_obligation qs fvar) RCs |
|
206 val invs_proof_obligations = map (shift o mk_inv_proof_obligation inv qs fvar) RCs |
141 in |
207 in |
142 Logic.mk_implies |
208 Logic.mk_implies |
143 (HOLogic.mk_Trueprop (HOLogic.eq_const domT $ shift lhs $ lhs'), |
209 (HOLogic.mk_Trueprop (HOLogic.eq_const domT $ shift lhs $ lhs'), |
144 HOLogic.mk_Trueprop (HOLogic.eq_const ranT $ shift rhs $ rhs')) |
210 HOLogic.mk_Trueprop (HOLogic.eq_const ranT $ shift rhs $ rhs')) |
145 |> fold_rev (curry Logic.mk_implies) (map shift gs @ gs') |
211 |> fold_rev (curry Logic.mk_implies) (map shift gs @ gs') |
|
212 |> fold_rev (curry Logic.mk_implies) invs_proof_obligations (* nominal *) |
146 |> fold_rev (curry Logic.mk_implies) eqvts_proof_obligations (* nominal *) |
213 |> fold_rev (curry Logic.mk_implies) eqvts_proof_obligations (* nominal *) |
147 |> fold_rev (fn (n,T) => fn b => Term.all T $ Abs(n,T,b)) (qs @ qs') |
214 |> fold_rev (fn (n,T) => fn b => Term.all T $ Abs(n,T,b)) (qs @ qs') |
148 |> curry abstract_over fvar |
215 |> curry abstract_over fvar |
149 |> curry subst_bound f |
216 |> curry subst_bound f |
150 end |
217 end |
151 in |
218 in |
152 map mk_impl (unordered_pairs (glrs ~~ RCss)) |
219 map mk_impl (unordered_pairs (glrs ~~ RCss)) |
153 end |
220 end |
154 |
|
155 |
221 |
156 fun mk_completeness (Globals {x, Pbool, ...}) clauses qglrs = |
222 fun mk_completeness (Globals {x, Pbool, ...}) clauses qglrs = |
157 let |
223 let |
158 fun mk_case (ClauseContext {qs, gs, lhs, ...}, (oqs, _, _, _)) = |
224 fun mk_case (ClauseContext {qs, gs, lhs, ...}, (oqs, _, _, _)) = |
159 HOLogic.mk_Trueprop Pbool |
225 HOLogic.mk_Trueprop Pbool |
258 nth (nth cts (i - 1)) (j - i) |
324 nth (nth cts (i - 1)) (j - i) |
259 |
325 |
260 (* nominal *) |
326 (* nominal *) |
261 (* Returns "Gsi, Gsj, lhs_i = lhs_j |-- rhs_j_f = rhs_i_f" *) |
327 (* Returns "Gsi, Gsj, lhs_i = lhs_j |-- rhs_j_f = rhs_i_f" *) |
262 (* if j < i, then turn around *) |
328 (* if j < i, then turn around *) |
263 fun get_compat_thm thy cts eqvtsi eqvtsj i j ctxi ctxj = |
329 fun get_compat_thm thy cts eqvtsi eqvtsj invsi invsj i j ctxi ctxj = |
264 let |
330 let |
265 val ClauseContext {cqs=cqsi,ags=agsi,lhs=lhsi,case_hyp=case_hypi,...} = ctxi |
331 val ClauseContext {cqs=cqsi,ags=agsi,lhs=lhsi,case_hyp=case_hypi,...} = ctxi |
266 val ClauseContext {cqs=cqsj,ags=agsj,lhs=lhsj,case_hyp=case_hypj,...} = ctxj |
332 val ClauseContext {cqs=cqsj,ags=agsj,lhs=lhsj,case_hyp=case_hypj,...} = ctxj |
267 |
333 |
268 val lhsi_eq_lhsj = cterm_of thy (HOLogic.mk_Trueprop (mk_eq (lhsi, lhsj))) |
334 val lhsi_eq_lhsj = cterm_of thy (HOLogic.mk_Trueprop (mk_eq (lhsi, lhsj))) |
282 val compat = lookup_compat_thm i j cts |
349 val compat = lookup_compat_thm i j cts |
283 in |
350 in |
284 compat (* "!!qi qj. Gsi => Gsj => lhsi = lhsj ==> rhsi = rhsj" *) |
351 compat (* "!!qi qj. Gsi => Gsj => lhsi = lhsj ==> rhsi = rhsj" *) |
285 |> fold Thm.forall_elim (cqsi @ cqsj) (* "Gsi => Gsj => lhsi = lhsj ==> rhsi = rhsj" *) |
352 |> fold Thm.forall_elim (cqsi @ cqsj) (* "Gsi => Gsj => lhsi = lhsj ==> rhsi = rhsj" *) |
286 |> fold Thm.elim_implies eqvtsi (* nominal *) |
353 |> fold Thm.elim_implies eqvtsi (* nominal *) |
|
354 |> fold Thm.elim_implies invsi (* nominal *) |
287 |> fold Thm.elim_implies agsi |
355 |> fold Thm.elim_implies agsi |
288 |> fold Thm.elim_implies agsj |
356 |> fold Thm.elim_implies agsj |
289 |> Thm.elim_implies (Thm.assume lhsi_eq_lhsj) |
357 |> Thm.elim_implies (Thm.assume lhsi_eq_lhsj) |
290 |> (fn thm => thm RS sym) (* "Gsi, Gsj, lhsi = lhsj |-- rhsj = rhsi" *) |
358 |> (fn thm => thm RS sym) (* "Gsi, Gsj, lhsi = lhsj |-- rhsj = rhsi" *) |
291 end |
359 end |
345 |> map (fold_rev Thm.forall_intr cqs) |
413 |> map (fold_rev Thm.forall_intr cqs) |
346 |> map (Thm.close_derivation) |
414 |> map (Thm.close_derivation) |
347 end |
415 end |
348 |
416 |
349 (* nominal *) |
417 (* nominal *) |
350 fun mk_uniqueness_clause thy globals compat_store eqvts clausei clausej RLj = |
418 fun mk_invariant_lemma thy ih_inv clause = |
|
419 let |
|
420 val ClauseInfo {cdata=ClauseContext {cqs, ags, case_hyp, ...}, RCs, ...} = clause |
|
421 |
|
422 local open Conv in |
|
423 val ih_conv = arg1_conv o arg_conv o arg_conv |
|
424 end |
|
425 |
|
426 val ih_inv_case = |
|
427 Conv.fconv_rule (ih_conv (K (case_hyp RS eq_reflection))) ih_inv |
|
428 |
|
429 fun prep_inv (RCInfo {llRI, RIvs, CCas, ...}) = |
|
430 (llRI RS ih_inv_case) |
|
431 |> fold_rev (Thm.implies_intr o cprop_of) CCas |
|
432 |> fold_rev (Thm.forall_intr o cterm_of thy o Free) RIvs |
|
433 in |
|
434 map prep_inv RCs |
|
435 |> map (fold_rev (Thm.implies_intr o cprop_of) ags) |
|
436 |> map (Thm.implies_intr (cprop_of case_hyp)) |
|
437 |> map (fold_rev Thm.forall_intr cqs) |
|
438 |> map (Thm.close_derivation) |
|
439 end |
|
440 |
|
441 (* nominal *) |
|
442 fun mk_uniqueness_clause thy globals compat_store eqvts invs clausei clausej RLj = |
351 let |
443 let |
352 val Globals {h, y, x, fvar, ...} = globals |
444 val Globals {h, y, x, fvar, ...} = globals |
353 val ClauseInfo {no=i, cdata=cctxi as ClauseContext {ctxt=ctxti, lhs=lhsi, case_hyp, cqs = cqsi, |
445 val ClauseInfo {no=i, cdata=cctxi as ClauseContext {ctxt=ctxti, lhs=lhsi, case_hyp, cqs = cqsi, |
354 ags = agsi, ...}, ...} = clausei |
446 ags = agsi, ...}, ...} = clausei |
355 val ClauseInfo {no=j, qglr=cdescj, RCs=RCsj, ...} = clausej |
447 val ClauseInfo {no=j, qglr=cdescj, RCs=RCsj, ...} = clausej |
381 val eqvtsj = nth eqvts (j - 1) |
473 val eqvtsj = nth eqvts (j - 1) |
382 |> map (fold Thm.forall_elim cqsj') |
474 |> map (fold Thm.forall_elim cqsj') |
383 |> map (fold Thm.elim_implies [case_hypj']) |
475 |> map (fold Thm.elim_implies [case_hypj']) |
384 |> map (fold Thm.elim_implies agsj') |
476 |> map (fold Thm.elim_implies agsj') |
385 |
477 |
386 val compat = get_compat_thm thy compat_store eqvtsi eqvtsj i j cctxi cctxj |
478 val invsi = nth invs (i - 1) |
|
479 |> map (fold Thm.forall_elim cqsi) |
|
480 |> map (fold Thm.elim_implies [case_hyp]) |
|
481 |> map (fold Thm.elim_implies agsi) |
|
482 |
|
483 val invsj = nth invs (j - 1) |
|
484 |> map (fold Thm.forall_elim cqsj') |
|
485 |> map (fold Thm.elim_implies [case_hypj']) |
|
486 |> map (fold Thm.elim_implies agsj') |
|
487 |
|
488 val compat = get_compat_thm thy compat_store eqvtsi eqvtsj invsi invsj i j cctxi cctxj |
387 |
489 |
388 in |
490 in |
389 (trans OF [case_hyp, lhsi_eq_lhsj']) (* lhs_i = lhs_j' |-- x = lhs_j' *) |
491 (trans OF [case_hyp, lhsi_eq_lhsj']) (* lhs_i = lhs_j' |-- x = lhs_j' *) |
390 |> Thm.implies_elim RLj_import |
492 |> Thm.implies_elim RLj_import |
391 (* Rj1' ... Rjk', lhs_i = lhs_j' |-- rhs_j'_h = rhs_j'_f *) |
493 (* Rj1' ... Rjk', lhs_i = lhs_j' |-- rhs_j'_h = rhs_j'_f *) |
400 |> Thm.implies_intr (cprop_of lhsi_eq_lhsj') |
502 |> Thm.implies_intr (cprop_of lhsi_eq_lhsj') |
401 |> fold_rev Thm.forall_intr (cterm_of thy h :: cqsj') |
503 |> fold_rev Thm.forall_intr (cterm_of thy h :: cqsj') |
402 end |
504 end |
403 |
505 |
404 (* nominal *) |
506 (* nominal *) |
405 fun mk_uniqueness_case thy globals G f ihyp ih_intro G_cases compat_store clauses replems eqvtlems clausei = |
507 fun mk_uniqueness_case thy globals G f ihyp ih_intro G_cases compat_store clauses replems eqvtlems invlems |
|
508 clausei = |
406 let |
509 let |
407 val Globals {x, y, ranT, fvar, ...} = globals |
510 val Globals {x, y, ranT, fvar, ...} = globals |
408 val ClauseInfo {cdata = ClauseContext {lhs, rhs, cqs, ags, case_hyp, ...}, lGI, RCs, ...} = clausei |
511 val ClauseInfo {cdata = ClauseContext {lhs, rhs, cqs, ags, case_hyp, ...}, lGI, RCs, ...} = clausei |
409 val rhsC = Pattern.rewrite_term thy [(fvar, f)] [] rhs |
512 val rhsC = Pattern.rewrite_term thy [(fvar, f)] [] rhs |
410 |
513 |
474 val ihyp_thm = Thm.assume ihyp |> Thm.forall_elim_vars 0 |
577 val ihyp_thm = Thm.assume ihyp |> Thm.forall_elim_vars 0 |
475 val ih_intro = ihyp_thm RS (f_def RS ex1_implies_ex) |
578 val ih_intro = ihyp_thm RS (f_def RS ex1_implies_ex) |
476 val ih_elim = ihyp_thm RS (f_def RS ex1_implies_un) |
579 val ih_elim = ihyp_thm RS (f_def RS ex1_implies_un) |
477 |> instantiate' [] [NONE, SOME (cterm_of thy h)] |
580 |> instantiate' [] [NONE, SOME (cterm_of thy h)] |
478 val ih_eqvt = ihyp_thm RS (G_eqvt RS (f_def RS @{thm fundef_ex1_eqvt_at})) |
581 val ih_eqvt = ihyp_thm RS (G_eqvt RS (f_def RS @{thm fundef_ex1_eqvt_at})) |
479 |
582 val ih_inv = ihyp_thm RS (invariant COMP (f_def RS @{thm fundef_ex1_prop})) |
|
583 |
480 val _ = trace_msg (K "Proving Replacement lemmas...") |
584 val _ = trace_msg (K "Proving Replacement lemmas...") |
481 val repLemmas = map (mk_replacement_lemma thy h ih_elim) clauses |
585 val repLemmas = map (mk_replacement_lemma thy h ih_elim) clauses |
482 |
586 |
483 val _ = trace_msg (K "Proving Equivariance lemmas...") |
587 val _ = trace_msg (K "Proving Equivariance lemmas...") |
484 val eqvtLemmas = map (mk_eqvt_lemma thy ih_eqvt) clauses |
588 val eqvtLemmas = map (mk_eqvt_lemma thy ih_eqvt) clauses |
|
589 |
|
590 val _ = trace_msg (K "Proving Invariance lemmas...") |
|
591 val invLemmas = map (mk_invariant_lemma thy ih_inv) clauses |
485 |
592 |
486 val _ = trace_msg (K "Proving cases for unique existence...") |
593 val _ = trace_msg (K "Proving cases for unique existence...") |
487 val (ex1s, values) = |
594 val (ex1s, values) = |
488 split_list (map (mk_uniqueness_case thy globals G f |
595 split_list (map (mk_uniqueness_case thy globals G f |
489 ihyp ih_intro G_elim compat_store clauses repLemmas eqvtLemmas) clauses) |
596 ihyp ih_intro G_elim compat_store clauses repLemmas eqvtLemmas invLemmas) clauses) |
490 |
597 |
491 val _ = trace_msg (K "Proving: Graph is a function") |
598 val _ = trace_msg (K "Proving: Graph is a function") |
492 val graph_is_function = complete |
599 val graph_is_function = complete |
493 |> Thm.forall_elim_vars 0 |
600 |> Thm.forall_elim_vars 0 |
494 |> fold (curry op COMP) ex1s |
601 |> fold (curry op COMP) ex1s |
497 |> Thm.forall_intr (cterm_of thy x) |
604 |> Thm.forall_intr (cterm_of thy x) |
498 |> (fn it => Drule.compose_single (it, 2, acc_induct_rule)) (* "EX! y. (?x,y):G" *) |
605 |> (fn it => Drule.compose_single (it, 2, acc_induct_rule)) (* "EX! y. (?x,y):G" *) |
499 |> (fn it => fold (Thm.forall_intr o cterm_of thy o Var) (Term.add_vars (prop_of it) []) it) |
606 |> (fn it => fold (Thm.forall_intr o cterm_of thy o Var) (Term.add_vars (prop_of it) []) it) |
500 |
607 |
501 val goalstate = |
608 val goalstate = |
502 Conjunction.intr (Conjunction.intr graph_is_function complete) G_eqvt |
609 Conjunction.intr (Conjunction.intr (Conjunction.intr graph_is_function complete) invariant) G_eqvt |
503 |> Thm.close_derivation |
610 |> Thm.close_derivation |
504 |> Goal.protect |
611 |> Goal.protect |
505 |> fold_rev (Thm.implies_intr o cprop_of) compat |
612 |> fold_rev (Thm.implies_intr o cprop_of) compat |
506 |> Thm.implies_intr (cprop_of complete) |
613 |> Thm.implies_intr (cprop_of complete) |
|
614 |> Thm.implies_intr (cprop_of invariant) |
507 |> Thm.implies_intr (cprop_of G_eqvt) |
615 |> Thm.implies_intr (cprop_of G_eqvt) |
508 in |
616 in |
509 (goalstate, values) |
617 (goalstate, values) |
510 end |
618 end |
511 |
619 |
903 |
1011 |
904 |
1012 |
905 (* nominal *) |
1013 (* nominal *) |
906 fun prepare_nominal_function config defname [((fname, fT), mixfix)] abstract_qglrs lthy = |
1014 fun prepare_nominal_function config defname [((fname, fT), mixfix)] abstract_qglrs lthy = |
907 let |
1015 let |
908 val NominalFunctionConfig {domintros, default=default_opt, ...} = config |
1016 val NominalFunctionConfig {domintros, default=default_opt, inv=invariant_opt,...} = config |
909 |
1017 |
910 val default_str = the_default "%x. undefined" default_opt (*FIXME dynamic scoping*) |
1018 val default_str = the_default "%x. undefined" default_opt (*FIXME dynamic scoping*) |
|
1019 val invariant_str = the_default "%x y. True" invariant_opt |
911 val fvar = Free (fname, fT) |
1020 val fvar = Free (fname, fT) |
912 val domT = domain_type fT |
1021 val domT = domain_type fT |
913 val ranT = range_type fT |
1022 val ranT = range_type fT |
914 |
1023 |
915 val default = Syntax.parse_term lthy default_str |
1024 val default = Syntax.parse_term lthy default_str |
916 |> Type.constraint fT |> Syntax.check_term lthy |
1025 |> Type.constraint fT |> Syntax.check_term lthy |
917 |
1026 |
|
1027 val invariant_trm = Syntax.parse_term lthy invariant_str |
|
1028 |> Type.constraint ([domT, ranT] ---> @{typ bool}) |> Syntax.check_term lthy |
|
1029 |
918 val (globals, ctxt') = fix_globals domT ranT fvar lthy |
1030 val (globals, ctxt') = fix_globals domT ranT fvar lthy |
919 |
1031 |
920 val Globals { x, h, ... } = globals |
1032 val Globals { x, h, ... } = globals |
921 |
1033 |
922 val clauses = map (mk_clause_context x ctxt') abstract_qglrs |
1034 val clauses = map (mk_clause_context x ctxt') abstract_qglrs |
955 |
1067 |
956 val complete = |
1068 val complete = |
957 mk_completeness globals clauses abstract_qglrs |> cert |> Thm.assume |
1069 mk_completeness globals clauses abstract_qglrs |> cert |> Thm.assume |
958 |
1070 |
959 val compat = |
1071 val compat = |
960 mk_compat_proof_obligations domT ranT fvar f RCss abstract_qglrs |
1072 mk_compat_proof_obligations domT ranT fvar f RCss invariant_trm abstract_qglrs |
961 |> map (cert #> Thm.assume) |
1073 |> map (cert #> Thm.assume) |
962 |
1074 |
963 val G_eqvt = mk_eqvt G |> cert |> Thm.assume |
1075 val G_eqvt = mk_eqvt G |> cert |> Thm.assume |
964 |
1076 |
|
1077 val invariant = mk_invariant globals G invariant_trm |> cert |> Thm.assume |
|
1078 |
965 val compat_store = store_compat_thms n compat |
1079 val compat_store = store_compat_thms n compat |
966 |
1080 |
967 val (goalstate, values) = PROFILE "prove_stuff" |
1081 val (goalstate, values) = PROFILE "prove_stuff" |
968 (prove_stuff lthy globals G f R xclauses complete compat |
1082 (prove_stuff lthy globals G f R xclauses complete compat |
969 compat_store G_elim G_eqvt) f_defthm |
1083 compat_store G_elim G_eqvt invariant) f_defthm |
970 |
1084 |
971 fun mk_partial_rules provedgoal = |
1085 fun mk_partial_rules provedgoal = |
972 let |
1086 let |
973 val newthy = theory_of_thm provedgoal (*FIXME*) |
1087 val newthy = theory_of_thm provedgoal (*FIXME*) |
974 |
1088 |
975 val ((graph_is_function, complete_thm), _) = |
1089 val (graph_is_function, complete_thm) = |
976 provedgoal |
1090 provedgoal |
|
1091 |> fst o Conjunction.elim |
|
1092 |> fst o Conjunction.elim |
977 |> Conjunction.elim |
1093 |> Conjunction.elim |
978 |>> Conjunction.elim |
1094 |> apfst (Thm.forall_elim_vars 0) |
979 |>> apfst (Thm.forall_elim_vars 0) |
|
980 |
1095 |
981 val f_iff = graph_is_function RS (f_defthm RS ex1_implies_iff) |
1096 val f_iff = graph_is_function RS (f_defthm RS ex1_implies_iff) |
982 |
1097 |
983 val psimps = PROFILE "Proving simplification rules" |
1098 val psimps = PROFILE "Proving simplification rules" |
984 (mk_psimps newthy globals R xclauses values f_iff) graph_is_function |
1099 (mk_psimps newthy globals R xclauses values f_iff) graph_is_function |