packages feed

Folly 0.1.4.6 → 0.1.5.0

raw patch · 9 files changed

+183/−90 lines, 9 filesPVP: major bump suggested

API removals or changes: PVP suggests a major version bump

API changes (from Hackage documentation)

- Folly.Formula: isTautology :: [Formula] -> Bool
+ Folly.Clause: data Clause
+ Folly.Clause: deleteTautologies :: Set Clause -> Set Clause
+ Folly.Clause: empty :: Clause
+ Folly.Clause: givenClause :: Set Formula -> Clause
+ Folly.Clause: instance GHC.Classes.Eq Folly.Clause.Clause
+ Folly.Clause: instance GHC.Classes.Eq Folly.Clause.Justification
+ Folly.Clause: instance GHC.Classes.Ord Folly.Clause.Clause
+ Folly.Clause: instance GHC.Classes.Ord Folly.Clause.Justification
+ Folly.Clause: instance GHC.Show.Show Folly.Clause.Clause
+ Folly.Clause: instance GHC.Show.Show Folly.Clause.Justification
+ Folly.Clause: resolvedClauses :: Clause -> Clause -> Set Clause
+ Folly.Clause: showTrace :: Clause -> [Char]
+ Folly.Formula: isAtom :: Formula -> Bool
+ Folly.Formula: stripNegations :: Formula -> Formula
+ Folly.Unification: type Unifier = Map Term Term

Files

