Четвърта задача
- Краен срок
- 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)
.