(* ========================================================================= *) (* 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 handle Error err => raise Bug ("Proof.pp: shouldn't fail:\n" ^ err);
*)
end;
val inferenceToString = Print.toString ppInference;
local fun reconstructSubst cl cl' = let fun recon [] = let (*MetisTrace3 val () = Print.trace LiteralSet.pp "reconstructSubst: cl" cl val () = Print.trace LiteralSet.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 handle Error err => raise Bug ("Proof.recontructSubst: shouldn't fail:\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 handle Error err => raise Bug ("Proof.recontructResolvant: shouldn't fail:\n" ^ err);
*)
fun reconstructEquality cl = let (*MetisTrace3 val () = Print.trace LiteralSet.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
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.trace Print.ppInt "Proof.proof: unnecessary clauses" (LiteralSetMap.size ths)
*) in List.rev acc end; in fun proof th = let (*MetisTrace3 val () = Print.trace Thm.pp "Proof.proof: th" th
*) val ths = mkThms th val infs = mkProof ths th (*MetisTrace3 val () = Print.trace Print.ppInt "Proof.proof: size" (length infs)
*) 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 ist noch experimentell.