Add files via upload

This commit is contained in:
Gregory Bednov 2025-01-10 20:51:21 +03:00 committed by GitHub
commit e743b85002
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 154 additions and 0 deletions

68
Ternary/Vee.hs Normal file
View file

@ -0,0 +1,68 @@
module Ternary.Vee (isObvious, newFact, cleared, think) where
import Data.List (head, intersect, length, nub, null, union, (\\))
import Data.Maybe (Maybe (Nothing), mapMaybe)
import Prelude (Bool (False, True), Eq, any, foldr, fst, map,
not, notElem, otherwise, return, snd, ($), (&&),
(.), (/=), (<$>), (<*>), (=<<), (==))
import Ternary.Term (Item (..), Term (..), Vee)
isSubsetOf :: (Eq a) => [a] -> [a] -> Bool
a `isSubsetOf` b = nda && not ndb
where
nda = null $ a \\ b
ndb = null $ b \\ a
isObvious :: (Eq a) => Vee a -> Vee a -> Bool
isObvious (Term x (Item a)) (Term y (Item b))
| x /= y = False
| x = a `isSubsetOf` b
| not x = b `isSubsetOf` a
newFact :: (Eq a) => Vee a -> Vee a -> ([Vee a], Maybe (Vee a))
newFact a@(Term True _) b@(Term False _) = newFact b a
newFact (Term False (Item iF)) tT@(Term True (Item iT))
| length ldF /= 1 = ([], Nothing)
| otherwise =
if d'F `notElem` iT
then (return tT, return (Term True (Item (d'F:iT))))
else ([], Nothing)
where
ldF = iF \\ iT
d'F = notT . head $ ldF
notT (Term x v) = Term (not x) v
newFact (Term False (Item i0)) (Term False (Item i1))
| length e /= 1 = ([], Nothing)
| otherwise =
if null d0 && null d1
then (map (Term False . Item) [i0, i1], vee0)
else ([], vee0)
where
notT (Term x v) = Term (not x) v
terms = (i0 `intersect` i1) `union` d0 `union` d1
e = map notT i0 `intersect` i1
d0 = (i0 \\ i1) \\ map notT e
d1 = (i1 \\ i0) \\ e
vee0 = return (Term False (Item terms))
newFact _ _ = ([], Nothing)
pseudofix :: (Eq a) => (a -> a) -> a -> a
pseudofix f x0
| y == y' = y
| otherwise = y'
where
y = f x0
y' = f y
next :: (Eq a) => ([Vee a], [Vee a]) -> ([Vee a], [Vee a])
next (o,n) = (o `union` n \\ (fst =<< r), mapMaybe snd r)
where
r = newFact <$> o <*> n
applyFacts :: (Eq a) => [Vee a] -> [Vee a] -> [Vee a]
applyFacts old new = fst $ pseudofix next (old, new)
cleared :: (Eq a) => [Vee a] -> [Vee a]
cleared vees = nub [vee | vee <- vees, not $ any (isObvious vee) vees]
think :: (Eq a) => ([Vee a]->[Vee a]) -> [Vee a] -> [Vee a]
think addition = foldr (applyFacts . withUni . return) [] where
withUni vees = applyFacts (addition vees) vees