src/HOL/Tools/Nitpick/nitpick_mono.ML
changeset 40993 52ee2a187cdb
parent 40991 902ad76994d5
child 40994 3bdb8df0daf0
equal deleted inserted replaced
40992:8cacefe9851c 40993:52ee2a187cdb
     9 sig
     9 sig
    10   type hol_context = Nitpick_HOL.hol_context
    10   type hol_context = Nitpick_HOL.hol_context
    11 
    11 
    12   val trace : bool Unsynchronized.ref
    12   val trace : bool Unsynchronized.ref
    13   val formulas_monotonic :
    13   val formulas_monotonic :
    14     hol_context -> bool -> typ -> term list * term list -> bool
    14     hol_context -> bool -> int -> typ -> term list * term list -> bool
    15   val finitize_funs :
    15   val finitize_funs :
    16     hol_context -> bool -> (typ option * bool option) list -> typ
    16     hol_context -> bool -> (typ option * bool option) list -> int -> typ
    17     -> term list * term list -> term list * term list
    17     -> term list * term list -> term list * term list
    18 end;
    18 end;
    19 
    19 
    20 structure Nitpick_Mono : NITPICK_MONO =
    20 structure Nitpick_Mono : NITPICK_MONO =
    21 struct
    21 struct
   371     | NONE => SOME ((x, a) :: asgs)
   371     | NONE => SOME ((x, a) :: asgs)
   372 
   372 
   373 fun add_assign_disjunct _ NONE = NONE
   373 fun add_assign_disjunct _ NONE = NONE
   374   | add_assign_disjunct asg (SOME asgs) = SOME (insert (op =) asg asgs)
   374   | add_assign_disjunct asg (SOME asgs) = SOME (insert (op =) asg asgs)
   375 
   375 
   376 fun add_annotation_atom_comp Eq [] aa1 aa2 (accum as (asgs, comps)) =
   376 fun do_annotation_atom_comp Eq [] aa1 aa2 (accum as (asgs, comps)) =
   377     (case (aa1, aa2) of
   377     (case (aa1, aa2) of
   378        (A a1, A a2) => if a1 = a2 then SOME accum else NONE
   378        (A a1, A a2) => if a1 = a2 then SOME accum else NONE
   379      | (V x1, A a2) =>
   379      | (V x1, A a2) =>
   380        SOME asgs |> add_assign_conjunct (x1, a2) |> Option.map (rpair comps)
   380        SOME asgs |> add_assign_conjunct (x1, a2) |> Option.map (rpair comps)
   381      | (V _, V _) => SOME (asgs, insert (op =) (aa1, aa2, Eq, []) comps)
   381      | (V _, V _) => SOME (asgs, insert (op =) (aa1, aa2, Eq, []) comps)
   382      | _ => add_annotation_atom_comp Eq [] aa2 aa1 accum)
   382      | _ => do_annotation_atom_comp Eq [] aa2 aa1 accum)
   383   | add_annotation_atom_comp Leq [] aa1 aa2 (accum as (asgs, comps)) =
   383   | do_annotation_atom_comp Leq [] aa1 aa2 (accum as (asgs, comps)) =
   384     (case (aa1, aa2) of
   384     (case (aa1, aa2) of
   385        (_, A Gen) => SOME accum
   385        (_, A Gen) => SOME accum
   386      | (A Gen, A _) => NONE
   386      | (A Gen, A _) => NONE
   387      | (A a1, A a2) => if a1 = a2 then SOME accum else NONE
   387      | (A a1, A a2) => if a1 = a2 then SOME accum else NONE
   388      | _ => SOME (asgs, insert (op =) (aa1, aa2, Leq, []) comps))
   388      | _ => SOME (asgs, insert (op =) (aa1, aa2, Leq, []) comps))
   389   | add_annotation_atom_comp cmp xs aa1 aa2 (asgs, comps) =
   389   | do_annotation_atom_comp cmp xs aa1 aa2 (asgs, comps) =
   390     SOME (asgs, insert (op =) (aa1, aa2, cmp, xs) comps)
   390     SOME (asgs, insert (op =) (aa1, aa2, cmp, xs) comps)
       
   391 
       
   392 fun add_annotation_atom_comp cmp xs aa1 aa2
       
   393                              ((asgs, comps, clauses) : constraint_set) =
       
   394   (trace_msg (fn () => "*** Add " ^ string_for_annotation_atom aa1 ^ " " ^
       
   395                        string_for_comp_op cmp ^ " " ^
       
   396                        string_for_annotation_atom aa2);
       
   397    case do_annotation_atom_comp cmp xs aa1 aa2 (asgs, comps) of
       
   398      NONE => (trace_msg (K "**** Unsolvable"); raise UNSOLVABLE ())
       
   399    | SOME (asgs, comps) => (asgs, comps, clauses))
   391 
   400 
   392 fun do_mtype_comp _ _ _ _ NONE = NONE
   401 fun do_mtype_comp _ _ _ _ NONE = NONE
   393   | do_mtype_comp _ _ MAlpha MAlpha accum = accum
   402   | do_mtype_comp _ _ MAlpha MAlpha accum = accum
   394   | do_mtype_comp Eq xs (MFun (M11, aa1, M12)) (MFun (M21, aa2, M22))
   403   | do_mtype_comp Eq xs (MFun (M11, aa1, M12)) (MFun (M21, aa2, M22))
   395                   (SOME accum) =
   404                   (SOME accum) =
   396      accum |> add_annotation_atom_comp Eq xs aa1 aa2
   405      accum |> do_annotation_atom_comp Eq xs aa1 aa2
   397            |> do_mtype_comp Eq xs M11 M21 |> do_mtype_comp Eq xs M12 M22
   406            |> do_mtype_comp Eq xs M11 M21 |> do_mtype_comp Eq xs M12 M22
   398   | do_mtype_comp Leq xs (MFun (M11, aa1, M12)) (MFun (M21, aa2, M22))
   407   | do_mtype_comp Leq xs (MFun (M11, aa1, M12)) (MFun (M21, aa2, M22))
   399                   (SOME accum) =
   408                   (SOME accum) =
   400     (if exists_alpha_sub_mtype M11 then
   409     (if exists_alpha_sub_mtype M11 then
   401        accum |> add_annotation_atom_comp Leq xs aa1 aa2
   410        accum |> do_annotation_atom_comp Leq xs aa1 aa2
   402              |> do_mtype_comp Leq xs M21 M11
   411              |> do_mtype_comp Leq xs M21 M11
   403              |> (case aa2 of
   412              |> (case aa2 of
   404                    A Gen => I
   413                    A Gen => I
   405                  | A _ => do_mtype_comp Leq xs M11 M21
   414                  | A _ => do_mtype_comp Leq xs M11 M21
   406                  | V x => do_mtype_comp Leq (x :: xs) M11 M21)
   415                  | V x => do_mtype_comp Leq (x :: xs) M11 M21)
   433   | do_notin_mtype_fv Plus [] MAlpha _ = NONE
   442   | do_notin_mtype_fv Plus [] MAlpha _ = NONE
   434   | do_notin_mtype_fv Plus [(x, a)] MAlpha (SOME (asgs, clauses)) =
   443   | do_notin_mtype_fv Plus [(x, a)] MAlpha (SOME (asgs, clauses)) =
   435     SOME asgs |> add_assign_conjunct (x, a) |> Option.map (rpair clauses)
   444     SOME asgs |> add_assign_conjunct (x, a) |> Option.map (rpair clauses)
   436   | do_notin_mtype_fv Plus clause MAlpha (SOME (asgs, clauses)) =
   445   | do_notin_mtype_fv Plus clause MAlpha (SOME (asgs, clauses)) =
   437     SOME (asgs, insert (op =) clause clauses)
   446     SOME (asgs, insert (op =) clause clauses)
   438   | do_notin_mtype_fv sn clause (MFun (M1, A aa, M2)) accum =
   447   | do_notin_mtype_fv sn clause (MFun (M1, A a, M2)) accum =
   439     accum |> (if aa <> Gen andalso sn = Plus then
   448     accum |> (if a <> Gen andalso sn = Plus then
   440                 do_notin_mtype_fv Plus clause M1
   449                 do_notin_mtype_fv Plus clause M1
   441               else
   450               else
   442                 I)
   451                 I)
   443           |> (if aa = Gen orelse sn = Plus then
   452           |> (if a = Gen orelse sn = Plus then
   444                 do_notin_mtype_fv Minus clause M1
   453                 do_notin_mtype_fv Minus clause M1
   445               else
   454               else
   446                 I)
   455                 I)
   447           |> do_notin_mtype_fv sn clause M2
   456           |> do_notin_mtype_fv sn clause M2
   448   | do_notin_mtype_fv Plus clause (MFun (M1, V x, M2)) accum =
   457   | do_notin_mtype_fv Plus clause (MFun (M1, V x, M2)) accum =
   450                 NONE => I
   459                 NONE => I
   451               | SOME clause' => do_notin_mtype_fv Plus clause' M1)
   460               | SOME clause' => do_notin_mtype_fv Plus clause' M1)
   452           |> do_notin_mtype_fv Minus clause M1
   461           |> do_notin_mtype_fv Minus clause M1
   453           |> do_notin_mtype_fv Plus clause M2
   462           |> do_notin_mtype_fv Plus clause M2
   454   | do_notin_mtype_fv Minus clause (MFun (M1, V x, M2)) accum =
   463   | do_notin_mtype_fv Minus clause (MFun (M1, V x, M2)) accum =
   455     accum |> (case fold (fn a => add_assign_disjunct (x, a)) [New, Fls, Tru]
   464     accum |> (case fold (fn a => add_assign_disjunct (x, a)) [Fls, Tru]
   456                         (SOME clause) of
   465                         (SOME clause) of
   457                 NONE => I
   466                 NONE => I
   458               | SOME clause' => do_notin_mtype_fv Plus clause' M1)
   467               | SOME clause' => do_notin_mtype_fv Plus clause' M1)
   459           |> do_notin_mtype_fv Minus clause M2
   468           |> do_notin_mtype_fv Minus clause M2
   460   | do_notin_mtype_fv sn clause (MPair (M1, M2)) accum =
   469   | do_notin_mtype_fv sn clause (MPair (M1, M2)) accum =
   472    | SOME (asgs, clauses) => (asgs, comps, clauses))
   481    | SOME (asgs, clauses) => (asgs, comps, clauses))
   473 
   482 
   474 val add_mtype_is_concrete = add_notin_mtype_fv Minus
   483 val add_mtype_is_concrete = add_notin_mtype_fv Minus
   475 val add_mtype_is_complete = add_notin_mtype_fv Plus
   484 val add_mtype_is_complete = add_notin_mtype_fv Plus
   476 
   485 
   477 fun fst_var n = 2 * n
       
   478 fun snd_var n = 2 * n + 1
       
   479 
       
   480 val bool_table =
   486 val bool_table =
   481   [(Gen, (false, false)),
   487   [(Gen, (false, false)),
   482    (New, (false, true)),
   488    (New, (false, true)),
   483    (Fls, (true, false)),
   489    (Fls, (true, false)),
   484    (Tru, (true, true))]
   490    (Tru, (true, true))]
       
   491 
       
   492 fun fst_var n = 2 * n
       
   493 fun snd_var n = 2 * n + 1
   485 
   494 
   486 val bools_from_annotation = AList.lookup (op =) bool_table #> the
   495 val bools_from_annotation = AList.lookup (op =) bool_table #> the
   487 val annotation_from_bools = AList.find (op =) bool_table #> the_single
   496 val annotation_from_bools = AList.find (op =) bool_table #> the_single
   488 
   497 
   489 fun prop_for_bool b = if b then PL.True else PL.False
   498 fun prop_for_bool b = if b then PL.True else PL.False
   512     PL.SOr (prop_for_atom_equality (aa1, aa2), prop_for_atom_assign (aa2, Gen))
   521     PL.SOr (prop_for_atom_equality (aa1, aa2), prop_for_atom_assign (aa2, Gen))
   513   | prop_for_comp (aa1, aa2, cmp, xs) =
   522   | prop_for_comp (aa1, aa2, cmp, xs) =
   514     PL.SOr (prop_for_exists_var_assign xs Gen,
   523     PL.SOr (prop_for_exists_var_assign xs Gen,
   515             prop_for_comp (aa1, aa2, cmp, []))
   524             prop_for_comp (aa1, aa2, cmp, []))
   516 
   525 
   517 fun fix_bool_options (NONE, NONE) = (false, false)
   526 (* The "calculus" parameter may be 1, 2, or 3, corresponding approximately to
   518   | fix_bool_options (NONE, SOME b) = (b, b)
   527    the M1, M2, and M3 calculi from Blanchette & Krauss 2011. *)
   519   | fix_bool_options (SOME b, NONE) = (b, b)
   528 fun variable_domain calculus =
   520   | fix_bool_options (SOME b1, SOME b2) = (b1, b2)
   529   [Gen] @ (if calculus > 1 then [Fls] else [])
       
   530   @ (if calculus > 2 then [New, Tru] else [])
       
   531 
       
   532 fun prop_for_variable_domain calculus x =
       
   533   PL.exists (map (curry prop_for_assign x) (variable_domain calculus))
   521 
   534 
   522 fun extract_assigns max_var assigns asgs =
   535 fun extract_assigns max_var assigns asgs =
   523   fold (fn x => fn accum =>
   536   fold (fn x => fn accum =>
   524            if AList.defined (op =) asgs x then
   537            if AList.defined (op =) asgs x then
   525              accum
   538              accum
   526            else case (fst_var x, snd_var x) |> pairself assigns of
   539            else case (fst_var x, snd_var x) |> pairself assigns of
   527              (NONE, NONE) => accum
   540              (NONE, NONE) => accum
   528            | bp => (x, annotation_from_bools (fix_bool_options bp)) :: accum)
   541            | bp => (x, annotation_from_bools (pairself (the_default false) bp))
       
   542                    :: accum)
   529        (max_var downto 1) asgs
   543        (max_var downto 1) asgs
   530 
   544 
   531 fun print_problem asgs comps clauses =
   545 fun print_problem asgs comps clauses =
   532   trace_msg (fn () => "*** Problem:\n" ^
   546   trace_msg (fn () => "*** Problem:\n" ^
   533                       cat_lines (map string_for_assign asgs @
   547                       cat_lines (map string_for_assign asgs @
   541        |> AList.group (op =)
   555        |> AList.group (op =)
   542        |> map (fn (a, xs) => string_for_annotation a ^ ": " ^
   556        |> map (fn (a, xs) => string_for_annotation a ^ ": " ^
   543                              string_for_vars ", " xs)
   557                              string_for_vars ", " xs)
   544        |> space_implode "\n"))
   558        |> space_implode "\n"))
   545 
   559 
   546 fun solve max_var (asgs, comps, clauses) =
   560 fun solve calculus max_var (asgs, comps, clauses) =
   547   let
   561   let
   548     fun do_assigns assigns =
   562     fun do_assigns assigns =
   549       SOME (extract_assigns max_var assigns asgs |> tap print_solution)
   563       SOME (extract_assigns max_var assigns asgs |> tap print_solution)
   550     val _ = print_problem asgs comps clauses
   564     val _ = print_problem asgs comps clauses
   551     val prop = PL.all (map prop_for_assign asgs @
   565     val prop =
   552                        map prop_for_comp comps @
   566       map prop_for_assign asgs @
   553                        map prop_for_assign_clause clauses)
   567       map prop_for_comp comps @
       
   568       map prop_for_assign_clause clauses @
       
   569       (if calculus < 3 then
       
   570          map (prop_for_variable_domain calculus) (1 upto max_var)
       
   571        else
       
   572          [])
       
   573       |> PL.all
   554   in
   574   in
   555     if PL.eval (K false) prop then
   575     if PL.eval (K false) prop then
   556       do_assigns (K (SOME false))
   576       do_assigns (K (SOME false))
   557     else if PL.eval (K true) prop then
   577     else if PL.eval (K true) prop then
   558       do_assigns (K (SOME true))
   578       do_assigns (K (SOME true))
   579 type accumulator = mtype_context * constraint_set
   599 type accumulator = mtype_context * constraint_set
   580 
   600 
   581 val initial_gamma =
   601 val initial_gamma =
   582   {bound_Ts = [], bound_Ms = [], bound_frame = [], frees = [], consts = []}
   602   {bound_Ts = [], bound_Ms = [], bound_frame = [], frees = [], consts = []}
   583 
   603 
   584 fun push_bound T M {bound_Ts, bound_Ms, bound_frame, frees, consts} =
   604 fun push_bound aa T M {bound_Ts, bound_Ms, bound_frame, frees, consts} =
   585   {bound_Ts = T :: bound_Ts, bound_Ms = M :: bound_Ms,
   605   {bound_Ts = T :: bound_Ts, bound_Ms = M :: bound_Ms,
   586    bound_frame = bound_frame, frees = frees, consts = consts}
   606    bound_frame = (length bound_Ts, aa) :: bound_frame, frees = frees,
       
   607    consts = consts}
   587 fun pop_bound {bound_Ts, bound_Ms, bound_frame, frees, consts} =
   608 fun pop_bound {bound_Ts, bound_Ms, bound_frame, frees, consts} =
   588   {bound_Ts = tl bound_Ts, bound_Ms = tl bound_Ms, bound_frame = bound_frame,
   609   {bound_Ts = tl bound_Ts, bound_Ms = tl bound_Ms,
       
   610    bound_frame = bound_frame
       
   611                  |> filter_out (fn (depth, _) => depth = length bound_Ts - 1),
   589    frees = frees, consts = consts}
   612    frees = frees, consts = consts}
   590   handle List.Empty => initial_gamma (* FIXME: needed? *)
   613   handle List.Empty => initial_gamma (* FIXME: needed? *)
   591 
   614 
   592 fun consider_term (mdata as {hol_ctxt = {thy, ctxt, stds, ...}, alpha_T,
   615 fun consider_term (mdata as {hol_ctxt = {thy, ctxt, stds, ...}, alpha_T,
   593                              max_fresh, ...}) =
   616                              max_fresh, ...}) =
   646         pair (MFun (M, A Gen, if n = 0 then a_M else b_M))
   669         pair (MFun (M, A Gen, if n = 0 then a_M else b_M))
   647       | M => raise MTYPE ("Nitpick_Mono.consider_term.do_nth_pair_sel", [M], [])
   670       | M => raise MTYPE ("Nitpick_Mono.consider_term.do_nth_pair_sel", [M], [])
   648     fun do_bounded_quantifier t0 abs_s abs_T connective_t bound_t body_t accum =
   671     fun do_bounded_quantifier t0 abs_s abs_T connective_t bound_t body_t accum =
   649       let
   672       let
   650         val abs_M = mtype_for abs_T
   673         val abs_M = mtype_for abs_T
       
   674         val aa = V (Unsynchronized.inc max_fresh)
   651         val (bound_m, accum) =
   675         val (bound_m, accum) =
   652           accum |>> push_bound abs_T abs_M |> do_term bound_t
   676           accum |>> push_bound aa abs_T abs_M |> do_term bound_t
   653         val expected_bound_M = plus_set_mtype_for_dom abs_M
   677         val expected_bound_M = plus_set_mtype_for_dom abs_M
   654         val (body_m, accum) =
   678         val (body_m, accum) =
   655           accum ||> add_mtypes_equal expected_bound_M (mtype_of_mterm bound_m)
   679           accum ||> add_mtypes_equal expected_bound_M (mtype_of_mterm bound_m)
   656                 |> do_term body_t ||> apfst pop_bound
   680                 |> do_term body_t ||> apfst pop_bound
   657         val bound_M = mtype_of_mterm bound_m
   681         val bound_M = mtype_of_mterm bound_m
   658         val (M1, aa, _) = dest_MFun bound_M
   682         val (M1, aa', _) = dest_MFun bound_M
   659       in
   683       in
   660         (MApp (MRaw (t0, MFun (bound_M, A Gen, bool_M)),
   684         (MApp (MRaw (t0, MFun (bound_M, aa, bool_M)),
   661                MAbs (abs_s, abs_T, M1, aa,
   685                MAbs (abs_s, abs_T, M1, aa',
   662                      MApp (MApp (MRaw (connective_t,
   686                      MApp (MApp (MRaw (connective_t,
   663                                        mtype_for (fastype_of connective_t)),
   687                                        mtype_for (fastype_of connective_t)),
   664                                  MApp (bound_m, MRaw (Bound 0, M1))),
   688                                  MApp (bound_m, MRaw (Bound 0, M1))),
   665                            body_m))), accum)
   689                            body_m))), accum)
   666       end
   690       end
   667     and do_term t (accum as ({bound_Ts, bound_Ms, bound_frame, frees, consts},
   691     and do_term t (accum as ({bound_Ts, bound_Ms, bound_frame, frees, consts},
   668                              cset)) =
   692                              cset)) =
   669         (trace_msg (fn () => "  \<Gamma> \<turnstile> " ^
   693       (trace_msg (fn () => "  \<Gamma> \<turnstile> " ^
   670                              Syntax.string_of_term ctxt t ^ " : _?");
   694                            Syntax.string_of_term ctxt t ^ " : _?");
   671          case t of
   695        case t of
   672            Const (x as (s, T)) =>
   696          Const (x as (s, T)) =>
   673            (case AList.lookup (op =) consts x of
   697          (case AList.lookup (op =) consts x of
   674               SOME M => (M, accum)
   698             SOME M => (M, accum)
   675             | NONE =>
   699           | NONE =>
       
   700             case s of
       
   701               @{const_name False} =>
       
   702               (bool_M, accum ||> fold (add_annotation_atom_comp Leq [] (A Fls))
       
   703                                       (map snd bound_frame))
       
   704             | @{const_name True} =>
       
   705               (bool_M, accum ||> fold (add_annotation_atom_comp Leq [] (A Tru))
       
   706                                       (map snd bound_frame))
       
   707             | _ =>
   676               if not (could_exist_alpha_subtype alpha_T T) then
   708               if not (could_exist_alpha_subtype alpha_T T) then
   677                 (mtype_for T, accum)
   709                 (mtype_for T, accum)
   678               else case s of
   710               else case s of
   679                 @{const_name all} => do_all T accum
   711                 @{const_name all} => do_all T accum
   680               | @{const_name "=="} => do_equals T accum
   712               | @{const_name "=="} => do_equals T accum
   740                   val x = Unsynchronized.inc max_fresh
   772                   val x = Unsynchronized.inc max_fresh
   741                   fun mtype_for_set T =
   773                   fun mtype_for_set T =
   742                     MFun (mtype_for (domain_type T), V x, bool_M)
   774                     MFun (mtype_for (domain_type T), V x, bool_M)
   743                   val a_set_T = domain_type T
   775                   val a_set_T = domain_type T
   744                   val a_M = mtype_for (domain_type a_set_T)
   776                   val a_M = mtype_for (domain_type a_set_T)
   745                   val b_set_M = mtype_for_set (range_type (domain_type
   777                   val b_set_M =
   746                                                                (range_type T)))
   778                     mtype_for_set (range_type (domain_type (range_type T)))
   747                   val a_set_M = mtype_for_set a_set_T
   779                   val a_set_M = mtype_for_set a_set_T
   748                   val a_to_b_set_M = MFun (a_M, A Gen, b_set_M)
   780                   val a_to_b_set_M = MFun (a_M, A Gen, b_set_M)
   749                   val ab_set_M = mtype_for_set (nth_range_type 2 T)
   781                   val ab_set_M = mtype_for_set (nth_range_type 2 T)
   750                 in
   782                 in
   751                   (MFun (a_set_M, A Gen, MFun (a_to_b_set_M, A Gen, ab_set_M)),
   783                   (MFun (a_set_M, A Gen, MFun (a_to_b_set_M, A Gen, ab_set_M)),
   786          | Abs (s, T, t') =>
   818          | Abs (s, T, t') =>
   787            (case fin_fun_body T (fastype_of1 (T :: bound_Ts, t')) t' of
   819            (case fin_fun_body T (fastype_of1 (T :: bound_Ts, t')) t' of
   788               SOME t' =>
   820               SOME t' =>
   789               let
   821               let
   790                 val M = mtype_for T
   822                 val M = mtype_for T
   791                 val aa = V (Unsynchronized.inc max_fresh)
   823                 val (m', accum) = do_term t' (accum |>> push_bound (A Fls) T M)
   792                 val (m', accum) = do_term t' (accum |>> push_bound T M)
   824               in (MAbs (s, T, M, A Fls, m'), accum |>> pop_bound) end
   793               in (MAbs (s, T, M, aa, m'), accum |>> pop_bound) end
       
   794             | NONE =>
   825             | NONE =>
   795               ((case t' of
   826               ((case t' of
   796                   t1' $ Bound 0 =>
   827                   t1' $ Bound 0 =>
   797                   if not (loose_bvar1 (t1', 0)) andalso
   828                   if not (loose_bvar1 (t1', 0)) andalso
   798                      is_enough_eta_expanded t1' then
   829                      is_enough_eta_expanded t1' then
   806                     raise SAME ()
   837                     raise SAME ()
   807                 | _ => raise SAME ())
   838                 | _ => raise SAME ())
   808                handle SAME () =>
   839                handle SAME () =>
   809                       let
   840                       let
   810                         val M = mtype_for T
   841                         val M = mtype_for T
   811                         val (m', accum) = do_term t' (accum |>> push_bound T M)
   842                         val aa = V (Unsynchronized.inc max_fresh)
   812                       in (MAbs (s, T, M, A Gen, m'), accum |>> pop_bound) end))
   843                         val (m', accum) =
       
   844                           do_term t' (accum |>> push_bound aa T M)
       
   845                       in (MAbs (s, T, M, aa, m'), accum |>> pop_bound) end))
   813          | (t0 as Const (@{const_name All}, _))
   846          | (t0 as Const (@{const_name All}, _))
   814            $ Abs (s', T', (t10 as @{const HOL.implies}) $ (t11 $ Bound 0) $ t12) =>
   847            $ Abs (s', T', (t10 as @{const HOL.implies})
       
   848                           $ (t11 $ Bound 0) $ t12) =>
   815            do_bounded_quantifier t0 s' T' t10 t11 t12 accum
   849            do_bounded_quantifier t0 s' T' t10 t11 t12 accum
   816          | (t0 as Const (@{const_name Ex}, _))
   850          | (t0 as Const (@{const_name Ex}, _))
   817            $ Abs (s', T', (t10 as @{const HOL.conj}) $ (t11 $ Bound 0) $ t12) =>
   851            $ Abs (s', T', (t10 as @{const HOL.conj})
       
   852                           $ (t11 $ Bound 0) $ t12) =>
   818            do_bounded_quantifier t0 s' T' t10 t11 t12 accum
   853            do_bounded_quantifier t0 s' T' t10 t11 t12 accum
   819          | Const (@{const_name Let}, _) $ t1 $ t2 =>
   854          | Const (@{const_name Let}, _) $ t1 $ t2 =>
   820            do_term (betapply (t2, t1)) accum
   855            do_term (betapply (t2, t1)) accum
   821          | t1 $ t2 =>
   856          | t1 $ t2 =>
   822            let
   857            let
   863     fun do_formula sn t accum =
   898     fun do_formula sn t accum =
   864         let
   899         let
   865           fun do_quantifier (quant_x as (quant_s, _)) abs_s abs_T body_t =
   900           fun do_quantifier (quant_x as (quant_s, _)) abs_s abs_T body_t =
   866             let
   901             let
   867               val abs_M = mtype_for abs_T
   902               val abs_M = mtype_for abs_T
       
   903               val a = Gen (* FIXME: strengthen *)
   868               val side_cond = ((sn = Minus) = (quant_s = @{const_name Ex}))
   904               val side_cond = ((sn = Minus) = (quant_s = @{const_name Ex}))
   869               val (body_m, accum) =
   905               val (body_m, accum) =
   870                 accum ||> side_cond ? add_mtype_is_complete abs_M
   906                 accum ||> side_cond ? add_mtype_is_complete abs_M
   871                       |>> push_bound abs_T abs_M |> do_formula sn body_t
   907                       |>> push_bound (A a) abs_T abs_M |> do_formula sn body_t
   872               val body_M = mtype_of_mterm body_m
   908               val body_M = mtype_of_mterm body_m
   873             in
   909             in
   874               (MApp (MRaw (Const quant_x,
   910               (MApp (MRaw (Const quant_x,
   875                            MFun (MFun (abs_M, A Gen, body_M), A Gen, body_M)),
   911                            MFun (MFun (abs_M, A Gen, body_M), A Gen, body_M)),
   876                      MAbs (abs_s, abs_T, abs_M, A Gen, body_m)),
   912                      MAbs (abs_s, abs_T, abs_M, A Gen, body_m)),
   967       val do_term = consider_term mdata
  1003       val do_term = consider_term mdata
   968       fun do_all quant_t abs_s abs_T body_t accum =
  1004       fun do_all quant_t abs_s abs_T body_t accum =
   969         let
  1005         let
   970           val abs_M = mtype_for abs_T
  1006           val abs_M = mtype_for abs_T
   971           val (body_m, accum) =
  1007           val (body_m, accum) =
   972             accum |>> push_bound abs_T abs_M |> do_formula body_t
  1008             accum |>> push_bound (A Gen) abs_T abs_M |> do_formula body_t
   973           val body_M = mtype_of_mterm body_m
  1009           val body_M = mtype_of_mterm body_m
   974         in
  1010         in
   975           (MApp (MRaw (quant_t, MFun (MFun (abs_M, A Gen, body_M), A Gen,
  1011           (MApp (MRaw (quant_t, MFun (MFun (abs_M, A Gen, body_M), A Gen,
   976                        body_M)),
  1012                        body_M)),
   977                  MAbs (abs_s, abs_T, abs_M, A Gen, body_m)),
  1013                  MAbs (abs_s, abs_T, abs_M, A Gen, body_m)),
  1025       |> cat_lines)
  1061       |> cat_lines)
  1026 
  1062 
  1027 fun amass f t (ms, accum) =
  1063 fun amass f t (ms, accum) =
  1028   let val (m, accum) = f t accum in (m :: ms, accum) end
  1064   let val (m, accum) = f t accum in (m :: ms, accum) end
  1029 
  1065 
  1030 fun infer which no_harmless (hol_ctxt as {ctxt, ...}) binarize alpha_T
  1066 fun infer which no_harmless (hol_ctxt as {ctxt, ...}) binarize calculus alpha_T
  1031           (nondef_ts, def_ts) =
  1067           (nondef_ts, def_ts) =
  1032   let
  1068   let
  1033     val _ = trace_msg (fn () => "****** " ^ which ^ " analysis: " ^
  1069     val _ = trace_msg (fn () => "****** " ^ which ^ " analysis: " ^
  1034                                 string_for_mtype MAlpha ^ " is " ^
  1070                                 string_for_mtype MAlpha ^ " is " ^
  1035                                 Syntax.string_of_typ ctxt alpha_T)
  1071                                 Syntax.string_of_typ ctxt alpha_T)
  1041                   |> fold (amass (consider_nondefinitional_axiom mdata))
  1077                   |> fold (amass (consider_nondefinitional_axiom mdata))
  1042                           (tl nondef_ts)
  1078                           (tl nondef_ts)
  1043     val (def_ms, (gamma, cset)) =
  1079     val (def_ms, (gamma, cset)) =
  1044       ([], accum) |> fold (amass (consider_definitional_axiom mdata)) def_ts
  1080       ([], accum) |> fold (amass (consider_definitional_axiom mdata)) def_ts
  1045   in
  1081   in
  1046     case solve (!max_fresh) cset of
  1082     case solve calculus (!max_fresh) cset of
  1047       SOME asgs => (print_mtype_context ctxt asgs gamma;
  1083       SOME asgs => (print_mtype_context ctxt asgs gamma;
  1048                     SOME (asgs, (nondef_ms, def_ms), !constr_mcache))
  1084                     SOME (asgs, (nondef_ms, def_ms), !constr_mcache))
  1049     | _ => NONE
  1085     | _ => NONE
  1050   end
  1086   end
  1051   handle UNSOLVABLE () => NONE
  1087   handle UNSOLVABLE () => NONE
  1053          raise BAD (loc, commas (map string_for_mtype Ms @
  1089          raise BAD (loc, commas (map string_for_mtype Ms @
  1054                                  map (Syntax.string_of_typ ctxt) Ts))
  1090                                  map (Syntax.string_of_typ ctxt) Ts))
  1055        | MTERM (loc, ms) =>
  1091        | MTERM (loc, ms) =>
  1056          raise BAD (loc, commas (map (string_for_mterm ctxt) ms))
  1092          raise BAD (loc, commas (map (string_for_mterm ctxt) ms))
  1057 
  1093 
  1058 val formulas_monotonic = is_some oooo infer "Monotonicity" false
  1094 fun formulas_monotonic hol_ctxt =
       
  1095   is_some oooo infer "Monotonicity" false hol_ctxt
  1059 
  1096 
  1060 fun fin_fun_constr T1 T2 =
  1097 fun fin_fun_constr T1 T2 =
  1061   (@{const_name FinFun}, (T1 --> T2) --> Type (@{type_name fin_fun}, [T1, T2]))
  1098   (@{const_name FinFun}, (T1 --> T2) --> Type (@{type_name fin_fun}, [T1, T2]))
  1062 
  1099 
  1063 fun finitize_funs (hol_ctxt as {thy, ctxt, stds, constr_cache, ...})
  1100 fun finitize_funs (hol_ctxt as {thy, ctxt, stds, constr_cache, ...}) binarize
  1064                   binarize finitizes alpha_T tsp =
  1101                   finitizes calculus alpha_T tsp =
  1065   case infer "Finiteness" true hol_ctxt binarize alpha_T tsp of
  1102   case infer "Finiteness" true hol_ctxt binarize calculus alpha_T tsp of
  1066     SOME (asgs, msp, constr_mtypes) =>
  1103     SOME (asgs, msp, constr_mtypes) =>
  1067     if forall (curry (op =) Gen o snd) asgs then
  1104     if forall (curry (op =) Gen o snd) asgs then
  1068       tsp
  1105       tsp
  1069     else
  1106     else
  1070       let
  1107       let