Передавая лямбды с аргументами в Джесс - PullRequest
3 голосов
/ 23 ноября 2011

Я определил булеву функцию Jess, которая принимает лямбду, следующим образом:

(deffunction at-least(?n ?lambda $?values)
    (>= (length$ (filter ?lambda ?values)) ?n))

Который я могу назвать следующим образом:

(bind ?condition1 (at-least 1 (lambda (?arg) (= ?arg 0)) ?a ?b ?c))
(bind ?condition2 (at-least 2 (lambda (?arg) (< ?arg 0)) ?a ?b ?c))

Это работает просто отлично. Но я использую одни и те же лямбды во многих разных местах, поэтому я хотел бы сделать код немного более кратким, определив некоторые функции для них:

(deffunction fn-zero()
    (lambda (?arg) (= ?arg 0)))

И назовите это так:

(bind ?condition1 (at-least 1 (fn-zero) ?a ?b ?c))

Это тоже отлично работает.

Но как только я хочу добавить параметр, я получаю сообщение об ошибке. У меня есть этот код:

(deffunction fn-less-than(?x)
    (lambda (?arg) (< ?arg ?x)))

(bind ?condition2 (at-least 1 (fn-less-than 0) ?a ?b ?c))

Выдает следующее исключение:

jess.JessException: No such variable x

Я не могу понять, что я делаю здесь неправильно. Почему это работает для функции без параметров, но не для функции с параметрами? Что еще более важно: как я могу заставить это работать?

1 Ответ

2 голосов
/ 17 января 2012

Jess лямбды не являются замыканиями, поэтому ?x недоступно при выполнении функции. Способ дурачиться с порядком выполнения в Jess - это оценивать строки; мы хотим жестко закодировать значение? x в функцию, когда она возвращается, поэтому нам нужно вычислить? x, когда функция собирается. Примерно так будет работать нормально:

(deffunction fn-less-than(?x)
    (eval (str-cat "(lambda (?arg) (< ?arg " ?x "))")))
...