[英]Mercury: This predicate works if declared at the top level, but not as a lambda
(The excerpt below is from this test suite , which is half of the two-file program found here .) (以下摘录来自该测试套件 ,它是此处找到的两个文件程序的一半。)
I've defined an auxiliary predicate in two ways: once at the top level (called helper
), and once as a lambda (called Helper
). 我用两种方式定义了一个辅助谓词:一次是在顶层(称为
helper
),一次是作为lambda(称为Helper
)。 In the last three lines of the code below, I use that auxiliary predicate. 在下面的代码的最后三行中,我使用了该辅助谓词。 If I use
helper
it works, but if I use Helper
I get an error (below). 如果使用
helper
程序,则可以使用,但是如果使用Helper
则会出现错误(如下)。
I suspect the problem might be that I am able to specify a type signature as well as a mode signature for the type-level predicate, but only a mode signature for the lambda. 我怀疑问题可能在于我能够为类型级别谓词指定类型签名以及模式签名,但只能为lambda指定模式签名。 (If that's the problem, I don't know what to do about it.)
(如果那是问题,我不知道该怎么办。)
Here's the relevant code: 以下是相关代码:
:- 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 )
Here's the error I get from using Helper
: 这是我从使用
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'.
I don't have a complete answer to your question, but I believe this has something to do with currying the predicate. 对于您的问题,我没有完整的答案,但我相信这与引述谓词有关。 I wrote some test code which queries a small database of fish.
我写了一些测试代码,查询一个小的鱼类数据库。
:- pred fish(string::out, int::out) is multi.
fish("Red", 1).
fish("Blue", 2).
fish("Green", 3).
This helper produces the same error as above: 该助手产生与上面相同的错误:
Helper = (pred(S::in, L::out) is nondet :- fish(S, L)),
solutions(Helper("Red"), Sols)
This helper works fine: 这个助手工作正常:
Helper2 = (pred(X::out) is nondet :- fish("Red", X)),
solutions(Helper2, Sols)
I also tried wrapping the solutions function. 我也尝试包装解决方案功能。 This works fine:
这工作正常:
:- func solutions_to(string) = list(int).
solutions_to(Color) = Answers :-
P = (pred(X::out) is nondet :- fish(Color, X)),
solutions(P, Answers).
I was able to write a predicate that returned a lambda predicate, however I was unable to write a function to do the same. 我能够编写一个返回lambda谓词的谓词,但是我无法编写一个函数来执行相同的操作。 This is where I start to get confused.
这就是我开始感到困惑的地方。 According to this page it is only possible to return a predicate with mode information if you wrap the predicate in a discriminated union type.
根据此页面 ,仅当将谓词包装为已区分的联合类型时,才可能返回带有模式信息的谓词。 The following code isn't really useful, but it manages to both
以下代码并不是真正有用,但可以
See: 看到:
:- 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)).
And then to use it: 然后使用它:
Inner = inner((pred(X::out, Y::out) is multi :- fish(X, Y))),
WP = make_pred(Inner, "Red"),
WP = wrapper(P),
solutions(P, Sols),
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.