src/HOL/Tools/Nitpick/nitpick_nut.ML
changeset 35220 2bcdae5f4fdb
parent 35190 ce653cc27a94
child 35280 54ab4921f826
equal deleted inserted replaced
35219:15a5f213ef5b 35220:2bcdae5f4fdb
   465 (* typ * term -> (typ * term) list *)
   465 (* typ * term -> (typ * term) list *)
   466 fun factorize (z as (Type ("*", _), _)) = maps factorize [mk_fst z, mk_snd z]
   466 fun factorize (z as (Type ("*", _), _)) = maps factorize [mk_fst z, mk_snd z]
   467   | factorize z = [z]
   467   | factorize z = [z]
   468 
   468 
   469 (* hol_context -> op2 -> term -> nut *)
   469 (* hol_context -> op2 -> term -> nut *)
   470 fun nut_from_term (hol_ctxt as {thy, fast_descrs, special_funs, ...}) eq =
   470 fun nut_from_term (hol_ctxt as {thy, stds, fast_descrs, special_funs, ...}) eq =
   471   let
   471   let
   472     (* string list -> typ list -> term -> nut *)
   472     (* string list -> typ list -> term -> nut *)
   473     fun aux eq ss Ts t =
   473     fun aux eq ss Ts t =
   474       let
   474       let
   475         (* term -> nut *)
   475         (* term -> nut *)
   601              Cst (True, bool_T, Any)
   601              Cst (True, bool_T, Any)
   602            else case t1 of
   602            else case t1 of
   603              Const (@{const_name top}, _) => Cst (False, bool_T, Any)
   603              Const (@{const_name top}, _) => Cst (False, bool_T, Any)
   604            | _ => Op1 (Finite, bool_T, Any, sub t1))
   604            | _ => Op1 (Finite, bool_T, Any, sub t1))
   605         | (Const (@{const_name nat}, T), []) => Cst (IntToNat, T, Any)
   605         | (Const (@{const_name nat}, T), []) => Cst (IntToNat, T, Any)
   606         | (Const (@{const_name zero_nat_inst.zero_nat}, T), []) =>
   606         | (Const (x as (s as @{const_name zero_class.zero}, T)), []) =>
   607           Cst (Num 0, T, Any)
   607           if is_built_in_const thy stds false x then
   608         | (Const (@{const_name one_nat_inst.one_nat}, T), []) =>
   608             Cst (Num 0, T, Any)
   609           Cst (Num 1, T, Any)
   609           else if is_constr thy stds x then
   610         | (Const (@{const_name plus_nat_inst.plus_nat}, T), []) =>
   610             let val (s', T') = discr_for_constr x in
   611           Cst (Add, T, Any)
   611               Construct ([ConstName (s', T', Any)], T, Any, [])
   612         | (Const (@{const_name minus_nat_inst.minus_nat}, T), []) =>
   612             end
   613           Cst (Subtract, T, Any)
   613           else
   614         | (Const (@{const_name times_nat_inst.times_nat}, T), []) =>
   614             ConstName (s, T, Any)
   615           Cst (Multiply, T, Any)
   615         | (Const (x as (s as @{const_name one_class.one}, T)), []) =>
   616         | (Const (@{const_name div_nat_inst.div_nat}, T), []) =>
   616           if is_built_in_const thy stds false x then Cst (Num 1, T, Any)
   617           Cst (Divide, T, Any)
   617           else ConstName (s, T, Any)
   618         | (Const (@{const_name ord_nat_inst.less_nat}, T), [t1, t2]) =>
   618         | (Const (x as (s as @{const_name plus_class.plus}, T)), []) =>
   619           Op2 (Less, bool_T, Any, sub t1, sub t2)
   619           if is_built_in_const thy stds false x then Cst (Add, T, Any)
   620         | (Const (@{const_name ord_nat_inst.less_eq_nat}, T), [t1, t2]) =>
   620           else ConstName (s, T, Any)
   621           Op1 (Not, bool_T, Any, Op2 (Less, bool_T, Any, sub t2, sub t1))
   621         | (Const (@{const_name minus_class.minus},
       
   622                   Type ("fun", [T1 as Type ("fun", [_, @{typ bool}]), _])),
       
   623            [t1, t2]) =>
       
   624           Op2 (SetDifference, T1, Any, sub t1, sub t2)
       
   625         | (Const (x as (s as @{const_name minus_class.minus}, T)), []) =>
       
   626           if is_built_in_const thy stds false x then Cst (Subtract, T, Any)
       
   627           else ConstName (s, T, Any)
       
   628         | (Const (x as (s as @{const_name times_class.times}, T)), []) =>
       
   629           if is_built_in_const thy stds false x then Cst (Multiply, T, Any)
       
   630           else ConstName (s, T, Any)
       
   631         | (Const (x as (s as @{const_name div_class.div}, T)), []) =>
       
   632           if is_built_in_const thy stds false x then Cst (Divide, T, Any)
       
   633           else ConstName (s, T, Any)
       
   634         | (t0 as Const (x as (s as @{const_name ord_class.less}, T)),
       
   635            ts as [t1, t2]) =>
       
   636           if is_built_in_const thy stds false x then
       
   637             Op2 (Less, bool_T, Any, sub t1, sub t2)
       
   638           else
       
   639             do_apply t0 ts
       
   640         | (Const (@{const_name ord_class.less_eq},
       
   641                   Type ("fun", [Type ("fun", [_, @{typ bool}]), _])),
       
   642            [t1, t2]) =>
       
   643           Op2 (Subset, bool_T, Any, sub t1, sub t2)
       
   644         (* FIXME: find out if this case is necessary *)
       
   645         | (t0 as Const (x as (s as @{const_name ord_class.less_eq}, T)),
       
   646            ts as [t1, t2]) =>
       
   647           if is_built_in_const thy stds false x then
       
   648             Op1 (Not, bool_T, Any, Op2 (Less, bool_T, Any, sub t2, sub t1))
       
   649           else
       
   650             do_apply t0 ts
   622         | (Const (@{const_name nat_gcd}, T), []) => Cst (Gcd, T, Any)
   651         | (Const (@{const_name nat_gcd}, T), []) => Cst (Gcd, T, Any)
   623         | (Const (@{const_name nat_lcm}, T), []) => Cst (Lcm, T, Any)
   652         | (Const (@{const_name nat_lcm}, T), []) => Cst (Lcm, T, Any)
   624         | (Const (@{const_name zero_int_inst.zero_int}, T), []) =>
   653         | (Const (x as (s as @{const_name uminus_class.uminus}, T)), []) =>
   625           Cst (Num 0, T, Any)
   654           if is_built_in_const thy stds false x then
   626         | (Const (@{const_name one_int_inst.one_int}, T), []) =>
   655             let val num_T = domain_type T in
   627           Cst (Num 1, T, Any)
   656               Op2 (Apply, num_T --> num_T, Any,
   628         | (Const (@{const_name plus_int_inst.plus_int}, T), []) =>
   657                    Cst (Subtract, num_T --> num_T --> num_T, Any),
   629           Cst (Add, T, Any)
   658                    Cst (Num 0, num_T, Any))
   630         | (Const (@{const_name minus_int_inst.minus_int}, T), []) =>
   659             end
   631           Cst (Subtract, T, Any)
   660           else
   632         | (Const (@{const_name times_int_inst.times_int}, T), []) =>
   661             ConstName (s, T, Any)
   633           Cst (Multiply, T, Any)
       
   634         | (Const (@{const_name div_int_inst.div_int}, T), []) =>
       
   635           Cst (Divide, T, Any)
       
   636         | (Const (@{const_name uminus_int_inst.uminus_int}, T), []) =>
       
   637           let val num_T = domain_type T in
       
   638             Op2 (Apply, num_T --> num_T, Any,
       
   639                  Cst (Subtract, num_T --> num_T --> num_T, Any),
       
   640                  Cst (Num 0, num_T, Any))
       
   641           end
       
   642         | (Const (@{const_name ord_int_inst.less_int}, T), [t1, t2]) =>
       
   643           Op2 (Less, bool_T, Any, sub t1, sub t2)
       
   644         | (Const (@{const_name ord_int_inst.less_eq_int}, T), [t1, t2]) =>
       
   645           Op1 (Not, bool_T, Any, Op2 (Less, bool_T, Any, sub t2, sub t1))
       
   646         | (Const (@{const_name unknown}, T), []) => Cst (Unknown, T, Any)
   662         | (Const (@{const_name unknown}, T), []) => Cst (Unknown, T, Any)
   647         | (Const (@{const_name is_unknown}, T), [t1]) =>
   663         | (Const (@{const_name is_unknown}, T), [t1]) =>
   648           Op1 (IsUnknown, bool_T, Any, sub t1)
   664           Op1 (IsUnknown, bool_T, Any, sub t1)
   649         | (Const (@{const_name Tha}, Type ("fun", [_, T2])), [t1]) =>
   665         | (Const (@{const_name Tha}, Type ("fun", [_, T2])), [t1]) =>
   650           Op1 (Tha, T2, Any, sub t1)
   666           Op1 (Tha, T2, Any, sub t1)
   653         | (Const (@{const_name of_nat}, T as @{typ "nat => int"}), []) =>
   669         | (Const (@{const_name of_nat}, T as @{typ "nat => int"}), []) =>
   654           Cst (NatToInt, T, Any)
   670           Cst (NatToInt, T, Any)
   655         | (Const (@{const_name of_nat},
   671         | (Const (@{const_name of_nat},
   656                   T as @{typ "unsigned_bit word => signed_bit word"}), []) =>
   672                   T as @{typ "unsigned_bit word => signed_bit word"}), []) =>
   657           Cst (NatToInt, T, Any)
   673           Cst (NatToInt, T, Any)
   658         | (Const (@{const_name semilattice_inf_fun_inst.inf_fun}, T),
   674         | (Const (@{const_name semilattice_inf_class.inf},
   659                   [t1, t2]) =>
   675                   Type ("fun", [T1 as Type ("fun", [_, @{typ bool}]), _])),
   660           Op2 (Intersect, nth_range_type 2 T, Any, sub t1, sub t2)
   676            [t1, t2]) =>
   661         | (Const (@{const_name semilattice_sup_fun_inst.sup_fun}, T),
   677           Op2 (Intersect, T1, Any, sub t1, sub t2)
   662                   [t1, t2]) =>
   678         | (Const (@{const_name semilattice_sup_class.sup},
   663           Op2 (Union, nth_range_type 2 T, Any, sub t1, sub t2)
   679                   Type ("fun", [T1 as Type ("fun", [_, @{typ bool}]), _])),
   664         | (t0 as Const (@{const_name minus_fun_inst.minus_fun}, T), [t1, t2]) =>
   680            [t1, t2]) =>
   665           Op2 (SetDifference, nth_range_type 2 T, Any, sub t1, sub t2)
   681           Op2 (Union, T1, Any, sub t1, sub t2)
   666         | (t0 as Const (@{const_name ord_fun_inst.less_eq_fun}, T), [t1, t2]) =>
       
   667           Op2 (Subset, bool_T, Any, sub t1, sub t2)
       
   668         | (t0 as Const (x as (s, T)), ts) =>
   682         | (t0 as Const (x as (s, T)), ts) =>
   669           if is_constr thy x then
   683           if is_constr thy stds x then
   670             case num_binder_types T - length ts of
   684             case num_binder_types T - length ts of
   671               0 => Construct (map ((fn (s, T) => ConstName (s, T, Any))
   685               0 => Construct (map ((fn (s, T) => ConstName (s, T, Any))
   672                                     o nth_sel_for_constr x)
   686                                     o nth_sel_for_constr x)
   673                                   (~1 upto num_sels_for_constr_type T - 1),
   687                                   (~1 upto num_sels_for_constr_type T - 1),
   674                               body_type T, Any,
   688                               body_type T, Any,
   676                                  |> maps factorize |> map (sub o snd))
   690                                  |> maps factorize |> map (sub o snd))
   677             | k => sub (eta_expand Ts t k)
   691             | k => sub (eta_expand Ts t k)
   678           else if String.isPrefix numeral_prefix s then
   692           else if String.isPrefix numeral_prefix s then
   679             Cst (Num (the (Int.fromString (unprefix numeral_prefix s))), T, Any)
   693             Cst (Num (the (Int.fromString (unprefix numeral_prefix s))), T, Any)
   680           else
   694           else
   681             (case arity_of_built_in_const fast_descrs x of
   695             (case arity_of_built_in_const thy stds fast_descrs x of
   682                SOME n =>
   696                SOME n =>
   683                (case n - length ts of
   697                (case n - length ts of
   684                   0 => raise TERM ("Nitpick_Nut.nut_from_term.aux", [t])
   698                   0 => raise TERM ("Nitpick_Nut.nut_from_term.aux", [t])
   685                 | k => if k > 0 then sub (eta_expand Ts t k)
   699                 | k => if k > 0 then sub (eta_expand Ts t k)
   686                        else do_apply t0 ts)
   700                        else do_apply t0 ts)