4 Copyright 1997 University of Cambridge |
4 Copyright 1997 University of Cambridge |
5 |
5 |
6 Postprocessing of TFL definitions |
6 Postprocessing of TFL definitions |
7 *) |
7 *) |
8 |
8 |
9 (*------------------------------------------------------------------------- |
|
10 Three postprocessors are applied to the definition: |
|
11 - a wellfoundedness prover (WF_TAC) |
|
12 - a simplifier (tries to eliminate the language of termination expressions) |
|
13 - a termination prover |
|
14 *-------------------------------------------------------------------------*) |
|
15 |
|
16 signature TFL = |
9 signature TFL = |
17 sig |
10 sig |
18 structure Prim : TFL_sig |
11 structure Prim : TFL_sig |
19 |
12 |
20 val tgoalw : theory -> thm list -> thm list -> thm list |
13 val tgoalw : theory -> thm list -> thm list -> thm list |
21 val tgoal: theory -> thm list -> thm list |
14 val tgoal: theory -> thm list -> thm list |
22 |
15 |
23 val WF_TAC : thm list -> tactic |
16 val std_postprocessor : simpset -> theory |
24 |
|
25 val simplifier : thm -> thm |
|
26 val std_postprocessor : theory |
|
27 -> {induction:thm, rules:thm, TCs:term list list} |
17 -> {induction:thm, rules:thm, TCs:term list list} |
28 -> {induction:thm, rules:thm, nested_tcs:thm list} |
18 -> {induction:thm, rules:thm, nested_tcs:thm list} |
29 |
19 |
30 val define_i : theory -> string -> term -> term list |
20 val define_i : theory -> string -> term -> term list |
31 -> theory * (thm * Prim.pattern list) |
21 -> theory * Prim.pattern list |
32 |
22 |
33 val define : theory -> string -> string -> string list |
23 val define : theory -> string -> string -> string list |
34 -> theory * Prim.pattern list |
24 -> theory * Prim.pattern list |
35 |
25 |
36 val simplify_defn : theory * (string * Prim.pattern list) |
26 val simplify_defn : simpset -> theory * (string * Prim.pattern list) |
37 -> {rules:thm list, induct:thm, tcs:term list} |
27 -> {rules:thm list, induct:thm, tcs:term list} |
38 |
28 |
39 (*------------------------------------------------------------------------- |
29 (*------------------------------------------------------------------------- |
40 val function : theory -> term -> {theory:theory, eq_ind : thm} |
30 val function : theory -> term -> {theory:theory, eq_ind : thm} |
41 val lazyR_def: theory -> term -> {theory:theory, eqns : thm} |
31 val lazyR_def: theory -> term -> {theory:theory, eqns : thm} |
54 (*--------------------------------------------------------------------------- |
44 (*--------------------------------------------------------------------------- |
55 * Extract termination goals so that they can be put it into a goalstack, or |
45 * Extract termination goals so that they can be put it into a goalstack, or |
56 * have a tactic directly applied to them. |
46 * have a tactic directly applied to them. |
57 *--------------------------------------------------------------------------*) |
47 *--------------------------------------------------------------------------*) |
58 fun termination_goals rules = |
48 fun termination_goals rules = |
59 map (Logic.freeze_vars o HOLogic.dest_Trueprop) |
49 map (#1 o Type.freeze_thaw o HOLogic.dest_Trueprop) |
60 (foldr (fn (th,A) => union_term (prems_of th, A)) (rules, [])); |
50 (foldr (fn (th,A) => union_term (prems_of th, A)) (rules, [])); |
61 |
51 |
62 (*--------------------------------------------------------------------------- |
52 (*--------------------------------------------------------------------------- |
63 * Finds the termination conditions in (highly massaged) definition and |
53 * Finds the termination conditions in (highly massaged) definition and |
64 * puts them into a goalstack. |
54 * puts them into a goalstack. |
65 *--------------------------------------------------------------------------*) |
55 *--------------------------------------------------------------------------*) |
66 fun tgoalw thy defs rules = |
56 fun tgoalw thy defs rules = |
67 let val L = termination_goals rules |
57 let val L = termination_goals rules |
68 open USyntax |
58 open USyntax |
69 val g = cterm_of (sign_of thy) (HOLogic.mk_Trueprop(list_mk_conj L)) |
59 val g = cterm_of (sign_of thy) (HOLogic.mk_Trueprop(list_mk_conj L)) |
70 in goalw_cterm defs g |
60 in goalw_cterm defs g |
71 end; |
61 end; |
72 |
62 |
73 fun tgoal thy = tgoalw thy []; |
63 fun tgoal thy = tgoalw thy []; |
74 |
64 |
75 (*--------------------------------------------------------------------------- |
65 (*--------------------------------------------------------------------------- |
76 * Simple wellfoundedness prover. |
66 * Three postprocessors are applied to the definition. It |
77 *--------------------------------------------------------------------------*) |
67 * attempts to prove wellfoundedness of the given relation, simplifies the |
78 fun WF_TAC thms = REPEAT(FIRST1(map rtac thms)) |
68 * non-proved termination conditions, and finally attempts to prove the |
79 val WFtac = WF_TAC[wf_measure, wf_inv_image, wf_lex_prod, wf_less_than, |
69 * simplified termination conditions. |
80 wf_trancl]; |
70 *--------------------------------------------------------------------------*) |
81 |
71 fun std_postprocessor ss = |
82 val terminator = simp_tac(!simpset addsimps [less_Suc_eq]) 1 |
72 Prim.postprocess |
83 THEN TRY(best_tac |
73 {WFtac = REPEAT (ares_tac [wf_measure, wf_inv_image, wf_lex_prod, |
84 (!claset addSDs [not0_implies_Suc] |
74 wf_less_than, wf_trancl] 1), |
85 addss (!simpset)) 1); |
75 terminator = asm_simp_tac ss 1 |
86 |
76 THEN TRY(best_tac |
87 val simpls = [less_eq RS eq_reflection, |
77 (!claset addSDs [not0_implies_Suc] addss ss) 1), |
88 lex_prod_def, measure_def, inv_image_def]; |
78 simplifier = Rules.simpl_conv ss []}; |
89 |
79 |
90 (*--------------------------------------------------------------------------- |
80 fun tflcongs thy = Prim.Context.read() @ (#case_congs(Thry.extract_info thy)); |
91 * Does some standard things with the termination conditions of a definition: |
|
92 * attempts to prove wellfoundedness of the given relation; simplifies the |
|
93 * non-proven termination conditions; and finally attempts to prove the |
|
94 * simplified termination conditions. |
|
95 *--------------------------------------------------------------------------*) |
|
96 val std_postprocessor = Prim.postprocess{WFtac = WFtac, |
|
97 terminator = terminator, |
|
98 simplifier = Rules.simpl_conv simpls}; |
|
99 |
|
100 val simplifier = rewrite_rule (simpls @ #simps(rep_ss (!simpset)) @ |
|
101 [pred_list_def]); |
|
102 |
|
103 fun tflcongs thy = Prim.Context.read() @ (#case_congs(Thry.extract_info thy)); |
|
104 |
81 |
105 |
82 |
106 val concl = #2 o Rules.dest_thm; |
83 val concl = #2 o Rules.dest_thm; |
107 |
84 |
108 (*--------------------------------------------------------------------------- |
85 (*--------------------------------------------------------------------------- |
109 * Defining a function with an associated termination relation. |
86 * Defining a function with an associated termination relation. |
110 *---------------------------------------------------------------------------*) |
87 *---------------------------------------------------------------------------*) |
111 fun define_i thy fid R eqs = |
88 fun define_i thy fid R eqs = |
112 let val dummy = require_thy thy "WF_Rel" "recursive function definitions" |
89 let val dummy = require_thy thy "WF_Rel" "recursive function definitions" |
113 val {functional,pats} = Prim.mk_functional thy eqs |
90 val {functional,pats} = Prim.mk_functional thy eqs |
114 val (thm,thry) = Prim.wfrec_definition0 thy fid R functional |
91 in (Prim.wfrec_definition0 thy fid R functional, pats) |
115 in (thry,(thm,pats)) |
|
116 end; |
92 end; |
117 |
93 |
118 (*lcp's version: takes strings; doesn't return "thm" |
94 (*lcp's version: takes strings; doesn't return "thm" |
119 (whose signature is a draft and therefore useless) *) |
95 (whose signature is a draft and therefore useless) *) |
120 fun define thy fid R eqs = |
96 fun define thy fid R eqs = |
121 let fun read thy = readtm (sign_of thy) (TVar(("DUMMY",0),[])) |
97 let fun read thy = readtm (sign_of thy) (TVar(("DUMMY",0),[])) |
122 val (thy',(_,pats)) = |
98 in define_i thy fid (read thy R) (map (read thy) eqs) end |
123 define_i thy fid (read thy R) (map (read thy) eqs) |
|
124 in (thy',pats) end |
|
125 handle Utils.ERR {mesg,...} => error mesg; |
99 handle Utils.ERR {mesg,...} => error mesg; |
126 |
100 |
127 (*--------------------------------------------------------------------------- |
101 (*--------------------------------------------------------------------------- |
128 * Postprocess a definition made by "define". This is a separate stage of |
102 * Postprocess a definition made by "define". This is a separate stage of |
129 * processing from the definition stage. |
103 * processing from the definition stage. |
162 (R.DISCH_ALL |
137 (R.DISCH_ALL |
163 (rewrite (map (R.ASSUME o tych) cntxt) (R.SPEC_ALL th))) |
138 (rewrite (map (R.ASSUME o tych) cntxt) (R.SPEC_ALL th))) |
164 end |
139 end |
165 val gen_all = S.gen_all |
140 val gen_all = S.gen_all |
166 in |
141 in |
167 (*--------------------------------------------------------------------------- |
142 fun proof_stage ss theory {f, R, rules, full_pats_TCs, TCs} = |
168 * The "reducer" argument is |
|
169 * (fn thl => rewrite (map standard thl @ #simps(rep_ss (!simpset)))); |
|
170 *---------------------------------------------------------------------------*) |
|
171 fun proof_stage theory reducer {f, R, rules, full_pats_TCs, TCs} = |
|
172 let val dummy = prs "Proving induction theorem.. " |
143 let val dummy = prs "Proving induction theorem.. " |
173 val ind = Prim.mk_induction theory f R full_pats_TCs |
144 val ind = Prim.mk_induction theory f R full_pats_TCs |
174 val dummy = writeln "Proved induction theorem." |
145 val dummy = prs "Proved induction theorem.\nPostprocessing.. " |
175 val pp = std_postprocessor theory |
146 val {rules, induction, nested_tcs} = |
176 val dummy = prs "Postprocessing.. " |
147 std_postprocessor ss theory {rules=rules, induction=ind, TCs=TCs} |
177 val {rules,induction,nested_tcs} = pp{rules=rules,induction=ind,TCs=TCs} |
|
178 in |
148 in |
179 case nested_tcs |
149 case nested_tcs |
180 of [] => (writeln "Postprocessing done."; |
150 of [] => (writeln "Postprocessing done."; |
181 {induction=induction, rules=rules,tcs=[]}) |
151 {induction=induction, rules=rules,tcs=[]}) |
182 | L => let val dummy = prs "Simplifying nested TCs.. " |
152 | L => let val dummy = prs "Simplifying nested TCs.. " |
184 U.itlist (fn th => fn (So,Si,St) => |
154 U.itlist (fn th => fn (So,Si,St) => |
185 if (id_thm th) then (So, Si, th::St) else |
155 if (id_thm th) then (So, Si, th::St) else |
186 if (solved th) then (th::So, Si, St) |
156 if (solved th) then (th::So, Si, St) |
187 else (So, th::Si, St)) nested_tcs ([],[],[]) |
157 else (So, th::Si, St)) nested_tcs ([],[],[]) |
188 val simplified' = map join_assums simplified |
158 val simplified' = map join_assums simplified |
189 val induction' = reducer (solved@simplified') induction |
159 val rewr = rewrite (solved @ simplified' @ #simps(rep_ss ss)) |
190 val rules' = reducer (solved@simplified') rules |
160 val induction' = rewr induction |
|
161 and rules' = rewr rules |
191 val dummy = writeln "Postprocessing done." |
162 val dummy = writeln "Postprocessing done." |
192 in |
163 in |
193 {induction = induction', |
164 {induction = induction', |
194 rules = rules', |
165 rules = rules', |
195 tcs = map (gen_all o S.rhs o #2 o S.strip_forall o concl) |
166 tcs = map (gen_all o S.rhs o #2 o S.strip_forall o concl) |
210 ORELSE' etac conjE)); |
181 ORELSE' etac conjE)); |
211 |
182 |
212 (*Strip off the outer !P*) |
183 (*Strip off the outer !P*) |
213 val spec'= read_instantiate [("x","P::?'b=>bool")] spec; |
184 val spec'= read_instantiate [("x","P::?'b=>bool")] spec; |
214 |
185 |
215 |
186 val wf_rel_defs = [lex_prod_def, measure_def, inv_image_def]; |
216 fun simplify_defn (thy,(id,pats)) = |
187 |
|
188 fun simplify_defn ss (thy,(id,pats)) = |
217 let val dummy = deny (id mem map ! (stamps_of_thy thy)) |
189 let val dummy = deny (id mem map ! (stamps_of_thy thy)) |
218 ("Recursive definition " ^ id ^ |
190 ("Recursive definition " ^ id ^ |
219 " would clash with the theory of the same name!") |
191 " would clash with the theory of the same name!") |
220 val def = freezeT(get_def thy id RS meta_eq_to_obj_eq) |
192 val def = freezeT(get_def thy id) RS meta_eq_to_obj_eq |
|
193 val ss' = ss addsimps ((less_Suc_eq RS iffD2) :: wf_rel_defs) |
221 val {theory,rules,TCs,full_pats_TCs,patterns} = |
194 val {theory,rules,TCs,full_pats_TCs,patterns} = |
222 Prim.post_definition (thy,(def,pats)) |
195 Prim.post_definition ss' (thy,(def,pats)) |
223 val {lhs=f,rhs} = S.dest_eq(concl def) |
196 val {lhs=f,rhs} = S.dest_eq(concl def) |
224 val (_,[R,_]) = S.strip_comb rhs |
197 val (_,[R,_]) = S.strip_comb rhs |
225 val {induction, rules, tcs} = |
198 val {induction, rules, tcs} = |
226 proof_stage theory reducer |
199 proof_stage ss' theory |
227 {f = f, R = R, rules = rules, |
200 {f = f, R = R, rules = rules, |
228 full_pats_TCs = full_pats_TCs, |
201 full_pats_TCs = full_pats_TCs, |
229 TCs = TCs} |
202 TCs = TCs} |
230 val rules' = map (standard o normalize_thm [RSmp]) (R.CONJUNCTS rules) |
203 val rules' = map (standard o normalize_thm [RSmp]) (R.CONJUNCTS rules) |
231 in {induct = meta_outer |
204 in {induct = meta_outer |