存在高尔夫


22

数学有很多符号。有些人可能会说太多符号。因此,让我们对图片进行一些数学运算。

让我们来一张纸,我们将以此为基础。首先,本文为空,我们将说等同于或。真正

如果我们在纸上写其他东西,它们也将是正确的。

例如

P和Q

表示声明和是正确的。P

现在让我们说,如果我们围绕某个陈述画一个圆圈,则该陈述是错误的。这代表逻辑不。

例如:

不是P和Q

表示为假,为真。P

我们甚至可以将圆圈放在多个子语句周围:

不(P和Q)

由于圆内的部分通常在圆上加上一个圆,因此读作,因此表示。我们甚至可以嵌套圈子P 和 不 P 和 

不是(不是P和Q)

读为。不 不 P 和 

如果我们绘制一个没有任何内容的圆,则表示 或。

假

由于空白为真,因此对否定为假。

现在,使用这种简单的可视方法,我们实际上可以表示命题逻辑中的任何陈述。

证明

能够表示语句之后的下一步就是能够证明它们。对于证明,我们有4种不同的规则可用于变换图形。我们总是从一张空纸开始,我们知道这是一个虚无的事实,然后使用这些不同的规则将空纸转换为一个定理。

我们的第一个推理规则是插入

插入

我们将子图与顶层之间的否定数称为“深度”。插入允许我们以奇怪的深度介绍我们希望的任何语句。

这是我们执行插入的示例:

插入示例

在这里,我们选择,但是我们也可以选择我们想要的任何语句。P

删除

下一个推断规则是Erasure擦除告诉我们,如果我们发表的声明深度不一,则可以将其完全删除。

以下是应用擦除的示例:

删除示例

这里我们删除了,因为它嵌套了级别。即使我们想要我们也不能擦除因为它是级嵌套的。2P1个

双切

Double Cut是等效的。这意味着,与之前的推论不同,它也可以颠倒。 Double Cut告诉我们可以在任何子图上绘制两个圆,如果子图上有两个圆,则可以将它们都删除。

下面是示例两倍减少所使用

双切示例

在这里,我们对使用Double Cut

迭代

迭代也是等效的。1相反,这称为Deiteration 如果我们在同一级别上有一条语句和剪切,则可以在剪切中复制该语句。

例如:

迭代示例

细化允许我们逆转迭代。如果语句在下一级上存在,则可以通过Deiteration删除该语句。


这种表示和证明的格式不是我自己的发明。它们是对称为Alpha Existential Graphs的逻辑图的较小修改。如果您想阅读更多有关此的内容,则没有很多文献,但是链接的文章是一个好的开始。


任务

您的任务将是证明以下定理:

Łukasiewicz-塔克西公理

当翻译成传统的逻辑符号时,

一种一种¬Cd¬ËCdFËdËFGHG

也称为Łukasiewicz-TarskiAxiom

它看起来似乎很复杂,但是当涉及到证明长度时,存在图非常有效。我选择此定理是因为我确实认为它是一个有趣且具有挑战性的难题的适当长度。如果您对此有疑问,我建议您先尝试一些更基本的定理来掌握系统的原理。这些的列表可以在帖子底部找到。

这是因此您的分数将是证明中从头到尾的总步数。目的是使您的分数最小化。

格式

挑战的格式很灵活,您可以以任何清晰可读的格式提交答案,包括手绘或渲染格式。但是为了清楚起见,我建议使用以下简单格式:

  • 我们用括号来表示切口,无论切口是放在括号内。空切只是一个()例子。

  • 我们只用原子来表示原子。

例如,以下是这种格式的目标声明:

(((A((B(A))))(((((C)((D((E)))))(((C((D(F))))(((E(D))((E(F))))))))(G))))((H(G))))

这种格式很不错,因为它既可以人工读取,也可以机器可读,因此在您的帖子中包含它也是不错的选择。

如果您需要一些漂亮的图表,则可以使用以下代码将该格式转换为:大号一种ŤËX

在线尝试!

至于您的实际工作,我建议在锻炼时使用铅笔和纸。我发现在存在图方面,文字不像纸张那样直观。

样例证明

在此示例证明中,我们将证明以下定理:

对立定律

现在,这乍一看对您来说似乎陌生,但是如果将其转换为传统的逻辑表示法,我们会得到,也被称为对立定律。一种¬¬一种