Folly.cabal view
@@ -2,7 +2,7 @@ --  see http://haskell.org/cabal/users-guide/  name:                Folly-version:             0.1.4.6+version:             0.1.5.0 synopsis:            A first order logic library in Haskell description:         An implementation of first order logic in Haskell that 		     includes a library of modules for incorporating first@@ -20,7 +20,7 @@ cabal-version:       >=1.8  library-  exposed-modules:     Folly.Formula, Folly.Unification, Folly.Resolution, Folly.Utils, Folly.Theorem, Folly.Lexer, Folly.Parser+  exposed-modules:     Folly.Formula, Folly.Unification, Folly.Resolution, Folly.Utils, Folly.Theorem, Folly.Lexer, Folly.Parser, Folly.Clause   build-depends:       base < 6, containers, parsec   hs-source-dirs:      src @@ -31,7 +31,7 @@   hs-source-dirs:      src  executable Folly-tests-  main-is:             Main.hs-  other-modules:       Folly.FormulaTests, Folly.LexerTests, Folly.ParserTests, Folly.ResolutionTests, Folly.UnificationTests, Folly.TestUtils+  main-is:             TestMain.hs+  other-modules:       Folly.FormulaTests, Folly.LexerTests, Folly.ParserTests, Folly.ResolutionTests, Folly.UnificationTests, Folly.TestUtils, Folly.Clause   build-depends:       base < 6, HUnit, containers, parsec   hs-source-dirs:      test, src
+ src/Folly/Clause.hs view
@@ -0,0 +1,85 @@+module Folly.Clause(Clause,+                    givenClause, Folly.Clause.empty,+                    deleteTautologies,+                    resolvedClauses,+                    showTrace) where++import Data.List as L+import Data.Maybe+import Data.Set as S++import Folly.Formula+import Folly.Unification++data Clause = Clause (Set Formula) Justification+           deriving (Show)++instance Eq Clause where+  (==) (Clause cs1 _) (Clause cs2 _) = cs1 == cs2++instance Ord Clause where+  (<=) (Clause cs1 _) (Clause cs2 _) = cs1 <= cs2++givenClause cs = Clause cs Given+resolvedClause cs lc rc mgu = Clause cs (Resolved lc rc mgu)++empty = Clause S.empty Given++data Justification+  = Given+  | Resolved Clause Clause Unifier+    deriving (Eq, Ord, Show)++deleteTautologies :: Set Clause -> Set Clause+deleteTautologies formulas = S.filter (not . dnfIsTautology) formulas++dnfIsTautology :: Clause -> Bool+dnfIsTautology (Clause lits _) = isTautology lits++isTautology :: Set Formula -> Bool+isTautology c = S.size (S.intersection atoms negAtoms) > 0+  where+    atoms = S.filter isAtom c+    negAtoms = S.map stripNegations $ S.filter (not . isAtom) c++resolvedClauses :: Clause -> Clause -> Set Clause+resolvedClauses l@(Clause left _) r@(Clause right _) =+  case left == right of+   True ->  S.empty+   False -> S.fromList resClauses+  where+    possibleResCombos = [(x, l, y, r) | x <- (S.toList left), y <- (S.toList right)]+    mResClauses = L.map (\(x, l, y, r) -> tryToResolve x l y r) possibleResCombos+    resClauses = L.map fromJust $ L.filter (/= Nothing) mResClauses++tryToResolve :: Formula -> Clause -> Formula -> Clause -> Maybe Clause+tryToResolve leftLiteral leftClause rightLiteral rightClause =+  case matchingLiterals leftLiteral rightLiteral of+    True -> unifiedResolvedClause leftLiteral leftClause rightLiteral rightClause+    False -> Nothing++unifiedResolvedClause :: Formula -> Clause -> Formula -> Clause -> Maybe Clause+unifiedResolvedClause lLit l@(Clause lc _) rLit r@(Clause rc _) =+  case L.length (literalArgs lLit) == L.length (literalArgs rLit) of+   True ->+     case mostGeneralUnifier $ zip (literalArgs lLit) (literalArgs rLit) of+      Just mgu ->+        Just $ mkResolvedClause mgu resolvedLits l r+      Nothing -> Nothing+   False -> Nothing+  where+    resolvedLits = S.union (S.delete lLit lc) (S.delete rLit rc)++mkResolvedClause :: Unifier -> Set Formula -> Clause -> Clause -> Clause+mkResolvedClause mgu lits lc rc =+  resolvedClause (S.map (\lit -> applyToTerms lit (applyUnifier mgu)) lits) lc rc mgu++showTrace c = showTraceRec 0 c++showTraceRec n c@(Clause cs Given) = (ind n) ++ "GIVEN " ++ show cs+showTraceRec n c@(Clause cs (Resolved a b u)) =+  (ind n) ++ show cs ++ "\t" ++ show u ++ "\n" +++  showTraceRec (n+1) a ++ "\n" +++  showTraceRec (n+1) b++ind n = L.concat $ L.replicate n "  "
src/Folly/Formula.hs view
@@ -5,13 +5,12 @@   appendVarName,   var, func, constant,   te, fa, pr, con, dis, neg, imp, bic, t, f,-  vars, freeVars,+  vars, freeVars, isAtom, stripNegations,   generalize, subFormula,   applyToTerms,   literalArgs,   toPNF, toSkolemForm, skf,   toClausalForm,-  isTautology,   matchingLiterals) where  import Control.Monad@@ -295,9 +294,3 @@ splitDis :: Formula -> [Formula] splitDis (B "|" l r) = (splitDis l) ++ (splitDis r) splitDis f = [f]--isTautology :: [Formula] -> Bool-isTautology c = L.length (L.intersect atoms negAtoms) > 0-  where-    atoms = L.filter isAtom c-    negAtoms = L.map stripNegations $ L.filter (not . isAtom) c
src/Folly/Resolution.hs view
@@ -1,60 +1,39 @@-module Folly.Resolution(-  isValid) where+module Folly.Resolution(isValid) where  import Data.List as L-import Data.Maybe import Data.Set as S +import Folly.Clause as C import Folly.Formula import Folly.Theorem-import Folly.Unification  isValid :: Theorem -> Bool isValid t = not $ resolve $ deleteTautologies $ clauseSet   where     formulas = (neg (conclusion t)) : (hypothesis t)-    clauses = uniqueVarNames $ L.concat $ L.map toClausalForm formulas+    clauses = L.map (givenClause . S.fromList) $ uniqueVarNames $ toClausalForm $ L.foldr (\l r -> con l r) (head formulas) (tail formulas)     clauseSet = S.fromList clauses -resolve :: Set [Formula] -> Bool-resolve cls = case S.member [] cls of-  True -> True+resolve :: Set Clause -> Bool+resolve cls = case S.member C.empty cls of+  True -> False   False -> resolveIter [cls] -resolveIter :: [Set [Formula]] -> Bool+resolveIter :: [Set Clause] -> Bool resolveIter [] = error "Empty list of clause sets" resolveIter clauseSets = case S.size newClauses == 0 of   True -> True-  False -> case S.member [] newClauses of+  False -> case S.member C.empty newClauses of     True -> False     False -> resolveIter (newClauses:clauseSets)   where-    newClauses = case L.length clauseSets of-      1 -> generateNewClauses (head clauseSets) (head clauseSets)-      _ -> generateNewClauses (head clauseSets) (L.foldl S.union S.empty (tail clauseSets))+    newClauses = generateNewClauses (head clauseSets) (L.foldl S.union S.empty clauseSets) -generateNewClauses :: Set [Formula] -> Set [Formula] -> Set [Formula]+generateNewClauses :: Set Clause -> Set Clause -> Set Clause generateNewClauses recent old = deleteTautologies $ newClauses   where-    newClauses = S.fold S.union S.empty $ S.map (\ c -> genNewClauses c old) recent-    genNewClauses c cs = S.fold S.union S.empty $ S.map (\ x -> resolvedClauses c x) cs--resolvedClauses :: [Formula] -> [Formula] -> Set [Formula]-resolvedClauses left right = S.fromList resClauses-  where-    mResClauses = L.map (\ x -> (L.map (\ y -> tryToResolve x left y right) right)) left-    resClauses = L.map fromJust $ L.filter (/= Nothing) $ L.concat mResClauses --tryToResolve :: Formula -> [Formula] -> Formula -> [Formula] -> Maybe [Formula]-tryToResolve leftLiteral leftClause rightLiteral rightClause =-  case matchingLiterals leftLiteral rightLiteral of-    True -> unifiedResolvedClause leftLiteral leftClause rightLiteral rightClause-    False -> Nothing--unifiedResolvedClause :: Formula -> [Formula] -> Formula -> [Formula] -> Maybe [Formula]-unifiedResolvedClause lLit lc rLit rc = case mostGeneralUnifier $ zip (literalArgs lLit) (literalArgs rLit) of-  Just mgu -> Just $ L.map (\ lit -> applyToTerms lit (applyUnifier mgu)) ((L.delete lLit lc) ++ (L.delete rLit rc))-  Nothing -> Nothing+    newClauses = S.fold S.union S.empty $ S.map (\c -> genNewClauses c old) recent+    genNewClauses c cs = S.fold S.union S.empty $ S.map (\x -> resolvedClauses c x) cs  uniqueVarNames :: [[Formula]] -> [[Formula]] uniqueVarNames cls = zipWith attachSuffix cls (L.map show [1..length cls])@@ -64,6 +43,3 @@  addSuffixToVarNames :: String -> Formula -> Formula addSuffixToVarNames suffix form = applyToTerms form (appendVarName suffix)--deleteTautologies :: Set [Formula] -> Set [Formula]-deleteTautologies clauses = S.filter (not . isTautology) clauses
src/Folly/Theorem.hs view
@@ -15,10 +15,10 @@   show = showThm  showThm :: Theorem -> String-showThm (Theorem h c) = "Hypothesis:\n" ++ hypStr ++ "\n\n|=\n\n" ++ conclStr+showThm (Theorem h c) = "\n" ++ hypStr ++ "\n\n|=\n\n" ++ conclStr   where     hypStr = (L.concat $ L.intersperse "\n" $ L.map show h)-    conclStr = "Conclusion:\n" ++ show c+    conclStr = show c  theorem = Theorem 
src/Folly/Unification.hs view
@@ -1,7 +1,7 @@-module Folly.Unification(-  applyUnifier,-  mostGeneralUnifier,-  unifier) where+module Folly.Unification(Unifier,+                         applyUnifier,+                         mostGeneralUnifier,+                         unifier) where  import Control.Monad import Data.List as L
test/Folly/ResolutionTests.hs view
@@ -11,31 +11,70 @@ testIsValid =   testFunction isValid isValidTestCases +x = var "x"+y = var "y"+z = var "z"+a = var "a"+d = var "d"+p = var "p"++one = constant "1"+john = constant "John"+fido = constant "Fido"++times a b = func "*" [a, b]++eq a b = pr "=" [a, b]+dog d = pr "Dog" [d]+owns a b = pr "Owns" [a, b]+kills a b = pr "Kills" [a, b]+loves a b = pr "Loves" [a, b]+lovesAnimals a = pr "LovesAnimals" [a]+ isValidTestCases :: [(Theorem, Bool)] isValidTestCases =-  [(theorem [] (fa (var "a") (dis (pr "d" [var "a"]) (neg (pr "d" [var "a"])))), True),-   (theorem [] (pr "d" [var "k"]), False),-   (theorem [pr "Dog" [var "x"]] (pr "Dog" [var "x"]), True),-   (theorem-    [(fa (var "d") (imp (pr "Dog" [var "d"]) (pr "Loves" [constant "John", var "d"]))),-     (pr "Dog" [constant "Fido"])]-    (pr "Loves" [constant "John", constant "Fido"]), True),-   (theorem-    [(fa (var "p") (imp (te (var "d") (con (pr "Dog" [var "d"]) (pr "Owns" [var "p", var "d"]))) (pr "LovesAnimals" [var "p"]))),-     (imp (pr "LovesAnimals" [var "x"]) (fa (var "a") (neg (pr "Kills" [var "x", var "a"])))),-     (pr "Owns" [constant "John", constant "Fido"]),-     (pr "Dog" [constant "Fido"])]-    (fa (var "a") (neg (pr "Kills" [constant "John", var "a"]))), True),-   (theorem groupWithEquals (imp (con (con (con (pr "=" [func "*" [var "x", var "y"], constant "1"]) (pr "=" [func "*" [var "y", var "x"], constant "1"])) (pr "=" [func "*" [var "x", var "z"], constant "1"])) (pr "=" [func "*" [var "z", var "x"], constant "1"])) (pr "=" [var "y", var "z"])), True),-   (theorem groupWithEquals (imp (fa (var "x") (con (pr "=" [func "*" [var "x", var "z"], constant "1"]) (pr "=" [func "*" [var "z", var "x"], constant "1"]))) (pr "=" [var "z", constant "1"])), True)]+  [(dog1, True),+   (dog2, False),+   (dog3, True),+   (dog4, True),+   (dog5, True),+   (dog6, False),+   (group1, True),+   (group2, True)]+--   (group3, False)] +dog1 = theorem [] (fa a (dis (dog a) (neg (dog a))))+dog2 = theorem [] (dog a)+dog3 = theorem [dog x] (dog x)+dog4 = theorem [(fa d (imp (dog d) (loves john d))), dog fido] (loves john fido)+dog5 = theorem+       [(fa p (imp (te d (con (dog d) (owns p d))) (lovesAnimals p))),+        (imp (lovesAnimals x) (fa a (neg (kills x a)))),+        owns john fido,+        dog fido]+       (fa a (neg (kills john a)))+dog6 = theorem [] (con (dog a) (neg $ dog a))++group1 = theorem+         groupAxioms+         (imp+          (con (con (con (eq (times x y) one) (eq (times y x) one)) (eq (times x z) one)) (eq (times z x) one))+          (eq y z))+group2 = theorem groupAxioms (imp (fa x (con (eq (times x z) one) (eq (times z x) one))) (eq z one))++group3 =+  theorem groupAxioms (fa x (fa y (eq (times x y) (times y x))))++group4 = theorem (tail equalityAxioms) (head equalityAxioms)+ equalityAxioms :: [Formula] equalityAxioms =-  [(fa (var "x") (pr "=" [var "x", var "x"])),-   (fa (var "x") (fa (var "y") (imp (pr "=" [var "x", var "y"]) (pr "=" [var "y", var "x"])))),-   (fa (var "x") (fa (var "y") (fa (var "z") (imp (con (pr "=" [var "x", var "y"]) (pr "=" [var "y", var "z"])) (pr "=" [var "x", var "z"])))))]+   [(fa x (pr "=" [x, x])),+    (fa x (fa y (imp (eq x y) (eq y x)))),+    (fa x (fa y (fa z (imp (con (eq x y) (eq y z)) (eq x z)))))] -groupWithEquals =-  [(fa (var "x") (te (var "y") (con (pr "=" [func "*" [var "x", var "y"], constant "1"]) (pr "=" [func "*" [var "y", var "x"], constant "1"])))),-   (fa (var "x") (fa (var "y") (fa (var "z") (pr "=" [func "*" [var "x", func "*" [var "y", var "z"]], func "*" [func "*" [var "x", var "y"], var "z"]])))),-   (fa (var "x") (con (pr "=" [func "*" [var "x", constant "1"], var "x"]) (pr "=" [func "*" [constant "1", var "x"], constant "x"])))] ++ equalityAxioms+groupAxioms =+   [(fa x (te y (con (eq (times x y) one) (eq (times y x) one)))),+    (fa x (fa y (fa z (eq (times x (times y z)) (times (times x y) z))))),+    (fa x (con (eq (times x one) x) (eq (times one x) x)))] +++   equalityAxioms
− test/Main.hs
@@ -1,14 +0,0 @@-module Main(main) where--import Folly.FormulaTests-import Folly.LexerTests-import Folly.ParserTests-import Folly.ResolutionTests-import Folly.UnificationTests--main = do-  allFormulaTests-  allLexerTests-  allParserTests-  allResolutionTests-  allUnificationTests
+ test/TestMain.hs view
@@ -0,0 +1,14 @@+module TestMain(main) where++import Folly.FormulaTests+import Folly.LexerTests+import Folly.ParserTests+import Folly.ResolutionTests+import Folly.UnificationTests++main = do+  allFormulaTests+  allLexerTests+  allParserTests+  allResolutionTests+  allUnificationTests