Golf existencial

22

Las matemáticas tienen muchos símbolos. Algunos pueden decir demasiados símbolos. Así que hagamos un poco de matemáticas con imágenes

Vamos a tener un papel, en el que nos basaremos. Para comenzar el papel está vacío, diremos que es equivalente a o cierto .

Si escribimos otras cosas en el papel, también serán ciertas.

Por ejemplo

P y Q

Indica que las afirmaciones PAGS y Q son verdaderas.

Ahora digamos que si dibujamos un círculo alrededor de alguna declaración, esa declaración es falsa. Esto representa lógico no.

Por ejemplo:

no P y Q

Indica que es falso y Q es verdadero.PAGSQ

Incluso podemos colocar el círculo alrededor de múltiples subdeclaraciones:

no (P y Q)

Dado que la parte dentro del círculo normalmente se lee como al poner un círculo a su alrededor, significa que no  ( P  y  Q ) . Incluso podemos anidar círculosPAGS y Qno (PAGS y Q)

no (no P y Q)

Esto se lee como no ((no PAGS) y Q) .

Si dibujamos un círculo sin nada dentro, eso representa o falso . falso

Falso

Como el espacio vacío era verdadero, entonces la negación de lo verdadero es falsa.

Ahora, usando este método visual simple, podemos representar cualquier declaración en lógica proposicional.

Pruebas

El siguiente paso después de poder representar declaraciones es poder probarlas. Para las pruebas tenemos 4 reglas diferentes que se pueden usar para transformar un gráfico. Siempre comenzamos con una hoja vacía que, como sabemos, es una verdad vacía y luego usamos estas diferentes reglas para transformar nuestra hoja de papel vacía en un teorema.

Nuestra primera regla de inferencia es la inserción .

Inserción

Llamaremos al número de negaciones entre un sub-gráfico y el nivel superior es "profundidad". Inserción nos permite introducir cualquier declaración que deseamos a una profundidad extraña.

Aquí hay un ejemplo de nosotros realizando la inserción:

Ejemplo de inserción

PAGS

Borradura

La siguiente regla de inferencia es Erasure . Erasure nos dice que si tenemos una declaración que está a una profundidad uniforme, podemos eliminarla por completo.

Aquí hay un ejemplo de borrado aplicado:

Ejemplo de borrado

Q2PAGS1

Corte doble

Double Cut es una equivalencia. Lo que significa que, a diferencia de las inferencias anteriores, también se puede revertir. Doble corte nos dice que podemos dibujar dos círculos alrededor de cualquier gráfico secundario, y si hay dos círculos alrededor de un gráfico secundario, podemos eliminarlos a ambos.

Aquí está un ejemplo de la doble corte que se utiliza

Ejemplo de corte doble

Q

Iteración

La iteración también es una equivalencia. 1 Su reverso se llama Deiteración. Si tenemos una declaración y un corte en el mismo nivel, podemos copiar esa declaración dentro de un corte.

Por ejemplo:

Ejemplo de iteración

La deiteración nos permite revertir una iteración . Una declaración puede eliminarse mediante Deiteración si existe una copia de la misma en el siguiente nivel.


Este formato de representación y prueba no es de mi propia invención. Son una modificación menor de una lógica esquemática que se denominan Gráficos existenciales alfa . Si desea leer más sobre esto, no hay mucha literatura, pero el artículo vinculado es un buen comienzo.


Tarea

Su tarea será probar el siguiente teorema:

Łukasiewicz - Tarksi Axiom

Esto, cuando se traduce a la simbolización lógica tradicional es

((UNA(siUNA))(((¬do(re¬mi))((do(reF))((mire)(miF))))sol))(Hsol).

También conocido como el Axioma Łukasiewicz-Tarski .

Puede parecer complicado, pero los gráficos existenciales son muy eficientes cuando se trata de la longitud de la prueba. Seleccioné este teorema porque creo que es una longitud apropiada para un rompecabezas divertido y desafiante. Si tiene problemas con este, le recomendaría probar algunos teoremas más básicos primero para familiarizarse con el sistema. Puede encontrar una lista de estos en la parte inferior de la publicación.

Esto es por lo que su puntaje será el número total de pasos en su prueba de principio a fin. El objetivo es minimizar tu puntaje.

Formato

