(* ========================================================================= *) (* FIRST ORDER LOGIC FORMULAS *) (* Copyright (c) 2001 Joe Leslie-Hurd, distributed under the BSD License *) (* ========================================================================= *)
structure Formula :> Formula = struct
open Useful;
(* ------------------------------------------------------------------------- *) (* A type of first order logic formulas. *) (* ------------------------------------------------------------------------- *)
datatype formula = True
| False
| Atom of Atom.atom
| Notof formula
| Andof formula * formula
| Orof formula * formula
| Imp of formula * formula
| Iff of formula * formula
| Forall of Term.var * formula
| Existsof Term.var * formula;
fun listMkExists ([],body) = body
| listMkExists (v :: vs, body) = Exists (v, listMkExists (vs,body));
fun setMkExists (vs,body) = NameSet.foldr Exists body vs;
local fun strip vs (Exists (v,b)) = strip (v :: vs) b
| strip vs tm = (List.rev vs, tm); in val stripExists = strip []; end;
(* ------------------------------------------------------------------------- *) (* The size of a formula in symbols. *) (* ------------------------------------------------------------------------- *)
local fun sz n [] = n
| sz n (True :: fms) = sz (n + 1) fms
| sz n (False :: fms) = sz (n + 1) fms
| sz n (Atom atm :: fms) = sz (n + Atom.symbols atm) fms
| sz n (Not p :: fms) = sz (n + 1) (p :: fms)
| sz n (And (p,q) :: fms) = sz (n + 1) (p :: q :: fms)
| sz n (Or (p,q) :: fms) = sz (n + 1) (p :: q :: fms)
| sz n (Imp (p,q) :: fms) = sz (n + 1) (p :: q :: fms)
| sz n (Iff (p,q) :: fms) = sz (n + 1) (p :: q :: fms)
| sz n (Forall (_,p) :: fms) = sz (n + 1) (p :: fms)
| sz n (Exists (_,p) :: fms) = sz (n + 1) (p :: fms); in fun symbols fm = sz 0 [fm]; end;
(* ------------------------------------------------------------------------- *) (* A total comparison function for formulas. *) (* ------------------------------------------------------------------------- *)
local fun cmp [] = EQUAL
| cmp (f1_f2 :: fs) = if Portable.pointerEqual f1_f2 then cmp fs else case f1_f2 of
(True,True) => cmp fs
| (True,_) => LESS
| (_,True) => GREATER
| (False,False) => cmp fs
| (False,_) => LESS
| (_,False) => GREATER
| (Atom atm1, Atom atm2) =>
(case Atom.compare (atm1,atm2) of
LESS => LESS
| EQUAL => cmp fs
| GREATER => GREATER)
| (Atom _, _) => LESS
| (_, Atom _) => GREATER
| (Not p1, Not p2) => cmp ((p1,p2) :: fs)
| (Not _, _) => LESS
| (_, Not _) => GREATER
| (And (p1,q1), And (p2,q2)) => cmp ((p1,p2) :: (q1,q2) :: fs)
| (And _, _) => LESS
| (_, And _) => GREATER
| (Or (p1,q1), Or (p2,q2)) => cmp ((p1,p2) :: (q1,q2) :: fs)
| (Or _, _) => LESS
| (_, Or _) => GREATER
| (Imp (p1,q1), Imp (p2,q2)) => cmp ((p1,p2) :: (q1,q2) :: fs)
| (Imp _, _) => LESS
| (_, Imp _) => GREATER
| (Iff (p1,q1), Iff (p2,q2)) => cmp ((p1,p2) :: (q1,q2) :: fs)
| (Iff _, _) => LESS
| (_, Iff _) => GREATER
| (Forall (v1,p1), Forall (v2,p2)) =>
(case Name.compare (v1,v2) of
LESS => LESS
| EQUAL => cmp ((p1,p2) :: fs)
| GREATER => GREATER)
| (Forall _, Exists _) => LESS
| (Exists _, Forall _) => GREATER
| (Exists (v1,p1), Exists (v2,p2)) =>
(case Name.compare (v1,v2) of
LESS => LESS
| EQUAL => cmp ((p1,p2) :: fs)
| GREATER => GREATER); in fun compare fm1_fm2 = cmp [fm1_fm2]; end;
fun freeIn v = let fun f [] = false
| f (True :: fms) = f fms
| f (False :: fms) = f fms
| f (Atom atm :: fms) = Atom.freeIn v atm orelse f fms
| f (Not p :: fms) = f (p :: fms)
| f (And (p,q) :: fms) = f (p :: q :: fms)
| f (Or (p,q) :: fms) = f (p :: q :: fms)
| f (Imp (p,q) :: fms) = f (p :: q :: fms)
| f (Iff (p,q) :: fms) = f (p :: q :: fms)
| f (Forall (w,p) :: fms) = if Name.equal v w then f fms else f (p :: fms)
| f (Exists (w,p) :: fms) = if Name.equal v w then f fms else f (p :: fms) in
fn fm => f [fm] end;
local fun fv vs [] = vs
| fv vs ((_,True) :: fms) = fv vs fms
| fv vs ((_,False) :: fms) = fv vs fms
| fv vs ((bv, Atom atm) :: fms) =
fv (NameSet.union vs (NameSet.difference (Atom.freeVars atm) bv)) fms
| fv vs ((bv, Not p) :: fms) = fv vs ((bv,p) :: fms)
| fv vs ((bv, And (p,q)) :: fms) = fv vs ((bv,p) :: (bv,q) :: fms)
| fv vs ((bv, Or (p,q)) :: fms) = fv vs ((bv,p) :: (bv,q) :: fms)
| fv vs ((bv, Imp (p,q)) :: fms) = fv vs ((bv,p) :: (bv,q) :: fms)
| fv vs ((bv, Iff (p,q)) :: fms) = fv vs ((bv,p) :: (bv,q) :: fms)
| fv vs ((bv, Forall (v,p)) :: fms) = fv vs ((NameSet.add bv v, p) :: fms)
| fv vs ((bv, Exists (v,p)) :: fms) = fv vs ((NameSet.add bv v, p) :: fms);
fun add (fm,vs) = fv vs [(NameSet.empty,fm)]; in fun freeVars fm = add (fm,NameSet.empty);
fun freeVarsList fms = List.foldl add NameSet.empty fms; end;
fun specialize fm = snd (stripForall fm);
fun generalize fm = listMkForall (NameSet.toList (freeVars fm), fm);
local fun substCheck sub fm = if Subst.null subthen fm else substFm sub fm
and substFm sub fm = case fm of True => fm
| False => fm
| Atom (p,tms) => let val tms' = Sharing.map (Subst.subst sub) tms in if Portable.pointerEqual (tms,tms') then fm else Atom (p,tms') end
| Not p => let val p' = substFm sub p in if Portable.pointerEqual (p,p') then fm else Not p' end
| And (p,q) => substConn sub fm And p q
| Or (p,q) => substConn sub fm Or p q
| Imp (p,q) => substConn sub fm Imp p q
| Iff (p,q) => substConn sub fm Iff p q
| Forall (v,p) => substQuant sub fm Forall v p
| Exists (v,p) => substQuant sub fm Exists v p
and substConn sub fm conn p q = let val p' = substFm sub p and q' = substFm sub q in if Portable.pointerEqual (p,p') andalso
Portable.pointerEqual (q,q') then fm else conn (p',q') end
and substQuant sub fm quant v p = let val v' = let fun f (w,s) = if Name.equal w v then s else case Subst.peek sub w of
NONE => NameSet.add s w
| SOME tm => NameSet.union s (Term.freeVars tm)
val vars = freeVars p val vars = NameSet.foldl f NameSet.empty vars in
Term.variantPrime vars v end
valsub = if Name.equal v v' then Subst.remove sub (NameSet.singleton v) else Subst.insert sub (v, Term.Var v')
val p' = substCheck sub p in if Name.equal v v' andalso Portable.pointerEqual (p,p') then fm else quant (v',p') end; in val subst = substCheck; end;
val truthName = Name.fromString "T" and falsityName = Name.fromString "F" and conjunctionName = Name.fromString "/\\" and disjunctionName = Name.fromString "\\/" and implicationName = Name.fromString "==>" and equivalenceName = Name.fromString "<=>" and universalName = Name.fromString "!" and existentialName = Name.fromString "?";
local fun add_asms asms goal = ifList.null asms then goal else Imp (listMkConj (List.rev asms), goal);
fun add_var_asms asms v goal = add_asms asms (Forall (v,goal));
fun split asms pol fm = case (pol,fm) of (* Positive splittables *)
(true,True) => []
| (true, Not f) => split asms false f
| (true, And (f1,f2)) => split asms true f1 @ split (f1 :: asms) true f2
| (true, Or (f1,f2)) => split (Not f1 :: asms) true f2
| (true, Imp (f1,f2)) => split (f1 :: asms) true f2
| (true, Iff (f1,f2)) =>
split (f1 :: asms) true f2 @ split (f2 :: asms) true f1
| (true, Forall (v,f)) => List.map (add_var_asms asms v) (split [] true f) (* Negative splittables *)
| (false,False) => []
| (false, Not f) => split asms true f
| (false, And (f1,f2)) => split (f1 :: asms) false f2
| (false, Or (f1,f2)) =>
split asms false f1 @ split (Not f1 :: asms) false f2
| (false, Imp (f1,f2)) => split asms true f1 @ split (f1 :: asms) false f2
| (false, Iff (f1,f2)) =>
split (f1 :: asms) false f2 @ split (Not f2 :: asms) true f1
| (false, Exists (v,f)) => List.map (add_var_asms asms v) (split [] false f) (* Unsplittables *)
| _ => [add_asms asms (if pol then fm elseNot fm)]; in fun splitGoal fm = split [] true fm; end;
(*MetisTrace3 val splitGoal = fn fm => let val result = splitGoal fm val () = Print.trace pp "Formula.splitGoal: fm" fm val () = Print.trace (Print.ppList pp) "Formula.splitGoal: result" result in result end;
*)
end
structure FormulaOrdered = structtype t = Formula.formula val compare = Formula.compare end
structure FormulaMap = KeyMap (FormulaOrdered);
structure FormulaSet = ElementSet (FormulaMap);
¤ Dauer der Verarbeitung: 0.13 Sekunden
(vorverarbeitet)
¤
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.