Nominal/Fv.thy
changeset 1670 ed89a26b7074
parent 1669 9911824a5396
child 1672 94b8b70f7bc0
equal deleted inserted replaced
1669:9911824a5396 1670:ed89a26b7074
   138 ML {*
   138 ML {*
   139 datatype alpha_type = AlphaGen | AlphaRes | AlphaLst;
   139 datatype alpha_type = AlphaGen | AlphaRes | AlphaLst;
   140 *}
   140 *}
   141 
   141 
   142 ML {*
   142 ML {*
       
   143 fun atyp_const AlphaGen = @{const_name alpha_gen}
       
   144   | atyp_const AlphaRes = @{const_name alpha_res}
       
   145   | atyp_const AlphaLst = @{const_name alpha_lst}
       
   146 *}
       
   147 
       
   148 (* TODO: make sure that parser checks that bindings are compatible *)
       
   149 ML {*
       
   150 fun alpha_const_for_binds [] = atyp_const AlphaGen
       
   151   | alpha_const_for_binds ((NONE, _, _, at) :: t) = atyp_const at
       
   152   | alpha_const_for_binds ((SOME (_, _), _, _, at) :: _) = atyp_const at
       
   153 *}
       
   154 
       
   155 ML {*
   143 fun is_atom thy typ =
   156 fun is_atom thy typ =
   144   Sign.of_sort thy (typ, @{sort at})
   157   Sign.of_sort thy (typ, @{sort at})
   145 
   158 
   146 fun is_atom_set thy (Type ("fun", [t, @{typ bool}])) = is_atom thy t
   159 fun is_atom_set thy (Type ("fun", [t, @{typ bool}])) = is_atom thy t
   147   | is_atom_set _ _ = false;
   160   | is_atom_set _ _ = false;
   165 ML {*
   178 ML {*
   166 fun gather_binds binds =
   179 fun gather_binds binds =
   167 let
   180 let
   168   fun gather_binds_cons binds =
   181   fun gather_binds_cons binds =
   169     let
   182     let
   170       val common = map (fn (f, bi, _) => (f, bi)) binds
   183       val common = map (fn (f, bi, _, aty) => (f, bi, aty)) binds
   171       val nodups = distinct (op =) common
   184       val nodups = distinct (op =) common
   172       fun find_bodys (sf, sbi) =
   185       fun find_bodys (sf, sbi, sty) =
   173         filter (fn (f, bi, _) => f = sf andalso bi = sbi) binds
   186         filter (fn (f, bi, _, aty) => f = sf andalso bi = sbi andalso aty = sty) binds
   174       val bodys = map ((map (fn (_, _, bo) => bo)) o find_bodys) nodups
   187       val bodys = map ((map (fn (_, _, bo, _) => bo)) o find_bodys) nodups
   175     in
   188     in
   176       nodups ~~ bodys
   189       nodups ~~ bodys
   177     end
   190     end
   178 in
   191 in
   179   map (map gather_binds_cons) binds
   192   map (map gather_binds_cons) binds
   180 end
   193 end
   181 *}
   194 *}
   182 
   195 
   183 ML {*
   196 ML {*
   184 fun un_gather_binds_cons binds =
   197 fun un_gather_binds_cons binds =
   185   flat (map (fn (((f, bi), bos), pi) => map (fn bo => ((f, bi, bo), pi)) bos) binds)
   198   flat (map (fn (((f, bi, aty), bos), pi) => map (fn bo => ((f, bi, bo, aty), pi)) bos) binds)
   186 *}
   199 *}
   187 
   200 
   188 ML {*
   201 ML {*
   189   open Datatype_Aux; (* typ_of_dtyp, DtRec, ... *);
   202   open Datatype_Aux; (* typ_of_dtyp, DtRec, ... *);
       
   203 *}
       
   204 ML {*
   190   (* TODO: It is the same as one in 'nominal_atoms' *)
   205   (* TODO: It is the same as one in 'nominal_atoms' *)
   191   fun mk_atom ty = Const (@{const_name atom}, ty --> @{typ atom});
   206   fun mk_atom ty = Const (@{const_name atom}, ty --> @{typ atom});
   192   val noatoms = @{term "{} :: atom set"};
   207   val noatoms = @{term "{} :: atom set"};
   193   fun mk_single_atom x = HOLogic.mk_set @{typ atom} [mk_atom (type_of x) $ x];
   208   fun mk_single_atom x = HOLogic.mk_set @{typ atom} [mk_atom (type_of x) $ x];
   194   fun mk_union sets =
   209   fun mk_union sets =
   261 ML {* fun add_perm (p1, p2) = Const(@{const_name plus}, @{typ "perm \<Rightarrow> perm \<Rightarrow> perm"}) $ p1 $ p2 *}
   276 ML {* fun add_perm (p1, p2) = Const(@{const_name plus}, @{typ "perm \<Rightarrow> perm \<Rightarrow> perm"}) $ p1 $ p2 *}
   262 
   277 
   263 ML {*
   278 ML {*
   264 fun non_rec_binds l =
   279 fun non_rec_binds l =
   265 let
   280 let
   266   fun is_non_rec (SOME (f, false), _, _) = SOME f
   281   fun is_non_rec (SOME (f, false), _, _, _) = SOME f
   267     | is_non_rec _ = NONE
   282     | is_non_rec _ = NONE
   268 in
   283 in
   269   distinct (op =) (map_filter is_non_rec (flat (flat l)))
   284   distinct (op =) (map_filter is_non_rec (flat (flat l)))
   270 end
   285 end
   271 *}
   286 *}
   309 in
   324 in
   310   ((bn, fvbn), eqs)
   325   ((bn, fvbn), eqs)
   311 end
   326 end
   312 *}
   327 *}
   313 
   328 
       
   329 ML {* print_depth 100 *}
   314 ML {*
   330 ML {*
   315 fun fv_bns thy dt_info fv_frees rel_bns =
   331 fun fv_bns thy dt_info fv_frees rel_bns =
   316 let
   332 let
   317   fun mk_fvbn_free (bn, ith, _) =
   333   fun mk_fvbn_free (bn, ith, _) =
   318     let
   334     let
   388 
   404 
   389 
   405 
   390 (* Checks that a list of bindings contains only compatible ones *)
   406 (* Checks that a list of bindings contains only compatible ones *)
   391 ML {*
   407 ML {*
   392 fun bns_same l =
   408 fun bns_same l =
   393   length (distinct (op =) (map (fn ((b, _, _), _) => b) l)) = 1
   409   length (distinct (op =) (map (fn ((b, _, _, atyp), _) => (b, atyp)) l)) = 1
   394 *}
   410 *}
   395 
   411 
   396 (* TODO: Notice datatypes without bindings and replace alpha with equality *)
   412 (* TODO: Notice datatypes without bindings and replace alpha with equality *)
   397 ML {*
   413 ML {*
   398 fun define_fv_alpha (dt_info : Datatype_Aux.info) bindsall bns lthy =
   414 fun define_fv_alpha (dt_info : Datatype_Aux.info) bindsall bns lthy =
   439       val args2 = map Free (names2 ~~ Ts);
   455       val args2 = map Free (names2 ~~ Ts);
   440       val c = Const (cname, Ts ---> (nth_dtyp ith_dtyp));
   456       val c = Const (cname, Ts ---> (nth_dtyp ith_dtyp));
   441       val fv_c = nth fv_frees ith_dtyp;
   457       val fv_c = nth fv_frees ith_dtyp;
   442       val alpha = nth alpha_frees ith_dtyp;
   458       val alpha = nth alpha_frees ith_dtyp;
   443       val arg_nos = 0 upto (length dts - 1)
   459       val arg_nos = 0 upto (length dts - 1)
   444       fun fv_bind args (NONE, i, _) =
   460       fun fv_bind args (NONE, i, _, _) =
   445             if is_rec_type (nth dts i) then (nth fv_frees (body_index (nth dts i))) $ (nth args i) else
   461             if is_rec_type (nth dts i) then (nth fv_frees (body_index (nth dts i))) $ (nth args i) else
   446             if ((is_atom thy) o fastype_of) (nth args i) then mk_single_atom (nth args i) else
   462             if ((is_atom thy) o fastype_of) (nth args i) then mk_single_atom (nth args i) else
   447             if ((is_atom_set thy) o fastype_of) (nth args i) then mk_atom_set (nth args i) else
   463             if ((is_atom_set thy) o fastype_of) (nth args i) then mk_atom_set (nth args i) else
   448             if ((is_atom_fset thy) o fastype_of) (nth args i) then mk_atom_fset (nth args i) else
   464             if ((is_atom_fset thy) o fastype_of) (nth args i) then mk_atom_fset (nth args i) else
   449             (* TODO we do not know what to do with non-atomizable things *)
   465             (* TODO we do not know what to do with non-atomizable things *)
   450             @{term "{} :: atom set"}
   466             @{term "{} :: atom set"}
   451         | fv_bind args (SOME (f, _), i, _) = f $ (nth args i);
   467         | fv_bind args (SOME (f, _), i, _, _) = f $ (nth args i);
   452       fun fv_binds args relevant = mk_union (map (fv_bind args) relevant)
   468       fun fv_binds args relevant = mk_union (map (fv_bind args) relevant)
   453       fun find_nonrec_binder j (SOME (f, false), i, _) = if i = j then SOME f else NONE
   469       fun find_nonrec_binder j (SOME (f, false), i, _, _) = if i = j then SOME f else NONE
   454         | find_nonrec_binder _ _ = NONE
   470         | find_nonrec_binder _ _ = NONE
   455       fun fv_arg ((dt, x), arg_no) =
   471       fun fv_arg ((dt, x), arg_no) =
   456         case get_first (find_nonrec_binder arg_no) bindcs of
   472         case get_first (find_nonrec_binder arg_no) bindcs of
   457           SOME f =>
   473           SOME f =>
   458             (case get_first (fn (x, y) => if x = f then SOME y else NONE) bn_fv_bns of
   474             (case get_first (fn (x, y) => if x = f then SOME y else NONE) bn_fv_bns of
   466                 if ((is_atom_set thy) o fastype_of) x then mk_atom_set x else
   482                 if ((is_atom_set thy) o fastype_of) x then mk_atom_set x else
   467                 if ((is_atom_fset thy) o fastype_of) x then mk_atom_fset x else
   483                 if ((is_atom_fset thy) o fastype_of) x then mk_atom_fset x else
   468                 (* TODO we do not know what to do with non-atomizable things *)
   484                 (* TODO we do not know what to do with non-atomizable things *)
   469                 @{term "{} :: atom set"};
   485                 @{term "{} :: atom set"};
   470               (* If i = j then we generate it only once *)
   486               (* If i = j then we generate it only once *)
   471               val relevant = filter (fn (_, i, j) => ((i = arg_no) orelse (j = arg_no))) bindcs;
   487               val relevant = filter (fn (_, i, j, _) => ((i = arg_no) orelse (j = arg_no))) bindcs;
   472               val sub = fv_binds args relevant
   488               val sub = fv_binds args relevant
   473             in
   489             in
   474               mk_diff arg sub
   490               mk_diff arg sub
   475             end;
   491             end;
   476       val fv_eq = HOLogic.mk_Trueprop (HOLogic.mk_eq
   492       val fv_eq = HOLogic.mk_Trueprop (HOLogic.mk_eq
   477         (fv_c $ list_comb (c, args), mk_union (map fv_arg  (dts ~~ args ~~ arg_nos))))
   493         (fv_c $ list_comb (c, args), mk_union (map fv_arg  (dts ~~ args ~~ arg_nos))))
   478       val alpha_rhs =
   494       val alpha_rhs =
   479         HOLogic.mk_Trueprop (alpha $ (list_comb (c, args)) $ (list_comb (c, args2)));
   495         HOLogic.mk_Trueprop (alpha $ (list_comb (c, args)) $ (list_comb (c, args2)));
   480       fun alpha_arg ((dt, arg_no), (arg, arg2)) =
   496       fun alpha_arg ((dt, arg_no), (arg, arg2)) =
   481         let
   497         let
   482           val rel_in_simp_binds = filter (fn ((NONE, i, _), _) => i = arg_no | _ => false) bind_pis;
   498           val rel_in_simp_binds = filter (fn ((NONE, i, _, _), _) => i = arg_no | _ => false) bind_pis;
   483           val rel_in_comp_binds = filter (fn ((SOME _, i, _), _) => i = arg_no | _ => false) bind_pis;
   499           val rel_in_comp_binds = filter (fn ((SOME _, i, _, _), _) => i = arg_no | _ => false) bind_pis;
   484           val rel_has_binds = filter (fn ((NONE, _, j), _) => j = arg_no
   500           val rel_has_binds = filter (fn ((NONE, _, j, _), _) => j = arg_no
   485                                        | ((SOME (_, false), _, j), _) => j = arg_no
   501                                        | ((SOME (_, false), _, j, _), _) => j = arg_no
   486                                        | _ => false) bind_pis;
   502                                        | _ => false) bind_pis;
   487           val rel_has_rec_binds = filter 
   503           val rel_has_rec_binds = filter
   488             (fn ((SOME (_, true), _, j), _) => j = arg_no | _ => false) bind_pis;
   504             (fn ((SOME (_, true), _, j, _), _) => j = arg_no | _ => false) bind_pis;
   489         in
   505         in
   490           case (rel_in_simp_binds, rel_in_comp_binds, rel_has_binds, rel_has_rec_binds) of
   506           case (rel_in_simp_binds, rel_in_comp_binds, rel_has_binds, rel_has_rec_binds) of
   491             ([], [], [], []) =>
   507             ([], [], [], []) =>
   492               if is_rec_type dt then (nth alpha_frees (body_index dt) $ arg $ arg2)
   508               if is_rec_type dt then (nth alpha_frees (body_index dt) $ arg $ arg2)
   493               else (HOLogic.mk_eq (arg, arg2))
   509               else (HOLogic.mk_eq (arg, arg2))
   494           | (_, [], [], []) => @{term True}
   510           | (_, [], [], []) => @{term True}
   495           | ([], [], [], _) => @{term True}
   511           | ([], [], [], _) => @{term True}
   496           | ([], ((((SOME (bn, is_rec)), _, _), _) :: _), [], []) =>
   512           | ([], ((((SOME (bn, is_rec)), _, _, atyp), _) :: _), [], []) =>
   497             if not (bns_same rel_in_comp_binds) then error "incompatible bindings for an argument" else
   513             if not (bns_same rel_in_comp_binds) then error "incompatible bindings for an argument" else
   498             if is_rec then
   514             if is_rec then
   499               let
   515               let
   500                 val (rbinds, rpis) = split_list rel_in_comp_binds
   516                 val (rbinds, rpis) = split_list rel_in_comp_binds
   501                 val bound_in_nos = map (fn (_, _, i) => i) rbinds
   517                 val bound_in_nos = map (fn (_, _, i, _) => i) rbinds
   502                 val bound_in_ty_nos = map (fn i => body_index (nth dts i)) bound_in_nos;
   518                 val bound_in_ty_nos = map (fn i => body_index (nth dts i)) bound_in_nos;
   503                 val bound_args = arg :: map (nth args) bound_in_nos;
   519                 val bound_args = arg :: map (nth args) bound_in_nos;
   504                 val bound_args2 = arg2 :: map (nth args2) bound_in_nos;
   520                 val bound_args2 = arg2 :: map (nth args2) bound_in_nos;
   505                 val lhs_binds = fv_binds args rbinds
   521                 val lhs_binds = fv_binds args rbinds
   506                 val lhs_arg = foldr1 HOLogic.mk_prod bound_args
   522                 val lhs_arg = foldr1 HOLogic.mk_prod bound_args
   511                 val fvs = map (nth fv_frees) ((body_index dt) :: bound_in_ty_nos);
   527                 val fvs = map (nth fv_frees) ((body_index dt) :: bound_in_ty_nos);
   512                 val fv = mk_compound_fv fvs;
   528                 val fv = mk_compound_fv fvs;
   513                 val alphas = map (nth alpha_frees) ((body_index dt) :: bound_in_ty_nos);
   529                 val alphas = map (nth alpha_frees) ((body_index dt) :: bound_in_ty_nos);
   514                 val alpha = mk_compound_alpha alphas;
   530                 val alpha = mk_compound_alpha alphas;
   515                 val pi = foldr1 add_perm (distinct (op =) rpis);
   531                 val pi = foldr1 add_perm (distinct (op =) rpis);
   516                 val alpha_gen_pre = Const (@{const_name alpha_gen}, dummyT) $ lhs $ alpha $ fv $ pi $ rhs;
   532                 val alpha_gen_pre = Const (atyp_const atyp, dummyT) $ lhs $ alpha $ fv $ pi $ rhs;
   517                 val alpha_gen = Syntax.check_term lthy alpha_gen_pre
   533                 val alpha_gen = Syntax.check_term lthy alpha_gen_pre
   518               in
   534               in
   519                 alpha_gen
   535                 alpha_gen
   520               end
   536               end
   521             else
   537             else
   533               val rhs_binds = fv_binds args2 rbinds;
   549               val rhs_binds = fv_binds args2 rbinds;
   534               val rhs = mk_pair (rhs_binds, arg2);
   550               val rhs = mk_pair (rhs_binds, arg2);
   535               val alpha = nth alpha_frees (body_index dt);
   551               val alpha = nth alpha_frees (body_index dt);
   536               val fv = nth fv_frees (body_index dt);
   552               val fv = nth fv_frees (body_index dt);
   537               val pi = foldr1 add_perm (distinct (op =) rpis);
   553               val pi = foldr1 add_perm (distinct (op =) rpis);
   538               val alpha_gen_pre = Const (@{const_name alpha_gen}, dummyT) $ lhs $ alpha $ fv $ pi $ rhs;
   554               val alpha_const = alpha_const_for_binds rbinds;
       
   555               val alpha_gen_pre = Const (alpha_const, dummyT) $ lhs $ alpha $ fv $ pi $ rhs;
   539               val alpha_gen = Syntax.check_term lthy alpha_gen_pre
   556               val alpha_gen = Syntax.check_term lthy alpha_gen_pre
   540             in
   557             in
   541               alpha_gen
   558               alpha_gen
   542             end
   559             end
   543           | _ => error "Fv.alpha: not supported binding structure"
   560           | _ => error "Fv.alpha: not supported binding structure"