Corrigindo um sistema lógico


16

Você recebe um conjunto de instruções lógicas. Seu desafio é remover todos os que contradizem os outros, mas da maneira ideal (por exemplo, remover um número mínimo de declarações).

Desafio

Você escreverá um programa ou uma função que recebe como entrada uma lista de instruções, remove o número mínimo de instruções de forma que exista uma solução e gera o restante.

Lógica

As instruções consistem em variáveis A-Z e operadores entre elas.

Existem 5 operadores : -(não), v(ou), ^(e), ->(se) e <->(iff).

Tabela da verdade:

A | B | -A | AvB | A^B | A->B | A<->B
0 | 0 |  1 |  0  |  0  |   1  |   1
0 | 1 |  1 |  1  |  0  |   1  |   0
1 | 0 |  0 |  1  |  0  |   0  |   0
1 | 1 |  0 |  1  |  1  |   1  |   1

Esses operadores podem ser combinados com parênteses ():

A | B | -(AvB) | Av(-A) | A^(-A) | (AvB)->(-B)
0 | 0 |    1   |    1   |    0   |      1
0 | 1 |    0   |    1   |    0   |      0
1 | 0 |    0   |    1   |    0   |      1
1 | 1 |    0   |    1   |    0   |      0

Os sistemas lógicos consistem em 1 ou mais instruções .

Uma solução para o sistema lógico é um estado em que todas as instruções são simultaneamente verdadeiras.

Exemplos de sistemas lógicos:

AvB
-(A<->B)
(AvB)->(-B)

A única solução é A = 1, B = 0.

A^B
-(B<->A)

Este não tem solução ; sem combinação de Ae Bambas as afirmações são verdadeiras.

Entrada

Você receberá um conjunto de instruções como entrada. Isso pode ser obtido via STDIN ou argumentos de função, formatados como uma matriz (em um formato conveniente) ou como uma sequência de nova linha ou espaço.

As declarações terão a seguinte forma (quase no ABNF ):

statement        = variable / operation
operation        = not-operation / binary-operation
not-operation    = "-" operand
binary-operation = operand binary-operator operand
operand          = variable / "(" operation ")"
variable         = "A"-"Z"
binary-operator  = "v" / "^" / "->" / "<->"

Exemplos de instruções:

A
Av(-B)
(A<->(Q^C))v((-B)vH)

Resultado

Você deve retornar o conjunto (possivelmente) reduzido de instruções, na forma exata em que as recebeu. Mais uma vez, a lista pode ser formatada como uma matriz de cadeias ou uma cadeia separada por nova linha ou separada por espaço.

Regras

  • Você sempre deve remover o número mínimo de instruções. Se houver várias soluções possíveis, imprima uma delas.
  • Você pode assumir que a entrada sempre contém pelo menos 1 instrução e que nenhuma instrução é repetida na entrada.
  • Você não pode assumir que a saída sempre contém uma declaração. (veja exemplos)
  • O uso de brechas padrão contradiz que sua resposta seja válida e uma delas deve ser removida.
  • Isso é , então a resposta mais curta em bytes vence.

Exemplos

Entrada:

A^(-A)

Resultado:

(nothing)

Entrada:

A^B A<->(-B) A<->B

Resultado:

A^B A<->B

Entrada:

["AvB","A^B"]

Resultado:

["AvB","A^B"]

3
Não sei se isso é relevante, mas esse problema se resume ao conjunto máximo de embalagens, que é NP-completo.
Leif Willerts

De acordo com a sua gramática, a terceira declaração no exemplo não está correta ( (AvB)->-Bdeve ser (AvB)->(-B))
haskeller orgulhoso

@proudhaskeller Obrigado, corrigi-lo.
PurkkaKoodari

Além disso, os parênteses em A<->(Q^C))v((-B)vHsão misturados.
haskeller orgulhoso

@proudhaskeller Obrigado novamente.
PurkkaKoodari

Respostas:


3

Rubi, 299 298 283 279 bytes

class Object;def * o;!self|o;end;def s;w=join.gsub(/\W/,"").chars.uniq;n=w.size;(0..2**n).any?{|i|n.times{|j|eval(w[j]+"=#{i[j]>0}")};all?{|e|eval([%w[<-> ==],%w[-> *],%w[- !],%w[^ &],%w[v |]].inject(e){|x,i|x.gsub(*i)})}}?self:combination(size-1).map(&:s).max_by(&:size);end;end
  • Espera uma matriz de expressões.
  • Se você for executá-lo, defina $ VERBOSE = nil a partir do ruby ​​para não receber muitos avisos sobre a redefinição de constantes.
  • Observe que ele também define a variável "v", mas não faz diferença.
  • Usa valores de verdade porque eles já têm todos os operadores necessários, exceto implicação. Infelizmente, Ruby não tem uma classe booleana, por isso precisamos fazer o patch do Object para obter implicações :)
  • Poderia torná-lo mais curto se apenas definirmos TODAS as variáveis ​​maiúsculas, mas levaria muito tempo para ser executado. Provavelmente deveria ter uma ressalva na pergunta sobre isso.

Ungolfed:

class Object
  def * o 
    !self|o
  end 
end

def sat? exs 
  #exs: an array of expressions
  s=[%w[<-> ==], %w[-> *], "-!", "^&", %w[v ||]]

  w=exs.join.gsub(/\W/,"").chars.uniq #variable names
  n=w.size
  if (0...2**n).any? {|i|
    n.times do |vi|
      eval("#{w[vi]}=#{i[vi]==1}")
    end 
    exs.all?{|ex|eval(s.inject(ex){|x,i|x.gsub(i[0],i[1])})}
  }
    exs
  else
    exs.combination(exs.size-1).map{|sm|sat?(sm)}.max_by(&:size)
  end
end

5

Python 3, 431 bytes

Não estou muito interessado no momento, mas acho que faria a bola rolar com uma resposta. Experimente aqui , g()é a principal função.

import re,itertools as H
def g(i):
 y=re.sub(r'\W','',''.join(set(i)).upper());l=i.split()
 def e(s):
  def f(a):
   for v,w in a:exec(v+'='+w)
   return eval(re.sub('[^A-Z()]+',lambda x:{'v':' or ','^':'*','<->':'==','->':'<=','-':'not '}[x.group()],s))
  return[c for c in H.product("01",repeat=len(y))if f(zip(y,c))]
 for n in range(len(l),-1,-1):
  for q in H.combinations(l,n):
   if e('('+')^('.join(q)+')'):return' '.join(q)

Muito legal. Eu consegui baixá
PurkkaKoodari

Há um problema com a maneira como você está modelando valores de verdade. Por exemplo, g ("A (AvA) <-> A") deve retornar sua entrada, mas não funciona porque se A = 1, AvA = 2.
Ibrahim Tencer

Aha, você está certo, obrigado por apontar isso. Reverti de volta para "e" por enquanto, pois não conseguia pensar em uma maneira mais curta de compará-los. Também obrigado pelas mudanças no golfe Pietu!
TheMadHaberdasher

Eu acredito que vseja or.
PurkkaKoodari

...sim. Obrigado.
TheMadHaberdasher
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.