简体   繁体   English

检查一个命题公式是否隐含另一个命题公式(在Haskell中)

[英]Checking if One Propositional Formula Implies Another (in Haskell)

Suppose we have 假设我们有

data Exp = Prop String -- a proposition
         | And Exp Exp -- a conjunction of propositions
         | Or Exp Exp  -- a disjunction of propositions

Then is there a way to see if one nested expression implies another one? 然后有没有办法查看一个嵌套表达式是否暗含了另一个? That is, I'm looking for something like the following: 也就是说,我正在寻找以下内容:

implies :: Exp -> Exp -> Bool
implies = {- returns true if and only if the first expression 
               implies the second expression                    -}

implies
  (And (Prop "Apple") (Prop "Banana")) 
  (Or  (Prop "Apple") (Prop "Banana"))
-- => True, since "Apple and Banana" implies "Apple or Banana"

implies 
  (Or  (Prop "Apple") (Prop "Banana"))  
  (And (Prop "Apple") (Prop "Banana")) 
-- => False, since "Apple or Banana" does not imply "Apple and Banana"

Is there a way to implement this, or is there some library that implements this? 有没有办法实现这一目标,或者有一些库可以实现这一目标? If it makes a difference: I only need And and Or (ie, I don't need material implication). 如果会有所不同:我只需要AndOr (即,我不需要实质性暗示)。

Normally you would use a SAT solver (as pointed out in the other answer) but for your specific example you could also exploit the fact that propositional formulae over a set of literals U can be represented by subsets of U . 通常,您将使用SAT求解器(如另一个答案中所指出),但是对于您的特定示例,您还可以利用以下事实:一组文字U命题公式可以由U的子集表示。 These "representing subsets" are the models of a formula. 这些“代表子集”是公式的模型。

In your example, U = { Apple, Banana } . 在您的示例中, U = { Apple, Banana } The expression (Apple AND Banana) is only represented by a single subset of U , namely by { Apple, Banana } . 表达式(Apple AND Banana)仅由U的单个子集表示,即{ Apple, Banana } (Apple OR Banana) on the other hand has three models: { Apple } , { Banana } and { Apple, Banana } . (Apple OR Banana)具有三种模型: { Apple }{ Banana }{ Apple, Banana }

If a proposition p is in models(f) then p is true, otherwise it is false. 如果命题pmodels(f)p为true,否则为false。 The models for a formula f AND g are those subsets of U that are models of f and of g . 公式f AND g模型是U那些子集,它们是fg模型。 A model f OR g is any set that is a model of f or a model of g . 模型f OR g是任何一组是的模型f或模型g

In Haskell this looks like (if we add import qualified Data.Set as S at the top): 在Haskell中,这看起来像(如果我们在顶部添加import qualified Data.Set as S ):

-- The powerset of `U = {Apple, Banana}`
u = [S.empty, S.singleton "Apple", S.singleton "Banana", S.fromList ["Apple", "Banana"]]

isModelOf :: S.Set String -> Exp -> Bool
isModelOf s = any ((==) s) . models

models :: Exp -> [S.Set String]
models e = case e of
  Prop s -> filter (s `S.member`) u
  And l r -> filter (flip isModelOf r) $ models l
  Or l r -> models l ++ models r

Finally, a formula f implies a formula g if every model of f is also a model of g : 最后,式f意味着式g如果每一个模型f也是一个模型g

implies :: Exp -> Exp -> Bool
implies f g = all isGModel fModels where
  fModels = models f
  gModels = models g
  isGModel s = any ((==) s) gModels

Please note that this approach is highly inefficient and does not scale beyond a small number of literals (because models are computed by enumerating subsets of all literals). 请注意,这种方法效率极低,并且无法扩展到少量文字(因为模型是通过枚举所有文字的子集来计算的)。 But it can be educational to think about the problem in terms of sets. 但是从集合的角度考虑问题可能具有教育意义。

This touches on one of the keystone problems in computer science. 这触及了计算机科学中的关键问题之一。 For an expression of ANDs and ORs of boolean variables, can we determine whether the expression is satisfiable? 对于布尔变量的AND和OR的表达式,我们能否确定该表达式是否可满足? Or is the expression always false? 还是表达总是假的?

A simple algorithm is to construct a proof by contradiction and then iteratively applying resolution . 一种简单的算法是通过矛盾构造证明,然后迭代地应用分辨率

For example, the first problem is equivalent to proving invalid APPLE && BANANA && NOT (APPLE || BANANA) . 例如,第一个问题等同于证明APPLE && BANANA && NOT (APPLE || BANANA)无效。 Well, that expression is equivalent to APPLE && BANANA && NOT APPLE && NOT BANANA and that expression is invalid so we can conclude that the implication holds. 好吧,该表达式等效于APPLE && BANANA && NOT APPLE && NOT BANANA并且该表达式无效,因此我们可以得出结论认为。

Similarly the second problem is equivalent to proving invalid (APPLE || BANANA) && NOT (APPLE && BANANA) . 同样,第二个问题等效于证明无效(APPLE || BANANA) && NOT (APPLE && BANANA) This splits into four expressions: APPLE && NOT APPLE , APPLE && NOT BANANA , BANANA && NOT APPLE , BANANA & NOT BANANA . 这分为四个表达式: APPLE && NOT APPLEAPPLE && NOT BANANABANANA && NOT APPLEBANANA & NOT BANANA The first and the last subexpressions can be proven invalid but the others cannot. 可以证明第一个和最后一个子表达式无效,而其他子表达式不能。 The resolution algorithm realizes it is stuck and so the implication does not hold. 解析算法意识到它被卡住了,因此含义不成立。

Algorithms like this one that tackle the question of whether formulas are valid fall under the heading of SAT solvers . 诸如此类的解决公式是否有效的算法属于SAT求解器 The boolean satisfiability problem is more general than the problem you are facing, and the packages for tackling it (such as incremental-sat-solver on Hackage and funsat on Hackage ) employ a more sophisticated algorithm than outlined here, but you should find it possible to translate your expression to a satisfiability problem. 布尔可满足性问题比您要面对的问题更为普遍,解决该问题的软件包(例如Hackage上的 增量式-sat-solverHackage上的funsat )采用了比此处概述的算法更为复杂的算法,但是您应该找到可能的方法将您的表达转化为可满足性的问题。 Generally you will be asked to create one expression that is not unlike your abstract data type, using variables and ANDs and ORs. 通常,系统会要求您使用变量以及AND与OR来创建一个与抽象数据类型相同的表达式。 Both packages will spit out a result data type telling you that either the expression is unsatisfiable or that it is satisfiable and here are what all the variables should be. 这两个软件包都将吐出一个结果数据类型,告诉您表达式是不满足要求的还是表达式可以满足的,这就是所有变量的含义。 Your propositions can be implemented as variables whose truth values you already know to be true. 您的主张可以实现为变量,您已经知道其真值是真实的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM