Mercury中lambda和谓词的匹配决定论
在Mercury中,我可以声明lambda与包含lambda的谓词的模式具有相同的决定论吗 这就是我要做的。我在array2d类型上编写了一个fold函数(如下)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
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,因此它们不能调用semidetPred
。如果我将lambdas更改为semidet,则整个fold
不能是det
我如何解决这个问题?看起来最直接的方法是声明lambda从fold
谓词继承了它们的决定论——所以当fold
用作det时,它们是det,同样对于semidet——但我不知道这是否可能
当然,另一种方法是将
FoldRows
和FoldCols
转换为具有多种模式的命名谓词(而不是lambda)。但这很快就变得不雅观了,我想知道是否有更直接的解决方案。Mercury有时可以推断谓词的模式和决定论,所以我最初尝试从lambda表达式中省略决定论声明。但是Mercury的lambda语法不允许我这样做,所以这个推断不能用于lambda
我担心,正如您所猜测的,唯一的解决方案是将FoldRows和FoldCols转换为多模式命名谓词