haskell添加了两个CNF

haskell添加了两个CNF,haskell,logic,Haskell,Logic,对于我的编程,我实现了以下结构: data Logic a = Empty |And (Logic a) (Logic a) | Or (Logic a) (Logic a) | Equal (AtomVariable a) (AtomVariable a) | Not (Logic a) deriving (Show, Eq, Or

对于我的编程,我实现了以下结构:

data Logic a = Empty
              |And     (Logic a) (Logic a)
              | Or      (Logic a) (Logic a)
              | Equal   (AtomVariable a) (AtomVariable a)
              | Not (Logic a) 
              deriving (Show, Eq, Ord)
我将有相等或不相等的CNF。我的目标是将一个CNF添加到另一个CNF,并在必要时修改结果。例如,如果我有(a=b或a=c)和(c!=b),我想加上(a!=b),结果应该是a=c和c=b和a=B 我成功地对一个等式执行了此操作(将a=b或a!=b添加到逻辑中):


我想这不是最好的方法,但我想进一步添加一个完整的逻辑到另一个。

您的数据类型可以包含比CNF中更复杂的表达式。如果您希望以独占方式使用CNF,则应缩减数据类型,使其只能表示CNF表达式。这将使所有的简化规则更容易。是的,我只需要CNF。但我认为这已经尽可能简单了。我该怎么做呢?维基百科上说:“[CNF]是一个或多个子句的连词,其中一个子句是文本的析取”:那么,如何:
newtype CNF=连词[子句];newtype子句=析取[Literal];键入Literal=Bool
。我们甚至可以在不了解问题域的情况下完成这项工作。注意,这并不完全正确,因为我认为我们希望两个列表都是非空的。hackage上有非空的列表库,或者您可以自己滚动某些内容或以不同的方式构造某些内容,但保持相同的常规形状。@jberryman Bool似乎不是CNF表达式的良好基类型。您可能需要某种符号来表示变量,例如
newtype Var=Var String
。列表是否为空并不重要:零分句的合取或析取有合理的解释,问题是我没有布尔值,我只有方程。即使我可以简化我的逻辑,我应该如何做我所要求的(将一个逻辑添加到另一个逻辑)?您的数据类型可以包含比CNF中更复杂的表达式。如果您希望以独占方式使用CNF,则应缩减数据类型,使其只能表示CNF表达式。这将使所有的简化规则更容易。是的,我只需要CNF。但我认为这已经尽可能简单了。我该怎么做呢?维基百科上说:“[CNF]是一个或多个子句的连词,其中一个子句是文本的析取”:那么,如何:
newtype CNF=连词[子句];newtype子句=析取[Literal];键入Literal=Bool
。我们甚至可以在不了解问题域的情况下完成这项工作。注意,这并不完全正确,因为我认为我们希望两个列表都是非空的。hackage上有非空的列表库,或者您可以自己滚动某些内容或以不同的方式构造某些内容,但保持相同的常规形状。@jberryman Bool似乎不是CNF表达式的良好基类型。您可能需要某种符号来表示变量,例如
newtype Var=Var String
。列表是否为空并不重要:零分句的合取或析取有合理的解释,问题是我没有布尔值,我只有方程。即使我可以简化我的逻辑,我应该如何做我所要求的(将一个逻辑添加到另一个逻辑)?
check :: Eq a => Logic a -> Logic a -> Bool
check (Equal a b) (Equal c d)
    | a == c && b == d = False
    | a == d && b == c = False
    | otherwise = True

check (Equal a b) (Not (Equal c d)) 
    | a == c && b == d = False
    | a == d && b == c = False
    | otherwise = True

check (Equal a b) (Or c d) = ((check (Equal a b) c) || (check (Equal a b) d))

check (Equal a b) (And c d) = ((check (Equal a b) c) && (check (Equal a b) d))

check (Equal a b) (Implication c d e)  = check (Equal a b) (And (Equal c d) (Not (Equal c e)))

check1 :: Eq a => Logic a -> Logic a -> Bool
check1 (Not (Equal a b)) (Equal c d) 
    | a == c && b == d = False
    | a == d && b == c = False
    | otherwise = True

check1 (Not (Equal a b)) (Not (Equal c d)) 
    | (check1 (Not (Equal a b)) (Equal c d)) == False = False
    | otherwise = True

check1 (Not (Equal a b)) (Or c d) = ((check1 (Not (Equal a b)) c) || (check1 (Not (Equal a b)) d))

check1 (Not (Equal a b)) (And c d) = ((check1 (Not (Equal a b)) c) && (check1 (Not (Equal a b)) d))

check1 (Not (Equal a b)) (Implication c d e)  = check1 (Not (Equal a b)) (And (Equal c d) (Not (Equal c e)))

add1 :: Eq a => Logic a -> Logic a -> Logic a
add1 (Equal a b) logic
    | check (Equal a b) logic == True = And logic (Equal a b)
    | otherwise = logic


add1 (Not (Equal a b)) logic
    | (check1 (Not (Equal a b)) logic) == True = And logic (Equal a b)
    | otherwise = logic