src/HOL/Tools/Sledgehammer/sledgehammer_atp_translate.ML
changeset 42534 46e690db16b8
parent 42533 dc81fe6b7a87
child 42538 9e3e45636459
equal deleted inserted replaced
42533:dc81fe6b7a87 42534:46e690db16b8
    53 val is_base = "is"
    53 val is_base = "is"
    54 val type_prefix = "ty_"
    54 val type_prefix = "ty_"
    55 
    55 
    56 fun make_type ty = type_prefix ^ ascii_of ty
    56 fun make_type ty = type_prefix ^ ascii_of ty
    57 
    57 
       
    58 (* official TPTP TFF syntax *)
       
    59 val tff_bool_type = "$o"
       
    60 
    58 (* Freshness almost guaranteed! *)
    61 (* Freshness almost guaranteed! *)
    59 val sledgehammer_weak_prefix = "Sledgehammer:"
    62 val sledgehammer_weak_prefix = "Sledgehammer:"
    60 
    63 
    61 type translated_formula =
    64 type translated_formula =
    62   {name: string,
    65   {name: string,
   115        |> filter (fn TyLitVar _ => kind <> Conjecture
   118        |> filter (fn TyLitVar _ => kind <> Conjecture
   116                    | TyLitFree _ => kind = Conjecture)
   119                    | TyLitFree _ => kind = Conjecture)
   117 
   120 
   118 fun mk_anot phi = AConn (ANot, [phi])
   121 fun mk_anot phi = AConn (ANot, [phi])
   119 fun mk_aconn c phi1 phi2 = AConn (c, [phi1, phi2])
   122 fun mk_aconn c phi1 phi2 = AConn (c, [phi1, phi2])
       
   123 fun mk_aconns c phis =
       
   124   let val (phis', phi') = split_last phis in
       
   125     fold_rev (mk_aconn c) phis' phi'
       
   126   end
   120 fun mk_ahorn [] phi = phi
   127 fun mk_ahorn [] phi = phi
   121   | mk_ahorn (phi :: phis) psi =
   128   | mk_ahorn phis psi = AConn (AImplies, [mk_aconns AAnd phis, psi])
   122     AConn (AImplies, [fold (mk_aconn AAnd) phis phi, psi])
       
   123 fun mk_aquant _ [] phi = phi
   129 fun mk_aquant _ [] phi = phi
   124   | mk_aquant q xs (phi as AQuant (q', xs', phi')) =
   130   | mk_aquant q xs (phi as AQuant (q', xs', phi')) =
   125     if q = q' then AQuant (q, xs @ xs', phi') else AQuant (q, xs, phi)
   131     if q = q' then AQuant (q, xs @ xs', phi') else AQuant (q, xs, phi)
   126   | mk_aquant q xs phi = AQuant (q, xs, phi)
   132   | mk_aquant q xs phi = AQuant (q, xs, phi)
   127 
   133 
   438 
   444 
   439 fun mangled_type_suffix f g tys =
   445 fun mangled_type_suffix f g tys =
   440   fold_rev (curry (op ^) o g o prefix mangled_type_sep
   446   fold_rev (curry (op ^) o g o prefix mangled_type_sep
   441             o mangled_combtyp_component f) tys ""
   447             o mangled_combtyp_component f) tys ""
   442 
   448 
   443 fun mangled_const (s, s') ty_args =
   449 fun mangled_const_fst ty_args s = s ^ mangled_type_suffix fst ascii_of ty_args
   444   (s ^ mangled_type_suffix fst ascii_of ty_args,
   450 fun mangled_const_snd ty_args s' = s' ^ mangled_type_suffix snd I ty_args
   445    s' ^ mangled_type_suffix snd I ty_args)
   451 fun mangled_const ty_args (s, s') =
       
   452   (mangled_const_fst ty_args s, mangled_const_snd ty_args s')
   446 
   453 
   447 val parse_mangled_ident =
   454 val parse_mangled_ident =
   448   Scan.many1 (not o member (op =) ["(", ")", ","]) >> implode
   455   Scan.many1 (not o member (op =) ["(", ")", ","]) >> implode
   449 
   456 
   450 fun parse_mangled_type x =
   457 fun parse_mangled_type x =
   468 
   475 
   469 fun pred_combtyp ty =
   476 fun pred_combtyp ty =
   470   case combtyp_from_typ @{typ "unit => bool"} of
   477   case combtyp_from_typ @{typ "unit => bool"} of
   471     CombType (name, [_, bool_ty]) => CombType (name, [ty, bool_ty])
   478     CombType (name, [_, bool_ty]) => CombType (name, [ty, bool_ty])
   472   | _ => raise Fail "expected two-argument type constructor"
   479   | _ => raise Fail "expected two-argument type constructor"
       
   480 
       
   481 fun has_type_combatom ty tm =
       
   482   CombApp (CombConst ((const_prefix ^ is_base, is_base), pred_combtyp ty, [ty]),
       
   483            tm)
       
   484   |> AAtom
   473 
   485 
   474 fun formula_for_combformula ctxt type_sys =
   486 fun formula_for_combformula ctxt type_sys =
   475   let
   487   let
   476     fun do_term top_level u =
   488     fun do_term top_level u =
   477       let
   489       let
   494                | SOME s'' =>
   506                | SOME s'' =>
   495                  let val s'' = invert_const s'' in
   507                  let val s'' = invert_const s'' in
   496                    case type_arg_policy type_sys s'' of
   508                    case type_arg_policy type_sys s'' of
   497                      No_Type_Args => (name, [])
   509                      No_Type_Args => (name, [])
   498                    | Explicit_Type_Args => (name, ty_args)
   510                    | Explicit_Type_Args => (name, ty_args)
   499                    | Mangled_Types => (mangled_const name ty_args, [])
   511                    | Mangled_Types => (mangled_const ty_args name, [])
   500                  end)
   512                  end)
   501           | CombVar (name, _) => (name, [])
   513           | CombVar (name, _) => (name, [])
   502           | CombApp _ => raise Fail "impossible \"CombApp\""
   514           | CombApp _ => raise Fail "impossible \"CombApp\""
   503         val t = ATerm (x, map fo_term_for_combtyp ty_args @
   515         val t = ATerm (x, map fo_term_for_combtyp ty_args @
   504                           map (do_term false) args)
   516                           map (do_term false) args)
   512     val do_bound_type =
   524     val do_bound_type =
   513       if type_sys = Many_Typed then SOME o mangled_combtyp else K NONE
   525       if type_sys = Many_Typed then SOME o mangled_combtyp else K NONE
   514     val do_out_of_bound_type =
   526     val do_out_of_bound_type =
   515       if member (op =) [Args true, Mangled true] type_sys then
   527       if member (op =) [Args true, Mangled true] type_sys then
   516         (fn (s, ty) =>
   528         (fn (s, ty) =>
   517             CombApp (CombConst ((const_prefix ^ is_base, is_base),
   529             has_type_combatom ty (CombVar (s, ty))
   518                                 pred_combtyp ty, [ty]),
   530             |> formula_for_combformula ctxt type_sys |> SOME)
   519                      CombVar (s, ty))
       
   520             |> AAtom |> formula_for_combformula ctxt type_sys |> SOME)
       
   521       else
   531       else
   522         K NONE
   532         K NONE
   523     fun do_formula (AQuant (q, xs, phi)) =
   533     fun do_formula (AQuant (q, xs, phi)) =
   524         AQuant (q, xs |> map (apsnd (fn NONE => NONE
   534         AQuant (q, xs |> map (apsnd (fn NONE => NONE
   525                                       | SOME ty => do_bound_type ty)),
   535                                       | SOME ty => do_bound_type ty)),
   526                 (if q = AForall then mk_ahorn else fold (mk_aconn AAnd))
   536                 (if q = AForall then mk_ahorn else fold_rev (mk_aconn AAnd))
   527                     (map_filter
   537                     (map_filter
   528                          (fn (_, NONE) => NONE
   538                          (fn (_, NONE) => NONE
   529                            | (s, SOME ty) => do_out_of_bound_type (s, ty)) xs)
   539                            | (s, SOME ty) => do_out_of_bound_type (s, ty)) xs)
   530                     (do_formula phi))
   540                     (do_formula phi))
   531       | do_formula (AConn (c, phis)) = AConn (c, map do_formula phis)
   541       | do_formula (AConn (c, phis)) = AConn (c, map do_formula phis)
   708     Formula (ident, kind, repair_formula thy type_sys sym_tab phi, source,
   718     Formula (ident, kind, repair_formula thy type_sys sym_tab phi, source,
   709              useful_info)
   719              useful_info)
   710   | repair_problem_line _ _ _ _ = raise Fail "unexpected non-formula"
   720   | repair_problem_line _ _ _ _ = raise Fail "unexpected non-formula"
   711 fun repair_problem thy = map o apsnd o map oo repair_problem_line thy
   721 fun repair_problem thy = map o apsnd o map oo repair_problem_line thy
   712 
   722 
   713 fun is_const_relevant s =
   723 fun is_const_relevant type_sys sym_tab unmangled_s s =
   714   case strip_prefix_and_unascii const_prefix s of
   724   not (String.isPrefix bound_var_prefix unmangled_s) andalso
   715     SOME @{const_name HOL.eq} => false
   725   unmangled_s <> "equal" andalso
   716   | opt => is_some opt
   726   (type_sys = Many_Typed orelse not (is_pred_sym sym_tab s))
   717 
   727 
   718 fun consider_combterm_consts sym_tab (*FIXME: use*) tm =
   728 fun consider_combterm_consts type_sys sym_tab tm =
   719   let val (head, args) = strip_combterm_comb tm in
   729   let val (head, args) = strip_combterm_comb tm in
   720     (case head of
   730     (case head of
   721        CombConst ((s, s'), ty, ty_args) =>
   731        CombConst ((s, s'), ty, ty_args) =>
   722        (* FIXME: exploit type subsumption *)
   732        (* FIXME: exploit type subsumption *)
   723        is_const_relevant s ? Symtab.insert_list (op =) (s, (s', ty_args, ty))
   733        is_const_relevant type_sys sym_tab s
       
   734                          (s |> member (op =) [Many_Typed, Mangled true] type_sys
       
   735                                ? mangled_const_fst ty_args)
       
   736        ? Symtab.insert_list (op =) (s, (s', ty_args, ty))
   724      | _ => I) (* FIXME: hAPP on var *)
   737      | _ => I) (* FIXME: hAPP on var *)
   725     #> fold (consider_combterm_consts sym_tab) args
   738     #> fold (consider_combterm_consts type_sys sym_tab) args
   726   end
   739   end
   727 
   740 
   728 fun consider_fact_consts sym_tab ({combformula, ...} : translated_formula) =
   741 fun consider_fact_consts type_sys sym_tab
   729   fold_formula (consider_combterm_consts sym_tab) combformula
   742                          ({combformula, ...} : translated_formula) =
       
   743   fold_formula (consider_combterm_consts type_sys sym_tab) combformula
   730 
   744 
   731 fun const_table_for_facts type_sys sym_tab facts =
   745 fun const_table_for_facts type_sys sym_tab facts =
   732   Symtab.empty |> member (op =) [Many_Typed, Args true, Mangled true] type_sys
   746   Symtab.empty |> member (op =) [Many_Typed, Args true, Mangled true] type_sys
   733                   ? fold (consider_fact_consts sym_tab) facts
   747                   ? fold (consider_fact_consts type_sys sym_tab) facts
   734 
   748 
   735 fun fo_type_from_combtyp (ty as CombType ((s, _), tys)) =
   749 fun strip_and_map_combtyp f (ty as CombType ((s, _), tys)) =
   736     (case (strip_prefix_and_unascii type_const_prefix s, tys) of
   750     (case (strip_prefix_and_unascii type_const_prefix s, tys) of
   737        (SOME @{type_name fun}, [dom_ty, ran_ty]) =>
   751        (SOME @{type_name fun}, [dom_ty, ran_ty]) =>
   738        fo_type_from_combtyp ran_ty |>> cons (mangled_combtyp dom_ty)
   752        strip_and_map_combtyp f ran_ty |>> cons (f dom_ty)
   739      | _ => ([], mangled_combtyp ty))
   753      | _ => ([], f ty))
   740   | fo_type_from_combtyp ty = ([], mangled_combtyp ty)
   754   | strip_and_map_combtyp f ty = ([], f ty)
   741 
   755 
   742 fun type_decl_line_for_const_entry Many_Typed s (s', ty_args, ty) =
   756 fun type_decl_line_for_const_entry ctxt type_sys sym_tab s (s', ty_args, ty) =
       
   757   if type_sys = Many_Typed then
   743     let
   758     let
   744       val (s, s') = mangled_const (s, s') ty_args
   759       val (arg_tys, res_ty) = strip_and_map_combtyp mangled_combtyp ty
   745       val (arg_tys, res_ty) = fo_type_from_combtyp ty
   760       val (s, s') = (s, s') |> mangled_const ty_args
   746     in Type_Decl (type_decl_prefix ^ ascii_of s, (s, s'), arg_tys, res_ty) end
   761     in
   747   | type_decl_line_for_const_entry _ _ _ = raise Fail "not implemented yet"
   762       Type_Decl (type_decl_prefix ^ ascii_of s, (s, s'), arg_tys,
   748 fun type_decl_lines_for_const type_sys (s, xs) =
   763                  if is_pred_sym sym_tab s then `I tff_bool_type else res_ty)
   749   map (type_decl_line_for_const_entry type_sys s) xs
   764     end
       
   765   else
       
   766     let
       
   767       val (arg_tys, res_ty) = strip_and_map_combtyp I ty
       
   768       val bounds =
       
   769         map (`I o make_bound_var o string_of_int) (1 upto length arg_tys)
       
   770         ~~ map SOME arg_tys
       
   771       val bound_tms =
       
   772         map (fn (name, ty) => CombConst (name, the ty, [])) bounds
       
   773     in
       
   774       Formula (type_decl_prefix ^ ascii_of s, Axiom,
       
   775                mk_aquant AForall bounds
       
   776                          (has_type_combatom res_ty
       
   777                               (fold (curry (CombApp o swap)) bound_tms
       
   778                                     (CombConst ((s, s'), ty, ty_args))))
       
   779                |> formula_for_combformula ctxt type_sys,
       
   780                NONE, NONE)
       
   781     end
       
   782 fun type_decl_lines_for_const ctxt type_sys sym_tab (s, xs) =
       
   783   map (type_decl_line_for_const_entry ctxt type_sys sym_tab s) xs
   750 
   784 
   751 val factsN = "Relevant facts"
   785 val factsN = "Relevant facts"
   752 val class_relsN = "Class relationships"
   786 val class_relsN = "Class relationships"
   753 val aritiesN = "Arity declarations"
   787 val aritiesN = "Arity declarations"
   754 val helpersN = "Helper facts"
   788 val helpersN = "Helper facts"
   784       problem |> maps (map_filter (fn Formula (_, _, phi, _, _) => SOME phi
   818       problem |> maps (map_filter (fn Formula (_, _, phi, _, _) => SOME phi
   785                                     | _ => NONE) o snd)
   819                                     | _ => NONE) o snd)
   786               |> get_helper_facts ctxt type_sys
   820               |> get_helper_facts ctxt type_sys
   787     val const_tab = const_table_for_facts type_sys sym_tab (conjs @ facts)
   821     val const_tab = const_table_for_facts type_sys sym_tab (conjs @ facts)
   788     val type_decl_lines =
   822     val type_decl_lines =
   789       Symtab.fold_rev (append o type_decl_lines_for_const type_sys) const_tab []
   823       Symtab.fold_rev (append o type_decl_lines_for_const ctxt type_sys sym_tab)
       
   824                       const_tab []
   790     val helper_lines =
   825     val helper_lines =
   791       helper_facts
   826       helper_facts
   792       |>> map (pair 0
   827       |>> map (pair 0
   793                #> problem_line_for_fact ctxt helper_prefix type_sys
   828                #> problem_line_for_fact ctxt helper_prefix type_sys
   794                #> repair_problem_line thy type_sys sym_tab)
   829                #> repair_problem_line thy type_sys sym_tab)