author | Christian Urban <urbanc@in.tum.de> |
Sat, 17 Dec 2011 17:31:40 +0000 | |
branch | Nominal2-Isabelle2011-1 |
changeset 3073 | ec31c31b2bb1 |
parent 3068 | f89ee40fbb08 |
permissions | -rw-r--r-- |
2976 | 1 |
(* Nominal Termination |
2 |
Author: Christian Urban |
|
3 |
||
4 |
heavily based on the code of Alexander Krauss |
|
5 |
(code forked on 18 July 2011) |
|
6 |
||
7 |
Redefinition of the termination command |
|
8 |
*) |
|
9 |
||
10 |
signature NOMINAL_FUNCTION_TERMINATION = |
|
11 |
sig |
|
12 |
include NOMINAL_FUNCTION_DATA |
|
3068
f89ee40fbb08
backported no_eqvt changeset 1afcbaf4242b
Christian Urban <urbanc@in.tum.de>
parents:
2982
diff
changeset
|
13 |
|
f89ee40fbb08
backported no_eqvt changeset 1afcbaf4242b
Christian Urban <urbanc@in.tum.de>
parents:
2982
diff
changeset
|
14 |
val termination : bool -> term option -> local_theory -> Proof.state |
f89ee40fbb08
backported no_eqvt changeset 1afcbaf4242b
Christian Urban <urbanc@in.tum.de>
parents:
2982
diff
changeset
|
15 |
val termination_cmd : bool -> string option -> local_theory -> Proof.state |
2976 | 16 |
end |
17 |
||
18 |
structure Nominal_Function_Termination : NOMINAL_FUNCTION_TERMINATION = |
|
19 |
struct |
|
20 |
||
21 |
open Function_Lib |
|
22 |
open Function_Common |
|
23 |
open Nominal_Function_Common |
|
24 |
||
25 |
val simp_attribs = map (Attrib.internal o K) |
|
26 |
[Simplifier.simp_add, |
|
27 |
Code.add_default_eqn_attribute, |
|
28 |
Nitpick_Simps.add] |
|
29 |
||
30 |
val eqvt_attrib = Attrib.internal (K Nominal_ThmDecls.eqvt_add) |
|
31 |
||
3068
f89ee40fbb08
backported no_eqvt changeset 1afcbaf4242b
Christian Urban <urbanc@in.tum.de>
parents:
2982
diff
changeset
|
32 |
fun prepare_termination_proof prep_term is_eqvt raw_term_opt lthy = |
2976 | 33 |
let |
34 |
val term_opt = Option.map (prep_term lthy) raw_term_opt |
|
35 |
val info = the (case term_opt of |
|
36 |
SOME t => (import_function_data t lthy |
|
37 |
handle Option.Option => |
|
38 |
error ("Not a function: " ^ quote (Syntax.string_of_term lthy t))) |
|
39 |
| NONE => (import_last_function lthy handle Option.Option => error "Not a function")) |
|
40 |
||
41 |
val { termination, fs, R, add_simps, case_names, psimps, |
|
42 |
pinducts, defname, eqvts, ...} = info |
|
43 |
val domT = domain_type (fastype_of R) |
|
2982
4a00077c008f
completed the eqvt-proofs for functions; they are stored under the name function_name.eqvt and added to the eqvt-list
Christian Urban <urbanc@in.tum.de>
parents:
2981
diff
changeset
|
44 |
|
2976 | 45 |
val goal = HOLogic.mk_Trueprop |
46 |
(HOLogic.mk_all ("x", domT, mk_acc domT R $ Free ("x", domT))) |
|
47 |
fun afterqed [[totality]] lthy = |
|
48 |
let |
|
49 |
val totality = Thm.close_derivation totality |
|
50 |
val remove_domain_condition = |
|
51 |
full_simplify (HOL_basic_ss addsimps [totality, @{thm True_implies_equals}]) |
|
52 |
val tsimps = map remove_domain_condition psimps |
|
2982
4a00077c008f
completed the eqvt-proofs for functions; they are stored under the name function_name.eqvt and added to the eqvt-list
Christian Urban <urbanc@in.tum.de>
parents:
2981
diff
changeset
|
53 |
val tinducts = map remove_domain_condition pinducts |
2976 | 54 |
val teqvts = map remove_domain_condition eqvts |
2981 | 55 |
|
2976 | 56 |
fun qualify n = Binding.name n |
57 |
|> Binding.qualify true defname |
|
58 |
in |
|
59 |
lthy |
|
60 |
|> add_simps I "simps" I simp_attribs tsimps |
|
3068
f89ee40fbb08
backported no_eqvt changeset 1afcbaf4242b
Christian Urban <urbanc@in.tum.de>
parents:
2982
diff
changeset
|
61 |
||>> Local_Theory.note ((qualify "eqvt", if is_eqvt then [eqvt_attrib] else []), teqvts) |
2976 | 62 |
||>> Local_Theory.note |
63 |
((qualify "induct", |
|
64 |
[Attrib.internal (K (Rule_Cases.case_names case_names))]), |
|
2982
4a00077c008f
completed the eqvt-proofs for functions; they are stored under the name function_name.eqvt and added to the eqvt-list
Christian Urban <urbanc@in.tum.de>
parents:
2981
diff
changeset
|
65 |
tinducts) |
2976 | 66 |
|-> (fn ((simps, (_, eqvts)), (_, inducts)) => fn lthy => |
67 |
let val info' = { is_partial=false, defname=defname, add_simps=add_simps, |
|
68 |
case_names=case_names, fs=fs, R=R, psimps=psimps, pinducts=pinducts, |
|
2981 | 69 |
simps=SOME simps, inducts=SOME inducts, termination=termination, eqvts=teqvts } |
2976 | 70 |
in |
71 |
(info', |
|
72 |
lthy |
|
73 |
|> Local_Theory.declaration false (add_function_data o morph_function_data info') |
|
74 |
|> Spec_Rules.add Spec_Rules.Equational (fs, tsimps)) |
|
75 |
end) |
|
76 |
end |
|
77 |
in |
|
78 |
(goal, afterqed, termination) |
|
79 |
end |
|
80 |
||
3068
f89ee40fbb08
backported no_eqvt changeset 1afcbaf4242b
Christian Urban <urbanc@in.tum.de>
parents:
2982
diff
changeset
|
81 |
fun gen_termination prep_term is_eqvt raw_term_opt lthy = |
2976 | 82 |
let |
3068
f89ee40fbb08
backported no_eqvt changeset 1afcbaf4242b
Christian Urban <urbanc@in.tum.de>
parents:
2982
diff
changeset
|
83 |
val (goal, afterqed, termination) = prepare_termination_proof prep_term is_eqvt raw_term_opt lthy |
2976 | 84 |
in |
85 |
lthy |
|
86 |
|> Proof_Context.note_thmss "" |
|
87 |
[((Binding.empty, [Context_Rules.rule_del]), [([allI], [])])] |> snd |
|
88 |
|> Proof_Context.note_thmss "" |
|
89 |
[((Binding.empty, [Context_Rules.intro_bang (SOME 1)]), [([allI], [])])] |> snd |
|
90 |
|> Proof_Context.note_thmss "" |
|
91 |
[((Binding.name "termination", [Context_Rules.intro_bang (SOME 0)]), |
|
92 |
[([Goal.norm_result termination], [])])] |> snd |
|
93 |
|> Proof.theorem NONE (snd oo afterqed) [[(goal, [])]] |
|
94 |
end |
|
95 |
||
96 |
val termination = gen_termination Syntax.check_term |
|
97 |
val termination_cmd = gen_termination Syntax.read_term |
|
98 |
||
99 |
(* outer syntax *) |
|
100 |
||
101 |
val option_parser = |
|
102 |
(Scan.optional (Parse.$$$ "(" |-- Parse.!!! |
|
3068
f89ee40fbb08
backported no_eqvt changeset 1afcbaf4242b
Christian Urban <urbanc@in.tum.de>
parents:
2982
diff
changeset
|
103 |
((Parse.reserved "eqvt" >> K (true, true)) || |
f89ee40fbb08
backported no_eqvt changeset 1afcbaf4242b
Christian Urban <urbanc@in.tum.de>
parents:
2982
diff
changeset
|
104 |
(Parse.reserved "no_eqvt" >> K (true, false))) --| Parse.$$$ ")") (false, false)) |
2976 | 105 |
|
106 |
val _ = |
|
107 |
Outer_Syntax.local_theory_to_proof "termination" "prove termination of a recursive function" |
|
108 |
Keyword.thy_goal |
|
109 |
(option_parser -- Scan.option Parse.term >> |
|
3068
f89ee40fbb08
backported no_eqvt changeset 1afcbaf4242b
Christian Urban <urbanc@in.tum.de>
parents:
2982
diff
changeset
|
110 |
(fn ((is_nominal, is_eqvt), opt_trm) => |
f89ee40fbb08
backported no_eqvt changeset 1afcbaf4242b
Christian Urban <urbanc@in.tum.de>
parents:
2982
diff
changeset
|
111 |
if is_nominal then termination_cmd is_eqvt opt_trm else Function.termination_cmd opt_trm)) |
2976 | 112 |
|
113 |
end |