0

如果列表中的数字exactly/2恰好等于 1 ,我编写了以下谓词:NL

:- pred exactly(int, list(int)).
:- mode exactly(in, in) is semidet.
:- mode exactly(out, in) is det.
exactly(N, L) :-
    length(filter(pred(X::in) is semidet :- (X = 1), L), N).

例如,调用exactly(X, [1, 0, 0, 1, 0, 1])将绑定X3.

N我想创建类似的东西,但对于谓词:如果列表中的目标完全成功,我想编写一个成功的谓词L

例如,调用exactly(X, [true, false, member(1, [1, 2, 3]), member(0, [1, 2, 3])])应该绑定X2.

4

1 回答 1

1

实际上,这是可以做到的,如下代码所示:

:- module exactly.

:- interface.
:- import_module io.

:- pred main(io::di, io::uo) is det.

:- implementation.

:- import_module int.
:- import_module list.

main(!IO) :-
    Test1 = list_member(1, [1, 2, 3]),
    Test2 = list_member(0, [1, 2, 3]),
    Tests = [Test1, Test2],
    exactly(N, Tests),
    io.write_line(N, !IO).

:- pred exactly(int::out, list((pred))::in(list_skel((pred) is semidet)))
    is det.

exactly(0, []).
exactly(N, [Test | Tests]) :-
    exactly(NTail, Tests),
    ( if Test then
        N = NTail + 1
    else
        N = NTail
    ).

:- pred list_member(T::in, list(T)::in) is semidet.

list_member(E, L) :-
    list.member(E, L).

谓词 list_member 告诉编译器您要调用哪种 list.member 模式。至于真假,您还需要定义这些名称的谓词。(默认情况下,它们仅作为目标存在。)

于 2020-11-18T02:36:37.033 回答