Nominal/Fv.thy
changeset 1364 226693549aa0
parent 1362 e72d9d9eada3
child 1366 2bf82fa871e7
equal deleted inserted replaced
1363:f00761b5957e 1364:226693549aa0
     1 theory Fv
     1 theory Fv
     2 imports "Nominal2_Atoms" "Abs" "Perm" "Rsp"
     2 imports "Nominal2_Atoms" "Abs" "Perm" "Rsp"
     3 begin
     3 begin
     4 
     4 
     5 (* Bindings are given as a list which has a length being equal
     5 (* Bindings are a list of lists of lists of triples.
     6    to the length of the number of constructors.
     6 
     7 
     7    The first list represents the datatypes defined.
     8    Each element is a list whose length is equal to the number
     8    The second list represents the constructors.
     9    of arguents.
     9    The internal list is a list of all the bndings that
    10 
    10    concern the constructor.
    11    Every element specifies bindings of this argument given as
    11 
    12    a tuple: function, bound argument.
    12    Every triple consists of a function, the binding and
       
    13    the body.
    13 
    14 
    14   Eg:
    15   Eg:
    15 nominal_datatype
    16 nominal_datatype
    16 
    17 
    17    C1
    18    C1
    19  | C3 x y z bind f x in z bind g y in z
    20  | C3 x y z bind f x in z bind g y in z
    20 
    21 
    21 yields:
    22 yields:
    22 [
    23 [
    23  [],
    24  [],
    24  [[], [], [(NONE, 0)]],
    25  [(NONE, 0, 2)],
    25  [[], [], [(SOME (Const f), 0), (Some (Const g), 1)]]]
    26  [(SOME (Const f), 0, 2), (Some (Const g), 1, 2)]]
    26 
    27 
    27 A SOME binding has to have a function returning an atom set,
    28 A SOME binding has to have a function which takes an appropriate
    28 and a NONE binding has to be on an argument that is an atom
    29 argument and returns an atom set. A NONE binding has to be on an
    29 or an atom set.
    30 argument that is an atom or an atom set.
    30 
    31 
    31 How the procedure works:
    32 How the procedure works:
    32   For each of the defined datatypes,
    33   For each of the defined datatypes,
    33   For each of the constructors,
    34   For each of the constructors,
    34   It creates a union of free variables for each argument.
    35   It creates a union of free variables for each argument.
    50     For an atom set, the atom set itself.
    51     For an atom set, the atom set itself.
    51     For a recursive argument, the appropriate fv function applied to it.
    52     For a recursive argument, the appropriate fv function applied to it.
    52     (* TODO: This one is not implemented *)
    53     (* TODO: This one is not implemented *)
    53     For other arguments it should be an appropriate fv function stored
    54     For other arguments it should be an appropriate fv function stored
    54       in the database.
    55       in the database.
       
    56 
       
    57   For every argument that is a binding, we add a the same binding in its
       
    58   body.
    55 *)
    59 *)
    56 
    60 
       
    61 ML {*
       
    62 fun is_atom thy typ =
       
    63   Sign.of_sort thy (typ, @{sort at})
       
    64 *}
       
    65 
       
    66 
       
    67 (* Like map2, only if the second list is empty passes empty lists insted of error *)
    57 ML {*
    68 ML {*
    58 fun map2i _ [] [] = []
    69 fun map2i _ [] [] = []
    59   | map2i f (x :: xs) (y :: ys) = f x y :: map2i f xs ys
    70   | map2i f (x :: xs) (y :: ys) = f x y :: map2i f xs ys
    60   | map2i f (x :: xs) [] = f x [] :: map2i f xs []
    71   | map2i f (x :: xs) [] = f x [] :: map2i f xs []
    61   | map2i _ _ _ = raise UnequalLengths;
    72   | map2i _ _ _ = raise UnequalLengths;
       
    73 *}
       
    74 
       
    75 (* Finds bindings with the same function and binding, and gathers all
       
    76    bodys for such pairs *)
       
    77 ML {*
       
    78 fun gather_binds binds =
       
    79 let
       
    80   fun gather_binds_cons binds =
       
    81     let
       
    82       val common = map (fn (f, bi, _) => (f, bi)) binds
       
    83       val nodups = distinct (op =) common
       
    84       fun find_bodys (sf, sbi) =
       
    85         filter (fn (f, bi, _) => f = sf andalso bi = sbi) binds
       
    86       val bodys = map ((map (fn (_, _, bo) => bo)) o find_bodys) nodups
       
    87     in
       
    88       nodups ~~ bodys
       
    89     end
       
    90 in
       
    91   map (map gather_binds_cons) binds
       
    92 end
       
    93 *}
       
    94 
       
    95 ML {*
       
    96 fun un_gather_binds_cons binds =
       
    97   flat (map (fn (((f, bi), bos), pi) => map (fn bo => ((f, bi, bo), pi)) bos) binds)
    62 *}
    98 *}
    63 
    99 
    64 ML {*
   100 ML {*
    65   open Datatype_Aux; (* typ_of_dtyp, DtRec, ... *);
   101   open Datatype_Aux; (* typ_of_dtyp, DtRec, ... *);
    66   (* TODO: It is the same as one in 'nominal_atoms' *)
   102   (* TODO: It is the same as one in 'nominal_atoms' *)
   108 
   144 
   109 (* TODO: Notice datatypes without bindings and replace alpha with equality *)
   145 (* TODO: Notice datatypes without bindings and replace alpha with equality *)
   110 ML {*
   146 ML {*
   111 fun define_fv_alpha (dt_info : Datatype_Aux.info) bindsall lthy =
   147 fun define_fv_alpha (dt_info : Datatype_Aux.info) bindsall lthy =
   112 let
   148 let
   113   val thy = ProofContext.theory_of lthy;
       
   114   val {descr, sorts, ...} = dt_info;
   149   val {descr, sorts, ...} = dt_info;
   115   fun nth_dtyp i = typ_of_dtyp descr sorts (DtRec i);
   150   fun nth_dtyp i = typ_of_dtyp descr sorts (DtRec i);
   116   val fv_names = Datatype_Prop.indexify_names (map (fn (i, _) =>
   151   val fv_names = Datatype_Prop.indexify_names (map (fn (i, _) =>
   117     "fv_" ^ name_of_typ (nth_dtyp i)) descr);
   152     "fv_" ^ name_of_typ (nth_dtyp i)) descr);
   118   val fv_types = map (fn (i, _) => nth_dtyp i --> @{typ "atom set"}) descr;
   153   val fv_types = map (fn (i, _) => nth_dtyp i --> @{typ "atom set"}) descr;
   126       val Ts = map (typ_of_dtyp descr sorts) dts;
   161       val Ts = map (typ_of_dtyp descr sorts) dts;
   127       val bindslen = length bindcs
   162       val bindslen = length bindcs
   128       val pi_strs_same = replicate bindslen "pi"
   163       val pi_strs_same = replicate bindslen "pi"
   129       val pi_strs = Name.variant_list [] pi_strs_same;
   164       val pi_strs = Name.variant_list [] pi_strs_same;
   130       val pis = map (fn ps => Free (ps, @{typ perm})) pi_strs;
   165       val pis = map (fn ps => Free (ps, @{typ perm})) pi_strs;
   131       val bind_pis = bindcs ~~ pis;
   166       val bind_pis_gath = bindcs ~~ pis;
       
   167       val bind_pis = un_gather_binds_cons bind_pis_gath;
       
   168       val bindcs = map fst bind_pis;
   132       val names = Name.variant_list pi_strs (Datatype_Prop.make_tnames Ts);
   169       val names = Name.variant_list pi_strs (Datatype_Prop.make_tnames Ts);
   133       val args = map Free (names ~~ Ts);
   170       val args = map Free (names ~~ Ts);
   134       val names2 = Name.variant_list (pi_strs @ names) (Datatype_Prop.make_tnames Ts);
   171       val names2 = Name.variant_list (pi_strs @ names) (Datatype_Prop.make_tnames Ts);
   135       val args2 = map Free (names2 ~~ Ts);
   172       val args2 = map Free (names2 ~~ Ts);
   136       val c = Const (cname, Ts ---> (nth_dtyp ith_dtyp));
   173       val c = Const (cname, Ts ---> (nth_dtyp ith_dtyp));
   176               val lhs = mk_pair (lhs_binds, arg);
   213               val lhs = mk_pair (lhs_binds, arg);
   177               val rhs_binds = fv_binds args2 rbinds;
   214               val rhs_binds = fv_binds args2 rbinds;
   178               val rhs = mk_pair (rhs_binds, arg2);
   215               val rhs = mk_pair (rhs_binds, arg2);
   179               val alpha = nth alpha_frees (body_index dt);
   216               val alpha = nth alpha_frees (body_index dt);
   180               val fv = nth fv_frees (body_index dt);
   217               val fv = nth fv_frees (body_index dt);
   181               val pi = foldr1 add_perm rpis;
   218               val pi = foldr1 add_perm (distinct (op =) rpis);
   182               val alpha_gen_pre = Const (@{const_name alpha_gen}, dummyT) $ lhs $ alpha $ fv $ pi $ rhs;
   219               val alpha_gen_pre = Const (@{const_name alpha_gen}, dummyT) $ lhs $ alpha $ fv $ pi $ rhs;
   183               val alpha_gen = Syntax.check_term lthy alpha_gen_pre
   220               val alpha_gen = Syntax.check_term lthy alpha_gen_pre
   184               val pi_supps = map ((curry op $) @{term "supp :: perm \<Rightarrow> atom set"}) rpis;
   221 (*              val pi_supps = map ((curry op $) @{term "supp :: perm \<Rightarrow> atom set"}) rpis;
   185               val pi_supps_eq = HOLogic.mk_eq (mk_inter pi_supps, @{term "{} :: atom set"})
   222               val pi_supps_eq = HOLogic.mk_eq (mk_inter pi_supps, @{term "{} :: atom set"}) *)
   186             in
   223             in
   187               (*if length pi_supps > 1 then
   224               (*if length pi_supps > 1 then HOLogic.mk_conj (alpha_gen, pi_supps_eq) else*)
   188                 HOLogic.mk_conj (alpha_gen, pi_supps_eq) else*) alpha_gen
   225               alpha_gen
   189             (* TODO Add some test that is makes sense *)
   226             (* TODO Add some test that is makes sense *)
   190             end else @{term "True"}
   227             end else @{term "True"}
   191         end
   228         end
   192       val alphas = map alpha_arg (dts ~~ arg_nos ~~ (args ~~ args2))
   229       val alphas = map alpha_arg (dts ~~ arg_nos ~~ (args ~~ args2))
   193       val alpha_lhss = mk_conjl alphas
   230       val alpha_lhss = mk_conjl alphas
   196       val alpha_eq = Logic.mk_implies (HOLogic.mk_Trueprop alpha_lhss_ex, alpha_rhs)
   233       val alpha_eq = Logic.mk_implies (HOLogic.mk_Trueprop alpha_lhss_ex, alpha_rhs)
   197     in
   234     in
   198       (fv_eq, alpha_eq)
   235       (fv_eq, alpha_eq)
   199     end;
   236     end;
   200   fun fv_alpha_eq (i, (_, _, constrs)) binds = map2i (fv_alpha_constr i) constrs binds;
   237   fun fv_alpha_eq (i, (_, _, constrs)) binds = map2i (fv_alpha_constr i) constrs binds;
   201   val (fv_eqs, alpha_eqs) = split_list (flat (map2i fv_alpha_eq descr bindsall))
   238   val (fv_eqs, alpha_eqs) = split_list (flat (map2i fv_alpha_eq descr (gather_binds bindsall)))
   202   val add_binds = map (fn x => (Attrib.empty_binding, x))
   239   val add_binds = map (fn x => (Attrib.empty_binding, x))
   203   val (fvs, lthy') = (Primrec.add_primrec
   240   val (fvs, lthy') = (Primrec.add_primrec
   204     (map (fn s => (Binding.name s, NONE, NoSyn)) fv_names) (add_binds fv_eqs) lthy)
   241     (map (fn s => (Binding.name s, NONE, NoSyn)) fv_names) (add_binds fv_eqs) lthy)
   205   val (alphas, lthy'') = (Inductive.add_inductive_i
   242   val (alphas, lthy'') = (Inductive.add_inductive_i
   206      {quiet_mode = true, verbose = false, alt_name = Binding.empty,
   243      {quiet_mode = true, verbose = false, alt_name = Binding.empty,
   234 | BVr "name"
   271 | BVr "name"
   235 | BPr "bp" "bp"
   272 | BPr "bp" "bp"
   236 
   273 
   237 (* to be given by the user *)
   274 (* to be given by the user *)
   238 
   275 
   239 primrec 
   276 primrec
   240   bv1
   277   bv1
   241 where
   278 where
   242   "bv1 (BUnit) = {}"
   279   "bv1 (BUnit) = {}"
   243 | "bv1 (BVr x) = {atom x}"
   280 | "bv1 (BVr x) = {atom x}"
   244 | "bv1 (BPr bp1 bp2) = (bv1 bp1) \<union> (bv1 bp1)"
   281 | "bv1 (BPr bp1 bp2) = (bv1 bp1) \<union> (bv1 bp1)"