src/HOL/Tools/Datatype/rep_datatype.ML
changeset 51717 9e7d1c139569
parent 51673 4dfa00e264d8
child 51798 ad3a241def73
equal deleted inserted replaced
51709:19b47bfac6ef 51717:9e7d1c139569
   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;