水星:此谓词在顶层声明时有效,但不能作为lambda声明

时间:2018-12-29 18:44:13

标签: lambda signature mercury

(以下摘录来自该test suite,它是找到的here两个文件程序的一半。)

我已经通过两种方式定义了一个辅助谓词:一次是在顶层(称为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'.

1 个答案:

答案 0 :(得分:0)

对于您的问题,我没有完整的答案,但我认为这与引述谓词有关。我写了一些测试代码,查询小的鱼数据库。

:- 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谓词的谓词,但是我无法编写一个函数来执行相同的操作。这就是我开始感到困惑的地方。根据{{​​3}},只有将谓词包装为已区分的联合类型时,才可能返回带有模式信息的谓词。以下代码并不是真正有用,但可以同时实现两者

  1. 实施穷人的拉姆达法轮功
  2. 从函数返回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),