El formato para este desafío es flexible; puede enviar respuestas en cualquier formato que sea claramente legible, incluidos los formatos dibujados a mano o renderizados. Sin embargo, para mayor claridad, sugiero el siguiente formato simple:

  • Representamos un corte con paréntesis, todo lo que estamos cortando se coloca dentro de los parentescos. El corte vacío sería solo, ()por ejemplo.

  • Representamos átomos con solo sus letras.

Como ejemplo, aquí está la declaración de objetivos en este formato:

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

Este formato es bueno porque es legible tanto para humanos como para máquinas, por lo que incluirlo en tu publicación sería bueno.

LUNATmiX

Pruébalo en línea!

En cuanto a su trabajo real, le recomiendo lápiz y papel cuando haga ejercicio. Me parece que el texto no es tan intuitivo como el papel cuando se trata de gráficos existenciales.

Prueba de ejemplo

En este ejemplo, demostraremos el siguiente teorema:

Ley de contra-positivos

(UNAsi)(¬si¬UNA)

Prueba:

Prueba de ejemplo 1

Teoremas de práctica

Aquí hay algunos teoremas simples que puede usar para practicar el sistema:

Segundo axioma de Łukasiewicz

Segundo axioma de Łukasiewicz

El axioma de Meredith

El axioma de Meredith

1: La mayoría de las fuentes usan una versión más sofisticada y poderosa de Iteration , pero para mantener este desafío simple, estoy usando esta versión. Son funcionalmente equivalentes.

Asistente de trigo
fuente
Siento que esta pregunta es más adecuada para un enigma
Conor O'Brien
44
@ ConorO'Brien ¿Por qué? El enigma se preocupa principalmente por responder en lugar de optimizar. Esta pregunta es muy fácil de responder, lo que la convierte en un desafío de golf.
Wheat Wizard
El desconcierto puede estar muy relacionado con la optimización. Siento que este desafío podría encontrar un mejor hogar para los enigmas, pero esa es, por supuesto, solo mi opinión
Conor O'Brien el
44
@connorobrien prueba-golf es una parte establecida desde hace mucho tiempo de esta comunidad, y puede continuar por mucho tiempo.
Nathaniel
1
Aquí hay un sitio con un divertido applet interactivo de Flash sobre este tipo de expresiones: markability.net
Woofmao

Respuestas:

7

19 pasos

  1. (()) [doble corte]
  2. (AB()(((G)))) [inserción]
  3. (AB(A)(((G)))) [iteración]
  4. (((AB(A)))(((G)))) [doble corte]
  5. (((AB(A))(((G))))(((G)))) [iteración]
  6. (((AB(A))(((G))))((H(G)))) [inserción]
  7. (((AB(A))(((G)(()))))((H(G)))) [doble corte]
  8. (((AB(A))(((DE()(C)(F))(G))))((H(G)))) [inserción]
  9. (((AB(A))(((DE(C)(DE(C))(F))(G))))((H(G)))) [iteración]
  10. (((AB(A))(((DE(CD(F))(DE(C))(F))(G))))((H(G)))) [iteración]
  11. (((AB(A))(((E(CD(F))(DE(C))(F)((D)))(G))))((H(G)))) [doble corte]
  12. (((AB(A))(((E(CD(F))(DE(C))(E(D))(F))(G))))((H(G)))) [iteración]
  13. (((AB(A))(((G)((CD(F))(DE(C))(E(D))((E(F)))))))((H(G)))) [doble corte]
  14. (((AB(A))(((G)((CD(F))(DE(C))(((E(D))((E(F)))))))))((H(G)))) [doble corte]
  15. (((AB(A))(((G)((C((D(F))))(DE(C))(((E(D))((E(F)))))))))((H(G)))) [doble corte]
  16. (((AB(A))(((G)((DE(C))(((C((D(F))))(((E(D))((E(F)))))))))))((H(G)))) [doble corte]
  17. (((AB(A))(((G)((D(C)((E)))(((C((D(F))))(((E(D))((E(F)))))))))))((H(G)))) [doble corte]
  18. (((AB(A))(((G)(((C)((D((E)))))(((C((D(F))))(((E(D))((E(F)))))))))))((H(G)))) [doble corte]
  19. (((A((B(A))))(((G)(((C)((D((E)))))(((C((D(F))))(((E(D))((E(F)))))))))))((H(G)))) [doble corte]

