Nominal/nominal_mutual.ML
changeset 3218 89158f401b07
parent 3204 b69c8660de14
child 3219 e5d9b6bca88c
equal deleted inserted replaced
3217:d67a6a48f1c7 3218:89158f401b07
   196   in
   196   in
   197     Goal.prove ctxt [] []
   197     Goal.prove ctxt [] []
   198       (HOLogic.Trueprop $ HOLogic.mk_eq (list_comb (f, args), rhs))
   198       (HOLogic.Trueprop $ HOLogic.mk_eq (list_comb (f, args), rhs))
   199       (fn _ => (Local_Defs.unfold_tac ctxt all_orig_fdefs)
   199       (fn _ => (Local_Defs.unfold_tac ctxt all_orig_fdefs)
   200          THEN EqSubst.eqsubst_tac ctxt [0] [simp] 1
   200          THEN EqSubst.eqsubst_tac ctxt [0] [simp] 1
   201          THEN (simp_tac (simpset_of ctxt)) 1) (* FIXME: global simpset?!! *)
   201          THEN (simp_tac ctxt) 1)
   202     |> restore_cond
   202     |> restore_cond
   203     |> export
   203     |> export
   204   end
   204   end
   205 
   205 
   206 val inl_perm = @{lemma "x = Inl y ==> Sum_Type.Projl (permute p x) = permute p (Sum_Type.Projl x)" by simp}
   206 val inl_perm = @{lemma "x = Inl y ==> Sum_Type.Projl (permute p x) = permute p (Sum_Type.Projl x)" by simp}
   221     val ([p], ctxt') = ctxt
   221     val ([p], ctxt') = ctxt
   222       |> fold Variable.declare_term args  
   222       |> fold Variable.declare_term args  
   223       |> Variable.variant_fixes ["p"] 		   
   223       |> Variable.variant_fixes ["p"] 		   
   224     val p = Free (p, @{typ perm})
   224     val p = Free (p, @{typ perm})
   225 
   225 
   226     val ss = HOL_basic_ss addsimps 
   226     val simpset =
       
   227       put_simpset HOL_basic_ss ctxt' addsimps 
   227       @{thms permute_sum.simps[symmetric] Pair_eqvt[symmetric]} @
   228       @{thms permute_sum.simps[symmetric] Pair_eqvt[symmetric]} @
   228       @{thms Projr.simps Projl.simps} @
   229       @{thms Projr.simps Projl.simps} @
   229       [(cond MRS eqvt_thm) RS @{thm sym}] @ 
   230       [(cond MRS eqvt_thm) RS @{thm sym}] @ 
   230       [inl_perm, inr_perm, simp] 
   231       [inl_perm, inr_perm, simp] 
   231     val goal_lhs = mk_perm p (list_comb (f, args))
   232     val goal_lhs = mk_perm p (list_comb (f, args))
   232     val goal_rhs = list_comb (f, map (mk_perm p) args)
   233     val goal_rhs = list_comb (f, map (mk_perm p) args)
   233   in
   234   in
   234     Goal.prove ctxt' [] [] (HOLogic.Trueprop $ HOLogic.mk_eq (goal_lhs, goal_rhs))
   235     Goal.prove ctxt' [] [] (HOLogic.Trueprop $ HOLogic.mk_eq (goal_lhs, goal_rhs))
   235       (fn _ => (Local_Defs.unfold_tac ctxt all_orig_fdefs)
   236       (fn _ => (Local_Defs.unfold_tac ctxt all_orig_fdefs)
   236          THEN (asm_full_simp_tac ss 1))
   237          THEN (asm_full_simp_tac simpset 1))
   237     |> singleton (Proof_Context.export ctxt' ctxt)
   238     |> singleton (Proof_Context.export ctxt' ctxt)
   238     |> restore_cond
   239     |> restore_cond
   239     |> export
   240     |> export
   240   end
   241   end
   241 
   242 
   248     |> Conv.fconv_rule (Thm.beta_conversion true)
   249     |> Conv.fconv_rule (Thm.beta_conversion true)
   249     |> fold_rev Thm.forall_intr xs
   250     |> fold_rev Thm.forall_intr xs
   250     |> Thm.forall_elim_vars 0
   251     |> Thm.forall_elim_vars 0
   251   end
   252   end
   252 
   253 
   253 fun mutual_induct_rules lthy induct all_f_defs (Mutual {n, ST, parts, ...}) =
   254 fun mutual_induct_rules ctxt induct all_f_defs (Mutual {n, ST, parts, ...}) =
   254   let
   255   let
   255     val cert = cterm_of (Proof_Context.theory_of lthy)
   256     val cert = cterm_of (Proof_Context.theory_of ctxt)
   256     val newPs =
   257     val newPs =
   257       map2 (fn Pname => fn MutualPart {cargTs, ...} =>
   258       map2 (fn Pname => fn MutualPart {cargTs, ...} =>
   258           Free (Pname, cargTs ---> HOLogic.boolT))
   259           Free (Pname, cargTs ---> HOLogic.boolT))
   259         (mutual_induct_Pnames (length parts)) parts
   260         (mutual_induct_Pnames (length parts)) parts
   260 
   261 
   269     val Ps = map2 mk_P parts newPs
   270     val Ps = map2 mk_P parts newPs
   270     val case_exp = SumTree.mk_sumcases HOLogic.boolT Ps
   271     val case_exp = SumTree.mk_sumcases HOLogic.boolT Ps
   271 
   272 
   272     val induct_inst =
   273     val induct_inst =
   273       Thm.forall_elim (cert case_exp) induct
   274       Thm.forall_elim (cert case_exp) induct
   274       |> full_simplify SumTree.sumcase_split_ss
   275       |> full_simplify (put_simpset SumTree.sumcase_split_ss ctxt)
   275       |> full_simplify (HOL_basic_ss addsimps all_f_defs)
   276       |> full_simplify (put_simpset HOL_basic_ss ctxt addsimps all_f_defs)
   276 
   277 
   277     fun project rule (MutualPart {cargTs, i, ...}) k =
   278     fun project rule (MutualPart {cargTs, i, ...}) k =
   278       let
   279       let
   279         val afs = map_index (fn (j,T) => Free ("a" ^ string_of_int (j + k), T)) cargTs (* FIXME! *)
   280         val afs = map_index (fn (j,T) => Free ("a" ^ string_of_int (j + k), T)) cargTs (* FIXME! *)
   280         val inj = SumTree.mk_inj ST n i (foldr1 HOLogic.mk_prod afs)
   281         val inj = SumTree.mk_inj ST n i (foldr1 HOLogic.mk_prod afs)
   281       in
   282       in
   282         (rule
   283         (rule
   283          |> Thm.forall_elim (cert inj)
   284          |> Thm.forall_elim (cert inj)
   284          |> full_simplify SumTree.sumcase_split_ss
   285          |> full_simplify (put_simpset SumTree.sumcase_split_ss ctxt)
   285          |> fold_rev (Thm.forall_intr o cert) (afs @ newPs),
   286          |> fold_rev (Thm.forall_intr o cert) (afs @ newPs),
   286          k + length cargTs)
   287          k + length cargTs)
   287       end
   288       end
   288   in
   289   in
   289     fst (fold_map (project induct_inst) parts 0)
   290     fst (fold_map (project induct_inst) parts 0)
   348     |> singleton (Proof_Context.export ctxt' ctxt)
   349     |> singleton (Proof_Context.export ctxt' ctxt)
   349     |> split_conj_thm
   350     |> split_conj_thm
   350     |> map (fn th => th RS mp)
   351     |> map (fn th => th RS mp)
   351   end
   352   end
   352 
   353 
   353 fun mk_partial_rules_mutual lthy inner_cont (m as Mutual {parts, fqgars, ...}) proof =
   354 fun mk_partial_rules_mutual ctxt inner_cont (m as Mutual {parts, fqgars, ...}) proof =
   354   let
   355   let
   355     val result = inner_cont proof
   356     val result = inner_cont proof
   356 
   357 
   357     val NominalFunctionResult {G, R, cases, psimps, simple_pinducts=[simple_pinduct],
   358     val NominalFunctionResult {G, R, cases, psimps, simple_pinducts=[simple_pinduct],
   358       termination, domintros, eqvts=[eqvt],...} = result
   359       termination, domintros, eqvts=[eqvt],...} = result
   359 
   360 
   360     val (all_f_defs, fs) =
   361     val (all_f_defs, fs) =
   361       map (fn MutualPart {f_defthm = SOME f_def, f = SOME f, cargTs, ...} =>
   362       map (fn MutualPart {f_defthm = SOME f_def, f = SOME f, cargTs, ...} =>
   362           (mk_applied_form lthy cargTs (Thm.symmetric f_def), f))
   363           (mk_applied_form ctxt cargTs (Thm.symmetric f_def), f))
   363       parts
   364       parts
   364       |> split_list
   365       |> split_list
   365 
   366 
   366     val all_orig_fdefs =
   367     val all_orig_fdefs =
   367       map (fn MutualPart {f_defthm = SOME f_def, ...} => f_def) parts
   368       map (fn MutualPart {f_defthm = SOME f_def, ...} => f_def) parts
   368 
   369 
   369     val cargTss =
   370     val cargTss =
   370       map (fn MutualPart {f = SOME f, cargTs, ...} => cargTs) parts
   371       map (fn MutualPart {f = SOME f, cargTs, ...} => cargTs) parts
   371 
   372 
   372     fun mk_mpsimp fqgar sum_psimp =
   373     fun mk_mpsimp fqgar sum_psimp =
   373       in_context lthy fqgar (recover_mutual_psimp all_orig_fdefs parts) sum_psimp
   374       in_context ctxt fqgar (recover_mutual_psimp all_orig_fdefs parts) sum_psimp
   374 
   375 
   375     fun mk_meqvts fqgar sum_psimp =
   376     fun mk_meqvts fqgar sum_psimp =
   376       in_context lthy fqgar (recover_mutual_eqvt eqvt all_orig_fdefs parts) sum_psimp
   377       in_context ctxt fqgar (recover_mutual_eqvt eqvt all_orig_fdefs parts) sum_psimp
   377 
   378 
   378     val rew_ss = HOL_basic_ss addsimps all_f_defs
   379     val rew_simpset = put_simpset HOL_basic_ss ctxt addsimps all_f_defs
   379     val mpsimps = map2 mk_mpsimp fqgars psimps
   380     val mpsimps = map2 mk_mpsimp fqgars psimps
   380     val minducts = mutual_induct_rules lthy simple_pinduct all_f_defs m
   381     val minducts = mutual_induct_rules ctxt simple_pinduct all_f_defs m
   381     val mtermination = full_simplify rew_ss termination
   382     val mtermination = full_simplify rew_simpset termination
   382     val mdomintros = Option.map (map (full_simplify rew_ss)) domintros
   383     val mdomintros = Option.map (map (full_simplify rew_simpset)) domintros
   383     val meqvts = map2 mk_meqvts fqgars psimps
   384     val meqvts = map2 mk_meqvts fqgars psimps
   384     val meqvt_funs = prove_eqvt lthy fs cargTss meqvts minducts
   385     val meqvt_funs = prove_eqvt ctxt fs cargTss meqvts minducts
   385  in
   386  in
   386     NominalFunctionResult { fs=fs, G=G, R=R,
   387     NominalFunctionResult { fs=fs, G=G, R=R,
   387       psimps=mpsimps, simple_pinducts=minducts,
   388       psimps=mpsimps, simple_pinducts=minducts,
   388       cases=cases, termination=mtermination,
   389       cases=cases, termination=mtermination,
   389       domintros=mdomintros, eqvts=meqvt_funs }
   390       domintros=mdomintros, eqvts=meqvt_funs }
   470       |> all x |> all y
   471       |> all x |> all y
   471     val goal_iff2 = Logic.mk_implies (G_prem, G_aux_prem)
   472     val goal_iff2 = Logic.mk_implies (G_prem, G_aux_prem)
   472       |> all x |> all y
   473       |> all x |> all y
   473 
   474 
   474     val simp_thms = @{thms Projl.simps Projr.simps sum.inject sum.cases sum.distinct o_apply}
   475     val simp_thms = @{thms Projl.simps Projr.simps sum.inject sum.cases sum.distinct o_apply}
   475     val ss0 = HOL_basic_ss addsimps simp_thms
   476     val simpset0 = put_simpset HOL_basic_ss lthy''' addsimps simp_thms
   476     val ss1 = HOL_ss addsimps simp_thms
   477     val simpset1 = put_simpset HOL_ss lthy''' addsimps simp_thms
   477 
   478 
   478     val inj_thm = Goal.prove lthy''' [] [] goal_inj 
   479     val inj_thm = Goal.prove lthy''' [] [] goal_inj 
   479       (K (HEADGOAL (DETERM o etac G_aux_induct THEN_ALL_NEW asm_simp_tac ss1)))
   480       (K (HEADGOAL (DETERM o etac G_aux_induct THEN_ALL_NEW asm_simp_tac simpset1)))
   480 
   481 
   481     fun aux_tac thm = 
   482     fun aux_tac thm = 
   482       rtac (Drule.gen_all thm) THEN_ALL_NEW (asm_full_simp_tac (ss1 addsimps [inj_thm]))
   483       rtac (Drule.gen_all thm) THEN_ALL_NEW (asm_full_simp_tac (simpset1 addsimps [inj_thm]))
   483     
   484     
   484     val iff1_thm = Goal.prove lthy''' [] [] goal_iff1 
   485     val iff1_thm = Goal.prove lthy''' [] [] goal_iff1 
   485       (K (HEADGOAL (DETERM o etac G_aux_induct THEN' RANGE (map aux_tac GIntro_thms))))
   486       (K (HEADGOAL (DETERM o etac G_aux_induct THEN' RANGE (map aux_tac GIntro_thms))))
   486       |> Drule.gen_all
   487       |> Drule.gen_all
   487     val iff2_thm = Goal.prove lthy''' [] [] goal_iff2 
   488     val iff2_thm = Goal.prove lthy''' [] [] goal_iff2 
   488       (K (HEADGOAL (DETERM o etac G_induct THEN' RANGE (map (aux_tac o simplify ss0) GIntro_aux_thms))))
   489       (K (HEADGOAL (DETERM o etac G_induct THEN' RANGE
       
   490         (map (aux_tac o simplify simpset0) GIntro_aux_thms))))
   489       |> Drule.gen_all
   491       |> Drule.gen_all
   490 
   492 
   491     val iff_thm = Goal.prove lthy''' [] [] (HOLogic.mk_Trueprop (HOLogic.mk_eq (G, G_aux)))
   493     val iff_thm = Goal.prove lthy''' [] [] (HOLogic.mk_Trueprop (HOLogic.mk_eq (G, G_aux)))
   492       (K (HEADGOAL (EVERY' ((map rtac @{thms ext ext iffI}) @ [etac iff2_thm, etac iff1_thm]))))
   494       (K (HEADGOAL (EVERY' ((map rtac @{thms ext ext iffI}) @ [etac iff2_thm, etac iff1_thm]))))
   493  
   495  
   494     val tac = HEADGOAL (simp_tac (HOL_basic_ss addsimps [iff_thm]))
   496     val tac = HEADGOAL (simp_tac (put_simpset HOL_basic_ss lthy''' addsimps [iff_thm]))
   495     val goalstate' = 
   497     val goalstate' = 
   496       case (SINGLE tac) goalstate of
   498       case (SINGLE tac) goalstate of
   497         NONE => error "auxiliary equivalence proof failed"
   499         NONE => error "auxiliary equivalence proof failed"
   498       | SOME st => st
   500       | SOME st => st
   499   in
   501   in