Сравнение строк с булевыми функциями истинности

Я искал и до сих пор не имею ни малейшего понятия, поэтому, пожалуйста, потерпите меня.

У меня есть строки, каждая из которых соответствует определенной матрице признаков. Примеры:

'a' = [-vegetable, +fruit, +apple, -orange]
'o' = [-vegetable, +fruit, -apple, +orange]
't' = [+vegetable, -fruit, -apple, -orange]

Обратите внимание, что это просто обозначение, которое я выбрал для представления матриц здесь.

Что я хочу сделать, так это взять любое количество таких строк и сравнить их с некоторым количеством функций истинности. Итак, оценивая строку 'aoaot' по сравнению с:

[+fruit] => [+apple]
equivalently: (not [+fruit]) or [+apple]

должен возвращать количество раз, когда это значение является ложным для данной строки. Либо что-то вроде этого:

[True, False, True, False, True]

Или абсолютный подсчет количества оценок до False, например. 2 здесь. Какой разумный способ сделать это в питоне? Я изучаю NLTK, но не уверен.


person Pygmalion    schedule 04.12.2011    source источник
comment
Если вы не хотите анализировать запросы на естественном языке, вам не нужен NLTK. Разбор логических выражений, даже если разрешена произвольная вложенность, довольно прост с большинством технологий синтаксического анализа (почти тривиально с некоторыми).   -  person    schedule 05.12.2011
comment
Я делаю. Я пытаюсь создать теоретико-оптимальную функцию eval() для ранжирования фонологических ограничений.   -  person Pygmalion    schedule 05.12.2011
comment
Если «t» означает «помидор», это на самом деле фрукт, по крайней мере, с ботанической точки зрения. oxforddictionaries.com/page/tomatofruitveg   -  person PaulMcG    schedule 05.12.2011


Ответы (2)


Вы можете реализовать необходимую логику, используя тип set.

m = {
    'a':set(['fruit', 'apple']),
    'o':set(['fruit', 'orange']),
    't':set(['vegetable'])
}

pred = lambda f: ('fruit' in f) <= ('apple' in f)

# True/False array
[ pred(m[f]) for f in 'aoaot' ]

# Number of falses
sum( not pred(m[f]) for f in 'aoaot' )
person Marcelo Cantos    schedule 04.12.2011
comment
Что именно здесь сравнивают? - person Pygmalion; 05.12.2011
comment
('fruit' in f) <= ('apple' in f) возвращает true, если f не содержит фруктов или содержит яблоко. - person Marcelo Cantos; 05.12.2011

Если вы хотите иметь больше гибкости в своем собственном синтаксисе, вот простой синтаксический анализатор для данных, которые вы дали:

data = """\
a = [-vegetable, +fruit, +apple, -orange, -citrus] 
o = [-vegetable, +fruit, -apple, +orange, +citrus] 
t = [+vegetable, -fruit]"""

from pyparsing import Word, alphas, oneOf, Group, delimitedList

# a basic token for a word of alpha characters plus underscores
ident = Word(alphas + '_')

# define a token for leading '+' or '-', with parse action to convert to bool value
inclFlag = oneOf('+ -')
inclFlag.setParseAction(lambda t: t[0] == '+')

# define a feature as the combination of an inclFlag and a feature name
feature = Group(inclFlag('has') + ident('feature'))

# define a definition
defn = ident('name') + '=' + '[' + delimitedList(feature)('features') + ']'

# search through the input test data for defns, and print out the parsed data
# by name, and the associated features
defns = defn.searchString(data)
for d in defns:
    print d.dump()
    for f in d.features:
        print f.dump('  ')
    print

Отпечатки:

['a', '=', '[', [False, 'vegetable'], [True, 'fruit'], [True, 'apple'], [False, 'orange'], [False, 'citrus'], ']']
- features: [[False, 'vegetable'], [True, 'fruit'], [True, 'apple'], [False, 'orange'], [False, 'citrus']]
- name: a
  [False, 'vegetable']
  - feature: vegetable
  - has: False
  [True, 'fruit']
  - feature: fruit
  - has: True
  [True, 'apple']
  - feature: apple
  - has: True
  [False, 'orange']
  - feature: orange
  - has: False
  [False, 'citrus']
  - feature: citrus
  - has: False

['o', '=', '[', [False, 'vegetable'], [True, 'fruit'], [False, 'apple'], [True, 'orange'], [True, 'citrus'], ']']
- features: [[False, 'vegetable'], [True, 'fruit'], [False, 'apple'], [True, 'orange'], [True, 'citrus']]
- name: o
  [False, 'vegetable']
  - feature: vegetable
  - has: False
  [True, 'fruit']
  - feature: fruit
  - has: True
  [False, 'apple']
  - feature: apple
  - has: False
  [True, 'orange']
  - feature: orange
  - has: True
  [True, 'citrus']
  - feature: citrus
  - has: True

['t', '=', '[', [True, 'vegetable'], [False, 'fruit'], ']']
- features: [[True, 'vegetable'], [False, 'fruit']]
- name: t
  [True, 'vegetable']
  - feature: vegetable
  - has: True
  [False, 'fruit']
  - feature: fruit
  - has: False

Pyparsing делает за вас большую часть накладных расходов, таких как перебор входной строки, пропуск ненужных пробелов и возврат проанализированных данных с использованием именованных атрибутов. Ознакомьтесь с логическим оценщиком на вики-странице pyparsing (SimpleBool.py) или с более полным пакетом логического оценщика booleano.

person PaulMcG    schedule 05.12.2011