Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/list/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/ruby-on-rails/54.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
List 如何生成只有两个1和给定长度的其他0的列表?_List_Prolog_Clpfd - Fatal编程技术网

List 如何生成只有两个1和给定长度的其他0的列表?

List 如何生成只有两个1和给定长度的其他0的列表?,list,prolog,clpfd,List,Prolog,Clpfd,我必须生成由2个“1”组成的列表,其他元素为“0”。我尝试了以下代码,但不起作用: count([], _, 0). count([X|T], X, Y) :- count(T, X, Z), Y is 1+Z. count([X1|T],X,Z):- X1\=X,count(T,X,Z). two(X) :- count(X, 1, Counter), Counter =:= 2. 查询长度(Vs,4),Vs ins 0..1,two(Vs)。不会给出任何结果 如何正确生成此类列表? 我希

我必须生成由2个“1”组成的列表,其他元素为“0”。我尝试了以下代码,但不起作用:

count([], _, 0).
count([X|T], X, Y) :- count(T, X, Z), Y is 1+Z.
count([X1|T],X,Z):- X1\=X,count(T,X,Z).

two(X) :- count(X, 1, Counter), Counter =:= 2.
查询
长度(Vs,4),Vs ins 0..1,two(Vs)。
不会给出任何结果

如何正确生成此类列表? 我希望得到类似于[1,1,0,0]、[1,0,1,0]的结果。。。[0, 0, 1, 1].

twoones(Bs) :-
   Bs ins 0..1,
   sum(Bs, #=, 2).

| ?- length(Bs,4), twoones(Bs).
Bs = [_A,_B,_C,_D],
clpz:(_A+_B+_C+_D#=2),
clpz:(_A in 0..1),
clpz:(_B in 0..1),
clpz:(_C in 0..1),
clpz:(_D in 0..1) ? 
yes
| ?- length(Bs,4), twoones(Bs), labeling([], Bs).
Bs = [0,0,1,1] ? ;
Bs = [0,1,0,1] ? ;
Bs = [0,1,1,0] ? ...

在这里,我使用的是
library(clpz)
,它是
library(clpfd)
的继承者。对于这样简单的例子,没有太大区别。

我认为您在这里把它弄得太复杂了。您不必在这里使用
clpfd
,只需创建一个生成此类列表的谓词即可

我们可以首先创建一个谓词,该谓词与仅包含
0
s的所有列表相统一:

all0([]).
all0([0|T]) :-
    all0(T).
接下来,我们可以使用1s(N,l)创建一个谓词
,该谓词将在它生成的列表中“注入”
N
个谓词:

with1s(0, L) :-
    all0(L).
with1s(N, [H|T]) :-
    N > 0,
    ((H=1, N1 is N-1);
     (H=0, N1 = N)),
    with1s(N1, T).
例如,对于三个元素的列表,我们得到:

?- L = [_,_,_], with1s(2, L).
L = [1, 1, 0] ;
L = [1, 0, 1] ;
L = [0, 1, 1] ;
false.

当然,这不是双向的,我把它作为进一步改进谓词的练习。

这些都是很好的答案

这是另一个
nth0
来自
库(列表)

  • SWI序言
  • 干细胞

  • 为了便于说明,两个
    1
    已被
    a
    b
    替换

  • findall(0,介于(1,Zlen,uu,Zlist)之间)
    创建长度为
    Zlen
    0
    Zlist
    )列表。看

语法是指定列表模式的一种非常自然的方式:

two --> [1], one ; [0], two.
one --> [1], zeros ; [0], one.
zeros --> [] ; [0], zeros.
示例调用:

?- length(Xs, 3), phrase(two, Xs, []).
Xs = [1, 1, 0]
Yes (0.00s cpu, solution 1, maybe more)
Xs = [1, 0, 1]
Yes (0.00s cpu, solution 2, maybe more)
Xs = [0, 1, 1]
Yes (0.00s cpu, solution 3, maybe more)
No (0.00s cpu)

您可以使用
trace
找出它卡住的地方。
length(Zlist,Zlen),maplist((0),Zlist)
是此
findall/3
的纯版本。您可以去掉/3之间剩余的第一个
。但是,对
列表的实例化不会对计算产生太大的影响(删减)。没有人期待这样的结果!在这种情况下,
短语((零[1],零[1],零),Xs)。
two --> [1], one ; [0], two.
one --> [1], zeros ; [0], one.
zeros --> [] ; [0], zeros.
?- length(Xs, 3), phrase(two, Xs, []).
Xs = [1, 1, 0]
Yes (0.00s cpu, solution 1, maybe more)
Xs = [1, 0, 1]
Yes (0.00s cpu, solution 2, maybe more)
Xs = [0, 1, 1]
Yes (0.00s cpu, solution 3, maybe more)
No (0.00s cpu)