Objetivo:
Escrever um programa completo ou função que tem uma fórmula em lógica proposicional (daqui em diante referido como uma expressão lógica ou expressão ) e saídas que a fórmula na forma normal conjuntiva . Há duas constantes, ⊤
e ⊥
que representa o verdadeiro eo falso, um operador unário ¬
representando negação e operadores binários ⇒
, ⇔
, ∧
, e ∨
representando implicação, equivalência, conjunção e disjunção, respectivamente, que obedecer todas as operações lógicas habituais ( lei de DeMorgan , eliminação dupla negação etc.).
A forma normal conjuntiva é definida da seguinte forma:
- Qualquer expressão atômica (incluindo
⊤
e⊥
) está na forma conjuntiva normal. - A negação de qualquer expressão construída anteriormente está na forma conjuntiva normal.
- A disjunção de quaisquer duas expressões construídas anteriormente está na forma conjuntiva normal.
- A conjunção de quaisquer duas expressões construídas anteriormente está na forma normal conjuntiva.
- Qualquer outra expressão não está na forma normal conjuntiva.
Qualquer expressão lógica pode ser convertida (de maneira não exclusiva) em uma expressão logicamente equivalente na forma normal conjuntiva (consulte este algoritmo ). Você não precisa usar esse algoritmo específico.
Entrada:
Você pode receber informações em qualquer formato conveniente; por exemplo, uma expressão lógica simbólica (se o seu idioma suportar), uma string, alguma outra estrutura de dados. Você não precisa usar os mesmos símbolos para operadores verdadeiros, falsos e lógicos que eu faço aqui, mas sua escolha deve ser consistente e você deve explicar suas escolhas em sua resposta, se não estiver claro. Você não pode aceitar nenhuma outra entrada ou codificar nenhuma informação adicional em seu formato de entrada. Você deve ter alguma maneira de expressar um número arbitrário de expressões atômicas; por exemplo, números inteiros, caracteres, strings, etc.
Resultado:
A fórmula na forma normal conjuntiva, novamente em qualquer formato conveniente. Ele não precisa estar no mesmo formato da sua entrada, mas você deve explicar se há alguma diferença.
Casos de teste:
P ∧ (P ⇒ R) -> P ∧ R
P ⇔ (¬ P) -> ⊥
(¬ P) ∨ (Q ⇔ (P ∧ R)) -> ((¬ P) ∨ ((¬ Q) ∨ R)) ∧ ((¬ P) ∨ (Q ∨ (¬ R)))
Notas:
- Se a expressão de entrada for uma tautologia,
⊤
seria uma saída válida. Da mesma forma, se a expressão de entrada for uma contradição,⊥
seria uma saída válida. - Os formatos de entrada e saída devem ter uma ordem de operações bem definida, capaz de expressar todas as expressões lógicas possíveis. Você pode precisar de parênteses de algum tipo.
- Você pode usar qualquer opção bem definida de notação de infixo, prefixo ou postfix para as operações lógicas. Se sua escolha for diferente do padrão (negação é prefixo, o restante é infixo), explique-o na sua resposta.
- A forma normal conjuntiva não é única em geral (nem mesmo reordenando). Você só precisa gerar um formulário válido.
- Entretanto, como você representa expressões atômicas, elas devem ser distintas das constantes lógicas, operadores e símbolos de agrupamento (se você os tiver).
- São permitidos embutidos que calculam a forma normal conjuntiva.
- As brechas padrão são proibidas.
- Isso é código-golfe ; a resposta mais curta (em bytes) vence.
P
e (P ∨ Q) ∧ (P ∨ (¬Q))
ambas estão na forma normal conjuntiva.