证明:

样例1

实践定理

以下是一些可以用来练习系统的简单定理:

Łukasiewicz的第二公理

Łukasiewicz的第二公理

梅勒迪斯公理

梅勒迪斯公理

1:大多数资源使用更复杂,功能更强大的Iteration版本,但是为了简化此挑战,我正在使用此版本。它们在功能上是等效的。


我觉得这个问题更适合令人困惑
Conor O'Brien

4
@ ConorO'Brien为什么?令人费解的主要是回答而不是优化。这个问题很容易回答,主要是打高尔夫球。
小麦巫师

令人费解的事情可能与优化有关。我觉得这个挑战可能会让您感到困惑,但这当然只是我的意见
Conor O'Brien

4
@connorobrien 证明高尔夫是这个社区中一个由来已久的部分,并且可能会持续很长时间。
纳撒尼尔(Nathaniel)

1
这是一个带有有趣的交互式Flash小程序的网站,涉及这些类型的表达式:markability.net
Woofmao

Answers:


7

19步

  1. (()) [双剪]
  2. (AB()(((G)))) [插入]
  3. (AB(A)(((G)))) [迭代]
  4. (((AB(A)))(((G)))) [双剪]
  5. (((AB(A))(((G))))(((G)))) [迭代]
  6. (((AB(A))(((G))))((H(G)))) [插入]
  7. (((AB(A))(((G)(()))))((H(G)))) [双剪]
  8. (((AB(A))(((DE()(C)(F))(G))))((H(G)))) [插入]
  9. (((AB(A))(((DE(C)(DE(C))(F))(G))))((H(G)))) [迭代]
  10. (((AB(A))(((DE(CD(F))(DE(C))(F))(G))))((H(G)))) [迭代]
  11. (((AB(A))(((E(CD(F))(DE(C))(F)((D)))(G))))((H(G)))) [双剪]
  12. (((AB(A))(((E(CD(F))(DE(C))(E(D))(F))(G))))((H(G)))) [迭代]
  13. (((AB(A))(((G)((CD(F))(DE(C))(E(D))((E(F)))))))((H(G)))) [双剪]
  14. (((AB(A))(((G)((CD(F))(DE(C))(((E(D))((E(F)))))))))((H(G)))) [双剪]
  15. (((AB(A))(((G)((C((D(F))))(DE(C))(((E(D))((E(F)))))))))((H(G)))) [双剪]
  16. (((AB(A))(((G)((DE(C))(((C((D(F))))(((E(D))((E(F)))))))))))((H(G)))) [双剪]
  17. (((AB(A))(((G)((D(C)((E)))(((C((D(F))))(((E(D))((E(F)))))))))))((H(G)))) [双剪]
  18. (((AB(A))(((G)(((C)((D((E)))))(((C((D(F))))(((E(D))((E(F)))))))))))((H(G)))) [双剪]
  19. (((A((B(A))))(((G)(((C)((D((E)))))(((C((D(F))))(((E(D))((E(F)))))))))))((H(G)))) [双剪]

实践定理

Łukasiewicz的第二个公理:7步

  1. (()) [双剪]
  2. (A()(B)(C)) [插入]
  3. (A(A(B))(B)(C)) [迭代]
  4. (A(AB(C))(A(B))(C)) [迭代]
  5. ((AB(C))(A(B))((A(C)))) [双剪]
  6. ((AB(C))(((A(B))((A(C)))))) [双剪]
  7. ((A((B(C))))(((A(B))((A(C)))))) [双剪]

梅勒迪斯的公理:11个步骤

  1. (()) [双剪]
  2. (()(D(A)(E))) [插入]
  3. ((D(A)(E))((D(A)(E)))) [迭代]
  4. ((D(A)(E))((D(A)(E(A))))) [迭代]
  5. ((D(A)(E))(((E(A))((D(A)))))) [双剪]
  6. (((E)((D(A))))(((E(A))((D(A)))))) [双剪]
  7. (((E)((C)(D(A))))(((E(A))((D(A)))))) [插入]
  8. (((E)((C)(D(A)(C))))(((E(A))((D(A)))))) [迭代]
  9. (((E)((C)((A)(C)((D)))))(((E(A))((D(A)))))) [双剪]
  10. (((E)((C)((A)(((C)((D)))))))(((E(A))((D(A)))))) [双剪]
  11. (((E)((C)((A(B))(((C)((D)))))))(((E(A))((D(A)))))) [插入]