Practica teoremas

Segundo axioma de Łukasiewicz: 7 pasos

  1. (()) [doble corte]
  2. (A()(B)(C)) [inserción]
  3. (A(A(B))(B)(C)) [iteración]
  4. (A(AB(C))(A(B))(C)) [iteración]
  5. ((AB(C))(A(B))((A(C)))) [doble corte]
  6. ((AB(C))(((A(B))((A(C)))))) [doble corte]
  7. ((A((B(C))))(((A(B))((A(C)))))) [doble corte]

El axioma de Meredith: 11 pasos

  1. (()) [doble corte]
  2. (()(D(A)(E))) [inserción]
  3. ((D(A)(E))((D(A)(E)))) [iteración]
  4. ((D(A)(E))((D(A)(E(A))))) [iteración]
  5. ((D(A)(E))(((E(A))((D(A)))))) [doble corte]
  6. (((E)((D(A))))(((E(A))((D(A)))))) [doble corte]
  7. (((E)((C)(D(A))))(((E(A))((D(A)))))) [inserción]
  8. (((E)((C)(D(A)(C))))(((E(A))((D(A)))))) [iteración]
  9. (((E)((C)((A)(C)((D)))))(((E(A))((D(A)))))) [doble corte]
  10. (((E)((C)((A)(((C)((D)))))))(((E(A))((D(A)))))) [doble corte]
  11. (((E)((C)((A(B))(((C)((D)))))))(((E(A))((D(A)))))) [inserción]

Haskell buscador de pruebas

(¿Qué, pensaste que iba a hacer eso a mano? :-P)

Esto solo intenta la inserción, la introducción de doble corte y la iteración. Por lo tanto, aún es posible que estas soluciones se superen mediante el borrado, la eliminación de doble corte o la deiteración.

{-# 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)
Anders Kaseorg
fuente
4

22 pasos

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

(((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)))) [Iteración]

(((A((B(A))))(((((C)((D((E)))))((((((D))E(F)))(C((D(F)))))))(G))))((H(G)))) [Doble corte x5]

(((A((B(A))))(((((C)((D((E)))))((((((D)E)E(F)))(C((D(F)))))))(G))))((H(G)))) [Iteración]

(((A((B(A))))(((((C)((D((E)))))((((((D)E)((E(F)))))(C((D(F)))))(G))))))((H(G)))) [Doble corte]


Algunas cosas que aprendí al completar este rompecabezas:

  • Reducir la representación provista. Esto implica invertir dobles cortes e iteraciones. Por ejemplo, este axioma se reduce (((AB(A))(((C)DE)(CD(F))(E(D))(E(F)))(G))H(G))después de revertir los cortes dobles y (((AB(A))(()CDE(F)))H(G)))después de revertir las iteraciones.

  • Busca átomos perdidos. Por ejemplo, H se usa como una variable ficticia y, por lo tanto, se puede insertar en cualquier punto.


Soluciones de teorema de práctica:

Solución para el segundo axioma de Łukasiewicz: [8 pasos]

(()) [Doble corte]

(()AB(C)) [Inserción]

((AB(C))AB(C)) [Iteración]

((A((B(C))))A((B))(C)) [Doble corte x2]

((A((B(C))))A(A(B))(C)) [Iteración]

((A((B(C))))(((A(B))((A(C)))))) [Doble corte x2]

Solución para el Axioma de Meredith: [12 pasos]

(()) [Doble corte]

(()(A)D(E)) [Inserción]

(((A)D(E))(A)D(E(A))) [Iteración x2]

(((((A)D))(E))(A)D(E(A))) [Doble corte]

(((((A(B))D)(C))(E))(A)D(E(A))) [Inserción x2]

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

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

Logikable
fuente
He actualizado para incluir mi solución completa. Divertido rompecabezas! Por favor, hágame saber cómo puedo mejorar mi publicación.
Logikable
En general, aquí las respuestas no están ocultas; la suposición es que leer la respuesta implica un "spoiler" a la solución. También tenemos MathJax aquí, que utiliza \$como principio / fin, lo que creo que haría que su solución sea mucho más fácil de leer. Espero que
pases
He actualizado el número de reglas utilizadas (la prueba sigue siendo la misma). ¿Alguien que sea bueno para formatear puede ayudarme a mejorar mi respuesta?
Logikable