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 (* ------------------------------------------------------------------------- *) |
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) = |
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 |
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 |