Haskell证明搜索者

(什么,你以为我要手动做?:-P)

这仅尝试插入,双切引入和迭代。因此,仍然有可能使用擦除,双截消除或除法来击败这些解决方案。

{-# LANGUAGE ViewPatterns #-}

import Control.Applicative hiding (many)
import Data.Char
import Data.Function hiding ((&))
import qualified Data.Map as M
import Data.Maybe
import qualified Data.MultiSet as S
import qualified Data.PQueue.Prio.Min as Q
import System.IO
import Text.ParserCombinators.ReadP

type Var = Char

data Part
  = Var Var
  | Not Conj
  deriving (Eq, Ord)

instance Show Part where
  show (Var s) = [s]
  show (Not c) = "(" ++ show c ++ ")"

newtype Conj = Conj
  { parts :: S.MultiSet Part
  } deriving (Eq, Ord)

instance Show Conj where
  show (Conj (S.toAscList -> [])) = ""
  show (Conj (S.toAscList -> g:gs)) =
    show g ++ concat ["" ++ show g1 | g1 <- gs]

true :: Conj
true = Conj S.empty

not_ :: Conj -> Conj
not_ = Conj . S.singleton . Not

(&) :: Conj -> Conj -> Conj
Conj as & Conj bs = Conj (S.union as bs)

intersect :: Conj -> Conj -> Conj
intersect (Conj as) (Conj bs) = Conj (S.intersection as bs)

diff :: Conj -> Conj -> Conj
diff (Conj as) (Conj bs) = Conj (S.difference as bs)

splits :: Conj -> [(Conj, Conj)]
splits =
  S.foldOccur
    (\a o bcs ->
       [ (Conj (S.insertMany a o1 bs), Conj (S.insertMany a (o - o1) cs))
       | (Conj bs, Conj cs) <- bcs
       , o1 <- [0 .. o]
       ])
    [(true, true)] .
  parts

moves :: Bool -> Conj -> [(Conj, String)]
moves ev a =
  (do (b, c) <- splits a
      andMoves ev b c) ++
  (do (p, _) <- S.toOccurList (parts a)
      partMoves ev p (Conj (S.delete p (parts a))))

andMoves :: Bool -> Conj -> Conj -> [(Conj, String)]
andMoves ev a b = [(a, "insertion") | not ev]

partMoves :: Bool -> Part -> Conj -> [(Conj, String)]
partMoves ev (Not a) b =
  [(a1 & b, why) | (a1, why) <- notMoves ev a] ++
  [ (not_ (diff a d) & b, "iteration")
  | (d, _) <- splits (intersect a b)
  , d /= true
  ]
partMoves _ (Var _) _ = []

notMoves :: Bool -> Conj -> [(Conj, String)]
notMoves ev a =
  (case S.toList (parts a) of
     [Not b] -> [(b, "double cut")]
     _ -> []) ++
  [(not_ a1, why) | (a1, why) <- moves (not ev) a]

partSat :: Part -> Bool -> M.Map Var Bool -> [M.Map Var Bool]
partSat (Var var) b m =
  case M.lookup var m of
    Nothing -> [M.insert var b m]
    Just b1 -> [m | b1 == b]
partSat (Not c) b m = conjSat c (not b) m

conjSat :: Conj -> Bool -> M.Map Var Bool -> [M.Map Var Bool]
conjSat c False m = do
  (p, _) <- S.toOccurList (parts c)
  partSat p False m
conjSat c True m = S.foldOccur (\p _ -> (partSat p True =<<)) [m] (parts c)

readConj :: ReadP Conj
readConj = Conj . S.fromList <$> many readPart

readPart :: ReadP Part
readPart =
  Var <$> satisfy isAlphaNum <|> Not <$> (char '(' *> readConj <* char ')')

parse :: String -> Maybe Conj
parse s = listToMaybe [c | (c, "") <- readP_to_S readConj s]

partSize :: Part -> Int
partSize (Var _) = 1
partSize (Not c) = 1 + conjSize c

conjSize :: Conj -> Int
conjSize c = sum [partSize p * o | (p, o) <- S.toOccurList (parts c)]

data Pri = Pri
  { dist :: Int
  , size :: Int
  } deriving (Eq, Show)

instance Ord Pri where
  compare = compare `on` \(Pri d s) -> (s + d, d)

search ::
     Q.MinPQueue Pri (Conj, [(Conj, String)])
  -> M.Map Conj Int
  -> [[(Conj, String)]]
search (Q.minViewWithKey -> Nothing) _ = []
search (Q.minViewWithKey -> Just ((pri, (a, proof)), q)) m =
  [proof | a == true] ++
  uncurry search (foldr (addMove pri a proof) (q, m) (moves True a))

addMove ::
     Pri
  -> Conj
  -> [(Conj, String)]
  -> (Conj, String)
  -> (Q.MinPQueue Pri (Conj, [(Conj, String)]), M.Map Conj Int)
  -> (Q.MinPQueue Pri (Conj, [(Conj, String)]), M.Map Conj Int)
addMove pri b proof (a, why) (q, m) =
  case M.lookup a m of
    Just d
      | d <= d1 -> (q, m)
    _
      | null (conjSat a False M.empty) ->
        ( Q.insert (Pri d1 (conjSize a)) (a, (b, why) : proof) q
        , M.insert a d1 m)
    _ -> (q, m)
  where
    d1 = dist pri + 1

prove :: Conj -> [[(Conj, String)]]
prove c = search (Q.singleton (Pri 0 (conjSize c)) (c, [])) (M.singleton c 0)

printProof :: [(Conj, String)] -> IO ()
printProof proof = do
  mapM_
    (\(i, (a, why)) ->
       putStrLn (show i ++ ". `" ++ show a ++ "`  [" ++ why ++ "]"))
    (zip [1 ..] proof)
  putStrLn ""
  hFlush stdout

main :: IO ()
main = do
  Just theorem <- parse <$> getLine
  mapM_ printProof (prove theorem)

4

22步

(((())(())))

(((AB())(CDE(F)()))H(G))

(((AB(A))(CDE(F)(CD(F)))(G))H(G))

(((A((B(A))))(((((C))DE(F)(C((D(F)))))(G))))((H(G))))

(((A((B(A))))(((((C)DE)DE(F)(C((D(F)))))(G))))((H(G))))

(((A((B(A))))(((((C)((D((E)))))((((((D))E(F)))(C((D(F)))))))(G))))((H(G))))

(((A((B(A))))(((((C)((D((E)))))((((((D)E)E(F)))(C((D(F)))))))(G))))((H(G))))

(((A((B(A))))(((((C)((D((E)))))((((((D)E)((E(F)))))(C((D(F)))))(G))))))((H(G))))


我从完成此难题中学到了一些东西:

  • 减少提供的表示形式。这涉及到逆转两次切割和迭代。例如,该公理(((AB(A))(((C)DE)(CD(F))(E(D))(E(F)))(G))H(G))在反转两次切割后和(((AB(A))(()CDE(F)))H(G)))反转迭代后都减少为。

  • 寻找杂散原子。例如,H用作伪变量,因此可以在任何点插入。


练习定理解决方案:

Łukasiewicz第二公理的解决方案: [8个步骤]

(())

(()AB(C))

((AB(C))AB(C))

((A((B(C))))A((B))(C))

((A((B(C))))A(A(B))(C))

((A((B(C))))(((A(B))((A(C))))))

梅雷迪思公理的解决方案: [12个步骤]

(())

(()(A)D(E))

(((A)D(E))(A)D(E(A)))

(((((A)D))(E))(A)D(E(A)))

(((((A(B))D)(C))(E))(A)D(E(A)))

(((((A(B))(C)D)(C))(E))(A)D(E(A)))

(((((A(B))(((C)((D)))))(C))(E))(((((A)D))(E(A)))))


我已经更新了完整的解决方案。有趣的难题!请让我知道如何改善我的职位。
记录的

通常,这里的答案不是隐藏的-假定阅读答案就意味着解决方案的“破坏者”。另外,我们在这里有MathJax,\$用作开始/结束,我认为这将使您的解决方案更易于阅读。希望您在这里过得愉快:)
FryAmTheEggman '18

我已经更新了所使用规则的数量(证明保持不变)。擅长格式化的人可以帮助改善我的答案吗?
Logikable
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.