Закріплення логічної системи


16

Вам надається набір логічних висловлювань. Ваше завдання полягає в тому, щоб видалити всі, які суперечать іншим, але оптимальним способом (тобто видалити мінімальну кількість висловлювань).

Виклик

Ви напишете програму або функцію, яка приймає в якості списку висловлювань, видаляє мінімальну кількість висловлювань таким чином, що є рішення та виводить решту.

Логіка

Заяви складаються з змінних A-Z та операторів між ними.

Існує 5 операторів : -(не), v(або), ^(і), ->(якщо) і <->(iff).

Таблиця правди:

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

Ці оператори можуть бути об'єднані разом з дужками ():

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

Логічні системи складаються з 1 або більше операторів .

Рішення для логічної системи є стан , в якому все заяви одночасно є правдою.

Приклади логічних систем:

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

Єдине рішення - це A = 1, B = 0.

A^B
-(B<->A)

У цього немає рішення ; без поєднання Aі Bобох тверджень є правдивими.

Вхідні дані

Ви отримаєте набір операторів як вхідних даних. Це можна прийняти за допомогою STDIN або аргументів функції, відформатованих у вигляді масиву (у зручному форматі) або нового рядка, розділеного рядком або пробілом.

Виписки будуть мати таку форму (майже - 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" / "^" / "->" / "<->"

Приклади тверджень:

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

Вихідні дані

Ви повинні повернути (можливо) зменшений набір висловлювань у точній формі, в якій ви їх отримали. Знову ж таки, список може бути відформатований у вигляді масиву рядків або рядка, розділеного новим рядком або розділеного пробілом.

Правила

  • Ви завжди повинні видаляти мінімальну кількість висловлювань. Якщо існує кілька можливих рішень, виведіть одне з них.
  • Ви можете припустити, що вхід завжди містить щонайменше 1 вислів і що жодні заяви не повторюються у введенні.
  • Ви можете не припускати, що результат завжди містить оператор. (див. приклади)
  • Використання стандартних прорізів суперечить тому, що ваша відповідь є дійсною, і одну з них потрібно видалити.
  • Це , тому найкоротша відповідь у байтах виграє.

Приклади

Вхід:

A^(-A)

Вихід:

(nothing)

Вхід:

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

Вихід:

A^B A<->B

Вхід:

["AvB","A^B"]

Вихід:

["AvB","A^B"]

3
Я не знаю, чи це актуально, але ця проблема зводиться до максимальної кількості упаковки, яка не відповідає NP.
Лейф Віллерс

Відповідно до вашої граматики, третє твердження в прикладі (AvB)->-B(AvB)->(-B)
невірне

@proudhaskeller Спасибі, виправили це.
PurkkaKoodari

також круглі дужки в A<->(Q^C))v((-B)vHпюре.
гордий haskeller

@proudhaskeller Ще раз дякую.
PurkkaKoodari

Відповіді:


3

Рубі, 299 298 283 279 байт

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
  • Очікує масив виразів.
  • Якщо ви збираєтеся запустити його, встановіть $ VERBOSE = нуль зсередини рубіну, щоб у вас не було багато попереджень про перевизначення констант.
  • Зауважте, що вона фактично встановлює також змінну "v", але це не має значення.
  • Використовує значення істинності, оскільки вони вже мають усі необхідні оператори, крім імплікації. На жаль, у Ruby немає булевого класу, тому нам потрібно маніпулювати патч-об'єкт, щоб отримати наслідки :)
  • Можна зробити це коротше, якщо ми просто встановимо ВСІ великі великі величини, але тоді для запуску знадобиться величезна кількість часу. Напевно, має бути застереження у питанні про це.

Безголівки:

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 байт

Зараз не дуже гольф, але я вважаю, що отримав би м'яч з відповіддю. Спробуйте тут , g()це основна функція.

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)

Дуже круто. Я отримав це до 428: repl.it/BCzp
PurkkaKoodari

Існує проблема з тим, як ви моделюєте значення істини. Наприклад, g ("A (AvA) <-> A") повинен повернути свій вхід, але він не працює, тому що якщо A = 1, то AvA = 2.
Ібрагім Тенсер

Ага, ти маєш рацію, дякую, що вказав на це. Повернув його назад до "і", оскільки я не міг придумати коротший спосіб їх порівняння. Також дякую за зміни в гольф на Піетю!
TheMadHaberdasher

Я вважаю v, що так or.
PurkkaKoodari

...так. Спасибі.
TheMadHaberdasher
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.