(* ========================================================================= *) (* PROOFS IN FIRST ORDER LOGIC *) (* Copyright (c) 2001 Joe Leslie-Hurd, distributed under the BSD License *) (* ========================================================================= *)
structure Proof :> Proof = struct
open Useful;
(* ------------------------------------------------------------------------- *) (* A type of first order logic proofs. *) (* ------------------------------------------------------------------------- *)
datatype inference =
Axiom of LiteralSet.set
| Assume of Atom.atom
| Subst of Subst.subst * Thm.thm
| Resolve of Atom.atom * Thm.thm * Thm.thm
| Refl of Term.term
| Equality of Literal.literal * Term.path * Term.term;
fun ppInf ppAxiom ppThm inf = let val infString = Thm.inferenceTypeToString (inferenceType inf) in Print.inconsistentBlock 2
[Print.ppString infString,
(case inf of
Axiom cl => ppAxiom cl
| Assume x => ppAssume x
| Subst x => ppSubst ppThm x
| Resolve x => ppResolve ppThm x
| Refl x => ppRefl x
| Equality x => ppEquality x)] end;
fun ppAxiom cl = Print.sequence Print.break
(Print.ppMap
LiteralSet.toList
(Print.ppBracket "{""}" (Print.ppOpList "," Literal.pp)) cl); in val ppInference = ppInf ppAxiom Thm.pp;
fun pp prf = let fun thmString n = "(" ^ Int.toString n ^ ")"
val prf = enumerate prf
fun ppThm th = Print.ppString let val cl = Thm.clause th
fun pred (_,(th',_)) = LiteralSet.equal (Thm.clause th') cl in caseList.find pred prf of
NONE => "(?)"
| SOME (n,_) => thmString n end
fun ppStep (n,(th,inf)) = let val s = thmString n in Print.sequence
(Print.consistentBlock (1 + size s)
[Print.ppString (s ^ " "),
Thm.pp th, Print.breaks 2, Print.ppBracket "[""]" (ppInf (K Print.skip) ppThm) inf]) Print.newline end in Print.consistentBlock 0
[Print.ppString "START OF PROOF", Print.newline, Print.program (List.map ppStep prf), Print.ppString "END OF PROOF"] end (*MetisDebug handleErrorerr=>raiseBug("Proof.pp:shouldn'tfail:\n"^err);
*)
end;
val inferenceToString = Print.toString ppInference;
local fun reconstructSubst cl cl' = let fun recon [] = let (*MetisTrace3 val()=Print.traceLiteralSet.pp"reconstructSubst:cl"cl val()=Print.traceLiteralSet.pp"reconstructSubst:cl'"cl'
*) in raise Bug "can't reconstruct Subst rule" end
| recon (([],sub) :: others) = if LiteralSet.equal (LiteralSet.subst sub cl) cl' then sub else recon others
| recon ((lit :: lits, sub) :: others) = let fun checkLit (lit',acc) = case total (Literal.matchsub lit) lit' of
NONE => acc
| SOME sub => (lits,sub) :: acc in
recon (LiteralSet.foldl checkLit others cl') end in
Subst.normalize (recon [(LiteralSet.toList cl, Subst.empty)]) end (*MetisDebug handleErrorerr=> raiseBug("Proof.recontructSubst:shouldn'tfail:\n"^err);
*)
fun reconstructResolvant cl1 cl2 cl =
(ifnot (LiteralSet.subset cl1 cl) then
LiteralSet.pick (LiteralSet.difference cl1 cl) elseifnot (LiteralSet.subset cl2 cl) then
Literal.negate (LiteralSet.pick (LiteralSet.difference cl2 cl)) else (* A useless resolution, but we must reconstruct it anyway *) let val cl1' = LiteralSet.negate cl1 and cl2' = LiteralSet.negate cl2 val lits = LiteralSet.intersectList [cl1,cl1',cl2,cl2'] in ifnot (LiteralSet.null lits) then LiteralSet.pick lits elseraise Bug "can't reconstruct Resolve rule" end) (*MetisDebug handleErrorerr=> raiseBug("Proof.recontructResolvant:shouldn'tfail:\n"^err);
*)
fun reconstructEquality cl = let (*MetisTrace3 val()=Print.traceLiteralSet.pp"Proof.reconstructEquality:cl"cl
*)
fun sync s t path (f,a) (f',a') = ifnot (Name.equal f f' andalso length a = length a') then NONE else let val itms = enumerate (zip a a') in caseList.filter (not o uncurry Term.equal o snd) itms of
[(i,(tm,tm'))] => let val path = i :: path in if Term.equal tm s andalso Term.equal tm' t then
SOME (List.rev path) else case (tm,tm') of
(Term.Fn f_a, Term.Fn f_a') => sync s t path f_a f_a'
| _ => NONE end
| _ => NONE end
fun recon (neq,(pol,atm),(pol',atm')) = if pol = pol' then NONE else let val (s,t) = Literal.destNeq neq
val path = ifnot (Term.equal s t) then sync s t [] atm atm' elseifnot (Atom.equal atm atm') then NONE else Atom.find (Term.equal s) atm in case path of
SOME path => SOME ((pol',atm),path,t)
| NONE => NONE end
(*MetisTrace3 valppCands= Print.ppList(Print.ppTripleLiteral.ppLiteral.ppLiteral.pp) val()=Print.traceppCands "Proof.reconstructEquality:candidates"candidates
*) in case first recon candidates of
SOME info => info
| NONE => raise Bug "can't reconstruct Equality rule" end (*MetisDebug handleErrorerr=> raiseBug("Proof.recontructEquality:shouldn'tfail:\n"^err);
*)
fun reconstruct cl (Thm.Axiom,[]) = Axiom cl
| reconstruct cl (Thm.Assume,[]) =
(case LiteralSet.findl Literal.positive cl of
SOME (_,atm) => Assume atm
| NONE => raise Bug "malformed Assume inference")
| reconstruct cl (Thm.Subst,[th]) =
Subst (reconstructSubst (Thm.clause th) cl, th)
| reconstruct cl (Thm.Resolve,[th1,th2]) = let val cl1 = Thm.clause th1 and cl2 = Thm.clause th2 val (pol,atm) = reconstructResolvant cl1 cl2 cl in if pol then Resolve (atm,th1,th2) else Resolve (atm,th2,th1) end
| reconstruct cl (Thm.Refl,[]) =
(case LiteralSet.findl (K true) cl of
SOME lit => Refl (Literal.destRefl lit)
| NONE => raise Bug "malformed Refl inference")
| reconstruct cl (Thm.Equality,[]) = Equality (reconstructEquality cl)
| reconstruct _ _ = raise Bug "malformed inference"; in fun thmToInference th = let (*MetisTrace3 val()=Print.traceThm.pp"Proof.thmToInference:th"th
*)
local val emptyThms : Thm.thm LiteralSetMap.map = LiteralSetMap.new ();
fun addThms (th,ths) = let val cl = Thm.clause th in if LiteralSetMap.inDomain cl ths then ths else let val (_,pars) = Thm.inference th val ths = List.foldl addThms ths pars in if LiteralSetMap.inDomain cl ths then ths else LiteralSetMap.insert ths (cl,th) end end;
fun mkThms th = addThms (th,emptyThms);
fun addProof (th,(ths,acc)) = let val cl = Thm.clause th in case LiteralSetMap.peek ths cl of
NONE => (ths,acc)
| SOME th => let val (_,pars) = Thm.inference th val (ths,acc) = List.foldl addProof (ths,acc) pars val ths = LiteralSetMap.delete ths cl val acc = (th, thmToInference th) :: acc in
(ths,acc) end end;
fun mkProof ths th = let val (ths,acc) = addProof (th,(ths,[])) (*MetisTrace4 val()=Print.tracePrint.ppInt"Proof.proof:unnecessaryclauses"(LiteralSetMap.sizeths)
*) in List.rev acc end; in fun proof th = let (*MetisTrace3 val()=Print.traceThm.pp"Proof.proof:th"th
*) val ths = mkThms th val infs = mkProof ths th (*MetisTrace3 val()=Print.tracePrint.ppInt"Proof.proof:size"(lengthinfs)
*) in
infs end; end;
fun freeIn v = let fun free th_inf = case th_inf of
(_, Axiom lits) => LiteralSet.freeIn v lits
| (_, Assume atm) => Atom.freeIn v atm
| (th, Subst _) => Thm.freeIn v th
| (_, Resolve _) => false
| (_, Refl tm) => Term.freeIn v tm
| (_, Equality (lit,_,tm)) =>
Literal.freeIn v lit orelse Term.freeIn v tm in List.exists free end;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.