У меня нет полного ответа на ваш вопрос, но я считаю, что это как-то связано с каррированием предиката.Я написал тестовый код, который запрашивает небольшую базу данных рыб.
:- pred fish(string::out, int::out) is multi.
fish("Red", 1).
fish("Blue", 2).
fish("Green", 3).
Этот помощник выдает ту же ошибку, что и выше:
Helper = (pred(S::in, L::out) is nondet :- fish(S, L)),
solutions(Helper("Red"), Sols)
Этот помощник работает нормально:
Helper2 = (pred(X::out) is nondet :- fish("Red", X)),
solutions(Helper2, Sols)
Я также попытался обернуть функцию решений.Это прекрасно работает:
:- func solutions_to(string) = list(int).
solutions_to(Color) = Answers :-
P = (pred(X::out) is nondet :- fish(Color, X)),
solutions(P, Answers).
Мне удалось написать предикат, который возвращал лямбда-предикат, однако я не смог написать функцию, которая бы делала то же самое.Здесь я начинаю путаться.Согласно этой странице вернуть предикат с информацией о режиме можно только в том случае, если вы преобразуете предикат в дискриминируемый тип объединения.Следующий код не очень полезен, но он позволяет одновременно
- реализовать лямбда-карри бедняков
- возвращает лямбда-предикат из функции
См .:
:- type inner
---> inner(pred(string:: out, int::out) is multi).
:- type wrapper
---> wrapper(pred(int::out) is nondet).
:- func make_pred(inner, string) = wrapper.
make_pred(Inner, Param) = P :-
Inner = inner(I),
P = wrapper(pred(X::out) is nondet :- I(Param, X)).
А затем использовать его:
Inner = inner((pred(X::out, Y::out) is multi :- fish(X, Y))),
WP = make_pred(Inner, "Red"),
WP = wrapper(P),
solutions(P, Sols),