Как определить, является ли true / false, а затем вернуть функцию - PullRequest
0 голосов
/ 28 сентября 2019

У меня есть таблицы истинности для разных логических операторов;

truthtable a1
 | a1 == "mynot"   = [(p,q,r,s) | p <- [0,1], q <- [0,1], let r = mynot p, s <- ["mynot"]]
 | a1 == "myand"   = [(p,q,r,s) | p <- [0,1], q <- [0,1], let r = myand p q, s <- ["myand"]]
 | a1 == "myor"    = [(p,q,r,s) | p <- [0,1], q <- [0,1], let r = myor p q, s <- ["myor"]]
 | a1 == "myimply" = [(p,q,r,s) | p <- [0,1], q <- [0,1], let r = myimply p q, s <- ["myimply"]]

Теперь я должен создать функцию (equiv), которая определяет, действуют ли два оператора одинаково, и приводит пример счетчика, если нет.Таким образом, для equiv "myimply" "myimply" он должен определить, что это эквивалентно, но для equiv "myimply" "myor" он должен вызвать функцию counterEx, которая дает контрпример (что операторы не совпадают).

Теперь у меня было это:

equiv a1 a2
 | truthtable a1 == truthtable a2 = True
 | otherwise = counterEx a1 a2

counterEx a1 a2 = truthtable a1 ++ truthtable a2

Но, конечно, equiv имеет разные результаты и, следовательно, это невозможно.Однако я действительно не знаю, как я могу привести лучший контрпример (чем просто дать все возможности, и вы просто посмотрите, что не то же самое).Также я не знаю, как я могу вызвать функцию counterEx, если таблицы истинности не эквивалентны, а только определить, что они одинаковы, если таблицы истинности действительно одинаковы.

1 Ответ

2 голосов
/ 28 сентября 2019

Наиболее идиоматичным решением здесь является использование пользовательского типа возвращаемых данных

type TTable = [(Int,Int,Int,Int)]

data EquivResult
  = Equivalent
  | NotEquivalent TTable

equiv :: TTable -> TTable -> EquivResult
equiv a1 a2
 | truthtable a1 == truthtable a2 = Equivalent
 | otherwise                      = NotEquivalent (counterEx a1 a2)

Можно также использовать Maybe TTable вместо определения пользовательского EquivResult, но менее очевидно, что Nothingбудет означать «эквивалент», а Just _ будет означать «_ контрпример».

equiv :: TTable -> TTable -> Maybe TTable
equiv a1 a2
 | truthtable a1 == truthtable a2 = Nothing
 | otherwise                      = Just (counterEx a1 a2)

Кстати, почему вы используете целые числа 0 и 1 для логических значений?Почему бы не False и True типа Bool.Использование Int для логических значений кажется странным и допускает недопустимые значения, такие как 2.

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

...