применение списка к введенной функции для проверки на тавтологию

Я хочу написать функцию в haskell, которая определяет, является ли логическая функция (введенная с лямбда-выражением в ghci) тавтологией или нет. Ввод должен выглядеть так:

taut n (\[x..] -> ... == ...)

taut 3 (\[x,y,z] -> ((x||y)||z) == (x||(y||z)) )

Я уже создал все возможные логические комбинации с

combinations n = replicateM n [True,False] 

cmb n = concat (combinations n)

но теперь мне нужна функция, которая берет эти элементы списка и вставляет их в n переменных в введенной затем функции.

Заранее спасибо :)


person rsng    schedule 11.12.2011    source источник
comment
Это не совсем домашняя работа, это дополнительное задание для модуля в университете... мы можем сделать это, если захотим, но это не обязательно - но я хочу это сделать, потому что хочу хоть как-то понять хаскелл...   -  person rsng    schedule 11.12.2011


Ответы (1)


Ваша функция combinations уже создает список списков длины n, содержащих все возможные перестановки True и False. Вам не нужно использовать concat; результат уже включает все возможные записи в вашу функцию. Дело в том, что функция, которую вы проверяете, уже ожидает список (в форме \[a,b,c...]).

То есть для fn, берущего список длины 3, combinations 3 будет:

[[True,True,True],[True,True,False],[True,False,True],[True,False,False],
 [False,True,True],[False,True,False],[False,False,True],[False,False,False]]

Каждый элемент этого списка является списком; вы можете напрямую передать их в функцию, которую вы проверяете (та, которая может быть тавтологией). Учитывая приведенный выше список, все, что вам нужно сделать, это попробовать каждый элемент.

РЕДАКТИРОВАТЬ (пытаясь немного уточнить):

Вам нужна функция taut, которая принимает другую функцию типа [Bool] -> Bool и определяет, является ли эта функция тавтологией. Это означает, что taut будет иметь тип, подобный Int -> ([Bool] -> Bool) -> Bool. Допустим, вы начинаете это так:

taut :: Int -> ([Bool] -> Bool) -> Bool
taut n fn = ...

Теперь n — это длина, а fn — это функция. Ваша функция combinations принимает n и возвращает все возможные допустимые входные данные в fn. Обратите внимание, что fn ожидает [Bool], а combinations n — это [[Bool]], что означает, что каждый элемент может быть входом для fn. Зная это, все, что вам нужно сделать, это применить fn к каждому элементу combinations n и посмотреть, всегда ли результат будет одинаковым.

В вашей функции taut вам не нужно беспокоиться о том, как назначаются переменные внутри тестируемой функции. Когда вы на самом деле пишете эту функцию, если она имеет форму \[x,y,z]->..., x, y и z, она будет назначена внутри нее благодаря сопоставлению с образцом.

person Tikhon Jelvis    schedule 11.12.2011
comment
Да, я уже задавался вопросом, действительно ли мне нужно поместить их в один список, но я подумал, может быть, я мог бы использовать этот список и каким-то образом подсчитать и вставить логические значения в переменные... но это действительно то, с чего начинается проблема - Я подумал, что могу начать тестировать, как я могу ввести лямбда-функцию в код, поэтому я набрал taut [x,y,z] = (\[x,y,z] -> ((x||y)||z) == (x||(y||z)) ), чтобы увидеть, могу ли я вставить логические значения для x, y, z, но даже это не дало мне экземпляр... от использования ошибки «печати», которую я действительно не понимаю... - person rsng; 11.12.2011
comment
Я немного смущен тем, как именно вы ожидаете, что функция taut будет работать. Я думал, вы хотите, чтобы он брал лямбду и пробовал каждую комбинацию входных данных. Вы думаете сделать это как-то по-другому? Кроме того, taut в вашем комментарии кажется совершенно отличным от taut в вашем вопросе - первый принимает число и функцию; второй, кажется, занимает два списка (Int -> [Bool] -> Bool vs [Bool] -> [Bool] -> Bool). - person Tikhon Jelvis; 11.12.2011
comment
Второе предложение именно так, как я хочу, чтобы оно работало... моя натянутая функция в комментарии выше была просто тестом, в котором я мог видеть, как я могу вставить значения, чтобы приблизиться к решению, но, видимо, это не работает во всяком случае, и я сомневаюсь, что Haskell работает так же. - person rsng; 11.12.2011
comment
Правильно. Я попытаюсь уточнить свой ответ. - person Tikhon Jelvis; 11.12.2011
comment
О, и что касается вашей ошибки no instance...: вы, вероятно, получили ее, введя значение, которое было функцией. Это просто означает, что ghci не знает, как напечатать значение, которое вы ему дали, и не знает, как превратить функцию в строку. - person Tikhon Jelvis; 11.12.2011
comment
Это действительно очень помогло... Я даже понял, как применить аргумент функции в параметрах, вспомнив свою базовую математику, прежде чем увидел ваш ответ... Я думаю, что теперь я близок к фактическому решению, поскольку я применил список логических значений для моей функции taut с taut n fx = map fx(combinations n) - теперь я получаю список [True,True..] и в настоящее время выясняю, как объединить их в 1 единственный вывод, если все они верны. - person rsng; 11.12.2011
comment
и готово - taut n fx = and(map fx(combinations n)) работает отлично. Оглядываясь назад, все кажется таким простым :/ Я очень ценю вашу помощь, я думаю, что она продвинула меня намного дальше на моем пути, чтобы понять, что я делаю. - person rsng; 11.12.2011
comment
Приятно слышать, что у вас все получилось — моя цель состояла в том, чтобы прояснить достаточно, чтобы вы сами получили ответ, не выдавая его. Это станет проще, когда вы напишете кучу программ на Haskell. Примечание по стилю: вы можете заменить круглые скобки на . и $, чтобы у вас было taut n fx = and . map fn $ combinations n, которое немного легче читать (на мой взгляд). - person Tikhon Jelvis; 11.12.2011