src/Tools/Metis/src/Tptp.sml
changeset 25430 372d6749f00e
parent 23510 4521fead5609
child 39353 7f11d833d65b
equal deleted inserted replaced
25429:9e14fbd43e6b 25430:372d6749f00e
     1 (* ========================================================================= *)
     1 (* ========================================================================= *)
     2 (* INTERFACE TO TPTP PROBLEM FILES                                           *)
     2 (* THE TPTP PROBLEM FILE FORMAT (TPTP v2)                                    *)
     3 (* Copyright (c) 2001-2007 Joe Hurd, distributed under the BSD License *)
     3 (* Copyright (c) 2001-2007 Joe Hurd, distributed under the BSD License *)
     4 (* ========================================================================= *)
     4 (* ========================================================================= *)
     5 
     5 
     6 structure Tptp :> Tptp =
     6 structure Tptp :> Tptp =
     7 struct
     7 struct
    12 (* Constants.                                                                *)
    12 (* Constants.                                                                *)
    13 (* ------------------------------------------------------------------------- *)
    13 (* ------------------------------------------------------------------------- *)
    14 
    14 
    15 val ROLE_NEGATED_CONJECTURE = "negated_conjecture"
    15 val ROLE_NEGATED_CONJECTURE = "negated_conjecture"
    16 and ROLE_CONJECTURE = "conjecture";
    16 and ROLE_CONJECTURE = "conjecture";
       
    17 
       
    18 (* ------------------------------------------------------------------------- *)
       
    19 (* Helper functions.                                                         *)
       
    20 (* ------------------------------------------------------------------------- *)
       
    21 
       
    22 fun isHdTlString hp tp s =
       
    23     let
       
    24       fun ct 0 = true
       
    25         | ct i = tp (String.sub (s,i)) andalso ct (i - 1)
       
    26 
       
    27       val n = size s
       
    28     in
       
    29       n > 0 andalso hp (String.sub (s,0)) andalso ct (n - 1)
       
    30     end;
    17 
    31 
    18 (* ------------------------------------------------------------------------- *)
    32 (* ------------------------------------------------------------------------- *)
    19 (* Mapping TPTP functions and relations to different names.                  *)
    33 (* Mapping TPTP functions and relations to different names.                  *)
    20 (* ------------------------------------------------------------------------- *)
    34 (* ------------------------------------------------------------------------- *)
    21 
    35 
   150 
   164 
   151 (* ------------------------------------------------------------------------- *)
   165 (* ------------------------------------------------------------------------- *)
   152 (* Printing formulas using TPTP syntax.                                      *)
   166 (* Printing formulas using TPTP syntax.                                      *)
   153 (* ------------------------------------------------------------------------- *)
   167 (* ------------------------------------------------------------------------- *)
   154 
   168 
       
   169 val ppVar = Parser.ppString;
       
   170 
   155 local
   171 local
   156   fun term pp (Term.Var v) = PP.add_string pp v
   172   fun term pp (Term.Var v) = ppVar pp v
   157     | term pp (Term.Fn (c,[])) = PP.add_string pp c
   173     | term pp (Term.Fn (c,[])) = Parser.addString pp c
   158     | term pp (Term.Fn (f,tms)) =
   174     | term pp (Term.Fn (f,tms)) =
   159       (PP.begin_block pp PP.INCONSISTENT 2;
   175       (Parser.beginBlock pp Parser.Inconsistent 2;
   160        PP.add_string pp (f ^ "(");
   176        Parser.addString pp (f ^ "(");
   161        Parser.ppSequence "," term pp tms;
   177        Parser.ppSequence "," term pp tms;
   162        PP.add_string pp ")";
   178        Parser.addString pp ")";
   163        PP.end_block pp);
   179        Parser.endBlock pp);
   164 
   180 in
       
   181   fun ppTerm pp tm =
       
   182       (Parser.beginBlock pp Parser.Inconsistent 0;
       
   183        term pp tm;
       
   184        Parser.endBlock pp);
       
   185 end;
       
   186 
       
   187 fun ppAtom pp atm = ppTerm pp (Term.Fn atm);
       
   188 
       
   189 local
   165   open Formula;
   190   open Formula;
   166 
   191 
   167   fun fof pp (fm as And _) = assoc_binary pp ("&", stripConj fm)
   192   fun fof pp (fm as And _) = assoc_binary pp ("&", stripConj fm)
   168     | fof pp (fm as Or _) = assoc_binary pp ("|", stripDisj fm)
   193     | fof pp (fm as Or _) = assoc_binary pp ("|", stripDisj fm)
   169     | fof pp (Imp a_b) = nonassoc_binary pp ("=>",a_b)
   194     | fof pp (Imp a_b) = nonassoc_binary pp ("=>",a_b)
   179       if isForall fm then quantified pp ("!", stripForall fm)
   204       if isForall fm then quantified pp ("!", stripForall fm)
   180       else if isExists fm then quantified pp ("?", stripExists fm)
   205       else if isExists fm then quantified pp ("?", stripExists fm)
   181       else if atom pp fm then ()
   206       else if atom pp fm then ()
   182       else if isNeg fm then
   207       else if isNeg fm then
   183         let
   208         let
   184           fun pr () = (PP.add_string pp "~"; PP.add_break pp (1,0))
   209           fun pr () = (Parser.addString pp "~"; Parser.addBreak pp (1,0))
   185           val (n,fm) = Formula.stripNeg fm
   210           val (n,fm) = Formula.stripNeg fm
   186         in
   211         in
   187           PP.begin_block pp PP.INCONSISTENT 2;
   212           Parser.beginBlock pp Parser.Inconsistent 2;
   188           funpow n pr ();
   213           funpow n pr ();
   189           unitary pp fm;
   214           unitary pp fm;
   190           PP.end_block pp
   215           Parser.endBlock pp
   191         end
   216         end
   192       else
   217       else
   193         (PP.begin_block pp PP.INCONSISTENT 1;
   218         (Parser.beginBlock pp Parser.Inconsistent 1;
   194          PP.add_string pp "(";
   219          Parser.addString pp "(";
   195          fof pp fm;
   220          fof pp fm;
   196          PP.add_string pp ")";
   221          Parser.addString pp ")";
   197          PP.end_block pp)
   222          Parser.endBlock pp)
   198 
   223 
   199   and quantified pp (q,(vs,fm)) =
   224   and quantified pp (q,(vs,fm)) =
   200       (PP.begin_block pp PP.INCONSISTENT 2;
   225       (Parser.beginBlock pp Parser.Inconsistent 2;
   201        PP.add_string pp (q ^ " ");
   226        Parser.addString pp (q ^ " ");
   202        PP.begin_block pp PP.INCONSISTENT (String.size q);
   227        Parser.beginBlock pp Parser.Inconsistent (String.size q);
   203        PP.add_string pp "[";
   228        Parser.addString pp "[";
   204        Parser.ppSequence "," Parser.ppString pp vs;
   229        Parser.ppSequence "," ppVar pp vs;
   205        PP.add_string pp "] :";
   230        Parser.addString pp "] :";
   206        PP.end_block pp;
   231        Parser.endBlock pp;
   207        PP.add_break pp (1,0);
   232        Parser.addBreak pp (1,0);
   208        unitary pp fm;
   233        unitary pp fm;
   209        PP.end_block pp)
   234        Parser.endBlock pp)
   210       
   235       
   211   and atom pp True = (PP.add_string pp "$true"; true)
   236   and atom pp True = (Parser.addString pp "$true"; true)
   212     | atom pp False = (PP.add_string pp "$false"; true)
   237     | atom pp False = (Parser.addString pp "$false"; true)
   213     | atom pp fm =
   238     | atom pp fm =
   214       case total destEq fm of
   239       case total destEq fm of
   215         SOME a_b => (Parser.ppBinop " =" term term pp a_b; true)
   240         SOME a_b => (Parser.ppBinop " =" ppTerm ppTerm pp a_b; true)
   216       | NONE =>
   241       | NONE =>
   217         case total destNeq fm of
   242         case total destNeq fm of
   218           SOME a_b => (Parser.ppBinop " !=" term term pp a_b; true)
   243           SOME a_b => (Parser.ppBinop " !=" ppTerm ppTerm pp a_b; true)
   219         | NONE =>
   244         | NONE => case fm of Atom atm => (ppAtom pp atm; true) | _ => false;
   220           case fm of
       
   221             Atom atm => (term pp (Term.Fn atm); true)
       
   222           | _ => false;
       
   223 in
   245 in
   224   fun ppFof pp fm =
   246   fun ppFof pp fm =
   225       (PP.begin_block pp PP.INCONSISTENT 0;
   247       (Parser.beginBlock pp Parser.Inconsistent 0;
   226        fof pp fm;
   248        fof pp fm;
   227        PP.end_block pp);
   249        Parser.endBlock pp);
   228 end;
   250 end;
   229 
   251 
   230 (* ------------------------------------------------------------------------- *)
   252 (* ------------------------------------------------------------------------- *)
   231 (* TPTP clauses.                                                             *)
   253 (* TPTP clauses.                                                             *)
   232 (* ------------------------------------------------------------------------- *)
   254 (* ------------------------------------------------------------------------- *)
   263 
   285 
   264 fun clauseToFormula lits = Formula.listMkDisj (map literalToFormula lits);
   286 fun clauseToFormula lits = Formula.listMkDisj (map literalToFormula lits);
   265 
   287 
   266 fun clauseFromFormula fm = map literalFromFormula (Formula.stripDisj fm);
   288 fun clauseFromFormula fm = map literalFromFormula (Formula.stripDisj fm);
   267 
   289 
       
   290 fun clauseFromLiteralSet cl =
       
   291     clauseFromFormula
       
   292       (Formula.listMkDisj (LiteralSet.transform Literal.toFormula cl));
       
   293 
       
   294 fun clauseFromThm th = clauseFromLiteralSet (Thm.clause th);
       
   295 
   268 val ppClause = Parser.ppMap clauseToFormula ppFof;
   296 val ppClause = Parser.ppMap clauseToFormula ppFof;
   269 
   297 
   270 (* ------------------------------------------------------------------------- *)
   298 (* ------------------------------------------------------------------------- *)
   271 (* TPTP formulas.                                                            *)
   299 (* TPTP formulas.                                                            *)
   272 (* ------------------------------------------------------------------------- *)
   300 (* ------------------------------------------------------------------------- *)
   315 
   343 
   316 fun formulaIsConjecture (CnfFormula {role,...}) = role = ROLE_NEGATED_CONJECTURE
   344 fun formulaIsConjecture (CnfFormula {role,...}) = role = ROLE_NEGATED_CONJECTURE
   317   | formulaIsConjecture (FofFormula {role,...}) = role = ROLE_CONJECTURE;
   345   | formulaIsConjecture (FofFormula {role,...}) = role = ROLE_CONJECTURE;
   318 
   346 
   319 local
   347 local
   320   val mkTptpString =
   348   open Parser;
   321       let
   349 
   322         fun tr #"'" = ""
   350   infixr 8 ++
   323           | tr c =
   351   infixr 7 >>
   324             if c = #"_" orelse Char.isAlphaNum c then str c
   352   infixr 6 ||
   325             else raise Error "bad character"
   353 
   326       in
   354   datatype token =
   327         String.translate tr
   355       AlphaNum of string
       
   356     | Punct of char
       
   357     | Quote of string;
       
   358 
       
   359   fun isAlphaNum #"_" = true
       
   360     | isAlphaNum c = Char.isAlphaNum c;
       
   361 
       
   362   local
       
   363     val alphaNumToken = atLeastOne (some isAlphaNum) >> (AlphaNum o implode);
       
   364 
       
   365     val punctToken =
       
   366         let
       
   367           val punctChars = "<>=-*+/\\?@|!$%&#^:;~()[]{}.,"
       
   368         in
       
   369           some (Char.contains punctChars) >> Punct
       
   370         end;
       
   371 
       
   372     val quoteToken =
       
   373         let
       
   374           val escapeParser =
       
   375               exact #"'" >> singleton ||
       
   376               exact #"\\" >> singleton
       
   377 
       
   378           fun stopOn #"'" = true
       
   379             | stopOn #"\n" = true
       
   380             | stopOn _ = false
       
   381 
       
   382           val quotedParser =
       
   383               exact #"\\" ++ escapeParser >> op:: ||
       
   384               some (not o stopOn) >> singleton
       
   385         in
       
   386           exact #"'" ++ many quotedParser ++ exact #"'" >>
       
   387           (fn (_,(l,_)) => Quote (implode (List.concat l)))
       
   388         end;
       
   389 
       
   390     val lexToken = alphaNumToken || punctToken || quoteToken;
       
   391 
       
   392     val space = many (some Char.isSpace) >> K ();
       
   393   in
       
   394     val lexer = (space ++ lexToken ++ space) >> (fn ((),(tok,())) => tok);
       
   395   end;
       
   396 
       
   397   fun someAlphaNum p =
       
   398       maybe (fn AlphaNum s => if p s then SOME s else NONE | _ => NONE);
       
   399 
       
   400   fun alphaNumParser s = someAlphaNum (equal s) >> K ();
       
   401 
       
   402   fun isLower s = Char.isLower (String.sub (s,0));
       
   403 
       
   404   val lowerParser = someAlphaNum isLower;
       
   405 
       
   406   val upperParser = someAlphaNum (fn s => Char.isUpper (String.sub (s,0)));
       
   407 
       
   408   val stringParser = lowerParser || upperParser;
       
   409 
       
   410   val numberParser = someAlphaNum (List.all Char.isDigit o explode);
       
   411 
       
   412   fun somePunct p =
       
   413       maybe (fn Punct c => if p c then SOME c else NONE | _ => NONE);
       
   414 
       
   415   fun punctParser c = somePunct (equal c) >> K ();
       
   416 
       
   417   fun quoteParser p =
       
   418       let
       
   419         fun q s = if p s then s else "'" ^ s ^ "'"
       
   420       in
       
   421         maybe (fn Quote s => SOME (q s) | _ => NONE)
   328       end;
   422       end;
   329 
   423 
   330   fun mkTptpName a n =
   424   local
   331       let
   425     fun f [] = raise Bug "symbolParser"
   332         val n' = mkTptpString n
   426       | f [x] = x
   333 
   427       | f (h :: t) = (h ++ f t) >> K ();
   334         val n' =
   428   in
   335             case explode n' of
   429     fun symbolParser s = f (map punctParser (explode s));
   336               [] => raise Error "empty"
   430   end;
   337             | c :: cs =>
   431 
   338               if Char.isLower c then n'
   432   val definedParser =
   339               else if Char.isDigit c andalso List.all Char.isDigit cs then n'
   433       punctParser #"$" ++ someAlphaNum (K true) >> (fn ((),s) => "$" ^ s);
   340               else if Char.isUpper c then implode (Char.toLower c :: cs)
   434 
   341               else raise Error "bad initial character"
   435   val systemParser =
   342       in
   436       punctParser #"$" ++ punctParser #"$" ++ someAlphaNum (K true) >>
   343         if n = n' then n else Term.variantNum a n'
   437       (fn ((),((),s)) => "$$" ^ s);
       
   438 
       
   439   val nameParser = stringParser || numberParser || quoteParser (K false);
       
   440 
       
   441   val roleParser = lowerParser;
       
   442 
       
   443   local
       
   444     fun isProposition s = isHdTlString Char.isLower isAlphaNum s;
       
   445   in
       
   446     val propositionParser =
       
   447         someAlphaNum isProposition ||
       
   448         definedParser || systemParser || quoteParser isProposition;
       
   449   end;
       
   450 
       
   451   local
       
   452     fun isFunction s = isHdTlString Char.isLower isAlphaNum s;
       
   453   in
       
   454     val functionParser =
       
   455         someAlphaNum isFunction ||
       
   456         definedParser || systemParser || quoteParser isFunction;
       
   457   end;
       
   458 
       
   459   local
       
   460     fun isConstant s =
       
   461         isHdTlString Char.isLower isAlphaNum s orelse
       
   462         isHdTlString Char.isDigit Char.isDigit s;
       
   463   in
       
   464     val constantParser =
       
   465         someAlphaNum isConstant ||
       
   466         definedParser || systemParser || quoteParser isConstant;
       
   467   end;
       
   468 
       
   469   val varParser = upperParser;
       
   470 
       
   471   val varListParser =
       
   472       (punctParser #"[" ++ varParser ++
       
   473        many ((punctParser #"," ++ varParser) >> snd) ++
       
   474        punctParser #"]") >>
       
   475       (fn ((),(h,(t,()))) => h :: t);
       
   476 
       
   477   fun termParser input =
       
   478       ((functionArgumentsParser >> Term.Fn) ||
       
   479        nonFunctionArgumentsTermParser) input
       
   480 
       
   481   and functionArgumentsParser input =
       
   482       ((functionParser ++ punctParser #"(" ++ termParser ++
       
   483         many ((punctParser #"," ++ termParser) >> snd) ++
       
   484         punctParser #")") >>
       
   485        (fn (f,((),(t,(ts,())))) => (f, t :: ts))) input
       
   486 
       
   487   and nonFunctionArgumentsTermParser input =
       
   488       ((varParser >> Term.Var) ||
       
   489        (constantParser >> (fn n => Term.Fn (n,[])))) input
       
   490 
       
   491   val binaryAtomParser =
       
   492       ((punctParser #"=" ++ termParser) >>
       
   493        (fn ((),r) => fn l => Literal.mkEq (l,r))) ||
       
   494       ((symbolParser "!=" ++ termParser) >>
       
   495        (fn ((),r) => fn l => Literal.mkNeq (l,r)));
       
   496 
       
   497   val maybeBinaryAtomParser =
       
   498       optional binaryAtomParser >>
       
   499       (fn SOME f => (fn a => f (Term.Fn a))
       
   500         | NONE => (fn a => (true,a)));
       
   501 
       
   502   val literalAtomParser =
       
   503       ((functionArgumentsParser ++ maybeBinaryAtomParser) >>
       
   504        (fn (a,f) => f a)) ||
       
   505       ((nonFunctionArgumentsTermParser ++ binaryAtomParser) >>
       
   506        (fn (a,f) => f a)) ||
       
   507       (propositionParser >>
       
   508        (fn n => (true,(n,[]))));
       
   509 
       
   510   val atomParser =
       
   511       literalAtomParser >>
       
   512       (fn (pol,("$true",[])) => Boolean pol
       
   513         | (pol,("$false",[])) => Boolean (not pol)
       
   514         | (pol,("$equal",[a,b])) => Literal (pol, Atom.mkEq (a,b))
       
   515         | lit => Literal lit);
       
   516 
       
   517   val literalParser =
       
   518       ((punctParser #"~" ++ atomParser) >> (negate o snd)) ||
       
   519       atomParser;
       
   520 
       
   521   val disjunctionParser =
       
   522       (literalParser ++ many ((punctParser #"|" ++ literalParser) >> snd)) >>
       
   523       (fn (h,t) => h :: t);
       
   524 
       
   525   val clauseParser =
       
   526       ((punctParser #"(" ++ disjunctionParser ++ punctParser #")") >>
       
   527        (fn ((),(c,())) => c)) ||
       
   528       disjunctionParser;
       
   529 
       
   530 (*
       
   531   An exact transcription of the fof_formula syntax from
       
   532 
       
   533     TPTP-v3.2.0/Documents/SyntaxBNF,
       
   534 
       
   535   fun fofFormulaParser input =
       
   536       (binaryFormulaParser || unitaryFormulaParser) input
       
   537   
       
   538   and binaryFormulaParser input =
       
   539       (nonAssocBinaryFormulaParser || assocBinaryFormulaParser) input
       
   540 
       
   541   and nonAssocBinaryFormulaParser input =
       
   542       ((unitaryFormulaParser ++ binaryConnectiveParser ++
       
   543         unitaryFormulaParser) >>
       
   544        (fn (f,(c,g)) => c (f,g))) input
       
   545 
       
   546   and binaryConnectiveParser input =
       
   547       ((symbolParser "<=>" >> K Formula.Iff) ||
       
   548        (symbolParser "=>" >> K Formula.Imp) ||
       
   549        (symbolParser "<=" >> K (fn (f,g) => Formula.Imp (g,f))) ||
       
   550        (symbolParser "<~>" >> K (Formula.Not o Formula.Iff)) ||
       
   551        (symbolParser "~|" >> K (Formula.Not o Formula.Or)) ||
       
   552        (symbolParser "~&" >> K (Formula.Not o Formula.And))) input
       
   553 
       
   554   and assocBinaryFormulaParser input =
       
   555       (orFormulaParser || andFormulaParser) input
       
   556 
       
   557   and orFormulaParser input =
       
   558       ((unitaryFormulaParser ++
       
   559         atLeastOne ((punctParser #"|" ++ unitaryFormulaParser) >> snd)) >>
       
   560        (fn (f,fs) => Formula.listMkDisj (f :: fs))) input
       
   561 
       
   562   and andFormulaParser input =
       
   563       ((unitaryFormulaParser ++
       
   564         atLeastOne ((punctParser #"&" ++ unitaryFormulaParser) >> snd)) >>
       
   565        (fn (f,fs) => Formula.listMkConj (f :: fs))) input
       
   566 
       
   567   and unitaryFormulaParser input =
       
   568       (quantifiedFormulaParser ||
       
   569        unaryFormulaParser ||
       
   570        ((punctParser #"(" ++ fofFormulaParser ++ punctParser #")") >>
       
   571         (fn ((),(f,())) => f)) ||
       
   572        (atomParser >>
       
   573         (fn Boolean b => Formula.mkBoolean b
       
   574           | Literal l => Literal.toFormula l))) input
       
   575 
       
   576   and quantifiedFormulaParser input =
       
   577       ((quantifierParser ++ varListParser ++ punctParser #":" ++
       
   578         unitaryFormulaParser) >>
       
   579        (fn (q,(v,((),f))) => q (v,f))) input
       
   580 
       
   581   and quantifierParser input =
       
   582       ((punctParser #"!" >> K Formula.listMkForall) ||
       
   583        (punctParser #"?" >> K Formula.listMkExists)) input
       
   584 
       
   585   and unaryFormulaParser input =
       
   586       ((unaryConnectiveParser ++ unitaryFormulaParser) >>
       
   587        (fn (c,f) => c f)) input
       
   588 
       
   589   and unaryConnectiveParser input =
       
   590       (punctParser #"~" >> K Formula.Not) input;
       
   591 *)
       
   592 
       
   593 (*
       
   594   This version is supposed to be equivalent to the spec version above,
       
   595   but uses closures to avoid reparsing prefixes.
       
   596 *)
       
   597 
       
   598   fun fofFormulaParser input =
       
   599       ((unitaryFormulaParser ++ optional binaryFormulaParser) >>
       
   600        (fn (f,NONE) => f | (f, SOME t) => t f)) input
       
   601   
       
   602   and binaryFormulaParser input =
       
   603       (nonAssocBinaryFormulaParser || assocBinaryFormulaParser) input
       
   604 
       
   605   and nonAssocBinaryFormulaParser input =
       
   606       ((binaryConnectiveParser ++ unitaryFormulaParser) >>
       
   607        (fn (c,g) => fn f => c (f,g))) input
       
   608 
       
   609   and binaryConnectiveParser input =
       
   610       ((symbolParser "<=>" >> K Formula.Iff) ||
       
   611        (symbolParser "=>" >> K Formula.Imp) ||
       
   612        (symbolParser "<=" >> K (fn (f,g) => Formula.Imp (g,f))) ||
       
   613        (symbolParser "<~>" >> K (Formula.Not o Formula.Iff)) ||
       
   614        (symbolParser "~|" >> K (Formula.Not o Formula.Or)) ||
       
   615        (symbolParser "~&" >> K (Formula.Not o Formula.And))) input
       
   616 
       
   617   and assocBinaryFormulaParser input =
       
   618       (orFormulaParser || andFormulaParser) input
       
   619 
       
   620   and orFormulaParser input =
       
   621       (atLeastOne ((punctParser #"|" ++ unitaryFormulaParser) >> snd) >>
       
   622        (fn fs => fn f => Formula.listMkDisj (f :: fs))) input
       
   623 
       
   624   and andFormulaParser input =
       
   625       (atLeastOne ((punctParser #"&" ++ unitaryFormulaParser) >> snd) >>
       
   626        (fn fs => fn f => Formula.listMkConj (f :: fs))) input
       
   627 
       
   628   and unitaryFormulaParser input =
       
   629       (quantifiedFormulaParser ||
       
   630        unaryFormulaParser ||
       
   631        ((punctParser #"(" ++ fofFormulaParser ++ punctParser #")") >>
       
   632         (fn ((),(f,())) => f)) ||
       
   633        (atomParser >>
       
   634         (fn Boolean b => Formula.mkBoolean b
       
   635           | Literal l => Literal.toFormula l))) input
       
   636 
       
   637   and quantifiedFormulaParser input =
       
   638       ((quantifierParser ++ varListParser ++ punctParser #":" ++
       
   639         unitaryFormulaParser) >>
       
   640        (fn (q,(v,((),f))) => q (v,f))) input
       
   641 
       
   642   and quantifierParser input =
       
   643       ((punctParser #"!" >> K Formula.listMkForall) ||
       
   644        (punctParser #"?" >> K Formula.listMkExists)) input
       
   645 
       
   646   and unaryFormulaParser input =
       
   647       ((unaryConnectiveParser ++ unitaryFormulaParser) >>
       
   648        (fn (c,f) => c f)) input
       
   649 
       
   650   and unaryConnectiveParser input =
       
   651       (punctParser #"~" >> K Formula.Not) input;
       
   652 
       
   653   val cnfParser =
       
   654       (alphaNumParser "cnf" ++ punctParser #"(" ++
       
   655        nameParser ++ punctParser #"," ++
       
   656        roleParser ++ punctParser #"," ++
       
   657        clauseParser ++ punctParser #")" ++
       
   658        punctParser #".") >>
       
   659       (fn ((),((),(n,((),(r,((),(c,((),())))))))) =>
       
   660           CnfFormula {name = n, role = r, clause = c});
       
   661 
       
   662   val fofParser =
       
   663       (alphaNumParser "fof" ++ punctParser #"(" ++
       
   664        nameParser ++ punctParser #"," ++
       
   665        roleParser ++ punctParser #"," ++
       
   666        fofFormulaParser ++ punctParser #")" ++
       
   667        punctParser #".") >>
       
   668       (fn ((),((),(n,((),(r,((),(f,((),())))))))) =>
       
   669           FofFormula {name = n, role = r, formula = f});
       
   670 
       
   671   val formulaParser = cnfParser || fofParser;
       
   672 
       
   673   fun parseChars parser chars =
       
   674       let
       
   675         val tokens = Parser.everything (lexer >> singleton) chars
       
   676       in
       
   677         Parser.everything (parser >> singleton) tokens
       
   678       end;
       
   679 
       
   680   fun canParseString parser s =
       
   681       let
       
   682         val chars = Stream.fromString s
       
   683       in
       
   684         case Stream.toList (parseChars parser chars) of
       
   685           [_] => true
       
   686         | _ => false
   344       end
   687       end
   345       handle Error err => raise Error ("bad name \"" ^ n ^ "\": " ^ err);
   688       handle NoParse => false;
   346 
   689 in
   347   fun mkMap set mapping =
   690   val parseFormula = parseChars formulaParser;
       
   691 
       
   692   val isTptpRelation = canParseString functionParser
       
   693   and isTptpProposition = canParseString propositionParser
       
   694   and isTptpFunction = canParseString functionParser
       
   695   and isTptpConstant = canParseString constantParser;
       
   696 end;
       
   697 
       
   698 fun formulaFromString s =
       
   699     case Stream.toList (parseFormula (Stream.fromList (explode s))) of
       
   700       [fm] => fm
       
   701     | _ => raise Parser.NoParse;
       
   702 
       
   703 local
       
   704   local
       
   705     fun explodeAlpha s = List.filter Char.isAlpha (explode s);
       
   706   in
       
   707     fun normTptpName s n =
       
   708         case explodeAlpha n of
       
   709           [] => s
       
   710         | c :: cs => implode (Char.toLower c :: cs);
       
   711 
       
   712     fun normTptpVar s n =
       
   713         case explodeAlpha n of
       
   714           [] => s
       
   715         | c :: cs => implode (Char.toUpper c :: cs);
       
   716   end;
       
   717 
       
   718   fun normTptpFunc (n,0) = if isTptpConstant n then n else normTptpName "c" n
       
   719     | normTptpFunc (n,_) = if isTptpFunction n then n else normTptpName "f" n;
       
   720 
       
   721   fun normTptpRel (n,0) = if isTptpProposition n then n else normTptpName "p" n
       
   722     | normTptpRel (n,_) = if isTptpRelation n then n else normTptpName "r" n;
       
   723 
       
   724   fun mkMap set norm mapping =
   348       let
   725       let
   349         val mapping = mappingToTptp mapping
   726         val mapping = mappingToTptp mapping
   350 
   727 
   351         fun mk ((n,r),(a,m)) =
   728         fun mk (n_r,(a,m)) =
   352             case NameArityMap.peek mapping (n,r) of
   729             case NameArityMap.peek mapping n_r of
   353               SOME t => (a, NameArityMap.insert m ((n,r),t))
   730               SOME t => (a, NameArityMap.insert m (n_r,t))
   354             | NONE =>
   731             | NONE =>
   355               let
   732               let
   356                 val t = mkTptpName a n
   733                 val t = norm n_r
       
   734                 val (n,_) = n_r
       
   735                 val t = if t = n then n else Term.variantNum a t
   357               in
   736               in
   358                 (NameSet.add a t, NameArityMap.insert m ((n,r),t))
   737                 (NameSet.add a t, NameArityMap.insert m (n_r,t))
   359               end
   738               end
   360 
   739 
   361         val avoid =
   740         val avoid =
   362             let
   741             let
   363               fun mk ((n,r),s) =
   742               fun mk ((n,r),s) =
   371             end
   750             end
   372       in
   751       in
   373         snd (NameAritySet.foldl mk (avoid, NameArityMap.new ()) set)
   752         snd (NameAritySet.foldl mk (avoid, NameArityMap.new ()) set)
   374       end;
   753       end;
   375 
   754 
   376   fun mkTptpVar a v =
   755   fun mkTptpVar a v = Term.variantNum a (normTptpVar "V" v);
   377       let
       
   378         val v' = mkTptpString v
       
   379 
       
   380         val v' =
       
   381             case explode v' of
       
   382               [] => raise Error "empty"
       
   383             | c :: cs =>
       
   384               if c = #"_" orelse Char.isUpper c then v'
       
   385               else if Char.isLower c then implode (Char.toUpper c :: cs)
       
   386               else raise Error "bad initial character"
       
   387       in
       
   388         Term.variantNum a v'
       
   389       end
       
   390       handle Error err => raise Error ("bad var \"" ^ v ^ "\": " ^ err);
       
   391 
   756 
   392   fun isTptpVar v = mkTptpVar NameSet.empty v = v;
   757   fun isTptpVar v = mkTptpVar NameSet.empty v = v;
   393 
   758 
   394   fun alphaFormula fm =
   759   fun alphaFormula fm =
   395       let
   760       let
   438   fun formulasToTptp formulas =
   803   fun formulasToTptp formulas =
   439       let
   804       let
   440         val funcs = formulasFunctions formulas
   805         val funcs = formulasFunctions formulas
   441         and rels = formulasRelations formulas
   806         and rels = formulasRelations formulas
   442                    
   807                    
   443         val functionMap = mkMap funcs (!functionMapping)
   808         val functionMap = mkMap funcs normTptpFunc (!functionMapping)
   444         and relationMap = mkMap rels (!relationMapping)
   809         and relationMap = mkMap rels normTptpRel (!relationMapping)
   445                           
   810 
   446         val maps = {functionMap = functionMap, relationMap = relationMap}
   811         val maps = {functionMap = functionMap, relationMap = relationMap}
   447       in
   812       in
   448         map (formulaToTptp maps) formulas
   813         map (formulaToTptp maps) formulas
   449       end;
   814       end;
   450 end;
   815 end;
   459       map (mapFormula maps) formulas
   824       map (mapFormula maps) formulas
   460     end;
   825     end;
   461 
   826 
   462 local
   827 local
   463   fun ppGen ppX pp (gen,name,role,x) =
   828   fun ppGen ppX pp (gen,name,role,x) =
   464       (PP.begin_block pp PP.INCONSISTENT (size gen + 1);
   829       (Parser.beginBlock pp Parser.Inconsistent (size gen + 1);
   465        PP.add_string pp (gen ^ "(" ^ name ^ ",");
   830        Parser.addString pp (gen ^ "(" ^ name ^ ",");
   466        PP.add_break pp (1,0);
   831        Parser.addBreak pp (1,0);
   467        PP.add_string pp (role ^ ",");
   832        Parser.addString pp (role ^ ",");
   468        PP.add_break pp (1,0);
   833        Parser.addBreak pp (1,0);
   469        PP.begin_block pp PP.CONSISTENT 1;
   834        Parser.beginBlock pp Parser.Consistent 1;
   470        PP.add_string pp "(";
   835        Parser.addString pp "(";
   471        ppX pp x;
   836        ppX pp x;
   472        PP.add_string pp ")";
   837        Parser.addString pp ")";
   473        PP.end_block pp;
   838        Parser.endBlock pp;
   474        PP.add_string pp ").";
   839        Parser.addString pp ").";
   475        PP.end_block pp);
   840        Parser.endBlock pp);
   476 in
   841 in
   477   fun ppFormula pp (CnfFormula {name,role,clause}) =
   842   fun ppFormula pp (CnfFormula {name,role,clause}) =
   478       ppGen ppClause pp ("cnf",name,role,clause)
   843       ppGen ppClause pp ("cnf",name,role,clause)
   479     | ppFormula pp (FofFormula {name,role,formula}) =
   844     | ppFormula pp (FofFormula {name,role,formula}) =
   480       ppGen ppFof pp ("fof",name,role,formula);
   845       ppGen ppFof pp ("fof",name,role,formula);
   481 end;
   846 end;
   482 
   847 
   483 val formulaToString = Parser.toString ppFormula;
   848 val formulaToString = Parser.toString ppFormula;
   484 
       
   485 local
       
   486   open Parser;
       
   487 
       
   488   infixr 8 ++
       
   489   infixr 7 >>
       
   490   infixr 6 ||
       
   491 
       
   492   datatype token = AlphaNum of string | Punct of char;
       
   493 
       
   494   local
       
   495     fun isAlphaNum #"_" = true
       
   496       | isAlphaNum c = Char.isAlphaNum c;
       
   497 
       
   498     val alphaNumToken = atLeastOne (some isAlphaNum) >> (AlphaNum o implode);
       
   499 
       
   500     val punctToken =
       
   501         let
       
   502           val punctChars = explode "<>=-*+/\\?@|!$%&#^:;~()[]{}.,"
       
   503 
       
   504           fun isPunctChar c = mem c punctChars
       
   505         in
       
   506           some isPunctChar >> Punct
       
   507         end;
       
   508 
       
   509     val lexToken = alphaNumToken || punctToken;
       
   510 
       
   511     val space = many (some Char.isSpace);
       
   512   in
       
   513     val lexer = (space ++ lexToken ++ space) >> (fn (_,(tok,_)) => tok);
       
   514   end;
       
   515 
       
   516   fun someAlphaNum p =
       
   517       maybe (fn AlphaNum s => if p s then SOME s else NONE | _ => NONE);
       
   518 
       
   519   fun alphaNumParser s = someAlphaNum (equal s) >> K ();
       
   520 
       
   521   val lowerParser = someAlphaNum (fn s => Char.isLower (String.sub (s,0)));
       
   522 
       
   523   val upperParser = someAlphaNum (fn s => Char.isUpper (String.sub (s,0)));
       
   524 
       
   525   val stringParser = lowerParser || upperParser;
       
   526 
       
   527   val numberParser = someAlphaNum (List.all Char.isDigit o explode);
       
   528 
       
   529   fun somePunct p =
       
   530       maybe (fn Punct c => if p c then SOME c else NONE | _ => NONE);
       
   531 
       
   532   fun punctParser c = somePunct (equal c) >> K ();
       
   533 
       
   534   local
       
   535     fun f [] = raise Bug "symbolParser"
       
   536       | f [x] = x
       
   537       | f (h :: t) = (h ++ f t) >> K ();
       
   538   in
       
   539     fun symbolParser s = f (map punctParser (explode s));
       
   540   end;
       
   541 
       
   542   val varParser = upperParser;
       
   543 
       
   544   val varListParser =
       
   545       (punctParser #"[" ++ varParser ++
       
   546        many ((punctParser #"," ++ varParser) >> snd) ++
       
   547        punctParser #"]") >>
       
   548       (fn ((),(h,(t,()))) => h :: t);
       
   549 
       
   550   val functionParser = lowerParser;
       
   551 
       
   552   val constantParser = lowerParser || numberParser;
       
   553 
       
   554   val propositionParser = lowerParser;
       
   555 
       
   556   val booleanParser =
       
   557       (punctParser #"$" ++
       
   558        ((alphaNumParser "true" >> K true) ||
       
   559         (alphaNumParser "false" >> K false))) >> snd;
       
   560 
       
   561   fun termParser input =
       
   562       ((functionArgumentsParser >> Term.Fn) ||
       
   563        nonFunctionArgumentsTermParser) input
       
   564 
       
   565   and functionArgumentsParser input =
       
   566       ((functionParser ++ punctParser #"(" ++ termParser ++
       
   567         many ((punctParser #"," ++ termParser) >> snd) ++
       
   568         punctParser #")") >>
       
   569        (fn (f,((),(t,(ts,())))) => (f, t :: ts))) input
       
   570 
       
   571   and nonFunctionArgumentsTermParser input =
       
   572       ((varParser >> Term.Var) ||
       
   573        (constantParser >> (fn n => Term.Fn (n,[])))) input
       
   574 
       
   575   val binaryAtomParser =
       
   576       ((punctParser #"=" ++ termParser) >>
       
   577        (fn ((),r) => fn l => Literal.mkEq (l,r))) ||
       
   578       ((symbolParser "!=" ++ termParser) >>
       
   579        (fn ((),r) => fn l => Literal.mkNeq (l,r)));
       
   580 
       
   581   val maybeBinaryAtomParser =
       
   582       optional binaryAtomParser >>
       
   583       (fn SOME f => (fn a => f (Term.Fn a))
       
   584         | NONE => (fn a => (true,a)));
       
   585 
       
   586   val literalAtomParser =
       
   587       ((functionArgumentsParser ++ maybeBinaryAtomParser) >>
       
   588        (fn (a,f) => f a)) ||
       
   589       ((nonFunctionArgumentsTermParser ++ binaryAtomParser) >>
       
   590        (fn (a,f) => f a)) ||
       
   591       (propositionParser >>
       
   592        (fn n => (true,(n,[]))));
       
   593 
       
   594   val atomParser =
       
   595       (booleanParser >> Boolean) ||
       
   596       (literalAtomParser >> Literal);
       
   597 
       
   598   val literalParser =
       
   599       ((punctParser #"~" ++ atomParser) >> (negate o snd)) ||
       
   600       atomParser;
       
   601 
       
   602   val disjunctionParser =
       
   603       (literalParser ++ many ((punctParser #"|" ++ literalParser) >> snd)) >>
       
   604       (fn (h,t) => h :: t);
       
   605 
       
   606   val clauseParser =
       
   607       ((punctParser #"(" ++ disjunctionParser ++ punctParser #")") >>
       
   608        (fn ((),(c,())) => c)) ||
       
   609       disjunctionParser;
       
   610 
       
   611 (*
       
   612   An exact transcription of the fof_formula syntax from
       
   613 
       
   614     TPTP-v3.2.0/Documents/SyntaxBNF,
       
   615 
       
   616   fun fofFormulaParser input =
       
   617       (binaryFormulaParser || unitaryFormulaParser) input
       
   618   
       
   619   and binaryFormulaParser input =
       
   620       (nonAssocBinaryFormulaParser || assocBinaryFormulaParser) input
       
   621 
       
   622   and nonAssocBinaryFormulaParser input =
       
   623       ((unitaryFormulaParser ++ binaryConnectiveParser ++
       
   624         unitaryFormulaParser) >>
       
   625        (fn (f,(c,g)) => c (f,g))) input
       
   626 
       
   627   and binaryConnectiveParser input =
       
   628       ((symbolParser "<=>" >> K Formula.Iff) ||
       
   629        (symbolParser "=>" >> K Formula.Imp) ||
       
   630        (symbolParser "<=" >> K (fn (f,g) => Formula.Imp (g,f))) ||
       
   631        (symbolParser "<~>" >> K (Formula.Not o Formula.Iff)) ||
       
   632        (symbolParser "~|" >> K (Formula.Not o Formula.Or)) ||
       
   633        (symbolParser "~&" >> K (Formula.Not o Formula.And))) input
       
   634 
       
   635   and assocBinaryFormulaParser input =
       
   636       (orFormulaParser || andFormulaParser) input
       
   637 
       
   638   and orFormulaParser input =
       
   639       ((unitaryFormulaParser ++
       
   640         atLeastOne ((punctParser #"|" ++ unitaryFormulaParser) >> snd)) >>
       
   641        (fn (f,fs) => Formula.listMkDisj (f :: fs))) input
       
   642 
       
   643   and andFormulaParser input =
       
   644       ((unitaryFormulaParser ++
       
   645         atLeastOne ((punctParser #"&" ++ unitaryFormulaParser) >> snd)) >>
       
   646        (fn (f,fs) => Formula.listMkConj (f :: fs))) input
       
   647 
       
   648   and unitaryFormulaParser input =
       
   649       (quantifiedFormulaParser ||
       
   650        unaryFormulaParser ||
       
   651        ((punctParser #"(" ++ fofFormulaParser ++ punctParser #")") >>
       
   652         (fn ((),(f,())) => f)) ||
       
   653        (atomParser >>
       
   654         (fn Boolean b => Formula.mkBoolean b
       
   655           | Literal l => Literal.toFormula l))) input
       
   656 
       
   657   and quantifiedFormulaParser input =
       
   658       ((quantifierParser ++ varListParser ++ punctParser #":" ++
       
   659         unitaryFormulaParser) >>
       
   660        (fn (q,(v,((),f))) => q (v,f))) input
       
   661 
       
   662   and quantifierParser input =
       
   663       ((punctParser #"!" >> K Formula.listMkForall) ||
       
   664        (punctParser #"?" >> K Formula.listMkExists)) input
       
   665 
       
   666   and unaryFormulaParser input =
       
   667       ((unaryConnectiveParser ++ unitaryFormulaParser) >>
       
   668        (fn (c,f) => c f)) input
       
   669 
       
   670   and unaryConnectiveParser input =
       
   671       (punctParser #"~" >> K Formula.Not) input;
       
   672 *)
       
   673 
       
   674 (*
       
   675   This version is supposed to be equivalent to the spec version above,
       
   676   but uses closures to avoid reparsing prefixes.
       
   677 *)
       
   678 
       
   679   fun fofFormulaParser input =
       
   680       ((unitaryFormulaParser ++ optional binaryFormulaParser) >>
       
   681        (fn (f,NONE) => f | (f, SOME t) => t f)) input
       
   682   
       
   683   and binaryFormulaParser input =
       
   684       (nonAssocBinaryFormulaParser || assocBinaryFormulaParser) input
       
   685 
       
   686   and nonAssocBinaryFormulaParser input =
       
   687       ((binaryConnectiveParser ++ unitaryFormulaParser) >>
       
   688        (fn (c,g) => fn f => c (f,g))) input
       
   689 
       
   690   and binaryConnectiveParser input =
       
   691       ((symbolParser "<=>" >> K Formula.Iff) ||
       
   692        (symbolParser "=>" >> K Formula.Imp) ||
       
   693        (symbolParser "<=" >> K (fn (f,g) => Formula.Imp (g,f))) ||
       
   694        (symbolParser "<~>" >> K (Formula.Not o Formula.Iff)) ||
       
   695        (symbolParser "~|" >> K (Formula.Not o Formula.Or)) ||
       
   696        (symbolParser "~&" >> K (Formula.Not o Formula.And))) input
       
   697 
       
   698   and assocBinaryFormulaParser input =
       
   699       (orFormulaParser || andFormulaParser) input
       
   700 
       
   701   and orFormulaParser input =
       
   702       (atLeastOne ((punctParser #"|" ++ unitaryFormulaParser) >> snd) >>
       
   703        (fn fs => fn f => Formula.listMkDisj (f :: fs))) input
       
   704 
       
   705   and andFormulaParser input =
       
   706       (atLeastOne ((punctParser #"&" ++ unitaryFormulaParser) >> snd) >>
       
   707        (fn fs => fn f => Formula.listMkConj (f :: fs))) input
       
   708 
       
   709   and unitaryFormulaParser input =
       
   710       (quantifiedFormulaParser ||
       
   711        unaryFormulaParser ||
       
   712        ((punctParser #"(" ++ fofFormulaParser ++ punctParser #")") >>
       
   713         (fn ((),(f,())) => f)) ||
       
   714        (atomParser >>
       
   715         (fn Boolean b => Formula.mkBoolean b
       
   716           | Literal l => Literal.toFormula l))) input
       
   717 
       
   718   and quantifiedFormulaParser input =
       
   719       ((quantifierParser ++ varListParser ++ punctParser #":" ++
       
   720         unitaryFormulaParser) >>
       
   721        (fn (q,(v,((),f))) => q (v,f))) input
       
   722 
       
   723   and quantifierParser input =
       
   724       ((punctParser #"!" >> K Formula.listMkForall) ||
       
   725        (punctParser #"?" >> K Formula.listMkExists)) input
       
   726 
       
   727   and unaryFormulaParser input =
       
   728       ((unaryConnectiveParser ++ unitaryFormulaParser) >>
       
   729        (fn (c,f) => c f)) input
       
   730 
       
   731   and unaryConnectiveParser input =
       
   732       (punctParser #"~" >> K Formula.Not) input;
       
   733 
       
   734   val cnfParser =
       
   735       (alphaNumParser "cnf" ++ punctParser #"(" ++
       
   736        stringParser ++ punctParser #"," ++
       
   737        stringParser ++ punctParser #"," ++
       
   738        clauseParser ++ punctParser #")" ++
       
   739        punctParser #".") >>
       
   740       (fn ((),((),(n,((),(r,((),(c,((),())))))))) =>
       
   741           CnfFormula {name = n, role = r, clause = c});
       
   742 
       
   743   val fofParser =
       
   744       (alphaNumParser "fof" ++ punctParser #"(" ++
       
   745        stringParser ++ punctParser #"," ++
       
   746        stringParser ++ punctParser #"," ++
       
   747        fofFormulaParser ++ punctParser #")" ++
       
   748        punctParser #".") >>
       
   749       (fn ((),((),(n,((),(r,((),(f,((),())))))))) =>
       
   750           FofFormula {name = n, role = r, formula = f});
       
   751 
       
   752   val formulaParser = cnfParser || fofParser;
       
   753 in
       
   754   fun parseFormula chars =
       
   755       let
       
   756         val tokens = Parser.everything (lexer >> singleton) chars
       
   757                      
       
   758         val formulas = Parser.everything (formulaParser >> singleton) tokens
       
   759       in
       
   760         formulas
       
   761       end;
       
   762 end;
       
   763 
       
   764 fun formulaFromString s =
       
   765     case Stream.toList (parseFormula (Stream.fromList (explode s))) of
       
   766       [fm] => fm
       
   767     | _ => raise Parser.NoParse;
       
   768 
   849 
   769 (* ------------------------------------------------------------------------- *)
   850 (* ------------------------------------------------------------------------- *)
   770 (* TPTP problems.                                                            *)
   851 (* TPTP problems.                                                            *)
   771 (* ------------------------------------------------------------------------- *)
   852 (* ------------------------------------------------------------------------- *)
   772 
   853 
   791 
   872 
   792         val lines = Stream.map chomp lines
   873         val lines = Stream.map chomp lines
   793 
   874 
   794         val (comments,lines) = stripComments [] lines
   875         val (comments,lines) = stripComments [] lines
   795 
   876 
   796         val chars =
   877         val chars = Stream.concat (Stream.map Stream.fromString lines)
   797             let
       
   798               fun f line = Stream.fromList (explode line)
       
   799             in
       
   800               Stream.concat (Stream.map f lines)
       
   801             end
       
   802 
   878 
   803         val formulas = Stream.toList (parseFormula chars)
   879         val formulas = Stream.toList (parseFormula chars)
   804 
   880 
   805         val formulas = formulasFromTptp formulas
   881         val formulas = formulasFromTptp formulas
   806       in
   882       in
   893 end;
   969 end;
   894 
   970 
   895 local
   971 local
   896   fun fromClause cl n =
   972   fun fromClause cl n =
   897       let
   973       let
   898         val name = "clause" ^ Int.toString n
   974         val name = "clause_" ^ Int.toString n
   899         val role = ROLE_NEGATED_CONJECTURE
   975         val role = ROLE_NEGATED_CONJECTURE
   900         val clause =
   976         val clause = clauseFromLiteralSet cl
   901             clauseFromFormula
       
   902               (Formula.listMkDisj (LiteralSet.transform Literal.toFormula cl))
       
   903       in
   977       in
   904         (CnfFormula {name = name, role = role, clause = clause}, n + 1)
   978         (CnfFormula {name = name, role = role, clause = clause}, n + 1)
   905       end;
   979       end;
   906 in
   980 in
   907   fun fromProblem prob =
   981   fun fromProblem prob =
   933       in
  1007       in
   934         List.all refute problems
  1008         List.all refute problems
   935       end;
  1009       end;
   936 end;
  1010 end;
   937 
  1011 
       
  1012 (* ------------------------------------------------------------------------- *)
       
  1013 (* TSTP proofs.                                                              *)
       
  1014 (* ------------------------------------------------------------------------- *)
       
  1015 
       
  1016 local
       
  1017   fun ppAtomInfo pp atm =
       
  1018       case total Atom.destEq atm of
       
  1019         SOME (a,b) => ppAtom pp ("$equal",[a,b])
       
  1020       | NONE => ppAtom pp atm;
       
  1021 
       
  1022   fun ppLiteralInfo pp (pol,atm) =
       
  1023       if pol then ppAtomInfo pp atm
       
  1024       else
       
  1025         (Parser.beginBlock pp Parser.Inconsistent 2;
       
  1026          Parser.addString pp "~";
       
  1027          Parser.addBreak pp (1,0);
       
  1028          ppAtomInfo pp atm;
       
  1029          Parser.endBlock pp);
       
  1030 
       
  1031   val ppAssumeInfo = Parser.ppBracket "(" ")" ppAtomInfo;
       
  1032 
       
  1033   val ppSubstInfo =
       
  1034       Parser.ppMap
       
  1035         Subst.toList
       
  1036         (Parser.ppSequence ","
       
  1037            (Parser.ppBracket "[" "]"
       
  1038               (Parser.ppBinop "," ppVar (Parser.ppBracket "(" ")" ppTerm))));
       
  1039 
       
  1040   val ppResolveInfo = Parser.ppBracket "(" ")" ppAtomInfo;
       
  1041 
       
  1042   val ppReflInfo = Parser.ppBracket "(" ")" ppTerm;
       
  1043         
       
  1044   fun ppEqualityInfo pp (lit,path,res) =
       
  1045       (Parser.ppBracket "(" ")" ppLiteralInfo pp lit;
       
  1046        Parser.addString pp ",";
       
  1047        Parser.addBreak pp (1,0);
       
  1048        Term.ppPath pp path;
       
  1049        Parser.addString pp ",";
       
  1050        Parser.addBreak pp (1,0);
       
  1051        Parser.ppBracket "(" ")" ppTerm pp res);
       
  1052 
       
  1053   fun ppInfInfo pp inf =
       
  1054       case inf of
       
  1055         Proof.Axiom _ => raise Bug "ppInfInfo"
       
  1056       | Proof.Assume atm => ppAssumeInfo pp atm
       
  1057       | Proof.Subst (sub,_) => ppSubstInfo pp sub
       
  1058       | Proof.Resolve (res,_,_) => ppResolveInfo pp res
       
  1059       | Proof.Refl tm => ppReflInfo pp tm
       
  1060       | Proof.Equality x => ppEqualityInfo pp x;
       
  1061 in
       
  1062   fun ppProof p prf =
       
  1063       let
       
  1064         fun thmString n = Int.toString n
       
  1065                           
       
  1066         val prf = enumerate prf
       
  1067 
       
  1068         fun ppThm p th =
       
  1069             let
       
  1070               val cl = Thm.clause th
       
  1071 
       
  1072               fun pred (_,(th',_)) = LiteralSet.equal (Thm.clause th') cl
       
  1073             in
       
  1074               case List.find pred prf of
       
  1075                 NONE => Parser.addString p "(?)"
       
  1076               | SOME (n,_) => Parser.addString p (thmString n)
       
  1077             end
       
  1078 
       
  1079         fun ppInf p inf =
       
  1080             let
       
  1081               val name = Thm.inferenceTypeToString (Proof.inferenceType inf)
       
  1082               val name = String.map Char.toLower name
       
  1083             in
       
  1084               Parser.addString p (name ^ ",");
       
  1085               Parser.addBreak p (1,0);
       
  1086               Parser.ppBracket "[" "]" ppInfInfo p inf;
       
  1087               case Proof.parents inf of
       
  1088                 [] => ()
       
  1089               | ths =>
       
  1090                 (Parser.addString p ",";
       
  1091                  Parser.addBreak p (1,0);
       
  1092                  Parser.ppList ppThm p ths)
       
  1093             end
       
  1094               
       
  1095         fun ppTaut p inf =
       
  1096             (Parser.addString p "tautology,";
       
  1097              Parser.addBreak p (1,0);
       
  1098              Parser.ppBracket "[" "]" ppInf p inf)
       
  1099              
       
  1100         fun ppStepInfo p (n,(th,inf)) =
       
  1101             let
       
  1102               val is_axiom = case inf of Proof.Axiom _ => true | _ => false
       
  1103               val name = thmString n
       
  1104               val role =
       
  1105                   if is_axiom then "axiom"
       
  1106                   else if Thm.isContradiction th then "theorem"
       
  1107                   else "plain"
       
  1108               val cl = clauseFromThm th
       
  1109             in
       
  1110               Parser.addString p (name ^ ",");
       
  1111               Parser.addBreak p (1,0);
       
  1112               Parser.addString p (role ^ ",");
       
  1113               Parser.addBreak p (1,0);
       
  1114               Parser.ppBracket "(" ")" ppClause p cl;
       
  1115               if is_axiom then ()
       
  1116               else
       
  1117                 let
       
  1118                   val is_tautology = null (Proof.parents inf)
       
  1119                 in
       
  1120                   Parser.addString p ",";
       
  1121                   Parser.addBreak p (1,0);
       
  1122                   if is_tautology then
       
  1123                     Parser.ppBracket "introduced(" ")" ppTaut p inf
       
  1124                   else
       
  1125                     Parser.ppBracket "inference(" ")" ppInf p inf
       
  1126                 end
       
  1127             end
       
  1128 
       
  1129         fun ppStep p step =
       
  1130             (Parser.ppBracket "cnf(" ")" ppStepInfo p step;
       
  1131              Parser.addString p ".";
       
  1132              Parser.addNewline p)
       
  1133       in
       
  1134         Parser.beginBlock p Parser.Consistent 0;
       
  1135         app (ppStep p) prf;
       
  1136         Parser.endBlock p
       
  1137       end
       
  1138 (*DEBUG
       
  1139       handle Error err => raise Bug ("Tptp.ppProof: shouldn't fail:\n" ^ err);
       
  1140 *)
       
  1141 end;
       
  1142 
       
  1143 val proofToString = Parser.toString ppProof;
       
  1144 
   938 end
  1145 end