375 |
375 |
376 fun do_annotation_atom_comp Eq [] aa1 aa2 (cset as (comps, clauses)) = |
376 fun do_annotation_atom_comp Eq [] aa1 aa2 (cset as (comps, clauses)) = |
377 (case (aa1, aa2) of |
377 (case (aa1, aa2) of |
378 (A a1, A a2) => if a1 = a2 then SOME cset else NONE |
378 (A a1, A a2) => if a1 = a2 then SOME cset else NONE |
379 | (V x1, A a2) => |
379 | (V x1, A a2) => |
380 clauses |> add_assign (x1, a2) |> Option.map (pair comps) |
380 clauses |> add_assign_literal (x1, a2) |> Option.map (pair comps) |
381 | (V _, V _) => SOME (insert (op =) (aa1, aa2, Eq, []) comps, clauses) |
381 | (V _, V _) => SOME (insert (op =) (aa1, aa2, Eq, []) comps, clauses) |
382 | _ => do_annotation_atom_comp Eq [] aa2 aa1 cset) |
382 | _ => do_annotation_atom_comp Eq [] aa2 aa1 cset) |
383 | do_annotation_atom_comp Leq [] aa1 aa2 (cset as (comps, clauses)) = |
383 | do_annotation_atom_comp Leq [] aa1 aa2 (cset as (comps, clauses)) = |
384 (case (aa1, aa2) of |
384 (case (aa1, aa2) of |
385 (_, A Gen) => SOME cset |
385 (_, A Gen) => SOME cset |
493 |
493 |
494 fun prop_for_bool b = if b then PL.True else PL.False |
494 fun prop_for_bool b = if b then PL.True else PL.False |
495 fun prop_for_bool_var_equality (v1, v2) = |
495 fun prop_for_bool_var_equality (v1, v2) = |
496 PL.And (PL.Or (PL.BoolVar v1, PL.Not (PL.BoolVar v2)), |
496 PL.And (PL.Or (PL.BoolVar v1, PL.Not (PL.BoolVar v2)), |
497 PL.Or (PL.Not (PL.BoolVar v1), PL.BoolVar v2)) |
497 PL.Or (PL.Not (PL.BoolVar v1), PL.BoolVar v2)) |
498 fun prop_for_assign (x, a) = |
498 fun prop_for_assign_literal (x, a) = |
499 let val (b1, b2) = bools_from_annotation a in |
499 let val (b1, b2) = bools_from_annotation a in |
500 PL.And (PL.BoolVar (fst_var x) |> not b1 ? PL.Not, |
500 PL.And (PL.BoolVar (fst_var x) |> not b1 ? PL.Not, |
501 PL.BoolVar (snd_var x) |> not b2 ? PL.Not) |
501 PL.BoolVar (snd_var x) |> not b2 ? PL.Not) |
502 end |
502 end |
503 fun prop_for_atom_assign (A a', a) = prop_for_bool (a = a') |
503 fun prop_for_atom_assign (A a', a) = prop_for_bool (a = a') |
504 | prop_for_atom_assign (V x, a) = prop_for_assign (x, a) |
504 | prop_for_atom_assign (V x, a) = prop_for_assign_literal (x, a) |
505 fun prop_for_atom_equality (aa1, A a2) = prop_for_atom_assign (aa1, a2) |
505 fun prop_for_atom_equality (aa1, A a2) = prop_for_atom_assign (aa1, a2) |
506 | prop_for_atom_equality (A a1, aa2) = prop_for_atom_assign (aa2, a1) |
506 | prop_for_atom_equality (A a1, aa2) = prop_for_atom_assign (aa2, a1) |
507 | prop_for_atom_equality (V x1, V x2) = |
507 | prop_for_atom_equality (V x1, V x2) = |
508 PL.And (prop_for_bool_var_equality (pairself fst_var (x1, x2)), |
508 PL.And (prop_for_bool_var_equality (pairself fst_var (x1, x2)), |
509 prop_for_bool_var_equality (pairself snd_var (x1, x2))) |
509 prop_for_bool_var_equality (pairself snd_var (x1, x2))) |
510 val prop_for_assign_clause = PL.exists o map prop_for_assign |
510 val prop_for_assign_clause = PL.exists o map prop_for_assign_literal |
511 fun prop_for_exists_var_assign xs a = |
511 fun prop_for_exists_var_assign_literal xs a = |
512 PL.exists (map (fn x => prop_for_assign (x, a)) xs) |
512 PL.exists (map (fn x => prop_for_assign_literal (x, a)) xs) |
513 fun prop_for_comp (aa1, aa2, Eq, []) = |
513 fun prop_for_comp (aa1, aa2, Eq, []) = |
514 PL.SAnd (prop_for_comp (aa1, aa2, Leq, []), |
514 PL.SAnd (prop_for_comp (aa1, aa2, Leq, []), |
515 prop_for_comp (aa2, aa1, Leq, [])) |
515 prop_for_comp (aa2, aa1, Leq, [])) |
516 | prop_for_comp (aa1, aa2, Leq, []) = |
516 | prop_for_comp (aa1, aa2, Leq, []) = |
517 PL.SOr (prop_for_atom_equality (aa1, aa2), prop_for_atom_assign (aa2, Gen)) |
517 PL.SOr (prop_for_atom_equality (aa1, aa2), prop_for_atom_assign (aa2, Gen)) |
518 | prop_for_comp (aa1, aa2, cmp, xs) = |
518 | prop_for_comp (aa1, aa2, cmp, xs) = |
519 PL.SOr (prop_for_exists_var_assign xs Gen, |
519 PL.SOr (prop_for_exists_var_assign_literal xs Gen, |
520 prop_for_comp (aa1, aa2, cmp, [])) |
520 prop_for_comp (aa1, aa2, cmp, [])) |
521 |
521 |
522 (* The "calculus" parameter may be 1, 2, or 3, corresponding approximately to |
522 (* The "calculus" parameter may be 1, 2, or 3, corresponding approximately to |
523 the M1, M2, and M3 calculi from Blanchette & Krauss 2011. *) |
523 the M1, M2, and M3 calculi from Blanchette & Krauss 2011. *) |
524 fun variable_domain calculus = |
524 fun variable_domain calculus = |
525 [Gen] @ (if calculus > 1 then [Fls] else []) |
525 [Gen] @ (if calculus > 1 then [Fls] else []) |
526 @ (if calculus > 2 then [New, Tru] else []) |
526 @ (if calculus > 2 then [New, Tru] else []) |
527 |
527 |
528 fun prop_for_variable_domain calculus x = |
528 fun prop_for_variable_domain calculus x = |
529 PL.exists (map (curry prop_for_assign x) (variable_domain calculus)) |
529 PL.exists (map (curry prop_for_assign_literal x) (variable_domain calculus)) |
530 |
530 |
531 fun extract_assigns max_var assigns asgs = |
531 fun extract_assigns max_var assigns asgs = |
532 fold (fn x => fn accum => |
532 fold (fn x => fn accum => |
533 if AList.defined (op =) asgs x then |
533 if AList.defined (op =) asgs x then |
534 accum |
534 accum |
638 fun do_var (j, A Fls) = (j, A (case sn of Plus => Fls | Minus => Tru)) |
639 fun do_var (j, A Fls) = (j, A (case sn of Plus => Fls | Minus => Tru)) |
639 | do_var (j, A Gen) = (j, A Gen) |
640 | do_var (j, A Gen) = (j, A Gen) |
640 | do_var (j, _) = (j, V (Unsynchronized.inc max_fresh)) |
641 | do_var (j, _) = (j, V (Unsynchronized.inc max_fresh)) |
641 in map do_var end |
642 in map do_var end |
642 |
643 |
643 fun add_imp_frames res_frame frame1 frame2 = I |
644 fun do_not_var j aa0 aa1 _ = I |
644 (*### |
645 (* |
645 let |
646 x1 ~= T | x0 = F |
646 fun do_var_pair (j, aa0) (_, aa1) (_, aa2) = |
647 x1 ~= F | x0 = T |
647 in map3 do_var_pair res_frame frame1 frame2 end |
648 x1 ~= G | x0 = G |
|
649 x1 ~= N | x0 = G |
648 *) |
650 *) |
|
651 |
|
652 fun do_conj_var j aa0 aa1 aa2 = I |
|
653 (* |
|
654 (x1 ≠ T | x2 ≠ T | x0 = T) & |
|
655 (x1 ≠ F | x0 = F) & |
|
656 (x2 ≠ F | x0 = F) & |
|
657 (x1 ≠ G | x2 = F | x0 = G) & |
|
658 (x1 ≠ N | x2 = F | x0 = G) & |
|
659 (x1 = F | x2 ≠ G | x0 = G) & |
|
660 (x1 = F | x2 ≠ N | x0 = G)" |
|
661 *) |
|
662 |
|
663 fun do_disj_var j aa0 aa1 aa2 = I |
|
664 fun do_imp_var j aa0 aa1 aa2 = I |
|
665 |
|
666 fun add_connective_frames do_var res_frame frame1 frame2 = |
|
667 fold I (map3 (fn (j, aa0) => fn (_, aa1) => fn (_, aa2) => |
|
668 do_var j aa0 aa1 aa2) res_frame frame1 frame2) |
649 |
669 |
650 fun consider_term (mdata as {hol_ctxt = {thy, ctxt, stds, ...}, alpha_T, |
670 fun consider_term (mdata as {hol_ctxt = {thy, ctxt, stds, ...}, alpha_T, |
651 max_fresh, ...}) = |
671 max_fresh, ...}) = |
652 let |
672 let |
653 fun is_enough_eta_expanded t = |
673 fun is_enough_eta_expanded t = |
720 MAbs (abs_s, abs_T, M1, aa', |
740 MAbs (abs_s, abs_T, M1, aa', |
721 MApp (MApp (MRaw (connective_t, |
741 MApp (MApp (MRaw (connective_t, |
722 mtype_for (fastype_of connective_t)), |
742 mtype_for (fastype_of connective_t)), |
723 MApp (bound_m, MRaw (Bound 0, M1))), |
743 MApp (bound_m, MRaw (Bound 0, M1))), |
724 body_m))), accum) |
744 body_m))), accum) |
|
745 end |
|
746 and do_connect do_var t0 t1 t2 (accum as ({bound_frame, ...}, _)) = |
|
747 let |
|
748 val frame1 = fresh_imp_frame mdata Minus bound_frame |
|
749 val frame2 = fresh_imp_frame mdata Plus bound_frame |
|
750 val (m1, accum) = accum |>> set_frame frame1 |> do_term t1 |
|
751 val (m2, accum) = accum |>> set_frame frame2 |> do_term t2 |
|
752 in |
|
753 (MApp (MApp (MRaw (t0, mtype_for (fastype_of t0)), m1), m2), |
|
754 accum |>> set_frame bound_frame |
|
755 ||> add_connective_frames do_var bound_frame frame1 frame2) |
725 end |
756 end |
726 and do_term t (accum as ({bound_Ts, bound_Ms, bound_frame, frees, consts}, |
757 and do_term t (accum as ({bound_Ts, bound_Ms, bound_frame, frees, consts}, |
727 cset)) = |
758 cset)) = |
728 (trace_msg (fn () => " \<Gamma> \<turnstile> " ^ |
759 (trace_msg (fn () => " \<Gamma> \<turnstile> " ^ |
729 Syntax.string_of_term ctxt t ^ " : _?"); |
760 Syntax.string_of_term ctxt t ^ " : _?"); |
877 val M = mtype_for T |
908 val M = mtype_for T |
878 val aa = V (Unsynchronized.inc max_fresh) |
909 val aa = V (Unsynchronized.inc max_fresh) |
879 val (m', accum) = |
910 val (m', accum) = |
880 do_term t' (accum |>> push_bound aa T M) |
911 do_term t' (accum |>> push_bound aa T M) |
881 in (MAbs (s, T, M, aa, m'), accum |>> pop_bound) end)) |
912 in (MAbs (s, T, M, aa, m'), accum |>> pop_bound) end)) |
882 | (t0 as @{const implies}) $ t1 $ t2 => |
|
883 let |
|
884 val frame1 = fresh_imp_frame mdata Minus bound_frame |
|
885 val frame2 = fresh_imp_frame mdata Plus bound_frame |
|
886 val (m0, accum) = accum |> do_term t0 |
|
887 val (m1, accum) = accum |>> set_frame frame1 |> do_term t1 |
|
888 val (m2, accum) = accum |>> set_frame frame2 |> do_term t2 |
|
889 in |
|
890 (MApp (MApp (m0, m1), m2), |
|
891 accum |>> set_frame bound_frame |
|
892 ||> add_imp_frames bound_frame frame1 frame2) |
|
893 end |
|
894 | (t0 as Const (@{const_name All}, _)) |
913 | (t0 as Const (@{const_name All}, _)) |
895 $ Abs (s', T', (t10 as @{const HOL.implies}) |
914 $ Abs (s', T', (t10 as @{const HOL.implies}) |
896 $ (t11 $ Bound 0) $ t12) => |
915 $ (t11 $ Bound 0) $ t12) => |
897 do_bounded_quantifier t0 s' T' t10 t11 t12 accum |
916 do_bounded_quantifier t0 s' T' t10 t11 t12 accum |
898 | (t0 as Const (@{const_name Ex}, _)) |
917 | (t0 as Const (@{const_name Ex}, _)) |
899 $ Abs (s', T', (t10 as @{const HOL.conj}) |
918 $ Abs (s', T', (t10 as @{const HOL.conj}) |
900 $ (t11 $ Bound 0) $ t12) => |
919 $ (t11 $ Bound 0) $ t12) => |
901 do_bounded_quantifier t0 s' T' t10 t11 t12 accum |
920 do_bounded_quantifier t0 s' T' t10 t11 t12 accum |
|
921 | (t0 as @{const Not}) $ t1 => |
|
922 let |
|
923 val frame1 = fresh_imp_frame mdata Minus bound_frame |
|
924 val (m1, accum) = accum |>> set_frame frame1 |> do_term t1 |
|
925 in |
|
926 (MApp (MRaw (t0, mtype_for (fastype_of t0)), m1), |
|
927 accum |>> set_frame bound_frame |
|
928 ||> add_connective_frames do_not_var bound_frame frame1 |
|
929 frame1) |
|
930 end |
|
931 | (t0 as @{const conj}) $ t1 $ t2 => |
|
932 do_connect do_conj_var t0 t1 t2 accum |
|
933 | (t0 as @{const disj}) $ t1 $ t2 => |
|
934 do_connect do_disj_var t0 t1 t2 accum |
|
935 | (t0 as @{const implies}) $ t1 $ t2 => |
|
936 do_connect do_imp_var t0 t1 t2 accum |
902 | Const (@{const_name Let}, _) $ t1 $ t2 => |
937 | Const (@{const_name Let}, _) $ t1 $ t2 => |
903 do_term (betapply (t2, t1)) accum |
938 do_term (betapply (t2, t1)) accum |
904 | t1 $ t2 => |
939 | t1 $ t2 => |
905 let |
940 let |
906 val (m1, accum) = do_term t1 accum |
941 val (m1, accum) = do_term t1 accum |