Mercury中lambda和谓词的匹配决定论

Mercury中lambda和谓词的匹配决定论,lambda,non-deterministic,mercury,Lambda,Non Deterministic,Mercury,在Mercury中,我可以声明lambda与包含lambda的谓词的模式具有相同的决定论吗 这就是我要做的。我在array2d类型上编写了一个fold函数(如下)fold为数组中的每个元素调用调用方提供的谓词。只要它只接受det谓词作为参数,它就可以正常工作 :- pred fold(array2d(T), pred(T, int, int, A, A), A, A). :- mode fold(in, pred(in, in, in, in, o

在Mercury中,我可以声明lambda与包含lambda的谓词的模式具有相同的决定论吗

这就是我要做的。我在array2d类型上编写了一个fold函数(如下)
fold
为数组中的每个元素调用调用方提供的谓词。只要它只接受det谓词作为参数,它就可以正常工作

:- pred fold(array2d(T), pred(T,  int, int, A, A),              A,  A).
:- mode fold(in,         pred(in, in,  in, in, out) is det,     in, out) is det.
% Uncommenting the next line causes mode errors during compilation
% :- mode fold(in,       pred(in, in,  in, in, out) is semidet, in, out) is semidet.

fold(Array, Pred, !Accumulator) :-
    bounds(Array, NumRows, NumCols),

    FoldRows = (pred(RowNumber :: in, RowAccIn :: in, RowAccOut :: out) is det :-
        FoldCols = (pred(ColNumber :: in, ColAccIn :: in, ColAccOut :: out) is det :-
            Value = Array^elem(RowNumber, ColNumber),
            Pred(Value, RowNumber, ColNumber, ColAccIn, ColAccOut)
        ),
        int.fold_up(FoldCols, 0, NumCols - 1, RowAccIn, RowAccOut)
    ),
    int.fold_up(FoldRows, 0, NumRows - 1, !Accumulator).
但是我想
fold
接受det或semidet谓词(如果任何对谓词的调用失败,则失败)。正在取消对
模式的注释。。。是semidet
行给我不知道如何解决的编译器错误。问题是
fold
中的lambda被声明为det,因此它们不能调用semidet
Pred
。如果我将lambdas更改为semidet,则整个
fold
不能是det

我如何解决这个问题?看起来最直接的方法是声明lambda从
fold
谓词继承了它们的决定论——所以当
fold
用作det时,它们是det,同样对于semidet——但我不知道这是否可能


当然,另一种方法是将
FoldRows
FoldCols
转换为具有多种模式的命名谓词(而不是lambda)。但这很快就变得不雅观了,我想知道是否有更直接的解决方案。

Mercury有时可以推断谓词的模式和决定论,所以我最初尝试从lambda表达式中省略决定论声明。但是Mercury的lambda语法不允许我这样做,所以这个推断不能用于lambda

我担心,正如您所猜测的,唯一的解决方案是将FoldRows和FoldCols转换为多模式命名谓词