[英]Find number of successes from a list of terms/goals
I have written the following predicate exactly/2
that succeeds if exactly N
of the numbers in the list L
are equal to 1:如果列表
L
中的N
个数字恰好等于 1,我已经编写了以下谓词exactly/2
:
:- 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).
For example, the call exactly(X, [1, 0, 0, 1, 0, 1])
will bind X
to 3
.例如,调用
exactly(X, [1, 0, 0, 1, 0, 1])
会将X
绑定到3
。
I want to create something similar, but for predicates: I want to write a predicate that succeeds if exactly N
goals from the list L
are successful.我想创建类似的东西,但对于谓词:我想编写一个谓词,如果列表
L
中的N
个目标成功,则该谓词成功。
For example, the call exactly(X, [true, false, member(1, [1, 2, 3]), member(0, [1, 2, 3])])
should bind X
to 2
.例如,调用
exactly(X, [true, false, member(1, [1, 2, 3]), member(0, [1, 2, 3])])
应该将X
绑定到2
。
Actually, this can be done, as shown by this code:实际上,这是可以做到的,如以下代码所示:
:- 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).
The predicate list_member tells the compiler which mode of list.member you want to call.谓词 list_member 告诉编译器您要调用 list.member 的哪种模式。 As for true and false, you would need to define predicates of those names as well.
至于真假,您还需要定义这些名称的谓词。 (By default, they exist as goals only.)
(默认情况下,它们仅作为目标存在。)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.