태그 보관물: proof-golf

proof-golf

기존 골프 우리는 컷의

수학에는 많은 기호가 있습니다. 일부는 너무 많은 기호를 말할 수 있습니다. 그림으로 수학을 해봅시다.

우리가 그릴 종이를 만들어 봅시다. 종이를 비우려면 또는 .사실

참된

우리가 종이에 다른 것을 쓰면 그것들도 사실입니다.

예를 들어

P와 Q

클레임 및 가 참 임을 나타냅니다 .Q

이제 우리가 어떤 진술에 동그라미를 그리면 그 진술이 거짓이라고 말합시다. 논리적이지 않음을 나타냅니다.

예를 들면 다음과 같습니다.

P와 Q가 아님

가 거짓이고 가 참 임을 나타냅니다 .Q

여러 하위 문 주위에 원을 배치 할 수도 있습니다.

아닙니다 (P와 Q)

원 안의 부분은 일반적으로 원 을 넣어 로 읽으므로 합니다. 우리는 심지어 서클을 중첩시킬 수 있습니다아님  ( P  와  Q )

 과 

아니 ( 과 )

아님 (P와 Q 아님)

이것은 로 읽습니다 .

아니 ((아니 ) 과 )

아무것도없는 원을 그리면 또는 를 나타냅니다 . 거짓

그릇된

그릇된

빈 공간이 참이므로 참에 대한 부정은 거짓입니다.

이제이 간단한 시각적 방법을 사용하여 실제로 모든 제안서를 논리로 표현할 수 있습니다.

증명

진술을 표현한 후 다음 단계는이를 입증 할 수있는 것입니다. 증명을 위해 그래프를 변환하는 데 사용할 수있는 4 가지 규칙이 있습니다. 우리는 항상 공허한 진실이라는 빈 시트로 시작한 다음이 다른 규칙을 사용하여 빈 종이를 정리로 변환합니다.

첫 번째 추론 규칙은 삽입 입니다.

삽입

하위 그래프와 최상위 수준 사이의 부정 수를 “깊이”라고합니다. 삽입 은 우리가 원하는 깊이의 진술을 이상한 깊이로 소개 할 수있게합니다.

다음은 삽입을 수행하는 예입니다.

삽입 예

여기서 를 선택 했지만 원하는 문장을 선택할 수도 있습니다.

지워 없앰

다음 추론 규칙은 삭제 입니다. Erasure 는 우리에게 깊이있는 진술이 있으면 완전히 제거 할 수 있다고 말합니다.

삭제가 적용되는 예는 다음과 같습니다.

삭제 예

2

1

더블 컷

더블 컷 은 동등합니다. 즉, 이전의 추론과 달리 반대로 할 수도 있습니다. Double Cut 은 하위 그래프 주위에 두 개의 원을 그릴 수 있으며 하위 그래프 주위에 두 개의 원이 있으면 둘 다 제거 할 수 있습니다.

다음은 사용중인 더블 컷 의 예입니다.

더블 컷 예

되풀이

반복 도 동등합니다. 1 그것은 역이라고있어 Deiteration 우리가 성명과 동일한 수준에 상처가있는 경우, 우리는 컷의 내부에 그 문을 복사 할 수 있습니다.

예를 들면 다음과 같습니다.

반복 예

Deiteration는 우리가 반대 할 수 반복을 . 다음 레벨에서 사본이 있으면 반복을 통해 명령문을 제거 할 수 있습니다 .


이러한 형식의 표현 및 증거는 저 자신의 발명이 아닙니다. 그것들은 Alpha Existential Graphs 라고 불리는 다이어그램 논리를 약간 수정 한 것입니다 . 이것에 대해 더 많이 읽으려면 많은 문헌이 없지만 링크 된 기사가 좋습니다.


태스크

당신의 임무는 다음 정리를 증명하는 것입니다.

우카지에 비츠-Tarksi Axiom

이것은 전통적인 논리 기호로 변환 할 때

((에이(에이))(((¬기음(¬이자형))((기음(에프))((이자형)(이자형에프))))))(H)

.

Łukasiewicz-Tarski Axiom 이라고도합니다 .

포함 된 것처럼 보일 수도 있지만 실증 길이 에 대해서는 실존 그래프가 매우 효율적입니다. 재미 있고 도전적인 퍼즐에 적합한 길이라고 생각하기 때문에이 정리를 선택했습니다. 이 문제에 어려움이 있다면 먼저 시스템의 중단을 얻기 위해 몇 가지 기본 정리를 시도하는 것이 좋습니다. 이 목록은 게시물 하단에 있습니다.

이것은 이므로 점수는 증거의 처음부터 끝까지의 총 단계 수입니다. 목표는 점수를 최소화하는 것입니다.

체재

이 과제의 형식은 유연성이 뛰어나므로 직접 작성하거나 렌더링 한 형식을 포함하여 명확하게 읽을 수있는 형식으로 답변을 제출할 수 있습니다. 그러나 명확성을 위해 다음과 같은 간단한 형식을 제안합니다.

  • 우리는 괄호 안에 컷을 나타냅니다. 빈 컷은 ()예를 들어 있습니다.

  • 우리는 단지 글자로 원자를 나타냅니다.

다음은이 형식의 목표 설명입니다.

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

이 형식은 사람이 읽을 수 있고 기계를 읽을 수 있으므로 게시물에 포함시키는 것이 좋습니다.

멋진 (ish) 다이어그램을 원한다면이 형식을 로 변환하는 코드가 있습니다.

에이이자형엑스

온라인으로 사용해보십시오!

실제 작업은 운동 할 때 연필과 종이를 권장합니다. 실존 그래프와 관련하여 텍스트가 종이만큼 직관적이지 않다는 것을 알았습니다.

증거 예

이 예시 증명에서 우리는 다음 정리를 증명할 것입니다.

피임약의 법칙

(에이)(¬¬에이)

증명:

예제 1

연습 정리

다음은 시스템을 연습하는 데 사용할 수있는 간단한 정리입니다.

우카시에 비츠의 두 번째 원칙

우카시에 비츠의 두 번째 원칙

메러디스의 공리

메러디스의 공리

1 : 대부분의 소스는 더 정교하고 강력한 Iteration 버전을 사용 하지만이 과제를 간단하게 유지하기 위해이 버전을 사용하고 있습니다. 그것들은 기능적으로 동일합니다.



답변

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)))) 【더블 컷】

연습 정리

우카시에 비츠의 두 번째 원칙 : 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)))))) [삽입]

하스켈 증명 검색기

(내가 손으로 그렇게 할 줄 알았 니? :-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)


답변

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는 더미 변수로 사용되므로 언제든지 삽입 할 수 있습니다.


연습 정리 솔루션 :

우카지에 비치의 두 번째 원칙에 대한 해결책 : [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)))))


답변