229 fun string_for_op1 Not = "Not" |
231 fun string_for_op1 Not = "Not" |
230 | string_for_op1 Finite = "Finite" |
232 | string_for_op1 Finite = "Finite" |
231 | string_for_op1 Converse = "Converse" |
233 | string_for_op1 Converse = "Converse" |
232 | string_for_op1 Closure = "Closure" |
234 | string_for_op1 Closure = "Closure" |
233 | string_for_op1 SingletonSet = "SingletonSet" |
235 | string_for_op1 SingletonSet = "SingletonSet" |
|
236 | string_for_op1 IsUnknown = "IsUnknown" |
234 | string_for_op1 Tha = "Tha" |
237 | string_for_op1 Tha = "Tha" |
235 | string_for_op1 First = "First" |
238 | string_for_op1 First = "First" |
236 | string_for_op1 Second = "Second" |
239 | string_for_op1 Second = "Second" |
237 | string_for_op1 Cast = "Cast" |
240 | string_for_op1 Cast = "Cast" |
238 |
241 |
565 | (Const (@{const_name Let}, T), [t1, Abs (s, T', t2)]) => |
568 | (Const (@{const_name Let}, T), [t1, Abs (s, T', t2)]) => |
566 Op3 (Let, nth_range_type 2 T, Any, BoundName (length Ts, T', Any, s), |
569 Op3 (Let, nth_range_type 2 T, Any, BoundName (length Ts, T', Any, s), |
567 sub t1, sub_abs s T' t2) |
570 sub t1, sub_abs s T' t2) |
568 | (t0 as Const (@{const_name Let}, T), [t1, t2]) => |
571 | (t0 as Const (@{const_name Let}, T), [t1, t2]) => |
569 sub (t0 $ t1 $ eta_expand Ts t2 1) |
572 sub (t0 $ t1 $ eta_expand Ts t2 1) |
570 | (Const (@{const_name unknown}, T), []) => Cst (Unknown, T, Any) |
|
571 | (@{const Unity}, []) => Cst (Unity, @{typ unit}, Any) |
573 | (@{const Unity}, []) => Cst (Unity, @{typ unit}, Any) |
572 | (Const (@{const_name Pair}, T), [t1, t2]) => |
574 | (Const (@{const_name Pair}, T), [t1, t2]) => |
573 Tuple (nth_range_type 2 T, Any, map sub [t1, t2]) |
575 Tuple (nth_range_type 2 T, Any, map sub [t1, t2]) |
574 | (Const (@{const_name fst}, T), [t1]) => |
576 | (Const (@{const_name fst}, T), [t1]) => |
575 Op1 (First, range_type T, Any, sub t1) |
577 Op1 (First, range_type T, Any, sub t1) |
639 end |
641 end |
640 | (Const (@{const_name ord_int_inst.less_int}, T), [t1, t2]) => |
642 | (Const (@{const_name ord_int_inst.less_int}, T), [t1, t2]) => |
641 Op2 (Less, bool_T, Any, sub t1, sub t2) |
643 Op2 (Less, bool_T, Any, sub t1, sub t2) |
642 | (Const (@{const_name ord_int_inst.less_eq_int}, T), [t1, t2]) => |
644 | (Const (@{const_name ord_int_inst.less_eq_int}, T), [t1, t2]) => |
643 Op1 (Not, bool_T, Any, Op2 (Less, bool_T, Any, sub t2, sub t1)) |
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) |
|
647 | (Const (@{const_name is_unknown}, T), [t1]) => |
|
648 Op1 (IsUnknown, bool_T, Any, sub t1) |
644 | (Const (@{const_name Tha}, Type ("fun", [_, T2])), [t1]) => |
649 | (Const (@{const_name Tha}, Type ("fun", [_, T2])), [t1]) => |
645 Op1 (Tha, T2, Any, sub t1) |
650 Op1 (Tha, T2, Any, sub t1) |
646 | (Const (@{const_name Frac}, T), []) => Cst (Fracs, T, Any) |
651 | (Const (@{const_name Frac}, T), []) => Cst (Fracs, T, Any) |
647 | (Const (@{const_name norm_frac}, T), []) => Cst (NormFrac, T, Any) |
652 | (Const (@{const_name norm_frac}, T), []) => Cst (NormFrac, T, Any) |
648 | (Const (@{const_name of_nat}, T as @{typ "nat => int"}), []) => |
653 | (Const (@{const_name of_nat}, T as @{typ "nat => int"}), []) => |
713 val x as (s, T) = (nickname_of v, type_of v) |
718 val x as (s, T) = (nickname_of v, type_of v) |
714 val R = (if is_abs_fun thy x then |
719 val R = (if is_abs_fun thy x then |
715 rep_for_abs_fun |
720 rep_for_abs_fun |
716 else if is_rep_fun thy x then |
721 else if is_rep_fun thy x then |
717 Func oo best_non_opt_symmetric_reps_for_fun_type |
722 Func oo best_non_opt_symmetric_reps_for_fun_type |
718 else if all_exact orelse is_skolem_name v |
723 else if all_exact orelse is_skolem_name v orelse |
719 orelse member (op =) [@{const_name undefined_fast_The}, |
724 member (op =) [@{const_name undefined_fast_The}, |
720 @{const_name undefined_fast_Eps}, |
725 @{const_name undefined_fast_Eps}, |
721 @{const_name bisim}, |
726 @{const_name bisim}, |
722 @{const_name bisim_iterator_max}] |
727 @{const_name bisim_iterator_max}] |
723 (original_name s) then |
728 (original_name s) then |
724 best_non_opt_set_rep_for_type |
729 best_non_opt_set_rep_for_type |
725 else if member (op =) [@{const_name set}, @{const_name distinct}, |
730 else if member (op =) [@{const_name set}, @{const_name distinct}, |
726 @{const_name ord_class.less}, |
731 @{const_name ord_class.less}, |
727 @{const_name ord_class.less_eq}] |
732 @{const_name ord_class.less_eq}] |
728 (original_name s) then |
733 (original_name s) then |
744 -> nut list * rep NameTable.table *) |
749 -> nut list * rep NameTable.table *) |
745 fun choose_rep_for_nth_sel_for_constr (scope as {ext_ctxt, ...}) (x as (_, T)) n |
750 fun choose_rep_for_nth_sel_for_constr (scope as {ext_ctxt, ...}) (x as (_, T)) n |
746 (vs, table) = |
751 (vs, table) = |
747 let |
752 let |
748 val (s', T') = boxed_nth_sel_for_constr ext_ctxt x n |
753 val (s', T') = boxed_nth_sel_for_constr ext_ctxt x n |
749 val R' = if n = ~1 orelse is_word_type (body_type T) |
754 val R' = if n = ~1 orelse is_word_type (body_type T) orelse |
750 orelse (is_fun_type (range_type T') |
755 (is_fun_type (range_type T') andalso |
751 andalso is_boolean_type (body_type T')) then |
756 is_boolean_type (body_type T')) then |
752 best_non_opt_set_rep_for_type scope T' |
757 best_non_opt_set_rep_for_type scope T' |
753 else |
758 else |
754 best_opt_set_rep_for_type scope T' |> unopt_rep |
759 best_opt_set_rep_for_type scope T' |> unopt_rep |
755 val v = ConstName (s', T', R') |
760 val v = ConstName (s', T', R') |
756 in (v :: vs, NameTable.update (v, R') table) end |
761 in (v :: vs, NameTable.update (v, R') table) end |
796 (* nut -> nut *) |
801 (* nut -> nut *) |
797 fun optimize_unit u = |
802 fun optimize_unit u = |
798 if rep_of u = Unit then Cst (Unity, type_of u, Unit) else u |
803 if rep_of u = Unit then Cst (Unity, type_of u, Unit) else u |
799 (* typ -> rep -> nut *) |
804 (* typ -> rep -> nut *) |
800 fun unknown_boolean T R = |
805 fun unknown_boolean T R = |
801 Cst (case R of |
806 Cst (case R of Formula Pos => False | Formula Neg => True | _ => Unknown, |
802 Formula Pos => False |
807 T, R) |
803 | Formula Neg => True |
|
804 | _ => Unknown, T, R) |
|
805 |
808 |
806 (* op1 -> typ -> rep -> nut -> nut *) |
809 (* op1 -> typ -> rep -> nut -> nut *) |
807 fun s_op1 oper T R u1 = |
810 fun s_op1 oper T R u1 = |
808 ((if oper = Not then |
811 ((if oper = Not then |
809 if is_Cst True u1 then Cst (False, T, R) |
812 if is_Cst True u1 then Cst (False, T, R) |
952 else if member (op =) [Add, Subtract, Multiply, Divide, Gcd, Lcm] |
955 else if member (op =) [Add, Subtract, Multiply, Divide, Gcd, Lcm] |
953 cst then |
956 cst then |
954 let |
957 let |
955 val T1 = domain_type T |
958 val T1 = domain_type T |
956 val R1 = Atom (spec_of_type scope T1) |
959 val R1 = Atom (spec_of_type scope T1) |
957 val total = T1 = nat_T |
960 val total = T1 = nat_T andalso |
958 andalso (cst = Subtract orelse cst = Divide |
961 (cst = Subtract orelse cst = Divide orelse cst = Gcd) |
959 orelse cst = Gcd) |
|
960 in Cst (cst, T, Func (R1, Func (R1, (not total ? Opt) R1))) end |
962 in Cst (cst, T, Func (R1, Func (R1, (not total ? Opt) R1))) end |
961 else if cst = NatToInt orelse cst = IntToNat then |
963 else if cst = NatToInt orelse cst = IntToNat then |
962 let |
964 let |
963 val (dom_card, dom_j0) = spec_of_type scope (domain_type T) |
965 val (dom_card, dom_j0) = spec_of_type scope (domain_type T) |
964 val (ran_card, ran_j0) = spec_of_type scope (range_type T) |
966 val (ran_card, ran_j0) = spec_of_type scope (range_type T) |
965 val total = not (is_word_type (domain_type T)) |
967 val total = not (is_word_type (domain_type T)) andalso |
966 andalso (if cst = NatToInt then |
968 (if cst = NatToInt then |
967 max_int_for_card ran_card >= dom_card + 1 |
969 max_int_for_card ran_card >= dom_card + 1 |
968 else |
970 else |
969 max_int_for_card dom_card < ran_card) |
971 max_int_for_card dom_card < ran_card) |
970 in |
972 in |
971 Cst (cst, T, Func (Atom (dom_card, dom_j0), |
973 Cst (cst, T, Func (Atom (dom_card, dom_j0), |
972 Atom (ran_card, ran_j0) |> not total ? Opt)) |
974 Atom (ran_card, ran_j0) |> not total ? Opt)) |
973 end |
975 end |
974 else |
976 else |
977 (case gsub def (flip_polarity polar) u1 of |
979 (case gsub def (flip_polarity polar) u1 of |
978 Op2 (Triad, T, R, u11, u12) => |
980 Op2 (Triad, T, R, u11, u12) => |
979 triad (s_op1 Not T (Formula Pos) u12) |
981 triad (s_op1 Not T (Formula Pos) u12) |
980 (s_op1 Not T (Formula Neg) u11) |
982 (s_op1 Not T (Formula Neg) u11) |
981 | u1' => s_op1 Not T (flip_rep_polarity (rep_of u1')) u1') |
983 | u1' => s_op1 Not T (flip_rep_polarity (rep_of u1')) u1') |
|
984 | Op1 (IsUnknown, T, _, u1) => |
|
985 let val u1 = sub u1 in |
|
986 if is_opt_rep (rep_of u1) then Op1 (IsUnknown, T, Formula Neut, u1) |
|
987 else Cst (False, T, Formula Neut) |
|
988 end |
982 | Op1 (oper, T, _, u1) => |
989 | Op1 (oper, T, _, u1) => |
983 let |
990 let |
984 val u1 = sub u1 |
991 val u1 = sub u1 |
985 val R1 = rep_of u1 |
992 val R1 = rep_of u1 |
986 val R = case oper of |
993 val R = case oper of |
1027 fun hybrid_case u = |
1034 fun hybrid_case u = |
1028 (* hackish optimization *) |
1035 (* hackish optimization *) |
1029 if is_constructive u then s_op2 Eq T (Formula Neut) u1' u2' |
1036 if is_constructive u then s_op2 Eq T (Formula Neut) u1' u2' |
1030 else opt_opt_case () |
1037 else opt_opt_case () |
1031 in |
1038 in |
1032 if liberal orelse polar = Neg |
1039 if liberal orelse polar = Neg orelse |
1033 orelse is_concrete_type datatypes (type_of u1) then |
1040 is_concrete_type datatypes (type_of u1) then |
1034 case (is_opt_rep (rep_of u1'), is_opt_rep (rep_of u2')) of |
1041 case (is_opt_rep (rep_of u1'), is_opt_rep (rep_of u2')) of |
1035 (true, true) => opt_opt_case () |
1042 (true, true) => opt_opt_case () |
1036 | (true, false) => hybrid_case u1' |
1043 | (true, false) => hybrid_case u1' |
1037 | (false, true) => hybrid_case u2' |
1044 | (false, true) => hybrid_case u2' |
1038 | (false, false) => non_opt_case () |
1045 | (false, false) => non_opt_case () |
1106 let |
1113 let |
1107 val table' = NameTable.update (u1, R1) table |
1114 val table' = NameTable.update (u1, R1) table |
1108 val u1' = aux table' false Neut u1 |
1115 val u1' = aux table' false Neut u1 |
1109 val u2' = aux table' false Neut u2 |
1116 val u2' = aux table' false Neut u2 |
1110 val R = |
1117 val R = |
1111 if is_opt_rep (rep_of u2') |
1118 if is_opt_rep (rep_of u2') orelse |
1112 orelse (range_type T = bool_T andalso |
1119 (range_type T = bool_T andalso |
1113 not (is_Cst False |
1120 not (is_Cst False (unrepify_nut_in_nut table false Neut |
1114 (unrepify_nut_in_nut table false Neut |
1121 u1 u2 |
1115 u1 u2 |
1122 |> optimize_nut))) then |
1116 |> optimize_nut))) then |
|
1117 opt_rep ofs T R |
1123 opt_rep ofs T R |
1118 else |
1124 else |
1119 unopt_rep R |
1125 unopt_rep R |
1120 in s_op2 Lambda T R u1' u2' end |
1126 in s_op2 Lambda T R u1' u2' end |
1121 | R => raise NUT ("Nitpick_Nut.aux.choose_reps_in_nut", [u])) |
1127 | R => raise NUT ("Nitpick_Nut.aux.choose_reps_in_nut", [u])) |
1129 in |
1135 in |
1130 if polar = Neut andalso is_opt_rep (rep_of u2') then |
1136 if polar = Neut andalso is_opt_rep (rep_of u2') then |
1131 triad_fn (fn polar => gsub def polar u) |
1137 triad_fn (fn polar => gsub def polar u) |
1132 else |
1138 else |
1133 let val quant_u = s_op2 oper T (Formula polar) u1' u2' in |
1139 let val quant_u = s_op2 oper T (Formula polar) u1' u2' in |
1134 if def |
1140 if def orelse |
1135 orelse (liberal andalso (polar = Pos) = (oper = All)) |
1141 (liberal andalso (polar = Pos) = (oper = All)) orelse |
1136 orelse is_complete_type datatypes (type_of u1) then |
1142 is_complete_type datatypes (type_of u1) then |
1137 quant_u |
1143 quant_u |
1138 else |
1144 else |
1139 let |
1145 let |
1140 val connective = if oper = All then And else Or |
1146 val connective = if oper = All then And else Or |
1141 val unrepified_u = unrepify_nut_in_nut table def polar |
1147 val unrepified_u = unrepify_nut_in_nut table def polar |
1229 constr_spec datatypes (original_name (nickname_of (hd us')), T) |
1235 constr_spec datatypes (original_name (nickname_of (hd us')), T) |
1230 val opt = exists is_opt_rep Rs orelse not total |
1236 val opt = exists is_opt_rep Rs orelse not total |
1231 in Construct (map sub us', T, R |> opt ? Opt, us) end |
1237 in Construct (map sub us', T, R |> opt ? Opt, us) end |
1232 | _ => |
1238 | _ => |
1233 let val u = modify_name_rep u (the_name table u) in |
1239 let val u = modify_name_rep u (the_name table u) in |
1234 if polar = Neut orelse not (is_boolean_type (type_of u)) |
1240 if polar = Neut orelse not (is_boolean_type (type_of u)) orelse |
1235 orelse not (is_opt_rep (rep_of u)) then |
1241 not (is_opt_rep (rep_of u)) then |
1236 u |
1242 u |
1237 else |
1243 else |
1238 s_op1 Cast (type_of u) (Formula polar) u |
1244 s_op1 Cast (type_of u) (Formula polar) u |
1239 end |
1245 end |
1240 end |
1246 end |