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, |