429 "ALL n. nat (int n) = n" |
429 "ALL n. nat (int n) = n" |
430 "ALL i. i >= 0 --> int (nat i) = i" |
430 "ALL i. i >= 0 --> int (nat i) = i" |
431 "ALL i. i < 0 --> int (nat i) = 0" |
431 "ALL i. i < 0 --> int (nat i) = 0" |
432 by simp_all} |
432 by simp_all} |
433 |
433 |
434 val nat_ops = [ |
434 val simple_nat_ops = [ |
435 @{const less (nat)}, @{const less_eq (nat)}, |
435 @{const less (nat)}, @{const less_eq (nat)}, |
436 @{const Suc}, @{const plus (nat)}, @{const minus (nat)}, |
436 @{const Suc}, @{const plus (nat)}, @{const minus (nat)}] |
437 @{const times (nat)}, @{const div (nat)}, @{const mod (nat)}] |
437 |
|
438 val mult_nat_ops = |
|
439 [@{const times (nat)}, @{const div (nat)}, @{const mod (nat)}] |
|
440 |
|
441 val nat_ops = simple_nat_ops @ mult_nat_ops |
438 |
442 |
439 val nat_consts = nat_ops @ [@{const number_of (nat)}, |
443 val nat_consts = nat_ops @ [@{const number_of (nat)}, |
440 @{const zero_class.zero (nat)}, @{const one_class.one (nat)}] |
444 @{const zero_class.zero (nat)}, @{const one_class.one (nat)}] |
441 |
445 |
442 val nat_int_coercions = [@{const of_nat (int)}, @{const nat}] |
446 val nat_int_coercions = [@{const of_nat (int)}, @{const nat}] |
443 |
447 |
444 val nat_ops' = nat_int_coercions @ nat_ops |
448 val builtin_nat_ops = nat_int_coercions @ simple_nat_ops |
445 |
449 |
446 val is_nat_const = member (op aconv) nat_consts |
450 val is_nat_const = member (op aconv) nat_consts |
|
451 |
|
452 fun is_nat_const' @{const of_nat (int)} = true |
|
453 | is_nat_const' t = is_nat_const t |
447 |
454 |
448 val expands = map mk_meta_eq @{lemma |
455 val expands = map mk_meta_eq @{lemma |
449 "0 = nat 0" |
456 "0 = nat 0" |
450 "1 = nat 1" |
457 "1 = nat 1" |
451 "(number_of :: int => nat) = (%i. nat (number_of i))" |
458 "(number_of :: int => nat) = (%i. nat (number_of i))" |
492 (case Thm.term_of ct of |
499 (case Thm.term_of ct of |
493 @{const of_nat (int)} $ (n as (@{const number_of (nat)} $ _)) => |
500 @{const of_nat (int)} $ (n as (@{const number_of (nat)} $ _)) => |
494 Conv.rewr_conv (mk_number_eq ctxt (snd (HOLogic.dest_number n)) ct) |
501 Conv.rewr_conv (mk_number_eq ctxt (snd (HOLogic.dest_number n)) ct) |
495 | @{const of_nat (int)} $ _ => |
502 | @{const of_nat (int)} $ _ => |
496 (Conv.rewrs_conv ints then_conv Conv.sub_conv ints_conv ctxt) else_conv |
503 (Conv.rewrs_conv ints then_conv Conv.sub_conv ints_conv ctxt) else_conv |
497 Conv.top_sweep_conv nat_conv ctxt |
504 Conv.sub_conv (Conv.top_sweep_conv nat_conv) ctxt |
498 | _ => Conv.no_conv) ct |
505 | _ => Conv.no_conv) ct |
499 |
506 |
500 and ints_conv ctxt = Conv.top_sweep_conv int_conv ctxt |
507 and ints_conv ctxt = Conv.top_sweep_conv int_conv ctxt |
501 |
508 |
502 and expand_conv ctxt = |
509 and expand_conv ctxt = |
503 U.if_conv (not o is_nat_const o Term.head_of) Conv.no_conv |
510 U.if_conv (is_nat_const o Term.head_of) |
504 (expand_head_conv (Conv.rewrs_conv expands) then_conv ints_conv ctxt) |
511 (expand_head_conv (Conv.rewrs_conv expands) then_conv ints_conv ctxt) |
505 |
512 (int_conv ctxt) |
506 and nat_conv ctxt = U.if_exists_conv is_nat_const |
513 |
|
514 and nat_conv ctxt = U.if_exists_conv is_nat_const' |
507 (Conv.top_sweep_conv expand_conv ctxt) |
515 (Conv.top_sweep_conv expand_conv ctxt) |
508 |
516 |
509 val uses_nat_int = Term.exists_subterm (member (op aconv) nat_int_coercions) |
517 val uses_nat_int = Term.exists_subterm (member (op aconv) nat_int_coercions) |
510 in |
518 in |
511 |
519 |
515 if exists (uses_nat_int o Thm.prop_of) thms then (thms, nat_embedding) |
523 if exists (uses_nat_int o Thm.prop_of) thms then (thms, nat_embedding) |
516 else (thms, []) |
524 else (thms, []) |
517 |
525 |
518 val setup_nat_as_int = |
526 val setup_nat_as_int = |
519 B.add_builtin_typ_ext (@{typ nat}, K true) #> |
527 B.add_builtin_typ_ext (@{typ nat}, K true) #> |
520 fold (B.add_builtin_fun_ext' o Term.dest_Const) nat_ops' |
528 fold (B.add_builtin_fun_ext' o Term.dest_Const) builtin_nat_ops |
521 |
529 |
522 end |
530 end |
523 |
531 |
524 |
532 |
525 (** normalize numerals **) |
533 (** normalize numerals **) |