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 *) |
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; |