Nominal/nominal_dt_alpha.ML
changeset 2320 d835a2771608
parent 2316 08bbde090a17
child 2322 24de7e548094
equal deleted inserted replaced
2319:7c8783d2dcd0 2320:d835a2771608
    17   val mk_alpha_eq_iff: Proof.context -> thm list -> thm list -> thm list -> thm list -> thm list
    17   val mk_alpha_eq_iff: Proof.context -> thm list -> thm list -> thm list -> thm list -> thm list
    18 
    18 
    19   val raw_prove_refl: term list -> term list -> thm list -> thm -> Proof.context -> thm list
    19   val raw_prove_refl: term list -> term list -> thm list -> thm -> Proof.context -> thm list
    20   val raw_prove_sym: term list -> thm list -> thm -> Proof.context -> thm list
    20   val raw_prove_sym: term list -> thm list -> thm -> Proof.context -> thm list
    21   val raw_prove_trans: term list -> thm list -> thm list -> thm -> thm list -> Proof.context -> thm list
    21   val raw_prove_trans: term list -> thm list -> thm list -> thm -> thm list -> Proof.context -> thm list
       
    22   val raw_prove_bn_imp: term list -> term list -> thm list -> thm -> Proof.context -> thm list
    22 end
    23 end
    23 
    24 
    24 structure Nominal_Dt_Alpha: NOMINAL_DT_ALPHA =
    25 structure Nominal_Dt_Alpha: NOMINAL_DT_ALPHA =
    25 struct
    26 struct
       
    27 
       
    28 fun lookup xs x = the (AList.lookup (op=) xs x)
       
    29 fun group xs = AList.group (op=) xs
    26 
    30 
    27 (** definition of the inductive rules for alpha and alpha_bn **)
    31 (** definition of the inductive rules for alpha and alpha_bn **)
    28 
    32 
    29 (* construct the compound terms for prod_fv and prod_alpha *)
    33 (* construct the compound terms for prod_fv and prod_alpha *)
    30 fun mk_prod_fv (t1, t2) =
    34 fun mk_prod_fv (t1, t2) =
    87 fun mk_alpha_bn_prem alpha_bn_map args args' bodies binder = 
    91 fun mk_alpha_bn_prem alpha_bn_map args args' bodies binder = 
    88   case binder of
    92   case binder of
    89     (NONE, _) => []
    93     (NONE, _) => []
    90   | (SOME bn, i) =>
    94   | (SOME bn, i) =>
    91      if member (op=) bodies i then [] 
    95      if member (op=) bodies i then [] 
    92      else [the (AList.lookup (op=) alpha_bn_map bn) $ (nth args i) $ (nth args' i)]
    96      else [lookup alpha_bn_map bn $ nth args i $ nth args' i]
    93 
    97 
    94 (* generat the premises for an alpha rule; mk_frees is used
    98 (* generat the premises for an alpha rule; mk_frees is used
    95    if no binders are present *)
    99    if no binders are present *)
    96 fun mk_alpha_prems lthy alpha_map alpha_bn_map is_rec (args, args') bclause =
   100 fun mk_alpha_prems lthy alpha_map alpha_bn_map is_rec (args, args') bclause =
    97 let
   101 let
   100       val arg = nth args i
   104       val arg = nth args i
   101       val arg' = nth args' i
   105       val arg' = nth args' i
   102       val ty = fastype_of arg
   106       val ty = fastype_of arg
   103     in
   107     in
   104       if nth is_rec i
   108       if nth is_rec i
   105       then fst (the (AList.lookup (op=) alpha_map ty)) $ arg $ arg'
   109       then fst (lookup alpha_map ty) $ arg $ arg'
   106       else HOLogic.mk_eq (arg, arg')
   110       else HOLogic.mk_eq (arg, arg')
   107     end
   111     end
   108 
   112 
   109   fun mk_alpha_fv i = 
   113   fun mk_alpha_fv i = 
   110     let
   114     let
   139 let
   143 let
   140   val arg_names = Datatype_Prop.make_tnames arg_tys
   144   val arg_names = Datatype_Prop.make_tnames arg_tys
   141   val arg_names' = Name.variant_list arg_names arg_names
   145   val arg_names' = Name.variant_list arg_names arg_names
   142   val args = map Free (arg_names ~~ arg_tys)
   146   val args = map Free (arg_names ~~ arg_tys)
   143   val args' = map Free (arg_names' ~~ arg_tys)
   147   val args' = map Free (arg_names' ~~ arg_tys)
   144   val alpha = fst (the (AList.lookup (op=) alpha_map ty))
   148   val alpha = fst (lookup alpha_map ty)
   145   val concl = HOLogic.mk_Trueprop (alpha $ list_comb (constr, args) $ list_comb (constr, args'))
   149   val concl = HOLogic.mk_Trueprop (alpha $ list_comb (constr, args) $ list_comb (constr, args'))
   146   val prems = map (mk_alpha_prems lthy alpha_map alpha_bn_map is_rec (args, args')) bclauses
   150   val prems = map (mk_alpha_prems lthy alpha_map alpha_bn_map is_rec (args, args')) bclauses
   147 in
   151 in
   148   Library.foldr Logic.mk_implies (flat prems, concl)
   152   Library.foldr Logic.mk_implies (flat prems, concl)
   149 end
   153 end
   167     case AList.lookup (op=) bn_args i of
   171     case AList.lookup (op=) bn_args i of
   168       NONE => (case (AList.lookup (op=) alpha_map ty) of
   172       NONE => (case (AList.lookup (op=) alpha_map ty) of
   169                  NONE =>  [HOLogic.mk_eq (arg, arg')]
   173                  NONE =>  [HOLogic.mk_eq (arg, arg')]
   170                | SOME (alpha, _) => [alpha $ arg $ arg'])
   174                | SOME (alpha, _) => [alpha $ arg $ arg'])
   171     | SOME (NONE) => []
   175     | SOME (NONE) => []
   172     | SOME (SOME bn) => [the (AList.lookup (op=) alpha_bn_map bn) $ arg $ arg']
   176     | SOME (SOME bn) => [lookup alpha_bn_map bn $ arg $ arg']
   173   end  
   177   end  
   174 in
   178 in
   175   case bclause of
   179   case bclause of
   176     BC (_, [], bodies) => 
   180     BC (_, [], bodies) => 
   177       map HOLogic.mk_Trueprop 
   181       map HOLogic.mk_Trueprop 
   183 let
   187 let
   184   val arg_names = Datatype_Prop.make_tnames arg_tys
   188   val arg_names = Datatype_Prop.make_tnames arg_tys
   185   val arg_names' = Name.variant_list arg_names arg_names
   189   val arg_names' = Name.variant_list arg_names arg_names
   186   val args = map Free (arg_names ~~ arg_tys)
   190   val args = map Free (arg_names ~~ arg_tys)
   187   val args' = map Free (arg_names' ~~ arg_tys)
   191   val args' = map Free (arg_names' ~~ arg_tys)
   188   val alpha_bn = the (AList.lookup (op=) alpha_bn_map bn_trm)
   192   val alpha_bn = lookup alpha_bn_map bn_trm
   189   val concl = HOLogic.mk_Trueprop (alpha_bn $ list_comb (constr, args) $ list_comb (constr, args'))
   193   val concl = HOLogic.mk_Trueprop (alpha_bn $ list_comb (constr, args) $ list_comb (constr, args'))
   190   val prems = map (mk_alpha_bn lthy alpha_map alpha_bn_map bn_args is_rec (args, args')) bclauses
   194   val prems = map (mk_alpha_bn lthy alpha_map alpha_bn_map bn_args is_rec (args, args')) bclauses
   191 in
   195 in
   192   Library.foldr Logic.mk_implies (flat prems, concl)
   196   Library.foldr Logic.mk_implies (flat prems, concl)
   193 end
   197 end
   359   val arg_bn_tys = 
   363   val arg_bn_tys = 
   360     alpha_bns
   364     alpha_bns
   361     |> map fastype_of
   365     |> map fastype_of
   362     |> map domain_type
   366     |> map domain_type
   363   val arg_names = Datatype_Prop.make_tnames arg_tys
   367   val arg_names = Datatype_Prop.make_tnames arg_tys
   364   val arg_bn_names = map (fn ty => the (AList.lookup (op=) (arg_tys ~~ arg_names) ty)) arg_bn_tys
   368   val arg_bn_names = map (lookup (arg_tys ~~ arg_names)) arg_bn_tys
   365   val args = map Free (arg_names ~~ arg_tys)
   369   val args = map Free (arg_names ~~ arg_tys)
   366   val arg_bns = map Free (arg_bn_names ~~ arg_bn_tys)
   370   val arg_bns = map Free (arg_bn_names ~~ arg_bn_tys)
   367   val goal = 
   371   val goal = 
   368     AList.group (op=) ((arg_bns ~~ alpha_bns) @ (args ~~ alpha_trms))
   372     group ((arg_bns ~~ alpha_bns) @ (args ~~ alpha_trms))
   369     |> map (fn (ar, cnsts) => map (fn c => c $ ar $ ar) cnsts) 
   373     |> map (fn (ar, cnsts) => map (fn c => c $ ar $ ar) cnsts) 
   370     |> map (foldr1 HOLogic.mk_conj)
   374     |> map (foldr1 HOLogic.mk_conj)
   371     |> foldr1 HOLogic.mk_conj
   375     |> foldr1 HOLogic.mk_conj
   372     |> HOLogic.mk_Trueprop
   376     |> HOLogic.mk_Trueprop
   373 in
   377 in
   536     |> singleton (ProofContext.export ctxt' ctxt)
   540     |> singleton (ProofContext.export ctxt' ctxt)
   537     |> Datatype_Aux.split_conj_thm 
   541     |> Datatype_Aux.split_conj_thm 
   538     |> map (fn th => zero_var_indexes (th RS norm))
   542     |> map (fn th => zero_var_indexes (th RS norm))
   539 end
   543 end
   540 
   544 
       
   545 
       
   546 (* proves that alpha_raw implies alpha_bn *)
       
   547 
       
   548 fun is_true @{term "Trueprop True"} = true
       
   549   | is_true _ = false 
       
   550 
       
   551 fun raw_prove_bn_imp_tac pred_names alpha_intros ctxt = 
       
   552   Subgoal.FOCUS (fn {prems, context, ...} => 
       
   553     let
       
   554       val prems' = flat (map Datatype_Aux.split_conj_thm prems)
       
   555       val prems'' = map (transform_prem1 context pred_names) prems'
       
   556     in
       
   557       HEADGOAL (REPEAT o 
       
   558         FIRST' [ rtac @{thm TrueI}, 
       
   559                  rtac @{thm conjI}, 
       
   560                  resolve_tac prems', 
       
   561                  resolve_tac prems'',
       
   562                  resolve_tac alpha_intros ])
       
   563     end) ctxt
       
   564 
       
   565 fun raw_prove_bn_imp alpha_trms alpha_bns alpha_intros alpha_induct ctxt =
       
   566 let
       
   567   val alpha_names =  map (fst o dest_Const) alpha_trms
       
   568 
       
   569   val arg_tys = 
       
   570     alpha_trms
       
   571     |> map fastype_of
       
   572     |> map domain_type
       
   573   val arg_bn_tys = 
       
   574     alpha_bns
       
   575     |> map fastype_of
       
   576     |> map domain_type
       
   577   val (arg_names1, (arg_names2, ctxt')) =
       
   578     ctxt
       
   579     |> Variable.variant_fixes (replicate (length arg_tys) "x") 
       
   580     ||> Variable.variant_fixes (replicate (length arg_tys) "y")
       
   581   val arg_bn_names1 = map (lookup (arg_tys ~~ arg_names1)) arg_bn_tys
       
   582   val arg_bn_names2 = map (lookup (arg_tys ~~ arg_names2)) arg_bn_tys
       
   583   val args1 = map Free (arg_names1 ~~ arg_tys)
       
   584   val args2 = map Free (arg_names2 ~~ arg_tys)
       
   585   val arg_bns1 = map Free (arg_bn_names1 ~~ arg_bn_tys)
       
   586   val arg_bns2 = map Free (arg_bn_names2 ~~ arg_bn_tys)
       
   587 
       
   588   val alpha_bn_trms = map2 (fn t => fn (ar1, ar2) => t $ ar1 $ ar2) alpha_bns (arg_bns1 ~~ arg_bns2)
       
   589   val true_trms = map (K @{term True}) arg_tys
       
   590 
       
   591   val goal_rhs = 
       
   592     group ((arg_bn_tys ~~ alpha_bn_trms) @ (arg_tys ~~ true_trms))
       
   593     |> map snd 
       
   594     |> map (foldr1 HOLogic.mk_conj)
       
   595 
       
   596   val goal_lhs = map2 (fn t => fn (ar1, ar2) => t $ ar1 $ ar2) alpha_trms (args1 ~~ args2)
       
   597   val goal_rest = map (fn t => HOLogic.mk_imp (t, @{term "True"})) alpha_bn_trms  
       
   598 
       
   599   val goal =
       
   600     (map2 (curry HOLogic.mk_imp) goal_lhs goal_rhs) @ goal_rest
       
   601     |> foldr1 HOLogic.mk_conj
       
   602     |> HOLogic.mk_Trueprop
       
   603 in
       
   604   Goal.prove ctxt' [] [] goal
       
   605     (fn {context, ...} => 
       
   606        HEADGOAL (DETERM o (rtac alpha_induct) 
       
   607          THEN_ALL_NEW raw_prove_bn_imp_tac alpha_names alpha_intros context)) 
       
   608   |> singleton (ProofContext.export ctxt' ctxt)
       
   609   |> Datatype_Aux.split_conj_thm 
       
   610   |> map (fn th => zero_var_indexes (th RS mp))
       
   611   |> map Datatype_Aux.split_conj_thm 
       
   612   |> flat
       
   613   |> filter_out (is_true o concl_of)
       
   614 end
       
   615 
       
   616 
   541 end (* structure *)
   617 end (* structure *)
   542 
   618