我正在尝试检查列表列表中的所有子列表是否等于列表列表的长度。
例如,如果我有[[1,2],[3,4]]为真,因为我有2个列表 2个元素。
否则,如果我有
[[1],[2,3]]为假,因为有2个列表,但并非所有列表都有2个 元素
[[1,2,2,[2,3],[3,4]]为假,因为我有2个列表,所有列表都有 2个元素,而不是两个
。
我做了这两个功能:
count([],0).
count([_H|T],N):-count(T,N1),N is N1+1 .
ma([],0).
ma([H|T],N):- count(H,M1),ma(T,N1), M1 is N1.
我对列表中的count元素进行了“计数”(和工作),并向列表中返回N个元素。
“ ma”函数不起作用,因为执行“ count”直到0,然后在执行ma但执行1步之后直接返回M1为N1,然后返回2,显然返回false。 我希望在程序结束时使M1为N1(就像在另一种编程语言中一样,但我认为那是当时不正确的形式。
编辑:
Daniel建议使用:
ma([H], N) :- length(H, N).
ma([H|T], N) :- length(H, N), ma(T, N).
但是一个包含3个子列表且每个元素都包含2个元素的列表将得出结果2,相反结果将为false(错误),因为该列表的N个数必须等于ALL Sublist中的N个元素。
我将自己做,而无需内置序言。
答案 0 :(得分:1)
您的count/2
与内置的length/2
相似,除了内置的实例化模式更多(尝试length(X, Y)
来查看)。更喜欢length/2
。
您是正确的,您的ma/2
谓词无济于事,因为0不是子列表的长度。基本上,您在这里选择了错误的基本案例;您的基本情况应该是其中仅包含一项的列表:
ma_1([H], N) :- length(H, N).
ma_1([H|T], N) :- length(H, N), ma(T, N).
您需要将其包装在确保长度与外部列表的长度匹配的东西中
ma(L, N) :- length(L, N), ma_1(L, N).
请注意,无需获取单独的变量并声明它们的相等性(您与N和N1共舞)。如果N没有正确的值,Prolog只会失败,这就是您想要的。 (注意,请勿统一使用is
。is
的目的是将右侧的算术表达式简化为一个值并将其分配给左侧的变量,例如{{1 }}。
另一种方法是以逻辑形式编写您的实际请求,然后将其写入。该请求的逻辑形式将类似于“如果N是L的长度,并且对于L的所有项目X,它们也是长度N的列表,则ma(L,N)成立”。看起来像这样:
X is 2 + 3*4
这样做的好处是,尽管担心通常是过早的优化,但没有多余的选择点。
另一种方法是使用ma(L, N) :-
length(L, N),
forall(member(X, L),
length(X, N)).
,它的优点是可以为您提供带有变量的后列表。不幸的是,maplist/N
的参数顺序错误,因此您无法做真正可爱的事情,只需编写length/2
。但是,您可以创建一个maplist(length(2), L)
谓词,该谓词会围绕参数翻转:
flip/3
或者,您可以导入flip(P, Y, X) :- call(P, X, Y).
ma(L, N) :- length(L, N), maplist(flip(length, N), L).
并使用其lambda表达式:
library(yall)
这两种方法都允许采用以下解决方案:
ma(L, N) :- length(L, N), maplist({N}/[X]>>length(X, N), L).
答案 1 :(得分:1)
这是一个非常基本解决方案,没有内置谓词:
count_elements([],N,N).
count_elements([_|T],N,N0):-
N1 is N+1,
count_elements(T,N1,N0).
count_length_sub([],_).
count_length_sub([H|T],N):-
count_elements(H,0,N),
count_length_sub(T,N).
solve(L):-
count_elements(L,0,NO),
count_length_sub(L,NO).
?- solve([[1,2],[3,4]]).
true.
?- solve([[1,2],[2,3],[3,4]]).
false.