Четвърта задача

Краен срок
05.05.2011 17:00

Срокът за предаване на решения е отминал

История на промените

Напишете миниатюрна библиотека за комбиниране на предикати.

По-точно

За нашите цели, "предикат" е функция на един аргумент, която връща True или False. Може да имате фунции, които връщат предикати. Например gt(x) е предикат, който "казва" дали аргумента му е по-голям от x.

positive = gt(0)
positive(10) # True
positive(-10) # False

Аналогично, lt(x):

negative = lt(0)
negative(10) # False
negative(-10) # True

Предикати

Имплементирайте следните предикати:

  • gt(x) -- връща дали аргумента е по-голям (но не и равен) от x
  • lt(x) -- връща дали аргумента е по-малък (но не и равен) от x
  • eq(x) -- връща дали аргумента е равен на x
  • oftype(t) -- връща дали аргумена е от тип t (проверява с instanceof)
  • present() -- връща истина, ако аргумента е различен от None
  • pred(function) -- връща истина, ако function връща истина за обекта

Комбиниране на предикати

Предикатите могат да се комбинират по няколко начина.

  • a & b (конюнкция) -- връща истина за x, ако a(x) и b(x) са истина
  • a | b (дизюнкция) -- връща истина за x, ако a(x) или b(x) е истина
  • ~a (отрицание) -- връща истина за x, ако a(x) е неистина
  • a(x) >> b(x) (импликация) -- ако a(x) е истина, връща b(x); в противен случай -- връща истина
  • for_any(*predicates) -- връща истина, ако поне един от предикатите в predicates връща истина за аргумента
  • for_all(*predicates) -- връща истина, ако всички предикати в predicates връщат истина за аргумента

Примери

digit = oftype(int) & gt(-1) & lt(10)
binary = eq(0) | eq(1)
number = for_any(oftype(int), oftype(float), oftype(complex))
is_the_empty_string = pred(lambda x: x is "")

Бележки

  • Няма значение дали комбинатори ще оценяват предикати, когато това не нужно. Ако a(x) е неистина, то няма значение дали a(x) & b(x) ще оцени b(x)
  • Задължително изпълнете примерния тест. В него очакваме да дефинирате и осемте предиката -- ако import-а се провали, ще имате 0 точки.
  • Има много начини, по които тази задача може да се реши. Помислете в кое решение ще бъде най-лесно да се добавя нов предикат.
  • Правете проверки за истина и неистина, а не за True или False.

Идеи за решение

Няколко различни начина, по които мислим, че може да решите задачата.

  • Сторете дърво, което да обработвате при изпълнение проверка на предикат
  • Направете йерархия, в която всеки предикат да е клас.
  • Всеки предикат може да се представи като една ламбда.
  • Може да направите функции, които вземат ламба и връщат предикатен клас. Например gt = make(lambda x, m: x > m).