src/HOL/Tools/res_hol_clause.ML
author paulson
Wed Oct 10 10:50:11 2007 +0200 (2007-10-10)
changeset 24940 8f9dea697b8d
parent 24937 340523598914
child 24943 5f5679e2ec2f
permissions -rw-r--r--
getting rid of type typ_var
     1 (* ID: $Id$
     2    Author: Jia Meng, NICTA
     3 
     4 FOL clauses translated from HOL formulae.
     5 
     6 The combinator code needs to be deleted after the translation paper has been published.
     7 It cannot be used with proof reconstruction because combinators are not introduced by proof.
     8 The Turner combinators (B', C', S') yield no improvement and should be deleted.
     9 *)
    10 
    11 signature RES_HOL_CLAUSE =
    12 sig
    13   val ext: thm
    14   val comb_I: thm
    15   val comb_K: thm
    16   val comb_B: thm
    17   val comb_C: thm
    18   val comb_S: thm
    19   datatype type_level = T_FULL | T_CONST
    20   val typ_level: type_level ref
    21   val minimize_applies: bool ref
    22   type axiom_name = string
    23   type polarity = bool
    24   type clause_id = int
    25   datatype combterm =
    26       CombConst of string * ResClause.fol_type * ResClause.fol_type list (*Const and Free*)
    27     | CombVar of string * ResClause.fol_type
    28     | CombApp of combterm * combterm
    29   datatype literal = Literal of polarity * combterm
    30   val strip_comb: combterm -> combterm * combterm list
    31   val literals_of_term: theory -> term -> literal list * typ list
    32   val tptp_write_file: theory -> bool -> thm list -> string ->
    33     (thm * (axiom_name * clause_id)) list * ResClause.classrelClause list *
    34       ResClause.arityClause list -> string list -> axiom_name list
    35   val dfg_write_file: theory -> bool -> thm list -> string ->
    36     (thm * (axiom_name * clause_id)) list * ResClause.classrelClause list *
    37       ResClause.arityClause list -> string list -> axiom_name list
    38 end
    39 
    40 structure ResHolClause: RES_HOL_CLAUSE =
    41 struct
    42 
    43 structure RC = ResClause;
    44 
    45 (* theorems for combinators and function extensionality *)
    46 val ext = thm "HOL.ext";
    47 val comb_I = thm "ATP_Linkup.COMBI_def";
    48 val comb_K = thm "ATP_Linkup.COMBK_def";
    49 val comb_B = thm "ATP_Linkup.COMBB_def";
    50 val comb_C = thm "ATP_Linkup.COMBC_def";
    51 val comb_S = thm "ATP_Linkup.COMBS_def";
    52 val comb_B' = thm "ATP_Linkup.COMBB'_def";
    53 val comb_C' = thm "ATP_Linkup.COMBC'_def";
    54 val comb_S' = thm "ATP_Linkup.COMBS'_def";
    55 val fequal_imp_equal = thm "ATP_Linkup.fequal_imp_equal";
    56 val equal_imp_fequal = thm "ATP_Linkup.equal_imp_fequal";
    57 
    58 
    59 (*The different translations of types*)
    60 datatype type_level = T_FULL | T_CONST;
    61 
    62 val typ_level = ref T_CONST;
    63 
    64 (*If true, each function will be directly applied to as many arguments as possible, avoiding
    65   use of the "apply" operator. Use of hBOOL is also minimized.*)
    66 val minimize_applies = ref true;
    67 
    68 val const_min_arity = ref (Symtab.empty : int Symtab.table);
    69 
    70 val const_needs_hBOOL = ref (Symtab.empty : bool Symtab.table);
    71 
    72 fun min_arity_of c = getOpt (Symtab.lookup(!const_min_arity) c, 0);
    73 
    74 (*True if the constant ever appears outside of the top-level position in literals.
    75   If false, the constant always receives all of its arguments and is used as a predicate.*)
    76 fun needs_hBOOL c = not (!minimize_applies) orelse
    77                     getOpt (Symtab.lookup(!const_needs_hBOOL) c, false);
    78 
    79 
    80 (******************************************************)
    81 (* data types for typed combinator expressions        *)
    82 (******************************************************)
    83 
    84 type axiom_name = string;
    85 type polarity = bool;
    86 type clause_id = int;
    87 
    88 datatype combterm = CombConst of string * RC.fol_type * RC.fol_type list (*Const and Free*)
    89                   | CombVar of string * RC.fol_type
    90                   | CombApp of combterm * combterm
    91 
    92 datatype literal = Literal of polarity * combterm;
    93 
    94 datatype clause =
    95          Clause of {clause_id: clause_id,
    96                     axiom_name: axiom_name,
    97                     th: thm,
    98                     kind: RC.kind,
    99                     literals: literal list,
   100                     ctypes_sorts: typ list};
   101 
   102 
   103 (*********************************************************************)
   104 (* convert a clause with type Term.term to a clause with type clause *)
   105 (*********************************************************************)
   106 
   107 fun isFalse (Literal(pol, CombConst(c,_,_))) =
   108       (pol andalso c = "c_False") orelse
   109       (not pol andalso c = "c_True")
   110   | isFalse _ = false;
   111 
   112 fun isTrue (Literal (pol, CombConst(c,_,_))) =
   113       (pol andalso c = "c_True") orelse
   114       (not pol andalso c = "c_False")
   115   | isTrue _ = false;
   116 
   117 fun isTaut (Clause {literals,...}) = exists isTrue literals;
   118 
   119 fun type_of (Type (a, Ts)) =
   120       let val (folTypes,ts) = types_of Ts
   121       in  (RC.Comp(RC.make_fixed_type_const a, folTypes), ts)  end
   122   | type_of (tp as (TFree(a,s))) =
   123       (RC.AtomF (RC.make_fixed_type_var a), [tp])
   124   | type_of (tp as (TVar(v,s))) =
   125       (RC.AtomV (RC.make_schematic_type_var v), [tp])
   126 and types_of Ts =
   127       let val (folTyps,ts) = ListPair.unzip (map type_of Ts)
   128       in  (folTyps, RC.union_all ts)  end;
   129 
   130 (* same as above, but no gathering of sort information *)
   131 fun simp_type_of (Type (a, Ts)) =
   132       RC.Comp(RC.make_fixed_type_const a, map simp_type_of Ts)
   133   | simp_type_of (TFree (a,s)) = RC.AtomF(RC.make_fixed_type_var a)
   134   | simp_type_of (TVar (v,s)) = RC.AtomV(RC.make_schematic_type_var v);
   135 
   136 
   137 fun const_type_of thy (c,t) =
   138       let val (tp,ts) = type_of t
   139       in  (tp, ts, map simp_type_of (Sign.const_typargs thy (c,t))) end;
   140 
   141 (* convert a Term.term (with combinators) into a combterm, also accummulate sort info *)
   142 fun combterm_of thy (Const(c,t)) =
   143       let val (tp,ts,tvar_list) = const_type_of thy (c,t)
   144           val c' = CombConst(RC.make_fixed_const c, tp, tvar_list)
   145       in  (c',ts)  end
   146   | combterm_of thy (Free(v,t)) =
   147       let val (tp,ts) = type_of t
   148           val v' = if RC.isMeta v then CombVar(RC.make_schematic_var(v,0),tp)
   149                    else CombConst(RC.make_fixed_var v, tp, [])
   150       in  (v',ts)  end
   151   | combterm_of thy (Var(v,t)) =
   152       let val (tp,ts) = type_of t
   153           val v' = CombVar(RC.make_schematic_var v,tp)
   154       in  (v',ts)  end
   155   | combterm_of thy (P $ Q) =
   156       let val (P',tsP) = combterm_of thy P
   157           val (Q',tsQ) = combterm_of thy Q
   158       in  (CombApp(P',Q'), tsP union tsQ)  end
   159   | combterm_of thy (t as Abs _) = raise RC.CLAUSE("HOL CLAUSE",t);
   160 
   161 fun predicate_of thy ((Const("Not",_) $ P), polarity) = predicate_of thy (P, not polarity)
   162   | predicate_of thy (t,polarity) = (combterm_of thy t, polarity);
   163 
   164 fun literals_of_term1 thy args (Const("Trueprop",_) $ P) = literals_of_term1 thy args P
   165   | literals_of_term1 thy args (Const("op |",_) $ P $ Q) =
   166       literals_of_term1 thy (literals_of_term1 thy args P) Q
   167   | literals_of_term1 thy (lits,ts) P =
   168       let val ((pred,ts'),pol) = predicate_of thy (P,true)
   169       in
   170           (Literal(pol,pred)::lits, ts union ts')
   171       end;
   172 
   173 fun literals_of_term thy P = literals_of_term1 thy ([],[]) P;
   174 
   175 (* making axiom and conjecture clauses *)
   176 fun make_clause thy (clause_id,axiom_name,kind,th) =
   177     let val (lits,ctypes_sorts) = literals_of_term thy (prop_of th)
   178     in
   179         if forall isFalse lits
   180         then error "Problem too trivial for resolution (empty clause)"
   181         else
   182             Clause {clause_id = clause_id, axiom_name = axiom_name, th = th, kind = kind,
   183                     literals = lits, ctypes_sorts = ctypes_sorts}
   184     end;
   185 
   186 
   187 fun add_axiom_clause thy ((th,(name,id)), pairs) =
   188   let val cls = make_clause thy (id, name, RC.Axiom, th)
   189   in
   190       if isTaut cls then pairs else (name,cls)::pairs
   191   end;
   192 
   193 fun make_axiom_clauses thy = foldl (add_axiom_clause thy) [];
   194 
   195 fun make_conjecture_clauses_aux _ _ [] = []
   196   | make_conjecture_clauses_aux thy n (th::ths) =
   197       make_clause thy (n,"conjecture", RC.Conjecture, th) ::
   198       make_conjecture_clauses_aux thy (n+1) ths;
   199 
   200 fun make_conjecture_clauses thy = make_conjecture_clauses_aux thy 0;
   201 
   202 
   203 (**********************************************************************)
   204 (* convert clause into ATP specific formats:                          *)
   205 (* TPTP used by Vampire and E                                         *)
   206 (* DFG used by SPASS                                                  *)
   207 (**********************************************************************)
   208 
   209 (*Result of a function type; no need to check that the argument type matches.*)
   210 fun result_type (RC.Comp ("tc_fun", [_, tp2])) = tp2
   211   | result_type _ = raise ERROR "result_type"
   212 
   213 fun type_of_combterm (CombConst(c,tp,_)) = tp
   214   | type_of_combterm (CombVar(v,tp)) = tp
   215   | type_of_combterm (CombApp(t1,t2)) = result_type (type_of_combterm t1);
   216 
   217 (*gets the head of a combinator application, along with the list of arguments*)
   218 fun strip_comb u =
   219     let fun stripc (CombApp(t,u), ts) = stripc (t, u::ts)
   220         |   stripc  x =  x
   221     in  stripc(u,[])  end;
   222 
   223 val type_wrapper = "ti";
   224 
   225 fun head_needs_hBOOL (CombConst(c,_,_)) = needs_hBOOL c
   226   | head_needs_hBOOL _ = true;
   227 
   228 fun wrap_type (s, tp) =
   229   if !typ_level=T_FULL then
   230       type_wrapper ^ RC.paren_pack [s, RC.string_of_fol_type tp]
   231   else s;
   232 
   233 fun apply ss = "hAPP" ^ RC.paren_pack ss;
   234 
   235 fun rev_apply (v, []) = v
   236   | rev_apply (v, arg::args) = apply [rev_apply (v, args), arg];
   237 
   238 fun string_apply (v, args) = rev_apply (v, rev args);
   239 
   240 (*Apply an operator to the argument strings, using either the "apply" operator or
   241   direct function application.*)
   242 fun string_of_applic (CombConst(c,tp,tvars), args) =
   243       let val c = if c = "equal" then "c_fequal" else c
   244           val nargs = min_arity_of c
   245           val args1 = List.take(args, nargs)
   246             handle Subscript => raise ERROR ("string_of_applic: " ^ c ^ " has arity " ^
   247                                              Int.toString nargs ^ " but is applied to " ^
   248                                              space_implode ", " args)
   249           val args2 = List.drop(args, nargs)
   250           val targs = if !typ_level = T_CONST then map RC.string_of_fol_type tvars
   251                       else []
   252       in
   253           string_apply (c ^ RC.paren_pack (args1@targs), args2)
   254       end
   255   | string_of_applic (CombVar(v,tp), args) = string_apply (v, args)
   256   | string_of_applic _ = raise ERROR "string_of_applic";
   257 
   258 fun wrap_type_if (head, s, tp) = if head_needs_hBOOL head then wrap_type (s, tp) else s;
   259 
   260 fun string_of_combterm t =
   261   let val (head, args) = strip_comb t
   262   in  wrap_type_if (head,
   263                     string_of_applic (head, map string_of_combterm args),
   264                     type_of_combterm t)
   265   end;
   266 
   267 (*Boolean-valued terms are here converted to literals.*)
   268 fun boolify t = "hBOOL" ^ RC.paren_pack [string_of_combterm t];
   269 
   270 fun string_of_predicate t =
   271   case t of
   272       (CombApp(CombApp(CombConst("equal",_,_), t1), t2)) =>
   273           (*DFG only: new TPTP prefers infix equality*)
   274           ("equal" ^ RC.paren_pack [string_of_combterm t1, string_of_combterm t2])
   275     | _ =>
   276           case #1 (strip_comb t) of
   277               CombConst(c,_,_) => if needs_hBOOL c then boolify t else string_of_combterm t
   278             | _ => boolify t;
   279 
   280 fun string_of_clausename (cls_id,ax_name) =
   281     RC.clause_prefix ^ RC.ascii_of ax_name ^ "_" ^ Int.toString cls_id;
   282 
   283 fun string_of_type_clsname (cls_id,ax_name,idx) =
   284     string_of_clausename (cls_id,ax_name) ^ "_tcs" ^ (Int.toString idx);
   285 
   286 
   287 (*** tptp format ***)
   288 
   289 fun tptp_of_equality pol (t1,t2) =
   290   let val eqop = if pol then " = " else " != "
   291   in  string_of_combterm t1 ^ eqop ^ string_of_combterm t2  end;
   292 
   293 fun tptp_literal (Literal(pol, CombApp(CombApp(CombConst("equal",_,_), t1), t2))) =
   294       tptp_of_equality pol (t1,t2)
   295   | tptp_literal (Literal(pol,pred)) =
   296       RC.tptp_sign pol (string_of_predicate pred);
   297 
   298 (*Given a clause, returns its literals paired with a list of literals concerning TFrees;
   299   the latter should only occur in conjecture clauses.*)
   300 fun tptp_type_lits pos (Clause{literals, ctypes_sorts, ...}) =
   301       (map tptp_literal literals, 
   302        map (RC.tptp_of_typeLit pos) (RC.add_typs ctypes_sorts));
   303 
   304 fun clause2tptp (cls as Clause{axiom_name,clause_id,kind,ctypes_sorts,...}) =
   305   let val (lits,tylits) = tptp_type_lits (kind = RC.Conjecture) cls
   306   in
   307       (RC.gen_tptp_cls(clause_id,axiom_name,kind,lits,tylits), tylits)
   308   end;
   309 
   310 
   311 (*** dfg format ***)
   312 
   313 fun dfg_literal (Literal(pol,pred)) = RC.dfg_sign pol (string_of_predicate pred);
   314 
   315 fun dfg_type_lits pos (Clause{literals, ctypes_sorts, ...}) =
   316       (map dfg_literal literals, 
   317        map (RC.dfg_of_typeLit pos) (RC.add_typs ctypes_sorts));
   318 
   319 fun get_uvars (CombConst _) vars = vars
   320   | get_uvars (CombVar(v,_)) vars = (v::vars)
   321   | get_uvars (CombApp(P,Q)) vars = get_uvars P (get_uvars Q vars);
   322 
   323 fun get_uvars_l (Literal(_,c)) = get_uvars c [];
   324 
   325 fun dfg_vars (Clause {literals,...}) = RC.union_all (map get_uvars_l literals);
   326 
   327 fun clause2dfg (cls as Clause{axiom_name,clause_id,kind,ctypes_sorts,...}) =
   328   let val (lits,tylits) = dfg_type_lits (kind = RC.Conjecture) cls
   329       val vars = dfg_vars cls
   330       val tvars = RC.get_tvar_strs ctypes_sorts
   331   in
   332       (RC.gen_dfg_cls(clause_id, axiom_name, kind, lits, tylits, tvars@vars), tylits)
   333   end;
   334 
   335 
   336 (** For DFG format: accumulate function and predicate declarations **)
   337 
   338 fun addtypes tvars tab = foldl RC.add_foltype_funcs tab tvars;
   339 
   340 fun add_decls (CombConst(c,tp,tvars), (funcs,preds)) =
   341       if c = "equal" then (addtypes tvars funcs, preds)
   342       else
   343 	let val arity = min_arity_of c
   344 	    val ntys = if !typ_level = T_CONST then length tvars else 0
   345 	    val addit = Symtab.update(c, arity+ntys)
   346 	in
   347 	    if needs_hBOOL c then (addtypes tvars (addit funcs), preds)
   348 	    else (addtypes tvars funcs, addit preds)
   349 	end
   350   | add_decls (CombVar(_,ctp), (funcs,preds)) =
   351       (RC.add_foltype_funcs (ctp,funcs), preds)
   352   | add_decls (CombApp(P,Q),decls) = add_decls(P,add_decls (Q,decls));
   353 
   354 fun add_literal_decls (Literal(_,c), decls) = add_decls (c,decls);
   355 
   356 fun add_clause_decls (Clause {literals, ...}, decls) =
   357     foldl add_literal_decls decls literals
   358     handle Symtab.DUP a => raise ERROR ("function " ^ a ^ " has multiple arities")
   359 
   360 fun decls_of_clauses clauses arity_clauses =
   361   let val init_functab = Symtab.update (type_wrapper,2) (Symtab.update ("hAPP",2) RC.init_functab)
   362       val init_predtab = Symtab.update ("hBOOL",1) Symtab.empty
   363       val (functab,predtab) = (foldl add_clause_decls (init_functab, init_predtab) clauses)
   364   in
   365       (Symtab.dest (foldl RC.add_arityClause_funcs functab arity_clauses),
   366        Symtab.dest predtab)
   367   end;
   368 
   369 fun add_clause_preds (Clause {ctypes_sorts, ...}, preds) =
   370   foldl RC.add_type_sort_preds preds ctypes_sorts
   371   handle Symtab.DUP a => raise ERROR ("predicate " ^ a ^ " has multiple arities")
   372 
   373 (*Higher-order clauses have only the predicates hBOOL and type classes.*)
   374 fun preds_of_clauses clauses clsrel_clauses arity_clauses =
   375     Symtab.dest
   376         (foldl RC.add_classrelClause_preds
   377                (foldl RC.add_arityClause_preds
   378                       (foldl add_clause_preds Symtab.empty clauses)
   379                       arity_clauses)
   380                clsrel_clauses)
   381 
   382 
   383 (**********************************************************************)
   384 (* write clauses to files                                             *)
   385 (**********************************************************************)
   386 
   387 val init_counters =
   388     Symtab.make [("c_COMBI", 0), ("c_COMBK", 0),
   389                  ("c_COMBB", 0), ("c_COMBC", 0),
   390                  ("c_COMBS", 0), ("c_COMBB_e", 0),
   391                  ("c_COMBC_e", 0), ("c_COMBS_e", 0)];
   392 
   393 fun count_combterm (CombConst(c,tp,_), ct) =
   394      (case Symtab.lookup ct c of NONE => ct  (*no counter*)
   395                                | SOME n => Symtab.update (c,n+1) ct)
   396   | count_combterm (CombVar(v,tp), ct) = ct
   397   | count_combterm (CombApp(t1,t2), ct) = count_combterm(t1, count_combterm(t2, ct));
   398 
   399 fun count_literal (Literal(_,t), ct) = count_combterm(t,ct);
   400 
   401 fun count_clause (Clause{literals,...}, ct) = foldl count_literal ct literals;
   402 
   403 fun count_user_clause user_lemmas (Clause{axiom_name,literals,...}, ct) =
   404   if axiom_name mem_string user_lemmas then foldl count_literal ct literals
   405   else ct;
   406 
   407 val cnf_helper_thms = ResAxioms.cnf_rules_pairs o (map ResAxioms.pairname)
   408 
   409 fun get_helper_clauses thy isFO (conjectures, axclauses, user_lemmas) =
   410   if isFO then []  (*first-order*)
   411   else
   412     let val ct0 = foldl count_clause init_counters conjectures
   413         val ct = foldl (count_user_clause user_lemmas) ct0 axclauses
   414         fun needed c = valOf (Symtab.lookup ct c) > 0
   415         val IK = if needed "c_COMBI" orelse needed "c_COMBK"
   416                  then (Output.debug (fn () => "Include combinator I K"); cnf_helper_thms [comb_I,comb_K])
   417                  else []
   418         val BC = if needed "c_COMBB" orelse needed "c_COMBC"
   419                  then (Output.debug (fn () => "Include combinator B C"); cnf_helper_thms [comb_B,comb_C])
   420                  else []
   421         val S = if needed "c_COMBS"
   422                 then (Output.debug (fn () => "Include combinator S"); cnf_helper_thms [comb_S])
   423                 else []
   424         val B'C' = if needed "c_COMBB_e" orelse needed "c_COMBC_e"
   425                    then (Output.debug (fn () => "Include combinator B' C'"); cnf_helper_thms [comb_B', comb_C'])
   426                    else []
   427         val S' = if needed "c_COMBS_e"
   428                  then (Output.debug (fn () => "Include combinator S'"); cnf_helper_thms [comb_S'])
   429                  else []
   430         val other = cnf_helper_thms [ext,fequal_imp_equal,equal_imp_fequal]
   431     in
   432         map #2 (make_axiom_clauses thy (other @ IK @ BC @ S @ B'C' @ S'))
   433     end;
   434 
   435 (*Find the minimal arity of each function mentioned in the term. Also, note which uses
   436   are not at top level, to see if hBOOL is needed.*)
   437 fun count_constants_term toplev t =
   438   let val (head, args) = strip_comb t
   439       val n = length args
   440       val _ = List.app (count_constants_term false) args
   441   in
   442       case head of
   443           CombConst (a,_,_) => (*predicate or function version of "equal"?*)
   444             let val a = if a="equal" andalso not toplev then "c_fequal" else a
   445             in
   446               const_min_arity := Symtab.map_default (a,n) (curry Int.min n) (!const_min_arity);
   447               if toplev then ()
   448               else const_needs_hBOOL := Symtab.update (a,true) (!const_needs_hBOOL)
   449             end
   450         | ts => ()
   451   end;
   452 
   453 (*A literal is a top-level term*)
   454 fun count_constants_lit (Literal (_,t)) = count_constants_term true t;
   455 
   456 fun count_constants_clause (Clause{literals,...}) = List.app count_constants_lit literals;
   457 
   458 fun display_arity (c,n) =
   459   Output.debug (fn () => "Constant: " ^ c ^ " arity:\t" ^ Int.toString n ^
   460                 (if needs_hBOOL c then " needs hBOOL" else ""));
   461 
   462 fun count_constants (conjectures, axclauses, helper_clauses) =
   463   if !minimize_applies then
   464     (const_min_arity := Symtab.empty;
   465      const_needs_hBOOL := Symtab.empty;
   466      List.app count_constants_clause conjectures;
   467      List.app count_constants_clause axclauses;
   468      List.app count_constants_clause helper_clauses;
   469      List.app display_arity (Symtab.dest (!const_min_arity)))
   470   else ();
   471 
   472 (* tptp format *)
   473 
   474 (* write TPTP format to a single file *)
   475 fun tptp_write_file thy isFO thms filename (ax_tuples,classrel_clauses,arity_clauses) user_lemmas =
   476     let val _ = Output.debug (fn () => ("Preparing to write the TPTP file " ^ filename))
   477         val _ = RC.dfg_format := false
   478         val conjectures = make_conjecture_clauses thy thms
   479         val (clnames,axclauses) = ListPair.unzip (make_axiom_clauses thy ax_tuples)
   480         val helper_clauses = get_helper_clauses thy isFO (conjectures, axclauses, user_lemmas)
   481         val _ = count_constants (conjectures, axclauses, helper_clauses);
   482         val (tptp_clss,tfree_litss) = ListPair.unzip (map clause2tptp conjectures)
   483         val tfree_clss = map RC.tptp_tfree_clause (foldl (op union_string) [] tfree_litss)
   484         val out = TextIO.openOut filename
   485     in
   486         List.app (curry TextIO.output out o #1 o clause2tptp) axclauses;
   487         RC.writeln_strs out tfree_clss;
   488         RC.writeln_strs out tptp_clss;
   489         List.app (curry TextIO.output out o RC.tptp_classrelClause) classrel_clauses;
   490         List.app (curry TextIO.output out o RC.tptp_arity_clause) arity_clauses;
   491         List.app (curry TextIO.output out o #1 o clause2tptp) helper_clauses;
   492         TextIO.closeOut out;
   493         clnames
   494     end;
   495 
   496 
   497 (* dfg format *)
   498 
   499 fun dfg_write_file thy isFO thms filename (ax_tuples,classrel_clauses,arity_clauses) user_lemmas =
   500     let val _ = Output.debug (fn () => ("Preparing to write the DFG file " ^ filename))
   501         val _ = RC.dfg_format := true
   502         val conjectures = make_conjecture_clauses thy thms
   503         val (clnames,axclauses) = ListPair.unzip (make_axiom_clauses thy ax_tuples)
   504         val helper_clauses = get_helper_clauses thy isFO (conjectures, axclauses, user_lemmas)
   505         val _ = count_constants (conjectures, axclauses, helper_clauses);
   506         val (dfg_clss, tfree_litss) = ListPair.unzip (map clause2dfg conjectures)
   507         and probname = Path.implode (Path.base (Path.explode filename))
   508         val axstrs = map (#1 o clause2dfg) axclauses
   509         val tfree_clss = map RC.dfg_tfree_clause (RC.union_all tfree_litss)
   510         val out = TextIO.openOut filename
   511         val helper_clauses_strs = map (#1 o clause2dfg) helper_clauses
   512         val (funcs,cl_preds) = decls_of_clauses (helper_clauses @ conjectures @ axclauses) arity_clauses
   513         and ty_preds = preds_of_clauses axclauses classrel_clauses arity_clauses
   514     in
   515         TextIO.output (out, RC.string_of_start probname);
   516         TextIO.output (out, RC.string_of_descrip probname);
   517         TextIO.output (out, RC.string_of_symbols
   518                               (RC.string_of_funcs funcs)
   519                               (RC.string_of_preds (cl_preds @ ty_preds)));
   520         TextIO.output (out, "list_of_clauses(axioms,cnf).\n");
   521         RC.writeln_strs out axstrs;
   522         List.app (curry TextIO.output out o RC.dfg_classrelClause) classrel_clauses;
   523         List.app (curry TextIO.output out o RC.dfg_arity_clause) arity_clauses;
   524         RC.writeln_strs out helper_clauses_strs;
   525         TextIO.output (out, "end_of_list.\n\nlist_of_clauses(conjectures,cnf).\n");
   526         RC.writeln_strs out tfree_clss;
   527         RC.writeln_strs out dfg_clss;
   528         TextIO.output (out, "end_of_list.\n\n");
   529         (*VarWeight=3 helps the HO problems, probably by counteracting the presence of hAPP*)
   530         TextIO.output (out, "list_of_settings(SPASS).\n{*\nset_flag(VarWeight,3).\n*}\nend_of_list.\n\n");
   531         TextIO.output (out, "end_problem.\n");
   532         TextIO.closeOut out;
   533         clnames
   534     end;
   535 
   536 end