154 (* S {(x, y). p x y} = {(x, y). P p x y} *) |
154 (* S {(x, y). p x y} = {(x, y). P p x y} *) |
155 (* *) |
155 (* *) |
156 (* where s and p are parameters *) |
156 (* where s and p are parameters *) |
157 (***********************************************************) |
157 (***********************************************************) |
158 |
158 |
159 structure PredSetConvData = Generic_Data |
159 structure Data = Generic_Data |
160 ( |
160 ( |
161 type T = |
161 type T = |
162 {(* rules for converting predicates to sets *) |
162 {(* rules for converting predicates to sets *) |
163 to_set_simps: thm list, |
163 to_set_simps: thm list, |
164 (* rules for converting sets to predicates *) |
164 (* rules for converting sets to predicates *) |
267 end; |
267 end; |
268 |
268 |
269 |
269 |
270 (**** declare rules for converting predicates to sets ****) |
270 (**** declare rules for converting predicates to sets ****) |
271 |
271 |
272 fun add ctxt thm (tab as {to_set_simps, to_pred_simps, set_arities, pred_arities}) = |
272 exception Malformed of string; |
273 case prop_of thm of |
273 |
|
274 fun add context thm (tab as {to_set_simps, to_pred_simps, set_arities, pred_arities}) = |
|
275 (case prop_of thm of |
274 Const (@{const_name Trueprop}, _) $ (Const (@{const_name HOL.eq}, Type (_, [T, _])) $ lhs $ rhs) => |
276 Const (@{const_name Trueprop}, _) $ (Const (@{const_name HOL.eq}, Type (_, [T, _])) $ lhs $ rhs) => |
275 (case body_type T of |
277 (case body_type T of |
276 @{typ bool} => |
278 @{typ bool} => |
277 let |
279 let |
278 val thy = Context.theory_of ctxt; |
280 val thy = Context.theory_of context; |
279 fun factors_of t fs = case strip_abs_body t of |
281 fun factors_of t fs = case strip_abs_body t of |
280 Const (@{const_name Set.member}, _) $ u $ S => |
282 Const (@{const_name Set.member}, _) $ u $ S => |
281 if is_Free S orelse is_Var S then |
283 if is_Free S orelse is_Var S then |
282 let val ps = HOLogic.flat_tuple_paths u |
284 let val ps = HOLogic.flat_tuple_paths u |
283 in (SOME ps, (S, ps) :: fs) end |
285 in (SOME ps, (S, ps) :: fs) end |
287 val (pfs, fs) = fold_map factors_of ts []; |
289 val (pfs, fs) = fold_map factors_of ts []; |
288 val ((h', ts'), fs') = (case rhs of |
290 val ((h', ts'), fs') = (case rhs of |
289 Abs _ => (case strip_abs_body rhs of |
291 Abs _ => (case strip_abs_body rhs of |
290 Const (@{const_name Set.member}, _) $ u $ S => |
292 Const (@{const_name Set.member}, _) $ u $ S => |
291 (strip_comb S, SOME (HOLogic.flat_tuple_paths u)) |
293 (strip_comb S, SOME (HOLogic.flat_tuple_paths u)) |
292 | _ => error "member symbol on right-hand side expected") |
294 | _ => raise Malformed "member symbol on right-hand side expected") |
293 | _ => (strip_comb rhs, NONE)) |
295 | _ => (strip_comb rhs, NONE)) |
294 in |
296 in |
295 case (name_type_of h, name_type_of h') of |
297 case (name_type_of h, name_type_of h') of |
296 (SOME (s, T), SOME (s', T')) => |
298 (SOME (s, T), SOME (s', T')) => |
297 if exists (fn (U, _) => |
299 if exists (fn (U, _) => |
306 mk_to_pred_eq h fs fs' T' thm :: to_pred_simps, |
308 mk_to_pred_eq h fs fs' T' thm :: to_pred_simps, |
307 set_arities = Symtab.insert_list op = (s', |
309 set_arities = Symtab.insert_list op = (s', |
308 (T', (map (AList.lookup op = fs) ts', fs'))) set_arities, |
310 (T', (map (AList.lookup op = fs) ts', fs'))) set_arities, |
309 pred_arities = Symtab.insert_list op = (s, |
311 pred_arities = Symtab.insert_list op = (s, |
310 (T, (pfs, fs'))) pred_arities} |
312 (T, (pfs, fs'))) pred_arities} |
311 | _ => error "set / predicate constant expected" |
313 | _ => raise Malformed "set / predicate constant expected" |
312 end |
314 end |
313 | _ => error "equation between predicates expected") |
315 | _ => raise Malformed "equation between predicates expected") |
314 | _ => error "equation expected"; |
316 | _ => raise Malformed "equation expected") |
|
317 handle Malformed msg => |
|
318 (warning ("Ignoring malformed set / predicate conversion rule: " ^ msg ^ |
|
319 "\n" ^ Display.string_of_thm (Context.proof_of context) thm); tab); |
315 |
320 |
316 val pred_set_conv_att = Thm.declaration_attribute |
321 val pred_set_conv_att = Thm.declaration_attribute |
317 (fn thm => fn ctxt => PredSetConvData.map (add ctxt thm) ctxt); |
322 (fn thm => fn ctxt => Data.map (add ctxt thm) ctxt); |
318 |
323 |
319 |
324 |
320 (**** convert theorem in set notation to predicate notation ****) |
325 (**** convert theorem in set notation to predicate notation ****) |
321 |
326 |
322 fun is_pred tab t = |
327 fun is_pred tab t = |
338 |
343 |
339 fun to_pred thms ctxt thm = |
344 fun to_pred thms ctxt thm = |
340 let |
345 let |
341 val thy = Context.theory_of ctxt; |
346 val thy = Context.theory_of ctxt; |
342 val {to_pred_simps, set_arities, pred_arities, ...} = |
347 val {to_pred_simps, set_arities, pred_arities, ...} = |
343 fold (add ctxt) thms (PredSetConvData.get ctxt); |
348 fold (add ctxt) thms (Data.get ctxt); |
344 val fs = filter (is_Var o fst) |
349 val fs = filter (is_Var o fst) |
345 (infer_arities thy set_arities (NONE, prop_of thm) []); |
350 (infer_arities thy set_arities (NONE, prop_of thm) []); |
346 (* instantiate each set parameter with {(x, y). p x y} *) |
351 (* instantiate each set parameter with {(x, y). p x y} *) |
347 val insts = mk_to_pred_inst thy fs |
352 val insts = mk_to_pred_inst thy fs |
348 in |
353 in |
361 |
366 |
362 fun to_set thms ctxt thm = |
367 fun to_set thms ctxt thm = |
363 let |
368 let |
364 val thy = Context.theory_of ctxt; |
369 val thy = Context.theory_of ctxt; |
365 val {to_set_simps, pred_arities, ...} = |
370 val {to_set_simps, pred_arities, ...} = |
366 fold (add ctxt) thms (PredSetConvData.get ctxt); |
371 fold (add ctxt) thms (Data.get ctxt); |
367 val fs = filter (is_Var o fst) |
372 val fs = filter (is_Var o fst) |
368 (infer_arities thy pred_arities (NONE, prop_of thm) []); |
373 (infer_arities thy pred_arities (NONE, prop_of thm) []); |
369 (* instantiate each predicate parameter with %x y. (x, y) : s *) |
374 (* instantiate each predicate parameter with %x y. (x, y) : s *) |
370 val insts = map (fn (x, ps) => |
375 val insts = map (fn (x, ps) => |
371 let |
376 let |
395 (**** preprocessor for code generator ****) |
400 (**** preprocessor for code generator ****) |
396 |
401 |
397 fun codegen_preproc thy = |
402 fun codegen_preproc thy = |
398 let |
403 let |
399 val {to_pred_simps, set_arities, pred_arities, ...} = |
404 val {to_pred_simps, set_arities, pred_arities, ...} = |
400 PredSetConvData.get (Context.Theory thy); |
405 Data.get (Context.Theory thy); |
401 fun preproc thm = |
406 fun preproc thm = |
402 if exists_Const (fn (s, _) => case Symtab.lookup set_arities s of |
407 if exists_Const (fn (s, _) => case Symtab.lookup set_arities s of |
403 NONE => false |
408 NONE => false |
404 | SOME arities => exists (fn (_, (xs, _)) => |
409 | SOME arities => exists (fn (_, (xs, _)) => |
405 forall is_none xs) arities) (prop_of thm) |
410 forall is_none xs) arities) (prop_of thm) |
420 {quiet_mode, verbose, alt_name, coind, no_elim, no_ind, skip_mono} |
425 {quiet_mode, verbose, alt_name, coind, no_elim, no_ind, skip_mono} |
421 cs intros monos params cnames_syn lthy = |
426 cs intros monos params cnames_syn lthy = |
422 let |
427 let |
423 val thy = Proof_Context.theory_of lthy; |
428 val thy = Proof_Context.theory_of lthy; |
424 val {set_arities, pred_arities, to_pred_simps, ...} = |
429 val {set_arities, pred_arities, to_pred_simps, ...} = |
425 PredSetConvData.get (Context.Proof lthy); |
430 Data.get (Context.Proof lthy); |
426 fun infer (Abs (_, _, t)) = infer t |
431 fun infer (Abs (_, _, t)) = infer t |
427 | infer (Const (@{const_name Set.member}, _) $ t $ u) = |
432 | infer (Const (@{const_name Set.member}, _) $ t $ u) = |
428 infer_arities thy set_arities (SOME (HOLogic.flat_tuple_paths t), u) |
433 infer_arities thy set_arities (SOME (HOLogic.flat_tuple_paths t), u) |
429 | infer (t $ u) = infer t #> infer u |
434 | infer (t $ u) = infer t #> infer u |
430 | infer _ = I; |
435 | infer _ = I; |