verify graph paths incl laws graph

This commit is contained in:
hi 2025-08-15 11:35:50 +00:00
parent fa1a39d1da
commit e8a5e2caa7
3 changed files with 84 additions and 31 deletions

View file

@ -38,6 +38,8 @@ Just ["add","double","add","double","double","add"]
data VerifyPathError vertex edge data VerifyPathError vertex edge
= NoSuchEdge vertex edge = NoSuchEdge vertex edge
| GoalNotReached [vertex]
deriving Show
verifyPath verifyPath
:: (Eq vertex, Ord vertex, Eq edge) :: (Eq vertex, Ord vertex, Eq edge)
@ -45,11 +47,22 @@ verifyPath
-> vertex -> vertex
-> vertex -> vertex
-> [edge] -> [edge]
-> Either (VerifyPathError vertex edge) Bool -> Either (VerifyPathError vertex edge) [vertex]
verifyPath getEdges goal start path = verifyPath getEdges goal start path =
case path of case aux start path of
[] -> Right $ start == goal Right (vertices, True) -> Right vertices
Right (vertices, False) -> Left $ GoalNotReached vertices
Left x -> Left x
where
aux vertex path' = cons vertex <$>
case path' of
[] -> Right $
if vertex == goal
then ([], True)
else ([], False)
(thisEdge:nextEdges) -> (thisEdge:nextEdges) ->
case map fst $ filter (\(next, realEdge) -> realEdge == thisEdge) $ getEdges start of case map fst $ filter (\(next, realEdge) -> realEdge == thisEdge) $ getEdges vertex of
[] -> Left $ NoSuchEdge start thisEdge [] -> Left $ NoSuchEdge vertex thisEdge
(next:_) -> verifyPath getEdges goal next nextEdges (next:_) -> aux next nextEdges
cons vertex (vertices, bool) = (vertex:vertices, bool)

View file

