Nominal/nominal_dt_rawfuns.ML
changeset 2295 8aff3f3ce47f
parent 2294 72ad4e766acf
child 2296 45a69c9cc4cc
equal deleted inserted replaced
2294:72ad4e766acf 2295:8aff3f3ce47f
     6   functions
     6   functions
     7 *)
     7 *)
     8 
     8 
     9 signature NOMINAL_DT_RAWFUNS =
     9 signature NOMINAL_DT_RAWFUNS =
    10 sig
    10 sig
       
    11   (* info of binding functions *)
       
    12   type bn_info = (term * int * (int * term option) list list) list
       
    13 
    11   (* binding modes and binding clauses *)
    14   (* binding modes and binding clauses *)
    12 
       
    13   datatype bmode = Lst | Res | Set
    15   datatype bmode = Lst | Res | Set
    14 
       
    15   datatype bclause = BC of bmode * (term option * int) list * int list
    16   datatype bclause = BC of bmode * (term option * int) list * int list
    16 
    17 
    17   val setify: Proof.context -> term -> term
    18   val setify: Proof.context -> term -> term
    18   val listify: Proof.context -> term -> term
    19   val listify: Proof.context -> term -> term
    19 
    20 
    20   val define_raw_fvs: 
    21   val define_raw_fvs: Datatype_Aux.descr -> (string * sort) list -> bn_info ->
    21      Datatype_Aux.descr ->
    22     bclause list list list -> Proof.context -> term list * term list * thm list * local_theory
    22      (string * sort) list ->
       
    23      term list ->
       
    24      (term * int * (int * term option) list list) list ->
       
    25      bclause list list list -> Proof.context -> term list * term list * thm list * local_theory
       
    26 end
    23 end
    27 
    24 
    28 
    25 
    29 structure Nominal_Dt_RawFuns: NOMINAL_DT_RAWFUNS =
    26 structure Nominal_Dt_RawFuns: NOMINAL_DT_RAWFUNS =
    30 struct
    27 struct
       
    28 
       
    29 type bn_info = (term * int * (int * term option) list list) list
    31 
    30 
    32 datatype bmode = Lst | Res | Set
    31 datatype bmode = Lst | Res | Set
    33 datatype bclause = BC of bmode * (term option * int) list * int list
    32 datatype bclause = BC of bmode * (term option * int) list * int list
    34 
    33 
    35 (* testing for concrete atom types *)
    34 (* testing for concrete atom types *)
    74   val map_ty = atom_ty --> ty --> @{typ "atom list"};
    73   val map_ty = atom_ty --> ty --> @{typ "atom list"};
    75 in
    74 in
    76   Const (@{const_name map}, map_ty) $ mk_atom_ty atom_ty t
    75   Const (@{const_name map}, map_ty) $ mk_atom_ty atom_ty t
    77 end
    76 end
    78 
    77 
    79 (* functions that coerces concrete atoms, sets and fsets into sets
    78 (* functions that coerces singletons, sets and fsets of concrete atoms
    80    of general atoms *)
    79    into sets of general atoms *)
    81 fun setify ctxt t =
    80 fun setify ctxt t =
    82 let
    81 let
    83   val ty = fastype_of t;
    82   val ty = fastype_of t;
    84 in
    83 in
    85   if is_atom ctxt ty
    84   if is_atom ctxt ty
    89   else if is_atom_fset ctxt ty
    88   else if is_atom_fset ctxt ty
    90     then mk_atom_fset t
    89     then mk_atom_fset t
    91   else raise TERM ("setify", [t])
    90   else raise TERM ("setify", [t])
    92 end
    91 end
    93 
    92 
    94 (* functions that coerces concrete atoms and lists into lists of 
    93 (* functions that coerces singletons and lists of concrete atoms
    95    general atoms  *)
    94    into lists of general atoms  *)
    96 fun listify ctxt t =
    95 fun listify ctxt t =
    97 let
    96 let
    98   val ty = fastype_of t;
    97   val ty = fastype_of t;
    99 in
    98 in
   100   if is_atom ctxt ty
    99   if is_atom ctxt ty
   109   if fastype_of t = @{typ "atom list"}
   108   if fastype_of t = @{typ "atom list"}
   110   then @{term "set::atom list => atom set"} $ t
   109   then @{term "set::atom list => atom set"} $ t
   111   else t
   110   else t
   112 
   111 
   113 
   112 
   114 (* functions that construct the equations for fv and fv_bn *)
   113 (** functions that construct the equations for fv and fv_bn **)
   115 
       
   116 fun mk_fv_body fv_map args i = 
       
   117 let
       
   118   val arg = nth args i
       
   119   val ty = fastype_of arg
       
   120 in
       
   121   case (AList.lookup (op=) fv_map ty) of
       
   122     NONE => mk_supp arg
       
   123   | SOME fv => fv $ arg
       
   124 end  
       
   125 
       
   126 fun mk_fv_binder lthy fv_bn_map args (bn_option, i) = 
       
   127 let
       
   128   val arg = nth args i
       
   129 in
       
   130   case bn_option of
       
   131     NONE => (setify lthy arg, @{term "{}::atom set"})
       
   132   | SOME bn => (to_set (bn $ arg), the (AList.lookup (op=) fv_bn_map bn) $ arg)
       
   133 end  
       
   134 
       
   135 fun mk_fv_bn_body fv_map fv_bn_map bn_args args i = 
       
   136 let
       
   137   val arg = nth args i
       
   138   val ty = fastype_of arg
       
   139 in
       
   140   case AList.lookup (op=) bn_args i of
       
   141     NONE => (case (AList.lookup (op=) fv_map ty) of
       
   142               NONE => mk_supp arg
       
   143             | SOME fv => fv $ arg)
       
   144   | SOME (NONE) => @{term "{}::atom set"}
       
   145   | SOME (SOME bn) => the (AList.lookup (op=) fv_bn_map bn) $ arg
       
   146 end  
       
   147 
   114 
   148 fun mk_fv_rhs lthy fv_map fv_bn_map args (BC (_, binders, bodies)) =
   115 fun mk_fv_rhs lthy fv_map fv_bn_map args (BC (_, binders, bodies)) =
   149 let
   116 let
       
   117   fun mk_fv_body fv_map args i = 
       
   118   let
       
   119     val arg = nth args i
       
   120     val ty = fastype_of arg
       
   121   in
       
   122     case AList.lookup (op=) fv_map ty of
       
   123       NONE => mk_supp arg
       
   124     | SOME fv => fv $ arg
       
   125   end  
       
   126 
       
   127   fun mk_fv_binder lthy fv_bn_map args (bn_option, i) = 
       
   128   let
       
   129     val arg = nth args i
       
   130   in
       
   131     case bn_option of
       
   132       NONE => (setify lthy arg, @{term "{}::atom set"})
       
   133     | SOME bn => (to_set (bn $ arg), the (AList.lookup (op=) fv_bn_map bn) $ arg)
       
   134   end  
       
   135 
   150   val t1 = map (mk_fv_body fv_map args) bodies
   136   val t1 = map (mk_fv_body fv_map args) bodies
   151   val (t2, t3) = split_list (map (mk_fv_binder lthy fv_bn_map args) binders)
   137   val (t2, t3) = split_list (map (mk_fv_binder lthy fv_bn_map args) binders)
   152 in 
   138 in 
   153   fold_union (mk_diff (fold_union t1, fold_union t2)::t3)
   139   fold_union (mk_diff (fold_union t1, fold_union t2)::t3)
   154 end
   140 end
   155 
   141 
   156 (* in case of fv_bn we have to treat the case special, where an
   142 (* in case of fv_bn we have to treat the case special, where an
   157    "empty" binding clause is given *)
   143    "empty" binding clause is given *)
   158 fun mk_fv_bn_rhs lthy fv_map fv_bn_map bn_args args bclause =
   144 fun mk_fv_bn_rhs lthy fv_map fv_bn_map bn_args args bclause =
       
   145 let
       
   146   fun mk_fv_bn_body fv_map fv_bn_map bn_args args i = 
       
   147   let
       
   148     val arg = nth args i
       
   149     val ty = fastype_of arg
       
   150   in
       
   151     case AList.lookup (op=) bn_args i of
       
   152       NONE => (case (AList.lookup (op=) fv_map ty) of
       
   153                  NONE => mk_supp arg
       
   154               | SOME fv => fv $ arg)
       
   155     | SOME (NONE) => @{term "{}::atom set"}
       
   156     | SOME (SOME bn) => the (AList.lookup (op=) fv_bn_map bn) $ arg
       
   157   end  
       
   158 in
   159   case bclause of
   159   case bclause of
   160     BC (_, [], bodies) => fold_union (map (mk_fv_bn_body fv_map fv_bn_map bn_args args) bodies)
   160     BC (_, [], bodies) => fold_union (map (mk_fv_bn_body fv_map fv_bn_map bn_args args) bodies)
   161   | _ => mk_fv_rhs lthy fv_map fv_bn_map args bclause
   161   | _ => mk_fv_rhs lthy fv_map fv_bn_map args bclause
   162 
   162 end
   163 
   163 
   164 fun mk_fv_eq lthy fv_map fv_bn_map (constr, ty, arg_tys) bclauses = 
   164 fun mk_fv_eq lthy fv_map fv_bn_map (constr, ty, arg_tys) bclauses = 
   165 let
   165 let
   166   val arg_names = Datatype_Prop.make_tnames arg_tys
   166   val arg_names = Datatype_Prop.make_tnames arg_tys
   167   val args = map Free (arg_names ~~ arg_tys)
   167   val args = map Free (arg_names ~~ arg_tys)
   191   val nth_bclausess = nth bclausesss bn_n
   191   val nth_bclausess = nth bclausesss bn_n
   192 in
   192 in
   193   map2 (mk_fv_bn_eq lthy bn_trm fv_map fv_bn_map) (bn_argss ~~ nth_constrs_info) nth_bclausess
   193   map2 (mk_fv_bn_eq lthy bn_trm fv_map fv_bn_map) (bn_argss ~~ nth_constrs_info) nth_bclausess
   194 end
   194 end
   195 
   195 
   196 fun define_raw_fvs dt_descr sorts bn_trms bn_funs2 bclausesss lthy =
   196 fun define_raw_fvs descr sorts bn_info bclausesss lthy =
   197 let
   197 let
   198   val fv_names = prefix_dt_names dt_descr sorts "fv_"
   198   val fv_names = prefix_dt_names descr sorts "fv_"
   199   val fv_arg_tys = map (fn (i, _) => nth_dtyp dt_descr sorts i) dt_descr;
   199   val fv_arg_tys = map (fn (i, _) => nth_dtyp descr sorts i) descr;
   200   val fv_tys = map (fn ty => ty --> @{typ "atom set"}) fv_arg_tys;
   200   val fv_tys = map (fn ty => ty --> @{typ "atom set"}) fv_arg_tys;
   201   val fv_frees = map Free (fv_names ~~ fv_tys);
   201   val fv_frees = map Free (fv_names ~~ fv_tys);
   202   val fv_map = fv_arg_tys ~~ fv_frees
   202   val fv_map = fv_arg_tys ~~ fv_frees
   203 
   203 
   204   val bn_tys2 = map (fn (_, i, _) => i) bn_funs2
   204   val (bns, bn_tys) = split_list (map (fn (bn, i, _) => (bn, i)) bn_info)
   205   val fv_bn_names2 = map (fn bn => "fv_" ^ (Long_Name.base_name (fst (dest_Const bn)))) bn_trms
   205   val bn_names = map (fn bn => Long_Name.base_name (fst (dest_Const bn))) bns
   206   val fv_bn_arg_tys2 = map (fn i => nth_dtyp dt_descr sorts i) bn_tys2
   206   val fv_bn_names = map (prefix "fv_") bn_names
   207   val fv_bn_tys2 = map (fn ty => ty --> @{typ "atom set"}) fv_bn_arg_tys2
   207   val fv_bn_arg_tys = map (fn i => nth_dtyp descr sorts i) bn_tys
   208   val fv_bn_frees2 = map Free (fv_bn_names2 ~~ fv_bn_tys2)
   208   val fv_bn_tys = map (fn ty => ty --> @{typ "atom set"}) fv_bn_arg_tys
   209   val fv_bn_map = bn_trms ~~ fv_bn_frees2
   209   val fv_bn_frees = map Free (fv_bn_names ~~ fv_bn_tys)
   210 
   210   val fv_bn_map = bns ~~ fv_bn_frees
   211   val constrs_info = all_dtyp_constrs_types dt_descr sorts
   211 
   212 
   212   val constrs_info = all_dtyp_constrs_types descr sorts
   213   val fv_eqs2 = map2 (map2 (mk_fv_eq lthy fv_map fv_bn_map)) constrs_info bclausesss 
   213 
   214   val fv_bn_eqs2 = map (mk_fv_bn_eqs lthy fv_map fv_bn_map constrs_info bclausesss) bn_funs2
   214   val fv_eqs = map2 (map2 (mk_fv_eq lthy fv_map fv_bn_map)) constrs_info bclausesss 
       
   215   val fv_bn_eqs = map (mk_fv_bn_eqs lthy fv_map fv_bn_map constrs_info bclausesss) bn_info
   215   
   216   
   216   val all_fv_names = map (fn s => (Binding.name s, NONE, NoSyn)) (fv_names @ fv_bn_names2)
   217   val all_fun_names = map (fn s => (Binding.name s, NONE, NoSyn)) (fv_names @ fv_bn_names)
   217   val all_fv_eqs = map (pair Attrib.empty_binding) (flat fv_eqs2 @ flat fv_bn_eqs2)
   218   val all_fun_eqs = map (pair Attrib.empty_binding) (flat fv_eqs @ flat fv_bn_eqs)
   218 
   219 
   219   fun pat_completeness_auto lthy =
   220   fun pat_completeness_auto lthy =
   220     Pat_Completeness.pat_completeness_tac lthy 1
   221     Pat_Completeness.pat_completeness_tac lthy 1
   221       THEN auto_tac (clasimpset_of lthy)
   222       THEN auto_tac (clasimpset_of lthy)
   222 
   223 
   223   fun prove_termination lthy =
   224   fun prove_termination lthy =
   224     Function.prove_termination NONE
   225     Function.prove_termination NONE
   225       (Lexicographic_Order.lexicographic_order_tac true lthy) lthy
   226       (Lexicographic_Order.lexicographic_order_tac true lthy) lthy
   226 
   227 
   227   val (_, lthy') = Function.add_function all_fv_names all_fv_eqs
   228   val (_, lthy') = Function.add_function all_fun_names all_fun_eqs
   228     Function_Common.default_config pat_completeness_auto lthy
   229     Function_Common.default_config pat_completeness_auto lthy
   229 
   230 
   230   val (info, lthy'') = prove_termination (Local_Theory.restore lthy')
   231   val (info, lthy'') = prove_termination (Local_Theory.restore lthy')
   231 
   232 
   232   val {fs, simps, ...} = info;
   233   val {fs, simps, ...} = info;