154 |
154 |
155 (* prove uniqueness and termination of primrec combinators *) |
155 (* prove uniqueness and termination of primrec combinators *) |
156 |
156 |
157 val _ = Datatype_Aux.message config "Proving termination and uniqueness of primrec functions ..."; |
157 val _ = Datatype_Aux.message config "Proving termination and uniqueness of primrec functions ..."; |
158 |
158 |
159 fun mk_unique_tac ((((i, (tname, _, constrs)), elim), T), T') (tac, intrs) = |
159 fun mk_unique_tac ctxt ((((i, (tname, _, constrs)), elim), T), T') (tac, intrs) = |
160 let |
160 let |
161 val distinct_tac = |
161 val distinct_tac = |
162 if i < length newTs then |
162 if i < length newTs then |
163 full_simp_tac (HOL_ss addsimps (nth dist_rewrites i)) 1 |
163 full_simp_tac (put_simpset HOL_ss ctxt addsimps (nth dist_rewrites i)) 1 |
164 else full_simp_tac (HOL_ss addsimps (flat other_dist_rewrites)) 1; |
164 else full_simp_tac (put_simpset HOL_ss ctxt addsimps (flat other_dist_rewrites)) 1; |
165 |
165 |
166 val inject = |
166 val inject = |
167 map (fn r => r RS iffD1) |
167 map (fn r => r RS iffD1) |
168 (if i < length newTs then nth constr_inject i else injects_of tname); |
168 (if i < length newTs then nth constr_inject i else injects_of tname); |
169 |
169 |
201 val cert = cterm_of thy1; |
201 val cert = cterm_of thy1; |
202 val insts = |
202 val insts = |
203 map (fn ((i, T), t) => absfree ("x" ^ string_of_int i, T) t) |
203 map (fn ((i, T), t) => absfree ("x" ^ string_of_int i, T) t) |
204 ((1 upto length recTs) ~~ recTs ~~ rec_unique_ts); |
204 ((1 upto length recTs) ~~ recTs ~~ rec_unique_ts); |
205 val induct' = cterm_instantiate (map cert induct_Ps ~~ map cert insts) induct; |
205 val induct' = cterm_instantiate (map cert induct_Ps ~~ map cert insts) induct; |
206 val (tac, _) = |
|
207 fold mk_unique_tac (descr' ~~ rec_elims ~~ recTs ~~ rec_result_Ts) |
|
208 (((rtac induct' THEN_ALL_NEW Object_Logic.atomize_prems_tac) 1 THEN |
|
209 rewrite_goals_tac [mk_meta_eq @{thm choice_eq}], rec_intrs)); |
|
210 in |
206 in |
211 Datatype_Aux.split_conj_thm (Goal.prove_sorry_global thy1 [] [] |
207 Datatype_Aux.split_conj_thm (Goal.prove_sorry_global thy1 [] [] |
212 (HOLogic.mk_Trueprop (Datatype_Aux.mk_conj rec_unique_ts)) (K tac)) |
208 (HOLogic.mk_Trueprop (Datatype_Aux.mk_conj rec_unique_ts)) |
|
209 (fn {context = ctxt, ...} => |
|
210 #1 (fold (mk_unique_tac ctxt) (descr' ~~ rec_elims ~~ recTs ~~ rec_result_Ts) |
|
211 (((rtac induct' THEN_ALL_NEW Object_Logic.atomize_prems_tac) 1 THEN |
|
212 rewrite_goals_tac [mk_meta_eq @{thm choice_eq}], rec_intrs))))) |
213 end; |
213 end; |
214 |
214 |
215 val rec_total_thms = map (fn r => r RS @{thm theI'}) rec_unique_thms; |
215 val rec_total_thms = map (fn r => r RS @{thm theI'}) rec_unique_thms; |
216 |
216 |
217 (* define primrec combinators *) |
217 (* define primrec combinators *) |
357 fun prove_split_thms ((((((t1, t2), inject), dist_rewrites'), exhaustion), case_thms'), T) = |
357 fun prove_split_thms ((((((t1, t2), inject), dist_rewrites'), exhaustion), case_thms'), T) = |
358 let |
358 let |
359 val cert = cterm_of thy; |
359 val cert = cterm_of thy; |
360 val _ $ (_ $ lhs $ _) = hd (Logic.strip_assums_hyp (hd (prems_of exhaustion))); |
360 val _ $ (_ $ lhs $ _) = hd (Logic.strip_assums_hyp (hd (prems_of exhaustion))); |
361 val exhaustion' = cterm_instantiate [(cert lhs, cert (Free ("x", T)))] exhaustion; |
361 val exhaustion' = cterm_instantiate [(cert lhs, cert (Free ("x", T)))] exhaustion; |
362 val tac = |
362 fun tac ctxt = |
363 EVERY [rtac exhaustion' 1, |
363 EVERY [rtac exhaustion' 1, |
364 ALLGOALS (asm_simp_tac (HOL_ss addsimps (dist_rewrites' @ inject @ case_thms')))]; |
364 ALLGOALS (asm_simp_tac |
|
365 (put_simpset HOL_ss ctxt addsimps (dist_rewrites' @ inject @ case_thms')))]; |
365 in |
366 in |
366 (Goal.prove_sorry_global thy [] [] t1 (K tac), |
367 (Goal.prove_sorry_global thy [] [] t1 (tac o #context), |
367 Goal.prove_sorry_global thy [] [] t2 (K tac)) |
368 Goal.prove_sorry_global thy [] [] t2 (tac o #context)) |
368 end; |
369 end; |
369 |
370 |
370 val split_thm_pairs = |
371 val split_thm_pairs = |
371 map prove_split_thms |
372 map prove_split_thms |
372 (Datatype_Prop.make_splits case_names descr thy ~~ constr_inject ~~ |
373 (Datatype_Prop.make_splits case_names descr thy ~~ constr_inject ~~ |
427 val nchotomy' = nchotomy RS spec; |
428 val nchotomy' = nchotomy RS spec; |
428 val [v] = Term.add_vars (concl_of nchotomy') []; |
429 val [v] = Term.add_vars (concl_of nchotomy') []; |
429 val nchotomy'' = cterm_instantiate [(cert (Var v), cert Ma)] nchotomy'; |
430 val nchotomy'' = cterm_instantiate [(cert (Var v), cert Ma)] nchotomy'; |
430 in |
431 in |
431 Goal.prove_sorry_global thy [] (Logic.strip_imp_prems t) (Logic.strip_imp_concl t) |
432 Goal.prove_sorry_global thy [] (Logic.strip_imp_prems t) (Logic.strip_imp_concl t) |
432 (fn {prems, ...} => |
433 (fn {context = ctxt, prems, ...} => |
433 let val simplify = asm_simp_tac (HOL_ss addsimps (prems @ case_rewrites)) in |
434 let |
|
435 val simplify = asm_simp_tac (put_simpset HOL_ss ctxt addsimps (prems @ case_rewrites)) |
|
436 in |
434 EVERY [ |
437 EVERY [ |
435 simp_tac (HOL_ss addsimps [hd prems]) 1, |
438 simp_tac (put_simpset HOL_ss ctxt addsimps [hd prems]) 1, |
436 cut_tac nchotomy'' 1, |
439 cut_tac nchotomy'' 1, |
437 REPEAT (etac disjE 1 THEN REPEAT (etac exE 1) THEN simplify 1), |
440 REPEAT (etac disjE 1 THEN REPEAT (etac exE 1) THEN simplify 1), |
438 REPEAT (etac exE 1) THEN simplify 1 (* Get last disjunct *)] |
441 REPEAT (etac exE 1) THEN simplify 1 (* Get last disjunct *)] |
439 end) |
442 end) |
440 end; |
443 end; |