author | Christian Urban <urbanc@in.tum.de> |
Wed, 29 Feb 2012 17:14:31 +0000 | |
changeset 3131 | 3e37322465e2 |
parent 3055 | 1afcbaf4242b |
child 3135 | 92b9b8d2888d |
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 |
|
13 |
||
3055
1afcbaf4242b
termination does not automatically prove equivariance for the defined function (label: no_eqvt)
Christian Urban <urbanc@in.tum.de>
parents:
3045
diff
changeset
|
14 |
val termination : bool -> term option -> local_theory -> Proof.state |
1afcbaf4242b
termination does not automatically prove equivariance for the defined function (label: no_eqvt)
Christian Urban <urbanc@in.tum.de>
parents:
3045
diff
changeset
|
15 |
val termination_cmd : bool -> string option -> local_theory -> Proof.state |
2976 | 16 |
|
17 |
end |
|
18 |
||
19 |
structure Nominal_Function_Termination : NOMINAL_FUNCTION_TERMINATION = |
|
20 |
struct |
|
21 |
||
22 |
open Function_Lib |
|
23 |
open Function_Common |
|
24 |
open Nominal_Function_Common |
|
25 |
||
26 |
val simp_attribs = map (Attrib.internal o K) |
|
27 |
[Simplifier.simp_add, |
|
28 |
Code.add_default_eqn_attribute, |
|
29 |
Nitpick_Simps.add] |
|
30 |
||
31 |
val eqvt_attrib = Attrib.internal (K Nominal_ThmDecls.eqvt_add) |
|
32 |
||
3055
1afcbaf4242b
termination does not automatically prove equivariance for the defined function (label: no_eqvt)
Christian Urban <urbanc@in.tum.de>
parents:
3045
diff
changeset
|
33 |
fun prepare_termination_proof prep_term is_eqvt raw_term_opt lthy = |
2976 | 34 |
let |
35 |
val term_opt = Option.map (prep_term lthy) raw_term_opt |
|
36 |
val info = the (case term_opt of |
|
37 |
SOME t => (import_function_data t lthy |
|
38 |
handle Option.Option => |
|
39 |
error ("Not a function: " ^ quote (Syntax.string_of_term lthy t))) |
|
40 |
| NONE => (import_last_function lthy handle Option.Option => error "Not a function")) |
|
41 |
||
42 |
val { termination, fs, R, add_simps, case_names, psimps, |
|
43 |
pinducts, defname, eqvts, ...} = info |
|
44 |
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
|
45 |
|
2976 | 46 |
val goal = HOLogic.mk_Trueprop |
47 |
(HOLogic.mk_all ("x", domT, mk_acc domT R $ Free ("x", domT))) |
|
48 |
fun afterqed [[totality]] lthy = |
|
49 |
let |
|
50 |
val totality = Thm.close_derivation totality |
|
51 |
val remove_domain_condition = |
|
52 |
full_simplify (HOL_basic_ss addsimps [totality, @{thm True_implies_equals}]) |
|
53 |
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
|
54 |
val tinducts = map remove_domain_condition pinducts |
2976 | 55 |
val teqvts = map remove_domain_condition eqvts |
2981 | 56 |
|
2976 | 57 |
fun qualify n = Binding.name n |
58 |
|> Binding.qualify true defname |
|
59 |
in |
|
60 |
lthy |
|
61 |
|> add_simps I "simps" I simp_attribs tsimps |
|
3055
1afcbaf4242b
termination does not automatically prove equivariance for the defined function (label: no_eqvt)
Christian Urban <urbanc@in.tum.de>
parents:
3045
diff
changeset
|
62 |
||>> Local_Theory.note ((qualify "eqvt", if is_eqvt then [eqvt_attrib] else []), teqvts) |
2976 | 63 |
||>> Local_Theory.note |
64 |
((qualify "induct", |
|
65 |
[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
|
66 |
tinducts) |
2976 | 67 |
|-> (fn ((simps, (_, eqvts)), (_, inducts)) => fn lthy => |
68 |
let val info' = { is_partial=false, defname=defname, add_simps=add_simps, |
|
69 |
case_names=case_names, fs=fs, R=R, psimps=psimps, pinducts=pinducts, |
|
2981 | 70 |
simps=SOME simps, inducts=SOME inducts, termination=termination, eqvts=teqvts } |
2976 | 71 |
in |
72 |
(info', |
|
73 |
lthy |
|
3045
d0ad264f8c4f
updated to Isabelle 3 Nov; it includes a hack to work around a bug in the localised version of the quotient package
Christian Urban <urbanc@in.tum.de>
parents:
2982
diff
changeset
|
74 |
|> Local_Theory.declaration {syntax = false, pervasive = false} |
d0ad264f8c4f
updated to Isabelle 3 Nov; it includes a hack to work around a bug in the localised version of the quotient package
Christian Urban <urbanc@in.tum.de>
parents:
2982
diff
changeset
|
75 |
(add_function_data o morph_function_data info') |
2976 | 76 |
|> Spec_Rules.add Spec_Rules.Equational (fs, tsimps)) |
77 |
end) |
|
78 |
end |
|
79 |
in |
|
80 |
(goal, afterqed, termination) |
|
81 |
end |
|
82 |
||
3055
1afcbaf4242b
termination does not automatically prove equivariance for the defined function (label: no_eqvt)
Christian Urban <urbanc@in.tum.de>
parents:
3045
diff
changeset
|
83 |
fun gen_termination prep_term is_eqvt raw_term_opt lthy = |
2976 | 84 |
let |
3055
1afcbaf4242b
termination does not automatically prove equivariance for the defined function (label: no_eqvt)
Christian Urban <urbanc@in.tum.de>
parents:
3045
diff
changeset
|
85 |
val (goal, afterqed, termination) = prepare_termination_proof prep_term is_eqvt raw_term_opt lthy |
2976 | 86 |
in |
87 |
lthy |
|
88 |
|> Proof_Context.note_thmss "" |
|
89 |
[((Binding.empty, [Context_Rules.rule_del]), [([allI], [])])] |> snd |
|
90 |
|> Proof_Context.note_thmss "" |
|
91 |
[((Binding.empty, [Context_Rules.intro_bang (SOME 1)]), [([allI], [])])] |> snd |
|
92 |
|> Proof_Context.note_thmss "" |
|
93 |
[((Binding.name "termination", [Context_Rules.intro_bang (SOME 0)]), |
|
94 |
[([Goal.norm_result termination], [])])] |> snd |
|
95 |
|> Proof.theorem NONE (snd oo afterqed) [[(goal, [])]] |
|
96 |
end |
|
97 |
||
98 |
val termination = gen_termination Syntax.check_term |
|
99 |
val termination_cmd = gen_termination Syntax.read_term |
|
100 |
||
101 |
(* outer syntax *) |
|
102 |
||
103 |
val option_parser = |
|
104 |
(Scan.optional (Parse.$$$ "(" |-- Parse.!!! |
|
3055
1afcbaf4242b
termination does not automatically prove equivariance for the defined function (label: no_eqvt)
Christian Urban <urbanc@in.tum.de>
parents:
3045
diff
changeset
|
105 |
((Parse.reserved "eqvt" >> K (true, true)) || |
1afcbaf4242b
termination does not automatically prove equivariance for the defined function (label: no_eqvt)
Christian Urban <urbanc@in.tum.de>
parents:
3045
diff
changeset
|
106 |
(Parse.reserved "no_eqvt" >> K (true, false))) --| Parse.$$$ ")") (false, false)) |
2976 | 107 |
|
108 |
val _ = |
|
109 |
Outer_Syntax.local_theory_to_proof "termination" "prove termination of a recursive function" |
|
110 |
Keyword.thy_goal |
|
111 |
(option_parser -- Scan.option Parse.term >> |
|
3055
1afcbaf4242b
termination does not automatically prove equivariance for the defined function (label: no_eqvt)
Christian Urban <urbanc@in.tum.de>
parents:
3045
diff
changeset
|
112 |
(fn ((is_nominal, is_eqvt), opt_trm) => |
1afcbaf4242b
termination does not automatically prove equivariance for the defined function (label: no_eqvt)
Christian Urban <urbanc@in.tum.de>
parents:
3045
diff
changeset
|
113 |
if is_nominal then termination_cmd is_eqvt opt_trm else Function.termination_cmd opt_trm)) |
2976 | 114 |
|
115 |
end |