src/HOL/TPTP/atp_problem_import.ML
changeset 48436 762eb0dacaa6
parent 48433 a72239723ae8
child 48514 e33c2be488fe
equal deleted inserted replaced
48435:8074b18d8d76 48436:762eb0dacaa6
    15 end;
    15 end;
    16 
    16 
    17 structure ATP_Problem_Import : ATP_PROBLEM_IMPORT =
    17 structure ATP_Problem_Import : ATP_PROBLEM_IMPORT =
    18 struct
    18 struct
    19 
    19 
    20 open ATP_Util
    20 (** TPTP parsing **)
    21 open ATP_Problem
       
    22 open ATP_Proof
       
    23 
    21 
    24 
    22 (* cf. "close_form" in "refute.ML" *)
    25 (** Crude TPTP CNF and FOF parsing **)
    23 fun close_form t =
    26 
    24   fold (fn ((s, i), T) => fn t' =>
    27 exception SYNTAX of string
    25            Logic.all_const T $ Abs (s, T, abstract_over (Var ((s, i), T), t')))
    28 exception THF of unit
    26        (Term.add_vars t []) t
    29 
       
    30 val tptp_explode = raw_explode o strip_spaces_except_between_idents
       
    31 
       
    32 fun parse_file_path (c :: ss) =
       
    33     if c = "'" orelse c = "\"" then
       
    34       ss |> chop_while (curry (op <>) c) |>> implode ||> tl
       
    35     else
       
    36       raise SYNTAX "invalid file path"
       
    37   | parse_file_path [] = raise SYNTAX "invalid file path"
       
    38 
       
    39 fun parse_include x =
       
    40   let
       
    41     val (file_name, rest) =
       
    42       (Scan.this_string "include" |-- $$ "(" |-- parse_file_path --| $$ ")"
       
    43        --| $$ ".") x
       
    44     val path = file_name |> Path.explode
       
    45     val path =
       
    46       path |> not (Path.is_absolute path) ? Path.append (Path.explode "$TPTP")
       
    47   in ((), (path |> File.read |> tptp_explode) @ rest) end
       
    48 
       
    49 val parse_cnf_or_fof =
       
    50   (Scan.this_string "cnf" || Scan.this_string "fof") |-- $$ "(" |--
       
    51   Scan.many (not_equal ",") |-- $$ "," |--
       
    52   (Scan.this_string "axiom" || Scan.this_string "definition"
       
    53    || Scan.this_string "theorem" || Scan.this_string "lemma"
       
    54    || Scan.this_string "hypothesis" || Scan.this_string "conjecture"
       
    55    || Scan.this_string "negated_conjecture") --| $$ "," -- parse_formula
       
    56       --| $$ ")" --| $$ "."
       
    57     >> (fn ("conjecture", phi) => (true, AConn (ANot, [phi]))
       
    58          | (_, phi) => (false, phi))
       
    59   || Scan.this_string "thf" >> (fn _ => raise THF ())
       
    60 
       
    61 val parse_problem =
       
    62   Scan.repeat parse_include
       
    63   |-- Scan.repeat (parse_cnf_or_fof --| Scan.repeat parse_include)
       
    64 
       
    65 val parse_tptp_problem =
       
    66   Scan.finite Symbol.stopper
       
    67       (Scan.error (!! (fn _ => raise SYNTAX "malformed TPTP input")
       
    68                   parse_problem))
       
    69   o tptp_explode
       
    70 
       
    71 val iota_T = @{typ iota}
       
    72 val quant_T = @{typ "(iota => bool) => bool"}
       
    73 
       
    74 fun is_variable s = Char.isUpper (String.sub (s, 0))
       
    75 
       
    76 fun hol_term_from_fo_term res_T (ATerm (x, us)) =
       
    77   let val ts = map (hol_term_from_fo_term iota_T) us in
       
    78     list_comb ((case x of
       
    79                   "$true" => @{const_name True}
       
    80                 | "$false" => @{const_name False}
       
    81                 | "=" => @{const_name HOL.eq}
       
    82                 | "equal" => @{const_name HOL.eq}
       
    83                 | _ => x, map fastype_of ts ---> res_T)
       
    84                |> (if is_variable x then Free else Const), ts)
       
    85   end
       
    86 
       
    87 fun hol_prop_from_formula phi =
       
    88   case phi of
       
    89     AQuant (_, [], phi') => hol_prop_from_formula phi'
       
    90   | AQuant (q, (x, _) :: xs, phi') =>
       
    91     Const (case q of AForall => @{const_name All} | AExists => @{const_name Ex},
       
    92            quant_T)
       
    93     $ lambda (Free (x, iota_T)) (hol_prop_from_formula (AQuant (q, xs, phi')))
       
    94   | AConn (ANot, [u']) => HOLogic.mk_not (hol_prop_from_formula u')
       
    95   | AConn (c, [u1, u2]) =>
       
    96     pairself hol_prop_from_formula (u1, u2)
       
    97     |> (case c of
       
    98           AAnd => HOLogic.mk_conj
       
    99         | AOr => HOLogic.mk_disj
       
   100         | AImplies => HOLogic.mk_imp
       
   101         | AIff => HOLogic.mk_eq
       
   102         | ANot => raise Fail "binary \"ANot\"")
       
   103   | AConn _ => raise Fail "malformed AConn"
       
   104   | AAtom u => hol_term_from_fo_term @{typ bool} u
       
   105 
       
   106 fun mk_all x t = Const (@{const_name All}, quant_T) $ lambda x t
       
   107 
       
   108 fun close_hol_prop t = fold (mk_all o Free) (Term.add_frees t []) t
       
   109 
    27 
   110 fun mk_meta_not P = Logic.mk_implies (P, @{prop False})
    28 fun mk_meta_not P = Logic.mk_implies (P, @{prop False})
   111 
    29 
   112 fun get_tptp_formula (_, role, P, _) =
    30 fun get_tptp_formula (_, role, P, _) =
   113   P |> role = TPTP_Syntax.Role_Conjecture ? mk_meta_not
    31   P |> Logic.varify_global |> close_form
       
    32     |> role = TPTP_Syntax.Role_Conjecture ? mk_meta_not
   114 
    33 
   115 fun read_tptp_file thy file_name =
    34 fun read_tptp_file thy file_name =
   116   let val path = Path.explode file_name in
    35   let
   117     (case parse_tptp_problem (File.read path) of
    36     val path = Path.explode file_name
   118        (_, s :: ss) =>
    37     val problem =
   119        raise SYNTAX ("cannot parse " ^ quote (implode (s :: ss)))
    38       TPTP_Interpret.interpret_file true (Path.explode "$TPTP") path [] [] thy
   120      | (problem, []) =>
    39       |> fst |> #3
   121        (exists fst problem,
    40   in
   122         map (HOLogic.mk_Trueprop o close_hol_prop o hol_prop_from_formula o snd)
    41     (exists (fn (_, role, _, _) => role = TPTP_Syntax.Role_Conjecture) problem,
   123             problem))
    42      map get_tptp_formula problem)
   124     handle THF () =>
       
   125     let
       
   126       val problem =
       
   127         TPTP_Interpret.interpret_file true (Path.explode "$TPTP") path [] [] thy
       
   128         |> fst |> #3
       
   129     in
       
   130       (exists (fn (_, role, _, _) => role = TPTP_Syntax.Role_Conjecture) problem,
       
   131        map get_tptp_formula problem)
       
   132     end
       
   133   end
    43   end
   134 
    44 
   135 (** Isabelle (combination of provers) **)
    45 (** Isabelle (combination of provers) **)
   136 
    46 
   137 fun isabelle_tptp_file file_name = ()
    47 fun isabelle_tptp_file file_name = ()