@ -4,7 +4,7 @@ import Logic.Parse (eof, mkInput)
import Logic.Statement (Statement(..)) import Logic.Statement (Statement(..))
import Logic.Statement.Parse (stmt) import Logic.Statement.Parse (stmt)
import Logic.Statement.Serialize (serialize, SerializeFormat(Plain)) import Logic.Statement.Serialize (serialize, SerializeFormat(Plain))
import Logic.Graph (bfs) import Logic.Graph (bfs, verifyPath, VerifyPathError)
import Data.Either (fromRight, rights) import Data.Either (fromRight, rights)
import Data.Maybe (fromJust, listToMaybe) import Data.Maybe (fromJust, listToMaybe)
@ -220,16 +220,25 @@ firstLeft [] = Right []
firstLeft ((Left a):_) = Left a firstLeft ((Left a):_) = Left a
firstLeft ((Right b):xs) = (b:) <$> firstLeft xs firstLeft ((Right b):xs) = (b:) <$> firstLeft xs
data Direction
= Forward
| Reverse
deriving (Eq, Show)
data LawsGraphEdge = LawsGraphEdge data LawsGraphEdge = LawsGraphEdge
{ lgeLaw :: Law { lgeDirection :: Direction
, lgeReverse :: Bool
, lgeIndex :: Integer , lgeIndex :: Integer
, lgeLaw :: Law
} deriving Eq } deriving Eq
instance Show LawsGraphEdge where instance Show LawsGraphEdge where
show edge = show edge =
"LawsGraphEdge{" "LawsGraphEdge{"
<> (if lgeReverse edge then "< " else "> ") <> (
case lgeDirection edge of
Forward -> "> "
Reverse -> "< "
)
<> lawName (lgeLaw edge) <> lawName (lgeLaw edge)
<> " " <> " "
<> show (lgeIndex edge) <> show (lgeIndex edge)
@ -246,27 +255,26 @@ getLawsGraphEdges s = concat $ rights $ map aux laws
where where
aux :: Law -> Either ReplaceError [(Statement, LawsGraphEdge)] aux :: Law -> Either ReplaceError [(Statement, LawsGraphEdge)]
aux law = do aux law = do
forward <- direction law lawLhs lawRhs False forward <- edges Forward law
reverse <- direction law lawRhs lawLhs True reverse <- edges Reverse law
return $ forward ++ reverse return $ forward ++ reverse
direction replaceds :: Direction -> Law -> Either ReplaceError [Statement]
:: Law replaceds direction law =
-> (Law -> Statement)
-> (Law -> Statement)
-> Bool
-> Either ReplaceError [(Statement, LawsGraphEdge)]
direction law mkPattern1 mkPattern2 isReverse = do
replaceds <- replace (mkPattern1 law) (mkPattern2 law) s
return $
(flip map) (zip [0..] replaceds) $ \(index, s') ->
let let
edge = LawsGraphEdge (pattern1, pattern2) =
{ lgeLaw = law case direction of
, lgeReverse = isReverse Forward -> (lawLhs law, lawRhs law)
, lgeIndex = index Reverse -> (lawRhs law, lawLhs law)
} in replace pattern1 pattern2 s
in (s', edge)
mkEdges :: Direction -> Law -> [Statement] -> [(Statement, LawsGraphEdge)]
mkEdges direction law statements = do
(index, s') <- zip [0..] statements
return (s', LawsGraphEdge direction index law)
edges :: Direction -> Law -> Either ReplaceError [(Statement, LawsGraphEdge)]
edges direction law = mkEdges direction law <$> replaceds direction law
{- {-
ghci> fromString x = fromRight undefined $ eof stmt $ mkInput x ghci> fromString x = fromRight undefined $ eof stmt $ mkInput x
@ -314,3 +322,34 @@ ghci> time $ putStrLn $ show $ niceEdges <$> bfsLaws (fromString "!!!!!!!!!!!!p"
Just ["> dbl_neg 0","> dbl_neg 0","> dbl_neg 0","> dbl_neg 0","> dbl_neg 0","> dbl_neg 0"] Just ["> dbl_neg 0","> dbl_neg 0","> dbl_neg 0","> dbl_neg 0","> dbl_neg 0","> dbl_neg 0"]
3066.211460539s 3066.211460539s
-} -}
data LawsGraphPath = LawsGraphPath
{ lgpStart :: Statement
, lgpGoal :: Statement
, lgpEdges :: [LawsGraphEdge]
} deriving Show
verifyLawsPath
:: LawsGraphPath
-> Either (VerifyPathError Statement LawsGraphEdge) [Statement]
verifyLawsPath path =
verifyPath getLawsGraphEdges (lgpGoal path) (lgpStart path) (lgpEdges path)
lawsPathExample1 :: LawsGraphPath
lawsPathExample1 = LawsGraphPath start goal edges
where
start = Implies (Atom "p") (Atom "q")
goal = Implies (Not (Atom "q")) (Not (Atom "p"))
edges =
[ LawsGraphEdge Forward 1 $ law "dbl_neg"
, LawsGraphEdge Forward 0 $ law "implies_and"
, LawsGraphEdge Forward 0 $ law "and_comm"
, LawsGraphEdge Reverse 0 $ law "implies_and"
]
law = fromJust . lookupLaw
{-
ghci> import Logic.Statement.Serialize (serialize, SerializeFormat(..))
ghci> map (serialize Plain) <$> verifyLawsPath lawsPathExample1
Right ["(p->q)","(!!p->q)","!(!!p&!q)","!(!q&!!p)","(!q->!p)"]
-}

View file

@ -9,6 +9,7 @@ things that are in here:
### [Logic.Graph](Graph.hs) ### [Logic.Graph](Graph.hs)
- generic breadth-first search - generic breadth-first search
- verify graph paths reach the goal and have all extant edges
## statement things ## statement things
@ -38,7 +39,7 @@ things that are in here:
### [Logic.Statements.Laws](Statements/Laws.hs) ### [Logic.Statements.Laws](Statements/Laws.hs)
- match/replace patterns in statements (e.g. logical laws) - match/replace patterns in statements (e.g. logical laws)
- verify logical-law equivalence of statements (TODO) - verify logical-law equivalence of statements
- find logical-law equivalence of statements with breadth-first search (slow) - find logical-law equivalence of statements with breadth-first search (slow)
### [Logic.Language](Language.hs) ### [Logic.Language](Language.hs)