lambda - Mercury:如果在顶层声明,则此谓词有效,但不能作为 lambda
问题描述
(下面的摘录来自这个测试套件,它是这里找到的两文件程序的一半。)
我以两种方式定义了辅助谓词:一次在顶层(称为helper
),一次作为 lambda(称为Helper
)。在下面代码的最后三行中,我使用了那个辅助谓词。如果我使用helper
它可以工作,但如果我使用Helper
我会得到一个错误(如下)。
我怀疑问题可能是我能够为类型级别谓词指定类型签名和模式签名,但只能为 lambda 指定模式签名。(如果这是问题所在,我不知道该怎么办。)
以下是相关代码:
:- pred helper( query, int ).
:- mode helper( in, out ) is nondet.
helper( Q, F ) :-
inQuery( fiveNumberSpace, Q, F ).
testQAnd = Res :-
QQF = qqFind( qFind( list.filter( <(3) ) ) )
, QQC = qqCond( qCond( func( Int )
= (if Int > 4 then no else yes) ) )
, Helper = ( pred( Q :: in, F :: out ) is nondet :-
inQuery( fiveNumberSpace, Q, F ) )
% TODO Why can't I use Helper instead of helper for these?
, solutions( helper( qqAnd( [QQF ] ) ) , F1 )
, solutions( helper( qqAnd( [QQF, QQC] ) ) , F2 )
, solutions( helper( qqAnd( [ QQC] ) ) , F3 )
这是我从使用中得到的错误Helper
:
Making Mercury/cs/test.c
test.m:098: In clause for function `testQAnd'/0:
test.m:098: in argument 1 of call to predicate `solutions'/2:
test.m:098: in unification of argument
test.m:098: and term `Helper(V_34)':
test.m:098: type error in argument(s) of higher-order term (with arity 1).
test.m:098: Functor (Helper) has type `pred(query.query, int)',
test.m:098: expected type was `((func V_13) = V_14)'.
** Error making `Mercury/cs/test.c'.
解决方案
我对您的问题没有完整的答案,但我相信这与使用谓词有关。我写了一些测试代码来查询一个小型的鱼数据库。
:- 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).
我能够编写一个返回 lambda 谓词的谓词,但是我无法编写一个函数来做同样的事情。这是我开始感到困惑的地方。根据此页面,如果您将谓词包装在可区分的联合类型中,则只能返回带有模式信息的谓词。以下代码并不是真正有用,但它可以同时实现
- 实现一个穷人对 lambda 的柯里化
- 从函数返回一个 lambda 谓词
看:
:- 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),
推荐阅读
- excel - 宏 Essbase 检索
- python - 基于来自另一个字典的整数值从字典列表值中随机抽样,具有匹配的键
- python - 有没有办法从不同长度的熊猫数据框中移动多行?
- xcode - .h 和 .m 类查看的 Xcode 11 问题
- javascript - React 组件在首次提交时不显示 Flash 消息
- java - Java Spring 框架资源未找到 IntelliJ
- python - Python Beautifulsoup 分解从元素中删除元素
- javascript - 在 JavaScript 中单击按钮后删除输出
- java - OSX UnsatisfiedLinkErrors 在 OSX catalina 10.15.x 上运行 JNI 包装的库
- c# - C# 将 XML 解析为不同的列表