수성에서 람다가 람다를 포함하는 술어의 모드와 동일한 결정론을 가지고 있다고 선언 할 수 있습니까?수성에서 람다와 술어의 일치 결정
다음은 내가하려는 일입니다. 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).
그러나 나는 DET 또는 semidet 조건 중 하나를 동의 (그리고 술어에 대한 호출이 실패 할 경우 실패)에 fold
를 원한다. mode ... is semidet
행의 주석 처리를 제거하면 해결 방법을 모르는 컴파일러 오류가 발생합니다. 문제는 fold
의 람다가 det로 선언되었으므로 semid를 Pred
으로 부를 수 없다는 것입니다. lambda를 semidet으로 변경하면 fold
은 전체적으로 det 할 수 없습니다.
어떻게 해결할 수 있습니까? 람다가 fold
술어에서 결정론을 상속 받았다고 선언하는 것이 가장 직접적인 방법 인 것처럼 보입니다. 따라서 fold
이 det와 마찬가지로 semidet에 사용되는 경우에는 det가됩니다. 그러나 가능하면 그럴 수 있습니다. .
다른 접근법은 물론 FoldRows
과 FoldCols
을 다중 모드가있는 명명 된 술어 (람다가 아님)로 변환하는 것입니다. 그러나 그것은 신속하게 비 효과적이되고, 나는 더 간단한 해결책이 있는지 궁금해하고 있습니다.