检查haskell中的公式是否正确

时间:2012-04-23 07:41:28

标签: haskell gadt

----更新2 ----

最后,他告诉我那是Exists ......

谢谢大家。

----更新----

好的,我们称之为Forsome

ex3: forsome x0::[False,True]. forsome x1::[0,1,2]. (x0 || (0 < x1))

(谁告诉我“什么是forall”补充):

the constructor says "forall x in blah" but it really means "for some x in blah". 

the formula is satisfied for some assignment of variables so it is satisfiable.

我该怎么办? 感谢

----原创----

假设我们有一个公式ex3

ex3: forall x0::[False,True]. forall x1::[0,1,2]. (x0 || (0 < x1))

起初我认为ex3是False,因为当x0 = Falsex1 = 0公式为(False || (0 < 0))时,ex3绝对是假的。但我被告知ex3是True

"satisfiable ex3 is true because there is at least one combination from sets x0 and x1 which returns true. So as long as there is 1 valid solution in Forall, it is true."

假设这是正确的......

我认为需要检查具有相同级别的组合组,但我不知道该怎么做。确定“他们是同一群体”似乎很难。

这是我的代码:

文件:Formula.hs

{-# LANGUAGE GADTs #-}

module Formula where

-- Datatype of formulas
-- --------------------

data Formula ts where
  Body   :: Term Bool                     -> Formula ()
  Forall :: Show a 
         => [a] -> (Term a -> Formula as) -> Formula (a, as)

data Term t where
  Con     :: t         -> Term t
  And     :: Term Bool -> Term Bool -> Term Bool
  Or      :: Term Bool -> Term Bool -> Term Bool
  Smaller :: Term Int  -> Term Int  -> Term Bool
  Plus    :: Term Int  -> Term Int  -> Term Int
  Name    :: String    -> Term t    -- to facilitate pretty printing

-- Pretty printing formulas
-- ------------------------

instance Show t => Show (Term t) where
  show (Con v)       = show v
  show (And p q)     = "(" ++ show p ++ " && " ++ show q ++ ")"
  show (Or p q)      = "(" ++ show p ++ " || " ++ show q ++ ")"
  show (Smaller n m) = "(" ++ show n ++ " < "  ++ show m ++ ")"
  show (Plus n m)    = "(" ++ show n ++ " + "  ++ show m ++ ")"
  show (Name name)   = name

instance Show (Formula ts) where
  show = show' ['x' : show i | i <- [0..]]
    where
      show' :: [String] -> Formula ts' -> String
      show' ns     (Body body)   = show body
      show' (n:ns) (Forall vs p) = "forall " ++ n ++ "::" ++ show vs ++ ". " ++ show' ns (p (Name n))


-- Example formulas
-- ----------------

ex1 :: Formula ()
ex1 = Body (Con True)

ex2 :: Formula (Int, ())
ex2 = Forall [1..10] $ \n ->
        Body $ n `Smaller` (n `Plus` Con 1)

ex3 :: Formula (Bool, (Int, ()))
ex3 = Forall [False, True] $ \p -> 
      Forall [0..2] $ \n -> 
        Body $ p `Or` (Con 0 `Smaller` n)

wrongFormula :: Formula (Int, ())
wrongFormula = Forall [0..4] $ \n ->
                 Body $ n `Smaller` (Con 0)

文件:Solver.hs

{-# LANGUAGE GADTs #-}

module Solver where

import Formula


-- Evaluating terms
-- ----------------

eval :: Term t -> t
eval (Con     v)   = v
eval (And     p q) = eval p && eval q
eval (Or      p q) = eval p || eval q
eval (Smaller n m) = eval n <  eval m
eval (Plus    n m) = eval n +  eval m
eval (Name    _)   = error "eval: Name"


-- Checking formulas
-- -----------------

satisfiable :: Formula ts -> Bool
satisfiable (Body body)    = eval body
-- FIXME wrong implement
--satisfiable (Forall xs f) = helper f xs
--  where helper :: (Term a -> Formula t) -> [a] -> Bool
--        helper fn (a:as) = (satisfiable $ (fn . Con) a) && (helper fn as)
--        helper _ []     = True

任何建议都将受到赞赏。

1 个答案:

答案 0 :(得分:1)

我同意丹尼尔的说法,这描述的是Exists,而不是Forall,但如果您想以这种方式解释,则只需将&&更改为||即可TrueFalse

或者,更好的是,使用Prelude功能

all :: (a -> Bool) -> [a] -> Bool  -- is predicate true for all elements?
any :: (a -> Bool) -> [a] -> Bool  -- is predicate true for any element?

您可以将现有的实现编写为

satisfiable (Forall xs f) = all (satisfiable . f . Con) xs

所以要更改它,您只需将all更改为any