3 Preprocessing functions to predicates |
3 Preprocessing functions to predicates |
4 *) |
4 *) |
5 |
5 |
6 signature PREDICATE_COMPILE_FUN = |
6 signature PREDICATE_COMPILE_FUN = |
7 sig |
7 sig |
8 val define_predicates : (string * thm list) list -> theory -> theory |
8 val define_predicates : (string * thm list) list -> theory -> (string * thm list) list * theory |
9 val rewrite_intro : theory -> thm -> thm list |
9 val rewrite_intro : theory -> thm -> thm list |
10 val setup_oracle : theory -> theory |
10 val setup_oracle : theory -> theory |
11 val pred_of_function : theory -> string -> string option |
11 val pred_of_function : theory -> string -> string option |
12 end; |
12 end; |
13 |
13 |
102 (Free (Long_Name.base_name name ^ "P", pred_type T)) |
102 (Free (Long_Name.base_name name ^ "P", pred_type T)) |
103 end |
103 end |
104 |
104 |
105 fun mk_param lookup_pred (t as Free (v, _)) = lookup_pred t |
105 fun mk_param lookup_pred (t as Free (v, _)) = lookup_pred t |
106 | mk_param lookup_pred t = |
106 | mk_param lookup_pred t = |
107 let |
107 if Predicate_Compile_Aux.is_predT (fastype_of t) then |
108 val (vs, body) = strip_abs t |
108 t |
109 val names = Term.add_free_names body [] |
109 else |
110 val vs_names = Name.variant_list names (map fst vs) |
110 error "not implemented" |
111 val vs' = map2 (curry Free) vs_names (map snd vs) |
111 (* |
112 val body' = subst_bounds (rev vs', body) |
112 let |
113 val (f, args) = strip_comb body' |
113 val (vs, body) = strip_abs t |
114 val resname = Name.variant (vs_names @ names) "res" |
114 val names = Term.add_free_names body [] |
115 val resvar = Free (resname, body_type (fastype_of body')) |
115 val vs_names = Name.variant_list names (map fst vs) |
116 val P = lookup_pred f |
116 val vs' = map2 (curry Free) vs_names (map snd vs) |
117 val pred_body = list_comb (P, args @ [resvar]) |
117 val body' = subst_bounds (rev vs', body) |
118 val param = fold_rev lambda (vs' @ [resvar]) pred_body |
118 val (f, args) = strip_comb body' |
119 in param end; |
119 val resname = Name.variant (vs_names @ names) "res" |
120 |
120 val resvar = Free (resname, body_type (fastype_of body')) |
|
121 val P = lookup_pred f |
|
122 val pred_body = list_comb (P, args @ [resvar]) |
|
123 val param = fold_rev lambda (vs' @ [resvar]) pred_body |
|
124 in param end; |
|
125 *) |
121 |
126 |
122 (* creates the list of premises for every intro rule *) |
127 (* creates the list of premises for every intro rule *) |
123 (* theory -> term -> (string list, term list list) *) |
128 (* theory -> term -> (string list, term list list) *) |
124 |
129 |
125 fun dest_code_eqn eqn = let |
130 fun dest_code_eqn eqn = let |
215 if is_constr thy name orelse (is_none (try lookup_pred t)) then |
220 if is_constr thy name orelse (is_none (try lookup_pred t)) then |
216 [(t, (names, prems))] |
221 [(t, (names, prems))] |
217 else [(lookup_pred t, (names, prems))] |
222 else [(lookup_pred t, (names, prems))] |
218 | mk_prems' (t as Free (f, T)) (names, prems) = |
223 | mk_prems' (t as Free (f, T)) (names, prems) = |
219 [(lookup_pred t, (names, prems))] |
224 [(lookup_pred t, (names, prems))] |
|
225 | mk_prems' (t as Abs _) (names, prems) = |
|
226 if Predicate_Compile_Aux.is_predT (fastype_of t) then |
|
227 [(t, (names, prems))] else error "mk_prems': Abs " |
|
228 (* mk_param *) |
220 | mk_prems' t (names, prems) = |
229 | mk_prems' t (names, prems) = |
221 if Predicate_Compile_Aux.is_constrt thy t then |
230 if Predicate_Compile_Aux.is_constrt thy t then |
222 [(t, (names, prems))] |
231 [(t, (names, prems))] |
223 else |
232 else |
224 if has_split_rule_term' thy (fst (strip_comb t)) then |
233 if has_split_rule_term' thy (fst (strip_comb t)) then |
286 let |
295 let |
287 val prem = HOLogic.mk_Trueprop (list_comb (pred, argvs @ [resvar])) |
296 val prem = HOLogic.mk_Trueprop (list_comb (pred, argvs @ [resvar])) |
288 in (names', prem :: prems') end) |
297 in (names', prem :: prems') end) |
289 end |
298 end |
290 | mk_prems'' t = |
299 | mk_prems'' t = |
291 let |
300 error ("Invalid term: " ^ Syntax.string_of_term_global thy t) |
292 val _ = tracing ("must define new constant for " |
|
293 ^ (Syntax.string_of_term_global thy t)) |
|
294 in |
|
295 (*if is_predT (fastype_of t) then |
|
296 else*) |
|
297 error ("Invalid term: " ^ Syntax.string_of_term_global thy t) |
|
298 end |
|
299 in |
301 in |
300 map (pair resvar) (mk_prems'' f) |
302 map (pair resvar) (mk_prems'' f) |
301 end |
303 end |
302 in |
304 in |
303 mk_prems' t (names, prems) |
305 mk_prems' t (names, prems) |
304 end; |
306 end; |
305 |
307 |
306 (* assumption: mutual recursive predicates all have the same parameters. *) |
308 (* assumption: mutual recursive predicates all have the same parameters. *) |
307 fun define_predicates specs thy = |
309 fun define_predicates specs thy = |
308 if forall (fn (const, _) => member (op =) (Symtab.keys (Pred_Compile_Preproc.get thy)) const) specs then |
310 if forall (fn (const, _) => member (op =) (Symtab.keys (Pred_Compile_Preproc.get thy)) const) specs then |
309 thy |
311 ([], thy) |
310 else |
312 else |
311 let |
313 let |
312 val consts = map fst specs |
314 val consts = map fst specs |
313 val eqns = maps snd specs |
315 val eqns = maps snd specs |
314 (*val eqns = maps (Predicate_Compile_Preproc_Data.get_specification thy) consts*) |
316 (*val eqns = maps (Predicate_Compile_Preproc_Data.get_specification thy) consts*) |
361 Logic.list_implies (prems, HOLogic.mk_Trueprop (list_comb (pred, args @ [resultt])))) |
363 Logic.list_implies (prems, HOLogic.mk_Trueprop (list_comb (pred, args @ [resultt])))) |
362 end |
364 end |
363 fun mk_rewr_thm (func, pred) = @{thm refl} |
365 fun mk_rewr_thm (func, pred) = @{thm refl} |
364 in |
366 in |
365 case try (maps mk_intros) ((funs ~~ preds) ~~ (argss' ~~ rhss)) of |
367 case try (maps mk_intros) ((funs ~~ preds) ~~ (argss' ~~ rhss)) of |
366 NONE => thy |
368 NONE => ([], thy) |
367 | SOME intr_ts => let |
369 | SOME intr_ts => let |
368 val _ = map (tracing o (Syntax.string_of_term_global thy)) intr_ts |
370 val _ = map (tracing o (Syntax.string_of_term_global thy)) intr_ts |
|
371 val _ = map (cterm_of thy) intr_ts |
369 in |
372 in |
370 if is_some (try (map (cterm_of thy)) intr_ts) then |
373 if is_some (try (map (cterm_of thy)) intr_ts) then |
371 let |
374 let |
372 val (ind_result, thy') = |
375 val (ind_result, thy') = |
373 Inductive.add_inductive_global (serial_string ()) |
376 Inductive.add_inductive_global (serial_string ()) |
379 (map (fn x => (Attrib.empty_binding, x)) intr_ts) |
382 (map (fn x => (Attrib.empty_binding, x)) intr_ts) |
380 [] thy |
383 [] thy |
381 val prednames = map (fst o dest_Const) (#preds ind_result) |
384 val prednames = map (fst o dest_Const) (#preds ind_result) |
382 (* val rewr_thms = map mk_rewr_eq ((distinct (op =) funs) ~~ (#preds ind_result)) *) |
385 (* val rewr_thms = map mk_rewr_eq ((distinct (op =) funs) ~~ (#preds ind_result)) *) |
383 (* add constants to my table *) |
386 (* add constants to my table *) |
384 in Pred_Compile_Preproc.map (fold Symtab.update_new (consts ~~ prednames)) thy' end |
387 val specs = map (fn predname => (predname, filter (Predicate_Compile_Aux.is_intro predname) (#intrs ind_result))) prednames |
|
388 val thy'' = Pred_Compile_Preproc.map (fold Symtab.update_new (consts ~~ prednames)) thy' |
|
389 in |
|
390 (specs, thy'') |
|
391 end |
385 else |
392 else |
386 thy |
393 let |
|
394 val (p, _) = strip_comb (HOLogic.dest_Trueprop (hd (Logic.strip_imp_prems (hd intr_ts)))) |
|
395 val (_, T) = dest_Const p |
|
396 val _ = tracing (Syntax.string_of_typ_global thy T) |
|
397 val _ = tracing "Introduction rules of function_predicate are not welltyped" |
|
398 in ([], thy) end |
387 end |
399 end |
388 end |
400 end |
389 |
401 |
390 (* preprocessing intro rules - uses oracle *) |
402 (* preprocessing intro rules - uses oracle *) |
391 |
403 |