402 | (V _, V _) => SOME (insert (op =) (aa1, aa2, cmp, []) comps, clauses)) |
404 | (V _, V _) => SOME (insert (op =) (aa1, aa2, cmp, []) comps, clauses)) |
403 | do_annotation_atom_comp cmp xs aa1 aa2 (comps, clauses) = |
405 | do_annotation_atom_comp cmp xs aa1 aa2 (comps, clauses) = |
404 SOME (insert (op =) (aa1, aa2, cmp, xs) comps, clauses) |
406 SOME (insert (op =) (aa1, aa2, cmp, xs) comps, clauses) |
405 |
407 |
406 fun add_annotation_atom_comp cmp xs aa1 aa2 (comps, clauses) = |
408 fun add_annotation_atom_comp cmp xs aa1 aa2 (comps, clauses) = |
407 (trace_msg (fn () => "*** Add " ^ string_for_annotation_atom aa1 ^ " " ^ |
409 (trace_msg (fn () => "*** Add " ^ string_for_comp (aa1, aa2, cmp, xs)); |
408 string_for_comp_op cmp ^ " " ^ |
|
409 string_for_annotation_atom aa2); |
|
410 case do_annotation_atom_comp cmp xs aa1 aa2 (comps, clauses) of |
410 case do_annotation_atom_comp cmp xs aa1 aa2 (comps, clauses) of |
411 NONE => (trace_msg (K "**** Unsolvable"); raise UNSOLVABLE ()) |
411 NONE => (trace_msg (K "**** Unsolvable"); raise UNSOLVABLE ()) |
412 | SOME cset => cset) |
412 | SOME cset => cset) |
413 |
413 |
414 fun do_mtype_comp _ _ _ _ NONE = NONE |
414 fun do_mtype_comp _ _ _ _ NONE = NONE |
600 SatSolver.SATISFIABLE assigns => do_assigns assigns |
600 SatSolver.SATISFIABLE assigns => do_assigns assigns |
601 | _ => (trace_msg (K "*** Unsolvable"); NONE) |
601 | _ => (trace_msg (K "*** Unsolvable"); NONE) |
602 end |
602 end |
603 end |
603 end |
604 |
604 |
605 type mtype_schema = mtyp * constraint_set |
605 type mcontext = |
606 type mtype_context = |
|
607 {bound_Ts: typ list, |
606 {bound_Ts: typ list, |
608 bound_Ms: mtyp list, |
607 bound_Ms: mtyp list, |
609 bound_frame: (int * annotation_atom) list, |
608 frame: (int * annotation_atom) list, |
610 frees: (styp * mtyp) list, |
609 frees: (styp * mtyp) list, |
611 consts: (styp * mtyp) list} |
610 consts: (styp * mtyp) list} |
612 |
611 |
613 type accumulator = mtype_context * constraint_set |
612 fun string_for_bound ctxt Ms (j, aa) = |
|
613 Syntax.string_of_term ctxt (Bound (length Ms - j - 1)) ^ " :\<^bsup>" ^ |
|
614 string_for_annotation_atom aa ^ "\<^esup> " ^ |
|
615 string_for_mtype (nth Ms (length Ms - j - 1)) |
|
616 fun string_for_free relevant_frees ((s, _), M) = |
|
617 if member (op =) relevant_frees s then SOME (s ^ " : " ^ string_for_mtype M) |
|
618 else NONE |
|
619 fun string_for_mcontext ctxt t {bound_Ms, frame, frees, ...} = |
|
620 (map_filter (string_for_free (Term.add_free_names t [])) frees @ |
|
621 map (string_for_bound ctxt bound_Ms) frame) |
|
622 |> commas |> enclose "[" "]" |
614 |
623 |
615 val initial_gamma = |
624 val initial_gamma = |
616 {bound_Ts = [], bound_Ms = [], bound_frame = [], frees = [], consts = []} |
625 {bound_Ts = [], bound_Ms = [], frame = [], frees = [], consts = []} |
617 |
626 |
618 fun push_bound aa T M {bound_Ts, bound_Ms, bound_frame, frees, consts} = |
627 fun push_bound aa T M {bound_Ts, bound_Ms, frame, frees, consts} = |
619 {bound_Ts = T :: bound_Ts, bound_Ms = M :: bound_Ms, |
628 {bound_Ts = T :: bound_Ts, bound_Ms = M :: bound_Ms, |
620 bound_frame = (length bound_Ts, aa) :: bound_frame, frees = frees, |
629 frame = frame @ [(length bound_Ts, aa)], frees = frees, consts = consts} |
621 consts = consts} |
630 fun pop_bound {bound_Ts, bound_Ms, frame, frees, consts} = |
622 fun pop_bound {bound_Ts, bound_Ms, bound_frame, frees, consts} = |
|
623 {bound_Ts = tl bound_Ts, bound_Ms = tl bound_Ms, |
631 {bound_Ts = tl bound_Ts, bound_Ms = tl bound_Ms, |
624 bound_frame = bound_frame |
632 frame = frame |> filter_out (fn (j, _) => j = length bound_Ts - 1), |
625 |> filter_out (fn (j, _) => j = length bound_Ts - 1), |
|
626 frees = frees, consts = consts} |
633 frees = frees, consts = consts} |
627 handle List.Empty => initial_gamma (* FIXME: needed? *) |
634 handle List.Empty => initial_gamma (* FIXME: needed? *) |
628 |
635 |
629 fun set_frame bound_frame ({bound_Ts, bound_Ms, frees, consts, ...} |
636 fun set_frame frame ({bound_Ts, bound_Ms, frees, consts, ...} : mcontext) = |
630 : mtype_context) = |
637 {bound_Ts = bound_Ts, bound_Ms = bound_Ms, frame = frame, frees = frees, |
631 {bound_Ts = bound_Ts, bound_Ms = bound_Ms, bound_frame = bound_frame, |
638 consts = consts} |
632 frees = frees, consts = consts} |
|
633 |
639 |
634 (* FIXME: make sure tracing messages are complete *) |
640 (* FIXME: make sure tracing messages are complete *) |
635 |
641 |
636 fun add_comp_frame a cmp = fold (add_annotation_atom_comp cmp [] (A a) o snd) |
642 fun add_comp_frame aa cmp = fold (add_annotation_atom_comp cmp [] aa o snd) |
637 |
643 |
638 fun add_bound_frame j frame = |
644 fun add_bound_frame j frame = |
639 let |
645 let |
640 val (new_frame, gen_frame) = List.partition (curry (op =) j o fst) frame |
646 val (new_frame, gen_frame) = List.partition (curry (op =) j o fst) frame |
641 in |
647 in |
642 add_comp_frame New Leq new_frame |
648 add_comp_frame (A New) Leq new_frame |
643 #> add_comp_frame Gen Eq gen_frame |
649 #> add_comp_frame (A Gen) Eq gen_frame |
644 end |
650 end |
645 |
651 |
646 fun fresh_frame ({max_fresh, ...} : mdata) fls tru = |
652 fun fresh_frame ({max_fresh, ...} : mdata) fls tru = |
647 map (apsnd (fn aa => |
653 map (apsnd (fn aa => |
648 case (aa, fls, tru) of |
654 case (aa, fls, tru) of |
682 case aa of |
688 case aa of |
683 A a' => if annotation_comp cmp a' a then NONE |
689 A a' => if annotation_comp cmp a' a then NONE |
684 else (trace_msg (K "**** Unsolvable"); raise UNSOLVABLE ()) |
690 else (trace_msg (K "**** Unsolvable"); raise UNSOLVABLE ()) |
685 | V x => SOME (x, (sign_for_comp_op cmp, a)) |
691 | V x => SOME (x, (sign_for_comp_op cmp, a)) |
686 |
692 |
687 val annotation_clause_from_quasi_clause = |
693 val assign_clause_from_quasi_clause = |
688 map_filter annotation_literal_from_quasi_literal |
694 map_filter annotation_literal_from_quasi_literal |
689 |
695 val add_quasi_clause = assign_clause_from_quasi_clause #> add_assign_clause |
690 val add_quasi_clause = annotation_clause_from_quasi_clause #> add_assign_clause |
|
691 |
696 |
692 fun add_connective_var conn mk_quasi_clauses res_aa aa1 aa2 = |
697 fun add_connective_var conn mk_quasi_clauses res_aa aa1 aa2 = |
693 (trace_msg (fn () => "*** Add " ^ string_for_annotation_atom res_aa ^ " = " ^ |
698 (trace_msg (fn () => "*** Add " ^ string_for_annotation_atom res_aa ^ " = " ^ |
694 string_for_annotation_atom aa1 ^ " " ^ conn ^ " " ^ |
699 string_for_annotation_atom aa1 ^ " " ^ conn ^ " " ^ |
695 string_for_annotation_atom aa2); |
700 string_for_annotation_atom aa2); |
697 |
702 |
698 fun add_connective_frames conn mk_quasi_clauses res_frame frame1 frame2 = |
703 fun add_connective_frames conn mk_quasi_clauses res_frame frame1 frame2 = |
699 fold I (map3 (fn (_, res_aa) => fn (_, aa1) => fn (_, aa2) => |
704 fold I (map3 (fn (_, res_aa) => fn (_, aa1) => fn (_, aa2) => |
700 add_connective_var conn mk_quasi_clauses res_aa aa1 aa2) |
705 add_connective_var conn mk_quasi_clauses res_aa aa1 aa2) |
701 res_frame frame1 frame2) |
706 res_frame frame1 frame2) |
|
707 |
|
708 fun kill_unused_in_frame is_in (accum as ({frame, ...}, _)) = |
|
709 let val (used_frame, unused_frame) = List.partition is_in frame in |
|
710 accum |>> set_frame used_frame |
|
711 ||> add_comp_frame (A Gen) Eq unused_frame |
|
712 end |
|
713 |
|
714 fun split_frame is_in_fun (gamma as {frame, ...}, cset) = |
|
715 let |
|
716 fun bubble fun_frame arg_frame [] cset = |
|
717 ((rev fun_frame, rev arg_frame), cset) |
|
718 | bubble fun_frame arg_frame ((bound as (_, aa)) :: rest) cset = |
|
719 if is_in_fun bound then |
|
720 bubble (bound :: fun_frame) arg_frame rest |
|
721 (cset |> add_comp_frame aa Leq arg_frame) |
|
722 else |
|
723 bubble fun_frame (bound :: arg_frame) rest cset |
|
724 in cset |> bubble [] [] frame ||> pair gamma end |
|
725 |
|
726 fun add_annotation_atom_comp_alt _ (A Gen) _ _ = I |
|
727 | add_annotation_atom_comp_alt _ (A _) _ _ = |
|
728 (trace_msg (K "*** Expected G"); raise UNSOLVABLE ()) |
|
729 | add_annotation_atom_comp_alt cmp (V x) aa1 aa2 = |
|
730 add_annotation_atom_comp cmp [x] aa1 aa2 |
|
731 |
|
732 fun add_arg_order1 ((_, aa), (_, prev_aa)) = |
|
733 add_annotation_atom_comp_alt Neq prev_aa (A Gen) aa |
|
734 fun add_app1 fun_aa ((_, res_aa), (_, arg_aa)) = |
|
735 add_annotation_atom_comp_alt Leq arg_aa fun_aa res_aa |
|
736 ##> add_quasi_clause [(arg_aa, (Neq, Gen)), (res_aa, (Eq, Gen))] |
|
737 fun add_app _ [] [] = I |
|
738 | add_app fun_aa res_frame arg_frame = |
|
739 add_comp_frame (A New) Leq arg_frame |
|
740 #> fold add_arg_order1 (tl arg_frame ~~ (fst (split_last arg_frame))) |
|
741 #> fold (add_app1 fun_aa) (res_frame ~~ arg_frame) |
702 |
742 |
703 fun consider_term (mdata as {hol_ctxt = {thy, ctxt, stds, ...}, alpha_T, |
743 fun consider_term (mdata as {hol_ctxt = {thy, ctxt, stds, ...}, alpha_T, |
704 max_fresh, ...}) = |
744 max_fresh, ...}) = |
705 let |
745 let |
706 fun is_enough_eta_expanded t = |
746 fun is_enough_eta_expanded t = |
777 MApp (MApp (MRaw (connective_t, |
817 MApp (MApp (MRaw (connective_t, |
778 mtype_for (fastype_of connective_t)), |
818 mtype_for (fastype_of connective_t)), |
779 MApp (bound_m, MRaw (Bound 0, M1))), |
819 MApp (bound_m, MRaw (Bound 0, M1))), |
780 body_m))), accum) |
820 body_m))), accum) |
781 end |
821 end |
782 and do_connect conn mk_quasi_clauses t0 t1 t2 |
822 and do_connect conn mk_quasi_clauses t0 t1 t2 (accum as ({frame, ...}, _)) = |
783 (accum as ({bound_frame, ...}, _)) = |
|
784 let |
823 let |
785 val frame1 = fresh_frame mdata (SOME Tru) NONE bound_frame |
824 val frame1 = fresh_frame mdata (SOME Tru) NONE frame |
786 val frame2 = fresh_frame mdata (SOME Fls) NONE bound_frame |
825 val frame2 = fresh_frame mdata (SOME Fls) NONE frame |
787 val (m1, accum) = accum |>> set_frame frame1 |> do_term t1 |
826 val (m1, accum) = accum |>> set_frame frame1 |> do_term t1 |
788 val (m2, accum) = accum |>> set_frame frame2 |> do_term t2 |
827 val (m2, accum) = accum |>> set_frame frame2 |> do_term t2 |
789 in |
828 in |
790 (MApp (MApp (MRaw (t0, mtype_for (fastype_of t0)), m1), m2), |
829 (MApp (MApp (MRaw (t0, mtype_for (fastype_of t0)), m1), m2), |
791 accum |>> set_frame bound_frame |
830 accum |>> set_frame frame |
792 ||> apsnd (add_connective_frames conn mk_quasi_clauses |
831 ||> apsnd (add_connective_frames conn mk_quasi_clauses |
793 bound_frame frame1 frame2)) |
832 frame frame1 frame2)) |
794 end |
833 end |
795 and do_term t (accum as ({bound_Ts, bound_Ms, bound_frame, frees, consts}, |
834 and do_term t |
796 cset)) = |
835 (accum as (gamma as {bound_Ts, bound_Ms, frame, frees, consts}, |
797 (trace_msg (fn () => " \<Gamma> \<turnstile> " ^ |
836 cset)) = |
798 Syntax.string_of_term ctxt t ^ " : _?"); |
837 (trace_msg (fn () => " " ^ string_for_mcontext ctxt t gamma ^ |
|
838 " \<turnstile> " ^ Syntax.string_of_term ctxt t ^ |
|
839 " : _?"); |
799 case t of |
840 case t of |
800 @{const False} => |
841 @{const False} => |
801 (MRaw (t, bool_M), accum ||> add_comp_frame Fls Leq bound_frame) |
842 (MRaw (t, bool_M), accum ||> add_comp_frame (A Fls) Leq frame) |
802 | @{const True} => |
843 | @{const True} => |
803 (MRaw (t, bool_M), accum ||> add_comp_frame Tru Leq bound_frame) |
844 (MRaw (t, bool_M), accum ||> add_comp_frame (A Tru) Leq frame) |
804 | Const (x as (s, T)) => |
845 | Const (x as (s, T)) => |
805 (case AList.lookup (op =) consts x of |
846 (case AList.lookup (op =) consts x of |
806 SOME M => (M, accum) |
847 SOME M => (M, accum) |
807 | NONE => |
848 | NONE => |
808 if not (could_exist_alpha_subtype alpha_T T) then |
849 if not (could_exist_alpha_subtype alpha_T T) then |
898 (mtype_for_constr mdata x, accum) |
939 (mtype_for_constr mdata x, accum) |
899 else if is_built_in_const thy stds x then |
940 else if is_built_in_const thy stds x then |
900 (fresh_mtype_for_type mdata true T, accum) |
941 (fresh_mtype_for_type mdata true T, accum) |
901 else |
942 else |
902 let val M = mtype_for T in |
943 let val M = mtype_for T in |
903 (M, ({bound_Ts = bound_Ts, bound_Ms = bound_Ms, |
944 (M, ({bound_Ts = bound_Ts, bound_Ms = bound_Ms, frame = frame, |
904 bound_frame = bound_frame, frees = frees, |
945 frees = frees, consts = (x, M) :: consts}, cset)) |
905 consts = (x, M) :: consts}, cset)) |
|
906 end) |
946 end) |
907 |>> curry MRaw t |
947 |>> curry MRaw t |
908 ||> apsnd (add_comp_frame Gen Eq bound_frame) |
948 ||> apsnd (add_comp_frame (A Gen) Eq frame) |
909 | Free (x as (_, T)) => |
949 | Free (x as (_, T)) => |
910 (case AList.lookup (op =) frees x of |
950 (case AList.lookup (op =) frees x of |
911 SOME M => (M, accum) |
951 SOME M => (M, accum) |
912 | NONE => |
952 | NONE => |
913 let val M = mtype_for T in |
953 let val M = mtype_for T in |
914 (M, ({bound_Ts = bound_Ts, bound_Ms = bound_Ms, |
954 (M, ({bound_Ts = bound_Ts, bound_Ms = bound_Ms, frame = frame, |
915 bound_frame = bound_frame, frees = (x, M) :: frees, |
955 frees = (x, M) :: frees, consts = consts}, cset)) |
916 consts = consts}, cset)) |
|
917 end) |
956 end) |
918 |>> curry MRaw t ||> apsnd (add_comp_frame Gen Eq bound_frame) |
957 |>> curry MRaw t ||> apsnd (add_comp_frame (A Gen) Eq frame) |
919 | Var _ => (trace_msg (K "*** Var"); raise UNSOLVABLE ()) |
958 | Var _ => (trace_msg (K "*** Var"); raise UNSOLVABLE ()) |
920 | Bound j => |
959 | Bound j => |
921 (MRaw (t, nth bound_Ms j), |
960 (MRaw (t, nth bound_Ms j), |
922 accum ||> add_bound_frame (length bound_Ts - j - 1) bound_frame) |
961 accum ||> add_bound_frame (length bound_Ts - j - 1) frame) |
923 | Abs (s, T, t') => |
962 | Abs (s, T, t') => |
924 (case fin_fun_body T (fastype_of1 (T :: bound_Ts, t')) t' of |
963 (case fin_fun_body T (fastype_of1 (T :: bound_Ts, t')) t' of |
925 SOME t' => |
964 SOME t' => |
926 let |
965 let |
927 val M = mtype_for T |
966 val M = mtype_for T |
965 do_connect "\<implies>" imp_clauses t0 t1 t2 accum |
1004 do_connect "\<implies>" imp_clauses t0 t1 t2 accum |
966 | Const (@{const_name Let}, _) $ t1 $ t2 => |
1005 | Const (@{const_name Let}, _) $ t1 $ t2 => |
967 do_term (betapply (t2, t1)) accum |
1006 do_term (betapply (t2, t1)) accum |
968 | t1 $ t2 => |
1007 | t1 $ t2 => |
969 let |
1008 let |
970 val (m1, accum) = do_term t1 accum |
1009 fun is_in t (j, _) = loose_bvar1 (t, length bound_Ts - j - 1) |
971 val (m2, accum) = do_term t2 accum |
1010 val accum as ({frame, ...}, _) = |
|
1011 accum |> kill_unused_in_frame (is_in t) |
|
1012 val ((frame1a, frame1b), accum) = accum |> split_frame (is_in t1) |
|
1013 val frame2a = frame1a |> map (apsnd (K (A Gen))) |
|
1014 val frame2b = |
|
1015 frame1b |> map (apsnd (fn _ => V (Unsynchronized.inc max_fresh))) |
|
1016 val frame2 = frame2a @ frame2b |
|
1017 val (m1, accum) = accum |>> set_frame frame1a |> do_term t1 |
|
1018 val (m2, accum) = accum |>> set_frame frame2 |> do_term t2 |
972 in |
1019 in |
973 let |
1020 let |
974 val M11 = mtype_of_mterm m1 |> dest_MFun |> #1 |
1021 val (M11, aa, _) = mtype_of_mterm m1 |> dest_MFun |
975 val M2 = mtype_of_mterm m2 |
1022 val M2 = mtype_of_mterm m2 |
976 in (MApp (m1, m2), accum ||> add_is_sub_mtype M2 M11) end |
1023 in |
|
1024 (MApp (m1, m2), |
|
1025 accum |>> set_frame frame |
|
1026 ||> add_is_sub_mtype M2 M11 |
|
1027 ||> add_app aa frame1b frame2b) |
|
1028 end |
977 end) |
1029 end) |
978 |> tap (fn (m, _) => trace_msg (fn () => " \<Gamma> \<turnstile> " ^ |
1030 |> tap (fn (m, (gamma, _)) => |
979 string_for_mterm ctxt m)) |
1031 trace_msg (fn () => " " ^ string_for_mcontext ctxt t gamma ^ |
|
1032 " \<turnstile> " ^ |
|
1033 string_for_mterm ctxt m)) |
980 in do_term end |
1034 in do_term end |
981 |
1035 |
982 fun force_minus_funs 0 _ = I |
1036 fun force_minus_funs 0 _ = I |
983 | force_minus_funs n (M as MFun (M1, _, M2)) = |
1037 | force_minus_funs n (M as MFun (M1, _, M2)) = |
984 add_mtypes_equal M (MFun (M1, A Gen, M2)) #> force_minus_funs (n - 1) M2 |
1038 add_mtypes_equal M (MFun (M1, A Gen, M2)) #> force_minus_funs (n - 1) M2 |
1027 fun do_equals x t1 t2 = |
1081 fun do_equals x t1 t2 = |
1028 case sn of |
1082 case sn of |
1029 Plus => do_term t accum |
1083 Plus => do_term t accum |
1030 | Minus => consider_general_equals mdata false x t1 t2 accum |
1084 | Minus => consider_general_equals mdata false x t1 t2 accum |
1031 in |
1085 in |
1032 (trace_msg (fn () => " \<Gamma> \<turnstile> " ^ |
1086 (trace_msg (fn () => " " ^ string_for_mcontext ctxt t gamma ^ |
1033 Syntax.string_of_term ctxt t ^ " : o\<^sup>" ^ |
1087 " \<turnstile> " ^ Syntax.string_of_term ctxt t ^ |
1034 string_for_sign sn ^ "?"); |
1088 " : o\<^sup>" ^ string_for_sign sn ^ "?"); |
1035 case t of |
1089 case t of |
1036 Const (x as (@{const_name all}, _)) $ Abs (s1, T1, t1) => |
1090 Const (x as (@{const_name all}, _)) $ Abs (s1, T1, t1) => |
1037 do_quantifier x s1 T1 t1 |
1091 do_quantifier x s1 T1 t1 |
1038 | Const (x as (@{const_name "=="}, _)) $ t1 $ t2 => do_equals x t1 t2 |
1092 | Const (x as (@{const_name "=="}, _)) $ t1 $ t2 => do_equals x t1 t2 |
1039 | @{const Trueprop} $ t1 => |
1093 | @{const Trueprop} $ t1 => |
1190 (tl nondef_ts) |
1245 (tl nondef_ts) |
1191 val (def_ms, (gamma, cset)) = |
1246 val (def_ms, (gamma, cset)) = |
1192 ([], accum) |> fold (amass (consider_definitional_axiom mdata)) def_ts |
1247 ([], accum) |> fold (amass (consider_definitional_axiom mdata)) def_ts |
1193 in |
1248 in |
1194 case solve calculus (!max_fresh) cset of |
1249 case solve calculus (!max_fresh) cset of |
1195 SOME asgs => (print_mtype_context ctxt asgs gamma; |
1250 SOME asgs => (print_mcontext ctxt asgs gamma; |
1196 SOME (asgs, (nondef_ms, def_ms), !constr_mcache)) |
1251 SOME (asgs, (nondef_ms, def_ms), !constr_mcache)) |
1197 | _ => NONE |
1252 | _ => NONE |
1198 end |
1253 end |
1199 handle UNSOLVABLE () => NONE |
1254 handle UNSOLVABLE () => NONE |
1200 | MTYPE (loc, Ms, Ts) => |
1255 | MTYPE (loc, Ms, Ts) => |