実存ゴルフ


22

数学には多くの記号があります。シンボルが多すぎると言う人もいるかもしれません。それでは、写真でいくつかの数学をしましょう。

紙を用意しましょう。これを参考にします。紙が空の状態で開始するには、それがまたはtrueと同等であると言いますtrue

紙に他のことを書くと、それも真実です。

例えば

PおよびQ

クレームおよびQが真であることを示します。PQ

ここで、ステートメントの周りに円を描くと、そのステートメントは偽であると言えます。これは論理的な否定を表します。

例えば:

PおよびQではない

が偽で、Qが真であることを示します。PQ

複数のサブステートメントの周りに円を配置することもできます。

ない(PおよびQ)

円の内側の部分は円を囲むことで通常として読むので、それは意味しません  P  と  Q 。サークルをネストすることもできますP and Qnot (P and Q)

not(PおよびQではない)

not ((not P) and Q)

false

偽

空のスペースが真であったため、真の否定は偽です。

この単純な視覚的方法を使用して、命題論理のステートメントを実際に表現できます。

証明

ステートメントを表現できるようになった後の次のステップは、ステートメントを証明できるようにすることです。証明には、グラフの変換に使用できる4つの異なるルールがあります。私たちは常に空のシートから始めます。これは私たちが知っているように空虚な真実であり、次にこれらの異なるルールを使用して空のシートを定理に変換します。

最初の推論ルールはInsertionです。

挿入

サブグラフとトップレベルの間の否定の数を「深さ」と呼びます。挿入により、私たちは奇妙な深さで私たちが望む任意のステートメントを導入することができます。

挿入を実行する例は次のとおりです。

挿入例

P

消去

次の推論規則はErasureです。 Erasureは、より深いステートメントがある場合、完全に削除できることを示しています。

適用される消去の例を次に示します。

消去の例

Q2P1

ダブルカット

ダブルカットは同等です。つまり、以前の推論とは異なり、逆にすることもできます。 ダブルカットは、サブグラフの周りに2つの円を描くことができ、サブグラフの周りに2つの円がある場合、両方を削除できることを示しています。

以下は、使用されているダブルカットの例です

ダブルカットの例

Q

反復

反復も同等です。1その逆は「反復」と呼ば れます。同じレベルにステートメントとカットがある場合、カット内にそのステートメントをコピーできます。

例えば:

反復の例

反復により、反復を逆にすることができます。次のレベルでコピーが存在する場合、ステートメントはDeiterationを介して削除できます。


この表現と証明の形式は、私自身の発明ではありません。これらは、Alpha Existential Graphsと呼ばれるダイアグラムロジックの小さな変更です。これについてもっと読みたい場合は、たくさんの文献はありませんが、リンクされた記事は良い出発点です。


仕事

あなたの仕事は、次の定理を証明することです。

Łukasiewicz-タルクシ公理

これは、従来の論理記号化に変換すると

((A(BA))(((¬C(D¬E))((C(DF))((ED)(EF))))G))(HG)

Łukasiewicz-Tarski公理とも呼ばれます。

複雑に思えるかもしれませんが、実在グラフは証明長に関して非常に効率的です。この定理を選んだのは、楽しくてやりがいのあるパズルに適した長さだと思うからです。これで問題が発生した場合は、最初にいくつかの基本的な定理を試して、システムのハングを取得することをお勧めします。これらのリストは、投稿の下部にあります。

これはので、スコアはプルーフの最初から最後までの合計ステップ数になります。目標は、スコアを最小化することです。

フォーマット

このチャレンジの形式は柔軟で、手書き形式やレンダリング形式など、明確に判読可能な形式で回答を送信できます。ただし、明確にするために、次の単純な形式をお勧めします。

  • かっこでカットを表します。カットするものはすべて括弧の内側に配置されます。空のカットは単なる()例です。

  • 原子を文字だけで表します。

例として、この形式の目標ステートメントを示します。

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

この形式は人間と機械の両方で読み取り可能であるため便利であり、投稿に含めるとよいでしょう。

素敵な(図式的な)図が必要な場合は、この形式を変換するコードがありますLATEX

オンラインでお試しください!

実際の仕事については、ワークアウトするときに鉛筆と紙をお勧めします。実在するグラフに関しては、テキストは紙ほど直感的ではないことがわかります。

証明の例

この証明の例では、次の定理を証明します。

反陽性の法則

(AB)(¬B¬A)

証明:

証明の例1

練習定理

以下に、システムの練習に使用できる簡単な定理をいくつか示します。

Łukasiewiczの第二公理

Łukasiewiczの第二公理

メレディスの公理

メレディスの公理

1:ほとんどのソースは、より洗練された強力なバージョンのIterationを使用していますが、この課題を簡単にするために、このバージョンを使用しています。それらは機能的に同等です。


この質問は不可解に適しているように感じます
コナーオブライエン

4
@ ConorO'Brienなんで?パズルは、主に最適化よりも回答に関係しています。この質問への回答は非常に簡単で、ほとんどがゴルフの課題です。
小麦ウィザード

不可解は最適化に非常に関係します。私はこの挑戦が不可解でより良い家を見つけるかもしれないと感じます、しかしそれはもちろん私の意見です
コナー・オブライエン

4
@connorobrien proof-golfは、このコミュニティの長い間確立された一部であり、今後も長く続くでしょう。
ナサニエル

1
これらの種類の表現に関する楽しいインタラクティブなFlashアプレットを備えたサイトを次に示します。markability.net
Woofmao

回答:


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の2番目の公理: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の第2公理の解決策: [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))))))

Meredithの公理のソリューション: [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があり、\$開始/終了として使用しているため、ソリューションが読みやすくなります。ここで
楽しい

使用するルールの数を更新しました(証明は変わりません)。フォーマットに長けた人が私の答えを改善するのを手伝ってもらえますか?
ロジカブル
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.