src/HOL/Tools/SMT/smt_normalize.ML
changeset 41280 a7de9d36f4f2
parent 41224 8a104c2a186f
child 41300 528f5d00b542
equal deleted inserted replaced
41277:1369c27c6966 41280:a7de9d36f4f2
   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 **)