906 val (out_ts', in_ts') = List.partition (is_constrt thy) out_ts; |
906 val (out_ts', in_ts') = List.partition (is_constrt thy) out_ts; |
907 val vTs = maps term_vTs out_ts'; |
907 val vTs = maps term_vTs out_ts'; |
908 val dupTs = map snd (duplicates (op =) vTs) @ |
908 val dupTs = map snd (duplicates (op =) vTs) @ |
909 map_filter (AList.lookup (op =) vTs) vs; |
909 map_filter (AList.lookup (op =) vTs) vs; |
910 in |
910 in |
911 gen_subset (op =) (terms_vs (in_ts @ in_ts'), vs) andalso |
911 subset (op =) (terms_vs (in_ts @ in_ts'), vs) andalso |
912 forall (is_eqT o fastype_of) in_ts' andalso |
912 forall (is_eqT o fastype_of) in_ts' andalso |
913 gen_subset (op =) (term_vs t, vs) andalso |
913 subset (op =) (term_vs t, vs) andalso |
914 forall is_eqT dupTs |
914 forall is_eqT dupTs |
915 end) |
915 end) |
916 (modes_of_term modes t handle Option => |
916 (modes_of_term modes t handle Option => |
917 error ("Bad predicate: " ^ Syntax.string_of_term_global thy t)) |
917 error ("Bad predicate: " ^ Syntax.string_of_term_global thy t)) |
918 | Negprem (us, t) => find_first (fn Mode (_, is, _) => |
918 | Negprem (us, t) => find_first (fn Mode (_, is, _) => |
919 length us = length is andalso |
919 length us = length is andalso |
920 gen_subset (op =) (terms_vs us, vs) andalso |
920 subset (op =) (terms_vs us, vs) andalso |
921 gen_subset (op =) (term_vs t, vs) |
921 subset (op =) (term_vs t, vs) |
922 (modes_of_term modes t handle Option => |
922 (modes_of_term modes t handle Option => |
923 error ("Bad predicate: " ^ Syntax.string_of_term_global thy t)) |
923 error ("Bad predicate: " ^ Syntax.string_of_term_global thy t)) |
924 | Sidecond t => if gen_subset (op =) (term_vs t, vs) then SOME (Mode (([], []), [], [])) |
924 | Sidecond t => if subset (op =) (term_vs t, vs) then SOME (Mode (([], []), [], [])) |
925 else NONE |
925 else NONE |
926 ) ps); |
926 ) ps); |
927 |
927 |
928 fun fold_prem f (Prem (args, _)) = fold f args |
928 fun fold_prem f (Prem (args, _)) = fold f args |
929 | fold_prem f (Negprem (args, _)) = fold f args |
929 | fold_prem f (Negprem (args, _)) = fold f args |
962 | check_mode_prems acc_ps vs ps = (case select_mode_prem thy modes' vs ps of |
962 | check_mode_prems acc_ps vs ps = (case select_mode_prem thy modes' vs ps of |
963 NONE => |
963 NONE => |
964 (if with_generator then |
964 (if with_generator then |
965 (case select_mode_prem thy gen_modes' vs ps of |
965 (case select_mode_prem thy gen_modes' vs ps of |
966 SOME (p, SOME mode) => check_mode_prems ((gen_prem p, mode) :: acc_ps) |
966 SOME (p, SOME mode) => check_mode_prems ((gen_prem p, mode) :: acc_ps) |
967 (case p of Prem (us, _) => gen_union (op =) (vs, terms_vs us) | _ => vs) |
967 (case p of Prem (us, _) => union (op =) (vs, terms_vs us) | _ => vs) |
968 (filter_out (equal p) ps) |
968 (filter_out (equal p) ps) |
969 | NONE => |
969 | NONE => |
970 let |
970 let |
971 val all_generator_vs = all_subsets (prem_vs \\ vs) |> sort (int_ord o (pairself length)) |
971 val all_generator_vs = all_subsets (prem_vs \\ vs) |> sort (int_ord o (pairself length)) |
972 in |
972 in |
973 case (find_first (fn generator_vs => is_some |
973 case (find_first (fn generator_vs => is_some |
974 (select_mode_prem thy modes' (gen_union (op =) (vs, generator_vs)) ps)) all_generator_vs) of |
974 (select_mode_prem thy modes' (union (op =) (vs, generator_vs)) ps)) all_generator_vs) of |
975 SOME generator_vs => check_mode_prems ((map (generator vTs) generator_vs) @ acc_ps) |
975 SOME generator_vs => check_mode_prems ((map (generator vTs) generator_vs) @ acc_ps) |
976 (gen_union (op =) (vs, generator_vs)) ps |
976 (union (op =) (vs, generator_vs)) ps |
977 | NONE => NONE |
977 | NONE => NONE |
978 end) |
978 end) |
979 else |
979 else |
980 NONE) |
980 NONE) |
981 | SOME (p, SOME mode) => check_mode_prems ((if with_generator then param_gen_prem param_vs p else p, mode) :: acc_ps) |
981 | SOME (p, SOME mode) => check_mode_prems ((if with_generator then param_gen_prem param_vs p else p, mode) :: acc_ps) |
982 (case p of Prem (us, _) => gen_union (op =) (vs, terms_vs us) | _ => vs) |
982 (case p of Prem (us, _) => union (op =) (vs, terms_vs us) | _ => vs) |
983 (filter_out (equal p) ps)) |
983 (filter_out (equal p) ps)) |
984 val (in_ts, in_ts') = List.partition (is_constrt thy) (fst (split_smode is ts)); |
984 val (in_ts, in_ts') = List.partition (is_constrt thy) (fst (split_smode is ts)); |
985 val in_vs = terms_vs in_ts; |
985 val in_vs = terms_vs in_ts; |
986 val concl_vs = terms_vs ts |
986 val concl_vs = terms_vs ts |
987 in |
987 in |
988 if forall is_eqT (map snd (duplicates (op =) (maps term_vTs in_ts))) andalso |
988 if forall is_eqT (map snd (duplicates (op =) (maps term_vTs in_ts))) andalso |
989 forall (is_eqT o fastype_of) in_ts' then |
989 forall (is_eqT o fastype_of) in_ts' then |
990 case check_mode_prems [] (gen_union (op =) (param_vs, in_vs)) ps of |
990 case check_mode_prems [] (union (op =) (param_vs, in_vs)) ps of |
991 NONE => NONE |
991 NONE => NONE |
992 | SOME (acc_ps, vs) => |
992 | SOME (acc_ps, vs) => |
993 if with_generator then |
993 if with_generator then |
994 SOME (ts, (rev acc_ps) @ (map (generator vTs) (concl_vs \\ vs))) |
994 SOME (ts, (rev acc_ps) @ (map (generator vTs) (concl_vs \\ vs))) |
995 else |
995 else |
996 if gen_subset (op =) (concl_vs, vs) then SOME (ts, rev acc_ps) else NONE |
996 if subset (op =) (concl_vs, vs) then SOME (ts, rev acc_ps) else NONE |
997 else NONE |
997 else NONE |
998 end; |
998 end; |
999 |
999 |
1000 fun check_modes_pred with_generator thy param_vs preds modes gen_modes (p, ms) = |
1000 fun check_modes_pred with_generator thy param_vs preds modes gen_modes (p, ms) = |
1001 let val SOME rs = AList.lookup (op =) preds p |
1001 let val SOME rs = AList.lookup (op =) preds p |